@nyaruka/temba-components 0.140.0 → 0.141.1

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 (297) hide show
  1. package/.lintstagedrc.js +10 -0
  2. package/CHANGELOG.md +22 -0
  3. package/dist/locales/es.js +5 -5
  4. package/dist/locales/es.js.map +1 -1
  5. package/dist/locales/fr.js +5 -5
  6. package/dist/locales/fr.js.map +1 -1
  7. package/dist/locales/locale-codes.js +11 -2
  8. package/dist/locales/locale-codes.js.map +1 -1
  9. package/dist/locales/pt.js +5 -5
  10. package/dist/locales/pt.js.map +1 -1
  11. package/dist/temba-components.js +263 -156
  12. package/dist/temba-components.js.map +1 -1
  13. package/out-tsc/src/display/FloatingTab.js +1 -1
  14. package/out-tsc/src/display/FloatingTab.js.map +1 -1
  15. package/out-tsc/src/flow/CanvasNode.js +1 -1
  16. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  17. package/out-tsc/src/flow/Editor.js +239 -43
  18. package/out-tsc/src/flow/Editor.js.map +1 -1
  19. package/out-tsc/src/flow/Plumber.js +61 -14
  20. package/out-tsc/src/flow/Plumber.js.map +1 -1
  21. package/out-tsc/src/flow/actions/add_contact_groups.js +4 -1
  22. package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -1
  23. package/out-tsc/src/flow/actions/add_input_labels.js +4 -1
  24. package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
  25. package/out-tsc/src/flow/actions/remove_contact_groups.js +6 -1
  26. package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -1
  27. package/out-tsc/src/flow/actions/send_broadcast.js +6 -2
  28. package/out-tsc/src/flow/actions/send_broadcast.js.map +1 -1
  29. package/out-tsc/src/flow/actions/set_contact_channel.js +13 -0
  30. package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -1
  31. package/out-tsc/src/flow/actions/set_contact_status.js +7 -5
  32. package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -1
  33. package/out-tsc/src/flow/actions/start_session.js +10 -3
  34. package/out-tsc/src/flow/actions/start_session.js.map +1 -1
  35. package/out-tsc/src/flow/nodes/split_by_contact_field.js +18 -5
  36. package/out-tsc/src/flow/nodes/split_by_contact_field.js.map +1 -1
  37. package/out-tsc/src/flow/nodes/split_by_expression.js +1 -1
  38. package/out-tsc/src/flow/nodes/split_by_expression.js.map +1 -1
  39. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +0 -1
  40. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -1
  41. package/out-tsc/src/flow/nodes/split_by_random.js +0 -1
  42. package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -1
  43. package/out-tsc/src/flow/nodes/split_by_run_result.js +10 -4
  44. package/out-tsc/src/flow/nodes/split_by_run_result.js.map +1 -1
  45. package/out-tsc/src/flow/nodes/wait_for_digits.js +1 -1
  46. package/out-tsc/src/flow/nodes/wait_for_digits.js.map +1 -1
  47. package/out-tsc/src/flow/nodes/wait_for_response.js +1 -1
  48. package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
  49. package/out-tsc/src/form/FieldRenderer.js +7 -0
  50. package/out-tsc/src/form/FieldRenderer.js.map +1 -1
  51. package/out-tsc/src/layout/Dialog.js +0 -1
  52. package/out-tsc/src/layout/Dialog.js.map +1 -1
  53. package/out-tsc/src/layout/Modax.js +20 -2
  54. package/out-tsc/src/layout/Modax.js.map +1 -1
  55. package/out-tsc/src/list/ContentMenu.js +14 -1
  56. package/out-tsc/src/list/ContentMenu.js.map +1 -1
  57. package/out-tsc/src/live/ContactChat.js +10 -1
  58. package/out-tsc/src/live/ContactChat.js.map +1 -1
  59. package/out-tsc/src/live/TembaChart.js.map +1 -1
  60. package/out-tsc/src/locales/es.js +5 -5
  61. package/out-tsc/src/locales/es.js.map +1 -1
  62. package/out-tsc/src/locales/fr.js +5 -5
  63. package/out-tsc/src/locales/fr.js.map +1 -1
  64. package/out-tsc/src/locales/locale-codes.js +11 -2
  65. package/out-tsc/src/locales/locale-codes.js.map +1 -1
  66. package/out-tsc/src/locales/pt.js +5 -5
  67. package/out-tsc/src/locales/pt.js.map +1 -1
  68. package/out-tsc/src/simulator/Simulator.js +11 -0
  69. package/out-tsc/src/simulator/Simulator.js.map +1 -1
  70. package/out-tsc/src/store/AppState.js +13 -0
  71. package/out-tsc/src/store/AppState.js.map +1 -1
  72. package/out-tsc/src/version.js +9 -0
  73. package/out-tsc/src/version.js.map +1 -0
  74. package/out-tsc/test/actions/add_contact_groups.test.js +35 -0
  75. package/out-tsc/test/actions/add_contact_groups.test.js.map +1 -1
  76. package/out-tsc/test/actions/add_input_labels.test.js +53 -0
  77. package/out-tsc/test/actions/add_input_labels.test.js.map +1 -0
  78. package/out-tsc/test/actions/enter_flow.test.js +71 -0
  79. package/out-tsc/test/actions/enter_flow.test.js.map +1 -0
  80. package/out-tsc/test/actions/remove_contact_groups.test.js +24 -0
  81. package/out-tsc/test/actions/remove_contact_groups.test.js.map +1 -1
  82. package/out-tsc/test/actions/send_broadcast.test.js +41 -0
  83. package/out-tsc/test/actions/send_broadcast.test.js.map +1 -1
  84. package/out-tsc/test/actions/set_contact_channel.test.js +67 -0
  85. package/out-tsc/test/actions/set_contact_channel.test.js.map +1 -0
  86. package/out-tsc/test/actions/set_contact_field.test.js +52 -0
  87. package/out-tsc/test/actions/set_contact_field.test.js.map +1 -0
  88. package/out-tsc/test/actions/set_contact_language.test.js +39 -0
  89. package/out-tsc/test/actions/set_contact_language.test.js.map +1 -0
  90. package/out-tsc/test/actions/set_contact_name.test.js +28 -0
  91. package/out-tsc/test/actions/set_contact_name.test.js.map +1 -0
  92. package/out-tsc/test/actions/set_contact_status.test.js +44 -0
  93. package/out-tsc/test/actions/set_contact_status.test.js.map +1 -0
  94. package/out-tsc/test/actions/set_run_result.test.js +47 -0
  95. package/out-tsc/test/actions/set_run_result.test.js.map +1 -0
  96. package/out-tsc/test/actions/start_session.test.js +76 -0
  97. package/out-tsc/test/actions/start_session.test.js.map +1 -1
  98. package/out-tsc/test/nodes/split_by_contact_field.test.js +50 -0
  99. package/out-tsc/test/nodes/split_by_contact_field.test.js.map +1 -1
  100. package/out-tsc/test/nodes/split_by_run_result.test.js +82 -0
  101. package/out-tsc/test/nodes/split_by_run_result.test.js.map +1 -1
  102. package/out-tsc/test/nodes/split_by_ticket.test.js +139 -0
  103. package/out-tsc/test/nodes/split_by_ticket.test.js.map +1 -0
  104. package/out-tsc/test/nodes/split_by_webhook.test.js +111 -0
  105. package/out-tsc/test/nodes/split_by_webhook.test.js.map +1 -0
  106. package/out-tsc/test/temba-contact-chat.test.js +12 -0
  107. package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
  108. package/out-tsc/test/temba-flow-editor.test.js +206 -0
  109. package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
  110. package/out-tsc/test/temba-flow-plumber.test.js +19 -0
  111. package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
  112. package/out-tsc/test/temba-select.test.js +4 -1
  113. package/out-tsc/test/temba-select.test.js.map +1 -1
  114. package/out-tsc/test/utils.test.js +4 -2
  115. package/out-tsc/test/utils.test.js.map +1 -1
  116. package/package.json +3 -9
  117. package/rollup.components.mjs +7 -1
  118. package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
  119. package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
  120. package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
  121. package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
  122. package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
  123. package/screenshots/truth/actions/add_contact_urn/render/expression-facebook.png +0 -0
  124. package/screenshots/truth/actions/add_contact_urn/render/expression-phone.png +0 -0
  125. package/screenshots/truth/actions/add_contact_urn/render/facebook-id.png +0 -0
  126. package/screenshots/truth/actions/add_contact_urn/render/instagram-handle.png +0 -0
  127. package/screenshots/truth/actions/add_contact_urn/render/line-id.png +0 -0
  128. package/screenshots/truth/actions/add_contact_urn/render/phone-number.png +0 -0
  129. package/screenshots/truth/actions/add_contact_urn/render/telegram-id.png +0 -0
  130. package/screenshots/truth/actions/add_contact_urn/render/viber-id.png +0 -0
  131. package/screenshots/truth/actions/add_contact_urn/render/wechat-id.png +0 -0
  132. package/screenshots/truth/actions/add_contact_urn/render/whatsapp.png +0 -0
  133. package/screenshots/truth/actions/add_input_labels/editor/multiple-labels.png +0 -0
  134. package/screenshots/truth/actions/add_input_labels/editor/single-label.png +0 -0
  135. package/screenshots/truth/actions/add_input_labels/render/multiple-labels.png +0 -0
  136. package/screenshots/truth/actions/add_input_labels/render/single-label.png +0 -0
  137. package/screenshots/truth/actions/enter_flow/editor/basic-flow.png +0 -0
  138. package/screenshots/truth/actions/enter_flow/editor/long-flow-name.png +0 -0
  139. package/screenshots/truth/actions/enter_flow/render/basic-flow.png +0 -0
  140. package/screenshots/truth/actions/enter_flow/render/long-flow-name.png +0 -0
  141. package/screenshots/truth/actions/play_audio/render/expression-url.png +0 -0
  142. package/screenshots/truth/actions/play_audio/render/static-url.png +0 -0
  143. package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
  144. package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
  145. package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
  146. package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
  147. package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
  148. package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
  149. package/screenshots/truth/actions/say_msg/render/multiline-text.png +0 -0
  150. package/screenshots/truth/actions/say_msg/render/simple-text.png +0 -0
  151. package/screenshots/truth/actions/say_msg/render/text-with-audio-url.png +0 -0
  152. package/screenshots/truth/actions/send_broadcast/render/contacts-only.png +0 -0
  153. package/screenshots/truth/actions/send_broadcast/render/groups-and-contacts.png +0 -0
  154. package/screenshots/truth/actions/send_broadcast/render/groups-only.png +0 -0
  155. package/screenshots/truth/actions/send_broadcast/render/many-groups.png +0 -0
  156. package/screenshots/truth/actions/send_broadcast/render/multiline-text.png +0 -0
  157. package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
  158. package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
  159. package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
  160. package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
  161. package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
  162. package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
  163. package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
  164. package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
  165. package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
  166. package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
  167. package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
  168. package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
  169. package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
  170. package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
  171. package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
  172. package/screenshots/truth/actions/set_contact_channel/editor/sms-channel.png +0 -0
  173. package/screenshots/truth/actions/set_contact_channel/editor/whatsapp-channel.png +0 -0
  174. package/screenshots/truth/actions/set_contact_channel/render/sms-channel.png +0 -0
  175. package/screenshots/truth/actions/set_contact_channel/render/whatsapp-channel.png +0 -0
  176. package/screenshots/truth/actions/set_contact_field/editor/clear-value.png +0 -0
  177. package/screenshots/truth/actions/set_contact_field/editor/set-value.png +0 -0
  178. package/screenshots/truth/actions/set_contact_field/render/clear-value.png +0 -0
  179. package/screenshots/truth/actions/set_contact_field/render/set-value.png +0 -0
  180. package/screenshots/truth/actions/set_contact_language/editor/english.png +0 -0
  181. package/screenshots/truth/actions/set_contact_language/editor/french.png +0 -0
  182. package/screenshots/truth/actions/set_contact_language/render/english.png +0 -0
  183. package/screenshots/truth/actions/set_contact_language/render/french.png +0 -0
  184. package/screenshots/truth/actions/set_contact_name/editor/expression-name.png +0 -0
  185. package/screenshots/truth/actions/set_contact_name/editor/static-name.png +0 -0
  186. package/screenshots/truth/actions/set_contact_name/render/expression-name.png +0 -0
  187. package/screenshots/truth/actions/set_contact_name/render/static-name.png +0 -0
  188. package/screenshots/truth/actions/set_contact_status/editor/active.png +0 -0
  189. package/screenshots/truth/actions/set_contact_status/editor/archived.png +0 -0
  190. package/screenshots/truth/actions/set_contact_status/editor/blocked.png +0 -0
  191. package/screenshots/truth/actions/set_contact_status/render/active.png +0 -0
  192. package/screenshots/truth/actions/set_contact_status/render/archived.png +0 -0
  193. package/screenshots/truth/actions/set_contact_status/render/blocked.png +0 -0
  194. package/screenshots/truth/actions/set_run_result/editor/expression-value.png +0 -0
  195. package/screenshots/truth/actions/set_run_result/editor/with-category.png +0 -0
  196. package/screenshots/truth/actions/set_run_result/render/expression-value.png +0 -0
  197. package/screenshots/truth/actions/set_run_result/render/with-category.png +0 -0
  198. package/screenshots/truth/actions/start_session/render/contact-query.png +0 -0
  199. package/screenshots/truth/actions/start_session/render/contacts-only.png +0 -0
  200. package/screenshots/truth/actions/start_session/render/create-contact.png +0 -0
  201. package/screenshots/truth/actions/start_session/render/groups-and-contacts.png +0 -0
  202. package/screenshots/truth/actions/start_session/render/groups-only.png +0 -0
  203. package/screenshots/truth/actions/start_session/render/many-recipients.png +0 -0
  204. package/screenshots/truth/editor/wait.png +0 -0
  205. package/screenshots/truth/nodes/split_by_llm/render/information-extraction.png +0 -0
  206. package/screenshots/truth/nodes/split_by_llm/render/sentiment-analysis.png +0 -0
  207. package/screenshots/truth/nodes/split_by_llm/render/summarization.png +0 -0
  208. package/screenshots/truth/nodes/split_by_llm/render/translation-task.png +0 -0
  209. package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
  210. package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.png +0 -0
  211. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  212. package/screenshots/truth/nodes/split_by_llm_categorize/editor/many-categories.png +0 -0
  213. package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.png +0 -0
  214. package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
  215. package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
  216. package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
  217. package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
  218. package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
  219. package/screenshots/truth/nodes/split_by_random/editor/ab-test-multiple-variants.png +0 -0
  220. package/screenshots/truth/nodes/split_by_random/editor/sampling-split.png +0 -0
  221. package/screenshots/truth/nodes/split_by_random/editor/three-way-split.png +0 -0
  222. package/screenshots/truth/nodes/split_by_random/editor/two-bucket-split.png +0 -0
  223. package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
  224. package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
  225. package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
  226. package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
  227. package/screenshots/truth/nodes/wait_for_audio/render/basic-audio-wait.png +0 -0
  228. package/screenshots/truth/nodes/wait_for_dial/render/basic-dial.png +0 -0
  229. package/screenshots/truth/nodes/wait_for_dial/render/dial-with-limits.png +0 -0
  230. package/screenshots/truth/nodes/wait_for_digits/editor/basic-digits-wait.png +0 -0
  231. package/screenshots/truth/nodes/wait_for_digits/editor/digits-with-rules.png +0 -0
  232. package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
  233. package/screenshots/truth/nodes/wait_for_digits/render/digits-with-rules.png +0 -0
  234. package/screenshots/truth/nodes/wait_for_menu/render/menu-with-digits.png +0 -0
  235. package/screenshots/truth/nodes/wait_for_response/editor/basic-wait.png +0 -0
  236. package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
  237. package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
  238. package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.png +0 -0
  239. package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
  240. package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
  241. package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
  242. package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
  243. package/src/display/FloatingTab.ts +1 -1
  244. package/src/flow/CanvasNode.ts +1 -1
  245. package/src/flow/Editor.ts +299 -88
  246. package/src/flow/Plumber.ts +89 -14
  247. package/src/flow/actions/add_contact_groups.ts +4 -1
  248. package/src/flow/actions/add_input_labels.ts +4 -1
  249. package/src/flow/actions/remove_contact_groups.ts +6 -1
  250. package/src/flow/actions/send_broadcast.ts +6 -2
  251. package/src/flow/actions/set_contact_channel.ts +13 -1
  252. package/src/flow/actions/set_contact_status.ts +7 -5
  253. package/src/flow/actions/start_session.ts +10 -3
  254. package/src/flow/nodes/split_by_contact_field.ts +16 -5
  255. package/src/flow/nodes/split_by_expression.ts +1 -1
  256. package/src/flow/nodes/split_by_llm_categorize.ts +0 -1
  257. package/src/flow/nodes/split_by_random.ts +0 -1
  258. package/src/flow/nodes/split_by_run_result.ts +10 -4
  259. package/src/flow/nodes/wait_for_digits.ts +2 -1
  260. package/src/flow/nodes/wait_for_response.ts +1 -1
  261. package/src/form/FieldRenderer.ts +7 -0
  262. package/src/layout/Dialog.ts +0 -1
  263. package/src/layout/Modax.ts +19 -2
  264. package/src/list/ContentMenu.ts +15 -1
  265. package/src/live/ContactChat.ts +10 -1
  266. package/src/live/TembaChart.ts +1 -1
  267. package/src/locales/es.ts +18 -13
  268. package/src/locales/fr.ts +18 -13
  269. package/src/locales/locale-codes.ts +11 -2
  270. package/src/locales/pt.ts +18 -13
  271. package/src/simulator/Simulator.ts +12 -0
  272. package/src/store/AppState.ts +15 -0
  273. package/src/store/flow-definition.d.ts +1 -0
  274. package/src/version.ts +10 -0
  275. package/test/actions/add_contact_groups.test.ts +38 -0
  276. package/test/actions/add_input_labels.test.ts +67 -0
  277. package/test/actions/enter_flow.test.ts +88 -0
  278. package/test/actions/remove_contact_groups.test.ts +29 -0
  279. package/test/actions/send_broadcast.test.ts +44 -0
  280. package/test/actions/set_contact_channel.test.ts +88 -0
  281. package/test/actions/set_contact_field.test.ts +68 -0
  282. package/test/actions/set_contact_language.test.ts +55 -0
  283. package/test/actions/set_contact_name.test.ts +39 -0
  284. package/test/actions/set_contact_status.test.ts +64 -0
  285. package/test/actions/set_run_result.test.ts +61 -0
  286. package/test/actions/start_session.test.ts +82 -0
  287. package/test/nodes/split_by_contact_field.test.ts +59 -0
  288. package/test/nodes/split_by_run_result.test.ts +100 -0
  289. package/test/nodes/split_by_ticket.test.ts +157 -0
  290. package/test/nodes/split_by_webhook.test.ts +131 -0
  291. package/test/temba-contact-chat.test.ts +17 -0
  292. package/test/temba-flow-editor.test.ts +264 -0
  293. package/test/temba-flow-plumber.test.ts +62 -0
  294. package/test/temba-select.test.ts +6 -1
  295. package/test/utils.test.ts +4 -2
  296. package/web-dev-server.config.mjs +5 -1
  297. package/web-test-runner.config.mjs +4 -1
