@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,396 @@
|
|
|
1
|
+
/// <reference types="cypress" />
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Blocks Scope API - Tests
|
|
5
|
+
*
|
|
6
|
+
* Test suite for blocks scope filtering functionality.
|
|
7
|
+
* Validates that GET /api/v1/blocks correctly filters blocks by scope parameter.
|
|
8
|
+
*
|
|
9
|
+
* Scope types:
|
|
10
|
+
* - 'pages': Blocks available in page builder
|
|
11
|
+
* - 'posts': Blocks available in post editor
|
|
12
|
+
* - No scope: Returns all blocks
|
|
13
|
+
*
|
|
14
|
+
* Tags: @api, @feat-page-builder, @scope
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import * as allure from 'allure-cypress'
|
|
18
|
+
|
|
19
|
+
describe('Blocks Scope API - Filtering Tests', {
|
|
20
|
+
tags: ['@api', '@feat-page-builder', '@scope']
|
|
21
|
+
}, () => {
|
|
22
|
+
// Test constants
|
|
23
|
+
const SUPERADMIN_API_KEY = 'test_api_key_for_testing_purposes_only_not_a_real_secret_key_abc123'
|
|
24
|
+
const BASE_URL = Cypress.config('baseUrl') || 'http://localhost:5173'
|
|
25
|
+
const API_BLOCKS = `${BASE_URL}/api/v1/blocks`
|
|
26
|
+
|
|
27
|
+
// Helper to make authenticated API key requests
|
|
28
|
+
const apiRequest = (method: string, url: string, body?: object) => {
|
|
29
|
+
return cy.request({
|
|
30
|
+
method,
|
|
31
|
+
url,
|
|
32
|
+
headers: {
|
|
33
|
+
'x-api-key': SUPERADMIN_API_KEY,
|
|
34
|
+
'Content-Type': 'application/json'
|
|
35
|
+
},
|
|
36
|
+
body,
|
|
37
|
+
failOnStatusCode: false
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
allure.epic('API')
|
|
43
|
+
allure.feature('Blocks')
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
// ============================================================
|
|
47
|
+
// GET /api/v1/blocks - List All Blocks (No Scope Filter)
|
|
48
|
+
// ============================================================
|
|
49
|
+
describe('GET /api/v1/blocks - List All Blocks', () => {
|
|
50
|
+
it('BLOCKS_API_001: Should list all blocks without scope filter', { tags: '@smoke' }, () => {
|
|
51
|
+
allure.story('Scope Filtering')
|
|
52
|
+
allure.severity('critical')
|
|
53
|
+
|
|
54
|
+
apiRequest('GET', API_BLOCKS).then((response) => {
|
|
55
|
+
expect(response.status).to.eq(200)
|
|
56
|
+
expect(response.body.success).to.be.true
|
|
57
|
+
expect(response.body.data).to.be.an('array')
|
|
58
|
+
expect(response.body.data.length).to.be.greaterThan(0)
|
|
59
|
+
|
|
60
|
+
cy.log(`Found ${response.body.data.length} total blocks`)
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('BLOCKS_API_002: Should return blocks with expected structure', () => {
|
|
65
|
+
apiRequest('GET', API_BLOCKS).then((response) => {
|
|
66
|
+
expect(response.status).to.eq(200)
|
|
67
|
+
|
|
68
|
+
if (response.body.data.length > 0) {
|
|
69
|
+
const block = response.body.data[0]
|
|
70
|
+
|
|
71
|
+
// Verify block structure
|
|
72
|
+
expect(block).to.have.property('slug')
|
|
73
|
+
expect(block).to.have.property('name')
|
|
74
|
+
expect(block).to.have.property('description')
|
|
75
|
+
expect(block).to.have.property('category')
|
|
76
|
+
expect(block).to.have.property('fieldDefinitions')
|
|
77
|
+
expect(block).to.have.property('scope')
|
|
78
|
+
|
|
79
|
+
cy.log(`Block structure verified: ${block.name}`)
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
// ============================================================
|
|
86
|
+
// GET /api/v1/blocks?scope=pages - Filter by Pages Scope
|
|
87
|
+
// ============================================================
|
|
88
|
+
describe('GET /api/v1/blocks?scope=pages - Filter by Pages Scope', () => {
|
|
89
|
+
it('BLOCKS_API_010: Should filter blocks by scope=pages', { tags: '@smoke' }, () => {
|
|
90
|
+
allure.story('Scope Filtering')
|
|
91
|
+
allure.severity('critical')
|
|
92
|
+
|
|
93
|
+
apiRequest('GET', `${API_BLOCKS}?scope=pages`).then((response) => {
|
|
94
|
+
expect(response.status).to.eq(200)
|
|
95
|
+
expect(response.body.success).to.be.true
|
|
96
|
+
expect(response.body.data).to.be.an('array')
|
|
97
|
+
|
|
98
|
+
// All returned blocks should include 'pages' in their scope
|
|
99
|
+
response.body.data.forEach((block: any) => {
|
|
100
|
+
expect(block.scope).to.exist
|
|
101
|
+
expect(block.scope).to.be.an('array')
|
|
102
|
+
expect(block.scope).to.include('pages')
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
cy.log(`Found ${response.body.data.length} blocks with scope 'pages'`)
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('BLOCKS_API_011: Should include expected blocks for pages', () => {
|
|
110
|
+
apiRequest('GET', `${API_BLOCKS}?scope=pages`).then((response) => {
|
|
111
|
+
expect(response.status).to.eq(200)
|
|
112
|
+
|
|
113
|
+
const blockSlugs = response.body.data.map((b: any) => b.slug)
|
|
114
|
+
|
|
115
|
+
// Expected blocks for pages (from plan.md)
|
|
116
|
+
const expectedBlocks = [
|
|
117
|
+
'cta-section',
|
|
118
|
+
'features-grid',
|
|
119
|
+
'testimonials',
|
|
120
|
+
'text-content',
|
|
121
|
+
'benefits'
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
expectedBlocks.forEach((expectedSlug) => {
|
|
125
|
+
expect(blockSlugs).to.include(expectedSlug)
|
|
126
|
+
cy.log(`Verified block '${expectedSlug}' is available for pages`)
|
|
127
|
+
})
|
|
128
|
+
})
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
it('BLOCKS_API_012: Should not include posts-only blocks', () => {
|
|
132
|
+
apiRequest('GET', `${API_BLOCKS}?scope=pages`).then((response) => {
|
|
133
|
+
expect(response.status).to.eq(200)
|
|
134
|
+
|
|
135
|
+
// Verify no block has scope=['posts'] only (without 'pages')
|
|
136
|
+
response.body.data.forEach((block: any) => {
|
|
137
|
+
if (block.scope && block.scope.length === 1 && block.scope[0] === 'posts') {
|
|
138
|
+
throw new Error(`Block '${block.slug}' should not appear in pages scope`)
|
|
139
|
+
}
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
cy.log('Verified posts-only blocks are excluded')
|
|
143
|
+
})
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
// ============================================================
|
|
148
|
+
// GET /api/v1/blocks?scope=posts - Filter by Posts Scope
|
|
149
|
+
// ============================================================
|
|
150
|
+
describe('GET /api/v1/blocks?scope=posts - Filter by Posts Scope', () => {
|
|
151
|
+
it('BLOCKS_API_020: Should filter blocks by scope=posts', { tags: '@smoke' }, () => {
|
|
152
|
+
allure.story('Scope Filtering')
|
|
153
|
+
allure.severity('critical')
|
|
154
|
+
|
|
155
|
+
apiRequest('GET', `${API_BLOCKS}?scope=posts`).then((response) => {
|
|
156
|
+
expect(response.status).to.eq(200)
|
|
157
|
+
expect(response.body.success).to.be.true
|
|
158
|
+
expect(response.body.data).to.be.an('array')
|
|
159
|
+
|
|
160
|
+
// All returned blocks should include 'posts' in their scope
|
|
161
|
+
response.body.data.forEach((block: any) => {
|
|
162
|
+
expect(block.scope).to.exist
|
|
163
|
+
expect(block.scope).to.be.an('array')
|
|
164
|
+
expect(block.scope).to.include('posts')
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
cy.log(`Found ${response.body.data.length} blocks with scope 'posts'`)
|
|
168
|
+
})
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
it('BLOCKS_API_021: Should include hero block for posts', () => {
|
|
172
|
+
apiRequest('GET', `${API_BLOCKS}?scope=posts`).then((response) => {
|
|
173
|
+
expect(response.status).to.eq(200)
|
|
174
|
+
|
|
175
|
+
const blockSlugs = response.body.data.map((b: any) => b.slug)
|
|
176
|
+
|
|
177
|
+
// Hero block should be available for posts (from plan.md)
|
|
178
|
+
expect(blockSlugs).to.include('hero')
|
|
179
|
+
|
|
180
|
+
const heroBlock = response.body.data.find((b: any) => b.slug === 'hero')
|
|
181
|
+
expect(heroBlock).to.exist
|
|
182
|
+
expect(heroBlock.scope).to.include('posts')
|
|
183
|
+
|
|
184
|
+
cy.log("Verified 'hero' block is available for posts")
|
|
185
|
+
})
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
it('BLOCKS_API_022: Should have fewer blocks than pages scope', () => {
|
|
189
|
+
// Get blocks for pages
|
|
190
|
+
apiRequest('GET', `${API_BLOCKS}?scope=pages`).then((pagesResponse) => {
|
|
191
|
+
const pagesCount = pagesResponse.body.data.length
|
|
192
|
+
|
|
193
|
+
// Get blocks for posts
|
|
194
|
+
apiRequest('GET', `${API_BLOCKS}?scope=posts`).then((postsResponse) => {
|
|
195
|
+
const postsCount = postsResponse.body.data.length
|
|
196
|
+
|
|
197
|
+
// Posts scope should have fewer blocks (only hero according to plan.md)
|
|
198
|
+
expect(postsCount).to.be.lessThan(pagesCount)
|
|
199
|
+
|
|
200
|
+
cy.log(`Pages blocks: ${pagesCount}, Posts blocks: ${postsCount}`)
|
|
201
|
+
})
|
|
202
|
+
})
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
it('BLOCKS_API_023: Should not include pages-only blocks', () => {
|
|
206
|
+
apiRequest('GET', `${API_BLOCKS}?scope=posts`).then((response) => {
|
|
207
|
+
expect(response.status).to.eq(200)
|
|
208
|
+
|
|
209
|
+
// Verify no block has scope=['pages'] only (without 'posts')
|
|
210
|
+
response.body.data.forEach((block: any) => {
|
|
211
|
+
if (block.scope && block.scope.length === 1 && block.scope[0] === 'pages') {
|
|
212
|
+
throw new Error(`Block '${block.slug}' should not appear in posts scope`)
|
|
213
|
+
}
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
cy.log('Verified pages-only blocks are excluded')
|
|
217
|
+
})
|
|
218
|
+
})
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
// ============================================================
|
|
222
|
+
// Edge Cases and Validation
|
|
223
|
+
// ============================================================
|
|
224
|
+
describe('Edge Cases and Validation', () => {
|
|
225
|
+
it('BLOCKS_API_030: Should handle invalid scope parameter gracefully', () => {
|
|
226
|
+
apiRequest('GET', `${API_BLOCKS}?scope=invalid-scope`).then((response) => {
|
|
227
|
+
expect(response.status).to.eq(200)
|
|
228
|
+
expect(response.body.success).to.be.true
|
|
229
|
+
expect(response.body.data).to.be.an('array')
|
|
230
|
+
|
|
231
|
+
// Should return empty array or no blocks matching the invalid scope
|
|
232
|
+
// (depending on implementation)
|
|
233
|
+
cy.log(`Invalid scope returned ${response.body.data.length} blocks`)
|
|
234
|
+
})
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
it('BLOCKS_API_031: Should handle empty scope parameter', () => {
|
|
238
|
+
apiRequest('GET', `${API_BLOCKS}?scope=`).then((response) => {
|
|
239
|
+
expect(response.status).to.eq(200)
|
|
240
|
+
expect(response.body.success).to.be.true
|
|
241
|
+
expect(response.body.data).to.be.an('array')
|
|
242
|
+
|
|
243
|
+
cy.log(`Empty scope parameter returned ${response.body.data.length} blocks`)
|
|
244
|
+
})
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
it('BLOCKS_API_032: Should handle multiple scope parameters', () => {
|
|
248
|
+
// Test if API supports multiple scopes (optional feature)
|
|
249
|
+
apiRequest('GET', `${API_BLOCKS}?scope=pages&scope=posts`).then((response) => {
|
|
250
|
+
expect(response.status).to.eq(200)
|
|
251
|
+
expect(response.body.success).to.be.true
|
|
252
|
+
expect(response.body.data).to.be.an('array')
|
|
253
|
+
|
|
254
|
+
cy.log(`Multiple scope parameters returned ${response.body.data.length} blocks`)
|
|
255
|
+
})
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
it('BLOCKS_API_033: Should verify blocks without scope are not returned', () => {
|
|
259
|
+
// Get all blocks
|
|
260
|
+
apiRequest('GET', API_BLOCKS).then((allResponse) => {
|
|
261
|
+
// Verify all blocks have a scope property
|
|
262
|
+
allResponse.body.data.forEach((block: any) => {
|
|
263
|
+
expect(block).to.have.property('scope')
|
|
264
|
+
// Blocks with undefined or empty scope should not appear in filtered results
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
cy.log('Verified all blocks have scope property')
|
|
268
|
+
})
|
|
269
|
+
})
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
// ============================================================
|
|
273
|
+
// Integration - Scope Consistency
|
|
274
|
+
// ============================================================
|
|
275
|
+
describe('Integration - Scope Consistency', () => {
|
|
276
|
+
it('BLOCKS_API_100: Should maintain scope consistency across requests', () => {
|
|
277
|
+
// Get all blocks
|
|
278
|
+
apiRequest('GET', API_BLOCKS).then((allResponse) => {
|
|
279
|
+
const allBlocks = allResponse.body.data
|
|
280
|
+
const totalBlocks = allBlocks.length
|
|
281
|
+
|
|
282
|
+
// Get pages scope
|
|
283
|
+
apiRequest('GET', `${API_BLOCKS}?scope=pages`).then((pagesResponse) => {
|
|
284
|
+
const pagesBlocks = pagesResponse.body.data
|
|
285
|
+
|
|
286
|
+
// Get posts scope
|
|
287
|
+
apiRequest('GET', `${API_BLOCKS}?scope=posts`).then((postsResponse) => {
|
|
288
|
+
const postsBlocks = postsResponse.body.data
|
|
289
|
+
|
|
290
|
+
// Verify consistency
|
|
291
|
+
cy.log(`Total blocks: ${totalBlocks}`)
|
|
292
|
+
cy.log(`Pages blocks: ${pagesBlocks.length}`)
|
|
293
|
+
cy.log(`Posts blocks: ${postsBlocks.length}`)
|
|
294
|
+
|
|
295
|
+
// Verify all filtered blocks exist in total blocks
|
|
296
|
+
pagesBlocks.forEach((pageBlock: any) => {
|
|
297
|
+
const existsInAll = allBlocks.some((b: any) => b.slug === pageBlock.slug)
|
|
298
|
+
expect(existsInAll).to.be.true
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
postsBlocks.forEach((postBlock: any) => {
|
|
302
|
+
const existsInAll = allBlocks.some((b: any) => b.slug === postBlock.slug)
|
|
303
|
+
expect(existsInAll).to.be.true
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
cy.log('Scope consistency verified across all requests')
|
|
307
|
+
})
|
|
308
|
+
})
|
|
309
|
+
})
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
it('BLOCKS_API_101: Should verify scope array structure', () => {
|
|
313
|
+
apiRequest('GET', API_BLOCKS).then((response) => {
|
|
314
|
+
expect(response.status).to.eq(200)
|
|
315
|
+
|
|
316
|
+
// Verify each block's scope is an array of strings
|
|
317
|
+
response.body.data.forEach((block: any) => {
|
|
318
|
+
expect(block.scope).to.exist
|
|
319
|
+
expect(block.scope).to.be.an('array')
|
|
320
|
+
|
|
321
|
+
block.scope.forEach((scopeValue: any) => {
|
|
322
|
+
expect(scopeValue).to.be.a('string')
|
|
323
|
+
// Verify it's a valid scope value
|
|
324
|
+
expect(['pages', 'posts']).to.include(scopeValue)
|
|
325
|
+
})
|
|
326
|
+
})
|
|
327
|
+
|
|
328
|
+
cy.log('All block scopes have valid array structure')
|
|
329
|
+
})
|
|
330
|
+
})
|
|
331
|
+
|
|
332
|
+
it('BLOCKS_API_102: Should verify dual-scope blocks appear in both filters', () => {
|
|
333
|
+
// Get hero block from posts scope
|
|
334
|
+
apiRequest('GET', `${API_BLOCKS}?scope=posts`).then((postsResponse) => {
|
|
335
|
+
const heroInPosts = postsResponse.body.data.find((b: any) => b.slug === 'hero')
|
|
336
|
+
|
|
337
|
+
if (heroInPosts) {
|
|
338
|
+
// If hero is in posts, it might also be in pages
|
|
339
|
+
apiRequest('GET', `${API_BLOCKS}?scope=pages`).then((pagesResponse) => {
|
|
340
|
+
const heroInPages = pagesResponse.body.data.find((b: any) => b.slug === 'hero')
|
|
341
|
+
|
|
342
|
+
if (heroInPages) {
|
|
343
|
+
// Verify hero has both 'pages' and 'posts' in scope
|
|
344
|
+
expect(heroInPosts.scope).to.include('posts')
|
|
345
|
+
expect(heroInPages.scope).to.include('pages')
|
|
346
|
+
|
|
347
|
+
cy.log("Hero block correctly appears in both scopes")
|
|
348
|
+
} else {
|
|
349
|
+
// Hero is posts-only
|
|
350
|
+
expect(heroInPosts.scope).to.deep.equal(['posts'])
|
|
351
|
+
cy.log("Hero block is posts-only")
|
|
352
|
+
}
|
|
353
|
+
})
|
|
354
|
+
}
|
|
355
|
+
})
|
|
356
|
+
})
|
|
357
|
+
})
|
|
358
|
+
|
|
359
|
+
// ============================================================
|
|
360
|
+
// Public Access (Blocks API is publicly accessible)
|
|
361
|
+
// ============================================================
|
|
362
|
+
describe('Public Access', () => {
|
|
363
|
+
it('BLOCKS_API_200: Should allow public access without authentication', { tags: '@security' }, () => {
|
|
364
|
+
/**
|
|
365
|
+
* NOTE: The blocks API is intentionally public to allow frontend
|
|
366
|
+
* applications to fetch block definitions without authentication.
|
|
367
|
+
* This enables page/post editors to load block schemas client-side.
|
|
368
|
+
*/
|
|
369
|
+
cy.request({
|
|
370
|
+
method: 'GET',
|
|
371
|
+
url: API_BLOCKS,
|
|
372
|
+
failOnStatusCode: false
|
|
373
|
+
}).then((response) => {
|
|
374
|
+
expect(response.status).to.eq(200)
|
|
375
|
+
expect(response.body.success).to.be.true
|
|
376
|
+
expect(response.body.data).to.be.an('array')
|
|
377
|
+
|
|
378
|
+
cy.log('Blocks API is publicly accessible (by design)')
|
|
379
|
+
})
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
it('BLOCKS_API_201: Should allow scope filter without authentication', { tags: '@security' }, () => {
|
|
383
|
+
cy.request({
|
|
384
|
+
method: 'GET',
|
|
385
|
+
url: `${API_BLOCKS}?scope=pages`,
|
|
386
|
+
failOnStatusCode: false
|
|
387
|
+
}).then((response) => {
|
|
388
|
+
expect(response.status).to.eq(200)
|
|
389
|
+
expect(response.body.success).to.be.true
|
|
390
|
+
expect(response.body.data).to.be.an('array')
|
|
391
|
+
|
|
392
|
+
cy.log('Blocks scope filter is publicly accessible (by design)')
|
|
393
|
+
})
|
|
394
|
+
})
|
|
395
|
+
})
|
|
396
|
+
})
|