diff --git a/frontend/src/pages/instance/components/InstanceForm.vue b/frontend/src/pages/instance/components/InstanceForm.vue index a51ef6b60b..96fba71934 100644 --- a/frontend/src/pages/instance/components/InstanceForm.vue +++ b/frontend/src/pages/instance/components/InstanceForm.vue @@ -655,7 +655,7 @@ export default { ...this.preDefinedInputs } } - if (this.teamInstanceLimitReached || this.teamRuntimeLimitReached) { + if (this.teamInstanceLimitReached || this.teamRuntimeLimitReached || !this.instancesAvailable) { this.input.createInstance = false } }, diff --git a/test/e2e/frontend/cypress/tests-ee/free-tier/free-tier.spec.js b/test/e2e/frontend/cypress/tests-ee/free-tier/free-tier.spec.js new file mode 100644 index 0000000000..a768cc2df2 --- /dev/null +++ b/test/e2e/frontend/cypress/tests-ee/free-tier/free-tier.spec.js @@ -0,0 +1,22 @@ +describe('FlowFuse EE - Free Tier', () => { + beforeEach(() => { + cy.login('freddie', 'ffPassword') + cy.home() + }) + + it('shows that Hosted Instances are a premium feature in the side navigation', () => { + cy.get('[data-nav="team-instances"]').get('[data-el="premium-feature"]').should('exist') + }) + + it('shows that Hosted Instances are a premium feature when on the /team//instances page', () => { + cy.get('[data-nav="team-instances"]').click() + cy.get('[data-el="page-banner-feature-unavailable-to-team"]').should('exist') + }) + + it('redirects to /application/devices after creating an Application when Hosted Instances are not enabled', () => { + cy.get('[data-el="empty-state"] [data-action="create-application"]').click() + cy.get('[data-form="application-name"] input[type="text"]').type('My Application') + cy.get('[data-action="create-project"]').click() + cy.url().should('include', '/devices') + }) +}) diff --git a/test/e2e/frontend/test_environment_ee.js b/test/e2e/frontend/test_environment_ee.js index ed68b25d4d..695f5841da 100644 --- a/test/e2e/frontend/test_environment_ee.js +++ b/test/e2e/frontend/test_environment_ee.js @@ -102,6 +102,27 @@ const { Roles } = FF_UTIL.require('forge/lib/roles') } }) + // Mimic the FF Cloud "Free" Team Type + const userFreddie = await factory.createUser({ username: 'freddie', name: 'Freddie Fett', email: 'freddie@example.com', password: 'ffPassword', email_verified: true, password_expired: false }) + const freeTeamType = await factory.createTeamType({ + name: 'Free Team', + description: 'team type description', + active: true, + order: 4, + properties: { + instances: { [flowforge.projectTypes[0].hashid]: { active: false } }, + devices: {}, + users: {}, + features: {} + } + }) + const freeTeam = await factory.createTeam({ + name: 'FFeam', + TeamTypeId: freeTeamType.id + }) + await factory.createSubscription(freeTeam) + await freeTeam.addUser(userFreddie, { through: { role: Roles.Owner } }) + // create a snapshot on DeviceB const deviceB = flowforge.applicationDevices.find((device) => device.name === 'application-device-b') await factory.createDeviceSnapshot({ name: 'application-device-b snapshot 1' }, deviceB, userTerry)