mirror of
https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
synced 2025-08-11 21:23:54 -04:00
Compare commits
4 commits
896bd588bd
...
c473212f2a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c473212f2a | ||
|
|
f781173695 | ||
|
|
2de7671666 | ||
|
|
23e053e24f |
18 changed files with 217 additions and 89 deletions
|
|
@ -16,5 +16,18 @@
|
||||||
"jest.disabledWorkspaceFolders": [
|
"jest.disabledWorkspaceFolders": [
|
||||||
"EvalueTonSavoir"
|
"EvalueTonSavoir"
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll.eslint": true
|
||||||
|
},
|
||||||
|
"eslint.validate": [
|
||||||
|
"javascript",
|
||||||
|
"typescript",
|
||||||
|
"javascriptreact",
|
||||||
|
"typescriptreact"
|
||||||
|
],
|
||||||
|
// use the same eslint config as `npx eslint`
|
||||||
|
"eslint.experimental.useFlatConfig": true,
|
||||||
|
"eslint.nodePath": "./node_modules"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
env: { browser: true, es2020: true },
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:@typescript-eslint/recommended',
|
|
||||||
'plugin:react-hooks/recommended',
|
|
||||||
],
|
|
||||||
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
plugins: ['react-refresh'],
|
|
||||||
rules: {
|
|
||||||
'react-refresh/only-export-components': [
|
|
||||||
'warn',
|
|
||||||
{ allowConstantExport: true },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* eslint-disable no-undef */
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript']
|
presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript']
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,78 @@
|
||||||
|
import react from "eslint-plugin-react";
|
||||||
|
import typescriptEslint from "@typescript-eslint/eslint-plugin";
|
||||||
|
import typescriptParser from "@typescript-eslint/parser";
|
||||||
import globals from "globals";
|
import globals from "globals";
|
||||||
import pluginJs from "@eslint/js";
|
import pluginJs from "@eslint/js";
|
||||||
import tseslint from "typescript-eslint";
|
import jest from "eslint-plugin-jest";
|
||||||
import pluginReact from "eslint-plugin-react";
|
import reactRefresh from "eslint-plugin-react-refresh";
|
||||||
|
import unusedImports from "eslint-plugin-unused-imports";
|
||||||
|
import eslintComments from "eslint-plugin-eslint-comments";
|
||||||
|
|
||||||
/** @type {import('eslint').Linter.Config[]} */
|
/** @type {import('eslint').Linter.Config[]} */
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
ignores: ["dist/**"], // Place this at the root level
|
ignores: ["node_modules", "dist/**/*"],
|
||||||
},
|
|
||||||
{
|
|
||||||
files: ["src/**/*.{js,mjs,cjs,ts,jsx,tsx}"],
|
|
||||||
// ignores: ["./dist/**"],
|
|
||||||
languageOptions: {
|
|
||||||
globals: globals.browser,
|
|
||||||
},
|
},
|
||||||
rules: {
|
{
|
||||||
"no-unused-vars": ["error", {
|
files: ["**/*.{js,jsx,mjs,cjs,ts,tsx}"],
|
||||||
"argsIgnorePattern": "^_",
|
languageOptions: {
|
||||||
"varsIgnorePattern": "^_",
|
parser: typescriptParser,
|
||||||
"caughtErrorsIgnorePattern": "^_" // Ignore catch clause parameters that start with _
|
parserOptions: {
|
||||||
}],
|
ecmaFeatures: {
|
||||||
},
|
jsx: true,
|
||||||
settings: {
|
},
|
||||||
react: {
|
},
|
||||||
version: "detect", // Automatically detect the React version
|
globals: {
|
||||||
},
|
...globals.serviceworker,
|
||||||
},
|
...globals.browser,
|
||||||
},
|
...globals.jest,
|
||||||
pluginJs.configs.recommended,
|
...globals.node,
|
||||||
...tseslint.configs.recommended,
|
process: "readonly",
|
||||||
pluginReact.configs.flat.recommended,
|
},
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
"@typescript-eslint": typescriptEslint,
|
||||||
|
react,
|
||||||
|
jest,
|
||||||
|
"react-refresh": reactRefresh,
|
||||||
|
"unused-imports": unusedImports,
|
||||||
|
"eslint-comments": eslintComments
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
// Auto-fix unused variables
|
||||||
|
"@typescript-eslint/no-unused-vars": "off",
|
||||||
|
"no-unused-vars": "off",
|
||||||
|
"unused-imports/no-unused-vars": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"vars": "all",
|
||||||
|
"varsIgnorePattern": "^_",
|
||||||
|
"args": "after-used",
|
||||||
|
"argsIgnorePattern": "^_",
|
||||||
|
"destructuredArrayIgnorePattern": "^_"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// Handle directive comments
|
||||||
|
"eslint-comments/no-unused-disable": "warn",
|
||||||
|
"eslint-comments/no-unused-enable": "warn",
|
||||||
|
|
||||||
|
// Jest configurations
|
||||||
|
"jest/valid-expect": ["error", { "alwaysAwait": true }],
|
||||||
|
"jest/prefer-to-have-length": "warn",
|
||||||
|
"jest/no-disabled-tests": "off",
|
||||||
|
"jest/no-focused-tests": "error",
|
||||||
|
"jest/no-identical-title": "error",
|
||||||
|
|
||||||
|
// React refresh
|
||||||
|
"react-refresh/only-export-components": ["warn", {
|
||||||
|
allowConstantExport: true
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: "detect",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* eslint-disable no-undef */
|
|
||||||
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
/* eslint-disable no-undef */
|
|
||||||
process.env.VITE_BACKEND_URL = 'http://localhost:4000/';
|
process.env.VITE_BACKEND_URL = 'http://localhost:4000/';
|
||||||
process.env.VITE_BACKEND_SOCKET_URL = 'https://ets-glitch-backend.glitch.me/';
|
process.env.VITE_BACKEND_SOCKET_URL = 'https://ets-glitch-backend.glitch.me/';
|
||||||
|
|
|
||||||
71
client/package-lock.json
generated
71
client/package-lock.json
generated
|
|
@ -54,9 +54,12 @@
|
||||||
"@typescript-eslint/parser": "^8.5.0",
|
"@typescript-eslint/parser": "^8.5.0",
|
||||||
"@vitejs/plugin-react-swc": "^3.7.2",
|
"@vitejs/plugin-react-swc": "^3.7.2",
|
||||||
"eslint": "^9.18.0",
|
"eslint": "^9.18.0",
|
||||||
|
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||||
|
"eslint-plugin-jest": "^28.11.0",
|
||||||
"eslint-plugin-react": "^7.37.3",
|
"eslint-plugin-react": "^7.37.3",
|
||||||
"eslint-plugin-react-hooks": "^5.1.0-rc-206df66e-20240912",
|
"eslint-plugin-react-hooks": "^5.1.0-rc-206df66e-20240912",
|
||||||
"eslint-plugin-react-refresh": "^0.4.12",
|
"eslint-plugin-react-refresh": "^0.4.12",
|
||||||
|
"eslint-plugin-unused-imports": "^4.1.4",
|
||||||
"globals": "^15.14.0",
|
"globals": "^15.14.0",
|
||||||
"identity-obj-proxy": "^3.0.0",
|
"identity-obj-proxy": "^3.0.0",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
|
|
@ -6695,6 +6698,59 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint-plugin-eslint-comments": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"escape-string-regexp": "^1.0.5",
|
||||||
|
"ignore": "^5.0.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.5.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/mysticatea"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"eslint": ">=4.19.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-plugin-eslint-comments/node_modules/escape-string-regexp": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-plugin-jest": {
|
||||||
|
"version": "28.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.11.0.tgz",
|
||||||
|
"integrity": "sha512-QAfipLcNCWLVocVbZW8GimKn5p5iiMcgGbRzz8z/P5q7xw+cNEpYqyzFMtIF/ZgF2HLOyy+dYBut+DoYolvqig==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^16.10.0 || ^18.12.0 || >=20.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0",
|
||||||
|
"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0",
|
||||||
|
"jest": "*"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@typescript-eslint/eslint-plugin": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"jest": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eslint-plugin-react": {
|
"node_modules/eslint-plugin-react": {
|
||||||
"version": "7.37.4",
|
"version": "7.37.4",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz",
|
||||||
|
|
@ -6793,6 +6849,21 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint-plugin-unused-imports": {
|
||||||
|
"version": "4.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.4.tgz",
|
||||||
|
"integrity": "sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peerDependencies": {
|
||||||
|
"@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0",
|
||||||
|
"eslint": "^9.0.0 || ^8.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@typescript-eslint/eslint-plugin": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eslint-scope": {
|
"node_modules/eslint-scope": {
|
||||||
"version": "8.2.0",
|
"version": "8.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -58,9 +58,12 @@
|
||||||
"@typescript-eslint/parser": "^8.5.0",
|
"@typescript-eslint/parser": "^8.5.0",
|
||||||
"@vitejs/plugin-react-swc": "^3.7.2",
|
"@vitejs/plugin-react-swc": "^3.7.2",
|
||||||
"eslint": "^9.18.0",
|
"eslint": "^9.18.0",
|
||||||
|
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||||
|
"eslint-plugin-jest": "^28.11.0",
|
||||||
"eslint-plugin-react": "^7.37.3",
|
"eslint-plugin-react": "^7.37.3",
|
||||||
"eslint-plugin-react-hooks": "^5.1.0-rc-206df66e-20240912",
|
"eslint-plugin-react-hooks": "^5.1.0-rc-206df66e-20240912",
|
||||||
"eslint-plugin-react-refresh": "^0.4.12",
|
"eslint-plugin-react-refresh": "^0.4.12",
|
||||||
|
"eslint-plugin-unused-imports": "^4.1.4",
|
||||||
"globals": "^15.14.0",
|
"globals": "^15.14.0",
|
||||||
"identity-obj-proxy": "^3.0.0",
|
"identity-obj-proxy": "^3.0.0",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,6 @@ describe('StudentType', () => {
|
||||||
|
|
||||||
expect(user.name).toBe('Student');
|
expect(user.name).toBe('Student');
|
||||||
expect(user.id).toBe('123');
|
expect(user.id).toBe('123');
|
||||||
expect(user.answers.length).toBe(0);
|
expect(user.answers).toHaveLength(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,47 +5,64 @@ import GIFTTemplatePreview from 'src/components/GiftTemplate/GIFTTemplatePreview
|
||||||
|
|
||||||
describe('GIFTTemplatePreview Component', () => {
|
describe('GIFTTemplatePreview Component', () => {
|
||||||
test('renders error message when questions contain invalid syntax', () => {
|
test('renders error message when questions contain invalid syntax', () => {
|
||||||
render(<GIFTTemplatePreview questions={['Invalid GIFT syntax']} />);
|
render(<GIFTTemplatePreview questions={[':: title']} />);
|
||||||
const errorMessage = screen.findByText(/Erreur inconnue/i, {}, { timeout: 5000 });
|
const errorMessage = screen.getByText(/Title ::, Category, Description, or Question formatted stem but ":" found./i);
|
||||||
expect(errorMessage).resolves.toBeInTheDocument();
|
expect(errorMessage).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('renders preview when valid questions are provided', () => {
|
test('renders preview when valid questions are provided', () => {
|
||||||
const questions = [
|
const questions = [
|
||||||
'Question 1 { A | B | C }',
|
'Stem1 {=ans1 ~ans2 ~ans3}',
|
||||||
'Question 2 { D | E | F }',
|
|
||||||
];
|
];
|
||||||
render(<GIFTTemplatePreview questions={questions} />);
|
render(<GIFTTemplatePreview questions={questions} />);
|
||||||
const previewContainer = screen.getByTestId('preview-container');
|
const previewContainer = screen.getByTestId('preview-container');
|
||||||
expect(previewContainer).toBeInTheDocument();
|
expect(previewContainer).toBeInTheDocument();
|
||||||
|
// const question1 = screen.getByText('Stem1');
|
||||||
|
const mcQuestion1 = screen.getByText('Stem1');
|
||||||
|
const ans1 = screen.getByText('ans1');
|
||||||
|
const ans2 = screen.getByText('ans2');
|
||||||
|
const ans3 = screen.getByText('ans3');
|
||||||
|
expect(mcQuestion1).toBeInTheDocument();
|
||||||
|
expect(ans1).toBeInTheDocument();
|
||||||
|
expect(ans2).toBeInTheDocument();
|
||||||
|
expect(ans3).toBeInTheDocument();
|
||||||
|
|
||||||
|
// each answer should have a radio button before it
|
||||||
|
const radioButtons = screen.getAllByRole('radio');
|
||||||
|
expect(radioButtons).toHaveLength(3);
|
||||||
|
// ans1 should be the <label> for the first radio button
|
||||||
|
expect(radioButtons[0].nextElementSibling).toBe(ans1);
|
||||||
|
// ans2 should be the <label> for the second radio button
|
||||||
|
expect(radioButtons[1].nextElementSibling).toBe(ans2);
|
||||||
|
// ans3 should be the <label> for the third radio button
|
||||||
|
expect(radioButtons[2].nextElementSibling).toBe(ans3);
|
||||||
|
|
||||||
|
// after the <label> for correct answer (ans1) there should be an svg with aria-hidden="true"
|
||||||
|
expect(ans1.nextElementSibling).toHaveAttribute('aria-hidden', 'true');
|
||||||
|
// after the <label> for incorrect answer (ans2) there should be an svg with aria-hidden="true"
|
||||||
|
expect(ans2.nextElementSibling).toHaveAttribute('aria-hidden', 'true');
|
||||||
|
// after the <label> for incorrect answer (ans3) there should be an svg with aria-hidden="true"
|
||||||
|
expect(ans3.nextElementSibling).toHaveAttribute('aria-hidden', 'true');
|
||||||
|
|
||||||
});
|
});
|
||||||
test('hides answers when hideAnswers prop is true', () => {
|
test('hides correct/incorrect answers when hideAnswers prop is true', () => {
|
||||||
const questions = [
|
const questions = [
|
||||||
'Question 1 { A | B | C }',
|
'Stem1 {=ans1 ~ans2 ~ans3}',
|
||||||
'Question 2 { D | E | F }',
|
|
||||||
];
|
];
|
||||||
render(<GIFTTemplatePreview questions={questions} hideAnswers />);
|
render(<GIFTTemplatePreview questions={questions} hideAnswers />);
|
||||||
const previewContainer = screen.getByTestId('preview-container');
|
const previewContainer = screen.getByTestId('preview-container');
|
||||||
expect(previewContainer).toBeInTheDocument();
|
expect(previewContainer).toBeInTheDocument();
|
||||||
|
const ans1 = screen.queryByText('ans1');
|
||||||
|
const ans2 = screen.queryByText('ans2');
|
||||||
|
const ans3 = screen.queryByText('ans3');
|
||||||
|
|
||||||
|
const radioButtons = screen.getAllByRole('radio');
|
||||||
|
expect(radioButtons).toHaveLength(3);
|
||||||
|
expect(radioButtons[0].nextElementSibling).toBe(ans1);
|
||||||
|
expect(ans1?.nextElementSibling).toBeNull();
|
||||||
|
expect(radioButtons[1].nextElementSibling).toBe(ans2);
|
||||||
|
expect(ans2?.nextElementSibling).toBeNull();
|
||||||
|
expect(radioButtons[2].nextElementSibling).toBe(ans3);
|
||||||
|
expect(ans3?.nextElementSibling).toBeNull();
|
||||||
});
|
});
|
||||||
// it('renders images correctly', () => {
|
|
||||||
// const questions = [
|
|
||||||
// 'Question 1',
|
|
||||||
// '<img src="image1.jpg" alt="Image 1">',
|
|
||||||
// 'Question 2',
|
|
||||||
// '<img src="image2.jpg" alt="Image 2">',
|
|
||||||
// ];
|
|
||||||
// const { getByAltText } = render(<GIFTTemplatePreview questions={questions} />);
|
|
||||||
// const image1 = getByAltText('Image 1');
|
|
||||||
// const image2 = getByAltText('Image 2');
|
|
||||||
// expect(image1).toBeInTheDocument();
|
|
||||||
// expect(image2).toBeInTheDocument();
|
|
||||||
// });
|
|
||||||
// it('renders non-images correctly', () => {
|
|
||||||
// const questions = ['Question 1', 'Question 2'];
|
|
||||||
// const { queryByAltText } = render(<GIFTTemplatePreview questions={questions} />);
|
|
||||||
// const image1 = queryByAltText('Image 1');
|
|
||||||
// const image2 = queryByAltText('Image 2');
|
|
||||||
// expect(image1).toBeNull();
|
|
||||||
// expect(image2).toBeNull();
|
|
||||||
// });
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,10 @@ describe('TextType', () => {
|
||||||
format: ''
|
format: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line no-irregular-whitespace
|
|
||||||
// warning: there are zero-width spaces "" in the expected output -- you must enable seeing them with an extension such as Gremlins tracker in VSCode
|
// warning: there are zero-width spaces "" in the expected output -- you must enable seeing them with an extension such as Gremlins tracker in VSCode
|
||||||
|
|
||||||
// eslint-disable-next-line no-irregular-whitespace
|
|
||||||
const expectedOutput = `Inline matrix: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo fence="true">(</mo><mtable rowspacing="0.16em"><mtr><mtd><mstyle displaystyle="false" scriptlevel="0"><mi>a</mi></mstyle></mtd><mtd><mstyle displaystyle="false" scriptlevel="0"><mi>b</mi></mstyle></mtd></mtr><mtr><mtd><mstyle displaystyle="false" scriptlevel="0"><mi>c</mi></mstyle></mtd><mtd><mstyle displaystyle="false" scriptlevel="0"><mi>d</mi></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow> \\begin{pmatrix} a & b \\\\ c & d \\end{pmatrix} </math></span><span aria-hidden="true" class="katex-html"><span class="base"><span style="height:2.4em;vertical-align:-0.95em;" class="strut"></span><span class="minner"><span style="top:0em;" class="mopen delimcenter"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span style="height:1.45em;" class="vlist"><span style="top:-3.61em;"><span style="height:3em;" class="pstrut"></span><span class="mord"><span class="mord mathnormal">a</span></span></span><span style="top:-2.41em;"><span style="height:3em;" class="pstrut"></span><span class="mord"><span class="mord mathnormal">c</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span style="height:0.95em;" class="vlist"><span></span></span></span></span></span><span style="width:0.5em;" class="arraycolsep"></span><span style="width:0.5em;" class="arraycolsep"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span style="height:1.45em;" class="vlist"><span style="top:-3.61em;"><span style="height:3em;" class="pstrut"></span><span class="mord"><span class="mord mathnormal">b</span></span></span><span style="top:-2.41em;"><span style="height:3em;" class="pstrut"></span><span class="mord"><span class="mord mathnormal">d</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span style="height:0.95em;" class="vlist"><span></span></span></span></span></span></span></span><span style="top:0em;" class="mclose delimcenter"><span class="delimsizing size3">)</span></span></span></span></span></span>`;
|
const expectedOutput = `Inline matrix: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo fence="true">(</mo><mtable rowspacing="0.16em"><mtr><mtd><mstyle displaystyle="false" scriptlevel="0"><mi>a</mi></mstyle></mtd><mtd><mstyle displaystyle="false" scriptlevel="0"><mi>b</mi></mstyle></mtd></mtr><mtr><mtd><mstyle displaystyle="false" scriptlevel="0"><mi>c</mi></mstyle></mtd><mtd><mstyle displaystyle="false" scriptlevel="0"><mi>d</mi></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow> \\begin{pmatrix} a & b \\\\ c & d \\end{pmatrix} </math></span><span aria-hidden="true" class="katex-html"><span class="base"><span style="height:2.4em;vertical-align:-0.95em;" class="strut"></span><span class="minner"><span style="top:0em;" class="mopen delimcenter"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span style="height:1.45em;" class="vlist"><span style="top:-3.61em;"><span style="height:3em;" class="pstrut"></span><span class="mord"><span class="mord mathnormal">a</span></span></span><span style="top:-2.41em;"><span style="height:3em;" class="pstrut"></span><span class="mord"><span class="mord mathnormal">c</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span style="height:0.95em;" class="vlist"><span></span></span></span></span></span><span style="width:0.5em;" class="arraycolsep"></span><span style="width:0.5em;" class="arraycolsep"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span style="height:1.45em;" class="vlist"><span style="top:-3.61em;"><span style="height:3em;" class="pstrut"></span><span class="mord"><span class="mord mathnormal">b</span></span></span><span style="top:-2.41em;"><span style="height:3em;" class="pstrut"></span><span class="mord"><span class="mord mathnormal">d</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span style="height:0.95em;" class="vlist"><span></span></span></span></span></span></span></span><span style="top:0em;" class="mclose delimcenter"><span class="delimsizing size3">)</span></span></span></span></span></span>`;
|
||||||
expect(FormattedTextTemplate(input)).toContain(expectedOutput);
|
expect(FormattedTextTemplate(input)).toContain(expectedOutput);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ function convertStylesToObject(styles: string): React.CSSProperties {
|
||||||
styles.split(';').forEach((style) => {
|
styles.split(';').forEach((style) => {
|
||||||
const [property, value] = style.split(':');
|
const [property, value] = style.split(':');
|
||||||
if (property && value) {
|
if (property && value) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
(styleObject as any)[property.trim()] = value.trim();
|
(styleObject as any)[property.trim()] = value.trim();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import { Question } from 'gift-pegjs';
|
||||||
|
|
||||||
interface StudentModeQuizProps {
|
interface StudentModeQuizProps {
|
||||||
questions: QuestionType[];
|
questions: QuestionType[];
|
||||||
submitAnswer: (answer: string | number | boolean, idQuestion: number) => void;
|
submitAnswer: (_answer: string | number | boolean, _idQuestion: number) => void;
|
||||||
disconnectWebSocket: () => void;
|
disconnectWebSocket: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import './studentWaitPage.css';
|
||||||
interface Props {
|
interface Props {
|
||||||
students: StudentType[];
|
students: StudentType[];
|
||||||
launchQuiz: () => void;
|
launchQuiz: () => void;
|
||||||
setQuizMode: (mode: 'student' | 'teacher') => void;
|
setQuizMode: (_mode: 'student' | 'teacher') => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StudentWaitPage: React.FC<Props> = ({ students, launchQuiz, setQuizMode }) => {
|
const StudentWaitPage: React.FC<Props> = ({ students, launchQuiz, setQuizMode }) => {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import { Question } from 'gift-pegjs';
|
||||||
|
|
||||||
interface TeacherModeQuizProps {
|
interface TeacherModeQuizProps {
|
||||||
questionInfos: QuestionType;
|
questionInfos: QuestionType;
|
||||||
submitAnswer: (answer: string | number | boolean, idQuestion: number) => void;
|
submitAnswer: (_answer: string | number | boolean, _idQuestion: number) => void;
|
||||||
disconnectWebSocket: () => void;
|
disconnectWebSocket: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -196,8 +196,8 @@ const Dashboard: React.FC = () => {
|
||||||
// questions[i] = QuestionService.ignoreImgTags(questions[i]);
|
// questions[i] = QuestionService.ignoreImgTags(questions[i]);
|
||||||
const parsedItem = parse(questions[i]);
|
const parsedItem = parse(questions[i]);
|
||||||
Template(parsedItem[0]);
|
Template(parsedItem[0]);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error('Error parsing question:', error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -182,9 +182,8 @@ const QuizForm: React.FC = () => {
|
||||||
if (fileInputRef.current) {
|
if (fileInputRef.current) {
|
||||||
fileInputRef.current.value = '';
|
fileInputRef.current.value = '';
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.alert(`Une erreur est survenue.\n Veuillez réessayer plus tard`)
|
window.alert(`Une erreur est survenue.\n${error}\nVeuillez réessayer plus tard.`)
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,6 @@ const ManageRoom: React.FC = () => {
|
||||||
// This is here to make sure the correct value is sent when user join
|
// This is here to make sure the correct value is sent when user join
|
||||||
if (socket) {
|
if (socket) {
|
||||||
console.log(`Listening for user-joined in room ${roomName}`);
|
console.log(`Listening for user-joined in room ${roomName}`);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
socket.on('user-joined', (_student: StudentType) => {
|
socket.on('user-joined', (_student: StudentType) => {
|
||||||
if (quizMode === 'teacher') {
|
if (quizMode === 'teacher') {
|
||||||
webSocketService.nextQuestion(roomName, currentQuestion);
|
webSocketService.nextQuestion(roomName, currentQuestion);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue