Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/

import { createBucket } from '@linode/api-v4/lib/object-storage';
import { getNewRegionLabel } from '@linode/utilities';
import { authenticate } from 'support/api/authentication';
import {
interceptGetNetworkUtilization,
Expand All @@ -16,6 +17,7 @@
interceptGetBuckets,
interceptUpdateBucketAccess,
} from 'support/intercepts/object-storage';
import { interceptGetRegions } from 'support/intercepts/regions';
import { ui } from 'support/ui';
import { cleanUp } from 'support/util/cleanup';
import { chooseCluster } from 'support/util/clusters';
Expand All @@ -27,6 +29,8 @@
createObjectStorageBucketFactoryLegacy,
} from 'src/factories';

import type { Region } from '@linode/api-v4/lib/object-storage';

/**
* Create a bucket with the given label and cluster.
*
Expand All @@ -41,23 +45,29 @@
*/
const setUpBucket = (
label: string,
cluster: string,
region: string,
cors_enabled: boolean = true
) => {
return createBucket(
createObjectStorageBucketFactoryLegacy.build({
cluster,
region,
cors_enabled,
label,

// API accepts either `cluster` or `region`, but not both. Our factory
// populates both fields, so we have to manually set `region` to `undefined`
// populates both fields, so we have to manually set `cluster` to `undefined`
// to avoid 400 responses from the API.
region: undefined,
cluster: undefined,
})
);
};

const setupBuckets = (bucketsDetails: { label: string; region: string }[]) => {
return Promise.all(
bucketsDetails.map(({ label, region }) => setUpBucket(label, region))
);
};

