@scality/data-browser-library 1.0.4 → 1.0.6
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/dist/components/DataBrowserUI.js +18 -8
- package/dist/components/__tests__/BucketCreate.test.js +60 -20
- package/dist/components/__tests__/BucketList.test.js +91 -6
- package/dist/components/__tests__/BucketNotificationFormPage.test.js +54 -19
- package/dist/components/__tests__/BucketReplicationFormPage.test.js +183 -61
- package/dist/components/__tests__/MetadataSearch.test.js +18 -12
- package/dist/components/__tests__/ObjectList.test.js +94 -2
- package/dist/components/buckets/BucketCreate.d.ts +1 -0
- package/dist/components/buckets/BucketCreate.js +57 -7
- package/dist/components/buckets/BucketDetails.js +0 -1
- package/dist/components/buckets/BucketLifecycleFormPage.js +209 -213
- package/dist/components/buckets/BucketList.js +25 -4
- package/dist/components/buckets/BucketReplicationFormPage.js +9 -3
- package/dist/components/buckets/DeleteBucketConfigRuleButton.js +1 -1
- package/dist/components/buckets/notifications/BucketNotificationList.js +1 -1
- package/dist/components/objects/DeleteObjectButton.d.ts +1 -0
- package/dist/components/objects/DeleteObjectButton.js +11 -5
- package/dist/components/objects/ObjectDetails/FormComponents.d.ts +9 -0
- package/dist/components/objects/ObjectDetails/FormComponents.js +37 -0
- package/dist/components/objects/ObjectDetails/ObjectMetadata.js +182 -204
- package/dist/components/objects/ObjectDetails/ObjectSummary.js +22 -5
- package/dist/components/objects/ObjectDetails/ObjectTags.js +109 -154
- package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.js +3 -3
- package/dist/components/objects/ObjectDetails/__tests__/ObjectMetadata.test.d.ts +1 -0
- package/dist/components/objects/ObjectDetails/__tests__/ObjectMetadata.test.js +230 -0
- package/dist/components/objects/ObjectDetails/__tests__/ObjectTags.test.d.ts +1 -0
- package/dist/components/objects/ObjectDetails/__tests__/ObjectTags.test.js +342 -0
- package/dist/components/objects/ObjectDetails/__tests__/formUtils.test.d.ts +1 -0
- package/dist/components/objects/ObjectDetails/__tests__/formUtils.test.js +202 -0
- package/dist/components/objects/ObjectDetails/index.d.ts +2 -1
- package/dist/components/objects/ObjectDetails/index.js +12 -16
- package/dist/components/objects/ObjectList.d.ts +3 -2
- package/dist/components/objects/ObjectList.js +204 -104
- package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.js +78 -26
- package/dist/components/objects/ObjectPage.js +22 -5
- package/dist/components/ui/ArrayFieldActions.js +0 -2
- package/dist/components/ui/FilterFormSection.js +17 -36
- package/dist/components/ui/FormGrid.d.ts +7 -0
- package/dist/components/ui/FormGrid.js +37 -0
- package/dist/components/ui/Table.elements.js +1 -0
- package/dist/config/__tests__/factory.test.js +29 -1
- package/dist/config/factory.d.ts +2 -0
- package/dist/config/factory.js +3 -1
- package/dist/config/types.d.ts +45 -2
- package/dist/hooks/__tests__/usePresigningS3Client.test.d.ts +1 -0
- package/dist/hooks/__tests__/usePresigningS3Client.test.js +104 -0
- package/dist/hooks/factories/index.d.ts +1 -1
- package/dist/hooks/factories/index.js +2 -2
- package/dist/hooks/factories/useCreateS3MutationHook.d.ts +2 -1
- package/dist/hooks/factories/useCreateS3MutationHook.js +10 -3
- package/dist/hooks/factories/useCreateS3QueryHook.d.ts +1 -0
- package/dist/hooks/factories/useCreateS3QueryHook.js +9 -6
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +2 -1
- package/dist/hooks/presignedOperations.js +4 -4
- package/dist/hooks/useBucketLocations.d.ts +6 -0
- package/dist/hooks/useBucketLocations.js +45 -0
- package/dist/hooks/usePresigningS3Client.d.ts +13 -0
- package/dist/hooks/usePresigningS3Client.js +21 -0
- package/package.json +4 -3
|
@@ -55,8 +55,12 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
55
55
|
const mockMutate = jest.fn();
|
|
56
56
|
const fillRequiredFields = async (options)=>{
|
|
57
57
|
const { roleArn = 'arn:aws:iam::123456789012:role/replication-role', ruleId, targetBucket = 'destination-bucket' } = options;
|
|
58
|
-
await user_event.type(screen.
|
|
59
|
-
|
|
58
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
59
|
+
name: /role arn/i
|
|
60
|
+
}), roleArn);
|
|
61
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
62
|
+
name: /rule id/i
|
|
63
|
+
}), ruleId);
|
|
60
64
|
const targetBucketSelect = screen.getByLabelText(/target bucket/i);
|
|
61
65
|
await user_event.click(targetBucketSelect);
|
|
62
66
|
await user_event.click(screen.getByRole('option', {
|
|
@@ -147,8 +151,12 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
147
151
|
it('displays all form sections', async ()=>{
|
|
148
152
|
renderBucketReplicationFormPage();
|
|
149
153
|
await waitFor(()=>{
|
|
150
|
-
expect(screen.
|
|
151
|
-
|
|
154
|
+
expect(screen.getByRole('textbox', {
|
|
155
|
+
name: /role arn/i
|
|
156
|
+
})).toBeInTheDocument();
|
|
157
|
+
expect(screen.getByRole('textbox', {
|
|
158
|
+
name: /rule id/i
|
|
159
|
+
})).toBeInTheDocument();
|
|
152
160
|
expect(screen.getByText('Replicate encrypted objects')).toBeInTheDocument();
|
|
153
161
|
expect(screen.getByText('Delete marker replication')).toBeInTheDocument();
|
|
154
162
|
});
|
|
@@ -157,14 +165,20 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
157
165
|
describe('Form Fields - Initial State', ()=>{
|
|
158
166
|
it('renders required form fields in create mode', ()=>{
|
|
159
167
|
renderBucketReplicationFormPage();
|
|
160
|
-
expect(screen.
|
|
161
|
-
|
|
168
|
+
expect(screen.getByRole('textbox', {
|
|
169
|
+
name: /role arn/i
|
|
170
|
+
})).toBeInTheDocument();
|
|
171
|
+
expect(screen.getByRole('textbox', {
|
|
172
|
+
name: /rule id/i
|
|
173
|
+
})).toBeInTheDocument();
|
|
162
174
|
expect(screen.getByLabelText(/status/i)).toBeInTheDocument();
|
|
163
175
|
expect(screen.getByLabelText(/target bucket/i)).toBeInTheDocument();
|
|
164
176
|
});
|
|
165
177
|
it('shows Role ARN input when no existing rules', ()=>{
|
|
166
178
|
renderBucketReplicationFormPage();
|
|
167
|
-
const roleInput = screen.
|
|
179
|
+
const roleInput = screen.getByRole('textbox', {
|
|
180
|
+
name: /role arn/i
|
|
181
|
+
});
|
|
168
182
|
expect(roleInput).toBeInTheDocument();
|
|
169
183
|
expect(roleInput.tagName).toBe('INPUT');
|
|
170
184
|
});
|
|
@@ -194,7 +208,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
194
208
|
});
|
|
195
209
|
it('shows Rule ID input in create mode', ()=>{
|
|
196
210
|
renderBucketReplicationFormPage();
|
|
197
|
-
const ruleIdInput = screen.
|
|
211
|
+
const ruleIdInput = screen.getByRole('textbox', {
|
|
212
|
+
name: /rule id/i
|
|
213
|
+
});
|
|
198
214
|
expect(ruleIdInput).toBeInTheDocument();
|
|
199
215
|
expect(ruleIdInput.tagName).toBe('INPUT');
|
|
200
216
|
});
|
|
@@ -229,14 +245,18 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
229
245
|
it('renders Status select field', async ()=>{
|
|
230
246
|
renderBucketReplicationFormPage();
|
|
231
247
|
await waitFor(()=>{
|
|
232
|
-
expect(screen.
|
|
248
|
+
expect(screen.getByRole('textbox', {
|
|
249
|
+
name: /rule id/i
|
|
250
|
+
})).toBeInTheDocument();
|
|
233
251
|
});
|
|
234
252
|
const statusElement = document.querySelector('[id="status"]');
|
|
235
253
|
expect(statusElement).toBeInTheDocument();
|
|
236
254
|
});
|
|
237
255
|
it('renders Priority number input with auto-assigned placeholder', ()=>{
|
|
238
256
|
renderBucketReplicationFormPage();
|
|
239
|
-
const priorityInput = screen.
|
|
257
|
+
const priorityInput = screen.getByRole('spinbutton', {
|
|
258
|
+
name: /rule priority/i
|
|
259
|
+
});
|
|
240
260
|
expect(priorityInput).toBeInTheDocument();
|
|
241
261
|
expect(priorityInput).toHaveAttribute('placeholder', 'Example: Auto-assigned: 0');
|
|
242
262
|
});
|
|
@@ -255,7 +275,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
255
275
|
});
|
|
256
276
|
it('renders storage class select with all options', async ()=>{
|
|
257
277
|
renderBucketReplicationFormPage();
|
|
258
|
-
const storageClassSelect = screen.getByLabelText(/storage class/i
|
|
278
|
+
const storageClassSelect = screen.getByLabelText(/storage class/i, {
|
|
279
|
+
selector: 'input'
|
|
280
|
+
});
|
|
259
281
|
await user_event.click(storageClassSelect);
|
|
260
282
|
expect(screen.getByRole('option', {
|
|
261
283
|
name: 'Same as source'
|
|
@@ -283,7 +305,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
283
305
|
describe('Form Validation', ()=>{
|
|
284
306
|
it('validates Role ARN is required for first replication rule', async ()=>{
|
|
285
307
|
renderBucketReplicationFormPage();
|
|
286
|
-
const roleInput = screen.
|
|
308
|
+
const roleInput = screen.getByRole('textbox', {
|
|
309
|
+
name: /role arn/i
|
|
310
|
+
});
|
|
287
311
|
await user_event.type(roleInput, 'test');
|
|
288
312
|
await user_event.clear(roleInput);
|
|
289
313
|
await waitFor(()=>{
|
|
@@ -310,7 +334,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
310
334
|
status: 'success'
|
|
311
335
|
});
|
|
312
336
|
renderBucketReplicationFormPage();
|
|
313
|
-
await user_event.type(screen.
|
|
337
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
338
|
+
name: /rule id/i
|
|
339
|
+
}), 'new-rule');
|
|
314
340
|
const targetBucketSelect = screen.getByLabelText(/target bucket/i);
|
|
315
341
|
await user_event.click(targetBucketSelect);
|
|
316
342
|
await user_event.click(screen.getByRole('option', {
|
|
@@ -325,7 +351,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
325
351
|
});
|
|
326
352
|
it('validates Rule ID is required', async ()=>{
|
|
327
353
|
renderBucketReplicationFormPage();
|
|
328
|
-
const ruleIdInput = screen.
|
|
354
|
+
const ruleIdInput = screen.getByRole('textbox', {
|
|
355
|
+
name: /rule id/i
|
|
356
|
+
});
|
|
329
357
|
await user_event.type(ruleIdInput, 'test');
|
|
330
358
|
await user_event.clear(ruleIdInput);
|
|
331
359
|
await waitFor(()=>{
|
|
@@ -352,7 +380,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
352
380
|
status: 'success'
|
|
353
381
|
});
|
|
354
382
|
renderBucketReplicationFormPage();
|
|
355
|
-
const ruleIdInput = screen.
|
|
383
|
+
const ruleIdInput = screen.getByRole('textbox', {
|
|
384
|
+
name: /rule id/i
|
|
385
|
+
});
|
|
356
386
|
await user_event.type(ruleIdInput, 'existing-rule');
|
|
357
387
|
await waitFor(()=>{
|
|
358
388
|
expect(screen.getByText(/a rule with this id already exists/i)).toBeInTheDocument();
|
|
@@ -360,8 +390,12 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
360
390
|
});
|
|
361
391
|
it('validates Priority must be >= 0', async ()=>{
|
|
362
392
|
renderBucketReplicationFormPage();
|
|
363
|
-
await user_event.type(screen.
|
|
364
|
-
|
|
393
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
394
|
+
name: /rule id/i
|
|
395
|
+
}), 'test-rule');
|
|
396
|
+
const priorityInput = screen.getByRole('spinbutton', {
|
|
397
|
+
name: /rule priority/i
|
|
398
|
+
});
|
|
365
399
|
await user_event.clear(priorityInput);
|
|
366
400
|
await user_event.type(priorityInput, '-1');
|
|
367
401
|
await user_event.tab();
|
|
@@ -371,8 +405,12 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
371
405
|
});
|
|
372
406
|
it('disables submit button when Target Bucket is not selected', async ()=>{
|
|
373
407
|
renderBucketReplicationFormPage();
|
|
374
|
-
await user_event.type(screen.
|
|
375
|
-
|
|
408
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
409
|
+
name: /role arn/i
|
|
410
|
+
}), 'arn:aws:iam::123456789012:role/role');
|
|
411
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
412
|
+
name: /rule id/i
|
|
413
|
+
}), 'test-rule');
|
|
376
414
|
await waitFor(()=>{
|
|
377
415
|
const createButton = screen.getByRole('button', {
|
|
378
416
|
name: /create/i
|
|
@@ -385,7 +423,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
385
423
|
const sameAccountToggle = findToggleByLabel('Same account destination');
|
|
386
424
|
await user_event.click(sameAccountToggle);
|
|
387
425
|
await waitFor(()=>{
|
|
388
|
-
expect(screen.
|
|
426
|
+
expect(screen.getByRole('textbox', {
|
|
427
|
+
name: /target account id/i
|
|
428
|
+
})).toBeInTheDocument();
|
|
389
429
|
});
|
|
390
430
|
});
|
|
391
431
|
it('shows Replica KMS Key ID field when encryptReplicatedObjects is true', async ()=>{
|
|
@@ -393,7 +433,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
393
433
|
const encryptToggle = findToggleByLabel('Encrypt replicated objects');
|
|
394
434
|
await user_event.click(encryptToggle);
|
|
395
435
|
await waitFor(()=>{
|
|
396
|
-
expect(screen.
|
|
436
|
+
expect(screen.getByRole('textbox', {
|
|
437
|
+
name: /replica kms key id/i
|
|
438
|
+
})).toBeInTheDocument();
|
|
397
439
|
});
|
|
398
440
|
});
|
|
399
441
|
it('shows prefix field when filterType is prefix', async ()=>{
|
|
@@ -409,7 +451,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
409
451
|
name: 'Prefix filter'
|
|
410
452
|
}));
|
|
411
453
|
await waitFor(()=>{
|
|
412
|
-
expect(screen.
|
|
454
|
+
expect(screen.getByRole('textbox', {
|
|
455
|
+
name: /prefix/i
|
|
456
|
+
})).toBeInTheDocument();
|
|
413
457
|
});
|
|
414
458
|
});
|
|
415
459
|
});
|
|
@@ -505,7 +549,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
505
549
|
const sameAccountToggle = findToggleByLabel('Same account destination');
|
|
506
550
|
await user_event.click(sameAccountToggle);
|
|
507
551
|
await waitFor(()=>{
|
|
508
|
-
expect(screen.
|
|
552
|
+
expect(screen.getByRole('textbox', {
|
|
553
|
+
name: /target account id/i
|
|
554
|
+
})).toBeInTheDocument();
|
|
509
555
|
});
|
|
510
556
|
});
|
|
511
557
|
it('renders target bucket as Input for cross-account replication', async ()=>{
|
|
@@ -523,7 +569,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
523
569
|
const encryptToggle = findToggleByLabel('Encrypt replicated objects');
|
|
524
570
|
await user_event.click(encryptToggle);
|
|
525
571
|
await waitFor(()=>{
|
|
526
|
-
expect(screen.
|
|
572
|
+
expect(screen.getByRole('textbox', {
|
|
573
|
+
name: /replica kms key id/i
|
|
574
|
+
})).toBeInTheDocument();
|
|
527
575
|
});
|
|
528
576
|
});
|
|
529
577
|
});
|
|
@@ -556,9 +604,15 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
556
604
|
});
|
|
557
605
|
it('submits complete replication rule with all optional fields', async ()=>{
|
|
558
606
|
renderBucketReplicationFormPage();
|
|
559
|
-
await user_event.type(screen.
|
|
560
|
-
|
|
561
|
-
|
|
607
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
608
|
+
name: /role arn/i
|
|
609
|
+
}), 'arn:aws:iam::123456789012:role/replication-role');
|
|
610
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
611
|
+
name: /rule id/i
|
|
612
|
+
}), 'complete-rule');
|
|
613
|
+
await user_event.type(screen.getByRole('spinbutton', {
|
|
614
|
+
name: /rule priority/i
|
|
615
|
+
}), '5');
|
|
562
616
|
const filterSelect = document.querySelector('[id="filterType"]');
|
|
563
617
|
await user_event.click(filterSelect);
|
|
564
618
|
await waitFor(()=>{
|
|
@@ -570,15 +624,23 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
570
624
|
name: 'Prefix filter'
|
|
571
625
|
}));
|
|
572
626
|
await waitFor(()=>{
|
|
573
|
-
expect(screen.
|
|
627
|
+
expect(screen.getByRole('textbox', {
|
|
628
|
+
name: /prefix/i
|
|
629
|
+
})).toBeInTheDocument();
|
|
574
630
|
});
|
|
575
|
-
await user_event.type(screen.
|
|
631
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
632
|
+
name: /prefix/i
|
|
633
|
+
}), 'logs/');
|
|
576
634
|
const sameAccountToggle = findToggleByLabel('Same account destination');
|
|
577
635
|
await user_event.click(sameAccountToggle);
|
|
578
636
|
await waitFor(()=>{
|
|
579
|
-
expect(screen.
|
|
637
|
+
expect(screen.getByRole('textbox', {
|
|
638
|
+
name: /target account id/i
|
|
639
|
+
})).toBeInTheDocument();
|
|
580
640
|
});
|
|
581
|
-
await user_event.type(screen.
|
|
641
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
642
|
+
name: /target account id/i
|
|
643
|
+
}), '987654321098');
|
|
582
644
|
await user_event.type(screen.getByLabelText(/target bucket/i), 'cross-account-bucket');
|
|
583
645
|
const storageClassSelect = document.querySelector('[id="storageClass"]');
|
|
584
646
|
await user_event.click(storageClassSelect);
|
|
@@ -595,9 +657,13 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
595
657
|
const includeEncryptedToggle = findToggleByLabel('Replicate encrypted objects');
|
|
596
658
|
await user_event.click(includeEncryptedToggle);
|
|
597
659
|
await waitFor(()=>{
|
|
598
|
-
expect(screen.
|
|
660
|
+
expect(screen.getByRole('textbox', {
|
|
661
|
+
name: /replica kms key id/i
|
|
662
|
+
})).toBeInTheDocument();
|
|
599
663
|
});
|
|
600
|
-
await user_event.type(screen.
|
|
664
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
665
|
+
name: /replica kms key id/i
|
|
666
|
+
}), 'arn:aws:kms:us-east-1:987654321098:key/12345678-1234-1234-1234-123456789012');
|
|
601
667
|
const enforceRTCToggle = findToggleByLabel('Replication Time Control (RTC)');
|
|
602
668
|
await user_event.click(enforceRTCToggle);
|
|
603
669
|
const replicaModToggle = findToggleByLabel('Replica modification sync');
|
|
@@ -674,7 +740,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
674
740
|
status: 'success'
|
|
675
741
|
});
|
|
676
742
|
renderBucketReplicationFormPage();
|
|
677
|
-
await user_event.type(screen.
|
|
743
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
744
|
+
name: /rule id/i
|
|
745
|
+
}), 'new-rule');
|
|
678
746
|
const targetBucketSelect = screen.getByLabelText(/target bucket/i);
|
|
679
747
|
await user_event.click(targetBucketSelect);
|
|
680
748
|
await user_event.click(screen.getByRole('option', {
|
|
@@ -753,7 +821,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
753
821
|
});
|
|
754
822
|
it('disables submit button when form is invalid', async ()=>{
|
|
755
823
|
renderBucketReplicationFormPage();
|
|
756
|
-
await user_event.type(screen.
|
|
824
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
825
|
+
name: /rule id/i
|
|
826
|
+
}), 'test');
|
|
757
827
|
await waitFor(()=>{
|
|
758
828
|
const createButton = screen.getByRole('button', {
|
|
759
829
|
name: /create/i
|
|
@@ -1033,7 +1103,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1033
1103
|
});
|
|
1034
1104
|
renderBucketReplicationFormPage('test-bucket', 'prefix-rule');
|
|
1035
1105
|
await waitFor(()=>{
|
|
1036
|
-
const prefixInput = screen.
|
|
1106
|
+
const prefixInput = screen.getByRole('textbox', {
|
|
1107
|
+
name: /prefix/i
|
|
1108
|
+
});
|
|
1037
1109
|
expect(prefixInput).toHaveValue('documents/');
|
|
1038
1110
|
});
|
|
1039
1111
|
});
|
|
@@ -1106,7 +1178,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1106
1178
|
});
|
|
1107
1179
|
renderBucketReplicationFormPage('test-bucket', 'and-rule');
|
|
1108
1180
|
await waitFor(()=>{
|
|
1109
|
-
const prefixInput = screen.
|
|
1181
|
+
const prefixInput = screen.getByRole('textbox', {
|
|
1182
|
+
name: /prefix/i
|
|
1183
|
+
});
|
|
1110
1184
|
expect(prefixInput).toHaveValue('logs/');
|
|
1111
1185
|
expect(screen.getByDisplayValue('type')).toBeInTheDocument();
|
|
1112
1186
|
expect(screen.getByDisplayValue('audit')).toBeInTheDocument();
|
|
@@ -1172,7 +1246,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1172
1246
|
await waitFor(()=>{
|
|
1173
1247
|
const encryptReplicatedToggle = findToggleByLabel('Encrypt replicated objects');
|
|
1174
1248
|
expect(encryptReplicatedToggle).toBeChecked();
|
|
1175
|
-
const kmsKeyInput = screen.
|
|
1249
|
+
const kmsKeyInput = screen.getByRole('textbox', {
|
|
1250
|
+
name: /replica kms key id/i
|
|
1251
|
+
});
|
|
1176
1252
|
expect(kmsKeyInput).toHaveValue('arn:aws:kms:us-east-1:123456789012:key/12345');
|
|
1177
1253
|
});
|
|
1178
1254
|
});
|
|
@@ -1300,7 +1376,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1300
1376
|
await waitFor(()=>{
|
|
1301
1377
|
const sameAccountToggle = screen.getByText(/not same account destination/i);
|
|
1302
1378
|
expect(sameAccountToggle).toBeInTheDocument();
|
|
1303
|
-
const accountIdInput = screen.
|
|
1379
|
+
const accountIdInput = screen.getByRole('textbox', {
|
|
1380
|
+
name: /target account id/i
|
|
1381
|
+
});
|
|
1304
1382
|
expect(accountIdInput).toHaveValue('987654321098');
|
|
1305
1383
|
const targetBucketInput = screen.getByLabelText(/target bucket/i);
|
|
1306
1384
|
expect(targetBucketInput).toHaveValue('cross-account-bucket');
|
|
@@ -1359,7 +1437,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1359
1437
|
});
|
|
1360
1438
|
renderBucketReplicationFormPage('test-bucket', 'storage-class-rule');
|
|
1361
1439
|
await waitFor(()=>{
|
|
1362
|
-
const storageClassSelect = screen.getByLabelText(/storage class/i
|
|
1440
|
+
const storageClassSelect = screen.getByLabelText(/storage class/i, {
|
|
1441
|
+
selector: 'input'
|
|
1442
|
+
});
|
|
1363
1443
|
expect(storageClassSelect).toBeInTheDocument();
|
|
1364
1444
|
});
|
|
1365
1445
|
});
|
|
@@ -1385,7 +1465,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1385
1465
|
});
|
|
1386
1466
|
renderBucketReplicationFormPage('test-bucket', 'priority-rule');
|
|
1387
1467
|
await waitFor(()=>{
|
|
1388
|
-
const priorityInput = screen.
|
|
1468
|
+
const priorityInput = screen.getByRole('spinbutton', {
|
|
1469
|
+
name: /rule priority/i
|
|
1470
|
+
});
|
|
1389
1471
|
expect(priorityInput).toHaveValue(99);
|
|
1390
1472
|
});
|
|
1391
1473
|
});
|
|
@@ -1393,7 +1475,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1393
1475
|
describe('Priority Auto-assignment', ()=>{
|
|
1394
1476
|
it('auto-assigns priority 0 when no existing rules', ()=>{
|
|
1395
1477
|
renderBucketReplicationFormPage();
|
|
1396
|
-
const priorityInput = screen.
|
|
1478
|
+
const priorityInput = screen.getByRole('spinbutton', {
|
|
1479
|
+
name: /rule priority/i
|
|
1480
|
+
});
|
|
1397
1481
|
expect(priorityInput).toHaveAttribute('placeholder', 'Example: Auto-assigned: 0');
|
|
1398
1482
|
});
|
|
1399
1483
|
it('auto-assigns next available priority when rules exist', ()=>{
|
|
@@ -1424,19 +1508,27 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1424
1508
|
status: 'success'
|
|
1425
1509
|
});
|
|
1426
1510
|
renderBucketReplicationFormPage();
|
|
1427
|
-
const priorityInput = screen.
|
|
1511
|
+
const priorityInput = screen.getByRole('spinbutton', {
|
|
1512
|
+
name: /rule priority/i
|
|
1513
|
+
});
|
|
1428
1514
|
expect(priorityInput).toHaveAttribute('placeholder', 'Example: Auto-assigned: 11');
|
|
1429
1515
|
});
|
|
1430
1516
|
it('allows manual priority override', async ()=>{
|
|
1431
1517
|
renderBucketReplicationFormPage();
|
|
1432
|
-
const priorityInput = screen.
|
|
1518
|
+
const priorityInput = screen.getByRole('spinbutton', {
|
|
1519
|
+
name: /rule priority/i
|
|
1520
|
+
});
|
|
1433
1521
|
await user_event.type(priorityInput, '25');
|
|
1434
1522
|
expect(priorityInput).toHaveValue(25);
|
|
1435
1523
|
});
|
|
1436
1524
|
it('accepts empty priority and defaults to 0 on submit', async ()=>{
|
|
1437
1525
|
renderBucketReplicationFormPage();
|
|
1438
|
-
await user_event.type(screen.
|
|
1439
|
-
|
|
1526
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
1527
|
+
name: /role arn/i
|
|
1528
|
+
}), 'arn:aws:iam::123456789012:role/role');
|
|
1529
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
1530
|
+
name: /rule id/i
|
|
1531
|
+
}), 'no-priority-rule');
|
|
1440
1532
|
const targetBucketSelect = screen.getByLabelText(/target bucket/i);
|
|
1441
1533
|
await user_event.click(targetBucketSelect);
|
|
1442
1534
|
await user_event.click(screen.getByRole('option', {
|
|
@@ -1520,8 +1612,12 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1520
1612
|
isPending: true
|
|
1521
1613
|
});
|
|
1522
1614
|
renderBucketReplicationFormPage();
|
|
1523
|
-
await user_event.type(screen.
|
|
1524
|
-
|
|
1615
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
1616
|
+
name: /role arn/i
|
|
1617
|
+
}), 'arn:aws:iam::123456789012:role/role');
|
|
1618
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
1619
|
+
name: /rule id/i
|
|
1620
|
+
}), 'test-rule');
|
|
1525
1621
|
const targetBucketSelect = screen.getByLabelText(/target bucket/i);
|
|
1526
1622
|
await user_event.click(targetBucketSelect);
|
|
1527
1623
|
await user_event.click(screen.getByRole('option', {
|
|
@@ -1619,7 +1715,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1619
1715
|
});
|
|
1620
1716
|
renderBucketReplicationFormPage('test-bucket', 'no-priority');
|
|
1621
1717
|
await waitFor(()=>{
|
|
1622
|
-
const priorityInput = screen.
|
|
1718
|
+
const priorityInput = screen.getByRole('spinbutton', {
|
|
1719
|
+
name: /rule priority/i
|
|
1720
|
+
});
|
|
1623
1721
|
expect(priorityInput).toHaveValue(null);
|
|
1624
1722
|
});
|
|
1625
1723
|
});
|
|
@@ -1645,7 +1743,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1645
1743
|
});
|
|
1646
1744
|
renderBucketReplicationFormPage('test-bucket', 'no-storage-class');
|
|
1647
1745
|
await waitFor(()=>{
|
|
1648
|
-
const storageClassSelect = screen.getByLabelText(/storage class/i
|
|
1746
|
+
const storageClassSelect = screen.getByLabelText(/storage class/i, {
|
|
1747
|
+
selector: 'input'
|
|
1748
|
+
});
|
|
1649
1749
|
expect(storageClassSelect).toBeInTheDocument();
|
|
1650
1750
|
});
|
|
1651
1751
|
});
|
|
@@ -1654,7 +1754,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1654
1754
|
it('accepts Rule ID with reasonable length', async ()=>{
|
|
1655
1755
|
renderBucketReplicationFormPage();
|
|
1656
1756
|
const longRuleId = 'rule-name-with-many-segments-' + 'segment-'.repeat(10);
|
|
1657
|
-
const ruleIdInput = screen.
|
|
1757
|
+
const ruleIdInput = screen.getByRole('textbox', {
|
|
1758
|
+
name: /rule id/i
|
|
1759
|
+
});
|
|
1658
1760
|
await user_event.type(ruleIdInput, longRuleId);
|
|
1659
1761
|
await waitFor(()=>{
|
|
1660
1762
|
expect(ruleIdInput).toHaveValue(longRuleId);
|
|
@@ -1663,7 +1765,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1663
1765
|
it('handles special characters in Rule ID', async ()=>{
|
|
1664
1766
|
renderBucketReplicationFormPage();
|
|
1665
1767
|
const validSpecialChars = 'rule-name_with.special-chars_123';
|
|
1666
|
-
const ruleIdInput = screen.
|
|
1768
|
+
const ruleIdInput = screen.getByRole('textbox', {
|
|
1769
|
+
name: /rule id/i
|
|
1770
|
+
});
|
|
1667
1771
|
await user_event.type(ruleIdInput, validSpecialChars);
|
|
1668
1772
|
await user_event.tab();
|
|
1669
1773
|
await waitFor(()=>{
|
|
@@ -1672,8 +1776,12 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1672
1776
|
});
|
|
1673
1777
|
it('validates Priority with boundary values', async ()=>{
|
|
1674
1778
|
renderBucketReplicationFormPage();
|
|
1675
|
-
await user_event.type(screen.
|
|
1676
|
-
|
|
1779
|
+
await user_event.type(screen.getByRole('textbox', {
|
|
1780
|
+
name: /rule id/i
|
|
1781
|
+
}), 'boundary-test');
|
|
1782
|
+
const priorityInput = screen.getByRole('spinbutton', {
|
|
1783
|
+
name: /rule priority/i
|
|
1784
|
+
});
|
|
1677
1785
|
await user_event.clear(priorityInput);
|
|
1678
1786
|
await user_event.type(priorityInput, '0');
|
|
1679
1787
|
await user_event.tab();
|
|
@@ -1700,10 +1808,14 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1700
1808
|
name: 'Prefix filter'
|
|
1701
1809
|
}));
|
|
1702
1810
|
await waitFor(()=>{
|
|
1703
|
-
expect(screen.
|
|
1811
|
+
expect(screen.getByRole('textbox', {
|
|
1812
|
+
name: /prefix/i
|
|
1813
|
+
})).toBeInTheDocument();
|
|
1704
1814
|
});
|
|
1705
1815
|
const longPrefix = 'logs/' + 'a'.repeat(100);
|
|
1706
|
-
const prefixInput = screen.
|
|
1816
|
+
const prefixInput = screen.getByRole('textbox', {
|
|
1817
|
+
name: /prefix/i
|
|
1818
|
+
});
|
|
1707
1819
|
await user_event.type(prefixInput, longPrefix);
|
|
1708
1820
|
await waitFor(()=>{
|
|
1709
1821
|
expect(prefixInput).toHaveValue(longPrefix);
|
|
@@ -1711,7 +1823,9 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1711
1823
|
});
|
|
1712
1824
|
it('accepts valid Role ARN format', async ()=>{
|
|
1713
1825
|
renderBucketReplicationFormPage();
|
|
1714
|
-
const roleArnInput = screen.
|
|
1826
|
+
const roleArnInput = screen.getByRole('textbox', {
|
|
1827
|
+
name: /role arn/i
|
|
1828
|
+
});
|
|
1715
1829
|
await user_event.type(roleArnInput, 'arn:aws:iam::123456789012:role/replication-role');
|
|
1716
1830
|
await user_event.tab();
|
|
1717
1831
|
await waitFor(()=>{
|
|
@@ -1723,9 +1837,13 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1723
1837
|
const sameAccountToggle = findToggleByLabel('Same account destination');
|
|
1724
1838
|
await user_event.click(sameAccountToggle);
|
|
1725
1839
|
await waitFor(()=>{
|
|
1726
|
-
expect(screen.
|
|
1840
|
+
expect(screen.getByRole('textbox', {
|
|
1841
|
+
name: /target account id/i
|
|
1842
|
+
})).toBeInTheDocument();
|
|
1843
|
+
});
|
|
1844
|
+
const accountIdInput = screen.getByRole('textbox', {
|
|
1845
|
+
name: /target account id/i
|
|
1727
1846
|
});
|
|
1728
|
-
const accountIdInput = screen.getByLabelText(/target account id/i);
|
|
1729
1847
|
await user_event.type(accountIdInput, '123456789012');
|
|
1730
1848
|
await user_event.tab();
|
|
1731
1849
|
await waitFor(()=>{
|
|
@@ -1744,9 +1862,13 @@ describe('BucketReplicationFormPage', ()=>{
|
|
|
1744
1862
|
const encryptToggle = findToggleByLabel('Encrypt replicated objects');
|
|
1745
1863
|
await user_event.click(encryptToggle);
|
|
1746
1864
|
await waitFor(()=>{
|
|
1747
|
-
expect(screen.
|
|
1865
|
+
expect(screen.getByRole('textbox', {
|
|
1866
|
+
name: /replica kms key id/i
|
|
1867
|
+
})).toBeInTheDocument();
|
|
1868
|
+
});
|
|
1869
|
+
const kmsKeyInput = screen.getByRole('textbox', {
|
|
1870
|
+
name: /replica kms key id/i
|
|
1748
1871
|
});
|
|
1749
|
-
const kmsKeyInput = screen.getByLabelText(/replica kms key id/i);
|
|
1750
1872
|
const validKmsArn = 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012';
|
|
1751
1873
|
await user_event.type(kmsKeyInput, validKmsArn);
|
|
1752
1874
|
await waitFor(()=>{
|
|
@@ -47,27 +47,33 @@ describe('MetadataSearch', ()=>{
|
|
|
47
47
|
await user_event.type(input, 'test query');
|
|
48
48
|
expect(searchButton).toBeEnabled();
|
|
49
49
|
});
|
|
50
|
-
it('shows search icon by default', ()=>{
|
|
50
|
+
it('shows search icon by default', async ()=>{
|
|
51
51
|
renderMetadataSearch();
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
await waitFor(()=>{
|
|
53
|
+
expect(screen.getByRole('img', {
|
|
54
|
+
hidden: true
|
|
55
|
+
})).toBeInTheDocument();
|
|
56
|
+
});
|
|
55
57
|
});
|
|
56
|
-
it('shows check icon when metadata search is active', ()=>{
|
|
58
|
+
it('shows check icon when metadata search is active', async ()=>{
|
|
57
59
|
renderMetadataSearch({}, [
|
|
58
60
|
'/bucket/test-bucket?metadatasearch=test'
|
|
59
61
|
]);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
await waitFor(()=>{
|
|
63
|
+
expect(screen.getByRole('img', {
|
|
64
|
+
hidden: true
|
|
65
|
+
})).toBeInTheDocument();
|
|
66
|
+
});
|
|
63
67
|
});
|
|
64
|
-
it('shows error icon when error prop is true', ()=>{
|
|
68
|
+
it('shows error icon when error prop is true', async ()=>{
|
|
65
69
|
renderMetadataSearch({
|
|
66
70
|
isError: true
|
|
67
71
|
});
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
await waitFor(()=>{
|
|
73
|
+
expect(screen.getByRole('img', {
|
|
74
|
+
hidden: true
|
|
75
|
+
})).toBeInTheDocument();
|
|
76
|
+
});
|
|
71
77
|
});
|
|
72
78
|
it('populates input with existing search query from URL', ()=>{
|
|
73
79
|
renderMetadataSearch({}, [
|