diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index b1b87779f..000000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,18 +0,0 @@
-module.exports = {
- root: true,
- env: {
- node: true,
- },
- parserOptions: {
- parser: '@babel/eslint-parser',
- },
- extends: [
- 'eslint:recommended',
- 'plugin:vue/essential',
- 'plugin:prettier/recommended',
- ],
- rules: {
- 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
- 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
- },
-};
diff --git a/.github/workflows/_meta-build.yaml b/.github/workflows/_meta-build.yaml
index bb9a7b844..d088adc90 100644
--- a/.github/workflows/_meta-build.yaml
+++ b/.github/workflows/_meta-build.yaml
@@ -35,13 +35,27 @@ jobs:
node-version: '20'
cache: 'npm'
- - name: Run Npm Build
+ - name: Install Dependencies
env:
CI: true
run: |-
npm ci
+
+ - name: Run Npm Build
+ env:
+ CI: true
+ run: |-
npm run build --if-present
+ - name: Run Cypress Tests
+ uses: cypress-io/github-action@v6
+ env:
+ CI: true
+ timeout-minutes: 15
+ with:
+ component: true
+ command: npm run cy:run:coverage --if-present
+
- name: Upload Artifacts
uses: actions/upload-artifact@v4.6.2
with:
diff --git a/.gitignore b/.gitignore
index 83dde679d..9e81ac204 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,6 @@
.DS_Store
node_modules
/dist
-/coverage
/tests/e2e/reports/
selenium-debug.log
@@ -29,3 +28,11 @@ src/version.json
# IntelliJ
.idea/*
!.idea/icon.svg
+
+# Test files
+/coverage
+/cypress/screenshots
+/cypress/videos
+/cypress/downloads
+/.nyc_output
+.output.txt
diff --git a/.nycrc b/.nycrc
new file mode 100644
index 000000000..09133f5c7
--- /dev/null
+++ b/.nycrc
@@ -0,0 +1,24 @@
+{
+ "all": true,
+ "include": [
+ "src/**/*.js",
+ "src/**/*.vue"
+ ],
+ "exclude": [
+ "**/*.spec.js",
+ "**/*.cy.js",
+ "cypress/**/*.*",
+ "node_modules/**/*.*"
+ ],
+ "reporter": [
+ "lcov",
+ "text",
+ "html"
+ ],
+ "report-dir": "coverage",
+ "extension": [
+ ".js",
+ ".vue"
+ ],
+ "check-coverage": false
+}
diff --git a/.postcssrc.js b/.postcssrc.js
deleted file mode 100644
index a47ef4f95..000000000
--- a/.postcssrc.js
+++ /dev/null
@@ -1,5 +0,0 @@
-module.exports = {
- plugins: {
- autoprefixer: {},
- },
-};
diff --git a/babel.config.js b/babel.config.js
index bcdde9806..d08fdd72b 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -1,12 +1,8 @@
module.exports = {
- presets: [
- ['@vue/babel-preset-jsx'],
- [
- '@babel/preset-env',
- {
- useBuiltIns: 'entry',
- corejs: '3.33',
- },
- ],
- ],
+ presets: [['@vue/babel-preset-jsx']],
+ env: {
+ test: {
+ plugins: process.env.VITE_COVERAGE === 'true' ? ['istanbul'] : [],
+ },
+ },
};
diff --git a/cypress.config.js b/cypress.config.js
new file mode 100644
index 000000000..102af2d3f
--- /dev/null
+++ b/cypress.config.js
@@ -0,0 +1,34 @@
+const { defineConfig } = require('cypress');
+const path = require('path');
+
+module.exports = defineConfig({
+ video: true,
+ videoCompression: 32,
+ trashAssetsBeforeRuns: false,
+ component: {
+ devServer: {
+ framework: 'vue2',
+ bundler: 'vite',
+ // TODO this is just a workaround, making the tests _more_ deterministic, but they are still non-deterministic
+ warmup: {
+ clientFiles: ['cypress/support/component.js', 'src/**/*.cy.js'],
+ },
+ viteConfig: (viteConfig) => {
+ let configFile;
+ if (process.env.VITE_COVERAGE === 'true') {
+ configFile = path.resolve(__dirname, 'vite.coverage.config.js');
+ } else {
+ configFile = path.resolve(__dirname, 'vite.config.js');
+ }
+
+ return { configFile };
+ },
+ },
+ setupNodeEvents(on, config) {
+ if (process.env.VITE_COVERAGE === 'true') {
+ require('@cypress/code-coverage/task')(on, config);
+ }
+ return config;
+ },
+ },
+});
diff --git a/cypress/support/component-index.html b/cypress/support/component-index.html
new file mode 100644
index 000000000..5c221daf2
--- /dev/null
+++ b/cypress/support/component-index.html
@@ -0,0 +1,10 @@
+
+
+
+
+ Cypress Component Test
+
+
+
+
+
diff --git a/cypress/support/component.js b/cypress/support/component.js
new file mode 100644
index 000000000..5ed2374f4
--- /dev/null
+++ b/cypress/support/component.js
@@ -0,0 +1,99 @@
+import '@cypress/code-coverage/support';
+import { mount } from '@cypress/vue2';
+import Vue from 'vue';
+
+import api from '@/shared/api.json';
+import oidc from '@/shared/oidc.json';
+import version from '@/version';
+import '@/validation';
+import { installBootstrap } from '@/plugins/bootstrap';
+import installPermissionDirective from '@/directives/VuePermission';
+import 'bootstrap/dist/css/bootstrap.min.css';
+import '@/assets/scss/style.scss';
+
+Vue.prototype.$api = api;
+Vue.prototype.$oidc = oidc;
+Vue.prototype.$version = version;
+
+Vue.prototype.$dtrack = Vue.prototype.dtrack = {
+ application: 'Dependency-Track',
+ version: '4.8.0',
+ uuid: '12345-67890-abcdef',
+ timestamp: Date.now(),
+ framework: {
+ name: 'Alpine',
+ version: '3.16',
+ },
+ database: {
+ productName: 'PostgreSQL',
+ productVersion: '14.5',
+ },
+ systemUuid: '98765-43210-fedcba',
+ systemInitialDate: new Date().toISOString(),
+};
+
+installBootstrap(Vue);
+
+/**
+ * Enhanced mount command with common mocks
+ *
+ * @param {Object} component - The Vue component to mount
+ * @param {Object} options - Mount options
+ * @param {Object} options.mocks - Custom mocks to override defaults
+ */
+Cypress.Commands.add('mount', (component, options = {}) => {
+ const defaultPrototypeMocks = {
+ $i18n: Vue.observable({
+ locale: 'en',
+ availableLocales: ['en', 'es', 'fr', 'de', 'zh', 'ja', 'hi'],
+ t: (key) => key,
+ }),
+ $t: (key) => key,
+ $router: {
+ afterEach: cy.stub(),
+ },
+ };
+
+ const prototypeMocks = {
+ ...defaultPrototypeMocks,
+ ...(options.prototypeMocks || {}),
+ };
+
+ const localVue = Vue.extend();
+ // TODO installBootstrapPageTitlePlugin(localVue, prototypeMocks.$router);
+ installPermissionDirective(localVue);
+ Object.keys(prototypeMocks).forEach((key) => {
+ Object.defineProperty(localVue.prototype, key, {
+ value: prototypeMocks[key],
+ writable: true,
+ configurable: true,
+ enumerable: true,
+ });
+ });
+
+ return mount(component, {
+ ...options,
+ localVue,
+ }).then(({ wrapper }) => {
+ return cy.wrap(wrapper).as('vue');
+ });
+});
+
+Cypress.Commands.add('setToken', (permissions = []) => {
+ const tokenPayload = {
+ permissions: permissions.join(','),
+ };
+
+ // Encode the payload to Base64URL
+ const base64Url = Cypress.Buffer.from(JSON.stringify(tokenPayload))
+ .toString('base64')
+ .replace(/\+/g, '-')
+ .replace(/\//g, '_')
+ .replace(/=+$/, '');
+
+ const fakeToken = `fake-header.${base64Url}.fake-signature`;
+
+ cy.window().then((win) => {
+ win.sessionStorage.setItem('token', fakeToken);
+ });
+});
diff --git a/cypress/support/utils.js b/cypress/support/utils.js
new file mode 100644
index 000000000..52e176019
--- /dev/null
+++ b/cypress/support/utils.js
@@ -0,0 +1,31 @@
+export function genAxiosResponse(responses) {
+ return (url) => {
+ if (responses[url] === undefined) {
+ console.warn('axios stub for URL not available: ' + url);
+ return Promise.resolve({
+ data: null,
+ statusCode: 500,
+ });
+ }
+
+ console.log('axios stub for URL: ' + url);
+ return Promise.resolve({
+ data: responses[url],
+ });
+ };
+}
+
+export function shouldShowModal(id) {
+ cy.get('@vue').then((wrapper) => {
+ const $root = wrapper.vm.$root;
+ const bvModal = $root.$bvModal;
+ if (bvModal) {
+ bvModal.show(id);
+ } else {
+ $root.$emit('bv::show::modal', id);
+ }
+ });
+
+ cy.get(`#${id}`).should('exist');
+ cy.get(`#${id}`).should('be.visible');
+}
diff --git a/eslint.config.js b/eslint.config.js
new file mode 100644
index 000000000..d08f49caa
--- /dev/null
+++ b/eslint.config.js
@@ -0,0 +1,42 @@
+import pluginVue from 'eslint-plugin-vue';
+import recommendedConfig from 'eslint-plugin-prettier/recommended';
+
+export default [
+ {
+ name: 'app/files-to-lint',
+ files: ['src/**/*.{js,jsx,vue,md,yaml}'],
+ },
+
+ {
+ languageOptions: {
+ parserOptions: {
+ ecmaVersion: 'latest',
+ sourceType: 'module',
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+ },
+
+ recommendedConfig,
+ ...pluginVue.configs['flat/vue2-essential'],
+ {
+ rules: {
+ 'no-var': 'error',
+ 'prefer-const': 'warn',
+ 'vue/component-tags-order': 'warn',
+ 'vue/order-in-components': 'warn',
+ 'vue/attribute-hyphenation': 'warn',
+ 'vue/one-component-per-file': 'warn',
+ 'vue/v-bind-style': 'warn',
+ 'vue/v-on-style': 'warn',
+ 'vue/v-slot-style': 'warn',
+ 'vue/no-unused-components': 'warn',
+ 'vue/no-side-effects-in-computed-properties': 'off', // FIXME enable this later (P1)
+ 'vue/no-mutating-props': 'off', // FIXME enable this later (P1)
+ 'vue/no-undef-components': 'warn',
+ 'vue/multi-word-component-names': 'off', // TODO enable this later (P3)
+ },
+ },
+];
diff --git a/public/index.html b/index.html
similarity index 96%
rename from public/index.html
rename to index.html
index 6a576e19c..ab14067cd 100644
--- a/public/index.html
+++ b/index.html
@@ -15,6 +15,7 @@
>
+
diff --git a/src/assets/scss/style.scss b/src/assets/scss/style.scss
index f1c68e7eb..7949b4512 100644
--- a/src/assets/scss/style.scss
+++ b/src/assets/scss/style.scss
@@ -2,9 +2,9 @@
@import "variables";
// Import styles
-@import "~@coreui/coreui/scss/coreui";
+@import "@coreui/coreui/scss/coreui";
-@import '~vue-easy-pie-chart/dist/vue-easy-pie-chart.css';
+@import 'vue-easy-pie-chart/dist/vue-easy-pie-chart.css';
@import "code";
@@ -14,4 +14,4 @@
// ie fixes
@import "ie-fix";
-@import "~vue-multiselect/dist/vue-multiselect.min.css";
+@import "vue-multiselect/dist/vue-multiselect.min.css";
diff --git a/src/containers/DefaultContainer.cy.js b/src/containers/DefaultContainer.cy.js
new file mode 100644
index 000000000..62b5dd5b1
--- /dev/null
+++ b/src/containers/DefaultContainer.cy.js
@@ -0,0 +1,25 @@
+import DefaultContainer from './DefaultContainer.vue';
+
+describe('DefaultContainer', () => {
+ it('mounts successfully', () => {
+ cy.setToken();
+
+ cy.mount(DefaultContainer, {
+ stubs: {
+ RouterView: true,
+ },
+ prototypeMocks: {
+ $route: {
+ name: 'Home',
+ meta: {
+ sectionName: 'Test Section',
+ i18n: 'message.test_section',
+ sectionPath: '/test-section',
+ },
+ },
+ },
+ });
+
+ cy.get('.app').should('exist');
+ });
+});
diff --git a/src/containers/DefaultContainer.vue b/src/containers/DefaultContainer.vue
index 98b9b369b..44a85975c 100644
--- a/src/containers/DefaultContainer.vue
+++ b/src/containers/DefaultContainer.vue
@@ -1,13 +1,13 @@
-
+
-
+
-
+
@@ -16,7 +16,7 @@
-
+
@@ -24,32 +24,28 @@
diff --git a/src/containers/DefaultFooter.cy.js b/src/containers/DefaultFooter.cy.js
new file mode 100644
index 000000000..1c59acda5
--- /dev/null
+++ b/src/containers/DefaultFooter.cy.js
@@ -0,0 +1,13 @@
+import DefaultFooter from './DefaultFooter.vue';
+
+describe('DefaultFooter', () => {
+ it('mounts successfully', () => {
+ cy.mount(DefaultFooter, {
+ prototypeMocks: {
+ $currentUser: {
+ username: 'admin',
+ },
+ },
+ });
+ });
+});
diff --git a/src/containers/DefaultFooter.vue b/src/containers/DefaultFooter.vue
index d596dd8ef..a855f5ded 100644
--- a/src/containers/DefaultFooter.vue
+++ b/src/containers/DefaultFooter.vue
@@ -12,17 +12,16 @@
diff --git a/src/views/administration/configuration/Email.cy.js b/src/views/administration/configuration/Email.cy.js
new file mode 100644
index 000000000..16b95cb87
--- /dev/null
+++ b/src/views/administration/configuration/Email.cy.js
@@ -0,0 +1,34 @@
+import Email from './Email.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('Email', () => {
+ it('mounts successfully', () => {
+ cy.mount(Email, {
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/configProperty/': [
+ {
+ groupName: 'artifact',
+ propertyName: 'cyclonedx.enabled',
+ propertyValue: 'false',
+ },
+ {
+ groupName: 'artifact',
+ propertyName: 'bom.validation.mode',
+ propertyValue: 'ENABLED',
+ },
+ {
+ groupName: 'artifact',
+ propertyName: 'bom.validation.tags.inclusive',
+ propertyValue: '[]',
+ },
+ ],
+ }),
+ },
+ },
+ });
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/configuration/Email.vue b/src/views/administration/configuration/Email.vue
index 58d06fd1a..87870295d 100644
--- a/src/views/administration/configuration/Email.vue
+++ b/src/views/administration/configuration/Email.vue
@@ -98,20 +98,25 @@
diff --git a/src/views/administration/configuration/EmailTestConfigurationModal.cy.js b/src/views/administration/configuration/EmailTestConfigurationModal.cy.js
new file mode 100644
index 000000000..36cc6e0bf
--- /dev/null
+++ b/src/views/administration/configuration/EmailTestConfigurationModal.cy.js
@@ -0,0 +1,16 @@
+import { shouldShowModal } from '../../../../cypress/support/utils';
+
+import EmailTestConfigurationModal from './EmailTestConfigurationModal.vue';
+
+describe('EmailTestConfigurationModal', () => {
+ it('mounts successfully', () => {
+ cy.mount(EmailTestConfigurationModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ });
+
+ shouldShowModal('emailTestConfigurationModal');
+ });
+});
diff --git a/src/views/administration/configuration/EmailTestConfigurationModal.vue b/src/views/administration/configuration/EmailTestConfigurationModal.vue
index 605e5df3f..986699856 100644
--- a/src/views/administration/configuration/EmailTestConfigurationModal.vue
+++ b/src/views/administration/configuration/EmailTestConfigurationModal.vue
@@ -17,7 +17,7 @@
tooltip="Enter an email address you control to test your send configuration."
lazy="true"
/>
-
+
{{
$t('message.close')
}}
@@ -32,13 +32,14 @@
diff --git a/src/views/administration/configuration/General.cy.js b/src/views/administration/configuration/General.cy.js
new file mode 100644
index 000000000..af53b4abd
--- /dev/null
+++ b/src/views/administration/configuration/General.cy.js
@@ -0,0 +1,18 @@
+import General from './General.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('General', () => {
+ it('mounts successfully', () => {
+ cy.mount(General, {
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/configProperty/': [],
+ }),
+ },
+ },
+ });
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/configuration/General.vue b/src/views/administration/configuration/General.vue
index 8f75934e0..6b6aed731 100644
--- a/src/views/administration/configuration/General.vue
+++ b/src/views/administration/configuration/General.vue
@@ -71,23 +71,39 @@
diff --git a/src/views/administration/configuration/InternalComponents.cy.js b/src/views/administration/configuration/InternalComponents.cy.js
new file mode 100644
index 000000000..98a37218b
--- /dev/null
+++ b/src/views/administration/configuration/InternalComponents.cy.js
@@ -0,0 +1,18 @@
+import InternalComponents from './InternalComponents.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('InternalComponents', () => {
+ it('mounts successfully', () => {
+ cy.mount(InternalComponents, {
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/configProperty/': [],
+ }),
+ },
+ },
+ });
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/configuration/InternalComponents.vue b/src/views/administration/configuration/InternalComponents.vue
index 74832bc0b..34381ca80 100644
--- a/src/views/administration/configuration/InternalComponents.vue
+++ b/src/views/administration/configuration/InternalComponents.vue
@@ -36,25 +36,46 @@
diff --git a/src/views/administration/configuration/JiraConfig.cy.js b/src/views/administration/configuration/JiraConfig.cy.js
new file mode 100644
index 000000000..72a30bb56
--- /dev/null
+++ b/src/views/administration/configuration/JiraConfig.cy.js
@@ -0,0 +1,18 @@
+import JiraConfig from './JiraConfig.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('JiraConfig', () => {
+ it('mounts successfully', () => {
+ cy.mount(JiraConfig, {
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/configProperty/': [],
+ }),
+ },
+ },
+ });
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/configuration/JiraConfig.vue b/src/views/administration/configuration/JiraConfig.vue
index 95cbaecfb..84ff47775 100644
--- a/src/views/administration/configuration/JiraConfig.vue
+++ b/src/views/administration/configuration/JiraConfig.vue
@@ -59,17 +59,23 @@
diff --git a/src/views/administration/configuration/Search.cy.js b/src/views/administration/configuration/Search.cy.js
new file mode 100644
index 000000000..a1304329a
--- /dev/null
+++ b/src/views/administration/configuration/Search.cy.js
@@ -0,0 +1,18 @@
+import Search from './Search.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('Search', () => {
+ it('mounts successfully', () => {
+ cy.mount(Search, {
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/configProperty/': [],
+ }),
+ },
+ },
+ });
+
+ cy.get('div').should('be.visible');
+ });
+});
diff --git a/src/views/administration/configuration/Search.vue b/src/views/administration/configuration/Search.vue
index 810b7a4d9..3ee23dd08 100644
--- a/src/views/administration/configuration/Search.vue
+++ b/src/views/administration/configuration/Search.vue
@@ -118,18 +118,23 @@
diff --git a/src/views/administration/configuration/Telemetry.cy.js b/src/views/administration/configuration/Telemetry.cy.js
new file mode 100644
index 000000000..af27944f5
--- /dev/null
+++ b/src/views/administration/configuration/Telemetry.cy.js
@@ -0,0 +1,18 @@
+import Telemetry from './Telemetry.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('Telemetry', () => {
+ it('mounts successfully', () => {
+ cy.mount(Telemetry, {
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/configProperty/': [],
+ }),
+ },
+ },
+ });
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/configuration/Telemetry.vue b/src/views/administration/configuration/Telemetry.vue
index b1e09703f..ccce006cf 100644
--- a/src/views/administration/configuration/Telemetry.vue
+++ b/src/views/administration/configuration/Telemetry.vue
@@ -44,11 +44,38 @@
diff --git a/src/views/administration/configuration/WelcomeMessage.cy.js b/src/views/administration/configuration/WelcomeMessage.cy.js
new file mode 100644
index 000000000..a54fe0193
--- /dev/null
+++ b/src/views/administration/configuration/WelcomeMessage.cy.js
@@ -0,0 +1,18 @@
+import WelcomeMessage from './WelcomeMessage.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('WelcomeMessage', () => {
+ it('mounts successfully', () => {
+ cy.mount(WelcomeMessage, {
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/configProperty/': [],
+ }),
+ },
+ },
+ });
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/configuration/WelcomeMessage.vue b/src/views/administration/configuration/WelcomeMessage.vue
index ba732c2c7..4ed17ad32 100644
--- a/src/views/administration/configuration/WelcomeMessage.vue
+++ b/src/views/administration/configuration/WelcomeMessage.vue
@@ -54,36 +54,53 @@
diff --git a/src/views/administration/integrations/FortifySsc.cy.js b/src/views/administration/integrations/FortifySsc.cy.js
new file mode 100644
index 000000000..8c0e7c74e
--- /dev/null
+++ b/src/views/administration/integrations/FortifySsc.cy.js
@@ -0,0 +1,18 @@
+import FortifySsc from './FortifySsc.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('FortifySsc', () => {
+ it('mounts successfully', () => {
+ cy.mount(FortifySsc, {
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/configProperty/': [],
+ }),
+ },
+ },
+ });
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/integrations/FortifySsc.vue b/src/views/administration/integrations/FortifySsc.vue
index 9ef3c058b..c3901bf50 100644
--- a/src/views/administration/integrations/FortifySsc.vue
+++ b/src/views/administration/integrations/FortifySsc.vue
@@ -49,18 +49,23 @@
diff --git a/src/views/administration/integrations/KennaSecurity.cy.js b/src/views/administration/integrations/KennaSecurity.cy.js
new file mode 100644
index 000000000..2bfc8b62c
--- /dev/null
+++ b/src/views/administration/integrations/KennaSecurity.cy.js
@@ -0,0 +1,18 @@
+import KennaSecurity from './KennaSecurity.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('KennaSecurity', () => {
+ it('mounts successfully', () => {
+ cy.mount(KennaSecurity, {
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/configProperty/': [],
+ }),
+ },
+ },
+ });
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/integrations/KennaSecurity.vue b/src/views/administration/integrations/KennaSecurity.vue
index 4c1618a62..e8b858ced 100644
--- a/src/views/administration/integrations/KennaSecurity.vue
+++ b/src/views/administration/integrations/KennaSecurity.vue
@@ -49,18 +49,23 @@
diff --git a/src/views/administration/mixins/configPropertyMixin.js b/src/views/administration/mixins/configPropertyMixin.js
index 350cbb162..44a9b5175 100644
--- a/src/views/administration/mixins/configPropertyMixin.js
+++ b/src/views/administration/mixins/configPropertyMixin.js
@@ -1,6 +1,4 @@
-import Vue from 'vue';
-import axios from 'axios';
-import common from '../../../shared/common';
+import common from '@/shared/common';
export default {
data() {
@@ -14,13 +12,13 @@ export default {
},
methods: {
updateConfigProperties: function (configProperties) {
- let props = [];
+ const props = [];
for (let i = 0; i < configProperties.length; i++) {
- let prop = configProperties[i];
+ const prop = configProperties[i];
prop.propertyValue = common.trimToNull(prop.propertyValue);
props.push(prop);
}
- let url = `${this.$api.BASE_URL}/${this.$api.URL_CONFIG_PROPERTY}/aggregate`;
+ const url = `${this.$api.BASE_URL}/${this.$api.URL_CONFIG_PROPERTY}/aggregate`;
this.axios
.post(url, props)
.then((response) => {
@@ -54,7 +52,7 @@ export default {
*/
updateConfigProperty: function (groupName, propertyName, propertyValue) {
propertyValue = common.trimToNull(propertyValue);
- let url = `${this.$api.BASE_URL}/${this.$api.URL_CONFIG_PROPERTY}/`;
+ const url = `${this.$api.BASE_URL}/${this.$api.URL_CONFIG_PROPERTY}/`;
this.axios
.post(url, {
groupName: groupName,
diff --git a/src/views/administration/notifications/Alerts.cy.js b/src/views/administration/notifications/Alerts.cy.js
new file mode 100644
index 000000000..407949571
--- /dev/null
+++ b/src/views/administration/notifications/Alerts.cy.js
@@ -0,0 +1,13 @@
+import Alerts from './Alerts.vue';
+
+describe('Alerts', () => {
+ it('mounts successfully', () => {
+ cy.mount(Alerts, {
+ stubs: {
+ 'create-alert-modal': true,
+ },
+ });
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/notifications/Alerts.vue b/src/views/administration/notifications/Alerts.vue
index cdbcbf762..a63fd44a3 100644
--- a/src/views/administration/notifications/Alerts.vue
+++ b/src/views/administration/notifications/Alerts.vue
@@ -18,46 +18,49 @@
>
-
+
diff --git a/src/views/administration/notifications/CreateAlertModal.cy.js b/src/views/administration/notifications/CreateAlertModal.cy.js
new file mode 100644
index 000000000..0252976fe
--- /dev/null
+++ b/src/views/administration/notifications/CreateAlertModal.cy.js
@@ -0,0 +1,26 @@
+import {
+ genAxiosResponse,
+ shouldShowModal,
+} from '../../../../cypress/support/utils';
+
+import CreateAlertModal from './CreateAlertModal.vue';
+
+describe('CreateAlertModal', () => {
+ it('mounts successfully', () => {
+ cy.mount(CreateAlertModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/notification/publisher': [],
+ }),
+ },
+ },
+ });
+
+ shouldShowModal('createAlertModal');
+ });
+});
diff --git a/src/views/administration/notifications/CreateAlertModal.vue b/src/views/administration/notifications/CreateAlertModal.vue
index cddfac151..10627c441 100644
--- a/src/views/administration/notifications/CreateAlertModal.vue
+++ b/src/views/administration/notifications/CreateAlertModal.vue
@@ -69,7 +69,7 @@
buttons
/>
-
+
{{
$t('message.close')
}}
@@ -81,10 +81,25 @@
diff --git a/src/views/administration/repositories/Composer.cy.js b/src/views/administration/repositories/Composer.cy.js
new file mode 100644
index 000000000..18e2e4853
--- /dev/null
+++ b/src/views/administration/repositories/Composer.cy.js
@@ -0,0 +1,9 @@
+import Composer from './Composer.vue';
+
+describe('Composer', () => {
+ it('mounts successfully', () => {
+ cy.mount(Composer);
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/repositories/Composer.vue b/src/views/administration/repositories/Composer.vue
index 8ea3e75ba..802d2568b 100644
--- a/src/views/administration/repositories/Composer.vue
+++ b/src/views/administration/repositories/Composer.vue
@@ -4,12 +4,13 @@
diff --git a/src/views/administration/repositories/Cpan.cy.js b/src/views/administration/repositories/Cpan.cy.js
new file mode 100644
index 000000000..5d9b72550
--- /dev/null
+++ b/src/views/administration/repositories/Cpan.cy.js
@@ -0,0 +1,9 @@
+import Cpan from './Cpan.vue';
+
+describe('Cpan', () => {
+ it('mounts successfully', () => {
+ cy.mount(Cpan);
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/repositories/Cpan.vue b/src/views/administration/repositories/Cpan.vue
index 22a1da8a8..49d1b1fcc 100644
--- a/src/views/administration/repositories/Cpan.vue
+++ b/src/views/administration/repositories/Cpan.vue
@@ -4,12 +4,13 @@
diff --git a/src/views/administration/repositories/Gem.cy.js b/src/views/administration/repositories/Gem.cy.js
new file mode 100644
index 000000000..5f2e1ffd2
--- /dev/null
+++ b/src/views/administration/repositories/Gem.cy.js
@@ -0,0 +1,9 @@
+import Gem from './Gem.vue';
+
+describe('Gem', () => {
+ it('mounts successfully', () => {
+ cy.mount(Gem);
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/repositories/Gem.vue b/src/views/administration/repositories/Gem.vue
index 3715a41c8..83d8a7d7a 100644
--- a/src/views/administration/repositories/Gem.vue
+++ b/src/views/administration/repositories/Gem.vue
@@ -4,12 +4,13 @@
diff --git a/src/views/administration/repositories/GitHub.cy.js b/src/views/administration/repositories/GitHub.cy.js
new file mode 100644
index 000000000..9b531f492
--- /dev/null
+++ b/src/views/administration/repositories/GitHub.cy.js
@@ -0,0 +1,9 @@
+import GitHub from './GitHub.vue';
+
+describe('GitHub', () => {
+ it('mounts successfully', () => {
+ cy.mount(GitHub);
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/repositories/GitHub.vue b/src/views/administration/repositories/GitHub.vue
index 8585f9e9a..c5937291b 100644
--- a/src/views/administration/repositories/GitHub.vue
+++ b/src/views/administration/repositories/GitHub.vue
@@ -4,12 +4,13 @@
diff --git a/src/views/administration/repositories/GoModules.cy.js b/src/views/administration/repositories/GoModules.cy.js
new file mode 100644
index 000000000..4e4ed90c6
--- /dev/null
+++ b/src/views/administration/repositories/GoModules.cy.js
@@ -0,0 +1,9 @@
+import GoModules from './GoModules.vue';
+
+describe('GoModules', () => {
+ it('mounts successfully', () => {
+ cy.mount(GoModules);
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/repositories/GoModules.vue b/src/views/administration/repositories/GoModules.vue
index 36cdb9cb6..a727c5956 100644
--- a/src/views/administration/repositories/GoModules.vue
+++ b/src/views/administration/repositories/GoModules.vue
@@ -4,12 +4,13 @@
diff --git a/src/views/administration/repositories/Hackage.cy.js b/src/views/administration/repositories/Hackage.cy.js
new file mode 100644
index 000000000..3a6af615f
--- /dev/null
+++ b/src/views/administration/repositories/Hackage.cy.js
@@ -0,0 +1,9 @@
+import Hackage from './Hackage.vue';
+
+describe('Hackage', () => {
+ it('mounts successfully', () => {
+ cy.mount(Hackage);
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/repositories/Hackage.vue b/src/views/administration/repositories/Hackage.vue
index 2a61a8b2d..71a3d53e9 100644
--- a/src/views/administration/repositories/Hackage.vue
+++ b/src/views/administration/repositories/Hackage.vue
@@ -4,12 +4,13 @@
diff --git a/src/views/administration/repositories/Hex.cy.js b/src/views/administration/repositories/Hex.cy.js
new file mode 100644
index 000000000..11b31a15f
--- /dev/null
+++ b/src/views/administration/repositories/Hex.cy.js
@@ -0,0 +1,9 @@
+import Hex from './Hex.vue';
+
+describe('Hex', () => {
+ it('mounts successfully', () => {
+ cy.mount(Hex);
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/repositories/Hex.vue b/src/views/administration/repositories/Hex.vue
index 4fb46c088..91ce2cbd3 100644
--- a/src/views/administration/repositories/Hex.vue
+++ b/src/views/administration/repositories/Hex.vue
@@ -4,12 +4,13 @@
diff --git a/src/views/administration/repositories/Maven.cy.js b/src/views/administration/repositories/Maven.cy.js
new file mode 100644
index 000000000..1a8dbb286
--- /dev/null
+++ b/src/views/administration/repositories/Maven.cy.js
@@ -0,0 +1,9 @@
+import Maven from './Maven.vue';
+
+describe('Maven', () => {
+ it('mounts successfully', () => {
+ cy.mount(Maven);
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/repositories/Maven.vue b/src/views/administration/repositories/Maven.vue
index 05baa22c4..3a4e73957 100644
--- a/src/views/administration/repositories/Maven.vue
+++ b/src/views/administration/repositories/Maven.vue
@@ -4,12 +4,13 @@
diff --git a/src/views/administration/repositories/Nixpkgs.cy.js b/src/views/administration/repositories/Nixpkgs.cy.js
new file mode 100644
index 000000000..006ef68c3
--- /dev/null
+++ b/src/views/administration/repositories/Nixpkgs.cy.js
@@ -0,0 +1,9 @@
+import Nixpkgs from './Nixpkgs.vue';
+
+describe('Nixpkgs', () => {
+ it('mounts successfully', () => {
+ cy.mount(Nixpkgs);
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/repositories/Nixpkgs.vue b/src/views/administration/repositories/Nixpkgs.vue
index 08c449e1a..595d48fab 100644
--- a/src/views/administration/repositories/Nixpkgs.vue
+++ b/src/views/administration/repositories/Nixpkgs.vue
@@ -4,12 +4,13 @@
diff --git a/src/views/administration/repositories/Npm.cy.js b/src/views/administration/repositories/Npm.cy.js
new file mode 100644
index 000000000..5e4af14cb
--- /dev/null
+++ b/src/views/administration/repositories/Npm.cy.js
@@ -0,0 +1,9 @@
+import Npm from './Npm.vue';
+
+describe('Npm', () => {
+ it('mounts successfully', () => {
+ cy.mount(Npm);
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/repositories/Npm.vue b/src/views/administration/repositories/Npm.vue
index e65b263d1..f14d2b3da 100644
--- a/src/views/administration/repositories/Npm.vue
+++ b/src/views/administration/repositories/Npm.vue
@@ -4,12 +4,13 @@
diff --git a/src/views/administration/repositories/Nuget.cy.js b/src/views/administration/repositories/Nuget.cy.js
new file mode 100644
index 000000000..40de5eef7
--- /dev/null
+++ b/src/views/administration/repositories/Nuget.cy.js
@@ -0,0 +1,9 @@
+import Nuget from './Nuget.vue';
+
+describe('Nuget', () => {
+ it('mounts successfully', () => {
+ cy.mount(Nuget);
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/repositories/Nuget.vue b/src/views/administration/repositories/Nuget.vue
index e3512976b..1dc7f84c8 100644
--- a/src/views/administration/repositories/Nuget.vue
+++ b/src/views/administration/repositories/Nuget.vue
@@ -4,12 +4,13 @@
diff --git a/src/views/administration/repositories/Python.cy.js b/src/views/administration/repositories/Python.cy.js
new file mode 100644
index 000000000..29d7232f3
--- /dev/null
+++ b/src/views/administration/repositories/Python.cy.js
@@ -0,0 +1,9 @@
+import Python from './Python.vue';
+
+describe('Python', () => {
+ it('mounts successfully', () => {
+ cy.mount(Python);
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/repositories/Python.vue b/src/views/administration/repositories/Python.vue
index 2cac02a05..0d4e20f10 100644
--- a/src/views/administration/repositories/Python.vue
+++ b/src/views/administration/repositories/Python.vue
@@ -4,12 +4,13 @@
diff --git a/src/views/administration/repositories/Repositories.cy.js b/src/views/administration/repositories/Repositories.cy.js
new file mode 100644
index 000000000..977056770
--- /dev/null
+++ b/src/views/administration/repositories/Repositories.cy.js
@@ -0,0 +1,9 @@
+import Repositories from './Repositories.vue';
+
+describe('Repositories', () => {
+ it('mounts successfully', () => {
+ cy.mount(Repositories);
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/repositories/Repositories.vue b/src/views/administration/repositories/Repositories.vue
index 7ea296d9f..fcb470c68 100644
--- a/src/views/administration/repositories/Repositories.vue
+++ b/src/views/administration/repositories/Repositories.vue
@@ -20,7 +20,7 @@
@@ -28,46 +28,27 @@
diff --git a/src/views/administration/repositories/RepositoryCreateRepositoryModal.cy.js b/src/views/administration/repositories/RepositoryCreateRepositoryModal.cy.js
new file mode 100644
index 000000000..d73b5cc38
--- /dev/null
+++ b/src/views/administration/repositories/RepositoryCreateRepositoryModal.cy.js
@@ -0,0 +1,16 @@
+import { shouldShowModal } from '../../../../cypress/support/utils';
+
+import RepositoryCreateRepositoryModal from './RepositoryCreateRepositoryModal.vue';
+
+describe('RepositoryCreateRepositoryModal', () => {
+ it('mounts successfully', () => {
+ cy.mount(RepositoryCreateRepositoryModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ });
+
+ shouldShowModal('repositoryCreateRepositoryModal');
+ });
+});
diff --git a/src/views/administration/repositories/RepositoryCreateRepositoryModal.vue b/src/views/administration/repositories/RepositoryCreateRepositoryModal.vue
index 23a759e5d..31742f2d6 100644
--- a/src/views/administration/repositories/RepositoryCreateRepositoryModal.vue
+++ b/src/views/administration/repositories/RepositoryCreateRepositoryModal.vue
@@ -67,7 +67,7 @@
$t('admin.enabled')
}}
-
+
{{
$t('message.close')
}}
@@ -80,22 +80,20 @@
diff --git a/src/views/administration/vuln-sources/VulnSourceNvd.cy.js b/src/views/administration/vuln-sources/VulnSourceNvd.cy.js
new file mode 100644
index 000000000..5c9915fec
--- /dev/null
+++ b/src/views/administration/vuln-sources/VulnSourceNvd.cy.js
@@ -0,0 +1,18 @@
+import VulnSourceNvd from './VulnSourceNvd.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('VulnSourceNvd', () => {
+ it('mounts successfully', () => {
+ cy.mount(VulnSourceNvd, {
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/configProperty/': [],
+ }),
+ },
+ },
+ });
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/vuln-sources/VulnSourceNvd.vue b/src/views/administration/vuln-sources/VulnSourceNvd.vue
index dfea3a7f3..181f2c3a9 100644
--- a/src/views/administration/vuln-sources/VulnSourceNvd.vue
+++ b/src/views/administration/vuln-sources/VulnSourceNvd.vue
@@ -122,20 +122,36 @@
diff --git a/src/views/administration/vuln-sources/VulnSourceOSVAdvisories.cy.js b/src/views/administration/vuln-sources/VulnSourceOSVAdvisories.cy.js
new file mode 100644
index 000000000..820133f01
--- /dev/null
+++ b/src/views/administration/vuln-sources/VulnSourceOSVAdvisories.cy.js
@@ -0,0 +1,18 @@
+import VulnSourceOSVAdvisories from './VulnSourceOSVAdvisories.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('VulnSourceOSVAdvisories', () => {
+ it('mounts successfully', () => {
+ cy.mount(VulnSourceOSVAdvisories, {
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/configProperty/': [],
+ }),
+ },
+ },
+ });
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/administration/vuln-sources/VulnSourceOSVAdvisories.vue b/src/views/administration/vuln-sources/VulnSourceOSVAdvisories.vue
index a3d0a9c93..7a3931ae8 100644
--- a/src/views/administration/vuln-sources/VulnSourceOSVAdvisories.vue
+++ b/src/views/administration/vuln-sources/VulnSourceOSVAdvisories.vue
@@ -68,27 +68,39 @@
{{ $t('message.update') }}
-
+
diff --git a/src/views/audit/PolicyViolationAudit.cy.js b/src/views/audit/PolicyViolationAudit.cy.js
new file mode 100644
index 000000000..46badb69d
--- /dev/null
+++ b/src/views/audit/PolicyViolationAudit.cy.js
@@ -0,0 +1,11 @@
+import PolicyViolationAudit from './PolicyViolationAudit.vue';
+
+describe('PolicyViolationAudit', () => {
+ it('mounts successfully', () => {
+ cy.setToken(['VIEW_POLICY_VIOLATION']);
+
+ cy.mount(PolicyViolationAudit);
+
+ cy.get('div.animated.fadeIn').should('be.visible');
+ });
+});
diff --git a/src/views/audit/PolicyViolationAudit.vue b/src/views/audit/PolicyViolationAudit.vue
index 64918916c..5a3ba0bbd 100644
--- a/src/views/audit/PolicyViolationAudit.vue
+++ b/src/views/audit/PolicyViolationAudit.vue
@@ -10,8 +10,8 @@
style="float: right"
@click="clearAllFilters()"
>
- {{ this.$t('message.clear_all') }}
+ {{ this.$t('message.clear_all') }}
+
-
-
+
+ >
diff --git a/src/views/components/AboutModal.cy.js b/src/views/components/AboutModal.cy.js
new file mode 100644
index 000000000..01176ea9d
--- /dev/null
+++ b/src/views/components/AboutModal.cy.js
@@ -0,0 +1,19 @@
+import AboutModal from './AboutModal.vue';
+import { shouldShowModal } from '../../../cypress/support/utils';
+
+describe('AboutModal', () => {
+ it('mounts successfully', () => {
+ const mockCommon = {
+ formatTimestamp: cy.stub().returns('01 Jan 2023 at 12:00:00'),
+ };
+
+ cy.mount(AboutModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ });
+
+ shouldShowModal('aboutModal');
+ });
+});
diff --git a/src/views/components/AboutModal.vue b/src/views/components/AboutModal.vue
index c52743897..48f6e0733 100644
--- a/src/views/components/AboutModal.vue
+++ b/src/views/components/AboutModal.vue
@@ -8,10 +8,18 @@
>
-
+
-
+
@@ -110,23 +118,29 @@
-
+
Copyright © OWASP Foundation. All Rights Reserved.
- {{
- $t('message.close')
- }}
+ {{ $t('message.close') }}
+
diff --git a/src/views/components/ExternalReferencesDropdown.cy.js b/src/views/components/ExternalReferencesDropdown.cy.js
new file mode 100644
index 000000000..c0c23117b
--- /dev/null
+++ b/src/views/components/ExternalReferencesDropdown.cy.js
@@ -0,0 +1,17 @@
+import ExternalReferencesDropdown from './ExternalReferencesDropdown.vue';
+
+describe('ExternalReferencesDropdown', () => {
+ it('mounts successfully', () => {
+ const mockReferences = [
+ { type: 'website', url: 'https://example.com' },
+ { type: 'bom', url: 'https://example.org/bom' },
+ { type: 'documentation', url: 'https://docs.example.com' },
+ ];
+
+ cy.mount(ExternalReferencesDropdown, {
+ propsData: {
+ externalReferences: mockReferences,
+ },
+ });
+ });
+});
diff --git a/src/views/components/ExternalReferencesDropdown.vue b/src/views/components/ExternalReferencesDropdown.vue
index b37930eec..cfcd1772c 100644
--- a/src/views/components/ExternalReferencesDropdown.vue
+++ b/src/views/components/ExternalReferencesDropdown.vue
@@ -27,7 +27,13 @@
diff --git a/src/views/dashboard/ChartAuditingFindingsProgress.cy.js b/src/views/dashboard/ChartAuditingFindingsProgress.cy.js
new file mode 100644
index 000000000..fe9471ff6
--- /dev/null
+++ b/src/views/dashboard/ChartAuditingFindingsProgress.cy.js
@@ -0,0 +1,11 @@
+import ChartAuditingFindingsProgress from '@/views/dashboard/ChartAuditingFindingsProgress.vue';
+
+describe('ChartAuditingFindingsProgress', () => {
+ it('mounts successfully', () => {
+ cy.mount(ChartAuditingFindingsProgress, {
+ propsData: {
+ height: 300,
+ },
+ });
+ });
+});
diff --git a/src/views/dashboard/ChartAuditingFindingsProgress.vue b/src/views/dashboard/ChartAuditingFindingsProgress.vue
index 971aa6a03..ab137e6ad 100644
--- a/src/views/dashboard/ChartAuditingFindingsProgress.vue
+++ b/src/views/dashboard/ChartAuditingFindingsProgress.vue
@@ -1,5 +1,5 @@
diff --git a/src/views/globalAudit/VulnerabilityAuditByOccurrence.cy.js b/src/views/globalAudit/VulnerabilityAuditByOccurrence.cy.js
new file mode 100644
index 000000000..84d2d9235
--- /dev/null
+++ b/src/views/globalAudit/VulnerabilityAuditByOccurrence.cy.js
@@ -0,0 +1,20 @@
+import VulnerabilityAuditByOccurrence from './VulnerabilityAuditByOccurrence.vue';
+
+describe('VulnerabilityAuditByOccurrence', () => {
+ it('mounts successfully', () => {
+ const mockCommon = {
+ formatSeverityLabel: cy.stub().returns(''),
+ formatAnalyzerLabel: cy.stub().returns(''),
+ formatTimestamp: cy.stub().returns(''),
+ formatSourceLabel: cy.stub().returns(''),
+ concatenateComponentName: cy.stub().returns(''),
+ valueWithDefault: cy.stub().returns(''),
+ capitalize: cy.stub().returns(''),
+ makeAnalysisStateLabelFormatter: cy.stub().returns(() => ''),
+ };
+
+ cy.mount(VulnerabilityAuditByOccurrence);
+
+ cy.get('div').should('exist');
+ });
+});
diff --git a/src/views/globalAudit/VulnerabilityAuditByOccurrence.vue b/src/views/globalAudit/VulnerabilityAuditByOccurrence.vue
index 8942f65b9..dc22da314 100644
--- a/src/views/globalAudit/VulnerabilityAuditByOccurrence.vue
+++ b/src/views/globalAudit/VulnerabilityAuditByOccurrence.vue
@@ -79,35 +79,35 @@
id="publish-date-form-group"
:label="this.$t('message.published')"
>
-
-
+
+ >
-
-
+
+ >
option.value,
- );
- },
- methods: {
- initializeWatchers: function () {
- this.simpleWatcher = this.$watch('watchers', () => this.refreshTable());
- this.textSearchSelectedWatcher = this.$watch('textSearchSelected', () => {
- if (this.textSearchInput.trim().length !== 0) {
- this.refreshTable();
- }
- });
- this.textSearchInputWatcher = this.$watch(
- 'textSearchInput',
- (newInput, oldInput) => {
- if (!(newInput.trim().length === 0 && oldInput.trim().length === 0)) {
- this.refreshTable();
- }
- },
- );
- this.cvssv2FromWatcher = this.$watch('cvssv2From', () => {
- if (this.cvssv2FromState() !== false) {
- this.refreshTable();
- }
- });
- this.cvssv2ToWatcher = this.$watch('cvssv2To', () => {
- if (this.cvssv2ToState() !== false) {
- this.refreshTable();
- }
- });
- this.cvssv3FromWatcher = this.$watch('cvssv3From', () => {
- if (this.cvssv3FromState() !== false) {
- this.refreshTable();
- }
- });
- this.cvssv3ToWatcher = this.$watch('cvssv3To', () => {
- if (this.cvssv3ToState() !== false) {
- this.refreshTable();
- }
- });
- },
- apiUrl: function () {
- let url = `${this.$api.BASE_URL}/${this.$api.URL_FINDING}`;
- url +=
- '?showInactive=' +
- (this.showInactive === 'true') +
- '&showSuppressed=' +
- (this.showSuppressed === 'true');
- if (this.severitySelected && this.severitySelected.length > 0) {
- url += '&severity=' + this.severitySelected;
- }
- if (
- this.analysisStatusSelected &&
- this.analysisStatusSelected.length > 0
- ) {
- url += '&analysisStatus=' + this.analysisStatusSelected;
- }
- if (
- this.vendorResponseSelected &&
- this.vendorResponseSelected.length > 0
- ) {
- url += '&vendorResponse=' + this.vendorResponseSelected;
- }
- if (this.publishDateFrom && this.publishDateFrom.length > 0) {
- url += '&publishDateFrom=' + this.publishDateFrom;
- }
- if (this.publishDateTo && this.publishDateTo.length > 0) {
- url += '&publishDateTo=' + this.publishDateTo;
- }
- if (this.attributedOnDateFrom && this.attributedOnDateFrom.length > 0) {
- url += '&attributedOnDateFrom=' + this.attributedOnDateFrom;
- }
- if (this.attributedOnDateTo && this.attributedOnDateTo.length > 0) {
- url += '&attributedOnDateTo=' + this.attributedOnDateTo;
- }
- if (this.textSearchInput && this.textSearchInput.trim().length > 0) {
- url +=
- '&textSearchField=' +
- this.textSearchSelected +
- '&textSearchInput=' +
- this.textSearchInput.trim();
- }
- if (this.cvssv2From && this.cvssv2From.trim().length > 0) {
- url += '&cvssv2From=' + this.cvssv2From;
- }
- if (this.cvssv2To && this.cvssv2To.trim().length > 0) {
- url += '&cvssv2To=' + this.cvssv2To;
- }
- if (this.cvssv3From && this.cvssv3From.trim().length > 0) {
- url += '&cvssv3From=' + this.cvssv3From;
- }
- if (this.cvssv3To && this.cvssv3To.trim().length > 0) {
- url += '&cvssv3To=' + this.cvssv3To;
- }
- return url;
- },
- clearAllFilters: function () {
- this.simpleWatcher();
- this.textSearchSelectedWatcher();
- this.textSearchInputWatcher();
- this.cvssv2FromWatcher();
- this.cvssv2ToWatcher();
- this.cvssv3FromWatcher();
- this.cvssv3ToWatcher();
- this.showInactive = false;
- this.showSuppressed = false;
- this.severitySelected = [];
- this.analysisStatusSelected = [];
- this.vendorResponseSelected = [];
- this.publishDateFrom = '';
- this.publishDateTo = '';
- this.attributedOnDateFrom = '';
- this.attributedOnDateTo = '';
- this.textSearchInput = '';
- this.textSearchSelected = this.textSearchOptions.map(
- (option) => option.value,
- );
- this.cvssv2From = '';
- this.cvssv2To = '';
- this.cvssv3From = '';
- this.cvssv3To = '';
- this.refreshTable();
- this.initializeWatchers();
- },
- refreshTable: function () {
- this.$refs.table.refresh({
- url: this.apiUrl(),
- silent: true,
- pageNumber: 1,
- });
- },
- initializeTooltips: function () {
- $('[data-toggle="tooltip"]').tooltip({
- trigger: 'hover',
- });
- },
- cvssv2UpperLimit: function () {
- return this.cvssv2To ? this.cvssv2To : 10;
- },
- cvssv2LowerLimit: function () {
- return this.cvssv2From ? this.cvssv2From : 0;
- },
- cvssv2FromState() {
- return this.cvssv2From
- ? !isNaN(this.cvssv2From) &&
- (!this.cvssv2To ||
- !isNaN(this.cvssv2To) ||
- this.cvssv2From <= this.cvssv2To) &&
- this.cvssv2From <= 10 &&
- this.cvssv2From >= 0
- : null;
- },
- cvssv2ToState() {
- return this.cvssv2To
- ? !isNaN(this.cvssv2To) &&
- (!this.cvssv2From ||
- !isNaN(this.cvssv2From) ||
- this.cvssv2To >= this.cvssv2From) &&
- this.cvssv2To <= 10 &&
- this.cvssv2To >= 0
- : null;
- },
- cvssv3UpperLimit: function () {
- return this.cvssv3To ? this.cvssv3To : 10;
- },
- cvssv3LowerLimit: function () {
- return this.cvssv3From ? this.cvssv3From : 0;
- },
- cvssv3FromState() {
- return this.cvssv3From
- ? !isNaN(this.cvssv3From) &&
- (!this.cvssv3To ||
- !isNaN(this.cvssv3To) ||
- this.cvssv3From <= this.cvssv3To) &&
- this.cvssv3From <= 10 &&
- this.cvssv3From >= 0
- : null;
- },
- cvssv3ToState() {
- return this.cvssv3To
- ? !isNaN(this.cvssv3To) &&
- (!this.cvssv3From ||
- !isNaN(this.cvssv3From) ||
- this.cvssv3To >= this.cvssv3From) &&
- this.cvssv3To <= 10 &&
- this.cvssv3To >= 0
- : null;
- },
- onLoadSuccess: function () {
- loadUserPreferencesForBootstrapTable(
- this,
- 'VulnerabilityAuditByOccurrence',
- this.$refs.table.columns,
- );
- },
+ components: {
+ BRow,
+ BCol,
+ BButton,
+ BFormGroup,
+ BFormCheckbox,
+ BFormCheckboxGroup,
+ BFormInput,
+ BFormRow,
+ BFormDatepicker,
+ BootstrapTable,
},
data() {
return {
@@ -490,7 +301,7 @@ export default {
field: 'vulnerability.vulnId',
sortable: true,
formatter(value, row, index) {
- let url = xssFilters.uriInUnQuotedAttr(
+ const url = xssFilters.uriInUnQuotedAttr(
'../vulnerabilities/' +
row.vulnerability.source +
'/' +
@@ -549,7 +360,7 @@ export default {
if (typeof value !== 'undefined') {
let s = '';
for (let i = 0; i < value.length; i++) {
- let cwe = value[i];
+ const cwe = value[i];
if (i > 0) {
s += ', ';
}
@@ -588,10 +399,10 @@ export default {
field: 'component.projectName',
sortable: true,
formatter(value, row, index) {
- let url = xssFilters.uriInUnQuotedAttr(
+ const url = xssFilters.uriInUnQuotedAttr(
'../projects/' + row.component.project,
);
- let name = common.concatenateComponentName(
+ const name = common.concatenateComponentName(
null,
row.component.projectName,
row.component.projectVersion,
@@ -604,10 +415,10 @@ export default {
field: 'component.name',
sortable: true,
formatter: (value, row, index) => {
- let url = xssFilters.uriInUnQuotedAttr(
+ const url = xssFilters.uriInUnQuotedAttr(
'../../../components/' + row.component.uuid,
);
- let dependencyGraphUrl = xssFilters.uriInUnQuotedAttr(
+ const dependencyGraphUrl = xssFilters.uriInUnQuotedAttr(
'../../../projects/' +
row.component.project +
'/dependencyGraph/' +
@@ -743,5 +554,218 @@ export default {
},
};
},
+ computed: {
+ watchers() {
+ return [
+ this.showInactive,
+ this.showSuppressed,
+ this.severitySelected,
+ this.analysisStatusSelected,
+ this.vendorResponseSelected,
+ this.publishDateFrom,
+ this.publishDateTo,
+ this.attributedOnDateFrom,
+ this.attributedOnDateTo,
+ ];
+ },
+ },
+ beforeMount() {
+ this.initializeWatchers();
+ this.textSearchSelected = this.textSearchOptions.map(
+ (option) => option.value,
+ );
+ },
+ methods: {
+ initializeWatchers: function () {
+ this.simpleWatcher = this.$watch('watchers', () => this.refreshTable());
+ this.textSearchSelectedWatcher = this.$watch('textSearchSelected', () => {
+ if (this.textSearchInput.trim().length !== 0) {
+ this.refreshTable();
+ }
+ });
+ this.textSearchInputWatcher = this.$watch(
+ 'textSearchInput',
+ (newInput, oldInput) => {
+ if (!(newInput.trim().length === 0 && oldInput.trim().length === 0)) {
+ this.refreshTable();
+ }
+ },
+ );
+ this.cvssv2FromWatcher = this.$watch('cvssv2From', () => {
+ if (this.cvssv2FromState() !== false) {
+ this.refreshTable();
+ }
+ });
+ this.cvssv2ToWatcher = this.$watch('cvssv2To', () => {
+ if (this.cvssv2ToState() !== false) {
+ this.refreshTable();
+ }
+ });
+ this.cvssv3FromWatcher = this.$watch('cvssv3From', () => {
+ if (this.cvssv3FromState() !== false) {
+ this.refreshTable();
+ }
+ });
+ this.cvssv3ToWatcher = this.$watch('cvssv3To', () => {
+ if (this.cvssv3ToState() !== false) {
+ this.refreshTable();
+ }
+ });
+ },
+ apiUrl: function () {
+ let url = `${this.$api.BASE_URL}/${this.$api.URL_FINDING}`;
+ url +=
+ '?showInactive=' +
+ (this.showInactive === 'true') +
+ '&showSuppressed=' +
+ (this.showSuppressed === 'true');
+ if (this.severitySelected && this.severitySelected.length > 0) {
+ url += '&severity=' + this.severitySelected;
+ }
+ if (
+ this.analysisStatusSelected &&
+ this.analysisStatusSelected.length > 0
+ ) {
+ url += '&analysisStatus=' + this.analysisStatusSelected;
+ }
+ if (
+ this.vendorResponseSelected &&
+ this.vendorResponseSelected.length > 0
+ ) {
+ url += '&vendorResponse=' + this.vendorResponseSelected;
+ }
+ if (this.publishDateFrom && this.publishDateFrom.length > 0) {
+ url += '&publishDateFrom=' + this.publishDateFrom;
+ }
+ if (this.publishDateTo && this.publishDateTo.length > 0) {
+ url += '&publishDateTo=' + this.publishDateTo;
+ }
+ if (this.attributedOnDateFrom && this.attributedOnDateFrom.length > 0) {
+ url += '&attributedOnDateFrom=' + this.attributedOnDateFrom;
+ }
+ if (this.attributedOnDateTo && this.attributedOnDateTo.length > 0) {
+ url += '&attributedOnDateTo=' + this.attributedOnDateTo;
+ }
+ if (this.textSearchInput && this.textSearchInput.trim().length > 0) {
+ url +=
+ '&textSearchField=' +
+ this.textSearchSelected +
+ '&textSearchInput=' +
+ this.textSearchInput.trim();
+ }
+ if (this.cvssv2From && this.cvssv2From.trim().length > 0) {
+ url += '&cvssv2From=' + this.cvssv2From;
+ }
+ if (this.cvssv2To && this.cvssv2To.trim().length > 0) {
+ url += '&cvssv2To=' + this.cvssv2To;
+ }
+ if (this.cvssv3From && this.cvssv3From.trim().length > 0) {
+ url += '&cvssv3From=' + this.cvssv3From;
+ }
+ if (this.cvssv3To && this.cvssv3To.trim().length > 0) {
+ url += '&cvssv3To=' + this.cvssv3To;
+ }
+ return url;
+ },
+ clearAllFilters: function () {
+ this.simpleWatcher();
+ this.textSearchSelectedWatcher();
+ this.textSearchInputWatcher();
+ this.cvssv2FromWatcher();
+ this.cvssv2ToWatcher();
+ this.cvssv3FromWatcher();
+ this.cvssv3ToWatcher();
+ this.showInactive = false;
+ this.showSuppressed = false;
+ this.severitySelected = [];
+ this.analysisStatusSelected = [];
+ this.vendorResponseSelected = [];
+ this.publishDateFrom = '';
+ this.publishDateTo = '';
+ this.attributedOnDateFrom = '';
+ this.attributedOnDateTo = '';
+ this.textSearchInput = '';
+ this.textSearchSelected = this.textSearchOptions.map(
+ (option) => option.value,
+ );
+ this.cvssv2From = '';
+ this.cvssv2To = '';
+ this.cvssv3From = '';
+ this.cvssv3To = '';
+ this.refreshTable();
+ this.initializeWatchers();
+ },
+ refreshTable: function () {
+ this.$refs.table.refresh({
+ url: this.apiUrl(),
+ silent: true,
+ pageNumber: 1,
+ });
+ },
+ initializeTooltips: function () {
+ $('[data-toggle="tooltip"]').tooltip({
+ trigger: 'hover',
+ });
+ },
+ cvssv2UpperLimit: function () {
+ return this.cvssv2To ? this.cvssv2To : 10;
+ },
+ cvssv2LowerLimit: function () {
+ return this.cvssv2From ? this.cvssv2From : 0;
+ },
+ cvssv2FromState() {
+ return this.cvssv2From
+ ? !isNaN(this.cvssv2From) &&
+ (!this.cvssv2To ||
+ !isNaN(this.cvssv2To) ||
+ this.cvssv2From <= this.cvssv2To) &&
+ this.cvssv2From <= 10 &&
+ this.cvssv2From >= 0
+ : null;
+ },
+ cvssv2ToState() {
+ return this.cvssv2To
+ ? !isNaN(this.cvssv2To) &&
+ (!this.cvssv2From ||
+ !isNaN(this.cvssv2From) ||
+ this.cvssv2To >= this.cvssv2From) &&
+ this.cvssv2To <= 10 &&
+ this.cvssv2To >= 0
+ : null;
+ },
+ cvssv3UpperLimit: function () {
+ return this.cvssv3To ? this.cvssv3To : 10;
+ },
+ cvssv3LowerLimit: function () {
+ return this.cvssv3From ? this.cvssv3From : 0;
+ },
+ cvssv3FromState() {
+ return this.cvssv3From
+ ? !isNaN(this.cvssv3From) &&
+ (!this.cvssv3To ||
+ !isNaN(this.cvssv3To) ||
+ this.cvssv3From <= this.cvssv3To) &&
+ this.cvssv3From <= 10 &&
+ this.cvssv3From >= 0
+ : null;
+ },
+ cvssv3ToState() {
+ return this.cvssv3To
+ ? !isNaN(this.cvssv3To) &&
+ (!this.cvssv3From ||
+ !isNaN(this.cvssv3From) ||
+ this.cvssv3To >= this.cvssv3From) &&
+ this.cvssv3To <= 10 &&
+ this.cvssv3To >= 0
+ : null;
+ },
+ onLoadSuccess: function () {
+ loadUserPreferencesForBootstrapTable(
+ this,
+ 'VulnerabilityAuditByOccurrence',
+ this.$refs.table.columns,
+ );
+ },
+ },
};
diff --git a/src/views/globalAudit/VulnerabilityAuditGroupedByVulnerability.cy.js b/src/views/globalAudit/VulnerabilityAuditGroupedByVulnerability.cy.js
new file mode 100644
index 000000000..c1d8e55f1
--- /dev/null
+++ b/src/views/globalAudit/VulnerabilityAuditGroupedByVulnerability.cy.js
@@ -0,0 +1,17 @@
+import VulnerabilityAuditGroupedByVulnerability from './VulnerabilityAuditGroupedByVulnerability.vue';
+
+describe('VulnerabilityAuditGroupedByVulnerability', () => {
+ it('mounts successfully', () => {
+ const mockCommon = {
+ formatSeverityLabel: cy.stub().returns(''),
+ formatAnalyzerLabel: cy.stub().returns(''),
+ formatTimestamp: cy.stub().returns(''),
+ formatSourceLabel: cy.stub().returns(''),
+ capitalize: cy.stub().returns(''),
+ };
+
+ cy.mount(VulnerabilityAuditGroupedByVulnerability);
+
+ cy.get('div').should('exist');
+ });
+});
diff --git a/src/views/globalAudit/VulnerabilityAuditGroupedByVulnerability.vue b/src/views/globalAudit/VulnerabilityAuditGroupedByVulnerability.vue
index 5deb43191..d42562fc5 100644
--- a/src/views/globalAudit/VulnerabilityAuditGroupedByVulnerability.vue
+++ b/src/views/globalAudit/VulnerabilityAuditGroupedByVulnerability.vue
@@ -41,18 +41,18 @@
id="grouped-publish-date-form-group"
:label="this.$t('message.published')"
>
-
-
+
+ >
option.value,
- );
- },
- methods: {
- initializeWatchers: function () {
- this.simpleWatcher = this.$watch('watchers', () => this.refreshTable());
- this.textSearchSelectedWatcher = this.$watch('textSearchSelected', () => {
- if (this.textSearchInput.trim().length !== 0) {
- this.refreshTable();
- }
- });
- this.textSearchInputWatcher = this.$watch(
- 'textSearchInput',
- (newInput, oldInput) => {
- if (!(newInput.trim().length === 0 && oldInput.trim().length === 0)) {
- this.refreshTable();
- }
- },
- );
- this.cvssv2FromWatcher = this.$watch('cvssv2From', () => {
- if (this.cvssv2FromState() !== false) {
- this.refreshTable();
- }
- });
- this.cvssv2ToWatcher = this.$watch('cvssv2To', () => {
- if (this.cvssv2ToState() !== false) {
- this.refreshTable();
- }
- });
- this.cvssv3FromWatcher = this.$watch('cvssv3From', () => {
- if (this.cvssv3FromState() !== false) {
- this.refreshTable();
- }
- });
- this.cvssv3ToWatcher = this.$watch('cvssv3To', () => {
- if (this.cvssv3ToState() !== false) {
- this.refreshTable();
- }
- });
- this.occurrencesFromWatcher = this.$watch('occurrencesFrom', () => {
- if (this.occurrencesFromState() !== false) {
- this.refreshTable();
- }
- });
- this.occurrencesToWatcher = this.$watch('occurrencesTo', () => {
- if (this.occurrencesToState() !== false) {
- this.refreshTable();
- }
- });
- },
- apiUrl: function () {
- let url = `${this.$api.BASE_URL}/${this.$api.URL_FINDING}/grouped`;
- url +=
- '?showInactive=' +
- (this.showInactive === 'true') +
- '&showSuppressed=' +
- (this.showSuppressed === 'true');
- if (this.severitySelected && this.severitySelected.length > 0) {
- url += '&severity=' + this.severitySelected;
- }
- if (this.publishDateFrom && this.publishDateFrom.length > 0) {
- url += '&publishDateFrom=' + this.publishDateFrom;
- }
- if (this.publishDateTo && this.publishDateTo.length > 0) {
- url += '&publishDateTo=' + this.publishDateTo;
- }
- if (this.textSearchInput && this.textSearchInput.trim().length > 0) {
- url +=
- '&textSearchField=' +
- this.textSearchSelected +
- '&textSearchInput=' +
- this.textSearchInput.trim();
- }
- if (this.cvssv2From && this.cvssv2From.trim().length > 0) {
- url += '&cvssv2From=' + this.cvssv2From;
- }
- if (this.cvssv2To && this.cvssv2To.trim().length > 0) {
- url += '&cvssv2To=' + this.cvssv2To;
- }
- if (this.cvssv3From && this.cvssv3From.trim().length > 0) {
- url += '&cvssv3From=' + this.cvssv3From;
- }
- if (this.cvssv3To && this.cvssv3To.trim().length > 0) {
- url += '&cvssv3To=' + this.cvssv3To;
- }
- if (this.occurrencesFrom && this.occurrencesFrom.trim().length > 0) {
- url += '&occurrencesFrom=' + this.occurrencesFrom;
- }
- if (this.occurrencesTo && this.occurrencesTo.trim().length > 0) {
- url += '&occurrencesTo=' + this.occurrencesTo;
- }
- return url;
- },
- clearAllFilters: function () {
- this.simpleWatcher();
- this.textSearchSelectedWatcher();
- this.textSearchInputWatcher();
- this.cvssv2FromWatcher();
- this.cvssv2ToWatcher();
- this.cvssv3FromWatcher();
- this.cvssv3ToWatcher();
- this.occurrencesFromWatcher();
- this.occurrencesToWatcher();
- this.showInactive = false;
- this.severitySelected = [];
- this.publishDateFrom = '';
- this.publishDateTo = '';
- this.textSearchInput = '';
- this.textSearchSelected = this.textSearchOptions.map(
- (option) => option.value,
- );
- this.cvssv2From = '';
- this.cvssv2To = '';
- this.cvssv3From = '';
- this.cvssv3To = '';
- this.occurrencesFrom = '';
- this.occurrencesTo = '';
- this.refreshTable();
- this.initializeWatchers();
- },
- refreshTable: function () {
- this.$refs.table.refresh({
- url: this.apiUrl(),
- silent: true,
- pageNumber: 1,
- });
- },
- cvssv2UpperLimit: function () {
- return this.cvssv2To ? this.cvssv2To : 10;
- },
- cvssv2LowerLimit: function () {
- return this.cvssv2From ? this.cvssv2From : 0;
- },
- cvssv2FromState() {
- return this.cvssv2From
- ? !isNaN(this.cvssv2From) &&
- (!this.cvssv2To ||
- !isNaN(this.cvssv2To) ||
- this.cvssv2From <= this.cvssv2To) &&
- this.cvssv2From <= 10
- : null;
- },
- cvssv2ToState() {
- return this.cvssv2To
- ? !isNaN(this.cvssv2To) &&
- (!this.cvssv2From ||
- !isNaN(this.cvssv2From) ||
- this.cvssv2To >= this.cvssv2From) &&
- this.cvssv2To >= 0
- : null;
- },
- cvssv3UpperLimit: function () {
- return this.cvssv3To ? this.cvssv3To : 10;
- },
- cvssv3LowerLimit: function () {
- return this.cvssv3From ? this.cvssv3From : 0;
- },
- cvssv3FromState() {
- return this.cvssv3From
- ? !isNaN(this.cvssv3From) &&
- (!this.cvssv3To ||
- !isNaN(this.cvssv3To) ||
- this.cvssv3From <= this.cvssv3To) &&
- this.cvssv3From <= 10
- : null;
- },
- cvssv3ToState() {
- return this.cvssv3To
- ? !isNaN(this.cvssv3To) &&
- (!this.cvssv3From ||
- !isNaN(this.cvssv3From) ||
- this.cvssv3To >= this.cvssv3From) &&
- this.cvssv3To >= 0
- : null;
- },
- occurrencesUpperLimit: function () {
- return this.occurrencesTo ? this.occurrencesTo : null;
- },
- occurrencesLowerLimit: function () {
- return this.occurrencesFrom ? this.occurrencesFrom : 0;
- },
- occurrencesFromState: function () {
- return this.occurrencesFrom
- ? !isNaN(this.occurrencesFrom) &&
- (!this.occurrencesTo ||
- !isNaN(this.occurrencesTo) ||
- this.occurrencesFrom <= this.occurrencesTo) &&
- this.cvssv3From >= 0
- : null;
- },
- occurrencesToState: function () {
- return this.occurrencesTo
- ? !isNaN(this.occurrencesTo) &&
- (!this.occurrencesFrom ||
- !isNaN(this.occurrencesFrom) ||
- this.occurrencesTo >= this.occurrencesFrom) &&
- this.cvssv3To >= 0
- : null;
- },
- onLoadSuccess: function () {
- loadUserPreferencesForBootstrapTable(
- this,
- 'VulnerabilityAuditGroupedByVulnerability',
- this.$refs.table.columns,
- );
- },
+ components: {
+ BRow,
+ BCol,
+ BFormCheckbox,
+ BButton,
+ BFormInput,
+ BFormGroup,
+ BFormCheckboxGroup,
+ BFormDatepicker,
+ BFormRow,
+ BootstrapTable,
},
data() {
return {
@@ -455,7 +259,7 @@ export default {
field: 'vulnerability.vulnId',
sortable: true,
formatter(value, row, index) {
- let url = xssFilters.uriInUnQuotedAttr(
+ const url = xssFilters.uriInUnQuotedAttr(
'../vulnerabilities/' +
row.vulnerability.source +
'/' +
@@ -514,7 +318,7 @@ export default {
if (typeof value !== 'undefined') {
let s = '';
for (let i = 0; i < value.length; i++) {
- let cwe = value[i];
+ const cwe = value[i];
if (i > 0) {
s += ', ';
}
@@ -634,5 +438,225 @@ export default {
},
};
},
+ computed: {
+ watchers() {
+ return [
+ this.showInactive,
+ this.severitySelected,
+ this.publishDateFrom,
+ this.publishDateTo,
+ ];
+ },
+ },
+ beforeMount() {
+ this.initializeWatchers();
+ this.textSearchSelected = this.textSearchOptions.map(
+ (option) => option.value,
+ );
+ },
+ methods: {
+ initializeWatchers: function () {
+ this.simpleWatcher = this.$watch('watchers', () => this.refreshTable());
+ this.textSearchSelectedWatcher = this.$watch('textSearchSelected', () => {
+ if (this.textSearchInput.trim().length !== 0) {
+ this.refreshTable();
+ }
+ });
+ this.textSearchInputWatcher = this.$watch(
+ 'textSearchInput',
+ (newInput, oldInput) => {
+ if (!(newInput.trim().length === 0 && oldInput.trim().length === 0)) {
+ this.refreshTable();
+ }
+ },
+ );
+ this.cvssv2FromWatcher = this.$watch('cvssv2From', () => {
+ if (this.cvssv2FromState() !== false) {
+ this.refreshTable();
+ }
+ });
+ this.cvssv2ToWatcher = this.$watch('cvssv2To', () => {
+ if (this.cvssv2ToState() !== false) {
+ this.refreshTable();
+ }
+ });
+ this.cvssv3FromWatcher = this.$watch('cvssv3From', () => {
+ if (this.cvssv3FromState() !== false) {
+ this.refreshTable();
+ }
+ });
+ this.cvssv3ToWatcher = this.$watch('cvssv3To', () => {
+ if (this.cvssv3ToState() !== false) {
+ this.refreshTable();
+ }
+ });
+ this.occurrencesFromWatcher = this.$watch('occurrencesFrom', () => {
+ if (this.occurrencesFromState() !== false) {
+ this.refreshTable();
+ }
+ });
+ this.occurrencesToWatcher = this.$watch('occurrencesTo', () => {
+ if (this.occurrencesToState() !== false) {
+ this.refreshTable();
+ }
+ });
+ },
+ apiUrl: function () {
+ let url = `${this.$api.BASE_URL}/${this.$api.URL_FINDING}/grouped`;
+ url +=
+ '?showInactive=' +
+ (this.showInactive === 'true') +
+ '&showSuppressed=' +
+ (this.showSuppressed === 'true');
+ if (this.severitySelected && this.severitySelected.length > 0) {
+ url += '&severity=' + this.severitySelected;
+ }
+ if (this.publishDateFrom && this.publishDateFrom.length > 0) {
+ url += '&publishDateFrom=' + this.publishDateFrom;
+ }
+ if (this.publishDateTo && this.publishDateTo.length > 0) {
+ url += '&publishDateTo=' + this.publishDateTo;
+ }
+ if (this.textSearchInput && this.textSearchInput.trim().length > 0) {
+ url +=
+ '&textSearchField=' +
+ this.textSearchSelected +
+ '&textSearchInput=' +
+ this.textSearchInput.trim();
+ }
+ if (this.cvssv2From && this.cvssv2From.trim().length > 0) {
+ url += '&cvssv2From=' + this.cvssv2From;
+ }
+ if (this.cvssv2To && this.cvssv2To.trim().length > 0) {
+ url += '&cvssv2To=' + this.cvssv2To;
+ }
+ if (this.cvssv3From && this.cvssv3From.trim().length > 0) {
+ url += '&cvssv3From=' + this.cvssv3From;
+ }
+ if (this.cvssv3To && this.cvssv3To.trim().length > 0) {
+ url += '&cvssv3To=' + this.cvssv3To;
+ }
+ if (this.occurrencesFrom && this.occurrencesFrom.trim().length > 0) {
+ url += '&occurrencesFrom=' + this.occurrencesFrom;
+ }
+ if (this.occurrencesTo && this.occurrencesTo.trim().length > 0) {
+ url += '&occurrencesTo=' + this.occurrencesTo;
+ }
+ return url;
+ },
+ clearAllFilters: function () {
+ this.simpleWatcher();
+ this.textSearchSelectedWatcher();
+ this.textSearchInputWatcher();
+ this.cvssv2FromWatcher();
+ this.cvssv2ToWatcher();
+ this.cvssv3FromWatcher();
+ this.cvssv3ToWatcher();
+ this.occurrencesFromWatcher();
+ this.occurrencesToWatcher();
+ this.showInactive = false;
+ this.severitySelected = [];
+ this.publishDateFrom = '';
+ this.publishDateTo = '';
+ this.textSearchInput = '';
+ this.textSearchSelected = this.textSearchOptions.map(
+ (option) => option.value,
+ );
+ this.cvssv2From = '';
+ this.cvssv2To = '';
+ this.cvssv3From = '';
+ this.cvssv3To = '';
+ this.occurrencesFrom = '';
+ this.occurrencesTo = '';
+ this.refreshTable();
+ this.initializeWatchers();
+ },
+ refreshTable: function () {
+ this.$refs.table.refresh({
+ url: this.apiUrl(),
+ silent: true,
+ pageNumber: 1,
+ });
+ },
+ cvssv2UpperLimit: function () {
+ return this.cvssv2To ? this.cvssv2To : 10;
+ },
+ cvssv2LowerLimit: function () {
+ return this.cvssv2From ? this.cvssv2From : 0;
+ },
+ cvssv2FromState() {
+ return this.cvssv2From
+ ? !isNaN(this.cvssv2From) &&
+ (!this.cvssv2To ||
+ !isNaN(this.cvssv2To) ||
+ this.cvssv2From <= this.cvssv2To) &&
+ this.cvssv2From <= 10
+ : null;
+ },
+ cvssv2ToState() {
+ return this.cvssv2To
+ ? !isNaN(this.cvssv2To) &&
+ (!this.cvssv2From ||
+ !isNaN(this.cvssv2From) ||
+ this.cvssv2To >= this.cvssv2From) &&
+ this.cvssv2To >= 0
+ : null;
+ },
+ cvssv3UpperLimit: function () {
+ return this.cvssv3To ? this.cvssv3To : 10;
+ },
+ cvssv3LowerLimit: function () {
+ return this.cvssv3From ? this.cvssv3From : 0;
+ },
+ cvssv3FromState() {
+ return this.cvssv3From
+ ? !isNaN(this.cvssv3From) &&
+ (!this.cvssv3To ||
+ !isNaN(this.cvssv3To) ||
+ this.cvssv3From <= this.cvssv3To) &&
+ this.cvssv3From <= 10
+ : null;
+ },
+ cvssv3ToState() {
+ return this.cvssv3To
+ ? !isNaN(this.cvssv3To) &&
+ (!this.cvssv3From ||
+ !isNaN(this.cvssv3From) ||
+ this.cvssv3To >= this.cvssv3From) &&
+ this.cvssv3To >= 0
+ : null;
+ },
+ occurrencesUpperLimit: function () {
+ return this.occurrencesTo ? this.occurrencesTo : null;
+ },
+ occurrencesLowerLimit: function () {
+ return this.occurrencesFrom ? this.occurrencesFrom : 0;
+ },
+ occurrencesFromState: function () {
+ return this.occurrencesFrom
+ ? !isNaN(this.occurrencesFrom) &&
+ (!this.occurrencesTo ||
+ !isNaN(this.occurrencesTo) ||
+ this.occurrencesFrom <= this.occurrencesTo) &&
+ this.cvssv3From >= 0
+ : null;
+ },
+ occurrencesToState: function () {
+ return this.occurrencesTo
+ ? !isNaN(this.occurrencesTo) &&
+ (!this.occurrencesFrom ||
+ !isNaN(this.occurrencesFrom) ||
+ this.occurrencesTo >= this.occurrencesFrom) &&
+ this.cvssv3To >= 0
+ : null;
+ },
+ onLoadSuccess: function () {
+ loadUserPreferencesForBootstrapTable(
+ this,
+ 'VulnerabilityAuditGroupedByVulnerability',
+ this.$refs.table.columns,
+ );
+ },
+ },
};
diff --git a/src/views/modals/InformationalModal.cy.js b/src/views/modals/InformationalModal.cy.js
new file mode 100644
index 000000000..9a6bbe4d9
--- /dev/null
+++ b/src/views/modals/InformationalModal.cy.js
@@ -0,0 +1,31 @@
+import InformationalModal from '@/views/modals/InformationalModal.vue';
+import { shouldShowModal } from '../../../cypress/support/utils';
+
+describe('InformationalModal', () => {
+ it('contains the message', () => {
+ cy.setToken();
+
+ cy.mount(InformationalModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ propsData: {
+ message: 'Foo',
+ },
+ });
+
+ shouldShowModal('modal-informational');
+
+ cy.get('#modal-informational').invoke('css', 'display', 'block');
+ cy.get('#modal-informational').invoke('css', 'opacity', '1');
+ cy.get('#modal-informational').invoke('addClass', 'show');
+
+ cy.get('#modal-informational').should('be.visible');
+
+ cy.get('#modal-informational .modal-content').should('be.visible');
+ cy.get('#modal-informational .modal-content p')
+ .should('be.visible')
+ .should('contain.text', 'Foo');
+ });
+});
diff --git a/src/views/modals/InformationalModal.vue b/src/views/modals/InformationalModal.vue
index a91936428..424e7280b 100644
--- a/src/views/modals/InformationalModal.vue
+++ b/src/views/modals/InformationalModal.vue
@@ -1,6 +1,6 @@
- Information
+ Information
-
+
Close
+ >Close
+
diff --git a/src/views/pages/Page404.cy.js b/src/views/pages/Page404.cy.js
new file mode 100644
index 000000000..523fa6ea5
--- /dev/null
+++ b/src/views/pages/Page404.cy.js
@@ -0,0 +1,7 @@
+import Page404 from './Page404.vue';
+
+describe('Page404', () => {
+ it('mounts successfully', () => {
+ cy.mount(Page404);
+ });
+});
diff --git a/src/views/pages/Page404.vue b/src/views/pages/Page404.vue
index 5d8e9005f..495f32d35 100644
--- a/src/views/pages/Page404.vue
+++ b/src/views/pages/Page404.vue
@@ -8,9 +8,9 @@
{{ $t('404.heading') }}
{{ $t('404.message') }}
- {{
- $t('404.action')
- }}
+ {{ $t('404.action') }}
+
@@ -18,7 +18,13 @@
diff --git a/src/views/pages/PasswordForceChange.cy.js b/src/views/pages/PasswordForceChange.cy.js
new file mode 100644
index 000000000..39a95be0b
--- /dev/null
+++ b/src/views/pages/PasswordForceChange.cy.js
@@ -0,0 +1,13 @@
+import PasswordForceChange from './PasswordForceChange.vue';
+
+describe('PasswordForceChange', () => {
+ it('mounts successfully', () => {
+ cy.mount(PasswordForceChange, {
+ mocks: {
+ $toastr: {
+ s: cy.stub(),
+ },
+ },
+ });
+ });
+});
diff --git a/src/views/pages/PasswordForceChange.vue b/src/views/pages/PasswordForceChange.vue
index f4d987cb5..893fa3990 100644
--- a/src/views/pages/PasswordForceChange.vue
+++ b/src/views/pages/PasswordForceChange.vue
@@ -59,8 +59,8 @@
variant="primary"
class="px-4"
type="submit"
- >{{ $t('message.password_change') }}
+ >{{ $t('message.password_change') }}
+
@@ -77,6 +77,7 @@
@@ -85,24 +86,38 @@
-
+
diff --git a/src/views/policy/PolicyCondition.cy.js b/src/views/policy/PolicyCondition.cy.js
new file mode 100644
index 000000000..3d0bd879f
--- /dev/null
+++ b/src/views/policy/PolicyCondition.cy.js
@@ -0,0 +1,9 @@
+import PolicyCondition from './PolicyCondition.vue';
+
+describe('PolicyCondition', () => {
+ it('mounts successfully', () => {
+ cy.mount(PolicyCondition);
+
+ cy.get('li.list-group-item.align-middle').should('be.visible');
+ });
+});
diff --git a/src/views/policy/PolicyCondition.vue b/src/views/policy/PolicyCondition.vue
index 559c5e046..183158449 100644
--- a/src/views/policy/PolicyCondition.vue
+++ b/src/views/policy/PolicyCondition.vue
@@ -1,14 +1,14 @@
@@ -30,7 +30,7 @@
"
id="input-value"
required="true"
- v-on:change="saveCondition"
+ @change="saveCondition"
v-model="value"
:options="possibleValues"
/>
@@ -152,29 +152,26 @@
diff --git a/src/views/policy/PolicyManagement.cy.js b/src/views/policy/PolicyManagement.cy.js
new file mode 100644
index 000000000..6c5fcc178
--- /dev/null
+++ b/src/views/policy/PolicyManagement.cy.js
@@ -0,0 +1,23 @@
+import PolicyManagement from './PolicyManagement.vue';
+
+describe('PolicyManagement', () => {
+ it('mounts successfully', () => {
+ cy.setToken(['POLICY_MANAGEMENT']);
+
+ cy.mount(PolicyManagement, {
+ prototypeMocks: {
+ $route: {
+ fullPath: '/policy',
+ query: {
+ searchText: '',
+ },
+ },
+ $router: {
+ push: cy.stub(),
+ },
+ },
+ });
+
+ cy.get('div.animated.fadeIn').should('be.visible');
+ });
+});
diff --git a/src/views/policy/PolicyManagement.vue b/src/views/policy/PolicyManagement.vue
index 3cc1cd92b..bdaf73e0c 100644
--- a/src/views/policy/PolicyManagement.vue
+++ b/src/views/policy/PolicyManagement.vue
@@ -11,43 +11,55 @@
active
@click="routeTo()"
>
- {{ $t('message.policies') }}
{{ totalPolicies }}
-
+
-
{{ $t('message.license_groups') }}
{{
totalLicenseGroups
}}
-
+
diff --git a/src/views/policy/SelectLicenseModal.cy.js b/src/views/policy/SelectLicenseModal.cy.js
new file mode 100644
index 000000000..02d14671b
--- /dev/null
+++ b/src/views/policy/SelectLicenseModal.cy.js
@@ -0,0 +1,16 @@
+import { shouldShowModal } from '../../../cypress/support/utils';
+
+import SelectLicenseModal from './SelectLicenseModal.vue';
+
+describe('SelectLicenseModal', () => {
+ it('mounts successfully', () => {
+ cy.mount(SelectLicenseModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ });
+
+ shouldShowModal('selectLicenseModal');
+ });
+});
diff --git a/src/views/policy/SelectLicenseModal.vue b/src/views/policy/SelectLicenseModal.vue
index a61d9fcf7..94e1c3adb 100644
--- a/src/views/policy/SelectLicenseModal.vue
+++ b/src/views/policy/SelectLicenseModal.vue
@@ -13,7 +13,7 @@
:options="options"
>
-
+
{{
$t('message.cancel')
}}
@@ -29,10 +29,17 @@
diff --git a/src/views/portfolio/licenses/License.cy.js b/src/views/portfolio/licenses/License.cy.js
new file mode 100644
index 000000000..e0620114e
--- /dev/null
+++ b/src/views/portfolio/licenses/License.cy.js
@@ -0,0 +1,41 @@
+import License from '@/views/portfolio/licenses/License.vue';
+import { genAxiosResponse } from '/cypress/support/utils';
+
+describe('License', () => {
+ it('mounts successfully', () => {
+ cy.setToken();
+
+ cy.mount(License, {
+ prototypeMocks: {
+ $route: {
+ params: {
+ licenseId: 'test-license',
+ },
+ fullPath: '/licenses/test-license',
+ },
+ $toastr: {
+ s: cy.stub(),
+ w: cy.stub(),
+ },
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/license/test-license': {
+ name: 'License name',
+ licenseId: 'LICENSE-ID',
+ isOsiApproved: true,
+ isFsfLibre: true,
+ isDeprecatedLicenseId: true,
+ isCustomLicense: true,
+ licenseComments: 'License comments',
+ licenseText: 'License text',
+ standardLicenseTemplate: 'License template',
+ standardLicenseHeader: 'License header',
+ },
+ }),
+ },
+ },
+ });
+
+ cy.get('.animated').should('exist');
+ });
+});
diff --git a/src/views/portfolio/licenses/License.vue b/src/views/portfolio/licenses/License.vue
index 854720594..906368865 100644
--- a/src/views/portfolio/licenses/License.vue
+++ b/src/views/portfolio/licenses/License.vue
@@ -11,7 +11,7 @@
active
@click="routeTo()"
>
- {{ $t('message.overview') }}
+ {{ $t('message.overview') }}
{{ $t('message.license_name') }}: |
@@ -66,7 +66,7 @@
@@ -75,19 +75,19 @@
|
- {{ $t('message.license_text') }}
+ {{ $t('message.license_text') }}
{{ license.licenseText }}
- {{ $t('message.template') }}
+ {{ $t('message.template') }}
{{ license.standardLicenseTemplate }}
- {{ $t('message.source_header') }}
+ {{ $t('message.source_header') }}
@@ -104,15 +104,25 @@
diff --git a/src/views/portfolio/licenses/LicenseAddLicenseModal.cy.js b/src/views/portfolio/licenses/LicenseAddLicenseModal.cy.js
new file mode 100644
index 000000000..4b713a1be
--- /dev/null
+++ b/src/views/portfolio/licenses/LicenseAddLicenseModal.cy.js
@@ -0,0 +1,21 @@
+import LicenseAddLicenseModal from '@/views/portfolio/licenses/LicenseAddLicenseModal.vue';
+import { shouldShowModal } from '../../../../cypress/support/utils';
+
+describe('LicenseAddLicenseModal', () => {
+ it('mounts successfully', () => {
+ cy.mount(LicenseAddLicenseModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ prototypeMocks: {
+ $toastr: {
+ s: cy.stub(),
+ w: cy.stub(),
+ },
+ },
+ });
+
+ shouldShowModal('licenseAddLicenseModal');
+ });
+});
diff --git a/src/views/portfolio/licenses/LicenseAddLicenseModal.vue b/src/views/portfolio/licenses/LicenseAddLicenseModal.vue
index 4dc4862d5..bb12a5a32 100644
--- a/src/views/portfolio/licenses/LicenseAddLicenseModal.vue
+++ b/src/views/portfolio/licenses/LicenseAddLicenseModal.vue
@@ -9,7 +9,7 @@
>
- {{ $t('message.general') }}
@@ -80,7 +80,7 @@
-
{{ $t('message.extended') }}
@@ -132,7 +132,7 @@
-
+
{{
$t('message.close')
}}
@@ -146,12 +146,27 @@
diff --git a/src/views/portfolio/projects/Component.cy.js b/src/views/portfolio/projects/Component.cy.js
new file mode 100644
index 000000000..10bda74ec
--- /dev/null
+++ b/src/views/portfolio/projects/Component.cy.js
@@ -0,0 +1,58 @@
+import Component from '@/views/portfolio/projects/Component.vue';
+import { genAxiosResponse } from '/cypress/support/utils';
+
+describe('Component', () => {
+ it('mounts successfully', () => {
+ cy.setToken();
+
+ cy.mount(Component, {
+ prototypeMocks: {
+ $route: {
+ params: {
+ uuid: 'test-uuid',
+ },
+ fullPath: '/components/test-uuid',
+ },
+ $toastr: {
+ w: cy.stub(),
+ },
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/component/test-uuid': {
+ project: {
+ uuid: 'project-uuid',
+ name: 'project-name',
+ version: '1.0.0',
+ },
+ isInternal: false,
+ externalReferences: [],
+ purl: 'purl',
+ name: 'component-name',
+ group: 'com.example',
+ },
+ '/api/v1/metrics/component/test-uuid/current': {
+ critical: 0,
+ high: 0,
+ medium: 0,
+ low: 0,
+ unassigned: 0,
+ inheritedRiskScore: 0,
+ },
+ '/api/v1/metrics/component/test-uuid/days/90': [
+ {
+ critical: 0,
+ high: 0,
+ medium: 0,
+ low: 0,
+ unassigned: 0,
+ inheritedRiskScore: 0,
+ },
+ ],
+ }),
+ },
+ },
+ });
+
+ cy.get('.animated').should('exist');
+ });
+});
diff --git a/src/views/portfolio/projects/Component.vue b/src/views/portfolio/projects/Component.vue
index be1c89482..325e3c6b3 100644
--- a/src/views/portfolio/projects/Component.vue
+++ b/src/views/portfolio/projects/Component.vue
@@ -118,7 +118,7 @@
@@ -136,7 +136,7 @@
active
@click="routeTo()"
>
-
{{ $t('message.overview') }}
@@ -145,7 +145,7 @@
/>
- {{ $t('message.vulnerabilities') }}
{{
totalVulnerabilities
@@ -154,7 +154,7 @@
-
{{ $t('message.projects_also_used_in') }}
@@ -170,7 +170,7 @@
@@ -178,35 +178,70 @@
diff --git a/src/views/portfolio/projects/ComponentCreatePropertyModal.cy.js b/src/views/portfolio/projects/ComponentCreatePropertyModal.cy.js
new file mode 100644
index 000000000..8b7913681
--- /dev/null
+++ b/src/views/portfolio/projects/ComponentCreatePropertyModal.cy.js
@@ -0,0 +1,16 @@
+import { shouldShowModal } from '../../../../cypress/support/utils';
+
+import ComponentCreatePropertyModal from './ComponentCreatePropertyModal.vue';
+
+describe('ComponentCreatePropertyModal', () => {
+ it('mounts successfully', () => {
+ cy.mount(ComponentCreatePropertyModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ });
+
+ shouldShowModal('componentCreatePropertyModal');
+ });
+});
diff --git a/src/views/portfolio/projects/ComponentCreatePropertyModal.vue b/src/views/portfolio/projects/ComponentCreatePropertyModal.vue
index 32ba07194..75c933548 100644
--- a/src/views/portfolio/projects/ComponentCreatePropertyModal.vue
+++ b/src/views/portfolio/projects/ComponentCreatePropertyModal.vue
@@ -55,7 +55,7 @@
>
-
+
{{
$t('message.close')
}}
@@ -67,8 +67,24 @@
diff --git a/src/views/portfolio/projects/ComponentDashboard.cy.js b/src/views/portfolio/projects/ComponentDashboard.cy.js
new file mode 100644
index 000000000..de9ac8f7a
--- /dev/null
+++ b/src/views/portfolio/projects/ComponentDashboard.cy.js
@@ -0,0 +1,34 @@
+import ComponentDashboard from './ComponentDashboard.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('ComponentDashboard', () => {
+ it('mounts successfully', () => {
+ cy.setToken(['PORTFOLIO_MANAGEMENT']);
+
+ cy.mount(ComponentDashboard, {
+ prototypeMocks: {
+ $route: {
+ params: {
+ uuid: '123456-abcdef',
+ },
+ },
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/metrics/component/123456-abcdef/days/90': [
+ {
+ critical: 0,
+ high: 0,
+ medium: 0,
+ low: 0,
+ unassigned: 0,
+ inheritedRiskScore: 0,
+ },
+ ],
+ }),
+ },
+ },
+ });
+
+ cy.get('div').should('be.visible');
+ });
+});
diff --git a/src/views/portfolio/projects/ComponentDashboard.vue b/src/views/portfolio/projects/ComponentDashboard.vue
index f59da26df..301eeeb11 100644
--- a/src/views/portfolio/projects/ComponentDashboard.vue
+++ b/src/views/portfolio/projects/ComponentDashboard.vue
@@ -12,7 +12,7 @@
v-permission="'PORTFOLIO_MANAGEMENT'"
class="font-weight-bold"
style="margin-left: 6px"
- v-on:click="refreshMetrics"
+ @click="refreshMetrics"
>
@@ -21,7 +21,7 @@
diff --git a/src/views/portfolio/projects/ComponentDetailsModal.cy.js b/src/views/portfolio/projects/ComponentDetailsModal.cy.js
new file mode 100644
index 000000000..5f51017cd
--- /dev/null
+++ b/src/views/portfolio/projects/ComponentDetailsModal.cy.js
@@ -0,0 +1,37 @@
+import {
+ genAxiosResponse,
+ shouldShowModal,
+} from '../../../../cypress/support/utils';
+
+import ComponentDetailsModal from './ComponentDetailsModal.vue';
+
+describe('ComponentDetailsModal', () => {
+ it('mounts successfully', () => {
+ cy.setToken();
+
+ cy.mount(ComponentDetailsModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/license/concise': [],
+ }),
+ },
+ },
+ propsData: {
+ component: {
+ name: 'component',
+ version: '1.0.0',
+ supplier: {
+ name: 'supplier',
+ },
+ },
+ },
+ });
+
+ shouldShowModal('componentDetailsModal');
+ });
+});
diff --git a/src/views/portfolio/projects/ComponentDetailsModal.vue b/src/views/portfolio/projects/ComponentDetailsModal.vue
index df25e253e..97e85a391 100644
--- a/src/views/portfolio/projects/ComponentDetailsModal.vue
+++ b/src/views/portfolio/projects/ComponentDetailsModal.vue
@@ -9,7 +9,7 @@
>
- {{ $t('message.identity') }}
@@ -116,7 +116,7 @@
-
{{ $t('message.extended') }}
@@ -155,7 +155,7 @@
-
{{ $t('message.legal') }}
@@ -204,7 +204,7 @@
- {{ $t('message.hashes') }}
@@ -275,7 +275,7 @@
style="border: 0; padding: 0"
v-if="component.supplier"
>
-
{{ $t('message.supplier') }}
@@ -321,7 +321,7 @@
-
{{ $t('message.external_references') }}
@@ -336,7 +336,7 @@
- {{ $t('message.notes') }}
@@ -355,7 +355,7 @@
-
+
diff --git a/src/views/portfolio/projects/ComponentVulnerabilities.cy.js b/src/views/portfolio/projects/ComponentVulnerabilities.cy.js
new file mode 100644
index 000000000..dd16d6df2
--- /dev/null
+++ b/src/views/portfolio/projects/ComponentVulnerabilities.cy.js
@@ -0,0 +1,9 @@
+import ComponentVulnerabilities from './ComponentVulnerabilities.vue';
+
+describe('ComponentVulnerabilities', () => {
+ it('mounts successfully', () => {
+ cy.mount(ComponentVulnerabilities);
+
+ cy.get('div').should('be.visible');
+ });
+});
diff --git a/src/views/portfolio/projects/ComponentVulnerabilities.vue b/src/views/portfolio/projects/ComponentVulnerabilities.vue
index 491438374..8aab26f15 100644
--- a/src/views/portfolio/projects/ComponentVulnerabilities.vue
+++ b/src/views/portfolio/projects/ComponentVulnerabilities.vue
@@ -12,20 +12,20 @@
diff --git a/src/views/portfolio/projects/Project.cy.js b/src/views/portfolio/projects/Project.cy.js
new file mode 100644
index 000000000..3def32dbb
--- /dev/null
+++ b/src/views/portfolio/projects/Project.cy.js
@@ -0,0 +1,52 @@
+/*
+FIXME this test hangs after execution
+import Project from './Project.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('Project', () => {
+ it('mounts successfully', () => {
+ cy.setToken(['VIEW_PORTFOLIO']);
+
+ cy.mount(Project, {
+ prototypeMocks: {
+ $route: {
+ params: {
+ uuid: '123456-abcdef',
+ componentUuids: [],
+ },
+ fullPath: '/projects/123456-abcdef/overview',
+ },
+ $router: {
+ replace: cy.stub(),
+ },
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/metrics/project/123456-abcdef/days/90': [
+ {
+ critical: 0,
+ high: 0,
+ medium: 0,
+ low: 0,
+ unassigned: 0,
+ inheritedRiskScore: 0,
+ },
+ ],
+ '/api/v1/project/123456-abcdef': {
+ name: 'project',
+ },
+ }),
+ },
+ },
+ propsData: {
+ project: {
+ uuid: '123456-abcdef',
+ name: 'project',
+ active: true,
+ },
+ },
+ });
+
+ cy.get('div.animated.fadeIn').should('be.visible');
+ });
+});
+ */
diff --git a/src/views/portfolio/projects/Project.vue b/src/views/portfolio/projects/Project.vue
index 9252d768a..ae3666426 100644
--- a/src/views/portfolio/projects/Project.vue
+++ b/src/views/portfolio/projects/Project.vue
@@ -39,7 +39,10 @@
>
diff --git a/src/views/portfolio/projects/ProjectAddComponentModal.cy.js b/src/views/portfolio/projects/ProjectAddComponentModal.cy.js
new file mode 100644
index 000000000..1b4a71b6f
--- /dev/null
+++ b/src/views/portfolio/projects/ProjectAddComponentModal.cy.js
@@ -0,0 +1,28 @@
+import {
+ genAxiosResponse,
+ shouldShowModal,
+} from '../../../../cypress/support/utils';
+
+import ProjectAddComponentModal from './ProjectAddComponentModal.vue';
+
+describe('ProjectAddComponentModal', () => {
+ it('mounts successfully', () => {
+ cy.mount(ProjectAddComponentModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/configProperty/public/access-management/acl.enabled': {
+ propertyValue: 'false',
+ },
+ }),
+ },
+ },
+ });
+
+ shouldShowModal('projectAddComponentModal');
+ });
+});
diff --git a/src/views/portfolio/projects/ProjectAddComponentModal.vue b/src/views/portfolio/projects/ProjectAddComponentModal.vue
index dd39dcfb2..6cc96d596 100644
--- a/src/views/portfolio/projects/ProjectAddComponentModal.vue
+++ b/src/views/portfolio/projects/ProjectAddComponentModal.vue
@@ -8,7 +8,7 @@
>
- {{ $t('message.identity') }}
@@ -77,7 +77,7 @@
-
{{ $t('message.extended') }}
@@ -113,7 +113,7 @@
-
{{ $t('message.legal') }}
@@ -158,7 +158,7 @@
- {{ $t('message.hashes') }}
@@ -219,7 +219,7 @@
- {{ $t('message.notes') }}
@@ -237,7 +237,7 @@
-
+
{{
$t('message.close')
}}
@@ -253,18 +253,33 @@
diff --git a/src/views/portfolio/projects/ProjectDashboard.cy.js b/src/views/portfolio/projects/ProjectDashboard.cy.js
new file mode 100644
index 000000000..e9aad2615
--- /dev/null
+++ b/src/views/portfolio/projects/ProjectDashboard.cy.js
@@ -0,0 +1,35 @@
+import ProjectDashboard from './ProjectDashboard.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('ProjectDashboard', () => {
+ it('mounts successfully', () => {
+ cy.setToken(['PORTFOLIO_MANAGEMENT']);
+
+ cy.mount(ProjectDashboard, {
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/metrics/project/123456-abcdef/days/90': [
+ {
+ critical: 0,
+ high: 0,
+ medium: 0,
+ low: 0,
+ unassigned: 0,
+ inheritedRiskScore: 0,
+ },
+ ],
+ }),
+ },
+ },
+ propsData: {
+ uuid: '123456-abcdef',
+ project: {
+ collectionLogic: 'NONE',
+ },
+ },
+ });
+
+ cy.get('div.card').should('be.visible');
+ });
+});
diff --git a/src/views/portfolio/projects/ProjectDashboard.vue b/src/views/portfolio/projects/ProjectDashboard.vue
index 84562a541..751c95b0f 100644
--- a/src/views/portfolio/projects/ProjectDashboard.vue
+++ b/src/views/portfolio/projects/ProjectDashboard.vue
@@ -23,7 +23,7 @@
v-permission="'PORTFOLIO_MANAGEMENT'"
class="font-weight-bold"
style="margin-left: 6px"
- v-on:click="refreshMetrics"
+ @click="refreshMetrics"
>
@@ -35,7 +35,7 @@
diff --git a/src/views/portfolio/projects/ProjectDependencyGraph.cy.js b/src/views/portfolio/projects/ProjectDependencyGraph.cy.js
new file mode 100644
index 000000000..d09b389f2
--- /dev/null
+++ b/src/views/portfolio/projects/ProjectDependencyGraph.cy.js
@@ -0,0 +1,23 @@
+import ProjectDependencyGraph from './ProjectDependencyGraph.vue';
+
+describe('ProjectDependencyGraph', () => {
+ it('mounts successfully', () => {
+ cy.mount(ProjectDependencyGraph, {
+ prototypeMocks: {
+ $route: {
+ params: {
+ componentUuids: [],
+ },
+ },
+ },
+ propsData: {
+ uuid: '123456-abcdef',
+ project: {
+ uuid: '123456-abcdef',
+ },
+ },
+ });
+
+ cy.get('div').should('be.visible');
+ });
+});
diff --git a/src/views/portfolio/projects/ProjectDependencyGraph.vue b/src/views/portfolio/projects/ProjectDependencyGraph.vue
index d54c04f33..3b9a00005 100644
--- a/src/views/portfolio/projects/ProjectDependencyGraph.vue
+++ b/src/views/portfolio/projects/ProjectDependencyGraph.vue
@@ -56,43 +56,27 @@
-
diff --git a/src/views/portfolio/projects/ProjectServices.cy.js b/src/views/portfolio/projects/ProjectServices.cy.js
new file mode 100644
index 000000000..1b0ee44c2
--- /dev/null
+++ b/src/views/portfolio/projects/ProjectServices.cy.js
@@ -0,0 +1,9 @@
+import ProjectServices from './ProjectServices.vue';
+
+describe('ProjectServices', () => {
+ it('mounts successfully', () => {
+ cy.mount(ProjectServices);
+
+ cy.get('table').should('be.visible');
+ });
+});
diff --git a/src/views/portfolio/projects/ProjectServices.vue b/src/views/portfolio/projects/ProjectServices.vue
index 28029f151..34a468aa3 100644
--- a/src/views/portfolio/projects/ProjectServices.vue
+++ b/src/views/portfolio/projects/ProjectServices.vue
@@ -14,13 +14,17 @@
diff --git a/src/views/portfolio/projects/Service.cy.js b/src/views/portfolio/projects/Service.cy.js
new file mode 100644
index 000000000..102f588af
--- /dev/null
+++ b/src/views/portfolio/projects/Service.cy.js
@@ -0,0 +1,43 @@
+import Service from './Service.vue';
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+
+describe('Service', () => {
+ it('mounts successfully', () => {
+ cy.setToken(['VIEW_PORTFOLIO']);
+
+ cy.mount(Service, {
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/service/12345-67890-abcdef': {
+ name: 'service name',
+ group: 'service group',
+ description: 'service description',
+ version: '1.0.0',
+ uuid: '12345-67890-abcdef',
+ endpoints: [],
+ data: [],
+ externalReferences: [],
+ project: {
+ uuid: 'abcdef-67890-abcdef',
+ name: 'project name',
+ },
+ provider: {
+ name: 'provider name',
+ urls: [],
+ contacts: [],
+ },
+ },
+ }),
+ },
+ $route: {
+ params: {
+ uuid: '12345-67890-abcdef',
+ },
+ },
+ },
+ });
+
+ cy.get('div.animated.fadeIn').should('be.visible');
+ });
+});
diff --git a/src/views/portfolio/projects/Service.vue b/src/views/portfolio/projects/Service.vue
index fe536a187..550db712c 100644
--- a/src/views/portfolio/projects/Service.vue
+++ b/src/views/portfolio/projects/Service.vue
@@ -108,7 +108,7 @@
style="border-left: 0; border-right: 0; border-top: 0"
active
>
-
{{ $t('message.overview') }}
@@ -119,52 +119,43 @@
diff --git a/src/views/portfolio/projects/ServiceDashboard.cy.js b/src/views/portfolio/projects/ServiceDashboard.cy.js
new file mode 100644
index 000000000..8209ba06b
--- /dev/null
+++ b/src/views/portfolio/projects/ServiceDashboard.cy.js
@@ -0,0 +1,11 @@
+import ServiceDashboard from './ServiceDashboard.vue';
+
+describe('ServiceDashboard', () => {
+ it('mounts successfully', () => {
+ cy.setToken();
+
+ cy.mount(ServiceDashboard);
+
+ cy.get('#chart-portfolio-vulns').should('be.visible');
+ });
+});
diff --git a/src/views/portfolio/projects/ServiceDashboard.vue b/src/views/portfolio/projects/ServiceDashboard.vue
index 892df1e82..7d63d2c66 100644
--- a/src/views/portfolio/projects/ServiceDashboard.vue
+++ b/src/views/portfolio/projects/ServiceDashboard.vue
@@ -12,7 +12,7 @@
v-permission="'PORTFOLIO_MANAGEMENT'"
class="font-weight-bold"
style="margin-left: 6px"
- v-on:click="refreshMetrics"
+ @click="refreshMetrics"
>
@@ -21,7 +21,7 @@
diff --git a/src/views/portfolio/projects/ServiceDetailsModal.cy.js b/src/views/portfolio/projects/ServiceDetailsModal.cy.js
new file mode 100644
index 000000000..0c555344b
--- /dev/null
+++ b/src/views/portfolio/projects/ServiceDetailsModal.cy.js
@@ -0,0 +1,35 @@
+import { shouldShowModal } from '../../../../cypress/support/utils';
+
+import ServiceDetailsModal from './ServiceDetailsModal.vue';
+
+describe('ServiceDetailsModal', () => {
+ it('mounts successfully', () => {
+ cy.setToken();
+
+ cy.mount(ServiceDetailsModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ propsData: {
+ service: {
+ name: 'service name',
+ group: 'service group',
+ description: 'service description',
+ version: '1.0.0',
+ uuid: '12345-67890-abcdef',
+ endpoints: [],
+ data: [],
+ externalReferences: [],
+ provider: {
+ name: 'provider name',
+ urls: [],
+ contacts: [],
+ },
+ },
+ },
+ });
+
+ shouldShowModal('serviceDetailsModal');
+ });
+});
diff --git a/src/views/portfolio/projects/ServiceDetailsModal.vue b/src/views/portfolio/projects/ServiceDetailsModal.vue
index 2c9f215d7..06af6cba0 100644
--- a/src/views/portfolio/projects/ServiceDetailsModal.vue
+++ b/src/views/portfolio/projects/ServiceDetailsModal.vue
@@ -8,7 +8,7 @@
>
- {{ $t('message.identity') }}
@@ -75,7 +75,7 @@
-
{{ $t('message.provider') }}
@@ -120,7 +120,7 @@
- {{ $t('message.endpoints') }}
@@ -134,7 +134,7 @@
- {{ $t('message.data') }}
@@ -148,7 +148,7 @@
-
{{ $t('message.external_references') }}
@@ -163,7 +163,7 @@
-
+
diff --git a/src/views/portfolio/tags/TagList.cy.js b/src/views/portfolio/tags/TagList.cy.js
new file mode 100644
index 000000000..74cb28494
--- /dev/null
+++ b/src/views/portfolio/tags/TagList.cy.js
@@ -0,0 +1,42 @@
+import { genAxiosResponse } from '../../../../cypress/support/utils';
+import TagList from './TagList.vue';
+
+describe('TagList', () => {
+ it('mounts successfully', () => {
+ cy.setToken(['VIEW_PORTFOLIO', 'TAG_MANAGEMENT']);
+
+ cy.intercept('/api/v1/tag', []);
+ cy.mount(TagList, {
+ stubs: {
+ // TODO this component causes the test to hang after execution
+ 'portfolio-widget-row': true,
+ },
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/metrics/portfolio/90/days': [
+ {
+ vulnerabilities: 0,
+ vulnerableComponents: 0,
+ inheritedRiskScore: 0,
+ firstOccurrence: 0,
+ vulnerableProjects: 0,
+ },
+ ],
+ '/api/v1/tag?searchText=&pageSize=10&pageNumber=1': {
+ status: 200,
+ headers: { 'X-Total-Count': '0' },
+ data: [],
+ },
+ }),
+ },
+ $toastr: {
+ s: cy.stub(),
+ w: cy.stub(),
+ },
+ },
+ });
+
+ cy.get('div.animated.fadeIn').should('be.visible');
+ });
+});
diff --git a/src/views/portfolio/tags/TagList.vue b/src/views/portfolio/tags/TagList.vue
index bc5184401..189c9ef9a 100644
--- a/src/views/portfolio/tags/TagList.vue
+++ b/src/views/portfolio/tags/TagList.vue
@@ -13,11 +13,11 @@
diff --git a/src/views/portfolio/tags/TaggedCollectionProjectListModal.cy.js b/src/views/portfolio/tags/TaggedCollectionProjectListModal.cy.js
new file mode 100644
index 000000000..fad004ff5
--- /dev/null
+++ b/src/views/portfolio/tags/TaggedCollectionProjectListModal.cy.js
@@ -0,0 +1,21 @@
+import TaggedCollectionProjectListModal from './TaggedCollectionProjectListModal.vue';
+import { shouldShowModal } from '../../../../cypress/support/utils';
+
+describe('TaggedCollectionProjectListModal', () => {
+ it('mounts successfully', () => {
+ cy.setToken();
+
+ cy.mount(TaggedCollectionProjectListModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ propsData: {
+ tag: 'test-tag',
+ index: 0,
+ },
+ });
+
+ shouldShowModal('taggedCollectionProjectListModal-0');
+ });
+});
diff --git a/src/views/portfolio/tags/TaggedCollectionProjectListModal.vue b/src/views/portfolio/tags/TaggedCollectionProjectListModal.vue
index a432935b2..71272fb1a 100644
--- a/src/views/portfolio/tags/TaggedCollectionProjectListModal.vue
+++ b/src/views/portfolio/tags/TaggedCollectionProjectListModal.vue
@@ -14,7 +14,7 @@
:options="options"
>
-
+
{{ $t('message.cancel') }}
@@ -24,29 +24,24 @@
diff --git a/src/views/portfolio/tags/TaggedNotificationRuleListModal.cy.js b/src/views/portfolio/tags/TaggedNotificationRuleListModal.cy.js
new file mode 100644
index 000000000..0cef8b431
--- /dev/null
+++ b/src/views/portfolio/tags/TaggedNotificationRuleListModal.cy.js
@@ -0,0 +1,21 @@
+import TaggedNotificationRuleListModal from './TaggedNotificationRuleListModal.vue';
+import { shouldShowModal } from '../../../../cypress/support/utils';
+
+describe('TaggedNotificationRuleListModal', () => {
+ it('mounts successfully', () => {
+ cy.setToken();
+
+ cy.mount(TaggedNotificationRuleListModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ propsData: {
+ tag: 'test-tag',
+ index: 0,
+ },
+ });
+
+ shouldShowModal('taggedNotificationRuleListModal-0');
+ });
+});
diff --git a/src/views/portfolio/tags/TaggedNotificationRuleListModal.vue b/src/views/portfolio/tags/TaggedNotificationRuleListModal.vue
index dbc944555..0496c85d2 100644
--- a/src/views/portfolio/tags/TaggedNotificationRuleListModal.vue
+++ b/src/views/portfolio/tags/TaggedNotificationRuleListModal.vue
@@ -14,7 +14,7 @@
:options="options"
>
-
+
{{
$t('message.cancel')
}}
@@ -24,47 +24,22 @@
diff --git a/src/views/portfolio/tags/TaggedPoliciesListModal.js b/src/views/portfolio/tags/TaggedPoliciesListModal.js
new file mode 100644
index 000000000..553a3c7fe
--- /dev/null
+++ b/src/views/portfolio/tags/TaggedPoliciesListModal.js
@@ -0,0 +1,21 @@
+import TaggedPoliciesListModal from '@/views/portfolio/tags/TaggedPoliciesListModal.vue';
+import { shouldShowModal } from '../../../../cypress/support/utils';
+
+describe('TaggedPoliciesListModal', () => {
+ it('mounts successfully', () => {
+ cy.setToken();
+
+ cy.mount(TaggedPoliciesListModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ propsData: {
+ tag: 'test-tag',
+ index: 0,
+ },
+ });
+
+ shouldShowModal('taggedPoliciesListModal-0');
+ });
+});
diff --git a/src/views/portfolio/tags/TaggedPoliciesListModal.vue b/src/views/portfolio/tags/TaggedPoliciesListModal.vue
index bb11d45b5..9e58bde66 100644
--- a/src/views/portfolio/tags/TaggedPoliciesListModal.vue
+++ b/src/views/portfolio/tags/TaggedPoliciesListModal.vue
@@ -14,7 +14,7 @@
:options="options"
>
-
+
{{
$t('message.cancel')
}}
@@ -24,47 +24,22 @@
diff --git a/src/views/portfolio/tags/TaggedProjectListModal.cy.js b/src/views/portfolio/tags/TaggedProjectListModal.cy.js
new file mode 100644
index 000000000..8d0839d4d
--- /dev/null
+++ b/src/views/portfolio/tags/TaggedProjectListModal.cy.js
@@ -0,0 +1,21 @@
+import TaggedProjectListModal from '@/views/portfolio/tags/TaggedProjectListModal.vue';
+import { shouldShowModal } from '../../../../cypress/support/utils';
+
+describe('TaggedProjectListModal', () => {
+ it('mounts successfully', () => {
+ cy.setToken();
+
+ cy.mount(TaggedProjectListModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ propsData: {
+ tag: 'test-tag',
+ index: 0,
+ },
+ });
+
+ shouldShowModal('taggedProjectListModal-0');
+ });
+});
diff --git a/src/views/portfolio/tags/TaggedProjectListModal.vue b/src/views/portfolio/tags/TaggedProjectListModal.vue
index 3be1ff7c0..7311bb1d1 100644
--- a/src/views/portfolio/tags/TaggedProjectListModal.vue
+++ b/src/views/portfolio/tags/TaggedProjectListModal.vue
@@ -14,7 +14,7 @@
:options="options"
>
-
+
{{ $t('message.cancel') }}
@@ -24,49 +24,24 @@
diff --git a/src/views/portfolio/vulnerabilities/AddAffectedComponentModal.cy.js b/src/views/portfolio/vulnerabilities/AddAffectedComponentModal.cy.js
new file mode 100644
index 000000000..04a674087
--- /dev/null
+++ b/src/views/portfolio/vulnerabilities/AddAffectedComponentModal.cy.js
@@ -0,0 +1,17 @@
+import AddAffectedComponentModal from './AddAffectedComponentModal.vue';
+import { shouldShowModal } from '../../../../cypress/support/utils';
+
+describe('AddAffectedComponentModal', () => {
+ it('mounts successfully', () => {
+ cy.setToken(['VULNERABILITY_MANAGEMENT']);
+
+ cy.mount(AddAffectedComponentModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ });
+
+ shouldShowModal('addAffectedComponentModal');
+ });
+});
diff --git a/src/views/portfolio/vulnerabilities/AddAffectedComponentModal.vue b/src/views/portfolio/vulnerabilities/AddAffectedComponentModal.vue
index 3941e36d0..028e8dd24 100644
--- a/src/views/portfolio/vulnerabilities/AddAffectedComponentModal.vue
+++ b/src/views/portfolio/vulnerabilities/AddAffectedComponentModal.vue
@@ -77,7 +77,7 @@
-
+
{{
$t('message.cancel')
}}
@@ -89,18 +89,21 @@
diff --git a/src/views/portfolio/vulnerabilities/SelectCweModal.cy.js b/src/views/portfolio/vulnerabilities/SelectCweModal.cy.js
new file mode 100644
index 000000000..c17317c66
--- /dev/null
+++ b/src/views/portfolio/vulnerabilities/SelectCweModal.cy.js
@@ -0,0 +1,17 @@
+import SelectCweModal from './SelectCweModal.vue';
+import { shouldShowModal } from '../../../../cypress/support/utils';
+
+describe('SelectCweModal', () => {
+ it('mounts successfully', () => {
+ cy.setToken(['VULNERABILITY_MANAGEMENT']);
+
+ cy.mount(SelectCweModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ });
+
+ shouldShowModal('selectCweModal');
+ });
+});
diff --git a/src/views/portfolio/vulnerabilities/SelectCweModal.vue b/src/views/portfolio/vulnerabilities/SelectCweModal.vue
index e2cbfcaa2..12c0c7b2a 100644
--- a/src/views/portfolio/vulnerabilities/SelectCweModal.vue
+++ b/src/views/portfolio/vulnerabilities/SelectCweModal.vue
@@ -12,7 +12,7 @@
:options="options"
>
-
+
{{
$t('message.cancel')
}}
@@ -28,10 +28,17 @@
diff --git a/src/views/portfolio/vulnerabilities/VulnerabilityCreateVulnerabilityModal.cy.js b/src/views/portfolio/vulnerabilities/VulnerabilityCreateVulnerabilityModal.cy.js
new file mode 100644
index 000000000..8c9e2333c
--- /dev/null
+++ b/src/views/portfolio/vulnerabilities/VulnerabilityCreateVulnerabilityModal.cy.js
@@ -0,0 +1,25 @@
+import VulnerabilityCreateVulnerabilityModal from './VulnerabilityCreateVulnerabilityModal.vue';
+import {
+ genAxiosResponse,
+ shouldShowModal,
+} from '../../../../cypress/support/utils';
+
+describe('VulnerabilityCreateVulnerabilityModal', () => {
+ it('mounts successfully', () => {
+ cy.mount(VulnerabilityCreateVulnerabilityModal, {
+ attachTo: document.body,
+ stubs: {
+ transition: false,
+ },
+ prototypeMocks: {
+ axios: {
+ get: genAxiosResponse({
+ '/api/v1/vulnerability/vulnId': 'CVE-123-456',
+ }),
+ },
+ },
+ });
+
+ shouldShowModal('vulnerabilityCreateVulnerabilityModal');
+ });
+});
diff --git a/src/views/portfolio/vulnerabilities/VulnerabilityCreateVulnerabilityModal.vue b/src/views/portfolio/vulnerabilities/VulnerabilityCreateVulnerabilityModal.vue
index 5cfbc842d..f4edcf9f4 100644
--- a/src/views/portfolio/vulnerabilities/VulnerabilityCreateVulnerabilityModal.vue
+++ b/src/views/portfolio/vulnerabilities/VulnerabilityCreateVulnerabilityModal.vue
@@ -9,7 +9,7 @@
>
- {{ $t('message.general') }}
@@ -79,16 +79,16 @@
-
+
@@ -108,7 +108,7 @@
-
{{ $t('message.extended') }}
@@ -149,7 +149,7 @@
-
{{ $t('message.cvss_v2') }}
@@ -214,7 +214,7 @@
:options="cvssv2Options.av"
:aria-describedby="cvssv2AttackVector"
name="radios-btn-default"
- v-on:change="generateCvssV2Vector"
+ @change="generateCvssV2Vector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-3-btn"
buttons
@@ -229,7 +229,7 @@
:options="cvssv2Options.ac"
:aria-describedby="cvssv2AccessComplexity"
name="radios-btn-default"
- v-on:change="generateCvssV2Vector"
+ @change="generateCvssV2Vector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-3-btn"
buttons
@@ -244,7 +244,7 @@
:options="cvssv2Options.au"
:aria-describedby="cvssv2Authentication"
name="radios-btn-default"
- v-on:change="generateCvssV2Vector"
+ @change="generateCvssV2Vector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-3-btn"
buttons
@@ -261,7 +261,7 @@
:options="cvssv2Options.c"
:aria-describedby="cvssv2ConfidentialityImpact"
name="radios-btn-default"
- v-on:change="generateCvssV2Vector"
+ @change="generateCvssV2Vector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-3-btn"
buttons
@@ -276,7 +276,7 @@
:options="cvssv2Options.i"
:aria-describedby="cvssv2IntegrityImpact"
name="radios-btn-default"
- v-on:change="generateCvssV2Vector"
+ @change="generateCvssV2Vector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-3-btn"
buttons
@@ -291,7 +291,7 @@
:options="cvssv2Options.a"
:aria-describedby="cvssv2AvailabilityImpact"
name="radios-btn-default"
- v-on:change="generateCvssV2Vector"
+ @change="generateCvssV2Vector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-3-btn"
buttons
@@ -302,7 +302,7 @@
-
{{ $t('message.cvss_v3') }}
@@ -367,7 +367,7 @@
:options="cvssv3Options.av"
:aria-describedby="cvssv3AttackVector"
name="radios-btn-default"
- v-on:change="generateCvssV3Vector"
+ @change="generateCvssV3Vector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-4-btn"
buttons
@@ -382,7 +382,7 @@
:options="cvssv3Options.ac"
:aria-describedby="cvssv3AttackComplexity"
name="radios-btn-default"
- v-on:change="generateCvssV3Vector"
+ @change="generateCvssV3Vector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -397,7 +397,7 @@
:options="cvssv3Options.pr"
:aria-describedby="cvssv3PrivilegesRequired"
name="radios-btn-default"
- v-on:change="generateCvssV3Vector"
+ @change="generateCvssV3Vector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-3-btn"
buttons
@@ -412,7 +412,7 @@
:options="cvssv3Options.ui"
:aria-describedby="cvssv3UserInteraction"
name="radios-btn-default"
- v-on:change="generateCvssV3Vector"
+ @change="generateCvssV3Vector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -429,7 +429,7 @@
:options="cvssv3Options.s"
:aria-describedby="cvssv3Scope"
name="radios-btn-default"
- v-on:change="generateCvssV3Vector"
+ @change="generateCvssV3Vector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -444,7 +444,7 @@
:options="cvssv3Options.c"
:aria-describedby="cvssv3ConfidentialityImpact"
name="radios-btn-default"
- v-on:change="generateCvssV3Vector"
+ @change="generateCvssV3Vector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-3-btn"
buttons
@@ -459,7 +459,7 @@
:options="cvssv3Options.i"
:aria-describedby="cvssv3IntegrityImpact"
name="radios-btn-default"
- v-on:change="generateCvssV3Vector"
+ @change="generateCvssV3Vector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-3-btn"
buttons
@@ -474,7 +474,7 @@
:options="cvssv3Options.a"
:aria-describedby="cvssv3AvailabilityImpact"
name="radios-btn-default"
- v-on:change="generateCvssV3Vector"
+ @change="generateCvssV3Vector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-3-btn"
buttons
@@ -485,7 +485,7 @@
-
{{ $t('message.owasp_rr') }}
@@ -559,7 +559,7 @@
:options="owaspRROptions.sl"
:aria-describedby="owaspRRSkillLevel"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-4-btn"
buttons
@@ -574,7 +574,7 @@
:options="owaspRROptions.m"
:aria-describedby="owaspRRMotivation"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-4-btn"
buttons
@@ -589,7 +589,7 @@
:options="owaspRROptions.o"
:aria-describedby="owaspRROpportunity"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-4-btn"
buttons
@@ -604,7 +604,7 @@
:options="owaspRROptions.s"
:aria-describedby="owaspRRThreatSize"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-4-btn"
buttons
@@ -622,7 +622,7 @@
:options="owaspRROptions.ed"
:aria-describedby="owaspRREaseOfDiscovery"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -637,7 +637,7 @@
:options="owaspRROptions.ee"
:aria-describedby="owaspRREaseOfExploit"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -652,7 +652,7 @@
:options="owaspRROptions.a"
:aria-describedby="owaspRRAwareness"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -667,7 +667,7 @@
:options="owaspRROptions.id"
:aria-describedby="owaspRRIntrusionDetection"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -685,7 +685,7 @@
:options="owaspRROptions.lc"
:aria-describedby="owaspRRLossOfConfidentiality"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -700,7 +700,7 @@
:options="owaspRROptions.li"
:aria-describedby="owaspRRLossOfIntegrity"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -715,7 +715,7 @@
:options="owaspRROptions.lav"
:aria-describedby="owaspRRLossOfAvailibility"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -730,7 +730,7 @@
:options="owaspRROptions.lac"
:aria-describedby="owaspRRLossOfAccountability"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -748,7 +748,7 @@
:options="owaspRROptions.fd"
:aria-describedby="owaspRRFinancialDamage"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -763,7 +763,7 @@
:options="owaspRROptions.rd"
:aria-describedby="owaspRRReputationDamage"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -778,7 +778,7 @@
:options="owaspRROptions.nc"
:aria-describedby="owaspRRNonCompliance"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -793,7 +793,7 @@
:options="owaspRROptions.pv"
:aria-describedby="owaspRRPrivacyViolation"
name="radios-btn-default"
- v-on:change="generateOwaspRRVector"
+ @change="generateOwaspRRVector"
button-variant="outline-primary"
class="cvss-calc cvss-calc-2-btn"
buttons
@@ -804,7 +804,7 @@
-
{{ $t('message.affected_components') }}
@@ -820,19 +820,18 @@
"
>
@@ -841,7 +840,7 @@
- {{ $t('message.dates') }}
@@ -884,7 +883,7 @@
-
+
{{
$t('message.close')
}}
@@ -892,32 +891,39 @@
$t('message.create')
}}
-
+