@symbo.ls/sdk 2.33.27 → 2.33.28
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbo.ls/sdk",
|
|
3
|
-
"version": "2.33.
|
|
3
|
+
"version": "2.33.28",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
"test:user": "cross-env NODE_ENV=$NODE_ENV npx tape integration-tests/index.js integration-tests/user/*.test.js | tap-spec"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@domql/element": "^2.33.
|
|
50
|
-
"@domql/utils": "^2.33.
|
|
49
|
+
"@domql/element": "^2.33.28",
|
|
50
|
+
"@domql/utils": "^2.33.28",
|
|
51
51
|
"@grafana/faro-web-sdk": "^1.19.0",
|
|
52
52
|
"@grafana/faro-web-tracing": "^1.19.0",
|
|
53
|
-
"@symbo.ls/router": "^2.33.
|
|
54
|
-
"@symbo.ls/socket": "^2.33.
|
|
53
|
+
"@symbo.ls/router": "^2.33.28",
|
|
54
|
+
"@symbo.ls/socket": "^2.33.28",
|
|
55
55
|
"acorn": "^8.14.0",
|
|
56
56
|
"acorn-walk": "^8.3.4",
|
|
57
57
|
"dexie": "^4.0.11",
|
|
@@ -74,5 +74,5 @@
|
|
|
74
74
|
"tap-spec": "^5.0.0",
|
|
75
75
|
"tape": "^5.9.0"
|
|
76
76
|
},
|
|
77
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "58b2f9f34b228712ccc4352e15913c52d6007afb"
|
|
78
78
|
}
|
|
@@ -765,15 +765,7 @@ export class CollabService extends BaseService {
|
|
|
765
765
|
const root = this._stateManager?.root
|
|
766
766
|
if (root && typeof root.replace === 'function') {
|
|
767
767
|
root.clients = data
|
|
768
|
-
// root.replace(
|
|
769
|
-
// { clients: data },
|
|
770
|
-
// {
|
|
771
|
-
// fromSocket: true,
|
|
772
|
-
// preventUpdate: true
|
|
773
|
-
// }
|
|
774
|
-
// )
|
|
775
768
|
}
|
|
776
|
-
|
|
777
769
|
rootBus.emit('clients:updated', data)
|
|
778
770
|
}
|
|
779
771
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-undefined */
|
|
1
2
|
import test from 'tape'
|
|
2
3
|
import sinon from 'sinon'
|
|
3
4
|
import { PlanService } from '../../PlanService.js'
|
|
@@ -24,24 +25,33 @@ test('createPlan should return response data', async t => {
|
|
|
24
25
|
t.end()
|
|
25
26
|
})
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
await planServiceStub.createPlan(false)
|
|
34
|
-
t.fail('createPlan should have failed')
|
|
35
|
-
} catch (err) {
|
|
36
|
-
t.equal(
|
|
37
|
-
err.toString(),
|
|
38
|
-
'Error: Plan data is required',
|
|
39
|
-
'Error correctly returned'
|
|
40
|
-
)
|
|
28
|
+
function planDataValidation () {
|
|
29
|
+
const badData = {
|
|
30
|
+
falseValue: false,
|
|
31
|
+
undefinedValue: undefined,
|
|
32
|
+
stringValue: 'testString'
|
|
41
33
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
Object.keys(badData).forEach(key => {
|
|
35
|
+
test(`createPlan should return an error for ${key} - Plan data is required`, async t => {
|
|
36
|
+
t.plan(1)
|
|
37
|
+
const planServiceStub = new PlanService()
|
|
38
|
+
sandbox.stub(planServiceStub, '_requireReady').resolves()
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
await planServiceStub.createPlan(badData[key])
|
|
42
|
+
t.fail('createPlan should have failed')
|
|
43
|
+
} catch (err) {
|
|
44
|
+
t.equal(
|
|
45
|
+
err.toString(),
|
|
46
|
+
'Error: Plan data is required',
|
|
47
|
+
'Error correctly returned'
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
sandbox.restore()
|
|
51
|
+
t.end()
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
}
|
|
45
55
|
|
|
46
56
|
test('createPlan should return an error - Failed to parse URL', async t => {
|
|
47
57
|
t.plan(1)
|
|
@@ -82,6 +92,8 @@ test('createPlan should fail the requireReady', async t => {
|
|
|
82
92
|
sandbox.restore()
|
|
83
93
|
t.end()
|
|
84
94
|
})
|
|
95
|
+
|
|
96
|
+
planDataValidation()
|
|
85
97
|
// #endregion
|
|
86
98
|
|
|
87
99
|
// #region Cleanup
|
|
@@ -14,8 +14,7 @@ test('createPlanWithValidation should return response data', async t => {
|
|
|
14
14
|
const responseStub = [sandbox.stub()]
|
|
15
15
|
const planData = {
|
|
16
16
|
name: 'testName',
|
|
17
|
-
|
|
18
|
-
price: 1.0
|
|
17
|
+
description: 'test description'
|
|
19
18
|
}
|
|
20
19
|
const planServiceStub = new PlanService()
|
|
21
20
|
sandbox.stub(planServiceStub, 'createPlan').resolves(responseStub)
|
|
@@ -33,6 +32,10 @@ function planDataEmptyOrNotAnObject () {
|
|
|
33
32
|
name: 'planData is undefined',
|
|
34
33
|
testValue: undefined
|
|
35
34
|
},
|
|
35
|
+
planDataIsFalse: {
|
|
36
|
+
name: 'planData is false',
|
|
37
|
+
testValue: false
|
|
38
|
+
},
|
|
36
39
|
planDataNotAnObject: {
|
|
37
40
|
name: 'planData is not an object',
|
|
38
41
|
testValue: 'Not An Object'
|
|
@@ -64,11 +67,10 @@ function requiredFieldsMissing () {
|
|
|
64
67
|
// Data test object
|
|
65
68
|
const planData = {
|
|
66
69
|
name: 'testName',
|
|
67
|
-
|
|
68
|
-
price: 1.0
|
|
70
|
+
description: 'test description'
|
|
69
71
|
}
|
|
70
72
|
Object.keys(planData).forEach(field => {
|
|
71
|
-
test(
|
|
73
|
+
test(`Required field validation for missing ${field} should return an error`, async t => {
|
|
72
74
|
t.plan(1)
|
|
73
75
|
const { ...testData } = planData
|
|
74
76
|
delete testData[field]
|
|
@@ -91,36 +93,99 @@ function requiredFieldsMissing () {
|
|
|
91
93
|
})
|
|
92
94
|
}
|
|
93
95
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
test('Price validation should throw an error when price field is present', async t => {
|
|
97
|
+
t.plan(1)
|
|
98
|
+
const planData = {
|
|
99
|
+
name: 'testName',
|
|
100
|
+
description: 'test description',
|
|
101
|
+
price: 1.0
|
|
102
|
+
}
|
|
103
|
+
const responseStub = [sandbox.stub()]
|
|
104
|
+
const planServiceStub = new PlanService()
|
|
105
|
+
sandbox.stub(planServiceStub, 'createPlan').resolves(responseStub)
|
|
106
|
+
try {
|
|
107
|
+
await planServiceStub.createPlanWithValidation(planData)
|
|
108
|
+
t.fail('Price validation successfully threw an error')
|
|
109
|
+
} catch (err) {
|
|
110
|
+
t.equal(
|
|
111
|
+
err.toString(),
|
|
112
|
+
'Error: Field "price" is no longer supported. Use unified "pricingOptions" with "amount" instead.',
|
|
113
|
+
'planData validation detected unsupported price field'
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
sandbox.restore()
|
|
117
|
+
t.end()
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
function pricingOptionsValidation () {
|
|
121
|
+
// Data test object
|
|
122
|
+
const planData = {
|
|
123
|
+
name: 'testName',
|
|
124
|
+
description: 'test description'
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const badPricingOptions = {
|
|
128
|
+
stringValue: 'test string',
|
|
129
|
+
numberValue: 123,
|
|
130
|
+
booleanValue: false,
|
|
131
|
+
emptyArray: []
|
|
132
|
+
}
|
|
133
|
+
Object.keys(badPricingOptions).forEach(field => {
|
|
134
|
+
test(`pricingOptions validation throws error for ${field}`, async t => {
|
|
135
|
+
t.plan(1)
|
|
136
|
+
const { ...testData } = planData
|
|
137
|
+
testData.pricingOptions = badPricingOptions[field]
|
|
138
|
+
const responseStub = [sandbox.stub()]
|
|
139
|
+
const planServiceStub = new PlanService()
|
|
140
|
+
sandbox.stub(planServiceStub, 'createPlan').resolves(responseStub)
|
|
141
|
+
try {
|
|
142
|
+
await planServiceStub.createPlanWithValidation(testData)
|
|
143
|
+
t.fail('createPlanWithValidation failed - bad pricingOptions detected')
|
|
144
|
+
} catch (err) {
|
|
145
|
+
t.equal(
|
|
146
|
+
err.toString(),
|
|
147
|
+
'Error: pricingOptions must be a non-empty array when provided',
|
|
148
|
+
`Validation failed successfully on bad pricingOptions data: ${field}`
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
sandbox.restore()
|
|
152
|
+
t.end()
|
|
153
|
+
})
|
|
154
|
+
})
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function keyTypeValidation () {
|
|
158
|
+
const badKeyData = [
|
|
159
|
+
{ name: 'array value', key: [] },
|
|
160
|
+
{ name: 'number value', key: 123 },
|
|
161
|
+
{ name: 'null value', key: null },
|
|
162
|
+
{ name: 'undefined value', key: undefined },
|
|
163
|
+
{ name: 'false boolean value', key: false }
|
|
164
|
+
]
|
|
165
|
+
for (let ii = 0; ii < badKeyData.length; ii++) {
|
|
166
|
+
test(`Key validation should throw an error checking for: ${badKeyData[ii].name}`, async t => {
|
|
98
167
|
t.plan(1)
|
|
99
168
|
const planData = {
|
|
100
169
|
name: 'testName',
|
|
101
|
-
|
|
170
|
+
description: 'test description',
|
|
171
|
+
pricingOptions: []
|
|
102
172
|
}
|
|
103
|
-
planData.
|
|
173
|
+
planData.pricingOptions.push(badKeyData[ii])
|
|
104
174
|
const responseStub = [sandbox.stub()]
|
|
105
175
|
const planServiceStub = new PlanService()
|
|
106
176
|
sandbox.stub(planServiceStub, 'createPlan').resolves(responseStub)
|
|
107
177
|
try {
|
|
108
178
|
await planServiceStub.createPlanWithValidation(planData)
|
|
109
|
-
t.fail('
|
|
179
|
+
t.fail('Key type validation successfully threw an error')
|
|
110
180
|
} catch (err) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
err.toString(),
|
|
120
|
-
"Error: Required field 'price' is missing",
|
|
121
|
-
`Price validation detected bad price data: ${planData.price}`
|
|
122
|
-
)
|
|
123
|
-
}
|
|
181
|
+
t.ok(
|
|
182
|
+
err
|
|
183
|
+
.toString()
|
|
184
|
+
.includes(
|
|
185
|
+
"Error: Pricing option at index 0 is missing required field 'key'"
|
|
186
|
+
),
|
|
187
|
+
`Key type validation detected bad data: ${badKeyData[ii].name}`
|
|
188
|
+
)
|
|
124
189
|
}
|
|
125
190
|
sandbox.restore()
|
|
126
191
|
t.end()
|
|
@@ -128,33 +193,72 @@ function priceValidation () {
|
|
|
128
193
|
}
|
|
129
194
|
}
|
|
130
195
|
|
|
131
|
-
function
|
|
196
|
+
function keyFormatValidation () {
|
|
132
197
|
const badKeyData = [
|
|
133
|
-
'CAPITALLETTERS',
|
|
134
|
-
'Special @ Character',
|
|
135
|
-
'under_score',
|
|
136
|
-
'syntax!'
|
|
198
|
+
{ name: 'capital letters', key: 'CAPITALLETTERS' },
|
|
199
|
+
{ name: 'special character', key: 'Special @ Character' },
|
|
200
|
+
{ name: 'under score', key: 'under_score' },
|
|
201
|
+
{ name: 'punctuation', key: 'syntax!' }
|
|
137
202
|
]
|
|
138
203
|
for (let ii = 0; ii < badKeyData.length; ii++) {
|
|
139
|
-
test(`Key validation should throw an error checking for: ${badKeyData[ii]}`, async t => {
|
|
204
|
+
test(`Key validation should throw an error checking for: ${badKeyData[ii].name}`, async t => {
|
|
205
|
+
t.plan(1)
|
|
206
|
+
const planData = {
|
|
207
|
+
name: 'testName',
|
|
208
|
+
description: 'test description',
|
|
209
|
+
pricingOptions: []
|
|
210
|
+
}
|
|
211
|
+
planData.pricingOptions.push(badKeyData[ii])
|
|
212
|
+
const responseStub = [sandbox.stub()]
|
|
213
|
+
const planServiceStub = new PlanService()
|
|
214
|
+
sandbox.stub(planServiceStub, 'createPlan').resolves(responseStub)
|
|
215
|
+
try {
|
|
216
|
+
await planServiceStub.createPlanWithValidation(planData)
|
|
217
|
+
t.fail('Key type validation successfully threw an error')
|
|
218
|
+
} catch (err) {
|
|
219
|
+
t.equal(
|
|
220
|
+
err.toString(),
|
|
221
|
+
`Error: Pricing option key '${badKeyData[ii].key}' must contain only lowercase letters, numbers, and hyphens`,
|
|
222
|
+
`Key format validation detected bad data: ${badKeyData[ii].name}`
|
|
223
|
+
)
|
|
224
|
+
}
|
|
225
|
+
sandbox.restore()
|
|
226
|
+
t.end()
|
|
227
|
+
})
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function displayNameValidation () {
|
|
232
|
+
const badDisplayNameData = [
|
|
233
|
+
{
|
|
234
|
+
name: 'false boolean value',
|
|
235
|
+
displayName: false,
|
|
236
|
+
key: 'false-boolean-value'
|
|
237
|
+
},
|
|
238
|
+
{ name: 'number value', displayName: 123, key: 'number-value' },
|
|
239
|
+
{ name: 'undefined value', displayName: undefined, key: 'undefined-value' },
|
|
240
|
+
{ name: 'null value', displayName: null, key: 'null-value' }
|
|
241
|
+
]
|
|
242
|
+
for (let ii = 0; ii < badDisplayNameData.length; ii++) {
|
|
243
|
+
test(`Key validation should throw an error checking for: ${badDisplayNameData[ii].name}`, async t => {
|
|
140
244
|
t.plan(1)
|
|
141
245
|
const planData = {
|
|
142
246
|
name: 'testName',
|
|
143
|
-
|
|
144
|
-
|
|
247
|
+
description: 'test description',
|
|
248
|
+
pricingOptions: []
|
|
145
249
|
}
|
|
146
|
-
planData.
|
|
250
|
+
planData.pricingOptions.push(badDisplayNameData[ii])
|
|
147
251
|
const responseStub = [sandbox.stub()]
|
|
148
252
|
const planServiceStub = new PlanService()
|
|
149
253
|
sandbox.stub(planServiceStub, 'createPlan').resolves(responseStub)
|
|
150
254
|
try {
|
|
151
255
|
await planServiceStub.createPlanWithValidation(planData)
|
|
152
|
-
t.fail('Key validation successfully threw an error')
|
|
256
|
+
t.fail('Key type validation successfully threw an error')
|
|
153
257
|
} catch (err) {
|
|
154
258
|
t.equal(
|
|
155
259
|
err.toString(),
|
|
156
|
-
|
|
157
|
-
`
|
|
260
|
+
`Error: Pricing option \'${badDisplayNameData[ii].key}\' is missing required field \'displayName\'`,
|
|
261
|
+
`displayName validation detected bad data: ${badDisplayNameData[ii].name}`
|
|
158
262
|
)
|
|
159
263
|
}
|
|
160
264
|
sandbox.restore()
|
|
@@ -163,9 +267,11 @@ function keyValidation () {
|
|
|
163
267
|
}
|
|
164
268
|
}
|
|
165
269
|
|
|
166
|
-
|
|
167
|
-
|
|
270
|
+
displayNameValidation()
|
|
271
|
+
keyFormatValidation()
|
|
272
|
+
keyTypeValidation()
|
|
168
273
|
planDataEmptyOrNotAnObject()
|
|
274
|
+
pricingOptionsValidation()
|
|
169
275
|
requiredFieldsMissing()
|
|
170
276
|
// #endregion
|
|
171
277
|
|
|
@@ -8,7 +8,7 @@ const sandbox = sinon.createSandbox()
|
|
|
8
8
|
// #endregion
|
|
9
9
|
|
|
10
10
|
// #region Tests
|
|
11
|
-
test
|
|
11
|
+
test('updatePlanWithValidation should return response data', async t => {
|
|
12
12
|
t.plan(1)
|
|
13
13
|
const responseStub = [sandbox.stub()]
|
|
14
14
|
const testData = {
|
|
@@ -49,7 +49,7 @@ function planIdEmptyOrNotAString () {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
Object.keys(badData).forEach(key => {
|
|
52
|
-
test
|
|
52
|
+
test(`updatePlanWithValidation should return an error - ${badData[key].name}`, async t => {
|
|
53
53
|
t.plan(1)
|
|
54
54
|
const planData = {
|
|
55
55
|
name: 'testName',
|
|
@@ -88,7 +88,7 @@ function planDataEmptyOrNotAnObject () {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
Object.keys(badData).forEach(key => {
|
|
91
|
-
test
|
|
91
|
+
test(`updatePlanWithValidation should return an error - ${badData[key].name}`, async t => {
|
|
92
92
|
t.plan(1)
|
|
93
93
|
const planId = 'testString'
|
|
94
94
|
const planData = badData[key].testValue
|
|
@@ -112,7 +112,7 @@ function planDataEmptyOrNotAnObject () {
|
|
|
112
112
|
function priceValidation () {
|
|
113
113
|
const badPriceData = ['A string', -10, {}]
|
|
114
114
|
for (let ii = 0; ii < badPriceData.length; ii++) {
|
|
115
|
-
test
|
|
115
|
+
test(`Price validation should throw an error checking for: ${badPriceData[ii]}`, async t => {
|
|
116
116
|
t.plan(1)
|
|
117
117
|
const planData = {
|
|
118
118
|
name: 'testName',
|
|
@@ -174,6 +174,43 @@ function keyValidation () {
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
test('getActivePlans should return active plans', async t => {
|
|
178
|
+
t.plan(3)
|
|
179
|
+
const numActivePlans = 2
|
|
180
|
+
const plansStub = [
|
|
181
|
+
{
|
|
182
|
+
plan: 'plan1',
|
|
183
|
+
active: true
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
plan: 'plan2',
|
|
187
|
+
active: false
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
plan: 'plan3',
|
|
191
|
+
active: true
|
|
192
|
+
}
|
|
193
|
+
]
|
|
194
|
+
const planServiceStub = new PlanService()
|
|
195
|
+
sandbox.stub(planServiceStub, 'getPlans').resolves(plansStub)
|
|
196
|
+
const response = await planServiceStub.getActivePlans()
|
|
197
|
+
t.equal(
|
|
198
|
+
response.length,
|
|
199
|
+
numActivePlans,
|
|
200
|
+
'Correct number of active plans returned'
|
|
201
|
+
)
|
|
202
|
+
t.equal(
|
|
203
|
+
response[0].plan,
|
|
204
|
+
plansStub[0].plan,
|
|
205
|
+
'First plan successfully returned'
|
|
206
|
+
)
|
|
207
|
+
t.equal(
|
|
208
|
+
response[1].plan,
|
|
209
|
+
plansStub[2].plan,
|
|
210
|
+
'Third plan successfully returned'
|
|
211
|
+
)
|
|
212
|
+
})
|
|
213
|
+
|
|
177
214
|
keyValidation()
|
|
178
215
|
priceValidation()
|
|
179
216
|
planIdEmptyOrNotAString()
|