@northern.tech/testing 0.8.3 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/chunk-CKQMccvm.cjs +28 -0
  2. package/dist/mockData.cjs +1288 -953
  3. package/dist/mockData.cjs.map +1 -1
  4. package/dist/mockData.d.cts +595 -569
  5. package/dist/mockData.d.ts +595 -569
  6. package/dist/mockData.js +1278 -45
  7. package/dist/mockData.js.map +1 -1
  8. package/dist/openapi.yaml.d.cjs +0 -0
  9. package/dist/openapi.yaml.d.cts +4 -0
  10. package/dist/openapi.yaml.d.ts +5 -0
  11. package/dist/requestHandlers/deploymentHandlers.cjs +181 -1031
  12. package/dist/requestHandlers/deploymentHandlers.cjs.map +1 -1
  13. package/dist/requestHandlers/deploymentHandlers.d.cts +5 -3
  14. package/dist/requestHandlers/deploymentHandlers.d.ts +5 -3
  15. package/dist/requestHandlers/deploymentHandlers.js +190 -6
  16. package/dist/requestHandlers/deploymentHandlers.js.map +1 -1
  17. package/dist/requestHandlers/deviceHandlers.cjs +427 -1090
  18. package/dist/requestHandlers/deviceHandlers.cjs.map +1 -1
  19. package/dist/requestHandlers/deviceHandlers.d.cts +17 -15
  20. package/dist/requestHandlers/deviceHandlers.d.ts +17 -15
  21. package/dist/requestHandlers/deviceHandlers.js +427 -10
  22. package/dist/requestHandlers/deviceHandlers.js.map +1 -1
  23. package/dist/requestHandlers/monitorHandlers.cjs +21 -831
  24. package/dist/requestHandlers/monitorHandlers.cjs.map +1 -1
  25. package/dist/requestHandlers/monitorHandlers.d.cts +5 -3
  26. package/dist/requestHandlers/monitorHandlers.d.ts +5 -3
  27. package/dist/requestHandlers/monitorHandlers.js +21 -7
  28. package/dist/requestHandlers/monitorHandlers.js.map +1 -1
  29. package/dist/requestHandlers/organizationHandlers.cjs +296 -1113
  30. package/dist/requestHandlers/organizationHandlers.cjs.map +1 -1
  31. package/dist/requestHandlers/organizationHandlers.d.cts +5 -3
  32. package/dist/requestHandlers/organizationHandlers.d.ts +5 -3
  33. package/dist/requestHandlers/organizationHandlers.js +308 -6
  34. package/dist/requestHandlers/organizationHandlers.js.map +1 -1
  35. package/dist/requestHandlers/releaseHandlers.cjs +157 -960
  36. package/dist/requestHandlers/releaseHandlers.cjs.map +1 -1
  37. package/dist/requestHandlers/releaseHandlers.d.cts +5 -3
  38. package/dist/requestHandlers/releaseHandlers.d.ts +5 -3
  39. package/dist/requestHandlers/releaseHandlers.js +158 -6
  40. package/dist/requestHandlers/releaseHandlers.js.map +1 -1
  41. package/dist/requestHandlers/requestHandlers.cjs +26 -2000
  42. package/dist/requestHandlers/requestHandlers.cjs.map +1 -1
  43. package/dist/requestHandlers/requestHandlers.d.cts +5 -4
  44. package/dist/requestHandlers/requestHandlers.d.ts +5 -3
  45. package/dist/requestHandlers/requestHandlers.js +24 -32
  46. package/dist/requestHandlers/requestHandlers.js.map +1 -1
  47. package/dist/requestHandlers/userHandlers.cjs +139 -990
  48. package/dist/requestHandlers/userHandlers.cjs.map +1 -1
  49. package/dist/requestHandlers/userHandlers.d.cts +5 -3
  50. package/dist/requestHandlers/userHandlers.d.ts +5 -3
  51. package/dist/requestHandlers/userHandlers.js +139 -7
  52. package/dist/requestHandlers/userHandlers.js.map +1 -1
  53. package/dist/requestHandlers/validation.cjs +4 -0
  54. package/dist/requestHandlers/validation.d.cts +6 -0
  55. package/dist/requestHandlers/validation.d.ts +6 -0
  56. package/dist/requestHandlers/validation.js +2 -0
  57. package/dist/setupTests.cjs +148 -992
  58. package/dist/setupTests.cjs.map +1 -1
  59. package/dist/setupTests.d.cts +68 -66
  60. package/dist/setupTests.d.ts +68 -66
  61. package/dist/setupTests.js +114 -117
  62. package/dist/setupTests.js.map +1 -1
  63. package/dist/theme/light.cjs +7 -39
  64. package/dist/theme/light.cjs.map +1 -1
  65. package/dist/theme/light.d.cts +5 -10
  66. package/dist/theme/light.d.ts +5 -10
  67. package/dist/theme/light.js +7 -6
  68. package/dist/theme/light.js.map +1 -1
  69. package/dist/theme/mui.d.cjs +0 -0
  70. package/dist/theme/mui.d.cts +11 -0
  71. package/dist/theme/mui.d.ts +11 -0
  72. package/dist/utils.cjs +18 -68
  73. package/dist/utils.cjs.map +1 -1
  74. package/dist/utils.d.cts +6 -67
  75. package/dist/utils.d.ts +6 -67
  76. package/dist/utils.js +16 -10
  77. package/dist/utils.js.map +1 -1
  78. package/dist/validation-CsEFO-Cv.cjs +77 -0
  79. package/dist/validation-CsEFO-Cv.cjs.map +1 -0
  80. package/dist/validation-JDM_vsFz.js +64 -0
  81. package/dist/validation-JDM_vsFz.js.map +1 -0
  82. package/package.json +8 -6
  83. package/dist/chunk-3CVNBMEF.js +0 -161
  84. package/dist/chunk-3CVNBMEF.js.map +0 -1
  85. package/dist/chunk-7GNK7IRV.js +0 -29
  86. package/dist/chunk-7GNK7IRV.js.map +0 -1
  87. package/dist/chunk-AP4MOFMD.js +0 -239
  88. package/dist/chunk-AP4MOFMD.js.map +0 -1
  89. package/dist/chunk-DOHA53UH.js +0 -301
  90. package/dist/chunk-DOHA53UH.js.map +0 -1
  91. package/dist/chunk-H4J7L3HX.js +0 -188
  92. package/dist/chunk-H4J7L3HX.js.map +0 -1
  93. package/dist/chunk-HRGVXWMH.js +0 -17
  94. package/dist/chunk-HRGVXWMH.js.map +0 -1
  95. package/dist/chunk-KCLTR6QS.js +0 -34
  96. package/dist/chunk-KCLTR6QS.js.map +0 -1
  97. package/dist/chunk-M2TKDOPD.js +0 -266
  98. package/dist/chunk-M2TKDOPD.js.map +0 -1
  99. package/dist/chunk-O42KIJXJ.js +0 -933
  100. package/dist/chunk-O42KIJXJ.js.map +0 -1
  101. /package/dist/{baseTestConfig.json → public/baseTestConfig.json} +0 -0