@@ -1 +1 @@
1
- {"version":3,"file":"temba-flow-editor.test.js","sourceRoot":"","sources":["../../test/temba-flow-editor.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, fixture, expect } from '@open-wc/testing';\nimport { Editor } from '../src/flow/Editor';\nimport { Plumber } from '../src/flow/Plumber';\nimport { stub, restore } from 'sinon';\n\n// Register the component\ncustomElements.define('temba-flow-editor', Editor);\n\ndescribe('Editor', () => {\n let editor: Editor;\n\n beforeEach(() => {\n // Reset any stubs\n restore();\n });\n\n afterEach(() => {\n restore();\n });\n\n describe('basic functionality', () => {\n it('creates render root as element itself', () => {\n const editor = new Editor();\n expect(editor.createRenderRoot()).to.equal(editor);\n });\n\n it('has correct CSS styles defined', () => {\n const styles = Editor.styles;\n expect(styles).to.exist;\n expect(styles.cssText).to.contain('#editor');\n expect(styles.cssText).to.contain('#grid');\n expect(styles.cssText).to.contain('#canvas');\n expect(styles.cssText).to.contain('.plumb-connector');\n });\n\n it('creates with default properties', () => {\n editor = new Editor();\n expect(editor.flow).to.be.undefined;\n expect(editor.version).to.be.undefined;\n });\n\n it('accepts flow and version properties without getStore call', async () => {\n editor = document.createElement('temba-flow-editor') as Editor;\n editor.flow = 'test-flow-uuid';\n editor.version = '1.0';\n\n expect(editor.flow).to.equal('test-flow-uuid');\n expect(editor.version).to.equal('1.0');\n });\n });\n\n describe('lifecycle methods', () => {\n it('calls firstUpdated and initializes plumber', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Verify that plumber is initialized\n expect((editor as any).plumber).to.be.instanceOf(Plumber);\n });\n\n it('verifies firstUpdated method exists and can be called', () => {\n editor = new Editor();\n\n // Mock canvas element\n const mockCanvas = document.createElement('div');\n mockCanvas.id = 'canvas';\n\n // Mock querySelector to return our mock canvas\n stub(editor, 'querySelector').returns(mockCanvas);\n\n // Verify firstUpdated method exists\n expect(typeof (editor as any).firstUpdated).to.equal('function');\n\n // Test that calling firstUpdated doesn't throw (without getStore)\n expect(() => {\n // Only test the plumber initialization part\n (editor as any).plumber = new Plumber(mockCanvas, editor);\n }).to.not.throw();\n });\n\n it('handles updated with canvasSize changes', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Simulate canvasSize change\n (editor as any).canvasSize = { width: 800, height: 600 };\n const changes = new Map();\n changes.set('canvasSize', true);\n\n (editor as any).updated(changes);\n\n // Verify the canvasSize was set correctly\n expect((editor as any).canvasSize).to.deep.equal({\n width: 800,\n height: 600\n });\n });\n\n it('handles updated without canvasSize changes', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n const consoleStub = stub(console, 'log');\n\n const changes = new Map();\n changes.set('other', true);\n\n (editor as any).updated(changes);\n\n expect(consoleStub).to.not.have.been.called;\n\n consoleStub.restore();\n });\n });\n\n describe('render method', () => {\n it('renders loading when no definition', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Set canvas size to avoid undefined errors\n (editor as any).canvasSize = { width: 800, height: 600 };\n await editor.updateComplete;\n\n const loadingElement = editor.querySelector('temba-loading');\n expect(loadingElement).to.exist;\n });\n\n it('renders nodes when definition exists', async () => {\n const mockDefinition = {\n nodes: [\n {\n uuid: 'node-1',\n actions: [],\n exits: []\n },\n {\n uuid: 'node-2',\n actions: [],\n exits: []\n }\n ],\n _ui: {\n nodes: {\n 'node-1': { position: { left: 100, top: 200 } },\n 'node-2': { position: { left: 300, top: 400 } }\n }\n }\n };\n\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Set properties\n (editor as any).definition = mockDefinition;\n (editor as any).canvasSize = { width: 800, height: 600 };\n await editor.updateComplete;\n\n const flowNodes = editor.querySelectorAll('temba-flow-node');\n expect(flowNodes).to.have.length(2);\n });\n\n it('includes style elements in light DOM', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Set canvas size\n (editor as any).canvasSize = { width: 800, height: 600 };\n await editor.updateComplete;\n\n const styleElements = editor.querySelectorAll('style');\n expect(styleElements.length).to.be.greaterThan(0);\n });\n\n it('renders with correct grid dimensions', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n (editor as any).canvasSize = { width: 1200, height: 800 };\n await editor.updateComplete;\n\n const gridElement = editor.querySelector('#grid');\n expect(gridElement).to.exist;\n\n const style = gridElement?.getAttribute('style');\n expect(style).to.contain('width:1200px');\n expect(style).to.contain('height:800px');\n });\n\n it('renders editor structure', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n (editor as any).canvasSize = { width: 800, height: 600 };\n await editor.updateComplete;\n\n const editorElement = editor.querySelector('#editor');\n expect(editorElement).to.exist;\n\n const gridElement = editor.querySelector('#grid');\n expect(gridElement).to.exist;\n\n const canvasElement = editor.querySelector('#canvas');\n expect(canvasElement).to.exist;\n });\n });\n\n describe('property handling', () => {\n it('handles flow property change', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Change flow property\n editor.flow = 'new-flow-uuid';\n await editor.updateComplete;\n\n expect(editor.flow).to.equal('new-flow-uuid');\n });\n\n it('handles version property change', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n editor.version = '2.0';\n await editor.updateComplete;\n\n expect(editor.version).to.equal('2.0');\n });\n });\n\n describe('store integration', () => {\n it('has fromStore decorators for definition and canvasSize', () => {\n editor = new Editor();\n\n // Check that the properties exist (they are private but we can verify they exist)\n expect(editor).to.have.property('definition');\n expect(editor).to.have.property('canvasSize');\n });\n });\n\n describe('constructor behavior', () => {\n it('calls super in constructor', () => {\n // This mainly verifies the constructor doesn't throw\n expect(() => {\n new Editor();\n }).to.not.throw();\n });\n });\n\n describe('multi-selection functionality', () => {\n let mockDefinition: any;\n\n beforeEach(() => {\n mockDefinition = {\n nodes: [\n {\n uuid: 'node-1',\n actions: [],\n exits: []\n },\n {\n uuid: 'node-2',\n actions: [],\n exits: []\n }\n ],\n _ui: {\n nodes: {\n 'node-1': { position: { left: 100, top: 200 } },\n 'node-2': { position: { left: 300, top: 400 } }\n },\n stickies: {\n 'sticky-1': {\n position: { left: 200, top: 100 },\n title: 'Test Sticky',\n body: 'Test content',\n color: 'yellow'\n }\n }\n }\n };\n });\n\n it('initializes with empty selection', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n expect((editor as any).selectedItems.size).to.equal(0);\n expect((editor as any).isSelecting).to.be.false;\n expect((editor as any).selectionBox).to.be.null;\n });\n\n it('adds visual selection styling to selected items', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Set up mock definition and selection\n (editor as any).definition = mockDefinition;\n (editor as any).canvasSize = { width: 800, height: 600 };\n (editor as any).selectedItems = new Set(['node-1']);\n await editor.updateComplete;\n\n const selectedNode = editor.querySelector(\n 'temba-flow-node[uuid=\"node-1\"]'\n );\n expect(selectedNode).to.exist;\n expect(selectedNode.classList.contains('selected')).to.be.true;\n });\n\n it('renders selection box when selecting', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Set up selection state\n (editor as any).definition = mockDefinition;\n (editor as any).canvasSize = { width: 800, height: 600 };\n (editor as any).isSelecting = true;\n (editor as any).selectionBox = {\n startX: 50,\n startY: 50,\n endX: 150,\n endY: 150\n };\n await editor.updateComplete;\n\n const selectionBox = editor.querySelector('.selection-box');\n expect(selectionBox).to.exist;\n\n const style = selectionBox.getAttribute('style');\n expect(style).to.contain('left: 50px');\n expect(style).to.contain('top: 50px');\n expect(style).to.contain('width: 100px');\n expect(style).to.contain('height: 100px');\n });\n\n it('handles escape key to clear selection', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Set up selection\n (editor as any).selectedItems.add('node-1');\n (editor as any).selectedItems.add('node-2');\n\n const mockEvent = new KeyboardEvent('keydown', { key: 'Escape' });\n (editor as any).handleKeyDown(mockEvent);\n\n expect((editor as any).selectedItems.size).to.equal(0);\n });\n });\n\n describe('canvas initialization', () => {\n it('initializes plumber with canvas element', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n const plumber = (editor as any).plumber;\n expect(plumber).to.be.instanceOf(Plumber);\n });\n\n it('handles missing canvas element gracefully', async () => {\n editor = await fixture(html`<temba-flow-editor></temba-flow-editor>`);\n\n // Should not throw even without canvas\n expect((editor as any).plumber).to.be.instanceOf(Plumber);\n });\n });\n\n describe('canvas menu functionality', () => {\n afterEach(() => {\n restore();\n });\n\n it('has context menu handler set up', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"grid\">\n <div\n id=\"canvas\"\n style=\"position: relative; width: 800px; height: 600px;\"\n ></div>\n </div>\n </temba-flow-editor>\n `);\n\n // Set up required properties\n (editor as any).canvasSize = { width: 800, height: 600 };\n await editor.updateComplete;\n\n const canvas = editor.querySelector('#canvas') as HTMLElement;\n expect(canvas).to.exist;\n\n // Check that the context menu event listener is set up\n expect((editor as any).boundCanvasContextMenu).to.exist;\n expect(typeof (editor as any).boundCanvasContextMenu).to.equal(\n 'function'\n );\n\n // Test the snapToGrid functionality that would be used\n const snapToGrid = (value: number): number => {\n const snapped = Math.round(value / 20) * 20;\n return Math.max(snapped, 0);\n };\n\n // Test various snap positions\n expect(snapToGrid(245)).to.equal(240);\n expect(snapToGrid(255)).to.equal(260);\n expect(snapToGrid(150)).to.equal(160);\n expect(snapToGrid(-10)).to.equal(0); // Should not go negative\n });\n\n it('tests context menu handler logic independently', () => {\n // Test the logic that would be in handleCanvasContextMenu\n\n // Mock event with canvas target\n const canvasTarget = { id: 'canvas' };\n const validEvent = { target: canvasTarget };\n\n // Mock event with non-canvas target\n const nonCanvasTarget = { id: 'other-element' };\n const invalidEvent = { target: nonCanvasTarget };\n\n // Test the early return condition\n const shouldReturnEarly = (event: any) => {\n const target = event.target as HTMLElement;\n return target.id !== 'canvas';\n };\n\n expect(shouldReturnEarly(validEvent)).to.be.false;\n expect(shouldReturnEarly(invalidEvent)).to.be.true;\n });\n\n it('tests position calculation logic', () => {\n // Mock canvas getBoundingClientRect\n const mockCanvas = {\n getBoundingClientRect: () => ({\n left: 50,\n top: 100,\n right: 850,\n bottom: 700,\n width: 800,\n height: 600\n })\n };\n\n // Mock event\n const mockEvent = {\n clientX: 300,\n clientY: 250\n };\n\n // Calculate relative position (this is what handleCanvasDoubleClick does)\n const canvasRect = mockCanvas.getBoundingClientRect();\n const relativeX = mockEvent.clientX - canvasRect.left; // 300 - 50 = 250\n const relativeY = mockEvent.clientY - canvasRect.top; // 250 - 100 = 150\n\n // Apply snap to grid\n const snapToGrid = (value: number) =>\n Math.max(Math.round(value / 20) * 20, 0);\n const snappedLeft = snapToGrid(relativeX); // 250 -> 260\n const snappedTop = snapToGrid(relativeY); // 150 -> 160\n\n // Verify calculations\n expect(relativeX).to.equal(250);\n expect(relativeY).to.equal(150);\n expect(snappedLeft).to.equal(260);\n expect(snappedTop).to.equal(160);\n\n // This position would be passed to createStickyNote\n const expectedPosition = {\n left: snappedLeft,\n top: snappedTop\n };\n\n expect(expectedPosition).to.deep.equal({ left: 260, top: 160 });\n });\n });\n\n describe('flow-start indicator', () => {\n it('should mark the first node as flow-start', async () => {\n const { zustand } = await import('../src/store/AppState');\n\n // create a flow definition with multiple nodes\n const mockFlowDefinition = {\n language: 'en',\n localization: {},\n name: 'Test Flow',\n nodes: [\n {\n uuid: 'node-1',\n actions: [\n { type: 'send_msg', uuid: 'action-1', text: 'Message 1' }\n ],\n exits: [{ uuid: 'exit-1', destination_uuid: null }]\n },\n {\n uuid: 'node-2',\n actions: [\n { type: 'send_msg', uuid: 'action-2', text: 'Message 2' }\n ],\n exits: [{ uuid: 'exit-2', destination_uuid: null }]\n },\n {\n uuid: 'node-3',\n actions: [\n { type: 'send_msg', uuid: 'action-3', text: 'Message 3' }\n ],\n exits: [{ uuid: 'exit-3', destination_uuid: null }]\n }\n ],\n uuid: 'test-uuid',\n type: 'messaging' as const,\n revision: 1,\n spec_version: '14.3',\n _ui: {\n nodes: {\n 'node-1': { position: { left: 100, top: 100 }, type: 'send_msg' },\n 'node-2': { position: { left: 200, top: 200 }, type: 'send_msg' },\n 'node-3': { position: { left: 300, top: 300 }, type: 'send_msg' }\n },\n languages: []\n }\n };\n\n zustand.getState().setFlowContents({\n definition: mockFlowDefinition as any,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 3, languages: 1 },\n locals: []\n }\n });\n\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n await editor.updateComplete;\n\n // get all flow nodes\n const flowNodes = editor.querySelectorAll('temba-flow-node');\n expect(flowNodes.length).to.equal(3);\n\n // first node should have flow-start class\n expect(flowNodes[0].classList.contains('flow-start')).to.be.true;\n\n // other nodes should not have flow-start class\n expect(flowNodes[1].classList.contains('flow-start')).to.be.false;\n expect(flowNodes[2].classList.contains('flow-start')).to.be.false;\n });\n\n it('should update flow-start when node positions change', async () => {\n const { zustand } = await import('../src/store/AppState');\n\n // create a flow with nodes in a specific order\n const mockFlowDefinition = {\n language: 'en',\n localization: {},\n name: 'Test Flow',\n nodes: [\n {\n uuid: 'node-1',\n actions: [\n { type: 'send_msg', uuid: 'action-1', text: 'Message 1' }\n ],\n exits: [{ uuid: 'exit-1', destination_uuid: null }]\n },\n {\n uuid: 'node-2',\n actions: [\n { type: 'send_msg', uuid: 'action-2', text: 'Message 2' }\n ],\n exits: [{ uuid: 'exit-2', destination_uuid: null }]\n }\n ],\n uuid: 'test-uuid',\n type: 'messaging' as const,\n revision: 1,\n spec_version: '14.3',\n _ui: {\n nodes: {\n 'node-1': { position: { left: 100, top: 200 }, type: 'send_msg' },\n 'node-2': { position: { left: 100, top: 100 }, type: 'send_msg' }\n },\n languages: []\n }\n };\n\n zustand.getState().setFlowContents({\n definition: mockFlowDefinition as any,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 2, languages: 1 },\n locals: []\n }\n });\n\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n await editor.updateComplete;\n\n // node-2 is at top (top: 100 < top: 200) so it should be flow-start\n const node1 = editor.querySelector('temba-flow-node[uuid=\"node-1\"]');\n const node2 = editor.querySelector('temba-flow-node[uuid=\"node-2\"]');\n\n expect(node2).to.exist;\n expect(node1).to.exist;\n expect(node2.classList.contains('flow-start')).to.be.true;\n expect(node1.classList.contains('flow-start')).to.be.false;\n\n // move node-1 to the top\n zustand.getState().updateCanvasPositions({\n 'node-1': { left: 100, top: 50 }\n });\n\n await editor.updateComplete;\n\n // now node-1 should be first\n const updatedFlowNodes = editor.querySelectorAll('temba-flow-node');\n expect(updatedFlowNodes[0].getAttribute('uuid')).to.equal('node-1');\n expect(updatedFlowNodes[0].classList.contains('flow-start')).to.be.true;\n expect(updatedFlowNodes[1].classList.contains('flow-start')).to.be.false;\n });\n\n it('should maintain flow-start when nodes are added', async () => {\n const { zustand } = await import('../src/store/AppState');\n\n // start with one node\n const mockFlowDefinition = {\n language: 'en',\n localization: {},\n name: 'Test Flow',\n nodes: [\n {\n uuid: 'node-1',\n actions: [\n { type: 'send_msg', uuid: 'action-1', text: 'Message 1' }\n ],\n exits: [{ uuid: 'exit-1', destination_uuid: null }]\n }\n ],\n uuid: 'test-uuid',\n type: 'messaging' as const,\n revision: 1,\n spec_version: '14.3',\n _ui: {\n nodes: {\n 'node-1': { position: { left: 100, top: 200 }, type: 'send_msg' }\n },\n languages: []\n }\n };\n\n zustand.getState().setFlowContents({\n definition: mockFlowDefinition as any,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 1, languages: 1 },\n locals: []\n }\n });\n\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n await editor.updateComplete;\n\n const flowNodes = editor.querySelectorAll('temba-flow-node');\n expect(flowNodes[0].classList.contains('flow-start')).to.be.true;\n\n // add a new node at the top\n const newNode = {\n uuid: 'node-2',\n actions: [\n { type: 'send_msg' as const, uuid: 'action-2', text: 'Message 2' }\n ],\n exits: [{ uuid: 'exit-2', destination_uuid: null }]\n };\n const newNodeUI = {\n position: { left: 100, top: 100 },\n type: 'send_msg' as const\n };\n\n zustand.getState().addNode(newNode, newNodeUI);\n\n await editor.updateComplete;\n\n // new node should now be the flow-start\n const node1 = editor.querySelector('temba-flow-node[uuid=\"node-1\"]');\n const node2 = editor.querySelector('temba-flow-node[uuid=\"node-2\"]');\n\n expect(node2).to.exist;\n expect(node1).to.exist;\n expect(node2.classList.contains('flow-start')).to.be.true;\n expect(node1.classList.contains('flow-start')).to.be.false;\n });\n\n it('should handle flow-start when first node is removed', async () => {\n const { zustand } = await import('../src/store/AppState');\n\n // create flow with multiple nodes\n const mockFlowDefinition = {\n language: 'en',\n localization: {},\n name: 'Test Flow',\n nodes: [\n {\n uuid: 'node-1',\n actions: [\n { type: 'send_msg', uuid: 'action-1', text: 'Message 1' }\n ],\n exits: [{ uuid: 'exit-1', destination_uuid: null }]\n },\n {\n uuid: 'node-2',\n actions: [\n { type: 'send_msg', uuid: 'action-2', text: 'Message 2' }\n ],\n exits: [{ uuid: 'exit-2', destination_uuid: null }]\n }\n ],\n uuid: 'test-uuid',\n type: 'messaging' as const,\n revision: 1,\n spec_version: '14.3',\n _ui: {\n nodes: {\n 'node-1': { position: { left: 100, top: 100 }, type: 'send_msg' },\n 'node-2': { position: { left: 100, top: 200 }, type: 'send_msg' }\n },\n languages: []\n }\n };\n\n zustand.getState().setFlowContents({\n definition: mockFlowDefinition as any,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 2, languages: 1 },\n locals: []\n }\n });\n\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n await editor.updateComplete;\n\n let flowNodes = editor.querySelectorAll('temba-flow-node');\n expect(flowNodes[0].getAttribute('uuid')).to.equal('node-1');\n expect(flowNodes[0].classList.contains('flow-start')).to.be.true;\n\n // remove the first node\n zustand.getState().removeNodes(['node-1']);\n\n await editor.updateComplete;\n\n // node-2 should now be the flow-start\n flowNodes = editor.querySelectorAll('temba-flow-node');\n expect(flowNodes.length).to.equal(1);\n expect(flowNodes[0].getAttribute('uuid')).to.equal('node-2');\n expect(flowNodes[0].classList.contains('flow-start')).to.be.true;\n });\n });\n});\n"]}
1
+ {"version":3,"file":"temba-flow-editor.test.js","sourceRoot":"","sources":["../../test/temba-flow-editor.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, fixture, expect } from '@open-wc/testing';\nimport { Editor } from '../src/flow/Editor';\nimport { Plumber } from '../src/flow/Plumber';\nimport { stub, restore } from 'sinon';\nimport { zustand } from '../src/store/AppState';\nimport { TEMBA_COMPONENTS_VERSION } from '../src/version';\n\n// Register the component\ncustomElements.define('temba-flow-editor', Editor);\n\ndescribe('Editor', () => {\n let editor: Editor;\n\n beforeEach(() => {\n // Reset any stubs\n restore();\n });\n\n afterEach(() => {\n restore();\n });\n\n describe('basic functionality', () => {\n it('creates render root as element itself', () => {\n const editor = new Editor();\n expect(editor.createRenderRoot()).to.equal(editor);\n });\n\n it('has correct CSS styles defined', () => {\n const styles = Editor.styles;\n expect(styles).to.exist;\n expect(styles.cssText).to.contain('#editor');\n expect(styles.cssText).to.contain('#grid');\n expect(styles.cssText).to.contain('#canvas');\n expect(styles.cssText).to.contain('.plumb-connector');\n });\n\n it('creates with default properties', () => {\n editor = new Editor();\n expect(editor.flow).to.be.undefined;\n expect(editor.version).to.be.undefined;\n });\n\n it('accepts flow and version properties without getStore call', async () => {\n editor = document.createElement('temba-flow-editor') as Editor;\n editor.flow = 'test-flow-uuid';\n editor.version = '1.0';\n\n expect(editor.flow).to.equal('test-flow-uuid');\n expect(editor.version).to.equal('1.0');\n });\n });\n\n describe('lifecycle methods', () => {\n it('calls firstUpdated and initializes plumber', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Verify that plumber is initialized\n expect((editor as any).plumber).to.be.instanceOf(Plumber);\n });\n\n it('verifies firstUpdated method exists and can be called', () => {\n editor = new Editor();\n\n // Mock canvas element\n const mockCanvas = document.createElement('div');\n mockCanvas.id = 'canvas';\n\n // Mock querySelector to return our mock canvas\n stub(editor, 'querySelector').returns(mockCanvas);\n\n // Verify firstUpdated method exists\n expect(typeof (editor as any).firstUpdated).to.equal('function');\n\n // Test that calling firstUpdated doesn't throw (without getStore)\n expect(() => {\n // Only test the plumber initialization part\n (editor as any).plumber = new Plumber(mockCanvas, editor);\n }).to.not.throw();\n });\n\n it('handles updated with canvasSize changes', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Simulate canvasSize change\n (editor as any).canvasSize = { width: 800, height: 600 };\n const changes = new Map();\n changes.set('canvasSize', true);\n\n (editor as any).updated(changes);\n\n // Verify the canvasSize was set correctly\n expect((editor as any).canvasSize).to.deep.equal({\n width: 800,\n height: 600\n });\n });\n\n it('handles updated without canvasSize changes', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n const consoleStub = stub(console, 'log');\n\n const changes = new Map();\n changes.set('other', true);\n\n (editor as any).updated(changes);\n\n expect(consoleStub).to.not.have.been.called;\n\n consoleStub.restore();\n });\n });\n\n describe('disconnectedCallback', () => {\n it('clears flow data from the store when editor is removed', async () => {\n // Set up some flow-specific state\n zustand.setState({\n flowDefinition: { nodes: [], _ui: { nodes: {} } } as any,\n activity: { nodes: {}, segments: {} },\n simulatorActivity: { nodes: {}, segments: {} },\n simulatorActive: true,\n flowInfo: {\n results: [],\n dependencies: [],\n counts: { nodes: 0, languages: 0 },\n locals: []\n } as any,\n dirtyDate: new Date()\n });\n\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Verify state is populated\n expect(zustand.getState().flowDefinition).to.not.be.null;\n expect(zustand.getState().activity).to.not.be.null;\n\n // Remove the editor from the DOM\n editor.remove();\n\n // Verify all flow-specific state has been cleared\n expect(zustand.getState().flowDefinition).to.be.null;\n expect(zustand.getState().activity).to.be.null;\n expect(zustand.getState().simulatorActivity).to.be.null;\n expect(zustand.getState().simulatorActive).to.be.false;\n expect(zustand.getState().flowInfo).to.be.null;\n expect(zustand.getState().dirtyDate).to.be.null;\n });\n });\n\n describe('render method', () => {\n it('renders loading when no definition', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Set canvas size to avoid undefined errors\n (editor as any).canvasSize = { width: 800, height: 600 };\n await editor.updateComplete;\n\n const loadingElement = editor.querySelector('temba-loading');\n expect(loadingElement).to.exist;\n });\n\n it('renders nodes when definition exists', async () => {\n const mockDefinition = {\n nodes: [\n {\n uuid: 'node-1',\n actions: [],\n exits: []\n },\n {\n uuid: 'node-2',\n actions: [],\n exits: []\n }\n ],\n _ui: {\n nodes: {\n 'node-1': { position: { left: 100, top: 200 } },\n 'node-2': { position: { left: 300, top: 400 } }\n }\n }\n };\n\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Set properties\n (editor as any).definition = mockDefinition;\n (editor as any).canvasSize = { width: 800, height: 600 };\n await editor.updateComplete;\n\n const flowNodes = editor.querySelectorAll('temba-flow-node');\n expect(flowNodes).to.have.length(2);\n });\n\n it('includes style elements in light DOM', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Set canvas size\n (editor as any).canvasSize = { width: 800, height: 600 };\n await editor.updateComplete;\n\n const styleElements = editor.querySelectorAll('style');\n expect(styleElements.length).to.be.greaterThan(0);\n });\n\n it('renders with correct grid dimensions', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n (editor as any).canvasSize = { width: 1200, height: 800 };\n await editor.updateComplete;\n\n const gridElement = editor.querySelector('#grid');\n expect(gridElement).to.exist;\n\n const style = gridElement?.getAttribute('style');\n expect(style).to.contain('width:1200px');\n expect(style).to.contain('height:800px');\n });\n\n it('renders editor structure', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n (editor as any).canvasSize = { width: 800, height: 600 };\n await editor.updateComplete;\n\n const editorElement = editor.querySelector('#editor');\n expect(editorElement).to.exist;\n\n const gridElement = editor.querySelector('#grid');\n expect(gridElement).to.exist;\n\n const canvasElement = editor.querySelector('#canvas');\n expect(canvasElement).to.exist;\n });\n });\n\n describe('property handling', () => {\n it('handles flow property change', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Change flow property\n editor.flow = 'new-flow-uuid';\n await editor.updateComplete;\n\n expect(editor.flow).to.equal('new-flow-uuid');\n });\n\n it('handles version property change', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n editor.version = '2.0';\n await editor.updateComplete;\n\n expect(editor.version).to.equal('2.0');\n });\n });\n\n describe('store integration', () => {\n it('has fromStore decorators for definition and canvasSize', () => {\n editor = new Editor();\n\n // Check that the properties exist (they are private but we can verify they exist)\n expect(editor).to.have.property('definition');\n expect(editor).to.have.property('canvasSize');\n });\n });\n\n describe('constructor behavior', () => {\n it('calls super in constructor', () => {\n // This mainly verifies the constructor doesn't throw\n expect(() => {\n new Editor();\n }).to.not.throw();\n });\n });\n\n describe('multi-selection functionality', () => {\n let mockDefinition: any;\n\n beforeEach(() => {\n mockDefinition = {\n nodes: [\n {\n uuid: 'node-1',\n actions: [],\n exits: []\n },\n {\n uuid: 'node-2',\n actions: [],\n exits: []\n }\n ],\n _ui: {\n nodes: {\n 'node-1': { position: { left: 100, top: 200 } },\n 'node-2': { position: { left: 300, top: 400 } }\n },\n stickies: {\n 'sticky-1': {\n position: { left: 200, top: 100 },\n title: 'Test Sticky',\n body: 'Test content',\n color: 'yellow'\n }\n }\n }\n };\n });\n\n it('initializes with empty selection', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n expect((editor as any).selectedItems.size).to.equal(0);\n expect((editor as any).isSelecting).to.be.false;\n expect((editor as any).selectionBox).to.be.null;\n });\n\n it('adds visual selection styling to selected items', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Set up mock definition and selection\n (editor as any).definition = mockDefinition;\n (editor as any).canvasSize = { width: 800, height: 600 };\n (editor as any).selectedItems = new Set(['node-1']);\n await editor.updateComplete;\n\n const selectedNode = editor.querySelector(\n 'temba-flow-node[uuid=\"node-1\"]'\n );\n expect(selectedNode).to.exist;\n expect(selectedNode.classList.contains('selected')).to.be.true;\n });\n\n it('renders selection box when selecting', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Set up selection state\n (editor as any).definition = mockDefinition;\n (editor as any).canvasSize = { width: 800, height: 600 };\n (editor as any).isSelecting = true;\n (editor as any).selectionBox = {\n startX: 50,\n startY: 50,\n endX: 150,\n endY: 150\n };\n await editor.updateComplete;\n\n const selectionBox = editor.querySelector('.selection-box');\n expect(selectionBox).to.exist;\n\n const style = selectionBox.getAttribute('style');\n expect(style).to.contain('left: 50px');\n expect(style).to.contain('top: 50px');\n expect(style).to.contain('width: 100px');\n expect(style).to.contain('height: 100px');\n });\n\n it('handles escape key to clear selection', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n // Set up selection\n (editor as any).selectedItems.add('node-1');\n (editor as any).selectedItems.add('node-2');\n\n const mockEvent = new KeyboardEvent('keydown', { key: 'Escape' });\n (editor as any).handleKeyDown(mockEvent);\n\n expect((editor as any).selectedItems.size).to.equal(0);\n });\n });\n\n describe('canvas initialization', () => {\n it('initializes plumber with canvas element', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n const plumber = (editor as any).plumber;\n expect(plumber).to.be.instanceOf(Plumber);\n });\n\n it('handles missing canvas element gracefully', async () => {\n editor = await fixture(html`<temba-flow-editor></temba-flow-editor>`);\n\n // Should not throw even without canvas\n expect((editor as any).plumber).to.be.instanceOf(Plumber);\n });\n });\n\n describe('canvas menu functionality', () => {\n afterEach(() => {\n restore();\n });\n\n it('has context menu handler set up', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"grid\">\n <div\n id=\"canvas\"\n style=\"position: relative; width: 800px; height: 600px;\"\n ></div>\n </div>\n </temba-flow-editor>\n `);\n\n // Set up required properties\n (editor as any).canvasSize = { width: 800, height: 600 };\n await editor.updateComplete;\n\n const canvas = editor.querySelector('#canvas') as HTMLElement;\n expect(canvas).to.exist;\n\n // Check that the context menu event listener is set up\n expect((editor as any).boundCanvasContextMenu).to.exist;\n expect(typeof (editor as any).boundCanvasContextMenu).to.equal(\n 'function'\n );\n\n // Test the snapToGrid functionality that would be used\n const snapToGrid = (value: number): number => {\n const snapped = Math.round(value / 20) * 20;\n return Math.max(snapped, 0);\n };\n\n // Test various snap positions\n expect(snapToGrid(245)).to.equal(240);\n expect(snapToGrid(255)).to.equal(260);\n expect(snapToGrid(150)).to.equal(160);\n expect(snapToGrid(-10)).to.equal(0); // Should not go negative\n });\n\n it('tests context menu handler logic independently', () => {\n // Test the logic that would be in handleCanvasContextMenu\n\n // Mock event with canvas target\n const canvasTarget = { id: 'canvas' };\n const validEvent = { target: canvasTarget };\n\n // Mock event with non-canvas target\n const nonCanvasTarget = { id: 'other-element' };\n const invalidEvent = { target: nonCanvasTarget };\n\n // Test the early return condition\n const shouldReturnEarly = (event: any) => {\n const target = event.target as HTMLElement;\n return target.id !== 'canvas';\n };\n\n expect(shouldReturnEarly(validEvent)).to.be.false;\n expect(shouldReturnEarly(invalidEvent)).to.be.true;\n });\n\n it('tests position calculation logic', () => {\n // Mock canvas getBoundingClientRect\n const mockCanvas = {\n getBoundingClientRect: () => ({\n left: 50,\n top: 100,\n right: 850,\n bottom: 700,\n width: 800,\n height: 600\n })\n };\n\n // Mock event\n const mockEvent = {\n clientX: 300,\n clientY: 250\n };\n\n // Calculate relative position (this is what handleCanvasDoubleClick does)\n const canvasRect = mockCanvas.getBoundingClientRect();\n const relativeX = mockEvent.clientX - canvasRect.left; // 300 - 50 = 250\n const relativeY = mockEvent.clientY - canvasRect.top; // 250 - 100 = 150\n\n // Apply snap to grid\n const snapToGrid = (value: number) =>\n Math.max(Math.round(value / 20) * 20, 0);\n const snappedLeft = snapToGrid(relativeX); // 250 -> 260\n const snappedTop = snapToGrid(relativeY); // 150 -> 160\n\n // Verify calculations\n expect(relativeX).to.equal(250);\n expect(relativeY).to.equal(150);\n expect(snappedLeft).to.equal(260);\n expect(snappedTop).to.equal(160);\n\n // This position would be passed to createStickyNote\n const expectedPosition = {\n left: snappedLeft,\n top: snappedTop\n };\n\n expect(expectedPosition).to.deep.equal({ left: 260, top: 160 });\n });\n });\n\n describe('flow-start indicator', () => {\n it('should mark the first node as flow-start', async () => {\n const { zustand } = await import('../src/store/AppState');\n\n // create a flow definition with multiple nodes\n const mockFlowDefinition = {\n language: 'en',\n localization: {},\n name: 'Test Flow',\n nodes: [\n {\n uuid: 'node-1',\n actions: [\n { type: 'send_msg', uuid: 'action-1', text: 'Message 1' }\n ],\n exits: [{ uuid: 'exit-1', destination_uuid: null }]\n },\n {\n uuid: 'node-2',\n actions: [\n { type: 'send_msg', uuid: 'action-2', text: 'Message 2' }\n ],\n exits: [{ uuid: 'exit-2', destination_uuid: null }]\n },\n {\n uuid: 'node-3',\n actions: [\n { type: 'send_msg', uuid: 'action-3', text: 'Message 3' }\n ],\n exits: [{ uuid: 'exit-3', destination_uuid: null }]\n }\n ],\n uuid: 'test-uuid',\n type: 'messaging' as const,\n revision: 1,\n spec_version: '14.3',\n _ui: {\n nodes: {\n 'node-1': { position: { left: 100, top: 100 }, type: 'send_msg' },\n 'node-2': { position: { left: 200, top: 200 }, type: 'send_msg' },\n 'node-3': { position: { left: 300, top: 300 }, type: 'send_msg' }\n },\n languages: []\n }\n };\n\n zustand.getState().setFlowContents({\n definition: mockFlowDefinition as any,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 3, languages: 1 },\n locals: []\n }\n });\n\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n await editor.updateComplete;\n\n // get all flow nodes\n const flowNodes = editor.querySelectorAll('temba-flow-node');\n expect(flowNodes.length).to.equal(3);\n\n // first node should have flow-start class\n expect(flowNodes[0].classList.contains('flow-start')).to.be.true;\n\n // other nodes should not have flow-start class\n expect(flowNodes[1].classList.contains('flow-start')).to.be.false;\n expect(flowNodes[2].classList.contains('flow-start')).to.be.false;\n });\n\n it('should update flow-start when node positions change', async () => {\n const { zustand } = await import('../src/store/AppState');\n\n // create a flow with nodes in a specific order\n const mockFlowDefinition = {\n language: 'en',\n localization: {},\n name: 'Test Flow',\n nodes: [\n {\n uuid: 'node-1',\n actions: [\n { type: 'send_msg', uuid: 'action-1', text: 'Message 1' }\n ],\n exits: [{ uuid: 'exit-1', destination_uuid: null }]\n },\n {\n uuid: 'node-2',\n actions: [\n { type: 'send_msg', uuid: 'action-2', text: 'Message 2' }\n ],\n exits: [{ uuid: 'exit-2', destination_uuid: null }]\n }\n ],\n uuid: 'test-uuid',\n type: 'messaging' as const,\n revision: 1,\n spec_version: '14.3',\n _ui: {\n nodes: {\n 'node-1': { position: { left: 100, top: 200 }, type: 'send_msg' },\n 'node-2': { position: { left: 100, top: 100 }, type: 'send_msg' }\n },\n languages: []\n }\n };\n\n zustand.getState().setFlowContents({\n definition: mockFlowDefinition as any,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 2, languages: 1 },\n locals: []\n }\n });\n\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n await editor.updateComplete;\n\n // node-2 is at top (top: 100 < top: 200) so it should be flow-start\n const node1 = editor.querySelector('temba-flow-node[uuid=\"node-1\"]');\n const node2 = editor.querySelector('temba-flow-node[uuid=\"node-2\"]');\n\n expect(node2).to.exist;\n expect(node1).to.exist;\n expect(node2.classList.contains('flow-start')).to.be.true;\n expect(node1.classList.contains('flow-start')).to.be.false;\n\n // move node-1 to the top\n zustand.getState().updateCanvasPositions({\n 'node-1': { left: 100, top: 50 }\n });\n\n await editor.updateComplete;\n\n // now node-1 should be first\n const updatedFlowNodes = editor.querySelectorAll('temba-flow-node');\n expect(updatedFlowNodes[0].getAttribute('uuid')).to.equal('node-1');\n expect(updatedFlowNodes[0].classList.contains('flow-start')).to.be.true;\n expect(updatedFlowNodes[1].classList.contains('flow-start')).to.be.false;\n });\n\n it('should maintain flow-start when nodes are added', async () => {\n const { zustand } = await import('../src/store/AppState');\n\n // start with one node\n const mockFlowDefinition = {\n language: 'en',\n localization: {},\n name: 'Test Flow',\n nodes: [\n {\n uuid: 'node-1',\n actions: [\n { type: 'send_msg', uuid: 'action-1', text: 'Message 1' }\n ],\n exits: [{ uuid: 'exit-1', destination_uuid: null }]\n }\n ],\n uuid: 'test-uuid',\n type: 'messaging' as const,\n revision: 1,\n spec_version: '14.3',\n _ui: {\n nodes: {\n 'node-1': { position: { left: 100, top: 200 }, type: 'send_msg' }\n },\n languages: []\n }\n };\n\n zustand.getState().setFlowContents({\n definition: mockFlowDefinition as any,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 1, languages: 1 },\n locals: []\n }\n });\n\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n await editor.updateComplete;\n\n const flowNodes = editor.querySelectorAll('temba-flow-node');\n expect(flowNodes[0].classList.contains('flow-start')).to.be.true;\n\n // add a new node at the top\n const newNode = {\n uuid: 'node-2',\n actions: [\n { type: 'send_msg' as const, uuid: 'action-2', text: 'Message 2' }\n ],\n exits: [{ uuid: 'exit-2', destination_uuid: null }]\n };\n const newNodeUI = {\n position: { left: 100, top: 100 },\n type: 'send_msg' as const\n };\n\n zustand.getState().addNode(newNode, newNodeUI);\n\n await editor.updateComplete;\n\n // new node should now be the flow-start\n const node1 = editor.querySelector('temba-flow-node[uuid=\"node-1\"]');\n const node2 = editor.querySelector('temba-flow-node[uuid=\"node-2\"]');\n\n expect(node2).to.exist;\n expect(node1).to.exist;\n expect(node2.classList.contains('flow-start')).to.be.true;\n expect(node1.classList.contains('flow-start')).to.be.false;\n });\n\n it('should handle flow-start when first node is removed', async () => {\n const { zustand } = await import('../src/store/AppState');\n\n // create flow with multiple nodes\n const mockFlowDefinition = {\n language: 'en',\n localization: {},\n name: 'Test Flow',\n nodes: [\n {\n uuid: 'node-1',\n actions: [\n { type: 'send_msg', uuid: 'action-1', text: 'Message 1' }\n ],\n exits: [{ uuid: 'exit-1', destination_uuid: null }]\n },\n {\n uuid: 'node-2',\n actions: [\n { type: 'send_msg', uuid: 'action-2', text: 'Message 2' }\n ],\n exits: [{ uuid: 'exit-2', destination_uuid: null }]\n }\n ],\n uuid: 'test-uuid',\n type: 'messaging' as const,\n revision: 1,\n spec_version: '14.3',\n _ui: {\n nodes: {\n 'node-1': { position: { left: 100, top: 100 }, type: 'send_msg' },\n 'node-2': { position: { left: 100, top: 200 }, type: 'send_msg' }\n },\n languages: []\n }\n };\n\n zustand.getState().setFlowContents({\n definition: mockFlowDefinition as any,\n info: {\n results: [],\n dependencies: [],\n counts: { nodes: 2, languages: 1 },\n locals: []\n }\n });\n\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n await editor.updateComplete;\n\n let flowNodes = editor.querySelectorAll('temba-flow-node');\n expect(flowNodes[0].getAttribute('uuid')).to.equal('node-1');\n expect(flowNodes[0].classList.contains('flow-start')).to.be.true;\n\n // remove the first node\n zustand.getState().removeNodes(['node-1']);\n\n await editor.updateComplete;\n\n // node-2 should now be the flow-start\n flowNodes = editor.querySelectorAll('temba-flow-node');\n expect(flowNodes.length).to.equal(1);\n expect(flowNodes[0].getAttribute('uuid')).to.equal('node-2');\n expect(flowNodes[0].classList.contains('flow-start')).to.be.true;\n });\n });\n\n describe('save feedback', () => {\n let mockPostJSON: any;\n let storeElement: HTMLElement;\n\n before(() => {\n // Create a mock temba-store element that getStore() will find\n // Use the real zustand getState so all store interactions work\n storeElement = document.createElement('temba-store');\n (storeElement as any).getState = () => zustand.getState();\n document.body.appendChild(storeElement);\n });\n\n after(() => {\n storeElement.remove();\n });\n\n beforeEach(() => {\n mockPostJSON = stub();\n (storeElement as any).postJSON = mockPostJSON;\n });\n\n afterEach(() => {\n // Clean up any dialogs left in the DOM\n document.querySelectorAll('temba-dialog').forEach((d) => d.remove());\n });\n\n it('sets isSaving when dirtyDate changes', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n (editor as any).isSaving = false;\n\n // Simulate a dirtyDate change via updated()\n (editor as any).dirtyDate = new Date();\n const changes = new Map();\n changes.set('dirtyDate', null);\n (editor as any).updated(changes);\n\n expect((editor as any).isSaving).to.be.true;\n });\n\n it('renders save indicator with visible class when saving', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n (editor as any).canvasSize = { width: 800, height: 600 };\n (editor as any).isSaving = true;\n await editor.updateComplete;\n\n const indicator = editor.querySelector('.save-indicator');\n expect(indicator).to.exist;\n expect(indicator.classList.contains('visible')).to.be.true;\n });\n\n it('save indicator is not visible when not saving', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n (editor as any).canvasSize = { width: 800, height: 600 };\n (editor as any).isSaving = false;\n await editor.updateComplete;\n\n const indicator = editor.querySelector('.save-indicator');\n expect(indicator).to.exist;\n expect(indicator.classList.contains('visible')).to.be.false;\n });\n\n it('clears isSaving after successful save', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n editor.flow = 'test-flow';\n (editor as any).definition = { nodes: [], _ui: { nodes: {} } };\n\n mockPostJSON.resolves({\n status: 200,\n json: {},\n body: '{}',\n headers: new Headers()\n });\n\n await (editor as any).saveChanges();\n\n expect((editor as any).isSaving).to.be.false;\n });\n\n it('adds temba-components version under _ui.editor when saving', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n editor.flow = 'test-flow';\n (editor as any).definition = { nodes: [], _ui: { nodes: {} } };\n\n mockPostJSON.resolves({\n status: 200,\n json: {},\n body: '{}',\n headers: new Headers()\n });\n\n await (editor as any).saveChanges();\n\n const payload = mockPostJSON.firstCall.args[1];\n expect(payload._ui.editor).to.equal(TEMBA_COMPONENTS_VERSION);\n });\n\n it('shows error dialog on non-200 response', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n editor.flow = 'test-flow';\n (editor as any).definition = { nodes: [], _ui: { nodes: {} } };\n\n mockPostJSON.resolves({\n status: 400,\n json: { detail: 'Invalid flow definition' },\n body: '{\"detail\":\"Invalid flow definition\"}',\n headers: new Headers()\n });\n\n await (editor as any).saveChanges();\n await editor.updateComplete;\n\n expect((editor as any).isSaving).to.be.false;\n const dialog = document.querySelector('temba-dialog');\n expect(dialog).to.exist;\n expect(dialog.textContent).to.contain('Invalid flow definition');\n });\n\n it('shows error dialog on 500 server error', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n editor.flow = 'test-flow';\n (editor as any).definition = { nodes: [], _ui: { nodes: {} } };\n\n mockPostJSON.rejects(new Response(null, { status: 500 }));\n\n await (editor as any).saveChanges();\n await editor.updateComplete;\n\n expect((editor as any).isSaving).to.be.false;\n const dialog = document.querySelector('temba-dialog');\n expect(dialog).to.exist;\n expect(dialog.textContent).to.contain('Server error');\n });\n\n it('shows error dialog on network failure', async () => {\n editor = await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `);\n\n editor.flow = 'test-flow';\n (editor as any).definition = { nodes: [], _ui: { nodes: {} } };\n\n mockPostJSON.rejects(new Error('Network error'));\n\n await (editor as any).saveChanges();\n await editor.updateComplete;\n\n expect((editor as any).isSaving).to.be.false;\n const dialog = document.querySelector('temba-dialog');\n expect(dialog).to.exist;\n expect(dialog.textContent).to.contain('Unable to reach the server');\n });\n\n it('extracts error message from response json fields', () => {\n editor = new Editor();\n\n expect(\n (editor as any).extractErrorMessage({\n status: 400,\n json: { detail: 'Bad request' }\n })\n ).to.equal('Bad request');\n\n expect(\n (editor as any).extractErrorMessage({\n status: 400,\n json: { error: 'Something went wrong' }\n })\n ).to.equal('Something went wrong');\n\n expect(\n (editor as any).extractErrorMessage({\n status: 400,\n json: { description: 'Detailed error' }\n })\n ).to.equal('Detailed error');\n\n expect(\n (editor as any).extractErrorMessage({\n status: 403,\n json: {}\n })\n ).to.equal('Save failed with status 403.');\n });\n });\n});\n"]}
@@ -138,5 +138,24 @@ describe('calculateFlowchartPath', () => {
138
138
  expect(path).to.include('M 150 0');
139
139
  expect(path).to.include('L 50 100'); // ends at target
140
140
  });
