Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipa Lacerda <filipa@gitlab.com>2018-08-07 18:06:38 +0300
committerFilipa Lacerda <filipa@gitlab.com>2018-08-07 18:06:38 +0300
commitbcdc6f31195f176c6256c2960e6b87e56b62b522 (patch)
treed48daf07ceb830ab4deca120ee51893f88cede05 /spec/javascripts/reports
parentbf699ff49860aa186dc485a91f9b04081b346549 (diff)
Moves report components to reports folder
Diffstat (limited to 'spec/javascripts/reports')
-rw-r--r--spec/javascripts/reports/components/modal_open_name_spec.js45
-rw-r--r--spec/javascripts/reports/components/report_link_spec.js71
-rw-r--r--spec/javascripts/reports/components/report_section_spec.js197
-rw-r--r--spec/javascripts/reports/components/summary_row_spec.js37
4 files changed, 350 insertions, 0 deletions
diff --git a/spec/javascripts/reports/components/modal_open_name_spec.js b/spec/javascripts/reports/components/modal_open_name_spec.js
new file mode 100644
index 00000000000..b18b3ef03d1
--- /dev/null
+++ b/spec/javascripts/reports/components/modal_open_name_spec.js
@@ -0,0 +1,45 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import component from '~/reports/components/modal_open_name.vue';
+import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+
+describe('Modal open name', () => {
+ const Component = Vue.extend(component);
+ let vm;
+
+ const store = new Vuex.Store({
+ actions: {
+ openModal: () => {},
+ },
+ state: {},
+ mutations: {},
+ });
+
+ beforeEach(() => {
+ vm = mountComponentWithStore(Component, {
+ store,
+ props: {
+ issue: {
+ title: 'Issue',
+ },
+ status: 'failed',
+ },
+ });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders the issue name', () => {
+ expect(vm.$el.textContent.trim()).toEqual('Issue');
+ });
+
+ it('calls openModal actions when button is clicked', () => {
+ spyOn(vm, 'openModal');
+
+ vm.$el.click();
+
+ expect(vm.openModal).toHaveBeenCalled();
+ });
+});
diff --git a/spec/javascripts/reports/components/report_link_spec.js b/spec/javascripts/reports/components/report_link_spec.js
new file mode 100644
index 00000000000..cd6911e2f59
--- /dev/null
+++ b/spec/javascripts/reports/components/report_link_spec.js
@@ -0,0 +1,71 @@
+import Vue from 'vue';
+import component from '~/reports/components/report_link.vue';
+import mountComponent from '../../helpers/vue_mount_component_helper';
+
+describe('report link', () => {
+ let vm;
+
+ const Component = Vue.extend(component);
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('With url', () => {
+ it('renders link', () => {
+ vm = mountComponent(Component, {
+ issue: {
+ path: 'Gemfile.lock',
+ urlPath: '/Gemfile.lock',
+ },
+ });
+
+ expect(vm.$el.textContent.trim()).toContain('in');
+ expect(vm.$el.querySelector('a').getAttribute('href')).toEqual('/Gemfile.lock');
+ expect(vm.$el.querySelector('a').textContent.trim()).toEqual('Gemfile.lock');
+ });
+ });
+
+ describe('Without url', () => {
+ it('does not render link', () => {
+ vm = mountComponent(Component, {
+ issue: {
+ path: 'Gemfile.lock',
+ },
+ });
+
+ expect(vm.$el.querySelector('a')).toBeNull();
+ expect(vm.$el.textContent.trim()).toContain('in');
+ expect(vm.$el.textContent.trim()).toContain('Gemfile.lock');
+ });
+ });
+
+ describe('with line', () => {
+ it('renders line number', () => {
+ vm = mountComponent(Component, {
+ issue: {
+ path: 'Gemfile.lock',
+ urlPath:
+ 'https://groups.google.com/forum/#!topic/rubyonrails-security/335P1DcLG00',
+ line: 22,
+ },
+ });
+
+ expect(vm.$el.querySelector('a').textContent.trim()).toContain('Gemfile.lock:22');
+ });
+ });
+
+ describe('without line', () => {
+ it('does not render line number', () => {
+ vm = mountComponent(Component, {
+ issue: {
+ path: 'Gemfile.lock',
+ urlPath:
+ 'https://groups.google.com/forum/#!topic/rubyonrails-security/335P1DcLG00',
+ },
+ });
+
+ expect(vm.$el.querySelector('a').textContent.trim()).not.toContain(':22');
+ });
+ });
+});
diff --git a/spec/javascripts/reports/components/report_section_spec.js b/spec/javascripts/reports/components/report_section_spec.js
new file mode 100644
index 00000000000..6f6eb161d14
--- /dev/null
+++ b/spec/javascripts/reports/components/report_section_spec.js
@@ -0,0 +1,197 @@
+import Vue from 'vue';
+import reportSection from '~/reports/components/report_section.vue';
+import mountComponent, { mountComponentWithSlots } from 'spec/helpers/vue_mount_component_helper';
+
+describe('Report section', () => {
+ let vm;
+ const ReportSection = Vue.extend(reportSection);
+
+ const resolvedIssues = [
+ {
+ name: 'Insecure Dependency',
+ fingerprint: 'ca2e59451e98ae60ba2f54e3857c50e5',
+ path: 'Gemfile.lock',
+ line: 12,
+ urlPath: 'foo/Gemfile.lock',
+ },
+ ];
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('computed', () => {
+ beforeEach(() => {
+ vm = mountComponent(ReportSection, {
+ component: '',
+ status: 'SUCCESS',
+ loadingText: 'Loading codeclimate report',
+ errorText: 'foo',
+ successText: 'Code quality improved on 1 point and degraded on 1 point',
+ resolvedIssues,
+ hasIssues: false,
+ alwaysOpen: false,
+ });
+ });
+
+ describe('isCollapsible', () => {
+ const testMatrix = [
+ { hasIssues: false, alwaysOpen: false, isCollapsible: false },
+ { hasIssues: false, alwaysOpen: true, isCollapsible: false },
+ { hasIssues: true, alwaysOpen: false, isCollapsible: true },
+ { hasIssues: true, alwaysOpen: true, isCollapsible: false },
+ ];
+
+ testMatrix.forEach(({ hasIssues, alwaysOpen, isCollapsible }) => {
+ const issues = hasIssues ? 'has issues' : 'has no issues';
+ const open = alwaysOpen ? 'is always open' : 'is not always open';
+
+ it(`is ${isCollapsible}, if the report ${issues} and ${open}`, done => {
+ vm.hasIssues = hasIssues;
+ vm.alwaysOpen = alwaysOpen;
+
+ Vue.nextTick()
+ .then(() => {
+ expect(vm.isCollapsible).toBe(isCollapsible);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+ });
+
+ describe('isExpanded', () => {
+ const testMatrix = [
+ { isCollapsed: false, alwaysOpen: false, isExpanded: true },
+ { isCollapsed: false, alwaysOpen: true, isExpanded: true },
+ { isCollapsed: true, alwaysOpen: false, isExpanded: false },
+ { isCollapsed: true, alwaysOpen: true, isExpanded: true },
+ ];
+
+ testMatrix.forEach(({ isCollapsed, alwaysOpen, isExpanded }) => {
+ const issues = isCollapsed ? 'is collapsed' : 'is not collapsed';
+ const open = alwaysOpen ? 'is always open' : 'is not always open';
+
+ it(`is ${isExpanded}, if the report ${issues} and ${open}`, done => {
+ vm.isCollapsed = isCollapsed;
+ vm.alwaysOpen = alwaysOpen;
+
+ Vue.nextTick()
+ .then(() => {
+ expect(vm.isExpanded).toBe(isExpanded);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+ });
+ });
+ describe('when it is loading', () => {
+ it('should render loading indicator', () => {
+ vm = mountComponent(ReportSection, {
+ component: '',
+ status: 'LOADING',
+ loadingText: 'Loading codeclimate report',
+ errorText: 'foo',
+ successText: 'Code quality improved on 1 point and degraded on 1 point',
+ hasIssues: false,
+ });
+ expect(vm.$el.textContent.trim()).toEqual('Loading codeclimate report');
+ });
+ });
+
+ describe('with success status', () => {
+ beforeEach(() => {
+ vm = mountComponent(ReportSection, {
+ component: '',
+ status: 'SUCCESS',
+ loadingText: 'Loading codeclimate report',
+ errorText: 'foo',
+ successText: 'Code quality improved on 1 point and degraded on 1 point',
+ resolvedIssues,
+ hasIssues: true,
+ });
+ });
+
+ it('should render provided data', () => {
+ expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
+ 'Code quality improved on 1 point and degraded on 1 point',
+ );
+
+ expect(vm.$el.querySelectorAll('.js-mr-code-resolved-issues li').length).toEqual(
+ resolvedIssues.length,
+ );
+ });
+
+ describe('toggleCollapsed', () => {
+ const hiddenCss = { display: 'none' };
+
+ it('toggles issues', done => {
+ vm.$el.querySelector('button').click();
+
+ Vue.nextTick()
+ .then(() => {
+ expect(vm.$el.querySelector('.js-report-section-container')).not.toHaveCss(hiddenCss);
+ expect(vm.$el.querySelector('button').textContent.trim()).toEqual('Collapse');
+
+ vm.$el.querySelector('button').click();
+ })
+ .then(Vue.nextTick)
+ .then(() => {
+ expect(vm.$el.querySelector('.js-report-section-container')).toHaveCss(hiddenCss);
+ expect(vm.$el.querySelector('button').textContent.trim()).toEqual('Expand');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('is always expanded, if always-open is set to true', done => {
+ vm.alwaysOpen = true;
+ Vue.nextTick()
+ .then(() => {
+ expect(vm.$el.querySelector('.js-report-section-container')).not.toHaveCss(hiddenCss);
+ expect(vm.$el.querySelector('button')).toBeNull();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+ });
+
+ describe('with failed request', () => {
+ it('should render error indicator', () => {
+ vm = mountComponent(ReportSection, {
+ component: '',
+ status: 'ERROR',
+ loadingText: 'Loading codeclimate report',
+ errorText: 'Failed to load codeclimate report',
+ successText: 'Code quality improved on 1 point and degraded on 1 point',
+ hasIssues: false,
+ });
+ expect(vm.$el.textContent.trim()).toEqual('Failed to load codeclimate report');
+ });
+ });
+
+ describe('with action buttons passed to the slot', () => {
+ beforeEach(() => {
+ vm = mountComponentWithSlots(ReportSection, {
+ props: {
+ status: 'SUCCESS',
+ successText: 'success',
+ hasIssues: true,
+ },
+ slots: {
+ actionButtons: ['Action!'],
+ },
+ });
+ });
+
+ it('should render the passed button', () => {
+ expect(vm.$el.textContent.trim()).toContain('Action!');
+ });
+
+ it('should still render the expand/collapse button', () => {
+ expect(vm.$el.querySelector('.js-collapse-btn').textContent.trim()).toEqual('Expand');
+ });
+ });
+});
diff --git a/spec/javascripts/reports/components/summary_row_spec.js b/spec/javascripts/reports/components/summary_row_spec.js
new file mode 100644
index 00000000000..fab7693581c
--- /dev/null
+++ b/spec/javascripts/reports/components/summary_row_spec.js
@@ -0,0 +1,37 @@
+import Vue from 'vue';
+import component from '~/reports/components/summary_row.vue';
+import mountComponent from 'spec/helpers/vue_mount_component_helper';
+
+describe('Summary row', () => {
+ const Component = Vue.extend(component);
+ let vm;
+
+ const props = {
+ summary: 'SAST detected 1 new vulnerability and 1 fixed vulnerability',
+ popoverOptions: {
+ title: 'Static Application Security Testing (SAST)',
+ content: '<a>Learn more about SAST</a>',
+ },
+ statusIcon: 'warning',
+ };
+
+ beforeEach(() => {
+ vm = mountComponent(Component, props);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders provided summary', () => {
+ expect(
+ vm.$el.querySelector('.report-block-list-issue-description-text').textContent.trim(),
+ ).toEqual(props.summary);
+ });
+
+ it('renders provided icon', () => {
+ expect(vm.$el.querySelector('.report-block-list-icon span').classList).toContain(
+ 'js-ci-status-icon-warning',
+ );
+ });
+});