@nextsparkjs/core 0.1.0-beta.22 → 0.1.0-beta.24
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/dist/styles/classes.json +1 -1
- package/dist/styles/ui.css +1 -1
- package/dist/templates/contents/themes/starter/tests/cypress/e2e/_selectors/auth.cy.ts +199 -0
- package/dist/templates/contents/themes/starter/tests/cypress/e2e/_selectors/dashboard-navigation.cy.ts +104 -0
- package/dist/templates/contents/themes/starter/tests/cypress/e2e/_selectors/tasks.cy.ts +274 -0
- package/dist/templates/contents/themes/starter/tests/cypress/support/e2e.ts +36 -4
- package/dist/templates/contents/themes/starter/tests/cypress.config.ts +18 -15
- package/dist/templates/contents/themes/starter/tests/jest/__mocks__/jose.js +22 -0
- package/dist/templates/contents/themes/starter/tests/jest/__mocks__/next-server.js +56 -0
- package/dist/templates/contents/themes/starter/tests/jest/example.test.ts +87 -0
- package/dist/templates/contents/themes/starter/tests/jest/jest.config.cjs +90 -0
- package/dist/templates/contents/themes/starter/tests/jest/services/tasks.service.test.ts +547 -0
- package/dist/templates/contents/themes/starter/tests/jest/setup.ts +170 -0
- package/package.json +12 -12
- package/scripts/build/docs-registry.mjs +0 -0
- package/scripts/create-theme.mjs +0 -0
- package/scripts/deploy/release-version.mjs +0 -0
- package/scripts/deploy/vercel-deploy.mjs +0 -0
- package/scripts/dev/watch-plugins.mjs +0 -0
- package/scripts/maintenance/update-core.mjs +0 -0
- package/scripts/setup/npm-postinstall.mjs +0 -0
- package/scripts/setup/setup-claude.mjs +0 -0
- package/scripts/validation/check-imports.sh +0 -0
- package/templates/contents/themes/starter/tests/cypress/e2e/_selectors/auth.cy.ts +199 -0
- package/templates/contents/themes/starter/tests/cypress/e2e/_selectors/dashboard-navigation.cy.ts +104 -0
- package/templates/contents/themes/starter/tests/cypress/e2e/_selectors/tasks.cy.ts +274 -0
- package/templates/contents/themes/starter/tests/cypress/support/e2e.ts +36 -4
- package/templates/contents/themes/starter/tests/cypress.config.ts +18 -15
- package/templates/contents/themes/starter/tests/jest/__mocks__/jose.js +22 -0
- package/templates/contents/themes/starter/tests/jest/__mocks__/next-server.js +56 -0
- package/templates/contents/themes/starter/tests/jest/example.test.ts +87 -0
- package/templates/contents/themes/starter/tests/jest/jest.config.cjs +90 -0
- package/templates/contents/themes/starter/tests/jest/services/tasks.service.test.ts +547 -0
- package/templates/contents/themes/starter/tests/jest/setup.ts +170 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jest Setup for Starter Theme
|
|
3
|
+
*
|
|
4
|
+
* This file provides complete Jest setup for npm mode.
|
|
5
|
+
* It includes all necessary polyfills and mocks.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import '@testing-library/jest-dom'
|
|
9
|
+
import { TextEncoder, TextDecoder } from 'util'
|
|
10
|
+
|
|
11
|
+
// Polyfill TextEncoder/TextDecoder for jsdom
|
|
12
|
+
global.TextEncoder = TextEncoder
|
|
13
|
+
global.TextDecoder = TextDecoder as typeof global.TextDecoder
|
|
14
|
+
|
|
15
|
+
// Polyfill Web APIs for Next.js server components testing
|
|
16
|
+
class MockHeaders {
|
|
17
|
+
private _headers: Map<string, string> = new Map()
|
|
18
|
+
|
|
19
|
+
constructor(init?: HeadersInit) {
|
|
20
|
+
if (init) {
|
|
21
|
+
if (init instanceof MockHeaders) {
|
|
22
|
+
init._headers.forEach((value, key) => this._headers.set(key, value))
|
|
23
|
+
} else if (Array.isArray(init)) {
|
|
24
|
+
init.forEach(([key, value]) => this._headers.set(key.toLowerCase(), value))
|
|
25
|
+
} else {
|
|
26
|
+
Object.entries(init).forEach(([key, value]) => this._headers.set(key.toLowerCase(), value))
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get(name: string) { return this._headers.get(name.toLowerCase()) || null }
|
|
32
|
+
set(name: string, value: string) { this._headers.set(name.toLowerCase(), value) }
|
|
33
|
+
has(name: string) { return this._headers.has(name.toLowerCase()) }
|
|
34
|
+
delete(name: string) { this._headers.delete(name.toLowerCase()) }
|
|
35
|
+
forEach(cb: (value: string, key: string) => void) { this._headers.forEach(cb) }
|
|
36
|
+
entries() { return this._headers.entries() }
|
|
37
|
+
keys() { return this._headers.keys() }
|
|
38
|
+
values() { return this._headers.values() }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
class MockRequest {
|
|
42
|
+
url: string
|
|
43
|
+
method: string
|
|
44
|
+
headers: MockHeaders
|
|
45
|
+
private _body: any
|
|
46
|
+
|
|
47
|
+
constructor(input: string | URL, init?: RequestInit) {
|
|
48
|
+
this.url = typeof input === 'string' ? input : input.toString()
|
|
49
|
+
this.method = init?.method || 'GET'
|
|
50
|
+
this.headers = new MockHeaders(init?.headers as HeadersInit)
|
|
51
|
+
this._body = init?.body
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async json() {
|
|
55
|
+
if (!this._body) return {}
|
|
56
|
+
return typeof this._body === 'string' ? JSON.parse(this._body) : this._body
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async text() {
|
|
60
|
+
return this._body?.toString() || ''
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
clone() {
|
|
64
|
+
return new MockRequest(this.url, {
|
|
65
|
+
method: this.method,
|
|
66
|
+
headers: Object.fromEntries(this.headers.entries()),
|
|
67
|
+
body: this._body,
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
class MockResponse {
|
|
73
|
+
body: any
|
|
74
|
+
status: number
|
|
75
|
+
statusText: string
|
|
76
|
+
headers: MockHeaders
|
|
77
|
+
ok: boolean
|
|
78
|
+
|
|
79
|
+
constructor(body?: any, init?: ResponseInit) {
|
|
80
|
+
this.body = body
|
|
81
|
+
this.status = init?.status || 200
|
|
82
|
+
this.statusText = init?.statusText || 'OK'
|
|
83
|
+
this.headers = new MockHeaders(init?.headers as HeadersInit)
|
|
84
|
+
this.ok = this.status >= 200 && this.status < 300
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async json() {
|
|
88
|
+
if (!this.body) return {}
|
|
89
|
+
return typeof this.body === 'string' ? JSON.parse(this.body) : this.body
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async text() {
|
|
93
|
+
return this.body?.toString() || ''
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
clone() {
|
|
97
|
+
return new MockResponse(this.body, {
|
|
98
|
+
status: this.status,
|
|
99
|
+
statusText: this.statusText,
|
|
100
|
+
headers: Object.fromEntries(this.headers.entries()),
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
static json(data: any, init?: ResponseInit) {
|
|
105
|
+
return new MockResponse(JSON.stringify(data), {
|
|
106
|
+
...init,
|
|
107
|
+
headers: { 'Content-Type': 'application/json', ...(init?.headers || {}) as object },
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Assign to global scope
|
|
113
|
+
global.Headers = MockHeaders as any
|
|
114
|
+
global.Request = MockRequest as any
|
|
115
|
+
global.Response = MockResponse as any
|
|
116
|
+
|
|
117
|
+
// Mock fetch
|
|
118
|
+
global.fetch = jest.fn().mockResolvedValue(new MockResponse('{}', { status: 200 }))
|
|
119
|
+
|
|
120
|
+
// Mock Web Crypto API
|
|
121
|
+
const crypto = require('crypto')
|
|
122
|
+
Object.defineProperty(global, 'crypto', {
|
|
123
|
+
value: {
|
|
124
|
+
getRandomValues: (arr: Uint8Array) => crypto.randomFillSync(arr),
|
|
125
|
+
randomUUID: () => crypto.randomUUID(),
|
|
126
|
+
subtle: {
|
|
127
|
+
digest: async (algorithm: string, data: BufferSource) => {
|
|
128
|
+
const hash = crypto.createHash(algorithm.toLowerCase().replace('-', ''))
|
|
129
|
+
hash.update(Buffer.from(data as ArrayBuffer))
|
|
130
|
+
return hash.digest().buffer
|
|
131
|
+
},
|
|
132
|
+
encrypt: jest.fn(),
|
|
133
|
+
decrypt: jest.fn(),
|
|
134
|
+
sign: jest.fn(),
|
|
135
|
+
verify: jest.fn(),
|
|
136
|
+
generateKey: jest.fn(),
|
|
137
|
+
importKey: jest.fn(),
|
|
138
|
+
exportKey: jest.fn(),
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
// Mock matchMedia for component tests with media queries
|
|
144
|
+
Object.defineProperty(window, 'matchMedia', {
|
|
145
|
+
writable: true,
|
|
146
|
+
value: jest.fn().mockImplementation((query) => ({
|
|
147
|
+
matches: false,
|
|
148
|
+
media: query,
|
|
149
|
+
onchange: null,
|
|
150
|
+
addListener: jest.fn(),
|
|
151
|
+
removeListener: jest.fn(),
|
|
152
|
+
addEventListener: jest.fn(),
|
|
153
|
+
removeEventListener: jest.fn(),
|
|
154
|
+
dispatchEvent: jest.fn(),
|
|
155
|
+
})),
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
// Mock ResizeObserver
|
|
159
|
+
global.ResizeObserver = jest.fn().mockImplementation(() => ({
|
|
160
|
+
observe: jest.fn(),
|
|
161
|
+
unobserve: jest.fn(),
|
|
162
|
+
disconnect: jest.fn(),
|
|
163
|
+
}))
|
|
164
|
+
|
|
165
|
+
// Mock IntersectionObserver
|
|
166
|
+
global.IntersectionObserver = jest.fn().mockImplementation(() => ({
|
|
167
|
+
observe: jest.fn(),
|
|
168
|
+
unobserve: jest.fn(),
|
|
169
|
+
disconnect: jest.fn(),
|
|
170
|
+
}))
|