From 1c6241d6a099c9065f3339b107a224b4dd26e2a9 Mon Sep 17 00:00:00 2001 From: Connie Liu <139280159+coliu-akamai@users.noreply.github.com> Date: Thu, 3 Oct 2024 09:52:33 -0400 Subject: [PATCH] test: [M3-8440] - Cypress tests for OBJ Gen 2 bucket access tab changes (#10994) * skeleton tests * test for E0 endpoint * finish other tests, now time to cleanup * remove duplication * update description * Added changeset: Add cypress integration test for OBJ gen 2 bucket details tab changes * update test descriptions * cleanup: use contains instead of find by text * parameterize tests based on feedback @jdamore-linode * confirm testing AC and update tests/fix bug --- .../pr-10994-tests-1727202548403.md | 5 + .../bucket-details-gen2.spec.ts | 142 ++++++++++++++++++ .../support/intercepts/object-storage.ts | 27 +++- .../ObjectStorage/BucketDetail/index.tsx | 4 +- 4 files changed, 172 insertions(+), 6 deletions(-) create mode 100644 packages/manager/.changeset/pr-10994-tests-1727202548403.md create mode 100644 packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts diff --git a/packages/manager/.changeset/pr-10994-tests-1727202548403.md b/packages/manager/.changeset/pr-10994-tests-1727202548403.md new file mode 100644 index 00000000000..6bd97968d48 --- /dev/null +++ b/packages/manager/.changeset/pr-10994-tests-1727202548403.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Tests +--- + +Add cypress integration test for OBJ gen 2 bucket details tab changes ([#10994](https://github.com/linode/manager/pull/10994)) diff --git a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts new file mode 100644 index 00000000000..c7302697565 --- /dev/null +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -0,0 +1,142 @@ +import { mockGetAccount } from 'support/intercepts/account'; +import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags'; +import { + mockGetBucketsForRegion, + mockGetObjectStorageEndpoints, + mockGetBucketAccess, +} from 'support/intercepts/object-storage'; +import { + accountFactory, + objectStorageBucketFactoryGen2, + objectStorageEndpointsFactory, + regionFactory, +} from 'src/factories'; +import { ACLType, ObjectStorageEndpointTypes } from '@linode/api-v4'; + +describe('Object Storage Gen 2 bucket details Access and SSL/TLS tabs', () => { + beforeEach(() => { + mockAppendFeatureFlags({ + objMultiCluster: true, + objectStorageGen2: { enabled: true }, + }).as('getFeatureFlags'); + mockGetAccount( + accountFactory.build({ + capabilities: [ + 'Object Storage', + 'Object Storage Endpoint Types', + 'Object Storage Access Key Regions', + ], + }) + ).as('getAccount'); + }); + + const mockRegion = regionFactory.build({ + capabilities: ['Object Storage'], + }); + + const mockAccess = { + acl: 'private' as ACLType, + acl_xml: '', + cors_enabled: true, + cors_xml: '', + }; + + const createMocksBasedOnEndpointType = ( + endpointType: ObjectStorageEndpointTypes + ) => { + const mockBucket = objectStorageBucketFactoryGen2.build({ + endpoint_type: endpointType, + region: mockRegion.id, + }); + const mockEndpoint = objectStorageEndpointsFactory.build({ + endpoint_type: endpointType, + region: mockRegion.id, + }); + + return { mockBucket, mockEndpoint }; + }; + + ['E0', 'E1'].forEach((endpoint: ObjectStorageEndpointTypes) => { + /** + * Parameterized test for object storage endpoint types E0 and E1 + * - Confirms the CORS toggle still appears + * - Confirms the SSL/TLS tab appears + */ + it(`does not hide the CORS toggle and SSL/TLS tab for buckets with an ${endpoint} endpoint`, () => { + const { mockBucket, mockEndpoint } = createMocksBasedOnEndpointType( + endpoint + ); + const { cluster, label } = mockBucket; + + mockGetBucketAccess(label, cluster, mockAccess).as('getBucketAccess'); + mockGetBucketsForRegion(mockRegion.id, [mockBucket]).as( + 'getBucketsForRegion' + ); + mockGetObjectStorageEndpoints([mockEndpoint]).as( + 'getObjectStorageEndpoints' + ); + + cy.visitWithLogin(`/object-storage/buckets/${cluster}/${label}/access`); + cy.wait([ + '@getFeatureFlags', + '@getAccount', + '@getObjectStorageEndpoints', + '@getBucketsForRegion', + '@getBucketAccess', + ]); + + cy.findByText('Bucket Access').should('be.visible'); + cy.findByLabelText('Access Control List (ACL)').should('be.visible'); + // confirm CORS is visible + cy.findByText('CORS Enabled').should('be.visible'); + cy.contains( + 'Whether Cross-Origin Resource Sharing is enabled for all origins. For more fine-grained control of CORS, please use another S3-compatible tool.' + ).should('be.visible'); + + // Confirm SSL/TLS tab is not hidden and is clickable + cy.findByText('SSL/TLS').should('be.visible').click(); + cy.url().should('endWith', '/ssl'); + }); + }); + + ['E2', 'E3'].forEach((endpoint: ObjectStorageEndpointTypes) => { + /** + * Parameterized test for object storage endpoint types E2 and E3 + * - Confirms the CORS toggle is hidden + * - Confirms the SSL/TLS tab is hidden + */ + it(`hides the CORS toggle and SSL/TLS tab for for buckets with an ${endpoint} endpoint`, () => { + const { mockBucket, mockEndpoint } = createMocksBasedOnEndpointType( + endpoint + ); + const { cluster, label } = mockBucket; + + mockGetBucketAccess(label, cluster, mockAccess).as('getBucketAccess'); + mockGetBucketsForRegion(mockRegion.id, [mockBucket]).as( + 'getBucketsForRegion' + ); + mockGetObjectStorageEndpoints([mockEndpoint]).as( + 'getObjectStorageEndpoints' + ); + + cy.visitWithLogin(`/object-storage/buckets/${cluster}/${label}/access`); + cy.wait([ + '@getFeatureFlags', + '@getAccount', + '@getObjectStorageEndpoints', + '@getBucketsForRegion', + '@getBucketAccess', + ]); + + cy.findByText('Bucket Access').should('be.visible'); + cy.findByLabelText('Access Control List (ACL)').should('be.visible'); + // confirm CORS is not visible + cy.contains( + 'CORS (Cross Origin Sharing) is not available for endpoint types E2 and E3' + ).should('be.visible'); + + // confirms the SSL/TLS tab is not present + cy.findByText('SSL/TLS').should('not.exist'); + }); + }); +}); diff --git a/packages/manager/cypress/support/intercepts/object-storage.ts b/packages/manager/cypress/support/intercepts/object-storage.ts index 0515ca8266b..34cc91f800d 100644 --- a/packages/manager/cypress/support/intercepts/object-storage.ts +++ b/packages/manager/cypress/support/intercepts/object-storage.ts @@ -13,6 +13,7 @@ import { objectStorageBucketFactoryGen2 } from 'src/factories'; import type { CreateObjectStorageBucketPayload, ObjectStorageBucket, + ObjectStorageBucketAccess, ObjectStorageCluster, ObjectStorageEndpoint, ObjectStorageKey, @@ -452,11 +453,8 @@ export const mockGetClusters = ( /** * Intercepts GET request to fetch access information (ACL, CORS) for a given Bucket. * - * * @param label - Object storage bucket label. * @param cluster - Object storage bucket cluster. - * @param data - response data. - * @param statusCode - response status code. * * @returns Cypress chainable. */ @@ -489,7 +487,7 @@ export const interceptUpdateBucketAccess = ( }; /** - * Intercepts GET request to get object storage endpoints. + * Intercepts GET request to get object storage endpoints and mocks response. * * @param endpoints - Object Storage endpoints for which to mock response * @@ -504,3 +502,24 @@ export const mockGetObjectStorageEndpoints = ( paginateResponse(endpoints) ); }; + +/** + * Intercepts GET request to fetch access information (ACL, CORS) for a given Bucket, and mocks response. + * + * @param label - Object storage bucket label. + * @param cluster - Object storage bucket cluster. + * @param bucketAccess - Access details for which to mock the response + * + * @returns Cypress chainable. + */ +export const mockGetBucketAccess = ( + label: string, + cluster: string, + bucketAccess: ObjectStorageBucketAccess +): Cypress.Chainable => { + return cy.intercept( + 'GET', + apiMatcher(`object-storage/buckets/${cluster}/${label}/access`), + makeResponse(bucketAccess) + ); +}; diff --git a/packages/manager/src/features/ObjectStorage/BucketDetail/index.tsx b/packages/manager/src/features/ObjectStorage/BucketDetail/index.tsx index d3db2065c70..a3224c79c9b 100644 --- a/packages/manager/src/features/ObjectStorage/BucketDetail/index.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketDetail/index.tsx @@ -63,7 +63,7 @@ export const BucketDetailLanding = React.memo((props: Props) => { const { endpoint_type } = bucket ?? {}; - const isSSLEnabled = endpoint_type !== 'E2' && endpoint_type === 'E3'; + const isSSLEnabled = endpoint_type !== 'E2' && endpoint_type !== 'E3'; const tabs = [ { @@ -82,7 +82,7 @@ export const BucketDetailLanding = React.memo((props: Props) => { }, ] : []), - ...(!isSSLEnabled + ...(isSSLEnabled ? [ { routeName: `${props.match.url}/ssl`,