@nextsparkjs/theme-default 0.1.0-beta.20 → 0.1.0-beta.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/tests/cypress/e2e/_devtools/access.bdd.md +262 -0
- package/tests/cypress/e2e/_devtools/access.cy.ts +171 -0
- package/tests/cypress/e2e/_devtools/navigation.bdd.md +261 -0
- package/tests/cypress/e2e/_devtools/navigation.cy.ts +157 -0
- package/tests/cypress/e2e/_devtools/pages.bdd.md +303 -0
- package/tests/cypress/e2e/_devtools/pages.cy.ts +184 -0
- package/tests/cypress/e2e/_docs/README.md +215 -0
- package/tests/cypress/e2e/_docs/tutorials/sector7-superadmin-teams.narration.json +155 -0
- package/tests/cypress/e2e/_docs/tutorials/sector7-superadmin.cy.ts +390 -0
- package/tests/cypress/e2e/_docs/tutorials/teams-system.doc.cy.ts +349 -0
- package/tests/cypress/e2e/_docs/tutorials/teams-system.narration.json +165 -0
- package/tests/cypress/e2e/_selectors/auth.cy.ts +306 -0
- package/tests/cypress/e2e/_selectors/billing.cy.ts +89 -0
- package/tests/cypress/e2e/_selectors/dashboard-mobile.cy.ts +113 -0
- package/tests/cypress/e2e/_selectors/dashboard-navigation.cy.ts +89 -0
- package/tests/cypress/e2e/_selectors/dashboard-sidebar.cy.ts +60 -0
- package/tests/cypress/e2e/_selectors/dashboard-topnav.cy.ts +146 -0
- package/tests/cypress/e2e/_selectors/devtools.cy.ts +210 -0
- package/tests/cypress/e2e/_selectors/global-search.cy.ts +88 -0
- package/tests/cypress/e2e/_selectors/pages-editor.cy.ts +179 -0
- package/tests/cypress/e2e/_selectors/posts-editor.cy.ts +282 -0
- package/tests/cypress/e2e/_selectors/public.cy.ts +112 -0
- package/tests/cypress/e2e/_selectors/settings-api-keys.cy.ts +228 -0
- package/tests/cypress/e2e/_selectors/settings-billing.cy.ts +105 -0
- package/tests/cypress/e2e/_selectors/settings-layout.cy.ts +119 -0
- package/tests/cypress/e2e/_selectors/settings-password.cy.ts +71 -0
- package/tests/cypress/e2e/_selectors/settings-profile.cy.ts +82 -0
- package/tests/cypress/e2e/_selectors/settings-teams.cy.ts +68 -0
- package/tests/cypress/e2e/_selectors/superadmin.cy.ts +185 -0
- package/tests/cypress/e2e/_selectors/tasks.cy.ts +242 -0
- package/tests/cypress/e2e/_selectors/taxonomies.cy.ts +126 -0
- package/tests/cypress/e2e/_selectors/teams.cy.ts +142 -0
- package/tests/cypress/e2e/_superadmin/all-teams.bdd.md +261 -0
- package/tests/cypress/e2e/_superadmin/all-teams.cy.ts +177 -0
- package/tests/cypress/e2e/_superadmin/all-users.bdd.md +406 -0
- package/tests/cypress/e2e/_superadmin/all-users.cy.ts +294 -0
- package/tests/cypress/e2e/_superadmin/dashboard.bdd.md +235 -0
- package/tests/cypress/e2e/_superadmin/dashboard.cy.ts +149 -0
- package/tests/cypress/e2e/_superadmin/subscriptions-overview.bdd.md +290 -0
- package/tests/cypress/e2e/_superadmin/subscriptions-overview.cy.ts +194 -0
- package/tests/cypress/e2e/ai/ai-usage.cy.ts +209 -0
- package/tests/cypress/e2e/ai/chat-api.cy.ts +107 -0
- package/tests/cypress/e2e/ai/guardrails.cy.ts +332 -0
- package/tests/cypress/e2e/api/billing/BillingAPIController.js +319 -0
- package/tests/cypress/e2e/api/billing/check-action.cy.ts +326 -0
- package/tests/cypress/e2e/api/billing/checkout.cy.ts +358 -0
- package/tests/cypress/e2e/api/billing/lifecycle.cy.ts +423 -0
- package/tests/cypress/e2e/api/billing/plans/README.md +345 -0
- package/tests/cypress/e2e/api/billing/plans/business.cy.ts +412 -0
- package/tests/cypress/e2e/api/billing/plans/downgrade.cy.ts +510 -0
- package/tests/cypress/e2e/api/billing/plans/fixtures/billing-plans.json +163 -0
- package/tests/cypress/e2e/api/billing/plans/free.cy.ts +500 -0
- package/tests/cypress/e2e/api/billing/plans/pro.cy.ts +497 -0
- package/tests/cypress/e2e/api/billing/plans/starter.cy.ts +342 -0
- package/tests/cypress/e2e/api/billing/portal.cy.ts +313 -0
- package/tests/cypress/e2e/api/devtools/registries.bdd.md +300 -0
- package/tests/cypress/e2e/api/devtools/registries.cy.ts +368 -0
- package/tests/cypress/e2e/api/entities/blocks-scope.cy.ts +396 -0
- package/tests/cypress/e2e/api/entities/customers-crud.cy.ts +648 -0
- package/tests/cypress/e2e/api/entities/customers-metas.cy.ts +839 -0
- package/tests/cypress/e2e/api/entities/pages-crud.cy.ts +425 -0
- package/tests/cypress/e2e/api/entities/pages-status.cy.ts +335 -0
- package/tests/cypress/e2e/api/entities/post-categories-crud.cy.ts +610 -0
- package/tests/cypress/e2e/api/entities/posts-crud.cy.ts +709 -0
- package/tests/cypress/e2e/api/entities/posts-status.cy.ts +396 -0
- package/tests/cypress/e2e/api/entities/tasks-crud.cy.ts +602 -0
- package/tests/cypress/e2e/api/entities/tasks-metas.cy.ts +878 -0
- package/tests/cypress/e2e/api/entities/users-crud.cy.ts +469 -0
- package/tests/cypress/e2e/api/entities/users-metas.cy.ts +913 -0
- package/tests/cypress/e2e/api/entities/users-security.cy.ts +375 -0
- package/tests/cypress/e2e/api/scheduled-actions/cron-endpoint.bdd.md +375 -0
- package/tests/cypress/e2e/api/scheduled-actions/cron-endpoint.cy.ts +346 -0
- package/tests/cypress/e2e/api/scheduled-actions/devtools-endpoint.bdd.md +451 -0
- package/tests/cypress/e2e/api/scheduled-actions/devtools-endpoint.cy.ts +447 -0
- package/tests/cypress/e2e/api/scheduled-actions/scheduling.bdd.md +649 -0
- package/tests/cypress/e2e/api/scheduled-actions/scheduling.cy.ts +333 -0
- package/tests/cypress/e2e/api/settings/api-keys.crud.cy.ts +923 -0
- package/tests/cypress/e2e/uat/auth/app-roles/developer-login.bdd.md +231 -0
- package/tests/cypress/e2e/uat/auth/app-roles/developer-login.cy.ts +144 -0
- package/tests/cypress/e2e/uat/auth/app-roles/superadmin-login.bdd.md +118 -0
- package/tests/cypress/e2e/uat/auth/app-roles/superadmin-login.cy.ts +84 -0
- package/tests/cypress/e2e/uat/auth/custom-roles/editor-login.bdd.md +288 -0
- package/tests/cypress/e2e/uat/auth/custom-roles/editor-login.cy.ts +188 -0
- package/tests/cypress/e2e/uat/auth/login-logout.bdd.md +160 -0
- package/tests/cypress/e2e/uat/auth/login-logout.cy.ts +116 -0
- package/tests/cypress/e2e/uat/auth/password-reset.bdd.md +289 -0
- package/tests/cypress/e2e/uat/auth/password-reset.cy.ts +200 -0
- package/tests/cypress/e2e/uat/auth/team-roles/admin-login.bdd.md +225 -0
- package/tests/cypress/e2e/uat/auth/team-roles/admin-login.cy.ts +148 -0
- package/tests/cypress/e2e/uat/auth/team-roles/member-login.bdd.md +251 -0
- package/tests/cypress/e2e/uat/auth/team-roles/member-login.cy.ts +163 -0
- package/tests/cypress/e2e/uat/auth/team-roles/owner-login.bdd.md +231 -0
- package/tests/cypress/e2e/uat/auth/team-roles/owner-login.cy.ts +141 -0
- package/tests/cypress/e2e/uat/billing/extended.bdd.md +273 -0
- package/tests/cypress/e2e/uat/billing/extended.cy.ts +209 -0
- package/tests/cypress/e2e/uat/billing/feature-gates.bdd.md +407 -0
- package/tests/cypress/e2e/uat/billing/feature-gates.cy.ts +307 -0
- package/tests/cypress/e2e/uat/billing/page.bdd.md +329 -0
- package/tests/cypress/e2e/uat/billing/page.cy.ts +250 -0
- package/tests/cypress/e2e/uat/billing/status.bdd.md +190 -0
- package/tests/cypress/e2e/uat/billing/status.cy.ts +145 -0
- package/tests/cypress/e2e/uat/billing/team-switch.bdd.md +156 -0
- package/tests/cypress/e2e/uat/billing/team-switch.cy.ts +122 -0
- package/tests/cypress/e2e/uat/billing/usage.bdd.md +218 -0
- package/tests/cypress/e2e/uat/billing/usage.cy.ts +176 -0
- package/tests/cypress/e2e/uat/blocks/hero.bdd.md +124 -0
- package/tests/cypress/e2e/uat/blocks/hero.cy.ts +56 -0
- package/tests/cypress/e2e/uat/devtools/api-tester.cy.ts +390 -0
- package/tests/cypress/e2e/uat/entities/customers/member.bdd.md +275 -0
- package/tests/cypress/e2e/uat/entities/customers/member.cy.ts +122 -0
- package/tests/cypress/e2e/uat/entities/customers/owner.bdd.md +243 -0
- package/tests/cypress/e2e/uat/entities/customers/owner.cy.ts +165 -0
- package/tests/cypress/e2e/uat/entities/pages/block-crud.bdd.md +476 -0
- package/tests/cypress/e2e/uat/entities/pages/block-crud.cy.ts +486 -0
- package/tests/cypress/e2e/uat/entities/pages/block-editor.bdd.md +460 -0
- package/tests/cypress/e2e/uat/entities/pages/block-editor.cy.ts +301 -0
- package/tests/cypress/e2e/uat/entities/pages/list.bdd.md +432 -0
- package/tests/cypress/e2e/uat/entities/pages/list.cy.ts +273 -0
- package/tests/cypress/e2e/uat/entities/pages/public-rendering.bdd.md +696 -0
- package/tests/cypress/e2e/uat/entities/pages/public-rendering.cy.ts +340 -0
- package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.bdd.md +161 -0
- package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.cy.ts +104 -0
- package/tests/cypress/e2e/uat/entities/posts/categories.bdd.md +375 -0
- package/tests/cypress/e2e/uat/entities/posts/categories.cy.ts +241 -0
- package/tests/cypress/e2e/uat/entities/posts/editor.bdd.md +429 -0
- package/tests/cypress/e2e/uat/entities/posts/editor.cy.ts +257 -0
- package/tests/cypress/e2e/uat/entities/posts/list.bdd.md +340 -0
- package/tests/cypress/e2e/uat/entities/posts/list.cy.ts +177 -0
- package/tests/cypress/e2e/uat/entities/posts/public.bdd.md +614 -0
- package/tests/cypress/e2e/uat/entities/posts/public.cy.ts +249 -0
- package/tests/cypress/e2e/uat/entities/tasks/member.bdd.md +222 -0
- package/tests/cypress/e2e/uat/entities/tasks/member.cy.ts +165 -0
- package/tests/cypress/e2e/uat/entities/tasks/owner.bdd.md +419 -0
- package/tests/cypress/e2e/uat/entities/tasks/owner.cy.ts +191 -0
- package/tests/cypress/e2e/uat/roles/editor-role.bdd.md +552 -0
- package/tests/cypress/e2e/uat/roles/editor-role.cy.ts +210 -0
- package/tests/cypress/e2e/uat/roles/member-restrictions.bdd.md +450 -0
- package/tests/cypress/e2e/uat/roles/member-restrictions.cy.ts +189 -0
- package/tests/cypress/e2e/uat/roles/owner-full-crud.bdd.md +530 -0
- package/tests/cypress/e2e/uat/roles/owner-full-crud.cy.ts +247 -0
- package/tests/cypress/e2e/uat/scheduled-actions/devtools-ui.bdd.md +736 -0
- package/tests/cypress/e2e/uat/scheduled-actions/devtools-ui.cy.ts +740 -0
- package/tests/cypress/e2e/uat/teams/roles-matrix.bdd.md +553 -0
- package/tests/cypress/e2e/uat/teams/roles-matrix.cy.ts +185 -0
- package/tests/cypress/e2e/uat/teams/switcher.bdd.md +1151 -0
- package/tests/cypress/e2e/uat/teams/switcher.cy.ts +497 -0
- package/tests/cypress/e2e/uat/teams/team-switcher.md +198 -0
- package/tests/cypress/fixtures/blocks.json +218 -0
- package/tests/cypress/fixtures/entities.json +78 -0
- package/tests/cypress/fixtures/page-builder.json +21 -0
- package/tests/cypress/src/components/CategoriesPOM.ts +382 -0
- package/tests/cypress/src/components/CustomersPOM.ts +439 -0
- package/tests/cypress/src/components/DevKeyringPOM.ts +160 -0
- package/tests/cypress/src/components/EntityForm.ts +375 -0
- package/tests/cypress/src/components/EntityList.ts +389 -0
- package/tests/cypress/src/components/PageBuilderPOM.ts +710 -0
- package/tests/cypress/src/components/PostEditorPOM.ts +370 -0
- package/tests/cypress/src/components/PostsListPOM.ts +223 -0
- package/tests/cypress/src/components/PublicPagePOM.ts +447 -0
- package/tests/cypress/src/components/PublicPostPOM.ts +146 -0
- package/tests/cypress/src/components/TasksPOM.ts +272 -0
- package/tests/cypress/src/components/TeamSwitcherPOM.ts +450 -0
- package/tests/cypress/src/components/index.ts +21 -0
- package/tests/cypress/src/controllers/ApiKeysAPIController.js +178 -0
- package/tests/cypress/src/controllers/BaseAPIController.js +317 -0
- package/tests/cypress/src/controllers/CustomerAPIController.js +251 -0
- package/tests/cypress/src/controllers/PagesAPIController.js +226 -0
- package/tests/cypress/src/controllers/PostsAPIController.js +250 -0
- package/tests/cypress/src/controllers/TaskAPIController.js +240 -0
- package/tests/cypress/src/controllers/UsersAPIController.js +242 -0
- package/tests/cypress/src/controllers/index.js +25 -0
- package/tests/cypress/src/core/AuthPOM.ts +450 -0
- package/tests/cypress/src/core/BasePOM.ts +86 -0
- package/tests/cypress/src/core/BlockEditorBasePOM.ts +576 -0
- package/tests/cypress/src/core/DashboardEntityPOM.ts +692 -0
- package/tests/cypress/src/core/index.ts +14 -0
- package/tests/cypress/src/entities/CustomersPOM.ts +172 -0
- package/tests/cypress/src/entities/PagesPOM.ts +137 -0
- package/tests/cypress/src/entities/PostsPOM.ts +137 -0
- package/tests/cypress/src/entities/TasksPOM.ts +176 -0
- package/tests/cypress/src/entities/index.ts +14 -0
- package/tests/cypress/src/features/BillingPOM.ts +385 -0
- package/tests/cypress/src/features/DashboardPOM.ts +245 -0
- package/tests/cypress/src/features/DevtoolsPOM.ts +739 -0
- package/tests/cypress/src/features/PageBuilderPOM.ts +263 -0
- package/tests/cypress/src/features/PostEditorPOM.ts +313 -0
- package/tests/cypress/src/features/ScheduledActionsPOM.ts +463 -0
- package/tests/cypress/src/features/SettingsPOM.ts +362 -0
- package/tests/cypress/src/features/SuperadminPOM.ts +331 -0
- package/tests/cypress/src/features/SuperadminTeamRolesPOM.ts +285 -0
- package/tests/cypress/src/features/index.ts +28 -0
- package/tests/cypress/src/helpers/ApiInterceptor.ts +177 -0
- package/tests/cypress/src/index.ts +101 -0
- package/tests/cypress/src/pages/dashboard/Dashboard.js +677 -0
- package/tests/cypress/src/pages/dashboard/DashboardPage.js +43 -0
- package/tests/cypress/src/pages/dashboard/DashboardStats.js +546 -0
- package/tests/cypress/src/pages/dashboard/index.js +6 -0
- package/tests/cypress/src/pages/index.js +5 -0
- package/tests/cypress/src/pages/public/FeaturesPage.js +28 -0
- package/tests/cypress/src/pages/public/LandingPage.js +69 -0
- package/tests/cypress/src/pages/public/PricingPage.js +33 -0
- package/tests/cypress/src/pages/public/index.js +6 -0
- package/tests/cypress/src/selectors.ts +46 -0
- package/tests/cypress/src/session-helpers.ts +500 -0
- package/tests/cypress/support/doc-commands.ts +260 -0
- package/tests/cypress/support/e2e.ts +89 -0
- package/tests/cypress.config.ts +165 -0
- package/tests/jest/components/post-header.test.tsx +377 -0
- package/tests/jest/config/role-config.test.ts +529 -0
- package/tests/jest/jest.config.ts +81 -0
- package/tests/jest/langchain/COVERAGE.md +372 -0
- package/tests/jest/langchain/guardrails.test.ts +465 -0
- package/tests/jest/langchain/streaming.test.ts +367 -0
- package/tests/jest/langchain/token-tracker.test.ts +455 -0
- package/tests/jest/langchain/tracer-callbacks.test.ts +881 -0
- package/tests/jest/langchain/tracer.test.ts +823 -0
- package/tests/jest/user-roles/role-helpers.test.ts +432 -0
- package/tests/jest/validation/categories.test.ts +429 -0
- package/tests/jest/validation/posts.test.ts +546 -0
- package/tests/tsconfig.json +15 -0
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/// <reference types="cypress" />
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Billing API - Free Plan Tests
|
|
6
|
+
*
|
|
7
|
+
* BDD: Feature: Free Plan Restrictions
|
|
8
|
+
* As a user with a Free plan
|
|
9
|
+
* I want to understand my plan limitations
|
|
10
|
+
* So that I can decide if I need to upgrade
|
|
11
|
+
*
|
|
12
|
+
* Tests for:
|
|
13
|
+
* - Auto-subscription on team creation
|
|
14
|
+
* - Basic analytics access
|
|
15
|
+
* - Advanced analytics blocked
|
|
16
|
+
* - Team members limit (3)
|
|
17
|
+
* - Tasks limit (50)
|
|
18
|
+
* - Customers limit (25)
|
|
19
|
+
* - API calls monthly tracking
|
|
20
|
+
* - Domain features blocked
|
|
21
|
+
*
|
|
22
|
+
* Session: 2025-12-20-subscriptions-system-v2
|
|
23
|
+
* Phase: 9 (api-tester)
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import * as allure from 'allure-cypress'
|
|
27
|
+
|
|
28
|
+
const BillingAPIController = require('../BillingAPIController.js')
|
|
29
|
+
import billingPlans from './fixtures/billing-plans.json'
|
|
30
|
+
|
|
31
|
+
describe('Billing API - Free Plan Restrictions', () => {
|
|
32
|
+
let billingAPI: any
|
|
33
|
+
|
|
34
|
+
// Test data from fixtures
|
|
35
|
+
const FREE_PLAN = billingPlans.plans.free
|
|
36
|
+
const TEST_TEAM = billingPlans.testTeams.free
|
|
37
|
+
const SUPERADMIN = billingPlans.testCredentials.superadmin
|
|
38
|
+
const BASE_URL = Cypress.config('baseUrl') || 'http://localhost:5173'
|
|
39
|
+
|
|
40
|
+
before(() => {
|
|
41
|
+
billingAPI = new BillingAPIController(BASE_URL, SUPERADMIN.apiKey, TEST_TEAM.teamId)
|
|
42
|
+
cy.log('BillingAPIController initialized for Free Plan tests')
|
|
43
|
+
cy.log(`Team: ${TEST_TEAM.description}`)
|
|
44
|
+
cy.log(`Team ID: ${TEST_TEAM.teamId}`)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
beforeEach(() => {
|
|
48
|
+
allure.epic('Billing')
|
|
49
|
+
allure.feature('Free Plan')
|
|
50
|
+
allure.owner('qa-automation')
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
// ============================================================
|
|
54
|
+
// TEST GROUP 1: Subscription Verification
|
|
55
|
+
// ============================================================
|
|
56
|
+
describe('Subscription Verification', () => {
|
|
57
|
+
it('FREE_001: New team should have Free plan automatically assigned', () => {
|
|
58
|
+
allure.story('Auto-subscription')
|
|
59
|
+
allure.severity('critical')
|
|
60
|
+
allure.description(`
|
|
61
|
+
Scenario: New team gets Free plan automatically
|
|
62
|
+
Given I create a new team
|
|
63
|
+
Then the team should have an active Free subscription
|
|
64
|
+
And the plan slug should be "free"
|
|
65
|
+
`)
|
|
66
|
+
|
|
67
|
+
billingAPI.getSubscription(TEST_TEAM.teamId).then((response: any) => {
|
|
68
|
+
billingAPI.validateSubscriptionResponse(response, {
|
|
69
|
+
status: 'active',
|
|
70
|
+
planSlug: 'free'
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
cy.log('Free plan subscription verified')
|
|
74
|
+
cy.log(`Plan: ${response.body.data.subscription.plan.name}`)
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('FREE_002: Free plan should include basic_analytics feature', () => {
|
|
79
|
+
allure.story('Basic Features')
|
|
80
|
+
allure.severity('normal')
|
|
81
|
+
allure.description(`
|
|
82
|
+
Scenario: User can access basic analytics
|
|
83
|
+
When I check my subscription details
|
|
84
|
+
Then the plan features should include "basic_analytics"
|
|
85
|
+
`)
|
|
86
|
+
|
|
87
|
+
billingAPI.getSubscription(TEST_TEAM.teamId).then((response: any) => {
|
|
88
|
+
expect(response.body.data.subscription.plan.features).to.include('basic_analytics')
|
|
89
|
+
|
|
90
|
+
cy.log('basic_analytics feature is included in Free plan')
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
// ============================================================
|
|
96
|
+
// TEST GROUP 2: Feature Restrictions
|
|
97
|
+
// ============================================================
|
|
98
|
+
describe('Feature Restrictions', () => {
|
|
99
|
+
it('FREE_010: Should block advanced_analytics feature', () => {
|
|
100
|
+
allure.story('Feature Blocking')
|
|
101
|
+
allure.severity('critical')
|
|
102
|
+
allure.description(`
|
|
103
|
+
Scenario: User cannot access advanced analytics
|
|
104
|
+
When I check action "analytics.view_advanced"
|
|
105
|
+
Then the action should be denied
|
|
106
|
+
And the reason should be "feature_not_in_plan"
|
|
107
|
+
`)
|
|
108
|
+
|
|
109
|
+
billingAPI.checkAction('analytics.view_advanced').then((response: any) => {
|
|
110
|
+
billingAPI.validateActionDenied(response, 'feature_not_in_plan')
|
|
111
|
+
|
|
112
|
+
cy.log('advanced_analytics correctly blocked for Free plan')
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('FREE_011: Should block realtime_analytics feature', () => {
|
|
117
|
+
allure.story('Feature Blocking')
|
|
118
|
+
allure.severity('normal')
|
|
119
|
+
allure.description(`
|
|
120
|
+
Scenario: User cannot access realtime analytics
|
|
121
|
+
When I check action "analytics.view_realtime"
|
|
122
|
+
Then the action should be denied
|
|
123
|
+
And the reason should be "feature_not_in_plan"
|
|
124
|
+
`)
|
|
125
|
+
|
|
126
|
+
billingAPI.checkAction('analytics.view_realtime').then((response: any) => {
|
|
127
|
+
billingAPI.validateActionDenied(response, 'feature_not_in_plan')
|
|
128
|
+
|
|
129
|
+
cy.log('realtime_analytics correctly blocked for Free plan')
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it('FREE_012: Should block task_automation feature', () => {
|
|
134
|
+
allure.story('Domain Features')
|
|
135
|
+
allure.severity('normal')
|
|
136
|
+
allure.description(`
|
|
137
|
+
Scenario: Domain-specific features are not available
|
|
138
|
+
When I check action "tasks.automate"
|
|
139
|
+
Then the action should be denied
|
|
140
|
+
And the reason should be "feature_not_in_plan"
|
|
141
|
+
`)
|
|
142
|
+
|
|
143
|
+
billingAPI.checkAction('tasks.automate').then((response: any) => {
|
|
144
|
+
billingAPI.validateActionDenied(response, 'feature_not_in_plan')
|
|
145
|
+
|
|
146
|
+
cy.log('task_automation correctly blocked for Free plan')
|
|
147
|
+
})
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
it('FREE_013: Should block customer_import feature', () => {
|
|
151
|
+
allure.story('Domain Features')
|
|
152
|
+
allure.severity('normal')
|
|
153
|
+
allure.description(`
|
|
154
|
+
Scenario: Customer bulk import is not available
|
|
155
|
+
When I check action "customers.bulk_import"
|
|
156
|
+
Then the action should be denied
|
|
157
|
+
And the reason should be "feature_not_in_plan"
|
|
158
|
+
`)
|
|
159
|
+
|
|
160
|
+
billingAPI.checkAction('customers.bulk_import').then((response: any) => {
|
|
161
|
+
billingAPI.validateActionDenied(response, 'feature_not_in_plan')
|
|
162
|
+
|
|
163
|
+
cy.log('customer_import correctly blocked for Free plan')
|
|
164
|
+
})
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
it('FREE_014: Should block recurring_tasks feature', () => {
|
|
168
|
+
allure.story('Domain Features')
|
|
169
|
+
allure.severity('normal')
|
|
170
|
+
allure.description(`
|
|
171
|
+
Scenario: Recurring tasks are not available
|
|
172
|
+
When I check action "tasks.create_recurring"
|
|
173
|
+
Then the action should be denied
|
|
174
|
+
And the reason should be "feature_not_in_plan"
|
|
175
|
+
`)
|
|
176
|
+
|
|
177
|
+
billingAPI.checkAction('tasks.create_recurring').then((response: any) => {
|
|
178
|
+
billingAPI.validateActionDenied(response, 'feature_not_in_plan')
|
|
179
|
+
|
|
180
|
+
cy.log('recurring_tasks correctly blocked for Free plan')
|
|
181
|
+
})
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
it('FREE_015: Should block webhooks feature', () => {
|
|
185
|
+
allure.story('API Features')
|
|
186
|
+
allure.severity('normal')
|
|
187
|
+
allure.description(`
|
|
188
|
+
Scenario: Webhooks are not available in Free plan
|
|
189
|
+
When I check action "webhooks.create"
|
|
190
|
+
Then the action should be denied
|
|
191
|
+
Note: Can be blocked by feature, quota, or permission depending on plan configuration
|
|
192
|
+
`)
|
|
193
|
+
|
|
194
|
+
billingAPI.checkAction('webhooks.create').then((response: any) => {
|
|
195
|
+
// webhooks.create can be blocked by:
|
|
196
|
+
// - 'webhooks' feature (not in Free plan)
|
|
197
|
+
// - 'webhooks_count' limit (0 in Free plan)
|
|
198
|
+
// - 'no_permission' if RBAC check fails first
|
|
199
|
+
expect(response.body.data.allowed).to.be.false
|
|
200
|
+
expect(response.body.data.reason).to.be.oneOf([
|
|
201
|
+
'feature_not_in_plan',
|
|
202
|
+
'quota_exceeded',
|
|
203
|
+
'no_permission'
|
|
204
|
+
])
|
|
205
|
+
|
|
206
|
+
cy.log('Webhooks correctly blocked for Free plan')
|
|
207
|
+
cy.log(`Reason: ${response.body.data.reason}`)
|
|
208
|
+
})
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
it('FREE_016: Should block SSO configuration', () => {
|
|
212
|
+
allure.story('Security Features')
|
|
213
|
+
allure.severity('normal')
|
|
214
|
+
allure.description(`
|
|
215
|
+
Scenario: SSO configuration is not available
|
|
216
|
+
When I check action "auth.configure_sso"
|
|
217
|
+
Then the action should be denied
|
|
218
|
+
And the reason should be "feature_not_in_plan"
|
|
219
|
+
`)
|
|
220
|
+
|
|
221
|
+
billingAPI.checkAction('auth.configure_sso').then((response: any) => {
|
|
222
|
+
billingAPI.validateActionDenied(response, 'feature_not_in_plan')
|
|
223
|
+
|
|
224
|
+
cy.log('SSO correctly blocked for Free plan')
|
|
225
|
+
})
|
|
226
|
+
})
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
// ============================================================
|
|
230
|
+
// TEST GROUP 3: Quota Limits
|
|
231
|
+
// ============================================================
|
|
232
|
+
describe('Quota Limits', () => {
|
|
233
|
+
it('FREE_020: Should have team_members limit of 3', () => {
|
|
234
|
+
allure.story('Team Members Limit')
|
|
235
|
+
allure.severity('critical')
|
|
236
|
+
allure.description(`
|
|
237
|
+
Scenario: Team members limit of 3 is enforced
|
|
238
|
+
When I check usage for "team_members"
|
|
239
|
+
Then the max should be ${FREE_PLAN.limits.team_members}
|
|
240
|
+
`)
|
|
241
|
+
|
|
242
|
+
billingAPI.getUsage(TEST_TEAM.teamId, 'team_members').then((response: any) => {
|
|
243
|
+
billingAPI.validateUsageResponse(response, {
|
|
244
|
+
max: FREE_PLAN.limits.team_members
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
cy.log(`Team members limit: ${response.body.data.max}`)
|
|
248
|
+
cy.log(`Current usage: ${response.body.data.current}/${response.body.data.max}`)
|
|
249
|
+
})
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
it('FREE_021: Should have tasks limit of 50', () => {
|
|
253
|
+
allure.story('Tasks Limit')
|
|
254
|
+
allure.severity('critical')
|
|
255
|
+
allure.description(`
|
|
256
|
+
Scenario: Tasks limit of ${FREE_PLAN.limits.tasks} is enforced
|
|
257
|
+
When I check usage for "tasks"
|
|
258
|
+
Then the max should be ${FREE_PLAN.limits.tasks}
|
|
259
|
+
`)
|
|
260
|
+
|
|
261
|
+
billingAPI.getUsage(TEST_TEAM.teamId, 'tasks').then((response: any) => {
|
|
262
|
+
billingAPI.validateUsageResponse(response, {
|
|
263
|
+
max: FREE_PLAN.limits.tasks
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
cy.log(`Tasks limit: ${response.body.data.max}`)
|
|
267
|
+
cy.log(`Current usage: ${response.body.data.current}/${response.body.data.max}`)
|
|
268
|
+
})
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
it('FREE_022: Should have customers limit of 25', () => {
|
|
272
|
+
allure.story('Customers Limit')
|
|
273
|
+
allure.severity('critical')
|
|
274
|
+
allure.description(`
|
|
275
|
+
Scenario: Customers limit of ${FREE_PLAN.limits.customers} is enforced
|
|
276
|
+
When I check usage for "customers"
|
|
277
|
+
Then the max should be ${FREE_PLAN.limits.customers}
|
|
278
|
+
`)
|
|
279
|
+
|
|
280
|
+
billingAPI.getUsage(TEST_TEAM.teamId, 'customers').then((response: any) => {
|
|
281
|
+
billingAPI.validateUsageResponse(response, {
|
|
282
|
+
max: FREE_PLAN.limits.customers
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
cy.log(`Customers limit: ${response.body.data.max}`)
|
|
286
|
+
cy.log(`Current usage: ${response.body.data.current}/${response.body.data.max}`)
|
|
287
|
+
})
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
it('FREE_023: Should have api_calls limit of 1000 per month', () => {
|
|
291
|
+
allure.story('API Calls Limit')
|
|
292
|
+
allure.severity('normal')
|
|
293
|
+
allure.description(`
|
|
294
|
+
Scenario: API calls are tracked monthly
|
|
295
|
+
When I check usage for "api_calls"
|
|
296
|
+
Then the max should be ${FREE_PLAN.limits.api_calls}
|
|
297
|
+
`)
|
|
298
|
+
|
|
299
|
+
billingAPI.getUsage(TEST_TEAM.teamId, 'api_calls').then((response: any) => {
|
|
300
|
+
billingAPI.validateUsageResponse(response, {
|
|
301
|
+
max: FREE_PLAN.limits.api_calls
|
|
302
|
+
})
|
|
303
|
+
|
|
304
|
+
cy.log(`API calls limit: ${response.body.data.max}`)
|
|
305
|
+
cy.log(`Current usage: ${response.body.data.current}/${response.body.data.max}`)
|
|
306
|
+
})
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
it('FREE_024: Should have storage_gb limit of 1', () => {
|
|
310
|
+
allure.story('Storage Limit')
|
|
311
|
+
allure.severity('normal')
|
|
312
|
+
allure.description(`
|
|
313
|
+
Scenario: Storage limit of ${FREE_PLAN.limits.storage_gb}GB is enforced
|
|
314
|
+
When I check usage for "storage_gb"
|
|
315
|
+
Then the max should be ${FREE_PLAN.limits.storage_gb}
|
|
316
|
+
`)
|
|
317
|
+
|
|
318
|
+
billingAPI.getUsage(TEST_TEAM.teamId, 'storage_gb').then((response: any) => {
|
|
319
|
+
billingAPI.validateUsageResponse(response, {
|
|
320
|
+
max: FREE_PLAN.limits.storage_gb
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
cy.log(`Storage limit: ${response.body.data.max}GB`)
|
|
324
|
+
})
|
|
325
|
+
})
|
|
326
|
+
|
|
327
|
+
it('FREE_025: Should have webhooks_count limit of 0', () => {
|
|
328
|
+
allure.story('Webhooks Limit')
|
|
329
|
+
allure.severity('normal')
|
|
330
|
+
allure.description(`
|
|
331
|
+
Scenario: Webhooks count is 0 for Free plan
|
|
332
|
+
When I check usage for "webhooks_count"
|
|
333
|
+
Then the max should be ${FREE_PLAN.limits.webhooks_count}
|
|
334
|
+
`)
|
|
335
|
+
|
|
336
|
+
billingAPI.getUsage(TEST_TEAM.teamId, 'webhooks_count').then((response: any) => {
|
|
337
|
+
billingAPI.validateUsageResponse(response, {
|
|
338
|
+
max: FREE_PLAN.limits.webhooks_count
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
cy.log(`Webhooks limit: ${response.body.data.max}`)
|
|
342
|
+
})
|
|
343
|
+
})
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
// ============================================================
|
|
347
|
+
// TEST GROUP 4: Action Blocking at Quota
|
|
348
|
+
// ============================================================
|
|
349
|
+
describe('Quota Enforcement', () => {
|
|
350
|
+
it('FREE_030: Should block tasks.create when at limit', () => {
|
|
351
|
+
allure.story('Quota Blocking')
|
|
352
|
+
allure.severity('critical')
|
|
353
|
+
allure.description(`
|
|
354
|
+
Scenario: Tasks creation blocked when at limit
|
|
355
|
+
Given my team has reached the tasks limit
|
|
356
|
+
When I check action "tasks.create"
|
|
357
|
+
Then the action should be denied if at limit
|
|
358
|
+
And the reason should be "quota_exceeded" if at limit
|
|
359
|
+
`)
|
|
360
|
+
|
|
361
|
+
// First check current usage
|
|
362
|
+
billingAPI.getUsage(TEST_TEAM.teamId, 'tasks').then((response: any) => {
|
|
363
|
+
const currentUsage = response.body.data.current
|
|
364
|
+
const maxLimit = response.body.data.max
|
|
365
|
+
|
|
366
|
+
cy.log(`Tasks usage: ${currentUsage}/${maxLimit}`)
|
|
367
|
+
|
|
368
|
+
// Then check the action
|
|
369
|
+
billingAPI.checkAction('tasks.create').then((actionResponse: any) => {
|
|
370
|
+
if (currentUsage >= maxLimit) {
|
|
371
|
+
billingAPI.validateQuotaExceeded(actionResponse, {
|
|
372
|
+
current: currentUsage,
|
|
373
|
+
max: maxLimit
|
|
374
|
+
})
|
|
375
|
+
cy.log('tasks.create correctly blocked - quota exceeded')
|
|
376
|
+
} else {
|
|
377
|
+
billingAPI.validateActionAllowed(actionResponse)
|
|
378
|
+
cy.log(`tasks.create allowed - ${maxLimit - currentUsage} remaining`)
|
|
379
|
+
}
|
|
380
|
+
})
|
|
381
|
+
})
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
it('FREE_031: Should block customers.create when at limit', () => {
|
|
385
|
+
allure.story('Quota Blocking')
|
|
386
|
+
allure.severity('critical')
|
|
387
|
+
allure.description(`
|
|
388
|
+
Scenario: Customer creation blocked when at limit
|
|
389
|
+
Given my team has reached the customers limit
|
|
390
|
+
When I check action "customers.create"
|
|
391
|
+
Then the action should be denied if at limit
|
|
392
|
+
`)
|
|
393
|
+
|
|
394
|
+
// First check current usage
|
|
395
|
+
billingAPI.getUsage(TEST_TEAM.teamId, 'customers').then((response: any) => {
|
|
396
|
+
const currentUsage = response.body.data.current
|
|
397
|
+
const maxLimit = response.body.data.max
|
|
398
|
+
|
|
399
|
+
cy.log(`Customers usage: ${currentUsage}/${maxLimit}`)
|
|
400
|
+
|
|
401
|
+
// Then check the action
|
|
402
|
+
billingAPI.checkAction('customers.create').then((actionResponse: any) => {
|
|
403
|
+
if (currentUsage >= maxLimit) {
|
|
404
|
+
billingAPI.validateQuotaExceeded(actionResponse, {
|
|
405
|
+
current: currentUsage,
|
|
406
|
+
max: maxLimit
|
|
407
|
+
})
|
|
408
|
+
cy.log('customers.create correctly blocked - quota exceeded')
|
|
409
|
+
} else {
|
|
410
|
+
billingAPI.validateActionAllowed(actionResponse)
|
|
411
|
+
cy.log(`customers.create allowed - ${maxLimit - currentUsage} remaining`)
|
|
412
|
+
}
|
|
413
|
+
})
|
|
414
|
+
})
|
|
415
|
+
})
|
|
416
|
+
|
|
417
|
+
it('FREE_032: Should block team.members.invite when at limit', () => {
|
|
418
|
+
allure.story('Quota Blocking')
|
|
419
|
+
allure.severity('critical')
|
|
420
|
+
allure.description(`
|
|
421
|
+
Scenario: Team member invitation blocked when at limit
|
|
422
|
+
Given my team has reached the team_members limit
|
|
423
|
+
When I check action "team.members.invite"
|
|
424
|
+
Then the action should be denied if at limit
|
|
425
|
+
`)
|
|
426
|
+
|
|
427
|
+
// First check current usage
|
|
428
|
+
billingAPI.getUsage(TEST_TEAM.teamId, 'team_members').then((response: any) => {
|
|
429
|
+
const currentUsage = response.body.data.current
|
|
430
|
+
const maxLimit = response.body.data.max
|
|
431
|
+
|
|
432
|
+
cy.log(`Team members usage: ${currentUsage}/${maxLimit}`)
|
|
433
|
+
|
|
434
|
+
// Then check the action
|
|
435
|
+
billingAPI.checkAction('team.members.invite').then((actionResponse: any) => {
|
|
436
|
+
if (currentUsage >= maxLimit) {
|
|
437
|
+
billingAPI.validateQuotaExceeded(actionResponse, {
|
|
438
|
+
current: currentUsage,
|
|
439
|
+
max: maxLimit
|
|
440
|
+
})
|
|
441
|
+
cy.log('team.members.invite correctly blocked - quota exceeded')
|
|
442
|
+
} else {
|
|
443
|
+
billingAPI.validateActionAllowed(actionResponse)
|
|
444
|
+
cy.log(`team.members.invite allowed - ${maxLimit - currentUsage} remaining`)
|
|
445
|
+
}
|
|
446
|
+
})
|
|
447
|
+
})
|
|
448
|
+
})
|
|
449
|
+
})
|
|
450
|
+
|
|
451
|
+
// ============================================================
|
|
452
|
+
// TEST GROUP 5: Integration Tests
|
|
453
|
+
// ============================================================
|
|
454
|
+
describe('Integration', () => {
|
|
455
|
+
it('FREE_100: Should correctly enforce all Free plan restrictions', () => {
|
|
456
|
+
allure.story('Complete Validation')
|
|
457
|
+
allure.severity('critical')
|
|
458
|
+
allure.description(`
|
|
459
|
+
Integration test that validates all Free plan restrictions:
|
|
460
|
+
- Subscription is active with free plan
|
|
461
|
+
- All Pro/Business features are blocked
|
|
462
|
+
- All limits are correctly configured
|
|
463
|
+
`)
|
|
464
|
+
|
|
465
|
+
// 1. Verify subscription
|
|
466
|
+
billingAPI.getSubscription(TEST_TEAM.teamId).then((subResponse: any) => {
|
|
467
|
+
billingAPI.validateSubscriptionResponse(subResponse, {
|
|
468
|
+
status: 'active',
|
|
469
|
+
planSlug: 'free'
|
|
470
|
+
})
|
|
471
|
+
cy.log('1. Subscription verified: Free plan active')
|
|
472
|
+
})
|
|
473
|
+
|
|
474
|
+
// 2. Verify key blocked features
|
|
475
|
+
const blockedActions = [
|
|
476
|
+
'analytics.view_advanced',
|
|
477
|
+
'tasks.automate',
|
|
478
|
+
'customers.bulk_import'
|
|
479
|
+
]
|
|
480
|
+
|
|
481
|
+
blockedActions.forEach((action) => {
|
|
482
|
+
billingAPI.checkAction(action).then((response: any) => {
|
|
483
|
+
expect(response.body.data.allowed).to.be.false
|
|
484
|
+
cy.log(`2. ${action} correctly blocked`)
|
|
485
|
+
})
|
|
486
|
+
})
|
|
487
|
+
|
|
488
|
+
// 3. Verify limits match plan config
|
|
489
|
+
const limitsToCheck = ['tasks', 'customers', 'team_members']
|
|
490
|
+
limitsToCheck.forEach((limit) => {
|
|
491
|
+
billingAPI.getUsage(TEST_TEAM.teamId, limit).then((response: any) => {
|
|
492
|
+
expect(response.body.data.max).to.eq(FREE_PLAN.limits[limit])
|
|
493
|
+
cy.log(`3. ${limit} limit verified: ${response.body.data.max}`)
|
|
494
|
+
})
|
|
495
|
+
})
|
|
496
|
+
|
|
497
|
+
cy.log('Integration test completed successfully')
|
|
498
|
+
})
|
|
499
|
+
})
|
|
500
|
+
})
|