forked from verdnatura/salix-front
Merge branch 'dev' into 4834-create-worker-module
This commit is contained in:
commit
7ef50bcbe9
19
.babelrc
19
.babelrc
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
"plugins": ["@babel/plugin-syntax-dynamic-import"],
|
|
||||||
"env": {
|
|
||||||
"test": {
|
|
||||||
"plugins": ["dynamic-import-node"],
|
|
||||||
"presets": [
|
|
||||||
[
|
|
||||||
"@babel/preset-env",
|
|
||||||
{
|
|
||||||
"modules": "commonjs",
|
|
||||||
"targets": {
|
|
||||||
"node": "current"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +1,6 @@
|
||||||
/dist
|
/dist
|
||||||
/src-bex/www
|
|
||||||
/src-capacitor
|
/src-capacitor
|
||||||
/src-cordova
|
/src-cordova
|
||||||
/.quasar
|
/.quasar
|
||||||
/node_modules
|
/node_modules
|
||||||
.eslintrc.js
|
.eslintrc.js
|
||||||
babel.config.js
|
|
||||||
|
|
14
.eslintrc.js
14
.eslintrc.js
|
@ -5,13 +5,13 @@ module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
|
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
parser: '@babel/eslint-parser',
|
ecmaVersion: '2021', // Allows for the parsing of modern ECMAScript features
|
||||||
ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features
|
|
||||||
sourceType: 'module', // Allows for the use of imports
|
|
||||||
},
|
},
|
||||||
|
|
||||||
env: {
|
env: {
|
||||||
|
node: true,
|
||||||
browser: true,
|
browser: true,
|
||||||
|
'vue/setup-compiler-macros': true,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Rules order is important, please avoid shuffling them
|
// Rules order is important, please avoid shuffling them
|
||||||
|
@ -22,7 +22,7 @@ module.exports = {
|
||||||
// Uncomment any of the lines below to choose desired strictness,
|
// Uncomment any of the lines below to choose desired strictness,
|
||||||
// but leave only one uncommented!
|
// but leave only one uncommented!
|
||||||
// See https://eslint.vuejs.org/rules/#available-rules
|
// See https://eslint.vuejs.org/rules/#available-rules
|
||||||
//'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
|
// 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
|
||||||
'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
|
'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
|
||||||
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
|
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
|
||||||
|
|
||||||
|
@ -52,9 +52,6 @@ module.exports = {
|
||||||
process: 'readonly',
|
process: 'readonly',
|
||||||
Capacitor: 'readonly',
|
Capacitor: 'readonly',
|
||||||
chrome: 'readonly',
|
chrome: 'readonly',
|
||||||
defineProps: 'readonly', // Vue SFC setup compiler macro
|
|
||||||
defineEmits: 'readonly', // Vue SFC setup compiler macro
|
|
||||||
defineExpose: 'readonly', // Vue SFC setup compiler macro
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// add your custom rules here
|
// add your custom rules here
|
||||||
|
@ -64,10 +61,9 @@ module.exports = {
|
||||||
// allow debugger during development only
|
// allow debugger during development only
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||||
},
|
},
|
||||||
|
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
files: ['**/*.spec.{js,ts}'],
|
files: ['test/cypress/**/*.spec.{js,ts}'],
|
||||||
extends: [
|
extends: [
|
||||||
// Add Cypress-specific lint rules, globals and Cypress plugin
|
// Add Cypress-specific lint rules, globals and Cypress plugin
|
||||||
// See https://github.com/cypress-io/eslint-plugin-cypress#rules
|
// See https://github.com/cypress-io/eslint-plugin-cypress#rules
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.thumbs.db
|
.thumbs.db
|
||||||
node_modules
|
node_modules
|
||||||
junit.xml
|
|
||||||
|
|
||||||
# Quasar core related directories
|
# Quasar core related directories
|
||||||
.quasar
|
.quasar
|
||||||
|
@ -17,10 +16,6 @@ junit.xml
|
||||||
/src-capacitor/www
|
/src-capacitor/www
|
||||||
/src-capacitor/node_modules
|
/src-capacitor/node_modules
|
||||||
|
|
||||||
# BEX related directories and files
|
|
||||||
/src-bex/www
|
|
||||||
/src-bex/js/core
|
|
||||||
|
|
||||||
# Log files
|
# Log files
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
|
@ -32,3 +27,7 @@ yarn-error.log*
|
||||||
*.ntvs*
|
*.ntvs*
|
||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
|
|
||||||
|
# Cypress directories and files
|
||||||
|
/tests/cypress/videos
|
||||||
|
/tests/cypress/screenshots
|
|
@ -0,0 +1,3 @@
|
||||||
|
# pnpm-related options
|
||||||
|
shamefully-hoist=true
|
||||||
|
strict-peer-dependencies=false
|
|
@ -1,9 +0,0 @@
|
||||||
/* eslint-disable */
|
|
||||||
// https://github.com/michael-ciniawsky/postcss-load-config
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
plugins: [
|
|
||||||
// to edit target browsers: use "browserslist" field in package.json
|
|
||||||
require('autoprefixer'),
|
|
||||||
],
|
|
||||||
};
|
|
|
@ -3,7 +3,7 @@
|
||||||
"dbaeumer.vscode-eslint",
|
"dbaeumer.vscode-eslint",
|
||||||
"esbenp.prettier-vscode",
|
"esbenp.prettier-vscode",
|
||||||
"editorconfig.editorconfig",
|
"editorconfig.editorconfig",
|
||||||
"Vue.volar",
|
"vue.volar",
|
||||||
"wayou.vscode-todo-highlight"
|
"wayou.vscode-todo-highlight"
|
||||||
],
|
],
|
||||||
"unwantedRecommendations": [
|
"unwantedRecommendations": [
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [2253.01] - 2023-01-05
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added...
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Changed...
|
22
README.md
22
README.md
|
@ -1,12 +1,10 @@
|
||||||
# Salix (salix-front)
|
# Lilium (lilium-front)
|
||||||
|
|
||||||
Salix front-end
|
Lilium frontend
|
||||||
|
|
||||||
## Install the dependencies
|
## Install the dependencies
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn
|
|
||||||
# or
|
|
||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -22,20 +20,16 @@ sudo npm install -g @quasar/cli
|
||||||
quasar dev
|
quasar dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### Lint the files
|
### Run unit tests
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn lint
|
npm run test:unit
|
||||||
# or
|
|
||||||
npm run lint
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Format the files
|
### Run e2e tests
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn format
|
npm run test:e2e
|
||||||
# or
|
|
||||||
npm run format
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Build the app for production
|
### Build the app for production
|
||||||
|
@ -43,7 +37,3 @@ npm run format
|
||||||
```bash
|
```bash
|
||||||
quasar build
|
quasar build
|
||||||
```
|
```
|
||||||
|
|
||||||
### Customize the configuration
|
|
||||||
|
|
||||||
See [Configuring quasar.config.js](https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js).
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
/* eslint-env node */
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
||||||
const fs = require('fs-extra');
|
|
||||||
let extend = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The .babelrc file has been created to assist Jest for transpiling.
|
|
||||||
* You should keep your application's babel rules in this file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (fs.existsSync('./.babelrc')) {
|
|
||||||
extend = './.babelrc';
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
presets: ['@quasar/babel-preset-app'],
|
|
||||||
extends: extend,
|
|
||||||
};
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
const { defineConfig } = require('cypress');
|
||||||
|
|
||||||
|
module.exports = defineConfig({
|
||||||
|
e2e: {
|
||||||
|
baseUrl: 'http://localhost:8080/',
|
||||||
|
fixturesFolder: 'test/cypress/fixtures',
|
||||||
|
screenshotsFolder: 'test/cypress/screenshots',
|
||||||
|
supportFile: 'test/cypress/support/index.js',
|
||||||
|
videosFolder: 'test/cypress/videos',
|
||||||
|
video: true,
|
||||||
|
specPattern: 'test/cypress/integration/*.spec.js',
|
||||||
|
experimentalRunAllSpecs: true,
|
||||||
|
component: {
|
||||||
|
componentFolder: 'src',
|
||||||
|
testFiles: '**/*.spec.js',
|
||||||
|
supportFile: 'test/cypress/support/unit.js',
|
||||||
|
},
|
||||||
|
setupNodeEvents(on, config) {
|
||||||
|
// implement node event listeners here
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
15
cypress.json
15
cypress.json
|
@ -1,15 +0,0 @@
|
||||||
{
|
|
||||||
"baseUrl": "http://localhost:8080/",
|
|
||||||
"fixturesFolder": "tests/cypress/fixtures",
|
|
||||||
"integrationFolder": "tests/cypress/integration",
|
|
||||||
"pluginsFile": "tests/cypress/plugins/index.js",
|
|
||||||
"screenshotsFolder": "tests/cypress/screenshots",
|
|
||||||
"supportFile": "tests/cypress/support/index.js",
|
|
||||||
"videosFolder": "tests/cypress/videos",
|
|
||||||
"video": true,
|
|
||||||
"component": {
|
|
||||||
"componentFolder": "src",
|
|
||||||
"testFiles": "**/*.spec.js",
|
|
||||||
"supportFile": "tests/cypress/support/unit.js"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,7 +19,6 @@
|
||||||
<link rel="icon" type="image/ico" href="favicon.ico" />
|
<link rel="icon" type="image/ico" href="favicon.ico" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- DO NOT touch the following DIV -->
|
<!-- quasar:entry-point -->
|
||||||
<div id="q-app"></div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,59 +0,0 @@
|
||||||
const esModules = ['quasar', 'quasar/lang', 'lodash-es'].join('|');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
globals: {
|
|
||||||
__DEV__: true,
|
|
||||||
// TODO: Remove if resolved natively
|
|
||||||
// See https://github.com/vuejs/vue-jest/issues/175
|
|
||||||
'vue-jest': {
|
|
||||||
pug: { doctype: 'html' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Jest assumes we are testing in node environment, specify jsdom environment instead
|
|
||||||
testEnvironment: 'jsdom',
|
|
||||||
// noStackTrace: true,
|
|
||||||
// bail: true,
|
|
||||||
// cache: false,
|
|
||||||
// verbose: true,
|
|
||||||
// watch: true,
|
|
||||||
reporters: ['default', 'jest-junit'],
|
|
||||||
collectCoverage: false,
|
|
||||||
coverageDirectory: '<rootDir>/tests/jest/coverage',
|
|
||||||
collectCoverageFrom: ['<rootDir>/src/**/*.vue', '<rootDir>/src/**/*.js', '<rootDir>/src/**/*.jsx'],
|
|
||||||
// Needed in JS codebases too because of feature flags
|
|
||||||
coveragePathIgnorePatterns: ['/node_modules/', '.d.ts$'],
|
|
||||||
coverageThreshold: {
|
|
||||||
global: {
|
|
||||||
// branches: 50,
|
|
||||||
// functions: 50,
|
|
||||||
// lines: 50,
|
|
||||||
// statements: 50
|
|
||||||
},
|
|
||||||
},
|
|
||||||
testMatch: ['<rootDir>/src/**/__tests__/*.(spec|test).+(ts|js)?(x)'],
|
|
||||||
moduleFileExtensions: ['vue', 'js', 'jsx', 'json'],
|
|
||||||
moduleNameMapper: {
|
|
||||||
'^quasar$': 'quasar/dist/quasar.esm.prod.js',
|
|
||||||
'^~/(.*)$': '<rootDir>/$1',
|
|
||||||
'^src/(.*)$': '<rootDir>/src/$1',
|
|
||||||
'^app/(.*)$': '<rootDir>/$1',
|
|
||||||
'^components/(.*)$': '<rootDir>/src/components/$1',
|
|
||||||
'^composables/(.*)$': '<rootDir>/src/composables/$1',
|
|
||||||
'^filters/(.*)$': '<rootDir>/src/filters/$1',
|
|
||||||
'^layouts/(.*)$': '<rootDir>/src/layouts/$1',
|
|
||||||
'^pages/(.*)$': '<rootDir>/src/pages/$1',
|
|
||||||
'^assets/(.*)$': '<rootDir>/src/assets/$1',
|
|
||||||
'^boot/(.*)$': '<rootDir>/src/boot/$1',
|
|
||||||
'.*css$': '@quasar/quasar-app-extension-testing-unit-jest/stub.css',
|
|
||||||
},
|
|
||||||
transform: {
|
|
||||||
'.*\\.vue$': 'vue-jest',
|
|
||||||
'.*\\.js$': 'babel-jest',
|
|
||||||
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
|
|
||||||
// use these if NPM is being flaky, care as hosting could interfere with these
|
|
||||||
// '.*\\.vue$': '@quasar/quasar-app-extension-testing-unit-jest/node_modules/vue-jest',
|
|
||||||
// '.*\\.js$': '@quasar/quasar-app-extension-testing-unit-jest/node_modules/babel-jest'
|
|
||||||
},
|
|
||||||
transformIgnorePatterns: [`node_modules/(?!(${esModules}))`],
|
|
||||||
snapshotSerializers: ['jest-serializer-vue'],
|
|
||||||
};
|
|
|
@ -14,8 +14,5 @@
|
||||||
"vue$": ["node_modules/vue/dist/vue.runtime.esm-bundler.js"]
|
"vue$": ["node_modules/vue/dist/vue.runtime.esm-bundler.js"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exclude": ["dist", ".quasar", "node_modules"],
|
"exclude": ["dist", ".quasar", "node_modules"]
|
||||||
"vueCompilerOptions": {
|
|
||||||
"experimentalDisableTemplateSupport": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
55
package.json
55
package.json
|
@ -1,63 +1,54 @@
|
||||||
{
|
{
|
||||||
"name": "salix-front",
|
"name": "salix-front",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"description": "Salix front-end",
|
"description": "Salix frontend",
|
||||||
"productName": "Salix",
|
"productName": "Salix",
|
||||||
"author": "Verdnatura",
|
"author": "Verdnatura",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint --ext .js,.vue ./",
|
"lint": "eslint --ext .js,.vue ./",
|
||||||
"format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
|
"format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
|
||||||
|
"test:e2e": "cypress open",
|
||||||
|
"test:e2e:ci": "cypress run --browser chromium",
|
||||||
"test": "echo \"See package.json => scripts for available tests.\" && exit 0",
|
"test": "echo \"See package.json => scripts for available tests.\" && exit 0",
|
||||||
"test:unit": "jest --reporters=default --watchAll",
|
"test:unit": "vitest",
|
||||||
"test:unit:ci": "jest --ci --reporters=default --reporters=jest-junit --maxWorkers=2",
|
"test:unit:ci": "vitest run"
|
||||||
"test:unit:coverage": "jest --coverage",
|
|
||||||
"serve:test:coverage": "quasar serve test/jest/coverage/lcov-report/ --port 8788",
|
|
||||||
"concurrently:dev:jest": "concurrently \"quasar dev\" \"jest --watch\"",
|
|
||||||
"test:e2e": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress open\"",
|
|
||||||
"test:e2e:ci": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\""
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@quasar/extras": "^1.15.8",
|
"@quasar/extras": "^1.15.8",
|
||||||
"axios": "^1.2.1",
|
"axios": "^1.2.1",
|
||||||
"core-js": "^3.6.5",
|
|
||||||
"pinia": "^2.0.28",
|
"pinia": "^2.0.28",
|
||||||
"quasar": "^2.11.1",
|
"quasar": "^2.11.1",
|
||||||
"validator": "^13.7.0",
|
"validator": "^13.7.0",
|
||||||
"vue": "^3.2.45",
|
"vue": "^3.2.45",
|
||||||
"vue-i18n": "^9.2.2",
|
"vue-i18n": "^9.2.2",
|
||||||
"vue-router": "^4.1.6"
|
"vue-router": "^4.1.6",
|
||||||
|
"vue-router-mock": "^0.1.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/eslint-parser": "^7.13.14",
|
"@intlify/unplugin-vue-i18n": "^0.8.1",
|
||||||
"@intlify/vue-i18n-loader": "^4.1.0",
|
|
||||||
"@pinia/testing": "^0.0.14",
|
"@pinia/testing": "^0.0.14",
|
||||||
"@quasar/app-webpack": "^3.6.2",
|
"@quasar/app-vite": "^1.1.3",
|
||||||
"@quasar/quasar-app-extension-testing-e2e-cypress": "^4.2.2",
|
"@quasar/quasar-app-extension-testing-unit-vitest": "^0.1.2",
|
||||||
"@quasar/quasar-app-extension-testing-unit-jest": "^3.0.0-beta.5",
|
"@vue/test-utils": "^2.0.0",
|
||||||
|
"autoprefixer": "^10.4.13",
|
||||||
|
"cypress": "^12.2.0",
|
||||||
"eslint": "^8.30.0",
|
"eslint": "^8.30.0",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
"eslint-plugin-cypress": "^2.12.1",
|
"eslint-plugin-cypress": "^2.12.1",
|
||||||
"eslint-plugin-jest": "^27.1.7",
|
"eslint-plugin-vue": "^9.8.0",
|
||||||
"eslint-plugin-vue": "^8.7.1",
|
"postcss": "^8.4.20",
|
||||||
"eslint-webpack-plugin": "^3.2.0",
|
"prettier": "^2.8.1",
|
||||||
"jest-junit": "^13.0.0",
|
"vitest": "^0.26.3"
|
||||||
"prettier": "^2.5.1"
|
|
||||||
},
|
},
|
||||||
"browserslist": [
|
|
||||||
"last 10 Chrome versions",
|
|
||||||
"last 10 Firefox versions",
|
|
||||||
"last 4 Edge versions",
|
|
||||||
"last 7 Safari versions",
|
|
||||||
"last 8 Android versions",
|
|
||||||
"last 8 ChromeAndroid versions",
|
|
||||||
"last 8 FirefoxAndroid versions",
|
|
||||||
"last 10 iOS versions",
|
|
||||||
"last 5 Opera versions"
|
|
||||||
],
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 12.22.1",
|
"node": "^18 || ^16 || ^14.19",
|
||||||
"npm": ">= 6.13.4",
|
"npm": ">= 6.13.4",
|
||||||
"yarn": ">= 1.21.1"
|
"yarn": ">= 1.21.1"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"@vitejs/plugin-vue": "^4.0.0",
|
||||||
|
"vite": "^4.0.3",
|
||||||
|
"vitest": "^0.26.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* eslint-disable */
|
||||||
|
// https://github.com/michael-ciniawsky/postcss-load-config
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
plugins: [
|
||||||
|
// https://github.com/postcss/autoprefixer
|
||||||
|
require('autoprefixer')({
|
||||||
|
overrideBrowserslist: [
|
||||||
|
'last 4 Chrome versions',
|
||||||
|
'last 4 Firefox versions',
|
||||||
|
'last 4 Edge versions',
|
||||||
|
'last 4 Safari versions',
|
||||||
|
'last 4 Android versions',
|
||||||
|
'last 4 ChromeAndroid versions',
|
||||||
|
'last 4 FirefoxAndroid versions',
|
||||||
|
'last 4 iOS versions',
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
|
||||||
|
// https://github.com/elchininet/postcss-rtlcss
|
||||||
|
// If you want to support RTL css, then
|
||||||
|
// 1. yarn/npm install postcss-rtlcss
|
||||||
|
// 2. optionally set quasar.config.js > framework > lang to an RTL language
|
||||||
|
// 3. uncomment the following line:
|
||||||
|
// require('postcss-rtlcss')
|
||||||
|
],
|
||||||
|
};
|
232
quasar.config.js
232
quasar.config.js
|
@ -6,26 +6,32 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Configuration for your app
|
// Configuration for your app
|
||||||
// https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js
|
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js
|
||||||
|
|
||||||
const ESLintPlugin = require('eslint-webpack-plugin');
|
|
||||||
const { configure } = require('quasar/wrappers');
|
const { configure } = require('quasar/wrappers');
|
||||||
|
const VueI18nPlugin = require('@intlify/unplugin-vue-i18n/vite')
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
module.exports = configure(function (ctx) {
|
module.exports = configure(function (/* ctx */) {
|
||||||
return {
|
return {
|
||||||
// https://v2.quasar.dev/quasar-cli-webpack/supporting-ts
|
eslint: {
|
||||||
supportTS: false,
|
// fix: true,
|
||||||
|
// include = [],
|
||||||
|
// exclude = [],
|
||||||
|
// rawOptions = {},
|
||||||
|
warnings: true,
|
||||||
|
errors: true,
|
||||||
|
},
|
||||||
|
|
||||||
// https://v2.quasar.dev/quasar-cli-webpack/prefetch-feature
|
// https://v2.quasar.dev/quasar-cli/prefetch-feature
|
||||||
// preFetch: true,
|
// preFetch: true,
|
||||||
|
|
||||||
// app boot file (/src/boot)
|
// app boot file (/src/boot)
|
||||||
// --> boot files are part of "main.js"
|
// --> boot files are part of "main.js"
|
||||||
// https://v2.quasar.dev/quasar-cli-webpack/boot-files
|
// https://v2.quasar.dev/quasar-cli/boot-files
|
||||||
boot: ['i18n', 'axios', 'pinia'],
|
boot: ['i18n', 'axios'],
|
||||||
|
|
||||||
// https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-css
|
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css
|
||||||
css: ['app.scss'],
|
css: ['app.scss'],
|
||||||
|
|
||||||
// https://github.com/quasarframework/quasar/tree/dev/extras
|
// https://github.com/quasarframework/quasar/tree/dev/extras
|
||||||
|
@ -43,58 +49,63 @@ module.exports = configure(function (ctx) {
|
||||||
'material-symbols-outlined',
|
'material-symbols-outlined',
|
||||||
],
|
],
|
||||||
|
|
||||||
// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-build
|
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build
|
||||||
build: {
|
build: {
|
||||||
vueRouterMode: 'hash', // available values: 'hash', 'history'
|
target: {
|
||||||
|
browser: ['es2022', 'edge88', 'firefox78', 'chrome87', 'safari13.1'],
|
||||||
// transpile: false,
|
node: 'node18',
|
||||||
// publicPath: '/',
|
|
||||||
|
|
||||||
// Add dependencies for transpiling with Babel (Array of string/regex)
|
|
||||||
// (from node_modules, which are by default not transpiled).
|
|
||||||
// Applies only if "transpile" is set to true.
|
|
||||||
// transpileDependencies: [],
|
|
||||||
|
|
||||||
// rtl: true, // https://quasar.dev/options/rtl-support
|
|
||||||
// preloadChunks: true,
|
|
||||||
// showProgress: false,
|
|
||||||
// gzip: true,
|
|
||||||
// analyze: true,
|
|
||||||
|
|
||||||
// Options below are automatically set depending on the env, set them if you want to override
|
|
||||||
// extractCSS: false,
|
|
||||||
|
|
||||||
// https://v2.quasar.dev/quasar-cli-webpack/handling-webpack
|
|
||||||
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
|
|
||||||
|
|
||||||
chainWebpack(chain) {
|
|
||||||
chain.module
|
|
||||||
.rule('i18n')
|
|
||||||
.resourceQuery(/blockType=i18n/)
|
|
||||||
.type('javascript/auto')
|
|
||||||
.use('i18n')
|
|
||||||
.loader('@intlify/vue-i18n-loader')
|
|
||||||
.end();
|
|
||||||
|
|
||||||
chain.plugin('eslint-webpack-plugin').use(ESLintPlugin, [{ extensions: ['js', 'vue'] }]);
|
|
||||||
},
|
},
|
||||||
extendWebpack(cfg) {
|
|
||||||
cfg.resolve.alias = {
|
|
||||||
...cfg.resolve.alias, // This adds the existing alias
|
|
||||||
|
|
||||||
// Add your own alias like this
|
vueRouterMode: 'hash', // available values: 'hash', 'history'
|
||||||
composables: path.resolve(__dirname, './src/composables'),
|
// vueRouterBase,
|
||||||
filters: path.resolve(__dirname, './src/filters'),
|
// vueDevtools,
|
||||||
|
// vueOptionsAPI: false,
|
||||||
|
|
||||||
|
// rebuildCache: true, // rebuilds Vite/linter/etc cache on startup
|
||||||
|
|
||||||
|
// publicPath: '/',
|
||||||
|
// analyze: true,
|
||||||
|
// env: {},
|
||||||
|
// rawDefine: {}
|
||||||
|
// ignorePublicFolder: true,
|
||||||
|
// minify: false,
|
||||||
|
// polyfillModulePreload: true,
|
||||||
|
// distDir
|
||||||
|
|
||||||
|
extendViteConf(viteConf) {
|
||||||
|
// FIXME: Delete deprecated property polyfillModulePreload
|
||||||
|
// that is set by Quasar by default
|
||||||
|
delete viteConf.build.polyfillModulePreload;
|
||||||
|
viteConf.build.modulePreload = {
|
||||||
|
polyfill: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
// viteVuePluginOptions: {},
|
||||||
|
|
||||||
|
alias: {
|
||||||
|
composables: path.join(__dirname, './src/composables'),
|
||||||
|
filters: path.join(__dirname, './src/filters'),
|
||||||
},
|
},
|
||||||
|
|
||||||
// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-devServer
|
vitePlugins: [
|
||||||
|
[
|
||||||
|
VueI18nPlugin,
|
||||||
|
{
|
||||||
|
// if you want to use Vue I18n Legacy API, you need to set `compositionOnly: false`
|
||||||
|
// compositionOnly: false,
|
||||||
|
|
||||||
|
// you need to set i18n resource including paths !
|
||||||
|
include: path.resolve(__dirname, './src/i18n/**'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer
|
||||||
devServer: {
|
devServer: {
|
||||||
server: {
|
server: {
|
||||||
type: 'http',
|
type: 'http',
|
||||||
},
|
},
|
||||||
port: 8080,
|
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://0.0.0.0:3000',
|
target: 'http://0.0.0.0:3000',
|
||||||
|
@ -105,15 +116,17 @@ module.exports = configure(function (ctx) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
// https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-framework
|
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework
|
||||||
framework: {
|
framework: {
|
||||||
|
config: {
|
||||||
config: {
|
config: {
|
||||||
brand: {
|
brand: {
|
||||||
primary: 'orange',
|
primary: 'orange',
|
||||||
},
|
},
|
||||||
dark: 'auto',
|
dark: 'auto',
|
||||||
},
|
},
|
||||||
lang: 'es',
|
},
|
||||||
|
lang: 'en-GB',
|
||||||
|
|
||||||
// iconSet: 'material-icons', // Quasar icon set
|
// iconSet: 'material-icons', // Quasar icon set
|
||||||
// lang: 'en-US', // Quasar language pack
|
// lang: 'en-US', // Quasar language pack
|
||||||
|
@ -130,11 +143,29 @@ module.exports = configure(function (ctx) {
|
||||||
},
|
},
|
||||||
|
|
||||||
// animations: 'all', // --- includes all animations
|
// animations: 'all', // --- includes all animations
|
||||||
// https://quasar.dev/options/animations
|
// https://v2.quasar.dev/options/animations
|
||||||
animations: [],
|
animations: [],
|
||||||
|
|
||||||
// https://v2.quasar.dev/quasar-cli-webpack/developing-ssr/configuring-ssr
|
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#property-sourcefiles
|
||||||
|
// sourceFiles: {
|
||||||
|
// rootComponent: 'src/App.vue',
|
||||||
|
// router: 'src/router/index',
|
||||||
|
// store: 'src/store/index',
|
||||||
|
// registerServiceWorker: 'src-pwa/register-service-worker',
|
||||||
|
// serviceWorker: 'src-pwa/custom-service-worker',
|
||||||
|
// pwaManifestFile: 'src-pwa/manifest.json',
|
||||||
|
// electronMain: 'src-electron/electron-main',
|
||||||
|
// electronPreload: 'src-electron/electron-preload'
|
||||||
|
// },
|
||||||
|
|
||||||
|
// https://v2.quasar.dev/quasar-cli/developing-ssr/configuring-ssr
|
||||||
ssr: {
|
ssr: {
|
||||||
|
// ssrPwaHtmlFilename: 'offline.html', // do NOT use index.html as name!
|
||||||
|
// will mess up SSR
|
||||||
|
|
||||||
|
// extendSSRWebserverConf (esbuildConf) {},
|
||||||
|
// extendPackageJson (json) {},
|
||||||
|
|
||||||
pwa: false,
|
pwa: false,
|
||||||
|
|
||||||
// manualStoreHydration: true,
|
// manualStoreHydration: true,
|
||||||
|
@ -143,81 +174,42 @@ module.exports = configure(function (ctx) {
|
||||||
prodPort: 3000, // The default port that the production server should use
|
prodPort: 3000, // The default port that the production server should use
|
||||||
// (gets superseded if process.env.PORT is specified at runtime)
|
// (gets superseded if process.env.PORT is specified at runtime)
|
||||||
|
|
||||||
maxAge: 1000 * 60 * 60 * 24 * 30,
|
|
||||||
// Tell browser when a file from the server should expire from cache (in ms)
|
|
||||||
|
|
||||||
chainWebpackWebserver(chain) {
|
|
||||||
chain.plugin('eslint-webpack-plugin').use(ESLintPlugin, [{ extensions: ['js'] }]);
|
|
||||||
},
|
|
||||||
|
|
||||||
middlewares: [
|
middlewares: [
|
||||||
ctx.prod ? 'compression' : '',
|
|
||||||
'render', // keep this as last one
|
'render', // keep this as last one
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
// https://v2.quasar.dev/quasar-cli-webpack/developing-pwa/configuring-pwa
|
// https://v2.quasar.dev/quasar-cli/developing-pwa/configuring-pwa
|
||||||
pwa: {
|
pwa: {
|
||||||
workboxPluginMode: 'GenerateSW', // 'GenerateSW' or 'InjectManifest'
|
workboxMode: 'generateSW', // or 'injectManifest'
|
||||||
workboxOptions: {}, // only for GenerateSW
|
injectPwaMetaTags: true,
|
||||||
|
swFilename: 'sw.js',
|
||||||
// for the custom service worker ONLY (/src-pwa/custom-service-worker.[js|ts])
|
manifestFilename: 'manifest.json',
|
||||||
// if using workbox in InjectManifest mode
|
useCredentialsForManifestTag: false,
|
||||||
|
// useFilenameHashes: true,
|
||||||
chainWebpackCustomSW(chain) {
|
// extendGenerateSWOptions (cfg) {}
|
||||||
chain.plugin('eslint-webpack-plugin').use(ESLintPlugin, [{ extensions: ['js'] }]);
|
// extendInjectManifestOptions (cfg) {},
|
||||||
|
// extendManifestJson (json) {}
|
||||||
|
// extendPWACustomSWConf (esbuildConf) {}
|
||||||
},
|
},
|
||||||
|
|
||||||
manifest: {
|
// Full list of options: https://v2.quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova
|
||||||
name: `Salix`,
|
|
||||||
short_name: `Salix`,
|
|
||||||
description: `Salix front-end`,
|
|
||||||
display: 'standalone',
|
|
||||||
orientation: 'portrait',
|
|
||||||
background_color: '#ffffff',
|
|
||||||
theme_color: '#027be3',
|
|
||||||
icons: [
|
|
||||||
{
|
|
||||||
src: 'icons/icon-128x128.png',
|
|
||||||
sizes: '128x128',
|
|
||||||
type: 'image/png',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'icons/icon-192x192.png',
|
|
||||||
sizes: '192x192',
|
|
||||||
type: 'image/png',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'icons/icon-256x256.png',
|
|
||||||
sizes: '256x256',
|
|
||||||
type: 'image/png',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'icons/icon-384x384.png',
|
|
||||||
sizes: '384x384',
|
|
||||||
type: 'image/png',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'icons/icon-512x512.png',
|
|
||||||
sizes: '512x512',
|
|
||||||
type: 'image/png',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-cordova-apps/configuring-cordova
|
|
||||||
cordova: {
|
cordova: {
|
||||||
// noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing
|
// noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing
|
||||||
},
|
},
|
||||||
|
|
||||||
// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-capacitor-apps/configuring-capacitor
|
// Full list of options: https://v2.quasar.dev/quasar-cli/developing-capacitor-apps/configuring-capacitor
|
||||||
capacitor: {
|
capacitor: {
|
||||||
hideSplashscreen: true,
|
hideSplashscreen: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-electron-apps/configuring-electron
|
// Full list of options: https://v2.quasar.dev/quasar-cli/developing-electron-apps/configuring-electron
|
||||||
electron: {
|
electron: {
|
||||||
|
// extendElectronMainConf (esbuildConf)
|
||||||
|
// extendElectronPreloadConf (esbuildConf)
|
||||||
|
|
||||||
|
inspectPort: 5858,
|
||||||
|
|
||||||
bundler: 'packager', // 'packager' or 'builder'
|
bundler: 'packager', // 'packager' or 'builder'
|
||||||
|
|
||||||
packager: {
|
packager: {
|
||||||
|
@ -234,18 +226,16 @@ module.exports = configure(function (ctx) {
|
||||||
builder: {
|
builder: {
|
||||||
// https://www.electron.build/configuration/configuration
|
// https://www.electron.build/configuration/configuration
|
||||||
|
|
||||||
appId: 'salix-front',
|
appId: 'salix-frontend',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
|
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-browser-extensions/configuring-bex
|
||||||
|
bex: {
|
||||||
|
contentScripts: ['my-content-script'],
|
||||||
|
|
||||||
chainWebpackMain(chain) {
|
// extendBexScriptsConf (esbuildConf) {}
|
||||||
chain.plugin('eslint-webpack-plugin').use(ESLintPlugin, [{ extensions: ['js'] }]);
|
// extendBexManifestJson (json) {}
|
||||||
},
|
|
||||||
|
|
||||||
chainWebpackPreload(chain) {
|
|
||||||
chain.plugin('eslint-webpack-plugin').use(ESLintPlugin, [{ extensions: ['js'] }]);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
{
|
{
|
||||||
"@quasar/testing-unit-jest": {
|
"@quasar/testing-unit-vitest": {
|
||||||
"babel": "babelrc",
|
"options": [
|
||||||
"options": ["scripts"]
|
"scripts"
|
||||||
},
|
]
|
||||||
"@quasar/testing-e2e-cypress": {
|
|
||||||
"options": ["scripts"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,11 +1,5 @@
|
||||||
{
|
{
|
||||||
"unit-jest": {
|
"unit-vitest": {
|
||||||
"runnerCommand": "jest --ci"
|
"runnerCommand": "vitest run"
|
||||||
},
|
|
||||||
"e2e-cypress": {
|
|
||||||
"runnerCommand": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\""
|
|
||||||
},
|
|
||||||
"unit-cypress": {
|
|
||||||
"runnerCommand": "cypress run-ct"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,11 +1,13 @@
|
||||||
|
import { boot } from 'quasar/wrappers';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useSession } from 'src/composables/useSession';
|
import { useSession } from 'src/composables/useSession';
|
||||||
|
|
||||||
const { getToken } = useSession();
|
export default boot(() => {
|
||||||
|
const { getToken } = useSession();
|
||||||
|
|
||||||
axios.defaults.baseURL = '/api/';
|
axios.defaults.baseURL = '/api/';
|
||||||
|
|
||||||
axios.interceptors.request.use(
|
axios.interceptors.request.use(
|
||||||
function (context) {
|
function (context) {
|
||||||
const token = getToken();
|
const token = getToken();
|
||||||
|
|
||||||
|
@ -18,4 +20,5 @@ axios.interceptors.request.use(
|
||||||
function (error) {
|
function (error) {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
|
|
@ -5,9 +5,10 @@ import messages from 'src/i18n';
|
||||||
const i18n = createI18n({
|
const i18n = createI18n({
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
fallbackLocale: 'en',
|
fallbackLocale: 'en',
|
||||||
|
globalInjection: true,
|
||||||
messages,
|
messages,
|
||||||
|
missingWarn: false,
|
||||||
legacy: false,
|
legacy: false,
|
||||||
missingWarn: false
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default boot(({ app }) => {
|
export default boot(({ app }) => {
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
import { boot } from 'quasar/wrappers';
|
|
||||||
import { createPinia } from 'pinia';
|
|
||||||
|
|
||||||
export default boot(({ app }) => {
|
|
||||||
const pinia = createPinia();
|
|
||||||
|
|
||||||
app.use(pinia);
|
|
||||||
});
|
|
|
@ -14,13 +14,8 @@ const pinnedModules = computed(() => navigation.getPinnedModules());
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<q-menu
|
<q-menu anchor="bottom left" class="row q-pa-md q-col-gutter-lg" max-width="350px" max-height="400px">
|
||||||
anchor="bottom left"
|
<template v-if="pinnedModules.length">
|
||||||
class="row q-pa-md q-col-gutter-lg"
|
|
||||||
max-width="350px"
|
|
||||||
max-height="400px"
|
|
||||||
v-if="pinnedModules.length"
|
|
||||||
>
|
|
||||||
<div v-for="item of pinnedModules" :key="item.title" class="row no-wrap q-pa-xs flex-item">
|
<div v-for="item of pinnedModules" :key="item.title" class="row no-wrap q-pa-xs flex-item">
|
||||||
<q-btn
|
<q-btn
|
||||||
align="evenly"
|
align="evenly"
|
||||||
|
@ -38,6 +33,12 @@ const pinnedModules = computed(() => navigation.getPinnedModules());
|
||||||
</div>
|
</div>
|
||||||
</q-btn>
|
</q-btn>
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<div class="row no-wrap q-pa-xs flex-item text-center text-grey-5" style="min-width: 200px">
|
||||||
|
{{ t('globals.noPinnedModules') }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</q-menu>
|
</q-menu>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,16 @@ const userLocale = computed({
|
||||||
|
|
||||||
if (value === 'en') value = 'en-GB';
|
if (value === 'en') value = 'en-GB';
|
||||||
|
|
||||||
import(`quasar/lang/${value}`).then((language) => {
|
// FIXME: Dynamic imports from absolute paths are not compatible with vite:
|
||||||
Quasar.lang.set(language.default);
|
// https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations
|
||||||
|
try {
|
||||||
|
const langList = import.meta.glob('../../node_modules/quasar/lang/*.mjs');
|
||||||
|
langList[`../../node_modules/quasar/lang/${value}.mjs`]().then((lang) => {
|
||||||
|
Quasar.lang.set(lang.default);
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
//
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
import { jest, describe, expect, it, beforeAll } from '@jest/globals';
|
|
||||||
import { createWrapper } from 'app/tests/jest/jestHelpers';
|
|
||||||
import Leftmenu from '../LeftMenu.vue';
|
|
||||||
|
|
||||||
import { createTestingPinia } from '@pinia/testing';
|
|
||||||
import { useNavigationStore } from 'src/stores/useNavigationStore';
|
|
||||||
|
|
||||||
const mockPush = jest.fn();
|
|
||||||
|
|
||||||
jest.mock('vue-router', () => ({
|
|
||||||
useRouter: () => ({
|
|
||||||
push: mockPush,
|
|
||||||
currentRoute: { value: 'myCurrentRoute' },
|
|
||||||
}),
|
|
||||||
useRoute: () => ({
|
|
||||||
matched: [],
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('src/router/modules', () => [
|
|
||||||
{
|
|
||||||
path: '/customer',
|
|
||||||
name: 'Customer',
|
|
||||||
meta: {
|
|
||||||
title: 'customers',
|
|
||||||
icon: 'vn:client',
|
|
||||||
},
|
|
||||||
menus: {
|
|
||||||
main: ['CustomerList', 'CustomerCreate'],
|
|
||||||
card: ['CustomerBasicData'],
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '',
|
|
||||||
name: 'CustomerMain',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'list',
|
|
||||||
name: 'CustomerList',
|
|
||||||
meta: {
|
|
||||||
title: 'list',
|
|
||||||
icon: 'view_list',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'CustomerCreate',
|
|
||||||
meta: {
|
|
||||||
title: 'createCustomer',
|
|
||||||
icon: 'vn:addperson',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
describe('Leftmenu', () => {
|
|
||||||
let vm;
|
|
||||||
let navigation;
|
|
||||||
beforeAll(async () => {
|
|
||||||
vm = createWrapper(Leftmenu, {
|
|
||||||
propsData: {
|
|
||||||
source: 'main',
|
|
||||||
},
|
|
||||||
global: {
|
|
||||||
plugins: [createTestingPinia({ stubActions: false })],
|
|
||||||
},
|
|
||||||
}).vm;
|
|
||||||
|
|
||||||
navigation = useNavigationStore();
|
|
||||||
navigation.modules = ['customer']; // I should mock to have just one module but isn´t working
|
|
||||||
navigation.fetchPinned = jest.fn().mockReturnValue(Promise.resolve(true));
|
|
||||||
navigation.getModules = jest.fn().mockReturnValue({
|
|
||||||
value: [
|
|
||||||
{
|
|
||||||
name: 'customer',
|
|
||||||
title: 'customer.pageTitles.customers',
|
|
||||||
icon: 'vn:customer',
|
|
||||||
module: 'customer',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return a proper formated object with two child items', async () => {
|
|
||||||
const expectedMenuItem = [
|
|
||||||
{
|
|
||||||
name: 'CustomerList',
|
|
||||||
title: 'customer.pageTitles.list',
|
|
||||||
icon: 'view_list',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'CustomerCreate',
|
|
||||||
title: 'customer.pageTitles.createCustomer',
|
|
||||||
icon: 'vn:addperson',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const firstMenuItem = vm.items[0];
|
|
||||||
expect(firstMenuItem.children).toEqual(expect.arrayContaining(expectedMenuItem));
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useDialogPluginComponent } from 'quasar';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
const $props = defineProps({
|
||||||
|
question: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
defineEmits(['confirm', ...useDialogPluginComponent.emits]);
|
||||||
|
|
||||||
|
const { dialogRef, onDialogOK } = useDialogPluginComponent();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const question = ref($props.question);
|
||||||
|
const message = ref($props.question);
|
||||||
|
const isLoading = ref(false);
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<q-dialog ref="dialogRef" persistent>
|
||||||
|
<q-card class="q-pa-sm">
|
||||||
|
<q-card-section class="row items-center q-pb-none">
|
||||||
|
<span class="text-h6 text-grey">{{ message }}</span>
|
||||||
|
<q-space />
|
||||||
|
<q-btn icon="close" flat round dense v-close-popup />
|
||||||
|
</q-card-section>
|
||||||
|
<q-card-section class="row items-center">
|
||||||
|
{{ question }}
|
||||||
|
</q-card-section>
|
||||||
|
<q-card-actions align="right">
|
||||||
|
<q-btn :label="t('globals.cancel')" color="primary" flat v-close-popup />
|
||||||
|
<q-btn :label="t('globals.confirm')" color="primary" :loading="isLoading" @click="onDialogOK" />
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.q-card {
|
||||||
|
min-width: 350px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,112 +0,0 @@
|
||||||
import * as validator from 'validator';
|
|
||||||
|
|
||||||
export const validators = {
|
|
||||||
presence: ($translate, value) => {
|
|
||||||
if (validator.isEmpty(value ? String(value) : ''))
|
|
||||||
throw new Error(_($translate, `Value can't be empty`));
|
|
||||||
},
|
|
||||||
absence: ($translate, value) => {
|
|
||||||
if (!validator.isEmpty(value))
|
|
||||||
throw new Error(_($translate, `Value should be empty`));
|
|
||||||
},
|
|
||||||
length: ($translate, value, conf) => {
|
|
||||||
let options = {
|
|
||||||
min: conf.min || conf.is,
|
|
||||||
max: conf.max || conf.is
|
|
||||||
};
|
|
||||||
let val = value ? String(value) : '';
|
|
||||||
if (!validator.isLength(val, options)) {
|
|
||||||
if (conf.is) {
|
|
||||||
throw new Error(_($translate,
|
|
||||||
`Value should be %s characters long`, [conf.is]));
|
|
||||||
} else if (conf.min && conf.max) {
|
|
||||||
throw new Error(_($translate,
|
|
||||||
`Value should have a length between %s and %s`, [conf.min, conf.max]));
|
|
||||||
} else if (conf.min) {
|
|
||||||
throw new Error(_($translate,
|
|
||||||
`Value should have at least %s characters`, [conf.min]));
|
|
||||||
} else {
|
|
||||||
throw new Error(_($translate,
|
|
||||||
`Value should have at most %s characters`, [conf.max]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
numericality: ($translate, value, conf) => {
|
|
||||||
if (conf.int) {
|
|
||||||
if (!validator.isInt(value))
|
|
||||||
throw new Error(_($translate, `Value should be integer`));
|
|
||||||
} else if (!validator.isNumeric(value))
|
|
||||||
throw new Error(_($translate, `Value should be a number`));
|
|
||||||
},
|
|
||||||
inclusion: ($translate, value, conf) => {
|
|
||||||
if (!validator.isIn(value, conf.in))
|
|
||||||
throw new Error(_($translate, `Invalid value`));
|
|
||||||
},
|
|
||||||
exclusion: ($translate, value, conf) => {
|
|
||||||
if (validator.isIn(value, conf.in))
|
|
||||||
throw new Error(_($translate, `Invalid value`));
|
|
||||||
},
|
|
||||||
format: ($translate, value, conf) => {
|
|
||||||
if (!validator.matches(value, conf.with))
|
|
||||||
throw new Error(_($translate, `Invalid value`));
|
|
||||||
},
|
|
||||||
custom: ($translate, value, conf) => {
|
|
||||||
if (!conf.bindedFunction(value))
|
|
||||||
throw new Error(_($translate, `Invalid value`));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if value satisfies a set of validations.
|
|
||||||
*
|
|
||||||
* @param {*} value The value
|
|
||||||
* @param {Array} validations Array with validations
|
|
||||||
*/
|
|
||||||
export function validateAll($translate, value, validations) {
|
|
||||||
for (let conf of validations)
|
|
||||||
validate($translate, value, conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if value satisfies a validation.
|
|
||||||
*
|
|
||||||
* @param {*} value The value
|
|
||||||
* @param {Object} conf The validation configuration
|
|
||||||
*/
|
|
||||||
export function validate($translate, value, conf) {
|
|
||||||
let validator = validators[conf.validation];
|
|
||||||
try {
|
|
||||||
let isEmpty = value == null || value === '';
|
|
||||||
|
|
||||||
if (isEmpty)
|
|
||||||
checkNull($translate, value, conf);
|
|
||||||
if (validator && (!isEmpty || conf.validation == 'presence'))
|
|
||||||
validator($translate, value, conf);
|
|
||||||
} catch (e) {
|
|
||||||
let message = conf.message ? conf.message : e.message;
|
|
||||||
throw new Error(_($translate, message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if value satisfies a blank or not null validation.
|
|
||||||
*
|
|
||||||
* @param {*} value The value
|
|
||||||
* @param {Object} conf The validation configuration
|
|
||||||
*/
|
|
||||||
export function checkNull($translate, value, conf) {
|
|
||||||
if (conf.allowBlank === false && value === '')
|
|
||||||
throw new Error(_($translate, `Value can't be blank`));
|
|
||||||
else if (conf.allowNull === false && value == null)
|
|
||||||
throw new Error(_($translate, `Value can't be null`));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function _($translate, text, params = []) {
|
|
||||||
text = $translate.instant(text);
|
|
||||||
|
|
||||||
for (let i = 0; i < params.length; i++) {
|
|
||||||
text = text.replace('%s', params[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return text;
|
|
||||||
}
|
|
|
@ -1,14 +1,8 @@
|
||||||
// app global css in SCSS form
|
// app global css in SCSS form
|
||||||
@import './icons.scss';
|
@import './icons.scss';
|
||||||
|
|
||||||
.body--dark {
|
a {
|
||||||
.q-card--dark {
|
text-decoration: none;
|
||||||
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
.q-layout__shadow::after {
|
|
||||||
box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0px 10px rgba(0, 0, 0, 0.24) !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.link {
|
.link {
|
||||||
|
|
|
@ -23,8 +23,11 @@ $negative: #c10015;
|
||||||
$info: #31ccec;
|
$info: #31ccec;
|
||||||
$warning: #f2c037;
|
$warning: #f2c037;
|
||||||
|
|
||||||
$color-spacer-light: rgba(255, 255, 255, .12);
|
$color-spacer-light: rgba(255, 255, 255, 0.12);
|
||||||
$color-spacer:rgba(255, 255, 255, .3);
|
$color-spacer: rgba(255, 255, 255, 0.3);
|
||||||
$border-thin-light: 1px solid $color-spacer-light;
|
$border-thin-light: 1px solid $color-spacer-light;
|
||||||
|
|
||||||
|
$dark-shadow-color: #000;
|
||||||
|
$layout-shadow-dark: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0px 10px rgba(0, 0, 0, 0.24);
|
||||||
|
|
||||||
$spacing-md: 16px;
|
$spacing-md: 16px;
|
||||||
|
|
|
@ -30,6 +30,7 @@ export default {
|
||||||
rowAdded: 'Row added',
|
rowAdded: 'Row added',
|
||||||
rowRemoved: 'Row removed',
|
rowRemoved: 'Row removed',
|
||||||
pleaseWait: 'Please wait...',
|
pleaseWait: 'Please wait...',
|
||||||
|
noPinnedModules: 'You have dont have any pinned modules',
|
||||||
},
|
},
|
||||||
moduleIndex: {
|
moduleIndex: {
|
||||||
allModules: 'All modules',
|
allModules: 'All modules',
|
||||||
|
@ -296,7 +297,7 @@ export default {
|
||||||
},
|
},
|
||||||
invoiceOut: {
|
invoiceOut: {
|
||||||
pageTitles: {
|
pageTitles: {
|
||||||
invoiceOuts: 'InvoiceOuts',
|
invoiceOuts: 'Invoices Out',
|
||||||
list: 'List',
|
list: 'List',
|
||||||
createInvoiceOut: 'Create invoice out',
|
createInvoiceOut: 'Create invoice out',
|
||||||
summary: 'Summary',
|
summary: 'Summary',
|
||||||
|
|
|
@ -30,6 +30,7 @@ export default {
|
||||||
rowAdded: 'Fila añadida',
|
rowAdded: 'Fila añadida',
|
||||||
rowRemoved: 'Fila eliminada',
|
rowRemoved: 'Fila eliminada',
|
||||||
pleaseWait: 'Por favor, espera...',
|
pleaseWait: 'Por favor, espera...',
|
||||||
|
noPinnedModules: 'No has fijado ningún módulo',
|
||||||
},
|
},
|
||||||
moduleIndex: {
|
moduleIndex: {
|
||||||
allModules: 'Todos los módulos',
|
allModules: 'Todos los módulos',
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
import { jest, describe, expect, it, beforeAll } from '@jest/globals';
|
|
||||||
import { createWrapper, axios } from 'app/tests/jest/jestHelpers';
|
|
||||||
import ClaimDescriptorMenu from '../Card/ClaimDescriptorMenu.vue';
|
|
||||||
|
|
||||||
const mockPush = jest.fn();
|
|
||||||
|
|
||||||
jest.mock('vue-router', () => ({
|
|
||||||
useRouter: () => ({
|
|
||||||
push: mockPush,
|
|
||||||
currentRoute: {
|
|
||||||
value: {
|
|
||||||
params: {
|
|
||||||
id: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('ClaimDescriptorMenu', () => {
|
|
||||||
let vm;
|
|
||||||
beforeAll(() => {
|
|
||||||
vm = createWrapper(ClaimDescriptorMenu, {
|
|
||||||
propsData: {
|
|
||||||
claim: {
|
|
||||||
id: 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).vm;
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('deleteClaim()', () => {
|
|
||||||
it('should delete the claim', async () => {
|
|
||||||
jest.spyOn(axios, 'delete').mockResolvedValue({ data: true });
|
|
||||||
jest.spyOn(vm.quasar, 'notify');
|
|
||||||
|
|
||||||
await vm.deleteClaim();
|
|
||||||
|
|
||||||
expect(vm.quasar.notify).toHaveBeenCalledWith(expect.objectContaining(
|
|
||||||
{ 'type': 'positive' }
|
|
||||||
));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -21,9 +21,16 @@ const userLocale = computed({
|
||||||
|
|
||||||
if (value === 'en') value = 'en-GB';
|
if (value === 'en') value = 'en-GB';
|
||||||
|
|
||||||
import(`quasar/lang/${value}`).then((language) => {
|
// FIXME: Dynamic imports from absolute paths are not compatible with vite:
|
||||||
Quasar.lang.set(language.default);
|
// https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations
|
||||||
|
try {
|
||||||
|
const langList = import.meta.glob('../../node_modules/quasar/lang/*.mjs');
|
||||||
|
langList[`../../node_modules/quasar/lang/${value}.mjs`]().then((lang) => {
|
||||||
|
Quasar.lang.set(lang.default);
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
//
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -41,6 +48,7 @@ const password = ref('');
|
||||||
const keepLogin = ref(true);
|
const keepLogin = ref(true);
|
||||||
|
|
||||||
async function onSubmit() {
|
async function onSubmit() {
|
||||||
|
try {
|
||||||
const { data } = await axios.post('Accounts/login', {
|
const { data } = await axios.post('Accounts/login', {
|
||||||
user: username.value,
|
user: username.value,
|
||||||
password: password.value,
|
password: password.value,
|
||||||
|
@ -61,6 +69,9 @@ async function onSubmit() {
|
||||||
} else {
|
} else {
|
||||||
router.push({ name: 'Dashboard' });
|
router.push({ name: 'Dashboard' });
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
//
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -70,7 +81,15 @@ async function onSubmit() {
|
||||||
<q-page id="login">
|
<q-page id="login">
|
||||||
<q-page-sticky position="top-right">
|
<q-page-sticky position="top-right">
|
||||||
<q-toolbar>
|
<q-toolbar>
|
||||||
<q-btn :label="t('globals.language')" icon="translate" color="primary" size="sm" flat rounded>
|
<q-btn
|
||||||
|
id="switchLanguage"
|
||||||
|
:label="t('globals.language')"
|
||||||
|
icon="translate"
|
||||||
|
color="primary"
|
||||||
|
size="sm"
|
||||||
|
flat
|
||||||
|
rounded
|
||||||
|
>
|
||||||
<q-menu auto-close>
|
<q-menu auto-close>
|
||||||
<q-list dense>
|
<q-list dense>
|
||||||
<q-item @click="userLocale = 'en'" :active="userLocale == 'en'" v-ripple clickable>
|
<q-item @click="userLocale = 'en'" :active="userLocale == 'en'" v-ripple clickable>
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
import { jest, describe, expect, it, beforeAll } from '@jest/globals';
|
|
||||||
import { createWrapper, axios } from 'app/tests/jest/jestHelpers';
|
|
||||||
import TicketBoxing from '../TicketBoxing.vue';
|
|
||||||
|
|
||||||
const mockPush = jest.fn();
|
|
||||||
|
|
||||||
jest.mock('vue-router', () => ({
|
|
||||||
useRouter: () => ({
|
|
||||||
push: mockPush,
|
|
||||||
currentRoute: {
|
|
||||||
value: {
|
|
||||||
params: {
|
|
||||||
id: 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// #4836 - Investigate how to test q-drawer outside
|
|
||||||
// q-layout or how to teleport q-drawer inside
|
|
||||||
xdescribe('TicketBoxing', () => {
|
|
||||||
let vm;
|
|
||||||
beforeAll(() => {
|
|
||||||
vm = createWrapper(TicketBoxing).vm;
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getVideoList()', () => {
|
|
||||||
it('should when response videoList use to list', async () => {
|
|
||||||
const expeditionId = 1;
|
|
||||||
const timed = {
|
|
||||||
min: 1,
|
|
||||||
max: 2
|
|
||||||
}
|
|
||||||
const videoList = [
|
|
||||||
"2022-01-01T01-01-00.mp4",
|
|
||||||
"2022-02-02T02-02-00.mp4",
|
|
||||||
"2022-03-03T03-03-00.mp4",
|
|
||||||
]
|
|
||||||
|
|
||||||
jest.spyOn(axios, 'get').mockResolvedValue({ data: videoList });
|
|
||||||
jest.spyOn(vm.quasar, 'notify');
|
|
||||||
|
|
||||||
await vm.getVideoList(expeditionId, timed);
|
|
||||||
|
|
||||||
expect(vm.videoList.length).toEqual(videoList.length);
|
|
||||||
expect(vm.slide).toEqual(videoList.reverse()[0]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should if not have video show notify', async () => {
|
|
||||||
const expeditionId = 1;
|
|
||||||
const timed = {
|
|
||||||
min: 1,
|
|
||||||
max: 2
|
|
||||||
}
|
|
||||||
|
|
||||||
jest.spyOn(axios, 'get').mockResolvedValue({ data: [] });
|
|
||||||
jest.spyOn(vm.quasar, 'notify')
|
|
||||||
|
|
||||||
await vm.getVideoList(expeditionId, timed);
|
|
||||||
|
|
||||||
expect(vm.quasar.notify).toHaveBeenCalledWith(expect.objectContaining(
|
|
||||||
{ 'type': 'negative' }
|
|
||||||
));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -35,7 +35,7 @@ export default route(function (/* { store, ssrContext } */) {
|
||||||
// Leave this as is and make changes in quasar.conf.js instead!
|
// Leave this as is and make changes in quasar.conf.js instead!
|
||||||
// quasar.conf.js -> build -> vueRouterMode
|
// quasar.conf.js -> build -> vueRouterMode
|
||||||
// quasar.conf.js -> build -> publicPath
|
// quasar.conf.js -> build -> publicPath
|
||||||
history: createHistory(process.env.MODE === 'ssr' ? void 0 : process.env.VUE_ROUTER_BASE),
|
history: createHistory(process.env.VUE_ROUTER_BASE),
|
||||||
});
|
});
|
||||||
|
|
||||||
Router.beforeEach(async (to, from, next) => {
|
Router.beforeEach(async (to, from, next) => {
|
||||||
|
|
|
@ -30,7 +30,7 @@ const routes = [
|
||||||
worker,
|
worker,
|
||||||
invoiceOut,
|
invoiceOut,
|
||||||
{
|
{
|
||||||
path: '/:pathMatch(.*)*',
|
path: '/:catchAll(.*)*',
|
||||||
name: 'NotFound',
|
name: 'NotFound',
|
||||||
component: () => import('../pages/NotFound.vue'),
|
component: () => import('../pages/NotFound.vue'),
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { store } from 'quasar/wrappers';
|
||||||
|
import { createPinia } from 'pinia';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If not building with SSR mode, you can
|
||||||
|
* directly export the Store instantiation;
|
||||||
|
*
|
||||||
|
* The function below can be async too; either use
|
||||||
|
* async/await or return a Promise which resolves
|
||||||
|
* with the Store instance.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default store((/* { ssrContext } */) => {
|
||||||
|
const pinia = createPinia();
|
||||||
|
|
||||||
|
// You can add Pinia plugins here
|
||||||
|
// pinia.use(SomePiniaPlugin)
|
||||||
|
|
||||||
|
return pinia;
|
||||||
|
});
|
|
@ -0,0 +1,10 @@
|
||||||
|
/* eslint-disable */
|
||||||
|
// THIS FEATURE-FLAG FILE IS AUTOGENERATED,
|
||||||
|
// REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING
|
||||||
|
import "quasar/dist/types/feature-flag";
|
||||||
|
|
||||||
|
declare module "quasar/dist/types/feature-flag" {
|
||||||
|
interface QuasarFeatureFlags {
|
||||||
|
store: true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,8 @@
|
||||||
describe('Login', () => {
|
describe('Login', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('/#/login');
|
cy.visit('/#/login');
|
||||||
|
cy.get('#switchLanguage').click();
|
||||||
|
cy.get('div.q-menu div.q-item:nth-child(1)').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail to log in using wrong user', () => {
|
it('should fail to log in using wrong user', () => {
|
||||||
|
@ -36,7 +38,7 @@ describe('Login', () => {
|
||||||
cy.get('#logout').click();
|
cy.get('#logout').click();
|
||||||
cy.window().its('localStorage').invoke('getItem', 'token').should('not.exist');
|
cy.window().its('localStorage').invoke('getItem', 'token').should('not.exist');
|
||||||
cy.url().should('contain', '/login');
|
cy.url().should('contain', '/login');
|
||||||
})
|
});
|
||||||
|
|
||||||
it(`should get redirected to dashboard since employee can't create tickets`, () => {
|
it(`should get redirected to dashboard since employee can't create tickets`, () => {
|
||||||
cy.visit('/#/ticket/create', { failOnStatusCode: false });
|
cy.visit('/#/ticket/create', { failOnStatusCode: false });
|
||||||
|
@ -45,7 +47,7 @@ describe('Login', () => {
|
||||||
cy.get('input[aria-label="Password"]').type('nightmare');
|
cy.get('input[aria-label="Password"]').type('nightmare');
|
||||||
cy.get('button[type="submit"]').click();
|
cy.get('button[type="submit"]').click();
|
||||||
cy.url().should('contain', '/dashboard');
|
cy.url().should('contain', '/dashboard');
|
||||||
})
|
});
|
||||||
|
|
||||||
// ticket creation is not yet implemented, use this test once it is
|
// ticket creation is not yet implemented, use this test once it is
|
||||||
// it(`should get redirected to ticket creation after login since salesPerson can do it`, () => {
|
// it(`should get redirected to ticket creation after login since salesPerson can do it`, () => {
|
|
@ -1,8 +1,9 @@
|
||||||
describe('TicketBoxing', () => {
|
/// <reference types="cypress" />
|
||||||
|
xdescribe('TicketBoxing', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const ticketId = 1;
|
const ticketId = 1;
|
||||||
cy.viewport(1280, 720)
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer')
|
cy.login('developer');
|
||||||
cy.visit(`/#/ticket/${ticketId}/boxing`);
|
cy.visit(`/#/ticket/${ticketId}/boxing`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -23,16 +24,11 @@ describe('TicketBoxing', () => {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/api/Boxings/*',
|
url: '/api/Boxings/*',
|
||||||
},
|
},
|
||||||
[
|
['2022-01-01T01-01-00.mp4', '2022-02-02T02-02-00.mp4', '2022-03-03T03-03-00.mp4']
|
||||||
"2022-01-01T01-01-00.mp4",
|
|
||||||
"2022-02-02T02-02-00.mp4",
|
|
||||||
"2022-03-03T03-03-00.mp4",
|
|
||||||
]
|
|
||||||
).as('getVideoList');
|
).as('getVideoList');
|
||||||
cy.get('.q-list > :nth-child(3)').click();
|
cy.get('.q-list > :nth-child(3)').click();
|
||||||
|
|
||||||
cy.get('.q-list > :nth-child(1)').should('be.visible');
|
cy.get('.q-list > :nth-child(1)').should('be.visible');
|
||||||
cy.get('.q-list > :nth-child(2)').should('be.visible');
|
cy.get('.q-list > :nth-child(2)').should('be.visible');
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
// DO NOT REMOVE
|
// DO NOT REMOVE
|
||||||
// Imports Quasar Cypress AE predefined commands
|
// Imports Quasar Cypress AE predefined commands
|
||||||
import { registerCommands } from '@quasar/quasar-app-extension-testing-e2e-cypress';
|
// import { registerCommands } from '@quasar/quasar-app-extension-testing-e2e-cypress';
|
||||||
Cypress.Commands.add('login', (user) => {
|
Cypress.Commands.add('login', (user) => {
|
||||||
cy.visit('/#/login');
|
cy.visit('/#/login');
|
||||||
cy.request({
|
cy.request({
|
||||||
|
@ -34,10 +34,10 @@ Cypress.Commands.add('login', (user) => {
|
||||||
url: '/api/accounts/login',
|
url: '/api/accounts/login',
|
||||||
body: {
|
body: {
|
||||||
user: user,
|
user: user,
|
||||||
password: 'nightmare'
|
password: 'nightmare',
|
||||||
}
|
},
|
||||||
}).then(response => {
|
}).then((response) => {
|
||||||
window.localStorage.setItem('token', response.body.token);
|
window.localStorage.setItem('token', response.body.token);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
registerCommands();
|
// registerCommands();
|
|
@ -14,3 +14,4 @@
|
||||||
// ***********************************************************
|
// ***********************************************************
|
||||||
|
|
||||||
import './commands';
|
import './commands';
|
||||||
|
|
|
@ -1,21 +1,13 @@
|
||||||
import { jest, describe, expect, it, beforeAll } from '@jest/globals';
|
import { vi, describe, expect, it, beforeAll } from 'vitest';
|
||||||
import { createWrapper } from 'app/tests/jest/jestHelpers';
|
import { createWrapper } from 'app/test/vitest/helper';
|
||||||
import App from '../App.vue';
|
import App from 'src/App.vue';
|
||||||
import { useSession } from 'src/composables/useSession';
|
import { useSession } from 'src/composables/useSession';
|
||||||
|
|
||||||
const mockPush = jest.fn();
|
const mockLoggedIn = vi.fn();
|
||||||
const mockLoggedIn = jest.fn();
|
const mockDestroy = vi.fn();
|
||||||
const mockDestroy = jest.fn();
|
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
|
|
||||||
jest.mock('vue-router', () => ({
|
vi.mock('src/composables/useSession', () => ({
|
||||||
useRouter: () => ({
|
|
||||||
push: mockPush,
|
|
||||||
currentRoute: { value: 'myCurrentRoute' },
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('src/composables/useSession', () => ({
|
|
||||||
useSession: () => ({
|
useSession: () => ({
|
||||||
isLoggedIn: mockLoggedIn,
|
isLoggedIn: mockLoggedIn,
|
||||||
destroy: mockDestroy,
|
destroy: mockDestroy,
|
||||||
|
@ -24,6 +16,7 @@ jest.mock('src/composables/useSession', () => ({
|
||||||
|
|
||||||
describe('App', () => {
|
describe('App', () => {
|
||||||
let vm;
|
let vm;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
const options = {
|
const options = {
|
||||||
global: {
|
global: {
|
||||||
|
@ -34,7 +27,7 @@ describe('App', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return a login error message', async () => {
|
it('should return a login error message', async () => {
|
||||||
jest.spyOn(vm.quasar, 'notify');
|
vi.spyOn(vm.quasar, 'notify');
|
||||||
|
|
||||||
session.isLoggedIn.mockReturnValue(false);
|
session.isLoggedIn.mockReturnValue(false);
|
||||||
|
|
||||||
|
@ -54,7 +47,7 @@ describe('App', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return an unauthorized error message', async () => {
|
it('should return an unauthorized error message', async () => {
|
||||||
jest.spyOn(vm.quasar, 'notify');
|
vi.spyOn(vm.quasar, 'notify');
|
||||||
|
|
||||||
session.isLoggedIn.mockReturnValue(true);
|
session.isLoggedIn.mockReturnValue(true);
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
import { vi, describe, expect, it, beforeAll } from 'vitest';
|
||||||
|
import { createWrapper, axios } from 'app/test/vitest/helper';
|
||||||
|
import Leftmenu from 'components/LeftMenu.vue';
|
||||||
|
|
||||||
|
import { useNavigationStore } from 'src/stores/useNavigationStore';
|
||||||
|
|
||||||
|
vi.mock('src/router/modules', () => ({
|
||||||
|
default: [
|
||||||
|
{
|
||||||
|
path: '/customer',
|
||||||
|
name: 'Customer',
|
||||||
|
meta: {
|
||||||
|
title: 'customers',
|
||||||
|
icon: 'vn:client',
|
||||||
|
},
|
||||||
|
menus: {
|
||||||
|
main: ['CustomerList', 'CustomerCreate'],
|
||||||
|
card: ['CustomerBasicData'],
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
name: 'CustomerMain',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'list',
|
||||||
|
name: 'CustomerList',
|
||||||
|
meta: {
|
||||||
|
title: 'list',
|
||||||
|
icon: 'view_list',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'create',
|
||||||
|
name: 'CustomerCreate',
|
||||||
|
meta: {
|
||||||
|
title: 'createCustomer',
|
||||||
|
icon: 'vn:addperson',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('Leftmenu', () => {
|
||||||
|
let vm;
|
||||||
|
let navigation;
|
||||||
|
beforeAll(() => {
|
||||||
|
vi.spyOn(axios, 'get').mockResolvedValue({
|
||||||
|
data: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
vm = createWrapper(Leftmenu, {
|
||||||
|
propsData: {
|
||||||
|
source: 'main',
|
||||||
|
},
|
||||||
|
}).vm;
|
||||||
|
|
||||||
|
navigation = useNavigationStore();
|
||||||
|
navigation.fetchPinned = vi.fn().mockReturnValue(Promise.resolve(true));
|
||||||
|
navigation.getModules = vi.fn().mockReturnValue({
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
name: 'customer',
|
||||||
|
title: 'customer.pageTitles.customers',
|
||||||
|
icon: 'vn:customer',
|
||||||
|
module: 'customer',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a proper formated object with two child items', async () => {
|
||||||
|
const expectedMenuItem = [
|
||||||
|
{
|
||||||
|
name: 'CustomerList',
|
||||||
|
title: 'customer.pageTitles.list',
|
||||||
|
icon: 'view_list',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CustomerCreate',
|
||||||
|
title: 'customer.pageTitles.createCustomer',
|
||||||
|
icon: 'vn:addperson',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const firstMenuItem = vm.items[0];
|
||||||
|
expect(firstMenuItem.children).toEqual(expect.arrayContaining(expectedMenuItem));
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,15 +1,6 @@
|
||||||
import { jest, describe, expect, it, beforeAll } from '@jest/globals';
|
import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
|
||||||
import { createWrapper, axios } from 'app/tests/jest/jestHelpers';
|
import { createWrapper, axios } from 'app/test/vitest/helper';
|
||||||
import Paginate from '../PaginateData.vue';
|
import Paginate from 'components/PaginateData.vue';
|
||||||
|
|
||||||
const mockPush = jest.fn();
|
|
||||||
|
|
||||||
jest.mock('vue-router', () => ({
|
|
||||||
useRouter: () => ({
|
|
||||||
push: mockPush,
|
|
||||||
currentRoute: { value: 'myCurrentRoute' }
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('Paginate', () => {
|
describe('Paginate', () => {
|
||||||
const expectedUrl = '/api/customers';
|
const expectedUrl = '/api/customers';
|
||||||
|
@ -19,17 +10,17 @@ describe('Paginate', () => {
|
||||||
attrs: {
|
attrs: {
|
||||||
url: expectedUrl,
|
url: expectedUrl,
|
||||||
sortBy: 'id DESC',
|
sortBy: 'id DESC',
|
||||||
rowsPerPage: 3
|
rowsPerPage: 3,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
vm = createWrapper(Paginate, options).vm;
|
vm = createWrapper(Paginate, options).vm;
|
||||||
|
|
||||||
jest.spyOn(axios, 'get').mockResolvedValue({
|
vi.spyOn(axios, 'get').mockResolvedValue({
|
||||||
data: [
|
data: [
|
||||||
{ id: 1, name: 'Tony Stark' },
|
{ id: 1, name: 'Tony Stark' },
|
||||||
{ id: 2, name: 'Jessica Jones' },
|
{ id: 2, name: 'Jessica Jones' },
|
||||||
{ id: 3, name: 'Bruce Wayne' },
|
{ id: 3, name: 'Bruce Wayne' },
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -37,7 +28,7 @@ describe('Paginate', () => {
|
||||||
vm.rows = [];
|
vm.rows = [];
|
||||||
vm.pagination.page = 1;
|
vm.pagination.page = 1;
|
||||||
vm.hasMoreData = true;
|
vm.hasMoreData = true;
|
||||||
})
|
});
|
||||||
|
|
||||||
describe('paginate()', () => {
|
describe('paginate()', () => {
|
||||||
it('should call to the paginate() method and set the data on the rows property', async () => {
|
it('should call to the paginate() method and set the data on the rows property', async () => {
|
||||||
|
@ -46,9 +37,9 @@ describe('Paginate', () => {
|
||||||
filter: {
|
filter: {
|
||||||
order: 'id DESC',
|
order: 'id DESC',
|
||||||
limit: 3,
|
limit: 3,
|
||||||
skip: 0
|
skip: 0,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await vm.paginate();
|
await vm.paginate();
|
||||||
|
@ -63,9 +54,9 @@ describe('Paginate', () => {
|
||||||
filter: {
|
filter: {
|
||||||
order: 'id DESC',
|
order: 'id DESC',
|
||||||
limit: 3,
|
limit: 3,
|
||||||
skip: 0
|
skip: 0,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await vm.paginate();
|
await vm.paginate();
|
||||||
|
@ -78,9 +69,9 @@ describe('Paginate', () => {
|
||||||
filter: {
|
filter: {
|
||||||
order: 'id DESC',
|
order: 'id DESC',
|
||||||
limit: 3,
|
limit: 3,
|
||||||
skip: 3
|
skip: 3,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
vm.pagination.page = 2;
|
vm.pagination.page = 2;
|
||||||
|
@ -95,7 +86,7 @@ describe('Paginate', () => {
|
||||||
describe('onLoad()', () => {
|
describe('onLoad()', () => {
|
||||||
it('should call to the done() callback and not increment the pagination', async () => {
|
it('should call to the done() callback and not increment the pagination', async () => {
|
||||||
const index = 1;
|
const index = 1;
|
||||||
const done = jest.fn();
|
const done = vi.fn();
|
||||||
|
|
||||||
await vm.onLoad(index, done);
|
await vm.onLoad(index, done);
|
||||||
|
|
||||||
|
@ -113,7 +104,7 @@ describe('Paginate', () => {
|
||||||
expect(vm.pagination.page).toEqual(1);
|
expect(vm.pagination.page).toEqual(1);
|
||||||
|
|
||||||
const index = 1;
|
const index = 1;
|
||||||
const done = jest.fn();
|
const done = vi.fn();
|
||||||
|
|
||||||
await vm.onLoad(index, done);
|
await vm.onLoad(index, done);
|
||||||
|
|
||||||
|
@ -122,11 +113,11 @@ describe('Paginate', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call to the done() callback with true as argument to finish pagination', async () => {
|
it('should call to the done() callback with true as argument to finish pagination', async () => {
|
||||||
jest.spyOn(axios, 'get').mockResolvedValue({
|
vi.spyOn(axios, 'get').mockResolvedValue({
|
||||||
data: [
|
data: [
|
||||||
{ id: 1, name: 'Tony Stark' },
|
{ id: 1, name: 'Tony Stark' },
|
||||||
{ id: 2, name: 'Jessica Jones' }
|
{ id: 2, name: 'Jessica Jones' },
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
vm.rows = [
|
vm.rows = [
|
||||||
|
@ -138,7 +129,7 @@ describe('Paginate', () => {
|
||||||
expect(vm.pagination.page).toEqual(1);
|
expect(vm.pagination.page).toEqual(1);
|
||||||
|
|
||||||
const index = 1;
|
const index = 1;
|
||||||
const done = jest.fn();
|
const done = vi.fn();
|
||||||
|
|
||||||
vm.hasMoreData = false;
|
vm.hasMoreData = false;
|
||||||
|
|
|
@ -1,23 +1,22 @@
|
||||||
import { describe, expect, it, jest } from '@jest/globals';
|
import { vi, describe, expect, it } from 'vitest';
|
||||||
import { axios, flushPromises } from 'app/tests/jest/jestHelpers';
|
import { axios, flushPromises } from 'app/test/vitest/helper';
|
||||||
import { useRole } from '../useRole';
|
import { useRole } from 'composables/useRole';
|
||||||
const role = useRole();
|
const role = useRole();
|
||||||
|
|
||||||
describe('useRole', () => {
|
describe('useRole', () => {
|
||||||
|
|
||||||
describe('fetch', () => {
|
describe('fetch', () => {
|
||||||
it('should call setUser and setRoles of the state with the expected data', async () => {
|
it('should call setUser and setRoles of the state with the expected data', async () => {
|
||||||
const rolesData = [
|
const rolesData = [
|
||||||
{
|
{
|
||||||
role: {
|
role: {
|
||||||
name: 'salesPerson'
|
name: 'salesPerson',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: {
|
role: {
|
||||||
name: 'admin'
|
name: 'admin',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
const fetchedUser = {
|
const fetchedUser = {
|
||||||
id: 999,
|
id: 999,
|
||||||
|
@ -26,22 +25,22 @@ describe('useRole', () => {
|
||||||
lang: 'en',
|
lang: 'en',
|
||||||
userConfig: {
|
userConfig: {
|
||||||
darkMode: false,
|
darkMode: false,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
const expectedUser = {
|
const expectedUser = {
|
||||||
id: 999,
|
id: 999,
|
||||||
name: `T'Challa`,
|
name: `T'Challa`,
|
||||||
nickname: 'Black Panther',
|
nickname: 'Black Panther',
|
||||||
lang: 'en',
|
lang: 'en',
|
||||||
darkMode: false,
|
darkMode: false,
|
||||||
}
|
};
|
||||||
const expectedRoles = ['salesPerson', 'admin']
|
const expectedRoles = ['salesPerson', 'admin'];
|
||||||
jest.spyOn(axios, 'get').mockResolvedValue({
|
vi.spyOn(axios, 'get').mockResolvedValue({
|
||||||
data: { roles: rolesData, user: fetchedUser }
|
data: { roles: rolesData, user: fetchedUser },
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.spyOn(role.state, 'setUser');
|
vi.spyOn(role.state, 'setUser');
|
||||||
jest.spyOn(role.state, 'setRoles');
|
vi.spyOn(role.state, 'setRoles');
|
||||||
|
|
||||||
role.fetch();
|
role.fetch();
|
||||||
|
|
||||||
|
@ -50,19 +49,20 @@ describe('useRole', () => {
|
||||||
expect(role.state.setUser).toHaveBeenCalledWith(expectedUser);
|
expect(role.state.setUser).toHaveBeenCalledWith(expectedUser);
|
||||||
expect(role.state.setRoles).toHaveBeenCalledWith(expectedRoles);
|
expect(role.state.setRoles).toHaveBeenCalledWith(expectedRoles);
|
||||||
|
|
||||||
role.state.setRoles([])
|
role.state.setRoles([]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('hasAny', () => {
|
describe('hasAny', () => {
|
||||||
it('should return true if a role matched', async () => {
|
it('should return true if a role matched', async () => {
|
||||||
role.state.setRoles(['admin'])
|
role.state.setRoles(['admin']);
|
||||||
const hasRole = role.hasAny(['admin']);
|
const hasRole = role.hasAny(['admin']);
|
||||||
|
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
|
|
||||||
expect(hasRole).toBe(true);
|
expect(hasRole).toBe(true);
|
||||||
|
|
||||||
role.state.setRoles([])
|
role.state.setRoles([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false if no roles matched', async () => {
|
it('should return false if no roles matched', async () => {
|
|
@ -1,7 +1,7 @@
|
||||||
import { describe, expect, it, jest } from '@jest/globals';
|
import { vi, describe, expect, it } from 'vitest';
|
||||||
import { useSession } from '../useSession';
|
import { axios } from 'app/test/vitest/helper';
|
||||||
import { useState } from '../useState';
|
import { useSession } from 'composables/useSession';
|
||||||
import { axios } from 'app/tests/jest/jestHelpers';
|
import { useState } from 'composables/useState';
|
||||||
|
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const state = useState();
|
const state = useState();
|
||||||
|
@ -9,7 +9,7 @@ const state = useState();
|
||||||
describe('session', () => {
|
describe('session', () => {
|
||||||
describe('getToken / setToken', () => {
|
describe('getToken / setToken', () => {
|
||||||
it('should return an empty string if no token is found in local or session storage', async () => {
|
it('should return an empty string if no token is found in local or session storage', async () => {
|
||||||
const expectedToken = ''
|
const expectedToken = '';
|
||||||
|
|
||||||
const token = session.getToken();
|
const token = session.getToken();
|
||||||
|
|
||||||
|
@ -17,11 +17,11 @@ describe('session', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the token stored in local or session storage', async () => {
|
it('should return the token stored in local or session storage', async () => {
|
||||||
const expectedToken = 'myToken'
|
const expectedToken = 'myToken';
|
||||||
const data = {
|
const data = {
|
||||||
token: expectedToken,
|
token: expectedToken,
|
||||||
keepLogin: false
|
keepLogin: false,
|
||||||
}
|
};
|
||||||
session.setToken(data);
|
session.setToken(data);
|
||||||
|
|
||||||
const token = session.getToken();
|
const token = session.getToken();
|
||||||
|
@ -38,23 +38,22 @@ describe('session', () => {
|
||||||
nickname: 'Black Panther',
|
nickname: 'Black Panther',
|
||||||
lang: 'en',
|
lang: 'en',
|
||||||
darkMode: false,
|
darkMode: false,
|
||||||
}
|
};
|
||||||
const expectedUser = {
|
const expectedUser = {
|
||||||
id: 0,
|
id: 0,
|
||||||
name: '',
|
name: '',
|
||||||
nickname: '',
|
nickname: '',
|
||||||
lang: '',
|
lang: '',
|
||||||
darkMode: null,
|
darkMode: null,
|
||||||
}
|
};
|
||||||
let user = state.getUser();
|
let user = state.getUser();
|
||||||
|
|
||||||
localStorage.setItem('token', 'tokenToBeGone');
|
localStorage.setItem('token', 'tokenToBeGone');
|
||||||
state.setUser(previousUser)
|
state.setUser(previousUser);
|
||||||
|
|
||||||
expect(localStorage.getItem('token')).toEqual('tokenToBeGone');
|
expect(localStorage.getItem('token')).toEqual('tokenToBeGone');
|
||||||
expect(user.value).toEqual(previousUser);
|
expect(user.value).toEqual(previousUser);
|
||||||
|
|
||||||
|
|
||||||
session.destroy();
|
session.destroy();
|
||||||
|
|
||||||
user = state.getUser();
|
user = state.getUser();
|
||||||
|
@ -71,29 +70,29 @@ describe('session', () => {
|
||||||
lang: 'en',
|
lang: 'en',
|
||||||
userConfig: {
|
userConfig: {
|
||||||
darkMode: false,
|
darkMode: false,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
const rolesData = [
|
const rolesData = [
|
||||||
{
|
{
|
||||||
role: {
|
role: {
|
||||||
name: 'salesPerson'
|
name: 'salesPerson',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: {
|
role: {
|
||||||
name: 'admin'
|
name: 'admin',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
it('should fetch the user roles and then set token in the sessionStorage', async () => {
|
it('should fetch the user roles and then set token in the sessionStorage', async () => {
|
||||||
const expectedRoles = ['salesPerson', 'admin']
|
const expectedRoles = ['salesPerson', 'admin'];
|
||||||
jest.spyOn(axios, 'get').mockResolvedValue({
|
vi.spyOn(axios, 'get').mockResolvedValue({
|
||||||
data: { roles: rolesData, user: expectedUser }
|
data: { roles: rolesData, user: expectedUser },
|
||||||
});
|
});
|
||||||
|
|
||||||
const expectedToken = 'mySessionToken'
|
const expectedToken = 'mySessionToken';
|
||||||
const keepLogin = false
|
const keepLogin = false;
|
||||||
|
|
||||||
await session.login(expectedToken, keepLogin);
|
await session.login(expectedToken, keepLogin);
|
||||||
|
|
||||||
|
@ -105,17 +104,17 @@ describe('session', () => {
|
||||||
expect(localToken).toBeNull();
|
expect(localToken).toBeNull();
|
||||||
expect(sessionToken).toEqual(expectedToken);
|
expect(sessionToken).toEqual(expectedToken);
|
||||||
|
|
||||||
session.destroy() // this clears token and user for any other test
|
session.destroy(); // this clears token and user for any other test
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch the user roles and then set token in the localStorage', async () => {
|
it('should fetch the user roles and then set token in the localStorage', async () => {
|
||||||
const expectedRoles = ['salesPerson', 'admin']
|
const expectedRoles = ['salesPerson', 'admin'];
|
||||||
jest.spyOn(axios, 'get').mockResolvedValue({
|
vi.spyOn(axios, 'get').mockResolvedValue({
|
||||||
data: { roles: rolesData, user: expectedUser }
|
data: { roles: rolesData, user: expectedUser },
|
||||||
});
|
});
|
||||||
|
|
||||||
const expectedToken = 'myLocalToken'
|
const expectedToken = 'myLocalToken';
|
||||||
const keepLogin = true
|
const keepLogin = true;
|
||||||
|
|
||||||
await session.login(expectedToken, keepLogin);
|
await session.login(expectedToken, keepLogin);
|
||||||
|
|
||||||
|
@ -127,7 +126,7 @@ describe('session', () => {
|
||||||
expect(localToken).toEqual(expectedToken);
|
expect(localToken).toEqual(expectedToken);
|
||||||
expect(sessionToken).toBeNull();
|
expect(sessionToken).toBeNull();
|
||||||
|
|
||||||
session.destroy() // this clears token and user for any other test
|
session.destroy(); // this clears token and user for any other test
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
|
||||||
|
import { createWrapper, axios } from 'app/test/vitest/helper';
|
||||||
|
import ClaimDescriptorMenu from 'pages/Claim/Card/ClaimDescriptorMenu.vue';
|
||||||
|
|
||||||
|
describe('ClaimDescriptorMenu', () => {
|
||||||
|
let vm;
|
||||||
|
beforeAll(() => {
|
||||||
|
vm = createWrapper(ClaimDescriptorMenu, {
|
||||||
|
propsData: {
|
||||||
|
claim: {
|
||||||
|
id: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}).vm;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('deleteClaim()', () => {
|
||||||
|
it('should delete the claim', async () => {
|
||||||
|
vi.spyOn(axios, 'delete').mockResolvedValue({ data: true });
|
||||||
|
vi.spyOn(vm.quasar, 'notify');
|
||||||
|
|
||||||
|
await vm.deleteClaim();
|
||||||
|
|
||||||
|
expect(vm.quasar.notify).toHaveBeenCalledWith(expect.objectContaining({ type: 'positive' }));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,15 +1,6 @@
|
||||||
import { jest, describe, expect, it, beforeAll } from '@jest/globals';
|
import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
|
||||||
import { createWrapper, axios } from 'app/tests/jest/jestHelpers';
|
import { createWrapper, axios } from 'app/test/vitest/helper';
|
||||||
import Login from '../LoginMain.vue';
|
import Login from 'pages/Login/LoginMain.vue';
|
||||||
|
|
||||||
const mockPush = jest.fn();
|
|
||||||
|
|
||||||
jest.mock('vue-router', () => ({
|
|
||||||
useRouter: () => ({
|
|
||||||
push: mockPush,
|
|
||||||
currentRoute: { value: 'myCurrentRoute' }
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('Login', () => {
|
describe('Login', () => {
|
||||||
let vm;
|
let vm;
|
||||||
|
@ -18,7 +9,7 @@ describe('Login', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should successfully set the token into session', async () => {
|
it('should successfully set the token into session', async () => {
|
||||||
|
@ -29,26 +20,24 @@ describe('Login', () => {
|
||||||
lang: 'en',
|
lang: 'en',
|
||||||
userConfig: {
|
userConfig: {
|
||||||
darkMode: false,
|
darkMode: false,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
jest.spyOn(axios, 'post').mockResolvedValue({ data: { token: 'token' } });
|
vi.spyOn(axios, 'post').mockResolvedValue({ data: { token: 'token' } });
|
||||||
jest.spyOn(axios, 'get').mockResolvedValue({ data: { roles: [], user: expectedUser } });
|
vi.spyOn(axios, 'get').mockResolvedValue({ data: { roles: [], user: expectedUser } });
|
||||||
jest.spyOn(vm.quasar, 'notify');
|
vi.spyOn(vm.quasar, 'notify');
|
||||||
|
|
||||||
expect(vm.session.getToken()).toEqual('');
|
expect(vm.session.getToken()).toEqual('');
|
||||||
|
|
||||||
await vm.onSubmit();
|
await vm.onSubmit();
|
||||||
|
|
||||||
expect(vm.session.getToken()).toEqual('token');
|
expect(vm.session.getToken()).toEqual('token');
|
||||||
expect(vm.quasar.notify).toHaveBeenCalledWith(expect.objectContaining(
|
expect(vm.quasar.notify).toHaveBeenCalledWith(expect.objectContaining({ type: 'positive' }));
|
||||||
{ 'type': 'positive' }
|
|
||||||
));
|
|
||||||
vm.session.destroy();
|
vm.session.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not set the token into session if any error occurred', async () => {
|
it('should not set the token into session if any error occurred', async () => {
|
||||||
jest.spyOn(axios, 'post').mockReturnValue({ data: null });
|
vi.spyOn(axios, 'post').mockReturnValue({ data: null });
|
||||||
jest.spyOn(vm.quasar, 'notify');
|
vi.spyOn(vm.quasar, 'notify');
|
||||||
|
|
||||||
await vm.onSubmit();
|
await vm.onSubmit();
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
|
||||||
|
import { createWrapper, axios } from 'app/test/vitest/helper';
|
||||||
|
import TicketBoxing from 'pages/Ticket/Card/TicketBoxing.vue';
|
||||||
|
|
||||||
|
// #4836 - Investigate how to test q-drawer outside
|
||||||
|
// q-layout or how to teleport q-drawer inside
|
||||||
|
describe.skip('TicketBoxing', () => {
|
||||||
|
let vm;
|
||||||
|
beforeAll(() => {
|
||||||
|
vm = createWrapper(TicketBoxing).vm;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getVideoList()', () => {
|
||||||
|
it('should when response videoList use to list', async () => {
|
||||||
|
const expeditionId = 1;
|
||||||
|
const timed = {
|
||||||
|
min: 1,
|
||||||
|
max: 2,
|
||||||
|
};
|
||||||
|
const videoList = ['2022-01-01T01-01-00.mp4', '2022-02-02T02-02-00.mp4', '2022-03-03T03-03-00.mp4'];
|
||||||
|
|
||||||
|
vi.spyOn(axios, 'get').mockResolvedValue({ data: videoList });
|
||||||
|
vi.spyOn(vm.quasar, 'notify');
|
||||||
|
|
||||||
|
await vm.getVideoList(expeditionId, timed);
|
||||||
|
|
||||||
|
expect(vm.videoList.length).toEqual(videoList.length);
|
||||||
|
expect(vm.slide).toEqual(videoList.reverse()[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should if not have video show notify', async () => {
|
||||||
|
const expeditionId = 1;
|
||||||
|
const timed = {
|
||||||
|
min: 1,
|
||||||
|
max: 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.spyOn(axios, 'get').mockResolvedValue({ data: [] });
|
||||||
|
vi.spyOn(vm.quasar, 'notify');
|
||||||
|
|
||||||
|
await vm.getVideoList(expeditionId, timed);
|
||||||
|
|
||||||
|
expect(vm.quasar.notify).toHaveBeenCalledWith(expect.objectContaining({ type: 'negative' }));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,52 @@
|
||||||
|
import { installQuasar } from '@quasar/quasar-app-extension-testing-unit-vitest';
|
||||||
|
import { mount, flushPromises } from '@vue/test-utils';
|
||||||
|
import { createTestingPinia } from '@pinia/testing';
|
||||||
|
import { vi } from 'vitest';
|
||||||
|
import { i18n } from 'src/boot/i18n';
|
||||||
|
import { Notify, Dialog } from 'quasar';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
installQuasar({
|
||||||
|
plugins: {
|
||||||
|
Notify,
|
||||||
|
Dialog,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockPush = vi.fn();
|
||||||
|
vi.mock('vue-router', () => ({
|
||||||
|
useRouter: () => ({
|
||||||
|
push: mockPush,
|
||||||
|
currentRoute: { value: 'myCurrentRoute' },
|
||||||
|
}),
|
||||||
|
useRoute: () => ({
|
||||||
|
matched: [],
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export function createWrapper(component, options) {
|
||||||
|
const pinia = createTestingPinia({ createSpy: vi.fn, stubActions: false });
|
||||||
|
|
||||||
|
const defaultOptions = {
|
||||||
|
global: {
|
||||||
|
plugins: [i18n, pinia],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const mountOptions = Object.assign({}, defaultOptions);
|
||||||
|
|
||||||
|
if (options instanceof Object) {
|
||||||
|
Object.assign(mountOptions, options);
|
||||||
|
|
||||||
|
if (options.global) {
|
||||||
|
mountOptions.global.plugins = defaultOptions.global.plugins;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const wrapper = mount(component, mountOptions);
|
||||||
|
const vm = wrapper.vm;
|
||||||
|
|
||||||
|
return { vm, wrapper };
|
||||||
|
}
|
||||||
|
|
||||||
|
export { axios, flushPromises };
|
|
@ -0,0 +1 @@
|
||||||
|
// This file will be run before each test file
|
|
@ -1,31 +0,0 @@
|
||||||
/// <reference types="cypress" />
|
|
||||||
/* eslint-env node */
|
|
||||||
// ***********************************************************
|
|
||||||
// This example plugins/index.js can be used to load plugins
|
|
||||||
//
|
|
||||||
// You can change the location of this file or turn off loading
|
|
||||||
// the plugins file with the 'pluginsFile' configuration option.
|
|
||||||
//
|
|
||||||
// You can read more here:
|
|
||||||
// https://on.cypress.io/plugins-guide
|
|
||||||
// ***********************************************************
|
|
||||||
|
|
||||||
// This function is called when a project is opened or re-opened (e.g. due to
|
|
||||||
// the project's config changing)
|
|
||||||
|
|
||||||
// cypress/plugins/index.js
|
|
||||||
|
|
||||||
// const {injectDevServer} = require('@quasar/quasar-app-extension-testing-e2e-cypress/cct-dev-server');
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * @type {Cypress.PluginConfig}
|
|
||||||
// */
|
|
||||||
module.exports = async (on, config) => {
|
|
||||||
// // Enable component testing, you can safely remove this
|
|
||||||
// // if you don't plan to use Cypress for unit tests
|
|
||||||
// if (config.testingType === 'component') {
|
|
||||||
// await injectDevServer(on, config);
|
|
||||||
// }
|
|
||||||
|
|
||||||
return config;
|
|
||||||
};
|
|
|
@ -1,10 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
extends: [
|
|
||||||
// Removes 'no-undef' lint errors for Jest global functions (`describe`, `it`, etc),
|
|
||||||
// add Jest-specific lint rules and Jest plugin
|
|
||||||
// See https://github.com/jest-community/eslint-plugin-jest#recommended
|
|
||||||
'plugin:jest/recommended',
|
|
||||||
// Uncomment following line to apply style rules
|
|
||||||
// 'plugin:jest/style',
|
|
||||||
],
|
|
||||||
};
|
|
|
@ -1 +0,0 @@
|
||||||
coverage/*
|
|
|
@ -1,32 +0,0 @@
|
||||||
import { mount, flushPromises } from '@vue/test-utils';
|
|
||||||
import { installQuasarPlugin } from '@quasar/quasar-app-extension-testing-unit-jest';
|
|
||||||
import { i18n } from 'src/boot/i18n';
|
|
||||||
import { Notify, Dialog } from 'quasar';
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
installQuasarPlugin({
|
|
||||||
plugins: {
|
|
||||||
Notify,
|
|
||||||
Dialog,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export function createWrapper(component, options) {
|
|
||||||
const mountOptions = {};
|
|
||||||
|
|
||||||
if (options instanceof Object) Object.assign(mountOptions, options);
|
|
||||||
|
|
||||||
if (mountOptions.global && mountOptions.global.plugins) {
|
|
||||||
mountOptions.global.plugins.push(i18n);
|
|
||||||
} else {
|
|
||||||
if (!mountOptions.global) mountOptions.global = {};
|
|
||||||
mountOptions.global.plugins = [i18n];
|
|
||||||
}
|
|
||||||
|
|
||||||
const wrapper = mount(component, mountOptions);
|
|
||||||
const vm = wrapper.vm;
|
|
||||||
|
|
||||||
return { vm, wrapper };
|
|
||||||
}
|
|
||||||
|
|
||||||
export { axios, flushPromises };
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
import vue from '@vitejs/plugin-vue';
|
||||||
|
import { quasar, transformAssetUrls } from '@quasar/vite-plugin';
|
||||||
|
import jsconfigPaths from 'vite-jsconfig-paths';
|
||||||
|
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
environment: 'happy-dom',
|
||||||
|
setupFiles: 'test/vitest/setup-file.js',
|
||||||
|
include: [
|
||||||
|
// Matches vitest tests in any subfolder of 'src' or into 'test/vitest/__tests__'
|
||||||
|
// Matches all files with extension 'js', 'jsx', 'ts' and 'tsx'
|
||||||
|
'test/vitest/__tests__/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
vue({
|
||||||
|
template: { transformAssetUrls },
|
||||||
|
}),
|
||||||
|
quasar({
|
||||||
|
sassVariables: 'src/quasar-variables.scss',
|
||||||
|
}),
|
||||||
|
VueI18nPlugin({
|
||||||
|
include: path.resolve(__dirname, 'src/i18n/**'),
|
||||||
|
}),
|
||||||
|
jsconfigPaths(),
|
||||||
|
],
|
||||||
|
});
|
Loading…
Reference in New Issue