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
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-05 18:08:48 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-05 18:08:48 +0300
commiteabf8fd774fef6a54903e5141138f47bdafeb331 (patch)
treec74ff99fa6765cbe091767e9827374ce44b0df50 /spec
parent20d564f1064622ef0623434372ac3ceb03173331 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/frontend/environments/environment_actions_spec.js124
-rw-r--r--spec/frontend/repository/router_spec.js1
-rw-r--r--spec/javascripts/environments/environment_actions_spec.js117
-rw-r--r--spec/javascripts/vue_shared/components/bar_chart_spec.js79
-rw-r--r--spec/lib/quality/test_level_spec.rb4
-rw-r--r--spec/models/sentry_issue_spec.rb29
6 files changed, 150 insertions, 204 deletions
diff --git a/spec/frontend/environments/environment_actions_spec.js b/spec/frontend/environments/environment_actions_spec.js
new file mode 100644
index 00000000000..4c06e19cec0
--- /dev/null
+++ b/spec/frontend/environments/environment_actions_spec.js
@@ -0,0 +1,124 @@
+import { shallowMount } from '@vue/test-utils';
+import { TEST_HOST } from 'helpers/test_constants';
+import eventHub from '~/environments/event_hub';
+import EnvironmentActions from '~/environments/components/environment_actions.vue';
+import Icon from '~/vue_shared/components/icon.vue';
+import { GlLoadingIcon } from '@gitlab/ui';
+
+describe('EnvironmentActions Component', () => {
+ let vm;
+
+ beforeEach(() => {
+ vm = shallowMount(EnvironmentActions, { propsData: { actions: [] } });
+ });
+
+ afterEach(() => {
+ vm.destroy();
+ });
+
+ it('should render a dropdown button with 2 icons', () => {
+ expect(vm.find('.dropdown-new').findAll(Icon).length).toBe(2);
+ });
+
+ it('should render a dropdown button with aria-label description', () => {
+ expect(vm.find('.dropdown-new').attributes('aria-label')).toEqual('Deploy to...');
+ });
+
+ describe('is loading', () => {
+ beforeEach(() => {
+ vm.setData({ isLoading: true });
+ });
+
+ it('should render a dropdown button with a loading icon', () => {
+ expect(vm.findAll(GlLoadingIcon).length).toBe(1);
+ });
+ });
+
+ describe('manual actions', () => {
+ const actions = [
+ {
+ name: 'bar',
+ play_path: 'https://gitlab.com/play',
+ },
+ {
+ name: 'foo',
+ play_path: '#',
+ },
+ {
+ name: 'foo bar',
+ play_path: 'url',
+ playable: false,
+ },
+ ];
+
+ beforeEach(() => {
+ vm.setProps({ actions });
+ });
+
+ it('should render a dropdown with the provided list of actions', () => {
+ expect(vm.findAll('.dropdown-menu li').length).toEqual(actions.length);
+ });
+
+ it("should render a disabled action when it's not playable", () => {
+ expect(vm.find('.dropdown-menu li:last-child button').attributes('disabled')).toEqual(
+ 'disabled',
+ );
+
+ expect(vm.find('.dropdown-menu li:last-child button').classes('disabled')).toBe(true);
+ });
+ });
+
+ describe('scheduled jobs', () => {
+ const scheduledJobAction = {
+ name: 'scheduled action',
+ playPath: `${TEST_HOST}/scheduled/job/action`,
+ playable: true,
+ scheduledAt: '2063-04-05T00:42:00Z',
+ };
+ const expiredJobAction = {
+ name: 'expired action',
+ playPath: `${TEST_HOST}/expired/job/action`,
+ playable: true,
+ scheduledAt: '2018-10-05T08:23:00Z',
+ };
+ const findDropdownItem = action => {
+ const buttons = vm.findAll('.dropdown-menu li button');
+ return buttons.filter(button => button.text().startsWith(action.name)).at(0);
+ };
+
+ beforeEach(() => {
+ jest.spyOn(Date, 'now').mockImplementation(() => new Date('2063-04-04T00:42:00Z').getTime());
+ vm.setProps({ actions: [scheduledJobAction, expiredJobAction] });
+ });
+
+ it('emits postAction event after confirming', () => {
+ const emitSpy = jest.fn();
+ eventHub.$on('postAction', emitSpy);
+ jest.spyOn(window, 'confirm').mockImplementation(() => true);
+
+ findDropdownItem(scheduledJobAction).trigger('click');
+
+ expect(window.confirm).toHaveBeenCalled();
+ expect(emitSpy).toHaveBeenCalledWith({ endpoint: scheduledJobAction.playPath });
+ });
+
+ it('does not emit postAction event if confirmation is cancelled', () => {
+ const emitSpy = jest.fn();
+ eventHub.$on('postAction', emitSpy);
+ jest.spyOn(window, 'confirm').mockImplementation(() => false);
+
+ findDropdownItem(scheduledJobAction).trigger('click');
+
+ expect(window.confirm).toHaveBeenCalled();
+ expect(emitSpy).not.toHaveBeenCalled();
+ });
+
+ it('displays the remaining time in the dropdown', () => {
+ expect(findDropdownItem(scheduledJobAction).text()).toContain('24:00:00');
+ });
+
+ it('displays 00:00:00 for expired jobs in the dropdown', () => {
+ expect(findDropdownItem(expiredJobAction).text()).toContain('00:00:00');
+ });
+ });
+});
diff --git a/spec/frontend/repository/router_spec.js b/spec/frontend/repository/router_spec.js
index 1efd74a30c2..8f3ac53c37a 100644
--- a/spec/frontend/repository/router_spec.js
+++ b/spec/frontend/repository/router_spec.js
@@ -6,6 +6,7 @@ describe('Repository router spec', () => {
it.each`
path | component | componentName
${'/'} | ${IndexPage} | ${'IndexPage'}
+ ${'/tree/master'} | ${TreePage} | ${'TreePage'}
${'/-/tree/master'} | ${TreePage} | ${'TreePage'}
${'/-/tree/master/app/assets'} | ${TreePage} | ${'TreePage'}
${'/-/tree/123/app/assets'} | ${null} | ${'null'}
diff --git a/spec/javascripts/environments/environment_actions_spec.js b/spec/javascripts/environments/environment_actions_spec.js
deleted file mode 100644
index a844660f7bf..00000000000
--- a/spec/javascripts/environments/environment_actions_spec.js
+++ /dev/null
@@ -1,117 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import { TEST_HOST } from 'spec/test_constants';
-import eventHub from '~/environments/event_hub';
-import EnvironmentActions from '~/environments/components/environment_actions.vue';
-
-describe('EnvironmentActions Component', () => {
- const Component = Vue.extend(EnvironmentActions);
- let vm;
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('manual actions', () => {
- const actions = [
- {
- name: 'bar',
- play_path: 'https://gitlab.com/play',
- },
- {
- name: 'foo',
- play_path: '#',
- },
- {
- name: 'foo bar',
- play_path: 'url',
- playable: false,
- },
- ];
-
- beforeEach(() => {
- vm = mountComponent(Component, { actions });
- });
-
- it('should render a dropdown button with icon and title attribute', () => {
- expect(vm.$el.querySelector('.fa-caret-down')).toBeDefined();
- expect(vm.$el.querySelector('.dropdown-new').getAttribute('data-original-title')).toEqual(
- 'Deploy to...',
- );
-
- expect(vm.$el.querySelector('.dropdown-new').getAttribute('aria-label')).toEqual(
- 'Deploy to...',
- );
- });
-
- it('should render a dropdown with the provided list of actions', () => {
- expect(vm.$el.querySelectorAll('.dropdown-menu li').length).toEqual(actions.length);
- });
-
- it("should render a disabled action when it's not playable", () => {
- expect(
- vm.$el.querySelector('.dropdown-menu li:last-child button').getAttribute('disabled'),
- ).toEqual('disabled');
-
- expect(
- vm.$el.querySelector('.dropdown-menu li:last-child button').classList.contains('disabled'),
- ).toEqual(true);
- });
- });
-
- describe('scheduled jobs', () => {
- const scheduledJobAction = {
- name: 'scheduled action',
- playPath: `${TEST_HOST}/scheduled/job/action`,
- playable: true,
- scheduledAt: '2063-04-05T00:42:00Z',
- };
- const expiredJobAction = {
- name: 'expired action',
- playPath: `${TEST_HOST}/expired/job/action`,
- playable: true,
- scheduledAt: '2018-10-05T08:23:00Z',
- };
- const findDropdownItem = action => {
- const buttons = vm.$el.querySelectorAll('.dropdown-menu li button');
- return Array.prototype.find.call(buttons, element =>
- element.innerText.trim().startsWith(action.name),
- );
- };
-
- beforeEach(() => {
- spyOn(Date, 'now').and.callFake(() => new Date('2063-04-04T00:42:00Z').getTime());
- vm = mountComponent(Component, { actions: [scheduledJobAction, expiredJobAction] });
- });
-
- it('emits postAction event after confirming', () => {
- const emitSpy = jasmine.createSpy('emit');
- eventHub.$on('postAction', emitSpy);
- spyOn(window, 'confirm').and.callFake(() => true);
-
- findDropdownItem(scheduledJobAction).click();
-
- expect(window.confirm).toHaveBeenCalled();
- expect(emitSpy).toHaveBeenCalledWith({ endpoint: scheduledJobAction.playPath });
- });
-
- it('does not emit postAction event if confirmation is cancelled', () => {
- const emitSpy = jasmine.createSpy('emit');
- eventHub.$on('postAction', emitSpy);
- spyOn(window, 'confirm').and.callFake(() => false);
-
- findDropdownItem(scheduledJobAction).click();
-
- expect(window.confirm).toHaveBeenCalled();
- expect(emitSpy).not.toHaveBeenCalled();
- });
-
- it('displays the remaining time in the dropdown', () => {
- expect(findDropdownItem(scheduledJobAction)).toContainText('24:00:00');
- });
-
- it('displays 00:00:00 for expired jobs in the dropdown', () => {
- expect(findDropdownItem(expiredJobAction)).toContainText('00:00:00');
- });
- });
-});
diff --git a/spec/javascripts/vue_shared/components/bar_chart_spec.js b/spec/javascripts/vue_shared/components/bar_chart_spec.js
deleted file mode 100644
index 8f673c146ec..00000000000
--- a/spec/javascripts/vue_shared/components/bar_chart_spec.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import BarChart from '~/vue_shared/components/bar_chart.vue';
-
-function getRandomArbitrary(min, max) {
- return Math.random() * (max - min) + min;
-}
-
-function generateRandomData(dataNumber) {
- const randomGraphData = [];
-
- for (let i = 1; i <= dataNumber; i += 1) {
- randomGraphData.push({
- name: `random ${i}`,
- value: parseInt(getRandomArbitrary(1, 8), 10),
- });
- }
-
- return randomGraphData;
-}
-
-describe('Bar chart component', () => {
- let barChart;
- const graphData = generateRandomData(10);
-
- beforeEach(() => {
- const BarChartComponent = Vue.extend(BarChart);
-
- barChart = mountComponent(BarChartComponent, {
- graphData,
- yAxisLabel: 'data',
- });
- });
-
- afterEach(() => {
- barChart.$destroy();
- });
-
- it('calculates the padding for even distribution across bars', () => {
- barChart.vbWidth = 1000;
- const result = barChart.calculatePadding(30);
-
- // since padding can't be higher than 1 and lower than 0
- // for more info: https://github.com/d3/d3-scale#band-scales
- expect(result).not.toBeLessThan(0);
- expect(result).not.toBeGreaterThan(1);
- });
-
- it('formats the tooltip title', () => {
- const tooltipTitle = barChart.setTooltipTitle(barChart.graphData[0]);
-
- expect(tooltipTitle).toContain('random 1:');
- });
-
- it('has a translates the bar graphs on across the X axis', () => {
- barChart.panX = 100;
-
- expect(barChart.barTranslationTransform).toEqual('translate(100, 0)');
- });
-
- it('translates the scroll indicator to the far right side', () => {
- barChart.vbWidth = 500;
-
- expect(barChart.scrollIndicatorTransform).toEqual('translate(420, 0)');
- });
-
- it('translates the x-axis to the bottom of the viewbox and pan coordinates', () => {
- barChart.panX = 100;
- barChart.vbHeight = 250;
-
- expect(barChart.xAxisLocation).toEqual('translate(100, 250)');
- });
-
- it('rotates the x axis labels a total of 90 degress (CCW)', () => {
- const xAxisLabel = barChart.$el.querySelector('.x-axis').querySelectorAll('text')[0];
-
- expect(xAxisLabel.getAttribute('transform')).toEqual('rotate(-90)');
- });
-});
diff --git a/spec/lib/quality/test_level_spec.rb b/spec/lib/quality/test_level_spec.rb
index 621a426a18d..13817bdcc72 100644
--- a/spec/lib/quality/test_level_spec.rb
+++ b/spec/lib/quality/test_level_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe Quality::TestLevel do
context 'when level is unit' do
it 'returns a pattern' do
expect(subject.pattern(:unit))
- .to eq("spec/{bin,config,db,dependencies,factories,finders,frontend,graphql,haml_lint,helpers,initializers,javascripts,lib,models,policies,presenters,rack_servers,replicators,routing,rubocop,serializers,services,sidekiq,tasks,uploaders,validators,views,workers,elastic_integration}{,/**/}*_spec.rb")
+ .to eq("spec/{bin,config,db,dependencies,factories,finders,frontend,graphql,haml_lint,helpers,initializers,javascripts,lib,models,policies,presenters,rack_servers,routing,rubocop,serializers,services,sidekiq,tasks,uploaders,validators,views,workers,elastic_integration}{,/**/}*_spec.rb")
end
end
@@ -82,7 +82,7 @@ RSpec.describe Quality::TestLevel do
context 'when level is unit' do
it 'returns a regexp' do
expect(subject.regexp(:unit))
- .to eq(%r{spec/(bin|config|db|dependencies|factories|finders|frontend|graphql|haml_lint|helpers|initializers|javascripts|lib|models|policies|presenters|rack_servers|replicators|routing|rubocop|serializers|services|sidekiq|tasks|uploaders|validators|views|workers|elastic_integration)})
+ .to eq(%r{spec/(bin|config|db|dependencies|factories|finders|frontend|graphql|haml_lint|helpers|initializers|javascripts|lib|models|policies|presenters|rack_servers|routing|rubocop|serializers|services|sidekiq|tasks|uploaders|validators|views|workers|elastic_integration)})
end
end
diff --git a/spec/models/sentry_issue_spec.rb b/spec/models/sentry_issue_spec.rb
index 022cfd4734e..b4c1cf57761 100644
--- a/spec/models/sentry_issue_spec.rb
+++ b/spec/models/sentry_issue_spec.rb
@@ -13,6 +13,20 @@ describe SentryIssue do
it { is_expected.to validate_presence_of(:issue) }
it { is_expected.to validate_uniqueness_of(:issue) }
it { is_expected.to validate_presence_of(:sentry_issue_identifier) }
+
+ it 'allows duplicated sentry_issue_identifier' do
+ duplicate_sentry_issue = build(:sentry_issue, sentry_issue_identifier: sentry_issue.sentry_issue_identifier)
+
+ expect(duplicate_sentry_issue).to be_valid
+ end
+
+ it 'validates uniqueness of sentry_issue_identifier per project' do
+ second_issue = create(:issue, project: sentry_issue.issue.project)
+ duplicate_sentry_issue = build(:sentry_issue, issue: second_issue, sentry_issue_identifier: sentry_issue.sentry_issue_identifier)
+
+ expect(duplicate_sentry_issue).to be_invalid
+ expect(duplicate_sentry_issue.errors.full_messages.first).to include('is already associated')
+ end
end
describe 'callbacks' do
@@ -28,13 +42,16 @@ describe SentryIssue do
end
describe '.for_project_and_identifier' do
- let!(:sentry_issue) { create(:sentry_issue) }
- let(:project) { sentry_issue.issue.project }
- let(:identifier) { sentry_issue.sentry_issue_identifier }
- let!(:second_sentry_issue) { create(:sentry_issue) }
+ it 'finds the most recent per project and sentry_issue_identifier' do
+ sentry_issue = create(:sentry_issue)
+ create(:sentry_issue)
+ project = sentry_issue.issue.project
+ sentry_issue_3 = build(:sentry_issue, issue: create(:issue, project: project), sentry_issue_identifier: sentry_issue.sentry_issue_identifier)
+ sentry_issue_3.save(validate: false)
- subject { described_class.for_project_and_identifier(project, identifier) }
+ result = described_class.for_project_and_identifier(project, sentry_issue.sentry_issue_identifier)
- it { is_expected.to eq(sentry_issue) }
+ expect(result).to eq(sentry_issue_3)
+ end
end
end