@nyaruka/temba-components 0.123.0 → 0.124.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/copilot-instructions.md +22 -4
- package/CHANGELOG.md +11 -0
- package/demo/drag-drop-demo.html +141 -0
- package/demo/index.html +15 -0
- package/demo/test-drag-drop.html +94 -0
- package/dist/temba-components.js +323 -191
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/fields/FieldManager.js +27 -34
- package/out-tsc/src/fields/FieldManager.js.map +1 -1
- package/out-tsc/src/list/SortableList.js +257 -60
- package/out-tsc/src/list/SortableList.js.map +1 -1
- package/out-tsc/src/omnibox/Omnibox.js +1 -1
- package/out-tsc/src/omnibox/Omnibox.js.map +1 -1
- package/out-tsc/src/select/Select.js +198 -38
- package/out-tsc/src/select/Select.js.map +1 -1
- package/out-tsc/src/webchat/WebChat.js +5 -2
- package/out-tsc/src/webchat/WebChat.js.map +1 -1
- package/out-tsc/test/temba-flow-editor-node.test.js +273 -0
- package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -0
- package/out-tsc/test/temba-flow-editor.test.js +244 -0
- package/out-tsc/test/temba-flow-editor.test.js.map +1 -0
- package/out-tsc/test/temba-flow-plumber.test.js +145 -0
- package/out-tsc/test/temba-flow-plumber.test.js.map +1 -0
- package/out-tsc/test/temba-flow-render.test.js +171 -0
- package/out-tsc/test/temba-flow-render.test.js.map +1 -0
- package/out-tsc/test/temba-omnibox.test.js +2 -3
- package/out-tsc/test/temba-omnibox.test.js.map +1 -1
- package/out-tsc/test/temba-select.test.js +134 -53
- package/out-tsc/test/temba-select.test.js.map +1 -1
- package/out-tsc/test/temba-sortable-list.test.js +91 -15
- package/out-tsc/test/temba-sortable-list.test.js.map +1 -1
- package/out-tsc/test/temba-webchat-lightbox-fix.test.js +42 -0
- package/out-tsc/test/temba-webchat-lightbox-fix.test.js.map +1 -0
- package/out-tsc/test/utils.test.js +30 -0
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/flow/editor-basic.png +0 -0
- package/screenshots/truth/list/fields-dragging.png +0 -0
- package/screenshots/truth/list/sortable-dragging.png +0 -0
- package/screenshots/truth/list/sortable-dropped.png +0 -0
- package/screenshots/truth/list/sortable.png +0 -0
- package/screenshots/truth/omnibox/selected.png +0 -0
- package/screenshots/truth/select/disabled-multi-selection.png +0 -0
- package/screenshots/truth/select/disabled-selection.png +0 -0
- package/screenshots/truth/select/disabled.png +0 -0
- package/screenshots/truth/select/embedded.png +0 -0
- package/screenshots/truth/select/empty-options.png +0 -0
- package/screenshots/truth/select/expression-selected.png +0 -0
- package/screenshots/truth/select/expressions.png +0 -0
- package/screenshots/truth/select/functions.png +0 -0
- package/screenshots/truth/select/local-options.png +0 -0
- package/screenshots/truth/select/multi-reorder-final.png +0 -0
- package/screenshots/truth/select/multi-reorder-initial.png +0 -0
- package/screenshots/truth/select/multi-with-endpoint.png +0 -0
- package/screenshots/truth/select/multiple-initial-values.png +0 -0
- package/screenshots/truth/select/remote-options.png +0 -0
- package/screenshots/truth/select/search-enabled.png +0 -0
- package/screenshots/truth/select/search-multi-no-matches.png +0 -0
- package/screenshots/truth/select/search-selected-focus.png +0 -0
- package/screenshots/truth/select/search-selected.png +0 -0
- package/screenshots/truth/select/search-with-selected.png +0 -0
- package/screenshots/truth/select/searching.png +0 -0
- package/screenshots/truth/select/selected-multi-maxitems-reached.png +0 -0
- package/screenshots/truth/select/selected-multi.png +0 -0
- package/screenshots/truth/select/selected-single.png +0 -0
- package/screenshots/truth/select/selection-clearable.png +0 -0
- package/screenshots/truth/select/static-initial-value.png +0 -0
- package/screenshots/truth/select/static-initial-via-selected.png +0 -0
- package/screenshots/truth/select/truncated-selection.png +0 -0
- package/screenshots/truth/select/with-placeholder.png +0 -0
- package/screenshots/truth/select/without-placeholder.png +0 -0
- package/screenshots/truth/templates/default.png +0 -0
- package/screenshots/truth/templates/unapproved.png +0 -0
- package/src/fields/FieldManager.ts +30 -38
- package/src/list/SortableList.ts +291 -67
- package/src/omnibox/Omnibox.ts +1 -1
- package/src/select/Select.ts +213 -42
- package/src/webchat/WebChat.ts +5 -2
- package/test/temba-flow-editor-node.test.ts +344 -0
- package/test/temba-flow-editor.test.ts +301 -0
- package/test/temba-flow-plumber.test.ts +189 -0
- package/test/temba-flow-render.test.ts +220 -0
- package/test/temba-omnibox.test.ts +2 -3
- package/test/temba-select.test.ts +180 -79
- package/test/temba-sortable-list.test.ts +108 -15
- package/test/temba-webchat-lightbox-fix.test.ts +57 -0
- package/test/utils.test.ts +52 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { html, fixture, expect } from '@open-wc/testing';
|
|
2
|
+
import { Plumber, SOURCE_DEFAULTS, TARGET_DEFAULTS } from '../src/flow/Plumber';
|
|
3
|
+
import { stub, restore } from 'sinon';
|
|
4
|
+
describe('Plumber', () => {
|
|
5
|
+
let plumber;
|
|
6
|
+
let mockJsPlumb;
|
|
7
|
+
let container;
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
// Create a container with mock elements
|
|
10
|
+
container = await fixture(html `
|
|
11
|
+
<div>
|
|
12
|
+
<div id="test-canvas"></div>
|
|
13
|
+
<div id="test-source">Source Element</div>
|
|
14
|
+
<div id="test-target">Target Element</div>
|
|
15
|
+
<div id="test-from">From Element</div>
|
|
16
|
+
<div id="test-to">To Element</div>
|
|
17
|
+
</div>
|
|
18
|
+
`);
|
|
19
|
+
const canvas = container.querySelector('#test-canvas');
|
|
20
|
+
// Mock jsPlumb functionality
|
|
21
|
+
mockJsPlumb = {
|
|
22
|
+
addEndpoint: stub().returns({ uuid: 'mock-endpoint' }),
|
|
23
|
+
connect: stub(),
|
|
24
|
+
batch: stub().callsFake((fn) => fn())
|
|
25
|
+
};
|
|
26
|
+
// Create plumber instance and replace jsPlumb
|
|
27
|
+
plumber = new Plumber(canvas);
|
|
28
|
+
// Access private property for testing
|
|
29
|
+
plumber.jsPlumb = mockJsPlumb;
|
|
30
|
+
});
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
restore();
|
|
33
|
+
});
|
|
34
|
+
describe('constructor', () => {
|
|
35
|
+
it('creates a new plumber instance', () => {
|
|
36
|
+
expect(plumber).to.be.instanceOf(Plumber);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
describe('makeTarget', () => {
|
|
40
|
+
it('creates a target endpoint for the specified element', () => {
|
|
41
|
+
plumber.makeTarget('test-target');
|
|
42
|
+
expect(mockJsPlumb.addEndpoint).to.have.been.calledWith(container.querySelector('#test-target'), TARGET_DEFAULTS);
|
|
43
|
+
});
|
|
44
|
+
it('handles non-existent elements gracefully', () => {
|
|
45
|
+
plumber.makeTarget('non-existent');
|
|
46
|
+
expect(mockJsPlumb.addEndpoint).to.have.been.calledWith(null, TARGET_DEFAULTS);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe('makeSource', () => {
|
|
50
|
+
it('creates a source endpoint for the specified element', () => {
|
|
51
|
+
plumber.makeSource('test-source');
|
|
52
|
+
expect(mockJsPlumb.addEndpoint).to.have.been.calledWith(container.querySelector('#test-source'), SOURCE_DEFAULTS);
|
|
53
|
+
});
|
|
54
|
+
it('handles non-existent elements gracefully', () => {
|
|
55
|
+
plumber.makeSource('non-existent');
|
|
56
|
+
expect(mockJsPlumb.addEndpoint).to.have.been.calledWith(null, SOURCE_DEFAULTS);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe('connectIds', () => {
|
|
60
|
+
it('adds connection to pending connections and processes them', () => {
|
|
61
|
+
plumber.connectIds('test-from', 'test-to');
|
|
62
|
+
// Verify that the method doesn't throw and plumber exists
|
|
63
|
+
expect(plumber).to.exist;
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe('processPendingConnections', () => {
|
|
67
|
+
it('processes pending connections with timeout', (done) => {
|
|
68
|
+
// Add a connection to pending connections
|
|
69
|
+
plumber.connectIds('test-from', 'test-to');
|
|
70
|
+
// Wait for the debounced timeout
|
|
71
|
+
setTimeout(() => {
|
|
72
|
+
expect(mockJsPlumb.batch).to.have.been.called;
|
|
73
|
+
done();
|
|
74
|
+
}, 60); // Wait longer than the 50ms timeout
|
|
75
|
+
});
|
|
76
|
+
it('creates endpoints and connections for pending connections', (done) => {
|
|
77
|
+
plumber.connectIds('test-from', 'test-to');
|
|
78
|
+
setTimeout(() => {
|
|
79
|
+
expect(mockJsPlumb.addEndpoint).to.have.been.called;
|
|
80
|
+
expect(mockJsPlumb.connect).to.have.been.called;
|
|
81
|
+
done();
|
|
82
|
+
}, 60);
|
|
83
|
+
});
|
|
84
|
+
it('clears existing timeout when called multiple times', () => {
|
|
85
|
+
// Call processPendingConnections directly
|
|
86
|
+
plumber.processPendingConnections();
|
|
87
|
+
plumber.processPendingConnections();
|
|
88
|
+
// This mainly tests that no errors are thrown
|
|
89
|
+
expect(plumber).to.exist;
|
|
90
|
+
});
|
|
91
|
+
it('handles empty pending connections', (done) => {
|
|
92
|
+
// Call without adding any connections
|
|
93
|
+
plumber.processPendingConnections();
|
|
94
|
+
setTimeout(() => {
|
|
95
|
+
expect(mockJsPlumb.batch).to.have.been.called;
|
|
96
|
+
done();
|
|
97
|
+
}, 60);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
describe('constants', () => {
|
|
101
|
+
it('exports SOURCE_DEFAULTS with correct structure', () => {
|
|
102
|
+
expect(SOURCE_DEFAULTS).to.have.property('endpoint');
|
|
103
|
+
expect(SOURCE_DEFAULTS.endpoint).to.have.property('type');
|
|
104
|
+
expect(SOURCE_DEFAULTS.endpoint).to.have.property('options');
|
|
105
|
+
expect(SOURCE_DEFAULTS).to.have.property('anchors');
|
|
106
|
+
expect(SOURCE_DEFAULTS).to.have.property('maxConnections', 1);
|
|
107
|
+
expect(SOURCE_DEFAULTS).to.have.property('isSource', true);
|
|
108
|
+
expect(SOURCE_DEFAULTS).to.have.property('dragAllowedWhenFull', false);
|
|
109
|
+
expect(SOURCE_DEFAULTS).to.have.property('deleteEndpointsOnEmpty', true);
|
|
110
|
+
});
|
|
111
|
+
it('exports TARGET_DEFAULTS with correct structure', () => {
|
|
112
|
+
expect(TARGET_DEFAULTS).to.have.property('endpoint');
|
|
113
|
+
expect(TARGET_DEFAULTS.endpoint).to.have.property('type');
|
|
114
|
+
expect(TARGET_DEFAULTS.endpoint).to.have.property('options');
|
|
115
|
+
expect(TARGET_DEFAULTS).to.have.property('anchor');
|
|
116
|
+
expect(TARGET_DEFAULTS).to.have.property('isTarget', true);
|
|
117
|
+
expect(TARGET_DEFAULTS).to.have.property('dragAllowedWhenFull', false);
|
|
118
|
+
expect(TARGET_DEFAULTS).to.have.property('deleteEndpointsOnEmpty', true);
|
|
119
|
+
});
|
|
120
|
+
it('has correct SOURCE_DEFAULTS endpoint options', () => {
|
|
121
|
+
const options = SOURCE_DEFAULTS.endpoint.options;
|
|
122
|
+
expect(options).to.have.property('radius', 6);
|
|
123
|
+
expect(options).to.have.property('cssClass', 'plumb-source');
|
|
124
|
+
expect(options).to.have.property('hoverClass', 'plumb-source-hover');
|
|
125
|
+
expect(options).to.have.property('connectedClass', 'plumb-connected');
|
|
126
|
+
});
|
|
127
|
+
it('has correct TARGET_DEFAULTS endpoint options', () => {
|
|
128
|
+
const options = TARGET_DEFAULTS.endpoint.options;
|
|
129
|
+
expect(options).to.have.property('width', 23);
|
|
130
|
+
expect(options).to.have.property('height', 23);
|
|
131
|
+
expect(options).to.have.property('cssClass', 'plumb-target');
|
|
132
|
+
expect(options).to.have.property('hoverClass', 'plumb-target-hover');
|
|
133
|
+
});
|
|
134
|
+
it('has correct TARGET_DEFAULTS anchor options', () => {
|
|
135
|
+
const anchor = TARGET_DEFAULTS.anchor;
|
|
136
|
+
expect(anchor).to.have.property('type', 'Continuous');
|
|
137
|
+
expect(anchor.options).to.have.property('faces');
|
|
138
|
+
expect(anchor.options.faces).to.include('top');
|
|
139
|
+
expect(anchor.options.faces).to.include('left');
|
|
140
|
+
expect(anchor.options.faces).to.include('right');
|
|
141
|
+
expect(anchor.options).to.have.property('cssClass', 'continuos plumb-target-anchor');
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
//# sourceMappingURL=temba-flow-plumber.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temba-flow-plumber.test.js","sourceRoot":"","sources":["../../test/temba-flow-plumber.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEtC,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,IAAI,OAAgB,CAAC;IACrB,IAAI,WAAgB,CAAC;IACrB,IAAI,SAAsB,CAAC;IAE3B,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,wCAAwC;QACxC,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAA;;;;;;;;KAQ7B,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,SAAS,CAAC,aAAa,CAAC,cAAc,CAAgB,CAAC;QAEtE,6BAA6B;QAC7B,WAAW,GAAG;YACZ,WAAW,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;YACtD,OAAO,EAAE,IAAI,EAAE;YACf,KAAK,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC,EAAc,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;SAClD,CAAC;QAEF,8CAA8C;QAC9C,OAAO,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9B,sCAAsC;QACrC,OAAe,CAAC,OAAO,GAAG,WAAW,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;YAC7D,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;YAElC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CACrD,SAAS,CAAC,aAAa,CAAC,cAAc,CAAC,EACvC,eAAe,CAChB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CACrD,IAAI,EACJ,eAAe,CAChB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;YAC7D,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;YAElC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CACrD,SAAS,CAAC,aAAa,CAAC,cAAc,CAAC,EACvC,eAAe,CAChB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CACrD,IAAI,EACJ,eAAe,CAChB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;YACnE,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;YAE3C,0DAA0D;YAC1D,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACzC,EAAE,CAAC,4CAA4C,EAAE,CAAC,IAAI,EAAE,EAAE;YACxD,0CAA0C;YAC1C,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;YAE3C,iCAAiC;YACjC,UAAU,CAAC,GAAG,EAAE;gBACd,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC9C,IAAI,EAAE,CAAC;YACT,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,oCAAoC;QAC9C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2DAA2D,EAAE,CAAC,IAAI,EAAE,EAAE;YACvE,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;YAE3C,UAAU,CAAC,GAAG,EAAE;gBACd,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;gBACpD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;gBAChD,IAAI,EAAE,CAAC;YACT,CAAC,EAAE,EAAE,CAAC,CAAC;QACT,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,0CAA0C;YAC1C,OAAO,CAAC,yBAAyB,EAAE,CAAC;YACpC,OAAO,CAAC,yBAAyB,EAAE,CAAC;YAEpC,8CAA8C;YAC9C,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,CAAC,IAAI,EAAE,EAAE;YAC/C,sCAAsC;YACtC,OAAO,CAAC,yBAAyB,EAAE,CAAC;YAEpC,UAAU,CAAC,GAAG,EAAE;gBACd,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC9C,IAAI,EAAE,CAAC;YACT,CAAC,EAAE,EAAE,CAAC,CAAC;QACT,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;QACzB,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACrD,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC1D,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC7D,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACpD,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;YAC9D,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAC3D,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;YACvE,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,wBAAwB,EAAE,IAAI,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACrD,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC1D,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC7D,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACnD,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAC3D,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;YACvE,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,wBAAwB,EAAE,IAAI,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC;YACjD,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YAC9C,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;YAC7D,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC;YACrE,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC;YACjD,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC9C,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAC/C,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;YAC7D,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC;YACtC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;YACtD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACjD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAChD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACjD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CACrC,UAAU,EACV,+BAA+B,CAChC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { html, fixture, expect } from '@open-wc/testing';\nimport { Plumber, SOURCE_DEFAULTS, TARGET_DEFAULTS } from '../src/flow/Plumber';\nimport { stub, restore } from 'sinon';\n\ndescribe('Plumber', () => {\n let plumber: Plumber;\n let mockJsPlumb: any;\n let container: HTMLElement;\n\n beforeEach(async () => {\n // Create a container with mock elements\n container = await fixture(html`\n <div>\n <div id=\"test-canvas\"></div>\n <div id=\"test-source\">Source Element</div>\n <div id=\"test-target\">Target Element</div>\n <div id=\"test-from\">From Element</div>\n <div id=\"test-to\">To Element</div>\n </div>\n `);\n\n const canvas = container.querySelector('#test-canvas') as HTMLElement;\n\n // Mock jsPlumb functionality\n mockJsPlumb = {\n addEndpoint: stub().returns({ uuid: 'mock-endpoint' }),\n connect: stub(),\n batch: stub().callsFake((fn: () => void) => fn())\n };\n\n // Create plumber instance and replace jsPlumb\n plumber = new Plumber(canvas);\n // Access private property for testing\n (plumber as any).jsPlumb = mockJsPlumb;\n });\n\n afterEach(() => {\n 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('makeTarget', () => {\n it('creates a target endpoint for the specified element', () => {\n plumber.makeTarget('test-target');\n\n expect(mockJsPlumb.addEndpoint).to.have.been.calledWith(\n container.querySelector('#test-target'),\n TARGET_DEFAULTS\n );\n });\n\n it('handles non-existent elements gracefully', () => {\n plumber.makeTarget('non-existent');\n\n expect(mockJsPlumb.addEndpoint).to.have.been.calledWith(\n null,\n TARGET_DEFAULTS\n );\n });\n });\n\n describe('makeSource', () => {\n it('creates a source endpoint for the specified element', () => {\n plumber.makeSource('test-source');\n\n expect(mockJsPlumb.addEndpoint).to.have.been.calledWith(\n container.querySelector('#test-source'),\n SOURCE_DEFAULTS\n );\n });\n\n it('handles non-existent elements gracefully', () => {\n plumber.makeSource('non-existent');\n\n expect(mockJsPlumb.addEndpoint).to.have.been.calledWith(\n null,\n SOURCE_DEFAULTS\n );\n });\n });\n\n describe('connectIds', () => {\n it('adds connection to pending connections and processes them', () => {\n plumber.connectIds('test-from', 'test-to');\n\n // Verify that the method doesn't throw and plumber exists\n expect(plumber).to.exist;\n });\n });\n\n describe('processPendingConnections', () => {\n it('processes pending connections with timeout', (done) => {\n // Add a connection to pending connections\n plumber.connectIds('test-from', 'test-to');\n\n // Wait for the debounced timeout\n setTimeout(() => {\n expect(mockJsPlumb.batch).to.have.been.called;\n done();\n }, 60); // Wait longer than the 50ms timeout\n });\n\n it('creates endpoints and connections for pending connections', (done) => {\n plumber.connectIds('test-from', 'test-to');\n\n setTimeout(() => {\n expect(mockJsPlumb.addEndpoint).to.have.been.called;\n expect(mockJsPlumb.connect).to.have.been.called;\n done();\n }, 60);\n });\n\n it('clears existing timeout when called multiple times', () => {\n // Call processPendingConnections directly\n plumber.processPendingConnections();\n plumber.processPendingConnections();\n\n // This mainly tests that no errors are thrown\n expect(plumber).to.exist;\n });\n\n it('handles empty pending connections', (done) => {\n // Call without adding any connections\n plumber.processPendingConnections();\n\n setTimeout(() => {\n expect(mockJsPlumb.batch).to.have.been.called;\n done();\n }, 60);\n });\n });\n\n describe('constants', () => {\n it('exports SOURCE_DEFAULTS with correct structure', () => {\n expect(SOURCE_DEFAULTS).to.have.property('endpoint');\n expect(SOURCE_DEFAULTS.endpoint).to.have.property('type');\n expect(SOURCE_DEFAULTS.endpoint).to.have.property('options');\n expect(SOURCE_DEFAULTS).to.have.property('anchors');\n expect(SOURCE_DEFAULTS).to.have.property('maxConnections', 1);\n expect(SOURCE_DEFAULTS).to.have.property('isSource', true);\n expect(SOURCE_DEFAULTS).to.have.property('dragAllowedWhenFull', false);\n expect(SOURCE_DEFAULTS).to.have.property('deleteEndpointsOnEmpty', true);\n });\n\n it('exports TARGET_DEFAULTS with correct structure', () => {\n expect(TARGET_DEFAULTS).to.have.property('endpoint');\n expect(TARGET_DEFAULTS.endpoint).to.have.property('type');\n expect(TARGET_DEFAULTS.endpoint).to.have.property('options');\n expect(TARGET_DEFAULTS).to.have.property('anchor');\n expect(TARGET_DEFAULTS).to.have.property('isTarget', true);\n expect(TARGET_DEFAULTS).to.have.property('dragAllowedWhenFull', false);\n expect(TARGET_DEFAULTS).to.have.property('deleteEndpointsOnEmpty', true);\n });\n\n it('has correct SOURCE_DEFAULTS endpoint options', () => {\n const options = SOURCE_DEFAULTS.endpoint.options;\n expect(options).to.have.property('radius', 6);\n expect(options).to.have.property('cssClass', 'plumb-source');\n expect(options).to.have.property('hoverClass', 'plumb-source-hover');\n expect(options).to.have.property('connectedClass', 'plumb-connected');\n });\n\n it('has correct TARGET_DEFAULTS endpoint options', () => {\n const options = TARGET_DEFAULTS.endpoint.options;\n expect(options).to.have.property('width', 23);\n expect(options).to.have.property('height', 23);\n expect(options).to.have.property('cssClass', 'plumb-target');\n expect(options).to.have.property('hoverClass', 'plumb-target-hover');\n });\n\n it('has correct TARGET_DEFAULTS anchor options', () => {\n const anchor = TARGET_DEFAULTS.anchor;\n expect(anchor).to.have.property('type', 'Continuous');\n expect(anchor.options).to.have.property('faces');\n expect(anchor.options.faces).to.include('top');\n expect(anchor.options.faces).to.include('left');\n expect(anchor.options.faces).to.include('right');\n expect(anchor.options).to.have.property(\n 'cssClass',\n 'continuos plumb-target-anchor'\n );\n });\n });\n});\n"]}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { html, fixture, expect } from '@open-wc/testing';
|
|
2
|
+
import { renderSendMsg, renderSetContactName, renderSetRunResult, renderCallWebhook, renderAddToGroups } from '../src/flow/render';
|
|
3
|
+
describe('Flow Render Functions', () => {
|
|
4
|
+
const mockNode = {
|
|
5
|
+
uuid: 'test-node-uuid',
|
|
6
|
+
actions: [],
|
|
7
|
+
exits: []
|
|
8
|
+
};
|
|
9
|
+
describe('renderSendMsg', () => {
|
|
10
|
+
it('renders message text with line breaks', async () => {
|
|
11
|
+
const action = {
|
|
12
|
+
type: 'send_msg',
|
|
13
|
+
uuid: 'action-uuid-1',
|
|
14
|
+
text: 'Hello world\nThis is a new line',
|
|
15
|
+
quick_replies: []
|
|
16
|
+
};
|
|
17
|
+
const result = renderSendMsg(mockNode, action);
|
|
18
|
+
const container = await fixture(html `<div>${result}</div>`);
|
|
19
|
+
expect(container.innerHTML).to.contain('Hello world<br>This is a new line');
|
|
20
|
+
});
|
|
21
|
+
it('renders quick replies when present', async () => {
|
|
22
|
+
const action = {
|
|
23
|
+
type: 'send_msg',
|
|
24
|
+
uuid: 'action-uuid-2',
|
|
25
|
+
text: 'Choose an option:',
|
|
26
|
+
quick_replies: ['Yes', 'No', 'Maybe']
|
|
27
|
+
};
|
|
28
|
+
const result = renderSendMsg(mockNode, action);
|
|
29
|
+
const container = await fixture(html `<div>${result}</div>`);
|
|
30
|
+
expect(container.innerHTML).to.contain('Choose an option:');
|
|
31
|
+
expect(container.innerHTML).to.contain('quick-replies');
|
|
32
|
+
expect(container.innerHTML).to.contain('Yes');
|
|
33
|
+
expect(container.innerHTML).to.contain('No');
|
|
34
|
+
expect(container.innerHTML).to.contain('Maybe');
|
|
35
|
+
});
|
|
36
|
+
it('renders without quick replies when none provided', async () => {
|
|
37
|
+
const action = {
|
|
38
|
+
type: 'send_msg',
|
|
39
|
+
uuid: 'action-uuid-3',
|
|
40
|
+
text: 'Simple message',
|
|
41
|
+
quick_replies: []
|
|
42
|
+
};
|
|
43
|
+
const result = renderSendMsg(mockNode, action);
|
|
44
|
+
const container = await fixture(html `<div>${result}</div>`);
|
|
45
|
+
expect(container.innerHTML).to.contain('Simple message');
|
|
46
|
+
expect(container.innerHTML).to.not.contain('quick-replies');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe('renderSetContactName', () => {
|
|
50
|
+
it('renders contact name setting', async () => {
|
|
51
|
+
const action = {
|
|
52
|
+
type: 'set_contact_name',
|
|
53
|
+
uuid: 'action-uuid-4',
|
|
54
|
+
name: 'John Doe'
|
|
55
|
+
};
|
|
56
|
+
const result = renderSetContactName(mockNode, action);
|
|
57
|
+
const container = await fixture(html `<div>${result}</div>`);
|
|
58
|
+
expect(container.textContent).to.contain('Set contact name to');
|
|
59
|
+
expect(container.textContent).to.contain('John Doe');
|
|
60
|
+
expect(container.querySelector('b')).to.exist;
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
describe('renderSetRunResult', () => {
|
|
64
|
+
it('renders run result setting', async () => {
|
|
65
|
+
const action = {
|
|
66
|
+
type: 'set_run_result',
|
|
67
|
+
uuid: 'action-uuid-5',
|
|
68
|
+
category: 'success',
|
|
69
|
+
name: 'favorite_color',
|
|
70
|
+
value: 'blue'
|
|
71
|
+
};
|
|
72
|
+
const result = renderSetRunResult(mockNode, action);
|
|
73
|
+
const container = await fixture(html `<div>${result}</div>`);
|
|
74
|
+
expect(container.textContent).to.contain('Save blue as');
|
|
75
|
+
expect(container.textContent).to.contain('favorite_color');
|
|
76
|
+
expect(container.querySelector('b')).to.exist;
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
describe('renderCallWebhook', () => {
|
|
80
|
+
it('renders webhook URL', async () => {
|
|
81
|
+
const action = {
|
|
82
|
+
type: 'call_webhook',
|
|
83
|
+
uuid: 'action-uuid-6',
|
|
84
|
+
url: 'https://example.com/webhook'
|
|
85
|
+
};
|
|
86
|
+
const result = renderCallWebhook(mockNode, action);
|
|
87
|
+
const container = await fixture(html `<div>${result}</div>`);
|
|
88
|
+
expect(container.innerHTML).to.contain('https://example.com/webhook');
|
|
89
|
+
expect(container.querySelector('div')).to.have.style('word-break', 'break-all');
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
describe('renderAddToGroups', () => {
|
|
93
|
+
it('renders groups with icons', async () => {
|
|
94
|
+
const action = {
|
|
95
|
+
type: 'add_contact_groups',
|
|
96
|
+
uuid: 'action-uuid-7',
|
|
97
|
+
groups: [
|
|
98
|
+
{
|
|
99
|
+
uuid: 'group1',
|
|
100
|
+
name: 'VIP Customers',
|
|
101
|
+
status: 'active',
|
|
102
|
+
system: false,
|
|
103
|
+
query: '',
|
|
104
|
+
count: 10
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
uuid: 'group2',
|
|
108
|
+
name: 'Newsletter Subscribers',
|
|
109
|
+
status: 'active',
|
|
110
|
+
system: false,
|
|
111
|
+
query: '',
|
|
112
|
+
count: 25
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
};
|
|
116
|
+
const result = renderAddToGroups(mockNode, action);
|
|
117
|
+
const container = await fixture(html `<div>${result}</div>`);
|
|
118
|
+
expect(container.innerHTML).to.contain('VIP Customers');
|
|
119
|
+
expect(container.innerHTML).to.contain('Newsletter Subscribers');
|
|
120
|
+
expect(container.querySelectorAll('temba-icon')).to.have.length(2);
|
|
121
|
+
const icons = container.querySelectorAll('temba-icon');
|
|
122
|
+
icons.forEach((icon) => {
|
|
123
|
+
expect(icon.getAttribute('name')).to.equal('group');
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
it('renders empty groups array', async () => {
|
|
127
|
+
const action = {
|
|
128
|
+
type: 'add_contact_groups',
|
|
129
|
+
uuid: 'action-uuid-8',
|
|
130
|
+
groups: []
|
|
131
|
+
};
|
|
132
|
+
const result = renderAddToGroups(mockNode, action);
|
|
133
|
+
const container = await fixture(html `<div>${result}</div>`);
|
|
134
|
+
expect(container.querySelectorAll('temba-icon')).to.have.length(0);
|
|
135
|
+
});
|
|
136
|
+
it('renders groups without icons when undefined', async () => {
|
|
137
|
+
// Test the renderNamedObjects function without an icon parameter
|
|
138
|
+
const action = {
|
|
139
|
+
type: 'add_contact_groups',
|
|
140
|
+
uuid: 'action-uuid-9',
|
|
141
|
+
groups: [
|
|
142
|
+
{
|
|
143
|
+
uuid: 'group1',
|
|
144
|
+
name: 'Test Group',
|
|
145
|
+
status: 'active',
|
|
146
|
+
system: false,
|
|
147
|
+
query: '',
|
|
148
|
+
count: 5
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
};
|
|
152
|
+
// Create a test version that calls renderNamedObjects without icon
|
|
153
|
+
// to cover the null case in the render.ts file
|
|
154
|
+
const namedObjects = action.groups;
|
|
155
|
+
// Create a test version that calls renderNamedObjects without icon
|
|
156
|
+
const testRender = (assets) => {
|
|
157
|
+
return assets.map((asset) => {
|
|
158
|
+
return html `<div style="display:flex;items-align:center">
|
|
159
|
+
${null /* This should trigger the null branch */}
|
|
160
|
+
<div>${asset.name}</div>
|
|
161
|
+
</div>`;
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
const result = testRender(namedObjects);
|
|
165
|
+
const container = await fixture(html `<div>${result}</div>`);
|
|
166
|
+
expect(container.innerHTML).to.contain('Test Group');
|
|
167
|
+
expect(container.querySelectorAll('temba-icon')).to.have.length(0);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
//# sourceMappingURL=temba-flow-render.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temba-flow-render.test.js","sourceRoot":"","sources":["../../test/temba-flow-render.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAU5B,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,MAAM,QAAQ,GAAS;QACrB,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,EAAE;QACX,KAAK,EAAE,EAAE;KACV,CAAC;IAEF,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;YACrD,MAAM,MAAM,GAAY;gBACtB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE,iCAAiC;gBACvC,aAAa,EAAE,EAAE;aAClB,CAAC;YAEF,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC/C,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAA,QAAQ,MAAM,QAAQ,CAAC,CAAC;YAE5D,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CACpC,mCAAmC,CACpC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;YAClD,MAAM,MAAM,GAAY;gBACtB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE,mBAAmB;gBACzB,aAAa,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC;aACtC,CAAC;YAEF,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC/C,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAA,QAAQ,MAAM,QAAQ,CAAC,CAAC;YAE5D,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;YAC5D,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YACxD,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC9C,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC7C,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAChE,MAAM,MAAM,GAAY;gBACtB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE,gBAAgB;gBACtB,aAAa,EAAE,EAAE;aAClB,CAAC;YAEF,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC/C,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAA,QAAQ,MAAM,QAAQ,CAAC,CAAC;YAE5D,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;YACzD,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;YAC5C,MAAM,MAAM,GAAmB;gBAC7B,IAAI,EAAE,kBAAkB;gBACxB,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE,UAAU;aACjB,CAAC;YAEF,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACtD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAA,QAAQ,MAAM,QAAQ,CAAC,CAAC;YAE5D,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;YAChE,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YACrD,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;YAC1C,MAAM,MAAM,GAAiB;gBAC3B,IAAI,EAAE,gBAAgB;gBACtB,IAAI,EAAE,eAAe;gBACrB,QAAQ,EAAE,SAAS;gBACnB,IAAI,EAAE,gBAAgB;gBACtB,KAAK,EAAE,MAAM;aACd,CAAC;YAEF,MAAM,MAAM,GAAG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACpD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAA,QAAQ,MAAM,QAAQ,CAAC,CAAC;YAE5D,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YACzD,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;YAC3D,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;YACnC,MAAM,MAAM,GAAgB;gBAC1B,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,eAAe;gBACrB,GAAG,EAAE,6BAA6B;aACnC,CAAC;YAEF,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACnD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAA,QAAQ,MAAM,QAAQ,CAAC,CAAC;YAE5D,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;YACtE,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAClD,YAAY,EACZ,WAAW,CACZ,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;YACzC,MAAM,MAAM,GAAe;gBACzB,IAAI,EAAE,oBAAoB;gBAC1B,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE;oBACN;wBACE,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,eAAe;wBACrB,MAAM,EAAE,QAAQ;wBAChB,MAAM,EAAE,KAAK;wBACb,KAAK,EAAE,EAAE;wBACT,KAAK,EAAE,EAAE;qBACV;oBACD;wBACE,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,wBAAwB;wBAC9B,MAAM,EAAE,QAAQ;wBAChB,MAAM,EAAE,KAAK;wBACb,KAAK,EAAE,EAAE;wBACT,KAAK,EAAE,EAAE;qBACV;iBACF;aACF,CAAC;YAEF,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACnD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAA,QAAQ,MAAM,QAAQ,CAAC,CAAC;YAE5D,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YACxD,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;YACjE,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAEnE,MAAM,KAAK,GAAG,SAAS,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;YACvD,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;gBACrB,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACtD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;YAC1C,MAAM,MAAM,GAAe;gBACzB,IAAI,EAAE,oBAAoB;gBAC1B,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,EAAE;aACX,CAAC;YAEF,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACnD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAA,QAAQ,MAAM,QAAQ,CAAC,CAAC;YAE5D,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,iEAAiE;YACjE,MAAM,MAAM,GAAe;gBACzB,IAAI,EAAE,oBAAoB;gBAC1B,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE;oBACN;wBACE,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,YAAY;wBAClB,MAAM,EAAE,QAAQ;wBAChB,MAAM,EAAE,KAAK;wBACb,KAAK,EAAE,EAAE;wBACT,KAAK,EAAE,CAAC;qBACT;iBACF;aACF,CAAC;YAEF,mEAAmE;YACnE,+CAA+C;YAC/C,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;YAEnC,mEAAmE;YACnE,MAAM,UAAU,GAAG,CAAC,MAAa,EAAE,EAAE;gBACnC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC1B,OAAO,IAAI,CAAA;cACP,IAAI,CAAC,yCAAyC;mBACzC,KAAK,CAAC,IAAI;iBACZ,CAAC;gBACV,CAAC,CAAC,CAAC;YACL,CAAC,CAAC;YAEF,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;YACxC,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAA,QAAQ,MAAM,QAAQ,CAAC,CAAC;YAE5D,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YACrD,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { html, fixture, expect } from '@open-wc/testing';\nimport {\n renderSendMsg,\n renderSetContactName,\n renderSetRunResult,\n renderCallWebhook,\n renderAddToGroups\n} from '../src/flow/render';\nimport {\n Node,\n SendMsg,\n SetContactName,\n SetRunResult,\n CallWebhook,\n AddToGroup\n} from '../src/store/flow-definition.d';\n\ndescribe('Flow Render Functions', () => {\n const mockNode: Node = {\n uuid: 'test-node-uuid',\n actions: [],\n exits: []\n };\n\n describe('renderSendMsg', () => {\n it('renders message text with line breaks', async () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-uuid-1',\n text: 'Hello world\\nThis is a new line',\n quick_replies: []\n };\n\n const result = renderSendMsg(mockNode, action);\n const container = await fixture(html`<div>${result}</div>`);\n\n expect(container.innerHTML).to.contain(\n 'Hello world<br>This is a new line'\n );\n });\n\n it('renders quick replies when present', async () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-uuid-2',\n text: 'Choose an option:',\n quick_replies: ['Yes', 'No', 'Maybe']\n };\n\n const result = renderSendMsg(mockNode, action);\n const container = await fixture(html`<div>${result}</div>`);\n\n expect(container.innerHTML).to.contain('Choose an option:');\n expect(container.innerHTML).to.contain('quick-replies');\n expect(container.innerHTML).to.contain('Yes');\n expect(container.innerHTML).to.contain('No');\n expect(container.innerHTML).to.contain('Maybe');\n });\n\n it('renders without quick replies when none provided', async () => {\n const action: SendMsg = {\n type: 'send_msg',\n uuid: 'action-uuid-3',\n text: 'Simple message',\n quick_replies: []\n };\n\n const result = renderSendMsg(mockNode, action);\n const container = await fixture(html`<div>${result}</div>`);\n\n expect(container.innerHTML).to.contain('Simple message');\n expect(container.innerHTML).to.not.contain('quick-replies');\n });\n });\n\n describe('renderSetContactName', () => {\n it('renders contact name setting', async () => {\n const action: SetContactName = {\n type: 'set_contact_name',\n uuid: 'action-uuid-4',\n name: 'John Doe'\n };\n\n const result = renderSetContactName(mockNode, action);\n const container = await fixture(html`<div>${result}</div>`);\n\n expect(container.textContent).to.contain('Set contact name to');\n expect(container.textContent).to.contain('John Doe');\n expect(container.querySelector('b')).to.exist;\n });\n });\n\n describe('renderSetRunResult', () => {\n it('renders run result setting', async () => {\n const action: SetRunResult = {\n type: 'set_run_result',\n uuid: 'action-uuid-5',\n category: 'success',\n name: 'favorite_color',\n value: 'blue'\n };\n\n const result = renderSetRunResult(mockNode, action);\n const container = await fixture(html`<div>${result}</div>`);\n\n expect(container.textContent).to.contain('Save blue as');\n expect(container.textContent).to.contain('favorite_color');\n expect(container.querySelector('b')).to.exist;\n });\n });\n\n describe('renderCallWebhook', () => {\n it('renders webhook URL', async () => {\n const action: CallWebhook = {\n type: 'call_webhook',\n uuid: 'action-uuid-6',\n url: 'https://example.com/webhook'\n };\n\n const result = renderCallWebhook(mockNode, action);\n const container = await fixture(html`<div>${result}</div>`);\n\n expect(container.innerHTML).to.contain('https://example.com/webhook');\n expect(container.querySelector('div')).to.have.style(\n 'word-break',\n 'break-all'\n );\n });\n });\n\n describe('renderAddToGroups', () => {\n it('renders groups with icons', async () => {\n const action: AddToGroup = {\n type: 'add_contact_groups',\n uuid: 'action-uuid-7',\n groups: [\n {\n uuid: 'group1',\n name: 'VIP Customers',\n status: 'active',\n system: false,\n query: '',\n count: 10\n },\n {\n uuid: 'group2',\n name: 'Newsletter Subscribers',\n status: 'active',\n system: false,\n query: '',\n count: 25\n }\n ]\n };\n\n const result = renderAddToGroups(mockNode, action);\n const container = await fixture(html`<div>${result}</div>`);\n\n expect(container.innerHTML).to.contain('VIP Customers');\n expect(container.innerHTML).to.contain('Newsletter Subscribers');\n expect(container.querySelectorAll('temba-icon')).to.have.length(2);\n\n const icons = container.querySelectorAll('temba-icon');\n icons.forEach((icon) => {\n expect(icon.getAttribute('name')).to.equal('group');\n });\n });\n\n it('renders empty groups array', async () => {\n const action: AddToGroup = {\n type: 'add_contact_groups',\n uuid: 'action-uuid-8',\n groups: []\n };\n\n const result = renderAddToGroups(mockNode, action);\n const container = await fixture(html`<div>${result}</div>`);\n\n expect(container.querySelectorAll('temba-icon')).to.have.length(0);\n });\n\n it('renders groups without icons when undefined', async () => {\n // Test the renderNamedObjects function without an icon parameter\n const action: AddToGroup = {\n type: 'add_contact_groups',\n uuid: 'action-uuid-9',\n groups: [\n {\n uuid: 'group1',\n name: 'Test Group',\n status: 'active',\n system: false,\n query: '',\n count: 5\n }\n ]\n };\n\n // Create a test version that calls renderNamedObjects without icon\n // to cover the null case in the render.ts file\n const namedObjects = action.groups;\n\n // Create a test version that calls renderNamedObjects without icon\n const testRender = (assets: any[]) => {\n return assets.map((asset) => {\n return html`<div style=\"display:flex;items-align:center\">\n ${null /* This should trigger the null branch */}\n <div>${asset.name}</div>\n </div>`;\n });\n };\n\n const result = testRender(namedObjects);\n const container = await fixture(html`<div>${result}</div>`);\n\n expect(container.innerHTML).to.contain('Test Group');\n expect(container.querySelectorAll('temba-icon')).to.have.length(0);\n });\n });\n});\n"]}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { fixture, assert } from '@open-wc/testing';
|
|
2
2
|
import { Omnibox } from '../src/omnibox/Omnibox';
|
|
3
|
-
import { assertScreenshot, getClip } from './utils.test';
|
|
4
|
-
import { openAndClick } from './temba-select.test';
|
|
3
|
+
import { assertScreenshot, getClip, openAndClick } from './utils.test';
|
|
5
4
|
import { useFakeTimers, spy } from 'sinon';
|
|
6
5
|
export const getHTML = (attrs = { name: 'recipients' }) => {
|
|
7
6
|
const selectHTML = `
|
|
@@ -19,7 +18,7 @@ export const getHTML = (attrs = { name: 'recipients' }) => {
|
|
|
19
18
|
};
|
|
20
19
|
export const createOmnibox = async (clock, attrs = {}) => {
|
|
21
20
|
const parentNode = document.createElement('div');
|
|
22
|
-
parentNode.setAttribute('style', 'width:
|
|
21
|
+
parentNode.setAttribute('style', 'width: 400px;');
|
|
23
22
|
const omnibox = await fixture(getHTML(attrs), { parentNode });
|
|
24
23
|
clock.runAll();
|
|
25
24
|
await omnibox.updateComplete;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"temba-omnibox.test.js","sourceRoot":"","sources":["../../test/temba-omnibox.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"temba-omnibox.test.js","sourceRoot":"","sources":["../../test/temba-omnibox.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,QAAa,EAAE,IAAI,EAAE,YAAY,EAAE,EAAU,EAAE;IACrE,MAAM,UAAU,GAAG;kBACH,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;SAC/B,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE;QACpB,mCAAmC;QACnC,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;YACpC,OAAO,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC;QAC7D,CAAC;QACD,OAAO,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;IACrC,CAAC,CAAC;SACD,IAAI,CAAC,GAAG,CAAC;kBACI,CAAC;IACjB,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,KAAU,EACV,QAAa,EAAE,EACG,EAAE;IACpB,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACjD,UAAU,CAAC,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAElD,MAAM,OAAO,GAAY,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IACvE,KAAK,CAAC,MAAM,EAAE,CAAC;IACf,MAAM,OAAO,CAAC,cAAc,CAAC;IAC7B,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAI,KAAU,CAAC;IACf,UAAU,CAAC;QACT,KAAK,GAAG,aAAa,EAAE,CAAC;QACxB,WAAW,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC;QACR,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;QAC9B,MAAM,OAAO,GAAY,MAAM,OAAO,CACpC,OAAO,CAAC,EAAE,QAAQ,EAAE,kCAAkC,EAAE,CAAC,CAC1D,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,OAAO,GAAY,MAAM,aAAa,CAAC,KAAK,EAAE;YAClD,QAAQ,EAAE,kCAAkC;SAC7C,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC;QAC1B,OAAO,CAAC,gBAAgB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAEhD,MAAM,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;QAErD,MAAM,gBAAgB,CAAC,kBAAkB,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { fixture, assert } from '@open-wc/testing';\nimport { Omnibox } from '../src/omnibox/Omnibox';\nimport { assertScreenshot, getClip, openAndClick } from './utils.test';\nimport { useFakeTimers, spy } from 'sinon';\n\nexport const getHTML = (attrs: any = { name: 'recipients' }): string => {\n const selectHTML = `\n <temba-omnibox${Object.keys(attrs)\n .map((name: string) => {\n // check if it's a string attribute\n if (typeof attrs[name] === 'string') {\n return ` ${name}=\"${attrs[name].replace(/\"/g, '"')}\"`;\n }\n return ` ${name}=\"${attrs[name]}\"`;\n })\n .join(' ')}>\n </temba-select>`;\n return selectHTML;\n};\n\nexport const createOmnibox = async (\n clock: any,\n attrs: any = {}\n): Promise<Omnibox> => {\n const parentNode = document.createElement('div');\n parentNode.setAttribute('style', 'width: 400px;');\n\n const omnibox: Omnibox = await fixture(getHTML(attrs), { parentNode });\n clock.runAll();\n await omnibox.updateComplete;\n return omnibox;\n};\n\ndescribe('temba-omnibox', () => {\n let clock: any;\n beforeEach(function () {\n clock = useFakeTimers();\n setViewport({ width: 500, height: 1000, deviceScaleFactor: 2 });\n });\n\n afterEach(function () {\n clock.restore();\n });\n\n it('can be created', async () => {\n const omnibox: Omnibox = await fixture(\n getHTML({ endpoint: '/test-assets/select/omnibox.json' })\n );\n assert.instanceOf(omnibox, Omnibox);\n });\n\n it('fires change events on selection', async () => {\n const omnibox: Omnibox = await createOmnibox(clock, {\n endpoint: '/test-assets/select/omnibox.json'\n });\n\n const changeEvent = spy();\n omnibox.addEventListener('change', changeEvent);\n\n await openAndClick(clock, omnibox, 0);\n assert(changeEvent.called, 'change event not fired');\n\n await assertScreenshot('omnibox/selected', getClip(omnibox));\n });\n});\n"]}
|