@goatlab/tasks-adapter-gcp 0.3.4 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,65 +1,98 @@
1
1
  "use strict";
2
- // npx vitest test ./src/cloudtask.spec.ts
2
+ // npx vitest run ./src/cloudtask.spec.ts
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const tasks_core_1 = require("@goatlab/tasks-core");
5
+ const test_suite_1 = require("@goatlab/tasks-core/test-suite");
5
6
  const vitest_1 = require("vitest");
6
- const CloudTaskConnector_1 = require("./CloudTaskConnector");
7
- class TestTask extends tasks_core_1.ShouldQueue {
8
- postUrl = `http://localhost/task/this/url`;
9
- taskName = 'this_is_the_task_name';
10
- async handle(taskBody) {
11
- console.log('Running task with body:', taskBody);
12
- return undefined;
13
- }
7
+ const CloudTaskConnector_js_1 = require("./CloudTaskConnector.js");
8
+ // Parse service account from env
9
+ const serviceAccountBase64 = process.env.FIREBASE_SERVICE_ACCOUNT;
10
+ if (!serviceAccountBase64) {
11
+ throw new Error('FIREBASE_SERVICE_ACCOUNT environment variable is required');
14
12
  }
15
- (0, vitest_1.describe)('CloudTaskQueue', () => {
16
- let cloudTask;
17
- let task;
18
- (0, vitest_1.beforeAll)(() => {
19
- // Check if we have the required environment variable
20
- const serviceAccountBase64 = process.env.FIREBASE_SERVICE_ACCOUNT;
21
- if (!serviceAccountBase64) {
22
- console.warn('FIREBASE_SERVICE_ACCOUNT not found, skipping CloudTask tests');
23
- return;
24
- }
25
- try {
26
- // Decode and parse the service account
27
- const serviceAccountJson = Buffer.from(serviceAccountBase64, 'base64').toString('utf8');
28
- const gcpServiceAccount = JSON.parse(serviceAccountJson);
29
- cloudTask = new CloudTaskConnector_1.CloudTaskConnector({
30
- gcpServiceAccount,
31
- location: 'europe-west1',
32
- encryptionKey: 'some-encryption-key',
33
- gcpProject: 'gealium-develop'
34
- });
35
- task = new TestTask({
36
- connector: cloudTask
37
- });
38
- }
39
- catch (error) {
40
- console.error('Failed to parse FIREBASE_SERVICE_ACCOUNT:', error);
41
- throw new Error(`Invalid FIREBASE_SERVICE_ACCOUNT format: ${error.message}`);
42
- }
43
- });
44
- (0, vitest_1.it)('should create a task and run it', async () => {
45
- // Skip test if cloudTask wasn't initialized
46
- if (!cloudTask) {
47
- console.log('Skipping test: FIREBASE_SERVICE_ACCOUNT not available');
48
- return;
13
+ const serviceAccountJson = Buffer.from(serviceAccountBase64, 'base64').toString('utf8');
14
+ const gcpServiceAccount = JSON.parse(serviceAccountJson);
15
+ // Create real GCP Cloud Tasks connector
16
+ const cloudTaskConnector = new CloudTaskConnector_js_1.CloudTaskConnector({
17
+ gcpServiceAccount,
18
+ location: 'europe-west1',
19
+ encryptionKey: 'test-encryption-key-32chars!!!!',
20
+ gcpProject: gcpServiceAccount.project_id
21
+ });
22
+ // Run the standardized test suite
23
+ // Note: GCP Cloud Tasks uses HTTP callbacks, not workers.
24
+ // For lifecycle tests, tasks will fail because there's no real HTTP endpoint.
25
+ // We skip lifecycle tests since GCP doesn't have a startWorker concept.
26
+ (0, test_suite_1.taskConnectorTestSuite)({ describe: vitest_1.describe, it: vitest_1.it, expect: vitest_1.expect, beforeAll: vitest_1.beforeAll, afterAll: vitest_1.afterAll, beforeEach: vitest_1.beforeEach, afterEach: vitest_1.afterEach }, () => cloudTaskConnector, {
27
+ taskCompletionTimeout: 30000,
28
+ statusCheckInterval: 2000,
29
+ // Skip lifecycle tests - GCP Cloud Tasks doesn't use workers,
30
+ // it uses HTTP callbacks. Without a real HTTP server, tasks will fail.
31
+ skipLifecycleTests: true,
32
+ // No startWorker for GCP - it's HTTP callback based
33
+ startWorker: undefined
34
+ });
35
+ // GCP-specific tests for the HTTP callback model
36
+ (0, vitest_1.describe)('CloudTaskConnector GCP-Specific Tests', () => {
37
+ (0, vitest_1.it)('should queue a task and get its status', async () => {
38
+ class TestTask extends tasks_core_1.ShouldQueue {
39
+ postUrl = 'https://httpbin.org/post';
40
+ taskName = 'gcp_test_task';
41
+ constructor() {
42
+ super({ connector: cloudTaskConnector });
43
+ }
44
+ async handle() {
45
+ return undefined;
46
+ }
49
47
  }
50
- const status = await task.queue({ text: 'Hello, World!' });
48
+ const task = new TestTask();
49
+ const status = await task.queue({ text: 'Hello GCP!' });
51
50
  (0, vitest_1.expect)(status).toHaveProperty('id');
52
51
  (0, vitest_1.expect)(status).toHaveProperty('name');
53
52
  (0, vitest_1.expect)(status).toHaveProperty('status', 'QUEUED');
54
53
  (0, vitest_1.expect)(status).toHaveProperty('attempts', 0);
55
- (0, vitest_1.expect)(status.name).toContain('this_is_the_task_name');
56
- (0, vitest_1.expect)(status).not.toHaveProperty('payload');
57
- const getStatus = await task.getStatus(status.id);
58
- (0, vitest_1.expect)(getStatus).toHaveProperty('id', status.id);
59
- (0, vitest_1.expect)(getStatus).toHaveProperty('name', status.name);
60
- (0, vitest_1.expect)(getStatus).toHaveProperty('status', 'FAILED');
61
- (0, vitest_1.expect)(getStatus).toHaveProperty('payload');
62
- (0, vitest_1.expect)(getStatus.payload.text).toBe('Hello, World!');
54
+ (0, vitest_1.expect)(status.name).toContain('gcp_test_task');
55
+ // Get status - task may have already been dispatched or completed
56
+ // GCP Cloud Tasks removes completed tasks, so payload may be empty if task completed quickly
57
+ const fullStatus = await task.getStatus(status.id);
58
+ (0, vitest_1.expect)(fullStatus).toHaveProperty('id');
59
+ // If task still exists, check payload; if completed/removed, payload will be empty
60
+ if (fullStatus.status !== 'COMPLETED' ||
61
+ Object.keys(fullStatus.payload).length > 0) {
62
+ (0, vitest_1.expect)(fullStatus.payload).toHaveProperty('text', 'Hello GCP!');
63
+ }
64
+ });
65
+ (0, vitest_1.it)('should queue task with valid but unreachable endpoint', async () => {
66
+ class UnreachableTask extends tasks_core_1.ShouldQueue {
67
+ // Use a valid URL that will timeout/fail when GCP tries to call it
68
+ postUrl = 'https://example.invalid/webhook';
69
+ taskName = 'gcp_unreachable_task';
70
+ constructor() {
71
+ super({ connector: cloudTaskConnector });
72
+ }
73
+ async handle() {
74
+ return undefined;
75
+ }
76
+ }
77
+ const task = new UnreachableTask();
78
+ const status = await task.queue({ text: 'This endpoint is unreachable' });
79
+ (0, vitest_1.expect)(status).toHaveProperty('id');
80
+ (0, vitest_1.expect)(status.status).toBe('QUEUED');
81
+ // The task will eventually fail since the endpoint is unreachable
82
+ // We just verify we can queue and get status
83
+ const fullStatus = await task.getStatus(status.id);
84
+ (0, vitest_1.expect)(fullStatus).toHaveProperty('payload');
85
+ });
86
+ (0, vitest_1.it)('should encrypt task body to base64 string', () => {
87
+ const original = { text: 'secret data', nested: { value: 123 } };
88
+ // encryptBody expects an object with 'content' key containing stringified data
89
+ const encrypted = cloudTaskConnector.encryptBody({
90
+ content: JSON.stringify(original)
91
+ });
92
+ (0, vitest_1.expect)(encrypted).toBeDefined();
93
+ (0, vitest_1.expect)(typeof encrypted === 'string').toBe(true);
94
+ // Should be base64 encoded
95
+ (0, vitest_1.expect)(() => Buffer.from(encrypted, 'base64')).not.toThrow();
63
96
  });
64
97
  });
65
98
  //# sourceMappingURL=cloudtask.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cloudtask.spec.js","sourceRoot":"","sources":["../src/cloudtask.spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cloudtask.spec.js","sourceRoot":"","sources":["../src/cloudtask.spec.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- export { CloudTaskConnector } from './CloudTaskConnector';
2
- export type { GCPServiceAccount } from './CloudTaskConnector.types';
1
+ export { CloudTaskConnector } from './CloudTaskConnector.js';
2
+ export type { GCPServiceAccount } from './CloudTaskConnector.types.js';
3
+ export { MockCloudTaskConnector } from './MockCloudTaskConnector.js';
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CloudTaskConnector = void 0;
4
- var CloudTaskConnector_1 = require("./CloudTaskConnector");
5
- Object.defineProperty(exports, "CloudTaskConnector", { enumerable: true, get: function () { return CloudTaskConnector_1.CloudTaskConnector; } });
3
+ exports.MockCloudTaskConnector = exports.CloudTaskConnector = void 0;
4
+ var CloudTaskConnector_js_1 = require("./CloudTaskConnector.js");
5
+ Object.defineProperty(exports, "CloudTaskConnector", { enumerable: true, get: function () { return CloudTaskConnector_js_1.CloudTaskConnector; } });
6
+ var MockCloudTaskConnector_js_1 = require("./MockCloudTaskConnector.js");
7
+ Object.defineProperty(exports, "MockCloudTaskConnector", { enumerable: true, get: function () { return MockCloudTaskConnector_js_1.MockCloudTaskConnector; } });
6
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,2DAAyD;AAAhD,wHAAA,kBAAkB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iEAA4D;AAAnD,2HAAA,kBAAkB,OAAA;AAE3B,yEAAoE;AAA3D,mIAAA,sBAAsB,OAAA"}