pepr 0.36.0 → 0.37.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 (96) hide show
  1. package/dist/cli/init/index.d.ts.map +1 -1
  2. package/dist/cli/init/templates.d.ts +3 -1
  3. package/dist/cli/init/templates.d.ts.map +1 -1
  4. package/dist/cli/init/utils.d.ts.map +1 -1
  5. package/dist/cli/init/walkthrough.d.ts +10 -3
  6. package/dist/cli/init/walkthrough.d.ts.map +1 -1
  7. package/dist/cli.js +253 -31
  8. package/dist/controller.js +138 -1
  9. package/dist/lib/adjudicators.d.ts +63 -0
  10. package/dist/lib/adjudicators.d.ts.map +1 -0
  11. package/dist/lib/adjudicators.test.d.ts +2 -0
  12. package/dist/lib/adjudicators.test.d.ts.map +1 -0
  13. package/dist/lib/assets/loader.d.ts.map +1 -1
  14. package/dist/lib/assets/pods.d.ts +1 -0
  15. package/dist/lib/assets/pods.d.ts.map +1 -1
  16. package/dist/lib/capability.d.ts +1 -0
  17. package/dist/lib/capability.d.ts.map +1 -1
  18. package/dist/lib/capability.test.d.ts +2 -0
  19. package/dist/lib/capability.test.d.ts.map +1 -0
  20. package/dist/lib/controller/index.d.ts.map +1 -1
  21. package/dist/lib/controller/store.d.ts +4 -0
  22. package/dist/lib/controller/store.d.ts.map +1 -1
  23. package/dist/lib/controller/store.test.d.ts +2 -0
  24. package/dist/lib/controller/store.test.d.ts.map +1 -0
  25. package/dist/lib/filter.d.ts +2 -3
  26. package/dist/lib/filter.d.ts.map +1 -1
  27. package/dist/lib/filter.test.d.ts +2 -1
  28. package/dist/lib/filter.test.d.ts.map +1 -1
  29. package/dist/lib/finalizer.d.ts +6 -0
  30. package/dist/lib/finalizer.d.ts.map +1 -0
  31. package/dist/lib/finalizer.test.d.ts +2 -0
  32. package/dist/lib/finalizer.test.d.ts.map +1 -0
  33. package/dist/lib/helpers.d.ts +2 -2
  34. package/dist/lib/helpers.d.ts.map +1 -1
  35. package/dist/lib/helpers.test.d.ts +1 -1
  36. package/dist/lib/helpers.test.d.ts.map +1 -1
  37. package/dist/lib/k8s.d.ts.map +1 -1
  38. package/dist/lib/module.d.ts +2 -1
  39. package/dist/lib/module.d.ts.map +1 -1
  40. package/dist/lib/mutate-processor.d.ts +2 -1
  41. package/dist/lib/mutate-processor.d.ts.map +1 -1
  42. package/dist/lib/mutate-request.d.ts +1 -2
  43. package/dist/lib/mutate-request.d.ts.map +1 -1
  44. package/dist/lib/schedule.d.ts +1 -2
  45. package/dist/lib/schedule.d.ts.map +1 -1
  46. package/dist/lib/storage.d.ts.map +1 -1
  47. package/dist/lib/types.d.ts +115 -6
  48. package/dist/lib/types.d.ts.map +1 -1
  49. package/dist/lib/validate-processor.d.ts +4 -2
  50. package/dist/lib/validate-processor.d.ts.map +1 -1
  51. package/dist/lib/validate-request.d.ts +1 -1
  52. package/dist/lib/validate-request.d.ts.map +1 -1
  53. package/dist/lib/watch-processor.d.ts +1 -1
  54. package/dist/lib/watch-processor.d.ts.map +1 -1
  55. package/dist/lib.js +383 -204
  56. package/dist/lib.js.map +4 -4
  57. package/package.json +9 -7
  58. package/src/cli/build.ts +3 -3
  59. package/src/cli/init/index.ts +20 -11
  60. package/src/cli/init/templates.ts +1 -1
  61. package/src/cli/init/utils.test.ts +11 -20
  62. package/src/cli/init/utils.ts +5 -0
  63. package/src/cli/init/walkthrough.test.ts +92 -11
  64. package/src/cli/init/walkthrough.ts +71 -16
  65. package/src/cli/monitor.ts +1 -1
  66. package/src/cli.ts +4 -2
  67. package/src/fixtures/data/create-pod.json +1 -1
  68. package/src/fixtures/data/delete-pod.json +1 -1
  69. package/src/lib/adjudicators.test.ts +1232 -0
  70. package/src/lib/adjudicators.ts +235 -0
  71. package/src/lib/assets/index.ts +1 -1
  72. package/src/lib/assets/loader.ts +1 -0
  73. package/src/lib/assets/webhooks.ts +1 -1
  74. package/src/lib/capability.test.ts +655 -0
  75. package/src/lib/capability.ts +104 -11
  76. package/src/lib/controller/index.ts +7 -4
  77. package/src/lib/controller/store.test.ts +131 -0
  78. package/src/lib/controller/store.ts +43 -5
  79. package/src/lib/filter.test.ts +194 -8
  80. package/src/lib/filter.ts +46 -107
  81. package/src/lib/finalizer.test.ts +236 -0
  82. package/src/lib/finalizer.ts +63 -0
  83. package/src/lib/helpers.test.ts +329 -69
  84. package/src/lib/helpers.ts +141 -100
  85. package/src/lib/k8s.ts +4 -0
  86. package/src/lib/module.ts +3 -3
  87. package/src/lib/mutate-processor.ts +5 -4
  88. package/src/lib/mutate-request.test.ts +1 -2
  89. package/src/lib/mutate-request.ts +1 -3
  90. package/src/lib/schedule.ts +1 -1
  91. package/src/lib/storage.ts +5 -6
  92. package/src/lib/types.ts +151 -5
  93. package/src/lib/validate-processor.ts +5 -2
  94. package/src/lib/validate-request.test.ts +1 -4
  95. package/src/lib/validate-request.ts +1 -1
  96. package/src/lib/watch-processor.ts +19 -5
