@datalayer/core 0.0.12 → 0.0.13
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/README.md +2 -2
- package/lib/api/DatalayerApi.d.ts +38 -26
- package/lib/api/DatalayerApi.js +35 -8
- package/lib/api/iam/authentication.d.ts +8 -7
- package/lib/api/iam/authentication.js +14 -15
- package/lib/api/iam/healthz.d.ts +3 -2
- package/lib/api/iam/healthz.js +5 -3
- package/lib/api/iam/index.d.ts +9 -4
- package/lib/api/iam/index.js +9 -4
- package/lib/api/iam/oauth2.d.ts +115 -0
- package/lib/api/iam/oauth2.js +309 -0
- package/lib/api/iam/profile.d.ts +8 -1
- package/lib/api/iam/profile.js +17 -2
- package/lib/api/iam/usage.d.ts +56 -0
- package/lib/api/iam/usage.js +39 -0
- package/lib/api/index.d.ts +6 -5
- package/lib/api/index.js +6 -5
- package/lib/api/runtimes/environments.js +3 -2
- package/lib/api/runtimes/healthz.d.ts +3 -13
- package/lib/api/runtimes/healthz.js +4 -3
- package/lib/api/runtimes/index.d.ts +3 -2
- package/lib/api/runtimes/index.js +3 -2
- package/lib/api/runtimes/runtimes.js +17 -6
- package/lib/api/runtimes/snapshots.js +3 -2
- package/lib/api/spacer/documents.d.ts +12 -0
- package/lib/api/spacer/documents.js +43 -0
- package/lib/api/spacer/healthz.d.ts +3 -13
- package/lib/api/spacer/healthz.js +4 -3
- package/lib/api/spacer/index.d.ts +4 -2
- package/lib/api/spacer/index.js +4 -2
- package/lib/api/spacer/items.d.ts +9 -1
- package/lib/api/spacer/items.js +17 -2
- package/lib/api/spacer/lexicals.js +3 -2
- package/lib/api/spacer/notebooks.js +3 -2
- package/lib/api/spacer/spaces.js +3 -2
- package/lib/api/spacer/users.js +3 -2
- package/lib/api/types/common.d.ts +64 -0
- package/lib/api/types/iam.d.ts +88 -65
- package/lib/api/types/index.d.ts +4 -2
- package/lib/api/types/index.js +4 -2
- package/lib/api/types/runtimes.d.ts +9 -39
- package/lib/api/types/spacer.d.ts +37 -65
- package/lib/api/utils/validation.d.ts +24 -1
- package/lib/api/utils/validation.js +62 -1
- package/lib/client/base.d.ts +75 -0
- package/lib/client/base.js +199 -0
- package/lib/client/constants.d.ts +22 -0
- package/lib/client/constants.js +22 -0
- package/lib/client/index.d.ts +108 -0
- package/lib/client/index.js +79 -0
- package/lib/client/mixins/IAMMixin.d.ts +54 -0
- package/lib/client/mixins/IAMMixin.js +181 -0
- package/lib/client/mixins/RuntimesMixin.d.ts +93 -0
- package/lib/client/mixins/RuntimesMixin.js +229 -0
- package/lib/client/mixins/SpacerMixin.d.ts +111 -0
- package/lib/client/mixins/SpacerMixin.js +340 -0
- package/lib/client/models/Credits.d.ts +91 -0
- package/lib/client/models/Credits.js +130 -0
- package/lib/client/models/Environment.d.ts +73 -0
- package/lib/client/models/Environment.js +88 -0
- package/lib/client/models/HealthCheck.d.ts +72 -0
- package/lib/client/models/HealthCheck.js +107 -0
- package/lib/client/models/Item.d.ts +69 -0
- package/lib/client/models/Item.js +191 -0
- package/lib/client/models/Lexical.d.ts +83 -0
- package/lib/client/models/Lexical.js +152 -0
- package/lib/client/models/Notebook.d.ts +87 -0
- package/lib/client/models/Notebook.js +153 -0
- package/lib/client/models/Runtime.d.ts +122 -0
- package/lib/client/models/Runtime.js +204 -0
- package/lib/client/models/Snapshot.d.ts +92 -0
- package/lib/client/models/Snapshot.js +139 -0
- package/lib/client/models/Space.d.ts +135 -0
- package/lib/client/models/Space.js +234 -0
- package/lib/client/models/User.d.ts +64 -0
- package/lib/client/models/User.js +83 -0
- package/lib/client/models/index.d.ts +26 -0
- package/lib/client/models/index.js +25 -0
- package/lib/client/utils/mixins.d.ts +12 -0
- package/lib/{sdk/client → client}/utils/mixins.js +0 -28
- package/lib/client/utils/spacerUtils.d.ts +18 -0
- package/lib/client/utils/spacerUtils.js +32 -0
- package/lib/collaboration/DatalayerCollaboration.d.ts +6 -1
- package/lib/collaboration/DatalayerCollaboration.js +2 -2
- package/lib/collaboration/DatalayerCollaborationProvider.d.ts +5 -0
- package/lib/collaboration/DatalayerCollaborationProvider.js +10 -9
- package/lib/components/progress/CreditsIndicator.d.ts +1 -1
- package/lib/components/runtimes/RuntimeCellVariablesDialog.js +1 -1
- package/lib/components/runtimes/RuntimeLauncherDialog.d.ts +1 -1
- package/lib/components/runtimes/RuntimePickerBase.d.ts +1 -1
- package/lib/components/runtimes/RuntimePickerBase.js +1 -1
- package/lib/components/runtimes/RuntimePickerCell.js +2 -2
- package/lib/components/runtimes/RuntimePickerNotebook.d.ts +1 -1
- package/lib/components/runtimes/RuntimePickerNotebook.js +1 -1
- package/lib/components/runtimes/RuntimeTransfer.d.ts +1 -1
- package/lib/components/runtimes/RuntimeUtils.d.ts +1 -1
- package/lib/components/snapshots/RuntimeSnapshotMenu.d.ts +1 -1
- package/lib/components/snapshots/RuntimeSnapshotMenu.js +27 -20
- package/lib/config/Configuration.d.ts +8 -0
- package/lib/hooks/useDatalayer.js +1 -1
- package/lib/hooks/useRuntimes.js +1 -1
- package/lib/hooks/useToast.js +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.js +4 -2
- package/lib/sdk/index.d.ts +5 -4
- package/lib/sdk/index.js +6 -5
- package/lib/services/DatalayerServiceManager.js +1 -1
- package/lib/state/substates/CoreState.js +2 -0
- package/lib/state/substates/RuntimesState.d.ts +1 -1
- package/lib/state/substates/RuntimesState.js +1 -1
- package/lib/{sdk/stateful → stateful}/index.d.ts +1 -1
- package/lib/{sdk/stateful → stateful}/index.js +1 -1
- package/lib/{sdk/stateful → stateful}/jupyter/exec/Snippets.d.ts +1 -41
- package/lib/{sdk/stateful → stateful}/jupyter/exec/Snippets.js +1 -20
- package/lib/{sdk/stateful → stateful}/runtimes/actions.d.ts +3 -3
- package/lib/{sdk/stateful → stateful}/runtimes/actions.js +8 -8
- package/lib/{sdk/stateful → stateful}/runtimes/apis.d.ts +8 -8
- package/lib/stateful/runtimes/apis.js +5 -0
- package/package.json +12 -10
- package/lib/__tests__/hooks.test.d.ts +0 -1
- package/lib/__tests__/hooks.test.js +0 -19
- package/lib/__tests__/index.test.d.ts +0 -1
- package/lib/__tests__/index.test.js +0 -27
- package/lib/__tests__/integration.test.d.ts +0 -1
- package/lib/__tests__/integration.test.js +0 -57
- package/lib/__tests__/shared/cleanup-shared.d.ts +0 -4
- package/lib/__tests__/shared/cleanup-shared.js +0 -228
- package/lib/__tests__/shared/test-config.d.ts +0 -51
- package/lib/__tests__/shared/test-config.js +0 -110
- package/lib/__tests__/shared/test-constants.d.ts +0 -66
- package/lib/__tests__/shared/test-constants.js +0 -79
- package/lib/__tests__/utils.test.d.ts +0 -1
- package/lib/__tests__/utils.test.js +0 -59
- package/lib/api/__tests__/iam.authentication.integration.test.d.ts +0 -1
- package/lib/api/__tests__/iam.authentication.integration.test.js +0 -247
- package/lib/api/__tests__/iam.healthz.integration.test.d.ts +0 -1
- package/lib/api/__tests__/iam.healthz.integration.test.js +0 -63
- package/lib/api/__tests__/iam.profile.integration.test.d.ts +0 -1
- package/lib/api/__tests__/iam.profile.integration.test.js +0 -252
- package/lib/api/__tests__/runtimes.environments.integration.test.d.ts +0 -1
- package/lib/api/__tests__/runtimes.environments.integration.test.js +0 -122
- package/lib/api/__tests__/runtimes.healthz.integration.test.d.ts +0 -1
- package/lib/api/__tests__/runtimes.healthz.integration.test.js +0 -50
- package/lib/api/__tests__/runtimes.integration.test.d.ts +0 -1
- package/lib/api/__tests__/runtimes.integration.test.js +0 -369
- package/lib/api/__tests__/spacer.healthz.integration.test.d.ts +0 -1
- package/lib/api/__tests__/spacer.healthz.integration.test.js +0 -50
- package/lib/api/__tests__/spacer.integration.test.d.ts +0 -1
- package/lib/api/__tests__/spacer.integration.test.js +0 -519
- package/lib/api/iam/__tests__/authentication.unit.test.d.ts +0 -1
- package/lib/api/iam/__tests__/authentication.unit.test.js +0 -63
- package/lib/api/iam/__tests__/healthz.unit.test.d.ts +0 -1
- package/lib/api/iam/__tests__/healthz.unit.test.js +0 -60
- package/lib/api/iam/__tests__/profile.unit.test.d.ts +0 -1
- package/lib/api/iam/__tests__/profile.unit.test.js +0 -57
- package/lib/api/runtimes/__tests__/environments.unit.test.d.ts +0 -1
- package/lib/api/runtimes/__tests__/environments.unit.test.js +0 -77
- package/lib/api/runtimes/__tests__/healthz.unit.test.d.ts +0 -1
- package/lib/api/runtimes/__tests__/healthz.unit.test.js +0 -57
- package/lib/api/runtimes/__tests__/runtimes.unit.test.d.ts +0 -1
- package/lib/api/runtimes/__tests__/runtimes.unit.test.js +0 -139
- package/lib/api/runtimes/__tests__/snapshots.unit.test.d.ts +0 -1
- package/lib/api/runtimes/__tests__/snapshots.unit.test.js +0 -96
- package/lib/api/spacer/__tests__/healthz.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/healthz.unit.test.js +0 -57
- package/lib/api/spacer/__tests__/items.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/items.unit.test.js +0 -165
- package/lib/api/spacer/__tests__/lexicals.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/lexicals.unit.test.js +0 -323
- package/lib/api/spacer/__tests__/notebooks.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/notebooks.unit.test.js +0 -224
- package/lib/api/spacer/__tests__/users.unit.test.d.ts +0 -1
- package/lib/api/spacer/__tests__/users.unit.test.js +0 -132
- package/lib/api/utils/__tests__/validation.test.d.ts +0 -1
- package/lib/api/utils/__tests__/validation.test.js +0 -109
- package/lib/sdk/client/__tests__/sdk.health.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.health.integration.test.js +0 -110
- package/lib/sdk/client/__tests__/sdk.iam.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.iam.integration.test.js +0 -179
- package/lib/sdk/client/__tests__/sdk.models.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.models.integration.test.js +0 -376
- package/lib/sdk/client/__tests__/sdk.runtimes.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.runtimes.integration.test.js +0 -276
- package/lib/sdk/client/__tests__/sdk.spacer.integration.test.d.ts +0 -1
- package/lib/sdk/client/__tests__/sdk.spacer.integration.test.js +0 -361
- package/lib/sdk/client/base.d.ts +0 -88
- package/lib/sdk/client/base.js +0 -112
- package/lib/sdk/client/index.d.ts +0 -192
- package/lib/sdk/client/index.js +0 -128
- package/lib/sdk/client/mixins/HealthMixin.d.ts +0 -100
- package/lib/sdk/client/mixins/HealthMixin.js +0 -133
- package/lib/sdk/client/mixins/IAMMixin.d.ts +0 -59
- package/lib/sdk/client/mixins/IAMMixin.js +0 -83
- package/lib/sdk/client/mixins/RuntimesMixin.d.ts +0 -134
- package/lib/sdk/client/mixins/RuntimesMixin.js +0 -221
- package/lib/sdk/client/mixins/SpacerMixin.d.ts +0 -184
- package/lib/sdk/client/mixins/SpacerMixin.js +0 -278
- package/lib/sdk/client/models/Lexical.d.ts +0 -156
- package/lib/sdk/client/models/Lexical.js +0 -275
- package/lib/sdk/client/models/Notebook.d.ts +0 -174
- package/lib/sdk/client/models/Notebook.js +0 -311
- package/lib/sdk/client/models/Runtime.d.ts +0 -221
- package/lib/sdk/client/models/Runtime.js +0 -341
- package/lib/sdk/client/models/Snapshot.d.ts +0 -156
- package/lib/sdk/client/models/Snapshot.js +0 -244
- package/lib/sdk/client/models/Space.d.ts +0 -182
- package/lib/sdk/client/models/Space.js +0 -276
- package/lib/sdk/client/models/__tests__/Lexical.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Lexical.test.js +0 -288
- package/lib/sdk/client/models/__tests__/Notebook.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Notebook.test.js +0 -206
- package/lib/sdk/client/models/__tests__/Runtime.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Runtime.test.js +0 -133
- package/lib/sdk/client/models/__tests__/Snapshot.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Snapshot.test.js +0 -244
- package/lib/sdk/client/models/__tests__/Space.test.d.ts +0 -1
- package/lib/sdk/client/models/__tests__/Space.test.js +0 -334
- package/lib/sdk/client/models/index.d.ts +0 -30
- package/lib/sdk/client/models/index.js +0 -30
- package/lib/sdk/client/utils/mixins.d.ts +0 -42
- /package/lib/{sdk/stateful/runtimes/apis.js → api/types/common.js} +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/exec/Python.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/exec/Python.js +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/exec/index.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/exec/index.js +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/index.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/index.js +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/kernelsHandler.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/jupyter/kernelsHandler.js +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/index.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/index.js +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/settings.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/settings.js +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/snapshots.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/snapshots.js +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/utils.d.ts +0 -0
- /package/lib/{sdk/stateful → stateful}/runtimes/utils.js +0 -0
|
@@ -1,519 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
-
* Distributed under the terms of the Modified BSD License.
|
|
4
|
-
*/
|
|
5
|
-
import { describe, it, expect, beforeAll, afterAll, test } from 'vitest';
|
|
6
|
-
import { users, notebooks, lexicals, items } from '../spacer';
|
|
7
|
-
import { testConfig, debugLog, skipIfNoToken, } from '../../__tests__/shared/test-config';
|
|
8
|
-
import { performCleanup } from '../../__tests__/shared/cleanup-shared';
|
|
9
|
-
let DATALAYER_TOKEN;
|
|
10
|
-
let BASE_URL;
|
|
11
|
-
// Skip all tests if no token is available
|
|
12
|
-
const skipTests = skipIfNoToken();
|
|
13
|
-
beforeAll(async () => {
|
|
14
|
-
if (skipTests) {
|
|
15
|
-
console.log('WARNING: Skipping Spacer Lifecycle integration tests: No Datalayer API token configured');
|
|
16
|
-
console.log(' Set DATALAYER_API_TOKEN env var or DATALAYER_TEST_TOKEN in .env.test');
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
// Get token and base URL from test config
|
|
20
|
-
DATALAYER_TOKEN = testConfig.getToken();
|
|
21
|
-
BASE_URL = testConfig.getBaseUrl('SPACER');
|
|
22
|
-
debugLog('Test configuration loaded');
|
|
23
|
-
debugLog('Base URL:', BASE_URL);
|
|
24
|
-
debugLog('Token available:', !!DATALAYER_TOKEN);
|
|
25
|
-
// Pre-test cleanup
|
|
26
|
-
await performCleanup('setup');
|
|
27
|
-
});
|
|
28
|
-
afterAll(async () => {
|
|
29
|
-
if (skipTests) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
// Post-test cleanup
|
|
33
|
-
await performCleanup('teardown');
|
|
34
|
-
});
|
|
35
|
-
describe.skipIf(skipTests)('Spacer Complete Lifecycle Integration Tests', () => {
|
|
36
|
-
// Complete lifecycle test for spacer resources
|
|
37
|
-
describe.sequential('complete spacer resource lifecycle', () => {
|
|
38
|
-
let testSpaceId;
|
|
39
|
-
let createdNotebookId;
|
|
40
|
-
let createdLexicalId;
|
|
41
|
-
let createdItemIds = [];
|
|
42
|
-
const testNamePrefix = `test-${Date.now()}`;
|
|
43
|
-
// No cleanup needed - handled by global setup/teardown
|
|
44
|
-
test('1. should get user spaces to find a valid space ID', async () => {
|
|
45
|
-
console.log('Getting user spaces...');
|
|
46
|
-
const response = await users.getMySpaces(DATALAYER_TOKEN, BASE_URL);
|
|
47
|
-
expect(response).toBeDefined();
|
|
48
|
-
expect(response).toHaveProperty('success');
|
|
49
|
-
expect(response.success).toBe(true);
|
|
50
|
-
expect(response).toHaveProperty('spaces');
|
|
51
|
-
expect(Array.isArray(response.spaces)).toBe(true);
|
|
52
|
-
console.log(`Found ${response.spaces.length} space(s) for user`);
|
|
53
|
-
if (response.spaces.length > 0) {
|
|
54
|
-
const firstSpace = response.spaces[0];
|
|
55
|
-
testSpaceId = firstSpace.uid || firstSpace.id;
|
|
56
|
-
const spaceName = firstSpace.name || firstSpace.name_t;
|
|
57
|
-
console.log(`Using space ID: ${testSpaceId} (${spaceName})`);
|
|
58
|
-
// Verify space structure - check for either old or new field names
|
|
59
|
-
expect(firstSpace).toHaveProperty('uid');
|
|
60
|
-
expect(firstSpace).toSatisfy((space) => space.name !== undefined || space.name_t !== undefined);
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
console.log('WARNING: No spaces found - some tests may fail');
|
|
64
|
-
// Use a placeholder space ID
|
|
65
|
-
testSpaceId = 'test-space-id';
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
test('2. should create a notebook', async () => {
|
|
69
|
-
if (!testSpaceId) {
|
|
70
|
-
console.log('No space ID available, skipping notebook creation');
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
// Add initial delay to spread out load when running with other tests
|
|
74
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
75
|
-
console.log('Creating notebook...');
|
|
76
|
-
const notebookContent = {
|
|
77
|
-
cells: [
|
|
78
|
-
{
|
|
79
|
-
cell_type: 'markdown',
|
|
80
|
-
metadata: {},
|
|
81
|
-
source: [
|
|
82
|
-
'# Test Notebook\n',
|
|
83
|
-
'This is a test notebook created by integration tests',
|
|
84
|
-
],
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
cell_type: 'code',
|
|
88
|
-
metadata: {},
|
|
89
|
-
source: ['print("Hello from integration test")'],
|
|
90
|
-
outputs: [],
|
|
91
|
-
},
|
|
92
|
-
],
|
|
93
|
-
metadata: {
|
|
94
|
-
kernelspec: {
|
|
95
|
-
display_name: 'Python 3',
|
|
96
|
-
language: 'python',
|
|
97
|
-
name: 'python3',
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
nbformat: 4,
|
|
101
|
-
nbformat_minor: 4,
|
|
102
|
-
};
|
|
103
|
-
const file = new Blob([JSON.stringify(notebookContent)], {
|
|
104
|
-
type: 'application/json',
|
|
105
|
-
});
|
|
106
|
-
try {
|
|
107
|
-
const response = await notebooks.createNotebook(DATALAYER_TOKEN, {
|
|
108
|
-
spaceId: testSpaceId,
|
|
109
|
-
notebookType: 'jupyter',
|
|
110
|
-
name: `${testNamePrefix}-notebook`,
|
|
111
|
-
description: 'Integration test notebook',
|
|
112
|
-
file: file,
|
|
113
|
-
}, BASE_URL);
|
|
114
|
-
console.log('Notebook response:', JSON.stringify(response, null, 2));
|
|
115
|
-
if (response.success) {
|
|
116
|
-
expect(response).toHaveProperty('notebook');
|
|
117
|
-
expect(response.notebook).toHaveProperty('id');
|
|
118
|
-
createdNotebookId = response.notebook.uid;
|
|
119
|
-
console.log(`Created notebook with UID: ${createdNotebookId}`);
|
|
120
|
-
createdItemIds.push(createdNotebookId);
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
console.log('Notebook creation failed:', response.message);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
catch (error) {
|
|
127
|
-
console.error('Error creating notebook:', error.message);
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
test('3. should create a lexical document', async () => {
|
|
131
|
-
if (!testSpaceId) {
|
|
132
|
-
console.log('No space ID available, skipping lexical creation');
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
// Add delay to spread out load when running with other tests
|
|
136
|
-
await new Promise(resolve => setTimeout(resolve, 2000)); // Stagger more than notebook creation
|
|
137
|
-
console.log('Creating lexical document...');
|
|
138
|
-
const lexicalContent = {
|
|
139
|
-
root: {
|
|
140
|
-
type: 'root',
|
|
141
|
-
format: '',
|
|
142
|
-
indent: 0,
|
|
143
|
-
version: 1,
|
|
144
|
-
children: [
|
|
145
|
-
{
|
|
146
|
-
type: 'paragraph',
|
|
147
|
-
format: '',
|
|
148
|
-
indent: 0,
|
|
149
|
-
version: 1,
|
|
150
|
-
children: [
|
|
151
|
-
{
|
|
152
|
-
type: 'text',
|
|
153
|
-
format: 0,
|
|
154
|
-
style: '',
|
|
155
|
-
mode: 'normal',
|
|
156
|
-
text: 'Test lexical document from integration test',
|
|
157
|
-
version: 1,
|
|
158
|
-
detail: 0,
|
|
159
|
-
},
|
|
160
|
-
],
|
|
161
|
-
},
|
|
162
|
-
],
|
|
163
|
-
},
|
|
164
|
-
};
|
|
165
|
-
const file = new Blob([JSON.stringify(lexicalContent)], {
|
|
166
|
-
type: 'application/json',
|
|
167
|
-
});
|
|
168
|
-
try {
|
|
169
|
-
const response = await lexicals.createLexical(DATALAYER_TOKEN, {
|
|
170
|
-
spaceId: testSpaceId,
|
|
171
|
-
documentType: 'lexical',
|
|
172
|
-
name: `${testNamePrefix}-lexical`,
|
|
173
|
-
description: 'Integration test lexical document',
|
|
174
|
-
file: file,
|
|
175
|
-
}, BASE_URL);
|
|
176
|
-
console.log('Lexical response:', JSON.stringify(response, null, 2));
|
|
177
|
-
if (response.success) {
|
|
178
|
-
expect(response).toHaveProperty('document');
|
|
179
|
-
expect(response.document).toHaveProperty('id');
|
|
180
|
-
createdLexicalId = response.document.uid;
|
|
181
|
-
console.log(`Created lexical with UID: ${createdLexicalId}`);
|
|
182
|
-
createdItemIds.push(createdLexicalId);
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
console.log('Lexical creation failed:', response.message);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
catch (error) {
|
|
189
|
-
console.error('Error creating lexical:', error.message);
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
test('4. should list all items in the space', async () => {
|
|
193
|
-
if (!testSpaceId) {
|
|
194
|
-
console.log('No space ID available, skipping list items');
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
console.log('Listing items in space...');
|
|
198
|
-
const response = await items.getSpaceItems(DATALAYER_TOKEN, testSpaceId, BASE_URL);
|
|
199
|
-
console.log('Items response:', JSON.stringify(response, null, 2));
|
|
200
|
-
expect(response).toBeDefined();
|
|
201
|
-
expect(response).toHaveProperty('success');
|
|
202
|
-
expect(response).toHaveProperty('items');
|
|
203
|
-
if (response.success && Array.isArray(response.items)) {
|
|
204
|
-
console.log(`Found ${response.items.length} items in space`);
|
|
205
|
-
// Find our created items
|
|
206
|
-
const foundNotebook = createdNotebookId
|
|
207
|
-
? response.items.find((item) => item.id === createdNotebookId)
|
|
208
|
-
: null;
|
|
209
|
-
const foundLexical = createdLexicalId
|
|
210
|
-
? response.items.find((item) => item.id === createdLexicalId)
|
|
211
|
-
: null;
|
|
212
|
-
if (foundNotebook) {
|
|
213
|
-
console.log('✓ Found created notebook in items list');
|
|
214
|
-
console.log('Notebook object:', JSON.stringify(foundNotebook, null, 2));
|
|
215
|
-
// Handle both name formats that might be returned
|
|
216
|
-
const notebookName = foundNotebook.name || foundNotebook.name_t || '';
|
|
217
|
-
if (notebookName) {
|
|
218
|
-
expect(notebookName).toContain(testNamePrefix);
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
console.log('Warning: Notebook found but has no name field');
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
if (foundLexical) {
|
|
225
|
-
console.log('✓ Found created lexical in items list');
|
|
226
|
-
console.log('Lexical object:', JSON.stringify(foundLexical, null, 2));
|
|
227
|
-
// Handle both name formats that might be returned
|
|
228
|
-
const lexicalName = foundLexical.name || foundLexical.name_t || '';
|
|
229
|
-
if (lexicalName) {
|
|
230
|
-
expect(lexicalName).toContain(testNamePrefix);
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
console.log('Warning: Lexical found but has no name field');
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
test('5. should get notebook details', async () => {
|
|
239
|
-
if (!createdNotebookId) {
|
|
240
|
-
console.log('No notebook was created, skipping get test');
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
console.log('Getting notebook details...');
|
|
244
|
-
try {
|
|
245
|
-
// Add a small delay to allow server processing
|
|
246
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
247
|
-
const response = await notebooks.getNotebook(DATALAYER_TOKEN, createdNotebookId, BASE_URL);
|
|
248
|
-
console.log('Get notebook response:', JSON.stringify(response, null, 2));
|
|
249
|
-
expect(response).toBeDefined();
|
|
250
|
-
expect(response).toHaveProperty('success');
|
|
251
|
-
if (response.success) {
|
|
252
|
-
expect(response).toHaveProperty('notebook');
|
|
253
|
-
expect(response.notebook?.uid).toBe(createdNotebookId);
|
|
254
|
-
console.log('✓ Retrieved notebook details successfully');
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
catch (error) {
|
|
258
|
-
console.log('Expected error getting notebook:', error.message);
|
|
259
|
-
// The notebook might not be immediately available after creation
|
|
260
|
-
// This is acceptable for this test scenario
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
test('6. should get lexical details', async () => {
|
|
264
|
-
if (!createdLexicalId) {
|
|
265
|
-
console.log('No lexical was created, skipping get test');
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
console.log('Getting lexical details...');
|
|
269
|
-
try {
|
|
270
|
-
// Add a small delay to allow server processing
|
|
271
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
272
|
-
const response = await lexicals.getLexical(DATALAYER_TOKEN, createdLexicalId, BASE_URL);
|
|
273
|
-
console.log('Get lexical response:', JSON.stringify(response, null, 2));
|
|
274
|
-
expect(response).toBeDefined();
|
|
275
|
-
expect(response).toHaveProperty('success');
|
|
276
|
-
if (response.success) {
|
|
277
|
-
expect(response).toHaveProperty('document');
|
|
278
|
-
expect(response.document?.uid).toBe(createdLexicalId);
|
|
279
|
-
console.log('✓ Retrieved lexical details successfully');
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
catch (error) {
|
|
283
|
-
console.log('Expected error getting lexical:', error.message);
|
|
284
|
-
// The lexical might not be immediately available after creation
|
|
285
|
-
// This is acceptable for this test scenario
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
test('7. should update notebook', async () => {
|
|
289
|
-
if (!createdNotebookId) {
|
|
290
|
-
console.log('No notebook was created, skipping update test');
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
console.log('Updating notebook...');
|
|
294
|
-
const updateData = {
|
|
295
|
-
name: `${testNamePrefix}-notebook-updated`,
|
|
296
|
-
description: 'Updated integration test notebook',
|
|
297
|
-
};
|
|
298
|
-
try {
|
|
299
|
-
// Add delay to allow server processing and avoid resource contention
|
|
300
|
-
await new Promise(resolve => setTimeout(resolve, 5000)); // 5 second delay for bulk test runs
|
|
301
|
-
const response = await notebooks.updateNotebook(DATALAYER_TOKEN, createdNotebookId, updateData, BASE_URL);
|
|
302
|
-
console.log('Update notebook response:', JSON.stringify(response, null, 2));
|
|
303
|
-
expect(response).toBeDefined();
|
|
304
|
-
expect(response).toHaveProperty('success');
|
|
305
|
-
if (response.success) {
|
|
306
|
-
expect(response).toHaveProperty('notebook');
|
|
307
|
-
expect(response.notebook.uid).toBe(createdNotebookId);
|
|
308
|
-
const nameObj = response.notebook.name_t || response.notebook.name || {};
|
|
309
|
-
const notebookName = nameObj && typeof nameObj === 'object' && nameObj.set
|
|
310
|
-
? nameObj.set
|
|
311
|
-
: typeof nameObj === 'string'
|
|
312
|
-
? nameObj
|
|
313
|
-
: '';
|
|
314
|
-
expect(notebookName).toContain('updated');
|
|
315
|
-
console.log('✓ Updated notebook successfully');
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
catch (error) {
|
|
319
|
-
console.log('Error updating notebook:', error.message);
|
|
320
|
-
throw error; // Let the test fail
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
test('8. should update lexical', async () => {
|
|
324
|
-
if (!createdLexicalId) {
|
|
325
|
-
console.log('No lexical was created, skipping update test');
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
console.log('Updating lexical...');
|
|
329
|
-
const updateData = {
|
|
330
|
-
name: `${testNamePrefix}-lexical-updated`,
|
|
331
|
-
description: 'Updated integration test lexical',
|
|
332
|
-
};
|
|
333
|
-
try {
|
|
334
|
-
// Add delay to allow server processing and avoid resource contention
|
|
335
|
-
await new Promise(resolve => setTimeout(resolve, 5000)); // 5 second delay for bulk test runs
|
|
336
|
-
const response = await lexicals.updateLexical(DATALAYER_TOKEN, createdLexicalId, updateData, BASE_URL);
|
|
337
|
-
console.log('Update lexical response:', JSON.stringify(response, null, 2));
|
|
338
|
-
expect(response).toBeDefined();
|
|
339
|
-
expect(response).toHaveProperty('success');
|
|
340
|
-
if (response.success) {
|
|
341
|
-
expect(response).toHaveProperty('document');
|
|
342
|
-
expect(response.document.uid).toBe(createdLexicalId);
|
|
343
|
-
const nameObj = response.document.name_t || response.document.name || {};
|
|
344
|
-
const lexicalName = nameObj && typeof nameObj === 'object' && nameObj.set
|
|
345
|
-
? nameObj.set
|
|
346
|
-
: typeof nameObj === 'string'
|
|
347
|
-
? nameObj
|
|
348
|
-
: '';
|
|
349
|
-
expect(lexicalName).toContain('updated');
|
|
350
|
-
console.log('✓ Updated lexical successfully');
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
catch (error) {
|
|
354
|
-
console.log('Error updating lexical:', error.message);
|
|
355
|
-
throw error; // Let the test fail
|
|
356
|
-
}
|
|
357
|
-
});
|
|
358
|
-
test('9. should verify updates by getting items again', async () => {
|
|
359
|
-
if (!createdNotebookId && !createdLexicalId) {
|
|
360
|
-
console.log('No items were created, skipping verification');
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
console.log('Verifying updates...');
|
|
364
|
-
// Get notebook to verify update
|
|
365
|
-
if (createdNotebookId) {
|
|
366
|
-
const notebookResponse = await notebooks.getNotebook(DATALAYER_TOKEN, createdNotebookId, BASE_URL);
|
|
367
|
-
if (notebookResponse.success && notebookResponse.notebook) {
|
|
368
|
-
const notebookName = notebookResponse.notebook.name ||
|
|
369
|
-
notebookResponse.notebook.name_t ||
|
|
370
|
-
'';
|
|
371
|
-
expect(notebookName).toContain('updated');
|
|
372
|
-
console.log('✓ Notebook update verified');
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
// Get lexical to verify update
|
|
376
|
-
if (createdLexicalId) {
|
|
377
|
-
const lexicalResponse = await lexicals.getLexical(DATALAYER_TOKEN, createdLexicalId, BASE_URL);
|
|
378
|
-
if (lexicalResponse.success && lexicalResponse.document) {
|
|
379
|
-
const lexicalName = lexicalResponse.document.name ||
|
|
380
|
-
lexicalResponse.document.name_t ||
|
|
381
|
-
'';
|
|
382
|
-
expect(lexicalName).toContain('updated');
|
|
383
|
-
console.log('✓ Lexical update verified');
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
});
|
|
387
|
-
test('10. should delete notebook', async () => {
|
|
388
|
-
if (!createdNotebookId) {
|
|
389
|
-
console.log('No notebook was created, skipping delete test');
|
|
390
|
-
return;
|
|
391
|
-
}
|
|
392
|
-
console.log('Deleting notebook...');
|
|
393
|
-
try {
|
|
394
|
-
await items.deleteItem(DATALAYER_TOKEN, createdNotebookId, BASE_URL);
|
|
395
|
-
console.log('Notebook deletion request sent');
|
|
396
|
-
// Verify deletion
|
|
397
|
-
const getResponse = await notebooks.getNotebook(DATALAYER_TOKEN, createdNotebookId, BASE_URL);
|
|
398
|
-
if (!getResponse.success) {
|
|
399
|
-
console.log('✓ Notebook properly deleted');
|
|
400
|
-
}
|
|
401
|
-
else {
|
|
402
|
-
console.log('WARNING: Notebook still exists after deletion');
|
|
403
|
-
}
|
|
404
|
-
// Remove from cleanup list
|
|
405
|
-
createdNotebookId = undefined;
|
|
406
|
-
createdItemIds = createdItemIds.filter(id => id !== createdNotebookId);
|
|
407
|
-
}
|
|
408
|
-
catch (error) {
|
|
409
|
-
console.log('Expected deletion error:', error.message);
|
|
410
|
-
}
|
|
411
|
-
});
|
|
412
|
-
test('11. should delete lexical', async () => {
|
|
413
|
-
if (!createdLexicalId) {
|
|
414
|
-
console.log('No lexical was created, skipping delete test');
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
|
-
console.log('Deleting lexical...');
|
|
418
|
-
try {
|
|
419
|
-
await items.deleteItem(DATALAYER_TOKEN, createdLexicalId, BASE_URL);
|
|
420
|
-
console.log('Lexical deletion request sent');
|
|
421
|
-
// Verify deletion
|
|
422
|
-
const getResponse = await lexicals.getLexical(DATALAYER_TOKEN, createdLexicalId, BASE_URL);
|
|
423
|
-
if (!getResponse.success) {
|
|
424
|
-
console.log('✓ Lexical properly deleted');
|
|
425
|
-
}
|
|
426
|
-
else {
|
|
427
|
-
console.log('WARNING: Lexical still exists after deletion');
|
|
428
|
-
}
|
|
429
|
-
// Remove from cleanup list
|
|
430
|
-
createdLexicalId = undefined;
|
|
431
|
-
createdItemIds = createdItemIds.filter(id => id !== createdLexicalId);
|
|
432
|
-
}
|
|
433
|
-
catch (error) {
|
|
434
|
-
console.log('Expected deletion error:', error.message);
|
|
435
|
-
}
|
|
436
|
-
});
|
|
437
|
-
test('12. should verify all items are deleted', async () => {
|
|
438
|
-
if (!testSpaceId) {
|
|
439
|
-
console.log('No space ID available, skipping final verification');
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
console.log('Final verification...');
|
|
443
|
-
const response = await items.getSpaceItems(DATALAYER_TOKEN, testSpaceId, BASE_URL);
|
|
444
|
-
if (response.success && Array.isArray(response.items)) {
|
|
445
|
-
const remainingTestItems = response.items.filter((item) => item.name?.includes(testNamePrefix));
|
|
446
|
-
expect(remainingTestItems.length).toBe(0);
|
|
447
|
-
if (remainingTestItems.length === 0) {
|
|
448
|
-
console.log('✓ All test items successfully deleted');
|
|
449
|
-
}
|
|
450
|
-
else {
|
|
451
|
-
console.log(`WARNING: ${remainingTestItems.length} test items still exist`);
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
console.log('Complete spacer lifecycle test finished successfully!');
|
|
455
|
-
});
|
|
456
|
-
});
|
|
457
|
-
// Basic smoke tests that always run
|
|
458
|
-
describe('smoke tests', () => {
|
|
459
|
-
it('should successfully get user spaces', async () => {
|
|
460
|
-
console.log('Testing get user spaces endpoint...');
|
|
461
|
-
const response = await users.getMySpaces(DATALAYER_TOKEN, BASE_URL);
|
|
462
|
-
console.log(`Found ${response.spaces.length} space(s)`);
|
|
463
|
-
expect(response).toBeDefined();
|
|
464
|
-
expect(response).toHaveProperty('success');
|
|
465
|
-
expect(response.success).toBe(true);
|
|
466
|
-
expect(response).toHaveProperty('spaces');
|
|
467
|
-
expect(Array.isArray(response.spaces)).toBe(true);
|
|
468
|
-
if (response.spaces.length > 0) {
|
|
469
|
-
const firstSpace = response.spaces[0];
|
|
470
|
-
const spaceName = firstSpace.name || firstSpace.name_t;
|
|
471
|
-
console.log('First space:', spaceName);
|
|
472
|
-
expect(firstSpace).toHaveProperty('uid');
|
|
473
|
-
expect(firstSpace).toSatisfy((space) => space.name !== undefined || space.name_t !== undefined);
|
|
474
|
-
}
|
|
475
|
-
});
|
|
476
|
-
it('should handle non-existent notebook gracefully', async () => {
|
|
477
|
-
console.log('Testing get with non-existent notebook ID...');
|
|
478
|
-
try {
|
|
479
|
-
const response = await notebooks.getNotebook(DATALAYER_TOKEN, 'non-existent-notebook-id-123456789', BASE_URL);
|
|
480
|
-
console.log('404 response:', JSON.stringify(response, null, 2));
|
|
481
|
-
expect(response).toBeDefined();
|
|
482
|
-
expect(response).toHaveProperty('success');
|
|
483
|
-
expect(response).toHaveProperty('message');
|
|
484
|
-
if (!response.success) {
|
|
485
|
-
expect(response.notebook).toBeUndefined();
|
|
486
|
-
console.log('Expected 404 message:', response.message);
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
catch (error) {
|
|
490
|
-
console.log('Expected error for non-existent notebook:', error.message);
|
|
491
|
-
expect(error).toBeDefined();
|
|
492
|
-
// API may return either "not found" or "Network Error" for non-existent resources
|
|
493
|
-
expect(error.message.toLowerCase().includes('not found') ||
|
|
494
|
-
error.message.includes('Network Error')).toBeTruthy();
|
|
495
|
-
}
|
|
496
|
-
});
|
|
497
|
-
it('should handle non-existent lexical gracefully', async () => {
|
|
498
|
-
console.log('Testing get with non-existent lexical ID...');
|
|
499
|
-
try {
|
|
500
|
-
const response = await lexicals.getLexical(DATALAYER_TOKEN, 'non-existent-lexical-id-123456789', BASE_URL);
|
|
501
|
-
console.log('404 response:', JSON.stringify(response, null, 2));
|
|
502
|
-
expect(response).toBeDefined();
|
|
503
|
-
expect(response).toHaveProperty('success');
|
|
504
|
-
expect(response).toHaveProperty('message');
|
|
505
|
-
if (!response.success) {
|
|
506
|
-
expect(response.document).toBeUndefined();
|
|
507
|
-
console.log('Expected 404 message:', response.message);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
catch (error) {
|
|
511
|
-
console.log('Expected error for non-existent lexical:', error.message);
|
|
512
|
-
expect(error).toBeDefined();
|
|
513
|
-
// API may return either "not found" or "Network Error" for non-existent resources
|
|
514
|
-
expect(error.message.toLowerCase().includes('not found') ||
|
|
515
|
-
error.message.includes('Network Error')).toBeTruthy();
|
|
516
|
-
}
|
|
517
|
-
});
|
|
518
|
-
});
|
|
519
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
-
* Distributed under the terms of the Modified BSD License.
|
|
4
|
-
*/
|
|
5
|
-
import { describe, it, expect } from 'vitest';
|
|
6
|
-
import { authentication } from '..';
|
|
7
|
-
describe('IAM Authentication Unit Tests', () => {
|
|
8
|
-
describe('login parameter validation', () => {
|
|
9
|
-
const mockBaseUrl = 'https://example.com';
|
|
10
|
-
it('should fail when providing both token and credentials', async () => {
|
|
11
|
-
console.log('Testing invalid login with both token and credentials...');
|
|
12
|
-
await expect(authentication.login({
|
|
13
|
-
token: 'some-token',
|
|
14
|
-
handle: 'user@example.com',
|
|
15
|
-
password: 'password123',
|
|
16
|
-
}, mockBaseUrl)).rejects.toThrow('Cannot provide both credentials (handle/password) and token');
|
|
17
|
-
console.log('Correctly rejected login with both authentication methods');
|
|
18
|
-
});
|
|
19
|
-
it('should fail when providing neither token nor credentials', async () => {
|
|
20
|
-
console.log('Testing invalid login with no authentication...');
|
|
21
|
-
await expect(authentication.login({}, mockBaseUrl)).rejects.toThrow('Must provide either credentials (handle+password) or token');
|
|
22
|
-
console.log('Correctly rejected login with no authentication');
|
|
23
|
-
});
|
|
24
|
-
it('should fail when providing handle without password', async () => {
|
|
25
|
-
console.log('Testing invalid login with handle but no password...');
|
|
26
|
-
await expect(authentication.login({
|
|
27
|
-
handle: 'user@example.com',
|
|
28
|
-
}, mockBaseUrl)).rejects.toThrow('Both handle and password are required for credential-based authentication');
|
|
29
|
-
console.log('Correctly rejected login with incomplete credentials');
|
|
30
|
-
});
|
|
31
|
-
it('should fail when providing password without handle', async () => {
|
|
32
|
-
console.log('Testing invalid login with password but no handle...');
|
|
33
|
-
await expect(authentication.login({
|
|
34
|
-
password: 'password123',
|
|
35
|
-
}, mockBaseUrl)).rejects.toThrow('Both handle and password are required for credential-based authentication');
|
|
36
|
-
console.log('Correctly rejected login with incomplete credentials');
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
describe('logout parameter validation', () => {
|
|
40
|
-
it('should require a token for logout', async () => {
|
|
41
|
-
console.log('Testing logout without token...');
|
|
42
|
-
// TypeScript should prevent this at compile time, but let's test runtime behavior
|
|
43
|
-
// @ts-expect-error Testing missing required parameter
|
|
44
|
-
await expect(authentication.logout()).rejects.toThrow();
|
|
45
|
-
console.log('Correctly rejected logout without token');
|
|
46
|
-
});
|
|
47
|
-
it('should accept logout with only token (using default URL)', async () => {
|
|
48
|
-
console.log('Testing logout with token only (default URL)...');
|
|
49
|
-
// This should not throw a validation error (though it may fail with API)
|
|
50
|
-
// The method signature allows this since baseUrl has a default
|
|
51
|
-
const mockToken = 'mock-token';
|
|
52
|
-
// We can't test the actual API call in a unit test, but we can verify
|
|
53
|
-
// the method accepts this signature
|
|
54
|
-
expect(() => {
|
|
55
|
-
// This should not throw a compile-time or immediate runtime error
|
|
56
|
-
const promise = authentication.logout(mockToken);
|
|
57
|
-
// Cancel the promise to avoid actual API call in unit test
|
|
58
|
-
promise.catch(() => { }); // Ignore the error
|
|
59
|
-
}).not.toThrow();
|
|
60
|
-
console.log('Logout accepts token with default URL');
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
-
* Distributed under the terms of the Modified BSD License.
|
|
4
|
-
*/
|
|
5
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
6
|
-
import { ping } from '../healthz';
|
|
7
|
-
import { requestDatalayerAPI } from '../../DatalayerApi';
|
|
8
|
-
// Mock the DatalayerAPI module
|
|
9
|
-
vi.mock('../../DatalayerApi');
|
|
10
|
-
describe('IAM Healthz Unit Tests', () => {
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
vi.clearAllMocks();
|
|
13
|
-
});
|
|
14
|
-
describe('ping', () => {
|
|
15
|
-
it('should return health status on successful health check', async () => {
|
|
16
|
-
const mockResponse = {
|
|
17
|
-
success: true,
|
|
18
|
-
message: 'datalayer_iam is up and running.',
|
|
19
|
-
status: { status: 'OK' },
|
|
20
|
-
version: '1.0.7',
|
|
21
|
-
};
|
|
22
|
-
vi.mocked(requestDatalayerAPI).mockResolvedValueOnce(mockResponse);
|
|
23
|
-
const result = await ping();
|
|
24
|
-
expect(result).toEqual(mockResponse);
|
|
25
|
-
expect(requestDatalayerAPI).toHaveBeenCalledWith({
|
|
26
|
-
url: 'https://prod1.datalayer.run/api/iam/v1/ping',
|
|
27
|
-
method: 'GET',
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
it('should use custom base URL when provided', async () => {
|
|
31
|
-
const mockResponse = {
|
|
32
|
-
success: true,
|
|
33
|
-
message: 'Service is healthy',
|
|
34
|
-
status: { status: 'OK' },
|
|
35
|
-
version: '2.0.0',
|
|
36
|
-
};
|
|
37
|
-
const customUrl = 'https://custom.example.com';
|
|
38
|
-
vi.mocked(requestDatalayerAPI).mockResolvedValueOnce(mockResponse);
|
|
39
|
-
const result = await ping(customUrl);
|
|
40
|
-
expect(result).toEqual(mockResponse);
|
|
41
|
-
expect(requestDatalayerAPI).toHaveBeenCalledWith({
|
|
42
|
-
url: `${customUrl}/api/iam/v1/ping`,
|
|
43
|
-
method: 'GET',
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
it('should throw error with status code on failure', async () => {
|
|
47
|
-
const mockError = {
|
|
48
|
-
response: { status: 500 },
|
|
49
|
-
message: 'Internal Server Error',
|
|
50
|
-
};
|
|
51
|
-
vi.mocked(requestDatalayerAPI).mockRejectedValueOnce(mockError);
|
|
52
|
-
await expect(ping()).rejects.toThrow('Health check failed: Service unhealthy (status 500) - Internal Server Error');
|
|
53
|
-
});
|
|
54
|
-
it('should throw generic error on network failure', async () => {
|
|
55
|
-
const mockError = new Error('Network error');
|
|
56
|
-
vi.mocked(requestDatalayerAPI).mockRejectedValueOnce(mockError);
|
|
57
|
-
await expect(ping()).rejects.toThrow('Health check failed: Network error');
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|