keez-invoicing 1.1.5

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 (111) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +366 -0
  3. package/dist/coverage/lcov-report/block-navigation.js +71 -0
  4. package/dist/coverage/lcov-report/prettify.js +478 -0
  5. package/dist/coverage/lcov-report/sorter.js +177 -0
  6. package/dist/eslint.config.js +56 -0
  7. package/dist/jest.config.cjs +13 -0
  8. package/dist/jest.config.js +13 -0
  9. package/dist/src/api/__tests__/index.test.js +52 -0
  10. package/dist/src/api/authorise.js +48 -0
  11. package/dist/src/api/invoices/cancel.js +33 -0
  12. package/dist/src/api/invoices/create.js +97 -0
  13. package/dist/src/api/invoices/delete.js +33 -0
  14. package/dist/src/api/invoices/downloadPdf.js +31 -0
  15. package/dist/src/api/invoices/getAll.js +84 -0
  16. package/dist/src/api/invoices/sendMail.js +59 -0
  17. package/dist/src/api/invoices/submitEfactura.js +34 -0
  18. package/dist/src/api/invoices/update.js +61 -0
  19. package/dist/src/api/invoices/validate.js +39 -0
  20. package/dist/src/api/invoices/view.js +93 -0
  21. package/dist/src/api/items/create.js +42 -0
  22. package/dist/src/api/items/getAll.js +74 -0
  23. package/dist/src/api/items/getById.js +46 -0
  24. package/dist/src/api/items/index.js +14 -0
  25. package/dist/src/api/items/patch.js +49 -0
  26. package/dist/src/api/items/update.js +41 -0
  27. package/dist/src/config/constants.js +23 -0
  28. package/dist/src/config/constructorParam.js +3 -0
  29. package/dist/src/config/measureUnit.js +22 -0
  30. package/dist/src/config/paymentType.js +17 -0
  31. package/dist/src/config/paymentType.js.js +16 -0
  32. package/dist/src/dto/allInvoicesResponse.js +3 -0
  33. package/dist/src/dto/authResponse.js +3 -0
  34. package/dist/src/dto/common/index.js +3 -0
  35. package/dist/src/dto/common/paginationParams.js +3 -0
  36. package/dist/src/dto/createInvoiceRequest.js +3 -0
  37. package/dist/src/dto/invoiceResponse.js +3 -0
  38. package/dist/src/dto/invoices/index.js +3 -0
  39. package/dist/src/dto/invoices/invoiceFilterParams.js +3 -0
  40. package/dist/src/dto/invoices/invoiceRequestV2.js +3 -0
  41. package/dist/src/dto/invoices/sendInvoiceParams.js +3 -0
  42. package/dist/src/dto/items/allItemsResponse.js +3 -0
  43. package/dist/src/dto/items/index.js +3 -0
  44. package/dist/src/dto/items/itemRequest.js +3 -0
  45. package/dist/src/dto/items/itemResponse.js +3 -0
  46. package/dist/src/errors/KeezError.js +27 -0
  47. package/dist/src/helpers/logger.js +15 -0
  48. package/dist/src/index.js +15 -0
  49. package/dist/src/keezApi.js +283 -0
  50. package/dist/tests/additional-coverage.test.js +351 -0
  51. package/dist/tests/edge-cases.test.js +353 -0
  52. package/dist/tests/error-handling.test.js +224 -0
  53. package/dist/tests/filter-params.test.js +267 -0
  54. package/dist/tests/index.test.js +493 -0
  55. package/dist/tests/invoices-extended.test.js +168 -0
  56. package/dist/tests/items.test.js +142 -0
  57. package/dist/types/coverage/lcov-report/block-navigation.d.ts +1 -0
  58. package/dist/types/coverage/lcov-report/prettify.d.ts +0 -0
  59. package/dist/types/coverage/lcov-report/sorter.d.ts +1 -0
  60. package/dist/types/eslint.config.d.ts +2 -0
  61. package/dist/types/jest.config.d.cts +9 -0
  62. package/dist/types/jest.config.d.ts +9 -0
  63. package/dist/types/src/api/__tests__/index.test.d.ts +1 -0
  64. package/dist/types/src/api/authorise.d.ts +18 -0
  65. package/dist/types/src/api/invoices/cancel.d.ts +9 -0
  66. package/dist/types/src/api/invoices/create.d.ts +22 -0
  67. package/dist/types/src/api/invoices/delete.d.ts +9 -0
  68. package/dist/types/src/api/invoices/downloadPdf.d.ts +8 -0
  69. package/dist/types/src/api/invoices/getAll.d.ts +22 -0
  70. package/dist/types/src/api/invoices/sendMail.d.ts +24 -0
  71. package/dist/types/src/api/invoices/submitEfactura.d.ts +9 -0
  72. package/dist/types/src/api/invoices/update.d.ts +11 -0
  73. package/dist/types/src/api/invoices/validate.d.ts +21 -0
  74. package/dist/types/src/api/invoices/view.d.ts +22 -0
  75. package/dist/types/src/api/items/create.d.ts +10 -0
  76. package/dist/types/src/api/items/getAll.d.ts +10 -0
  77. package/dist/types/src/api/items/getById.d.ts +10 -0
  78. package/dist/types/src/api/items/index.d.ts +5 -0
  79. package/dist/types/src/api/items/patch.d.ts +11 -0
  80. package/dist/types/src/api/items/update.d.ts +11 -0
  81. package/dist/types/src/config/constants.d.ts +13 -0
  82. package/dist/types/src/config/constructorParam.d.ts +6 -0
  83. package/dist/types/src/config/measureUnit.d.ts +17 -0
  84. package/dist/types/src/config/paymentType.d.ts +12 -0
  85. package/dist/types/src/config/paymentType.js.d.ts +11 -0
  86. package/dist/types/src/dto/allInvoicesResponse.d.ts +21 -0
  87. package/dist/types/src/dto/authResponse.d.ts +7 -0
  88. package/dist/types/src/dto/common/index.d.ts +1 -0
  89. package/dist/types/src/dto/common/paginationParams.d.ts +4 -0
  90. package/dist/types/src/dto/createInvoiceRequest.d.ts +34 -0
  91. package/dist/types/src/dto/invoiceResponse.d.ts +48 -0
  92. package/dist/types/src/dto/invoices/index.d.ts +3 -0
  93. package/dist/types/src/dto/invoices/invoiceFilterParams.d.ts +8 -0
  94. package/dist/types/src/dto/invoices/invoiceRequestV2.d.ts +23 -0
  95. package/dist/types/src/dto/invoices/sendInvoiceParams.d.ts +5 -0
  96. package/dist/types/src/dto/items/allItemsResponse.d.ts +13 -0
  97. package/dist/types/src/dto/items/index.d.ts +3 -0
  98. package/dist/types/src/dto/items/itemRequest.d.ts +34 -0
  99. package/dist/types/src/dto/items/itemResponse.d.ts +15 -0
  100. package/dist/types/src/errors/KeezError.d.ts +11 -0
  101. package/dist/types/src/helpers/logger.d.ts +2 -0
  102. package/dist/types/src/index.d.ts +11 -0
  103. package/dist/types/src/keezApi.d.ts +114 -0
  104. package/dist/types/tests/additional-coverage.test.d.ts +1 -0
  105. package/dist/types/tests/edge-cases.test.d.ts +1 -0
  106. package/dist/types/tests/error-handling.test.d.ts +1 -0
  107. package/dist/types/tests/filter-params.test.d.ts +1 -0
  108. package/dist/types/tests/index.test.d.ts +1 -0
  109. package/dist/types/tests/invoices-extended.test.d.ts +1 -0
  110. package/dist/types/tests/items.test.d.ts +1 -0
  111. package/package.json +66 -0
