fcad-core-dragon 2.2.0-beta.1 → 2.2.0

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/vitest.config.js CHANGED
@@ -13,30 +13,42 @@ export default defineConfig({
13
13
  }
14
14
  }
15
15
  },
16
+
17
+ resolve: {
18
+ alias: {
19
+ '@': fileURLToPath(new URL('./src', import.meta.url)),
20
+ '@/router/routes.js': fileURLToPath(
21
+ new URL('./tests/mocks/routes.mock.js', import.meta.url)
22
+ )
23
+ }
24
+ },
25
+
16
26
  test: {
17
27
  setupFiles: ['vitest.setup.js'],
18
- alias: {
19
- '@': fileURLToPath(new URL('./src', import.meta.url))
20
- },
28
+ environment: 'happy-dom',
29
+
21
30
  server: {
22
31
  deps: {
23
32
  inline: ['vuetify']
24
33
  }
25
34
  },
26
- environment: 'happy-dom',
35
+
27
36
  exclude: [...configDefaults.exclude, 'tests/component/**', '**/_*.spec.js'],
37
+
28
38
  root: fileURLToPath(new URL('./', import.meta.url)),
39
+
29
40
  coverage: {
30
41
  provider: 'v8',
31
42
  reporter: ['text', 'json', 'cobertura'],
32
43
  reportsDirectory: './coverage',
33
44
  include: ['src/**/*.{js,vue}'],
34
45
  exclude: ['tests/**/*'],
35
- lines: 0, // test must cover at least 80% of lines
36
- branches: 0, // test must cover at least 80% of branches (if, else, switch, case...)
37
- functions: 0, // test must cover at least 80% of functions
38
- statements: 0 // test must cover at least 80% of statements/instructions
46
+ lines: 0,
47
+ branches: 0,
48
+ functions: 0,
49
+ statements: 0
39
50
  }
40
51
  },
52
+
41
53
  plugins: [vue()]
42
54
  })
package/vitest.setup.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //Mock Vuetify, vue-i18n and event bus
2
- import { vi } from 'vitest'
2
+ import { vi, beforeEach } from 'vitest'
3
3
  import { config } from '@vue/test-utils'
4
4
  import { createI18n } from 'vue-i18n'
5
5
  import { createVuetify } from 'vuetify'
@@ -7,7 +7,9 @@ import * as components from 'vuetify/components'
7
7
  import * as directives from 'vuetify/directives'
8
8
  import * as frMessages from './src/$locales/fr.json'
9
9
  import * as enMessages from './src/$locales/en.json'
10
+ import '@testing-library/jest-dom/vitest'
10
11
  import bus from './src/plugins/bus'
12
+ import { createPinia, setActivePinia } from 'pinia'
11
13
 
12
14
  //create vuetify instance
