@memberjunction/storage 4.1.0 → 4.3.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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@memberjunction/storage",
3
3
  "type": "module",
4
- "version": "4.1.0",
4
+ "version": "4.3.0",
5
5
  "description": "This library provides a set of objects that handle the interface between the server-side API and various cloud storage providers.",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -12,17 +12,15 @@
12
12
  "start": "ts-node-dev src/index.ts",
13
13
  "build": "tsc && tsc-alias -f",
14
14
  "watch": "tsc -w",
15
- "test": "jest",
16
- "test:watch": "jest --watch",
17
- "test:coverage": "jest --coverage"
15
+ "test": "vitest run",
16
+ "test:watch": "vitest",
17
+ "test:coverage": "vitest run --coverage"
18
18
  },
19
19
  "author": "MemberJunction.com",
20
20
  "license": "ISC",
21
21
  "devDependencies": {
22
- "@types/jest": "^30.0.0",
23
- "jest": "^30.2.0",
24
- "ts-jest": "^29.4.6",
25
22
  "ts-node-dev": "^2.0.0",
23
+ "vitest": "^3.1.1",
26
24
  "typescript": "^5.9.3"
27
25
  },
28
26
  "dependencies": {
@@ -31,10 +29,10 @@
31
29
  "@azure/identity": "^4.13.0",
32
30
  "@azure/storage-blob": "^12.30.0",
33
31
  "@google-cloud/storage": "^7.19.0",
34
- "@memberjunction/core": "4.1.0",
35
- "@memberjunction/core-entities": "4.1.0",
36
- "@memberjunction/credentials": "4.1.0",
37
- "@memberjunction/global": "4.1.0",
32
+ "@memberjunction/core": "4.3.0",
33
+ "@memberjunction/core-entities": "4.3.0",
34
+ "@memberjunction/credentials": "4.3.0",
35
+ "@memberjunction/global": "4.3.0",
38
36
  "@microsoft/mgt-element": "^4.6.0",
39
37
  "@microsoft/mgt-msal2-provider": "^4.6.0",
40
38
  "@microsoft/mgt-sharepoint-provider": "^4.6.0",
@@ -1,6 +0,0 @@
1
- /**
2
- * Unit tests for the FileStorageBase class.
3
- * These tests focus on the initialize() method and account information handling.
4
- */
5
- export {};
6
- //# sourceMappingURL=FileStorageBase.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FileStorageBase.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/FileStorageBase.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -1,275 +0,0 @@
1
- /**
2
- * Unit tests for the FileStorageBase class.
3
- * These tests focus on the initialize() method and account information handling.
4
- */
5
- import { FileStorageBase, UnsupportedOperationError, } from '../generic/FileStorageBase.js';
6
- /**
7
- * Concrete implementation of FileStorageBase for testing purposes.
8
- * This class implements all abstract methods with minimal functionality
9
- * to allow testing the base class behavior.
10
- */
11
- class TestableFileStorageDriver extends FileStorageBase {
12
- constructor() {
13
- super(...arguments);
14
- this.providerName = 'TestableProvider';
15
- this._isConfigured = false;
16
- this.configPassedToInitialize = null;
17
- }
18
- async initialize(config) {
19
- // Call the base implementation
20
- await super.initialize(config);
21
- // Store the config for test verification
22
- this.configPassedToInitialize = config || null;
23
- this._isConfigured = true;
24
- }
25
- get IsConfigured() {
26
- return this._isConfigured;
27
- }
28
- // Minimal implementations of abstract methods
29
- async CreatePreAuthUploadUrl(objectName) {
30
- return { UploadUrl: `https://test.url/${objectName}` };
31
- }
32
- async CreatePreAuthDownloadUrl(objectName) {
33
- return `https://test.url/${objectName}`;
34
- }
35
- async MoveObject(oldObjectName, newObjectName) {
36
- return true;
37
- }
38
- async DeleteObject(objectName) {
39
- return true;
40
- }
41
- async ListObjects(prefix, delimiter) {
42
- return { objects: [], prefixes: [] };
43
- }
44
- async CreateDirectory(directoryPath) {
45
- return true;
46
- }
47
- async DeleteDirectory(directoryPath, recursive) {
48
- return true;
49
- }
50
- async GetObjectMetadata(params) {
51
- return {
52
- name: 'test.txt',
53
- path: '/',
54
- fullPath: '/test.txt',
55
- size: 0,
56
- contentType: 'text/plain',
57
- lastModified: new Date(),
58
- isDirectory: false,
59
- };
60
- }
61
- async GetObject(params) {
62
- return Buffer.from('');
63
- }
64
- async PutObject(objectName, data, contentType, metadata) {
65
- return true;
66
- }
67
- async CopyObject(sourceObjectName, destinationObjectName) {
68
- return true;
69
- }
70
- async ObjectExists(objectName) {
71
- return false;
72
- }
73
- async DirectoryExists(directoryPath) {
74
- return false;
75
- }
76
- async SearchFiles(query, options) {
77
- return { results: [], hasMore: false };
78
- }
79
- // Expose the protected method for testing
80
- testThrowUnsupportedOperationError(methodName) {
81
- return this.throwUnsupportedOperationError(methodName);
82
- }
83
- }
84
- describe('FileStorageBase', () => {
85
- let driver;
86
- beforeEach(() => {
87
- driver = new TestableFileStorageDriver();
88
- });
89
- describe('initialize()', () => {
90
- it('should store accountId from config', async () => {
91
- const config = {
92
- accountId: 'test-account-id-123',
93
- };
94
- await driver.initialize(config);
95
- expect(driver.AccountId).toBe('test-account-id-123');
96
- });
97
- it('should store accountName from config when provided', async () => {
98
- const config = {
99
- accountId: 'test-account-id-123',
100
- accountName: 'My Test Storage Account',
101
- };
102
- await driver.initialize(config);
103
- expect(driver.AccountName).toBe('My Test Storage Account');
104
- });
105
- it('should handle undefined accountName gracefully', async () => {
106
- const config = {
107
- accountId: 'test-account-id-123',
108
- // accountName intentionally omitted
109
- };
110
- await driver.initialize(config);
111
- expect(driver.AccountId).toBe('test-account-id-123');
112
- expect(driver.AccountName).toBeUndefined();
113
- });
114
- it('should allow additional provider-specific config values', async () => {
115
- const config = {
116
- accountId: 'account-456',
117
- accountName: 'S3 Bucket Account',
118
- bucket: 'my-bucket',
119
- region: 'us-west-2',
120
- accessKeyId: 'AKIA...',
121
- };
122
- await driver.initialize(config);
123
- // Verify base properties are set
124
- expect(driver.AccountId).toBe('account-456');
125
- expect(driver.AccountName).toBe('S3 Bucket Account');
126
- // Verify the full config was passed through
127
- expect(driver.configPassedToInitialize).toEqual({
128
- accountId: 'account-456',
129
- accountName: 'S3 Bucket Account',
130
- bucket: 'my-bucket',
131
- region: 'us-west-2',
132
- accessKeyId: 'AKIA...',
133
- });
134
- });
135
- });
136
- describe('AccountId getter', () => {
137
- it('should return undefined before initialization', () => {
138
- expect(driver.AccountId).toBeUndefined();
139
- });
140
- it('should return the accountId after initialization', async () => {
141
- await driver.initialize({ accountId: 'my-account-id' });
142
- expect(driver.AccountId).toBe('my-account-id');
143
- });
144
- });
145
- describe('AccountName getter', () => {
146
- it('should return undefined before initialization', () => {
147
- expect(driver.AccountName).toBeUndefined();
148
- });
149
- it('should return the accountName after initialization', async () => {
150
- await driver.initialize({
151
- accountId: 'my-account-id',
152
- accountName: 'Production S3 Account',
153
- });
154
- expect(driver.AccountName).toBe('Production S3 Account');
155
- });
156
- });
157
- describe('UnsupportedOperationError', () => {
158
- it('should create error with correct message format', () => {
159
- const error = new UnsupportedOperationError('SearchFiles', 'AWS S3');
160
- expect(error.message).toBe("Operation 'SearchFiles' is not supported by the AWS S3 provider");
161
- expect(error.name).toBe('UnsupportedOperationError');
162
- });
163
- it('should throw UnsupportedOperationError via helper method', () => {
164
- expect(() => {
165
- driver.testThrowUnsupportedOperationError('TestMethod');
166
- }).toThrow(UnsupportedOperationError);
167
- expect(() => {
168
- driver.testThrowUnsupportedOperationError('TestMethod');
169
- }).toThrow("Operation 'TestMethod' is not supported by the TestableProvider provider");
170
- });
171
- });
172
- describe('IsConfigured', () => {
173
- it('should return false before initialization', () => {
174
- expect(driver.IsConfigured).toBe(false);
175
- });
176
- it('should return true after initialization', async () => {
177
- await driver.initialize({ accountId: 'test' });
178
- expect(driver.IsConfigured).toBe(true);
179
- });
180
- });
181
- });
182
- describe('StorageProviderConfig interface', () => {
183
- it('should allow accountId to be optional', () => {
184
- // This is a compile-time check - if the type is wrong, TypeScript will error
185
- const validConfigWithAccount = {
186
- accountId: 'optional-account-id',
187
- };
188
- const validConfigWithoutAccount = {};
189
- expect(validConfigWithAccount.accountId).toBe('optional-account-id');
190
- expect(validConfigWithoutAccount.accountId).toBeUndefined();
191
- });
192
- it('should allow optional accountName property', () => {
193
- const configWithName = {
194
- accountId: 'account-1',
195
- accountName: 'Optional Name',
196
- };
197
- const configWithoutName = {
198
- accountId: 'account-2',
199
- };
200
- expect(configWithName.accountName).toBe('Optional Name');
201
- expect(configWithoutName.accountName).toBeUndefined();
202
- });
203
- it('should allow additional provider-specific properties', () => {
204
- const s3Config = {
205
- accountId: 'aws-account',
206
- accountName: 'AWS S3 Account',
207
- bucket: 'my-bucket',
208
- region: 'us-east-1',
209
- accessKeyId: 'AKIA...',
210
- secretAccessKey: 'secret...',
211
- };
212
- expect(s3Config.bucket).toBe('my-bucket');
213
- expect(s3Config.region).toBe('us-east-1');
214
- });
215
- });
216
- describe('Unified Initialize Pattern', () => {
217
- let driver;
218
- beforeEach(() => {
219
- driver = new TestableFileStorageDriver();
220
- });
221
- describe('Simple Deployment (No Config)', () => {
222
- it('should initialize with no config (uses env vars)', async () => {
223
- // Simulate environment variable setup by calling initialize with no config
224
- await driver.initialize({});
225
- expect(driver.IsConfigured).toBe(true);
226
- expect(driver.AccountId).toBeUndefined(); // No accountId provided
227
- expect(driver.AccountName).toBeUndefined();
228
- });
229
- it('should allow initialize to be called without any config object', async () => {
230
- // Even calling with undefined should work
231
- await driver.initialize(undefined);
232
- // The driver should still be in some state (depends on implementation)
233
- // Implementation stores config || null, so undefined becomes null
234
- expect(driver.configPassedToInitialize).toBeNull();
235
- });
236
- });
237
- describe('Multi-Tenant (With Config)', () => {
238
- it('should initialize with full config', async () => {
239
- const config = {
240
- accountId: '12345-67890',
241
- accountName: 'Test Account',
242
- bucket: 'runtime-bucket',
243
- region: 'us-west-2',
244
- accessKeyId: 'runtime-key',
245
- };
246
- await driver.initialize(config);
247
- expect(driver.IsConfigured).toBe(true);
248
- expect(driver.AccountId).toBe('12345-67890');
249
- expect(driver.AccountName).toBe('Test Account');
250
- expect(driver.configPassedToInitialize).toEqual(config);
251
- });
252
- it('should allow partial config (accountId only)', async () => {
253
- const config = {
254
- accountId: 'account-123',
255
- };
256
- await driver.initialize(config);
257
- expect(driver.AccountId).toBe('account-123');
258
- expect(driver.AccountName).toBeUndefined();
259
- });
260
- });
261
- describe('Override Behavior', () => {
262
- it('should override with runtime config when both env and config provided', async () => {
263
- // Simulate: constructor loaded env vars, then initialize() called with config
264
- const runtimeConfig = {
265
- accountId: 'override-account',
266
- accountName: 'Override Account',
267
- bucket: 'override-bucket',
268
- };
269
- await driver.initialize(runtimeConfig);
270
- expect(driver.AccountId).toBe('override-account');
271
- expect(driver.AccountName).toBe('Override Account');
272
- });
273
- });
274
- });
275
- //# sourceMappingURL=FileStorageBase.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FileStorageBase.test.js","sourceRoot":"","sources":["../../src/__tests__/FileStorageBase.test.ts"],"names":[],"mappings":"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"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Unit tests for the MJStorage utility functions.
3
- * These tests focus on the initializeDriverWithAccountCredentials function
4
- * which is the core enterprise model for initializing storage drivers.
5
- */
6
- export {};
7
- //# sourceMappingURL=util.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"util.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/util.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -1,306 +0,0 @@
1
- /**
2
- * Unit tests for the MJStorage utility functions.
3
- * These tests focus on the initializeDriverWithAccountCredentials function
4
- * which is the core enterprise model for initializing storage drivers.
5
- */
6
- import { FileStorageBase, } from '../generic/FileStorageBase.js';
7
- import { MJGlobal } from '@memberjunction/global';
8
- // Mock the external dependencies
9
- jest.mock('@memberjunction/global', () => {
10
- const actualGlobal = jest.requireActual('@memberjunction/global');
11
- return {
12
- ...actualGlobal,
13
- MJGlobal: {
14
- Instance: {
15
- ClassFactory: {
16
- CreateInstance: jest.fn(),
17
- },
18
- },
19
- },
20
- };
21
- });
22
- jest.mock('@memberjunction/credentials', () => ({
23
- CredentialEngine: {
24
- Instance: {
25
- Config: jest.fn().mockResolvedValue(undefined),
26
- getCredentialById: jest.fn(),
27
- getCredential: jest.fn(),
28
- },
29
- },
30
- }));
31
- jest.mock('@memberjunction/core', () => ({
32
- LogStatus: jest.fn(),
33
- UserInfo: class MockUserInfo {
34
- constructor() {
35
- this.ID = 'test-user-id';
36
- this.Name = 'Test User';
37
- }
38
- },
39
- }));
40
- // Create a concrete implementation of FileStorageBase for testing
41
- class MockFileStorageDriver extends FileStorageBase {
42
- constructor() {
43
- super(...arguments);
44
- this.providerName = 'MockProvider';
45
- this.initializeCalledWith = null;
46
- this._isConfigured = false;
47
- }
48
- async initialize(config) {
49
- await super.initialize(config);
50
- this.initializeCalledWith = config;
51
- this._isConfigured = true;
52
- }
53
- get IsConfigured() {
54
- return this._isConfigured;
55
- }
56
- // Implement all abstract methods with minimal implementations
57
- async CreatePreAuthUploadUrl(objectName) {
58
- return { UploadUrl: `https://mock.upload.url/${objectName}` };
59
- }
60
- async CreatePreAuthDownloadUrl(objectName) {
61
- return `https://mock.download.url/${objectName}`;
62
- }
63
- async MoveObject(oldObjectName, newObjectName) {
64
- return true;
65
- }
66
- async DeleteObject(objectName) {
67
- return true;
68
- }
69
- async ListObjects(prefix, delimiter) {
70
- return { objects: [], prefixes: [] };
71
- }
72
- async CreateDirectory(directoryPath) {
73
- return true;
74
- }
75
- async DeleteDirectory(directoryPath, recursive) {
76
- return true;
77
- }
78
- async GetObjectMetadata(params) {
79
- return {
80
- name: 'test.txt',
81
- path: '/',
82
- fullPath: '/test.txt',
83
- size: 100,
84
- contentType: 'text/plain',
85
- lastModified: new Date(),
86
- isDirectory: false,
87
- };
88
- }
89
- async GetObject(params) {
90
- return Buffer.from('test content');
91
- }
92
- async PutObject(objectName, data, contentType, metadata) {
93
- return true;
94
- }
95
- async CopyObject(sourceObjectName, destinationObjectName) {
96
- return true;
97
- }
98
- async ObjectExists(objectName) {
99
- return true;
100
- }
101
- async DirectoryExists(directoryPath) {
102
- return true;
103
- }
104
- async SearchFiles(query, options) {
105
- return { results: [], hasMore: false };
106
- }
107
- }
108
- describe('initializeDriverWithAccountCredentials', () => {
109
- let mockDriver;
110
- let mockAccountEntity;
111
- let mockProviderEntity;
112
- let mockContextUser;
113
- beforeEach(() => {
114
- // Reset all mocks
115
- jest.clearAllMocks();
116
- // Create fresh mock instances
117
- mockDriver = new MockFileStorageDriver();
118
- // Setup the ClassFactory to return our mock driver
119
- MJGlobal.Instance.ClassFactory.CreateInstance.mockReturnValue(mockDriver);
120
- mockAccountEntity = {
121
- ID: 'account-123',
122
- Name: 'Test Storage Account',
123
- CredentialID: null,
124
- };
125
- mockProviderEntity = {
126
- Name: 'Test Provider',
127
- ServerDriverKey: 'TestDriver',
128
- Configuration: null,
129
- };
130
- mockContextUser = {
131
- ID: 'user-123',
132
- Name: 'Test User',
133
- };
134
- });
135
- describe('driver creation', () => {
136
- it('should create a driver instance using the provider ServerDriverKey', async () => {
137
- // Import the function we're testing
138
- const { initializeDriverWithAccountCredentials } = await import('../util.js');
139
- await initializeDriverWithAccountCredentials({
140
- accountEntity: mockAccountEntity,
141
- providerEntity: mockProviderEntity,
142
- contextUser: mockContextUser,
143
- });
144
- expect(MJGlobal.Instance.ClassFactory.CreateInstance).toHaveBeenCalledWith(FileStorageBase, 'TestDriver');
145
- });
146
- it('should throw an error if driver creation fails', async () => {
147
- MJGlobal.Instance.ClassFactory.CreateInstance.mockReturnValue(null);
148
- const { initializeDriverWithAccountCredentials } = await import('../util.js');
149
- await expect(initializeDriverWithAccountCredentials({
150
- accountEntity: mockAccountEntity,
151
- providerEntity: mockProviderEntity,
152
- contextUser: mockContextUser,
153
- })).rejects.toThrow(/Failed to create storage driver/);
154
- });
155
- });
156
- describe('account information', () => {
157
- it('should pass accountId from the account entity to the driver', async () => {
158
- const { initializeDriverWithAccountCredentials } = await import('../util.js');
159
- await initializeDriverWithAccountCredentials({
160
- accountEntity: mockAccountEntity,
161
- providerEntity: mockProviderEntity,
162
- contextUser: mockContextUser,
163
- });
164
- expect(mockDriver.initializeCalledWith).toBeDefined();
165
- expect(mockDriver.initializeCalledWith.accountId).toBe('account-123');
166
- });
167
- it('should pass accountName from the account entity to the driver', async () => {
168
- const { initializeDriverWithAccountCredentials } = await import('../util.js');
169
- await initializeDriverWithAccountCredentials({
170
- accountEntity: mockAccountEntity,
171
- providerEntity: mockProviderEntity,
172
- contextUser: mockContextUser,
173
- });
174
- expect(mockDriver.initializeCalledWith).toBeDefined();
175
- expect(mockDriver.initializeCalledWith.accountName).toBe('Test Storage Account');
176
- });
177
- });
178
- describe('credential handling', () => {
179
- it('should use Credential Engine when account has a CredentialID', async () => {
180
- const { CredentialEngine } = await import('@memberjunction/credentials');
181
- mockAccountEntity.CredentialID = 'credential-456';
182
- // Setup credential engine mocks
183
- CredentialEngine.Instance.getCredentialById.mockReturnValue({
184
- ID: 'credential-456',
185
- Name: 'Test Credential',
186
- });
187
- CredentialEngine.Instance.getCredential.mockResolvedValue({
188
- values: {
189
- accessKey: 'test-access-key',
190
- secretKey: 'test-secret-key',
191
- bucket: 'test-bucket',
192
- },
193
- });
194
- const { initializeDriverWithAccountCredentials } = await import('../util.js');
195
- await initializeDriverWithAccountCredentials({
196
- accountEntity: mockAccountEntity,
197
- providerEntity: mockProviderEntity,
198
- contextUser: mockContextUser,
199
- });
200
- // Verify Credential Engine was configured
201
- expect(CredentialEngine.Instance.Config).toHaveBeenCalledWith(false, mockContextUser);
202
- // Verify credential was looked up by ID
203
- expect(CredentialEngine.Instance.getCredentialById).toHaveBeenCalledWith('credential-456');
204
- // Verify getCredential was called with correct parameters
205
- expect(CredentialEngine.Instance.getCredential).toHaveBeenCalledWith('Test Credential', expect.objectContaining({
206
- credentialId: 'credential-456',
207
- contextUser: mockContextUser,
208
- subsystem: 'FileStorage',
209
- }));
210
- });
211
- it('should merge credential values with account info in driver config', async () => {
212
- const { CredentialEngine } = await import('@memberjunction/credentials');
213
- mockAccountEntity.CredentialID = 'credential-456';
214
- CredentialEngine.Instance.getCredentialById.mockReturnValue({
215
- ID: 'credential-456',
216
- Name: 'Test Credential',
217
- });
218
- CredentialEngine.Instance.getCredential.mockResolvedValue({
219
- values: {
220
- accessKey: 'decrypted-access-key',
221
- secretKey: 'decrypted-secret-key',
222
- region: 'us-west-2',
223
- },
224
- });
225
- const { initializeDriverWithAccountCredentials } = await import('../util.js');
226
- await initializeDriverWithAccountCredentials({
227
- accountEntity: mockAccountEntity,
228
- providerEntity: mockProviderEntity,
229
- contextUser: mockContextUser,
230
- });
231
- // Verify driver was initialized with merged config
232
- expect(mockDriver.initializeCalledWith).toMatchObject({
233
- accountId: 'account-123',
234
- accountName: 'Test Storage Account',
235
- accessKey: 'decrypted-access-key',
236
- secretKey: 'decrypted-secret-key',
237
- region: 'us-west-2',
238
- });
239
- // Verify that onTokenRefresh callback was added
240
- expect(mockDriver.initializeCalledWith.onTokenRefresh).toBeDefined();
241
- expect(typeof mockDriver.initializeCalledWith.onTokenRefresh).toBe('function');
242
- });
243
- it('should throw error if credential lookup fails', async () => {
244
- const { CredentialEngine } = await import('@memberjunction/credentials');
245
- mockAccountEntity.CredentialID = 'credential-456';
246
- // Return null to simulate credential not found
247
- CredentialEngine.Instance.getCredentialById.mockReturnValue(null);
248
- const { initializeDriverWithAccountCredentials } = await import('../util.js');
249
- await expect(initializeDriverWithAccountCredentials({
250
- accountEntity: mockAccountEntity,
251
- providerEntity: mockProviderEntity,
252
- contextUser: mockContextUser,
253
- })).rejects.toThrow(/Credential with ID credential-456 not found/);
254
- });
255
- });
256
- describe('fallback to provider configuration', () => {
257
- it('should use provider Configuration when no CredentialID', async () => {
258
- mockAccountEntity.CredentialID = null;
259
- mockProviderEntity.Configuration = JSON.stringify({
260
- defaultBucket: 'provider-default-bucket',
261
- defaultRegion: 'us-east-1',
262
- });
263
- const { initializeDriverWithAccountCredentials } = await import('../util.js');
264
- await initializeDriverWithAccountCredentials({
265
- accountEntity: mockAccountEntity,
266
- providerEntity: mockProviderEntity,
267
- contextUser: mockContextUser,
268
- });
269
- // Verify driver was initialized with provider config merged with account info
270
- expect(mockDriver.initializeCalledWith).toEqual({
271
- accountId: 'account-123',
272
- accountName: 'Test Storage Account',
273
- defaultBucket: 'provider-default-bucket',
274
- defaultRegion: 'us-east-1',
275
- });
276
- });
277
- it('should initialize with just account info when no credential or provider config', async () => {
278
- mockAccountEntity.CredentialID = null;
279
- mockProviderEntity.Configuration = null;
280
- const { initializeDriverWithAccountCredentials } = await import('../util.js');
281
- await initializeDriverWithAccountCredentials({
282
- accountEntity: mockAccountEntity,
283
- providerEntity: mockProviderEntity,
284
- contextUser: mockContextUser,
285
- });
286
- // Verify driver was initialized with only account info
287
- expect(mockDriver.initializeCalledWith).toEqual({
288
- accountId: 'account-123',
289
- accountName: 'Test Storage Account',
290
- });
291
- });
292
- });
293
- describe('return value', () => {
294
- it('should return the initialized driver', async () => {
295
- const { initializeDriverWithAccountCredentials } = await import('../util.js');
296
- const result = await initializeDriverWithAccountCredentials({
297
- accountEntity: mockAccountEntity,
298
- providerEntity: mockProviderEntity,
299
- contextUser: mockContextUser,
300
- });
301
- expect(result).toBe(mockDriver);
302
- expect(mockDriver.IsConfigured).toBe(true);
303
- });
304
- });
305
- });
306
- //# sourceMappingURL=util.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"util.test.js","sourceRoot":"","sources":["../../src/__tests__/util.test.ts"],"names":[],"mappings":"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"}