@@ -1,12 +1,429 @@
1
- import {
2
- defaultDeviceId,
3
- deviceHandlers,
4
- inventoryDevice
5
- } from "../chunk-DOHA53UH.js";
6
- import "../chunk-O42KIJXJ.js";
7
- export {
8
- defaultDeviceId,
9
- deviceHandlers,
10
- inventoryDevice
1
+ import { defaultCreationDate, defaultMacAddress, mockApiResponses } from "../mockData.js";
2
+ import { n as validated } from "../validation-JDM_vsFz.js";
3
+ import { DEVICE_FILTERING_OPTIONS, DEVICE_STATES, deviceAuthV2, deviceConfig, deviceConnect, headerNames, inventoryApiUrl, inventoryApiUrlV2, iotManagerBaseURL } from "@northern.tech/utils/constants";
4
+ import { HttpResponse, http } from "msw";
5
+ //#region src/requestHandlers/deviceHandlers.ts
6
+ const defaultDeviceId = "a1";
7
+ const deviceAuthDevice = {
8
+ id: "a1",
9
+ identity_data: { mac: defaultMacAddress },
10
+ status: "accepted",
11
+ decommissioning: false,
12
+ created_ts: defaultCreationDate,
13
+ updated_ts: "2019-01-01T09:25:00.000Z",
14
+ auth_sets: [{
15
+ id: "auth1",
16
+ identity_data: { mac: defaultMacAddress },
17
+ pubkey: "-----BEGIN PUBLIC KEY-----\nMIIBojWELzgJ62hcXIhAfqfoNiaB1326XZByZwcnHr5BuSPAgMBAAE=\n-----END PUBLIC KEY-----\n",
18
+ ts: defaultCreationDate,
19
+ status: "accepted"
20
+ }]
11
21
  };
22
+ const checkInTimeExact = "2019-01-01T10:25:00.000Z";
23
+ const updatedTime = "2019-01-01T09:25:00.000Z";
24
+ const inventoryDevice = {
25
+ id: "a1",
26
+ attributes: [
27
+ {
28
+ name: "network_interfaces",
29
+ value: ["eth0", "wlan0"],
30
+ scope: "inventory"
31
+ },
32
+ {
33
+ name: "kernel",
34
+ value: "Linux version 4.19.75-v7l+",
35
+ scope: "inventory"
36
+ },
37
+ {
38
+ name: "artifact_name",
39
+ value: "raspotifyInstaller",
40
+ scope: "inventory"
41
+ },
42
+ {
43
+ name: "ipv6_wlan0",
44
+ value: "fe80::68d9:8453:3e9c:7c80/64",
45
+ scope: "inventory"
46
+ },
47
+ {
48
+ name: "mac_eth0",
49
+ value: defaultMacAddress,
50
+ scope: "inventory"
51
+ },
52
+ {
53
+ name: "rootfs_type",
54
+ value: "ext4",
55
+ scope: "inventory"
56
+ },
57
+ {
58
+ name: "mender_bootloader_integration",
59
+ value: "unknown",
60
+ scope: "inventory"
61
+ },
62
+ {
63
+ name: "cpu_model",
64
+ value: "ARMv7 Processor rev 3 (v7l)",
65
+ scope: "inventory"
66
+ },
67
+ {
68
+ name: "hostname",
69
+ value: "raspberrypi",
70
+ scope: "inventory"
71
+ },
72
+ {
73
+ name: "mender_client_version",
74
+ value: "2.1.0",
75
+ scope: "inventory"
76
+ },
77
+ {
78
+ name: "ipv4_wlan0",
79
+ value: "192.168.10.141/24",
80
+ scope: "inventory"
81
+ },
82
+ {
83
+ name: "device_type",
84
+ value: "raspberrypi4",
85
+ scope: "inventory"
86
+ },
87
+ {
88
+ name: "mem_total_kB",
89
+ value: "1986024",
90
+ scope: "inventory"
91
+ },
92
+ {
93
+ name: "mac_wlan0",
94
+ value: "dc:a6:32:12:ad:c0",
95
+ scope: "inventory"
96
+ },
97
+ {
98
+ name: "os",
99
+ value: "Raspbian GNU/Linux 10 (buster)",
100
+ scope: "inventory"
101
+ },
102
+ {
103
+ name: "created_ts",
104
+ value: defaultCreationDate,
105
+ scope: "system"
106
+ },
107
+ {
108
+ name: "updated_ts",
109
+ value: updatedTime,
110
+ scope: "system"
111
+ },
112
+ {
113
+ name: "status",
114
+ value: "accepted",
115
+ scope: "identity"
116
+ },
117
+ {
118
+ name: "mac",
119
+ value: defaultMacAddress,
120
+ scope: "identity"
121
+ },
122
+ {
123
+ name: "group",
124
+ value: "test",
125
+ scope: "system"
126
+ }
127
+ ],
128
+ check_in_time: checkInTimeExact,
129
+ updated_ts: updatedTime
130
+ };
131
+ const deviceAttributes = [
132
+ {
133
+ name: "status",
134
+ scope: "identity",
135
+ count: 5
136
+ },
137
+ {
138
+ name: "created_ts",
139
+ scope: "system",
140
+ count: 5
141
+ },
142
+ {
143
+ name: "updated_ts",
144
+ scope: "system",
145
+ count: 5
146
+ },
147
+ {
148
+ name: "mac",
149
+ scope: "identity",
150
+ count: 1
151
+ },
152
+ {
153
+ name: "artifact_name",
154
+ scope: "inventory",
155
+ count: 1
156
+ },
157
+ {
158
+ name: "cpu_model",
159
+ scope: "inventory",
160
+ count: 1
161
+ },
162
+ {
163
+ name: "device_type",
164
+ scope: "inventory",
165
+ count: 1
166
+ },
167
+ {
168
+ name: "hostname",
169
+ scope: "inventory",
170
+ count: 1
171
+ },
172
+ {
173
+ name: "ipv4_wlan0",
174
+ scope: "inventory",
175
+ count: 1
176
+ },
177
+ {
178
+ name: "ipv6_wlan0",
179
+ scope: "inventory",
180
+ count: 1
181
+ },
182
+ {
183
+ name: "kernel",
184
+ scope: "inventory",
185
+ count: 1
186
+ },
187
+ {
188
+ name: "mac_eth0",
189
+ scope: "inventory",
190
+ count: 1
191
+ },
192
+ {
193
+ name: "mac_wlan0",
194
+ scope: "inventory",
195
+ count: 1
196
+ },
197
+ {
198
+ name: "mem_total_kB",
199
+ scope: "inventory",
200
+ count: 1
201
+ },
202
+ {
203
+ name: "mender_bootloader_integration",
204
+ scope: "inventory",
205
+ count: 1
206
+ },
207
+ {
208
+ name: "mender_client_version",
209
+ scope: "inventory",
210
+ count: 1
211
+ },
212
+ {
213
+ name: "network_interfaces",
214
+ scope: "inventory",
215
+ count: 1
216
+ },
217
+ {
218
+ name: "os",
219
+ scope: "inventory",
220
+ count: 1
221
+ },
222
+ {
223
+ name: "rootfs_type",
224
+ scope: "inventory",
225
+ count: 1
226
+ },
227
+ {
228
+ name: "group",
229
+ scope: "system",
230
+ count: 1
231
+ }
232
+ ];
233
+ const searchHandler = validated(async ({ request }) => {
234
+ const { page, per_page, filters } = await request.json();
235
+ if ([
236
+ page,
237
+ per_page,
238
+ filters
239
+ ].some((item) => !item)) return new HttpResponse(null, { status: 509 });
240
+ const status = filters.find((filter) => filter.scope === "identity" && filter.attribute === "status" && Object.values(DEVICE_STATES).includes(filter.value))?.value || "";
241
+ if (!status || filters.length > 1) {
242
+ if (filters.find((filter) => filter.attribute === "group" && filter.value.includes(Object.keys(mockApiResponses.devices.groups.byId)[0]))) return new HttpResponse(JSON.stringify([inventoryDevice, {
243
+ ...inventoryDevice,
244
+ id: "b1"
245
+ }]), { headers: { [headerNames.total]: 2 } });
246
+ if (filters.find((filter) => filter.scope === "monitor" && [
247
+ "failed_last_update",
248
+ "alerts",
249
+ "auth_request"
250
+ ].includes(filter.attribute))) return new HttpResponse(JSON.stringify([inventoryDevice]), { headers: { [headerNames.total]: 4 } });
251
+ return new HttpResponse(JSON.stringify([]), { headers: { [headerNames.total]: 0 } });
252
+ }
253
+ let deviceList = Array.from({ length: mockApiResponses.devices.byStatus[status].total }, (_, index) => ({
254
+ ...inventoryDevice,
255
+ attributes: [...inventoryDevice.attributes, {
256
+ name: "test-count",
257
+ value: index,
258
+ scope: "system"
259
+ }],
260
+ id: `${String.fromCharCode("a".charCodeAt(0) + index)}1`
261
+ }));
262
+ deviceList = deviceList.slice((page - 1) * per_page, page * per_page);
263
+ return new HttpResponse(JSON.stringify(deviceList), { headers: { [headerNames.total]: mockApiResponses.devices.byStatus[status].total } });
264
+ });
265
+ const deviceHandlers = [
266
+ http.delete(`${deviceAuthV2}/devices/:deviceId/auth/:authId`, ({ params: { authId, deviceId } }) => {
267
+ if (mockApiResponses.devices.byId[deviceId].auth_sets.find((authSet) => authSet.id === authId)) return new HttpResponse(null, { status: 200 });
268
+ return new HttpResponse(null, { status: 501 });
269
+ }),
270
+ http.delete(`${deviceAuthV2}/devices/:deviceId`, ({ params: { deviceId } }) => {
271
+ if (mockApiResponses.devices.byId[deviceId]) return new HttpResponse(null, { status: 200 });
272
+ return new HttpResponse(null, { status: 502 });
273
+ }),
274
+ http.delete(`${inventoryApiUrl}/groups/:group`, ({ params: { group } }) => {
275
+ if (mockApiResponses.devices.groups.byId[group]) return new HttpResponse(null, { status: 200 });
276
+ return new HttpResponse(null, { status: 515 });
277
+ }),
278
+ http.delete(`${inventoryApiUrl}/groups/:group/devices`, validated(async ({ params: { group }, request }) => {
279
+ const deviceIds = await request.json();
280
+ if (mockApiResponses.devices.groups.byId[group] && deviceIds.every((id) => !!mockApiResponses.devices.byId[id])) return new HttpResponse(null, { status: 200 });
281
+ return new HttpResponse(null, { status: 503 });
282
+ })),
283
+ http.delete(`${inventoryApiUrlV2}/filters/:filterId`, ({ params: { filterId } }) => {
284
+ if (Object.values(mockApiResponses.devices.groups.byId).find((group) => group.id === filterId)) return new HttpResponse(null, { status: 200 });
285
+ return new HttpResponse(null, { status: 504 });
286
+ }),
287
+ http.get(`${deviceAuthV2}/devices`, ({ request }) => {
288
+ const { searchParams } = new URL(request.url);
289
+ const deviceIds = searchParams.getAll("id");
290
+ if (deviceIds.every((id) => !!mockApiResponses.devices.byId[id])) return HttpResponse.json(deviceIds.map((id) => ({
291
+ ...deviceAuthDevice,
292
+ id
293
+ })));
294
+ return new HttpResponse(null, { status: 505 });
295
+ }),
296
+ http.get(`${deviceAuthV2}/limits/devices`, () => HttpResponse.json(mockApiResponses.devices.limits)),
297
+ http.get(`${inventoryApiUrl}/devices/:deviceId`, ({ params: { deviceId } }) => {
298
+ if (mockApiResponses.devices.byId[deviceId]) return HttpResponse.json(inventoryDevice);
299
+ return new HttpResponse(null, { status: 506 });
300
+ }),
301
+ http.put(`${inventoryApiUrl}/devices/:deviceId/tags`, validated(async ({ params: { deviceId }, request }) => {
302
+ const tags = await request.json();
303
+ if (!mockApiResponses.devices.byId[deviceId] && !Array.isArray(tags) && !tags.every((item) => item.name && item.value)) return new HttpResponse(null, { status: 506 });
304
+ return HttpResponse.json(tags);
305
+ })),
306
+ http.get(`${inventoryApiUrl}/groups`, () => {
307
+ const groups = Object.entries(mockApiResponses.devices.groups.byId).reduce((accu, [groupName, group]) => {
308
+ if (!group.id) accu.push(groupName);
309
+ return accu;
310
+ }, []);
311
+ return HttpResponse.json(groups);
312
+ }),
313
+ http.get(`${inventoryApiUrlV2}/filters/attributes`, () => HttpResponse.json(deviceAttributes)),
314
+ http.get(`${inventoryApiUrlV2}/filters`, () => HttpResponse.json([{
315
+ id: "filter1",
316
+ name: "testGroupDynamic",
317
+ terms: [
318
+ {
319
+ scope: "identity",
320
+ attribute: "id",
321
+ type: "$in",
322
+ value: ["a1"]
323
+ },
324
+ {
325
+ scope: "identity",
326
+ attribute: "mac",
327
+ type: "$exists",
328
+ value: false
329
+ },
330
+ {
331
+ scope: "identity",
332
+ attribute: "kernel",
333
+ type: "$exists",
334
+ value: true
335
+ }
336
+ ]
337
+ }])),
338
+ http.patch(`${inventoryApiUrl}/groups/:group/devices`, validated(async ({ params: { group }, request }) => {
339
+ const deviceIds = await request.json();
340
+ if (!!group && deviceIds.every((id) => !!mockApiResponses.devices.byId[id])) return new HttpResponse(null, { status: 200 });
341
+ return new HttpResponse(null, { status: 508 });
342
+ })),
343
+ http.post(`${deviceAuthV2}/devices`, validated(async ({ request }) => {
344
+ const authset = await request.json();
345
+ if (Object.values(mockApiResponses.devices.byId).some((device) => device.auth_sets.some((deviceAuthSet) => deviceAuthSet.pubkey == authset.pubkey || deviceAuthSet.identity_data == authset.identity_data))) return new HttpResponse(null, { status: 409 });
346
+ return new HttpResponse(null, { status: 200 });
347
+ })),
348
+ http.post(`${inventoryApiUrlV2}/filters/search`, searchHandler),
349
+ http.post(`${inventoryApiUrlV2}/filters`, validated(async ({ request }) => {
350
+ const { name, terms } = await request.json();
351
+ if ([name, terms].some((item) => !item) || mockApiResponses.devices.groups[name] || !terms.every((term) => DEVICE_FILTERING_OPTIONS[term.type] && [
352
+ "identity",
353
+ "inventory",
354
+ "system"
355
+ ].includes(term.scope) && !!term.value && !!term.attribute)) return new HttpResponse(null, { status: 510 });
356
+ return new HttpResponse(JSON.stringify({}), { headers: { location: "find/me/here/createdFilterId" } });
357
+ })),
358
+ http.get(`${inventoryApiUrlV2}/statistics`, async () => HttpResponse.json({ devices_by_status: {
359
+ accepted: {
360
+ standard: mockApiResponses.devices.byStatus.accepted.total,
361
+ micro: 0,
362
+ system: 0
363
+ },
364
+ pending: {
365
+ standard: mockApiResponses.devices.byStatus.pending.total,
366
+ micro: 0,
367
+ system: 0
368
+ }
369
+ } })),
370
+ http.put(`${deviceAuthV2}/devices/:deviceId/auth/:authId/status`, validated(async ({ params: { authId, deviceId }, request }) => {
371
+ const { status } = await request.json();
372
+ if (mockApiResponses.devices.byId[deviceId].auth_sets.find((authSet) => authSet.id === authId) && DEVICE_STATES[status]) return new HttpResponse(null, { status: 200 });
373
+ return new HttpResponse(null, { status: 511 });
374
+ })),
375
+ http.get(`${deviceConfig}/:deviceId`, ({ params: { deviceId } }) => {
376
+ if (deviceId === "testId") return new HttpResponse(JSON.stringify({ error: { status_code: 404 } }), { status: 404 });
377
+ if (mockApiResponses.devices.byId[deviceId]) return HttpResponse.json({
378
+ configured: {
379
+ test: true,
380
+ something: "else",
381
+ aNumber: 42
382
+ },
383
+ deployment_id: "config1",
384
+ reported: {
385
+ test: true,
386
+ something: "else",
387
+ aNumber: 42
388
+ },
389
+ updated_ts: updatedTime,
390
+ reported_ts: "2019-01-01T09:25:01.000Z"
391
+ });
392
+ return new HttpResponse(null, { status: 512 });
393
+ }),
394
+ http.put(`${deviceConfig}/:deviceId`, validated(async ({ params: { deviceId }, request }) => {
395
+ if ((await request.text()).includes("evilValue")) return new HttpResponse(null, { status: 418 });
396
+ return new HttpResponse(null, { status: mockApiResponses.devices.byId[deviceId] ? 201 : 513 });
397
+ })),
398
+ http.post(`${deviceConfig}/:deviceId/deploy`, validated(({ params: { deviceId } }) => {
399
+ if (mockApiResponses.devices.byId[deviceId]) return HttpResponse.json({ deployment_id: "config1" });
400
+ return new HttpResponse(null, { status: 514 });
401
+ })),
402
+ http.get(`${deviceConnect}/devices/:deviceId`, ({ params: { deviceId } }) => {
403
+ if (deviceId === "testId") return new HttpResponse(JSON.stringify({ error: { status_code: 404 } }), { status: 404 });
404
+ if (mockApiResponses.devices.byId[deviceId]) return HttpResponse.json({
405
+ status: "connected",
406
+ updated_ts: mockApiResponses.devices.byId[deviceId].updated_ts
407
+ });
408
+ return new HttpResponse(null, { status: 512 });
409
+ }),
410
+ http.post(`${deviceConnect}/devices/:deviceId/:action`, validated(({ params: { deviceId, action } }) => {
411
+ if (["check-update", "send-inventory"].includes(action) && mockApiResponses.devices.byId[deviceId]) return new HttpResponse(null, { status: 202 });
412
+ return new HttpResponse(null, { status: 518 });
413
+ })),
414
+ http.get(`${iotManagerBaseURL}/devices/:deviceId/state`, ({ params: { deviceId } }) => {
415
+ if (mockApiResponses.devices.byId[deviceId]) return HttpResponse.json({ deployment_id: mockApiResponses.deployments.byId.d1.id });
416
+ return new HttpResponse(null, { status: 515 });
417
+ }),
418
+ http.put(`${iotManagerBaseURL}/devices/:deviceId/state/:integrationId`, validated(async ({ params: { deviceId }, request }) => {
419
+ const body = await request.json();
420
+ if (mockApiResponses.devices.byId[deviceId] && body) return HttpResponse.json({ deployment_id: mockApiResponses.deployments.byId.d1.id });
421
+ return new HttpResponse(null, { status: 516 });
422
+ })),
423
+ http.put(`${deviceConnect}/devices/:deviceId/upload`, validated(({ params: { deviceId } }) => new HttpResponse(null, { status: mockApiResponses.devices.byId[deviceId] ? 200 : 517 }))),
424
+ http.get(`${deviceAuthV2}/license`, () => HttpResponse.text("test,report"))
425
+ ];
426
+ //#endregion
427
+ export { defaultDeviceId, deviceHandlers, inventoryDevice };
428
+
12
429
  //# sourceMappingURL=deviceHandlers.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"file":"deviceHandlers.js","names":[],"sources":["../../src/requestHandlers/deviceHandlers.ts"],"sourcesContent":["// Copyright 2020 Northern.tech AS\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//@ts-nocheck\nimport {\n DEVICE_FILTERING_OPTIONS,\n DEVICE_STATES,\n deviceAuthV2,\n deviceConfig,\n deviceConnect,\n headerNames,\n inventoryApiUrl,\n inventoryApiUrlV2,\n iotManagerBaseURL\n} from '@northern.tech/utils/constants';\nimport { HttpResponse, http } from 'msw';\n\nimport { defaultCreationDate, defaultMacAddress, mockApiResponses } from '../mockData';\nimport { validated } from './validation';\n\nexport const defaultDeviceId = 'a1';\n\nconst deviceAuthDevice = {\n id: defaultDeviceId,\n identity_data: { mac: defaultMacAddress },\n status: 'accepted',\n decommissioning: false,\n created_ts: defaultCreationDate,\n updated_ts: '2019-01-01T09:25:00.000Z',\n auth_sets: [\n {\n id: 'auth1',\n identity_data: { mac: defaultMacAddress },\n pubkey: '-----BEGIN PUBLIC KEY-----\\nMIIBojWELzgJ62hcXIhAfqfoNiaB1326XZByZwcnHr5BuSPAgMBAAE=\\n-----END PUBLIC KEY-----\\n',\n ts: defaultCreationDate,\n status: 'accepted'\n }\n ]\n};\n\nconst checkInTimeExact = '2019-01-01T10:25:00.000Z';\nconst updatedTime = '2019-01-01T09:25:00.000Z';\n\nexport const inventoryDevice = {\n id: defaultDeviceId,\n attributes: [\n { name: 'network_interfaces', value: ['eth0', 'wlan0'], scope: 'inventory' },\n { name: 'kernel', value: 'Linux version 4.19.75-v7l+', scope: 'inventory' },\n { name: 'artifact_name', value: 'raspotifyInstaller', scope: 'inventory' },\n { name: 'ipv6_wlan0', value: 'fe80::68d9:8453:3e9c:7c80/64', scope: 'inventory' },\n { name: 'mac_eth0', value: defaultMacAddress, scope: 'inventory' },\n { name: 'rootfs_type', value: 'ext4', scope: 'inventory' },\n { name: 'mender_bootloader_integration', value: 'unknown', scope: 'inventory' },\n { name: 'cpu_model', value: 'ARMv7 Processor rev 3 (v7l)', scope: 'inventory' },\n { name: 'hostname', value: 'raspberrypi', scope: 'inventory' },\n { name: 'mender_client_version', value: '2.1.0', scope: 'inventory' },\n { name: 'ipv4_wlan0', value: '192.168.10.141/24', scope: 'inventory' },\n { name: 'device_type', value: 'raspberrypi4', scope: 'inventory' },\n { name: 'mem_total_kB', value: '1986024', scope: 'inventory' },\n { name: 'mac_wlan0', value: 'dc:a6:32:12:ad:c0', scope: 'inventory' },\n { name: 'os', value: 'Raspbian GNU/Linux 10 (buster)', scope: 'inventory' },\n { name: 'created_ts', value: defaultCreationDate, scope: 'system' },\n { name: 'updated_ts', value: updatedTime, scope: 'system' },\n { name: 'status', value: 'accepted', scope: 'identity' },\n { name: 'mac', value: defaultMacAddress, scope: 'identity' },\n { name: 'group', value: 'test', scope: 'system' }\n ],\n check_in_time: checkInTimeExact,\n updated_ts: updatedTime\n};\n\nconst deviceAttributes = [\n { name: 'status', scope: 'identity', count: 5 },\n { name: 'created_ts', scope: 'system', count: 5 },\n { name: 'updated_ts', scope: 'system', count: 5 },\n { name: 'mac', scope: 'identity', count: 1 },\n { name: 'artifact_name', scope: 'inventory', count: 1 },\n { name: 'cpu_model', scope: 'inventory', count: 1 },\n { name: 'device_type', scope: 'inventory', count: 1 },\n { name: 'hostname', scope: 'inventory', count: 1 },\n { name: 'ipv4_wlan0', scope: 'inventory', count: 1 },\n { name: 'ipv6_wlan0', scope: 'inventory', count: 1 },\n { name: 'kernel', scope: 'inventory', count: 1 },\n { name: 'mac_eth0', scope: 'inventory', count: 1 },\n { name: 'mac_wlan0', scope: 'inventory', count: 1 },\n { name: 'mem_total_kB', scope: 'inventory', count: 1 },\n { name: 'mender_bootloader_integration', scope: 'inventory', count: 1 },\n { name: 'mender_client_version', scope: 'inventory', count: 1 },\n { name: 'network_interfaces', scope: 'inventory', count: 1 },\n { name: 'os', scope: 'inventory', count: 1 },\n { name: 'rootfs_type', scope: 'inventory', count: 1 },\n { name: 'group', scope: 'system', count: 1 }\n];\n\nconst searchHandler = validated(async ({ request }) => {\n const { page, per_page, filters } = await request.json();\n if ([page, per_page, filters].some(item => !item)) {\n return new HttpResponse(null, { status: 509 });\n }\n const filter = filters.find(filter => filter.scope === 'identity' && filter.attribute === 'status' && Object.values(DEVICE_STATES).includes(filter.value));\n const status = filter?.value || '';\n if (!status || filters.length > 1) {\n if (filters.find(filter => filter.attribute === 'group' && filter.value.includes(Object.keys(mockApiResponses.devices.groups.byId)[0]))) {\n return new HttpResponse(JSON.stringify([inventoryDevice, { ...inventoryDevice, id: 'b1' }]), {\n headers: { [headerNames.total]: 2 }\n });\n }\n if (filters.find(filter => filter.scope === 'monitor' && ['failed_last_update', 'alerts', 'auth_request'].includes(filter.attribute))) {\n return new HttpResponse(JSON.stringify([inventoryDevice]), { headers: { [headerNames.total]: 4 } });\n }\n return new HttpResponse(JSON.stringify([]), { headers: { [headerNames.total]: 0 } });\n }\n let deviceList = Array.from({ length: mockApiResponses.devices.byStatus[status].total }, (_, index) => ({\n ...inventoryDevice,\n attributes: [...inventoryDevice.attributes, { name: 'test-count', value: index, scope: 'system' }],\n id: `${String.fromCharCode('a'.charCodeAt(0) + index)}1`\n }));\n deviceList = deviceList.slice((page - 1) * per_page, page * per_page);\n return new HttpResponse(JSON.stringify(deviceList), { headers: { [headerNames.total]: mockApiResponses.devices.byStatus[status].total } });\n});\n\nexport const deviceHandlers = [\n http.delete(`${deviceAuthV2}/devices/:deviceId/auth/:authId`, ({ params: { authId, deviceId } }) => {\n if (mockApiResponses.devices.byId[deviceId].auth_sets.find(authSet => authSet.id === authId)) {\n return new HttpResponse(null, { status: 200 });\n }\n return new HttpResponse(null, { status: 501 });\n }),\n http.delete(`${deviceAuthV2}/devices/:deviceId`, ({ params: { deviceId } }) => {\n if (mockApiResponses.devices.byId[deviceId]) {\n return new HttpResponse(null, { status: 200 });\n }\n return new HttpResponse(null, { status: 502 });\n }),\n http.delete(`${inventoryApiUrl}/groups/:group`, ({ params: { group } }) => {\n if (mockApiResponses.devices.groups.byId[group]) {\n return new HttpResponse(null, { status: 200 });\n }\n return new HttpResponse(null, { status: 515 });\n }),\n http.delete(\n `${inventoryApiUrl}/groups/:group/devices`,\n validated(async ({ params: { group }, request }) => {\n const deviceIds = await request.json();\n if (mockApiResponses.devices.groups.byId[group] && deviceIds.every(id => !!mockApiResponses.devices.byId[id])) {\n return new HttpResponse(null, { status: 200 });\n }\n return new HttpResponse(null, { status: 503 });\n })\n ),\n http.delete(`${inventoryApiUrlV2}/filters/:filterId`, ({ params: { filterId } }) => {\n if (Object.values(mockApiResponses.devices.groups.byId).find(group => group.id === filterId)) {\n return new HttpResponse(null, { status: 200 });\n }\n return new HttpResponse(null, { status: 504 });\n }),\n http.get(`${deviceAuthV2}/devices`, ({ request }) => {\n const { searchParams } = new URL(request.url);\n const deviceIds = searchParams.getAll('id');\n if (deviceIds.every(id => !!mockApiResponses.devices.byId[id])) {\n return HttpResponse.json(deviceIds.map(id => ({ ...deviceAuthDevice, id })));\n }\n return new HttpResponse(null, { status: 505 });\n }),\n http.get(`${deviceAuthV2}/limits/devices`, () => HttpResponse.json(mockApiResponses.devices.limits)),\n http.get(`${inventoryApiUrl}/devices/:deviceId`, ({ params: { deviceId } }) => {\n if (mockApiResponses.devices.byId[deviceId]) {\n return HttpResponse.json(inventoryDevice);\n }\n return new HttpResponse(null, { status: 506 });\n }),\n http.put(\n `${inventoryApiUrl}/devices/:deviceId/tags`,\n validated(async ({ params: { deviceId }, request }) => {\n const tags = await request.json();\n if (!mockApiResponses.devices.byId[deviceId] && !Array.isArray(tags) && !tags.every(item => item.name && item.value)) {\n return new HttpResponse(null, { status: 506 });\n }\n return HttpResponse.json(tags);\n })\n ),\n http.get(`${inventoryApiUrl}/groups`, () => {\n const groups = Object.entries(mockApiResponses.devices.groups.byId).reduce((accu, [groupName, group]) => {\n if (!group.id) {\n accu.push(groupName);\n }\n return accu;\n }, []);\n return HttpResponse.json(groups);\n }),\n http.get(`${inventoryApiUrlV2}/filters/attributes`, () => HttpResponse.json(deviceAttributes)),\n http.get(`${inventoryApiUrlV2}/filters`, () =>\n HttpResponse.json([\n {\n id: 'filter1',\n name: 'testGroupDynamic',\n terms: [\n { scope: 'identity', attribute: 'id', type: '$in', value: [defaultDeviceId] },\n { scope: 'identity', attribute: 'mac', type: '$exists', value: false },\n { scope: 'identity', attribute: 'kernel', type: '$exists', value: true }\n ]\n }\n ])\n ),\n http.patch(\n `${inventoryApiUrl}/groups/:group/devices`,\n validated(async ({ params: { group }, request }) => {\n const deviceIds = await request.json();\n if (!!group && deviceIds.every(id => !!mockApiResponses.devices.byId[id])) {\n return new HttpResponse(null, { status: 200 });\n }\n return new HttpResponse(null, { status: 508 });\n })\n ),\n http.post(\n `${deviceAuthV2}/devices`,\n validated(async ({ request }) => {\n const authset = await request.json();\n if (\n Object.values(mockApiResponses.devices.byId).some(device =>\n device.auth_sets.some(deviceAuthSet => deviceAuthSet.pubkey == authset.pubkey || deviceAuthSet.identity_data == authset.identity_data)\n )\n ) {\n return new HttpResponse(null, { status: 409 });\n }\n return new HttpResponse(null, { status: 200 });\n })\n ),\n http.post(`${inventoryApiUrlV2}/filters/search`, searchHandler),\n http.post(\n `${inventoryApiUrlV2}/filters`,\n validated(async ({ request }) => {\n const { name, terms } = await request.json();\n if (\n [name, terms].some(item => !item) ||\n mockApiResponses.devices.groups[name] ||\n !terms.every(\n term => DEVICE_FILTERING_OPTIONS[term.type] && ['identity', 'inventory', 'system'].includes(term.scope) && !!term.value && !!term.attribute\n )\n ) {\n return new HttpResponse(null, { status: 510 });\n }\n return new HttpResponse(JSON.stringify({}), { headers: { location: 'find/me/here/createdFilterId' } });\n })\n ),\n http.get(`${inventoryApiUrlV2}/statistics`, async () =>\n HttpResponse.json({\n devices_by_status: {\n accepted: { standard: mockApiResponses.devices.byStatus.accepted.total, micro: 0, system: 0 },\n pending: { standard: mockApiResponses.devices.byStatus.pending.total, micro: 0, system: 0 }\n }\n })\n ),\n http.put(\n `${deviceAuthV2}/devices/:deviceId/auth/:authId/status`,\n validated(async ({ params: { authId, deviceId }, request }) => {\n const { status } = await request.json();\n if (mockApiResponses.devices.byId[deviceId].auth_sets.find(authSet => authSet.id === authId) && DEVICE_STATES[status]) {\n return new HttpResponse(null, { status: 200 });\n }\n return new HttpResponse(null, { status: 511 });\n })\n ),\n http.get(`${deviceConfig}/:deviceId`, ({ params: { deviceId } }) => {\n if (deviceId === 'testId') {\n return new HttpResponse(JSON.stringify({ error: { status_code: 404 } }), { status: 404 });\n }\n if (mockApiResponses.devices.byId[deviceId]) {\n return HttpResponse.json({\n configured: { test: true, something: 'else', aNumber: 42 },\n deployment_id: 'config1',\n reported: { test: true, something: 'else', aNumber: 42 },\n updated_ts: updatedTime,\n reported_ts: '2019-01-01T09:25:01.000Z'\n });\n }\n return new HttpResponse(null, { status: 512 });\n }),\n http.put(\n `${deviceConfig}/:deviceId`,\n validated(async ({ params: { deviceId }, request }) => {\n const body = await request.text();\n if (body.includes('evilValue')) {\n return new HttpResponse(null, { status: 418 });\n }\n return new HttpResponse(null, { status: mockApiResponses.devices.byId[deviceId] ? 201 : 513 });\n })\n ),\n http.post(\n `${deviceConfig}/:deviceId/deploy`,\n validated(({ params: { deviceId } }) => {\n if (mockApiResponses.devices.byId[deviceId]) {\n return HttpResponse.json({ deployment_id: 'config1' });\n }\n return new HttpResponse(null, { status: 514 });\n })\n ),\n http.get(`${deviceConnect}/devices/:deviceId`, ({ params: { deviceId } }) => {\n if (deviceId === 'testId') {\n return new HttpResponse(JSON.stringify({ error: { status_code: 404 } }), { status: 404 });\n }\n if (mockApiResponses.devices.byId[deviceId]) {\n return HttpResponse.json({ status: 'connected', updated_ts: mockApiResponses.devices.byId[deviceId].updated_ts });\n }\n return new HttpResponse(null, { status: 512 });\n }),\n http.post(\n `${deviceConnect}/devices/:deviceId/:action`,\n validated(({ params: { deviceId, action } }) => {\n if (['check-update', 'send-inventory'].includes(action) && mockApiResponses.devices.byId[deviceId]) {\n return new HttpResponse(null, { status: 202 });\n }\n return new HttpResponse(null, { status: 518 });\n })\n ),\n http.get(`${iotManagerBaseURL}/devices/:deviceId/state`, ({ params: { deviceId } }) => {\n if (mockApiResponses.devices.byId[deviceId]) {\n return HttpResponse.json({ deployment_id: mockApiResponses.deployments.byId.d1.id });\n }\n return new HttpResponse(null, { status: 515 });\n }),\n http.put(\n `${iotManagerBaseURL}/devices/:deviceId/state/:integrationId`,\n validated(async ({ params: { deviceId }, request }) => {\n const body = await request.json();\n if (mockApiResponses.devices.byId[deviceId] && body) {\n return HttpResponse.json({ deployment_id: mockApiResponses.deployments.byId.d1.id });\n }\n return new HttpResponse(null, { status: 516 });\n })\n ),\n http.put(\n `${deviceConnect}/devices/:deviceId/upload`,\n validated(({ params: { deviceId } }) => new HttpResponse(null, { status: mockApiResponses.devices.byId[deviceId] ? 200 : 517 }))\n ),\n http.get(`${deviceAuthV2}/license`, () => HttpResponse.text('test,report'))\n];\n"],"mappings":"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"}