@kumori/aurora-backend-handler 1.0.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.
@@ -0,0 +1,518 @@
1
+ import { Service } from "@hestekumori/aurora-interfaces";
2
+ import {
3
+ withDefaultValue,
4
+ handleParametersToGenerateData,
5
+ transformServiceToForm,
6
+ generateServiceSpec,
7
+ deployServiceHelper as deployService,
8
+ ServiceSpecForm,
9
+ } from "../api/deploy-service-helper";
10
+
11
+ jest.mock("@kumori/kumori-module-generator", () => ({
12
+ buildServiceDeploymentModuleWithLocalComponent: jest
13
+ .fn()
14
+ .mockResolvedValue(new Blob(["bundleFalso"])),
15
+ }));
16
+
17
+ jest.mock("../api/resources-api-service", () => ({
18
+ createVolume: jest.fn().mockResolvedValue({}),
19
+ }));
20
+
21
+ jest.mock("../websocket-manager", () => ({
22
+ getReferenceDomain: jest.fn().mockReturnValue("test-domain.com"),
23
+ }));
24
+
25
+ describe("withDefaultValue", () => {
26
+ it("retorna el valor si este no es null o undefined", () => {
27
+ expect(withDefaultValue("valor", "default")).toBe("valor");
28
+ expect(withDefaultValue(0, 10)).toBe(0);
29
+ expect(withDefaultValue(false, true)).toBe(false);
30
+ });
31
+
32
+ it("retorna el valor por defecto si el valor es null o undefined", () => {
33
+ expect(withDefaultValue(null, "default")).toBe("default");
34
+ expect(withDefaultValue(undefined, "default")).toBe("default");
35
+ });
36
+ });
37
+
38
+ describe("handleParametersToGenerateData", () => {
39
+ it("maneja parámetros básicos (string, number, boolean)", () => {
40
+ const formParams = [
41
+ { name: "param1", value: "valor1", type: "string" },
42
+ { name: "param2", value: "42", type: "number" },
43
+ { name: "param3", value: "true", type: "boolean" },
44
+ ];
45
+ const result = handleParametersToGenerateData(formParams, []);
46
+
47
+ expect(result.parameters).toHaveLength(3);
48
+ expect(result.environment).toHaveLength(3);
49
+ expect(result.parameters[0]).toEqual({
50
+ name: "param1",
51
+ type: "string",
52
+ defaultValue: "valor1",
53
+ });
54
+ expect(result.parameters[1].defaultValue).toBe(42);
55
+ expect(result.parameters[2].defaultValue).toBe(true);
56
+ });
57
+
58
+ it("maneja parámetros de tipo secret", () => {
59
+ const formParams = [{ name: "sec1", value: "secretValue", type: "secret" }];
60
+ const result = handleParametersToGenerateData(formParams, []);
61
+
62
+ expect(result.environment).toContainEqual({
63
+ varName: "sec1",
64
+ secret: "secretValue",
65
+ });
66
+ expect(result.resources).toContainEqual({
67
+ secret: { name: "secretValue" },
68
+ });
69
+ });
70
+
71
+ it("maneja parámetros de tipo file", () => {
72
+ const formParams = [
73
+ { name: "file1", value: "/path/to/file", type: "file" },
74
+ ];
75
+ const result = handleParametersToGenerateData(formParams, []);
76
+
77
+ expect(result.fileSystem).toContainEqual({
78
+ path: "/app/config/file1",
79
+ param: "file1",
80
+ });
81
+ });
82
+
83
+ it("maneja parámetros de tipo fileContent", () => {
84
+ const formParams = [
85
+ {
86
+ name: "file1",
87
+ value: "/custom/path",
88
+ type: "fileContent",
89
+ content: "contenido",
90
+ },
91
+ ];
92
+ const result = handleParametersToGenerateData(formParams, []);
93
+
94
+ expect(result.parameters[0].defaultValue).toBe("contenido");
95
+ expect(result.fileSystem[0].path).toBe("/custom/path");
96
+ });
97
+
98
+ it("maneja parámetros de tipo volume", () => {
99
+ const formParams = [{ name: "vol1", value: "/data", type: "volume" }];
100
+ const result = handleParametersToGenerateData(formParams, []);
101
+
102
+ expect(result.resources).toContainEqual({ volume: { name: "vol1" } });
103
+ expect(result.fileSystem).toContainEqual({
104
+ path: "/data",
105
+ resourceVolume: "vol1",
106
+ });
107
+ });
108
+
109
+ it("maneja parámetros de tipo serviceUrl", () => {
110
+ const formParams = [
111
+ { name: "url1", value: "https://api.example.com", type: "serviceUrl" },
112
+ ];
113
+ const result = handleParametersToGenerateData(formParams, []);
114
+
115
+ expect(result.parameters[0].defaultValue).toBe("https://api.example.com");
116
+ });
117
+
118
+ it("maneja tipos desconocidos", () => {
119
+ const consoleSpy = jest.spyOn(console, "warn").mockImplementation();
120
+ const formParams = [{ name: "param1", value: "valor", type: "unknown" }];
121
+
122
+ handleParametersToGenerateData(formParams, []);
123
+
124
+ expect(consoleSpy).toHaveBeenCalledWith("Unknown parameter type: unknown");
125
+ consoleSpy.mockRestore();
126
+ });
127
+
128
+ it("maneja recursos de tipo secret", () => {
129
+ const formResources = [
130
+ { name: "res1", type: "secret", value: "secretValue" },
131
+ ];
132
+ const result = handleParametersToGenerateData([], formResources);
133
+
134
+ expect(result.resources).toContainEqual({ secret: { name: "res1" } });
135
+ });
136
+ });
137
+
138
+ describe("transformServiceToForm", () => {
139
+ const createMockService = (overrides = {}): Service => ({
140
+ id: "servicio1",
141
+ tenant: "tenant1",
142
+ account: "account1",
143
+ environment: "env1",
144
+ name: "Servicio Prueba",
145
+ logo: "",
146
+ description: "",
147
+ revisions: [],
148
+ status: {
149
+ message: "running",
150
+ timestamp: "2024-01-01",
151
+ args: [],
152
+ code: "200",
153
+ },
154
+ role: [{ name: "servicio1", instances: [] }],
155
+ links: [],
156
+ resources: [],
157
+ parameters: [],
158
+ usage: {
159
+ current: {
160
+ cpu: 2,
161
+ memory: 512,
162
+ storage: 100,
163
+ volatileStorage: 10,
164
+ nonReplicatedStorage: 10,
165
+ persistentStorage: 20,
166
+ },
167
+ limit: {
168
+ cpu: { max: 4, min: 1 },
169
+ memory: { max: 1024, min: 256 },
170
+ storage: { max: 200, min: 50 },
171
+ volatileStorage: { max: 20, min: 5 },
172
+ nonReplicatedStorage: { max: 20, min: 5 },
173
+ persistentStorage: { max: 50, min: 10 },
174
+ },
175
+ cost: 100,
176
+ },
177
+ minReplicas: 1,
178
+ maxReplicas: 3,
179
+ lastDeployed: "",
180
+ project: "project1",
181
+ registry: "docker.io",
182
+ imageName: "miImagen",
183
+ entrypoint: "/iniciar",
184
+ cmd: "start",
185
+ serverChannels: [],
186
+ clientChannels: [],
187
+ duplexChannels: [],
188
+ cloudProvider: "aws",
189
+ ...overrides,
190
+ });
191
+
192
+ it("transforma correctamente un objeto Service básico", () => {
193
+ const service = createMockService({
194
+ clientChannels: [{ name: "clientChannel1", from: "", to: "" }],
195
+ serverChannels: [
196
+ {
197
+ name: "serverChannel1",
198
+ from: "",
199
+ to: "",
200
+ port: 8080,
201
+ isPublic: true,
202
+ protocol: "http",
203
+ portNum: 80,
204
+ },
205
+ ],
206
+ });
207
+
208
+ const form = transformServiceToForm(service);
209
+
210
+ expect(form.tenantId).toBe("tenant1");
211
+ expect(form.accountId).toBe("account1");
212
+ expect(form.serviceId).toBe("Servicio Prueba");
213
+ expect(form.cpuRequirements).toBe(4);
214
+ expect(form.memoryRequirements).toBe(1024);
215
+ expect(form.registryUrl).toBe("docker.io");
216
+ expect(form.imageTag).toBe("miImagen");
217
+ expect(form.clientChannels).toEqual([{ name: "clientChannel1" }]);
218
+ expect(form.channels[0].protocol).toBe("HTTPS");
219
+ });
220
+
221
+ it("maneja serverChannels con protocolo TCP", () => {
222
+ const service = createMockService({
223
+ serverChannels: [
224
+ {
225
+ name: "tcpChannel",
226
+ from: "",
227
+ to: "",
228
+ protocol: "tcp",
229
+ },
230
+ ],
231
+ });
232
+
233
+ const form = transformServiceToForm(service);
234
+ expect(form.channels[0].protocol).toBe("TCP");
235
+ });
236
+
237
+ it("maneja scaling configuration", () => {
238
+ const service = createMockService({
239
+ role: [
240
+ {
241
+ name: "servicio1",
242
+ instances: [],
243
+ scalling: {
244
+ cpu: { up: "80", down: "20" },
245
+ memory: { up: "80", down: "20" },
246
+ instances: { max: 5, min: 1 },
247
+ histeresys: "10",
248
+ },
249
+ },
250
+ ],
251
+ });
252
+
253
+ const form = transformServiceToForm(service);
254
+ expect(form.scaling).toBeDefined();
255
+ expect(form.scaling?.instances.max).toBe(5);
256
+ });
257
+ });
258
+
259
+ describe("generateServiceSpec", () => {
260
+ const createMockForm = (overrides = {}): ServiceSpecForm => ({
261
+ tenantId: "tenant1",
262
+ accountId: "account1",
263
+ environmentId: "env1",
264
+ serviceId: "servicio1",
265
+ cpuRequirements: 2,
266
+ memoryRequirements: 512,
267
+ registryUrl: "docker.io",
268
+ imageTag: "miImagen",
269
+ clientChannels: [],
270
+ channels: [],
271
+ defaultExecutable: {},
272
+ config: {
273
+ parameters: [],
274
+ resources: [],
275
+ },
276
+ ...overrides,
277
+ });
278
+
279
+ it("genera un ServiceWithLocalComponentSpec básico", async () => {
280
+ const form = createMockForm({
281
+ clientChannels: [{ name: "clientChannel1" }],
282
+ });
283
+
284
+ const serviceSpec = await generateServiceSpec(form);
285
+
286
+ expect(serviceSpec.type).toBe("service");
287
+ expect(serviceSpec.subtype).toBe("service_with_local_component");
288
+ expect(serviceSpec.tenantId).toBe("tenant1");
289
+ expect(serviceSpec.local_components["servicio1"].channels.client).toEqual([
290
+ "clientChannel1",
291
+ ]);
292
+ });
293
+
294
+ it("genera inbound roles para canales HTTPS públicos", async () => {
295
+ const form = createMockForm({
296
+ channels: [
297
+ {
298
+ channelName: "https1",
299
+ containerPort: 443,
300
+ isPublic: true,
301
+ protocol: "HTTPS",
302
+ domain: "example.com",
303
+ },
304
+ ],
305
+ });
306
+
307
+ const serviceSpec = await generateServiceSpec(form);
308
+
309
+ const inboundRole = serviceSpec.roles.find(
310
+ (role) => role.name === "https1_inbound"
311
+ );
312
+ expect(inboundRole).toBeDefined();
313
+ expect(inboundRole?.artifact.config.parameters).toContainEqual({
314
+ name: "type",
315
+ value: "https",
316
+ type: "string",
317
+ });
318
+ });
319
+
320
+ it("genera inbound roles para canales TCP públicos", async () => {
321
+ const form = createMockForm({
322
+ channels: [
323
+ {
324
+ channelName: "tcp1",
325
+ containerPort: 9000,
326
+ isPublic: true,
327
+ protocol: "TCP",
328
+ publicPort: "9000",
329
+ },
330
+ ],
331
+ });
332
+
333
+ const serviceSpec = await generateServiceSpec(form);
334
+
335
+ const inboundRole = serviceSpec.roles.find(
336
+ (role) => role.name === "tcp1_inbound"
337
+ );
338
+ expect(inboundRole).toBeDefined();
339
+ });
340
+
341
+ it("maneja volúmenes con diferentes tipos", async () => {
342
+ const consoleSpy = jest.spyOn(console, "warn").mockImplementation();
343
+
344
+ const form = createMockForm({
345
+ config: {
346
+ parameters: [],
347
+ resources: [
348
+ { name: "vol1", type: "volume", size: 5, kind: "volatile" },
349
+ { name: "vol2", type: "volume", size: 10, kind: "persistent" },
350
+ { name: "vol3", type: "volume", size: 15, kind: "nonreplicated" },
351
+ ],
352
+ },
353
+ });
354
+
355
+ const serviceSpec = await generateServiceSpec(form);
356
+
357
+ const resources = serviceSpec.deploymentConfig.resources;
358
+ expect(resources.some((r: any) => r.volume?.volume?.type === "volatile")).toBe(true);
359
+ expect(resources.some((r: any) => r.volume?.volume?.type === "persistent")).toBe(true);
360
+ expect(resources.some((r: any) => r.volume?.volume?.type === "nonreplicated")).toBe(true);
361
+
362
+ consoleSpy.mockRestore();
363
+ });
364
+
365
+ it("maneja scaling configuration", async () => {
366
+ const form = createMockForm({
367
+ scaling: {
368
+ cpu: { up: "80", down: "20" },
369
+ memory: { up: "80", down: "20" },
370
+ instances: { min: 1, max: 5 },
371
+ histeresys: "10",
372
+ },
373
+ });
374
+
375
+ const serviceSpec = await generateServiceSpec(form);
376
+
377
+ expect(serviceSpec.deploymentConfig.meta.scaling).toBeDefined();
378
+ expect(serviceSpec.deploymentConfig.meta.scaling.simple.servicio1.max_replicas).toBe(5);
379
+ });
380
+
381
+ it("genera spec con marketplace item de tipo service", async () => {
382
+ const form = createMockForm();
383
+ const marketplaceItem = {
384
+ type: "service" as const,
385
+ domain: "kumori.systems",
386
+ module: "marketplace/service",
387
+ version: "1.2.3",
388
+ serviceName: "MarketplaceService",
389
+ deploymentData: { name: "marketplaceRole" },
390
+ roles: ["role1", "role2"],
391
+ };
392
+
393
+ const serviceSpec = await generateServiceSpec(form, marketplaceItem as any);
394
+
395
+ const marketplaceRole = serviceSpec.roles.find(
396
+ (role) => role.name === "marketplaceRole"
397
+ );
398
+ expect(marketplaceRole?.artifact.artifactKind).toBe("service");
399
+ expect(serviceSpec.local_components).toEqual({});
400
+ });
401
+ });
402
+
403
+ describe("deployService", () => {
404
+ const mockClick = jest.fn();
405
+
406
+ beforeAll(() => {
407
+ (global as any).URL = {
408
+ createObjectURL: jest.fn(() => "blob:mock-url"),
409
+ };
410
+
411
+ (global as any).document = {
412
+ createElement: jest.fn(() => ({
413
+ click: mockClick,
414
+ target: "",
415
+ href: "",
416
+ })),
417
+ };
418
+ });
419
+
420
+ afterEach(() => {
421
+ jest.clearAllMocks();
422
+ });
423
+
424
+ const createMockService = (overrides = {}): Service => ({
425
+ id: "servicio1",
426
+ tenant: "tenant1",
427
+ account: "account1",
428
+ environment: "env1",
429
+ name: "Servicio Prueba",
430
+ logo: "",
431
+ description: "",
432
+ revisions: [],
433
+ status: {
434
+ message: "running",
435
+ timestamp: "2024-01-01",
436
+ args: [],
437
+ code: "200",
438
+ },
439
+ role: [{ name: "servicio1", instances: [] }],
440
+ links: [],
441
+ resources: [],
442
+ parameters: [],
443
+ usage: {
444
+ current: {
445
+ cpu: 2,
446
+ memory: 512,
447
+ storage: 100,
448
+ volatileStorage: 10,
449
+ nonReplicatedStorage: 10,
450
+ persistentStorage: 20,
451
+ },
452
+ limit: {
453
+ cpu: { max: 4, min: 1 },
454
+ memory: { max: 1024, min: 256 },
455
+ storage: { max: 200, min: 50 },
456
+ volatileStorage: { max: 20, min: 5 },
457
+ nonReplicatedStorage: { max: 20, min: 5 },
458
+ persistentStorage: { max: 50, min: 10 },
459
+ },
460
+ cost: 100,
461
+ },
462
+ minReplicas: 1,
463
+ maxReplicas: 3,
464
+ lastDeployed: "",
465
+ project: "project1",
466
+ registry: "docker.io",
467
+ imageName: "miImagen",
468
+ entrypoint: "/iniciar",
469
+ cmd: "start",
470
+ serverChannels: [],
471
+ clientChannels: [],
472
+ duplexChannels: [],
473
+ cloudProvider: "aws",
474
+ ...overrides,
475
+ });
476
+
477
+ it("retorna FormData con bundle y meta cuando download es false", async () => {
478
+ const service = createMockService({ download: false });
479
+
480
+ const formData = await deployService(service);
481
+
482
+ expect(formData.get("bundle")).toBeTruthy();
483
+ expect(formData.get("meta")).toBeTruthy();
484
+ expect(formData.get("comment")).toBe(" ");
485
+
486
+ const meta = JSON.parse(formData.get("meta") as string);
487
+ expect(meta.targetAccount).toBe("account1");
488
+ expect(meta.targetEnvironment).toBe("env1");
489
+ });
490
+
491
+ it("retorna FormData vacío y ejecuta descarga cuando download es true", async () => {
492
+ const service = createMockService({ download: true });
493
+
494
+ const formData = await deployService(service);
495
+
496
+ expect((global as any).URL.createObjectURL).toHaveBeenCalled();
497
+ expect((global as any).document.createElement).toHaveBeenCalledWith("a");
498
+ expect(mockClick).toHaveBeenCalled();
499
+ expect(Array.from(formData.keys()).length).toBe(0);
500
+ });
501
+
502
+ it("maneja deployment con marketplace item", async () => {
503
+ const service = createMockService();
504
+ const marketplaceItem = {
505
+ type: "service" as const,
506
+ domain: "kumori.systems",
507
+ module: "marketplace/service",
508
+ version: "1.0.0",
509
+ serviceName: "TestService",
510
+ deploymentData: { name: "testRole" },
511
+ roles: ["role1"],
512
+ };
513
+
514
+ const formData = await deployService(service, marketplaceItem as any);
515
+
516
+ expect(formData.get("bundle")).toBeTruthy();
517
+ });
518
+ });
@@ -0,0 +1,152 @@
1
+
2
+ import EventHelper from '../event-helper';
3
+ import { EventNames } from './../event-names';
4
+
5
+ beforeEach(() => {
6
+ jest.clearAllMocks();
7
+ });
8
+
9
+ describe('EventHelper', () => {
10
+ const dummyGlobalEventHandler = {
11
+ publish: jest.fn(),
12
+ subscribe: jest.fn(),
13
+ unsubscribe: jest.fn(),
14
+ };
15
+
16
+ const eventHelper = new EventHelper(dummyGlobalEventHandler);
17
+
18
+
19
+ // --- Tenant ---
20
+ describe('Tenant events', () => {
21
+ test('tenant.publish.creation llama a globalEventHandler.publish con el nombre de evento correcto y payload', () => {
22
+ const payload = { id: 'tenant1', name: 'Tenant One' };
23
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'publish');
24
+ eventHelper.tenant.publish.creation(payload as any);
25
+ expect(spy).toHaveBeenCalledWith(EventNames.CreateTenant, payload);
26
+ });
27
+
28
+ test('tenant.subscribe.creation llama a globalEventHandler.subscribe con el nombre de evento correcto y callback', () => {
29
+ const callback = jest.fn();
30
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'subscribe');
31
+ eventHelper.tenant.subscribe.creation(callback);
32
+ expect(spy).toHaveBeenCalledWith(EventNames.CreateTenant, callback);
33
+ });
34
+
35
+ test('tenant.unsubscribe.creation llama a globalEventHandler.unsubscribe con el nombre de evento correcto y callback', () => {
36
+ const callback = jest.fn();
37
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'unsubscribe');
38
+ eventHelper.tenant.unsubscribe.creation(callback);
39
+ expect(spy).toHaveBeenCalledWith(EventNames.CreateTenant, callback);
40
+ });
41
+ });
42
+
43
+ // --- User ---
44
+ describe('User events', () => {
45
+ test('user.publish.creation llama a globalEventHandler.publish con el nombre de evento correcto y payload', () => {
46
+ const payload = { id: 'user1', username: 'john.doe' };
47
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'publish');
48
+ eventHelper.user.publish.creation(payload as any);
49
+ expect(spy).toHaveBeenCalledWith(EventNames.CreateUser, payload);
50
+ });
51
+
52
+ test('user.subscribe.creation llama a globalEventHandler.subscribe con el nombre de evento correcto y callback', () => {
53
+ const callback = jest.fn();
54
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'subscribe');
55
+ eventHelper.user.subscribe.creation(callback);
56
+ expect(spy).toHaveBeenCalledWith(EventNames.CreateUser, callback);
57
+ });
58
+ });
59
+
60
+ // --- Account ---
61
+ describe('Account events', () => {
62
+ test('account.publish.creation llama a globalEventHandler.publish con el nombre de evento correcto y payload', () => {
63
+ const payload = { id: 'acc1', name: 'Account One' };
64
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'publish');
65
+ eventHelper.account.publish.creation(payload as any);
66
+ expect(spy).toHaveBeenCalledWith(EventNames.CreateAccount, payload);
67
+ });
68
+ });
69
+
70
+ // --- Environment ---
71
+ describe('Environment events', () => {
72
+ test('environment.publish.creation llama a globalEventHandler.publish con el nombre de evento correcto y payload', () => {
73
+ const payload = { id: 'env1', name: 'Environment One' };
74
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'publish');
75
+ eventHelper.environment.publish.creation(payload as any);
76
+ expect(spy).toHaveBeenCalledWith(EventNames.CreateEnvironment, payload);
77
+ });
78
+ });
79
+
80
+ // --- Service ---
81
+ describe('Service events', () => {
82
+ test('service.publish.deploy llama a globalEventHandler.publish con el nombre de evento correcto y payload', () => {
83
+ const payload = { id: 'svc1', name: 'Service One' };
84
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'publish');
85
+ eventHelper.service.publish.deploy(payload as any);
86
+ expect(spy).toHaveBeenCalledWith(EventNames.DeployService, payload);
87
+ });
88
+ });
89
+
90
+ // --- Marketplace ---
91
+ describe('Marketplace events', () => {
92
+ test('marketplace.publish.deployItem llama a globalEventHandler.publish con el nombre de evento correcto y payload', () => {
93
+ const payload = { id: 'mkt1', name: 'Marketplace Item' };
94
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'publish');
95
+ eventHelper.marketplace.publish.deployItem(payload as any);
96
+ expect(spy).toHaveBeenCalledWith(EventNames.DeployMarketplaceItem, payload);
97
+ });
98
+ });
99
+
100
+ // --- Resource ---
101
+ describe('Resource events', () => {
102
+ test('resource.publish.creation llama a globalEventHandler.publish con el nombre de evento correcto y payload', () => {
103
+ const payload = { id: 'res1', name: 'Resource One' };
104
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'publish');
105
+ eventHelper.resource.publish.creation(payload as any);
106
+ expect(spy).toHaveBeenCalledWith(EventNames.CreateResource, payload);
107
+ });
108
+ });
109
+
110
+ // --- Plan (payload de tipo string) ---
111
+ describe('Plan events', () => {
112
+ test('plan.publish.upgrade llama a globalEventHandler.publish con el nombre de evento correcto y payload', () => {
113
+ const payload = 'Upgrade Data';
114
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'publish');
115
+ eventHelper.plan.publish.upgrade(payload);
116
+ expect(spy).toHaveBeenCalledWith(EventNames.UpdatePlan, payload);
117
+ });
118
+ });
119
+
120
+ // --- Organization ---
121
+ describe('Organization events', () => {
122
+ test('organization.publish.creation llama a globalEventHandler.publish con el nombre de evento correcto y payload', () => {
123
+ const payload = { id: 'org1', name: 'Organization One' };
124
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'publish');
125
+ eventHelper.organization.publish.creation(payload as any);
126
+ expect(spy).toHaveBeenCalledWith(EventNames.CreateOrganization, payload);
127
+ });
128
+ });
129
+
130
+ // --- PlanProviders ---
131
+ describe('PlanProviders events', () => {
132
+ test('planProviders.publish.getPlans llama a globalEventHandler.publish con el nombre de evento correcto', () => {
133
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'publish');
134
+ eventHelper.planProviders.publish.loadPlans();
135
+ expect(spy).toHaveBeenCalledWith(EventNames.LoadPlanProviders, undefined);
136
+ });
137
+
138
+ test('planProviders.subscribe.getPlans llama a globalEventHandler.subscribe con el nombre de evento correcto y callback', () => {
139
+ const callback = jest.fn();
140
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'subscribe');
141
+ eventHelper.planProviders.subscribe.loadPlans(callback);
142
+ expect(spy).toHaveBeenCalledWith(EventNames.LoadPlanProviders, callback);
143
+ });
144
+
145
+ test('planProviders.unsubscribe.getPlans llama a globalEventHandler.unsubscribe con el nombre de evento correcto y callback', () => {
146
+ const callback = jest.fn();
147
+ const spy = jest.spyOn(eventHelper.globalEventHandler, 'unsubscribe');
148
+ eventHelper.planProviders.unsubscribe.loadPlans(callback);
149
+ expect(spy).toHaveBeenCalledWith(EventNames.LoadPlanProviders, callback);
150
+ });
151
+ });
152
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "allowJs": true,
5
+ "experimentalDecorators": true,
6
+ "useDefineForClassFields": false,
7
+ "module": "ESNext",
8
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
9
+ "skipLibCheck": true,
10
+ "esModuleInterop": true,
11
+
12
+ /* Bundler mode */
13
+ "moduleResolution": "bundler",
14
+ "allowImportingTsExtensions": true,
15
+ "isolatedModules": true,
16
+ "moduleDetection": "force",
17
+ "noEmit": true,
18
+
19
+ /* Linting */
20
+ "strict": true,
21
+ "noUnusedLocals": true,
22
+ "noUnusedParameters": true,
23
+ "noFallthroughCasesInSwitch": true,
24
+ "noUncheckedSideEffectImports": true
25
+ }
26
+ }