141
+ it('applies jogYOffset to shift the horizontal jog level', () => {
142
+ const pathNoOffset = calculateFlowchartPath(50, 0, 150, 200, 20, 10, 5, 'top', 0);
143
+ const pathPosOffset = calculateFlowchartPath(50, 0, 150, 200, 20, 10, 5, 'top', 10);
144
+ const pathNegOffset = calculateFlowchartPath(50, 0, 150, 200, 20, 10, 5, 'top', -10);
145
+ expect(pathNoOffset).to.not.equal(pathPosOffset);
146
+ expect(pathNoOffset).to.not.equal(pathNegOffset);
147
+ expect(pathPosOffset).to.not.equal(pathNegOffset);
148
+ });
149
+ it('produces same path with jogYOffset=0 as without offset', () => {
150
+ const pathDefault = calculateFlowchartPath(50, 0, 150, 200);
151
+ const pathZero = calculateFlowchartPath(50, 0, 150, 200, 20, 10, 5, 'top', 0);
152
+ expect(pathDefault).to.equal(pathZero);
153
+ });
154
+ it('clamps jogYOffset to valid bounds', () => {
155
+ // Large positive offset should not push jogY past entryY
156
+ const path = calculateFlowchartPath(50, 0, 150, 50, 20, 10, 5, 'top', 1000);
157
+ expect(path).to.include('M 50 0');
158
+ expect(path).to.include('L 150 50'); // should still reach target
159
+ });
141
160
  });
