@nyaruka/temba-components 0.109.0 → 0.110.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/temba-components.js +361 -354
  3. package/dist/temba-components.js.map +1 -1
  4. package/out-tsc/src/compose/Compose.js +62 -106
  5. package/out-tsc/src/compose/Compose.js.map +1 -1
  6. package/out-tsc/src/contacts/ContactChat.js +64 -59
  7. package/out-tsc/src/contacts/ContactChat.js.map +1 -1
  8. package/out-tsc/src/vectoricon/index.js +0 -1
  9. package/out-tsc/src/vectoricon/index.js.map +1 -1
  10. package/out-tsc/test/temba-compose.test.js +24 -440
  11. package/out-tsc/test/temba-compose.test.js.map +1 -1
  12. package/out-tsc/test/temba-contact-chat.test.js +30 -167
  13. package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
  14. package/package.json +1 -1
  15. package/screenshots/truth/compose/attachments-tab.png +0 -0
  16. package/screenshots/truth/compose/attachments-with-failures.png +0 -0
  17. package/screenshots/truth/compose/attachments-with-files-and-failures.png +0 -0
  18. package/screenshots/truth/compose/attachments-with-files-focused.png +0 -0
  19. package/screenshots/truth/compose/attachments-with-files.png +0 -0
  20. package/screenshots/truth/compose/intial-text.png +0 -0
  21. package/screenshots/truth/compose/no-counter.png +0 -0
  22. package/screenshots/truth/compose/wraps-text-and-spaces.png +0 -0
  23. package/screenshots/truth/compose/wraps-text-and-url.png +0 -0
  24. package/screenshots/truth/compose/wraps-text-no-spaces.png +0 -0
  25. package/screenshots/truth/contacts/chat-failure.png +0 -0
  26. package/src/compose/Compose.ts +69 -103
  27. package/src/contacts/ContactChat.ts +69 -70
  28. package/src/untyped.d.ts +1 -1
  29. package/src/vectoricon/index.ts +0 -1
  30. package/test/temba-compose.test.ts +29 -590
  31. package/test/temba-contact-chat.test.ts +30 -263
  32. package/web-test-runner.config.mjs +1 -0
  33. package/screenshots/truth/compose/attachments-and-send-button.png +0 -0
  34. package/screenshots/truth/compose/attachments-no-send-button.png +0 -0
  35. package/screenshots/truth/compose/attachments-with-all-files-and-click-send.png +0 -0
  36. package/screenshots/truth/compose/attachments-with-all-files.png +0 -0
  37. package/screenshots/truth/compose/attachments-with-failure-files.png +0 -0
  38. package/screenshots/truth/compose/attachments-with-success-files-and-click-send.png +0 -0
  39. package/screenshots/truth/compose/attachments-with-success-files.png +0 -0
  40. package/screenshots/truth/compose/chatbox-attachments-counter-and-send-button.png +0 -0
  41. package/screenshots/truth/compose/chatbox-attachments-counter-no-send-button.png +0 -0
  42. package/screenshots/truth/compose/chatbox-attachments-no-counter-and-send-button.png +0 -0
  43. package/screenshots/truth/compose/chatbox-attachments-no-counter-no-send-button.png +0 -0
  44. package/screenshots/truth/compose/chatbox-counter-and-send-button.png +0 -0
  45. package/screenshots/truth/compose/chatbox-counter-no-send-button.png +0 -0
  46. package/screenshots/truth/compose/chatbox-no-counter-and-send-button.png +0 -0
  47. package/screenshots/truth/compose/chatbox-no-counter-no-send-button.png +0 -0
  48. package/screenshots/truth/compose/chatbox-no-text-attachments-with-all-files-and-click-send.png +0 -0
  49. package/screenshots/truth/compose/chatbox-no-text-attachments-with-all-files.png +0 -0
  50. package/screenshots/truth/compose/chatbox-no-text-attachments-with-failure-files.png +0 -0
  51. package/screenshots/truth/compose/chatbox-no-text-attachments-with-success-files-and-click-send.png +0 -0
  52. package/screenshots/truth/compose/chatbox-no-text-attachments-with-success-files.png +0 -0
  53. package/screenshots/truth/compose/chatbox-with-text-and-click-send.png +0 -0
  54. package/screenshots/truth/compose/chatbox-with-text-and-hit-enter.png +0 -0
  55. package/screenshots/truth/compose/chatbox-with-text-and-spaces.png +0 -0
  56. package/screenshots/truth/compose/chatbox-with-text-and-url.png +0 -0
  57. package/screenshots/truth/compose/chatbox-with-text-attachments-no-files-and-click-send.png +0 -0
  58. package/screenshots/truth/compose/chatbox-with-text-attachments-no-files-and-hit-enter.png +0 -0
  59. package/screenshots/truth/compose/chatbox-with-text-attachments-no-files.png +0 -0
  60. package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files-and-click-send.png +0 -0
  61. package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files-and-hit-enter.png +0 -0
  62. package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files.png +0 -0
  63. package/screenshots/truth/compose/chatbox-with-text-attachments-with-failure-files.png +0 -0
  64. package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files-and-click-send.png +0 -0
  65. package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files-and-hit-enter.png +0 -0
  66. package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files.png +0 -0
  67. package/screenshots/truth/compose/chatbox-with-text-no-spaces.png +0 -0
  68. package/screenshots/truth/compose/chatbox-with-text.png +0 -0
  69. package/screenshots/truth/contacts/compose-attachments-no-text-failure.png +0 -0
  70. package/screenshots/truth/contacts/compose-text-and-attachments-failure-attachments.png +0 -0
  71. package/screenshots/truth/contacts/compose-text-and-attachments-failure-generic.png +0 -0
  72. package/screenshots/truth/contacts/compose-text-and-attachments-failure-text-and-attachments.png +0 -0
  73. package/screenshots/truth/contacts/compose-text-and-attachments-failure-text.png +0 -0
  74. package/screenshots/truth/contacts/compose-text-no-attachments-failure.png +0 -0
  75. package/screenshots/truth/contacts/compose-text-no-attachments-success.png +0 -0
  76. /package/screenshots/truth/contacts/{compose-attachments-no-text-success.png → chat-for-active-contact.png} +0 -0
  77. /package/screenshots/truth/contacts/{contact-archived-hide-chatbox.png → chat-for-archived-contact.png} +0 -0
  78. /package/screenshots/truth/contacts/{contact-blocked-hide-chatbox.png → chat-for-blocked-contact.png} +0 -0
  79. /package/screenshots/truth/contacts/{contact-stopped-hide-chatbox.png → chat-for-stopped-contact.png} +0 -0
  80. /package/screenshots/truth/contacts/{compose-text-and-attachments-success.png → chat-sends-attachments-only.png} +0 -0
  81. /package/screenshots/truth/contacts/{contact-active-default.png → chat-sends-text-and-attachments.png} +0 -0
  82. /package/screenshots/truth/contacts/{contact-active-show-chatbox.png → chat-sends-text-only.png} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"temba-compose.test.js","sourceRoot":"","sources":["../../test/temba-compose.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert, expect } from '@open-wc/testing';\nimport { Compose } from '../src/compose/Compose';\nimport { assertScreenshot, getClip, getComponent } from './utils.test';\nimport { Completion } from '../src/completion/Completion';\nimport { DEFAULT_MEDIA_ENDPOINT } from '../src/utils';\nimport { Attachment } from '../src/interfaces';\n\nconst TAG = 'temba-compose';\nconst getCompose = async (attrs: any = {}, width = 500, height = 500) => {\n const compose = (await getComponent(\n TAG,\n attrs,\n '',\n width,\n height,\n 'display:flex;flex-direction:column;flex-grow:1;'\n )) as Compose;\n return compose;\n};\n\nexport const updateComponent = async (\n compose: Compose,\n text?: string,\n attachments?: Attachment[]\n): Promise<void> => {\n compose.initialText = text ? text : '';\n compose.currentAttachments = attachments ? attachments : [];\n await compose.updateComplete;\n};\n\nconst getInitialValue = (\n text?: string,\n attachments?: Attachment[],\n quick_replies?: []\n): any => {\n const composeValue = {\n und: {\n text: text ? text : '',\n attachments: attachments ? attachments : [],\n quick_replies: quick_replies ? quick_replies : [],\n optin: null,\n template: null,\n variables: []\n }\n };\n return composeValue;\n};\nconst getComposeValue = (value: any): string => {\n return JSON.stringify(value);\n};\n\nexport const getValidText = () => {\n return 'sà-wàd-dee!';\n};\n// for a server limit of 640 chars, return a string that is 640+ chars\nexport const getInvalidText = () => {\n return \"p}h<r0P<?SCIbV1+pwW1Hj8g^J&=Sm2f)K=5LjFFUZ№5@ybpoLZ7DJ(27qdWxQMaO)I1nB4(D%d3c(H)QXOF6F?4>&d{lhd5?0`Lio!yAGMO№*AxN5{z5s.IO*dy?tm}vXJ#Lf-HlD;xmNp}0<P42=w#ll9)B-e9>Q#'{~Vp<dl:xC9`T^lhh@TosCZ^:(H<Ji<E(~PojvYk^rPB+poYy^Ne~Su1:9?IgH'4S5Q9v0g№FEIUc~!{S7;746j'Sd@Nfu3=x?CsuR;YLP4j+AOzDARZG?0(Ji(NMg=r%n0Fq?R1?E%Yf`bcoVZAJ^bl0J'^@;lH>T.HmxYxwS;1?(bfrh?pRdd73:iMxrfx5luQ(}<dCD1b3g'G0CtkB№;8KkbL=>krG{RO%Va4wwr%P>jE*+n(E11}Ju9#<.f^)<MTH09^b{RQv7~H`#@Hda6{MV&H@xdyEKq#M@nZng8WTU66!F@*!)w*EpQ+65XKuQCaESgq=PHmtqi@l;F?PHvl^g@Z:+}}Xyr`IC2=3?20^I'qSU*tkyinM^JF.ZI>}~XzRQJn№v3o-w?Vy&gC:c.l(&9{`M#-'N}{T#7lw8(4:iY621'>C^.&hVZn:R!G}Ek){D#'KkiJWawq#7~GLBN*?V!ncw)d%&(tXj\";\n};\n\n// valid = attachments that are uploaded sent to the server when the user clicks send\nexport const getValidAttachments = (numFiles = 2): Attachment[] => {\n const attachments = [];\n let index = 1;\n while (index <= numFiles) {\n const s = 's' + index;\n const attachment = {\n uuid: s,\n content_type: 'image/png',\n type: 'image/png',\n filename: 'name_' + s,\n url: 'url_' + s,\n size: 1024,\n error: null\n } as Attachment;\n attachments.push(attachment);\n index++;\n }\n return attachments;\n};\n// invalid = attachments that are not uploaded and are not sent to the server when the user clicks send\nexport const getInvalidAttachments = (): Attachment[] => {\n const f1 = 'f1';\n const fail1 = {\n uuid: f1,\n content_type: 'image/png',\n type: 'image/png',\n filename: 'name_' + f1,\n url: 'url_' + f1,\n size: 26624,\n error: 'Limit for file uploads is 25.0 MB'\n } as Attachment;\n const f2 = 'f2';\n const fail2 = {\n uuid: f2,\n content_type: 'application/octet-stream',\n type: 'application/octet-stream',\n filename: 'name_' + f2,\n url: 'url_' + f2,\n size: 1024,\n error: 'Unsupported file type'\n } as Attachment;\n\n return [fail1, fail2];\n};\n\n// for a test width of 500, return a string that is 60+ chars with spaces\n// to test that line breaks / word wrapping works as expected\nconst getValidText_Long_WithSpaces = () => {\n return 'bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb ';\n};\nconst getValidText_Long_WithNoSpaces = () => {\n return 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';\n};\nconst getValidText_Long_WithUrl = () => {\n return 'http://www.yourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmom.com';\n};\n\ndescribe('temba-compose chatbox', () => {\n it('can be created', async () => {\n const compose: Compose = await getCompose();\n assert.instanceOf(compose, Compose);\n expect(compose.endpoint).equals(DEFAULT_MEDIA_ENDPOINT);\n });\n\n it('cannot be created with a different endpoint', async () => {\n const compose: Compose = await getCompose({\n endpoint: '/schmsgmedia/schmupload/'\n });\n assert.instanceOf(compose, Compose);\n expect(compose.endpoint).equals(DEFAULT_MEDIA_ENDPOINT);\n });\n\n it('chatbox no counter no send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true\n });\n await assertScreenshot(\n 'compose/chatbox-no-counter-no-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox no counter and send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n button: true\n });\n await assertScreenshot(\n 'compose/chatbox-no-counter-and-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox counter no send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true\n });\n await assertScreenshot(\n 'compose/chatbox-counter-no-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox counter and send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await assertScreenshot(\n 'compose/chatbox-counter-and-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox counter and send button deserialize and serialize', async () => {\n const initialValue = getInitialValue();\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal('{}');\n });\n\n it('chatbox with text', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText());\n await assertScreenshot('compose/chatbox-with-text', getClip(compose));\n });\n\n it('chatbox with text deserialize and serialize', async () => {\n const initialValue = getInitialValue(getValidText());\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal(getValidText());\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('chatbox with text and spaces', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText_Long_WithSpaces());\n await assertScreenshot(\n 'compose/chatbox-with-text-and-spaces',\n getClip(compose)\n );\n });\n\n it('chatbox with text and no spaces', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText_Long_WithNoSpaces());\n await assertScreenshot(\n 'compose/chatbox-with-text-no-spaces',\n getClip(compose)\n );\n });\n\n it('chatbox with text and url', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText_Long_WithUrl());\n await assertScreenshot(\n 'compose/chatbox-with-text-and-url',\n getClip(compose)\n );\n });\n\n it('chatbox with text and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText());\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-with-text-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox with text and hit enter', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText());\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-with-text-and-hit-enter',\n getClip(compose)\n );\n });\n});\n\ndescribe('temba-compose attachments', () => {\n it('attachments no send button', async () => {\n const compose: Compose = await getCompose({\n attachments: true\n });\n await assertScreenshot(\n 'compose/attachments-no-send-button',\n getClip(compose)\n );\n });\n\n it('attachments and send button', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await assertScreenshot(\n 'compose/attachments-and-send-button',\n getClip(compose)\n );\n });\n\n it('attachments and send button deserialize and serialize', async () => {\n const initialValue = getInitialValue();\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n attachments: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal('{}');\n });\n\n it('attachments with success uploaded files', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n await assertScreenshot(\n 'compose/attachments-with-success-files',\n getClip(compose)\n );\n });\n\n it('attachments with success uploaded files deserialize and serialize', async () => {\n const initialValue = getInitialValue(null, getValidAttachments());\n const composeValue = getComposeValue(initialValue);\n const compose: Compose = await getCompose({\n attachments: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal(getValidAttachments());\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('attachments with failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, null);\n await assertScreenshot(\n 'compose/attachments-with-failure-files',\n getClip(compose)\n );\n });\n\n it('attachments with success and failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n await assertScreenshot(\n 'compose/attachments-with-all-files',\n getClip(compose)\n );\n });\n\n it('attachments with success uploaded files and click send', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n chatbox: true\n });\n await updateComponent(compose, null, getValidAttachments());\n\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n\n await assertScreenshot(\n 'compose/attachments-with-success-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('attachments with success and failure uploaded files and click send', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n chatbox: true\n });\n await updateComponent(compose, null, getValidAttachments());\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/attachments-with-all-files-and-click-send',\n getClip(compose)\n );\n });\n});\n\ndescribe('temba-compose chatbox and attachments', () => {\n it('chatbox and attachments no counter no send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true\n });\n await assertScreenshot(\n 'compose/chatbox-attachments-no-counter-no-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox and attachments no counter and send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await assertScreenshot(\n 'compose/chatbox-attachments-no-counter-and-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox and attachments counter no send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true\n });\n await assertScreenshot(\n 'compose/chatbox-attachments-counter-no-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox and attachments counter and send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true\n });\n await assertScreenshot(\n 'compose/chatbox-attachments-counter-and-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox and attachments counter and send button deserialize and serialize', async () => {\n const initialValue = getInitialValue();\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal('{}');\n });\n});\n\ndescribe('temba-compose chatbox with text and attachments no files', () => {\n it('chatbox with text, attachments no files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true\n });\n updateComponent(compose, getValidText());\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-no-files',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments no files deserialize and serialize', async () => {\n const initialValue = getInitialValue(getValidText());\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal(getValidText());\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('chatbox with text, attachments no files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true\n });\n updateComponent(compose, getValidText());\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-no-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments no files, and hit enter', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText());\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as HTMLElement;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-no-files-and-hit-enter',\n getClip(compose)\n );\n });\n});\n\ndescribe('temba-compose chatbox no text and attachments with files', () => {\n it('chatbox no text, attachments with success uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-success-files',\n getClip(compose)\n );\n });\n\n it('chatbox no text, attachments with success uploaded files deserialize and serialize', async () => {\n const initialValue = getInitialValue(null, getValidAttachments());\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal(getValidAttachments());\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('chatbox no text, attachments with failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, null);\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-failure-files',\n getClip(compose)\n );\n });\n\n it('chatbox no text, attachments with success and failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-all-files',\n getClip(compose)\n );\n });\n\n it('chatbox no text, attachments with success uploaded files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-success-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox no text, attachments with success and failure uploaded files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-all-files-and-click-send',\n getClip(compose)\n );\n });\n});\n\ndescribe('temba-compose chatbox with text and attachments with files', () => {\n it('chatbox with text, attachments with success uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-success-files',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success uploaded files deserialize and serialize', async () => {\n const initialValue = getInitialValue(getValidText(), getValidAttachments());\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true,\n value: composeValue\n });\n\n // deserialize\n expect(compose.currentText).to.equal(getValidText());\n\n expect(compose.currentAttachments).to.deep.equal(getValidAttachments());\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('chatbox with text, attachments with failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), null);\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-failure-files',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success and failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-all-files',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success uploaded files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-success-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success and failure uploaded files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-all-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success uploaded files, and hit enter', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as HTMLElement;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-success-files-and-hit-enter',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success and failure uploaded files, and hit enter', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n const chatbox = compose.shadowRoot.querySelector(\n '.chatbox'\n ) as HTMLInputElement;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n const newClip = getClip(compose);\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-all-files-and-hit-enter',\n newClip\n );\n });\n});\n"]}