@@ -0,0 +1,493 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const nock_1 = __importDefault(require("nock"));
7
+ const keezApi_1 = require("../src/keezApi");
8
+ const authorise_1 = require("../src/api/authorise");
9
+ const getAll_1 = require("../src/api/invoices/getAll");
10
+ const view_1 = require("../src/api/invoices/view");
11
+ const create_1 = require("../src/api/invoices/create");
12
+ const sendMail_1 = require("../src/api/invoices/sendMail");
13
+ const validate_1 = require("../src/api/invoices/validate");
14
+ const paymentType_1 = require("../src/config/paymentType");
15
+ const KeezError_1 = require("../src/errors/KeezError");
16
+ const STAGING_DOMAIN = 'https://staging.keez.ro';
17
+ const LIVE_DOMAIN = 'https://app.keez.ro';
18
+ describe('KeezApi class', () => {
19
+ let keezApi;
20
+ beforeAll(() => {
21
+ keezApi = new keezApi_1.KeezApi({
22
+ application_id: 'test-app-id',
23
+ client_eid: 'test-client-eid',
24
+ secret: 'test-secret',
25
+ live: true,
26
+ });
27
+ });
28
+ afterEach(() => {
29
+ nock_1.default.cleanAll();
30
+ });
31
+ test('should return live domain when live mode is true', () => {
32
+ keezApi.setLive(true);
33
+ expect(keezApi.getBaseDomain()).toBe(LIVE_DOMAIN);
34
+ });
35
+ test('should return staging domain when live mode is false', () => {
36
+ keezApi.setLive(false);
37
+ expect(keezApi.getBaseDomain()).toBe(STAGING_DOMAIN);
38
+ });
39
+ });
40
+ describe('apiGenerateToken', () => {
41
+ afterEach(() => {
42
+ nock_1.default.cleanAll();
43
+ });
44
+ test('should generate token successfully', async () => {
45
+ const mockResponse = {
46
+ access_token: 'test-access-token',
47
+ expires_in: 3600,
48
+ token_type: 'Bearer',
49
+ scope: 'public-api',
50
+ };
51
+ (0, nock_1.default)(STAGING_DOMAIN)
52
+ .post('/idp/connect/token')
53
+ .reply(200, mockResponse);
54
+ const result = await (0, authorise_1.apiGenerateToken)({
55
+ baseDomain: STAGING_DOMAIN,
56
+ appId: 'test-app-id',
57
+ apiSecret: 'test-secret',
58
+ });
59
+ expect(result.access_token).toBe('test-access-token');
60
+ expect(result.expires_in).toBe(3600);
61
+ expect(result.token_type).toBe('Bearer');
62
+ expect(result.scope).toBe('public-api');
63
+ expect(result.expires_at).toBeGreaterThan(Date.now());
64
+ });
65
+ test('should throw KeezAuthError on authentication failure', async () => {
66
+ (0, nock_1.default)(STAGING_DOMAIN)
67
+ .post('/idp/connect/token')
68
+ .reply(401, { error: 'invalid_client' });
69
+ await expect((0, authorise_1.apiGenerateToken)({
70
+ baseDomain: STAGING_DOMAIN,
71
+ appId: 'test-app-id',
72
+ apiSecret: 'wrong-secret',
73
+ })).rejects.toThrow(KeezError_1.KeezAuthError);
74
+ });
75
+ });
76
+ describe('apiGetAllInvoices', () => {
77
+ afterEach(() => {
78
+ nock_1.default.cleanAll();
79
+ });
80
+ test('should get all invoices successfully', async () => {
81
+ const mockResponse = {
82
+ first: 0,
83
+ last: 1,
84
+ recordsCount: 2,
85
+ data: [
86
+ {
87
+ externalId: 'invoice-1',
88
+ series: 'PDI',
89
+ number: 1,
90
+ documentDate: 20230423,
91
+ dueDate: 20230430,
92
+ status: 'draft',
93
+ clientName: 'Test Client',
94
+ partnerName: 'Test Partner',
95
+ currencyCode: 'RON',
96
+ referenceCurrencyCode: 'RON',
97
+ netAmount: 100,
98
+ vatAmount: 19,
99
+ grossAmount: 119,
100
+ },
101
+ {
102
+ externalId: 'invoice-2',
103
+ series: 'PDI',
104
+ number: 2,
105
+ documentDate: 20230424,
106
+ dueDate: 20230501,
107
+ status: 'valid',
108
+ clientName: 'Test Client 2',
109
+ partnerName: 'Test Partner 2',
110
+ currencyCode: 'EUR',
111
+ referenceCurrencyCode: 'RON',
112
+ netAmount: 200,
113
+ vatAmount: 38,
114
+ grossAmount: 238,
115
+ },
116
+ ],
117
+ };
118
+ (0, nock_1.default)(STAGING_DOMAIN)
119
+ .get('/api/v1.0/public-api/test-client-eid/invoices')
120
+ .reply(200, mockResponse);
121
+ const result = await (0, getAll_1.apiGetAllInvoices)({
122
+ baseDomain: STAGING_DOMAIN,
123
+ appId: 'test-app-id',
124
+ appClientId: 'test-client-eid',
125
+ bearerToken: 'test-token',
126
+ });
127
+ expect(result.recordsCount).toBe(2);
128
+ expect(result.data).toHaveLength(2);
129
+ expect(result.data[0].externalId).toBe('invoice-1');
130
+ expect(result.data[1].externalId).toBe('invoice-2');
131
+ });
132
+ test('should return empty array when no invoices exist', async () => {
133
+ const mockResponse = {
134
+ first: 0,
135
+ last: 0,
136
+ recordsCount: 0,
137
+ data: [],
138
+ };
139
+ (0, nock_1.default)(STAGING_DOMAIN)
140
+ .get('/api/v1.0/public-api/test-client-eid/invoices')
141
+ .reply(200, mockResponse);
142
+ const result = await (0, getAll_1.apiGetAllInvoices)({
143
+ baseDomain: STAGING_DOMAIN,
144
+ appId: 'test-app-id',
145
+ appClientId: 'test-client-eid',
146
+ bearerToken: 'test-token',
147
+ });
148
+ expect(result.recordsCount).toBe(0);
149
+ expect(result.data).toHaveLength(0);
150
+ });
151
+ test('should throw KeezApiError on failure', async () => {
152
+ (0, nock_1.default)(STAGING_DOMAIN)
153
+ .get('/api/v1.0/public-api/test-client-eid/invoices')
154
+ .reply(500, { error: 'Internal Server Error' });
155
+ await expect((0, getAll_1.apiGetAllInvoices)({
156
+ baseDomain: STAGING_DOMAIN,
157
+ appId: 'test-app-id',
158
+ appClientId: 'test-client-eid',
159
+ bearerToken: 'test-token',
160
+ })).rejects.toThrow(KeezError_1.KeezApiError);
161
+ });
162
+ });
163
+ describe('apiGetInvoiceByExternalId', () => {
164
+ afterEach(() => {
165
+ nock_1.default.cleanAll();
166
+ });
167
+ test('should get invoice by external ID successfully', async () => {
168
+ const mockResponse = {
169
+ currencyCode: 'RON',
170
+ discountGrossValue: 0,
171
+ discountNetValue: 0,
172
+ discountVatValue: 0,
173
+ discountValueOnNet: false,
174
+ exciseAmount: 0,
175
+ documentDate: 20230423,
176
+ dueDate: 20230430,
177
+ exchangeRate: 1,
178
+ grossAmount: 119,
179
+ netAmount: 100,
180
+ number: 1,
181
+ originalNetAmount: 100,
182
+ originalVatAmount: 19,
183
+ partner: {
184
+ addressDetails: 'Test Address',
185
+ cityName: 'Bucharest',
186
+ countryCode: 'RO',
187
+ countryName: 'Romania',
188
+ countyCode: 'RO.B',
189
+ countyName: 'Bucharest',
190
+ identificationNumber: '12345678',
191
+ isLegalPerson: false,
192
+ partnerName: 'Test Partner',
193
+ },
194
+ invoiceDetails: [
195
+ {
196
+ discountGrossValue: 0,
197
+ discountNetValue: 0,
198
+ discountVatValue: 0,
199
+ discountValueOnNet: false,
200
+ grossAmount: 119,
201
+ itemCode: 'ITEM-001',
202
+ itemDescription: 'Test Item',
203
+ itemExternalId: 'item-ext-1',
204
+ itemName: 'Test Item Name',
205
+ measureUnitId: 1,
206
+ netAmount: 100,
207
+ originalNetAmount: 100,
208
+ originalVatAmount: 19,
209
+ quantity: 1,
210
+ unMeasureUnit: 'buc',
211
+ unVatCategory: 'S',
212
+ unVatExemptionReason: '',
213
+ unitPrice: 100,
214
+ vatAmount: 19,
215
+ vatPercent: 19,
216
+ exciseAmount: 0,
217
+ },
218
+ ],
219
+ paymentTypeId: 3,
220
+ referenceCurrencyCode: 'RON',
221
+ series: 'PDI',
222
+ status: 'draft',
223
+ vatAmount: 19,
224
+ vatOnCollection: false,
225
+ };
226
+ (0, nock_1.default)(STAGING_DOMAIN)
227
+ .get('/api/v1.0/public-api/test-client-eid/invoices/invoice-ext-1')
228
+ .reply(200, mockResponse);
229
+ const result = await (0, view_1.apiGetInvoiceByExternalId)({
230
+ baseDomain: STAGING_DOMAIN,
231
+ appId: 'test-app-id',
232
+ appClientId: 'test-client-eid',
233
+ bearerToken: 'test-token',
234
+ invoiceId: 'invoice-ext-1',
235
+ });
236
+ expect(result.grossAmount).toBe(119);
237
+ expect(result.partner.partnerName).toBe('Test Partner');
238
+ expect(result.items).toHaveLength(1);
239
+ expect(result.items[0].itemName).toBe('Test Item Name');
240
+ });
241
+ test('should throw KeezApiError when invoice not found', async () => {
242
+ (0, nock_1.default)(STAGING_DOMAIN)
243
+ .get('/api/v1.0/public-api/test-client-eid/invoices/non-existent')
244
+ .reply(404, { error: 'Invoice not found' });
245
+ await expect((0, view_1.apiGetInvoiceByExternalId)({
246
+ baseDomain: STAGING_DOMAIN,
247
+ appId: 'test-app-id',
248
+ appClientId: 'test-client-eid',
249
+ bearerToken: 'test-token',
250
+ invoiceId: 'non-existent',
251
+ })).rejects.toThrow(KeezError_1.KeezApiError);
252
+ });
253
+ });
254
+ describe('apiCreateInvoice', () => {
255
+ afterEach(() => {
256
+ nock_1.default.cleanAll();
257
+ });
258
+ test('should create invoice successfully', async () => {
259
+ const mockResponse = {
260
+ externalId: 'new-invoice-ext-id',
261
+ };
262
+ (0, nock_1.default)(STAGING_DOMAIN)
263
+ .post('/api/v1.0/public-api/test-client-eid/invoices')
264
+ .reply(201, mockResponse);
265
+ const result = await (0, create_1.apiCreateInvoice)({
266
+ baseDomain: STAGING_DOMAIN,
267
+ appId: 'test-app-id',
268
+ appClientId: 'test-client-eid',
269
+ bearerToken: 'test-token',
270
+ invoice: {
271
+ series: 'PDI',
272
+ currencyCode: 'RON',
273
+ amount: 100,
274
+ paymentType: paymentType_1.PaymentType.BANK_TRANSFER,
275
+ partner: {
276
+ addressDetails: 'Test Address',
277
+ cityName: 'Bucharest',
278
+ countryCode: 'RO',
279
+ countryName: 'Romania',
280
+ countyCode: 'RO.B',
281
+ countyName: 'Bucharest',
282
+ identificationNumber: '12345678',
283
+ isLegalPerson: false,
284
+ partnerName: 'Test Partner',
285
+ },
286
+ itemId: 'item-ext-1',
287
+ },
288
+ });
289
+ expect(result).toBe('new-invoice-ext-id');
290
+ });
291
+ test('should create invoice with custom date and quantity', async () => {
292
+ const mockResponse = {
293
+ externalId: 'new-invoice-ext-id-2',
294
+ };
295
+ (0, nock_1.default)(STAGING_DOMAIN)
296
+ .post('/api/v1.0/public-api/test-client-eid/invoices', (body) => body.documentDate === 20240115 && body.invoiceDetails[0].quantity === 5)
297
+ .reply(201, mockResponse);
298
+ const result = await (0, create_1.apiCreateInvoice)({
299
+ baseDomain: STAGING_DOMAIN,
300
+ appId: 'test-app-id',
301
+ appClientId: 'test-client-eid',
302
+ bearerToken: 'test-token',
303
+ invoice: {
304
+ series: 'PDI',
305
+ currencyCode: 'RON',
306
+ amount: 500,
307
+ paymentType: paymentType_1.PaymentType.CARD_ONLINE,
308
+ partner: {
309
+ addressDetails: 'Test Address',
310
+ cityName: 'Bucharest',
311
+ countryCode: 'RO',
312
+ countryName: 'Romania',
313
+ countyCode: 'RO.B',
314
+ countyName: 'Bucharest',
315
+ identificationNumber: '12345678',
316
+ isLegalPerson: false,
317
+ partnerName: 'Test Partner',
318
+ },
319
+ itemId: 'item-ext-1',
320
+ documentDate: 20240115,
321
+ dueDate: 20240130,
322
+ quantity: 5,
323
+ },
324
+ });
325
+ expect(result).toBe('new-invoice-ext-id-2');
326
+ });
327
+ test('should throw KeezApiError on validation error', async () => {
328
+ (0, nock_1.default)(STAGING_DOMAIN)
329
+ .post('/api/v1.0/public-api/test-client-eid/invoices')
330
+ .reply(400, { Message: 'Validation failed' });
331
+ await expect((0, create_1.apiCreateInvoice)({
332
+ baseDomain: STAGING_DOMAIN,
333
+ appId: 'test-app-id',
334
+ appClientId: 'test-client-eid',
335
+ bearerToken: 'test-token',
336
+ invoice: {
337
+ series: 'PDI',
338
+ currencyCode: 'RON',
339
+ amount: -100,
340
+ paymentType: paymentType_1.PaymentType.BANK_TRANSFER,
341
+ partner: {
342
+ addressDetails: 'Test Address',
343
+ cityName: 'Bucharest',
344
+ countryCode: 'RO',
345
+ countryName: 'Romania',
346
+ countyCode: 'RO.B',
347
+ countyName: 'Bucharest',
348
+ identificationNumber: '',
349
+ isLegalPerson: false,
350
+ partnerName: '',
351
+ },
352
+ itemId: '',
353
+ },
354
+ })).rejects.toThrow(KeezError_1.KeezApiError);
355
+ });
356
+ });
357
+ describe('apiSendInvoice', () => {
358
+ afterEach(() => {
359
+ nock_1.default.cleanAll();
360
+ });
361
+ test('should send invoice email successfully', async () => {
362
+ (0, nock_1.default)(STAGING_DOMAIN)
363
+ .post('/api/v1.0/public-api/invoices/delivery')
364
+ .reply(200);
365
+ const result = await (0, sendMail_1.apiSendInvoice)({
366
+ baseDomain: STAGING_DOMAIN,
367
+ appId: 'test-app-id',
368
+ bearerToken: 'test-token',
369
+ clientMail: 'test@example.com',
370
+ invoiceId: 'invoice-ext-1',
371
+ });
372
+ expect(result).toBe('SENT');
373
+ });
374
+ test('should throw KeezApiError on send failure', async () => {
375
+ (0, nock_1.default)(STAGING_DOMAIN)
376
+ .post('/api/v1.0/public-api/invoices/delivery')
377
+ .reply(500, { error: 'Email service unavailable' });
378
+ await expect((0, sendMail_1.apiSendInvoice)({
379
+ baseDomain: STAGING_DOMAIN,
380
+ appId: 'test-app-id',
381
+ bearerToken: 'test-token',
382
+ clientMail: 'test@example.com',
383
+ invoiceId: 'invoice-ext-1',
384
+ })).rejects.toThrow(KeezError_1.KeezApiError);
385
+ });
386
+ });
387
+ describe('apiValidateInvoice', () => {
388
+ afterEach(() => {
389
+ nock_1.default.cleanAll();
390
+ });
391
+ test('should validate invoice successfully', async () => {
392
+ (0, nock_1.default)(STAGING_DOMAIN)
393
+ .post('/api/v1.0/public-api/test-client-eid/invoices/valid')
394
+ .reply(200);
395
+ const result = await (0, validate_1.apiValidateInvoice)({
396
+ baseDomain: STAGING_DOMAIN,
397
+ appId: 'test-app-id',
398
+ appClientId: 'test-client-eid',
399
+ bearerToken: 'test-token',
400
+ invoiceId: 'invoice-ext-1',
401
+ });
402
+ expect(result).toBe('VALIDATED');
403
+ });
404
+ test('should throw KeezApiError on validation failure', async () => {
405
+ (0, nock_1.default)(STAGING_DOMAIN)
406
+ .post('/api/v1.0/public-api/test-client-eid/invoices/valid')
407
+ .reply(400, { Message: 'Invoice cannot be validated' });
408
+ await expect((0, validate_1.apiValidateInvoice)({
409
+ baseDomain: STAGING_DOMAIN,
410
+ appId: 'test-app-id',
411
+ appClientId: 'test-client-eid',
412
+ bearerToken: 'test-token',
413
+ invoiceId: 'invalid-invoice',
414
+ })).rejects.toThrow(KeezError_1.KeezApiError);
415
+ });
416
+ });
417
+ describe('KeezApi integration tests', () => {
418
+ let keezApi;
419
+ beforeEach(() => {
420
+ keezApi = new keezApi_1.KeezApi({
421
+ application_id: 'test-app-id',
422
+ client_eid: 'test-client-eid',
423
+ secret: 'test-secret',
424
+ live: false,
425
+ });
426
+ });
427
+ afterEach(() => {
428
+ nock_1.default.cleanAll();
429
+ });
430
+ test('should auto-refresh token when expired', async () => {
431
+ // Mock token generation
432
+ (0, nock_1.default)(STAGING_DOMAIN)
433
+ .post('/idp/connect/token')
434
+ .reply(200, {
435
+ access_token: 'fresh-token',
436
+ expires_in: 3600,
437
+ token_type: 'Bearer',
438
+ scope: 'public-api',
439
+ });
440
+ // Mock get all invoices
441
+ (0, nock_1.default)(STAGING_DOMAIN)
442
+ .get('/api/v1.0/public-api/test-client-eid/invoices')
443
+ .reply(200, {
444
+ first: 0,
445
+ last: 0,
446
+ recordsCount: 0,
447
+ data: [],
448
+ });
449
+ const result = await keezApi.getAllInvoices();
450
+ expect(result.recordsCount).toBe(0);
451
+ });
452
+ test('should create and validate invoice flow', async () => {
453
+ // Mock token generation
454
+ (0, nock_1.default)(STAGING_DOMAIN)
455
+ .post('/idp/connect/token')
456
+ .reply(200, {
457
+ access_token: 'test-token',
458
+ expires_in: 3600,
459
+ token_type: 'Bearer',
460
+ scope: 'public-api',
461
+ });
462
+ // Mock create invoice
463
+ (0, nock_1.default)(STAGING_DOMAIN)
464
+ .post('/api/v1.0/public-api/test-client-eid/invoices')
465
+ .reply(201, { externalId: 'created-invoice-id' });
466
+ const invoiceId = await keezApi.createInvoice({
467
+ series: 'PDI',
468
+ currencyCode: 'RON',
469
+ amount: 100,
470
+ paymentType: paymentType_1.PaymentType.MEAL_VOUCHER,
471
+ partner: {
472
+ addressDetails: 'Test Address',
473
+ cityName: 'Bucharest',
474
+ countryCode: 'RO',
475
+ countryName: 'Romania',
476
+ countyCode: 'RO.B',
477
+ countyName: 'Bucharest',
478
+ identificationNumber: '12345678',
479
+ isLegalPerson: false,
480
+ partnerName: 'Test Partner',
481
+ },
482
+ itemId: 'item-ext-1',
483
+ });
484
+ expect(invoiceId).toBe('created-invoice-id');
485
+ // Mock validate invoice (reuse token)
486
+ (0, nock_1.default)(STAGING_DOMAIN)
487
+ .post('/api/v1.0/public-api/test-client-eid/invoices/valid')
488
+ .reply(200);
489
+ const validateResult = await keezApi.validateInvoice('created-invoice-id');
490
+ expect(validateResult).toBe('VALIDATED');
491
+ });
492
+ });
493
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXgudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3RzL2luZGV4LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxnREFBd0I7QUFDeEIsdUNBQW9DO0FBQ3BDLCtDQUFtRDtBQUNuRCxrREFBMEQ7QUFDMUQsOENBQWdFO0FBQ2hFLGtEQUF5RDtBQUN6RCxzREFBeUQ7QUFDekQsc0RBQTZEO0FBQzdELHNEQUFtRDtBQUNuRCxrREFBaUU7QUFFakUsTUFBTSxjQUFjLEdBQUcseUJBQXlCLENBQUM7QUFDakQsTUFBTSxXQUFXLEdBQUcscUJBQXFCLENBQUM7QUFFMUMsUUFBUSxDQUFDLGVBQWUsRUFBRSxHQUFHLEVBQUU7SUFDM0IsSUFBSSxPQUFnQixDQUFDO0lBRXJCLFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDWCxPQUFPLEdBQUcsSUFBSSxpQkFBTyxDQUFDO1lBQ2xCLGNBQWMsRUFBRSxhQUFhO1lBQzdCLFVBQVUsRUFBRSxpQkFBaUI7WUFDN0IsTUFBTSxFQUFFLGFBQWE7WUFDckIsSUFBSSxFQUFFLElBQUk7U0FDYixDQUFDLENBQUM7SUFDUCxDQUFDLENBQUMsQ0FBQztJQUVILFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDWCxjQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDcEIsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsa0RBQWtELEVBQUUsR0FBRyxFQUFFO1FBQzFELE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUN0RCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxzREFBc0QsRUFBRSxHQUFHLEVBQUU7UUFDOUQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN2QixNQUFNLENBQUMsT0FBTyxDQUFD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QU0sRUFBRSxLQUFLO1lBQ2IsWUFBWSxFQUFFLEtBQUs7WUFDbkIsTUFBTSxFQUFFLEdBQUc7WUFDWCxXQUFXLEVBQUUseUJBQVcsQ0FBQyxZQUFZO1lBQ3JDLE9BQU8sRUFBRTtnQkFDTCxjQUFjLEVBQUUsY0FBYztnQkFDOUIsUUFBUSxFQUFFLFdBQVc7Z0JBQ3JCLFdBQVcsRUFBRSxJQUFJO2dCQUNqQixXQUFXLEVBQUUsU0FBUztnQkFDdEIsVUFBVSxFQUFFLE1BQU07Z0JBQ2xCLFVBQVUsRUFBRSxXQUFXO2dCQUN2QixvQkFBb0IsRUFBRSxVQUFVO2dCQUNoQyxhQUFhLEVBQUUsS0FBSztnQkFDcEIsV0FBVyxFQUFFLGNBQWM7YUFDOUI7WUFDRCxNQUFNLEVBQUUsWUFBWTtTQUN2QixDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFFN0Msc0NBQXNDO1FBQ3RDLElBQUEsY0FBSSxFQUFDLGNBQWMsQ0FBQzthQUNmLElBQUksQ0FBQyxxREFBcUQsQ0FBQzthQUMzRCxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFaEIsTUFBTSxjQUFjLEdBQUcsTUFBTSxPQUFPLENBQUMsZUFBZSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDM0UsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUM3QyxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IG5vY2sgZnJvbSAnbm9jayc7XG5pbXBvcnQgeyBLZWV6QXBpIH0gZnJvbSAnQC9rZWV6QXBpJztcbmltcG9ydCB7IGFwaUdlbmVyYXRlVG9rZW4gfSBmcm9tICdAL2FwaS9hdXRob3Jpc2UnO1xuaW1wb3J0IHsgYXBpR2V0QWxsSW52b2ljZXMgfSBmcm9tICdAL2FwaS9pbnZvaWNlcy9nZXRBbGwnO1xuaW1wb3J0IHsgYXBpR2V0SW52b2ljZUJ5RXh0ZXJuYWxJZCB9IGZyb20gJ0AvYXBpL2ludm9pY2VzL3ZpZXcnO1xuaW1wb3J0IHsgYXBpQ3JlYXRlSW52b2ljZSB9IGZyb20gJ0AvYXBpL2ludm9pY2VzL2NyZWF0ZSc7XG5pbXBvcnQgeyBhcGlTZW5kSW52b2ljZSB9IGZyb20gJ0AvYXBpL2ludm9pY2VzL3NlbmRNYWlsJztcbmltcG9ydCB7IGFwaVZhbGlkYXRlSW52b2ljZSB9IGZyb20gJ0AvYXBpL2ludm9pY2VzL3ZhbGlkYXRlJztcbmltcG9ydCB7IFBheW1lbnRUeXBlIH0gZnJvbSAnQC9jb25maWcvcGF5bWVudFR5cGUnO1xuaW1wb3J0IHsgS2VlekF1dGhFcnJvciwgS2VlekFwaUVycm9yIH0gZnJvbSAnQC9lcnJvcnMvS2VlekVycm9yJztcblxuY29uc3QgU1RBR0lOR19ET01BSU4gPSAnaHR0cHM6Ly9zdGFnaW5nLmtlZXoucm8nO1xuY29uc3QgTElWRV9ET01BSU4gPSAnaHR0cHM6Ly9hcHAua2Vlei5ybyc7XG5cbmRlc2NyaWJlKCdLZWV6QXBpIGNsYXNzJywgKCkgPT4ge1xuICAgIGxldCBrZWV6QXBpOiBLZWV6QXBpO1xuXG4gICAgYmVmb3JlQWxsKCgpID0+IHtcbiAgICAgICAga2VlekFwaSA9IG5ldyBLZWV6QXBpKHtcbiAgICAgICAgICAgIGFwcGxpY2F0aW9uX2lkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgY2xpZW50X2VpZDogJ3Rlc3QtY2xpZW50LWVpZCcsXG4gICAgICAgICAgICBzZWNyZXQ6ICd0ZXN0LXNlY3JldCcsXG4gICAgICAgICAgICBsaXZlOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Nob3VsZCByZXR1cm4gbGl2ZSBkb21haW4gd2hlbiBsaXZlIG1vZGUgaXMgdHJ1ZScsICgpID0+IHtcbiAgICAgICAga2VlekFwaS5zZXRMaXZlKHRydWUpO1xuICAgICAgICBleHBlY3Qoa2VlekFwaS5nZXRCYXNlRG9tYWluKCkpLnRvQmUoTElWRV9ET01BSU4pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIHJldHVybiBzdGFnaW5nIGRvbWFpbiB3aGVuIGxpdmUgbW9kZSBpcyBmYWxzZScsICgpID0+IHtcbiAgICAgICAga2VlekFwaS5zZXRMaXZlKGZhbHNlKTtcbiAgICAgICAgZXhwZWN0KGtlZXpBcGkuZ2V0QmFzZURvbWFpbigpKS50b0JlKFNUQUdJTkdfRE9NQUlOKTtcbiAgICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnYXBpR2VuZXJhdGVUb2tlbicsICgpID0+IHtcbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzaG91bGQgZ2VuZXJhdGUgdG9rZW4gc3VjY2Vzc2Z1bGx5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBtb2NrUmVzcG9uc2UgPSB7XG4gICAgICAgICAgICBhY2Nlc3NfdG9rZW46ICd0ZXN0LWFjY2Vzcy10b2tlbicsXG4gICAgICAgICAgICBleHBpcmVzX2luOiAzNjAwLFxuICAgICAgICAgICAgdG9rZW5fdHlwZTogJ0JlYXJlcicsXG4gICAgICAgICAgICBzY29wZTogJ3B1YmxpYy1hcGknLFxuICAgICAgICB9O1xuXG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2lkcC9jb25uZWN0L3Rva2VuJylcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tSZXNwb25zZSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXBpR2VuZXJhdGVUb2tlbih7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYXBpU2VjcmV0OiAndGVzdC1zZWNyZXQnLFxuICAgICAgICB9KTtcblxuICAgICAgICBleHBlY3QocmVzdWx0LmFjY2Vzc190b2tlbikudG9CZSgndGVzdC1hY2Nlc3MtdG9rZW4nKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdC5leHBpcmVzX2luKS50b0JlKDM2MDApO1xuICAgICAgICBleHBlY3QocmVzdWx0LnRva2VuX3R5cGUpLnRvQmUoJ0JlYXJlcicpO1xuICAgICAgICBleHBlY3QocmVzdWx0LnNjb3BlKS50b0JlKCdwdWJsaWMtYXBpJyk7XG4gICAgICAgIGV4cGVjdChyZXN1bHQuZXhwaXJlc19hdCkudG9CZUdyZWF0ZXJUaGFuKERhdGUubm93KCkpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIHRocm93IEtlZXpBdXRoRXJyb3Igb24gYXV0aGVudGljYXRpb24gZmFpbHVyZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgbm9jayhTVEFHSU5HX0RPTUFJTilcbiAgICAgICAgICAgIC5wb3N0KCcvaWRwL2Nvbm5lY3QvdG9rZW4nKVxuICAgICAgICAgICAgLnJlcGx5KDQwMSwgeyBlcnJvcjogJ2ludmFsaWRfY2xpZW50JyB9KTtcblxuICAgICAgICBhd2FpdCBleHBlY3QoYXBpR2VuZXJhdGVUb2tlbih7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYXBpU2VjcmV0OiAnd3Jvbmctc2VjcmV0JyxcbiAgICAgICAgfSkpLnJlamVjdHMudG9UaHJvdyhLZWV6QXV0aEVycm9yKTtcbiAgICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnYXBpR2V0QWxsSW52b2ljZXMnLCAoKSA9PiB7XG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIGdldCBhbGwgaW52b2ljZXMgc3VjY2Vzc2Z1bGx5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBtb2NrUmVzcG9uc2UgPSB7XG4gICAgICAgICAgICBmaXJzdDogMCxcbiAgICAgICAgICAgIGxhc3Q6IDEsXG4gICAgICAgICAgICByZWNvcmRzQ291bnQ6IDIsXG4gICAgICAgICAgICBkYXRhOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBleHRlcm5hbElkOiAnaW52b2ljZS0xJyxcbiAgICAgICAgICAgICAgICAgICAgc2VyaWVzOiAnUERJJyxcbiAgICAgICAgICAgICAgICAgICAgbnVtYmVyOiAxLFxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudERhdGU6IDIwMjMwNDIzLFxuICAgICAgICAgICAgICAgICAgICBkdWVEYXRlOiAyMDIzMDQzMCxcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiAnZHJhZnQnLFxuICAgICAgICAgICAgICAgICAgICBjbGllbnROYW1lOiAnVGVzdCBDbGllbnQnLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0bmVyTmFtZTogJ1Rlc3QgUGFydG5lcicsXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbmN5Q29kZTogJ1JPTicsXG4gICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZUN1cnJlbmN5Q29kZTogJ1JPTicsXG4gICAgICAgICAgICAgICAgICAgIG5ldEFtb3VudDogMTAwLFxuICAgICAgICAgICAgICAgICAgICB2YXRBbW91bnQ6IDE5LFxuICAgICAgICAgICAgICAgICAgICBncm9zc0Ftb3VudDogMTE5LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBleHRlcm5hbElkOiAnaW52b2ljZS0yJyxcbiAgICAgICAgICAgICAgICAgICAgc2VyaWVzOiAnUERJJyxcbiAgICAgICAgICAgICAgICAgICAgbnVtYmVyOiAyLFxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudERhdGU6IDIwMjMwNDI0LFxuICAgICAgICAgICAgICAgICAgICBkdWVEYXRlOiAyMDIzMDUwMSxcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiAndmFsaWQnLFxuICAgICAgICAgICAgICAgICAgICBjbGllbnROYW1lOiAnVGVzdCBDbGllbnQgMicsXG4gICAgICAgICAgICAgICAgICAgIHBhcnRuZXJOYW1lOiAnVGVzdCBQYXJ0bmVyIDInLFxuICAgICAgICAgICAgICAgICAgICBjdXJyZW5jeUNvZGU6ICdFVVInLFxuICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2VDdXJyZW5jeUNvZGU6ICdST04nLFxuICAgICAgICAgICAgICAgICAgICBuZXRBbW91bnQ6IDIwMCxcbiAgICAgICAgICAgICAgICAgICAgdmF0QW1vdW50OiAzOCxcbiAgICAgICAgICAgICAgICAgICAgZ3Jvc3NBbW91bnQ6IDIzOCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgfTtcblxuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLmdldCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvdGVzdC1jbGllbnQtZWlkL2ludm9pY2VzJylcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tSZXNwb25zZSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXBpR2V0QWxsSW52b2ljZXMoe1xuICAgICAgICAgICAgYmFzZURvbWFpbjogU1RBR0lOR19ET01BSU4sXG4gICAgICAgICAgICBhcHBJZDogJ3Rlc3QtYXBwLWlkJyxcbiAgICAgICAgICAgIGFwcENsaWVudElkOiAndGVzdC1jbGllbnQtZWlkJyxcbiAgICAgICAgICAgIGJlYXJlclRva2VuOiAndGVzdC10b2tlbicsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGV4cGVjdChyZXN1bHQucmVjb3Jkc0NvdW50KS50b0JlKDIpO1xuICAgICAgICBleHBlY3QocmVzdWx0LmRhdGEpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdC5kYXRhWzBdLmV4dGVybmFsSWQpLnRvQmUoJ2ludm9pY2UtMScpO1xuICAgICAgICBleHBlY3QocmVzdWx0LmRhdGFbMV0uZXh0ZXJuYWxJZCkudG9CZSgnaW52b2ljZS0yJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzaG91bGQgcmV0dXJuIGVtcHR5IGFycmF5IHdoZW4gbm8gaW52b2ljZXMgZXhpc3QnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vY2tSZXNwb25zZSA9IHtcbiAgICAgICAgICAgIGZpcnN0OiAwLFxuICAgICAgICAgICAgbGFzdDogMCxcbiAgICAgICAgICAgIHJlY29yZHNDb3VudDogMCxcbiAgICAgICAgICAgIGRhdGE6IFtdLFxuICAgICAgICB9O1xuXG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAuZ2V0KCcvYXBpL3YxLjAvcHVibGljLWFwaS90ZXN0LWNsaWVudC1laWQvaW52b2ljZXMnKVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja1Jlc3BvbnNlKTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhcGlHZXRBbGxJbnZvaWNlcyh7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYXBwQ2xpZW50SWQ6ICd0ZXN0LWNsaWVudC1laWQnLFxuICAgICAgICAgICAgYmVhcmVyVG9rZW46ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZXhwZWN0KHJlc3VsdC5yZWNvcmRzQ291bnQpLnRvQmUoMCk7XG4gICAgICAgIGV4cGVjdChyZXN1bHQuZGF0YSkudG9IYXZlTGVuZ3RoKDApO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIHRocm93IEtlZXpBcGlFcnJvciBvbiBmYWlsdXJlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLmdldCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvdGVzdC1jbGllbnQtZWlkL2ludm9pY2VzJylcbiAgICAgICAgICAgIC5yZXBseSg1MDAsIHsgZXJyb3I6ICdJbnRlcm5hbCBTZXJ2ZXIgRXJyb3InIH0pO1xuXG4gICAgICAgIGF3YWl0IGV4cGVjdChhcGlHZXRBbGxJbnZvaWNlcyh7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYXBwQ2xpZW50SWQ6ICd0ZXN0LWNsaWVudC1laWQnLFxuICAgICAgICAgICAgYmVhcmVyVG9rZW46ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgfSkpLnJlamVjdHMudG9UaHJvdyhLZWV6QXBpRXJyb3IpO1xuICAgIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdhcGlHZXRJbnZvaWNlQnlFeHRlcm5hbElkJywgKCkgPT4ge1xuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Nob3VsZCBnZXQgaW52b2ljZSBieSBleHRlcm5hbCBJRCBzdWNjZXNzZnVsbHknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vY2tSZXNwb25zZSA9IHtcbiAgICAgICAgICAgIGN1cnJlbmN5Q29kZTogJ1JPTicsXG4gICAgICAgICAgICBkaXNjb3VudEdyb3NzVmFsdWU6IDAsXG4gICAgICAgICAgICBkaXNjb3VudE5ldFZhbHVlOiAwLFxuICAgICAgICAgICAgZGlzY291bnRWYXRWYWx1ZTogMCxcbiAgICAgICAgICAgIGRpc2NvdW50VmFsdWVPbk5ldDogZmFsc2UsXG4gICAgICAgICAgICBleGNpc2VBbW91bnQ6IDAsXG4gICAgICAgICAgICBkb2N1bWVudERhdGU6IDIwMjMwNDIzLFxuICAgICAgICAgICAgZHVlRGF0ZTogMjAyMzA0MzAsXG4gICAgICAgICAgICBleGNoYW5nZVJhdGU6IDEsXG4gICAgICAgICAgICBncm9zc0Ftb3VudDogMTE5LFxuICAgICAgICAgICAgbmV0QW1vdW50OiAxMDAsXG4gICAgICAgICAgICBudW1iZXI6IDEsXG4gICAgICAgICAgICBvcmlnaW5hbE5ldEFtb3VudDogMTAwLFxuICAgICAgICAgICAgb3JpZ2luYWxWYXRBbW91bnQ6IDE5LFxuICAgICAgICAgICAgcGFydG5lcjoge1xuICAgICAgICAgICAgICAgIGFkZHJlc3NEZXRhaWxzOiAnVGVzdCBBZGRyZXNzJyxcbiAgICAgICAgICAgICAgICBjaXR5TmFtZTogJ0J1Y2hhcmVzdCcsXG4gICAgICAgICAgICAgICAgY291bnRyeUNvZGU6ICdSTycsXG4gICAgICAgICAgICAgICAgY291bnRyeU5hbWU6ICdSb21hbmlhJyxcbiAgICAgICAgICAgICAgICBjb3VudHlDb2RlOiAnUk8uQicsXG4gICAgICAgICAgICAgICAgY291bnR5TmFtZTogJ0J1Y2hhcmVzdCcsXG4gICAgICAgICAgICAgICAgaWRlbnRpZmljYXRpb25OdW1iZXI6ICcxMjM0NTY3OCcsXG4gICAgICAgICAgICAgICAgaXNMZWdhbFBlcnNvbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgcGFydG5lck5hbWU6ICdUZXN0IFBhcnRuZXInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGludm9pY2VEZXRhaWxzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBkaXNjb3VudEdyb3NzVmFsdWU6IDAsXG4gICAgICAgICAgICAgICAgICAgIGRpc2NvdW50TmV0VmFsdWU6IDAsXG4gICAgICAgICAgICAgICAgICAgIGRpc2NvdW50VmF0VmFsdWU6IDAsXG4gICAgICAgICAgICAgICAgICAgIGRpc2NvdW50VmFsdWVPbk5ldDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGdyb3NzQW1vdW50OiAxMTksXG4gICAgICAgICAgICAgICAgICAgIGl0ZW1Db2RlOiAnSVRFTS0wMDEnLFxuICAgICAgICAgICAgICAgICAgICBpdGVtRGVzY3JpcHRpb246ICdUZXN0IEl0ZW0nLFxuICAgICAgICAgICAgICAgICAgICBpdGVtRXh0ZXJuYWxJZDogJ2l0ZW0tZXh0LTEnLFxuICAgICAgICAgICAgICAgICAgICBpdGVtTmFtZTogJ1Rlc3QgSXRlbSBOYW1lJyxcbiAgICAgICAgICAgICAgICAgICAgbWVhc3VyZVVuaXRJZDogMSxcbiAgICAgICAgICAgICAgICAgICAgbmV0QW1vdW50OiAxMDAsXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsTmV0QW1vdW50OiAxMDAsXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsVmF0QW1vdW50OiAxOSxcbiAgICAgICAgICAgICAgICAgICAgcXVhbnRpdHk6IDEsXG4gICAgICAgICAgICAgICAgICAgIHVuTWVhc3VyZVVuaXQ6ICdidWMnLFxuICAgICAgICAgICAgICAgICAgICB1blZhdENhdGVnb3J5OiAnUycsXG4gICAgICAgICAgICAgICAgICAgIHVuVmF0RXhlbXB0aW9uUmVhc29uOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgdW5pdFByaWNlOiAxMDAsXG4gICAgICAgICAgICAgICAgICAgIHZhdEFtb3VudDogMTksXG4gICAgICAgICAgICAgICAgICAgIHZhdFBlcmNlbnQ6IDE5LFxuICAgICAgICAgICAgICAgICAgICBleGNpc2VBbW91bnQ6IDAsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBwYXltZW50VHlwZUlkOiAzLFxuICAgICAgICAgICAgcmVmZXJlbmNlQ3VycmVuY3lDb2RlOiAnUk9OJyxcbiAgICAgICAgICAgIHNlcmllczogJ1BESScsXG4gICAgICAgICAgICBzdGF0dXM6ICdkcmFmdCcsXG4gICAgICAgICAgICB2YXRBbW91bnQ6IDE5LFxuICAgICAgICAgICAgdmF0T25Db2xsZWN0aW9uOiBmYWxzZSxcbiAgICAgICAgfTtcblxuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLmdldCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvdGVzdC1jbGllbnQtZWlkL2ludm9pY2VzL2ludm9pY2UtZXh0LTEnKVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja1Jlc3BvbnNlKTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhcGlHZXRJbnZvaWNlQnlFeHRlcm5hbElkKHtcbiAgICAgICAgICAgIGJhc2VEb21haW46IFNUQUdJTkdfRE9NQUlOLFxuICAgICAgICAgICAgYXBwSWQ6ICd0ZXN0LWFwcC1pZCcsXG4gICAgICAgICAgICBhcHBDbGllbnRJZDogJ3Rlc3QtY2xpZW50LWVpZCcsXG4gICAgICAgICAgICBiZWFyZXJUb2tlbjogJ3Rlc3QtdG9rZW4nLFxuICAgICAgICAgICAgaW52b2ljZUlkOiAnaW52b2ljZS1leHQtMScsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGV4cGVjdChyZXN1bHQuZ3Jvc3NBbW91bnQpLnRvQmUoMTE5KTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdC5wYXJ0bmVyLnBhcnRuZXJOYW1lKS50b0JlKCdUZXN0IFBhcnRuZXInKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdC5pdGVtcykudG9IYXZlTGVuZ3RoKDEpO1xuICAgICAgICBleHBlY3QocmVzdWx0Lml0ZW1zWzBdLml0ZW1OYW1lKS50b0JlKCdUZXN0IEl0ZW0gTmFtZScpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIHRocm93IEtlZXpBcGlFcnJvciB3aGVuIGludm9pY2Ugbm90IGZvdW5kJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLmdldCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvdGVzdC1jbGllbnQtZWlkL2ludm9pY2VzL25vbi1leGlzdGVudCcpXG4gICAgICAgICAgICAucmVwbHkoNDA0LCB7IGVycm9yOiAnSW52b2ljZSBub3QgZm91bmQnIH0pO1xuXG4gICAgICAgIGF3YWl0IGV4cGVjdChhcGlHZXRJbnZvaWNlQnlFeHRlcm5hbElkKHtcbiAgICAgICAgICAgIGJhc2VEb21haW46IFNUQUdJTkdfRE9NQUlOLFxuICAgICAgICAgICAgYXBwSWQ6ICd0ZXN0LWFwcC1pZCcsXG4gICAgICAgICAgICBhcHBDbGllbnRJZDogJ3Rlc3QtY2xpZW50LWVpZCcsXG4gICAgICAgICAgICBiZWFyZXJUb2tlbjogJ3Rlc3QtdG9rZW4nLFxuICAgICAgICAgICAgaW52b2ljZUlkOiAnbm9uLWV4aXN0ZW50JyxcbiAgICAgICAgfSkpLnJlamVjdHMudG9UaHJvdyhLZWV6QXBpRXJyb3IpO1xuICAgIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdhcGlDcmVhdGVJbnZvaWNlJywgKCkgPT4ge1xuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Nob3VsZCBjcmVhdGUgaW52b2ljZSBzdWNjZXNzZnVsbHknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vY2tSZXNwb25zZSA9IHtcbiAgICAgICAgICAgIGV4dGVybmFsSWQ6ICduZXctaW52b2ljZS1leHQtaWQnLFxuICAgICAgICB9O1xuXG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvdGVzdC1jbGllbnQtZWlkL2ludm9pY2VzJylcbiAgICAgICAgICAgIC5yZXBseSgyMDEsIG1vY2tSZXNwb25zZSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXBpQ3JlYXRlSW52b2ljZSh7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYXBwQ2xpZW50SWQ6ICd0ZXN0LWNsaWVudC1laWQnLFxuICAgICAgICAgICAgYmVhcmVyVG9rZW46ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgICAgIGludm9pY2U6IHtcbiAgICAgICAgICAgICAgICBzZXJpZXM6ICdQREknLFxuICAgICAgICAgICAgICAgIGN1cnJlbmN5Q29kZTogJ1JPTicsXG4gICAgICAgICAgICAgICAgYW1vdW50OiAxMDAsXG4gICAgICAgICAgICAgICAgcGF5bWVudFR5cGU6IFBheW1lbnRUeXBlLkJBTktfVFJBTlNGRVIsXG4gICAgICAgICAgICAgICAgcGFydG5lcjoge1xuICAgICAgICAgICAgICAgICAgICBhZGRyZXNzRGV0YWlsczogJ1Rlc3QgQWRkcmVzcycsXG4gICAgICAgICAgICAgICAgICAgIGNpdHlOYW1lOiAnQnVjaGFyZXN0JyxcbiAgICAgICAgICAgICAgICAgICAgY291bnRyeUNvZGU6ICdSTycsXG4gICAgICAgICAgICAgICAgICAgIGNvdW50cnlOYW1lOiAnUm9tYW5pYScsXG4gICAgICAgICAgICAgICAgICAgIGNvdW50eUNvZGU6ICdSTy5CJyxcbiAgICAgICAgICAgICAgICAgICAgY291bnR5TmFtZTogJ0J1Y2hhcmVzdCcsXG4gICAgICAgICAgICAgICAgICAgIGlkZW50aWZpY2F0aW9uTnVtYmVyOiAnMTIzNDU2NzgnLFxuICAgICAgICAgICAgICAgICAgICBpc0xlZ2FsUGVyc29uOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgcGFydG5lck5hbWU6ICdUZXN0IFBhcnRuZXInLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgaXRlbUlkOiAnaXRlbS1leHQtMScsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBleHBlY3QocmVzdWx0KS50b0JlKCduZXctaW52b2ljZS1leHQtaWQnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Nob3VsZCBjcmVhdGUgaW52b2ljZSB3aXRoIGN1c3RvbSBkYXRlIGFuZCBxdWFudGl0eScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgbW9ja1Jlc3BvbnNlID0ge1xuICAgICAgICAgICAgZXh0ZXJuYWxJZDogJ25ldy1pbnZvaWNlLWV4dC1pZC0yJyxcbiAgICAgICAgfTtcblxuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLnBvc3QoJy9hcGkvdjEuMC9wdWJsaWMtYXBpL3Rlc3QtY2xpZW50LWVpZC9pbnZvaWNlcycsIChib2R5OiB7IGRvY3VtZW50RGF0ZTogbnVtYmVyOyBpbnZvaWNlRGV0YWlsczogeyBxdWFudGl0eTogbnVtYmVyIH1bXSB9KSA9PiBib2R5LmRvY3VtZW50RGF0ZSA9PT0gMjAyNDAxMTUgJiYgYm9keS5pbnZvaWNlRGV0YWlsc1swXS5xdWFudGl0eSA9PT0gNSlcbiAgICAgICAgICAgIC5yZXBseSgyMDEsIG1vY2tSZXNwb25zZSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXBpQ3JlYXRlSW52b2ljZSh7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYXBwQ2xpZW50SWQ6ICd0ZXN0LWNsaWVudC1laWQnLFxuICAgICAgICAgICAgYmVhcmVyVG9rZW46ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgICAgIGludm9pY2U6IHtcbiAgICAgICAgICAgICAgICBzZXJpZXM6ICdQREknLFxuICAgICAgICAgICAgICAgIGN1cnJlbmN5Q29kZTogJ1JPTicsXG4gICAgICAgICAgICAgICAgYW1vdW50OiA1MDAsXG4gICAgICAgICAgICAgICAgcGF5bWVudFR5cGU6IFBheW1lbnRUeXBlLkNBUkRfT05MSU5FLFxuICAgICAgICAgICAgICAgIHBhcnRuZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgYWRkcmVzc0RldGFpbHM6ICdUZXN0IEFkZHJlc3MnLFxuICAgICAgICAgICAgICAgICAgICBjaXR5TmFtZTogJ0J1Y2hhcmVzdCcsXG4gICAgICAgICAgICAgICAgICAgIGNvdW50cnlDb2RlOiAnUk8nLFxuICAgICAgICAgICAgICAgICAgICBjb3VudHJ5TmFtZTogJ1JvbWFuaWEnLFxuICAgICAgICAgICAgICAgICAgICBjb3VudHlDb2RlOiAnUk8uQicsXG4gICAgICAgICAgICAgICAgICAgIGNvdW50eU5hbWU6ICdCdWNoYXJlc3QnLFxuICAgICAgICAgICAgICAgICAgICBpZGVudGlmaWNhdGlvbk51bWJlcjogJzEyMzQ1Njc4JyxcbiAgICAgICAgICAgICAgICAgICAgaXNMZWdhbFBlcnNvbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHBhcnRuZXJOYW1lOiAnVGVzdCBQYXJ0bmVyJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGl0ZW1JZDogJ2l0ZW0tZXh0LTEnLFxuICAgICAgICAgICAgICAgIGRvY3VtZW50RGF0ZTogMjAyNDAxMTUsXG4gICAgICAgICAgICAgICAgZHVlRGF0ZTogMjAyNDAxMzAsXG4gICAgICAgICAgICAgICAgcXVhbnRpdHk6IDUsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBleHBlY3QocmVzdWx0KS50b0JlKCduZXctaW52b2ljZS1leHQtaWQtMicpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIHRocm93IEtlZXpBcGlFcnJvciBvbiB2YWxpZGF0aW9uIGVycm9yJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLnBvc3QoJy9hcGkvdjEuMC9wdWJsaWMtYXBpL3Rlc3QtY2xpZW50LWVpZC9pbnZvaWNlcycpXG4gICAgICAgICAgICAucmVwbHkoNDAwLCB7IE1lc3NhZ2U6ICdWYWxpZGF0aW9uIGZhaWxlZCcgfSk7XG5cbiAgICAgICAgYXdhaXQgZXhwZWN0KGFwaUNyZWF0ZUludm9pY2Uoe1xuICAgICAgICAgICAgYmFzZURvbWFpbjogU1RBR0lOR19ET01BSU4sXG4gICAgICAgICAgICBhcHBJZDogJ3Rlc3QtYXBwLWlkJyxcbiAgICAgICAgICAgIGFwcENsaWVudElkOiAndGVzdC1jbGllbnQtZWlkJyxcbiAgICAgICAgICAgIGJlYXJlclRva2VuOiAndGVzdC10b2tlbicsXG4gICAgICAgICAgICBpbnZvaWNlOiB7XG4gICAgICAgICAgICAgICAgc2VyaWVzOiAnUERJJyxcbiAgICAgICAgICAgICAgICBjdXJyZW5jeUNvZGU6ICdST04nLFxuICAgICAgICAgICAgICAgIGFtb3VudDogLTEwMCxcbiAgICAgICAgICAgICAgICBwYXltZW50VHlwZTogUGF5bWVudFR5cGUuQkFOS19UUkFOU0ZFUixcbiAgICAgICAgICAgICAgICBwYXJ0bmVyOiB7XG4gICAgICAgICAgICAgICAgICAgIGFkZHJlc3NEZXRhaWxzOiAnVGVzdCBBZGRyZXNzJyxcbiAgICAgICAgICAgICAgICAgICAgY2l0eU5hbWU6ICdCdWNoYXJlc3QnLFxuICAgICAgICAgICAgICAgICAgICBjb3VudHJ5Q29kZTogJ1JPJyxcbiAgICAgICAgICAgICAgICAgICAgY291bnRyeU5hbWU6ICdSb21hbmlhJyxcbiAgICAgICAgICAgICAgICAgICAgY291bnR5Q29kZTogJ1JPLkInLFxuICAgICAgICAgICAgICAgICAgICBjb3VudHlOYW1lOiAnQnVjaGFyZXN0JyxcbiAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmljYXRpb25OdW1iZXI6ICcnLFxuICAgICAgICAgICAgICAgICAgICBpc0xlZ2FsUGVyc29uOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgcGFydG5lck5hbWU6ICcnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgaXRlbUlkOiAnJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pKS5yZWplY3RzLnRvVGhyb3coS2VlekFwaUVycm9yKTtcbiAgICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnYXBpU2VuZEludm9pY2UnLCAoKSA9PiB7XG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIHNlbmQgaW52b2ljZSBlbWFpbCBzdWNjZXNzZnVsbHknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvaW52b2ljZXMvZGVsaXZlcnknKVxuICAgICAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXBpU2VuZEludm9pY2Uoe1xuICAgICAgICAgICAgYmFzZURvbWFpbjogU1RBR0lOR19ET01BSU4sXG4gICAgICAgICAgICBhcHBJZDogJ3Rlc3QtYXBwLWlkJyxcbiAgICAgICAgICAgIGJlYXJlclRva2VuOiAndGVzdC10b2tlbicsXG4gICAgICAgICAgICBjbGllbnRNYWlsOiAndGVzdEBleGFtcGxlLmNvbScsXG4gICAgICAgICAgICBpbnZvaWNlSWQ6ICdpbnZvaWNlLWV4dC0xJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZSgnU0VOVCcpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIHRocm93IEtlZXpBcGlFcnJvciBvbiBzZW5kIGZhaWx1cmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvaW52b2ljZXMvZGVsaXZlcnknKVxuICAgICAgICAgICAgLnJlcGx5KDUwMCwgeyBlcnJvcjogJ0VtYWlsIHNlcnZpY2UgdW5hdmFpbGFibGUnIH0pO1xuXG4gICAgICAgIGF3YWl0IGV4cGVjdChhcGlTZW5kSW52b2ljZSh7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYmVhcmVyVG9rZW46ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgICAgIGNsaWVudE1haWw6ICd0ZXN0QGV4YW1wbGUuY29tJyxcbiAgICAgICAgICAgIGludm9pY2VJZDogJ2ludm9pY2UtZXh0LTEnLFxuICAgICAgICB9KSkucmVqZWN0cy50b1Rocm93KEtlZXpBcGlFcnJvcik7XG4gICAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ2FwaVZhbGlkYXRlSW52b2ljZScsICgpID0+IHtcbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzaG91bGQgdmFsaWRhdGUgaW52b2ljZSBzdWNjZXNzZnVsbHknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvdGVzdC1jbGllbnQtZWlkL2ludm9pY2VzL3ZhbGlkJylcbiAgICAgICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGFwaVZhbGlkYXRlSW52b2ljZSh7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYXBwQ2xpZW50SWQ6ICd0ZXN0LWNsaWVudC1laWQnLFxuICAgICAgICAgICAgYmVhcmVyVG9rZW46ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgICAgIGludm9pY2VJZDogJ2ludm9pY2UtZXh0LTEnLFxuICAgICAgICB9KTtcblxuICAgICAgICBleHBlY3QocmVzdWx0KS50b0JlKCdWQUxJREFURUQnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Nob3VsZCB0aHJvdyBLZWV6QXBpRXJyb3Igb24gdmFsaWRhdGlvbiBmYWlsdXJlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLnBvc3QoJy9hcGkvdjEuMC9wdWJsaWMtYXBpL3Rlc3QtY2xpZW50LWVpZC9pbnZvaWNlcy92YWxpZCcpXG4gICAgICAgICAgICAucmVwbHkoNDAwLCB7IE1lc3NhZ2U6ICdJbnZvaWNlIGNhbm5vdCBiZSB2YWxpZGF0ZWQnIH0pO1xuXG4gICAgICAgIGF3YWl0IGV4cGVjdChhcGlWYWxpZGF0ZUludm9pY2Uoe1xuICAgICAgICAgICAgYmFzZURvbWFpbjogU1RBR0lOR19ET01BSU4sXG4gICAgICAgICAgICBhcHBJZDogJ3Rlc3QtYXBwLWlkJyxcbiAgICAgICAgICAgIGFwcENsaWVudElkOiAndGVzdC1jbGllbnQtZWlkJyxcbiAgICAgICAgICAgIGJlYXJlclRva2VuOiAndGVzdC10b2tlbicsXG4gICAgICAgICAgICBpbnZvaWNlSWQ6ICdpbnZhbGlkLWludm9pY2UnLFxuICAgICAgICB9KSkucmVqZWN0cy50b1Rocm93KEtlZXpBcGlFcnJvcik7XG4gICAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ0tlZXpBcGkgaW50ZWdyYXRpb24gdGVzdHMnLCAoKSA9PiB7XG4gICAgbGV0IGtlZXpBcGk6IEtlZXpBcGk7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAga2VlekFwaSA9IG5ldyBLZWV6QXBpKHtcbiAgICAgICAgICAgIGFwcGxpY2F0aW9uX2lkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgY2xpZW50X2VpZDogJ3Rlc3QtY2xpZW50LWVpZCcsXG4gICAgICAgICAgICBzZWNyZXQ6ICd0ZXN0LXNlY3JldCcsXG4gICAgICAgICAgICBsaXZlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzaG91bGQgYXV0by1yZWZyZXNoIHRva2VuIHdoZW4gZXhwaXJlZCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gTW9jayB0b2tlbiBnZW5lcmF0aW9uXG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2lkcC9jb25uZWN0L3Rva2VuJylcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgICAgICBhY2Nlc3NfdG9rZW46ICdmcmVzaC10b2tlbicsXG4gICAgICAgICAgICAgICAgZXhwaXJlc19pbjogMzYwMCxcbiAgICAgICAgICAgICAgICB0b2tlbl90eXBlOiAnQmVhcmVyJyxcbiAgICAgICAgICAgICAgICBzY29wZTogJ3B1YmxpYy1hcGknLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTW9jayBnZXQgYWxsIGludm9pY2VzXG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAuZ2V0KCcvYXBpL3YxLjAvcHVibGljLWFwaS90ZXN0LWNsaWVudC1laWQvaW52b2ljZXMnKVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgICAgIGZpcnN0OiAwLFxuICAgICAgICAgICAgICAgIGxhc3Q6IDAsXG4gICAgICAgICAgICAgICAgcmVjb3Jkc0NvdW50OiAwLFxuICAgICAgICAgICAgICAgIGRhdGE6IFtdLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQga2VlekFwaS5nZXRBbGxJbnZvaWNlcygpO1xuICAgICAgICBleHBlY3QocmVzdWx0LnJlY29yZHNDb3VudCkudG9CZSgwKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Nob3VsZCBjcmVhdGUgYW5kIHZhbGlkYXRlIGludm9pY2UgZmxvdycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gTW9jayB0b2tlbiBnZW5lcmF0aW9uXG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2lkcC9jb25uZWN0L3Rva2VuJylcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgICAgICBhY2Nlc3NfdG9rZW46ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgICAgICAgICBleHBpcmVzX2luOiAzNjAwLFxuICAgICAgICAgICAgICAgIHRva2VuX3R5cGU6ICdCZWFyZXInLFxuICAgICAgICAgICAgICAgIHNjb3BlOiAncHVibGljLWFwaScsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAvLyBNb2NrIGNyZWF0ZSBpbnZvaWNlXG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvdGVzdC1jbGllbnQtZWlkL2ludm9pY2VzJylcbiAgICAgICAgICAgIC5yZXBseSgyMDEsIHsgZXh0ZXJuYWxJZDogJ2NyZWF0ZWQtaW52b2ljZS1pZCcgfSk7XG5cbiAgICAgICAgY29uc3QgaW52b2ljZUlkID0gYXdhaXQga2VlekFwaS5jcmVhdGVJbnZvaWNlKHtcbiAgICAgICAgICAgIHNlcmllczogJ1BESScsXG4gICAgICAgICAgICBjdXJyZW5jeUNvZGU6ICdST04nLFxuICAgICAgICAgICAgYW1vdW50OiAxMDAsXG4gICAgICAgICAgICBwYXltZW50VHlwZTogUGF5bWVudFR5cGUuTUVBTF9WT1VDSEVSLFxuICAgICAgICAgICAgcGFydG5lcjoge1xuICAgICAgICAgICAgICAgIGFkZHJlc3NEZXRhaWxzOiAnVGVzdCBBZGRyZXNzJyxcbiAgICAgICAgICAgICAgICBjaXR5TmFtZTogJ0J1Y2hhcmVzdCcsXG4gICAgICAgICAgICAgICAgY291bnRyeUNvZGU6ICdSTycsXG4gICAgICAgICAgICAgICAgY291bnRyeU5hbWU6ICdSb21hbmlhJyxcbiAgICAgICAgICAgICAgICBjb3VudHlDb2RlOiAnUk8uQicsXG4gICAgICAgICAgICAgICAgY291bnR5TmFtZTogJ0J1Y2hhcmVzdCcsXG4gICAgICAgICAgICAgICAgaWRlbnRpZmljYXRpb25OdW1iZXI6ICcxMjM0NTY3OCcsXG4gICAgICAgICAgICAgICAgaXNMZWdhbFBlcnNvbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgcGFydG5lck5hbWU6ICdUZXN0IFBhcnRuZXInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGl0ZW1JZDogJ2l0ZW0tZXh0LTEnLFxuICAgICAgICB9KTtcblxuICAgICAgICBleHBlY3QoaW52b2ljZUlkKS50b0JlKCdjcmVhdGVkLWludm9pY2UtaWQnKTtcblxuICAgICAgICAvLyBNb2NrIHZhbGlkYXRlIGludm9pY2UgKHJldXNlIHRva2VuKVxuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLnBvc3QoJy9hcGkvdjEuMC9wdWJsaWMtYXBpL3Rlc3QtY2xpZW50LWVpZC9pbnZvaWNlcy92YWxpZCcpXG4gICAgICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgICBjb25zdCB2YWxpZGF0ZVJlc3VsdCA9IGF3YWl0IGtlZXpBcGkudmFsaWRhdGVJbnZvaWNlKCdjcmVhdGVkLWludm9pY2UtaWQnKTtcbiAgICAgICAgZXhwZWN0KHZhbGlkYXRlUmVzdWx0KS50b0JlKCdWQUxJREFURUQnKTtcbiAgICB9KTtcbn0pO1xuIl19