From e9c7fd73975ced504d5a16a0dbbc313f15ccd8ab Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Thu, 21 Dec 2023 09:06:54 -0500 Subject: [PATCH] fix: Show public API upgrade CTA when feature is not enabled (#8109) ## Summary > Describe what the PR does and how to test. Photos and videos are recommended. Shows the public API upgrade CTA when the feature is not enabled. Now trialing users in cloud would see the API on the settings menu and can upgrade from there. When public API feature disabled: image When public API feature enabled with no API key: image When public API feature enabled with API key: image ## Related tickets and issues [> Include links to **Linear ticket** or Github issue or Community forum post. Important in order to close *automatically* and provide context to r](https://linear.app/n8n/issue/ADO-1282/feature-api-page-missing-for-trial-users)eviewers. ## Review / Merge checklist - [x] PR title and summary are descriptive. **Remember, the title automatically goes into the changelog. Use `(no-changelog)` otherwise.** ([conventions](https://github.com/n8n-io/n8n/blob/master/.github/pull_request_title_conventions.md)) - [x] Tests included. > A bug is not considered fixed, unless a test is added to prevent it from happening again. > A feature is not complete without tests. --- cypress/e2e/27-cloud.cy.ts | 119 ++++++++++++++++++ cypress/e2e/27-opt-in-trial-banner.cy.ts | 83 ------------ cypress/fixtures/Plan_data_opt_in_trial.json | 3 +- cypress/pages/index.ts | 1 + cypress/pages/settings-public-api.ts | 5 + packages/editor-ui/src/router.ts | 8 +- .../editor-ui/src/views/SettingsApiView.vue | 8 +- 7 files changed, 134 insertions(+), 93 deletions(-) create mode 100644 cypress/e2e/27-cloud.cy.ts delete mode 100644 cypress/e2e/27-opt-in-trial-banner.cy.ts create mode 100644 cypress/pages/settings-public-api.ts diff --git a/cypress/e2e/27-cloud.cy.ts b/cypress/e2e/27-cloud.cy.ts new file mode 100644 index 0000000000..965bc5bccf --- /dev/null +++ b/cypress/e2e/27-cloud.cy.ts @@ -0,0 +1,119 @@ +import { + BannerStack, + MainSidebar, + WorkflowPage, + visitPublicApiPage, + getPublicApiUpgradeCTA, +} from '../pages'; +import planData from '../fixtures/Plan_data_opt_in_trial.json'; +import { INSTANCE_OWNER } from '../constants'; + +const mainSidebar = new MainSidebar(); +const bannerStack = new BannerStack(); +const workflowPage = new WorkflowPage(); + +describe('Cloud', { disableAutoLogin: true }, () => { + before(() => { + const now = new Date(); + const fiveDaysFromNow = new Date(now.getTime() + 5 * 24 * 60 * 60 * 1000); + planData.expirationDate = fiveDaysFromNow.toJSON(); + }); + + describe('BannerStack', () => { + it('should render trial banner for opt-in cloud user', () => { + cy.intercept('GET', '/rest/admin/cloud-plan', { + body: planData, + }).as('getPlanData'); + + cy.intercept('GET', '/rest/settings', (req) => { + req.on('response', (res) => { + res.send({ + data: { ...res.body.data, deployment: { type: 'cloud' }, n8nMetadata: { userId: 1 } }, + }); + }); + }).as('loadSettings'); + + cy.signin({ email: INSTANCE_OWNER.email, password: INSTANCE_OWNER.password }); + + cy.visit(workflowPage.url); + + cy.wait('@getPlanData'); + + bannerStack.getters.banner().should('be.visible'); + + mainSidebar.actions.signout(); + + bannerStack.getters.banner().should('not.be.visible'); + + cy.signin({ email: INSTANCE_OWNER.email, password: INSTANCE_OWNER.password }); + + cy.visit(workflowPage.url); + + bannerStack.getters.banner().should('be.visible'); + + mainSidebar.actions.signout(); + }); + + it('should not render opt-in-trial banner for non cloud deployment', () => { + cy.intercept('GET', '/rest/settings', (req) => { + req.on('response', (res) => { + res.send({ + data: { ...res.body.data, deployment: { type: 'default' } }, + }); + }); + }).as('loadSettings'); + + cy.signin({ email: INSTANCE_OWNER.email, password: INSTANCE_OWNER.password }); + + cy.visit(workflowPage.url); + + bannerStack.getters.banner().should('not.be.visible'); + + mainSidebar.actions.signout(); + }); + }); + + describe('Admin Home', () => { + it('Should show admin button', () => { + cy.intercept('GET', '/rest/settings', (req) => { + req.on('response', (res) => { + res.send({ + data: { ...res.body.data, deployment: { type: 'cloud' }, n8nMetadata: { userId: 1 } }, + }); + }); + }).as('loadSettings'); + + cy.signin({ email: INSTANCE_OWNER.email, password: INSTANCE_OWNER.password }); + + cy.visit(workflowPage.url); + + mainSidebar.getters.adminPanel().should('be.visible'); + }); + }); + + describe('Public API', () => { + it('Should show upgrade CTA for Public API if user is trialing', () => { + cy.intercept('GET', '/rest/admin/cloud-plan', { + body: planData, + }).as('getPlanData'); + + cy.intercept('GET', '/rest/settings', (req) => { + req.on('response', (res) => { + res.send({ + data: { + ...res.body.data, + deployment: { type: 'cloud' }, + n8nMetadata: { userId: 1 }, + }, + }); + }); + }).as('loadSettings'); + + cy.signin({ email: INSTANCE_OWNER.email, password: INSTANCE_OWNER.password }); + + visitPublicApiPage(); + + getPublicApiUpgradeCTA().should('be.visible'); + }); + }); +}); diff --git a/cypress/e2e/27-opt-in-trial-banner.cy.ts b/cypress/e2e/27-opt-in-trial-banner.cy.ts deleted file mode 100644 index 6e24343bc7..0000000000 --- a/cypress/e2e/27-opt-in-trial-banner.cy.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { BannerStack, MainSidebar, WorkflowPage } from '../pages'; -import planData from '../fixtures/Plan_data_opt_in_trial.json'; -import { INSTANCE_OWNER } from '../constants'; - -const mainSidebar = new MainSidebar(); -const bannerStack = new BannerStack(); -const workflowPage = new WorkflowPage(); - -describe('BannerStack', { disableAutoLogin: true }, () => { - before(() => { - const now = new Date(); - const fiveDaysFromNow = new Date(now.getTime() + 5 * 24 * 60 * 60 * 1000); - planData.expirationDate = fiveDaysFromNow.toJSON(); - }); - - it('should render trial banner for opt-in cloud user', () => { - cy.intercept('GET', '/rest/admin/cloud-plan', { - body: planData, - }).as('getPlanData'); - - cy.intercept('GET', '/rest/settings', (req) => { - req.on('response', (res) => { - res.send({ - data: { ...res.body.data, deployment: { type: 'cloud' }, n8nMetadata: { userId: 1 } }, - }); - }); - }).as('loadSettings'); - - cy.signin({ email: INSTANCE_OWNER.email, password: INSTANCE_OWNER.password }); - - cy.visit(workflowPage.url); - - cy.wait('@getPlanData'); - - bannerStack.getters.banner().should('be.visible'); - - mainSidebar.actions.signout(); - - bannerStack.getters.banner().should('not.be.visible'); - - cy.signin({ email: INSTANCE_OWNER.email, password: INSTANCE_OWNER.password }); - - cy.visit(workflowPage.url); - - bannerStack.getters.banner().should('be.visible'); - - mainSidebar.actions.signout(); - }); - - it('should not render opt-in-trial banner for non cloud deployment', () => { - cy.intercept('GET', '/rest/settings', (req) => { - req.on('response', (res) => { - res.send({ - data: { ...res.body.data, deployment: { type: 'default' } }, - }); - }); - }).as('loadSettings'); - - cy.signin({ email: INSTANCE_OWNER.email, password: INSTANCE_OWNER.password }); - - cy.visit(workflowPage.url); - - bannerStack.getters.banner().should('not.be.visible'); - - mainSidebar.actions.signout(); - }); - - it('Should show admin button', () => { - cy.intercept('GET', '/rest/settings', (req) => { - req.on('response', (res) => { - res.send({ - data: { ...res.body.data, deployment: { type: 'cloud' }, n8nMetadata: { userId: 1 } }, - }); - }); - }).as('loadSettings'); - - cy.signin({ email: INSTANCE_OWNER.email, password: INSTANCE_OWNER.password }); - - cy.visit(workflowPage.url); - - mainSidebar.getters.adminPanel().should('be.visible'); - }); -}); diff --git a/cypress/fixtures/Plan_data_opt_in_trial.json b/cypress/fixtures/Plan_data_opt_in_trial.json index 504805de32..7a805708c6 100644 --- a/cypress/fixtures/Plan_data_opt_in_trial.json +++ b/cypress/fixtures/Plan_data_opt_in_trial.json @@ -13,8 +13,7 @@ "feat:advancedExecutionFilters": true, "quota:users": -1, "quota:maxVariables": -1, - "feat:variables": true, - "feat:apiDisabled": true + "feat:variables": true }, "metadata": { "version": "v1", diff --git a/cypress/pages/index.ts b/cypress/pages/index.ts index 6f03962c2a..39c9be3b56 100644 --- a/cypress/pages/index.ts +++ b/cypress/pages/index.ts @@ -12,3 +12,4 @@ export * from './workflow-executions-tab'; export * from './signin'; export * from './workflow-history'; export * from './workerView'; +export * from './settings-public-api'; diff --git a/cypress/pages/settings-public-api.ts b/cypress/pages/settings-public-api.ts new file mode 100644 index 0000000000..1a7d668136 --- /dev/null +++ b/cypress/pages/settings-public-api.ts @@ -0,0 +1,5 @@ +export const getPublicApiUpgradeCTA = () => cy.getByTestId('public-api-upgrade-cta'); + +export const visitPublicApiPage = () => { + cy.visit('/settings/api'); +}; diff --git a/packages/editor-ui/src/router.ts b/packages/editor-ui/src/router.ts index eac3900d0d..b9f9d1c180 100644 --- a/packages/editor-ui/src/router.ts +++ b/packages/editor-ui/src/router.ts @@ -517,13 +517,7 @@ export const routes = [ settingsView: SettingsApiView, }, meta: { - middleware: ['authenticated', 'custom'], - middlewareOptions: { - custom: () => { - const settingsStore = useSettingsStore(); - return settingsStore.isPublicApiEnabled; - }, - }, + middleware: ['authenticated'], telemetry: { pageCategory: 'settings', getProperties(route: RouteLocation) { diff --git a/packages/editor-ui/src/views/SettingsApiView.vue b/packages/editor-ui/src/views/SettingsApiView.vue index d09b1d4c4c..2f6c33f6b1 100644 --- a/packages/editor-ui/src/views/SettingsApiView.vue +++ b/packages/editor-ui/src/views/SettingsApiView.vue @@ -64,7 +64,8 @@