@stone-js/starters 0.8.8 → 0.8.9
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/README.md +2 -2
- package/basic-react-declarative/app/Application.tsx +0 -2
- package/basic-react-declarative/package.json +7 -7
- package/basic-react-declarative/public/favicon.svg +16 -0
- package/basic-react-declarative/tests/Application.spec.ts +25 -100
- package/basic-react-imperative/app/Application.tsx +2 -17
- package/basic-react-imperative/package.json +7 -7
- package/basic-react-imperative/public/favicon.svg +16 -0
- package/basic-react-imperative/tests/Application.spec.ts +25 -86
- package/basic-service-declarative/app/Application.ts +0 -2
- package/basic-service-declarative/package.json +6 -6
- package/basic-service-declarative/tests/Application.spec.ts +20 -53
- package/basic-service-imperative/app/Application.ts +2 -14
- package/basic-service-imperative/package.json +6 -6
- package/basic-service-imperative/tests/Application.spec.ts +19 -44
- package/continuum-showcase/package.json +11 -10
- package/continuum-showcase/public/favicon.svg +16 -0
- package/continuum-showcase/stone.config.mjs +2 -2
- package/continuum-showcase/tests/application.spec.ts +30 -0
- package/full-react-declarative/app/Application.ts +0 -4
- package/full-react-declarative/package.json +12 -12
- package/full-react-declarative/public/favicon.svg +16 -0
- package/full-react-declarative/stone.config.mjs +2 -2
- package/full-react-declarative/tests/application.spec.ts +30 -0
- package/full-react-imperative/app/Application.ts +1 -3
- package/full-react-imperative/package.json +12 -12
- package/full-react-imperative/public/favicon.svg +16 -0
- package/full-react-imperative/stone.config.mjs +2 -2
- package/full-react-imperative/tests/application.spec.ts +30 -0
- package/full-service-declarative/app/Application.ts +5 -2
- package/full-service-declarative/app/configurations/AppConfiguration.ts +1 -3
- package/full-service-declarative/package.json +13 -12
- package/full-service-declarative/stone.config.mjs +2 -2
- package/full-service-declarative/tests/application.spec.ts +30 -0
- package/full-service-imperative/app/Application.ts +8 -2
- package/full-service-imperative/app/configurations/AppConfiguration.ts +1 -3
- package/full-service-imperative/package.json +13 -12
- package/full-service-imperative/stone.config.mjs +2 -2
- package/full-service-imperative/tests/application.spec.ts +30 -0
- package/package.json +1 -1
- package/standard-react-declarative/package.json +11 -10
- package/standard-react-declarative/public/favicon.svg +16 -0
- package/standard-react-declarative/tests/application.spec.ts +30 -0
- package/standard-react-imperative/package.json +11 -10
- package/standard-react-imperative/public/favicon.svg +16 -0
- package/standard-react-imperative/tests/application.spec.ts +30 -0
- package/standard-service-declarative/package.json +9 -8
- package/standard-service-declarative/tests/Application.spec.ts +22 -94
- package/standard-service-imperative/package.json +9 -8
- package/standard-service-imperative/tests/Application.spec.ts +22 -78
- package/basic-react-declarative/vitest.config.ts +0 -24
- package/basic-react-imperative/vitest.config.ts +0 -24
- package/basic-service-declarative/vitest.config.ts +0 -24
- package/basic-service-imperative/vitest.config.ts +0 -24
- package/continuum-showcase/tests/HomePage.spec.tsx +0 -41
- package/continuum-showcase/vitest.config.ts +0 -31
- package/full-react-declarative/tests/AppLayout.spec.ts +0 -51
- package/full-react-declarative/tests/HomePage.spec.ts +0 -38
- package/full-react-declarative/vitest.config.ts +0 -24
- package/full-react-imperative/tests/HomePage.spec.ts +0 -45
- package/full-react-imperative/tests/LayoutHeader.spec.ts +0 -39
- package/full-react-imperative/vitest.config.ts +0 -24
- package/full-service-declarative/tests/PostService.spec.ts +0 -56
- package/full-service-declarative/tests/WelcomeEventHandler.spec.ts +0 -54
- package/full-service-declarative/vitest.config.ts +0 -24
- package/full-service-imperative/tests/PostService.spec.ts +0 -47
- package/full-service-imperative/tests/WelcomeEventHandler.spec.ts +0 -31
- package/full-service-imperative/vitest.config.ts +0 -24
- package/standard-react-declarative/tests/WelcomePage.spec.ts +0 -71
- package/standard-react-declarative/vitest.config.ts +0 -24
- package/standard-react-imperative/tests/WelcomePage.spec.ts +0 -53
- package/standard-react-imperative/vitest.config.ts +0 -24
- package/standard-service-declarative/vitest.config.ts +0 -24
- package/standard-service-imperative/vitest.config.ts +0 -24
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vitest/config'
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
test: {
|
|
5
|
-
globals: true,
|
|
6
|
-
environment: 'node',
|
|
7
|
-
include: ['./tests/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
|
|
8
|
-
coverage: {
|
|
9
|
-
provider: 'v8',
|
|
10
|
-
include: ['app/**/*.ts'],
|
|
11
|
-
reporter: ['text', 'html'],
|
|
12
|
-
reportsDirectory: './coverage',
|
|
13
|
-
thresholds: {
|
|
14
|
-
100: true
|
|
15
|
-
},
|
|
16
|
-
watermarks: {
|
|
17
|
-
statements: [60, 80],
|
|
18
|
-
functions: [60, 80],
|
|
19
|
-
branches: [60, 80],
|
|
20
|
-
lines: [60, 80]
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
}
|
|
24
|
-
});
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { renderToString } from 'react-dom/server'
|
|
2
|
-
import { HomePage } from '../app/pages/HomePage'
|
|
3
|
-
|
|
4
|
-
// Mock the page decorator so the class can be instantiated without a running app context.
|
|
5
|
-
vi.mock('@stone-js/use-react', async (importOriginal) => {
|
|
6
|
-
const actual: any = await importOriginal()
|
|
7
|
-
return {
|
|
8
|
-
...actual,
|
|
9
|
-
Page: vi.fn(() => vi.fn())
|
|
10
|
-
}
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
describe('HomePage', () => {
|
|
14
|
-
it('returns the domain message from handle', () => {
|
|
15
|
-
// Arrange
|
|
16
|
-
const page = new HomePage()
|
|
17
|
-
|
|
18
|
-
// Act
|
|
19
|
-
const data = page.handle()
|
|
20
|
-
|
|
21
|
-
// Assert
|
|
22
|
-
expect(data.message).toBe('Write your domain once. Stone.js applies the context.')
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
it('renders the Stone.js logo and the message', () => {
|
|
26
|
-
// Arrange
|
|
27
|
-
const page = new HomePage()
|
|
28
|
-
|
|
29
|
-
// Act
|
|
30
|
-
const html = renderToString(page.render({ data: page.handle() } as any))
|
|
31
|
-
|
|
32
|
-
// Assert: the premium welcome hero renders the Stone.js logo (Vite inlines the small SVG
|
|
33
|
-
// as a data URI), the brand title and the domain message.
|
|
34
|
-
expect(html).toContain('stone-welcome')
|
|
35
|
-
expect(html).toContain('<img')
|
|
36
|
-
expect(html).toContain('image/svg+xml')
|
|
37
|
-
expect(html).toContain('alt="Stone.js"')
|
|
38
|
-
expect(html).toContain('Stone.js')
|
|
39
|
-
expect(html).toContain('Write your domain once')
|
|
40
|
-
})
|
|
41
|
-
})
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { fileURLToPath } from 'node:url'
|
|
2
|
-
import { defineConfig } from 'vitest/config'
|
|
3
|
-
|
|
4
|
-
export default defineConfig({
|
|
5
|
-
// Mirror the CLI's static-asset aliases (see stone.config.mjs) so component imports like
|
|
6
|
-
// `import logo from '@img/logo.svg'` also resolve under the test runner.
|
|
7
|
-
resolve: {
|
|
8
|
-
alias: {
|
|
9
|
-
'@img': fileURLToPath(new URL('./assets/images', import.meta.url)),
|
|
10
|
-
'@css': fileURLToPath(new URL('./assets/css', import.meta.url)),
|
|
11
|
-
'@assets': fileURLToPath(new URL('./assets', import.meta.url))
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
test: {
|
|
15
|
-
globals: true,
|
|
16
|
-
environment: 'node',
|
|
17
|
-
include: ['./tests/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
|
|
18
|
-
coverage: {
|
|
19
|
-
provider: 'v8',
|
|
20
|
-
include: ['app/**/*.ts', 'app/**/*.tsx'],
|
|
21
|
-
reporter: ['text', 'html'],
|
|
22
|
-
reportsDirectory: './coverage',
|
|
23
|
-
watermarks: {
|
|
24
|
-
statements: [60, 80],
|
|
25
|
-
functions: [60, 80],
|
|
26
|
-
branches: [60, 80],
|
|
27
|
-
lines: [60, 80]
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
})
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { renderToString } from 'react-dom/server'
|
|
2
|
-
import { AppLayout } from '../app/layout/AppLayout/AppLayout'
|
|
3
|
-
|
|
4
|
-
// We must mock decorators and router-bound components to lighten the test environment
|
|
5
|
-
vi.mock('@stone-js/use-react', async (importOriginal) => {
|
|
6
|
-
const actual: any = await importOriginal()
|
|
7
|
-
return {
|
|
8
|
-
...actual,
|
|
9
|
-
PageLayout: vi.fn(() => vi.fn()),
|
|
10
|
-
StoneLink: ({ children }: any) => children,
|
|
11
|
-
StoneOutlet: ({ children }: any) => children
|
|
12
|
-
}
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
describe('AppLayout', () => {
|
|
16
|
-
let layout: AppLayout
|
|
17
|
-
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
layout = new AppLayout({} as any)
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
const render = (): string => {
|
|
23
|
-
const container = {
|
|
24
|
-
make: () => ({ getUser: () => undefined })
|
|
25
|
-
}
|
|
26
|
-
return renderToString(layout.render({ container, children: null } as any))
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
it('should create an App Layout instance', () => {
|
|
30
|
-
// Assert
|
|
31
|
-
expect(layout).toBeInstanceOf(AppLayout)
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
it('should render the real Stone.js logo', () => {
|
|
35
|
-
// Act
|
|
36
|
-
const html = render()
|
|
37
|
-
|
|
38
|
-
// Assert
|
|
39
|
-
expect(html).toContain('/logo.svg')
|
|
40
|
-
expect(html).toContain('alt="Stone.js"')
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it('should render the unauthenticated header', () => {
|
|
44
|
-
// Act
|
|
45
|
-
const html = render()
|
|
46
|
-
|
|
47
|
-
// Assert
|
|
48
|
-
expect(html).toContain('Login')
|
|
49
|
-
expect(html).toContain('Stone.js')
|
|
50
|
-
})
|
|
51
|
-
})
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { renderToString } from 'react-dom/server'
|
|
2
|
-
import { HomePage } from '../app/pages/home/HomePage'
|
|
3
|
-
|
|
4
|
-
// We must mock the @Page decorator and router-bound components to lighten the test environment
|
|
5
|
-
vi.mock('@stone-js/use-react', async (importOriginal) => {
|
|
6
|
-
const actual: any = await importOriginal()
|
|
7
|
-
return {
|
|
8
|
-
...actual,
|
|
9
|
-
Page: vi.fn(() => vi.fn()),
|
|
10
|
-
StoneLink: ({ children }: any) => children
|
|
11
|
-
}
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
describe('HomePage', () => {
|
|
15
|
-
const render = (): string => {
|
|
16
|
-
const page = new HomePage()
|
|
17
|
-
return renderToString(page.render())
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
it('should render the premium Stone.js welcome hero with the real logo', () => {
|
|
21
|
-
// Act
|
|
22
|
-
const html = render()
|
|
23
|
-
|
|
24
|
-
// Assert
|
|
25
|
-
expect(html).toContain('/logo.svg')
|
|
26
|
-
expect(html).toContain('alt="Stone.js"')
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
it('should render the Welcome to Stone.js headline', () => {
|
|
30
|
-
// Act
|
|
31
|
-
const html = render()
|
|
32
|
-
|
|
33
|
-
// Assert
|
|
34
|
-
expect(html).toContain('Welcome')
|
|
35
|
-
expect(html).toContain('Stone.js')
|
|
36
|
-
expect(html).toContain('stone-welcome')
|
|
37
|
-
})
|
|
38
|
-
})
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vitest/config'
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
test: {
|
|
5
|
-
globals: true,
|
|
6
|
-
environment: 'node',
|
|
7
|
-
include: ['./tests/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
|
|
8
|
-
coverage: {
|
|
9
|
-
provider: 'v8',
|
|
10
|
-
include: ['app/**/*.ts', 'app/**/*.tsx'],
|
|
11
|
-
reporter: ['text', 'html'],
|
|
12
|
-
reportsDirectory: './coverage',
|
|
13
|
-
thresholds: {
|
|
14
|
-
100: true
|
|
15
|
-
},
|
|
16
|
-
watermarks: {
|
|
17
|
-
statements: [60, 80],
|
|
18
|
-
functions: [60, 80],
|
|
19
|
-
branches: [60, 80],
|
|
20
|
-
lines: [60, 80]
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
}
|
|
24
|
-
});
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { renderToString } from 'react-dom/server'
|
|
2
|
-
import { HomePage } from '../app/pages/home/HomePage'
|
|
3
|
-
|
|
4
|
-
// We must mock router-bound components to lighten the test environment
|
|
5
|
-
vi.mock('@stone-js/use-react', async (importOriginal) => {
|
|
6
|
-
const actual: any = await importOriginal()
|
|
7
|
-
return {
|
|
8
|
-
...actual,
|
|
9
|
-
StoneLink: ({ children }: any) => children
|
|
10
|
-
}
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
describe('HomePage', () => {
|
|
14
|
-
const render = (data: any[] = []): string => {
|
|
15
|
-
const page = HomePage({ postService: {} as any })
|
|
16
|
-
return renderToString(page.render?.({ data } as any))
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
it('should render the premium Stone.js welcome hero with the real logo', () => {
|
|
20
|
-
// Act
|
|
21
|
-
const html = render()
|
|
22
|
-
|
|
23
|
-
// Assert
|
|
24
|
-
expect(html).toContain('/logo.svg')
|
|
25
|
-
expect(html).toContain('alt="Stone.js"')
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
it('should render the Welcome to Stone.js headline', () => {
|
|
29
|
-
// Act
|
|
30
|
-
const html = render()
|
|
31
|
-
|
|
32
|
-
// Assert
|
|
33
|
-
expect(html).toContain('Welcome')
|
|
34
|
-
expect(html).toContain('Stone.js')
|
|
35
|
-
expect(html).toContain('stone-welcome')
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('should reflect the number of published posts in the lead', () => {
|
|
39
|
-
// Act
|
|
40
|
-
const html = render([{ id: 1 }, { id: 2 }])
|
|
41
|
-
|
|
42
|
-
// Assert
|
|
43
|
-
expect(html).toContain('2 posts')
|
|
44
|
-
})
|
|
45
|
-
})
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { createElement } from 'react'
|
|
2
|
-
import { renderToString } from 'react-dom/server'
|
|
3
|
-
import { LayoutHeader } from '../app/components/LayoutHeader/LayoutHeader'
|
|
4
|
-
|
|
5
|
-
// We must mock router-bound components to lighten the test environment
|
|
6
|
-
vi.mock('@stone-js/use-react', async (importOriginal) => {
|
|
7
|
-
const actual: any = await importOriginal()
|
|
8
|
-
return {
|
|
9
|
-
...actual,
|
|
10
|
-
StoneLink: ({ children }: any) => children
|
|
11
|
-
}
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
describe('LayoutHeader', () => {
|
|
15
|
-
const render = (): string => {
|
|
16
|
-
const container = {
|
|
17
|
-
make: (key: string) => key === 'event' ? { getUser: () => undefined } : {}
|
|
18
|
-
} as any
|
|
19
|
-
return renderToString(createElement(LayoutHeader, { container }))
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
it('should render the real Stone.js logo', () => {
|
|
23
|
-
// Act
|
|
24
|
-
const html = render()
|
|
25
|
-
|
|
26
|
-
// Assert
|
|
27
|
-
expect(html).toContain('/logo.svg')
|
|
28
|
-
expect(html).toContain('alt="Stone.js"')
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('should render the Stone.js brand for an unauthenticated visitor', () => {
|
|
32
|
-
// Act
|
|
33
|
-
const html = render()
|
|
34
|
-
|
|
35
|
-
// Assert
|
|
36
|
-
expect(html).toContain('Stone.js')
|
|
37
|
-
expect(html).toContain('app-navbar')
|
|
38
|
-
})
|
|
39
|
-
})
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vitest/config'
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
test: {
|
|
5
|
-
globals: true,
|
|
6
|
-
environment: 'node',
|
|
7
|
-
include: ['./tests/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
|
|
8
|
-
coverage: {
|
|
9
|
-
provider: 'v8',
|
|
10
|
-
include: ['app/**/*.ts', 'app/**/*.tsx'],
|
|
11
|
-
reporter: ['text', 'html'],
|
|
12
|
-
reportsDirectory: './coverage',
|
|
13
|
-
thresholds: {
|
|
14
|
-
100: true
|
|
15
|
-
},
|
|
16
|
-
watermarks: {
|
|
17
|
-
statements: [60, 80],
|
|
18
|
-
functions: [60, 80],
|
|
19
|
-
branches: [60, 80],
|
|
20
|
-
lines: [60, 80]
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
}
|
|
24
|
-
});
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { NotFoundError } from '@stone-js/http-core'
|
|
2
|
-
import { PostService } from '../app/services/PostService'
|
|
3
|
-
import { PostRepository } from '../app/repositories/PostRepository'
|
|
4
|
-
import { Post } from '../app/models/Post'
|
|
5
|
-
|
|
6
|
-
// Neutralize the @Service decorator to lighten the test environment,
|
|
7
|
-
// while keeping the real `isNotEmpty` helper so we assert real behavior.
|
|
8
|
-
vi.mock(import('@stone-js/core'), async (importOriginal) => {
|
|
9
|
-
const actual = await importOriginal()
|
|
10
|
-
return {
|
|
11
|
-
...actual,
|
|
12
|
-
Service: vi.fn(() => vi.fn()),
|
|
13
|
-
}
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
describe('PostService', () => {
|
|
17
|
-
let service: PostService
|
|
18
|
-
let postRepository: PostRepository
|
|
19
|
-
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
postRepository = {
|
|
22
|
-
list: vi.fn(),
|
|
23
|
-
findById: vi.fn(),
|
|
24
|
-
} as unknown as PostRepository
|
|
25
|
-
|
|
26
|
-
service = new PostService({ postRepository })
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
it('should delegate list() to the repository with the given limit', async () => {
|
|
30
|
-
// Arrange
|
|
31
|
-
const posts = [{ id: 1, title: 'Hello' }] as unknown as Post[]
|
|
32
|
-
;(postRepository.list as any).mockResolvedValue(posts)
|
|
33
|
-
|
|
34
|
-
// Act
|
|
35
|
-
const result = await service.list(5)
|
|
36
|
-
|
|
37
|
-
// Assert
|
|
38
|
-
expect(result).toBe(posts)
|
|
39
|
-
expect(postRepository.list).toHaveBeenCalledWith({ limit: 5 })
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('should return the post when found and throw NotFoundError otherwise', async () => {
|
|
43
|
-
// Arrange
|
|
44
|
-
const post = { id: 42, title: 'Answer' } as unknown as Post
|
|
45
|
-
;(postRepository.findById as any).mockResolvedValueOnce(post)
|
|
46
|
-
|
|
47
|
-
// Act & Assert (found)
|
|
48
|
-
await expect(service.findById(42)).resolves.toBe(post)
|
|
49
|
-
|
|
50
|
-
// Arrange (not found)
|
|
51
|
-
;(postRepository.findById as any).mockResolvedValueOnce(undefined)
|
|
52
|
-
|
|
53
|
-
// Act & Assert (not found)
|
|
54
|
-
await expect(service.findById(99)).rejects.toBeInstanceOf(NotFoundError)
|
|
55
|
-
})
|
|
56
|
-
})
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { WelcomeEventHandler } from '../app/handlers/WelcomeEventHandler'
|
|
2
|
-
import { IncomingHttpEvent } from '@stone-js/http-core'
|
|
3
|
-
|
|
4
|
-
// Neutralize the routing/http decorators to lighten the test environment,
|
|
5
|
-
// while asserting the real branded payload the handler returns.
|
|
6
|
-
vi.mock(import('@stone-js/router'), async (importOriginal) => {
|
|
7
|
-
const actual = await importOriginal()
|
|
8
|
-
return {
|
|
9
|
-
...actual,
|
|
10
|
-
EventHandler: vi.fn(() => vi.fn()),
|
|
11
|
-
Get: vi.fn(() => vi.fn()),
|
|
12
|
-
}
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
vi.mock(import('@stone-js/http-core'), async (importOriginal) => {
|
|
16
|
-
const actual = await importOriginal()
|
|
17
|
-
return {
|
|
18
|
-
...actual,
|
|
19
|
-
JsonHttpResponse: vi.fn(() => vi.fn()),
|
|
20
|
-
}
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
describe('WelcomeEventHandler', () => {
|
|
24
|
-
let handler: WelcomeEventHandler
|
|
25
|
-
|
|
26
|
-
beforeEach(() => {
|
|
27
|
-
handler = new WelcomeEventHandler()
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
const makeEvent = (name?: string): IncomingHttpEvent => ({
|
|
31
|
-
get: vi.fn((_key: string, fallback: string) => name ?? fallback),
|
|
32
|
-
}) as unknown as IncomingHttpEvent
|
|
33
|
-
|
|
34
|
-
it('should return a branded Stone.js payload greeting the given name', () => {
|
|
35
|
-
// Act
|
|
36
|
-
const payload = handler.welcome(makeEvent('Ada'))
|
|
37
|
-
|
|
38
|
-
// Assert
|
|
39
|
-
expect(payload.message).toBe('Hello Ada! Welcome to Stone.js.')
|
|
40
|
-
expect(payload.framework.name).toBe('Stone.js')
|
|
41
|
-
expect(payload.framework.tagline).toBe('The continuum framework')
|
|
42
|
-
expect(payload.framework.docs).toBe('https://stonejs.dev')
|
|
43
|
-
expect(payload.framework.github).toBe('https://github.com/stone-foundation/stone-js-framework')
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
it('should fall back to the default name when none is provided', () => {
|
|
47
|
-
// Act
|
|
48
|
-
const payload = handler.welcome(makeEvent())
|
|
49
|
-
|
|
50
|
-
// Assert
|
|
51
|
-
expect(payload.message).toBe('Hello Stone! Welcome to Stone.js.')
|
|
52
|
-
expect(payload.framework.name).toBe('Stone.js')
|
|
53
|
-
})
|
|
54
|
-
})
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vitest/config'
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
test: {
|
|
5
|
-
globals: true,
|
|
6
|
-
environment: 'node',
|
|
7
|
-
include: ['./tests/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
|
|
8
|
-
coverage: {
|
|
9
|
-
provider: 'v8',
|
|
10
|
-
include: ['app/**/*.ts'],
|
|
11
|
-
reporter: ['text', 'html'],
|
|
12
|
-
reportsDirectory: './coverage',
|
|
13
|
-
thresholds: {
|
|
14
|
-
100: true
|
|
15
|
-
},
|
|
16
|
-
watermarks: {
|
|
17
|
-
statements: [60, 80],
|
|
18
|
-
functions: [60, 80],
|
|
19
|
-
branches: [60, 80],
|
|
20
|
-
lines: [60, 80]
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
}
|
|
24
|
-
});
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { NotFoundError } from '@stone-js/http-core'
|
|
2
|
-
import { factoryPostService } from '../app/services/PostService'
|
|
3
|
-
import { IPostService } from '../app/services/contracts/IPostService'
|
|
4
|
-
import { IPostRepository } from '../app/repositories/contracts/IPostRepository'
|
|
5
|
-
import { Post } from '../app/models/Post'
|
|
6
|
-
|
|
7
|
-
describe('factoryPostService', () => {
|
|
8
|
-
let service: IPostService
|
|
9
|
-
let postRepository: IPostRepository
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
postRepository = {
|
|
13
|
-
list: vi.fn(),
|
|
14
|
-
findById: vi.fn(),
|
|
15
|
-
} as unknown as IPostRepository
|
|
16
|
-
|
|
17
|
-
service = factoryPostService({ postRepository })
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it('should delegate list() to the repository with the given limit', async () => {
|
|
21
|
-
// Arrange
|
|
22
|
-
const posts = [{ id: 1, title: 'Hello' }] as unknown as Post[]
|
|
23
|
-
;(postRepository.list as any).mockResolvedValue(posts)
|
|
24
|
-
|
|
25
|
-
// Act
|
|
26
|
-
const result = await service.list(5)
|
|
27
|
-
|
|
28
|
-
// Assert
|
|
29
|
-
expect(result).toBe(posts)
|
|
30
|
-
expect(postRepository.list).toHaveBeenCalledWith({ limit: 5 })
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it('should return the post when found and throw NotFoundError otherwise', async () => {
|
|
34
|
-
// Arrange
|
|
35
|
-
const post = { id: 42, title: 'Answer' } as unknown as Post
|
|
36
|
-
;(postRepository.findById as any).mockResolvedValueOnce(post)
|
|
37
|
-
|
|
38
|
-
// Act & Assert (found)
|
|
39
|
-
await expect(service.findById(42)).resolves.toBe(post)
|
|
40
|
-
|
|
41
|
-
// Arrange (not found)
|
|
42
|
-
;(postRepository.findById as any).mockResolvedValueOnce(undefined)
|
|
43
|
-
|
|
44
|
-
// Act & Assert (not found)
|
|
45
|
-
await expect(service.findById(99)).rejects.toBeInstanceOf(NotFoundError)
|
|
46
|
-
})
|
|
47
|
-
})
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { IncomingHttpEvent } from '@stone-js/http-core'
|
|
2
|
-
import { factoryWelcomeEventHandler, WelcomePayload } from '../app/handlers/WelcomeEventHandler'
|
|
3
|
-
|
|
4
|
-
describe('factoryWelcomeEventHandler', () => {
|
|
5
|
-
const makeEvent = (name?: string): IncomingHttpEvent => ({
|
|
6
|
-
get: vi.fn((_key: string, fallback: string) => name ?? fallback),
|
|
7
|
-
}) as unknown as IncomingHttpEvent
|
|
8
|
-
|
|
9
|
-
it('should return a branded Stone.js payload greeting the given name', () => {
|
|
10
|
-
// Act
|
|
11
|
-
const handler = factoryWelcomeEventHandler()
|
|
12
|
-
const payload = handler(makeEvent('Ada')) as unknown as WelcomePayload
|
|
13
|
-
|
|
14
|
-
// Assert
|
|
15
|
-
expect(payload.message).toBe('Hello Ada! Welcome to Stone.js.')
|
|
16
|
-
expect(payload.framework.name).toBe('Stone.js')
|
|
17
|
-
expect(payload.framework.tagline).toBe('The continuum framework')
|
|
18
|
-
expect(payload.framework.docs).toBe('https://stonejs.dev')
|
|
19
|
-
expect(payload.framework.github).toBe('https://github.com/stone-foundation/stone-js-framework')
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
it('should fall back to the default name when none is provided', () => {
|
|
23
|
-
// Act
|
|
24
|
-
const handler = factoryWelcomeEventHandler()
|
|
25
|
-
const payload = handler(makeEvent()) as unknown as WelcomePayload
|
|
26
|
-
|
|
27
|
-
// Assert
|
|
28
|
-
expect(payload.message).toBe('Hello Stone! Welcome to Stone.js.')
|
|
29
|
-
expect(payload.framework.name).toBe('Stone.js')
|
|
30
|
-
})
|
|
31
|
-
})
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vitest/config'
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
test: {
|
|
5
|
-
globals: true,
|
|
6
|
-
environment: 'node',
|
|
7
|
-
include: ['./tests/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
|
|
8
|
-
coverage: {
|
|
9
|
-
provider: 'v8',
|
|
10
|
-
include: ['app/**/*.ts'],
|
|
11
|
-
reporter: ['text', 'html'],
|
|
12
|
-
reportsDirectory: './coverage',
|
|
13
|
-
thresholds: {
|
|
14
|
-
100: true
|
|
15
|
-
},
|
|
16
|
-
watermarks: {
|
|
17
|
-
statements: [60, 80],
|
|
18
|
-
functions: [60, 80],
|
|
19
|
-
branches: [60, 80],
|
|
20
|
-
lines: [60, 80]
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
}
|
|
24
|
-
});
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { ILogger } from '@stone-js/core'
|
|
2
|
-
import { renderToString } from 'react-dom/server'
|
|
3
|
-
import { ReactIncomingEvent } from '@stone-js/use-react'
|
|
4
|
-
import { WelcomePage } from '../app/pages/welcome/WelcomePage'
|
|
5
|
-
import { WelcomeService } from '../app/services/WelcomeService'
|
|
6
|
-
|
|
7
|
-
// We must mock decorators to lighten the test environment
|
|
8
|
-
vi.mock('@stone-js/use-react', async (importOriginal) => {
|
|
9
|
-
const actual: any = await importOriginal()
|
|
10
|
-
return {
|
|
11
|
-
...actual,
|
|
12
|
-
Page: vi.fn(() => vi.fn()),
|
|
13
|
-
}
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
// We must mock decorators to lighten the test environment
|
|
17
|
-
vi.mock('@stone-js/core', async (importOriginal) => {
|
|
18
|
-
const actual: any = await importOriginal()
|
|
19
|
-
return {
|
|
20
|
-
...actual,
|
|
21
|
-
Service: vi.fn(() => vi.fn()),
|
|
22
|
-
}
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
describe('WelcomePage', () => {
|
|
26
|
-
let page: WelcomePage
|
|
27
|
-
let mockedLogger: ILogger
|
|
28
|
-
|
|
29
|
-
beforeEach(() => {
|
|
30
|
-
mockedLogger = {
|
|
31
|
-
info: vi.fn(),
|
|
32
|
-
} as unknown as ILogger
|
|
33
|
-
|
|
34
|
-
page = new WelcomePage({ welcomeService: new WelcomeService({ logger: mockedLogger }) })
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it('should handle incoming events', () => {
|
|
38
|
-
// Arrange
|
|
39
|
-
const expectedMessage = 'Hello World!'
|
|
40
|
-
const event = { get: () => 'World' } as unknown as ReactIncomingEvent
|
|
41
|
-
|
|
42
|
-
// Act
|
|
43
|
-
const response = page.handle(event)
|
|
44
|
-
|
|
45
|
-
// Assert
|
|
46
|
-
expect(response.message).toBe(expectedMessage)
|
|
47
|
-
expect(mockedLogger.info).toHaveBeenCalledWith('Welcome World')
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
it('should render the message', () => {
|
|
51
|
-
// Arrange
|
|
52
|
-
const message = 'Hello World!'
|
|
53
|
-
|
|
54
|
-
// Act
|
|
55
|
-
const response = renderToString(page.render({ data: { message } } as any))
|
|
56
|
-
|
|
57
|
-
// Assert
|
|
58
|
-
expect(response).toContain(message)
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
it('should render the Stone.js logo', () => {
|
|
62
|
-
// Act
|
|
63
|
-
const response = renderToString(page.render({ data: { message: 'Hello World!' } } as any))
|
|
64
|
-
|
|
65
|
-
// Assert
|
|
66
|
-
expect(response).toContain('/logo.svg')
|
|
67
|
-
expect(response).toContain('alt="Stone.js"')
|
|
68
|
-
expect(response).toContain('Welcome')
|
|
69
|
-
expect(response).toContain('Stone.js')
|
|
70
|
-
})
|
|
71
|
-
})
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vitest/config'
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
test: {
|
|
5
|
-
globals: true,
|
|
6
|
-
environment: 'node',
|
|
7
|
-
include: ['./tests/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
|
|
8
|
-
coverage: {
|
|
9
|
-
provider: 'v8',
|
|
10
|
-
include: ['app/**/*.ts', 'app/**/*.tsx'],
|
|
11
|
-
reporter: ['text', 'html'],
|
|
12
|
-
reportsDirectory: './coverage',
|
|
13
|
-
thresholds: {
|
|
14
|
-
100: true
|
|
15
|
-
},
|
|
16
|
-
watermarks: {
|
|
17
|
-
statements: [60, 80],
|
|
18
|
-
functions: [60, 80],
|
|
19
|
-
branches: [60, 80],
|
|
20
|
-
lines: [60, 80]
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
}
|
|
24
|
-
});
|