Skip to content

Commit e06f0aa

Browse files
new: STORIF-310 - Bucket tab filters created.
1 parent 85edc8c commit e06f0aa

File tree

13 files changed

+462
-28
lines changed

13 files changed

+462
-28
lines changed

packages/manager/cypress/e2e/core/objectStorage/object-storage.e2e.spec.ts

Lines changed: 171 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
import { createBucket } from '@linode/api-v4/lib/object-storage';
6+
import { getNewRegionLabel } from '@linode/utilities';
67
import { authenticate } from 'support/api/authentication';
78
import {
89
interceptGetNetworkUtilization,
@@ -16,6 +17,7 @@ import {
1617
interceptGetBuckets,
1718
interceptUpdateBucketAccess,
1819
} from 'support/intercepts/object-storage';
20+
import { interceptGetRegions } from 'support/intercepts/regions';
1921
import { ui } from 'support/ui';
2022
import { cleanUp } from 'support/util/cleanup';
2123
import { chooseCluster } from 'support/util/clusters';
@@ -27,6 +29,8 @@ import {
2729
createObjectStorageBucketFactoryLegacy,
2830
} from 'src/factories';
2931

32+
import type { Region } from '@linode/api-v4/lib/object-storage';
33+
3034
/**
3135
* Create a bucket with the given label and cluster.
3236
*
@@ -41,23 +45,29 @@ import {
4145
*/
4246
const setUpBucket = (
4347
label: string,
44-
cluster: string,
48+
region: string,
4549
cors_enabled: boolean = true
4650
) => {
4751
return createBucket(
4852
createObjectStorageBucketFactoryLegacy.build({
49-
cluster,
53+
region,
5054
cors_enabled,
5155
label,
5256

5357
// API accepts either `cluster` or `region`, but not both. Our factory
54-
// populates both fields, so we have to manually set `region` to `undefined`
58+
// populates both fields, so we have to manually set `cluster` to `undefined`
5559
// to avoid 400 responses from the API.
56-
region: undefined,
60+
cluster: undefined,
5761
})
5862
);
5963
};
6064

65+
const setupBuckets = (bucketsDetails: { label: string; region: string }[]) => {
66+
return Promise.all(
67+
bucketsDetails.map(({ label, region }) => setUpBucket(label, region))
68+
);
69+
};
70+
6171
authenticate();
6272
beforeEach(() => {
6373
cy.tag('method:e2e');
@@ -78,12 +88,11 @@ describe('object storage end-to-end tests', () => {
7888
cy.tag('purpose:syntheticTesting');
7989
const bucketLabel = randomLabel();
8090
const bucketClusterObj = chooseCluster();
81-
const bucketCluster = bucketClusterObj.id;
8291
const bucketRegion = getRegionById(bucketClusterObj.region).label;
8392
const bucketHostname = `${bucketLabel}.${bucketClusterObj.domain}`;
8493
interceptGetBuckets().as('getBuckets');
8594
interceptCreateBucket().as('createBucket');
86-
interceptDeleteBucket(bucketLabel, bucketCluster).as('deleteBucket');
95+
interceptDeleteBucket().as('deleteBucket');
8796
interceptGetNetworkUtilization().as('getNetworkUtilization');
8897

8998
mockGetAccount(accountFactory.build({ capabilities: ['Object Storage'] }));
@@ -157,17 +166,15 @@ describe('object storage end-to-end tests', () => {
157166
it('can update bucket access', () => {
158167
const bucketLabel = randomLabel();
159168
const bucketClusterObj = chooseCluster();
160-
const bucketCluster = bucketClusterObj.id;
161-
const bucketAccessPage = `/object-storage/buckets/${bucketCluster}/${bucketLabel}/access`;
169+
const bucketRegion = bucketClusterObj.region;
170+
const bucketAccessPage = `/object-storage/buckets/${bucketRegion}/${bucketLabel}/access`;
162171

163172
cy.defer(
164-
() => setUpBucket(bucketLabel, bucketCluster),
173+
() => setUpBucket(bucketLabel, bucketRegion),
165174
'creating Object Storage bucket'
166175
).then(() => {
167-
interceptGetBucketAccess(bucketLabel, bucketCluster).as(
168-
'getBucketAccess'
169-
);
170-
interceptUpdateBucketAccess(bucketLabel, bucketCluster).as(
176+
interceptGetBucketAccess(bucketLabel, bucketRegion).as('getBucketAccess');
177+
interceptUpdateBucketAccess(bucketLabel, bucketRegion).as(
171178
'updateBucketAccess'
172179
);
173180

@@ -197,4 +204,155 @@ describe('object storage end-to-end tests', () => {
197204
cy.findByText('Bucket access updated successfully.');
198205
});
199206
});
207+
208+
/*
209+
* - Confirms that user can filter bucket list by region.
210+
*/
211+
it('can filter the list of buckets by region', () => {
212+
interceptGetBuckets().as('getBuckets');
213+
interceptGetRegions().as('getRegions');
214+
215+
const bucketsDetails = new Array(2).fill({}).map((_, index) => ({
216+
label: randomLabel(),
217+
region: index === 0 ? 'us-ord' : 'us-lax',
218+
}));
219+
220+
cy.defer(
221+
() => setupBuckets(bucketsDetails),
222+
'creating Object Storage bucket'
223+
).then(() => {
224+
cy.visitWithLogin('/object-storage/buckets');
225+
cy.wait(['@getBuckets', '@getRegions']).then(([_, { response }]) => {
226+
const regions: Region[] = response?.body.data;
227+
228+
const selectedBucket = bucketsDetails[0];
229+
const selectedRegion = regions.find(
230+
(region) => region.id === selectedBucket.region
231+
);
232+
233+
expect(
234+
selectedRegion,
235+
`expected region matching ${selectedBucket.region}`
236+
).to.exist;
237+
238+
const selectedRegionLabel = selectedRegion
239+
? getNewRegionLabel(selectedRegion)
240+
: '';
241+
242+
const regionSelect = ui.autocomplete
243+
.findByLabel('Region')
244+
.should('be.visible')
245+
.type(selectedRegionLabel);
246+
247+
ui.autocompletePopper
248+
.findByTitle(selectedRegionLabel, { exact: false })
249+
.should('be.visible')
250+
.click();
251+
252+
regionSelect.click();
253+
254+
cy.get('tbody').within(() => {
255+
cy.get('tr')
256+
.should('have.length', 1)
257+
.within(() => {
258+
cy.findByText(selectedBucket.label).should('be.visible');
259+
});
260+
});
261+
});
262+
});
263+
});
264+
265+
/*
266+
* - Confirms that user can filter bucket list by endpoint.
267+
*/
268+
it('can filter the list of buckets by endpoint', () => {
269+
interceptGetBuckets().as('getBuckets');
270+
interceptGetRegions().as('getRegions');
271+
272+
const bucketsDetails = new Array(2).fill({}).map((_, index) => ({
273+
label: randomLabel(),
274+
region: index === 0 ? 'us-ord' : 'us-lax',
275+
}));
276+
277+
cy.defer(
278+
() => setupBuckets(bucketsDetails),
279+
'creating Object Storage bucket'
280+
).then(() => {
281+
cy.visitWithLogin('/object-storage/buckets');
282+
cy.wait(['@getBuckets', '@getRegions']);
283+
284+
const selectedBucket = bucketsDetails[0];
285+
const selectedBucketRegion = selectedBucket.region;
286+
287+
const endpointSelect = ui.autocomplete.findByLabel('Endpoint');
288+
endpointSelect.should('be.visible').type(selectedBucketRegion);
289+
ui.autocompletePopper
290+
.findByTitle(selectedBucketRegion, { exact: false })
291+
.should('be.visible')
292+
.click();
293+
endpointSelect.click();
294+
295+
cy.get('tbody').within(() => {
296+
cy.get('tr')
297+
.should('have.length', 1)
298+
.within(() => {
299+
cy.findByText(selectedBucket.label).should('be.visible');
300+
});
301+
});
302+
});
303+
});
304+
305+
/*
306+
* - Confirms that when region is selected, endpoint multiselect.
307+
* shows only endpoints related to the selected region.
308+
*/
309+
it('should filter list of endpoints when region is selected', () => {
310+
interceptGetBuckets().as('getBuckets');
311+
interceptGetRegions().as('getRegions');
312+
313+
const bucketsDetails = new Array(2).fill({}).map((_, index) => ({
314+
label: randomLabel(),
315+
region: index === 0 ? 'us-ord' : 'us-lax',
316+
}));
317+
318+
cy.defer(
319+
() => setupBuckets(bucketsDetails),
320+
'creating Object Storage bucket'
321+
).then(() => {
322+
cy.visitWithLogin('/object-storage/buckets');
323+
cy.wait(['@getBuckets', '@getRegions']).then(([_, { response }]) => {
324+
const regions: Region[] = response?.body.data;
325+
326+
const selectedBucket = bucketsDetails[0];
327+
const selectedRegion = regions.find(
328+
(region) => region.id === selectedBucket.region
329+
);
330+
331+
expect(
332+
selectedRegion,
333+
`expected region matching ${selectedBucket.region}`
334+
).to.exist;
335+
336+
const selectedRegionLabel = selectedRegion
337+
? getNewRegionLabel(selectedRegion)
338+
: '';
339+
340+
const regionSelect = ui.autocomplete
341+
.findByLabel('Region')
342+
.should('be.visible')
343+
.type(selectedRegionLabel);
344+
ui.autocompletePopper
345+
.findByTitle(selectedRegionLabel, { exact: false })
346+
.should('be.visible')
347+
.click();
348+
regionSelect.click();
349+
350+
ui.autocomplete.findByLabel('Endpoint').should('be.visible').click();
351+
352+
ui.autocompletePopper
353+
.findByTitle(new RegExp('^.*-.*-.*\..*.'))
354+
.should('have.length', 1);
355+
});
356+
});
357+
});
200358
});

packages/manager/cypress/support/intercepts/object-storage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ export const interceptDeleteBucket = (
197197
apiMatcher(`object-storage/buckets/${cluster}/*`)
198198
);
199199
}
200-
return cy.intercept('DELETE', apiMatcher('object-storage/buckets/*'));
200+
return cy.intercept('DELETE', apiMatcher('object-storage/buckets/**/*'));
201201
};
202202

203203
/**

packages/manager/cypress/support/intercepts/regions.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ import { makeResponse } from 'support/util/response';
1414
import type { Region, RegionAvailability } from '@linode/api-v4';
1515
import type { ExtendedRegion } from 'support/util/regions';
1616

17+
/**
18+
* Intercepts GET regions request.
19+
*
20+
* @returns Cypress chainable.
21+
*/
22+
export const interceptGetRegions = (): Cypress.Chainable<null> => {
23+
return cy.intercept('GET', apiMatcher('regions*'));
24+
};
25+
1726
/**
1827
* Intercepts GET request to fetch Linode regions and mocks response.
1928
*

0 commit comments

Comments
 (0)