13
15
  const vuetify = createVuetify({
@@ -25,38 +27,20 @@ const i18n = createI18n({
25
27
  }
26
28
  })
27
29
 
28
- // Suppress console warnings and errors during tests
29
30
  vi.spyOn(console, 'warn').mockImplementation(() => {})
30
31
  vi.spyOn(console, 'error').mockImplementation(() => {})
31
32
 
32
33
  // Global mock of Router
33
34
  // =========================================
34
- vi.mock('@/router/index.js', () => ({
35
- default: {
35
+ vi.mock('vue-router', () => ({
36
+ useRouter: () => ({
36
37
  push: vi.fn(),
37
- back: vi.fn(),
38
- currentRoute: { value: { meta: {}, params: {}, query: {} } }
39
- }
40
- }))
41
-
42
- // Global mock of Pinia store
43
- // =========================================
44
- vi.mock('@/module/stores/appStore', () => ({
45
- useAppStore: () => ({
46
- getAppConfigs: {
47
- lang: 'fr'
48
- },
49
-
50
- getCurrentBrowser: 'Chrome',
51
-
52
- getCurrentPage: {
53
- id: 'P01',
54
- activityRef: 'A03'
55
- },
56
-
57
- updateCurrentMediaElements: vi.fn(() => Promise.resolve()),
58
- getPageInteraction: {},
59
- getUserInteraction: {}
38
+ back: vi.fn()
39
+ }),
40
+ useRoute: () => ({
41
+ meta: {},
42
+ params: {},
43
+ query: {}
60
44
  })
61
45
  }))
62
46
 
@@ -67,13 +51,28 @@ vi.mock('@/shared/validators.js', () => ({
67
51
  validateString: vi.fn(() => true),
68
52
  validateNumber: vi.fn(() => true),
69
53
  validateVideoData: vi.fn(() => []),
70
- validateAudioData: vi.fn(() => [])
54
+ validateAudioData: vi.fn(() => []),
55
+ validateProp: vi.fn(() => [])
71
56
  }))
72
57
 
73
58
  //setup as global plugins used by all tests
74
- config.global.plugins = [i18n, vuetify, bus]
59
+ config.global.plugins.push(i18n, vuetify, bus)
60
+
61
+ //Setup a new pinia instance before each test
62
+ //=========================================
63
+ //NOTE:
64
+ // Do NOT use createTestingPinia() globally
65
+ // Pinia mocking must be done per-test using createTestingPinia()
66
+ // to avoid hidden side effects and false-positive tests.
67
+ // https://pinia.vuejs.org/cookbook/testing.html#using-the-testing-plugin
68
+ // https://pinia.vuejs.org/cookbook/testing.html
69
+
70
+ beforeEach(() => {
71
+ setActivePinia(createPinia())
72
+ })
75
73
 
76
74
  // Global mock of components
75
+ //=========================================
77
76
  config.global.stubs = {
78
77
  AppBaseErrorDisplay: true,
79
78
  AppBaseSkeleton: true,
@@ -88,9 +87,12 @@ config.global.mocks = {
88
87
  id: 'P01'
89
88
  }
90
89
  },
91
- $bus: {
92
- $on: vi.fn(),
93
- $emit: vi.fn(),
94
- $off: vi.fn()
90
+ // $bus: {
91
+ // $on: vi.fn(),
92
+ // $emit: vi.fn(),
93
+ // $off: vi.fn()
94
+ // },
95
+ $helper: {
96
+ formatTime: vi.fn((t) => `00:${t}`)
95
97
  }
96
98
  }
@@ -1,8 +0,0 @@
1
- {
2
- "recommendations": [
3
- "Vue.volar",
4
- "dbaeumer.vscode-eslint",
5
- "EditorConfig.EditorConfig",
6
- "esbenp.prettier-vscode"
7
- ]
8
- }
@@ -1,16 +0,0 @@
1
- {
2
- "explorer.fileNesting.enabled": true,
3
- "explorer.fileNesting.patterns": {
4
- "tsconfig.json": "tsconfig.*.json, env.d.ts",
5
- "vite.config.*": "jsconfig*, vitest.config.*, cypress.config.*, playwright.config.*",
6
- "package.json": "package-lock.json, pnpm*, .yarnrc*, yarn*, .eslint*, eslint*, .oxlint*, oxlint*, .prettier*, prettier*, .editorconfig"
7
- },
8
- "editor.codeActionsOnSave": {
9
- "source.fixAll": "explicit"
10
- },
11
- "editor.formatOnSave": true,
12
- "editor.defaultFormatter": "esbenp.prettier-vscode",
13
- "[vue]": {
14
- "editor.defaultFormatter": "esbenp.prettier-vscode"
15
- }
16
- }
@@ -1,112 +0,0 @@
1
- import { mount } from '@vue/test-utils'
2
- import { beforeEach, describe, it, expect, vi } from 'vitest'
3
- import { createTestingPinia } from '@pinia/testing'
4
-
5
- // Les mocks doivent être "hoistés" (déclarés avant l'import du composant)
6
- beforeEach(() => {
7
- vi.mock('@/shared/generalfuncs.js', () => ({
8
- fileAssets: { getActivities: () => [] }
9
- }))
10
- vi.mock('@/router/routes.js', () => ({
11
- mappedFiles: []
12
- }))
13
- vi.mock('@/router/index.js', () => ({
14
- default: { push: vi.fn(), currentRoute: { value: {} } }
15
- }))
16
- vi.mock('@/shared/validators.js', () => ({
17
- validateObjType: () => true,
18
- validateString: () => true,
19
- validateQuizData: () => ({ errorInConsole: [] }),
20
- validateNumber: () => true
21
- }))
22
- })
23
-
24
- import AppCompQuizNext from '@/components/AppCompQuizNext.vue'
25
-
26
- describe('AppCompQuizNext', () => {
27
- const stubs = {
28
- AppCompInputRadio: {
29
- template: '<div class="stub-radio"></div>',
30
- props: ['modelValue', 'inputData', 'id', 'solution']
31
- },
32
- AppCompInputTextNx: {
33
- template: '<input class="stub-text" />',
34
- props: ['modelValue']
35
- },
36
- AppBaseErrorDisplay: {
37
- template: '<div class="stub-error"></div>',
38
- props: {
39
- /* ... (props omises pour la clarté) ... */
40
- }
41
- },
42
- AppBaseSkeleton: { template: '<div class="stub-skeleton"></div>' },
43
- AppBaseButton: { template: '<button class="stub-button"></button>' }
44
- }
45
-
46
- it('rend un input radio si la question est de type choix_unique', () => {
47
- const quizData = {
48
- id: 1,
49
- type_question: 'choix_unique',
50
- ennonce: 'Quel est la deuxieme lettre de alphabet',
51
- mode: ['A', 'B', 'C'],
52
- solution: ['B']
53
- }
54
-
55
- const wrapper = mount(AppCompQuizNext, {
56
- props: {
57
- modelValue: ['A', 'B', 'C'],
58
- consigne: false,
59
- shuffleAnswers: false,
60
- quizData: quizData // Passez la variable ici
61
- },
62
- global: {
63
- stubs,
64
- plugins: [createTestingPinia({ createSpy: vi.fn })],
65
- provide: {
66
- userInteraction: {
67
- recordAnswer: vi.fn(),
68
- hasInteracted: vi.fn(),
69
- quizAnswers: {
70
- [quizData.id]: { value: ['A'], total_attempts: 0 }
71
- }
72
- }
73
- }
74
- }
75
- })
76
-
77
- expect(wrapper.find('.stub-radio').exists()).toBe(true)
78
- })
79
-
80
- // it('rend un input texte si la question est de type text', async() => {
81
- // const wrapper = mount(AppCompQuizNext, {
82
- // props: {
83
- // question: {
84
- // id: 2,
85
- // type: 'text'
86
- // },
87
- // modelValue: ''
88
- // },
89
- // global: { stubs }
90
- // })
91
- // expect(wrapper.find('.stub-text').exists()).toBe(true)
92
- // })
93
-
94
- // it('émet update:modelValue quand l’utilisateur répond', async () => {
95
- // const wrapper = mount(AppCompQuizNext, {
96
- // props: {
97
- // question: { id: 1, type: 'text' },
98
- // modelValue: ''
99
- // },
100
- // global: {
101
- // stubs: {
102
- // AppCompInputTextNx: {
103
- // template: `<input @input="$emit('update:modelValue', 'hello')" />`
104
- // }
105
- // }
106
- // }
107
- // })
108
- // await wrapper.find('input').trigger('input')
109
-
110
- // expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['hello'])
111
- // })
112
- })