33 */
44
55import { createBucket } from '@linode/api-v4/lib/object-storage' ;
6+ import { getNewRegionLabel } from '@linode/utilities' ;
67import { authenticate } from 'support/api/authentication' ;
78import {
89 interceptGetNetworkUtilization ,
@@ -16,6 +17,7 @@ import {
1617 interceptGetBuckets ,
1718 interceptUpdateBucketAccess ,
1819} from 'support/intercepts/object-storage' ;
20+ import { interceptGetRegions } from 'support/intercepts/regions' ;
1921import { ui } from 'support/ui' ;
2022import { cleanUp } from 'support/util/cleanup' ;
2123import { 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 */
4246const 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+
6171authenticate ( ) ;
6272beforeEach ( ( ) => {
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} ) ;
0 commit comments