From e9914723151e8aad8d6a5affce187d10fb555e9f Mon Sep 17 00:00:00 2001 From: Andrew Wylde Date: Tue, 6 Feb 2024 11:22:52 -0600 Subject: [PATCH] feat(app-reg-v2): filter applications by auth_strategy_id (#385) --- cypress/e2e/fixtures/consts.ts | 65 ++++++++++++--- .../specs/application_registration.spec.ts | 82 ++++++++++++++++++- cypress/e2e/support/mock-commands.ts | 4 +- package.json | 2 +- src/components/ViewSpecRegistrationModal.vue | 42 ++++++++-- src/views/Spec.vue | 6 +- yarn.lock | 8 +- 7 files changed, 181 insertions(+), 28 deletions(-) diff --git a/cypress/e2e/fixtures/consts.ts b/cypress/e2e/fixtures/consts.ts index b116a99d..f9f33635 100644 --- a/cypress/e2e/fixtures/consts.ts +++ b/cypress/e2e/fixtures/consts.ts @@ -1,4 +1,4 @@ -import { GetApplicationResponse, GetRegistrationResponse, PortalContext, Product, ProductVersion } from '@kong/sdk-portal-js' +import { GetApplicationResponse, GetRegistrationResponse, PortalContext, Product, ProductVersion, RegistrationConfiguration } from '@kong/sdk-portal-js' const versions: ProductVersion[] = [ { @@ -11,14 +11,23 @@ const versions: ProductVersion[] = [ } ] +const keyAuthRegConfig: RegistrationConfiguration = { + name: 'key auth auth strategy', + credential_type: 'key_auth', + id: 'd668b397-8a0d-482d-9b97-9e05cbfc7618' +} + +const oidcAuthRegConfig: RegistrationConfiguration = { + auth_methods: ['bearer', 'client_credentials'], + name: 'oidc auth strategy', + credential_type: 'client_credentials', + id: '7b651144-0b48-431a-af9b-58604adc9268' +} + const versionWithOidcAuthStrategy: ProductVersion = { ...versions[0], registration_configs: [ - { - auth_methods: ['bearer', 'client_credentials'], - name: 'oidc auth strategy', - credential_type: 'client_credentials' - } + oidcAuthRegConfig ] } @@ -29,10 +38,7 @@ const versionWithKeyAuthAuthStrategy: ProductVersion = { name: 'v1-beta', deprecated: false, registration_configs: [ - { - name: 'key auth auth strategy', - credential_type: 'key_auth' - } + keyAuthRegConfig ] } @@ -50,6 +56,34 @@ const product: Product = { version_count: 1 } +export const productWithKeyAuthAppAuthStrategy: Product = { + created_at: '2022-03-23T14:52:41.893Z', + updated_at: '2022-03-23T14:52:41.893Z', + id: '29985c03-a866-46f2-8152-29406243b90f', + name: 'barAPI', + description: null, + document_count: 0, + latest_version: { + id: versionWithKeyAuthAuthStrategy.id, + name: versionWithKeyAuthAuthStrategy.name + }, + version_count: 1 +} + +export const productWithOidcAppAuthStrategy: Product = { + created_at: '2024-03-23T14:52:41.893Z', + updated_at: '2024-03-23T14:52:41.893Z', + id: '7b5f7176-bbb1-4e98-bb98-fa16ae492b64', + name: 'fooAPI', + description: null, + document_count: 0, + latest_version: { + id: versionWithOidcAuthStrategy.id, + name: versionWithOidcAuthStrategy.name + }, + version_count: 1 +} + const productVersion: ProductVersion = { ...versions[0], registration_configs: [] @@ -91,6 +125,17 @@ const apps: GetApplicationResponse[] = [ } ] +export const appWithAuthStrategy: GetApplicationResponse = { + name: 'My Key-Auth App', + description: 'My DCR App has an auth strategy id', + reference_id: '5', + redirect_uri: 'http://google.com', + id: crypto.randomUUID(), + created_at: '2022-03-25T13:15:02.104Z', + updated_at: '2022-03-25T13:15:02.104Z', + auth_strategy_id: '452664ba-7d37-4e12-875c-3ca8044446fd' +} + const productRegistration: GetRegistrationResponse = { created_at: '2022-03-25T13:15:02.104Z', updated_at: '2022-03-25T13:15:02.104Z', diff --git a/cypress/e2e/specs/application_registration.spec.ts b/cypress/e2e/specs/application_registration.spec.ts index 749f5e4e..a5c9577d 100644 --- a/cypress/e2e/specs/application_registration.spec.ts +++ b/cypress/e2e/specs/application_registration.spec.ts @@ -1,5 +1,5 @@ import { CredentialCreationResponse, GetApplicationResponse, ListCredentialsResponse, ListCredentialsResponseDataInner, ListRegistrationsResponse } from '@kong/sdk-portal-js' -import { product, versions, productRegistration, apps, versionWithKeyAuthAuthStrategy, versionWithOidcAuthStrategy } from '../fixtures/consts' +import { product, versions, productRegistration, apps, productWithKeyAuthAppAuthStrategy, appWithAuthStrategy, versionWithKeyAuthAuthStrategy, versionWithOidcAuthStrategy } from '../fixtures/consts' const mockApplicationWithCredAndReg = ( data: GetApplicationResponse, @@ -673,6 +673,58 @@ describe('Application Registration', () => { 'You will be notified upon approval' ) }) + it('appregv2 - can request registration to a product version with app auth strategy id with feature flag enabled', () => { + cy.mockLaunchDarklyFlags([ + { + name: 'tdx-3531-app-reg-v2', + value: true + } + ]) + cy.mockProductDocument(productWithKeyAuthAppAuthStrategy.id) + cy.mockProduct(productWithKeyAuthAppAuthStrategy.id, productWithKeyAuthAppAuthStrategy, [versionWithKeyAuthAuthStrategy]) + cy.mockProductVersionApplicationRegistration(versionWithKeyAuthAuthStrategy) + cy.mockGetProductDocuments(productWithKeyAuthAppAuthStrategy.id) + cy.mockProductOperations(productWithKeyAuthAppAuthStrategy.id, versionWithKeyAuthAuthStrategy.id) + cy.mockProductVersionSpec(productWithKeyAuthAppAuthStrategy.id, versionWithKeyAuthAuthStrategy.id) + cy.mockRegistrations('*', []) // mock with empty so that we add one. + + cy.viewport(1440, 900) + cy.visit(`/spec/${productWithKeyAuthAppAuthStrategy.id}`) + cy.get('.swagger-ui', { timeout: 12000 }) + + cy.mockApplications([appWithAuthStrategy], 1) + cy.mockProductVersionAvailableRegistrations(productWithKeyAuthAppAuthStrategy.id, versionWithKeyAuthAuthStrategy.id, [appWithAuthStrategy]) + cy.mockGrantedScopes(versionWithKeyAuthAuthStrategy.id, appWithAuthStrategy.id, ['scope1', 'scope2']) + cy.wait('@getProductVersions') + + cy.get('[data-testid="app-reg-v2-register-btn"]', { timeout: 12000 }).click() + cy.wait('@getProductVersionAvailableRegistrations').then(interception => { + // @ts-ignore the filter property is actually an object, but the type definition is wrong + expect(interception.request.query.filter?.auth_strategy_id).to.eq(versionWithKeyAuthAuthStrategy.registration_configs[0].id) + }) + cy.get(selectors.appRegModal).should('exist') + cy.get(`${selectors.appRegModal} [data-testid="register-${appWithAuthStrategy.name}"]`).should('contain', appWithAuthStrategy.name).click() + + const mockCreateRegResponse = { + ...productRegistration, + status: 'pending', + application: appWithAuthStrategy + } + + cy.intercept( + 'POST', + `/api/v2/applications/${appWithAuthStrategy.id}/registrations*`, + { + body: mockCreateRegResponse + } + ).as('postApplicationRegistration') + + cy.get('[data-testid="submit-registration"]').click() + cy.get(selectors.appRegModal).should( + 'contain', + 'You will be notified upon approval' + ) + }) it('appreg-v2 - feature flag off - does not show auth strategy card', () => { cy.mockLaunchDarklyFlags([ { @@ -751,6 +803,34 @@ describe('Application Registration', () => { cy.get('[data-testid="register-button"]', { timeout: 12000 }).should('not.exist') }) + it('appregv2 - shows link to create new application if no applications match with feature flag enabled', () => { + cy.mockLaunchDarklyFlags([ + { + name: 'tdx-3531-app-reg-v2', + value: true + } + ]) + cy.mockProductDocument(productWithKeyAuthAppAuthStrategy.id, versionWithKeyAuthAuthStrategy.id) + cy.mockProduct(productWithKeyAuthAppAuthStrategy.id, productWithKeyAuthAppAuthStrategy, [versionWithKeyAuthAuthStrategy]) + cy.mockProductVersionApplicationRegistration(versionWithKeyAuthAuthStrategy) + cy.mockGetProductDocuments(productWithKeyAuthAppAuthStrategy.id) + cy.mockProductOperations(productWithKeyAuthAppAuthStrategy.id, versionWithKeyAuthAuthStrategy.id) + cy.mockProductVersionSpec(productWithKeyAuthAppAuthStrategy.id, versionWithKeyAuthAuthStrategy.id) + cy.mockRegistrations('*', []) // mock with empty so that we add one. + + cy.viewport(1440, 900) + cy.visit(`/spec/${productWithKeyAuthAppAuthStrategy.id}`) + cy.get('.swagger-ui', { timeout: 12000 }) + + cy.mockApplications([], 0) + cy.mockProductVersionAvailableRegistrations(productWithKeyAuthAppAuthStrategy.id, versionWithKeyAuthAuthStrategy.id, []) + + cy.get('[data-testid="app-reg-v2-register-btn"]', { timeout: 12000 }).click() + cy.get(selectors.appRegModal).should('exist') + cy.get(`${selectors.appRegModal} [data-testid="create-application"]`).should('exist') + cy.get(`${selectors.appRegModal} [data-testid="create-application"]`).should('have.prop', 'href').should('contain', `/application/create?product=${productWithKeyAuthAppAuthStrategy.id}&product_version=${versionWithKeyAuthAuthStrategy.id}&auth-strategy-id=${versionWithKeyAuthAuthStrategy.registration_configs[0].id}`) + }) + it('does not show select available scopes if no scopes are available - feature flag on', () => { cy.mockProductDocument() cy.mockProduct() diff --git a/cypress/e2e/support/mock-commands.ts b/cypress/e2e/support/mock-commands.ts index e640467d..6e103143 100644 --- a/cypress/e2e/support/mock-commands.ts +++ b/cypress/e2e/support/mock-commands.ts @@ -277,11 +277,11 @@ Cypress.Commands.add('mockProduct', (productId = '*', mockProduct = product, moc } } - cy.intercept('GET', `**/api/v2/products/${productId}/versions*`, { + cy.intercept('GET', `**/api/v2/products/${productId}/versions**`, { statusCode: 200, delay: 100, body: versionsResponse - }) + }).as('getProductVersions') const productResponse: Product = { ...mockProduct diff --git a/package.json b/package.json index 68e2f9ab..74e12835 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "@kong-ui-public/spec-renderer": "0.13.5", "@kong/kong-auth-elements": "2.11.1", "@kong/kongponents": "8.127.0", - "@kong/sdk-portal-js": "2.6.1", + "@kong/sdk-portal-js": "2.7.0", "@xstate/vue": "2.0.0", "axios": "1.6.0", "date-fns": "3.3.0", diff --git a/src/components/ViewSpecRegistrationModal.vue b/src/components/ViewSpecRegistrationModal.vue index e381423b..0ef4fe0f 100644 --- a/src/components/ViewSpecRegistrationModal.vue +++ b/src/components/ViewSpecRegistrationModal.vue @@ -90,7 +90,7 @@ appearance="primary" :disabled="currentState.matches('pending')" class="button-spacing" - :to="{ name: 'create-application', query: { product: $route.params.product, product_version: $route.params.product_version } }" + :to="{ name: 'create-application', query: createApplicationQuery }" > {{ helpText.applicationRegistration.createApplication }} @@ -118,13 +118,13 @@