@paakd/api 0.0.1
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/dist/src/index.js +21 -0
- package/package.json +59 -0
- package/src/address.spec.ts +662 -0
- package/src/address.ts +300 -0
- package/src/auth.spec.ts +771 -0
- package/src/auth.ts +168 -0
- package/src/compressor/brotli.ts +26 -0
- package/src/index.ts +5 -0
- package/src/interceptors.spec.ts +1343 -0
- package/src/interceptors.ts +224 -0
- package/src/policies.spec.ts +595 -0
- package/src/policies.ts +431 -0
- package/src/products.spec.ts +710 -0
- package/src/products.ts +112 -0
- package/src/profile.spec.ts +626 -0
- package/src/profile.ts +169 -0
- package/src/proto/auth/v1/entities/auth.proto +140 -0
- package/src/proto/auth/v1/entities/policy.proto +57 -0
- package/src/proto/auth/v1/service.proto +26 -0
- package/src/proto/customers/v1/entities/address.proto +101 -0
- package/src/proto/customers/v1/entities/profile.proto +118 -0
- package/src/proto/customers/v1/service.proto +36 -0
- package/src/proto/files/v1/entities/file.proto +62 -0
- package/src/proto/files/v1/service.proto +19 -0
- package/src/proto/products/v1/entities/category.proto +98 -0
- package/src/proto/products/v1/entities/collection.proto +72 -0
- package/src/proto/products/v1/entities/product/create.proto +41 -0
- package/src/proto/products/v1/entities/product/option.proto +17 -0
- package/src/proto/products/v1/entities/product/shared.proto +255 -0
- package/src/proto/products/v1/entities/product/update.proto +66 -0
- package/src/proto/products/v1/entities/tag.proto +73 -0
- package/src/proto/products/v1/entities/taxonomy.proto +146 -0
- package/src/proto/products/v1/entities/type.proto +98 -0
- package/src/proto/products/v1/entities/variant.proto +127 -0
- package/src/proto/products/v1/service.proto +78 -0
- package/src/proto/promotions/v1/entities/campaign.proto +145 -0
- package/src/proto/promotions/v1/service.proto +17 -0
- package/src/proto/stocknodes/v1/entities/stocknode.proto +167 -0
- package/src/proto/stocknodes/v1/service.proto +21 -0
- package/src/registration.ts +170 -0
- package/src/test-utils.ts +176 -0
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
import { Code, ConnectError, createClient } from '@connectrpc/connect'
|
|
2
|
+
import { createGrpcTransport } from '@connectrpc/connect-node'
|
|
3
|
+
import { getCheckoutConfig } from '@paakd/config'
|
|
4
|
+
import {
|
|
5
|
+
createAuthenticationInterceptor,
|
|
6
|
+
createHeadersInterceptor,
|
|
7
|
+
} from './interceptors'
|
|
8
|
+
import {
|
|
9
|
+
addPolicies,
|
|
10
|
+
addPolicy,
|
|
11
|
+
getFilteredPolicy,
|
|
12
|
+
getPolicies,
|
|
13
|
+
removeFilteredPolicy,
|
|
14
|
+
removePolicies,
|
|
15
|
+
removePolicy,
|
|
16
|
+
savePolicies,
|
|
17
|
+
} from './policies'
|
|
18
|
+
|
|
19
|
+
// Mock dependencies
|
|
20
|
+
vi.mock('@connectrpc/connect', async () => {
|
|
21
|
+
const actual = await vi.importActual('@connectrpc/connect')
|
|
22
|
+
return {
|
|
23
|
+
...actual,
|
|
24
|
+
createClient: vi.fn(),
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
vi.mock('./compressor/brotli', () => ({
|
|
29
|
+
brotliCompression: {
|
|
30
|
+
name: 'brotli',
|
|
31
|
+
compress: vi.fn(),
|
|
32
|
+
decompress: vi.fn(),
|
|
33
|
+
},
|
|
34
|
+
}))
|
|
35
|
+
|
|
36
|
+
vi.mock('@connectrpc/connect-node', () => ({
|
|
37
|
+
createGrpcTransport: vi.fn(),
|
|
38
|
+
}))
|
|
39
|
+
|
|
40
|
+
vi.mock('@paakd/config', () => ({
|
|
41
|
+
getCheckoutConfig: vi.fn(),
|
|
42
|
+
}))
|
|
43
|
+
|
|
44
|
+
vi.mock('./interceptors', () => ({
|
|
45
|
+
createAuthenticationInterceptor: vi.fn(),
|
|
46
|
+
createHeadersInterceptor: vi.fn().mockReturnValue(() => {}),
|
|
47
|
+
}))
|
|
48
|
+
|
|
49
|
+
vi.mock('../gen/src/proto/auth/v1/service_pb', () => ({
|
|
50
|
+
AuthService: {},
|
|
51
|
+
}))
|
|
52
|
+
|
|
53
|
+
const mockGetCheckoutConfig = vi.mocked(getCheckoutConfig)
|
|
54
|
+
const mockCreateGrpcTransport = vi.mocked(createGrpcTransport)
|
|
55
|
+
const mockCreateClient = vi.mocked(createClient)
|
|
56
|
+
const mockCreateAuthenticationInterceptor = vi.mocked(
|
|
57
|
+
createAuthenticationInterceptor
|
|
58
|
+
)
|
|
59
|
+
const mockCreateHeadersInterceptor = vi.mocked(createHeadersInterceptor)
|
|
60
|
+
|
|
61
|
+
describe('policies', () => {
|
|
62
|
+
let mockAuthClient: any
|
|
63
|
+
let mockTransport: any
|
|
64
|
+
let mockCheckoutConfig: any
|
|
65
|
+
let mockInterceptor: any
|
|
66
|
+
|
|
67
|
+
beforeEach(() => {
|
|
68
|
+
// Reset all mocks
|
|
69
|
+
vi.clearAllMocks()
|
|
70
|
+
|
|
71
|
+
// Setup mock objects
|
|
72
|
+
mockAuthClient = {
|
|
73
|
+
getPolicies: vi.fn(),
|
|
74
|
+
savePolicies: vi.fn(),
|
|
75
|
+
addPolicy: vi.fn(),
|
|
76
|
+
addPolicies: vi.fn(),
|
|
77
|
+
removePolicy: vi.fn(),
|
|
78
|
+
removePolicies: vi.fn(),
|
|
79
|
+
removeFilteredPolicy: vi.fn(),
|
|
80
|
+
getFilteredPolicy: vi.fn(),
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
mockTransport = {}
|
|
84
|
+
mockCheckoutConfig = {
|
|
85
|
+
enterpriseURL: 'https://enterprise.example.com',
|
|
86
|
+
}
|
|
87
|
+
mockInterceptor = {}
|
|
88
|
+
|
|
89
|
+
// Setup mock implementations
|
|
90
|
+
mockGetCheckoutConfig.mockResolvedValue(mockCheckoutConfig)
|
|
91
|
+
mockCreateGrpcTransport.mockReturnValue(mockTransport)
|
|
92
|
+
mockCreateAuthenticationInterceptor.mockReturnValue(mockInterceptor)
|
|
93
|
+
mockCreateHeadersInterceptor.mockReturnValue(mockInterceptor)
|
|
94
|
+
mockCreateClient.mockReturnValue(mockAuthClient)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
describe('getPolicies', () => {
|
|
98
|
+
it('should return policies on success', async () => {
|
|
99
|
+
const mockPolicies = [
|
|
100
|
+
{ pType: 'p', v0: 'alice', v1: 'data1', v2: 'read' },
|
|
101
|
+
{ pType: 'p', v0: 'bob', v1: 'data2', v2: 'write' },
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
mockAuthClient.getPolicies.mockResolvedValue({
|
|
105
|
+
policies: mockPolicies,
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
const result = await getPolicies({
|
|
109
|
+
headers: {},
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
expect(getCheckoutConfig).toHaveBeenCalled()
|
|
113
|
+
expect(createGrpcTransport).toHaveBeenCalledWith({
|
|
114
|
+
baseUrl: mockCheckoutConfig.enterpriseURL,
|
|
115
|
+
interceptors: [mockInterceptor, mockInterceptor],
|
|
116
|
+
acceptCompression: expect.any(Array), // Accept gzip and Brotli compression
|
|
117
|
+
sendCompression: expect.any(Object), // Send Brotli compression
|
|
118
|
+
})
|
|
119
|
+
expect(createClient).toHaveBeenCalledWith({}, mockTransport)
|
|
120
|
+
expect(mockAuthClient.getPolicies).toHaveBeenCalledWith({})
|
|
121
|
+
|
|
122
|
+
expect(result).toEqual({
|
|
123
|
+
value: mockPolicies,
|
|
124
|
+
status: 'success',
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
it('should handle ConnectError', async () => {
|
|
129
|
+
const connectError = {
|
|
130
|
+
code: Code.Unauthenticated,
|
|
131
|
+
rawMessage: 'Invalid credentials',
|
|
132
|
+
message: 'Authentication failed',
|
|
133
|
+
name: 'ConnectError',
|
|
134
|
+
} as ConnectError
|
|
135
|
+
|
|
136
|
+
// Make it pass instanceof check
|
|
137
|
+
Object.setPrototypeOf(connectError, ConnectError.prototype)
|
|
138
|
+
|
|
139
|
+
mockAuthClient.getPolicies.mockRejectedValue(connectError)
|
|
140
|
+
|
|
141
|
+
const result = await getPolicies({
|
|
142
|
+
headers: {},
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
expect(result).toEqual({
|
|
146
|
+
...connectError,
|
|
147
|
+
message: 'Invalid credentials',
|
|
148
|
+
status: 'failed',
|
|
149
|
+
})
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it('should handle unexpected errors', async () => {
|
|
153
|
+
const unexpectedError = new Error('Network error')
|
|
154
|
+
mockAuthClient.getPolicies.mockRejectedValue(unexpectedError)
|
|
155
|
+
|
|
156
|
+
const result = await getPolicies({
|
|
157
|
+
headers: {},
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
expect(result).toEqual({
|
|
161
|
+
code: Code.Internal,
|
|
162
|
+
rawMessage: 'An unexpected error occurred during login.',
|
|
163
|
+
message: 'An unexpected error occurred during login.',
|
|
164
|
+
status: 'failed',
|
|
165
|
+
})
|
|
166
|
+
})
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
describe('savePolicies', () => {
|
|
170
|
+
it('should save policies successfully', async () => {
|
|
171
|
+
const inputPolicies = [
|
|
172
|
+
['p', 'alice', 'data1', 'read'],
|
|
173
|
+
['p', 'bob', 'data2', 'write'],
|
|
174
|
+
]
|
|
175
|
+
|
|
176
|
+
mockAuthClient.savePolicies.mockResolvedValue({})
|
|
177
|
+
|
|
178
|
+
const result = await savePolicies({
|
|
179
|
+
headers: {},
|
|
180
|
+
body: { inPolicies: inputPolicies },
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
expect(mockAuthClient.savePolicies).toHaveBeenCalledWith({
|
|
184
|
+
policies: [
|
|
185
|
+
{
|
|
186
|
+
pType: 'p',
|
|
187
|
+
v0: 'alice',
|
|
188
|
+
v1: 'data1',
|
|
189
|
+
v2: 'read',
|
|
190
|
+
v3: '',
|
|
191
|
+
v4: '',
|
|
192
|
+
v5: '',
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
pType: 'p',
|
|
196
|
+
v0: 'bob',
|
|
197
|
+
v1: 'data2',
|
|
198
|
+
v2: 'write',
|
|
199
|
+
v3: '',
|
|
200
|
+
v4: '',
|
|
201
|
+
v5: '',
|
|
202
|
+
},
|
|
203
|
+
],
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
expect(result).toEqual({ status: 'success' })
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
it('should handle policies with different lengths', async () => {
|
|
210
|
+
const inputPolicies = [
|
|
211
|
+
['p', 'alice'],
|
|
212
|
+
['p', 'bob', 'data2', 'write', 'extra1', 'extra2', 'extra3', 'extra4'],
|
|
213
|
+
]
|
|
214
|
+
|
|
215
|
+
mockAuthClient.savePolicies.mockResolvedValue({})
|
|
216
|
+
|
|
217
|
+
const result = await savePolicies({
|
|
218
|
+
headers: {},
|
|
219
|
+
body: { inPolicies: inputPolicies },
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
expect(mockAuthClient.savePolicies).toHaveBeenCalledWith({
|
|
223
|
+
policies: [
|
|
224
|
+
{ pType: 'p', v0: 'alice', v1: '', v2: '', v3: '', v4: '', v5: '' },
|
|
225
|
+
{
|
|
226
|
+
pType: 'p',
|
|
227
|
+
v0: 'bob',
|
|
228
|
+
v1: 'data2',
|
|
229
|
+
v2: 'write',
|
|
230
|
+
v3: 'extra1',
|
|
231
|
+
v4: 'extra2',
|
|
232
|
+
v5: 'extra3',
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
expect(result).toEqual({ status: 'success' })
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
it('should handle ConnectError', async () => {
|
|
241
|
+
const connectError = {
|
|
242
|
+
code: Code.Internal,
|
|
243
|
+
rawMessage: 'Database error',
|
|
244
|
+
message: 'Save failed',
|
|
245
|
+
name: 'ConnectError',
|
|
246
|
+
} as ConnectError
|
|
247
|
+
|
|
248
|
+
// Make it pass instanceof check
|
|
249
|
+
Object.setPrototypeOf(connectError, ConnectError.prototype)
|
|
250
|
+
|
|
251
|
+
mockAuthClient.savePolicies.mockRejectedValue(connectError)
|
|
252
|
+
|
|
253
|
+
const result = await savePolicies({
|
|
254
|
+
headers: {},
|
|
255
|
+
body: { inPolicies: [['p', 'alice']] },
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
expect(result).toEqual({
|
|
259
|
+
...connectError,
|
|
260
|
+
message: 'Database error',
|
|
261
|
+
status: 'failed',
|
|
262
|
+
})
|
|
263
|
+
})
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
describe('addPolicy', () => {
|
|
267
|
+
it('should add policy successfully', async () => {
|
|
268
|
+
const rule = ['alice', 'data1', 'read']
|
|
269
|
+
const pType = 'p'
|
|
270
|
+
|
|
271
|
+
mockAuthClient.addPolicy.mockResolvedValue({})
|
|
272
|
+
|
|
273
|
+
const result = await addPolicy({
|
|
274
|
+
headers: {},
|
|
275
|
+
body: { rule, pType },
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
expect(mockAuthClient.addPolicy).toHaveBeenCalledWith({ rule, pType })
|
|
279
|
+
|
|
280
|
+
expect(result).toEqual({ status: 'success' })
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
it('should handle ConnectError', async () => {
|
|
284
|
+
const connectError = {
|
|
285
|
+
code: Code.InvalidArgument,
|
|
286
|
+
rawMessage: 'Invalid policy format',
|
|
287
|
+
message: 'Add failed',
|
|
288
|
+
name: 'ConnectError',
|
|
289
|
+
} as ConnectError
|
|
290
|
+
|
|
291
|
+
// Make it pass instanceof check
|
|
292
|
+
Object.setPrototypeOf(connectError, ConnectError.prototype)
|
|
293
|
+
|
|
294
|
+
mockAuthClient.addPolicy.mockRejectedValue(connectError)
|
|
295
|
+
|
|
296
|
+
const result = await addPolicy({
|
|
297
|
+
headers: {},
|
|
298
|
+
body: { rule: ['alice'], pType: 'p' },
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
expect(result).toEqual({
|
|
302
|
+
...connectError,
|
|
303
|
+
message: 'Invalid policy format',
|
|
304
|
+
status: 'failed',
|
|
305
|
+
})
|
|
306
|
+
})
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
describe('addPolicies', () => {
|
|
310
|
+
it('should add multiple policies successfully', async () => {
|
|
311
|
+
const rules = [
|
|
312
|
+
['alice', 'data1', 'read'],
|
|
313
|
+
['bob', 'data2', 'write'],
|
|
314
|
+
]
|
|
315
|
+
const pType = 'p'
|
|
316
|
+
|
|
317
|
+
mockAuthClient.addPolicies.mockResolvedValue({})
|
|
318
|
+
|
|
319
|
+
const result = await addPolicies({
|
|
320
|
+
headers: {},
|
|
321
|
+
body: { inRules: rules, pType },
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
expect(mockAuthClient.addPolicies).toHaveBeenCalledWith({
|
|
325
|
+
rules: [
|
|
326
|
+
{ rules: ['alice', 'data1', 'read'] },
|
|
327
|
+
{ rules: ['bob', 'data2', 'write'] },
|
|
328
|
+
],
|
|
329
|
+
pType,
|
|
330
|
+
})
|
|
331
|
+
|
|
332
|
+
expect(result).toEqual({ status: 'success' })
|
|
333
|
+
})
|
|
334
|
+
|
|
335
|
+
it('should handle unexpected errors', async () => {
|
|
336
|
+
const unexpectedError = new Error('Network timeout')
|
|
337
|
+
mockAuthClient.addPolicies.mockRejectedValue(unexpectedError)
|
|
338
|
+
|
|
339
|
+
const result = await addPolicies({
|
|
340
|
+
headers: {},
|
|
341
|
+
body: { inRules: [['alice']], pType: 'p' },
|
|
342
|
+
})
|
|
343
|
+
|
|
344
|
+
expect(result).toEqual({
|
|
345
|
+
code: Code.Internal,
|
|
346
|
+
rawMessage: 'An unexpected error occurred while adding policies.',
|
|
347
|
+
message: 'An unexpected error occurred while adding policies.',
|
|
348
|
+
status: 'failed',
|
|
349
|
+
})
|
|
350
|
+
})
|
|
351
|
+
})
|
|
352
|
+
|
|
353
|
+
describe('removePolicy', () => {
|
|
354
|
+
it('should remove policy successfully', async () => {
|
|
355
|
+
const rule = ['alice', 'data1', 'read']
|
|
356
|
+
const pType = 'p'
|
|
357
|
+
|
|
358
|
+
mockAuthClient.removePolicy.mockResolvedValue({})
|
|
359
|
+
|
|
360
|
+
const result = await removePolicy({
|
|
361
|
+
headers: {},
|
|
362
|
+
body: { rule, pType },
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
expect(mockAuthClient.removePolicy).toHaveBeenCalledWith({ rule, pType })
|
|
366
|
+
|
|
367
|
+
expect(result).toEqual({ status: 'success' })
|
|
368
|
+
})
|
|
369
|
+
|
|
370
|
+
it('should handle ConnectError', async () => {
|
|
371
|
+
const connectError = {
|
|
372
|
+
code: Code.NotFound,
|
|
373
|
+
rawMessage: 'Policy not found',
|
|
374
|
+
message: 'Remove failed',
|
|
375
|
+
name: 'ConnectError',
|
|
376
|
+
} as ConnectError
|
|
377
|
+
|
|
378
|
+
// Make it pass instanceof check
|
|
379
|
+
Object.setPrototypeOf(connectError, ConnectError.prototype)
|
|
380
|
+
|
|
381
|
+
mockAuthClient.removePolicy.mockRejectedValue(connectError)
|
|
382
|
+
|
|
383
|
+
const result = await removePolicy({
|
|
384
|
+
headers: {},
|
|
385
|
+
body: { rule: ['alice'], pType: 'p' },
|
|
386
|
+
})
|
|
387
|
+
|
|
388
|
+
expect(result).toEqual({
|
|
389
|
+
...connectError,
|
|
390
|
+
message: 'Policy not found',
|
|
391
|
+
status: 'failed',
|
|
392
|
+
})
|
|
393
|
+
})
|
|
394
|
+
})
|
|
395
|
+
|
|
396
|
+
describe('removePolicies', () => {
|
|
397
|
+
it('should remove multiple policies successfully', async () => {
|
|
398
|
+
const rules = [
|
|
399
|
+
['alice', 'data1', 'read'],
|
|
400
|
+
['bob', 'data2', 'write'],
|
|
401
|
+
]
|
|
402
|
+
const pType = 'p'
|
|
403
|
+
|
|
404
|
+
mockAuthClient.removePolicies.mockResolvedValue({})
|
|
405
|
+
|
|
406
|
+
const result = await removePolicies({
|
|
407
|
+
headers: {},
|
|
408
|
+
body: { inRules: rules, pType },
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
expect(mockAuthClient.removePolicies).toHaveBeenCalledWith({
|
|
412
|
+
rules: [
|
|
413
|
+
{ rules: ['alice', 'data1', 'read'] },
|
|
414
|
+
{ rules: ['bob', 'data2', 'write'] },
|
|
415
|
+
],
|
|
416
|
+
pType,
|
|
417
|
+
})
|
|
418
|
+
|
|
419
|
+
expect(result).toEqual({ status: 'success' })
|
|
420
|
+
})
|
|
421
|
+
})
|
|
422
|
+
|
|
423
|
+
describe('removeFilteredPolicy', () => {
|
|
424
|
+
it('should remove filtered policy successfully', async () => {
|
|
425
|
+
const pType = 'p'
|
|
426
|
+
const fieldIndex = 0
|
|
427
|
+
const fieldValues = ['alice']
|
|
428
|
+
|
|
429
|
+
mockAuthClient.removeFilteredPolicy.mockResolvedValue({})
|
|
430
|
+
|
|
431
|
+
const result = await removeFilteredPolicy({
|
|
432
|
+
headers: {},
|
|
433
|
+
body: { pType, fieldIndex, fieldValues },
|
|
434
|
+
})
|
|
435
|
+
|
|
436
|
+
expect(mockAuthClient.removeFilteredPolicy).toHaveBeenCalledWith({
|
|
437
|
+
pType,
|
|
438
|
+
fieldIndex,
|
|
439
|
+
fieldValues,
|
|
440
|
+
})
|
|
441
|
+
|
|
442
|
+
expect(result).toEqual({ status: 'success' })
|
|
443
|
+
})
|
|
444
|
+
|
|
445
|
+
it('should handle ConnectError', async () => {
|
|
446
|
+
const connectError = {
|
|
447
|
+
code: Code.InvalidArgument,
|
|
448
|
+
rawMessage: 'Invalid filter criteria',
|
|
449
|
+
message: 'Filter failed',
|
|
450
|
+
name: 'ConnectError',
|
|
451
|
+
} as ConnectError
|
|
452
|
+
|
|
453
|
+
// Make it pass instanceof check
|
|
454
|
+
Object.setPrototypeOf(connectError, ConnectError.prototype)
|
|
455
|
+
|
|
456
|
+
mockAuthClient.removeFilteredPolicy.mockRejectedValue(connectError)
|
|
457
|
+
|
|
458
|
+
const result = await removeFilteredPolicy({
|
|
459
|
+
headers: {},
|
|
460
|
+
body: { pType: 'p', fieldIndex: 0, fieldValues: ['alice'] },
|
|
461
|
+
})
|
|
462
|
+
|
|
463
|
+
expect(result).toEqual({
|
|
464
|
+
...connectError,
|
|
465
|
+
message: 'Invalid filter criteria',
|
|
466
|
+
status: 'failed',
|
|
467
|
+
})
|
|
468
|
+
})
|
|
469
|
+
})
|
|
470
|
+
|
|
471
|
+
describe('getFilteredPolicy', () => {
|
|
472
|
+
it('should get filtered policies successfully', async () => {
|
|
473
|
+
const filter = {
|
|
474
|
+
v0: [['alice'], ['bob']],
|
|
475
|
+
v1: [['data1']],
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const mockPolicies = [
|
|
479
|
+
{ pType: 'p', v0: 'alice', v1: 'data1', v2: 'read' },
|
|
480
|
+
]
|
|
481
|
+
|
|
482
|
+
mockAuthClient.getFilteredPolicy.mockResolvedValue({
|
|
483
|
+
policies: mockPolicies,
|
|
484
|
+
})
|
|
485
|
+
|
|
486
|
+
const result = await getFilteredPolicy({
|
|
487
|
+
headers: {},
|
|
488
|
+
body: { inFilter: filter },
|
|
489
|
+
})
|
|
490
|
+
|
|
491
|
+
expect(mockAuthClient.getFilteredPolicy).toHaveBeenCalledWith({
|
|
492
|
+
filter: [
|
|
493
|
+
{
|
|
494
|
+
key: 'v0',
|
|
495
|
+
values: [{ items: ['alice'] }, { items: ['bob'] }],
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
key: 'v1',
|
|
499
|
+
values: [{ items: ['data1'] }],
|
|
500
|
+
},
|
|
501
|
+
],
|
|
502
|
+
})
|
|
503
|
+
|
|
504
|
+
expect(result).toEqual({
|
|
505
|
+
value: mockPolicies,
|
|
506
|
+
status: 'success',
|
|
507
|
+
})
|
|
508
|
+
})
|
|
509
|
+
|
|
510
|
+
it('should handle empty filter', async () => {
|
|
511
|
+
const filter = {}
|
|
512
|
+
|
|
513
|
+
mockAuthClient.getFilteredPolicy.mockResolvedValue({
|
|
514
|
+
policies: [],
|
|
515
|
+
})
|
|
516
|
+
|
|
517
|
+
const result = await getFilteredPolicy({
|
|
518
|
+
headers: {},
|
|
519
|
+
body: { inFilter: filter },
|
|
520
|
+
})
|
|
521
|
+
|
|
522
|
+
expect(mockAuthClient.getFilteredPolicy).toHaveBeenCalledWith({
|
|
523
|
+
filter: [],
|
|
524
|
+
})
|
|
525
|
+
|
|
526
|
+
expect(result).toEqual({
|
|
527
|
+
value: [],
|
|
528
|
+
status: 'success',
|
|
529
|
+
})
|
|
530
|
+
})
|
|
531
|
+
|
|
532
|
+
it('should handle unexpected errors', async () => {
|
|
533
|
+
const unexpectedError = new Error('Database connection failed')
|
|
534
|
+
mockAuthClient.getFilteredPolicy.mockRejectedValue(unexpectedError)
|
|
535
|
+
|
|
536
|
+
const result = await getFilteredPolicy({
|
|
537
|
+
headers: {},
|
|
538
|
+
body: { inFilter: {} },
|
|
539
|
+
})
|
|
540
|
+
|
|
541
|
+
expect(result).toEqual({
|
|
542
|
+
code: Code.Internal,
|
|
543
|
+
rawMessage: 'An unexpected error occurred while fetching policies.',
|
|
544
|
+
message: 'An unexpected error occurred while fetching policies.',
|
|
545
|
+
status: 'failed',
|
|
546
|
+
})
|
|
547
|
+
})
|
|
548
|
+
})
|
|
549
|
+
|
|
550
|
+
describe('common functionality', () => {
|
|
551
|
+
it('should setup transport and client consistently across all functions', async () => {
|
|
552
|
+
// Test one function to verify the setup pattern
|
|
553
|
+
await getPolicies({
|
|
554
|
+
headers: {},
|
|
555
|
+
})
|
|
556
|
+
|
|
557
|
+
expect(getCheckoutConfig).toHaveBeenCalled()
|
|
558
|
+
expect(createAuthenticationInterceptor).toHaveBeenCalledWith(
|
|
559
|
+
mockCheckoutConfig
|
|
560
|
+
)
|
|
561
|
+
expect(createGrpcTransport).toHaveBeenCalledWith({
|
|
562
|
+
baseUrl: mockCheckoutConfig.enterpriseURL,
|
|
563
|
+
interceptors: [mockInterceptor, mockInterceptor],
|
|
564
|
+
acceptCompression: expect.any(Array), // Accept gzip and Brotli compression
|
|
565
|
+
sendCompression: expect.any(Object), // Send Brotli compression
|
|
566
|
+
})
|
|
567
|
+
expect(createClient).toHaveBeenCalledWith({}, mockTransport)
|
|
568
|
+
})
|
|
569
|
+
|
|
570
|
+
it('should use consistent timeout across all functions', async () => {
|
|
571
|
+
mockAuthClient.getPolicies.mockResolvedValue({ policies: [] })
|
|
572
|
+
mockAuthClient.addPolicy.mockResolvedValue({})
|
|
573
|
+
mockAuthClient.removePolicy.mockResolvedValue({})
|
|
574
|
+
|
|
575
|
+
await getPolicies({
|
|
576
|
+
headers: {},
|
|
577
|
+
})
|
|
578
|
+
await addPolicy({
|
|
579
|
+
headers: {},
|
|
580
|
+
body: { rule: ['alice'], pType: 'p' },
|
|
581
|
+
})
|
|
582
|
+
await removePolicy({
|
|
583
|
+
headers: {},
|
|
584
|
+
body: { rule: ['bob'], pType: 'p' },
|
|
585
|
+
})
|
|
586
|
+
|
|
587
|
+
// Verify all calls use the same timeout
|
|
588
|
+
expect(mockAuthClient.getPolicies).toHaveBeenCalledWith({})
|
|
589
|
+
expect(mockAuthClient.addPolicy).toHaveBeenCalledWith(expect.any(Object))
|
|
590
|
+
expect(mockAuthClient.removePolicy).toHaveBeenCalledWith(
|
|
591
|
+
expect.any(Object)
|
|
592
|
+
)
|
|
593
|
+
})
|
|
594
|
+
})
|
|
595
|
+
})
|