From 65b6273a11b5e6d2c37c4e6f416afa3fb211de2e Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Mon, 23 Sep 2024 15:57:44 -0400 Subject: [PATCH 01/20] skeleton tests --- .../bucket-details-gen2.spec.ts | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts 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..3e053548aa5 --- /dev/null +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -0,0 +1,53 @@ +import { mockGetAccount } from 'support/intercepts/account'; +import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags'; +import { accountFactory } from 'src/factories'; + +describe('Object Storage Gen 2 bucket details tab tests', () => { + 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'); + }); + + /** + * - Confirms the CORS toggle still appears for buckets with endpoint type E0 + * - Confirms the SSL/TLS tab appears for buckets with endpoint type E0 + */ + it('does not hide the CORS toggle or SSL/TLS tab for buckets with the E0 endpoint', () => { + + }); + + /** + * - Confirms the CORS toggle still appears for buckets with endpoint type E1 + * - Confirms the SSL/TLS tab appears for buckets with endpoint type E1 + */ + it('does not hide the CORS toggle or SSL/TLS tab for buckets with the E1 endpoint', () => { + + }); + + /** + * - Confirms the CORS and display notice is hidden for buckets with endpoint type E2 + * - Confirms the SSL/TLS tab is hidden for buckets with endpoint type E2 + */ + it('hides the CORS and display notice and disables the SSL/TLS tab for the E2 endpoint', () => { + + }); + + /** + * - Confirms the CORS and display notice is hidden for buckets with endpoint type E3 + * - Confirms the SSL/TLS tab is hidden for buckets with endpoint type E3 + */ + it('hides the CORS and display notice and disables the SSL/TLS tab for the E3 endpoint', () => { + + }); +}); \ No newline at end of file From 3ca3c1a052cce547c9fe30874553ebe69684fddf Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Mon, 23 Sep 2024 17:35:21 -0400 Subject: [PATCH 02/20] test for E0 endpoint --- .../bucket-details-gen2.spec.ts | 82 +++++++++++++++---- .../support/intercepts/object-storage.ts | 27 +++++- 2 files changed, 91 insertions(+), 18 deletions(-) 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 index 3e053548aa5..d6f6594ec08 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -1,8 +1,19 @@ import { mockGetAccount } from 'support/intercepts/account'; import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags'; -import { accountFactory } from 'src/factories'; +import { + mockGetBucketsForRegion, + mockGetObjectStorageEndpoints, + mockGetBucketAccess, +} from 'support/intercepts/object-storage'; +import { + accountFactory, + objectStorageBucketFactoryGen2, + objectStorageEndpointsFactory, + regionFactory, +} from 'src/factories'; +import { ACLType } from '@linode/api-v4'; -describe('Object Storage Gen 2 bucket details tab tests', () => { +describe('Object Storage Gen 2 bucket details tab tests', () => { beforeEach(() => { mockAppendFeatureFlags({ objMultiCluster: true, @@ -19,35 +30,78 @@ describe('Object Storage Gen 2 bucket details tab tests', () => { ).as('getAccount'); }); + const mockRegion = regionFactory.build({ + capabilities: ['Object Storage'], + }); + + // TODO - figure out how to simulate it.each with mocha /** * - Confirms the CORS toggle still appears for buckets with endpoint type E0 * - Confirms the SSL/TLS tab appears for buckets with endpoint type E0 */ - it('does not hide the CORS toggle or SSL/TLS tab for buckets with the E0 endpoint', () => { + it.only('does not hide the CORS toggle or SSL/TLS tab for buckets with the E0 endpoint', () => { + const mockBucket = objectStorageBucketFactoryGen2.build({ + endpoint_type: 'E0', + region: mockRegion.id, + }); + const { cluster, label } = mockBucket; + const mockEndpoint = objectStorageEndpointsFactory.build({ + endpoint_type: 'E0', + region: mockRegion.id, + }); + const mockAccess = { + acl: 'private' as ACLType, + acl_xml: '', + cors_enabled: true, + cors_xml: '', + }; + + 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.findByText( + /Whether Cross-Origin Resource Sharing is enabled for all origins. For more fine-grained control of CORS, please use another/ + ).should('be.visible'); + cy.findByText(/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'); }); - + /** * - Confirms the CORS toggle still appears for buckets with endpoint type E1 * - Confirms the SSL/TLS tab appears for buckets with endpoint type E1 */ - it('does not hide the CORS toggle or SSL/TLS tab for buckets with the E1 endpoint', () => { - - }); + it('does not hide the CORS toggle or SSL/TLS tab for buckets with the E1 endpoint', () => {}); /** * - Confirms the CORS and display notice is hidden for buckets with endpoint type E2 * - Confirms the SSL/TLS tab is hidden for buckets with endpoint type E2 */ - it('hides the CORS and display notice and disables the SSL/TLS tab for the E2 endpoint', () => { - - }); + it('hides the CORS and display notice and disables the SSL/TLS tab for the E2 endpoint', () => {}); /** * - Confirms the CORS and display notice is hidden for buckets with endpoint type E3 * - Confirms the SSL/TLS tab is hidden for buckets with endpoint type E3 */ - it('hides the CORS and display notice and disables the SSL/TLS tab for the E3 endpoint', () => { - - }); -}); \ No newline at end of file + it('hides the CORS and display notice and disables the SSL/TLS tab for the E3 endpoint', () => {}); +}); 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) + ); +}; From 7b930b0e7e1dac287aa9bf8e8240c49ab6833b69 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 24 Sep 2024 10:55:43 -0400 Subject: [PATCH 03/20] finish other tests, now time to cleanup --- .../bucket-details-gen2.spec.ts | 138 ++++++++++++++++-- 1 file changed, 127 insertions(+), 11 deletions(-) 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 index d6f6594ec08..de3436d8b12 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -34,12 +34,19 @@ describe('Object Storage Gen 2 bucket details tab tests', () => { capabilities: ['Object Storage'], }); + const mockAccess = { + acl: 'private' as ACLType, + acl_xml: '', + cors_enabled: true, + cors_xml: '', + }; + // TODO - figure out how to simulate it.each with mocha /** * - Confirms the CORS toggle still appears for buckets with endpoint type E0 * - Confirms the SSL/TLS tab appears for buckets with endpoint type E0 */ - it.only('does not hide the CORS toggle or SSL/TLS tab for buckets with the E0 endpoint', () => { + it('does not hide the CORS toggle or SSL/TLS tab for buckets with the E0 endpoint', () => { const mockBucket = objectStorageBucketFactoryGen2.build({ endpoint_type: 'E0', region: mockRegion.id, @@ -49,12 +56,6 @@ describe('Object Storage Gen 2 bucket details tab tests', () => { endpoint_type: 'E0', region: mockRegion.id, }); - const mockAccess = { - acl: 'private' as ACLType, - acl_xml: '', - cors_enabled: true, - cors_xml: '', - }; mockGetBucketAccess(label, cluster, mockAccess).as('getBucketAccess'); mockGetBucketsForRegion(mockRegion.id, [mockBucket]).as( @@ -91,17 +92,132 @@ describe('Object Storage Gen 2 bucket details tab tests', () => { * - Confirms the CORS toggle still appears for buckets with endpoint type E1 * - Confirms the SSL/TLS tab appears for buckets with endpoint type E1 */ - it('does not hide the CORS toggle or SSL/TLS tab for buckets with the E1 endpoint', () => {}); + it('does not hide the CORS toggle or SSL/TLS tab for buckets with the E1 endpoint', () => { + const mockBucket = objectStorageBucketFactoryGen2.build({ + endpoint_type: 'E1', + region: mockRegion.id, + }); + const { cluster, label } = mockBucket; + const mockEndpoint = objectStorageEndpointsFactory.build({ + endpoint_type: 'E1', + region: mockRegion.id, + }); + + 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.findByText( + /Whether Cross-Origin Resource Sharing is enabled for all origins. For more fine-grained control of CORS, please use another/ + ).should('be.visible'); + cy.findByText(/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'); + }); /** * - Confirms the CORS and display notice is hidden for buckets with endpoint type E2 - * - Confirms the SSL/TLS tab is hidden for buckets with endpoint type E2 + * - Confirms the SSL/TLS tab is visible for buckets with endpoint type E2 */ - it('hides the CORS and display notice and disables the SSL/TLS tab for the E2 endpoint', () => {}); + it('hides the CORS and display notice and hides the SSL/TLS tab for the E2 endpoint', () => { + const mockBucket = objectStorageBucketFactoryGen2.build({ + endpoint_type: 'E2', + region: mockRegion.id, + }); + const { cluster, label } = mockBucket; + const mockEndpoint = objectStorageEndpointsFactory.build({ + endpoint_type: 'E2', + region: mockRegion.id, + }); + + 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.findByText( + /CORS \(Cross Origin Sharing\) is not available for endpoint types E2 and E3./ + ).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'); + }); /** * - Confirms the CORS and display notice is hidden for buckets with endpoint type E3 * - Confirms the SSL/TLS tab is hidden for buckets with endpoint type E3 */ - it('hides the CORS and display notice and disables the SSL/TLS tab for the E3 endpoint', () => {}); + it('hides the CORS and display notice and disables the SSL/TLS tab for the E3 endpoint', () => { + const mockBucket = objectStorageBucketFactoryGen2.build({ + endpoint_type: 'E3', + region: mockRegion.id, + }); + const { cluster, label } = mockBucket; + const mockEndpoint = objectStorageEndpointsFactory.build({ + endpoint_type: 'E3', + region: mockRegion.id, + }); + + 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.findByText( + /CORS \(Cross Origin Sharing\) is not available for endpoint types E2 and E3/ + ).should('be.visible'); + + // Confirm SSL/TLS tab is hidden + cy.findByText('SSL/TLS').should('not.exist'); + }); }); From c6b18c3aa101a8b36ddc12830b92041ed3c46bed Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 24 Sep 2024 14:22:41 -0400 Subject: [PATCH 04/20] remove duplication --- .../bucket-details-gen2.spec.ts | 148 +++++------------- 1 file changed, 37 insertions(+), 111 deletions(-) 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 index de3436d8b12..7929338f13e 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -11,7 +11,7 @@ import { objectStorageEndpointsFactory, regionFactory, } from 'src/factories'; -import { ACLType } from '@linode/api-v4'; +import { ACLType, ObjectStorageEndpointTypes } from '@linode/api-v4'; describe('Object Storage Gen 2 bucket details tab tests', () => { beforeEach(() => { @@ -41,19 +41,16 @@ describe('Object Storage Gen 2 bucket details tab tests', () => { cors_xml: '', }; - // TODO - figure out how to simulate it.each with mocha - /** - * - Confirms the CORS toggle still appears for buckets with endpoint type E0 - * - Confirms the SSL/TLS tab appears for buckets with endpoint type E0 - */ - it('does not hide the CORS toggle or SSL/TLS tab for buckets with the E0 endpoint', () => { + const createMocksAndNavigateToPage = ( + endpointType: ObjectStorageEndpointTypes + ) => { const mockBucket = objectStorageBucketFactoryGen2.build({ - endpoint_type: 'E0', + endpoint_type: endpointType, region: mockRegion.id, }); const { cluster, label } = mockBucket; const mockEndpoint = objectStorageEndpointsFactory.build({ - endpoint_type: 'E0', + endpoint_type: endpointType, region: mockRegion.id, }); @@ -73,7 +70,9 @@ describe('Object Storage Gen 2 bucket details tab tests', () => { '@getBucketsForRegion', '@getBucketAccess', ]); + }; + const confirmCORSToggleAndSSLTabPresent = () => { cy.findByText('Bucket Access').should('be.visible'); cy.findByLabelText('Access Control List (ACL)').should('be.visible'); // confirm CORS is visible @@ -86,6 +85,26 @@ describe('Object Storage Gen 2 bucket details tab tests', () => { // Confirm SSL/TLS tab is not hidden and is clickable cy.findByText('SSL/TLS').should('be.visible').click(); cy.url().should('endWith', '/ssl'); + }; + + const confirmCORSNotPresent = () => { + cy.findByText('Bucket Access').should('be.visible'); + cy.findByLabelText('Access Control List (ACL)').should('be.visible'); + // confirm CORS is not visible + cy.findByText( + /CORS \(Cross Origin Sharing\) is not available for endpoint types E2 and E3/ + ).should('be.visible'); + }; + + /** + * - Confirms the CORS toggle still appears for buckets with endpoint type E0 + * - Confirms the SSL/TLS tab appears for buckets with endpoint type E0 + */ + it('does not hide the CORS toggle or SSL/TLS tab for buckets with the E0 endpoint', () => { + createMocksAndNavigateToPage('E0'); + + // confirm CORS toggle is visible and the SSL/TLS tab is present + confirmCORSToggleAndSSLTabPresent(); }); /** @@ -93,45 +112,10 @@ describe('Object Storage Gen 2 bucket details tab tests', () => { * - Confirms the SSL/TLS tab appears for buckets with endpoint type E1 */ it('does not hide the CORS toggle or SSL/TLS tab for buckets with the E1 endpoint', () => { - const mockBucket = objectStorageBucketFactoryGen2.build({ - endpoint_type: 'E1', - region: mockRegion.id, - }); - const { cluster, label } = mockBucket; - const mockEndpoint = objectStorageEndpointsFactory.build({ - endpoint_type: 'E1', - region: mockRegion.id, - }); + createMocksAndNavigateToPage('E1'); - 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.findByText( - /Whether Cross-Origin Resource Sharing is enabled for all origins. For more fine-grained control of CORS, please use another/ - ).should('be.visible'); - cy.findByText(/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'); + // confirm CORS toggle is visible and the SSL/TLS tab is present + confirmCORSToggleAndSSLTabPresent(); }); /** @@ -139,39 +123,10 @@ describe('Object Storage Gen 2 bucket details tab tests', () => { * - Confirms the SSL/TLS tab is visible for buckets with endpoint type E2 */ it('hides the CORS and display notice and hides the SSL/TLS tab for the E2 endpoint', () => { - const mockBucket = objectStorageBucketFactoryGen2.build({ - endpoint_type: 'E2', - region: mockRegion.id, - }); - const { cluster, label } = mockBucket; - const mockEndpoint = objectStorageEndpointsFactory.build({ - endpoint_type: 'E2', - region: mockRegion.id, - }); + createMocksAndNavigateToPage('E2'); - 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.findByText( - /CORS \(Cross Origin Sharing\) is not available for endpoint types E2 and E3./ - ).should('be.visible'); + // confirms the CORS toggle is not visible + confirmCORSNotPresent(); // Confirm SSL/TLS tab is not hidden and is clickable cy.findByText('SSL/TLS').should('be.visible').click(); @@ -183,39 +138,10 @@ describe('Object Storage Gen 2 bucket details tab tests', () => { * - Confirms the SSL/TLS tab is hidden for buckets with endpoint type E3 */ it('hides the CORS and display notice and disables the SSL/TLS tab for the E3 endpoint', () => { - const mockBucket = objectStorageBucketFactoryGen2.build({ - endpoint_type: 'E3', - region: mockRegion.id, - }); - const { cluster, label } = mockBucket; - const mockEndpoint = objectStorageEndpointsFactory.build({ - endpoint_type: 'E3', - region: mockRegion.id, - }); + createMocksAndNavigateToPage('E3'); - 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.findByText( - /CORS \(Cross Origin Sharing\) is not available for endpoint types E2 and E3/ - ).should('be.visible'); + // confirms the CORS toggle is not visible + confirmCORSNotPresent(); // Confirm SSL/TLS tab is hidden cy.findByText('SSL/TLS').should('not.exist'); From 2df76a59ebb8ae18ee46f2a5aebc9968bd4f8230 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 24 Sep 2024 14:23:57 -0400 Subject: [PATCH 05/20] update description --- .../e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 7929338f13e..22b61d44144 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -13,7 +13,7 @@ import { } from 'src/factories'; import { ACLType, ObjectStorageEndpointTypes } from '@linode/api-v4'; -describe('Object Storage Gen 2 bucket details tab tests', () => { +describe('Object Storage Gen 2 bucket details Access and SSL/TLS tabs', () => { beforeEach(() => { mockAppendFeatureFlags({ objMultiCluster: true, From 278c6570099b60d93a0c3b9f19f9b00e5dea6fa2 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 24 Sep 2024 14:29:08 -0400 Subject: [PATCH 06/20] Added changeset: Add cypress integration test for OBJ gen 2 bucket details tab changes --- packages/manager/.changeset/pr-10994-tests-1727202548403.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/manager/.changeset/pr-10994-tests-1727202548403.md 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)) From 21915becf68f42e958ffa02437d444536065c549 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 24 Sep 2024 14:31:17 -0400 Subject: [PATCH 07/20] update test descriptions --- .../core/objectStorageGen2/bucket-details-gen2.spec.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 index 22b61d44144..7cfeaeb77d3 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -100,7 +100,7 @@ describe('Object Storage Gen 2 bucket details Access and SSL/TLS tabs', () => { * - Confirms the CORS toggle still appears for buckets with endpoint type E0 * - Confirms the SSL/TLS tab appears for buckets with endpoint type E0 */ - it('does not hide the CORS toggle or SSL/TLS tab for buckets with the E0 endpoint', () => { + it('does not hide the CORS toggle or SSL/TLS tab for buckets with an E0 endpoint', () => { createMocksAndNavigateToPage('E0'); // confirm CORS toggle is visible and the SSL/TLS tab is present @@ -111,7 +111,7 @@ describe('Object Storage Gen 2 bucket details Access and SSL/TLS tabs', () => { * - Confirms the CORS toggle still appears for buckets with endpoint type E1 * - Confirms the SSL/TLS tab appears for buckets with endpoint type E1 */ - it('does not hide the CORS toggle or SSL/TLS tab for buckets with the E1 endpoint', () => { + it('does not hide the CORS toggle or SSL/TLS tab for buckets with an E1 endpoint', () => { createMocksAndNavigateToPage('E1'); // confirm CORS toggle is visible and the SSL/TLS tab is present @@ -120,9 +120,9 @@ describe('Object Storage Gen 2 bucket details Access and SSL/TLS tabs', () => { /** * - Confirms the CORS and display notice is hidden for buckets with endpoint type E2 - * - Confirms the SSL/TLS tab is visible for buckets with endpoint type E2 + * - Confirms the SSL/TLS tab appears for buckets with endpoint type E2 */ - it('hides the CORS and display notice and hides the SSL/TLS tab for the E2 endpoint', () => { + it('hides the CORS toggle and displays a notice for buckets with an E2 endpoint', () => { createMocksAndNavigateToPage('E2'); // confirms the CORS toggle is not visible @@ -137,7 +137,7 @@ describe('Object Storage Gen 2 bucket details Access and SSL/TLS tabs', () => { * - Confirms the CORS and display notice is hidden for buckets with endpoint type E3 * - Confirms the SSL/TLS tab is hidden for buckets with endpoint type E3 */ - it('hides the CORS and display notice and disables the SSL/TLS tab for the E3 endpoint', () => { + it('hides the CORS toggle, displays a notice, and disables the SSL/TLS tab for buckets with an E3 endpoint', () => { createMocksAndNavigateToPage('E3'); // confirms the CORS toggle is not visible From 7dc731cd039cebbc897918837a533e93b64c92ab Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 24 Sep 2024 15:29:31 -0400 Subject: [PATCH 08/20] rearranging some things --- .../bucket-details-gen2.spec.ts | 208 +++++++++--------- 1 file changed, 105 insertions(+), 103 deletions(-) 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 index 7cfeaeb77d3..3e794439c33 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -13,7 +13,7 @@ import { } from 'src/factories'; import { ACLType, ObjectStorageEndpointTypes } from '@linode/api-v4'; -describe('Object Storage Gen 2 bucket details Access and SSL/TLS tabs', () => { +describe('Object Storage Gen 2 bucket details tabs', () => { beforeEach(() => { mockAppendFeatureFlags({ objMultiCluster: true, @@ -34,116 +34,118 @@ describe('Object Storage Gen 2 bucket details Access and SSL/TLS tabs', () => { capabilities: ['Object Storage'], }); - const mockAccess = { - acl: 'private' as ACLType, - acl_xml: '', - cors_enabled: true, - cors_xml: '', - }; - - const createMocksAndNavigateToPage = ( - endpointType: ObjectStorageEndpointTypes - ) => { - const mockBucket = objectStorageBucketFactoryGen2.build({ - endpoint_type: endpointType, - region: mockRegion.id, + describe('Access and SSL/TLS tabs', () => { + const mockAccess = { + acl: 'private' as ACLType, + acl_xml: '', + cors_enabled: true, + cors_xml: '', + }; + + const createMocksAndNavigateToPage = ( + endpointType: ObjectStorageEndpointTypes + ) => { + const mockBucket = objectStorageBucketFactoryGen2.build({ + endpoint_type: endpointType, + region: mockRegion.id, + }); + const { cluster, label } = mockBucket; + const mockEndpoint = objectStorageEndpointsFactory.build({ + endpoint_type: endpointType, + region: mockRegion.id, + }); + + 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', + ]); + }; + + const confirmCORSToggleAndSSLTabPresent = () => { + 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.findByText( + /Whether Cross-Origin Resource Sharing is enabled for all origins. For more fine-grained control of CORS, please use another/ + ).should('be.visible'); + cy.findByText(/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'); + }; + + const confirmCORSNotPresent = () => { + cy.findByText('Bucket Access').should('be.visible'); + cy.findByLabelText('Access Control List (ACL)').should('be.visible'); + // confirm CORS is not visible + cy.findByText( + /CORS \(Cross Origin Sharing\) is not available for endpoint types E2 and E3/ + ).should('be.visible'); + }; + + /** + * - Confirms the CORS toggle still appears for buckets with endpoint type E0 + * - Confirms the SSL/TLS tab appears for buckets with endpoint type E0 + */ + it('does not hide the CORS toggle or SSL/TLS tab for buckets with an E0 endpoint', () => { + createMocksAndNavigateToPage('E0'); + + // confirm CORS toggle is visible and the SSL/TLS tab is present + confirmCORSToggleAndSSLTabPresent(); }); - const { cluster, label } = mockBucket; - const mockEndpoint = objectStorageEndpointsFactory.build({ - endpoint_type: endpointType, - region: mockRegion.id, - }); - - 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', - ]); - }; - - const confirmCORSToggleAndSSLTabPresent = () => { - 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.findByText( - /Whether Cross-Origin Resource Sharing is enabled for all origins. For more fine-grained control of CORS, please use another/ - ).should('be.visible'); - cy.findByText(/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'); - }; - - const confirmCORSNotPresent = () => { - cy.findByText('Bucket Access').should('be.visible'); - cy.findByLabelText('Access Control List (ACL)').should('be.visible'); - // confirm CORS is not visible - cy.findByText( - /CORS \(Cross Origin Sharing\) is not available for endpoint types E2 and E3/ - ).should('be.visible'); - }; - - /** - * - Confirms the CORS toggle still appears for buckets with endpoint type E0 - * - Confirms the SSL/TLS tab appears for buckets with endpoint type E0 - */ - it('does not hide the CORS toggle or SSL/TLS tab for buckets with an E0 endpoint', () => { - createMocksAndNavigateToPage('E0'); - - // confirm CORS toggle is visible and the SSL/TLS tab is present - confirmCORSToggleAndSSLTabPresent(); - }); - /** - * - Confirms the CORS toggle still appears for buckets with endpoint type E1 - * - Confirms the SSL/TLS tab appears for buckets with endpoint type E1 - */ - it('does not hide the CORS toggle or SSL/TLS tab for buckets with an E1 endpoint', () => { - createMocksAndNavigateToPage('E1'); + /** + * - Confirms the CORS toggle still appears for buckets with endpoint type E1 + * - Confirms the SSL/TLS tab appears for buckets with endpoint type E1 + */ + it('does not hide the CORS toggle or SSL/TLS tab for buckets with an E1 endpoint', () => { + createMocksAndNavigateToPage('E1'); - // confirm CORS toggle is visible and the SSL/TLS tab is present - confirmCORSToggleAndSSLTabPresent(); - }); + // confirm CORS toggle is visible and the SSL/TLS tab is present + confirmCORSToggleAndSSLTabPresent(); + }); - /** - * - Confirms the CORS and display notice is hidden for buckets with endpoint type E2 - * - Confirms the SSL/TLS tab appears for buckets with endpoint type E2 - */ - it('hides the CORS toggle and displays a notice for buckets with an E2 endpoint', () => { - createMocksAndNavigateToPage('E2'); + /** + * - Confirms the CORS and display notice is hidden for buckets with endpoint type E2 + * - Confirms the SSL/TLS tab appears for buckets with endpoint type E2 + */ + it('hides the CORS toggle and displays a notice for buckets with an E2 endpoint', () => { + createMocksAndNavigateToPage('E2'); - // confirms the CORS toggle is not visible - confirmCORSNotPresent(); + // confirms the CORS toggle is not visible + confirmCORSNotPresent(); - // Confirm SSL/TLS tab is not hidden and is clickable - cy.findByText('SSL/TLS').should('be.visible').click(); - cy.url().should('endWith', '/ssl'); - }); + // Confirm SSL/TLS tab is not hidden and is clickable + cy.findByText('SSL/TLS').should('be.visible').click(); + cy.url().should('endWith', '/ssl'); + }); - /** - * - Confirms the CORS and display notice is hidden for buckets with endpoint type E3 - * - Confirms the SSL/TLS tab is hidden for buckets with endpoint type E3 - */ - it('hides the CORS toggle, displays a notice, and disables the SSL/TLS tab for buckets with an E3 endpoint', () => { - createMocksAndNavigateToPage('E3'); + /** + * - Confirms the CORS and display notice is hidden for buckets with endpoint type E3 + * - Confirms the SSL/TLS tab is hidden for buckets with endpoint type E3 + */ + it('hides the CORS toggle, displays a notice, and disables the SSL/TLS tab for buckets with an E3 endpoint', () => { + createMocksAndNavigateToPage('E3'); - // confirms the CORS toggle is not visible - confirmCORSNotPresent(); + // confirms the CORS toggle is not visible + confirmCORSNotPresent(); - // Confirm SSL/TLS tab is hidden - cy.findByText('SSL/TLS').should('not.exist'); + // Confirm SSL/TLS tab is hidden + cy.findByText('SSL/TLS').should('not.exist'); + }); }); }); From cf73bc85c62a59ec75eb431aa6a387f84f5dbc46 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 24 Sep 2024 16:08:35 -0400 Subject: [PATCH 09/20] skeleton tests --- .../bucket-details-gen2.spec.ts | 67 ++++++++++++++----- 1 file changed, 51 insertions(+), 16 deletions(-) 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 index 3e794439c33..d5f0571cc36 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -41,7 +41,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { cors_enabled: true, cors_xml: '', }; - + const createMocksAndNavigateToPage = ( endpointType: ObjectStorageEndpointTypes ) => { @@ -54,7 +54,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { endpoint_type: endpointType, region: mockRegion.id, }); - + mockGetBucketAccess(label, cluster, mockAccess).as('getBucketAccess'); mockGetBucketsForRegion(mockRegion.id, [mockBucket]).as( 'getBucketsForRegion' @@ -62,7 +62,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { mockGetObjectStorageEndpoints([mockEndpoint]).as( 'getObjectStorageEndpoints' ); - + cy.visitWithLogin(`/object-storage/buckets/${cluster}/${label}/access`); cy.wait([ '@getFeatureFlags', @@ -72,7 +72,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { '@getBucketAccess', ]); }; - + const confirmCORSToggleAndSSLTabPresent = () => { cy.findByText('Bucket Access').should('be.visible'); cy.findByLabelText('Access Control List (ACL)').should('be.visible'); @@ -82,12 +82,12 @@ describe('Object Storage Gen 2 bucket details tabs', () => { /Whether Cross-Origin Resource Sharing is enabled for all origins. For more fine-grained control of CORS, please use another/ ).should('be.visible'); cy.findByText(/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'); }; - + const confirmCORSNotPresent = () => { cy.findByText('Bucket Access').should('be.visible'); cy.findByLabelText('Access Control List (ACL)').should('be.visible'); @@ -96,56 +96,91 @@ describe('Object Storage Gen 2 bucket details tabs', () => { /CORS \(Cross Origin Sharing\) is not available for endpoint types E2 and E3/ ).should('be.visible'); }; - + /** * - Confirms the CORS toggle still appears for buckets with endpoint type E0 * - Confirms the SSL/TLS tab appears for buckets with endpoint type E0 */ it('does not hide the CORS toggle or SSL/TLS tab for buckets with an E0 endpoint', () => { createMocksAndNavigateToPage('E0'); - + // confirm CORS toggle is visible and the SSL/TLS tab is present confirmCORSToggleAndSSLTabPresent(); }); - + /** * - Confirms the CORS toggle still appears for buckets with endpoint type E1 * - Confirms the SSL/TLS tab appears for buckets with endpoint type E1 */ it('does not hide the CORS toggle or SSL/TLS tab for buckets with an E1 endpoint', () => { createMocksAndNavigateToPage('E1'); - + // confirm CORS toggle is visible and the SSL/TLS tab is present confirmCORSToggleAndSSLTabPresent(); }); - + /** * - Confirms the CORS and display notice is hidden for buckets with endpoint type E2 * - Confirms the SSL/TLS tab appears for buckets with endpoint type E2 */ it('hides the CORS toggle and displays a notice for buckets with an E2 endpoint', () => { createMocksAndNavigateToPage('E2'); - + // confirms the CORS toggle is not visible confirmCORSNotPresent(); - + // Confirm SSL/TLS tab is not hidden and is clickable cy.findByText('SSL/TLS').should('be.visible').click(); cy.url().should('endWith', '/ssl'); }); - + /** * - Confirms the CORS and display notice is hidden for buckets with endpoint type E3 * - Confirms the SSL/TLS tab is hidden for buckets with endpoint type E3 */ it('hides the CORS toggle, displays a notice, and disables the SSL/TLS tab for buckets with an E3 endpoint', () => { createMocksAndNavigateToPage('E3'); - + // confirms the CORS toggle is not visible confirmCORSNotPresent(); - + // Confirm SSL/TLS tab is hidden cy.findByText('SSL/TLS').should('not.exist'); }); }); + + describe.only('Properties tab', () => { + // TODO: Confirm AC as rn the properties tab shows up for E0/E1 (but it's basically a blank page) + // /** + // * - Confirms absence of Properties tab for buckets with endpoint type E0 + // */ + // it('does not show the properties tab for buckets with endpoint type E0', () => { + + // }); + + // /** + // * - Confirms absence of Properties tab for buckets with endpoint type E1 + // */ + // it('does not show the properties tab for buckets with endpoint type E1', () => { + + // }); + + /** + * For buckets with endpoint type E2, + * - Confirms Properties tab is present + * - Confirms the Properties tab contains the bucket rate limit table + */ + it('shows the properties tab and rate limit table for buckets with endpoint type E2', () => { + + }); + + /** + * For buckets with endpoint type E3, + * - Confirms Properties tab is present + * - Confirms the Properties tab contains the bucket rate limit table + */ + it('shows the properties tab and rate limit table for buckets with endpoint type E3', () => { + + }); + }); }); From 7ee3147126c813a8fb00f68742051ca4c41b626b Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 24 Sep 2024 16:29:51 -0400 Subject: [PATCH 10/20] need to cleanup --- .../bucket-create-gen2.spec.ts | 62 +++++----- .../bucket-details-gen2.spec.ts | 117 ++++++++++++++---- 2 files changed, 122 insertions(+), 57 deletions(-) diff --git a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-create-gen2.spec.ts b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-create-gen2.spec.ts index dce48e600f3..e126cc23192 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-create-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-create-gen2.spec.ts @@ -21,6 +21,38 @@ import type { ObjectStorageEndpointTypes, } from '@linode/api-v4'; +export const checkRateLimitsTable = ( + endpointType: ObjectStorageEndpointTypes +) => { + const expectedHeaders = ['Limits', 'GET', 'PUT', 'LIST', 'DELETE', 'OTHER']; + const expectedBasicValues = ['Basic', '2,000', '500', '100', '200', '400']; + const expectedHighValues = + endpointType === 'E3' + ? ['High', '20,000', '2,000', '400', '400', '1,000'] + : ['High', '5,000', '1,000', '200', '200', '800']; + + cy.get('[data-testid="bucket-rate-limit-table"]').within(() => { + expectedHeaders.forEach((header, index) => { + cy.get('th').eq(index).should('contain.text', header); + }); + + cy.contains('tr', 'Basic').within(() => { + expectedBasicValues.forEach((value, index) => { + cy.get('td').eq(index).should('contain.text', value); + }); + }); + + cy.contains('tr', 'High').within(() => { + expectedHighValues.forEach((value, index) => { + cy.get('td').eq(index).should('contain.text', value); + }); + }); + + // Check that Basic radio button is checked + cy.findByLabelText('Basic').should('be.checked'); + }); +}; + describe('Object Storage Gen2 create bucket tests', () => { beforeEach(() => { mockAppendFeatureFlags({ @@ -72,36 +104,6 @@ describe('Object Storage Gen2 create bucket tests', () => { }), ]; - const checkRateLimitsTable = (endpointType: ObjectStorageEndpointTypes) => { - const expectedHeaders = ['Limits', 'GET', 'PUT', 'LIST', 'DELETE', 'OTHER']; - const expectedBasicValues = ['Basic', '2,000', '500', '100', '200', '400']; - const expectedHighValues = - endpointType === 'E3' - ? ['High', '20,000', '2,000', '400', '400', '1,000'] - : ['High', '5,000', '1,000', '200', '200', '800']; - - cy.get('[data-testid="bucket-rate-limit-table"]').within(() => { - expectedHeaders.forEach((header, index) => { - cy.get('th').eq(index).should('contain.text', header); - }); - - cy.contains('tr', 'Basic').within(() => { - expectedBasicValues.forEach((value, index) => { - cy.get('td').eq(index).should('contain.text', value); - }); - }); - - cy.contains('tr', 'High').within(() => { - expectedHighValues.forEach((value, index) => { - cy.get('td').eq(index).should('contain.text', value); - }); - }); - - // Check that Basic radio button is checked - cy.findByLabelText('Basic').should('be.checked'); - }); - }; - /** * Confirms UI flow for creating a gen2 Object Storage bucket with endpoint E0 * Confirms all endpoints are displayed regardless if there's multiple of the same type 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 index d5f0571cc36..2042547320a 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -12,6 +12,7 @@ import { regionFactory, } from 'src/factories'; import { ACLType, ObjectStorageEndpointTypes } from '@linode/api-v4'; +import { checkRateLimitsTable } from './bucket-create-gen2.spec'; describe('Object Storage Gen 2 bucket details tabs', () => { beforeEach(() => { @@ -41,8 +42,8 @@ describe('Object Storage Gen 2 bucket details tabs', () => { cors_enabled: true, cors_xml: '', }; - - const createMocksAndNavigateToPage = ( + + const createMocksAndNavigateToTab = ( endpointType: ObjectStorageEndpointTypes ) => { const mockBucket = objectStorageBucketFactoryGen2.build({ @@ -54,7 +55,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { endpoint_type: endpointType, region: mockRegion.id, }); - + mockGetBucketAccess(label, cluster, mockAccess).as('getBucketAccess'); mockGetBucketsForRegion(mockRegion.id, [mockBucket]).as( 'getBucketsForRegion' @@ -62,7 +63,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { mockGetObjectStorageEndpoints([mockEndpoint]).as( 'getObjectStorageEndpoints' ); - + cy.visitWithLogin(`/object-storage/buckets/${cluster}/${label}/access`); cy.wait([ '@getFeatureFlags', @@ -72,7 +73,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { '@getBucketAccess', ]); }; - + const confirmCORSToggleAndSSLTabPresent = () => { cy.findByText('Bucket Access').should('be.visible'); cy.findByLabelText('Access Control List (ACL)').should('be.visible'); @@ -82,12 +83,12 @@ describe('Object Storage Gen 2 bucket details tabs', () => { /Whether Cross-Origin Resource Sharing is enabled for all origins. For more fine-grained control of CORS, please use another/ ).should('be.visible'); cy.findByText(/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'); }; - + const confirmCORSNotPresent = () => { cy.findByText('Bucket Access').should('be.visible'); cy.findByLabelText('Access Control List (ACL)').should('be.visible'); @@ -96,54 +97,54 @@ describe('Object Storage Gen 2 bucket details tabs', () => { /CORS \(Cross Origin Sharing\) is not available for endpoint types E2 and E3/ ).should('be.visible'); }; - + /** * - Confirms the CORS toggle still appears for buckets with endpoint type E0 * - Confirms the SSL/TLS tab appears for buckets with endpoint type E0 */ it('does not hide the CORS toggle or SSL/TLS tab for buckets with an E0 endpoint', () => { - createMocksAndNavigateToPage('E0'); - + createMocksAndNavigateToTab('E0'); + // confirm CORS toggle is visible and the SSL/TLS tab is present confirmCORSToggleAndSSLTabPresent(); }); - + /** * - Confirms the CORS toggle still appears for buckets with endpoint type E1 * - Confirms the SSL/TLS tab appears for buckets with endpoint type E1 */ it('does not hide the CORS toggle or SSL/TLS tab for buckets with an E1 endpoint', () => { - createMocksAndNavigateToPage('E1'); - + createMocksAndNavigateToTab('E1'); + // confirm CORS toggle is visible and the SSL/TLS tab is present confirmCORSToggleAndSSLTabPresent(); }); - + /** * - Confirms the CORS and display notice is hidden for buckets with endpoint type E2 * - Confirms the SSL/TLS tab appears for buckets with endpoint type E2 */ it('hides the CORS toggle and displays a notice for buckets with an E2 endpoint', () => { - createMocksAndNavigateToPage('E2'); - + createMocksAndNavigateToTab('E2'); + // confirms the CORS toggle is not visible confirmCORSNotPresent(); - + // Confirm SSL/TLS tab is not hidden and is clickable cy.findByText('SSL/TLS').should('be.visible').click(); cy.url().should('endWith', '/ssl'); }); - + /** * - Confirms the CORS and display notice is hidden for buckets with endpoint type E3 * - Confirms the SSL/TLS tab is hidden for buckets with endpoint type E3 */ it('hides the CORS toggle, displays a notice, and disables the SSL/TLS tab for buckets with an E3 endpoint', () => { - createMocksAndNavigateToPage('E3'); - + createMocksAndNavigateToTab('E3'); + // confirms the CORS toggle is not visible confirmCORSNotPresent(); - + // Confirm SSL/TLS tab is hidden cy.findByText('SSL/TLS').should('not.exist'); }); @@ -160,27 +161,89 @@ describe('Object Storage Gen 2 bucket details tabs', () => { // /** // * - Confirms absence of Properties tab for buckets with endpoint type E1 - // */ + // */ // it('does not show the properties tab for buckets with endpoint type E1', () => { - // }); - + // }); + /** * For buckets with endpoint type E2, * - Confirms Properties tab is present * - Confirms the Properties tab contains the bucket rate limit table - */ + */ it('shows the properties tab and rate limit table for buckets with endpoint type E2', () => { + const mockBucket = objectStorageBucketFactoryGen2.build({ + endpoint_type: 'E2', + region: mockRegion.id, + }); + const { cluster, label } = mockBucket; + const mockEndpoint = objectStorageEndpointsFactory.build({ + endpoint_type: 'E2', + region: mockRegion.id, + }); + + mockGetBucketsForRegion(mockRegion.id, [mockBucket]).as( + 'getBucketsForRegion' + ); + mockGetObjectStorageEndpoints([mockEndpoint]).as( + 'getObjectStorageEndpoints' + ); + cy.visitWithLogin( + `/object-storage/buckets/${cluster}/${label}/properties` + ); + cy.wait([ + '@getFeatureFlags', + '@getAccount', + '@getObjectStorageEndpoints', + '@getBucketsForRegion', + ]); + + cy.findByText('Bucket Rate Limits'); + cy.contains( + 'Specifies the maximum Requests Per Second (RPS) for a bucket. To increase it to High, open a support ticket. Understand bucket rate limits.' + ).should('be.visible'); + checkRateLimitsTable('E2'); }); /** * For buckets with endpoint type E3, * - Confirms Properties tab is present * - Confirms the Properties tab contains the bucket rate limit table - */ + */ it('shows the properties tab and rate limit table for buckets with endpoint type E3', () => { + const mockBucket = objectStorageBucketFactoryGen2.build({ + endpoint_type: 'E3', + region: mockRegion.id, + }); + const { cluster, label } = mockBucket; + const mockEndpoint = objectStorageEndpointsFactory.build({ + endpoint_type: 'E3', + region: mockRegion.id, + }); - }); + mockGetBucketsForRegion(mockRegion.id, [mockBucket]).as( + 'getBucketsForRegion' + ); + mockGetObjectStorageEndpoints([mockEndpoint]).as( + 'getObjectStorageEndpoints' + ); + + cy.visitWithLogin( + `/object-storage/buckets/${cluster}/${label}/properties` + ); + cy.wait([ + '@getFeatureFlags', + '@getAccount', + '@getObjectStorageEndpoints', + '@getBucketsForRegion', + ]); + + cy.findByText('Bucket Rate Limits'); + cy.contains( + 'Specifies the maximum Requests Per Second (RPS) for a bucket. To increase it to High, open a support ticket. Understand bucket rate limits.' + ).should('be.visible'); + checkRateLimitsTable('E3'); + }); }); }); From 9ab3a38350f456d01ba2b9c60ef4f145dfc4c9ed Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 24 Sep 2024 16:33:05 -0400 Subject: [PATCH 11/20] cleanup: use contains instead of find by text --- .../core/objectStorageGen2/bucket-details-gen2.spec.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) 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 index 7cfeaeb77d3..906db24d86f 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -77,10 +77,9 @@ describe('Object Storage Gen 2 bucket details Access and SSL/TLS tabs', () => { cy.findByLabelText('Access Control List (ACL)').should('be.visible'); // confirm CORS is visible cy.findByText('CORS Enabled').should('be.visible'); - cy.findByText( - /Whether Cross-Origin Resource Sharing is enabled for all origins. For more fine-grained control of CORS, please use another/ + 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'); - cy.findByText(/S3-compatible tool/).should('be.visible'); // Confirm SSL/TLS tab is not hidden and is clickable cy.findByText('SSL/TLS').should('be.visible').click(); @@ -91,8 +90,8 @@ describe('Object Storage Gen 2 bucket details Access and SSL/TLS tabs', () => { cy.findByText('Bucket Access').should('be.visible'); cy.findByLabelText('Access Control List (ACL)').should('be.visible'); // confirm CORS is not visible - cy.findByText( - /CORS \(Cross Origin Sharing\) is not available for endpoint types E2 and E3/ + cy.contains( + 'CORS (Cross Origin Sharing) is not available for endpoint types E2 and E3' ).should('be.visible'); }; From 24b7559e14f856dbab5a3f8162c5d79abb35ae8e Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 24 Sep 2024 16:44:44 -0400 Subject: [PATCH 12/20] why are the create tests also running without the .only?? --- .../bucket-details-gen2.spec.ts | 139 ++++++------------ 1 file changed, 49 insertions(+), 90 deletions(-) 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 index 2042547320a..a10fba69c7c 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -11,10 +11,14 @@ import { objectStorageEndpointsFactory, regionFactory, } from 'src/factories'; -import { ACLType, ObjectStorageEndpointTypes } from '@linode/api-v4'; +import { + ACLType, + ObjectStorageBucketAccess, + ObjectStorageEndpointTypes, +} from '@linode/api-v4'; import { checkRateLimitsTable } from './bucket-create-gen2.spec'; -describe('Object Storage Gen 2 bucket details tabs', () => { +describe.only('Object Storage Gen 2 bucket details tabs', () => { beforeEach(() => { mockAppendFeatureFlags({ objMultiCluster: true, @@ -35,6 +39,42 @@ describe('Object Storage Gen 2 bucket details tabs', () => { capabilities: ['Object Storage'], }); + const createMocksAndNavigateToTab = ( + endpointType: ObjectStorageEndpointTypes, + tab: string, + mockAccess?: ObjectStorageBucketAccess + ) => { + const mockBucket = objectStorageBucketFactoryGen2.build({ + endpoint_type: endpointType, + region: mockRegion.id, + }); + const { cluster, label } = mockBucket; + const mockEndpoint = objectStorageEndpointsFactory.build({ + endpoint_type: endpointType, + region: mockRegion.id, + }); + + mockGetBucketsForRegion(mockRegion.id, [mockBucket]).as( + 'getBucketsForRegion' + ); + mockGetObjectStorageEndpoints([mockEndpoint]).as( + 'getObjectStorageEndpoints' + ); + + cy.visitWithLogin(`/object-storage/buckets/${cluster}/${label}/${tab}`); + cy.wait([ + '@getFeatureFlags', + '@getAccount', + '@getObjectStorageEndpoints', + '@getBucketsForRegion', + ]); + + if (mockAccess) { + mockGetBucketAccess(label, cluster, mockAccess).as('getBucketAccess'); + cy.wait('@getBucketAccess'); + } + }; + describe('Access and SSL/TLS tabs', () => { const mockAccess = { acl: 'private' as ACLType, @@ -43,37 +83,6 @@ describe('Object Storage Gen 2 bucket details tabs', () => { cors_xml: '', }; - const createMocksAndNavigateToTab = ( - endpointType: ObjectStorageEndpointTypes - ) => { - const mockBucket = objectStorageBucketFactoryGen2.build({ - endpoint_type: endpointType, - region: mockRegion.id, - }); - const { cluster, label } = mockBucket; - const mockEndpoint = objectStorageEndpointsFactory.build({ - endpoint_type: endpointType, - region: mockRegion.id, - }); - - 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', - ]); - }; - const confirmCORSToggleAndSSLTabPresent = () => { cy.findByText('Bucket Access').should('be.visible'); cy.findByLabelText('Access Control List (ACL)').should('be.visible'); @@ -103,7 +112,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { * - Confirms the SSL/TLS tab appears for buckets with endpoint type E0 */ it('does not hide the CORS toggle or SSL/TLS tab for buckets with an E0 endpoint', () => { - createMocksAndNavigateToTab('E0'); + createMocksAndNavigateToTab('E0', 'access', mockAccess); // confirm CORS toggle is visible and the SSL/TLS tab is present confirmCORSToggleAndSSLTabPresent(); @@ -114,7 +123,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { * - Confirms the SSL/TLS tab appears for buckets with endpoint type E1 */ it('does not hide the CORS toggle or SSL/TLS tab for buckets with an E1 endpoint', () => { - createMocksAndNavigateToTab('E1'); + createMocksAndNavigateToTab('E1', 'access', mockAccess); // confirm CORS toggle is visible and the SSL/TLS tab is present confirmCORSToggleAndSSLTabPresent(); @@ -125,7 +134,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { * - Confirms the SSL/TLS tab appears for buckets with endpoint type E2 */ it('hides the CORS toggle and displays a notice for buckets with an E2 endpoint', () => { - createMocksAndNavigateToTab('E2'); + createMocksAndNavigateToTab('E2', 'access', mockAccess); // confirms the CORS toggle is not visible confirmCORSNotPresent(); @@ -140,7 +149,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { * - Confirms the SSL/TLS tab is hidden for buckets with endpoint type E3 */ it('hides the CORS toggle, displays a notice, and disables the SSL/TLS tab for buckets with an E3 endpoint', () => { - createMocksAndNavigateToTab('E3'); + createMocksAndNavigateToTab('E3', 'access', mockAccess); // confirms the CORS toggle is not visible confirmCORSNotPresent(); @@ -150,7 +159,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { }); }); - describe.only('Properties tab', () => { + describe('Properties tab', () => { // TODO: Confirm AC as rn the properties tab shows up for E0/E1 (but it's basically a blank page) // /** // * - Confirms absence of Properties tab for buckets with endpoint type E0 @@ -172,32 +181,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { * - Confirms the Properties tab contains the bucket rate limit table */ it('shows the properties tab and rate limit table for buckets with endpoint type E2', () => { - const mockBucket = objectStorageBucketFactoryGen2.build({ - endpoint_type: 'E2', - region: mockRegion.id, - }); - const { cluster, label } = mockBucket; - const mockEndpoint = objectStorageEndpointsFactory.build({ - endpoint_type: 'E2', - region: mockRegion.id, - }); - - mockGetBucketsForRegion(mockRegion.id, [mockBucket]).as( - 'getBucketsForRegion' - ); - mockGetObjectStorageEndpoints([mockEndpoint]).as( - 'getObjectStorageEndpoints' - ); - - cy.visitWithLogin( - `/object-storage/buckets/${cluster}/${label}/properties` - ); - cy.wait([ - '@getFeatureFlags', - '@getAccount', - '@getObjectStorageEndpoints', - '@getBucketsForRegion', - ]); + createMocksAndNavigateToTab('E2', 'properties'); cy.findByText('Bucket Rate Limits'); cy.contains( @@ -212,32 +196,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { * - Confirms the Properties tab contains the bucket rate limit table */ it('shows the properties tab and rate limit table for buckets with endpoint type E3', () => { - const mockBucket = objectStorageBucketFactoryGen2.build({ - endpoint_type: 'E3', - region: mockRegion.id, - }); - const { cluster, label } = mockBucket; - const mockEndpoint = objectStorageEndpointsFactory.build({ - endpoint_type: 'E3', - region: mockRegion.id, - }); - - mockGetBucketsForRegion(mockRegion.id, [mockBucket]).as( - 'getBucketsForRegion' - ); - mockGetObjectStorageEndpoints([mockEndpoint]).as( - 'getObjectStorageEndpoints' - ); - - cy.visitWithLogin( - `/object-storage/buckets/${cluster}/${label}/properties` - ); - cy.wait([ - '@getFeatureFlags', - '@getAccount', - '@getObjectStorageEndpoints', - '@getBucketsForRegion', - ]); + createMocksAndNavigateToTab('E3', 'properties'); cy.findByText('Bucket Rate Limits'); cy.contains( From eba37362b548dd9cbb83336de5d9ebf4ea5d3f70 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 24 Sep 2024 17:11:22 -0400 Subject: [PATCH 13/20] update abstraction --- .../core/objectStorageGen2/bucket-details-gen2.spec.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) 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 index a10fba69c7c..316c55a347a 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -62,17 +62,16 @@ describe.only('Object Storage Gen 2 bucket details tabs', () => { ); cy.visitWithLogin(`/object-storage/buckets/${cluster}/${label}/${tab}`); + if (mockAccess) { + mockGetBucketAccess(label, cluster, mockAccess).as('getBucketAccess'); + cy.wait('@getBucketAccess'); + } cy.wait([ '@getFeatureFlags', '@getAccount', '@getObjectStorageEndpoints', '@getBucketsForRegion', ]); - - if (mockAccess) { - mockGetBucketAccess(label, cluster, mockAccess).as('getBucketAccess'); - cy.wait('@getBucketAccess'); - } }; describe('Access and SSL/TLS tabs', () => { From fa9422f8a6091a6e617477751a1ebcdc1fde9662 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Thu, 26 Sep 2024 18:05:00 -0400 Subject: [PATCH 14/20] parameterize tests based on feedback @jdamore-linode --- .../bucket-details-gen2.spec.ts | 175 +++++++++--------- 1 file changed, 87 insertions(+), 88 deletions(-) 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 index 906db24d86f..e9650582dd5 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -41,108 +41,107 @@ describe('Object Storage Gen 2 bucket details Access and SSL/TLS tabs', () => { cors_xml: '', }; - const createMocksAndNavigateToPage = ( + const createMocksBasedOnEndpointType = ( endpointType: ObjectStorageEndpointTypes ) => { const mockBucket = objectStorageBucketFactoryGen2.build({ endpoint_type: endpointType, region: mockRegion.id, }); - const { cluster, label } = mockBucket; const mockEndpoint = objectStorageEndpointsFactory.build({ endpoint_type: endpointType, region: mockRegion.id, }); - 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', - ]); + return { mockBucket, mockEndpoint }; }; - const confirmCORSToggleAndSSLTabPresent = () => { - 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'); - }; - - const confirmCORSNotPresent = () => { - 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 CORS toggle still appears for buckets with endpoint type E0 - * - Confirms the SSL/TLS tab appears for buckets with endpoint type E0 - */ - it('does not hide the CORS toggle or SSL/TLS tab for buckets with an E0 endpoint', () => { - createMocksAndNavigateToPage('E0'); - - // confirm CORS toggle is visible and the SSL/TLS tab is present - confirmCORSToggleAndSSLTabPresent(); - }); - - /** - * - Confirms the CORS toggle still appears for buckets with endpoint type E1 - * - Confirms the SSL/TLS tab appears for buckets with endpoint type E1 - */ - it('does not hide the CORS toggle or SSL/TLS tab for buckets with an E1 endpoint', () => { - createMocksAndNavigateToPage('E1'); - - // confirm CORS toggle is visible and the SSL/TLS tab is present - confirmCORSToggleAndSSLTabPresent(); - }); - - /** - * - Confirms the CORS and display notice is hidden for buckets with endpoint type E2 - * - Confirms the SSL/TLS tab appears for buckets with endpoint type E2 - */ - it('hides the CORS toggle and displays a notice for buckets with an E2 endpoint', () => { - createMocksAndNavigateToPage('E2'); - - // confirms the CORS toggle is not visible - confirmCORSNotPresent(); - - // Confirm SSL/TLS tab is not hidden and is clickable - cy.findByText('SSL/TLS').should('be.visible').click(); - cy.url().should('endWith', '/ssl'); + ['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 or 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'); + }); }); - /** - * - Confirms the CORS and display notice is hidden for buckets with endpoint type E3 - * - Confirms the SSL/TLS tab is hidden for buckets with endpoint type E3 - */ - it('hides the CORS toggle, displays a notice, and disables the SSL/TLS tab for buckets with an E3 endpoint', () => { - createMocksAndNavigateToPage('E3'); - - // confirms the CORS toggle is not visible - confirmCORSNotPresent(); - - // Confirm SSL/TLS tab is hidden - cy.findByText('SSL/TLS').should('not.exist'); + ['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 present for E2 but hidden for E3 + */ + it(`hides the CORS toggle and confirms the correct state of the TLS/SSL tab for 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'); + + if (endpoint === 'E3') { + cy.findByText('SSL/TLS').should('not.exist'); + } else { + // For E2, the SSL/TLS tab is present and clickable + cy.findByText('SSL/TLS').should('be.visible').click(); + cy.url().should('endWith', '/ssl'); + } + }); }); }); From 67565f8d6815d77f8582abd3a1e3d4d802146496 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 1 Oct 2024 10:05:44 -0400 Subject: [PATCH 15/20] confirm testing AC and update tests/fix bug --- .../objectStorageGen2/bucket-details-gen2.spec.ts | 15 +++++---------- .../features/ObjectStorage/BucketDetail/index.tsx | 4 ++-- 2 files changed, 7 insertions(+), 12 deletions(-) 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 index e9650582dd5..c7302697565 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -62,7 +62,7 @@ describe('Object Storage Gen 2 bucket details Access and SSL/TLS tabs', () => { * - Confirms the CORS toggle still appears * - Confirms the SSL/TLS tab appears */ - it(`does not hide the CORS toggle or SSL/TLS tab for buckets with an ${endpoint} endpoint`, () => { + it(`does not hide the CORS toggle and SSL/TLS tab for buckets with an ${endpoint} endpoint`, () => { const { mockBucket, mockEndpoint } = createMocksBasedOnEndpointType( endpoint ); @@ -103,9 +103,9 @@ describe('Object Storage Gen 2 bucket details Access and SSL/TLS tabs', () => { /** * Parameterized test for object storage endpoint types E2 and E3 * - Confirms the CORS toggle is hidden - * - Confirms the SSL/TLS tab is present for E2 but hidden for E3 + * - Confirms the SSL/TLS tab is hidden */ - it(`hides the CORS toggle and confirms the correct state of the TLS/SSL tab for endpoint ${endpoint}`, () => { + it(`hides the CORS toggle and SSL/TLS tab for for buckets with an ${endpoint} endpoint`, () => { const { mockBucket, mockEndpoint } = createMocksBasedOnEndpointType( endpoint ); @@ -135,13 +135,8 @@ describe('Object Storage Gen 2 bucket details Access and SSL/TLS tabs', () => { 'CORS (Cross Origin Sharing) is not available for endpoint types E2 and E3' ).should('be.visible'); - if (endpoint === 'E3') { - cy.findByText('SSL/TLS').should('not.exist'); - } else { - // For E2, the SSL/TLS tab is present and clickable - cy.findByText('SSL/TLS').should('be.visible').click(); - cy.url().should('endWith', '/ssl'); - } + // confirms the SSL/TLS tab is not present + cy.findByText('SSL/TLS').should('not.exist'); }); }); }); 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`, From f623755cc0589521989697f25a0e25b9f358349f Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 1 Oct 2024 13:51:50 -0400 Subject: [PATCH 16/20] updated tests based on confirmed AC --- .../bucket-details-gen2.spec.ts | 130 ++++++++++++------ 1 file changed, 91 insertions(+), 39 deletions(-) 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 index a297d715a69..6f8d39538c1 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -5,6 +5,7 @@ import { mockGetObjectStorageEndpoints, mockGetBucketAccess, } from 'support/intercepts/object-storage'; +import { ui } from 'support/ui'; import { accountFactory, objectStorageBucketFactoryGen2, @@ -12,7 +13,7 @@ import { regionFactory, } from 'src/factories'; import { ACLType, ObjectStorageEndpointTypes } from '@linode/api-v4'; -//import { checkRateLimitsTable } from './bucket-create-gen2.spec'; +import { checkRateLimitsTable } from './bucket-create-gen2.spec'; describe('Object Storage Gen 2 bucket details tabs', () => { beforeEach(() => { @@ -143,43 +144,94 @@ describe('Object Storage Gen 2 bucket details tabs', () => { }); }); - describe('Properties tab', () => { - // TODO: Confirm AC as rn the properties tab shows up for E0/E1 (but it's basically a blank page) - // /** - // * - Confirms absence of Properties tab for buckets with endpoint type E0 - // */ - // it('does not show the properties tab for buckets with endpoint type E0', () => { - // }); - // /** - // * - Confirms absence of Properties tab for buckets with endpoint type E1 - // */ - // it('does not show the properties tab for buckets with endpoint type E1', () => { - // }); - /** - * For buckets with endpoint type E2, - * - Confirms Properties tab is present - * - Confirms the Properties tab contains the bucket rate limit table - */ - // it('shows the properties tab and rate limit table for buckets with endpoint type E2', () => { - // createMocksAndNavigateToTab('E2', 'properties'); - // cy.findByText('Bucket Rate Limits'); - // cy.contains( - // 'Specifies the maximum Requests Per Second (RPS) for a bucket. To increase it to High, open a support ticket. Understand bucket rate limits.' - // ).should('be.visible'); - // checkRateLimitsTable('E2'); - // }); - /** - * For buckets with endpoint type E3, - * - Confirms Properties tab is present - * - Confirms the Properties tab contains the bucket rate limit table - */ - // it('shows the properties tab and rate limit table for buckets with endpoint type E3', () => { - // createMocksAndNavigateToTab('E3', 'properties'); - // cy.findByText('Bucket Rate Limits'); - // cy.contains( - // 'Specifies the maximum Requests Per Second (RPS) for a bucket. To increase it to High, open a support ticket. Understand bucket rate limits.' - // ).should('be.visible'); - // checkRateLimitsTable('E3'); - // }); + describe.only('Properties tab', () => { + ['E0', 'E1'].forEach((endpoint: ObjectStorageEndpointTypes) => { + /** + * Parameterized test for buckets with endpoint types of E0 and E1 + * - Confirms the Properties tab is visible + * - Confirms there is no bucket rate limits table + */ + it(`confirms the Properties tab does not have a rate limits table for buckets with endpoint type ${endpoint}`, () => { + const { mockBucket, mockEndpoint } = createMocksBasedOnEndpointType( + endpoint + ); + const { cluster, label } = mockBucket; + + mockGetBucketsForRegion(mockRegion.id, [mockBucket]).as( + 'getBucketsForRegion' + ); + mockGetObjectStorageEndpoints([mockEndpoint]).as( + 'getObjectStorageEndpoints' + ); + + cy.visitWithLogin( + `/object-storage/buckets/${cluster}/${label}/properties` + ); + cy.wait([ + '@getFeatureFlags', + '@getAccount', + '@getObjectStorageEndpoints', + '@getBucketsForRegion', + ]); + + cy.findByText('Bucket Rate Limits').should('be.visible'); + // confirms helper text + cy.contains( + 'This endpoint type supports up to 750 Requests Per Second (RPS). Understand bucket rate limits' + ).should('be.visible'); + + // confirm bucket rate limit table should not exist + cy.get('[data-testid="bucket-rate-limit-table"]').should('not.exist'); + + // confirm 'Save' button is disabled (for now) + ui.button + .findByAttribute('label', 'Save') + .should('be.visible') + .should('be.disabled'); + }); + }); + + ['E2', 'E3'].forEach((endpoint: ObjectStorageEndpointTypes) => { + /** + * Parameterized test for buckets with endpoint types of E2 and E3 + * - Confirms the Properties tab is visible + * - Confirms bucket rates limit table exists + */ + it(`confirms the Properties tab and rate limits table for buckets with endpoint type ${endpoint}`, () => { + const { mockBucket, mockEndpoint } = createMocksBasedOnEndpointType( + endpoint + ); + const { cluster, label } = mockBucket; + + mockGetBucketsForRegion(mockRegion.id, [mockBucket]).as( + 'getBucketsForRegion' + ); + mockGetObjectStorageEndpoints([mockEndpoint]).as( + 'getObjectStorageEndpoints' + ); + + cy.visitWithLogin( + `/object-storage/buckets/${cluster}/${label}/properties` + ); + cy.wait([ + '@getFeatureFlags', + '@getAccount', + '@getObjectStorageEndpoints', + '@getBucketsForRegion', + ]); + + cy.findByText('Bucket Rate Limits'); + cy.contains( + 'Specifies the maximum Requests Per Second (RPS) for a bucket. To increase it to High, open a support ticket. Understand bucket rate limits.' + ).should('be.visible'); + checkRateLimitsTable(endpoint); + + // confirm 'Save' button is disabled (for now) + ui.button + .findByAttribute('label', 'Save') + .should('be.visible') + .should('be.disabled'); + }); + }); }); }); From 72f7046138297302a3ae91d90ec710a65375108c Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 1 Oct 2024 13:53:12 -0400 Subject: [PATCH 17/20] remove .only --- .../e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 6f8d39538c1..3c46228734e 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -144,7 +144,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { }); }); - describe.only('Properties tab', () => { + describe('Properties tab', () => { ['E0', 'E1'].forEach((endpoint: ObjectStorageEndpointTypes) => { /** * Parameterized test for buckets with endpoint types of E0 and E1 From 82c085d962b9ccfe24d147814c877424024af028 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 1 Oct 2024 15:08:57 -0400 Subject: [PATCH 18/20] utils file --- .../bucket-create-gen2.spec.ts | 38 +------------------ .../bucket-details-gen2.spec.ts | 2 +- .../support/util/object-storage-gen2.ts | 33 ++++++++++++++++ 3 files changed, 36 insertions(+), 37 deletions(-) create mode 100644 packages/manager/cypress/support/util/object-storage-gen2.ts diff --git a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-create-gen2.spec.ts b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-create-gen2.spec.ts index e126cc23192..7eeea7167ee 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-create-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-create-gen2.spec.ts @@ -8,6 +8,7 @@ import { } from 'support/intercepts/object-storage'; import { mockGetRegions } from 'support/intercepts/regions'; import { ui } from 'support/ui'; +import { checkRateLimitsTable } from 'support/util/object-storage-gen2'; import { randomLabel } from 'support/util/random'; import { accountFactory, @@ -16,42 +17,7 @@ import { regionFactory, } from 'src/factories'; import { chooseRegion } from 'support/util/regions'; -import type { - ObjectStorageEndpoint, - ObjectStorageEndpointTypes, -} from '@linode/api-v4'; - -export const checkRateLimitsTable = ( - endpointType: ObjectStorageEndpointTypes -) => { - const expectedHeaders = ['Limits', 'GET', 'PUT', 'LIST', 'DELETE', 'OTHER']; - const expectedBasicValues = ['Basic', '2,000', '500', '100', '200', '400']; - const expectedHighValues = - endpointType === 'E3' - ? ['High', '20,000', '2,000', '400', '400', '1,000'] - : ['High', '5,000', '1,000', '200', '200', '800']; - - cy.get('[data-testid="bucket-rate-limit-table"]').within(() => { - expectedHeaders.forEach((header, index) => { - cy.get('th').eq(index).should('contain.text', header); - }); - - cy.contains('tr', 'Basic').within(() => { - expectedBasicValues.forEach((value, index) => { - cy.get('td').eq(index).should('contain.text', value); - }); - }); - - cy.contains('tr', 'High').within(() => { - expectedHighValues.forEach((value, index) => { - cy.get('td').eq(index).should('contain.text', value); - }); - }); - - // Check that Basic radio button is checked - cy.findByLabelText('Basic').should('be.checked'); - }); -}; +import type { ObjectStorageEndpoint } from '@linode/api-v4'; describe('Object Storage Gen2 create bucket tests', () => { beforeEach(() => { 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 index 3c46228734e..f5419390f73 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -5,6 +5,7 @@ import { mockGetObjectStorageEndpoints, mockGetBucketAccess, } from 'support/intercepts/object-storage'; +import { checkRateLimitsTable } from 'support/util/object-storage-gen2'; import { ui } from 'support/ui'; import { accountFactory, @@ -13,7 +14,6 @@ import { regionFactory, } from 'src/factories'; import { ACLType, ObjectStorageEndpointTypes } from '@linode/api-v4'; -import { checkRateLimitsTable } from './bucket-create-gen2.spec'; describe('Object Storage Gen 2 bucket details tabs', () => { beforeEach(() => { diff --git a/packages/manager/cypress/support/util/object-storage-gen2.ts b/packages/manager/cypress/support/util/object-storage-gen2.ts new file mode 100644 index 00000000000..91d492638f4 --- /dev/null +++ b/packages/manager/cypress/support/util/object-storage-gen2.ts @@ -0,0 +1,33 @@ +import type { ObjectStorageEndpointTypes } from '@linode/api-v4'; + +export const checkRateLimitsTable = ( + endpointType: ObjectStorageEndpointTypes +) => { + const expectedHeaders = ['Limits', 'GET', 'PUT', 'LIST', 'DELETE', 'OTHER']; + const expectedBasicValues = ['Basic', '2,000', '500', '100', '200', '400']; + const expectedHighValues = + endpointType === 'E3' + ? ['High', '20,000', '2,000', '400', '400', '1,000'] + : ['High', '5,000', '1,000', '200', '200', '800']; + + cy.get('[data-testid="bucket-rate-limit-table"]').within(() => { + expectedHeaders.forEach((header, index) => { + cy.get('th').eq(index).should('contain.text', header); + }); + + cy.contains('tr', 'Basic').within(() => { + expectedBasicValues.forEach((value, index) => { + cy.get('td').eq(index).should('contain.text', value); + }); + }); + + cy.contains('tr', 'High').within(() => { + expectedHighValues.forEach((value, index) => { + cy.get('td').eq(index).should('contain.text', value); + }); + }); + + // Check that Basic radio button is checked + cy.findByLabelText('Basic').should('be.checked'); + }); +}; From c092c0bd5ecabf03aee39c24979fa3f3e0a5e40e Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 1 Oct 2024 15:50:27 -0400 Subject: [PATCH 19/20] changeset + add comment --- packages/manager/.changeset/pr-11002-tests-1727812216912.md | 5 +++++ .../e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts | 1 + 2 files changed, 6 insertions(+) create mode 100644 packages/manager/.changeset/pr-11002-tests-1727812216912.md diff --git a/packages/manager/.changeset/pr-11002-tests-1727812216912.md b/packages/manager/.changeset/pr-11002-tests-1727812216912.md new file mode 100644 index 00000000000..c2f42f4bb92 --- /dev/null +++ b/packages/manager/.changeset/pr-11002-tests-1727812216912.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Tests +--- + +Add integration test for Object Storage Gen2 Properties tab ([#11002](https://github.com/linode/manager/pull/11002)) 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 index f5419390f73..d673d1a318f 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -221,6 +221,7 @@ describe('Object Storage Gen 2 bucket details tabs', () => { ]); cy.findByText('Bucket Rate Limits'); + // Confirm bucket rate limits table exists with correct values and that its helper text exists cy.contains( 'Specifies the maximum Requests Per Second (RPS) for a bucket. To increase it to High, open a support ticket. Understand bucket rate limits.' ).should('be.visible'); From 0caa417718976e3c3fb4f7c06670c29cbd50c3a0 Mon Sep 17 00:00:00 2001 From: Connie Liu Date: Tue, 1 Oct 2024 15:52:02 -0400 Subject: [PATCH 20/20] update comment --- .../e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index d673d1a318f..0c29d1aecd8 100644 --- a/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts +++ b/packages/manager/cypress/e2e/core/objectStorageGen2/bucket-details-gen2.spec.ts @@ -221,10 +221,10 @@ describe('Object Storage Gen 2 bucket details tabs', () => { ]); cy.findByText('Bucket Rate Limits'); - // Confirm bucket rate limits table exists with correct values and that its helper text exists cy.contains( 'Specifies the maximum Requests Per Second (RPS) for a bucket. To increase it to High, open a support ticket. Understand bucket rate limits.' ).should('be.visible'); + // Confirm bucket rate limits table exists with correct values checkRateLimitsTable(endpoint); // confirm 'Save' button is disabled (for now)