@nyaruka/temba-components 0.129.3 → 0.129.4
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.
- package/.eslintrc.js +1 -0
- package/.github/workflows/build.yml +135 -3
- package/CHANGELOG.md +18 -0
- package/demo/data/flows/sample-flow.json +110 -87
- package/demo/field-config-demo.html +135 -0
- package/dist/temba-components.js +1257 -675
- package/dist/temba-components.js.map +1 -1
- package/docs/ActionEditor-Migration.md +118 -0
- package/out-tsc/src/events.js.map +1 -1
- package/out-tsc/src/flow/{EditorNode.js → CanvasNode.js} +345 -42
- package/out-tsc/src/flow/CanvasNode.js.map +1 -0
- package/out-tsc/src/flow/Editor.js +107 -3
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/NodeEditor.js +1200 -0
- package/out-tsc/src/flow/NodeEditor.js.map +1 -0
- package/out-tsc/src/flow/Plumber.js +0 -6
- package/out-tsc/src/flow/Plumber.js.map +1 -1
- package/out-tsc/src/flow/actions/add_contact_groups.js +40 -0
- package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -0
- package/out-tsc/src/flow/actions/add_contact_urn.js +16 -0
- package/out-tsc/src/flow/actions/add_contact_urn.js.map +1 -0
- package/out-tsc/src/flow/actions/add_input_labels.js +11 -0
- package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -0
- package/out-tsc/src/flow/actions/call_classifier.js +11 -0
- package/out-tsc/src/flow/actions/call_classifier.js.map +1 -0
- package/out-tsc/src/flow/actions/call_llm.js +11 -0
- package/out-tsc/src/flow/actions/call_llm.js.map +1 -0
- package/out-tsc/src/flow/actions/call_resthook.js +11 -0
- package/out-tsc/src/flow/actions/call_resthook.js.map +1 -0
- package/out-tsc/src/flow/actions/call_webhook.js +122 -0
- package/out-tsc/src/flow/actions/call_webhook.js.map +1 -0
- package/out-tsc/src/flow/actions/enter_flow.js +14 -0
- package/out-tsc/src/flow/actions/enter_flow.js.map +1 -0
- package/out-tsc/src/flow/actions/open_ticket.js +11 -0
- package/out-tsc/src/flow/actions/open_ticket.js.map +1 -0
- package/out-tsc/src/flow/actions/play_audio.js +11 -0
- package/out-tsc/src/flow/actions/play_audio.js.map +1 -0
- package/out-tsc/src/flow/actions/remove_contact_groups.js +62 -0
- package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -0
- package/out-tsc/src/flow/actions/request_optin.js +11 -0
- package/out-tsc/src/flow/actions/request_optin.js.map +1 -0
- package/out-tsc/src/flow/actions/say_msg.js +11 -0
- package/out-tsc/src/flow/actions/say_msg.js.map +1 -0
- package/out-tsc/src/flow/actions/send_broadcast.js +33 -0
- package/out-tsc/src/flow/actions/send_broadcast.js.map +1 -0
- package/out-tsc/src/flow/actions/send_email.js +56 -0
- package/out-tsc/src/flow/actions/send_email.js.map +1 -0
- package/out-tsc/src/flow/actions/send_msg.js +55 -0
- package/out-tsc/src/flow/actions/send_msg.js.map +1 -0
- package/out-tsc/src/flow/actions/set_contact_channel.js +12 -0
- package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -0
- package/out-tsc/src/flow/actions/set_contact_field.js +12 -0
- package/out-tsc/src/flow/actions/set_contact_field.js.map +1 -0
- package/out-tsc/src/flow/actions/set_contact_language.js +10 -0
- package/out-tsc/src/flow/actions/set_contact_language.js.map +1 -0
- package/out-tsc/src/flow/actions/set_contact_name.js +10 -0
- package/out-tsc/src/flow/actions/set_contact_name.js.map +1 -0
- package/out-tsc/src/flow/actions/set_contact_status.js +10 -0
- package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -0
- package/out-tsc/src/flow/actions/set_run_result.js +10 -0
- package/out-tsc/src/flow/actions/set_run_result.js.map +1 -0
- package/out-tsc/src/flow/actions/split_by_expression_example.js +77 -0
- package/out-tsc/src/flow/actions/split_by_expression_example.js.map +1 -0
- package/out-tsc/src/flow/actions/start_session.js +11 -0
- package/out-tsc/src/flow/actions/start_session.js.map +1 -0
- package/out-tsc/src/flow/actions/transfer_airtime.js +11 -0
- package/out-tsc/src/flow/actions/transfer_airtime.js.map +1 -0
- package/out-tsc/src/flow/config.js +88 -193
- package/out-tsc/src/flow/config.js.map +1 -1
- package/out-tsc/src/flow/nodes/execute_actions.js +4 -0
- package/out-tsc/src/flow/nodes/execute_actions.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_airtime.js +9 -0
- package/out-tsc/src/flow/nodes/split_by_airtime.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_contact_field.js +7 -0
- package/out-tsc/src/flow/nodes/split_by_contact_field.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_expression.js +7 -0
- package/out-tsc/src/flow/nodes/split_by_expression.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_groups.js +7 -0
- package/out-tsc/src/flow/nodes/split_by_groups.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_random.js +10 -0
- package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_run_result.js +7 -0
- package/out-tsc/src/flow/nodes/split_by_run_result.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_scheme.js +7 -0
- package/out-tsc/src/flow/nodes/split_by_scheme.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_subflow.js +9 -0
- package/out-tsc/src/flow/nodes/split_by_subflow.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_webhook.js +18 -0
- package/out-tsc/src/flow/nodes/split_by_webhook.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_audio.js +7 -0
- package/out-tsc/src/flow/nodes/wait_for_audio.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_digits.js +7 -0
- package/out-tsc/src/flow/nodes/wait_for_digits.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_image.js +7 -0
- package/out-tsc/src/flow/nodes/wait_for_image.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_location.js +7 -0
- package/out-tsc/src/flow/nodes/wait_for_location.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_menu.js +7 -0
- package/out-tsc/src/flow/nodes/wait_for_menu.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_response.js +7 -0
- package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_video.js +7 -0
- package/out-tsc/src/flow/nodes/wait_for_video.js.map +1 -0
- package/out-tsc/src/flow/types.js +79 -0
- package/out-tsc/src/flow/types.js.map +1 -0
- package/out-tsc/src/flow/utils.js +65 -0
- package/out-tsc/src/flow/utils.js.map +1 -0
- package/out-tsc/src/form/ArrayEditor.js +199 -0
- package/out-tsc/src/form/ArrayEditor.js.map +1 -0
- package/out-tsc/src/form/BaseListEditor.js +128 -0
- package/out-tsc/src/form/BaseListEditor.js.map +1 -0
- package/out-tsc/src/form/Checkbox.js +17 -2
- package/out-tsc/src/form/Checkbox.js.map +1 -1
- package/out-tsc/src/form/Completion.js +6 -0
- package/out-tsc/src/form/Completion.js.map +1 -1
- package/out-tsc/src/form/FormField.js +110 -11
- package/out-tsc/src/form/FormField.js.map +1 -1
- package/out-tsc/src/form/KeyValueEditor.js +223 -0
- package/out-tsc/src/form/KeyValueEditor.js.map +1 -0
- package/out-tsc/src/form/select/Select.js +77 -32
- package/out-tsc/src/form/select/Select.js.map +1 -1
- package/out-tsc/src/interfaces.js +6 -0
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/live/ContactChat.js +2 -76
- package/out-tsc/src/live/ContactChat.js.map +1 -1
- package/out-tsc/temba-modules.js +9 -2
- package/out-tsc/temba-modules.js.map +1 -1
- package/out-tsc/test/ActionHelper.js +116 -0
- package/out-tsc/test/ActionHelper.js.map +1 -0
- package/out-tsc/test/actions/add_contact_groups.test.js +66 -0
- package/out-tsc/test/actions/add_contact_groups.test.js.map +1 -0
- package/out-tsc/test/actions/remove_contact_groups.test.js +226 -0
- package/out-tsc/test/actions/remove_contact_groups.test.js.map +1 -0
- package/out-tsc/test/actions/send_email.test.js +160 -0
- package/out-tsc/test/actions/send_email.test.js.map +1 -0
- package/out-tsc/test/actions/send_msg.test.js +95 -0
- package/out-tsc/test/actions/send_msg.test.js.map +1 -0
- package/out-tsc/test/temba-action-editing-integration.test.js +183 -0
- package/out-tsc/test/temba-action-editing-integration.test.js.map +1 -0
- package/out-tsc/test/temba-checkbox.test.js +1 -1
- package/out-tsc/test/temba-checkbox.test.js.map +1 -1
- package/out-tsc/test/temba-field-config.test.js +133 -0
- package/out-tsc/test/temba-field-config.test.js.map +1 -0
- package/out-tsc/test/temba-flow-editor-node.test.js +14 -14
- package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
- package/out-tsc/test/temba-node-editor.test.js +283 -0
- package/out-tsc/test/temba-node-editor.test.js.map +1 -0
- package/out-tsc/test/temba-select.test.js +85 -0
- package/out-tsc/test/temba-select.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/actions/add_contact_groups/editor/descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/editor/long-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/editor/many-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/editor/multiple-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/editor/single-group.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/cleanup-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/multiple-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/single-group.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
- package/screenshots/truth/actions/send_email/editor/complex-business-email.png +0 -0
- package/screenshots/truth/actions/send_email/editor/empty-body.png +0 -0
- package/screenshots/truth/actions/send_email/editor/empty-subject.png +0 -0
- package/screenshots/truth/actions/send_email/editor/long-subject.png +0 -0
- package/screenshots/truth/actions/send_email/editor/multiline-body.png +0 -0
- package/screenshots/truth/actions/send_email/editor/multiple-recipients.png +0 -0
- package/screenshots/truth/actions/send_email/editor/simple-email.png +0 -0
- package/screenshots/truth/actions/send_email/editor/with-expressions.png +0 -0
- package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
- package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
- package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
- package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
- package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
- package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
- package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
- package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/long-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
- package/screenshots/truth/editor/router.png +0 -0
- package/screenshots/truth/editor/send_msg.png +0 -0
- package/screenshots/truth/editor/set_contact_language.png +0 -0
- package/screenshots/truth/editor/set_contact_name.png +0 -0
- package/screenshots/truth/editor/set_run_result.png +0 -0
- package/screenshots/truth/editor/wait.png +0 -0
- package/screenshots/truth/formfield/markdown-errors.png +0 -0
- package/screenshots/truth/formfield/plain-text-errors.png +0 -0
- package/screenshots/truth/formfield/widget-only-markdown-errors.png +0 -0
- package/screenshots/truth/integration/checkbox-markdown-errors.png +0 -0
- package/src/events.ts +1 -40
- package/src/flow/{EditorNode.ts → CanvasNode.ts} +424 -48
- package/src/flow/Editor.ts +140 -4
- package/src/flow/NodeEditor.ts +1443 -0
- package/src/flow/Plumber.ts +0 -9
- package/src/flow/actions/add_contact_groups.ts +42 -0
- package/src/flow/actions/add_contact_urn.ts +17 -0
- package/src/flow/actions/add_input_labels.ts +12 -0
- package/src/flow/actions/call_classifier.ts +12 -0
- package/src/flow/actions/call_llm.ts +12 -0
- package/src/flow/actions/call_resthook.ts +12 -0
- package/src/flow/actions/call_webhook.ts +133 -0
- package/src/flow/actions/enter_flow.ts +15 -0
- package/src/flow/actions/open_ticket.ts +12 -0
- package/src/flow/actions/play_audio.ts +12 -0
- package/src/flow/actions/remove_contact_groups.ts +66 -0
- package/src/flow/actions/request_optin.ts +12 -0
- package/src/flow/actions/say_msg.ts +12 -0
- package/src/flow/actions/send_broadcast.ts +35 -0
- package/src/flow/actions/send_email.ts +60 -0
- package/src/flow/actions/send_msg.ts +58 -0
- package/src/flow/actions/set_contact_channel.ts +13 -0
- package/src/flow/actions/set_contact_field.ts +13 -0
- package/src/flow/actions/set_contact_language.ts +11 -0
- package/src/flow/actions/set_contact_name.ts +11 -0
- package/src/flow/actions/set_contact_status.ts +11 -0
- package/src/flow/actions/set_run_result.ts +11 -0
- package/src/flow/actions/split_by_expression_example.ts +88 -0
- package/src/flow/actions/start_session.ts +12 -0
- package/src/flow/actions/transfer_airtime.ts +12 -0
- package/src/flow/config.ts +93 -232
- package/src/flow/nodes/execute_actions.ts +5 -0
- package/src/flow/nodes/split_by_airtime.ts +9 -0
- package/src/flow/nodes/split_by_contact_field.ts +7 -0
- package/src/flow/nodes/split_by_expression.ts +7 -0
- package/src/flow/nodes/split_by_groups.ts +7 -0
- package/src/flow/nodes/split_by_random.ts +10 -0
- package/src/flow/nodes/split_by_run_result.ts +7 -0
- package/src/flow/nodes/split_by_scheme.ts +7 -0
- package/src/flow/nodes/split_by_subflow.ts +9 -0
- package/src/flow/nodes/split_by_webhook.ts +19 -0
- package/src/flow/nodes/wait_for_audio.ts +7 -0
- package/src/flow/nodes/wait_for_digits.ts +7 -0
- package/src/flow/nodes/wait_for_image.ts +7 -0
- package/src/flow/nodes/wait_for_location.ts +7 -0
- package/src/flow/nodes/wait_for_menu.ts +7 -0
- package/src/flow/nodes/wait_for_response.ts +7 -0
- package/src/flow/nodes/wait_for_video.ts +7 -0
- package/src/flow/types.ts +352 -0
- package/src/flow/utils.ts +76 -0
- package/src/form/ArrayEditor.ts +240 -0
- package/src/form/BaseListEditor.ts +177 -0
- package/src/form/Checkbox.ts +22 -3
- package/src/form/Completion.ts +6 -0
- package/src/form/FormField.ts +115 -11
- package/src/form/KeyValueEditor.ts +251 -0
- package/src/form/select/Select.ts +89 -32
- package/src/interfaces.ts +7 -2
- package/src/live/ContactChat.ts +3 -97
- package/src/store/flow-definition.d.ts +6 -1
- package/static/api/contacts.json +30 -0
- package/static/api/groups.json +4 -426
- package/static/api/locations.json +24 -0
- package/static/api/media.json +5 -0
- package/static/api/optins.json +16 -0
- package/static/api/orgs.json +13 -0
- package/static/api/topics.json +21 -0
- package/static/api/users.json +26 -0
- package/static/css/temba-components.css +3 -6
- package/temba-modules.ts +9 -2
- package/test/ActionHelper.ts +142 -0
- package/test/actions/add_contact_groups.test.ts +89 -0
- package/test/actions/remove_contact_groups.test.ts +265 -0
- package/test/actions/send_email.test.ts +214 -0
- package/test/actions/send_msg.test.ts +130 -0
- package/test/temba-action-editing-integration.test.ts +240 -0
- package/test/temba-checkbox.test.ts +1 -1
- package/test/temba-field-config.test.ts +152 -0
- package/test/temba-flow-editor-node.test.ts +18 -18
- package/test/temba-node-editor.test.ts +353 -0
- package/test/temba-select.test.ts +127 -0
- package/test-assets/contacts/history.json +11 -33
- package/web-dev-server.config.mjs +34 -0
- package/.github/workflows/coverage.yml +0 -80
- package/demo/sticky-note-demo.html +0 -155
- package/out-tsc/src/flow/EditorNode.js.map +0 -1
- package/out-tsc/src/flow/render.js +0 -358
- package/out-tsc/src/flow/render.js.map +0 -1
- package/out-tsc/test/temba-flow-render.test.js +0 -794
- package/out-tsc/test/temba-flow-render.test.js.map +0 -1
- package/src/flow/render.ts +0 -443
- package/test/temba-flow-render.test.ts +0 -1003
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { expect } from '@open-wc/testing';
|
|
2
|
+
import { send_msg } from '../../src/flow/actions/send_msg';
|
|
3
|
+
import { SendMsg } from '../../src/store/flow-definition';
|
|
4
|
+
import { ActionTest } from '../ActionHelper';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Test suite for the send_msg action configuration.
|
|
8
|
+
*/
|
|
9
|
+
describe('send_msg action config', () => {
|
|
10
|
+
const helper = new ActionTest(send_msg, 'send_msg');
|
|
11
|
+
|
|
12
|
+
describe('basic properties', () => {
|
|
13
|
+
helper.testBasicProperties();
|
|
14
|
+
|
|
15
|
+
it('has correct name', () => {
|
|
16
|
+
expect(send_msg.name).to.equal('Send Message');
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
describe('action scenarios', () => {
|
|
21
|
+
helper.testAction(
|
|
22
|
+
{
|
|
23
|
+
uuid: 'test-action-1',
|
|
24
|
+
type: 'send_msg',
|
|
25
|
+
text: 'Hello world!',
|
|
26
|
+
quick_replies: []
|
|
27
|
+
} as SendMsg,
|
|
28
|
+
'simple-text'
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
helper.testAction(
|
|
32
|
+
{
|
|
33
|
+
uuid: 'test-action-2',
|
|
34
|
+
type: 'send_msg',
|
|
35
|
+
text: 'Hello\nworld!\nHow are you?',
|
|
36
|
+
quick_replies: []
|
|
37
|
+
} as SendMsg,
|
|
38
|
+
'text-with-linebreaks'
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
helper.testAction(
|
|
42
|
+
{
|
|
43
|
+
uuid: 'test-action-3',
|
|
44
|
+
type: 'send_msg',
|
|
45
|
+
text: 'Choose an option:',
|
|
46
|
+
quick_replies: ['Yes', 'No', 'Maybe']
|
|
47
|
+
} as SendMsg,
|
|
48
|
+
'text-with-quick-replies'
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
helper.testAction(
|
|
52
|
+
{
|
|
53
|
+
uuid: 'test-action-4',
|
|
54
|
+
type: 'send_msg',
|
|
55
|
+
text: 'Rate our service:',
|
|
56
|
+
quick_replies: [
|
|
57
|
+
'⭐',
|
|
58
|
+
'⭐⭐',
|
|
59
|
+
'⭐⭐⭐',
|
|
60
|
+
'⭐⭐⭐⭐',
|
|
61
|
+
'⭐⭐⭐⭐⭐',
|
|
62
|
+
'Not applicable'
|
|
63
|
+
]
|
|
64
|
+
} as SendMsg,
|
|
65
|
+
'text-with-many-quick-replies'
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
helper.testAction(
|
|
69
|
+
{
|
|
70
|
+
uuid: 'test-action-5',
|
|
71
|
+
type: 'send_msg',
|
|
72
|
+
text: 'Welcome to our service!\n\nPlease choose from the following options:\n- Option A: Basic plan\n- Option B: Premium plan\n- Option C: Enterprise plan',
|
|
73
|
+
quick_replies: ['Basic', 'Premium', 'Enterprise']
|
|
74
|
+
} as SendMsg,
|
|
75
|
+
'multiline-text-with-replies'
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
helper.testAction(
|
|
79
|
+
{
|
|
80
|
+
uuid: 'test-action-6',
|
|
81
|
+
type: 'send_msg',
|
|
82
|
+
text: 'Which department would you like to contact?',
|
|
83
|
+
quick_replies: [
|
|
84
|
+
'Customer Support Department',
|
|
85
|
+
'Technical Support Team',
|
|
86
|
+
'Billing and Accounts Department',
|
|
87
|
+
'Sales and Marketing Division'
|
|
88
|
+
]
|
|
89
|
+
} as SendMsg,
|
|
90
|
+
'long-quick-replies'
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
helper.testAction(
|
|
94
|
+
{
|
|
95
|
+
uuid: 'test-action-7',
|
|
96
|
+
type: 'send_msg',
|
|
97
|
+
text: 'This action definition is missing quick_replies altogether.'
|
|
98
|
+
} as SendMsg,
|
|
99
|
+
'text-without-quick-replies'
|
|
100
|
+
);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe('validation edge cases', () => {
|
|
104
|
+
it('fails validation for empty text', () => {
|
|
105
|
+
const action: SendMsg = {
|
|
106
|
+
uuid: 'test-action',
|
|
107
|
+
type: 'send_msg',
|
|
108
|
+
text: '',
|
|
109
|
+
quick_replies: []
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const result = send_msg.validate(action);
|
|
113
|
+
expect(result.valid).to.be.false;
|
|
114
|
+
expect(result.errors.text).to.equal('Message text is required');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('fails validation for whitespace-only text', () => {
|
|
118
|
+
const action: SendMsg = {
|
|
119
|
+
uuid: 'test-action',
|
|
120
|
+
type: 'send_msg',
|
|
121
|
+
text: ' \n\t ',
|
|
122
|
+
quick_replies: []
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const result = send_msg.validate(action);
|
|
126
|
+
expect(result.valid).to.be.false;
|
|
127
|
+
expect(result.errors.text).to.equal('Message text is required');
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { expect, fixture, html } from '@open-wc/testing';
|
|
2
|
+
import { CanvasNode } from '../src/flow/CanvasNode';
|
|
3
|
+
import { SendMsg, Node } from '../src/store/flow-definition';
|
|
4
|
+
import { CustomEventType } from '../src/interfaces';
|
|
5
|
+
import '../temba-modules';
|
|
6
|
+
|
|
7
|
+
describe('Action Editing Integration', () => {
|
|
8
|
+
it('should handle complete action editing workflow', async () => {
|
|
9
|
+
// Create a test node with a send_msg action
|
|
10
|
+
const testNode: Node = {
|
|
11
|
+
uuid: 'test-node',
|
|
12
|
+
actions: [
|
|
13
|
+
{
|
|
14
|
+
type: 'send_msg',
|
|
15
|
+
uuid: 'test-action',
|
|
16
|
+
text: 'Hello world',
|
|
17
|
+
quick_replies: []
|
|
18
|
+
} as SendMsg
|
|
19
|
+
],
|
|
20
|
+
exits: []
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Create EditorNode
|
|
24
|
+
const editorNode: CanvasNode = await fixture(html`
|
|
25
|
+
<temba-flow-node
|
|
26
|
+
.node=${testNode}
|
|
27
|
+
.ui=${{ position: { left: 0, top: 0 } }}
|
|
28
|
+
></temba-flow-node>
|
|
29
|
+
`);
|
|
30
|
+
|
|
31
|
+
await editorNode.updateComplete;
|
|
32
|
+
|
|
33
|
+
// Verify action is rendered
|
|
34
|
+
const actionElement = editorNode.querySelector('.action');
|
|
35
|
+
expect(actionElement).to.exist;
|
|
36
|
+
|
|
37
|
+
// Set up event listener to catch ActionEditRequested event
|
|
38
|
+
let editRequestedEvent: CustomEvent | null = null;
|
|
39
|
+
editorNode.addEventListener(
|
|
40
|
+
CustomEventType.ActionEditRequested,
|
|
41
|
+
(event: CustomEvent) => {
|
|
42
|
+
editRequestedEvent = event;
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
// Simulate clicking on the action content (not the remove button)
|
|
47
|
+
const actionContent = editorNode.querySelector(
|
|
48
|
+
'.action-content'
|
|
49
|
+
) as HTMLElement;
|
|
50
|
+
expect(actionContent).to.exist;
|
|
51
|
+
|
|
52
|
+
// Simulate a click (mousedown followed by mouseup at same position)
|
|
53
|
+
const mouseDownEvent = new MouseEvent('mousedown', {
|
|
54
|
+
clientX: 100,
|
|
55
|
+
clientY: 100,
|
|
56
|
+
bubbles: true
|
|
57
|
+
});
|
|
58
|
+
const mouseUpEvent = new MouseEvent('mouseup', {
|
|
59
|
+
clientX: 100,
|
|
60
|
+
clientY: 100,
|
|
61
|
+
bubbles: true
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
actionContent.dispatchEvent(mouseDownEvent);
|
|
65
|
+
actionContent.dispatchEvent(mouseUpEvent);
|
|
66
|
+
|
|
67
|
+
// Verify event was fired
|
|
68
|
+
expect(editRequestedEvent).to.exist;
|
|
69
|
+
expect(editRequestedEvent!.detail.action).to.deep.equal(
|
|
70
|
+
testNode.actions[0]
|
|
71
|
+
);
|
|
72
|
+
expect(editRequestedEvent!.detail.nodeUuid).to.equal('test-node');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should ignore clicks on remove button', async () => {
|
|
76
|
+
// Create a test node with a send_msg action
|
|
77
|
+
const testNode: Node = {
|
|
78
|
+
uuid: 'test-node',
|
|
79
|
+
actions: [
|
|
80
|
+
{
|
|
81
|
+
type: 'send_msg',
|
|
82
|
+
uuid: 'test-action',
|
|
83
|
+
text: 'Hello world',
|
|
84
|
+
quick_replies: []
|
|
85
|
+
} as SendMsg
|
|
86
|
+
],
|
|
87
|
+
exits: []
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// Create EditorNode
|
|
91
|
+
const editorNode: CanvasNode = await fixture(html`
|
|
92
|
+
<temba-flow-node
|
|
93
|
+
.node=${testNode}
|
|
94
|
+
.ui=${{ position: { left: 0, top: 0 } }}
|
|
95
|
+
></temba-flow-node>
|
|
96
|
+
`);
|
|
97
|
+
|
|
98
|
+
await editorNode.updateComplete;
|
|
99
|
+
|
|
100
|
+
// Set up event listener to catch ActionEditRequested event
|
|
101
|
+
let editRequestedEvent: CustomEvent | null = null;
|
|
102
|
+
editorNode.addEventListener(
|
|
103
|
+
CustomEventType.ActionEditRequested,
|
|
104
|
+
(event: CustomEvent) => {
|
|
105
|
+
editRequestedEvent = event;
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
// Simulate clicking on the remove button
|
|
110
|
+
const removeButton = editorNode.querySelector(
|
|
111
|
+
'.remove-button'
|
|
112
|
+
) as HTMLElement;
|
|
113
|
+
expect(removeButton).to.exist;
|
|
114
|
+
|
|
115
|
+
removeButton.click();
|
|
116
|
+
|
|
117
|
+
// Verify NO ActionEditRequested event was fired (only remove action handling)
|
|
118
|
+
expect(editRequestedEvent).to.be.null;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('should not open action editor when dragging beyond threshold', async () => {
|
|
122
|
+
// Create a test node with a send_msg action
|
|
123
|
+
const testNode: Node = {
|
|
124
|
+
uuid: 'test-node',
|
|
125
|
+
actions: [
|
|
126
|
+
{
|
|
127
|
+
type: 'send_msg',
|
|
128
|
+
uuid: 'test-action',
|
|
129
|
+
text: 'Hello world',
|
|
130
|
+
quick_replies: []
|
|
131
|
+
} as SendMsg
|
|
132
|
+
],
|
|
133
|
+
exits: []
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// Create EditorNode
|
|
137
|
+
const editorNode: CanvasNode = await fixture(html`
|
|
138
|
+
<temba-flow-node
|
|
139
|
+
.node=${testNode}
|
|
140
|
+
.ui=${{ position: { left: 0, top: 0 } }}
|
|
141
|
+
></temba-flow-node>
|
|
142
|
+
`);
|
|
143
|
+
|
|
144
|
+
await editorNode.updateComplete;
|
|
145
|
+
|
|
146
|
+
// Set up event listener to catch ActionEditRequested event
|
|
147
|
+
let editRequestedEvent: CustomEvent | null = null;
|
|
148
|
+
editorNode.addEventListener(
|
|
149
|
+
CustomEventType.ActionEditRequested,
|
|
150
|
+
(event: CustomEvent) => {
|
|
151
|
+
editRequestedEvent = event;
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
// Simulate a drag operation (mousedown followed by mouseup at different position beyond threshold)
|
|
156
|
+
const actionContent = editorNode.querySelector(
|
|
157
|
+
'.action-content'
|
|
158
|
+
) as HTMLElement;
|
|
159
|
+
expect(actionContent).to.exist;
|
|
160
|
+
|
|
161
|
+
const mouseDownEvent = new MouseEvent('mousedown', {
|
|
162
|
+
clientX: 100,
|
|
163
|
+
clientY: 100,
|
|
164
|
+
bubbles: true
|
|
165
|
+
});
|
|
166
|
+
const mouseUpEvent = new MouseEvent('mouseup', {
|
|
167
|
+
clientX: 110, // 10 pixels away, beyond the 5 pixel threshold
|
|
168
|
+
clientY: 100,
|
|
169
|
+
bubbles: true
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
actionContent.dispatchEvent(mouseDownEvent);
|
|
173
|
+
actionContent.dispatchEvent(mouseUpEvent);
|
|
174
|
+
|
|
175
|
+
// Verify NO ActionEditRequested event was fired because we dragged beyond threshold
|
|
176
|
+
expect(editRequestedEvent).to.be.null;
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('should open action editor when clicking within threshold', async () => {
|
|
180
|
+
// Create a test node with a send_msg action
|
|
181
|
+
const testNode: Node = {
|
|
182
|
+
uuid: 'test-node',
|
|
183
|
+
actions: [
|
|
184
|
+
{
|
|
185
|
+
type: 'send_msg',
|
|
186
|
+
uuid: 'test-action',
|
|
187
|
+
text: 'Hello world',
|
|
188
|
+
quick_replies: []
|
|
189
|
+
} as SendMsg
|
|
190
|
+
],
|
|
191
|
+
exits: []
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// Create EditorNode
|
|
195
|
+
const editorNode: CanvasNode = await fixture(html`
|
|
196
|
+
<temba-flow-node
|
|
197
|
+
.node=${testNode}
|
|
198
|
+
.ui=${{ position: { left: 0, top: 0 } }}
|
|
199
|
+
></temba-flow-node>
|
|
200
|
+
`);
|
|
201
|
+
|
|
202
|
+
await editorNode.updateComplete;
|
|
203
|
+
|
|
204
|
+
// Set up event listener to catch ActionEditRequested event
|
|
205
|
+
let editRequestedEvent: CustomEvent | null = null;
|
|
206
|
+
editorNode.addEventListener(
|
|
207
|
+
CustomEventType.ActionEditRequested,
|
|
208
|
+
(event: CustomEvent) => {
|
|
209
|
+
editRequestedEvent = event;
|
|
210
|
+
}
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
// Simulate a small movement (mousedown followed by mouseup at position within threshold)
|
|
214
|
+
const actionContent = editorNode.querySelector(
|
|
215
|
+
'.action-content'
|
|
216
|
+
) as HTMLElement;
|
|
217
|
+
expect(actionContent).to.exist;
|
|
218
|
+
|
|
219
|
+
const mouseDownEvent = new MouseEvent('mousedown', {
|
|
220
|
+
clientX: 100,
|
|
221
|
+
clientY: 100,
|
|
222
|
+
bubbles: true
|
|
223
|
+
});
|
|
224
|
+
const mouseUpEvent = new MouseEvent('mouseup', {
|
|
225
|
+
clientX: 103, // 3 pixels away, within the 5 pixel threshold
|
|
226
|
+
clientY: 102, // 2 pixels away
|
|
227
|
+
bubbles: true
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
actionContent.dispatchEvent(mouseDownEvent);
|
|
231
|
+
actionContent.dispatchEvent(mouseUpEvent);
|
|
232
|
+
|
|
233
|
+
// Verify ActionEditRequested event was fired because we stayed within threshold
|
|
234
|
+
expect(editRequestedEvent).to.exist;
|
|
235
|
+
expect(editRequestedEvent!.detail.action).to.deep.equal(
|
|
236
|
+
testNode.actions[0]
|
|
237
|
+
);
|
|
238
|
+
expect(editRequestedEvent!.detail.nodeUuid).to.equal('test-node');
|
|
239
|
+
});
|
|
240
|
+
});
|
|
@@ -71,7 +71,7 @@ describe('temba-checkbox', () => {
|
|
|
71
71
|
const el: Checkbox = await fixture(html`
|
|
72
72
|
<temba-checkbox name="My Checkbox"></temba-checkbox>
|
|
73
73
|
`);
|
|
74
|
-
expect(el.label).to.equal(
|
|
74
|
+
expect(el.label).to.equal(undefined);
|
|
75
75
|
//the ".wrapper.label" style results in the background hover effect
|
|
76
76
|
const wrapperDivEl = el.shadowRoot.querySelector(
|
|
77
77
|
'div.wrapper.label'
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { html, fixture, expect } from '@open-wc/testing';
|
|
2
|
+
import '../src/form/KeyValueEditor';
|
|
3
|
+
import '../src/form/ArrayEditor';
|
|
4
|
+
|
|
5
|
+
describe('Field Configuration System', () => {
|
|
6
|
+
describe('KeyValueEditor', () => {
|
|
7
|
+
it('should render with empty value and always show one empty row', async () => {
|
|
8
|
+
const el = await fixture(html`
|
|
9
|
+
<temba-key-value-editor></temba-key-value-editor>
|
|
10
|
+
`);
|
|
11
|
+
|
|
12
|
+
expect(el).to.exist;
|
|
13
|
+
// Should always have at least one row (empty row)
|
|
14
|
+
const rows = el.shadowRoot?.querySelectorAll('.row');
|
|
15
|
+
expect(rows?.length).to.equal(1);
|
|
16
|
+
// Should not have add button anymore
|
|
17
|
+
expect(el.shadowRoot?.querySelector('.add-btn')).to.not.exist;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should render with initial values and maintain empty row', async () => {
|
|
21
|
+
const initialValue = {
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
Authorization: 'Bearer token123'
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const el = await fixture(html`
|
|
27
|
+
<temba-key-value-editor .value=${initialValue}></temba-key-value-editor>
|
|
28
|
+
`);
|
|
29
|
+
|
|
30
|
+
expect(el).to.exist;
|
|
31
|
+
// Should have 2 data rows + 1 empty row = 3 total
|
|
32
|
+
const rows = el.shadowRoot?.querySelectorAll('.row');
|
|
33
|
+
expect(rows?.length).to.equal(3);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should emit clean values without empty rows', async () => {
|
|
37
|
+
const el = await fixture(html`
|
|
38
|
+
<temba-key-value-editor></temba-key-value-editor>
|
|
39
|
+
`);
|
|
40
|
+
|
|
41
|
+
let changeEvent: any = null;
|
|
42
|
+
el.addEventListener('change', (e) => {
|
|
43
|
+
changeEvent = e;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Trigger a field change that should cause an update
|
|
47
|
+
const keyInput = el.shadowRoot?.querySelector('temba-textinput') as any;
|
|
48
|
+
if (keyInput) {
|
|
49
|
+
keyInput.value = 'test-key';
|
|
50
|
+
keyInput.dispatchEvent(new Event('change'));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
await (el as any).updateComplete;
|
|
54
|
+
|
|
55
|
+
expect(changeEvent).to.exist;
|
|
56
|
+
// Should emit the array format with key-value pairs
|
|
57
|
+
expect(changeEvent.detail.value).to.be.an('array');
|
|
58
|
+
expect(changeEvent.detail.value).to.deep.include({
|
|
59
|
+
key: 'test-key',
|
|
60
|
+
value: ''
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should hide remove button for empty rows', async () => {
|
|
65
|
+
const initialValue = {
|
|
66
|
+
'Content-Type': 'application/json'
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const el = await fixture(html`
|
|
70
|
+
<temba-key-value-editor .value=${initialValue}></temba-key-value-editor>
|
|
71
|
+
`);
|
|
72
|
+
|
|
73
|
+
expect(el).to.exist;
|
|
74
|
+
const rows = el.shadowRoot?.querySelectorAll('.row');
|
|
75
|
+
expect(rows?.length).to.equal(2); // 1 data row + 1 empty row
|
|
76
|
+
|
|
77
|
+
// First row (with data) should have remove button
|
|
78
|
+
const firstRowRemoveBtn = rows?.[0]?.querySelector('.remove-btn');
|
|
79
|
+
expect(firstRowRemoveBtn).to.exist;
|
|
80
|
+
|
|
81
|
+
// Second row (empty) should have spacer instead of remove button
|
|
82
|
+
const secondRowRemoveBtn = rows?.[1]?.querySelector('.remove-btn');
|
|
83
|
+
const secondRowSpacer = rows?.[1]?.querySelector('.remove-btn-spacer');
|
|
84
|
+
expect(secondRowRemoveBtn).to.not.exist;
|
|
85
|
+
expect(secondRowSpacer).to.exist;
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('should show remove button when empty row gets content', async () => {
|
|
89
|
+
const el = await fixture(html`
|
|
90
|
+
<temba-key-value-editor></temba-key-value-editor>
|
|
91
|
+
`);
|
|
92
|
+
|
|
93
|
+
// Initially should have no remove button (empty row)
|
|
94
|
+
let rows = el.shadowRoot?.querySelectorAll('.row');
|
|
95
|
+
expect(rows?.[0]?.querySelector('.remove-btn')).to.not.exist;
|
|
96
|
+
expect(rows?.[0]?.querySelector('.remove-btn-spacer')).to.exist;
|
|
97
|
+
|
|
98
|
+
// Simulate adding content by setting value and triggering update
|
|
99
|
+
(el as any).value = { 'test-key': '' };
|
|
100
|
+
(el as any).requestUpdate();
|
|
101
|
+
await (el as any).updateComplete;
|
|
102
|
+
|
|
103
|
+
// Now should have remove button for the row with content
|
|
104
|
+
rows = el.shadowRoot?.querySelectorAll('.row');
|
|
105
|
+
expect(rows?.length).to.equal(2); // row with content + empty row
|
|
106
|
+
expect(rows?.[0]?.querySelector('.remove-btn')).to.exist;
|
|
107
|
+
expect(rows?.[1]?.querySelector('.remove-btn-spacer')).to.exist;
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe('ArrayEditor', () => {
|
|
112
|
+
it('should render with empty array', async () => {
|
|
113
|
+
const itemConfig = {
|
|
114
|
+
name: { type: 'text', label: 'Name', required: true },
|
|
115
|
+
value: { type: 'text', label: 'Value' }
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const el = await fixture(html`
|
|
119
|
+
<temba-array-editor .itemConfig=${itemConfig}></temba-array-editor>
|
|
120
|
+
`);
|
|
121
|
+
|
|
122
|
+
await (el as any).updateComplete;
|
|
123
|
+
|
|
124
|
+
expect(el).to.exist;
|
|
125
|
+
expect(el.shadowRoot?.querySelector('.add-btn')).to.exist;
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('should render with initial items', async () => {
|
|
129
|
+
const itemConfig = {
|
|
130
|
+
operator: { type: 'text', label: 'Operator' },
|
|
131
|
+
value: { type: 'text', label: 'Value' }
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const initialValue = [
|
|
135
|
+
{ operator: 'equals', value: 'test' },
|
|
136
|
+
{ operator: 'contains', value: 'example' }
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
const el = await fixture(html`
|
|
140
|
+
<temba-array-editor
|
|
141
|
+
.value=${initialValue}
|
|
142
|
+
.itemConfig=${itemConfig}
|
|
143
|
+
itemLabel="Rule"
|
|
144
|
+
></temba-array-editor>
|
|
145
|
+
`);
|
|
146
|
+
|
|
147
|
+
expect(el).to.exist;
|
|
148
|
+
const items = el.shadowRoot?.querySelectorAll('.array-item');
|
|
149
|
+
expect(items?.length).to.equal(2);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import '../temba-modules';
|
|
2
2
|
import { html, fixture, expect } from '@open-wc/testing';
|
|
3
|
-
import {
|
|
3
|
+
import { CanvasNode } from '../src/flow/CanvasNode';
|
|
4
4
|
import {
|
|
5
5
|
Node,
|
|
6
6
|
NodeUI,
|
|
@@ -12,7 +12,7 @@ import { stub, restore, useFakeTimers } from 'sinon';
|
|
|
12
12
|
import { CustomEventType } from '../src/interfaces';
|
|
13
13
|
|
|
14
14
|
describe('EditorNode', () => {
|
|
15
|
-
let editorNode:
|
|
15
|
+
let editorNode: CanvasNode;
|
|
16
16
|
let mockPlumber: any;
|
|
17
17
|
|
|
18
18
|
beforeEach(async () => {
|
|
@@ -30,14 +30,14 @@ describe('EditorNode', () => {
|
|
|
30
30
|
|
|
31
31
|
describe('basic functionality', () => {
|
|
32
32
|
it('creates render root as element itself', () => {
|
|
33
|
-
const editorNode = new
|
|
33
|
+
const editorNode = new CanvasNode();
|
|
34
34
|
expect(editorNode.createRenderRoot()).to.equal(editorNode);
|
|
35
35
|
});
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
describe('renderAction', () => {
|
|
39
39
|
beforeEach(() => {
|
|
40
|
-
editorNode = new
|
|
40
|
+
editorNode = new CanvasNode();
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
it('renders action with known config', () => {
|
|
@@ -77,7 +77,7 @@ describe('EditorNode', () => {
|
|
|
77
77
|
|
|
78
78
|
describe('renderRouter', () => {
|
|
79
79
|
beforeEach(() => {
|
|
80
|
-
editorNode = new
|
|
80
|
+
editorNode = new CanvasNode();
|
|
81
81
|
});
|
|
82
82
|
|
|
83
83
|
it('renders router with result name', () => {
|
|
@@ -129,7 +129,7 @@ describe('EditorNode', () => {
|
|
|
129
129
|
|
|
130
130
|
describe('renderCategories', () => {
|
|
131
131
|
beforeEach(() => {
|
|
132
|
-
editorNode = new
|
|
132
|
+
editorNode = new CanvasNode();
|
|
133
133
|
});
|
|
134
134
|
|
|
135
135
|
it('returns null when no router', () => {
|
|
@@ -179,7 +179,7 @@ describe('EditorNode', () => {
|
|
|
179
179
|
|
|
180
180
|
describe('renderExit', () => {
|
|
181
181
|
beforeEach(() => {
|
|
182
|
-
editorNode = new
|
|
182
|
+
editorNode = new CanvasNode();
|
|
183
183
|
});
|
|
184
184
|
|
|
185
185
|
it('renders exit with connected class when destination exists', async () => {
|
|
@@ -214,7 +214,7 @@ describe('EditorNode', () => {
|
|
|
214
214
|
|
|
215
215
|
describe('renderTitle', () => {
|
|
216
216
|
beforeEach(() => {
|
|
217
|
-
editorNode = new
|
|
217
|
+
editorNode = new CanvasNode();
|
|
218
218
|
});
|
|
219
219
|
|
|
220
220
|
it('renders title with config color and name', async () => {
|
|
@@ -235,7 +235,7 @@ describe('EditorNode', () => {
|
|
|
235
235
|
|
|
236
236
|
describe('updated lifecycle', () => {
|
|
237
237
|
it('handles updated without node changes', () => {
|
|
238
|
-
editorNode = new
|
|
238
|
+
editorNode = new CanvasNode();
|
|
239
239
|
(editorNode as any).plumber = mockPlumber;
|
|
240
240
|
|
|
241
241
|
const changes = new Map();
|
|
@@ -250,12 +250,12 @@ describe('EditorNode', () => {
|
|
|
250
250
|
});
|
|
251
251
|
|
|
252
252
|
it('verifies updated method exists', () => {
|
|
253
|
-
editorNode = new
|
|
253
|
+
editorNode = new CanvasNode();
|
|
254
254
|
expect(typeof (editorNode as any).updated).to.equal('function');
|
|
255
255
|
});
|
|
256
256
|
|
|
257
257
|
it('processes node changes and calls plumber methods', () => {
|
|
258
|
-
editorNode = new
|
|
258
|
+
editorNode = new CanvasNode();
|
|
259
259
|
(editorNode as any).plumber = mockPlumber;
|
|
260
260
|
|
|
261
261
|
const mockNode: Node = {
|
|
@@ -321,7 +321,7 @@ describe('EditorNode', () => {
|
|
|
321
321
|
};
|
|
322
322
|
|
|
323
323
|
// Test individual render methods work
|
|
324
|
-
editorNode = new
|
|
324
|
+
editorNode = new CanvasNode();
|
|
325
325
|
|
|
326
326
|
// Test renderAction
|
|
327
327
|
const actionResult = (editorNode as any).renderAction(
|
|
@@ -343,10 +343,10 @@ describe('EditorNode', () => {
|
|
|
343
343
|
});
|
|
344
344
|
|
|
345
345
|
describe('drag and drop functionality', () => {
|
|
346
|
-
let editorNode:
|
|
346
|
+
let editorNode: CanvasNode;
|
|
347
347
|
|
|
348
348
|
beforeEach(() => {
|
|
349
|
-
editorNode = new
|
|
349
|
+
editorNode = new CanvasNode();
|
|
350
350
|
});
|
|
351
351
|
|
|
352
352
|
it('renders actions with sortable class and proper IDs', async () => {
|
|
@@ -414,7 +414,7 @@ describe('EditorNode', () => {
|
|
|
414
414
|
exits: []
|
|
415
415
|
};
|
|
416
416
|
|
|
417
|
-
let editorNode:
|
|
417
|
+
let editorNode: CanvasNode = await fixture(
|
|
418
418
|
html`<temba-flow-node
|
|
419
419
|
.node=${mockNode}
|
|
420
420
|
.ui=${{ position: { left: 0, top: 0 } }}
|
|
@@ -681,7 +681,7 @@ describe('EditorNode', () => {
|
|
|
681
681
|
|
|
682
682
|
(window as any).getStore = () => mockStore;
|
|
683
683
|
|
|
684
|
-
editorNode = new
|
|
684
|
+
editorNode = new CanvasNode();
|
|
685
685
|
(editorNode as any).plumber = mockPlumber;
|
|
686
686
|
});
|
|
687
687
|
|
|
@@ -814,12 +814,12 @@ describe('EditorNode', () => {
|
|
|
814
814
|
});
|
|
815
815
|
|
|
816
816
|
describe('action removal', () => {
|
|
817
|
-
let editorNode:
|
|
817
|
+
let editorNode: CanvasNode;
|
|
818
818
|
let mockPlumber: any;
|
|
819
819
|
let getStoreStub: any;
|
|
820
820
|
|
|
821
821
|
beforeEach(() => {
|
|
822
|
-
editorNode = new
|
|
822
|
+
editorNode = new CanvasNode();
|
|
823
823
|
|
|
824
824
|
// Mock plumber
|
|
825
825
|
mockPlumber = {
|