@@ -0,0 +1,1232 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+
4
+ import { expect, describe, it } from "@jest/globals";
5
+ import * as sut from "./adjudicators";
6
+ import { KubernetesObject } from "kubernetes-fluent-client";
7
+ import { AdmissionRequest, Binding, DeepPartial, Event, Operation } from "./types";
8
+
9
+ describe("definesDeletionTimestamp", () => {
10
+ //[ Binding, result ]
11
+ it.each([
12
+ [{}, false],
13
+ [{ filters: {} }, false],
14
+ [{ filters: { deletionTimestamp: null } }, false],
15
+ [{ filters: { deletionTimestamp: false } }, false],
16
+ [{ filters: { deletionTimestamp: true } }, true],
17
+ ])("given %j, returns %s", (given, expected) => {
18
+ const binding = given as DeepPartial<Binding>;
19
+
20
+ const result = sut.definesDeletionTimestamp(binding);
21
+
22
+ expect(result).toBe(expected);
23
+ });
24
+ });
25
+
26
+ describe("ignoresDeletionTimestamp", () => {
27
+ //[ Binding, result ]
28
+ it.each([
29
+ [{}, true],
30
+ [{ filters: {} }, true],
31
+ [{ filters: { deletionTimestamp: null } }, true],
32
+ [{ filters: { deletionTimestamp: false } }, true],
33
+ [{ filters: { deletionTimestamp: true } }, false],
34
+ ])("given %j, returns %s", (given, expected) => {
35
+ const binding = given as DeepPartial<Binding>;
36
+
37
+ const result = sut.ignoresDeletionTimestamp(binding);
38
+
39
+ expect(result).toBe(expected);
40
+ });
41
+ });
42
+
43
+ describe("carriesDeletionTimestamp", () => {
44
+ //[ KubernetesObject, result ]
45
+ it.each([
46
+ [{}, false],
47
+ [{ metadata: {} }, false],
48
+ [{ metadata: { deletionTimestamp: null } }, false],
49
+ [{ metadata: { deletionTimestamp: new Date() } }, true],
50
+ ])("given %j, returns %s", (given, expected) => {
51
+ const ko = given as DeepPartial<KubernetesObject>;
52
+
53
+ const result = sut.carriesDeletionTimestamp(ko);
54
+
55
+ expect(result).toBe(expected);
56
+ });
57
+ });
58
+
59
+ describe("missingDeletionTimestamp", () => {
60
+ //[ KubernetesObject, result ]
61
+ it.each([
62
+ [{}, true],
63
+ [{ metadata: {} }, true],
64
+ [{ metadata: { deletionTimestamp: null } }, true],
65
+ [{ metadata: { deletionTimestamp: new Date() } }, false],
66
+ ])("given %j, returns %s", (given, expected) => {
67
+ const ko = given as DeepPartial<KubernetesObject>;
68
+
69
+ const result = sut.missingDeletionTimestamp(ko);
70
+
71
+ expect(result).toBe(expected);
72
+ });
73
+ });
74
+
75
+ describe("mismatchedDeletionTimestamp", () => {
76
+ //[ Binding, KubernetesObject, result ]
77
+ it.each([
78
+ [{}, {}, false],
79
+ [{}, { metadata: { deletionTimestamp: new Date() } }, false],
80
+ [{ filters: { deletionTimestamp: true } }, {}, true],
81
+ [{ filters: { deletionTimestamp: true } }, { metadata: { deletionTimestamp: new Date() } }, false],
82
+ ])("given binding %j and object %j, returns %s", (bnd, obj, expected) => {
83
+ const binding = bnd as DeepPartial<Binding>;
84
+ const object = obj as DeepPartial<KubernetesObject>;
85
+
86
+ const result = sut.mismatchedDeletionTimestamp(binding, object);
87
+
88
+ expect(result).toBe(expected);
89
+ });
90
+ });
91
+
92
+ describe("definedName", () => {
93
+ //[ Binding, result ]
94
+ it.each([
95
+ [{}, ""],
96
+ [{ filters: {} }, ""],
97
+ [{ filters: { name: null } }, ""],
98
+ [{ filters: { name: "name" } }, "name"],
99
+ ])("given %j, returns '%s'", (given, expected) => {
100
+ const binding = given as DeepPartial<Binding>;
101
+
102
+ const result = sut.definedName(binding);
103
+
104
+ expect(result).toBe(expected);
105
+ });
106
+ });
107
+
108
+ describe("definesName", () => {
109
+ //[ Binding, result ]
110
+ it.each([
111
+ [{}, false],
112
+ [{ filters: {} }, false],
113
+ [{ filters: { name: null } }, false],
114
+ [{ filters: { name: "name" } }, true],
115
+ ])("given %j, returns %s", (given, expected) => {
116
+ const binding = given as DeepPartial<Binding>;
117
+
118
+ const result = sut.definesName(binding);
119
+
120
+ expect(result).toBe(expected);
121
+ });
122
+ });
123
+
124
+ describe("ignoresName", () => {
125
+ //[ Binding, result ]
126
+ it.each([
127
+ [{}, true],
128
+ [{ filters: {} }, true],
129
+ [{ filters: { name: null } }, true],
130
+ [{ filters: { name: "name" } }, false],
131
+ ])("given %j, returns %s", (given, expected) => {
132
+ const binding = given as DeepPartial<Binding>;
133
+
134
+ const result = sut.ignoresName(binding);
135
+
136
+ expect(result).toBe(expected);
137
+ });
138
+ });
139
+
140
+ describe("definedNameRegex", () => {
141
+ //[ Binding, result ]
142
+ it.each([
143
+ [{}, ""],
144
+ [{ filters: {} }, ""],
145
+ [{ filters: { regexName: null } }, ""],
146
+ [{ filters: { regexName: "n.me" } }, "n.me"],
147
+ ])("given %j, returns '%s'", (given, expected) => {
148
+ const binding = given as DeepPartial<Binding>;
149
+
150
+ const result = sut.definedNameRegex(binding);
151
+
152
+ expect(result).toBe(expected);
153
+ });
154
+ });
155
+
156
+ describe("definesNameRegex", () => {
157
+ //[ Binding, result ]
158
+ it.each([
159
+ [{}, false],
160
+ [{ filters: {} }, false],
161
+ [{ filters: { regexName: null } }, false],
162
+ [{ filters: { regexName: "n.me" } }, true],
163
+ ])("given %j, returns %s", (given, expected) => {
164
+ const binding = given as DeepPartial<Binding>;
165
+
166
+ const result = sut.definesNameRegex(binding);
167
+
168
+ expect(result).toBe(expected);
169
+ });
170
+ });
171
+
172
+ describe("carriedName", () => {
173
+ //[ KubernetesObject, result ]
174
+ it.each([
175
+ [{}, ""],
176
+ [{ metadata: {} }, ""],
177
+ [{ metadata: { name: null } }, ""],
178
+ [{ metadata: { name: "name" } }, "name"],
179
+ ])("given %j, returns '%s'", (given, expected) => {
180
+ const binding = given as DeepPartial<Binding>;
181
+
182
+ const result = sut.carriedName(binding);
183
+
184
+ expect(result).toBe(expected);
185
+ });
186
+ });
187
+
188
+ describe("carriesName", () => {
189
+ //[ KubernetesObject, result ]
190
+ it.each([
191
+ [{}, false],
192
+ [{ metadata: {} }, false],
193
+ [{ metadata: { name: null } }, false],
194
+ [{ metadata: { name: "name" } }, true],
195
+ ])("given %j, returns %s", (given, expected) => {
196
+ const binding = given as DeepPartial<Binding>;
197
+
198
+ const result = sut.carriesName(binding);
199
+
200
+ expect(result).toBe(expected);
201
+ });
202
+ });
203
+
204
+ describe("missingName", () => {
205
+ //[ Binding, result ]
206
+ it.each([
207
+ [{}, true],
208
+ [{ metadata: {} }, true],
209
+ [{ metadata: { name: null } }, true],
210
+ [{ metadata: { name: "name" } }, false],
211
+ ])("given %j, returns %s", (given, expected) => {
212
+ const binding = given as DeepPartial<Binding>;
213
+
214
+ const result = sut.missingName(binding);
215
+
216
+ expect(result).toBe(expected);
217
+ });
218
+ });
219
+
220
+ describe("mismatchedName", () => {
221
+ //[ Binding, KubernetesObject, result ]
222
+ it.each([
223
+ [{}, {}, false],
224
+ [{}, { metadata: { name: "name" } }, false],
225
+ [{ filters: { name: "name" } }, {}, true],
226
+ [{ filters: { name: "name" } }, { metadata: { name: "name" } }, false],
227
+ ])("given binding %j and object %j, returns %s", (bnd, obj, expected) => {
228
+ const binding = bnd as DeepPartial<Binding>;
229
+ const object = obj as DeepPartial<KubernetesObject>;
230
+
231
+ const result = sut.mismatchedName(binding, object);
232
+
233
+ expect(result).toBe(expected);
234
+ });
235
+ });
236
+
237
+ describe("mismatchedNameRegex", () => {
238
+ //[ Binding, KubernetesObject, result ]
239
+ it.each([
240
+ [{}, {}, false],
241
+ [{}, { metadata: { name: "name" } }, false],
242
+ [{ filters: { regexName: "^n[aeiou]me$" } }, {}, true],
243
+ [{ filters: { regexName: "^n[aeiou]me$" } }, { metadata: { name: "name" } }, false],
244
+ [{ filters: { regexName: "^n[aeiou]me$" } }, { metadata: { name: "neme" } }, false],
245
+ [{ filters: { regexName: "^n[aeiou]me$" } }, { metadata: { name: "nime" } }, false],
246
+ [{ filters: { regexName: "^n[aeiou]me$" } }, { metadata: { name: "nome" } }, false],
247
+ [{ filters: { regexName: "^n[aeiou]me$" } }, { metadata: { name: "nume" } }, false],
248
+ [{ filters: { regexName: "^n[aeiou]me$" } }, { metadata: { name: "n3me" } }, true],
249
+ ])("given binding %j and object %j, returns %s", (bnd, obj, expected) => {
250
+ const binding = bnd as DeepPartial<Binding>;
251
+ const object = obj as DeepPartial<KubernetesObject>;
252
+
253
+ const result = sut.mismatchedNameRegex(binding, object);
254
+
255
+ expect(result).toBe(expected);
256
+ });
257
+ });
258
+
259
+ describe("bindsToKind", () => {
260
+ //[ Binding, Kind, result ]
261
+ it.each([
262
+ [{}, "", false],
263
+ [{ kind: {} }, "", false],
264
+ [{ kind: { kind: null } }, "", false],
265
+ [{ kind: { kind: "" } }, "", false],
266
+ [{}, "Kind", false],
267
+ [{ kind: {} }, "Kind", false],
268
+ [{ kind: { kind: null } }, "Kind", false],
269
+ [{ kind: { kind: "" } }, "Kind", false],
270
+ [{ kind: { kind: "Kind" } }, "Kind", true],
271
+ ])("given binding %j, and kind '%s', returns %s", (bnd, knd, expected) => {
272
+ const binding = bnd as DeepPartial<Binding>;
273
+ const kind = knd as string;
274
+
275
+ const result = sut.bindsToKind(binding, kind);
276
+
277
+ expect(result).toBe(expected);
278
+ });
279
+ });
280
+
281
+ describe("bindsToNamespace", () => {
282
+ //[ Binding, result ]
283
+ it.each([
284
+ [{}, false],
285
+ [{ kind: {} }, false],
286
+ [{ kind: { kind: null } }, false],
287
+ [{ kind: { kind: "" } }, false],
288
+ [{ kind: { kind: "Namespace" } }, true],
289
+ ])("given binding %j returns %s", (bnd, expected) => {
290
+ const binding = bnd as DeepPartial<Binding>;
291
+
292
+ const result = sut.bindsToNamespace(binding);
293
+
294
+ expect(result).toBe(expected);
295
+ });
296
+ });
297
+
298
+ describe("definedNamespaces", () => {
299
+ //[ Binding, result ]
300
+ it.each([
301
+ [{}, []],
302
+ [{ filters: {} }, []],
303
+ [{ filters: { namespaces: null } }, []],
304
+ [{ filters: { namespaces: [] } }, []],
305
+ [{ filters: { namespaces: ["namespace"] } }, ["namespace"]],
306
+ [{ filters: { namespaces: ["name", "space"] } }, ["name", "space"]],
307
+ ])("given %j, returns %j", (given, expected) => {
308
+ const binding = given as DeepPartial<Binding>;
309
+
310
+ const result = sut.definedNamespaces(binding);
311
+
312
+ expect(result).toEqual(expected);
313
+ });
314
+ });
315
+
316
+ describe("definesNamespaces", () => {
317
+ //[ Binding, result ]
318
+ it.each([
319
+ [{}, false],
320
+ [{ filters: {} }, false],
321
+ [{ filters: { namespaces: null } }, false],
322
+ [{ filters: { namespaces: [] } }, false],
323
+ [{ filters: { namespaces: ["namespace"] } }, true],
324
+ [{ filters: { namespaces: ["name", "space"] } }, true],
325
+ ])("given %j, returns %s", (given, expected) => {
326
+ const binding = given as DeepPartial<Binding>;
327
+
328
+ const result = sut.definesNamespaces(binding);
329
+
330
+ expect(result).toBe(expected);
331
+ });
332
+ });
333
+
334
+ describe("definedNamespaceRegexes", () => {
335
+ //[ Binding, result ]
336
+ it.each([
337
+ [{}, []],
338
+ [{ filters: {} }, []],
339
+ [{ filters: { regexNamespaces: null } }, []],
340
+ [{ filters: { regexNamespaces: [] } }, []],
341
+ [{ filters: { regexNamespaces: ["n.mesp.ce"] } }, ["n.mesp.ce"]],
342
+ [{ filters: { regexNamespaces: ["n.me", "sp.ce"] } }, ["n.me", "sp.ce"]],
343
+ ])("given %j, returns %j", (given, expected) => {
344
+ const binding = given as DeepPartial<Binding>;
345
+
346
+ const result = sut.definedNamespaceRegexes(binding);
347
+
348
+ expect(result).toEqual(expected);
349
+ });
350
+ });
351
+
352
+ describe("definesNamespaceRegexes", () => {
353
+ //[ Binding, result ]
354
+ it.each([
355
+ [{}, false],
356
+ [{ filters: {} }, false],
357
+ [{ filters: { regexNamespaces: null } }, false],
358
+ [{ filters: { regexNamespaces: [] } }, false],
359
+ [{ filters: { regexNamespaces: ["n.mesp.ce"] } }, true],
360
+ [{ filters: { regexNamespaces: ["n.me", "sp.ce"] } }, true],
361
+ ])("given %j, returns %s", (given, expected) => {
362
+ const binding = given as DeepPartial<Binding>;
363
+
364
+ const result = sut.definesNamespaceRegexes(binding);
365
+
366
+ expect(result).toBe(expected);
367
+ });
368
+ });
369
+
370
+ describe("carriedNamespace", () => {
371
+ //[ KubernetesObject, result ]
372
+ it.each([
373
+ [{}, ""],
374
+ [{ metadata: {} }, ""],
375
+ [{ metadata: { namespace: null } }, ""],
376
+ [{ metadata: { namespace: "" } }, ""],
377
+ [{ metadata: { namespace: "namespace" } }, "namespace"],
378
+ ])("given %j, returns %j", (given, expected) => {
379
+ const binding = given as DeepPartial<Binding>;
380
+
381
+ const result = sut.carriedNamespace(binding);
382
+
383
+ expect(result).toEqual(expected);
384
+ });
385
+ });
386
+
387
+ describe("carriesNamespace", () => {
388
+ //[ KubernetesObject, result ]
389
+ it.each([
390
+ [{}, false],
391
+ [{ metadata: {} }, false],
392
+ [{ metadata: { namespace: null } }, false],
393
+ [{ metadata: { namespace: "" } }, false],
394
+ [{ metadata: { namespace: "namespace" } }, true],
395
+ ])("given %j, returns %s", (given, expected) => {
396
+ const binding = given as DeepPartial<Binding>;
397
+
398
+ const result = sut.carriesNamespace(binding);
399
+
400
+ expect(result).toBe(expected);
401
+ });
402
+ });
403
+
404
+ describe("mismatchedNamespace", () => {
405
+ //[ Binding, KubernetesObject, result ]
406
+ it.each([
407
+ [{}, {}, false],
408
+ [{}, { metadata: { namespace: "namespace" } }, false],
409
+ [{ filters: { namespaces: ["namespace"] } }, {}, true],
410
+ [{ filters: { namespaces: ["namespace"] } }, { metadata: { namespace: "nopesause" } }, true],
411
+ [{ filters: { namespaces: ["namespace"] } }, { metadata: { namespace: "namespace" } }, false],
412
+ ])("given binding %j and object %j, returns %s", (bnd, obj, expected) => {
413
+ const binding = bnd as DeepPartial<Binding>;
414
+ const object = obj as DeepPartial<Binding>;
415
+
416
+ const result = sut.mismatchedNamespace(binding, object);
417
+
418
+ expect(result).toBe(expected);
419
+ });
420
+ });
421
+
422
+ describe("mismatchedNamespaceRegex", () => {
423
+ //[ Binding, KubernetesObject, result ]
424
+ it.each([
425
+ [{}, {}, false],
426
+ [{}, { metadata: { namespace: "namespace" } }, false],
427
+ [{ filters: { regexNamespaces: ["^n.mespace$"] } }, {}, true],
428
+
429
+ [{ filters: { regexNamespaces: ["^n[aeiou]mespace$"] } }, { metadata: { namespace: "namespace" } }, false],
430
+ [{ filters: { regexNamespaces: ["^n[aeiou]mespace$"] } }, { metadata: { namespace: "nemespace" } }, false],
431
+ [{ filters: { regexNamespaces: ["^n[aeiou]mespace$"] } }, { metadata: { namespace: "nimespace" } }, false],
432
+ [{ filters: { regexNamespaces: ["^n[aeiou]mespace$"] } }, { metadata: { namespace: "nomespace" } }, false],
433
+ [{ filters: { regexNamespaces: ["^n[aeiou]mespace$"] } }, { metadata: { namespace: "numespace" } }, false],
434
+ [{ filters: { regexNamespaces: ["^n[aeiou]mespace$"] } }, { metadata: { namespace: "n3mespace" } }, true],
435
+
436
+ [{ filters: { regexNamespaces: ["^n[aeiou]me$", "^sp[aeiou]ce$"] } }, { metadata: { namespace: "name" } }, false],
437
+ [{ filters: { regexNamespaces: ["^n[aeiou]me$", "^sp[aeiou]ce$"] } }, { metadata: { namespace: "space" } }, false],
438
+ [
439
+ { filters: { regexNamespaces: ["^n[aeiou]me$", "^sp[aeiou]ce$"] } },
440
+ { metadata: { namespace: "namespace" } },
441
+ true,
442
+ ],
443
+ ])("given binding %j and object %j, returns %s", (bnd, obj, expected) => {
444
+ const binding = bnd as DeepPartial<Binding>;
445
+ const object = obj as DeepPartial<Binding>;
446
+
447
+ const result = sut.mismatchedNamespaceRegex(binding, object);
448
+
449
+ expect(result).toBe(expected);
450
+ });
451
+ });
452
+
453
+ describe("misboundNamespace", () => {
454
+ //[ Binding, result ]
455
+ it.each([
456
+ [{ kind: { kind: "Kind" }, filters: { namespaces: [] } }, false],
457
+ [{ kind: { kind: "Kind" }, filters: { namespaces: ["namespace"] } }, false],
458
+ [{ kind: { kind: "Namespace" }, filters: { namespaces: [] } }, false],
459
+ [{ kind: { kind: "Namespace" }, filters: { namespaces: ["namespace"] } }, true],
460
+ ])("given %j, returns %s", (given, expected) => {
461
+ const binding = given as DeepPartial<Binding>;
462
+
463
+ const result = sut.misboundNamespace(binding);
464
+
465
+ expect(result).toBe(expected);
466
+ });
467
+ });
468
+
469
+ describe("definedAnnotations", () => {
470
+ //[ Binding, result ]
471
+ it.each([
472
+ [{}, {}],
473
+ [{ filters: {} }, {}],
474
+ [{ filters: { annotations: null } }, {}],
475
+ [{ filters: { annotations: {} } }, {}],
476
+ [{ filters: { annotations: { annotation: "" } } }, { annotation: "" }],
477
+ [{ filters: { annotations: { anno: "tation" } } }, { anno: "tation" }],
478
+ ])("given %j, returns %j", (given, expected) => {
479
+ const binding = given as DeepPartial<Binding>;
480
+
481
+ const result = sut.definedAnnotations(binding);
482
+
483
+ expect(result).toEqual(expected);
484
+ });
485
+ });
486
+
487
+ describe("definesAnnotations", () => {
488
+ //[ Binding, result ]
489
+ it.each([
490
+ [{}, false],
491
+ [{ filters: {} }, false],
492
+ [{ filters: { annotations: null } }, false],
493
+ [{ filters: { annotations: {} } }, false],
494
+ [{ filters: { annotations: { annotation: "" } } }, true],
495
+ [{ filters: { annotations: { anno: "tation" } } }, true],
496
+ ])("given %j, returns %s", (given, expected) => {
497
+ const binding = given as DeepPartial<Binding>;
498
+
499
+ const result = sut.definesAnnotations(binding);
500
+
501
+ expect(result).toBe(expected);
502
+ });
503
+ });
504
+
505
+ describe("carriedAnnotations", () => {
506
+ //[ KuberneteObject, result ]
507
+ it.each([
508
+ [{}, {}],
509
+ [{ metadata: {} }, {}],
510
+ [{ metadata: { annotations: null } }, {}],
511
+ [{ metadata: { annotations: {} } }, {}],
512
+ [{ metadata: { annotations: { annotation: "" } } }, { annotation: "" }],
513
+ [{ metadata: { annotations: { anno: "tation" } } }, { anno: "tation" }],
514
+ ])("given %j, returns %j", (given, expected) => {
515
+ const binding = given as DeepPartial<KubernetesObject>;
516
+
517
+ const result = sut.carriedAnnotations(binding);
518
+
519
+ expect(result).toEqual(expected);
520
+ });
521
+ });
522
+
523
+ describe("carriesAnnotations", () => {
524
+ //[ KubernetesObject, result ]
525
+ it.each([
526
+ [{}, false],
527
+ [{ metadata: {} }, false],
528
+ [{ metadata: { annotations: null } }, false],
529
+ [{ metadata: { annotations: {} } }, false],
530
+ [{ metadata: { annotations: { annotation: "" } } }, true],
531
+ [{ metadata: { annotations: { anno: "tation" } } }, true],
532
+ ])("given %j, returns %s", (given, expected) => {
533
+ const binding = given as DeepPartial<KubernetesObject>;
534
+
535
+ const result = sut.carriesAnnotations(binding);
536
+
537
+ expect(result).toBe(expected);
538
+ });
539
+ });
540
+
541
+ describe("metasMismatch", () => {
542
+ it.each([
543
+ [{}, {}, false],
544
+ [{}, { anno: "tate" }, false],
545
+
546
+ [{ anno: "" }, {}, true],
547
+ [{ anno: "" }, { anno: "" }, false],
548
+ [{ anno: "" }, { anno: "tate" }, false],
549
+
550
+ [{ anno: "tate" }, {}, true],
551
+ [{ anno: "tate" }, { anno: "" }, true],
552
+ [{ anno: "tate" }, { anno: "tate" }, false],
553
+
554
+ [{ an: "no", ta: "te" }, { an: "" }, true],
555
+ [{ an: "no", ta: "te" }, { an: "no" }, true],
556
+ [{ an: "no", ta: "te" }, { an: "no", ta: "" }, true],
557
+ [{ an: "no", ta: "te" }, { an: "no", ta: "te" }, false],
558
+ ])("given left %j and right %j, returns %s", (bnd, obj, expected) => {
559
+ const result = sut.metasMismatch(bnd, obj);
560
+
561
+ expect(result).toBe(expected);
562
+ });
563
+ });
564
+
565
+ describe("mismatchedAnnotations", () => {
566
+ //[ Binding, KubernetesObject, result ]
567
+ it.each([
568
+ [{}, {}, false],
569
+ [{}, { metadata: { annotations: { anno: "tate" } } }, false],
570
+
571
+ [{ filters: { annotations: { anno: "" } } }, {}, true],
572
+ [{ filters: { annotations: { anno: "" } } }, { metadata: { annotations: { anno: "" } } }, false],
573
+ [{ filters: { annotations: { anno: "" } } }, { metadata: { annotations: { anno: "tate" } } }, false],
574
+
575
+ [{ filters: { annotations: { anno: "tate" } } }, {}, true],
576
+ [{ filters: { annotations: { anno: "tate" } } }, { metadata: { annotations: { anno: "" } } }, true],
577
+ [{ filters: { annotations: { anno: "tate" } } }, { metadata: { annotations: { anno: "tate" } } }, false],
578
+
579
+ [{ filters: { annotations: { an: "no", ta: "te" } } }, { metadata: { annotations: { an: "" } } }, true],
580
+ [{ filters: { annotations: { an: "no", ta: "te" } } }, { metadata: { annotations: { an: "no" } } }, true],
581
+ [{ filters: { annotations: { an: "no", ta: "te" } } }, { metadata: { annotations: { an: "no", ta: "" } } }, true],
582
+ [
583
+ { filters: { annotations: { an: "no", ta: "te" } } },
584
+ { metadata: { annotations: { an: "no", ta: "te" } } },
585
+ false,
586
+ ],
587
+ ])("given binding %j and object %j, returns %s", (bnd, obj, expected) => {
588
+ const binding = bnd as DeepPartial<Binding>;
589
+ const object = obj as DeepPartial<Binding>;
590
+
591
+ const result = sut.mismatchedAnnotations(binding, object);
592
+
593
+ expect(result).toBe(expected);
594
+ });
595
+ });
596
+
597
+ describe("definedLabels", () => {
598
+ //[ Binding, result ]
599
+ it.each([
600
+ [{}, {}],
601
+ [{ filters: {} }, {}],
602
+ [{ filters: { labels: null } }, {}],
603
+ [{ filters: { labels: {} } }, {}],
604
+ [{ filters: { labels: { label: "" } } }, { label: "" }],
605
+ [{ filters: { labels: { lab: "el" } } }, { lab: "el" }],
606
+ ])("given %j, returns %j", (given, expected) => {
607
+ const binding = given as DeepPartial<Binding>;
608
+
609
+ const result = sut.definedLabels(binding);
610
+
611
+ expect(result).toEqual(expected);
612
+ });
613
+ });
614
+
615
+ describe("definesLabels", () => {
616
+ //[ Binding, result ]
617
+ it.each([
618
+ [{}, false],
619
+ [{ filters: {} }, false],
620
+ [{ filters: { labels: null } }, false],
621
+ [{ filters: { labels: {} } }, false],
622
+ [{ filters: { labels: { label: "" } } }, true],
623
+ [{ filters: { labels: { lab: "el" } } }, true],
624
+ ])("given %j, returns %s", (given, expected) => {
625
+ const binding = given as DeepPartial<Binding>;
626
+
627
+ const result = sut.definesLabels(binding);
628
+
629
+ expect(result).toBe(expected);
630
+ });
631
+ });
632
+
633
+ describe("carriedLabels", () => {
634
+ //[ KubernetesObject, result ]
635
+ it.each([
636
+ [{}, {}],
637
+ [{ metadata: {} }, {}],
638
+ [{ metadata: { labels: null } }, {}],
639
+ [{ metadata: { labels: {} } }, {}],
640
+ [{ metadata: { labels: { label: "" } } }, { label: "" }],
641
+ [{ metadata: { labels: { lab: "el" } } }, { lab: "el" }],
642
+ ])("given %j, returns %j", (given, expected) => {
643
+ const binding = given as DeepPartial<KubernetesObject>;
644
+
645
+ const result = sut.carriedLabels(binding);
646
+
647
+ expect(result).toEqual(expected);
648
+ });
649
+ });
650
+
651
+ describe("carriesLabels", () => {
652
+ //[ KubernetesObject, result ]
653
+ it.each([
654
+ [{}, false],
655
+ [{ metadata: {} }, false],
656
+ [{ metadata: { labels: null } }, false],
657
+ [{ metadata: { labels: {} } }, false],
658
+ [{ metadata: { labels: { label: "" } } }, true],
659
+ [{ metadata: { labels: { lab: "el" } } }, true],
660
+ ])("given %j, returns %s", (given, expected) => {
661
+ const binding = given as DeepPartial<KubernetesObject>;
662
+
663
+ const result = sut.carriesLabels(binding);
664
+
665
+ expect(result).toBe(expected);
666
+ });
667
+ });
668
+
669
+ describe("mismatchedLabels", () => {
670
+ //[ Binding, KubernetesObject, result ]
671
+ it.each([
672
+ [{}, {}, false],
673
+ [{}, { metadata: { labels: { la: "ble" } } }, false],
674
+
675
+ [{ filters: { labels: { la: "" } } }, {}, true],
676
+ [{ filters: { labels: { la: "" } } }, { metadata: { labels: { la: "" } } }, false],
677
+ [{ filters: { labels: { la: "" } } }, { metadata: { labels: { la: "ble" } } }, false],
678
+
679
+ [{ filters: { labels: { la: "ble" } } }, {}, true],
680
+ [{ filters: { labels: { la: "ble" } } }, { metadata: { labels: { la: "" } } }, true],
681
+ [{ filters: { labels: { la: "ble" } } }, { metadata: { labels: { la: "ble" } } }, false],
682
+
683
+ [{ filters: { labels: { l: "a", b: "le" } } }, { metadata: { labels: { l: "" } } }, true],
684
+ [{ filters: { labels: { l: "a", b: "le" } } }, { metadata: { labels: { l: "a" } } }, true],
685
+ [{ filters: { labels: { l: "a", b: "le" } } }, { metadata: { labels: { l: "a", b: "" } } }, true],
686
+ [{ filters: { labels: { l: "a", b: "le" } } }, { metadata: { labels: { l: "a", b: "le" } } }, false],
687
+ ])("given binding %j and object %j, returns %s", (bnd, obj, expected) => {
688
+ const binding = bnd as DeepPartial<Binding>;
689
+ const object = obj as DeepPartial<Binding>;
690
+
691
+ const result = sut.mismatchedLabels(binding, object);
692
+
693
+ expect(result).toBe(expected);
694
+ });
695
+ });
696
+
697
+ describe("uncarryableNamespace", () => {
698
+ //[ capa ns's, KubernetesObject, result ]
699
+ it.each([
700
+ [[], {}, false],
701
+ [[], { metadata: { namespace: "namespace" } }, false],
702
+
703
+ [["namespace"], {}, false],
704
+ [["namespace"], { metadata: {} }, false],
705
+ [["namespace"], { metadata: { namespace: null } }, false],
706
+ [["namespace"], { metadata: { namespace: "" } }, false],
707
+ [["namespace"], { metadata: { namespace: "incorrect" } }, true],
708
+ [["namespace"], { metadata: { namespace: "namespace" } }, false],
709
+
710
+ [["name", "space"], {}, false],
711
+ [["name", "space"], { metadata: {} }, false],
712
+ [["name", "space"], { metadata: { namespace: null } }, false],
713
+ [["name", "space"], { metadata: { namespace: "" } }, false],
714
+ [["name", "space"], { metadata: { namespace: "incorrect" } }, true],
715
+ [["name", "space"], { metadata: { namespace: "name" } }, false],
716
+ [["name", "space"], { metadata: { namespace: "space" } }, false],
717
+ ])("given capabilityNamespaces %j and object %j, returns %s", (nss, obj, expected) => {
718
+ const object = obj as DeepPartial<Binding>;
719
+
720
+ const result = sut.uncarryableNamespace(nss, object);
721
+
722
+ expect(result).toBe(expected);
723
+ });
724
+ });
725
+
726
+ describe("carriesIgnoredNamespace", () => {
727
+ //[ ignored ns's, KubernetesObject, result ]
728
+ it.each([
729
+ [[], {}, false],
730
+ [[], { metadata: { namespace: "whatever" } }, false],
731
+
732
+ [["ignored"], {}, false],
733
+ [["ignored"], { metadata: {} }, false],
734
+ [["ignored"], { metadata: { namespace: null } }, false],
735
+ [["ignored"], { metadata: { namespace: "" } }, false],
736
+ [["ignored"], { metadata: { namespace: "namespace" } }, false],
737
+ [["ignored"], { metadata: { namespace: "ignored" } }, true],
738
+
739
+ [["ign", "ored"], {}, false],
740
+ [["ign", "ored"], { metadata: {} }, false],
741
+ [["ign", "ored"], { metadata: { namespace: null } }, false],
742
+ [["ign", "ored"], { metadata: { namespace: "" } }, false],
743
+ [["ign", "ored"], { metadata: { namespace: "ign" } }, true],
744
+ [["ign", "ored"], { metadata: { namespace: "ored" } }, true],
745
+ [["ign", "ored"], { metadata: { namespace: "namespace" } }, false],
746
+ ])("given capabilityNamespaces %j and object %j, returns %s", (nss, obj, expected) => {
747
+ const object = obj as DeepPartial<Binding>;
748
+
749
+ const result = sut.carriesIgnoredNamespace(nss, object);
750
+
751
+ expect(result).toBe(expected);
752
+ });
753
+ });
754
+
755
+ describe("unbindableNamespaces", () => {
756
+ //[ capa ns's, Binding, result ]
757
+ it.each([
758
+ [[], {}, false],
759
+ [[], { metadata: { namespace: "namespace" } }, false],
760
+
761
+ [["namespace"], {}, false],
762
+ [["namespace"], { filters: {} }, false],
763
+ [["namespace"], { filters: { namespaces: null } }, false],
764
+ [["namespace"], { filters: { namespaces: [] } }, false],
765
+ [["namespace"], { filters: { namespaces: ["incorrect"] } }, true],
766
+ [["namespace"], { filters: { namespaces: ["namespace"] } }, false],
767
+
768
+ [["name", "space"], {}, false],
769
+ [["name", "space"], { filters: {} }, false],
770
+ [["name", "space"], { filters: { namespaces: null } }, false],
771
+ [["name", "space"], { filters: { namespaces: [] } }, false],
772
+ [["name", "space"], { filters: { namespaces: ["namespace"] } }, true],
773
+ [["name", "space"], { filters: { namespaces: ["name"] } }, false],
774
+ [["name", "space"], { filters: { namespaces: ["space"] } }, false],
775
+ [["name", "space"], { filters: { namespaces: ["incorrect", "space"] } }, true],
776
+ ])("given capabilityNamespaces %j and binding %j, returns %s", (nss, bnd, expected) => {
777
+ const binding = bnd as DeepPartial<Binding>;
778
+
779
+ const result = sut.unbindableNamespaces(nss, binding);
780
+
781
+ expect(result).toBe(expected);
782
+ });
783
+ });
784
+
785
+ describe("definedEvent", () => {
786
+ //[ Binding, result ]
787
+ it.each([
788
+ [{}, ""],
789
+ [{ event: "" }, ""],
790
+ [{ event: "nonsense" }, "nonsense"],
791
+ [{ event: Event.Create }, Event.Create],
792
+ [{ event: Event.CreateOrUpdate }, Event.CreateOrUpdate],
793
+ [{ event: Event.Update }, Event.Update],
794
+ [{ event: Event.Delete }, Event.Delete],
795
+ ])("given %j, returns '%s'", (given, expected) => {
796
+ const binding = given as DeepPartial<Binding>;
797
+
798
+ const result = sut.definedEvent(binding);
799
+
800
+ expect(result).toEqual(expected);
801
+ });
802
+ });
803
+
804
+ describe("definesDelete", () => {
805
+ //[ Binding, result ]
806
+ it.each([
807
+ [{}, false],
808
+ [{ event: "" }, false],
809
+ [{ event: "nonsense" }, false],
810
+ [{ event: Event.Create }, false],
811
+ [{ event: Event.CreateOrUpdate }, false],
812
+ [{ event: Event.Update }, false],
813
+ [{ event: Event.Delete }, true],
814
+ ])("given %j, returns %s", (given, expected) => {
815
+ const binding = given as DeepPartial<Binding>;
816
+
817
+ const result = sut.definesDelete(binding);
818
+
819
+ expect(result).toEqual(expected);
820
+ });
821
+ });
822
+
823
+ describe("misboundDeleteWithDeletionTimestamp", () => {
824
+ //[ Binding, result ]
825
+ it.each([
826
+ [{}, false],
827
+ [{ event: "" }, false],
828
+ [{ event: "nonsense" }, false],
829
+ [{ event: Event.Create }, false],
830
+ [{ event: Event.CreateOrUpdate }, false],
831
+ [{ event: Event.Update }, false],
832
+ [{ event: Event.Delete }, false],
833
+ [{ event: Event.Delete, filters: {} }, false],
834
+ [{ event: Event.Delete, filters: { deletionTimestamp: false } }, false],
835
+ [{ event: Event.Delete, filters: { deletionTimestamp: true } }, true],
836
+ ])("given %j, returns %s", (given, expected) => {
837
+ const binding = given as DeepPartial<Binding>;
838
+
839
+ const result = sut.misboundDeleteWithDeletionTimestamp(binding);
840
+
841
+ expect(result).toEqual(expected);
842
+ });
843
+ });
844
+
845
+ describe("operationMatchesEvent", () => {
846
+ //[ Operation, Event, result ]
847
+ it.each([
848
+ ["", "", true],
849
+ ["", Event.Create, false],
850
+ [Operation.CREATE, "", false],
851
+
852
+ [Operation.CREATE, Event.Create, true],
853
+ [Operation.CREATE, Event.Update, false],
854
+ [Operation.CREATE, Event.Delete, false],
855
+ [Operation.CREATE, Event.CreateOrUpdate, true],
856
+ [Operation.CREATE, Event.Any, true],
857
+
858
+ [Operation.UPDATE, Event.Create, false],
859
+ [Operation.UPDATE, Event.Update, true],
860
+ [Operation.UPDATE, Event.Delete, false],
861
+ [Operation.UPDATE, Event.CreateOrUpdate, true],
862
+ [Operation.UPDATE, Event.Any, true],
863
+
864
+ [Operation.DELETE, Event.Create, false],
865
+ [Operation.DELETE, Event.Update, false],
866
+ [Operation.DELETE, Event.Delete, true],
867
+ [Operation.DELETE, Event.CreateOrUpdate, false],
868
+ [Operation.DELETE, Event.Any, true],
869
+
870
+ [Operation.CONNECT, Event.Create, false],
871
+ [Operation.CONNECT, Event.Update, false],
872
+ [Operation.CONNECT, Event.Delete, false],
873
+ [Operation.CONNECT, Event.CreateOrUpdate, false],
874
+ [Operation.CONNECT, Event.Any, true],
875
+ ])("given operation %s and event %s, returns %s", (op, evt, expected) => {
876
+ const result = sut.operationMatchesEvent(op, evt);
877
+
878
+ expect(result).toEqual(expected);
879
+ });
880
+ });
881
+
882
+ describe("declaredOperation", () => {
883
+ //[ AdmissionRequest, result ]
884
+ it.each([
885
+ [{}, ""],
886
+ [{ operation: null }, ""],
887
+ [{ operation: "" }, ""],
888
+ [{ operation: "operation" }, "operation"],
889
+ [{ operation: Operation.CONNECT }, Operation.CONNECT],
890
+ [{ operation: Operation.CREATE }, Operation.CREATE],
891
+ [{ operation: Operation.UPDATE }, Operation.UPDATE],
892
+ [{ operation: Operation.DELETE }, Operation.DELETE],
893
+ ])("given %j, returns '%s'", (given, expected) => {
894
+ const request = given as DeepPartial<AdmissionRequest>;
895
+
896
+ const result = sut.declaredOperation(request);
897
+
898
+ expect(result).toEqual(expected);
899
+ });
900
+ });
901
+
902
+ describe("mismatchedEvent", () => {
903
+ //[ Binding, AdmissionRequest, result ]
904
+ it.each([
905
+ [{}, {}, false],
906
+ [{}, { operation: Operation.CREATE }, true],
907
+ [{ event: Event.Create }, {}, true],
908
+
909
+ [{ event: Event.Create }, { operation: Operation.CREATE }, false],
910
+ [{ event: Event.Update }, { operation: Operation.CREATE }, true],
911
+ [{ event: Event.Delete }, { operation: Operation.CREATE }, true],
912
+ [{ event: Event.CreateOrUpdate }, { operation: Operation.CREATE }, false],
913
+ [{ event: Event.Any }, { operation: Operation.CREATE }, false],
914
+
915
+ [{ event: Event.Create }, { operation: Operation.UPDATE }, true],
916
+ [{ event: Event.Update }, { operation: Operation.UPDATE }, false],
917
+ [{ event: Event.Delete }, { operation: Operation.UPDATE }, true],
918
+ [{ event: Event.CreateOrUpdate }, { operation: Operation.UPDATE }, false],
919
+ [{ event: Event.Any }, { operation: Operation.UPDATE }, false],
920
+
921
+ [{ event: Event.Create }, { operation: Operation.DELETE }, true],
922
+ [{ event: Event.Update }, { operation: Operation.DELETE }, true],
923
+ [{ event: Event.Delete }, { operation: Operation.DELETE }, false],
924
+ [{ event: Event.CreateOrUpdate }, { operation: Operation.DELETE }, true],
925
+ [{ event: Event.Any }, { operation: Operation.DELETE }, false],
926
+
927
+ [{ event: Event.Create }, { operation: Operation.CONNECT }, true],
928
+ [{ event: Event.Update }, { operation: Operation.CONNECT }, true],
929
+ [{ event: Event.Delete }, { operation: Operation.CONNECT }, true],
930
+ [{ event: Event.CreateOrUpdate }, { operation: Operation.CONNECT }, true],
931
+ [{ event: Event.Any }, { operation: Operation.CONNECT }, false],
932
+ ])("given binding %j and admission request %j, returns %s", (bnd, req, expected) => {
933
+ const binding = bnd as DeepPartial<Binding>;
934
+ const request = req as DeepPartial<AdmissionRequest>;
935
+
936
+ const result = sut.mismatchedEvent(binding, request);
937
+
938
+ expect(result).toEqual(expected);
939
+ });
940
+ });
941
+
942
+ describe("definedGroup", () => {
943
+ //[ Binding, result ]
944
+ it.each([
945
+ [{}, ""],
946
+ [{ kind: null }, ""],
947
+ [{ kind: {} }, ""],
948
+ [{ kind: { group: null } }, ""],
949
+ [{ kind: { group: "" } }, ""],
950
+ [{ kind: { group: "group" } }, "group"],
951
+ ])("given %j, returns '%s'", (given, expected) => {
952
+ const binding = given as DeepPartial<Binding>;
953
+
954
+ const result = sut.definedGroup(binding);
955
+
956
+ expect(result).toEqual(expected);
957
+ });
958
+ });
959
+
960
+ describe("definesGroup", () => {
961
+ //[ Binding, result ]
962
+ it.each([
963
+ [{}, false],
964
+ [{ kind: null }, false],
965
+ [{ kind: {} }, false],
966
+ [{ kind: { group: null } }, false],
967
+ [{ kind: { group: "" } }, false],
968
+ [{ kind: { group: "group" } }, true],
969
+ ])("given %j, returns %s", (given, expected) => {
970
+ const binding = given as DeepPartial<Binding>;
971
+
972
+ const result = sut.definesGroup(binding);
973
+
974
+ expect(result).toEqual(expected);
975
+ });
976
+ });
977
+
978
+ describe("declaredGroup", () => {
979
+ //[ AdmissionRequest, result ]
980
+ it.each([
981
+ [{}, ""],
982
+ [{ kind: null }, ""],
983
+ [{ kind: {} }, ""],
984
+ [{ kind: { group: null } }, ""],
985
+ [{ kind: { group: "" } }, ""],
986
+ [{ kind: { group: "group" } }, "group"],
987
+ ])("given %j, returns '%s'", (given, expected) => {
988
+ const request = given as DeepPartial<AdmissionRequest>;
989
+
990
+ const result = sut.declaredGroup(request);
991
+
992
+ expect(result).toEqual(expected);
993
+ });
994
+ });
995
+
996
+ describe("mismatchedGroup", () => {
997
+ //[ Binding, AdmissionRequest, result ]
998
+ it.each([
999
+ [{}, {}, false],
1000
+ [{}, { kind: { group: "group" } }, false],
1001
+ [{ kind: { group: "group" } }, {}, true],
1002
+ [{ kind: { group: "group" } }, { kind: { group: "wrong" } }, true],
1003
+ [{ kind: { group: "group" } }, { kind: { group: "group" } }, false],
1004
+ ])("given binding %j and admission request %j, returns %s", (bnd, req, expected) => {
1005
+ const binding = bnd as DeepPartial<Binding>;
1006
+ const request = req as DeepPartial<AdmissionRequest>;
1007
+
1008
+ const result = sut.mismatchedGroup(binding, request);
1009
+
1010
+ expect(result).toEqual(expected);
1011
+ });
1012
+ });
1013
+
1014
+ describe("definedVersion", () => {
1015
+ //[ Binding, result ]
1016
+ it.each([
1017
+ [{}, ""],
1018
+ [{ kind: null }, ""],
1019
+ [{ kind: {} }, ""],
1020
+ [{ kind: { version: null } }, ""],
1021
+ [{ kind: { version: "" } }, ""],
1022
+ [{ kind: { version: "version" } }, "version"],
1023
+ ])("given %j, returns '%s'", (given, expected) => {
1024
+ const binding = given as DeepPartial<Binding>;
1025
+
1026
+ const result = sut.definedVersion(binding);
1027
+
1028
+ expect(result).toEqual(expected);
1029
+ });
1030
+ });
1031
+
1032
+ describe("definesVersion", () => {
1033
+ //[ Binding, result ]
1034
+ it.each([
1035
+ [{}, false],
1036
+ [{ kind: null }, false],
1037
+ [{ kind: {} }, false],
1038
+ [{ kind: { version: null } }, false],
1039
+ [{ kind: { version: "" } }, false],
1040
+ [{ kind: { version: "version" } }, true],
1041
+ ])("given %j, returns %s", (given, expected) => {
1042
+ const binding = given as DeepPartial<Binding>;
1043
+
1044
+ const result = sut.definesVersion(binding);
1045
+
1046
+ expect(result).toEqual(expected);
1047
+ });
1048
+ });
1049
+
1050
+ describe("declaredVersion", () => {
1051
+ //[ AdmissionRequest, result ]
1052
+ it.each([
1053
+ [{}, ""],
1054
+ [{ kind: null }, ""],
1055
+ [{ kind: {} }, ""],
1056
+ [{ kind: { version: null } }, ""],
1057
+ [{ kind: { version: "" } }, ""],
1058
+ [{ kind: { version: "version" } }, "version"],
1059
+ ])("given %j, returns '%s'", (given, expected) => {
1060
+ const request = given as DeepPartial<AdmissionRequest>;
1061
+
1062
+ const result = sut.declaredVersion(request);
1063
+
1064
+ expect(result).toEqual(expected);
1065
+ });
1066
+ });
1067
+
1068
+ describe("mismatchedVersion", () => {
1069
+ //[ Binding, AdmissionRequest, result ]
1070
+ it.each([
1071
+ [{}, {}, false],
1072
+ [{}, { kind: { version: "version" } }, false],
1073
+ [{ kind: { version: "version" } }, {}, true],
1074
+ [{ kind: { version: "version" } }, { kind: { version: "wrong" } }, true],
1075
+ [{ kind: { version: "version" } }, { kind: { version: "version" } }, false],
1076
+ ])("given binding %j and admission request %j, returns %s", (bnd, req, expected) => {
1077
+ const binding = bnd as DeepPartial<Binding>;
1078
+ const request = req as DeepPartial<AdmissionRequest>;
1079
+
1080
+ const result = sut.mismatchedVersion(binding, request);
1081
+
1082
+ expect(result).toEqual(expected);
1083
+ });
1084
+ });
1085
+
1086
+ describe("definedKind", () => {
1087
+ //[ Binding, result ]
1088
+ it.each([
1089
+ [{}, ""],
1090
+ [{ kind: null }, ""],
1091
+ [{ kind: {} }, ""],
1092
+ [{ kind: { kind: null } }, ""],
1093
+ [{ kind: { kind: "" } }, ""],
1094
+ [{ kind: { kind: "kind" } }, "kind"],
1095
+ ])("given %j, returns '%s'", (given, expected) => {
1096
+ const binding = given as DeepPartial<Binding>;
1097
+
1098
+ const result = sut.definedKind(binding);
1099
+
1100
+ expect(result).toEqual(expected);
1101
+ });
1102
+ });
1103
+
1104
+ describe("definesKind", () => {
1105
+ //[ Binding, result ]
1106
+ it.each([
1107
+ [{}, false],
1108
+ [{ kind: null }, false],
1109
+ [{ kind: {} }, false],
1110
+ [{ kind: { kind: null } }, false],
1111
+ [{ kind: { kind: "" } }, false],
1112
+ [{ kind: { kind: "kind" } }, true],
1113
+ ])("given %j, returns %s", (given, expected) => {
1114
+ const binding = given as DeepPartial<Binding>;
1115
+
1116
+ const result = sut.definesKind(binding);
1117
+
1118
+ expect(result).toEqual(expected);
1119
+ });
1120
+ });
1121
+
1122
+ describe("declaredKind", () => {
1123
+ //[ AdmissionRequest, result ]
1124
+ it.each([
1125
+ [{}, ""],
1126
+ [{ kind: null }, ""],
1127
+ [{ kind: {} }, ""],
1128
+ [{ kind: { kind: null } }, ""],
1129
+ [{ kind: { kind: "" } }, ""],
1130
+ [{ kind: { kind: "kind" } }, "kind"],
1131
+ ])("given %j, returns '%s'", (given, expected) => {
1132
+ const request = given as DeepPartial<AdmissionRequest>;
1133
+
1134
+ const result = sut.declaredKind(request);
1135
+
1136
+ expect(result).toEqual(expected);
1137
+ });
1138
+ });
1139
+
1140
+ describe("mismatchedKind", () => {
1141
+ //[ Binding, AdmissionRequest, result ]
1142
+ it.each([
1143
+ [{}, {}, false],
1144
+ [{}, { kind: { kind: "kind" } }, false],
1145
+ [{ kind: { kind: "kind" } }, {}, true],
1146
+ [{ kind: { kind: "kind" } }, { kind: { kind: "wrong" } }, true],
1147
+ [{ kind: { kind: "kind" } }, { kind: { kind: "kind" } }, false],
1148
+ ])("given binding %j and admission request %j, returns %s", (bnd, req, expected) => {
1149
+ const binding = bnd as DeepPartial<Binding>;
1150
+ const request = req as DeepPartial<AdmissionRequest>;
1151
+
1152
+ const result = sut.mismatchedKind(binding, request);
1153
+
1154
+ expect(result).toEqual(expected);
1155
+ });
1156
+ });
1157
+
1158
+ describe("definedCategory", () => {
1159
+ //[ Binding, result ]
1160
+ it.each([
1161
+ [{}, ""],
1162
+ [{ isValidate: true }, "Validate"],
1163
+ [{ isMutate: true }, "Mutate"],
1164
+ [{ isWatch: true }, "Watch"],
1165
+ [{ isFinalize: true, isWatch: true }, "Finalize"],
1166
+ ])("given %j, returns %s", (given, expected) => {
1167
+ const binding = given as DeepPartial<Binding>;
1168
+
1169
+ const result = sut.definedCategory(binding);
1170
+
1171
+ expect(result).toEqual(expected);
1172
+ });
1173
+ });
1174
+
1175
+ describe("definedCallback", () => {
1176
+ const validateCallback = () => {};
1177
+ const mutateCallback = () => {};
1178
+ const watchCallback = () => {};
1179
+ const finalizeCallback = () => {};
1180
+
1181
+ //[ Binding, result ]
1182
+ it.each([
1183
+ [{}, null],
1184
+ [{ isValidate: true, validateCallback }, validateCallback],
1185
+ [{ isMutate: true, mutateCallback }, mutateCallback],
1186
+ [{ isWatch: true, watchCallback }, watchCallback],
1187
+ [{ isFinalize: true, finalizeCallback }, finalizeCallback],
1188
+ ])("given %j, returns %s", (given, expected) => {
1189
+ const binding = given as DeepPartial<Binding>;
1190
+
1191
+ const result = sut.definedCallback(binding);
1192
+
1193
+ expect(result).toEqual(expected);
1194
+ });
1195
+ });
1196
+
1197
+ describe("definedCallbackName", () => {
1198
+ const validateCallback = () => {};
1199
+ const mutateCallback = () => {};
1200
+ const watchCallback = () => {};
1201
+ const finalizeCallback = () => {};
1202
+
1203
+ //[ Binding, result ]
1204
+ it.each([
1205
+ [{}, ""],
1206
+ [{ isValidate: true, validateCallback }, "validateCallback"],
1207
+ [{ isMutate: true, mutateCallback }, "mutateCallback"],
1208
+ [{ isWatch: true, watchCallback }, "watchCallback"],
1209
+ [{ isFinalize: true, finalizeCallback }, "finalizeCallback"],
1210
+ ])("given %j, returns %s", (given, expected) => {
1211
+ const binding = given as DeepPartial<Binding>;
1212
+
1213
+ const result = sut.definedCallbackName(binding);
1214
+
1215
+ expect(result).toEqual(expected);
1216
+ });
1217
+ });
1218
+
1219
+ describe("declaredUid", () => {
1220
+ //[ AdmissionRequest, result ]
1221
+ it.each([
1222
+ [{}, ""],
1223
+ [{ uid: null }, ""],
1224
+ [{ uid: "uid" }, "uid"],
1225
+ ])("given %j, returns '%s'", (given, expected) => {
1226
+ const request = given as DeepPartial<AdmissionRequest>;
1227
+
1228
+ const result = sut.declaredUid(request);
1229
+
1230
+ expect(result).toEqual(expected);
1231
+ });
1232
+ });