1
+ {"version":3,"file":"temba-compose.test.js","sourceRoot":"","sources":["../../test/temba-compose.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert, expect } from '@open-wc/testing';\nimport { Compose } from '../src/compose/Compose';\nimport { assertScreenshot, getClip, getComponent } from './utils.test';\nimport { DEFAULT_MEDIA_ENDPOINT } from '../src/utils';\nimport { Attachment } from '../src/interfaces';\n\nconst TAG = 'temba-compose';\nconst getCompose = async (attrs: any = {}, width = 500, height = 500) => {\n const compose = (await getComponent(\n TAG,\n attrs,\n '',\n width,\n height,\n 'display:flex;flex-direction:column;flex-grow:1;'\n )) as Compose;\n return compose;\n};\n\nexport const updateComponent = async (\n compose: Compose,\n text?: string,\n attachments?: Attachment[]\n): Promise<void> => {\n compose.initialText = text ? text : '';\n compose.currentAttachments = attachments ? attachments : [];\n await compose.updateComplete;\n};\n\nconst getInitialValue = (\n text?: string,\n attachments?: Attachment[],\n quick_replies?: []\n): any => {\n const composeValue = {\n und: {\n text: text ? text : '',\n attachments: attachments ? attachments : [],\n quick_replies: quick_replies ? quick_replies : [],\n optin: null,\n template: null,\n variables: []\n }\n };\n return composeValue;\n};\nconst getComposeValue = (value: any): string => {\n return JSON.stringify(value);\n};\n\nexport const getValidText = () => {\n return 'sà-wàd-dee!';\n};\n\n// valid = attachments that are uploaded sent to the server when the user clicks send\nexport const getValidAttachments = (numFiles = 2): Attachment[] => {\n const attachments = [];\n let index = 1;\n while (index <= numFiles) {\n const s = 's' + index;\n const attachment = {\n uuid: s,\n content_type: 'image/png',\n type: 'image/png',\n filename: 'name_' + s,\n url: 'url_' + s,\n size: 1024,\n error: null\n } as Attachment;\n attachments.push(attachment);\n index++;\n }\n return attachments;\n};\n\n// for a test width of 500, return a string that is 60+ chars with spaces\n// to test that line breaks / word wrapping works as expected\nconst getValidText_Long_WithSpaces = () => {\n return 'bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb ';\n};\n\nconst getValidText_Long_WithNoSpaces = () => {\n return 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';\n};\n\nconst getValidText_Long_WithUrl = () => {\n return 'http://www.yourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmom.com';\n};\n\ndescribe('temba-compose chatbox', () => {\n it('can be created', async () => {\n const compose: Compose = await getCompose();\n assert.instanceOf(compose, Compose);\n expect(compose.endpoint).equals(DEFAULT_MEDIA_ENDPOINT);\n });\n\n it('cannot be created with a different endpoint', async () => {\n const compose: Compose = await getCompose({\n endpoint: '/schmsgmedia/schmupload/'\n });\n assert.instanceOf(compose, Compose);\n expect(compose.endpoint).equals(DEFAULT_MEDIA_ENDPOINT);\n });\n\n it('no counter', async () => {\n const compose: Compose = await getCompose({\n chatbox: true\n });\n await assertScreenshot('compose/no-counter', getClip(compose));\n });\n\n it('initializes with text', async () => {\n const compose: Compose = await getCompose({\n counter: true\n });\n await updateComponent(compose, getValidText());\n await assertScreenshot('compose/intial-text', getClip(compose));\n });\n\n it('serializes', async () => {\n const initialValue = getInitialValue(getValidText());\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n counter: true,\n value: composeValue\n });\n\n // deserialize\n expect(compose.currentText).to.equal(getValidText());\n expect(compose.currentAttachments).to.deep.equal([]);\n\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n // TODO: these are better suited for textinput tests\n it('wraps text and spaces', async () => {\n const compose: Compose = await getCompose({\n counter: true\n });\n await updateComponent(compose, getValidText_Long_WithSpaces());\n await assertScreenshot('compose/wraps-text-and-spaces', getClip(compose));\n });\n\n it('wraps text and no spaces', async () => {\n const compose: Compose = await getCompose({\n counter: true\n });\n await updateComponent(compose, getValidText_Long_WithNoSpaces());\n await assertScreenshot('compose/wraps-text-no-spaces', getClip(compose));\n });\n\n it('wraps with text and url', async () => {\n const compose: Compose = await getCompose({\n counter: true\n });\n await updateComponent(compose, getValidText_Long_WithUrl());\n await assertScreenshot('compose/wraps-text-and-url', getClip(compose));\n });\n});\n\ndescribe('temba-compose attachments', () => {\n it('supports attachments tab', async () => {\n const compose: Compose = await getCompose({\n attachments: true\n });\n await assertScreenshot('compose/attachments-tab', getClip(compose));\n });\n\n it('shows valid attachments', async () => {\n const compose: Compose = await getCompose({\n attachments: true\n });\n await updateComponent(compose, null, getValidAttachments());\n await assertScreenshot('compose/attachments-with-files', getClip(compose));\n\n // click on tab\n const tabs = compose.getTabs();\n tabs.focusTab('Attachments');\n\n await assertScreenshot(\n 'compose/attachments-with-files-focused',\n getClip(compose)\n );\n });\n\n it('serializes attachments', async () => {\n const initialValue = getInitialValue(null, getValidAttachments());\n const composeValue = getComposeValue(initialValue);\n const compose: Compose = await getCompose({\n attachments: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal(getValidAttachments());\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n});\n"]}
@@ -1,6 +1,8 @@
1
1
  import { useFakeTimers } from 'sinon';