142
161
  //# sourceMappingURL=temba-flow-plumber.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"temba-flow-plumber.test.js","sourceRoot":"","sources":["../../test/temba-flow-plumber.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { Plumber, calculateFlowchartPath } from '../src/flow/Plumber';\nimport { stub, useFakeTimers, SinonFakeTimers } from 'sinon';\n\ndescribe('Plumber', () => {\n let plumber: Plumber;\n let mockCanvas: HTMLElement;\n let clock: SinonFakeTimers;\n let mockElement: HTMLElement;\n\n beforeEach(() => {\n clock = useFakeTimers();\n\n mockCanvas = document.createElement('div');\n mockCanvas.id = 'canvas';\n document.body.appendChild(mockCanvas);\n\n mockElement = document.createElement('div');\n mockElement.id = 'test-exit';\n mockCanvas.appendChild(mockElement);\n\n const mockEditor = { fireCustomEvent: stub() };\n plumber = new Plumber(mockCanvas, mockEditor);\n });\n\n afterEach(() => {\n mockCanvas.remove();\n clock.restore();\n });\n\n describe('constructor', () => {\n it('creates a new plumber instance', () => {\n expect(plumber).to.be.instanceOf(Plumber);\n });\n });\n\n describe('makeSource', () => {\n it('registers a mousedown listener on the exit element', () => {\n const exitEl = document.createElement('div');\n exitEl.id = 'exit-1';\n mockCanvas.appendChild(exitEl);\n\n plumber.makeSource('exit-1');\n\n // Source should be tracked\n expect((plumber as any).sources.has('exit-1')).to.be.true;\n\n exitEl.remove();\n });\n\n it('cleans up previous listener when called again', () => {\n const exitEl = document.createElement('div');\n exitEl.id = 'exit-2';\n mockCanvas.appendChild(exitEl);\n\n plumber.makeSource('exit-2');\n plumber.makeSource('exit-2');\n\n expect((plumber as any).sources.has('exit-2')).to.be.true;\n\n exitEl.remove();\n });\n });\n\n describe('makeTarget', () => {\n it('is a no-op', () => {\n // Should not throw\n plumber.makeTarget('test-node');\n });\n });\n\n describe('connectIds', () => {\n it('adds connection to pending connections and processes them', () => {\n plumber.connectIds('test-node', 'test-from', 'test-to');\n expect((plumber as any).pendingConnections.length).to.equal(1);\n });\n });\n\n describe('processPendingConnections', () => {\n it('clears existing rAF when called multiple times', () => {\n const cancelSpy = stub(window, 'cancelAnimationFrame');\n const rafSpy = stub(window, 'requestAnimationFrame').returns(123 as any);\n\n plumber.processPendingConnections();\n plumber.processPendingConnections();\n\n expect(cancelSpy).to.have.been.calledOnce;\n expect(rafSpy).to.have.been.calledTwice;\n\n cancelSpy.restore();\n rafSpy.restore();\n });\n });\n\n describe('event system', () => {\n it('supports on/off/notify pattern', () => {\n let received = null;\n const handler = (info: any) => {\n received = info;\n };\n\n plumber.on('test-event', handler);\n (plumber as any).notifyListeners('test-event', { data: 'test' });\n expect(received).to.deep.equal({ data: 'test' });\n\n received = null;\n plumber.off('test-event', handler);\n (plumber as any).notifyListeners('test-event', { data: 'test2' });\n expect(received).to.be.null;\n });\n });\n\n describe('reset', () => {\n it('clears all state', () => {\n plumber.connectIds('test-node', 'test-from', 'test-to');\n plumber.reset();\n\n expect((plumber as any).pendingConnections.length).to.equal(0);\n expect((plumber as any).connections.size).to.equal(0);\n expect((plumber as any).sources.size).to.equal(0);\n });\n });\n});\n\ndescribe('calculateFlowchartPath', () => {\n it('generates a straight vertical path when source and target are aligned', () => {\n const path = calculateFlowchartPath(100, 0, 100, 100);\n expect(path).to.include('M 100 0');\n expect(path).to.include('L 100 100');\n // Should not contain Q (quadratic curve) for aligned points\n expect(path).to.not.include('Q');\n });\n\n it('generates a path with corners when source and target are offset', () => {\n const path = calculateFlowchartPath(50, 0, 150, 200);\n expect(path).to.include('M 50 0');\n expect(path).to.include('Q'); // Should have rounded corners\n expect(path).to.include('L 150 200');\n });\n\n it('handles custom stub and corner radius', () => {\n const path = calculateFlowchartPath(0, 0, 100, 100, 30, 15, 10);\n expect(path).to.include('M 0 0');\n expect(path).to.include('L 100 100');\n });\n\n it('handles cases where vertical space is tight by using reduced-radius corners', () => {\n // With stubs of 20+10=30, and only 35 total vertical space, there's only 5px for corners\n const path = calculateFlowchartPath(50, 0, 150, 35);\n expect(path).to.include('M 50 0');\n // Should still use rounded corners (L-shape with curves)\n expect(path).to.include('Q');\n });\n\n it('enforces midY is always below source exit for top face', () => {\n // Target above source — midY should not go above sourceY + stubStart\n const path = calculateFlowchartPath(50, 100, 150, 50);\n expect(path).to.include('M 50 100');\n // Should still exit downward with a curve at exitY (120)\n expect(path).to.include('Q');\n });\n\n it('generates a path entering from the left face', () => {\n const path = calculateFlowchartPath(50, 0, 150, 100, 20, 10, 5, 'left');\n expect(path).to.include('M 50 0');\n expect(path).to.include('L 150 100'); // ends at target\n });\n\n it('generates a path entering from the right face', () => {\n const path = calculateFlowchartPath(150, 0, 50, 100, 20, 10, 5, 'right');\n expect(path).to.include('M 150 0');\n expect(path).to.include('L 50 100'); // ends at target\n });\n});\n"]}
