@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.
Files changed (221) hide show
  1. package/package.json +1 -1
  2. package/tests/cypress/e2e/_devtools/access.bdd.md +262 -0
  3. package/tests/cypress/e2e/_devtools/access.cy.ts +171 -0
  4. package/tests/cypress/e2e/_devtools/navigation.bdd.md +261 -0
  5. package/tests/cypress/e2e/_devtools/navigation.cy.ts +157 -0
  6. package/tests/cypress/e2e/_devtools/pages.bdd.md +303 -0
  7. package/tests/cypress/e2e/_devtools/pages.cy.ts +184 -0
  8. package/tests/cypress/e2e/_docs/README.md +215 -0
  9. package/tests/cypress/e2e/_docs/tutorials/sector7-superadmin-teams.narration.json +155 -0
  10. package/tests/cypress/e2e/_docs/tutorials/sector7-superadmin.cy.ts +390 -0
  11. package/tests/cypress/e2e/_docs/tutorials/teams-system.doc.cy.ts +349 -0
  12. package/tests/cypress/e2e/_docs/tutorials/teams-system.narration.json +165 -0
  13. package/tests/cypress/e2e/_selectors/auth.cy.ts +306 -0
  14. package/tests/cypress/e2e/_selectors/billing.cy.ts +89 -0
  15. package/tests/cypress/e2e/_selectors/dashboard-mobile.cy.ts +113 -0
  16. package/tests/cypress/e2e/_selectors/dashboard-navigation.cy.ts +89 -0
  17. package/tests/cypress/e2e/_selectors/dashboard-sidebar.cy.ts +60 -0
  18. package/tests/cypress/e2e/_selectors/dashboard-topnav.cy.ts +146 -0
  19. package/tests/cypress/e2e/_selectors/devtools.cy.ts +210 -0
  20. package/tests/cypress/e2e/_selectors/global-search.cy.ts +88 -0
  21. package/tests/cypress/e2e/_selectors/pages-editor.cy.ts +179 -0
  22. package/tests/cypress/e2e/_selectors/posts-editor.cy.ts +282 -0
  23. package/tests/cypress/e2e/_selectors/public.cy.ts +112 -0
  24. package/tests/cypress/e2e/_selectors/settings-api-keys.cy.ts +228 -0
  25. package/tests/cypress/e2e/_selectors/settings-billing.cy.ts +105 -0
  26. package/tests/cypress/e2e/_selectors/settings-layout.cy.ts +119 -0
  27. package/tests/cypress/e2e/_selectors/settings-password.cy.ts +71 -0
  28. package/tests/cypress/e2e/_selectors/settings-profile.cy.ts +82 -0
  29. package/tests/cypress/e2e/_selectors/settings-teams.cy.ts +68 -0
  30. package/tests/cypress/e2e/_selectors/superadmin.cy.ts +185 -0
  31. package/tests/cypress/e2e/_selectors/tasks.cy.ts +242 -0
  32. package/tests/cypress/e2e/_selectors/taxonomies.cy.ts +126 -0
  33. package/tests/cypress/e2e/_selectors/teams.cy.ts +142 -0
  34. package/tests/cypress/e2e/_superadmin/all-teams.bdd.md +261 -0
  35. package/tests/cypress/e2e/_superadmin/all-teams.cy.ts +177 -0
  36. package/tests/cypress/e2e/_superadmin/all-users.bdd.md +406 -0
  37. package/tests/cypress/e2e/_superadmin/all-users.cy.ts +294 -0
  38. package/tests/cypress/e2e/_superadmin/dashboard.bdd.md +235 -0
  39. package/tests/cypress/e2e/_superadmin/dashboard.cy.ts +149 -0
  40. package/tests/cypress/e2e/_superadmin/subscriptions-overview.bdd.md +290 -0
  41. package/tests/cypress/e2e/_superadmin/subscriptions-overview.cy.ts +194 -0
  42. package/tests/cypress/e2e/ai/ai-usage.cy.ts +209 -0
  43. package/tests/cypress/e2e/ai/chat-api.cy.ts +107 -0
  44. package/tests/cypress/e2e/ai/guardrails.cy.ts +332 -0
  45. package/tests/cypress/e2e/api/billing/BillingAPIController.js +319 -0
  46. package/tests/cypress/e2e/api/billing/check-action.cy.ts +326 -0
  47. package/tests/cypress/e2e/api/billing/checkout.cy.ts +358 -0
  48. package/tests/cypress/e2e/api/billing/lifecycle.cy.ts +423 -0
  49. package/tests/cypress/e2e/api/billing/plans/README.md +345 -0
  50. package/tests/cypress/e2e/api/billing/plans/business.cy.ts +412 -0
  51. package/tests/cypress/e2e/api/billing/plans/downgrade.cy.ts +510 -0
  52. package/tests/cypress/e2e/api/billing/plans/fixtures/billing-plans.json +163 -0
  53. package/tests/cypress/e2e/api/billing/plans/free.cy.ts +500 -0
  54. package/tests/cypress/e2e/api/billing/plans/pro.cy.ts +497 -0
  55. package/tests/cypress/e2e/api/billing/plans/starter.cy.ts +342 -0
  56. package/tests/cypress/e2e/api/billing/portal.cy.ts +313 -0
  57. package/tests/cypress/e2e/api/devtools/registries.bdd.md +300 -0
  58. package/tests/cypress/e2e/api/devtools/registries.cy.ts +368 -0
  59. package/tests/cypress/e2e/api/entities/blocks-scope.cy.ts +396 -0
  60. package/tests/cypress/e2e/api/entities/customers-crud.cy.ts +648 -0
  61. package/tests/cypress/e2e/api/entities/customers-metas.cy.ts +839 -0
  62. package/tests/cypress/e2e/api/entities/pages-crud.cy.ts +425 -0
  63. package/tests/cypress/e2e/api/entities/pages-status.cy.ts +335 -0
  64. package/tests/cypress/e2e/api/entities/post-categories-crud.cy.ts +610 -0
  65. package/tests/cypress/e2e/api/entities/posts-crud.cy.ts +709 -0
  66. package/tests/cypress/e2e/api/entities/posts-status.cy.ts +396 -0
  67. package/tests/cypress/e2e/api/entities/tasks-crud.cy.ts +602 -0
  68. package/tests/cypress/e2e/api/entities/tasks-metas.cy.ts +878 -0
  69. package/tests/cypress/e2e/api/entities/users-crud.cy.ts +469 -0
  70. package/tests/cypress/e2e/api/entities/users-metas.cy.ts +913 -0
  71. package/tests/cypress/e2e/api/entities/users-security.cy.ts +375 -0
  72. package/tests/cypress/e2e/api/scheduled-actions/cron-endpoint.bdd.md +375 -0
  73. package/tests/cypress/e2e/api/scheduled-actions/cron-endpoint.cy.ts +346 -0
  74. package/tests/cypress/e2e/api/scheduled-actions/devtools-endpoint.bdd.md +451 -0
  75. package/tests/cypress/e2e/api/scheduled-actions/devtools-endpoint.cy.ts +447 -0
  76. package/tests/cypress/e2e/api/scheduled-actions/scheduling.bdd.md +649 -0
  77. package/tests/cypress/e2e/api/scheduled-actions/scheduling.cy.ts +333 -0
  78. package/tests/cypress/e2e/api/settings/api-keys.crud.cy.ts +923 -0
  79. package/tests/cypress/e2e/uat/auth/app-roles/developer-login.bdd.md +231 -0
  80. package/tests/cypress/e2e/uat/auth/app-roles/developer-login.cy.ts +144 -0
  81. package/tests/cypress/e2e/uat/auth/app-roles/superadmin-login.bdd.md +118 -0
  82. package/tests/cypress/e2e/uat/auth/app-roles/superadmin-login.cy.ts +84 -0
  83. package/tests/cypress/e2e/uat/auth/custom-roles/editor-login.bdd.md +288 -0
  84. package/tests/cypress/e2e/uat/auth/custom-roles/editor-login.cy.ts +188 -0
  85. package/tests/cypress/e2e/uat/auth/login-logout.bdd.md +160 -0
  86. package/tests/cypress/e2e/uat/auth/login-logout.cy.ts +116 -0
  87. package/tests/cypress/e2e/uat/auth/password-reset.bdd.md +289 -0
  88. package/tests/cypress/e2e/uat/auth/password-reset.cy.ts +200 -0
  89. package/tests/cypress/e2e/uat/auth/team-roles/admin-login.bdd.md +225 -0
  90. package/tests/cypress/e2e/uat/auth/team-roles/admin-login.cy.ts +148 -0
  91. package/tests/cypress/e2e/uat/auth/team-roles/member-login.bdd.md +251 -0
  92. package/tests/cypress/e2e/uat/auth/team-roles/member-login.cy.ts +163 -0
  93. package/tests/cypress/e2e/uat/auth/team-roles/owner-login.bdd.md +231 -0
  94. package/tests/cypress/e2e/uat/auth/team-roles/owner-login.cy.ts +141 -0
  95. package/tests/cypress/e2e/uat/billing/extended.bdd.md +273 -0
  96. package/tests/cypress/e2e/uat/billing/extended.cy.ts +209 -0
  97. package/tests/cypress/e2e/uat/billing/feature-gates.bdd.md +407 -0
  98. package/tests/cypress/e2e/uat/billing/feature-gates.cy.ts +307 -0
  99. package/tests/cypress/e2e/uat/billing/page.bdd.md +329 -0
  100. package/tests/cypress/e2e/uat/billing/page.cy.ts +250 -0
  101. package/tests/cypress/e2e/uat/billing/status.bdd.md +190 -0
  102. package/tests/cypress/e2e/uat/billing/status.cy.ts +145 -0
  103. package/tests/cypress/e2e/uat/billing/team-switch.bdd.md +156 -0
  104. package/tests/cypress/e2e/uat/billing/team-switch.cy.ts +122 -0
  105. package/tests/cypress/e2e/uat/billing/usage.bdd.md +218 -0
  106. package/tests/cypress/e2e/uat/billing/usage.cy.ts +176 -0
  107. package/tests/cypress/e2e/uat/blocks/hero.bdd.md +124 -0
  108. package/tests/cypress/e2e/uat/blocks/hero.cy.ts +56 -0
  109. package/tests/cypress/e2e/uat/devtools/api-tester.cy.ts +390 -0
  110. package/tests/cypress/e2e/uat/entities/customers/member.bdd.md +275 -0
  111. package/tests/cypress/e2e/uat/entities/customers/member.cy.ts +122 -0
  112. package/tests/cypress/e2e/uat/entities/customers/owner.bdd.md +243 -0
  113. package/tests/cypress/e2e/uat/entities/customers/owner.cy.ts +165 -0
  114. package/tests/cypress/e2e/uat/entities/pages/block-crud.bdd.md +476 -0
  115. package/tests/cypress/e2e/uat/entities/pages/block-crud.cy.ts +486 -0
  116. package/tests/cypress/e2e/uat/entities/pages/block-editor.bdd.md +460 -0
  117. package/tests/cypress/e2e/uat/entities/pages/block-editor.cy.ts +301 -0
  118. package/tests/cypress/e2e/uat/entities/pages/list.bdd.md +432 -0
  119. package/tests/cypress/e2e/uat/entities/pages/list.cy.ts +273 -0
  120. package/tests/cypress/e2e/uat/entities/pages/public-rendering.bdd.md +696 -0
  121. package/tests/cypress/e2e/uat/entities/pages/public-rendering.cy.ts +340 -0
  122. package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.bdd.md +161 -0
  123. package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.cy.ts +104 -0
  124. package/tests/cypress/e2e/uat/entities/posts/categories.bdd.md +375 -0
  125. package/tests/cypress/e2e/uat/entities/posts/categories.cy.ts +241 -0
  126. package/tests/cypress/e2e/uat/entities/posts/editor.bdd.md +429 -0
  127. package/tests/cypress/e2e/uat/entities/posts/editor.cy.ts +257 -0
  128. package/tests/cypress/e2e/uat/entities/posts/list.bdd.md +340 -0
  129. package/tests/cypress/e2e/uat/entities/posts/list.cy.ts +177 -0
  130. package/tests/cypress/e2e/uat/entities/posts/public.bdd.md +614 -0
  131. package/tests/cypress/e2e/uat/entities/posts/public.cy.ts +249 -0
  132. package/tests/cypress/e2e/uat/entities/tasks/member.bdd.md +222 -0
  133. package/tests/cypress/e2e/uat/entities/tasks/member.cy.ts +165 -0
  134. package/tests/cypress/e2e/uat/entities/tasks/owner.bdd.md +419 -0
  135. package/tests/cypress/e2e/uat/entities/tasks/owner.cy.ts +191 -0
  136. package/tests/cypress/e2e/uat/roles/editor-role.bdd.md +552 -0
  137. package/tests/cypress/e2e/uat/roles/editor-role.cy.ts +210 -0
  138. package/tests/cypress/e2e/uat/roles/member-restrictions.bdd.md +450 -0
  139. package/tests/cypress/e2e/uat/roles/member-restrictions.cy.ts +189 -0
  140. package/tests/cypress/e2e/uat/roles/owner-full-crud.bdd.md +530 -0
  141. package/tests/cypress/e2e/uat/roles/owner-full-crud.cy.ts +247 -0
  142. package/tests/cypress/e2e/uat/scheduled-actions/devtools-ui.bdd.md +736 -0
  143. package/tests/cypress/e2e/uat/scheduled-actions/devtools-ui.cy.ts +740 -0
  144. package/tests/cypress/e2e/uat/teams/roles-matrix.bdd.md +553 -0
  145. package/tests/cypress/e2e/uat/teams/roles-matrix.cy.ts +185 -0
  146. package/tests/cypress/e2e/uat/teams/switcher.bdd.md +1151 -0
  147. package/tests/cypress/e2e/uat/teams/switcher.cy.ts +497 -0
  148. package/tests/cypress/e2e/uat/teams/team-switcher.md +198 -0
  149. package/tests/cypress/fixtures/blocks.json +218 -0
  150. package/tests/cypress/fixtures/entities.json +78 -0
  151. package/tests/cypress/fixtures/page-builder.json +21 -0
  152. package/tests/cypress/src/components/CategoriesPOM.ts +382 -0
  153. package/tests/cypress/src/components/CustomersPOM.ts +439 -0
  154. package/tests/cypress/src/components/DevKeyringPOM.ts +160 -0
  155. package/tests/cypress/src/components/EntityForm.ts +375 -0
  156. package/tests/cypress/src/components/EntityList.ts +389 -0
  157. package/tests/cypress/src/components/PageBuilderPOM.ts +710 -0
  158. package/tests/cypress/src/components/PostEditorPOM.ts +370 -0
  159. package/tests/cypress/src/components/PostsListPOM.ts +223 -0
  160. package/tests/cypress/src/components/PublicPagePOM.ts +447 -0
  161. package/tests/cypress/src/components/PublicPostPOM.ts +146 -0
  162. package/tests/cypress/src/components/TasksPOM.ts +272 -0
  163. package/tests/cypress/src/components/TeamSwitcherPOM.ts +450 -0
  164. package/tests/cypress/src/components/index.ts +21 -0
  165. package/tests/cypress/src/controllers/ApiKeysAPIController.js +178 -0
  166. package/tests/cypress/src/controllers/BaseAPIController.js +317 -0
  167. package/tests/cypress/src/controllers/CustomerAPIController.js +251 -0
  168. package/tests/cypress/src/controllers/PagesAPIController.js +226 -0
  169. package/tests/cypress/src/controllers/PostsAPIController.js +250 -0
  170. package/tests/cypress/src/controllers/TaskAPIController.js +240 -0
  171. package/tests/cypress/src/controllers/UsersAPIController.js +242 -0
  172. package/tests/cypress/src/controllers/index.js +25 -0
  173. package/tests/cypress/src/core/AuthPOM.ts +450 -0
  174. package/tests/cypress/src/core/BasePOM.ts +86 -0
  175. package/tests/cypress/src/core/BlockEditorBasePOM.ts +576 -0
  176. package/tests/cypress/src/core/DashboardEntityPOM.ts +692 -0
  177. package/tests/cypress/src/core/index.ts +14 -0
  178. package/tests/cypress/src/entities/CustomersPOM.ts +172 -0
  179. package/tests/cypress/src/entities/PagesPOM.ts +137 -0
  180. package/tests/cypress/src/entities/PostsPOM.ts +137 -0
  181. package/tests/cypress/src/entities/TasksPOM.ts +176 -0
  182. package/tests/cypress/src/entities/index.ts +14 -0
  183. package/tests/cypress/src/features/BillingPOM.ts +385 -0
  184. package/tests/cypress/src/features/DashboardPOM.ts +245 -0
  185. package/tests/cypress/src/features/DevtoolsPOM.ts +739 -0
  186. package/tests/cypress/src/features/PageBuilderPOM.ts +263 -0
  187. package/tests/cypress/src/features/PostEditorPOM.ts +313 -0
  188. package/tests/cypress/src/features/ScheduledActionsPOM.ts +463 -0
  189. package/tests/cypress/src/features/SettingsPOM.ts +362 -0
  190. package/tests/cypress/src/features/SuperadminPOM.ts +331 -0
  191. package/tests/cypress/src/features/SuperadminTeamRolesPOM.ts +285 -0
  192. package/tests/cypress/src/features/index.ts +28 -0
  193. package/tests/cypress/src/helpers/ApiInterceptor.ts +177 -0
  194. package/tests/cypress/src/index.ts +101 -0
  195. package/tests/cypress/src/pages/dashboard/Dashboard.js +677 -0
  196. package/tests/cypress/src/pages/dashboard/DashboardPage.js +43 -0
  197. package/tests/cypress/src/pages/dashboard/DashboardStats.js +546 -0
  198. package/tests/cypress/src/pages/dashboard/index.js +6 -0
  199. package/tests/cypress/src/pages/index.js +5 -0
  200. package/tests/cypress/src/pages/public/FeaturesPage.js +28 -0
  201. package/tests/cypress/src/pages/public/LandingPage.js +69 -0
  202. package/tests/cypress/src/pages/public/PricingPage.js +33 -0
  203. package/tests/cypress/src/pages/public/index.js +6 -0
  204. package/tests/cypress/src/selectors.ts +46 -0
  205. package/tests/cypress/src/session-helpers.ts +500 -0
  206. package/tests/cypress/support/doc-commands.ts +260 -0
  207. package/tests/cypress/support/e2e.ts +89 -0
  208. package/tests/cypress.config.ts +165 -0
  209. package/tests/jest/components/post-header.test.tsx +377 -0
  210. package/tests/jest/config/role-config.test.ts +529 -0
  211. package/tests/jest/jest.config.ts +81 -0
  212. package/tests/jest/langchain/COVERAGE.md +372 -0
  213. package/tests/jest/langchain/guardrails.test.ts +465 -0
  214. package/tests/jest/langchain/streaming.test.ts +367 -0
  215. package/tests/jest/langchain/token-tracker.test.ts +455 -0
  216. package/tests/jest/langchain/tracer-callbacks.test.ts +881 -0
  217. package/tests/jest/langchain/tracer.test.ts +823 -0
  218. package/tests/jest/user-roles/role-helpers.test.ts +432 -0
  219. package/tests/jest/validation/categories.test.ts +429 -0
  220. package/tests/jest/validation/posts.test.ts +546 -0
  221. 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
+ })