BxDolAiChatUiTest.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <?php
  2. /**
  3. * Chat action buttons the agent asks for: only safe types, URLs and texts reach the chat.
  4. */
  5. class BxDolAiChatUiTest extends \PHPUnit\Framework\TestCase
  6. {
  7. private function sanitize($aActions)
  8. {
  9. return BxDolAiChatUi::getInstance()->sanitizeChatActions($aActions);
  10. }
  11. public function testRejectsBadInput()
  12. {
  13. $this->assertSame([], $this->sanitize('reply'));
  14. $this->assertSame([], $this->sanitize([
  15. 'not an array',
  16. ['type' => 'reply', 'label' => ' '],
  17. ['type' => 'script', 'label' => 'X'],
  18. ]));
  19. }
  20. public function testReplyAndLink()
  21. {
  22. $this->assertSame([
  23. ['type' => 'reply', 'label' => 'Yes'],
  24. ['type' => 'link', 'label' => 'Help', 'url' => 'https://una.io/help'],
  25. ], $this->sanitize([
  26. ['type' => 'REPLY', 'label' => ' Yes '],
  27. ['type' => 'link', 'label' => 'Help', 'url' => 'https://una.io/help'],
  28. ['type' => 'link', 'label' => 'Http', 'url' => 'http://una.io/'],
  29. ['type' => 'link', 'label' => 'Js', 'url' => 'javascript:alert(1)'],
  30. ['type' => 'link', 'label' => 'Local', 'url' => 'https://localhost/'],
  31. ['type' => 'link', 'label' => 'Private', 'url' => 'https://10.0.0.5/'],
  32. ]));
  33. }
  34. public function testLinkCheckUrlNeedsMessageAndServiceUrl()
  35. {
  36. $aOut = $this->sanitize([
  37. ['type' => 'link', 'label' => 'A', 'url' => 'https://a.test/', 'check_url' => 'bx_projects/get_provider_connected/&params[]=aws&params[]=1', 'message' => 'AWS is connected'],
  38. ['type' => 'link', 'label' => 'B', 'url' => 'https://a.test/', 'check_url' => 'bx_projects/get_provider_connected'],
  39. ['type' => 'link', 'label' => 'C', 'url' => 'https://a.test/', 'check_url' => 'https://evil.test/x', 'message' => 'm'],
  40. ['type' => 'link', 'label' => 'D', 'url' => 'https://a.test/', 'check_url' => 'a/b/&params[]=<x>', 'message' => 'm'],
  41. ]);
  42. $this->assertSame('bx_projects/get_provider_connected/&params[]=aws&params[]=1', $aOut[0]['check_url']);
  43. $this->assertSame('AWS is connected', $aOut[0]['message']);
  44. foreach ([1, 2, 3] as $i) {
  45. $this->assertArrayNotHasKey('check_url', $aOut[$i]);
  46. $this->assertArrayNotHasKey('message', $aOut[$i]);
  47. }
  48. }
  49. public function testForm()
  50. {
  51. $this->assertSame([
  52. ['type' => 'form', 'label' => 'Add keys', 'form_url' => 'bx_projects/get_block_sr_provider_add/&params[]=2', 'message' => 'AWS is connected'],
  53. ['type' => 'form', 'label' => 'No message', 'form_url' => 'bx_projects/get_block_sr_provider_add'],
  54. ], $this->sanitize([
  55. ['type' => 'form', 'label' => 'Add keys', 'form_url' => 'bx_projects/get_block_sr_provider_add/&params[]=2', 'message' => '<b>AWS</b> is connected'],
  56. ['type' => 'form', 'label' => 'No message', 'form_url' => 'bx_projects/get_block_sr_provider_add', 'message' => ' '],
  57. ['type' => 'form', 'label' => 'Bad', 'form_url' => '../../admin'],
  58. ['type' => 'form', 'label' => 'Bad', 'form_url' => 'https://evil.test/a/b'],
  59. ['type' => 'form', 'label' => 'Missing'],
  60. ]));
  61. }
  62. public function testMergeFormActions()
  63. {
  64. $oChat = BxDolAiChatUi::getInstance();
  65. $aKeys = ['type' => 'form', 'label' => 'Add keys', 'form_url' => 'bx_projects/get_block_sr_provider_add/&params[]=2'];
  66. $aRole = ['type' => 'form', 'label' => 'Add keys', 'form_url' => 'bx_projects/get_block_sr_provider_add/&params[]=3'];
  67. $aBad = ['type' => 'form', 'label' => 'Bad', 'form_url' => 'https://evil.test/a/b'];
  68. // same label and form_url is one button, another form_url is another one
  69. $this->assertSame([$aKeys, $aRole], $oChat->mergeChatActions([$aKeys, $aBad], [$aKeys, $aRole]));
  70. // a form never merges with a link of the same label
  71. $aLink = ['type' => 'link', 'label' => 'Add keys', 'url' => 'https://a.test/'];
  72. $this->assertCount(2, $oChat->mergeChatActions([$aKeys], [$aLink]));
  73. $this->assertCount(8, $oChat->mergeChatActions(
  74. array_map(fn($i) => ['type' => 'form', 'label' => 'F' . $i, 'form_url' => 'a/b'], range(1, 6)),
  75. array_map(fn($i) => ['type' => 'reply', 'label' => 'R' . $i], range(1, 6))
  76. ));
  77. }
  78. public function testLimits()
  79. {
  80. $aOut = $this->sanitize([
  81. ['type' => 'form', 'label' => str_repeat('я', 100), 'form_url' => 'a/b', 'message' => str_repeat('я', 300)],
  82. ]);
  83. $this->assertSame(80, mb_strlen($aOut[0]['label']));
  84. $this->assertSame(200, mb_strlen($aOut[0]['message']));
  85. $this->assertCount(8, $this->sanitize(array_fill(0, 12, ['type' => 'reply', 'label' => 'x'])));
  86. }
  87. }