From 581da5460efcd09f7bd007bd8632202e5525eb4e Mon Sep 17 00:00:00 2001 From: nirajCITZ <94716060+nirajCITZ@users.noreply.github.com> Date: Fri, 31 Mar 2023 13:27:42 -0700 Subject: [PATCH 1/2] Added following scenarios: (#791) 1)Cypress test to verify free (Public) access 2)Cypress Test - Delete Service account 3)Cypress Test - Verify rate_limiting_902 and rate_limiting plugins by applying them to different level 4)Cypress Test for Org Admin Co-authored-by: Niraj Patel --- e2e/cypress/fixtures/apiowner.json | 32 +++++ e2e/cypress/fixtures/developer.json | 10 ++ .../manage-control-config-setting.json | 3 +- .../manage-control/kong-plugin-config.json | 7 +- e2e/cypress/fixtures/rate-limiting-902.yml | 8 ++ e2e/cypress/pageObjects/apiDirectory.ts | 5 +- e2e/cypress/pageObjects/consumers.ts | 2 - e2e/cypress/pageObjects/products.ts | 10 +- e2e/cypress/pageObjects/serviceAccounts.ts | 15 +++ e2e/cypress/support/auth-commands.ts | 25 ++-- e2e/cypress/support/global.d.ts | 4 +- .../07-kong-public-auth.ts | 110 ++++++++++++++++++ .../03-delete-service-acc.ts | 58 +++++++++ .../01-client-cred-team-access.ts | 2 - 14 files changed, 265 insertions(+), 26 deletions(-) create mode 100644 e2e/cypress/fixtures/rate-limiting-902.yml create mode 100644 e2e/cypress/tests/09-update-product-env/07-kong-public-auth.ts create mode 100644 e2e/cypress/tests/10-clear-resources/03-delete-service-acc.ts diff --git a/e2e/cypress/fixtures/apiowner.json b/e2e/cypress/fixtures/apiowner.json index 1d4d97b95..c16eb318e 100644 --- a/e2e/cypress/fixtures/apiowner.json +++ b/e2e/cypress/fixtures/apiowner.json @@ -188,6 +188,38 @@ } } }, + "clientIdSecret_publicProfile": { + "product": { + "name": "Client Credentials Test Product", + "orgName": "Ministry of Health", + "orgUnitName": "Planning and Innovation Division", + "environment": { + "name": "test", + "config": { + "terms": "Terms of Use for API Gateway", + "authorization": "Public", + "optionalInstructions": "This is a automation test", + "serviceName": "cc-service-for-platform" + } + } + } + }, + "KongApiOnly": { + "product": { + "name": "Auto Test Product", + "orgName": "Ministry of Health", + "orgUnitName": "Planning and Innovation Division", + "environment": { + "name": "dev", + "config": { + "terms": "Terms of Use for API Gateway", + "authorization": "Kong API Key Only", + "optionalInstructions": "This is a automation test", + "serviceName": "a-service-for-newplatform" + } + } + } + }, "clientIdSecret_KongKeyToCC": { "product": { "name": "Auto Test Product", diff --git a/e2e/cypress/fixtures/developer.json b/e2e/cypress/fixtures/developer.json index 97f33802c..1be081bea 100644 --- a/e2e/cypress/fixtures/developer.json +++ b/e2e/cypress/fixtures/developer.json @@ -134,6 +134,16 @@ "environment": "dev" } }, + "elevatedAccess":{ + "application": { + "name": "Request for Elevated Acess", + "description": "Test application for auto test" + }, + "product": { + "name": "Auto Test Product", + "environment": "dev" + } + }, "deleteApplication":{ "application": { "name": "delete-application-without-access", diff --git a/e2e/cypress/fixtures/manage-control-config-setting.json b/e2e/cypress/fixtures/manage-control-config-setting.json index 0133242b5..cecd9ef62 100644 --- a/e2e/cypress/fixtures/manage-control-config-setting.json +++ b/e2e/cypress/fixtures/manage-control-config-setting.json @@ -1,7 +1,8 @@ { "rateLimiting": { "requestPerHour_Consumer" : "1", - "requestPerHour_Global" : "2" + "requestPerHour_Global" : "2", + "rateLimiting_hour": "25" }, "ipRestriction" :{ "ipRange_valid" : "192.168.0.1/0", diff --git a/e2e/cypress/fixtures/manage-control/kong-plugin-config.json b/e2e/cypress/fixtures/manage-control/kong-plugin-config.json index 9eaf278cd..758974149 100644 --- a/e2e/cypress/fixtures/manage-control/kong-plugin-config.json +++ b/e2e/cypress/fixtures/manage-control/kong-plugin-config.json @@ -4,6 +4,11 @@ "config.hour": "20", "config.policy": "local" }, + "rateLimiting902": { + "name": "rate-limiting_902", + "config.hour": "20", + "limit_by": "service" + }, "rateLimitingConsumer": { "name": "rate-limiting", "config.hour": "100", @@ -17,6 +22,6 @@ "username": "consumer1" }, "keyAuth": { - "config.anonymous": "09f98d53-4797-4ba9-a9e8-6417a1cee3b0" + "config.anonymous": "e60a4444-eeab-4d5b-8285-6e6a648d85ec" } } \ No newline at end of file diff --git a/e2e/cypress/fixtures/rate-limiting-902.yml b/e2e/cypress/fixtures/rate-limiting-902.yml new file mode 100644 index 000000000..69b4e9f11 --- /dev/null +++ b/e2e/cypress/fixtures/rate-limiting-902.yml @@ -0,0 +1,8 @@ + plugins: + - name: rate-limiting_902 + tags: [ns.newplatform] + config: + fault_tolerant: true + hide_client_headers: false + limit_by: service + minute: 30 \ No newline at end of file diff --git a/e2e/cypress/pageObjects/apiDirectory.ts b/e2e/cypress/pageObjects/apiDirectory.ts index e9eb39934..88a47ca23 100644 --- a/e2e/cypress/pageObjects/apiDirectory.ts +++ b/e2e/cypress/pageObjects/apiDirectory.ts @@ -19,9 +19,12 @@ class ApiDirectoryPage { addOrganizationBtn: string = '[data-testid="addOrganizationBtn"]' - createAccessRequest(product: any, app: any, accessRqst: any) { + createAccessRequest(product: any, app: any, accessRqst: any, elevatedAccess?: boolean) { cy.contains('a', product.name, { timeout: 10000 }).should('be.visible'); cy.contains(product.name).click() + if(elevatedAccess){ + cy.contains('For elevated access, please Request Access').should('be.visible'); + } cy.get(this.rqstAccessBtn).click() cy.get(this.appSelect).select(app.name) cy.get('[data-testid=access-rqst-app-env-' + product.environment + ']').click() diff --git a/e2e/cypress/pageObjects/consumers.ts b/e2e/cypress/pageObjects/consumers.ts index a5afb9d2b..11e383e0e 100644 --- a/e2e/cypress/pageObjects/consumers.ts +++ b/e2e/cypress/pageObjects/consumers.ts @@ -98,8 +98,6 @@ export default class ConsumersPage { cy.contains('span', 'Route').click({ force: true }) } cy.get(this.applyBtn).click() - // cy.contains('h2', 'ip-restriction').should('be.visible') - // cy.wait(500) cy.get(this.consumerDialogSaveBtn).click() cy.wait(1000) } diff --git a/e2e/cypress/pageObjects/products.ts b/e2e/cypress/pageObjects/products.ts index 4df354210..1883c9511 100644 --- a/e2e/cypress/pageObjects/products.ts +++ b/e2e/cypress/pageObjects/products.ts @@ -48,7 +48,7 @@ class Products { } createNewProduct(productName: string, env: string) { - cy.get(this.newProductBtn).click() + cy.get(this.newProductBtn).first().click() cy.get(this.productNameInput).type(productName) cy.get(`[data-testid=prd-env-${env}-radio]`).click() cy.get(this.createBtn).click() @@ -224,14 +224,6 @@ class Products { force: true, delay: 500 }) - // cy.get(this.catelogueDropDownMenu) - // .find('div') - // .find('p') - // .each(($e1, index, $list) => { - // if ($e1.text() === productName) { - // cy.wrap($e1).click() - // } - // }) this.updateProduct() } diff --git a/e2e/cypress/pageObjects/serviceAccounts.ts b/e2e/cypress/pageObjects/serviceAccounts.ts index 5999035d7..0bc7fbdf4 100644 --- a/e2e/cypress/pageObjects/serviceAccounts.ts +++ b/e2e/cypress/pageObjects/serviceAccounts.ts @@ -62,6 +62,21 @@ class ServiceAccountsPage { } }) } + + deleteServiceAccount(clientId : string) { + cy.wait(2000) + let namespaceText + cy.get(this.serviceAccountTbl).find('tr').each(($e1, index, $list) => { + namespaceText = $e1.find('td:nth-child(1)').text(); + cy.log('namespaceText --> '+namespaceText) + if (namespaceText===clientId) { + cy.wrap($e1).find('button').first().click() + cy.wrap($e1).find(this.serviceAcctDeleteBtn).first().click() + cy.get(this.deleteServiceAcctConfirmationBtn).click() + return false + } + }) + } } export default ServiceAccountsPage diff --git a/e2e/cypress/support/auth-commands.ts b/e2e/cypress/support/auth-commands.ts index 2af2260b2..81ba77095 100644 --- a/e2e/cypress/support/auth-commands.ts +++ b/e2e/cypress/support/auth-commands.ts @@ -472,18 +472,25 @@ Cypress.Commands.add('updatePluginFile', (filename: string, serviceName: string, }) }) -Cypress.Commands.add('updatePropertiesOfPluginFile', (filename: string, propertyName: string, propertyValue: any) => { + + +Cypress.Commands.add('updatePropertiesOfPluginFile', (filename: string, propertyName: any, propertyValue: any) => { cy.readFile('cypress/fixtures/' + filename).then((content: any) => { let obj = YAML.parse(content) const keys = Object.keys(obj); - Object.keys(obj.services).forEach(function (key, index) { - if (propertyName == "methods") { - obj.services[0].routes[0].methods = propertyValue - } - else { - obj.services[0].plugins[0].config[propertyName] = propertyValue - } - }); + if (propertyName === "config.anonymous") { + obj.plugins[0].config.anonymous = propertyValue + } + else { + Object.keys(obj.services).forEach(function (key, index) { + if (propertyName == "methods") { + obj.services[0].routes[0].methods = propertyValue + } + else { + obj.services[0].plugins[0].config[propertyName] = propertyValue + } + }); + } const yamlString = YAML.stringify(obj, 'utf8'); cy.writeFile('cypress/fixtures/' + filename, yamlString) }) diff --git a/e2e/cypress/support/global.d.ts b/e2e/cypress/support/global.d.ts index a1cadb0c9..19da26672 100644 --- a/e2e/cypress/support/global.d.ts +++ b/e2e/cypress/support/global.d.ts @@ -71,7 +71,9 @@ declare namespace Cypress { updatePluginFile (filename: string, serviceName: string, pluginFileName: string):Chainable> - updatePropertiesOfPluginFile(filename: string, propertyName: string, propertyValue: any):Chainable> + updateElementsInPluginFile(filename: string, elementName: string, elementValue: string):Chainable> + + updatePropertiesOfPluginFile(filename: string, propertyName: any, propertyValue: any):Chainable> keycloakLogin(username: string, password: string): Chainable diff --git a/e2e/cypress/tests/09-update-product-env/07-kong-public-auth.ts b/e2e/cypress/tests/09-update-product-env/07-kong-public-auth.ts new file mode 100644 index 000000000..12a48b816 --- /dev/null +++ b/e2e/cypress/tests/09-update-product-env/07-kong-public-auth.ts @@ -0,0 +1,110 @@ +import ApiDirectoryPage from '../../pageObjects/apiDirectory' +import ApplicationPage from '../../pageObjects/applications' +import ConsumersPage from '../../pageObjects/consumers' +import HomePage from '../../pageObjects/home' +import LoginPage from '../../pageObjects/login' +import MyAccessPage from '../../pageObjects/myAccess' +import Products from '../../pageObjects/products' + +describe('Verify for Kong Public Auth', () => { + const login = new LoginPage() + const apiDir = new ApiDirectoryPage() + const app = new ApplicationPage() + const myAccessPage = new MyAccessPage() + let consumerid: string + let consumerNumber: string + let existingAPIKey: string + var nameSpace: string + let userSession: string + const home = new HomePage() + const pd = new Products() + + before(() => { + cy.visit('/') + cy.deleteAllCookies() + cy.reload() + }) + + beforeEach(() => { + cy.preserveCookies() + cy.fixture('developer').as('developer') + cy.fixture('apiowner').as('apiowner') + cy.fixture('state/regen').as('regen') + cy.visit(login.path) + }) + + it('Authenticates api owner', () => { + cy.get('@apiowner').then(({ user }: any) => { + cy.login(user.credentials.username, user.credentials.password) + }) + }) + it('Activates the namespace', () => { + cy.getUserSession().then(() => { + cy.get('@apiowner').then(({ clientCredentials }: any) => { + nameSpace = clientCredentials.namespace + home.useNamespace(clientCredentials.namespace) + cy.get('@login').then(function (xhr: any) { + userSession = xhr.response.headers['x-auth-request-access-token'] + }) + }) + }) + }) + + it('Deactivate the service for Test environment', () => { + cy.visit(pd.path) + cy.get('@apiowner').then(({ clientCredentials }: any) => { + let product = clientCredentials.clientIdSecret_publicProfile.product + pd.deactivateService(product.name, product.environment.name, product.environment.config) + cy.wait(3000) + }) + }) + + it('Update the authorization scope from Kong ACL-API to Client Credential', () => { + cy.visit(pd.path) + cy.get('@apiowner').then(({ clientCredentials }: any) => { + let product = clientCredentials.clientIdSecret_publicProfile.product + pd.editProductEnvironment(product.name, product.environment.name) + pd.editProductEnvironmentConfig(product.environment.config) + }) + }) + + it('applies authorization plugin to service published to Kong Gateway', () => { + cy.get('@apiowner').then(({ clientCredentials }: any) => { + cy.publishApi('cc-service.yml', clientCredentials.namespace,true).then(() => { + cy.get('@publishAPIResponse').then((res: any) => { + cy.log(JSON.stringify(res.body)) + expect(res.body.message).to.contains("Sync successful") + }) + }) + }) + }) + + it('activate the service for Test environment', () => { + cy.visit(pd.path) + cy.get('@apiowner').then(({ clientCredentials }: any) => { + cy.wait(2000) + let product = clientCredentials.clientIdSecret_publicProfile.product + pd.activateService(product.name, product.environment.name, product.environment.config) + cy.wait(3000) + }) + }) + + it('Verify that API is accessible with out any credential', () => { + cy.readFile('cypress/fixtures/state/store.json').then((store_cred) => { + cy.get('@apiowner').then(({ clientCredentials }: any) => { + let product = clientCredentials.clientIdSecret_authProfile.product + cy.makeKongRequest(product.environment.config.serviceName, 'GET','').then((response) => { + cy.log(response) + expect(response.status).to.be.equal(200) + }) + }) + }) + }) + + after(() => { + cy.logout() + cy.clearLocalStorage({ log: true }) + cy.deleteAllCookies() + }) + +}) \ No newline at end of file diff --git a/e2e/cypress/tests/10-clear-resources/03-delete-service-acc.ts b/e2e/cypress/tests/10-clear-resources/03-delete-service-acc.ts new file mode 100644 index 000000000..205cbc26e --- /dev/null +++ b/e2e/cypress/tests/10-clear-resources/03-delete-service-acc.ts @@ -0,0 +1,58 @@ +import HomePage from '../../pageObjects/home' +import LoginPage from '../../pageObjects/login' +import NameSpacePage from '../../pageObjects/namespace' +import Products from '../../pageObjects/products' +import ServiceAccountsPage from '../../pageObjects/serviceAccounts' + + +describe('Create API Spec', () => { + const login = new LoginPage() + const home = new HomePage() + const sa = new ServiceAccountsPage() + const pd = new Products() + const ns = new NameSpacePage() + var nameSpace: string + let userSession: string + + before(() => { + cy.visit('/') + cy.deleteAllCookies() + cy.reload() + }) + + beforeEach(() => { + cy.preserveCookies() + cy.fixture('apiowner').as('apiowner') + cy.fixture('api').as('api') + // cy.visit(login.path) + }) + + it('authenticates Janis (api owner)', () => { + cy.get('@apiowner').then(({ user, namespace }: any) => { + cy.login(user.credentials.username, user.credentials.password) + cy.log('Logged in!') + home.useNamespace(namespace) + }) + }) + + it('Delete existing service account', () => { + cy.fixture('state/store').then((creds: any) => { + let cc = JSON.parse(creds.credentials) + const id = cc.clientId + cy.visit(sa.path) + sa.deleteServiceAccount(id) + }) + }) + + it('Verify that the service account is disabled', () => { + cy.fixture('state/store').then((creds: any) => { + let cc = JSON.parse(creds.credentials) + cy.getAccessToken(cc.clientId, cc.clientSecret).then(() => { + cy.get('@accessTokenResponse').then((token_res: any) => { + expect(token_res.status).to.be.equal(400) + expect(token_res.body.error).to.contains("unauthorized_client") + }) + }) + }) + }) +}) \ No newline at end of file diff --git a/e2e/cypress/tests/15-org-assignment/01-client-cred-team-access.ts b/e2e/cypress/tests/15-org-assignment/01-client-cred-team-access.ts index 8253994c9..6ac09b0c5 100644 --- a/e2e/cypress/tests/15-org-assignment/01-client-cred-team-access.ts +++ b/e2e/cypress/tests/15-org-assignment/01-client-cred-team-access.ts @@ -9,7 +9,6 @@ import ServiceAccountsPage from '../../pageObjects/serviceAccounts' import MyAccessPage from '../../pageObjects/myAccess' import ConsumersPage from '../../pageObjects/consumers' - describe('Add Organization to publish API', () => { const login = new LoginPage() const home = new HomePage() @@ -48,7 +47,6 @@ describe('Add Organization to publish API', () => { cy.visit(sa.path) cy.get('@apiowner').then(({ serviceAccount }: any) => { sa.createServiceAccount(serviceAccount.scopes) - cy.wait(6000) }) sa.saveServiceAcctCreds() }) From 970a73e1655c95d09052d34f77f0aac641144c58 Mon Sep 17 00:00:00 2001 From: nirajCITZ <94716060+nirajCITZ@users.noreply.github.com> Date: Thu, 11 May 2023 14:18:14 -0700 Subject: [PATCH 2/2] Cypress delete service acc (#805) * Added following scenarios: 1)Cypress test to verify free (Public) access 2)Cypress Test - Delete Service account 3)Cypress Test - Verify rate_limiting_902 and rate_limiting plugins by applying them to different level 4)Cypress Test for Org Admin * Added scenario for free elevated access rate limiting and update test execution sequence * Update authorization profile -inheritFrom scenario and update the execution order * Update free-elivated scenarios, added Link consumer to namespace scenarios and added test-dataid * Update free-elevated scenario --------- Co-authored-by: Niraj Patel --- e2e/cypress.config.ts | 2 +- e2e/cypress/fixtures/api.json | 2 +- .../manage-control-config-setting.json | 3 +- .../fixtures/service-plugin-key-auth-only.yml | 22 +- e2e/cypress/pageObjects/consumers.ts | 58 +++- e2e/cypress/pageObjects/myAccess.ts | 8 + e2e/cypress/pageObjects/namespaceAccess.ts | 1 - e2e/cypress/pageObjects/products.ts | 21 +- e2e/cypress/support/auth-commands.ts | 25 +- e2e/cypress/support/global.d.ts | 2 + .../tests/01-api-key/01-create-api.cy.ts | 7 + .../01-api-key/05-collect-credentials.cy.ts | 1 + .../08-apply-kong-api-only-consumer.cy.ts | 85 ------ ...09-kong-api-only-apply-rate-limiting.cy.ts | 58 ---- .../01-client-cred-team-access.cy.ts | 0 .../02-create_authorizarion_profile.cy.ts | 0 ...client-cred-create-api-prod-auth-pro.cy.ts | 0 .../04-cids-access-rqst.cy.ts | 0 .../05-cids-access-approve-api-rqst.cy.ts | 0 .../06-jwt-genkp-access-rqst.cy.ts | 0 ...07-jwt-genkp-access-approve-api-rqst.cy.ts | 0 .../08-jwks-url-gen-keys-access-rqst.cy.ts | 0 ...09-jwks-url-access-approval-api-rqst.cy.ts | 0 .../03-manage-labels/03-link-consumers.ts | 75 ++++++ .../01-gateway-service-details.cy.ts | 0 .../02-filter-gateway-service.cy.ts | 0 .../01-migrate-user-access.cy.ts | 0 .../01-api-key.cy.ts | 20 +- .../02-client-credentials.cy.ts | 0 .../01-ip-restriction.cy.ts | 0 .../02-rate-limiting.cy.ts | 0 ...03-kong-api-only-apply-rate-limiting.cy.ts | 248 ++++++++++++++++++ ...nt-role copy.ts => 03-read-client-role.ts} | 0 .../04-keycloak-shared-IDP-config.cy.ts | 66 +++++ ...s.cy.ts => 05-authorizationProfiles.cy.ts} | 0 .../{05-products.cy.ts => 06-products.cy.ts} | 0 ...directory.cy.ts => 07-api-directory.cy.ts} | 0 ...7-namespaces.cy.ts => 08-namespaces.cy.ts} | 0 local/feeder-init/organization-unit.yaml | 8 + .../link-consumer/link-consumer.tsx | 4 +- .../products-list/dataset-input.tsx | 2 +- 41 files changed, 517 insertions(+), 201 deletions(-) delete mode 100644 e2e/cypress/tests/01-api-key/08-apply-kong-api-only-consumer.cy.ts delete mode 100644 e2e/cypress/tests/01-api-key/09-kong-api-only-apply-rate-limiting.cy.ts rename e2e/cypress/tests/{04-client-credential-flow => 02-client-credential-flow}/01-client-cred-team-access.cy.ts (100%) rename e2e/cypress/tests/{04-client-credential-flow => 02-client-credential-flow}/02-create_authorizarion_profile.cy.ts (100%) rename e2e/cypress/tests/{04-client-credential-flow => 02-client-credential-flow}/03-client-cred-create-api-prod-auth-pro.cy.ts (100%) rename e2e/cypress/tests/{04-client-credential-flow => 02-client-credential-flow}/04-cids-access-rqst.cy.ts (100%) rename e2e/cypress/tests/{04-client-credential-flow => 02-client-credential-flow}/05-cids-access-approve-api-rqst.cy.ts (100%) rename e2e/cypress/tests/{04-client-credential-flow => 02-client-credential-flow}/06-jwt-genkp-access-rqst.cy.ts (100%) rename e2e/cypress/tests/{04-client-credential-flow => 02-client-credential-flow}/07-jwt-genkp-access-approve-api-rqst.cy.ts (100%) rename e2e/cypress/tests/{04-client-credential-flow => 02-client-credential-flow}/08-jwks-url-gen-keys-access-rqst.cy.ts (100%) rename e2e/cypress/tests/{04-client-credential-flow => 02-client-credential-flow}/09-jwks-url-access-approval-api-rqst.cy.ts (100%) create mode 100644 e2e/cypress/tests/03-manage-labels/03-link-consumers.ts rename e2e/cypress/tests/{05-gateway-services => 04-gateway-services}/01-gateway-service-details.cy.ts (100%) rename e2e/cypress/tests/{05-gateway-services => 04-gateway-services}/02-filter-gateway-service.cy.ts (100%) rename e2e/cypress/tests/{06-migrate-user => 05-migrate-user}/01-migrate-user-access.cy.ts (100%) rename e2e/cypress/tests/{07-refresh-credential => 06-refresh-credential}/01-api-key.cy.ts (83%) rename e2e/cypress/tests/{07-refresh-credential => 06-refresh-credential}/02-client-credentials.cy.ts (100%) rename e2e/cypress/tests/{02-manage-control => 07-manage-control}/01-ip-restriction.cy.ts (100%) rename e2e/cypress/tests/{02-manage-control => 07-manage-control}/02-rate-limiting.cy.ts (100%) create mode 100644 e2e/cypress/tests/07-manage-control/03-kong-api-only-apply-rate-limiting.cy.ts rename e2e/cypress/tests/08-client-role/{03-read-client-role copy.ts => 03-read-client-role.ts} (100%) create mode 100644 e2e/cypress/tests/16-aps-api/04-keycloak-shared-IDP-config.cy.ts rename e2e/cypress/tests/16-aps-api/{04-authorizationProfiles.cy.ts => 05-authorizationProfiles.cy.ts} (100%) rename e2e/cypress/tests/16-aps-api/{05-products.cy.ts => 06-products.cy.ts} (100%) rename e2e/cypress/tests/16-aps-api/{06-api-directory.cy.ts => 07-api-directory.cy.ts} (100%) rename e2e/cypress/tests/16-aps-api/{07-namespaces.cy.ts => 08-namespaces.cy.ts} (100%) diff --git a/e2e/cypress.config.ts b/e2e/cypress.config.ts index 9b30b00eb..023a06a0f 100644 --- a/e2e/cypress.config.ts +++ b/e2e/cypress.config.ts @@ -13,10 +13,10 @@ export default defineConfig({ config.specPattern=[ './cypress/tests/01-*/*.ts', './cypress/tests/02-*/*.ts', + './cypress/tests/06-*/*.ts', './cypress/tests/03-*/*.ts', './cypress/tests/04-*/*.ts', './cypress/tests/05-*/*.ts', - './cypress/tests/06-*/*.ts', './cypress/tests/07-*/*.ts', './cypress/tests/08-*/*.ts', './cypress/tests/09-*/*.ts', diff --git a/e2e/cypress/fixtures/api.json b/e2e/cypress/fixtures/api.json index 6f87b30c9..e7ae3668f 100644 --- a/e2e/cypress/fixtures/api.json +++ b/e2e/cypress/fixtures/api.json @@ -182,7 +182,7 @@ "mode": "auto", "environmentDetails": [ { - "environment": "dev", + "environment": "test", "issuerUrl": "http://keycloak.localtest.me:9080/auth/realms/master", "clientRegistration": "managed", "clientId": "gwa-api", diff --git a/e2e/cypress/fixtures/manage-control-config-setting.json b/e2e/cypress/fixtures/manage-control-config-setting.json index cecd9ef62..58be9e76d 100644 --- a/e2e/cypress/fixtures/manage-control-config-setting.json +++ b/e2e/cypress/fixtures/manage-control-config-setting.json @@ -2,7 +2,8 @@ "rateLimiting": { "requestPerHour_Consumer" : "1", "requestPerHour_Global" : "2", - "rateLimiting_hour": "25" + "rateLimiting_hour": "25", + "requestPerHour_Elevated" : "250" }, "ipRestriction" :{ "ipRange_valid" : "192.168.0.1/0", diff --git a/e2e/cypress/fixtures/service-plugin-key-auth-only.yml b/e2e/cypress/fixtures/service-plugin-key-auth-only.yml index 823116108..897d275a7 100644 --- a/e2e/cypress/fixtures/service-plugin-key-auth-only.yml +++ b/e2e/cypress/fixtures/service-plugin-key-auth-only.yml @@ -1,10 +1,12 @@ - plugins: - - name: key-auth - tags: [ ns.newplatform ] - protocols: [ http, https ] - config: - key_names: ["X-API-KEY"] - run_on_preflight: true - hide_credentials: true - key_in_body: false - +plugins: + - + name: key-auth + tags: + - ns.newplatform + protocols: + - http + - https + config: + key_names: + - x-api-key + anonymous: 1aaf2351-0622-4cc4-8d14-32e78771e620 diff --git a/e2e/cypress/pageObjects/consumers.ts b/e2e/cypress/pageObjects/consumers.ts index 11e383e0e..95e50f454 100644 --- a/e2e/cypress/pageObjects/consumers.ts +++ b/e2e/cypress/pageObjects/consumers.ts @@ -2,8 +2,12 @@ import { Assertion } from "chai" import { wrap } from "module" import dateformat from 'dateformat' import { checkElementExists } from "../support/e2e" +import { String } from "cypress/types/lodash" +import { StringLiteral } from "typescript" +import { truncate } from "fs/promises" export default class ConsumersPage { + path: string = '/manager/consumers' rateLimitHourInput: string = '[data-testid="ratelimit-hour-input"]' ipRestrictionAllowInput: string = '[data-testid="allow-ip-restriction-input-input"]' @@ -38,6 +42,9 @@ export default class ConsumersPage { removeRateLimitControlButton: string = '[data-testid="ratelimit-item-delete-btn-0"]' rateLimitRouteRadioBtn: string = '[data-testid="ratelimit-route-radio"]' consumerDialogCancelBtn: string = '[data-testid="edit-consumer-dialog-edit-cancel-btn"]' + linkConsumerToNamespaceBtn: string = '[data-testid="link-consumer-namespace"]' + userNameTxt: string = '[data-testid="link-consumer-username"]' + linkBtn: string = '[data-testid="link-consumer-link-btn"]' clickOnRateLimitingOption() { cy.get(this.rateLimitingOption, { timeout: 2000 }).click() @@ -65,14 +72,24 @@ export default class ConsumersPage { setRateLimiting(requestCount: string, scope = 'Service', policy = 'Local') { this.editConsumerDialog() cy.wait(2000) - if (!checkElementExists(this.rateLimitingOption)){ + if (!checkElementExists(this.rateLimitingOption)) { cy.get(this.consumerDialogCancelBtn).click() this.editConsumerDialog() } - // cy.wait(1000) + cy.wait(1000) + this.setRateLimitingWithOutConsumerID(requestCount, scope, policy) + // cy.wait(500) + cy.get(this.consumerDialogSaveBtn).click() + cy.get(this.consumerDialogSaveBtn, { timeout: 2000 }).should('not.exist') + cy.wait(3000) + } + + setRateLimitingWithOutConsumerID(requestCount: string, scope?: string, policy?: string) { + scope = scope || 'Service' + policy = policy || 'Local' this.clickOnRateLimitingOption() cy.wait(3000) - + cy.get(this.rateLimitHourInput, { timeout: 5000 }).click() cy.get(this.rateLimitHourInput, { timeout: 2000 }).type(requestCount) @@ -83,10 +100,6 @@ export default class ConsumersPage { cy.get(this.policyDropDown).select(policy, { force: true }).invoke('val') } cy.get(this.rateLimitingApplyBtn).click() - // cy.wait(500) - cy.get(this.consumerDialogSaveBtn).click() - cy.get(this.consumerDialogSaveBtn, { timeout: 2000 }).should('not.exist') - cy.wait(3000) } setAllowedIPAddress(allowIP: string, scope = 'Service') { @@ -149,7 +162,7 @@ export default class ConsumersPage { cy.verifyToastMessage("Access request approved") } - reviewThePendingRequest() : Boolean{ + reviewThePendingRequest(): Boolean { cy.wait(3000) var flag = false; cy.get("body").then($body => { @@ -308,7 +321,7 @@ export default class ConsumersPage { selectAuthorizationScope(scopes: any) { cy.contains("Authorization").click() scopes.forEach(function (scope: string) { - cy.get('[data-testid="client-scope-'+scope+'"]').click() + cy.get('[data-testid="client-scope-' + scope + '"]').click() cy.wait(1000) }) } @@ -316,8 +329,31 @@ export default class ConsumersPage { selectClientRole(roles: any) { cy.contains("Authorization").click() roles.forEach(function (role: string) { - cy.get('[data-testid="client-role-'+role.toLocaleLowerCase()+'"]').click() + cy.get('[data-testid="client-role-' + role.toLocaleLowerCase() + '"]').click() cy.wait(1000) }) } -} + + deleteConsumer(consumerID: any) { + cy.get(this.allConsumerTable).find('tr').each(($row, index) => { + cy.log($row.find('td:nth-child(1)').text()) + if ($row.find('td:nth-child(1)').text() == consumerID) { + cy.wrap($row).find('button').first().click() + cy.get('[data-testid="consumer-delete-menuitem"]').last().click({force:true}) + } + }) + } + + clickOnLinkConsumerToNamespaceBtn() { + cy.get(this.linkConsumerToNamespaceBtn).click({force:true}) + } + + linkTheConsumerToNamespace(consumerID: any) { + cy.get(this.userNameTxt).type(consumerID) + cy.get(this.linkBtn).click({force:true}) + } + + getText(){ + cy.get('[data-testid="all-consumer-control-tbl"]').find('tr').last().find('td').first().find('a').as('inputValue') + } +} \ No newline at end of file diff --git a/e2e/cypress/pageObjects/myAccess.ts b/e2e/cypress/pageObjects/myAccess.ts index e8fb9516e..9865f08b4 100644 --- a/e2e/cypress/pageObjects/myAccess.ts +++ b/e2e/cypress/pageObjects/myAccess.ts @@ -1,4 +1,5 @@ class myAccessPage { + generateSecretsBtn: string = '[data-testid=generate-secrets-button]' apiKyeValueTxt: string = '[data-testid=sa-new-creds-api-key]' clientId: string = '[data-testid=sa-new-creds-client-id]' @@ -12,6 +13,7 @@ class myAccessPage { regenerateCredentialBtn: string = '[data-testid=regenerate-credentials-btn]' regenerateCredentialCloseBtn: string = '[data-testid=regenerate-credentials-done-button]' collectCredentialsBtn: string = '[data-testid="generate-credentials-button"]' + clientIDValueTxt: string = '[data-testid="sa-new-creds-client-id"]' path: string = '/devportal/access' @@ -158,6 +160,12 @@ class myAccessPage { } }) } + + saveClientIDValue() { + cy.get(this.clientIDValueTxt).invoke('val').then(($clientID: any) => { + cy.saveState('clientID', $clientID) + }) + } } export default myAccessPage diff --git a/e2e/cypress/pageObjects/namespaceAccess.ts b/e2e/cypress/pageObjects/namespaceAccess.ts index e01b72ba3..bcc4d471e 100644 --- a/e2e/cypress/pageObjects/namespaceAccess.ts +++ b/e2e/cypress/pageObjects/namespaceAccess.ts @@ -29,7 +29,6 @@ class NamespaceAccessPage { // cy.get(this.userNameInput).type(editPermission.email); let accessRole: Array = editPermission.accessRole accessRole.forEach(function (accessName) { - debugger cy.contains("Permissions").next().find('li').find('label').each(($el, index, $list) => { // cy.wrap($el).find('input').uncheck({ force: true }); const textAccessRoleName = $el.text() diff --git a/e2e/cypress/pageObjects/products.ts b/e2e/cypress/pageObjects/products.ts index 1883c9511..31f030291 100644 --- a/e2e/cypress/pageObjects/products.ts +++ b/e2e/cypress/pageObjects/products.ts @@ -35,6 +35,7 @@ class Products { credentialIssuer: string = '[name="credentialIssuer"]' config: string | undefined publishAPI: string = '[id="orgEnabled"]' + messageForNotDataset: string = '[data-testid="no-result-for-dataset"]' getTestIdEnvName(env: string): string { switch (env) { @@ -110,16 +111,14 @@ class Products { authType === 'Oauth2 Authorization Code Flow' || authType === 'Oauth2 Client Credentials Flow' ) { - debugger let env = this.getTestIdEnvName(config.authIssuerEnv) cy.get('[name="credentialIssuer"]').select( `${config.authIssuer} (${env})` ) } - cy.get(this.envCfgOptText).type(config.optionalInstructions) + cy.get(this.envCfgOptText).clear().type(config.optionalInstructions) cy.get('[name="active"]').then($button => { - debugger if ($button.is(':disabled')) { flag = false } @@ -129,7 +128,6 @@ class Products { .as('checkbox') .invoke('is', ':checked') .then(checked => { - debugger if (invalid) { cy .get('@checkbox') @@ -148,7 +146,6 @@ class Products { .as('checkbox') .invoke('is', ':checked') .then(checked => { - debugger if (!isApproved) { cy .get('@checkbox') @@ -164,7 +161,6 @@ class Products { // cy.get(this.envCfgApprovalCheckbox).click() // cy.get(this.editPrdEnvConfigBtn).click() cy.wait(3000) - debugger if (flag) { cy.get(this.envCfgApplyChangesContinueBtn).click() } @@ -300,8 +296,7 @@ class Products { .get(this.publishAPI) .as('checkbox') .invoke('is', ':checked') - .then(checked => { - debugger + .then(checked => { if (status) { cy .get('@checkbox') @@ -314,6 +309,16 @@ class Products { } }); } + + checkMessageForNoDataset(productName: string,search_input: string ) { + this.editProduct(productName) + cy.get(this.catelogueDropDown).type(search_input + '{downArrow}' + '{enter}', { + force: true, + delay: 500 + }) + cy.get(this.messageForNotDataset).should('be.visible'); + + } } export default Products diff --git a/e2e/cypress/support/auth-commands.ts b/e2e/cypress/support/auth-commands.ts index 81ba77095..b259044d5 100644 --- a/e2e/cypress/support/auth-commands.ts +++ b/e2e/cypress/support/auth-commands.ts @@ -59,15 +59,6 @@ Cypress.Commands.add('login', (username: string, password: string, skipFlag = fa cy.get(login.loginSubmitButton).click() } - // log.end() - // cy.getLoginCallback().then(() => { - // cy.get('@login1').should((response :any) => { - // debugger - // if (response.status == 403) - // cy.wait(60000); - // cy.log("Trigger the block") - // }) - // }) if (!skipFlag) { cy.get(home.nsDropdown, { timeout: 6000 }).then(($el) => { expect($el).to.exist @@ -87,6 +78,14 @@ Cypress.Commands.add('keycloakLogin', (username: string, password: string) => { cy.get(login.loginSubmitButton).click() }) +Cypress.Commands.add('getLastConsumerID',() =>{ + let id : any + cy.get('[data-testid="all-consumer-control-tbl"]').find('tr').last().find('td').first().find('a').then(($text)=>{ + id = $text.text() + return id + }) +}) + Cypress.Commands.add('resetCredential', (accessRole: string) => { const login = new LoginPage() const home = new HomePage() @@ -291,7 +290,11 @@ Cypress.Commands.add('makeKongRequest', (serviceName: string, methodType: string let authorization cy.fixture('state/regen').then((creds: any) => { cy.wait(2000) - let token = key || creds.apikey + let token = key + if (key==undefined) + { + token = creds.apikey + } const service = serviceName cy.log("Token->" + token) return cy.request({ @@ -354,7 +357,7 @@ Cypress.Commands.add('updateKongPlugin', (pluginName: string, name: string, endP let endpoint if (pluginName == '') endpoint = 'plugins' - else + else if(id !== undefined) endpoint = pluginName.toLowerCase() + '/' + id.toString() + '/' + 'plugins' endpoint = (typeof endPoint !== 'undefined') ? endPoint : endpoint body = config[name] diff --git a/e2e/cypress/support/global.d.ts b/e2e/cypress/support/global.d.ts index 19da26672..734da1e79 100644 --- a/e2e/cypress/support/global.d.ts +++ b/e2e/cypress/support/global.d.ts @@ -79,6 +79,8 @@ declare namespace Cypress { selectLoginOptions(username: string): Chainable + getLastConsumerID(): Chainable + // isProductDisplay(productName: string, expResult : boolean) :Chainable> } } diff --git a/e2e/cypress/tests/01-api-key/01-create-api.cy.ts b/e2e/cypress/tests/01-api-key/01-create-api.cy.ts index 0149e41d4..5e1abba9c 100644 --- a/e2e/cypress/tests/01-api-key/01-create-api.cy.ts +++ b/e2e/cypress/tests/01-api-key/01-create-api.cy.ts @@ -86,6 +86,13 @@ describe('Create API Spec', () => { }) }) + it('Verify the message when no dataset is linked to BCDC', () => { + cy.visit(pd.path) + cy.get('@apiowner').then(({ product }: any) => { + pd.checkMessageForNoDataset(product.name,"health") + }) + }) + it('update the Dataset in BC Data Catelogue to appear the API in the Directory', () => { cy.visit(pd.path) cy.get('@apiowner').then(({ product }: any) => { diff --git a/e2e/cypress/tests/01-api-key/05-collect-credentials.cy.ts b/e2e/cypress/tests/01-api-key/05-collect-credentials.cy.ts index 2d381b69b..d70aaafe0 100644 --- a/e2e/cypress/tests/01-api-key/05-collect-credentials.cy.ts +++ b/e2e/cypress/tests/01-api-key/05-collect-credentials.cy.ts @@ -40,6 +40,7 @@ describe('Collect credential Spec', () => { myAccessPage.clickOnCollectCredentialButton() myAccessPage.clickOnGenerateSecretButton() cy.contains("API Key").should('be.visible') + myAccessPage.saveClientIDValue() myAccessPage.saveAPIKeyValue() }) diff --git a/e2e/cypress/tests/01-api-key/08-apply-kong-api-only-consumer.cy.ts b/e2e/cypress/tests/01-api-key/08-apply-kong-api-only-consumer.cy.ts deleted file mode 100644 index da8205eef..000000000 --- a/e2e/cypress/tests/01-api-key/08-apply-kong-api-only-consumer.cy.ts +++ /dev/null @@ -1,85 +0,0 @@ -describe('Apply Kong API key only plugin', () => { - var consumerID: string - var consumerKey: string - var pluginID: string - - beforeEach(() => { - cy.preserveCookies() - cy.fixture('access-manager').as('access-manager') - cy.fixture('developer').as('developer') - cy.fixture('apiowner').as('apiowner') - cy.fixture('state/store').as('store') - }) - - it('Apply Key-auth only authorization plugin to Kong Gateway', () => { - cy.get('@apiowner').then(({ namespace, product }: any) => { - cy.updatePluginFile('service-plugin.yml',product.environment.config.serviceName,'service-plugin-key-auth-only.yml') - cy.publishApi('service-plugin.yml', namespace).then(() => { - cy.get('@publishAPIResponse').then((res: any) => { - cy.log(JSON.stringify(res.body)) - }) - }) - }) - }) - - it('Get the plugin ID of Key-auth plugin', () => { - cy.makeKongGatewayRequest('plugins', '', 'GET').then((response) => { - expect(response.status).to.be.equal(200) - pluginID = _.get((_.filter(response.body.data,["name","key-auth"]))[0],'id') - }) - }) - - it('Create a new consumer and save the consumer Id', () => { - cy.makeKongGatewayRequest('consumers', 'createConsumer', 'POST').then((response) => { - expect(response.status).to.be.equal(201) - consumerID = response.body.id - cy.saveState("consumersid", consumerID) - }) - }) - - it('Create a key for the newly created consumer', () => { - const endpoint = 'consumers/' + consumerID + '/key-auth' - cy.makeKongGatewayRequest(endpoint, '', 'POST').then((response) => { - expect(response.status).to.be.equal(201) - consumerKey = response.body.key - cy.saveState("consumerkey", consumerKey) - }) - }) - - it('Update the Kong key-auth plugin the new consumer', () => { - cy.saveState("config.anonymous", consumerID) - cy.updateKongPlugin('', 'keyAuth', 'plugins/' + pluginID, 'PATCH').then((response) => { - expect(response.status).to.be.equal(200) - }) - }) -}) - -describe('Check the API key for free and elevated access', () => { - - beforeEach(() => { - cy.preserveCookies() - cy.fixture('apiowner').as('apiowner') - cy.fixture('state/store').as('store') - }) - - it('Verify the service is accessibale with API key for free access', () => { - cy.get('@apiowner').then(async ({ product }: any) => { - cy.fixture('state/store').then((creds: any) => { - const key = creds.consumerKey - cy.makeKongRequest(product.environment.config.serviceName, 'GET', key).then((response) => { - expect(response.status).to.be.equal(200) - }) - }) - }) - }) - - it('Verify the service is accessible with API key for elevated access', () => { - cy.get('@apiowner').then(async ({ product }: any) => { - cy.makeKongRequest(product.environment.config.serviceName, 'GET').then((response) => { - expect(response.status).to.be.equal(200) - }) - }) - }) -}) - - diff --git a/e2e/cypress/tests/01-api-key/09-kong-api-only-apply-rate-limiting.cy.ts b/e2e/cypress/tests/01-api-key/09-kong-api-only-apply-rate-limiting.cy.ts deleted file mode 100644 index 6ecf3fbbd..000000000 --- a/e2e/cypress/tests/01-api-key/09-kong-api-only-apply-rate-limiting.cy.ts +++ /dev/null @@ -1,58 +0,0 @@ - -describe('Check the API key for free and elevated access', () => { - - beforeEach(() => { - cy.preserveCookies() - cy.fixture('apiowner').as('apiowner') - cy.fixture('state/store').as('store') - }) - - it('Verify the service is accessibale with API key for free access', () => { - cy.get('@apiowner').then(async ({ product }: any) => { - cy.fixture('state/store').then((creds: any) => { - const key = creds.consumerKey - cy.makeKongRequest(product.environment.config.serviceName, 'GET', key).then((response) => { - expect(response.status).to.be.equal(200) - }) - }) - }) - }) - - it('Verify the service is accessible with API key for elevated access', () => { - cy.get('@apiowner').then(async ({ product }: any) => { - cy.fixture('state/store').then((creds: any) => { - cy.makeKongRequest(product.environment.config.serviceName, 'GET').then((response) => { - expect(response.status).to.be.equal(200) - }) - }) - }) - }) -}) - -describe('Apply Rate limiting for Free Access', () => { - - beforeEach(() => { - cy.preserveCookies() - cy.fixture('apiowner').as('apiowner') - cy.fixture('state/store').as('store') - }) - - it('set api rate limit to free access', () => { - cy.updateKongPlugin('consumers', 'rateLimitingConsumer').then((response) => { - expect(response.status).to.be.equal(201) - }) - }) - - it('Verify the rate limiting is applied for free access', () => { - cy.get('@apiowner').then(async ({ product }: any) => { - cy.fixture('state/store').then((creds: any) => { - const key = creds.consumerkey - cy.makeKongRequest(product.environment.config.serviceName, 'GET', key).then((response) => { - expect(response.status).to.be.equal(200) - expect(parseInt(response.headers["x-ratelimit-remaining-hour"])).to.be.equal(99) - }) - }) - }) - }) - -}) diff --git a/e2e/cypress/tests/04-client-credential-flow/01-client-cred-team-access.cy.ts b/e2e/cypress/tests/02-client-credential-flow/01-client-cred-team-access.cy.ts similarity index 100% rename from e2e/cypress/tests/04-client-credential-flow/01-client-cred-team-access.cy.ts rename to e2e/cypress/tests/02-client-credential-flow/01-client-cred-team-access.cy.ts diff --git a/e2e/cypress/tests/04-client-credential-flow/02-create_authorizarion_profile.cy.ts b/e2e/cypress/tests/02-client-credential-flow/02-create_authorizarion_profile.cy.ts similarity index 100% rename from e2e/cypress/tests/04-client-credential-flow/02-create_authorizarion_profile.cy.ts rename to e2e/cypress/tests/02-client-credential-flow/02-create_authorizarion_profile.cy.ts diff --git a/e2e/cypress/tests/04-client-credential-flow/03-client-cred-create-api-prod-auth-pro.cy.ts b/e2e/cypress/tests/02-client-credential-flow/03-client-cred-create-api-prod-auth-pro.cy.ts similarity index 100% rename from e2e/cypress/tests/04-client-credential-flow/03-client-cred-create-api-prod-auth-pro.cy.ts rename to e2e/cypress/tests/02-client-credential-flow/03-client-cred-create-api-prod-auth-pro.cy.ts diff --git a/e2e/cypress/tests/04-client-credential-flow/04-cids-access-rqst.cy.ts b/e2e/cypress/tests/02-client-credential-flow/04-cids-access-rqst.cy.ts similarity index 100% rename from e2e/cypress/tests/04-client-credential-flow/04-cids-access-rqst.cy.ts rename to e2e/cypress/tests/02-client-credential-flow/04-cids-access-rqst.cy.ts diff --git a/e2e/cypress/tests/04-client-credential-flow/05-cids-access-approve-api-rqst.cy.ts b/e2e/cypress/tests/02-client-credential-flow/05-cids-access-approve-api-rqst.cy.ts similarity index 100% rename from e2e/cypress/tests/04-client-credential-flow/05-cids-access-approve-api-rqst.cy.ts rename to e2e/cypress/tests/02-client-credential-flow/05-cids-access-approve-api-rqst.cy.ts diff --git a/e2e/cypress/tests/04-client-credential-flow/06-jwt-genkp-access-rqst.cy.ts b/e2e/cypress/tests/02-client-credential-flow/06-jwt-genkp-access-rqst.cy.ts similarity index 100% rename from e2e/cypress/tests/04-client-credential-flow/06-jwt-genkp-access-rqst.cy.ts rename to e2e/cypress/tests/02-client-credential-flow/06-jwt-genkp-access-rqst.cy.ts diff --git a/e2e/cypress/tests/04-client-credential-flow/07-jwt-genkp-access-approve-api-rqst.cy.ts b/e2e/cypress/tests/02-client-credential-flow/07-jwt-genkp-access-approve-api-rqst.cy.ts similarity index 100% rename from e2e/cypress/tests/04-client-credential-flow/07-jwt-genkp-access-approve-api-rqst.cy.ts rename to e2e/cypress/tests/02-client-credential-flow/07-jwt-genkp-access-approve-api-rqst.cy.ts diff --git a/e2e/cypress/tests/04-client-credential-flow/08-jwks-url-gen-keys-access-rqst.cy.ts b/e2e/cypress/tests/02-client-credential-flow/08-jwks-url-gen-keys-access-rqst.cy.ts similarity index 100% rename from e2e/cypress/tests/04-client-credential-flow/08-jwks-url-gen-keys-access-rqst.cy.ts rename to e2e/cypress/tests/02-client-credential-flow/08-jwks-url-gen-keys-access-rqst.cy.ts diff --git a/e2e/cypress/tests/04-client-credential-flow/09-jwks-url-access-approval-api-rqst.cy.ts b/e2e/cypress/tests/02-client-credential-flow/09-jwks-url-access-approval-api-rqst.cy.ts similarity index 100% rename from e2e/cypress/tests/04-client-credential-flow/09-jwks-url-access-approval-api-rqst.cy.ts rename to e2e/cypress/tests/02-client-credential-flow/09-jwks-url-access-approval-api-rqst.cy.ts diff --git a/e2e/cypress/tests/03-manage-labels/03-link-consumers.ts b/e2e/cypress/tests/03-manage-labels/03-link-consumers.ts new file mode 100644 index 000000000..446dd1bd8 --- /dev/null +++ b/e2e/cypress/tests/03-manage-labels/03-link-consumers.ts @@ -0,0 +1,75 @@ +import ConsumersPage from '../../pageObjects/consumers' +import LoginPage from '../../pageObjects/login' +import HomePage from '../../pageObjects/home' +import ProductPage from '../../pageObjects/products' + +describe('Link Consumers to Namespace', () => { + const login = new LoginPage() + const consumers = new ConsumersPage() + const home = new HomePage() + let consumerID: any + + before(() => { + cy.visit('/') + cy.deleteAllCookies() + cy.reload() + cy.getServiceOrRouteID('services') + cy.getServiceOrRouteID('routes') + }) + + beforeEach(() => { + cy.preserveCookies() + cy.fixture('access-manager').as('access-manager') + cy.fixture('apiowner').as('apiowner') + cy.fixture('developer').as('developer') + cy.fixture('state/store').as('store') + // cy.visit(login.path) + }) + + it('authenticates Mark (Access-Manager)', () => { + cy.get('@access-manager').then(({ user, namespace }: any) => { + cy.login(user.credentials.username, user.credentials.password) + home.useNamespace(namespace); + }) + }) + + it('Navigate to Consumer Page', () => { + cy.visit(consumers.path); + cy.wait(5000) + }) + + it('Get the consumer ID from the list', () => { + // cy.getLastConsumerID().then((title)=>{ + // consumerID = title + // }) + cy.wrap(consumers).its('inputValue').then(inputValue => { + consumerID = inputValue.text() + }) + }) + + it('Delete the consumer ID from the list', () => { + consumers.deleteConsumer(consumerID) + }) + + // it('Click on "Link Consumers to Namespace" button', () => { + // consumers.clickOnLinkConsumerToNamespaceBtn() + // }) + + // it('Link the delete consumer to the Namespace', () => { + // consumers.linkTheConsumerToNamespace(consumerID) + + // }) + + // it('Verify that the consumer is linked to the namespace', () => { + // cy.getLastConsumerID().then((title)=>{ + // expect(title).to.equal(consumerID) + // }) + // }) + + after(() => { + cy.logout() + cy.clearLocalStorage({ log: true }) + cy.deleteAllCookies() + }) + +}) \ No newline at end of file diff --git a/e2e/cypress/tests/05-gateway-services/01-gateway-service-details.cy.ts b/e2e/cypress/tests/04-gateway-services/01-gateway-service-details.cy.ts similarity index 100% rename from e2e/cypress/tests/05-gateway-services/01-gateway-service-details.cy.ts rename to e2e/cypress/tests/04-gateway-services/01-gateway-service-details.cy.ts diff --git a/e2e/cypress/tests/05-gateway-services/02-filter-gateway-service.cy.ts b/e2e/cypress/tests/04-gateway-services/02-filter-gateway-service.cy.ts similarity index 100% rename from e2e/cypress/tests/05-gateway-services/02-filter-gateway-service.cy.ts rename to e2e/cypress/tests/04-gateway-services/02-filter-gateway-service.cy.ts diff --git a/e2e/cypress/tests/06-migrate-user/01-migrate-user-access.cy.ts b/e2e/cypress/tests/05-migrate-user/01-migrate-user-access.cy.ts similarity index 100% rename from e2e/cypress/tests/06-migrate-user/01-migrate-user-access.cy.ts rename to e2e/cypress/tests/05-migrate-user/01-migrate-user-access.cy.ts diff --git a/e2e/cypress/tests/07-refresh-credential/01-api-key.cy.ts b/e2e/cypress/tests/06-refresh-credential/01-api-key.cy.ts similarity index 83% rename from e2e/cypress/tests/07-refresh-credential/01-api-key.cy.ts rename to e2e/cypress/tests/06-refresh-credential/01-api-key.cy.ts index 753e6960b..bb494f1b4 100644 --- a/e2e/cypress/tests/07-refresh-credential/01-api-key.cy.ts +++ b/e2e/cypress/tests/06-refresh-credential/01-api-key.cy.ts @@ -22,7 +22,7 @@ describe('Regenerate Credential for API Key', () => { cy.preserveCookies() cy.fixture('developer').as('developer') cy.fixture('apiowner').as('apiowner') - cy.fixture('state/regen').as('regen') + cy.fixture('state/store').as('store') cy.visit(login.path) }) @@ -33,22 +33,20 @@ describe('Regenerate Credential for API Key', () => { }) it('Get the consumer id based on consumer number', () => { - cy.get('@regen').then((creds: any) => { - const consumerNumber = creds.consumernumber + cy.get('@store').then(({clientid}: any) => { + debugger cy.makeKongGatewayRequest('consumers', '', 'GET').then((response) => { expect(response.status).to.be.equal(200) - consumerid = Cypress._.get((Cypress._.filter(response.body.data, ["custom_id", consumerNumber]))[0], 'id') + consumerid = Cypress._.get((Cypress._.filter(response.body.data, ["custom_id", clientid]))[0], 'id') }) }) }) it('Get current API Key', () => { - cy.get('@regen').then((creds: any) => { - cy.get('@developer').then(({ user }: any) => { - cy.makeKongGatewayRequest('consumers/' + consumerid + '/key-auth', '', 'GET').then((response: any) => { - expect(response.status).to.be.equal(200) - existingAPIKey = response.body.data[0].key - }) + cy.get('@developer').then(({ user }: any) => { + cy.makeKongGatewayRequest('consumers/' + consumerid + '/key-auth', '', 'GET').then((response: any) => { + expect(response.status).to.be.equal(200) + existingAPIKey = response.body.data[0].key }) }) }) @@ -74,11 +72,9 @@ describe('Regenerate Credential for API Key', () => { }) it('Verify that only one API key(new key) is set to the consumer in Kong gateway', () => { - cy.get('@regen').then((creds: any) => { cy.makeKongGatewayRequest('consumers/' + consumerid + '/key-auth', '', 'GET').then((response: any) => { expect(response.status).to.be.equal(200) expect(response.body.data.length).to.be.equal(1) - }) }) }) diff --git a/e2e/cypress/tests/07-refresh-credential/02-client-credentials.cy.ts b/e2e/cypress/tests/06-refresh-credential/02-client-credentials.cy.ts similarity index 100% rename from e2e/cypress/tests/07-refresh-credential/02-client-credentials.cy.ts rename to e2e/cypress/tests/06-refresh-credential/02-client-credentials.cy.ts diff --git a/e2e/cypress/tests/02-manage-control/01-ip-restriction.cy.ts b/e2e/cypress/tests/07-manage-control/01-ip-restriction.cy.ts similarity index 100% rename from e2e/cypress/tests/02-manage-control/01-ip-restriction.cy.ts rename to e2e/cypress/tests/07-manage-control/01-ip-restriction.cy.ts diff --git a/e2e/cypress/tests/02-manage-control/02-rate-limiting.cy.ts b/e2e/cypress/tests/07-manage-control/02-rate-limiting.cy.ts similarity index 100% rename from e2e/cypress/tests/02-manage-control/02-rate-limiting.cy.ts rename to e2e/cypress/tests/07-manage-control/02-rate-limiting.cy.ts diff --git a/e2e/cypress/tests/07-manage-control/03-kong-api-only-apply-rate-limiting.cy.ts b/e2e/cypress/tests/07-manage-control/03-kong-api-only-apply-rate-limiting.cy.ts new file mode 100644 index 000000000..f3d0f283b --- /dev/null +++ b/e2e/cypress/tests/07-manage-control/03-kong-api-only-apply-rate-limiting.cy.ts @@ -0,0 +1,248 @@ +import _ = require("cypress/types/lodash") +import ApiDirectoryPage from "../../pageObjects/apiDirectory" +import ApplicationPage from "../../pageObjects/applications" +import HomePage from "../../pageObjects/home" +import LoginPage from "../../pageObjects/login" +import Products from "../../pageObjects/products" +import MyAccessPage from '../../pageObjects/myAccess' +import ConsumersPage from "../../pageObjects/consumers" +let apiKey: any + +describe('Apply Kong API key only plugin', () => { + var consumerID: string + var consumerKey: string + var pluginID: string + var serviceID: string + var nameSpace: string + let userSession: string + const home = new HomePage() + const pd = new Products() + + before(() => { + cy.visit('/') + cy.deleteAllCookies() + cy.reload() + }) + + beforeEach(() => { + cy.preserveCookies() + cy.fixture('access-manager').as('access-manager') + cy.fixture('apiowner').as('apiowner') + cy.fixture('developer').as('developer') + cy.fixture('state/store').as('store') + }) + + it('Authenticates api owner', () => { + cy.get('@apiowner').then(({ user }: any) => { + cy.login(user.credentials.username, user.credentials.password) + }) + }) + + it('Activates the namespace', () => { + cy.getUserSession().then(() => { + cy.get('@apiowner').then(({ namespace }: any) => { + nameSpace = namespace + home.useNamespace(namespace) + }) + }) + }) + + it('Deactivate the service for Test environment', () => { + cy.visit(pd.path) + cy.get('@apiowner').then(({ product }: any) => { + pd.deactivateService(product.name, product.environment.name, product.environment.config) + cy.wait(3000) + }) + }) + + it('Create a new consumer and save the consumer Id', () => { + cy.makeKongGatewayRequest('consumers', 'createConsumer', 'POST').then((response) => { + expect(response.status).to.be.equal(201) + consumerID = response.body.id + cy.saveState("consumersid", consumerID) + }) + }) + + it('Set Consumer ID to key auth anonymous config', () => { + cy.updatePropertiesOfPluginFile('service-plugin-key-auth-only.yml', 'config.anonymous', consumerID) + }) + + it('Update the authorization scope from Kong ACL-API to Kong API Only', () => { + cy.visit(pd.path) + cy.get('@apiowner').then(({ clientCredentials }: any) => { + let product = clientCredentials.KongApiOnly.product + pd.editProductEnvironment(product.name, product.environment.name) + pd.editProductEnvironmentConfig(product.environment.config) + }) + }) + + it('Apply Key-auth only authorization plugin to Kong Gateway', () => { + cy.get('@apiowner').then(({ namespace, product }: any) => { + cy.updatePluginFile('service-plugin.yml', product.environment.config.serviceName, 'service-plugin-key-auth-only.yml') + cy.publishApi('service-plugin.yml', namespace).then(() => { + cy.get('@publishAPIResponse').then((res: any) => { + cy.log(JSON.stringify(res.body)) + }) + }) + }) + }) + + it('activate the service for Dev environment', () => { + cy.visit(pd.path) + cy.get('@apiowner').then(({ product }: any) => { + // pd.editProductEnvironment(product.name, product.environment.name) + pd.activateService(product.name, product.environment.name, product.environment.config) + cy.wait(3000) + }) + }) + + it('Apply Rate limiting on free access', () => { + cy.updateKongPlugin('consumers', 'rateLimitingConsumer', 'consumers/'+consumerID+'/plugins').then((response) => { + expect(response.status).to.be.equal(201) + }) + }) +}) + +describe('Check the API key for free access', () => { + + beforeEach(() => { + cy.preserveCookies() + cy.fixture('apiowner').as('apiowner') + cy.fixture('state/store').as('store') + }) + + it('Verify the service is accessibale with API key for free access', () => { + cy.get('@apiowner').then(async ({ product }: any) => { + cy.fixture('state/store').then((creds: any) => { + const key = creds.consumerKey + cy.makeKongRequest(product.environment.config.serviceName, 'GET','').then((response) => { + expect(response.status).to.be.equal(200) + expect(parseInt(response.headers["x-ratelimit-remaining-hour"])).to.be.equal(99) + }) + }) + }) + }) +}) + +describe('Check the API key for Elevated access', () => { + + const login = new LoginPage() + const apiDir = new ApiDirectoryPage() + const app = new ApplicationPage() + const ma = new MyAccessPage() + + before(() => { + cy.visit('/') + cy.deleteAllCookies() + cy.reload() + }) + + beforeEach(() => { + cy.preserveCookies() + cy.fixture('developer').as('developer') + // cy.visit(login.path) + }) + + it('Developer logs in', () => { + cy.get('@developer').then(({ user }: any) => { + cy.login(user.credentials.username, user.credentials.password) + }) + }) + + it('creates an application', () => { + cy.visit(app.path) + cy.get('@developer').then(({ elevatedAccess }: any) => { + app.createApplication(elevatedAccess.application) + }) + }) + + it('Collect the credentials', () => { + cy.visit(apiDir.path) + cy.get('@developer').then(async ({ elevatedAccess, accessRequest }: any) => { + apiDir.createAccessRequest(elevatedAccess.product, elevatedAccess.application, accessRequest, true) + ma.clickOnGenerateSecretButton() + cy.contains("API Key").should('be.visible') + cy.get(ma.apiKyeValueTxt).invoke('val').then(($apiKey: any) => { + apiKey = $apiKey + }) + ma.saveAPIKeyValue() + }) + }) + + after(() => { + cy.logout() + cy.clearLocalStorage({ log: true }) + cy.deleteAllCookies() + }) +}) + +describe('Approve Pending Request Spec', () => { + const login = new LoginPage() + const consumers = new ConsumersPage() + const home = new HomePage() + + before(() => { + cy.visit('/') + cy.deleteAllCookies() + cy.reload() + cy.getServiceOrRouteID('services') + cy.getServiceOrRouteID('routes') + }) + + beforeEach(() => { + cy.preserveCookies() + cy.fixture('access-manager').as('access-manager') + cy.fixture('manage-control-config-setting').as('manage-control-config-setting') + cy.fixture('apiowner').as('apiowner') + cy.fixture('developer').as('developer') + cy.fixture('state/store').as('store') + // cy.visit(login.path) + }) + + it('authenticates Mark (Access-Manager)', () => { + cy.get('@access-manager').then(({ user, namespace }: any) => { + cy.login(user.credentials.username, user.credentials.password) + home.useNamespace(namespace); + }) + }) + + it('verify the request details', () => { + cy.get('@apiowner').then(({ product }: any) => { + cy.get('@developer').then(({ accessRequest, elevatedAccess }: any) => { + cy.visit(consumers.path); + consumers.reviewThePendingRequest() + consumers.verifyRequestDetails(product, accessRequest, elevatedAccess.application) + }) + }) + }) + + it('Navigate to Control Tab', () => { + cy.contains('Controls').click() + }) + + it('Set Rate Limiting', () => { + cy.get('@manage-control-config-setting').then(({ rateLimiting }: any) => { + consumers.setRateLimitingWithOutConsumerID(rateLimiting.requestPerHour_Elevated, 'Route') + }) + }) + + it('approves an access request', () => { + consumers.approvePendingRequest() + }) + + it('Verify that API is accessible with the generated API Key', () => { + cy.get('@apiowner').then(async ({ product }: any) => { + cy.makeKongRequest(product.environment.config.serviceName, 'GET', apiKey).then((response) => { + expect(response.status).to.be.equal(200) + expect(parseInt(response.headers["x-ratelimit-remaining-hour"])).to.be.equal(249) + }) + }) + }) + + after(() => { + cy.logout() + cy.clearLocalStorage({ log: true }) + cy.deleteAllCookies() + }) + +}) diff --git a/e2e/cypress/tests/08-client-role/03-read-client-role copy.ts b/e2e/cypress/tests/08-client-role/03-read-client-role.ts similarity index 100% rename from e2e/cypress/tests/08-client-role/03-read-client-role copy.ts rename to e2e/cypress/tests/08-client-role/03-read-client-role.ts diff --git a/e2e/cypress/tests/16-aps-api/04-keycloak-shared-IDP-config.cy.ts b/e2e/cypress/tests/16-aps-api/04-keycloak-shared-IDP-config.cy.ts new file mode 100644 index 000000000..ed2fd5f48 --- /dev/null +++ b/e2e/cypress/tests/16-aps-api/04-keycloak-shared-IDP-config.cy.ts @@ -0,0 +1,66 @@ +import ApiDirectoryPage from '../../pageObjects/apiDirectory' +import ApplicationPage from '../../pageObjects/applications' +import AuthorizationProfile from '../../pageObjects/authProfile' +import ConsumersPage from '../../pageObjects/consumers' +import HomePage from '../../pageObjects/home' +import keycloakGroupPage from '../../pageObjects/keycloakGroup' +import KeycloakUserGroupPage from '../../pageObjects/keycloakUserGroup' +import LoginPage from '../../pageObjects/login' +import MyAccessPage from '../../pageObjects/myAccess' +import Products from '../../pageObjects/products' + +describe('Apply Shared IDP config at Keycloak user group', () => { + const userGroups = new KeycloakUserGroupPage() + const groups = new keycloakGroupPage() + var nameSpace: string + const home = new HomePage() + const authProfile = new AuthorizationProfile() + + before(() => { + cy.visit(Cypress.env('KEYCLOAK_URL')) + cy.deleteAllCookies() + cy.reload() + }) + + beforeEach(() => { + cy.preserveCookies() + cy.fixture('developer').as('developer') + cy.fixture('apiowner').as('apiowner') + cy.fixture('state/regen').as('regen') + cy.fixture('admin').as('admin') + }) + + it('Authenticates Admin owner', () => { + cy.get('@admin').then(({ user }: any) => { + cy.contains('Administration Console').click({force:true}) + cy.keycloakLogin(user.credentials.username, user.credentials.password) + }) + }) + + it('Navigate to User Groups', () => { + cy.contains('Groups').click() + }) + + it('Edit the namespace from the tree view', () => { + cy.get('@apiowner').then(({ apiTest }: any) => { + cy.contains(apiTest.namespace).click() + userGroups.clickOnEditButton() + }) + }) + + it('Navigate to attribute tab', () => { + userGroups.selectTab('Attributes') + }) + + it('Set the Attributes', () => { + groups.setAttribute('perm-protected-ns','allow') + }) + + after(() => { + cy.keycloakLogout() + cy.clearLocalStorage({ log: true }) + cy.deleteAllCookies() + }) + +}) + diff --git a/e2e/cypress/tests/16-aps-api/04-authorizationProfiles.cy.ts b/e2e/cypress/tests/16-aps-api/05-authorizationProfiles.cy.ts similarity index 100% rename from e2e/cypress/tests/16-aps-api/04-authorizationProfiles.cy.ts rename to e2e/cypress/tests/16-aps-api/05-authorizationProfiles.cy.ts diff --git a/e2e/cypress/tests/16-aps-api/05-products.cy.ts b/e2e/cypress/tests/16-aps-api/06-products.cy.ts similarity index 100% rename from e2e/cypress/tests/16-aps-api/05-products.cy.ts rename to e2e/cypress/tests/16-aps-api/06-products.cy.ts diff --git a/e2e/cypress/tests/16-aps-api/06-api-directory.cy.ts b/e2e/cypress/tests/16-aps-api/07-api-directory.cy.ts similarity index 100% rename from e2e/cypress/tests/16-aps-api/06-api-directory.cy.ts rename to e2e/cypress/tests/16-aps-api/07-api-directory.cy.ts diff --git a/e2e/cypress/tests/16-aps-api/07-namespaces.cy.ts b/e2e/cypress/tests/16-aps-api/08-namespaces.cy.ts similarity index 100% rename from e2e/cypress/tests/16-aps-api/07-namespaces.cy.ts rename to e2e/cypress/tests/16-aps-api/08-namespaces.cy.ts diff --git a/local/feeder-init/organization-unit.yaml b/local/feeder-init/organization-unit.yaml index 7ce1cf097..d427ca2fb 100644 --- a/local/feeder-init/organization-unit.yaml +++ b/local/feeder-init/organization-unit.yaml @@ -19,3 +19,11 @@ record: description: '' extSource: '' extRecordHash: '' + - id: 319b3297-846d-4b97-8095-ceb3ec505fdf + name: public-health + sector: 'Public Health and Safety' + title: 'Public Health' + tags: [] + description: '' + extSource: '' + extRecordHash: '' diff --git a/src/nextapp/components/link-consumer/link-consumer.tsx b/src/nextapp/components/link-consumer/link-consumer.tsx index 4a7b0a436..5e5a764d4 100644 --- a/src/nextapp/components/link-consumer/link-consumer.tsx +++ b/src/nextapp/components/link-consumer/link-consumer.tsx @@ -71,6 +71,7 @@ const LinkConsumerDialog: React.FC = ({ leftIcon={} onClick={onOpen} variant="primary" + data-testid="link-consumer-namespace" > {title} @@ -97,6 +98,7 @@ const LinkConsumerDialog: React.FC = ({ name="username" type="text" placeholder="Enter username of the Consumer you would like to link" + data-testid="link-consumer-username" /> @@ -107,7 +109,7 @@ const LinkConsumerDialog: React.FC = ({ - + diff --git a/src/nextapp/components/products-list/dataset-input.tsx b/src/nextapp/components/products-list/dataset-input.tsx index aabfbce21..7a8cbfa9c 100644 --- a/src/nextapp/components/products-list/dataset-input.tsx +++ b/src/nextapp/components/products-list/dataset-input.tsx @@ -163,7 +163,7 @@ const DatasetInput: React.FC = ({ dataset }) => { ))} {isOpen && isSuccess && !results.length && ( - + No results found