2
+ import { CustomEventType } from '../src/interfaces';
2
3
  import { assertScreenshot, clearMockPosts, getClip, getComponent, loadStore, mockGET, mockNow, mockPOST } from '../test/utils.test';
3
- import { getInvalidText, getValidAttachments, getValidText, updateComponent } from './temba-compose.test';
4
+ import { getValidAttachments, getValidText, updateComponent } from './temba-compose.test';
5
+ import { expect, oneEvent } from '@open-wc/testing';
4
6
  let clock;
5
7
  mockNow('2021-03-31T00:31:00.000-00:00');
6
8
  const TAG = 'temba-contact-chat';
@@ -19,33 +21,24 @@ const getResponseSuccessFiles = (attachments) => {
19
21
  });
20
22
  return response_attachments;
21
23
  };
22
- const responseTextError = 'Maximum allowed text is 640 characters.';
23
- const responseAttachmentError = 'Maximum allowed attachments is 10 files.';
24
- describe('temba-contact-chat - contact tests', () => {
24
+ describe('temba-contact-chat', () => {
25
25
  // map requests for contact history to our static files
26
26
  // we'll just us the same historylist for everybody for now
27
27
  beforeEach(() => {
28
+ clearMockPosts();
28
29
  mockGET(/\/contact\/history\/contact-.*/, '/test-assets/contacts/history.json');
29
30
  clock = useFakeTimers();
30
31
  });
31
32
  afterEach(function () {
32
33
  clock.restore();
33
34
  });
34
- it('can be created', async () => {
35
- // we are a StoreElement, so load a store first
36
- await loadStore();
37
- const chat = await getContactChat({
38
- contact: 'contact-dave-active'
39
- });
40
- await assertScreenshot('contacts/contact-active-default', getClip(chat));
41
- });
42
35
  it('show history and show chatbox if contact is active', async () => {
43
36
  // we are a StoreElement, so load a store first
44
37
  await loadStore();
45
38
  const chat = await getContactChat({
46
39
  contact: 'contact-dave-active'
47
40
  });
48
- await assertScreenshot('contacts/contact-active-show-chatbox', getClip(chat));
41
+ await assertScreenshot('contacts/chat-for-active-contact', getClip(chat));
49
42
  });
50
43
  it('show history and hide chatbox if contact is archived', async () => {
51
44
  // we are a StoreElement, so load a store first
@@ -53,7 +46,7 @@ describe('temba-contact-chat - contact tests', () => {
53
46
  const chat = await getContactChat({
54
47
  contact: 'contact-barack-archived'
55
48
  });
56
- await assertScreenshot('contacts/contact-archived-hide-chatbox', getClip(chat));
49
+ await assertScreenshot('contacts/chat-for-archived-contact', getClip(chat));
57
50
  });
58
51
  it('show history and hide chatbox if contact is blocked', async () => {
59
52
  // we are a StoreElement, so load a store first
@@ -61,7 +54,7 @@ describe('temba-contact-chat - contact tests', () => {
61
54
  const chat = await getContactChat({
62
55
  contact: 'contact-michelle-blocked'
63
56
  });
64
- await assertScreenshot('contacts/contact-blocked-hide-chatbox', getClip(chat));
57
+ await assertScreenshot('contacts/chat-for-blocked-contact', getClip(chat));
65
58
  });
66
59
  it('show history and hide chatbox if contact is stopped', async () => {
67
60
  // we are a StoreElement, so load a store first
@@ -69,19 +62,9 @@ describe('temba-contact-chat - contact tests', () => {
69
62
  const chat = await getContactChat({
70
63
  contact: 'contact-tim-stopped'
71
64
  });
72
- await assertScreenshot('contacts/contact-stopped-hide-chatbox', getClip(chat));
73
- });
74
- });
75
- describe('temba-contact-chat - contact tests - handle send tests - text no attachments', () => {
76
- beforeEach(() => {
77
- clearMockPosts();
78
- mockGET(/\/contact\/history\/contact-.*/, '/test-assets/contacts/history.json');
79
- clock = useFakeTimers();
65
+ await assertScreenshot('contacts/chat-for-stopped-contact', getClip(chat));
80
66
  });
81
- afterEach(function () {
82
- clock.restore();
83
- });
84
- it('with text no attachments - success', async () => {
67
+ it('sends text without attachments', async () => {
85
68
  // we are a StoreElement, so load a store first
86
69
  await loadStore();
87
70
  const chat = await getContactChat({
@@ -96,42 +79,12 @@ describe('temba-contact-chat - contact tests - handle send tests - text no attac
96
79
  attachments: []
97
80
  };
98
81
  mockPOST(/api\/v2\/messages\.json/, response_body);
99
- // press enter
100
- const chatbox = compose.shadowRoot.querySelector('.chatbox');
101
- chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
102
- await assertScreenshot('contacts/compose-text-no-attachments-success', getClip(chat));
82
+ const listener = oneEvent(compose, CustomEventType.Submitted, false);
83
+ await typeInto('temba-contact-chat:temba-compose', text, true, true);
84
+ expect(await listener).to.exist;
85
+ await assertScreenshot('contacts/chat-sends-text-only', getClip(chat));
103
86
  });
104
- it('with text no attachments - failure - more than 640 chars', async () => {
105
- // we are a StoreElement, so load a store first
106
- await loadStore();
107
- const chat = await getContactChat({
108
- contact: 'contact-dave-active'
109
- });
110
- const compose = chat.shadowRoot.querySelector('temba-compose');
111
- // set the chatbox to a string that is 640+ chars
112
- await updateComponent(compose, getInvalidText());
113
- const response_body = {
114
- text: [responseTextError]
115
- };
116
- const response_headers = {};
117
- const response_status = '400';
118
- mockPOST(/api\/v2\/messages\.json/, response_body, response_headers, response_status);
119
- // press enter
120
- const chatbox = compose.shadowRoot.querySelector('.chatbox');
121
- chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
122
- await assertScreenshot('contacts/compose-text-no-attachments-failure', getClip(chat));
123
- });
124
- });
125
- describe('temba-contact-chat - contact tests - handle send tests - attachments no text', () => {
126
- beforeEach(() => {
127
- clearMockPosts();
128
- mockGET(/\/contact\/history\/contact-.*/, '/test-assets/contacts/history.json');
129
- clock = useFakeTimers();
130
- });
131
- afterEach(function () {
132
- clock.restore();
133
- });
134
- it('with attachments no text - success', async () => {
87
+ it('sends attachments without text', async () => {
135
88
  // we are a StoreElement, so load a store first
136
89
  await loadStore();
137
90
  const chat = await getContactChat({
@@ -149,42 +102,12 @@ describe('temba-contact-chat - contact tests - handle send tests - attachments n
149
102
  const response_headers = {};
150
103
  const response_status = '200';
151
104
  mockPOST(/api\/v2\/messages\.json/, response_body, response_headers, response_status);
152
- // press enter
153
- const chatbox = compose.shadowRoot.querySelector('.chatbox');
154
- chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
155
- await assertScreenshot('contacts/compose-attachments-no-text-success', getClip(chat));
105
+ const listener = oneEvent(compose, CustomEventType.Submitted, false);
106
+ await typeInto('temba-contact-chat:temba-compose', '', false, true);
107
+ expect(await listener).to.exist;
108
+ await assertScreenshot('contacts/chat-sends-attachments-only', getClip(chat));
156
109
  });
157
- it('with attachments no text - failure - more than 10 files', async () => {
158
- // we are a StoreElement, so load a store first
159
- await loadStore();
160
- const chat = await getContactChat({
161
- contact: 'contact-dave-active'
162
- });
163
- const compose = chat.shadowRoot.querySelector('temba-compose');
164
- // set the attachments to a list that is 10+ items
165
- await updateComponent(compose, null, getValidAttachments(11));
166
- const response_body = {
167
- attachments: [responseAttachmentError]
168
- };
169
- const response_headers = {};
170
- const response_status = '400';
171
- mockPOST(/api\/v2\/messages\.json/, response_body, response_headers, response_status);
172
- // press enter
173
- const chatbox = compose.shadowRoot.querySelector('.chatbox');
174
- chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
175
- await assertScreenshot('contacts/compose-attachments-no-text-failure', getClip(chat));
176
- });
177
- });
178
- describe('temba-contact-chat - contact tests - handle send tests - text and attachments', () => {
179
- beforeEach(() => {
180
- clearMockPosts();
181
- mockGET(/\/contact\/history\/contact-.*/, '/test-assets/contacts/history.json');
182
- clock = useFakeTimers();
183
- });
184
- afterEach(function () {
185
- clock.restore();
186
- });
187
- it('with text and attachments - success', async () => {
110
+ it('sends text with attachments', async () => {
188
111
  // we are a StoreElement, so load a store first
189
112
  await loadStore();
190
113
  const chat = await getContactChat({
@@ -202,73 +125,12 @@ describe('temba-contact-chat - contact tests - handle send tests - text and atta
202
125
  };
203
126
  mockPOST(/api\/v2\/messages\.json/, response_body);
204
127
  // press enter
205
- const chatbox = compose.shadowRoot.querySelector('.chatbox');
206
- chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
207
- await assertScreenshot('contacts/compose-text-and-attachments-success', getClip(chat));
208
- });
209
- it('with text and attachments - failure - more than 640 chars', async () => {
210
- // we are a StoreElement, so load a store first
211
- await loadStore();
212
- const chat = await getContactChat({
213
- contact: 'contact-dave-active'
214
- });
215
- const compose = chat.shadowRoot.querySelector('temba-compose');
216
- // set the chatbox to a string that is 640+ chars
217
- await updateComponent(compose, getInvalidText(), getValidAttachments());
218
- const response_body = {
219
- text: [responseTextError]
220
- };
221
- const response_headers = {};
222
- const response_status = '400';
223
- mockPOST(/api\/v2\/messages\.json/, response_body, response_headers, response_status);
224
- // press enter
225
- const chatbox = compose.shadowRoot.querySelector('.chatbox');
226
- chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
227
- await assertScreenshot('contacts/compose-text-and-attachments-failure-text', getClip(chat));
228
- });
229
- it('with text and attachments - failure - more than 10 files', async () => {
230
- // we are a StoreElement, so load a store first
231
- await loadStore();
232
- const chat = await getContactChat({
233
- contact: 'contact-dave-active'
234
- });
235
- const compose = chat.shadowRoot.querySelector('temba-compose');
236
- // set the attachments to a list that is 10+ items
237
- await updateComponent(compose, getValidText(), getValidAttachments(11));
238
- const response_body = {
239
- attachments: [responseAttachmentError]
240
- };
241
- const response_headers = {};
242
- const response_status = '400';
243
- mockPOST(/api\/v2\/messages\.json/, response_body, response_headers, response_status);
244
- // press enter
245
- const chatbox = compose.shadowRoot.querySelector('.chatbox');
246
- chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
247
- await assertScreenshot('contacts/compose-text-and-attachments-failure-attachments', getClip(chat));
248
- });
249
- it('with text and attachments - failure - more than 640 chars and more than 10 files', async () => {
250
- // we are a StoreElement, so load a store first
251
- await loadStore();
252
- const chat = await getContactChat({
253
- contact: 'contact-dave-active'
254
- });
255
- const compose = chat.shadowRoot.querySelector('temba-compose');
256
- // set the chatbox to a string that is 640+ chars
257
- // set the attachments to a list that is 10+ items
258
- await updateComponent(compose, getInvalidText(), getValidAttachments(11));
259
- const response_body = {
260
- text: [responseTextError],
261
- attachments: [responseAttachmentError]
262
- };
263
- const response_headers = {};
264
- const response_status = '400';
265
- mockPOST(/api\/v2\/messages\.json/, response_body, response_headers, response_status);
266
- // press enter
267
- const chatbox = compose.shadowRoot.querySelector('.chatbox');
268
- chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
269
- await assertScreenshot('contacts/compose-text-and-attachments-failure-text-and-attachments', getClip(chat));
128
+ const listener = oneEvent(compose, CustomEventType.Submitted, false);
129
+ await typeInto('temba-contact-chat:temba-compose', '', false, true);
130
+ expect(await listener).to.exist;
131
+ await assertScreenshot('contacts/chat-sends-text-and-attachments', getClip(chat));
270
132
  });
271
- it('with text and attachments - failure - generic', async () => {
133
+ it('shows failure message with retry', async () => {
272
134
  // we are a StoreElement, so load a store first
273
135
  await loadStore();
274
136
  const chat = await getContactChat({
@@ -280,10 +142,11 @@ describe('temba-contact-chat - contact tests - handle send tests - text and atta
280
142
  const response_headers = {};
281
143
  const response_status = '500';
282
144
  mockPOST(/api\/v2\/messages\.json/, response_body, response_headers, response_status);
283
- // press enter
284
- const chatbox = compose.shadowRoot.querySelector('.chatbox');
285
- chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
286
- await assertScreenshot('contacts/compose-text-and-attachments-failure-generic', getClip(chat));
145
+ // press
146
+ const listener = oneEvent(compose, CustomEventType.Submitted, false);
147
+ await typeInto('temba-contact-chat:temba-compose', '', false, true);
148
+ expect(await listener).to.exist;
149
+ await assertScreenshot('contacts/chat-failure', getClip(chat));
287
150
  });
288
151
  });
289
152
  //# sourceMappingURL=temba-contact-chat.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"temba-contact-chat.test.js","sourceRoot":"","sources":["../../test/temba-contact-chat.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { useFakeTimers } from 'sinon';\nimport { Compose } from '../src/compose/Compose';\nimport { ContactChat } from '../src/contacts/ContactChat';\nimport { Attachment } from '../src/interfaces';\nimport {\n assertScreenshot,\n clearMockPosts,\n getClip,\n getComponent,\n loadStore,\n mockGET,\n mockNow,\n mockPOST\n} from '../test/utils.test';\nimport {\n getInvalidText,\n getValidAttachments,\n getValidText,\n updateComponent\n} from './temba-compose.test';\nimport { Completion } from '../src/completion/Completion';\n\nlet clock: any;\nmockNow('2021-03-31T00:31:00.000-00:00');\n\nconst TAG = 'temba-contact-chat';\nconst getContactChat = async (attrs: any = {}) => {\n attrs['endpoint'] = '/test-assets/contacts/';\n // add some sizes and styles to force our chat history to scroll\n const chat = (await getComponent(\n TAG,\n attrs,\n '',\n 500,\n 500,\n 'display:flex;flex-direction:column;flex-grow:1;min-height:0;'\n )) as ContactChat;\n\n // TODO: this should be waiting for an event instead\n await waitFor(100);\n await clock.tick(0);\n return chat;\n};\n\nconst getResponseSuccessFiles = (attachments: Attachment[]) => {\n const response_attachments = attachments.map((attachment) => {\n return { content_type: attachment.content_type, url: attachment.url };\n });\n return response_attachments;\n};\nconst responseTextError = 'Maximum allowed text is 640 characters.';\nconst responseAttachmentError = 'Maximum allowed attachments is 10 files.';\n\ndescribe('temba-contact-chat - contact tests', () => {\n // map requests for contact history to our static files\n // we'll just us the same historylist for everybody for now\n beforeEach(() => {\n mockGET(\n /\\/contact\\/history\\/contact-.*/,\n '/test-assets/contacts/history.json'\n );\n clock = useFakeTimers();\n });\n\n afterEach(function () {\n clock.restore();\n });\n\n it('can be created', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n\n await assertScreenshot('contacts/contact-active-default', getClip(chat));\n });\n\n it('show history and show chatbox if contact is active', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n\n await assertScreenshot(\n 'contacts/contact-active-show-chatbox',\n getClip(chat)\n );\n });\n\n it('show history and hide chatbox if contact is archived', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-barack-archived'\n });\n\n await assertScreenshot(\n 'contacts/contact-archived-hide-chatbox',\n getClip(chat)\n );\n });\n\n it('show history and hide chatbox if contact is blocked', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-michelle-blocked'\n });\n\n await assertScreenshot(\n 'contacts/contact-blocked-hide-chatbox',\n getClip(chat)\n );\n });\n\n it('show history and hide chatbox if contact is stopped', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-tim-stopped'\n });\n\n await assertScreenshot(\n 'contacts/contact-stopped-hide-chatbox',\n getClip(chat)\n );\n });\n});\n\ndescribe('temba-contact-chat - contact tests - handle send tests - text no attachments', () => {\n beforeEach(() => {\n clearMockPosts();\n mockGET(\n /\\/contact\\/history\\/contact-.*/,\n '/test-assets/contacts/history.json'\n );\n clock = useFakeTimers();\n });\n\n afterEach(function () {\n clock.restore();\n });\n\n it('with text no attachments - success', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n const text = getValidText();\n await updateComponent(compose, text);\n\n const response_body = {\n contact: { uuid: 'contact-dave-active', name: 'Dave Matthews' },\n text: text,\n attachments: []\n };\n mockPOST(/api\\/v2\\/messages\\.json/, response_body);\n\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n\n await assertScreenshot(\n 'contacts/compose-text-no-attachments-success',\n getClip(chat)\n );\n });\n\n it('with text no attachments - failure - more than 640 chars', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n // set the chatbox to a string that is 640+ chars\n await updateComponent(compose, getInvalidText());\n\n const response_body = {\n text: [responseTextError]\n };\n const response_headers = {};\n const response_status = '400';\n mockPOST(\n /api\\/v2\\/messages\\.json/,\n response_body,\n response_headers,\n response_status\n );\n\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n\n await assertScreenshot(\n 'contacts/compose-text-no-attachments-failure',\n getClip(chat)\n );\n });\n});\n\ndescribe('temba-contact-chat - contact tests - handle send tests - attachments no text', () => {\n beforeEach(() => {\n clearMockPosts();\n mockGET(\n /\\/contact\\/history\\/contact-.*/,\n '/test-assets/contacts/history.json'\n );\n clock = useFakeTimers();\n });\n\n afterEach(function () {\n clock.restore();\n });\n\n it('with attachments no text - success', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n const attachments = getValidAttachments();\n await updateComponent(compose, null, attachments);\n const response_attachments = getResponseSuccessFiles(attachments);\n const response_body = {\n contact: { uuid: 'contact-dave-active', name: 'Dave Matthews' },\n text: '',\n attachments: response_attachments\n };\n const response_headers = {};\n const response_status = '200';\n mockPOST(\n /api\\/v2\\/messages\\.json/,\n response_body,\n response_headers,\n response_status\n );\n\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n\n await assertScreenshot(\n 'contacts/compose-attachments-no-text-success',\n getClip(chat)\n );\n });\n it('with attachments no text - failure - more than 10 files', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n // set the attachments to a list that is 10+ items\n await updateComponent(compose, null, getValidAttachments(11));\n\n const response_body = {\n attachments: [responseAttachmentError]\n };\n const response_headers = {};\n const response_status = '400';\n mockPOST(\n /api\\/v2\\/messages\\.json/,\n response_body,\n response_headers,\n response_status\n );\n\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n\n await assertScreenshot(\n 'contacts/compose-attachments-no-text-failure',\n getClip(chat)\n );\n });\n});\n\ndescribe('temba-contact-chat - contact tests - handle send tests - text and attachments', () => {\n beforeEach(() => {\n clearMockPosts();\n mockGET(\n /\\/contact\\/history\\/contact-.*/,\n '/test-assets/contacts/history.json'\n );\n clock = useFakeTimers();\n });\n\n afterEach(function () {\n clock.restore();\n });\n\n it('with text and attachments - success', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n const text = getValidText();\n const attachments = getValidAttachments();\n await updateComponent(compose, text, attachments);\n const response_attachments = getResponseSuccessFiles(attachments);\n const response_body = {\n contact: { uuid: 'contact-dave-active', name: 'Dave Matthews' },\n text: text,\n attachments: response_attachments\n };\n mockPOST(/api\\/v2\\/messages\\.json/, response_body);\n\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n\n await assertScreenshot(\n 'contacts/compose-text-and-attachments-success',\n getClip(chat)\n );\n });\n\n it('with text and attachments - failure - more than 640 chars', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n // set the chatbox to a string that is 640+ chars\n await updateComponent(compose, getInvalidText(), getValidAttachments());\n\n const response_body = {\n text: [responseTextError]\n };\n const response_headers = {};\n const response_status = '400';\n mockPOST(\n /api\\/v2\\/messages\\.json/,\n response_body,\n response_headers,\n response_status\n );\n\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n\n await assertScreenshot(\n 'contacts/compose-text-and-attachments-failure-text',\n getClip(chat)\n );\n });\n\n it('with text and attachments - failure - more than 10 files', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n // set the attachments to a list that is 10+ items\n await updateComponent(compose, getValidText(), getValidAttachments(11));\n\n const response_body = {\n attachments: [responseAttachmentError]\n };\n const response_headers = {};\n const response_status = '400';\n mockPOST(\n /api\\/v2\\/messages\\.json/,\n response_body,\n response_headers,\n response_status\n );\n\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n\n await assertScreenshot(\n 'contacts/compose-text-and-attachments-failure-attachments',\n getClip(chat)\n );\n });\n\n it('with text and attachments - failure - more than 640 chars and more than 10 files', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n // set the chatbox to a string that is 640+ chars\n // set the attachments to a list that is 10+ items\n await updateComponent(compose, getInvalidText(), getValidAttachments(11));\n\n const response_body = {\n text: [responseTextError],\n attachments: [responseAttachmentError]\n };\n const response_headers = {};\n const response_status = '400';\n mockPOST(\n /api\\/v2\\/messages\\.json/,\n response_body,\n response_headers,\n response_status\n );\n\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n\n await assertScreenshot(\n 'contacts/compose-text-and-attachments-failure-text-and-attachments',\n getClip(chat)\n );\n });\n\n it('with text and attachments - failure - generic', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n await updateComponent(compose, getValidText(), getValidAttachments());\n\n const response_body = {};\n const response_headers = {};\n const response_status = '500';\n mockPOST(\n /api\\/v2\\/messages\\.json/,\n response_body,\n response_headers,\n response_status\n );\n\n // press enter\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n\n await assertScreenshot(\n 'contacts/compose-text-and-attachments-failure-generic',\n getClip(chat)\n );\n });\n});\n"]}
1
+ {"version":3,"file":"temba-contact-chat.test.js","sourceRoot":"","sources":["../../test/temba-contact-chat.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { useFakeTimers } from 'sinon';\nimport { Compose } from '../src/compose/Compose';\nimport { ContactChat } from '../src/contacts/ContactChat';\nimport { Attachment, CustomEventType } from '../src/interfaces';\nimport {\n assertScreenshot,\n clearMockPosts,\n getClip,\n getComponent,\n loadStore,\n mockGET,\n mockNow,\n mockPOST\n} from '../test/utils.test';\nimport {\n getValidAttachments,\n getValidText,\n updateComponent\n} from './temba-compose.test';\n\nimport { expect, oneEvent } from '@open-wc/testing';\n\nlet clock: any;\nmockNow('2021-03-31T00:31:00.000-00:00');\n\nconst TAG = 'temba-contact-chat';\nconst getContactChat = async (attrs: any = {}) => {\n attrs['endpoint'] = '/test-assets/contacts/';\n // add some sizes and styles to force our chat history to scroll\n const chat = (await getComponent(\n TAG,\n attrs,\n '',\n 500,\n 500,\n 'display:flex;flex-direction:column;flex-grow:1;min-height:0;'\n )) as ContactChat;\n\n // TODO: this should be waiting for an event instead\n await waitFor(100);\n await clock.tick(0);\n return chat;\n};\n\nconst getResponseSuccessFiles = (attachments: Attachment[]) => {\n const response_attachments = attachments.map((attachment) => {\n return { content_type: attachment.content_type, url: attachment.url };\n });\n return response_attachments;\n};\n\ndescribe('temba-contact-chat', () => {\n // map requests for contact history to our static files\n // we'll just us the same historylist for everybody for now\n beforeEach(() => {\n clearMockPosts();\n mockGET(\n /\\/contact\\/history\\/contact-.*/,\n '/test-assets/contacts/history.json'\n );\n clock = useFakeTimers();\n });\n\n afterEach(function () {\n clock.restore();\n });\n\n it('show history and show chatbox if contact is active', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n\n await assertScreenshot('contacts/chat-for-active-contact', getClip(chat));\n });\n\n it('show history and hide chatbox if contact is archived', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-barack-archived'\n });\n\n await assertScreenshot('contacts/chat-for-archived-contact', getClip(chat));\n });\n\n it('show history and hide chatbox if contact is blocked', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-michelle-blocked'\n });\n\n await assertScreenshot('contacts/chat-for-blocked-contact', getClip(chat));\n });\n\n it('show history and hide chatbox if contact is stopped', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-tim-stopped'\n });\n\n await assertScreenshot('contacts/chat-for-stopped-contact', getClip(chat));\n });\n\n it('sends text without attachments', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n const text = getValidText();\n await updateComponent(compose, text);\n\n const response_body = {\n contact: { uuid: 'contact-dave-active', name: 'Dave Matthews' },\n text: text,\n attachments: []\n };\n mockPOST(/api\\/v2\\/messages\\.json/, response_body);\n\n const listener = oneEvent(compose, CustomEventType.Submitted, false);\n await typeInto('temba-contact-chat:temba-compose', text, true, true);\n expect(await listener).to.exist;\n\n await assertScreenshot('contacts/chat-sends-text-only', getClip(chat));\n });\n\n it('sends attachments without text', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n const attachments = getValidAttachments();\n await updateComponent(compose, null, attachments);\n const response_attachments = getResponseSuccessFiles(attachments);\n const response_body = {\n contact: { uuid: 'contact-dave-active', name: 'Dave Matthews' },\n text: '',\n attachments: response_attachments\n };\n const response_headers = {};\n const response_status = '200';\n mockPOST(\n /api\\/v2\\/messages\\.json/,\n response_body,\n response_headers,\n response_status\n );\n\n const listener = oneEvent(compose, CustomEventType.Submitted, false);\n await typeInto('temba-contact-chat:temba-compose', '', false, true);\n expect(await listener).to.exist;\n\n await assertScreenshot(\n 'contacts/chat-sends-attachments-only',\n getClip(chat)\n );\n });\n\n it('sends text with attachments', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n const text = getValidText();\n const attachments = getValidAttachments();\n await updateComponent(compose, text, attachments);\n const response_attachments = getResponseSuccessFiles(attachments);\n const response_body = {\n contact: { uuid: 'contact-dave-active', name: 'Dave Matthews' },\n text: text,\n attachments: response_attachments\n };\n mockPOST(/api\\/v2\\/messages\\.json/, response_body);\n\n // press enter\n const listener = oneEvent(compose, CustomEventType.Submitted, false);\n await typeInto('temba-contact-chat:temba-compose', '', false, true);\n expect(await listener).to.exist;\n\n await assertScreenshot(\n 'contacts/chat-sends-text-and-attachments',\n getClip(chat)\n );\n });\n\n it('shows failure message with retry', async () => {\n // we are a StoreElement, so load a store first\n await loadStore();\n const chat: ContactChat = await getContactChat({\n contact: 'contact-dave-active'\n });\n const compose = chat.shadowRoot.querySelector('temba-compose') as Compose;\n await updateComponent(compose, getValidText(), getValidAttachments());\n\n const response_body = {};\n const response_headers = {};\n const response_status = '500';\n mockPOST(\n /api\\/v2\\/messages\\.json/,\n response_body,\n response_headers,\n response_status\n );\n\n // press\n const listener = oneEvent(compose, CustomEventType.Submitted, false);\n await typeInto('temba-contact-chat:temba-compose', '', false, true);\n expect(await listener).to.exist;\n\n await assertScreenshot('contacts/chat-failure', getClip(chat));\n });\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nyaruka/temba-components",
3
- "version": "0.109.0",
3
+ "version": "0.110.0",
4
4
  "description": "Web components to support rapidpro and related projects",
5
5
  "author": "Nyaruka <code@nyaruka.coim>",
6
6
  "main": "dist/index.js",