@onlineapps/conn-base-storage 1.0.1 → 1.0.3

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/conn-base-storage",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "MinIO storage connector with fingerprinting for immutable content storage",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -20,6 +20,8 @@
20
20
  "connector"
21
21
  ],
22
22
  "dependencies": {
23
+ "@onlineapps/runtime-config": "1.0.2",
24
+ "@onlineapps/storage-core": "1.0.8",
23
25
  "minio": "^7.1.3",
24
26
  "crypto": "^1.0.1",
25
27
  "winston": "^3.8.2"
package/src/config.js ADDED
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Runtime configuration schema for @onlineapps/conn-base-storage.
5
+ *
6
+ * Uses @onlineapps/runtime-config for unified priority:
7
+ * 1. Explicit config (passed to constructor)
8
+ * 2. Environment variable
9
+ * 3. Owner defaults (from ./defaults.js)
10
+ *
11
+ * NOTE:
12
+ * This module resolves MinIO runtime configuration via @onlineapps/runtime-config
13
+ * to avoid inline process.env access in implementation code.
14
+ *
15
+ * @module @onlineapps/conn-base-storage/config
16
+ */
17
+
18
+ const { createRuntimeConfig } = require('@onlineapps/runtime-config');
19
+ const DEFAULTS = require('./defaults');
20
+
21
+ /**
22
+ * Runtime config schema for StorageConnector
23
+ */
24
+ const runtimeCfg = createRuntimeConfig({
25
+ defaults: DEFAULTS,
26
+ schema: {
27
+ // MinIO topology (FAIL-FAST)
28
+ // Keep key names aligned with constructor config for predictability.
29
+ endPoint: { env: 'MINIO_ENDPOINT', required: true },
30
+ port: { env: 'MINIO_PORT', required: true, type: 'number' },
31
+ useSSL: { env: 'MINIO_USE_SSL', default: false, type: 'boolean' },
32
+ accessKey: { env: 'MINIO_ACCESS_KEY', required: true },
33
+ secretKey: { env: 'MINIO_SECRET_KEY', required: true },
34
+
35
+ // Wrapper behavior (module-owned defaults)
36
+ logLevel: { env: 'STORAGE_LOG_LEVEL', defaultKey: 'logLevel' },
37
+ defaultBucket: { env: 'MINIO_DEFAULT_BUCKET', defaultKey: 'defaultBucket' },
38
+ bucketName: { defaultKey: 'bucketName' },
39
+ cacheMaxSize: { defaultKey: 'cacheMaxSize', type: 'number' },
40
+ maxCacheSize: { defaultKey: 'maxCacheSize', type: 'number' },
41
+
42
+ // InternalUrlAdapter behavior (module-owned defaults + env hints)
43
+ nodeEnv: { env: 'NODE_ENV', default: 'development' },
44
+ dockerNetwork: { env: 'DOCKER_NETWORK', default: false, type: 'boolean' },
45
+ dockerEnv: { env: 'DOCKER_ENV' },
46
+ dockerContainer: { env: 'DOCKER_CONTAINER' },
47
+ hostname: { env: 'HOSTNAME' },
48
+ internalUrlServiceMap: { defaultKey: 'internalUrlServiceMap' },
49
+ }
50
+ });
51
+
52
+ module.exports = runtimeCfg;
53
+
@@ -0,0 +1,43 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Module-owned defaults for @onlineapps/conn-base-storage.
5
+ *
6
+ * Ownership rule:
7
+ * - Defaults for the StorageConnector wrapper live here (bucket naming, cache sizing, log level).
8
+ * - MinIO connection defaults belong to @onlineapps/storage-core.
9
+ */
10
+
11
+ module.exports = {
12
+ logLevel: 'info',
13
+ defaultBucket: 'api-storage',
14
+ bucketName: 'oa-drive-storage',
15
+ cacheMaxSize: 100,
16
+ maxCacheSize: 100,
17
+
18
+ // InternalUrlAdapter defaults (module-owned)
19
+ internalUrlServiceMap: {
20
+ storage: {
21
+ docker: 'api_services_storage:9000',
22
+ local: 'localhost:9000'
23
+ },
24
+ registry: {
25
+ docker: 'api_registry:8080',
26
+ local: 'localhost:8080'
27
+ },
28
+ monitoring: {
29
+ docker: 'api_monitoring:3000',
30
+ local: 'localhost:3000'
31
+ },
32
+ mq: {
33
+ docker: 'api_services_rabbit:5672',
34
+ local: 'localhost:5672'
35
+ },
36
+ cache: {
37
+ docker: 'api_node_cache:6379',
38
+ local: 'localhost:6379'
39
+ }
40
+ },
41
+ };
42
+
43
+
package/src/index.js CHANGED
@@ -9,10 +9,10 @@
9
9
  * @since 1.0.0
10
10
  */
11
11
 
12
- const Minio = require('minio');
13
- const crypto = require('crypto');
12
+ const { StorageCore } = require('@onlineapps/storage-core');
14
13
  const winston = require('winston');
15
14
  const SharedUrlAdapter = require('./sharedUrlAdapter');
15
+ const runtimeCfg = require('./config');
16
16
 
17
17
  /**
18
18
  * Storage connector for MinIO with automatic fingerprinting
@@ -69,9 +69,12 @@ class StorageConnector {
69
69
  * });
70
70
  */
71
71
  constructor(config = {}) {
72
+ // Resolve runtime configuration for wrapper behavior
73
+ const resolved = runtimeCfg.resolve(config);
74
+
72
75
  // Logger setup
73
76
  this.logger = winston.createLogger({
74
- level: config.logLevel || 'info',
77
+ level: resolved.logLevel,
75
78
  format: winston.format.combine(
76
79
  winston.format.timestamp(),
77
80
  winston.format.json()
@@ -81,33 +84,37 @@ class StorageConnector {
81
84
  ]
82
85
  });
83
86
 
84
- // MinIO client configuration
85
- const minioConfig = {
86
- endPoint: config.endPoint || process.env.MINIO_ENDPOINT || 'localhost',
87
- port: parseInt(config.port || process.env.MINIO_PORT || 9000),
88
- useSSL: config.useSSL || process.env.MINIO_USE_SSL === 'true',
89
- accessKey: config.accessKey || process.env.MINIO_ACCESS_KEY || 'minioadmin',
90
- secretKey: config.secretKey || process.env.MINIO_SECRET_KEY || 'minioadmin'
91
- };
87
+ // Create StorageCore instance (handles MinIO client internally)
88
+ this.core = new StorageCore({
89
+ endPoint: resolved.endPoint,
90
+ port: resolved.port,
91
+ useSSL: resolved.useSSL,
92
+ accessKey: resolved.accessKey,
93
+ secretKey: resolved.secretKey
94
+ });
92
95
 
93
- this.client = new Minio.Client(minioConfig);
94
- this.defaultBucket = config.defaultBucket || process.env.MINIO_DEFAULT_BUCKET || 'api-storage';
96
+ // Expose MinIO client for backward compatibility
97
+ this.client = this.core.client;
98
+ this.minioClient = this.core.client;
99
+
100
+ this.defaultBucket = resolved.defaultBucket;
95
101
 
96
102
  // Store config for access in tests
97
103
  this.config = {
98
- ...minioConfig,
99
- bucketName: this.validateBucketName(config.bucketName || 'oa-drive-storage'),
100
- cacheMaxSize: config.cacheMaxSize || 100
104
+ endPoint: this.core.config.endPoint,
105
+ port: this.core.config.port,
106
+ useSSL: this.core.config.useSSL,
107
+ accessKey: this.core.config.accessKey,
108
+ secretKey: this.core.config.secretKey,
109
+ bucketName: this.validateBucketName(config.bucketName || resolved.bucketName),
110
+ cacheMaxSize: resolved.cacheMaxSize
101
111
  };
102
112
 
103
- // MinIO client
104
- this.minioClient = this.client;
105
-
106
113
  // Cache configuration
107
114
  this.cacheEnabled = config.cacheEnabled !== false;
108
115
  this.cache = new Map();
109
116
  this.contentCache = new Map();
110
- this.maxCacheSize = config.maxCacheSize || 100; // Max items in cache
117
+ this.maxCacheSize = resolved.maxCacheSize;
111
118
 
112
119
  // Track initialization
113
120
  this.initialized = false;
@@ -116,8 +123,8 @@ class StorageConnector {
116
123
  this.sharedUrl = new SharedUrlAdapter(this);
117
124
 
118
125
  this.logger.info('StorageConnector initialized', {
119
- endpoint: minioConfig.endPoint,
120
- port: minioConfig.port,
126
+ endpoint: this.core.config.endPoint,
127
+ port: this.core.config.port,
121
128
  defaultBucket: this.defaultBucket
122
129
  });
123
130
  }
@@ -141,15 +148,16 @@ class StorageConnector {
141
148
  */
142
149
  async initialize() {
143
150
  try {
144
- // Check if default bucket exists
145
- const bucketExists = await this.client.bucketExists(this.defaultBucket);
151
+ // Initialize StorageCore
152
+ await this.core.initialize();
146
153
 
147
- if (!bucketExists) {
148
- // Create bucket with versioning
149
- await this.client.makeBucket(this.defaultBucket, 'us-east-1');
154
+ // Ensure default bucket exists (using StorageCore)
155
+ const created = await this.core.ensureBucket(this.defaultBucket);
156
+
157
+ if (created) {
150
158
  this.logger.info(`Bucket ${this.defaultBucket} created`);
151
159
 
152
- // Set bucket policy for read access
160
+ // Set bucket policy for read access (business-specific feature)
153
161
  const policy = {
154
162
  Version: '2012-10-17',
155
163
  Statement: [
@@ -193,25 +201,8 @@ class StorageConnector {
193
201
  * // Returns consistent hash for the object
194
202
  */
195
203
  generateFingerprint(content) {
196
- // Handle undefined and null
197
- if (content === undefined || content === null) {
198
- content = String(content);
199
- } else if (typeof content === 'symbol') {
200
- content = content.toString();
201
- } else if (typeof content !== 'string' && !Buffer.isBuffer(content)) {
202
- // Handle circular references
203
- try {
204
- content = JSON.stringify(content);
205
- } catch (err) {
206
- // If circular reference, use a deterministic string representation
207
- content = '[Circular Reference]';
208
- }
209
- }
210
-
211
- return crypto
212
- .createHash('sha256')
213
- .update(content)
214
- .digest('hex');
204
+ // Delegate to StorageCore
205
+ return this.core.calculateFingerprint(content);
215
206
  }
216
207
 
217
208
  /**
@@ -277,9 +268,9 @@ class StorageConnector {
277
268
  ? `${pathPrefix}/${fingerprint}.json`
278
269
  : `${fingerprint}.json`;
279
270
 
280
- // Check if object already exists (immutable)
281
- try {
282
- await this.client.statObject(bucket, path);
271
+ // Check if object already exists (immutable) - using StorageCore
272
+ const exists = await this.core.objectExists(bucket, path);
273
+ if (exists) {
283
274
  this.logger.debug(`Object already exists: ${bucket}/${path}`);
284
275
 
285
276
  return {
@@ -289,16 +280,13 @@ class StorageConnector {
289
280
  url: this.getPublicUrl(bucket, path),
290
281
  existed: true
291
282
  };
292
- } catch (err) {
293
- // Object doesn't exist, proceed with upload
294
283
  }
295
284
 
296
- // Upload to MinIO
297
- await this.client.putObject(
285
+ // Upload to MinIO - using StorageCore
286
+ await this.core.putObject(
298
287
  bucket,
299
288
  path,
300
289
  buffer,
301
- buffer.length,
302
290
  {
303
291
  'Content-Type': 'application/json',
304
292
  'x-amz-meta-fingerprint': fingerprint,
@@ -366,8 +354,8 @@ class StorageConnector {
366
354
  return this.contentCache.get(cacheKey);
367
355
  }
368
356
 
369
- // Download from MinIO
370
- const stream = await this.client.getObject(bucket, path);
357
+ // Download from MinIO - using StorageCore
358
+ const stream = await this.core.getObject(bucket, path);
371
359
 
372
360
  // Collect stream data
373
361
  const chunks = [];
@@ -376,16 +364,14 @@ class StorageConnector {
376
364
  }
377
365
  const buffer = Buffer.concat(chunks);
378
366
 
379
- // Verify fingerprint if provided
367
+ // Verify fingerprint if provided - using StorageCore
380
368
  if (expectedFingerprint) {
381
- const actualFingerprint = this.generateFingerprint(buffer);
382
-
369
+ const actualFingerprint = this.core.calculateFingerprint(buffer);
383
370
  if (actualFingerprint !== expectedFingerprint) {
384
371
  throw new Error(
385
372
  `Fingerprint mismatch! Expected: ${expectedFingerprint}, Got: ${actualFingerprint}`
386
373
  );
387
374
  }
388
-
389
375
  this.logger.debug(`Fingerprint verified for ${bucket}/${path}`);
390
376
  }
391
377
 
@@ -436,11 +422,8 @@ class StorageConnector {
436
422
  try {
437
423
  bucket = bucket || this.defaultBucket;
438
424
 
439
- const url = await this.client.presignedGetObject(
440
- bucket,
441
- path,
442
- expiry
443
- );
425
+ // Use StorageCore
426
+ const url = await this.core.getPresignedUrl(bucket, path, expiry);
444
427
 
445
428
  this.logger.debug(`Generated presigned URL for ${bucket}/${path}`);
446
429
  return url;
@@ -476,20 +459,25 @@ class StorageConnector {
476
459
  try {
477
460
  bucket = bucket || this.defaultBucket;
478
461
 
462
+ // Use StorageCore to list objects
463
+ const objectNames = await this.core.listByPrefix(bucket, prefix, true);
464
+
465
+ // Get metadata for each object
479
466
  const objects = [];
480
- const stream = this.client.listObjectsV2(bucket, prefix, true);
481
-
482
- for await (const obj of stream) {
483
- // Get metadata for each object
484
- const stat = await this.client.statObject(bucket, obj.name);
485
-
486
- objects.push({
487
- name: obj.name,
488
- size: obj.size,
489
- lastModified: obj.lastModified,
490
- fingerprint: stat.metaData['x-amz-meta-fingerprint'],
491
- uploadedAt: stat.metaData['x-amz-meta-uploaded-at']
492
- });
467
+ for (const name of objectNames) {
468
+ try {
469
+ const stat = await this.core.statObject(bucket, name);
470
+ objects.push({
471
+ name,
472
+ size: stat.size,
473
+ lastModified: stat.lastModified,
474
+ fingerprint: stat.metaData?.['x-amz-meta-fingerprint'],
475
+ uploadedAt: stat.metaData?.['x-amz-meta-uploaded-at']
476
+ });
477
+ } catch (err) {
478
+ // Skip objects that can't be stat'd
479
+ this.logger.warn(`Failed to stat object ${name}`, err);
480
+ }
493
481
  }
494
482
 
495
483
  return objects;
@@ -520,7 +508,8 @@ class StorageConnector {
520
508
  try {
521
509
  bucket = bucket || this.defaultBucket;
522
510
 
523
- await this.client.removeObject(bucket, path);
511
+ // Use StorageCore
512
+ await this.core.deleteObject(bucket, path);
524
513
  this.logger.warn(`Deleted object: ${bucket}/${path}`);
525
514
 
526
515
  // Clear from cache
@@ -594,10 +583,10 @@ class StorageConnector {
594
583
  */
595
584
  async ensureBucket(bucketName) {
596
585
  try {
597
- const exists = await this.client.bucketExists(bucketName);
586
+ // Use StorageCore
587
+ const created = await this.core.ensureBucket(bucketName);
598
588
 
599
- if (!exists) {
600
- await this.client.makeBucket(bucketName, 'us-east-1');
589
+ if (created) {
601
590
  this.logger.info(`Bucket ${bucketName} created`);
602
591
  }
603
592
 
@@ -4,34 +4,16 @@
4
4
  * Skrývá implementační detaily před službami
5
5
  */
6
6
 
7
+ const fs = require('fs');
8
+ const runtimeCfg = require('./config');
9
+
7
10
  class InternalUrlAdapter {
8
11
  constructor(config = {}) {
9
- this.environment = config.environment || process.env.NODE_ENV || 'development';
10
- this.dockerNetwork = config.dockerNetwork || process.env.DOCKER_NETWORK || false;
12
+ this.environment = runtimeCfg.get('nodeEnv', config.environment);
13
+ this.dockerNetwork = runtimeCfg.get('dockerNetwork', config.dockerNetwork);
11
14
 
12
15
  // Mapování služeb na jejich interní adresy
13
- this.serviceMap = {
14
- storage: {
15
- docker: 'api_services_storage:9000',
16
- local: 'localhost:9000'
17
- },
18
- registry: {
19
- docker: 'api_registry:8080',
20
- local: 'localhost:8080'
21
- },
22
- monitoring: {
23
- docker: 'api_monitoring:3000',
24
- local: 'localhost:3000'
25
- },
26
- mq: {
27
- docker: 'api_services_rabbit:5672',
28
- local: 'localhost:5672'
29
- },
30
- cache: {
31
- docker: 'api_node_cache:6379',
32
- local: 'localhost:6379'
33
- }
34
- };
16
+ this.serviceMap = { ...runtimeCfg.get('internalUrlServiceMap') };
35
17
 
36
18
  // Rozšiřitelné přes config
37
19
  if (config.services) {
@@ -91,11 +73,14 @@ class InternalUrlAdapter {
91
73
  */
92
74
  isRunningInDocker() {
93
75
  // Několik způsobů detekce Docker kontejneru
76
+ const dockerEnv = runtimeCfg.get('dockerEnv');
77
+ const dockerContainer = runtimeCfg.get('dockerContainer');
78
+ const hostname = runtimeCfg.get('hostname');
94
79
  return !!(
95
- process.env.DOCKER_ENV ||
96
- process.env.DOCKER_CONTAINER ||
97
- (require('fs').existsSync('/.dockerenv')) ||
98
- (process.env.HOSTNAME && process.env.HOSTNAME.length === 12) // Docker container ID
80
+ dockerEnv ||
81
+ dockerContainer ||
82
+ (fs.existsSync('/.dockerenv')) ||
83
+ (hostname && hostname.length === 12) // Docker container ID
99
84
  );
100
85
  }
101
86
 
@@ -9,6 +9,8 @@ describe('InternalUrlAdapter @unit', () => {
9
9
 
10
10
  beforeEach(() => {
11
11
  adapter = new InternalUrlAdapter();
12
+ // Tests run inside a Docker container; force local-mode behavior unless explicitly enabled.
13
+ adapter.isRunningInDocker = jest.fn(() => false);
12
14
  });
13
15
 
14
16
  describe('URL Resolution', () => {
@@ -202,6 +204,8 @@ describe('InternalUrlAdapter @unit', () => {
202
204
  }
203
205
  });
204
206
 
207
+ // Tests run inside Docker; force local-mode behavior for this adapter instance.
208
+ customAdapter.isRunningInDocker = jest.fn(() => false);
205
209
  customAdapter.dockerNetwork = false;
206
210
  const resolved = customAdapter.resolve('internal://my-service/api');
207
211
 
@@ -6,6 +6,14 @@
6
6
  const StorageConnector = require('../../src/index');
7
7
  const Minio = require('minio');
8
8
 
9
+ // Minimal required MinIO config for tests (all external I/O is mocked)
10
+ const MINIO_CONFIG = {
11
+ endPoint: 'localhost',
12
+ port: 9000,
13
+ accessKey: 'test',
14
+ secretKey: 'test',
15
+ };
16
+
9
17
  // Mock MinIO client
10
18
  jest.mock('minio');
11
19
 
@@ -321,15 +329,15 @@ describe('StorageConnector Extended Unit Tests @unit', () => {
321
329
 
322
330
  describe('Internal URL Generation', () => {
323
331
  test('should generate abstract internal URL', () => {
324
- storage = new StorageConnector();
332
+ storage = new StorageConnector(MINIO_CONFIG);
325
333
 
326
334
  const url = storage.getInternalUrl('bucket', 'path/to/object');
327
335
  expect(url).toBe('internal://storage/bucket/path/to/object');
328
336
  });
329
337
 
330
338
  test('should generate consistent internal URLs', () => {
331
- const storage1 = new StorageConnector();
332
- const storage2 = new StorageConnector();
339
+ const storage1 = new StorageConnector(MINIO_CONFIG);
340
+ const storage2 = new StorageConnector(MINIO_CONFIG);
333
341
 
334
342
  const url1 = storage1.getInternalUrl('bucket', 'object');
335
343
  const url2 = storage2.getInternalUrl('bucket', 'object');
@@ -341,7 +349,7 @@ describe('StorageConnector Extended Unit Tests @unit', () => {
341
349
 
342
350
  describe('Bucket Operations', () => {
343
351
  beforeEach(() => {
344
- storage = new StorageConnector();
352
+ storage = new StorageConnector(MINIO_CONFIG);
345
353
  });
346
354
 
347
355
  test('should ensure bucket exists', async () => {
@@ -373,7 +381,7 @@ describe('StorageConnector Extended Unit Tests @unit', () => {
373
381
 
374
382
  describe('Cache Operations', () => {
375
383
  test('should clear all caches', () => {
376
- storage = new StorageConnector();
384
+ storage = new StorageConnector(MINIO_CONFIG);
377
385
 
378
386
  // Add items to caches
379
387
  storage.cache.set('key1', 'value1');
@@ -389,7 +397,7 @@ describe('StorageConnector Extended Unit Tests @unit', () => {
389
397
  });
390
398
 
391
399
  test('should handle cache size limits', () => {
392
- storage = new StorageConnector({ cacheMaxSize: 2 });
400
+ storage = new StorageConnector({ ...MINIO_CONFIG, cacheMaxSize: 2 });
393
401
 
394
402
  storage.addToCache('key1', 'value1');
395
403
  storage.addToCache('key2', 'value2');
@@ -12,6 +12,14 @@
12
12
  const StorageConnector = require('../../src/index');
13
13
  const crypto = require('crypto');
14
14
 
15
+ // Minimal required MinIO config for tests (all external I/O is mocked)
16
+ const MINIO_CONFIG = {
17
+ endPoint: 'localhost',
18
+ port: 9000,
19
+ accessKey: 'test',
20
+ secretKey: 'test',
21
+ };
22
+
15
23
  // Mock MinIO client kompletně
16
24
  jest.mock('minio', () => {
17
25
  return {
@@ -38,7 +46,7 @@ jest.mock('minio', () => {
38
46
  describe('StorageConnector Unit Tests @unit', () => {
39
47
  describe('Initialization', () => {
40
48
  test('should create instance with default config', () => {
41
- const storage = new StorageConnector();
49
+ const storage = new StorageConnector(MINIO_CONFIG);
42
50
  expect(storage).toBeDefined();
43
51
  expect(storage.config).toBeDefined();
44
52
  expect(storage.config.endPoint).toBe('localhost');
@@ -67,7 +75,7 @@ describe('StorageConnector Unit Tests @unit', () => {
67
75
  let storage;
68
76
 
69
77
  beforeEach(() => {
70
- storage = new StorageConnector();
78
+ storage = new StorageConnector(MINIO_CONFIG);
71
79
  });
72
80
 
73
81
  test('should generate fingerprint for string content', () => {
@@ -144,7 +152,7 @@ describe('StorageConnector Unit Tests @unit', () => {
144
152
  let storage;
145
153
 
146
154
  beforeEach(() => {
147
- storage = new StorageConnector({ cacheMaxSize: 3 });
155
+ storage = new StorageConnector({ ...MINIO_CONFIG, cacheMaxSize: 3 });
148
156
  });
149
157
 
150
158
  test('should add items to cache', () => {
@@ -189,7 +197,7 @@ describe('StorageConnector Unit Tests @unit', () => {
189
197
  let storage;
190
198
 
191
199
  beforeEach(() => {
192
- storage = new StorageConnector();
200
+ storage = new StorageConnector(MINIO_CONFIG);
193
201
  });
194
202
 
195
203
  test('should handle invalid content types for fingerprinting', () => {
@@ -202,13 +210,13 @@ describe('StorageConnector Unit Tests @unit', () => {
202
210
  const invalidNames = ['', 'a', 'UPPERCASE', 'bucket_name', 'bucket-'];
203
211
 
204
212
  validNames.forEach(name => {
205
- const s = new StorageConnector({ bucketName: name });
213
+ const s = new StorageConnector({ ...MINIO_CONFIG, bucketName: name });
206
214
  expect(s.config.bucketName).toBe(name);
207
215
  });
208
216
 
209
217
  // Invalid names should use default
210
218
  invalidNames.forEach(name => {
211
- const s = new StorageConnector({ bucketName: name });
219
+ const s = new StorageConnector({ ...MINIO_CONFIG, bucketName: name });
212
220
  expect(s.config.bucketName).toBe('oa-drive-storage');
213
221
  });
214
222
  });
@@ -218,7 +226,7 @@ describe('StorageConnector Unit Tests @unit', () => {
218
226
  let storage;
219
227
 
220
228
  beforeEach(() => {
221
- storage = new StorageConnector();
229
+ storage = new StorageConnector(MINIO_CONFIG);
222
230
  });
223
231
 
224
232
  test('should generate object name with fingerprint', () => {
@@ -255,7 +263,7 @@ describe('StorageConnector Unit Tests @unit', () => {
255
263
 
256
264
  beforeEach(() => {
257
265
  jest.clearAllMocks();
258
- storage = new StorageConnector();
266
+ storage = new StorageConnector(MINIO_CONFIG);
259
267
  mockClient = storage.minioClient;
260
268
  });
261
269