1
+ {"version":3,"file":"temba-flow-plumber.test.js","sourceRoot":"","sources":["../../test/temba-flow-plumber.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { Plumber, calculateFlowchartPath } from '../src/flow/Plumber';\nimport { stub, useFakeTimers, SinonFakeTimers } from 'sinon';\n\ndescribe('Plumber', () => {\n let plumber: Plumber;\n let mockCanvas: HTMLElement;\n let clock: SinonFakeTimers;\n let mockElement: HTMLElement;\n\n beforeEach(() => {\n clock = useFakeTimers();\n\n mockCanvas = document.createElement('div');\n mockCanvas.id = 'canvas';\n document.body.appendChild(mockCanvas);\n\n mockElement = document.createElement('div');\n mockElement.id = 'test-exit';\n mockCanvas.appendChild(mockElement);\n\n const mockEditor = { fireCustomEvent: stub() };\n plumber = new Plumber(mockCanvas, mockEditor);\n });\n\n afterEach(() => {\n mockCanvas.remove();\n clock.restore();\n });\n\n describe('constructor', () => {\n it('creates a new plumber instance', () => {\n expect(plumber).to.be.instanceOf(Plumber);\n });\n });\n\n describe('makeSource', () => {\n it('registers a mousedown listener on the exit element', () => {\n const exitEl = document.createElement('div');\n exitEl.id = 'exit-1';\n mockCanvas.appendChild(exitEl);\n\n plumber.makeSource('exit-1');\n\n // Source should be tracked\n expect((plumber as any).sources.has('exit-1')).to.be.true;\n\n exitEl.remove();\n });\n\n it('cleans up previous listener when called again', () => {\n const exitEl = document.createElement('div');\n exitEl.id = 'exit-2';\n mockCanvas.appendChild(exitEl);\n\n plumber.makeSource('exit-2');\n plumber.makeSource('exit-2');\n\n expect((plumber as any).sources.has('exit-2')).to.be.true;\n\n exitEl.remove();\n });\n });\n\n describe('makeTarget', () => {\n it('is a no-op', () => {\n // Should not throw\n plumber.makeTarget('test-node');\n });\n });\n\n describe('connectIds', () => {\n it('adds connection to pending connections and processes them', () => {\n plumber.connectIds('test-node', 'test-from', 'test-to');\n expect((plumber as any).pendingConnections.length).to.equal(1);\n });\n });\n\n describe('processPendingConnections', () => {\n it('clears existing rAF when called multiple times', () => {\n const cancelSpy = stub(window, 'cancelAnimationFrame');\n const rafSpy = stub(window, 'requestAnimationFrame').returns(123 as any);\n\n plumber.processPendingConnections();\n plumber.processPendingConnections();\n\n expect(cancelSpy).to.have.been.calledOnce;\n expect(rafSpy).to.have.been.calledTwice;\n\n cancelSpy.restore();\n rafSpy.restore();\n });\n });\n\n describe('event system', () => {\n it('supports on/off/notify pattern', () => {\n let received = null;\n const handler = (info: any) => {\n received = info;\n };\n\n plumber.on('test-event', handler);\n (plumber as any).notifyListeners('test-event', { data: 'test' });\n expect(received).to.deep.equal({ data: 'test' });\n\n received = null;\n plumber.off('test-event', handler);\n (plumber as any).notifyListeners('test-event', { data: 'test2' });\n expect(received).to.be.null;\n });\n });\n\n describe('reset', () => {\n it('clears all state', () => {\n plumber.connectIds('test-node', 'test-from', 'test-to');\n plumber.reset();\n\n expect((plumber as any).pendingConnections.length).to.equal(0);\n expect((plumber as any).connections.size).to.equal(0);\n expect((plumber as any).sources.size).to.equal(0);\n });\n });\n});\n\ndescribe('calculateFlowchartPath', () => {\n it('generates a straight vertical path when source and target are aligned', () => {\n const path = calculateFlowchartPath(100, 0, 100, 100);\n expect(path).to.include('M 100 0');\n expect(path).to.include('L 100 100');\n // Should not contain Q (quadratic curve) for aligned points\n expect(path).to.not.include('Q');\n });\n\n it('generates a path with corners when source and target are offset', () => {\n const path = calculateFlowchartPath(50, 0, 150, 200);\n expect(path).to.include('M 50 0');\n expect(path).to.include('Q'); // Should have rounded corners\n expect(path).to.include('L 150 200');\n });\n\n it('handles custom stub and corner radius', () => {\n const path = calculateFlowchartPath(0, 0, 100, 100, 30, 15, 10);\n expect(path).to.include('M 0 0');\n expect(path).to.include('L 100 100');\n });\n\n it('handles cases where vertical space is tight by using reduced-radius corners', () => {\n // With stubs of 20+10=30, and only 35 total vertical space, there's only 5px for corners\n const path = calculateFlowchartPath(50, 0, 150, 35);\n expect(path).to.include('M 50 0');\n // Should still use rounded corners (L-shape with curves)\n expect(path).to.include('Q');\n });\n\n it('enforces midY is always below source exit for top face', () => {\n // Target above source — midY should not go above sourceY + stubStart\n const path = calculateFlowchartPath(50, 100, 150, 50);\n expect(path).to.include('M 50 100');\n // Should still exit downward with a curve at exitY (120)\n expect(path).to.include('Q');\n });\n\n it('generates a path entering from the left face', () => {\n const path = calculateFlowchartPath(50, 0, 150, 100, 20, 10, 5, 'left');\n expect(path).to.include('M 50 0');\n expect(path).to.include('L 150 100'); // ends at target\n });\n\n it('generates a path entering from the right face', () => {\n const path = calculateFlowchartPath(150, 0, 50, 100, 20, 10, 5, 'right');\n expect(path).to.include('M 150 0');\n expect(path).to.include('L 50 100'); // ends at target\n });\n\n it('applies jogYOffset to shift the horizontal jog level', () => {\n const pathNoOffset = calculateFlowchartPath(\n 50,\n 0,\n 150,\n 200,\n 20,\n 10,\n 5,\n 'top',\n 0\n );\n const pathPosOffset = calculateFlowchartPath(\n 50,\n 0,\n 150,\n 200,\n 20,\n 10,\n 5,\n 'top',\n 10\n );\n const pathNegOffset = calculateFlowchartPath(\n 50,\n 0,\n 150,\n 200,\n 20,\n 10,\n 5,\n 'top',\n -10\n );\n expect(pathNoOffset).to.not.equal(pathPosOffset);\n expect(pathNoOffset).to.not.equal(pathNegOffset);\n expect(pathPosOffset).to.not.equal(pathNegOffset);\n });\n\n it('produces same path with jogYOffset=0 as without offset', () => {\n const pathDefault = calculateFlowchartPath(50, 0, 150, 200);\n const pathZero = calculateFlowchartPath(\n 50,\n 0,\n 150,\n 200,\n 20,\n 10,\n 5,\n 'top',\n 0\n );\n expect(pathDefault).to.equal(pathZero);\n });\n\n it('clamps jogYOffset to valid bounds', () => {\n // Large positive offset should not push jogY past entryY\n const path = calculateFlowchartPath(50, 0, 150, 50, 20, 10, 5, 'top', 1000);\n expect(path).to.include('M 50 0');\n expect(path).to.include('L 150 50'); // should still reach target\n });\n});\n"]}
@@ -581,7 +581,10 @@ describe('temba-select', () => {
581
581
  }));
582
582
  await openSelect(clock, select);
583
583
  await typeInto('temba-select', 're', false);
584
- await openSelect(clock, select);
584
+ // Ensure Lit has processed the input change and scheduled the debounced fetch
585
+ await select.updateComplete;
586
+ clock.runAll();
587
+ await select.updateComplete;
585
588
  assert.equal(select.visibleOptions.length, 2);
586
589
  await assertScreenshot('select/searching', getClipWithOptions(select));
587
590
  });