authenticate();
beforeEach(() => {
cy.tag('method:e2e');
Expand Down Expand Up @@ -158,17 +168,15 @@
it('can update bucket access', () => {
const bucketLabel = randomLabel();
const bucketClusterObj = chooseCluster();
const bucketCluster = bucketClusterObj.id;
const bucketAccessPage = `/object-storage/buckets/${bucketCluster}/${bucketLabel}/access`;
const bucketRegion = bucketClusterObj.region;
const bucketAccessPage = `/object-storage/buckets/${bucketRegion}/${bucketLabel}/access`;

cy.defer(
() => setUpBucket(bucketLabel, bucketCluster),
() => setUpBucket(bucketLabel, bucketRegion),
'creating Object Storage bucket'
).then(() => {
interceptGetBucketAccess(bucketLabel, bucketCluster).as(
'getBucketAccess'
);
interceptUpdateBucketAccess(bucketLabel, bucketCluster).as(
interceptGetBucketAccess(bucketLabel, bucketRegion).as('getBucketAccess');
interceptUpdateBucketAccess(bucketLabel, bucketRegion).as(
'updateBucketAccess'
);

Expand Down Expand Up @@ -198,4 +206,155 @@
cy.findByText('Bucket access updated successfully.');
});
});

/*
* - Confirms that user can filter bucket list by region.
*/
it('can filter the list of buckets by region', () => {
interceptGetBuckets().as('getBuckets');
interceptGetRegions().as('getRegions');

const bucketsDetails = new Array(2).fill({}).map((_, index) => ({
label: randomLabel(),
region: index === 0 ? 'us-ord' : 'us-lax',
}));

cy.defer(
() => setupBuckets(bucketsDetails),
'creating Object Storage bucket'
).then(() => {
cy.visitWithLogin('/object-storage/buckets');
cy.wait(['@getBuckets', '@getRegions']).then(([_, { response }]) => {

Check warning on line 227 in packages/manager/cypress/e2e/core/objectStorage/object-storage.e2e.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 3 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 3 times.","line":227,"column":31,"nodeType":"Literal","endLine":227,"endColumn":44}
const regions: Region[] = response?.body.data;

const selectedBucket = bucketsDetails[0];
const selectedRegion = regions.find(
(region) => region.id === selectedBucket.region

Check warning on line 232 in packages/manager/cypress/e2e/core/objectStorage/object-storage.e2e.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Refactor this code to not nest functions more than 4 levels deep. Raw Output: {"ruleId":"sonarjs/no-nested-functions","severity":1,"message":"Refactor this code to not nest functions more than 4 levels deep.","line":232,"column":20,"nodeType":null,"endLine":232,"endColumn":22}
);

expect(
selectedRegion,
`expected region matching ${selectedBucket.region}`
).to.exist;

const selectedRegionLabel = selectedRegion
? getNewRegionLabel(selectedRegion)
: '';

const regionSelect = ui.autocomplete
.findByLabel('Region')
.should('be.visible')
.type(selectedRegionLabel);

ui.autocompletePopper
.findByTitle(selectedRegionLabel, { exact: false })
.should('be.visible')
.click();

regionSelect.click();

cy.get('tbody').within(() => {

Check warning on line 256 in packages/manager/cypress/e2e/core/objectStorage/object-storage.e2e.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Refactor this code to not nest functions more than 4 levels deep. Raw Output: {"ruleId":"sonarjs/no-nested-functions","severity":1,"message":"Refactor this code to not nest functions more than 4 levels deep.","line":256,"column":35,"nodeType":null,"endLine":256,"endColumn":37}
cy.get('tr')
.should('have.length', 1)

Check warning on line 258 in packages/manager/cypress/e2e/core/objectStorage/object-storage.e2e.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 3 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 3 times.","line":258,"column":21,"nodeType":"Literal","endLine":258,"endColumn":34}
.within(() => {
cy.findByText(selectedBucket.label).should('be.visible');
});
});
});
});
});

/*
* - Confirms that user can filter bucket list by endpoint.
*/
it('can filter the list of buckets by endpoint', () => {
interceptGetBuckets().as('getBuckets');
interceptGetRegions().as('getRegions');

const bucketsDetails = new Array(2).fill({}).map((_, index) => ({
label: randomLabel(),
region: index === 0 ? 'us-ord' : 'us-lax',
}));

cy.defer(
() => setupBuckets(bucketsDetails),
'creating Object Storage bucket'
).then(() => {
cy.visitWithLogin('/object-storage/buckets');
cy.wait(['@getBuckets', '@getRegions']);

const selectedBucket = bucketsDetails[0];
const selectedBucketRegion = selectedBucket.region;

const endpointSelect = ui.autocomplete.findByLabel('Endpoint');
endpointSelect.should('be.visible').type(selectedBucketRegion);
ui.autocompletePopper
.findByTitle(selectedBucketRegion, { exact: false })
.should('be.visible')
.click();
endpointSelect.click();

cy.get('tbody').within(() => {
cy.get('tr')
.should('have.length', 1)
.within(() => {

Check warning on line 300 in packages/manager/cypress/e2e/core/objectStorage/object-storage.e2e.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Refactor this code to not nest functions more than 4 levels deep. Raw Output: {"ruleId":"sonarjs/no-nested-functions","severity":1,"message":"Refactor this code to not nest functions more than 4 levels deep.","line":300,"column":22,"nodeType":null,"endLine":300,"endColumn":24}
cy.findByText(selectedBucket.label).should('be.visible');
});
});
});
});

/*
* - Confirms that when region is selected, endpoint multiselect.
* shows only endpoints related to the selected region.
*/
it('should filter list of endpoints when region is selected', () => {
interceptGetBuckets().as('getBuckets');
interceptGetRegions().as('getRegions');

const bucketsDetails = new Array(2).fill({}).map((_, index) => ({
label: randomLabel(),
region: index === 0 ? 'us-ord' : 'us-lax',
}));

cy.defer(
() => setupBuckets(bucketsDetails),
'creating Object Storage bucket'
).then(() => {
cy.visitWithLogin('/object-storage/buckets');
cy.wait(['@getBuckets', '@getRegions']).then(([_, { response }]) => {
const regions: Region[] = response?.body.data;

const selectedBucket = bucketsDetails[0];
const selectedRegion = regions.find(
(region) => region.id === selectedBucket.region

Check warning on line 330 in packages/manager/cypress/e2e/core/objectStorage/object-storage.e2e.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Refactor this code to not nest functions more than 4 levels deep. Raw Output: {"ruleId":"sonarjs/no-nested-functions","severity":1,"message":"Refactor this code to not nest functions more than 4 levels deep.","line":330,"column":20,"nodeType":null,"endLine":330,"endColumn":22}
);

expect(
selectedRegion,
`expected region matching ${selectedBucket.region}`
).to.exist;

const selectedRegionLabel = selectedRegion
? getNewRegionLabel(selectedRegion)
: '';

const regionSelect = ui.autocomplete
.findByLabel('Region')
.should('be.visible')
.type(selectedRegionLabel);
ui.autocompletePopper
.findByTitle(selectedRegionLabel, { exact: false })
.should('be.visible')
.click();
regionSelect.click();

ui.autocomplete.findByLabel('Endpoint').should('be.visible').click();

ui.autocompletePopper
.findByTitle(new RegExp('^.*-.*-.*\..*.'))

Check warning on line 355 in packages/manager/cypress/e2e/core/objectStorage/object-storage.e2e.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Unnecessary escape character: \.. Raw Output: {"ruleId":"no-useless-escape","severity":1,"message":"Unnecessary escape character: \..","line":355,"column":45,"nodeType":"Literal","messageId":"unnecessaryEscape","endLine":355,"endColumn":46,"suggestions":[{"messageId":"removeEscape","fix":{"range":[11467,11468],"text":""},"desc":"Remove the `\`. This maintains the current functionality."},{"messageId":"escapeBackslash","fix":{"range":[11467,11467],"text":"\"},"desc":"Replace the `\` with `\\` to include the actual backslash character."}]}
.should('have.length', 1);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ export const interceptDeleteBucket = (
apiMatcher(`object-storage/buckets/${cluster}/*`)
);
}
return cy.intercept('DELETE', apiMatcher('object-storage/buckets/*'));
return cy.intercept('DELETE', apiMatcher('object-storage/buckets/**/*'));
};

/**
Expand Down
9 changes: 9 additions & 0 deletions packages/manager/cypress/support/intercepts/regions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ import { makeResponse } from 'support/util/response';
import type { Region, RegionAvailability } from '@linode/api-v4';
import type { ExtendedRegion } from 'support/util/regions';

/**
* Intercepts GET regions request.
*
* @returns Cypress chainable.
*/
export const interceptGetRegions = (): Cypress.Chainable<null> => {
return cy.intercept('GET', apiMatcher('regions*'));
};

/**
* Intercepts GET request to fetch Linode regions and mocks response.
*
Expand Down
Loading
Loading