From 7b52c7cb634ef7047d30b0337fe477bcdcedf41d Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Mon, 2 Mar 2020 18:07:42 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .../helpers/dom_shims/image_element_properties.js | 12 + spec/frontend/helpers/dom_shims/index.js | 1 + spec/frontend/vue_mr_widget/mock_data.js | 318 ++++++++ .../vue_mr_widget/mr_widget_options_spec.js | 834 ++++++++++++++++++++ .../concerns/mutations/resolves_issuable_spec.rb | 72 ++ spec/helpers/form_helper_spec.rb | 19 + spec/javascripts/vue_mr_widget/mock_data.js | 320 +------- .../vue_mr_widget/mr_widget_options_spec.js | 842 --------------------- spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb | 24 +- spec/lib/gitlab/sidekiq_config/worker_spec.rb | 8 +- .../sidekiq_logging/structured_logger_spec.rb | 19 +- .../sidekiq_middleware/client_metrics_spec.rb | 29 +- .../sidekiq_middleware/server_metrics_spec.rb | 22 +- spec/models/concerns/avatarable_spec.rb | 2 +- spec/models/wiki_page_spec.rb | 11 +- spec/requests/api/repositories_spec.rb | 38 +- spec/requests/api/runner_spec.rb | 192 ++--- spec/requests/api/runners_spec.rb | 172 ++--- spec/requests/api/search_spec.rb | 42 +- spec/requests/api/services_spec.rb | 34 +- spec/requests/api/settings_spec.rb | 44 +- spec/requests/api/sidekiq_metrics_spec.rb | 8 +- spec/requests/api/snippets_spec.rb | 54 +- spec/requests/api/statistics_spec.rb | 6 +- spec/requests/api/submodules_spec.rb | 14 +- spec/requests/api/suggestions_spec.rb | 6 +- spec/requests/api/system_hooks_spec.rb | 22 +- spec/workers/every_sidekiq_worker_spec.rb | 30 +- 28 files changed, 1658 insertions(+), 1537 deletions(-) create mode 100644 spec/frontend/helpers/dom_shims/image_element_properties.js create mode 100644 spec/frontend/vue_mr_widget/mock_data.js create mode 100644 spec/frontend/vue_mr_widget/mr_widget_options_spec.js create mode 100644 spec/graphql/mutations/concerns/mutations/resolves_issuable_spec.rb delete mode 100644 spec/javascripts/vue_mr_widget/mr_widget_options_spec.js (limited to 'spec') diff --git a/spec/frontend/helpers/dom_shims/image_element_properties.js b/spec/frontend/helpers/dom_shims/image_element_properties.js new file mode 100644 index 00000000000..525246e6ade --- /dev/null +++ b/spec/frontend/helpers/dom_shims/image_element_properties.js @@ -0,0 +1,12 @@ +Object.defineProperty(global.HTMLImageElement.prototype, 'src', { + get() { + return this.$_jest_src; + }, + set(val) { + this.$_jest_src = val; + + if (this.onload) { + this.onload(); + } + }, +}); diff --git a/spec/frontend/helpers/dom_shims/index.js b/spec/frontend/helpers/dom_shims/index.js index 1b73f0e2ef5..855b707a4cf 100644 --- a/spec/frontend/helpers/dom_shims/index.js +++ b/spec/frontend/helpers/dom_shims/index.js @@ -4,3 +4,4 @@ import './inner_text'; import './window_scroll_to'; import './scroll_by'; import './size_properties'; +import './image_element_properties'; diff --git a/spec/frontend/vue_mr_widget/mock_data.js b/spec/frontend/vue_mr_widget/mock_data.js new file mode 100644 index 00000000000..d11756d712a --- /dev/null +++ b/spec/frontend/vue_mr_widget/mock_data.js @@ -0,0 +1,318 @@ +import { SUCCESS } from '~/vue_merge_request_widget/components/deployment/constants'; + +export default { + id: 132, + iid: 22, + assignee_id: null, + author_id: 1, + description: '', + lock_version: null, + milestone_id: null, + position: 0, + state: 'merged', + title: 'Update README.md', + updated_by_id: null, + created_at: '2017-04-07T12:27:26.718Z', + updated_at: '2017-04-07T15:39:25.852Z', + time_estimate: 0, + total_time_spent: 0, + human_access: 'Maintainer', + human_time_estimate: null, + human_total_time_spent: null, + in_progress_merge_commit_sha: null, + merge_commit_sha: '53027d060246c8f47e4a9310fb332aa52f221775', + short_merge_commit_sha: '53027d06', + merge_error: null, + merge_params: { + force_remove_source_branch: null, + }, + merge_status: 'can_be_merged', + merge_user_id: null, + pipelines_empty_svg_path: '/path/to/svg', + source_branch: 'daaaa', + source_branch_link: 'daaaa', + source_project_id: 19, + source_project_full_path: '/group1/project1', + target_branch: 'master', + target_project_id: 19, + target_project_full_path: '/group2/project2', + merge_request_add_ci_config_path: '/group2/project2/new/pipeline', + metrics: { + merged_by: { + name: 'Administrator', + username: 'root', + id: 1, + state: 'active', + avatar_url: + 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + web_url: 'http://localhost:3000/root', + }, + merged_at: '2017-04-07T15:39:25.696Z', + closed_by: null, + closed_at: null, + }, + author: { + name: 'Administrator', + username: 'root', + id: 1, + state: 'active', + avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + web_url: 'http://localhost:3000/root', + }, + merge_user: null, + diff_head_sha: '104096c51715e12e7ae41f9333e9fa35b73f385d', + diff_head_commit_short_id: '104096c5', + default_merge_commit_message: + "Merge branch 'daaaa' into 'master'\n\nUpdate README.md\n\nSee merge request !22", + pipeline: { + id: 172, + user: { + name: 'Administrator', + username: 'root', + id: 1, + state: 'active', + avatar_url: + 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + web_url: 'http://localhost:3000/root', + }, + active: false, + coverage: '92.16', + path: '/root/acets-app/pipelines/172', + details: { + status: { + icon: 'status_success', + favicon: 'favicon_status_success', + text: 'passed', + label: 'passed', + group: 'success', + has_details: true, + details_path: '/root/acets-app/pipelines/172', + }, + duration: null, + finished_at: '2017-04-07T14:00:14.256Z', + stages: [ + { + name: 'build', + title: 'build: failed', + status: { + icon: 'status_failed', + favicon: 'favicon_status_failed', + text: 'failed', + label: 'failed', + group: 'failed', + has_details: true, + details_path: '/root/acets-app/pipelines/172#build', + }, + path: '/root/acets-app/pipelines/172#build', + dropdown_path: '/root/acets-app/pipelines/172/stage.json?stage=build', + }, + { + name: 'review', + title: 'review: skipped', + status: { + icon: 'status_skipped', + favicon: 'favicon_status_skipped', + text: 'skipped', + label: 'skipped', + group: 'skipped', + has_details: true, + details_path: '/root/acets-app/pipelines/172#review', + }, + path: '/root/acets-app/pipelines/172#review', + dropdown_path: '/root/acets-app/pipelines/172/stage.json?stage=review', + }, + ], + artifacts: [], + manual_actions: [ + { + name: 'stop_review', + path: '/root/acets-app/builds/1427/play', + playable: false, + }, + ], + }, + flags: { + latest: false, + triggered: false, + stuck: false, + yaml_errors: false, + retryable: true, + cancelable: false, + merge_request_pipeline: false, + detached_merge_request_pipeline: true, + }, + ref: { + name: 'daaaa', + path: '/root/acets-app/tree/daaaa', + tag: false, + branch: true, + }, + merge_request: { + iid: 1, + path: '/root/detached-merge-request-pipelines/-/merge_requests/1', + title: 'Update README.md', + source_branch: 'feature-1', + source_branch_path: '/root/detached-merge-request-pipelines/branches/feature-1', + target_branch: 'master', + target_branch_path: '/root/detached-merge-request-pipelines/branches/master', + }, + commit: { + id: '104096c51715e12e7ae41f9333e9fa35b73f385d', + short_id: '104096c5', + title: 'Update README.md', + created_at: '2017-04-07T15:27:18.000+03:00', + parent_ids: ['2396536178668d8930c29d904e53bd4d06228b32'], + message: 'Update README.md', + author_name: 'Administrator', + author_email: 'admin@example.com', + authored_date: '2017-04-07T15:27:18.000+03:00', + committer_name: 'Administrator', + committer_email: 'admin@example.com', + committed_date: '2017-04-07T15:27:18.000+03:00', + author: { + name: 'Administrator', + username: 'root', + id: 1, + state: 'active', + avatar_url: + 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + web_url: 'http://localhost:3000/root', + }, + author_gravatar_url: + 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + commit_url: + 'http://localhost:3000/root/acets-app/commit/104096c51715e12e7ae41f9333e9fa35b73f385d', + commit_path: '/root/acets-app/commit/104096c51715e12e7ae41f9333e9fa35b73f385d', + }, + retry_path: '/root/acets-app/pipelines/172/retry', + created_at: '2017-04-07T12:27:19.520Z', + updated_at: '2017-04-07T15:28:44.800Z', + }, + pipelineCoverageDelta: '15.25', + work_in_progress: false, + source_branch_exists: false, + mergeable_discussions_state: true, + conflicts_can_be_resolved_in_ui: false, + branch_missing: true, + commits_count: 1, + has_conflicts: false, + can_be_merged: true, + has_ci: true, + ci_status: 'success', + pipeline_status_path: '/root/acets-app/-/merge_requests/22/pipeline_status', + issues_links: { + closing: '', + mentioned_but_not_closing: '', + }, + current_user: { + can_resolve_conflicts: true, + can_remove_source_branch: false, + can_revert_on_current_merge_request: true, + can_cherry_pick_on_current_merge_request: true, + }, + target_branch_path: '/root/acets-app/branches/master', + source_branch_path: '/root/acets-app/branches/daaaa', + conflict_resolution_ui_path: '/root/acets-app/-/merge_requests/22/conflicts', + remove_wip_path: '/root/acets-app/-/merge_requests/22/remove_wip', + cancel_auto_merge_path: '/root/acets-app/-/merge_requests/22/cancel_auto_merge', + create_issue_to_resolve_discussions_path: + '/root/acets-app/-/issues/new?merge_request_to_resolve_discussions_of=22', + merge_path: '/root/acets-app/-/merge_requests/22/merge', + cherry_pick_in_fork_path: + '/root/acets-app/forks?continue%5Bnotice%5D=You%27re+not+allowed+to+make+changes+to+this+project+directly.+A+fork+of+this+project+has+been+created+that+you+can+make+changes+in%2C+so+you+can+submit+a+merge+request.+Try+to+revert+this+commit+again.&continue%5Bnotice_now%5D=You%27re+not+allowed+to+make+changes+to+this+project+directly.+A+fork+of+this+project+is+being+created+that+you+can+make+changes+in%2C+so+you+can+submit+a+merge+request.&continue%5Bto%5D=%2Froot%2Facets-app%2Fmerge_requests%2F22&namespace_key=1', + revert_in_fork_path: + '/root/acets-app/forks?continue%5Bnotice%5D=You%27re+not+allowed+to+make+changes+to+this+project+directly.+A+fork+of+this+project+has+been+created+that+you+can+make+changes+in%2C+so+you+can+submit+a+merge+request.+Try+to+cherry-pick+this+commit+again.&continue%5Bnotice_now%5D=You%27re+not+allowed+to+make+changes+to+this+project+directly.+A+fork+of+this+project+is+being+created+that+you+can+make+changes+in%2C+so+you+can+submit+a+merge+request.&continue%5Bto%5D=%2Froot%2Facets-app%2Fmerge_requests%2F22&namespace_key=1', + email_patches_path: '/root/acets-app/-/merge_requests/22.patch', + plain_diff_path: '/root/acets-app/-/merge_requests/22.diff', + merge_request_basic_path: '/root/acets-app/-/merge_requests/22.json?serializer=basic', + merge_request_widget_path: '/root/acets-app/-/merge_requests/22/widget.json', + merge_request_cached_widget_path: '/cached.json', + merge_check_path: '/root/acets-app/-/merge_requests/22/merge_check', + ci_environments_status_url: '/root/acets-app/-/merge_requests/22/ci_environments_status', + project_archived: false, + default_merge_commit_message_with_description: + "Merge branch 'daaaa' into 'master'\n\nUpdate README.md\n\nSee merge request !22", + default_squash_commit_message: 'Test squash commit message', + diverged_commits_count: 0, + only_allow_merge_if_pipeline_succeeds: false, + commit_change_content_path: '/root/acets-app/-/merge_requests/22/commit_change_content', + merge_commit_path: + 'http://localhost:3000/root/acets-app/commit/53027d060246c8f47e4a9310fb332aa52f221775', + troubleshooting_docs_path: 'help', + merge_request_pipelines_docs_path: '/help/ci/merge_request_pipelines/index.md', + merge_train_when_pipeline_succeeds_docs_path: + '/help/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/#startadd-to-merge-train-when-pipeline-succeeds', + squash: true, + visual_review_app_available: true, + merge_trains_enabled: true, + merge_trains_count: 3, + merge_train_index: 1, +}; + +export const mockStore = { + pipeline: { + id: 0, + details: { + status: { + details_path: '/root/review-app-tester/pipelines/66', + favicon: + '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2. png', + group: 'success-with-warnings', + has_details: true, + icon: 'status_warning', + illustration: null, + label: 'passed with warnings', + text: 'passed', + tooltip: 'passed', + }, + }, + flags: {}, + ref: {}, + }, + mergePipeline: { + id: 1, + details: { + status: { + details_path: '/root/review-app-tester/pipelines/66', + favicon: + '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2. png', + group: 'success-with-warnings', + has_details: true, + icon: 'status_warning', + illustration: null, + label: 'passed with warnings', + text: 'passed', + tooltip: 'passed', + }, + }, + flags: {}, + ref: {}, + }, + targetBranch: 'target-branch', + sourceBranch: 'source-branch', + sourceBranchLink: 'source-branch-link', + deployments: [ + { + id: 0, + name: 'bogus', + external_url: 'https://fake.com', + external_url_formatted: 'https://fake.com', + status: SUCCESS, + }, + { + id: 1, + name: 'bogus-docs', + external_url: 'https://fake.com', + external_url_formatted: 'https://fake.com', + status: SUCCESS, + }, + ], + postMergeDeployments: [ + { id: 0, name: 'prod', status: SUCCESS }, + { id: 1, name: 'prod-docs', status: SUCCESS }, + ], + troubleshootingDocsPath: 'troubleshooting-docs-path', + ciStatus: 'ci-status', + hasCI: true, + exposedArtifactsPath: 'exposed_artifacts.json', +}; diff --git a/spec/frontend/vue_mr_widget/mr_widget_options_spec.js b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js new file mode 100644 index 00000000000..5edf41b1ec6 --- /dev/null +++ b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js @@ -0,0 +1,834 @@ +import Vue from 'vue'; +import MockAdapter from 'axios-mock-adapter'; +import mountComponent from 'helpers/vue_mount_component_helper'; +import axios from '~/lib/utils/axios_utils'; +import mrWidgetOptions from '~/vue_merge_request_widget/mr_widget_options.vue'; +import eventHub from '~/vue_merge_request_widget/event_hub'; +import notify from '~/lib/utils/notify'; +import SmartInterval from '~/smart_interval'; +import { stateKey } from '~/vue_merge_request_widget/stores/state_maps'; +import mockData from './mock_data'; +import { faviconDataUrl, overlayDataUrl } from '../lib/utils/mock_data'; +import { SUCCESS } from '~/vue_merge_request_widget/components/deployment/constants'; + +jest.mock('~/smart_interval'); + +const returnPromise = data => + new Promise(resolve => { + resolve({ + data, + }); + }); + +describe('mrWidgetOptions', () => { + let vm; + let mock; + let MrWidgetOptions; + + const COLLABORATION_MESSAGE = 'Allows commits from members who can merge to the target branch'; + + beforeEach(() => { + // Prevent component mounting + delete mrWidgetOptions.el; + + gl.mrWidgetData = { ...mockData }; + gon.features = { asyncMrWidget: true }; + + mock = new MockAdapter(axios); + mock.onGet(mockData.merge_request_widget_path).reply(() => [200, { ...mockData }]); + mock.onGet(mockData.merge_request_cached_widget_path).reply(() => [200, { ...mockData }]); + + MrWidgetOptions = Vue.extend(mrWidgetOptions); + }); + + afterEach(() => { + mock.restore(); + vm.$destroy(); + vm = null; + + gl.mrWidgetData = {}; + gon.features = {}; + }); + + const createComponent = () => { + if (vm) { + vm.$destroy(); + } + + vm = mountComponent(MrWidgetOptions, { + mrData: { ...mockData }, + }); + + return axios.waitForAll(); + }; + + describe('default', () => { + beforeEach(() => { + return createComponent(); + }); + + describe('data', () => { + it('should instantiate Store and Service', () => { + expect(vm.mr).toBeDefined(); + expect(vm.service).toBeDefined(); + }); + }); + + describe('computed', () => { + describe('componentName', () => { + it('should return merged component', () => { + expect(vm.componentName).toEqual('mr-widget-merged'); + }); + + it('should return conflicts component', () => { + vm.mr.state = 'conflicts'; + + expect(vm.componentName).toEqual('mr-widget-conflicts'); + }); + }); + + describe('shouldRenderMergeHelp', () => { + it('should return false for the initial merged state', () => { + expect(vm.shouldRenderMergeHelp).toBeFalsy(); + }); + + it('should return true for a state which requires help widget', () => { + vm.mr.state = 'conflicts'; + + expect(vm.shouldRenderMergeHelp).toBeTruthy(); + }); + }); + + describe('shouldRenderPipelines', () => { + it('should return true when hasCI is true', () => { + vm.mr.hasCI = true; + + expect(vm.shouldRenderPipelines).toBeTruthy(); + }); + + it('should return false when hasCI is false', () => { + vm.mr.hasCI = false; + + expect(vm.shouldRenderPipelines).toBeFalsy(); + }); + }); + + describe('shouldRenderRelatedLinks', () => { + it('should return false for the initial data', () => { + expect(vm.shouldRenderRelatedLinks).toBeFalsy(); + }); + + it('should return true if there is relatedLinks in MR', () => { + Vue.set(vm.mr, 'relatedLinks', {}); + + expect(vm.shouldRenderRelatedLinks).toBeTruthy(); + }); + }); + + describe('shouldRenderSourceBranchRemovalStatus', () => { + beforeEach(() => { + vm.mr.state = 'readyToMerge'; + }); + + it('should return true when cannot remove source branch and branch will be removed', () => { + vm.mr.canRemoveSourceBranch = false; + vm.mr.shouldRemoveSourceBranch = true; + + expect(vm.shouldRenderSourceBranchRemovalStatus).toEqual(true); + }); + + it('should return false when can remove source branch and branch will be removed', () => { + vm.mr.canRemoveSourceBranch = true; + vm.mr.shouldRemoveSourceBranch = true; + + expect(vm.shouldRenderSourceBranchRemovalStatus).toEqual(false); + }); + + it('should return false when cannot remove source branch and branch will not be removed', () => { + vm.mr.canRemoveSourceBranch = false; + vm.mr.shouldRemoveSourceBranch = false; + + expect(vm.shouldRenderSourceBranchRemovalStatus).toEqual(false); + }); + + it('should return false when in merged state', () => { + vm.mr.canRemoveSourceBranch = false; + vm.mr.shouldRemoveSourceBranch = true; + vm.mr.state = 'merged'; + + expect(vm.shouldRenderSourceBranchRemovalStatus).toEqual(false); + }); + + it('should return false when in nothing to merge state', () => { + vm.mr.canRemoveSourceBranch = false; + vm.mr.shouldRemoveSourceBranch = true; + vm.mr.state = 'nothingToMerge'; + + expect(vm.shouldRenderSourceBranchRemovalStatus).toEqual(false); + }); + }); + + describe('shouldRenderCollaborationStatus', () => { + describe('when collaboration is allowed', () => { + beforeEach(() => { + vm.mr.allowCollaboration = true; + }); + + describe('when merge request is opened', () => { + beforeEach(done => { + vm.mr.isOpen = true; + vm.$nextTick(done); + }); + + it('should render collaboration status', () => { + expect(vm.$el.textContent).toContain(COLLABORATION_MESSAGE); + }); + }); + + describe('when merge request is not opened', () => { + beforeEach(done => { + vm.mr.isOpen = false; + vm.$nextTick(done); + }); + + it('should not render collaboration status', () => { + expect(vm.$el.textContent).not.toContain(COLLABORATION_MESSAGE); + }); + }); + }); + + describe('when collaboration is not allowed', () => { + beforeEach(() => { + vm.mr.allowCollaboration = false; + }); + + describe('when merge request is opened', () => { + beforeEach(done => { + vm.mr.isOpen = true; + vm.$nextTick(done); + }); + + it('should not render collaboration status', () => { + expect(vm.$el.textContent).not.toContain(COLLABORATION_MESSAGE); + }); + }); + }); + }); + + describe('showMergePipelineForkWarning', () => { + describe('when the source project and target project are the same', () => { + beforeEach(done => { + Vue.set(vm.mr, 'mergePipelinesEnabled', true); + Vue.set(vm.mr, 'sourceProjectId', 1); + Vue.set(vm.mr, 'targetProjectId', 1); + vm.$nextTick(done); + }); + + it('should be false', () => { + expect(vm.showMergePipelineForkWarning).toEqual(false); + }); + }); + + describe('when merge pipelines are not enabled', () => { + beforeEach(done => { + Vue.set(vm.mr, 'mergePipelinesEnabled', false); + Vue.set(vm.mr, 'sourceProjectId', 1); + Vue.set(vm.mr, 'targetProjectId', 2); + vm.$nextTick(done); + }); + + it('should be false', () => { + expect(vm.showMergePipelineForkWarning).toEqual(false); + }); + }); + + describe('when merge pipelines are enabled _and_ the source project and target project are different', () => { + beforeEach(done => { + Vue.set(vm.mr, 'mergePipelinesEnabled', true); + Vue.set(vm.mr, 'sourceProjectId', 1); + Vue.set(vm.mr, 'targetProjectId', 2); + vm.$nextTick(done); + }); + + it('should be true', () => { + expect(vm.showMergePipelineForkWarning).toEqual(true); + }); + }); + }); + }); + + describe('methods', () => { + describe('checkStatus', () => { + it('should tell service to check status', () => { + jest.spyOn(vm.service, 'checkStatus').mockReturnValue(returnPromise(mockData)); + jest.spyOn(vm.mr, 'setData').mockImplementation(() => {}); + jest.spyOn(vm, 'handleNotification').mockImplementation(() => {}); + + let isCbExecuted = false; + const cb = () => { + isCbExecuted = true; + }; + + vm.checkStatus(cb); + + return vm.$nextTick().then(() => { + expect(vm.service.checkStatus).toHaveBeenCalled(); + expect(vm.mr.setData).toHaveBeenCalled(); + expect(vm.handleNotification).toHaveBeenCalledWith(mockData); + expect(isCbExecuted).toBeTruthy(); + }); + }); + }); + + describe('initPolling', () => { + it('should call SmartInterval', () => { + vm.initPolling(); + + expect(SmartInterval).toHaveBeenCalledWith( + expect.objectContaining({ + callback: vm.checkStatus, + }), + ); + }); + }); + + describe('initDeploymentsPolling', () => { + it('should call SmartInterval', () => { + vm.initDeploymentsPolling(); + + expect(SmartInterval).toHaveBeenCalledWith( + expect.objectContaining({ + callback: vm.fetchPreMergeDeployments, + }), + ); + }); + }); + + describe('fetchDeployments', () => { + it('should fetch deployments', () => { + jest + .spyOn(vm.service, 'fetchDeployments') + .mockReturnValue(returnPromise([{ id: 1, status: SUCCESS }])); + + vm.fetchPreMergeDeployments(); + + return vm.$nextTick().then(() => { + expect(vm.service.fetchDeployments).toHaveBeenCalled(); + expect(vm.mr.deployments.length).toEqual(1); + expect(vm.mr.deployments[0].id).toBe(1); + }); + }); + }); + + describe('fetchActionsContent', () => { + it('should fetch content of Cherry Pick and Revert modals', () => { + jest + .spyOn(vm.service, 'fetchMergeActionsContent') + .mockReturnValue(returnPromise('hello world')); + + vm.fetchActionsContent(); + + return vm.$nextTick().then(() => { + expect(vm.service.fetchMergeActionsContent).toHaveBeenCalled(); + expect(document.body.textContent).toContain('hello world'); + }); + }); + }); + + describe('bindEventHubListeners', () => { + it.each` + event | method | methodArgs + ${'MRWidgetUpdateRequested'} | ${'checkStatus'} | ${x => [x]} + ${'MRWidgetRebaseSuccess'} | ${'checkStatus'} | ${x => [x, true]} + ${'FetchActionsContent'} | ${'fetchActionsContent'} | ${() => []} + ${'EnablePolling'} | ${'resumePolling'} | ${() => []} + ${'DisablePolling'} | ${'stopPolling'} | ${() => []} + `('should bind to $event', ({ event, method, methodArgs }) => { + jest.spyOn(vm, method).mockImplementation(); + + const eventArg = {}; + eventHub.$emit(event, eventArg); + + expect(vm[method]).toHaveBeenCalledWith(...methodArgs(eventArg)); + }); + + it('should bind to SetBranchRemoveFlag', () => { + expect(vm.mr.isRemovingSourceBranch).toBe(false); + + eventHub.$emit('SetBranchRemoveFlag', [true]); + + expect(vm.mr.isRemovingSourceBranch).toBe(true); + }); + + it('should bind to FailedToMerge', () => { + vm.mr.state = ''; + vm.mr.mergeError = ''; + + const mergeError = 'Something bad happened!'; + eventHub.$emit('FailedToMerge', mergeError); + + expect(vm.mr.state).toBe('failedToMerge'); + expect(vm.mr.mergeError).toBe(mergeError); + }); + + it('should bind to UpdateWidgetData', () => { + jest.spyOn(vm.mr, 'setData').mockImplementation(); + + const data = { ...mockData }; + eventHub.$emit('UpdateWidgetData', data); + + expect(vm.mr.setData).toHaveBeenCalledWith(data); + }); + }); + + describe('setFavicon', () => { + let faviconElement; + + beforeEach(() => { + const favicon = document.createElement('link'); + favicon.setAttribute('id', 'favicon'); + favicon.setAttribute('data-original-href', faviconDataUrl); + document.body.appendChild(favicon); + + faviconElement = document.getElementById('favicon'); + }); + + afterEach(() => { + document.body.removeChild(document.getElementById('favicon')); + }); + + it('should call setFavicon method', done => { + vm.mr.ciStatusFaviconPath = overlayDataUrl; + vm.setFaviconHelper() + .then(() => { + /* + It would be better if we'd could mock commonUtils.setFaviconURL + with a spy and test that it was called. We are doing the following + tests as a proxy to show that the function has been called + */ + expect(faviconElement.getAttribute('href')).not.toEqual(null); + expect(faviconElement.getAttribute('href')).not.toEqual(overlayDataUrl); + expect(faviconElement.getAttribute('href')).not.toEqual(faviconDataUrl); + }) + .then(done) + .catch(done.fail); + }); + + it('should not call setFavicon when there is no ciStatusFaviconPath', done => { + vm.mr.ciStatusFaviconPath = null; + vm.setFaviconHelper() + .then(() => { + expect(faviconElement.getAttribute('href')).toEqual(null); + done(); + }) + .catch(done.fail); + }); + }); + + describe('handleNotification', () => { + const data = { + ci_status: 'running', + title: 'title', + pipeline: { details: { status: { label: 'running-label' } } }, + }; + + beforeEach(() => { + jest.spyOn(notify, 'notifyMe').mockImplementation(() => {}); + + vm.mr.ciStatus = 'failed'; + vm.mr.gitlabLogo = 'logo.png'; + }); + + it('should call notifyMe', () => { + vm.handleNotification(data); + + expect(notify.notifyMe).toHaveBeenCalledWith( + 'Pipeline running-label', + 'Pipeline running-label for "title"', + 'logo.png', + ); + }); + + it('should not call notifyMe if the status has not changed', () => { + vm.mr.ciStatus = data.ci_status; + + vm.handleNotification(data); + + expect(notify.notifyMe).not.toHaveBeenCalled(); + }); + + it('should not notify if no pipeline provided', () => { + vm.handleNotification({ + ...data, + pipeline: undefined, + }); + + expect(notify.notifyMe).not.toHaveBeenCalled(); + }); + }); + + describe('resumePolling', () => { + it('should call stopTimer on pollingInterval', () => { + jest.spyOn(vm.pollingInterval, 'resume').mockImplementation(() => {}); + + vm.resumePolling(); + + expect(vm.pollingInterval.resume).toHaveBeenCalled(); + }); + }); + + describe('stopPolling', () => { + it('should call stopTimer on pollingInterval', () => { + jest.spyOn(vm.pollingInterval, 'stopTimer').mockImplementation(() => {}); + + vm.stopPolling(); + + expect(vm.pollingInterval.stopTimer).toHaveBeenCalled(); + }); + }); + }); + + describe('rendering relatedLinks', () => { + beforeEach(done => { + vm.mr.relatedLinks = { + assignToMe: null, + closing: ` + + Close + + `, + mentioned: '', + }; + Vue.nextTick(done); + }); + + it('renders if there are relatedLinks', () => { + expect(vm.$el.querySelector('.close-related-link')).toBeDefined(); + }); + + it('does not render if state is nothingToMerge', done => { + vm.mr.state = stateKey.nothingToMerge; + Vue.nextTick(() => { + expect(vm.$el.querySelector('.close-related-link')).toBeNull(); + done(); + }); + }); + }); + + describe('rendering source branch removal status', () => { + it('renders when user cannot remove branch and branch should be removed', done => { + vm.mr.canRemoveSourceBranch = false; + vm.mr.shouldRemoveSourceBranch = true; + vm.mr.state = 'readyToMerge'; + + vm.$nextTick(() => { + const tooltip = vm.$el.querySelector('.fa-question-circle'); + + expect(vm.$el.textContent).toContain('Deletes source branch'); + expect(tooltip.getAttribute('data-original-title')).toBe( + 'A user with write access to the source branch selected this option', + ); + + done(); + }); + }); + + it('does not render in merged state', done => { + vm.mr.canRemoveSourceBranch = false; + vm.mr.shouldRemoveSourceBranch = true; + vm.mr.state = 'merged'; + + vm.$nextTick(() => { + expect(vm.$el.textContent).toContain('The source branch has been deleted'); + expect(vm.$el.textContent).not.toContain('Deletes source branch'); + + done(); + }); + }); + }); + + describe('rendering deployments', () => { + const changes = [ + { + path: 'index.html', + external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/index.html', + }, + { + path: 'imgs/gallery.html', + external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/imgs/gallery.html', + }, + { + path: 'about/', + external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/about/', + }, + ]; + const deploymentMockData = { + id: 15, + name: 'review/diplo', + url: '/root/acets-review-apps/environments/15', + stop_url: '/root/acets-review-apps/environments/15/stop', + metrics_url: '/root/acets-review-apps/environments/15/deployments/1/metrics', + metrics_monitoring_url: '/root/acets-review-apps/environments/15/metrics', + external_url: 'http://diplo.', + external_url_formatted: 'diplo.', + deployed_at: '2017-03-22T22:44:42.258Z', + deployed_at_formatted: 'Mar 22, 2017 10:44pm', + changes, + status: SUCCESS, + }; + + beforeEach(done => { + vm.mr.deployments.push( + { + ...deploymentMockData, + }, + { + ...deploymentMockData, + id: deploymentMockData.id + 1, + }, + ); + + vm.$nextTick(done); + }); + + it('renders multiple deployments', () => { + expect(vm.$el.querySelectorAll('.deploy-heading').length).toBe(2); + }); + + it('renders dropdpown with multiple file changes', () => { + expect( + vm.$el + .querySelector('.js-mr-wigdet-deployment-dropdown') + .querySelectorAll('.js-filtered-dropdown-result').length, + ).toEqual(changes.length); + }); + }); + + describe('pipeline for target branch after merge', () => { + describe('with information for target branch pipeline', () => { + beforeEach(done => { + vm.mr.state = 'merged'; + vm.mr.mergePipeline = { + id: 127, + user: { + id: 1, + name: 'Administrator', + username: 'root', + state: 'active', + avatar_url: null, + web_url: 'http://localhost:3000/root', + status_tooltip_html: null, + path: '/root', + }, + active: true, + coverage: null, + source: 'push', + created_at: '2018-10-22T11:41:35.186Z', + updated_at: '2018-10-22T11:41:35.433Z', + path: '/root/ci-web-terminal/pipelines/127', + flags: { + latest: true, + stuck: true, + auto_devops: false, + yaml_errors: false, + retryable: false, + cancelable: true, + failure_reason: false, + }, + details: { + status: { + icon: 'status_pending', + text: 'pending', + label: 'pending', + group: 'pending', + tooltip: 'pending', + has_details: true, + details_path: '/root/ci-web-terminal/pipelines/127', + illustration: null, + favicon: + '/assets/ci_favicons/favicon_status_pending-5bdf338420e5221ca24353b6bff1c9367189588750632e9a871b7af09ff6a2ae.png', + }, + duration: null, + finished_at: null, + stages: [ + { + name: 'test', + title: 'test: pending', + status: { + icon: 'status_pending', + text: 'pending', + label: 'pending', + group: 'pending', + tooltip: 'pending', + has_details: true, + details_path: '/root/ci-web-terminal/pipelines/127#test', + illustration: null, + favicon: + '/assets/ci_favicons/favicon_status_pending-5bdf338420e5221ca24353b6bff1c9367189588750632e9a871b7af09ff6a2ae.png', + }, + path: '/root/ci-web-terminal/pipelines/127#test', + dropdown_path: '/root/ci-web-terminal/pipelines/127/stage.json?stage=test', + }, + ], + artifacts: [], + manual_actions: [], + scheduled_actions: [], + }, + ref: { + name: 'master', + path: '/root/ci-web-terminal/commits/master', + tag: false, + branch: true, + }, + commit: { + id: 'aa1939133d373c94879becb79d91828a892ee319', + short_id: 'aa193913', + title: "Merge branch 'master-test' into 'master'", + created_at: '2018-10-22T11:41:33.000Z', + parent_ids: [ + '4622f4dd792468993003caf2e3be978798cbe096', + '76598df914cdfe87132d0c3c40f80db9fa9396a4', + ], + message: + "Merge branch 'master-test' into 'master'\n\nUpdate .gitlab-ci.yml\n\nSee merge request root/ci-web-terminal!1", + author_name: 'Administrator', + author_email: 'admin@example.com', + authored_date: '2018-10-22T11:41:33.000Z', + committer_name: 'Administrator', + committer_email: 'admin@example.com', + committed_date: '2018-10-22T11:41:33.000Z', + author: { + id: 1, + name: 'Administrator', + username: 'root', + state: 'active', + avatar_url: null, + web_url: 'http://localhost:3000/root', + status_tooltip_html: null, + path: '/root', + }, + author_gravatar_url: null, + commit_url: + 'http://localhost:3000/root/ci-web-terminal/commit/aa1939133d373c94879becb79d91828a892ee319', + commit_path: '/root/ci-web-terminal/commit/aa1939133d373c94879becb79d91828a892ee319', + }, + cancel_path: '/root/ci-web-terminal/pipelines/127/cancel', + }; + vm.$nextTick(done); + }); + + it('renders pipeline block', () => { + expect(vm.$el.querySelector('.js-post-merge-pipeline')).not.toBeNull(); + }); + + describe('with post merge deployments', () => { + beforeEach(done => { + vm.mr.postMergeDeployments = [ + { + id: 15, + name: 'review/diplo', + url: '/root/acets-review-apps/environments/15', + stop_url: '/root/acets-review-apps/environments/15/stop', + metrics_url: '/root/acets-review-apps/environments/15/deployments/1/metrics', + metrics_monitoring_url: '/root/acets-review-apps/environments/15/metrics', + external_url: 'http://diplo.', + external_url_formatted: 'diplo.', + deployed_at: '2017-03-22T22:44:42.258Z', + deployed_at_formatted: 'Mar 22, 2017 10:44pm', + changes: [ + { + path: 'index.html', + external_url: + 'http://root-master-patch-91341.volatile-watch.surge.sh/index.html', + }, + { + path: 'imgs/gallery.html', + external_url: + 'http://root-master-patch-91341.volatile-watch.surge.sh/imgs/gallery.html', + }, + { + path: 'about/', + external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/about/', + }, + ], + status: 'success', + }, + ]; + + vm.$nextTick(done); + }); + + it('renders post deployment information', () => { + expect(vm.$el.querySelector('.js-post-deployment')).not.toBeNull(); + }); + }); + }); + + describe('without information for target branch pipeline', () => { + beforeEach(done => { + vm.mr.state = 'merged'; + + vm.$nextTick(done); + }); + + it('does not render pipeline block', () => { + expect(vm.$el.querySelector('.js-post-merge-pipeline')).toBeNull(); + }); + }); + + describe('when state is not merged', () => { + beforeEach(done => { + vm.mr.state = 'archived'; + + vm.$nextTick(done); + }); + + it('does not render pipeline block', () => { + expect(vm.$el.querySelector('.js-post-merge-pipeline')).toBeNull(); + }); + + it('does not render post deployment information', () => { + expect(vm.$el.querySelector('.js-post-deployment')).toBeNull(); + }); + }); + }); + + it('should not suggest pipelines', () => { + vm.mr.mergeRequestAddCiConfigPath = null; + + expect(vm.shouldSuggestPipelines).toBeFalsy(); + }); + }); + + describe('given suggestPipeline feature flag is enabled', () => { + beforeEach(() => { + // This is needed because some grandchildren Bootstrap components throw warnings + // https://gitlab.com/gitlab-org/gitlab/issues/208458 + jest.spyOn(console, 'warn').mockImplementation(); + + gon.features = { suggestPipeline: true }; + return createComponent(); + }); + + it('should suggest pipelines when none exist', () => { + vm.mr.mergeRequestAddCiConfigPath = 'some/path'; + vm.mr.hasCI = false; + + expect(vm.shouldSuggestPipelines).toBeTruthy(); + }); + + it('should not suggest pipelines when they exist', () => { + vm.mr.mergeRequestAddCiConfigPath = null; + vm.mr.hasCI = false; + + expect(vm.shouldSuggestPipelines).toBeFalsy(); + }); + + it('should not suggest pipelines hasCI is true', () => { + vm.mr.mergeRequestAddCiConfigPath = 'some/path'; + vm.mr.hasCI = true; + + expect(vm.shouldSuggestPipelines).toBeFalsy(); + }); + }); +}); diff --git a/spec/graphql/mutations/concerns/mutations/resolves_issuable_spec.rb b/spec/graphql/mutations/concerns/mutations/resolves_issuable_spec.rb new file mode 100644 index 00000000000..064ad90f707 --- /dev/null +++ b/spec/graphql/mutations/concerns/mutations/resolves_issuable_spec.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Mutations::ResolvesIssuable do + let(:mutation_class) do + Class.new(Mutations::BaseMutation) do + include Mutations::ResolvesIssuable + end + end + + let(:project) { create(:project) } + let(:user) { create(:user) } + let(:context) { { current_user: user } } + let(:mutation) { mutation_class.new(object: nil, context: context) } + + shared_examples 'resolving an issuable' do |type| + context 'when user has access' do + let(:source) { type == :merge_request ? 'source_project' : 'project' } + let(:issuable) { create(type, author: user, "#{source}" => project) } + + subject { mutation.resolve_issuable(type: type, parent_path: project.full_path, iid: issuable.iid) } + + before do + project.add_developer(user) + end + + it 'resolves issuable by iid' do + result = type == :merge_request ? subject.sync : subject + expect(result).to eq(issuable) + end + + it 'uses the correct Resolver to resolve issuable' do + resolver_class = "Resolvers::#{type.to_s.classify.pluralize}Resolver".constantize + resolved_project = mutation.resolve_project(full_path: project.full_path) + + allow(mutation).to receive(:resolve_project) + .with(full_path: project.full_path) + .and_return(resolved_project) + + expect(resolver_class).to receive(:new) + .with(object: resolved_project, context: context) + .and_call_original + + subject + end + + it 'uses the ResolvesProject to resolve project' do + expect(Resolvers::ProjectResolver).to receive(:new) + .with(object: nil, context: context) + .and_call_original + + subject + end + + it 'returns nil if issuable is not found' do + result = mutation.resolve_issuable(type: type, parent_path: project.full_path, iid: "100") + result = type == :merge_request ? result.sync : result + + expect(result).to be_nil + end + end + end + + context 'with issues' do + it_behaves_like 'resolving an issuable', :issue + end + + context 'with merge requests' do + it_behaves_like 'resolving an issuable', :merge_request + end +end diff --git a/spec/helpers/form_helper_spec.rb b/spec/helpers/form_helper_spec.rb index 68aa0137cd5..6698d8970e7 100644 --- a/spec/helpers/form_helper_spec.rb +++ b/spec/helpers/form_helper_spec.rb @@ -39,6 +39,25 @@ describe FormHelper do end end + it 'renders messages truncated if requested' do + model = double(errors: errors_stub('Error 1', 'Error 2')) + model.errors.add(:title, 'is truncated') + model.errors.add(:base, 'Error 3') + + expect(model.class).to receive(:human_attribute_name) do |attribute| + attribute.to_s.capitalize + end + + errors = helper.form_errors(model, truncate: :title) + + aggregate_failures do + expect(errors).to include('
  • Error 1
  • ') + expect(errors).to include('
  • Error 2
  • ') + expect(errors).to include('
  • Title is truncated
  • ') + expect(errors).to include('
  • Error 3
  • ') + end + end + def errors_stub(*messages) ActiveModel::Errors.new(double).tap do |errors| messages.each { |msg| errors.add(:base, msg) } diff --git a/spec/javascripts/vue_mr_widget/mock_data.js b/spec/javascripts/vue_mr_widget/mock_data.js index d11756d712a..7783fcb6f93 100644 --- a/spec/javascripts/vue_mr_widget/mock_data.js +++ b/spec/javascripts/vue_mr_widget/mock_data.js @@ -1,318 +1,2 @@ -import { SUCCESS } from '~/vue_merge_request_widget/components/deployment/constants'; - -export default { - id: 132, - iid: 22, - assignee_id: null, - author_id: 1, - description: '', - lock_version: null, - milestone_id: null, - position: 0, - state: 'merged', - title: 'Update README.md', - updated_by_id: null, - created_at: '2017-04-07T12:27:26.718Z', - updated_at: '2017-04-07T15:39:25.852Z', - time_estimate: 0, - total_time_spent: 0, - human_access: 'Maintainer', - human_time_estimate: null, - human_total_time_spent: null, - in_progress_merge_commit_sha: null, - merge_commit_sha: '53027d060246c8f47e4a9310fb332aa52f221775', - short_merge_commit_sha: '53027d06', - merge_error: null, - merge_params: { - force_remove_source_branch: null, - }, - merge_status: 'can_be_merged', - merge_user_id: null, - pipelines_empty_svg_path: '/path/to/svg', - source_branch: 'daaaa', - source_branch_link: 'daaaa', - source_project_id: 19, - source_project_full_path: '/group1/project1', - target_branch: 'master', - target_project_id: 19, - target_project_full_path: '/group2/project2', - merge_request_add_ci_config_path: '/group2/project2/new/pipeline', - metrics: { - merged_by: { - name: 'Administrator', - username: 'root', - id: 1, - state: 'active', - avatar_url: - 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', - web_url: 'http://localhost:3000/root', - }, - merged_at: '2017-04-07T15:39:25.696Z', - closed_by: null, - closed_at: null, - }, - author: { - name: 'Administrator', - username: 'root', - id: 1, - state: 'active', - avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', - web_url: 'http://localhost:3000/root', - }, - merge_user: null, - diff_head_sha: '104096c51715e12e7ae41f9333e9fa35b73f385d', - diff_head_commit_short_id: '104096c5', - default_merge_commit_message: - "Merge branch 'daaaa' into 'master'\n\nUpdate README.md\n\nSee merge request !22", - pipeline: { - id: 172, - user: { - name: 'Administrator', - username: 'root', - id: 1, - state: 'active', - avatar_url: - 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', - web_url: 'http://localhost:3000/root', - }, - active: false, - coverage: '92.16', - path: '/root/acets-app/pipelines/172', - details: { - status: { - icon: 'status_success', - favicon: 'favicon_status_success', - text: 'passed', - label: 'passed', - group: 'success', - has_details: true, - details_path: '/root/acets-app/pipelines/172', - }, - duration: null, - finished_at: '2017-04-07T14:00:14.256Z', - stages: [ - { - name: 'build', - title: 'build: failed', - status: { - icon: 'status_failed', - favicon: 'favicon_status_failed', - text: 'failed', - label: 'failed', - group: 'failed', - has_details: true, - details_path: '/root/acets-app/pipelines/172#build', - }, - path: '/root/acets-app/pipelines/172#build', - dropdown_path: '/root/acets-app/pipelines/172/stage.json?stage=build', - }, - { - name: 'review', - title: 'review: skipped', - status: { - icon: 'status_skipped', - favicon: 'favicon_status_skipped', - text: 'skipped', - label: 'skipped', - group: 'skipped', - has_details: true, - details_path: '/root/acets-app/pipelines/172#review', - }, - path: '/root/acets-app/pipelines/172#review', - dropdown_path: '/root/acets-app/pipelines/172/stage.json?stage=review', - }, - ], - artifacts: [], - manual_actions: [ - { - name: 'stop_review', - path: '/root/acets-app/builds/1427/play', - playable: false, - }, - ], - }, - flags: { - latest: false, - triggered: false, - stuck: false, - yaml_errors: false, - retryable: true, - cancelable: false, - merge_request_pipeline: false, - detached_merge_request_pipeline: true, - }, - ref: { - name: 'daaaa', - path: '/root/acets-app/tree/daaaa', - tag: false, - branch: true, - }, - merge_request: { - iid: 1, - path: '/root/detached-merge-request-pipelines/-/merge_requests/1', - title: 'Update README.md', - source_branch: 'feature-1', - source_branch_path: '/root/detached-merge-request-pipelines/branches/feature-1', - target_branch: 'master', - target_branch_path: '/root/detached-merge-request-pipelines/branches/master', - }, - commit: { - id: '104096c51715e12e7ae41f9333e9fa35b73f385d', - short_id: '104096c5', - title: 'Update README.md', - created_at: '2017-04-07T15:27:18.000+03:00', - parent_ids: ['2396536178668d8930c29d904e53bd4d06228b32'], - message: 'Update README.md', - author_name: 'Administrator', - author_email: 'admin@example.com', - authored_date: '2017-04-07T15:27:18.000+03:00', - committer_name: 'Administrator', - committer_email: 'admin@example.com', - committed_date: '2017-04-07T15:27:18.000+03:00', - author: { - name: 'Administrator', - username: 'root', - id: 1, - state: 'active', - avatar_url: - 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', - web_url: 'http://localhost:3000/root', - }, - author_gravatar_url: - 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', - commit_url: - 'http://localhost:3000/root/acets-app/commit/104096c51715e12e7ae41f9333e9fa35b73f385d', - commit_path: '/root/acets-app/commit/104096c51715e12e7ae41f9333e9fa35b73f385d', - }, - retry_path: '/root/acets-app/pipelines/172/retry', - created_at: '2017-04-07T12:27:19.520Z', - updated_at: '2017-04-07T15:28:44.800Z', - }, - pipelineCoverageDelta: '15.25', - work_in_progress: false, - source_branch_exists: false, - mergeable_discussions_state: true, - conflicts_can_be_resolved_in_ui: false, - branch_missing: true, - commits_count: 1, - has_conflicts: false, - can_be_merged: true, - has_ci: true, - ci_status: 'success', - pipeline_status_path: '/root/acets-app/-/merge_requests/22/pipeline_status', - issues_links: { - closing: '', - mentioned_but_not_closing: '', - }, - current_user: { - can_resolve_conflicts: true, - can_remove_source_branch: false, - can_revert_on_current_merge_request: true, - can_cherry_pick_on_current_merge_request: true, - }, - target_branch_path: '/root/acets-app/branches/master', - source_branch_path: '/root/acets-app/branches/daaaa', - conflict_resolution_ui_path: '/root/acets-app/-/merge_requests/22/conflicts', - remove_wip_path: '/root/acets-app/-/merge_requests/22/remove_wip', - cancel_auto_merge_path: '/root/acets-app/-/merge_requests/22/cancel_auto_merge', - create_issue_to_resolve_discussions_path: - '/root/acets-app/-/issues/new?merge_request_to_resolve_discussions_of=22', - merge_path: '/root/acets-app/-/merge_requests/22/merge', - cherry_pick_in_fork_path: - '/root/acets-app/forks?continue%5Bnotice%5D=You%27re+not+allowed+to+make+changes+to+this+project+directly.+A+fork+of+this+project+has+been+created+that+you+can+make+changes+in%2C+so+you+can+submit+a+merge+request.+Try+to+revert+this+commit+again.&continue%5Bnotice_now%5D=You%27re+not+allowed+to+make+changes+to+this+project+directly.+A+fork+of+this+project+is+being+created+that+you+can+make+changes+in%2C+so+you+can+submit+a+merge+request.&continue%5Bto%5D=%2Froot%2Facets-app%2Fmerge_requests%2F22&namespace_key=1', - revert_in_fork_path: - '/root/acets-app/forks?continue%5Bnotice%5D=You%27re+not+allowed+to+make+changes+to+this+project+directly.+A+fork+of+this+project+has+been+created+that+you+can+make+changes+in%2C+so+you+can+submit+a+merge+request.+Try+to+cherry-pick+this+commit+again.&continue%5Bnotice_now%5D=You%27re+not+allowed+to+make+changes+to+this+project+directly.+A+fork+of+this+project+is+being+created+that+you+can+make+changes+in%2C+so+you+can+submit+a+merge+request.&continue%5Bto%5D=%2Froot%2Facets-app%2Fmerge_requests%2F22&namespace_key=1', - email_patches_path: '/root/acets-app/-/merge_requests/22.patch', - plain_diff_path: '/root/acets-app/-/merge_requests/22.diff', - merge_request_basic_path: '/root/acets-app/-/merge_requests/22.json?serializer=basic', - merge_request_widget_path: '/root/acets-app/-/merge_requests/22/widget.json', - merge_request_cached_widget_path: '/cached.json', - merge_check_path: '/root/acets-app/-/merge_requests/22/merge_check', - ci_environments_status_url: '/root/acets-app/-/merge_requests/22/ci_environments_status', - project_archived: false, - default_merge_commit_message_with_description: - "Merge branch 'daaaa' into 'master'\n\nUpdate README.md\n\nSee merge request !22", - default_squash_commit_message: 'Test squash commit message', - diverged_commits_count: 0, - only_allow_merge_if_pipeline_succeeds: false, - commit_change_content_path: '/root/acets-app/-/merge_requests/22/commit_change_content', - merge_commit_path: - 'http://localhost:3000/root/acets-app/commit/53027d060246c8f47e4a9310fb332aa52f221775', - troubleshooting_docs_path: 'help', - merge_request_pipelines_docs_path: '/help/ci/merge_request_pipelines/index.md', - merge_train_when_pipeline_succeeds_docs_path: - '/help/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/#startadd-to-merge-train-when-pipeline-succeeds', - squash: true, - visual_review_app_available: true, - merge_trains_enabled: true, - merge_trains_count: 3, - merge_train_index: 1, -}; - -export const mockStore = { - pipeline: { - id: 0, - details: { - status: { - details_path: '/root/review-app-tester/pipelines/66', - favicon: - '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2. png', - group: 'success-with-warnings', - has_details: true, - icon: 'status_warning', - illustration: null, - label: 'passed with warnings', - text: 'passed', - tooltip: 'passed', - }, - }, - flags: {}, - ref: {}, - }, - mergePipeline: { - id: 1, - details: { - status: { - details_path: '/root/review-app-tester/pipelines/66', - favicon: - '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2. png', - group: 'success-with-warnings', - has_details: true, - icon: 'status_warning', - illustration: null, - label: 'passed with warnings', - text: 'passed', - tooltip: 'passed', - }, - }, - flags: {}, - ref: {}, - }, - targetBranch: 'target-branch', - sourceBranch: 'source-branch', - sourceBranchLink: 'source-branch-link', - deployments: [ - { - id: 0, - name: 'bogus', - external_url: 'https://fake.com', - external_url_formatted: 'https://fake.com', - status: SUCCESS, - }, - { - id: 1, - name: 'bogus-docs', - external_url: 'https://fake.com', - external_url_formatted: 'https://fake.com', - status: SUCCESS, - }, - ], - postMergeDeployments: [ - { id: 0, name: 'prod', status: SUCCESS }, - { id: 1, name: 'prod-docs', status: SUCCESS }, - ], - troubleshootingDocsPath: 'troubleshooting-docs-path', - ciStatus: 'ci-status', - hasCI: true, - exposedArtifactsPath: 'exposed_artifacts.json', -}; +export { default } from '../../frontend/vue_mr_widget/mock_data'; +export * from '../../frontend/vue_mr_widget/mock_data'; diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js deleted file mode 100644 index 4237bdd80be..00000000000 --- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js +++ /dev/null @@ -1,842 +0,0 @@ -import Vue from 'vue'; -import MockAdapter from 'axios-mock-adapter'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import waitForPromises from 'spec/helpers/wait_for_promises'; -import axios from '~/lib/utils/axios_utils'; -import mrWidgetOptions from '~/vue_merge_request_widget/mr_widget_options.vue'; -import eventHub from '~/vue_merge_request_widget/event_hub'; -import notify from '~/lib/utils/notify'; -import { stateKey } from '~/vue_merge_request_widget/stores/state_maps'; -import mockData from './mock_data'; -import { faviconDataUrl, overlayDataUrl } from '../lib/utils/mock_data'; -import { SUCCESS } from '~/vue_merge_request_widget/components/deployment/constants'; - -const returnPromise = data => - new Promise(resolve => { - resolve({ - data, - }); - }); - -describe('mrWidgetOptions', () => { - let vm; - let mock; - let MrWidgetOptions; - - const COLLABORATION_MESSAGE = 'Allows commits from members who can merge to the target branch'; - - beforeEach(() => { - jasmine.clock().install(); - // Prevent component mounting - delete mrWidgetOptions.el; - - gl.mrWidgetData = { ...mockData }; - gon.features = { asyncMrWidget: true }; - - mock = new MockAdapter(axios); - mock.onGet(mockData.merge_request_widget_path).reply(() => [200, { ...mockData }]); - mock.onGet(mockData.merge_request_cached_widget_path).reply(() => [200, { ...mockData }]); - - MrWidgetOptions = Vue.extend(mrWidgetOptions); - }); - - afterEach(() => { - jasmine.clock().uninstall(); - mock.restore(); - - vm.$destroy(); - vm = null; - - gl.mrWidgetData = {}; - gon.features = {}; - }); - - const createComponent = () => { - if (vm) { - vm.$destroy(); - } - - vm = mountComponent(MrWidgetOptions, { - mrData: { ...mockData }, - }); - }; - - describe('default', () => { - beforeEach(() => { - createComponent(); - }); - - describe('data', () => { - it('should instantiate Store and Service', () => { - expect(vm.mr).toBeDefined(); - expect(vm.service).toBeDefined(); - }); - }); - - describe('computed', () => { - describe('componentName', () => { - it('should return merged component', () => { - expect(vm.componentName).toEqual('mr-widget-merged'); - }); - - it('should return conflicts component', () => { - vm.mr.state = 'conflicts'; - - expect(vm.componentName).toEqual('mr-widget-conflicts'); - }); - }); - - describe('shouldRenderMergeHelp', () => { - it('should return false for the initial merged state', () => { - expect(vm.shouldRenderMergeHelp).toBeFalsy(); - }); - - it('should return true for a state which requires help widget', () => { - vm.mr.state = 'conflicts'; - - expect(vm.shouldRenderMergeHelp).toBeTruthy(); - }); - }); - - describe('shouldRenderPipelines', () => { - it('should return true when hasCI is true', () => { - vm.mr.hasCI = true; - - expect(vm.shouldRenderPipelines).toBeTruthy(); - }); - - it('should return false when hasCI is false', () => { - vm.mr.hasCI = false; - - expect(vm.shouldRenderPipelines).toBeFalsy(); - }); - }); - - describe('shouldRenderRelatedLinks', () => { - it('should return false for the initial data', () => { - expect(vm.shouldRenderRelatedLinks).toBeFalsy(); - }); - - it('should return true if there is relatedLinks in MR', () => { - Vue.set(vm.mr, 'relatedLinks', {}); - - expect(vm.shouldRenderRelatedLinks).toBeTruthy(); - }); - }); - - describe('shouldRenderSourceBranchRemovalStatus', () => { - beforeEach(() => { - vm.mr.state = 'readyToMerge'; - }); - - it('should return true when cannot remove source branch and branch will be removed', () => { - vm.mr.canRemoveSourceBranch = false; - vm.mr.shouldRemoveSourceBranch = true; - - expect(vm.shouldRenderSourceBranchRemovalStatus).toEqual(true); - }); - - it('should return false when can remove source branch and branch will be removed', () => { - vm.mr.canRemoveSourceBranch = true; - vm.mr.shouldRemoveSourceBranch = true; - - expect(vm.shouldRenderSourceBranchRemovalStatus).toEqual(false); - }); - - it('should return false when cannot remove source branch and branch will not be removed', () => { - vm.mr.canRemoveSourceBranch = false; - vm.mr.shouldRemoveSourceBranch = false; - - expect(vm.shouldRenderSourceBranchRemovalStatus).toEqual(false); - }); - - it('should return false when in merged state', () => { - vm.mr.canRemoveSourceBranch = false; - vm.mr.shouldRemoveSourceBranch = true; - vm.mr.state = 'merged'; - - expect(vm.shouldRenderSourceBranchRemovalStatus).toEqual(false); - }); - - it('should return false when in nothing to merge state', () => { - vm.mr.canRemoveSourceBranch = false; - vm.mr.shouldRemoveSourceBranch = true; - vm.mr.state = 'nothingToMerge'; - - expect(vm.shouldRenderSourceBranchRemovalStatus).toEqual(false); - }); - }); - - describe('shouldRenderCollaborationStatus', () => { - describe('when collaboration is allowed', () => { - beforeEach(() => { - vm.mr.allowCollaboration = true; - }); - - describe('when merge request is opened', () => { - beforeEach(done => { - vm.mr.isOpen = true; - vm.$nextTick(done); - }); - - it('should render collaboration status', () => { - expect(vm.$el.textContent).toContain(COLLABORATION_MESSAGE); - }); - }); - - describe('when merge request is not opened', () => { - beforeEach(done => { - vm.mr.isOpen = false; - vm.$nextTick(done); - }); - - it('should not render collaboration status', () => { - expect(vm.$el.textContent).not.toContain(COLLABORATION_MESSAGE); - }); - }); - }); - - describe('when collaboration is not allowed', () => { - beforeEach(() => { - vm.mr.allowCollaboration = false; - }); - - describe('when merge request is opened', () => { - beforeEach(done => { - vm.mr.isOpen = true; - vm.$nextTick(done); - }); - - it('should not render collaboration status', () => { - expect(vm.$el.textContent).not.toContain(COLLABORATION_MESSAGE); - }); - }); - }); - }); - - describe('showMergePipelineForkWarning', () => { - describe('when the source project and target project are the same', () => { - beforeEach(done => { - Vue.set(vm.mr, 'mergePipelinesEnabled', true); - Vue.set(vm.mr, 'sourceProjectId', 1); - Vue.set(vm.mr, 'targetProjectId', 1); - vm.$nextTick(done); - }); - - it('should be false', () => { - expect(vm.showMergePipelineForkWarning).toEqual(false); - }); - }); - - describe('when merge pipelines are not enabled', () => { - beforeEach(done => { - Vue.set(vm.mr, 'mergePipelinesEnabled', false); - Vue.set(vm.mr, 'sourceProjectId', 1); - Vue.set(vm.mr, 'targetProjectId', 2); - vm.$nextTick(done); - }); - - it('should be false', () => { - expect(vm.showMergePipelineForkWarning).toEqual(false); - }); - }); - - describe('when merge pipelines are enabled _and_ the source project and target project are different', () => { - beforeEach(done => { - Vue.set(vm.mr, 'mergePipelinesEnabled', true); - Vue.set(vm.mr, 'sourceProjectId', 1); - Vue.set(vm.mr, 'targetProjectId', 2); - vm.$nextTick(done); - }); - - it('should be true', () => { - expect(vm.showMergePipelineForkWarning).toEqual(true); - }); - }); - }); - }); - - describe('methods', () => { - describe('checkStatus', () => { - it('should tell service to check status', () => { - spyOn(vm.service, 'checkStatus').and.returnValue(returnPromise(mockData)); - spyOn(vm.mr, 'setData'); - spyOn(vm, 'handleNotification'); - - let isCbExecuted = false; - const cb = () => { - isCbExecuted = true; - }; - - vm.checkStatus(cb); - - return vm.$nextTick().then(() => { - expect(vm.service.checkStatus).toHaveBeenCalled(); - expect(vm.mr.setData).toHaveBeenCalled(); - expect(vm.handleNotification).toHaveBeenCalledWith(mockData); - expect(isCbExecuted).toBeTruthy(); - }); - }); - }); - - describe('initPolling', () => { - it('should call SmartInterval', () => { - spyOn(vm, 'checkStatus').and.returnValue(Promise.resolve()); - vm.initPolling(); - - expect(vm.checkStatus).not.toHaveBeenCalled(); - - jasmine.clock().tick(10000); - - expect(vm.pollingInterval).toBeDefined(); - expect(vm.checkStatus).toHaveBeenCalled(); - }); - }); - - describe('initDeploymentsPolling', () => { - it('should call SmartInterval', () => { - spyOn(vm, 'fetchDeployments').and.returnValue(Promise.resolve()); - vm.initDeploymentsPolling(); - - expect(vm.deploymentsInterval).toBeDefined(); - expect(vm.fetchDeployments).toHaveBeenCalled(); - }); - }); - - describe('fetchDeployments', () => { - it('should fetch deployments', () => { - spyOn(vm.service, 'fetchDeployments').and.returnValue( - returnPromise([{ id: 1, status: SUCCESS }]), - ); - - vm.fetchPreMergeDeployments(); - - return vm.$nextTick().then(() => { - expect(vm.service.fetchDeployments).toHaveBeenCalled(); - expect(vm.mr.deployments.length).toEqual(1); - expect(vm.mr.deployments[0].id).toBe(1); - }); - }); - }); - - describe('fetchActionsContent', () => { - it('should fetch content of Cherry Pick and Revert modals', () => { - spyOn(vm.service, 'fetchMergeActionsContent').and.returnValue( - returnPromise('hello world'), - ); - - vm.fetchActionsContent(); - - return vm.$nextTick().then(() => { - expect(vm.service.fetchMergeActionsContent).toHaveBeenCalled(); - expect(document.body.textContent).toContain('hello world'); - }); - }); - }); - - describe('bindEventHubListeners', () => { - it('should bind eventHub listeners', () => { - spyOn(vm, 'checkStatus').and.returnValue(() => {}); - spyOn(vm.service, 'checkStatus').and.returnValue(returnPromise(mockData)); - spyOn(vm, 'fetchActionsContent'); - spyOn(vm.mr, 'setData'); - spyOn(vm, 'resumePolling'); - spyOn(vm, 'stopPolling'); - spyOn(eventHub, '$on').and.callThrough(); - - return waitForPromises().then(() => { - eventHub.$emit('SetBranchRemoveFlag', ['flag']); - - expect(vm.mr.isRemovingSourceBranch).toEqual('flag'); - - eventHub.$emit('FailedToMerge'); - - expect(vm.mr.state).toEqual('failedToMerge'); - - eventHub.$emit('UpdateWidgetData', mockData); - - expect(vm.mr.setData).toHaveBeenCalledWith(mockData); - - eventHub.$emit('EnablePolling'); - - expect(vm.resumePolling).toHaveBeenCalled(); - - eventHub.$emit('DisablePolling'); - - expect(vm.stopPolling).toHaveBeenCalled(); - - const listenersWithServiceRequest = { - MRWidgetUpdateRequested: true, - FetchActionsContent: true, - }; - - const allArgs = eventHub.$on.calls.allArgs(); - allArgs.forEach(params => { - const eventName = params[0]; - const callback = params[1]; - - if (listenersWithServiceRequest[eventName]) { - listenersWithServiceRequest[eventName] = callback; - } - }); - - listenersWithServiceRequest.MRWidgetUpdateRequested(); - - expect(vm.checkStatus).toHaveBeenCalled(); - - listenersWithServiceRequest.FetchActionsContent(); - - expect(vm.fetchActionsContent).toHaveBeenCalled(); - }); - }); - }); - - describe('setFavicon', () => { - let faviconElement; - - beforeEach(() => { - const favicon = document.createElement('link'); - favicon.setAttribute('id', 'favicon'); - favicon.setAttribute('data-original-href', faviconDataUrl); - document.body.appendChild(favicon); - - faviconElement = document.getElementById('favicon'); - }); - - afterEach(() => { - document.body.removeChild(document.getElementById('favicon')); - }); - - it('should call setFavicon method', done => { - vm.mr.ciStatusFaviconPath = overlayDataUrl; - vm.setFaviconHelper() - .then(() => { - /* - It would be better if we'd could mock commonUtils.setFaviconURL - with a spy and test that it was called. We are doing the following - tests as a proxy to show that the function has been called - */ - expect(faviconElement.getAttribute('href')).not.toEqual(null); - expect(faviconElement.getAttribute('href')).not.toEqual(overlayDataUrl); - expect(faviconElement.getAttribute('href')).not.toEqual(faviconDataUrl); - done(); - }) - .catch(done.fail); - }); - - it('should not call setFavicon when there is no ciStatusFaviconPath', done => { - vm.mr.ciStatusFaviconPath = null; - vm.setFaviconHelper() - .then(() => { - expect(faviconElement.getAttribute('href')).toEqual(null); - done(); - }) - .catch(done.fail); - }); - }); - - describe('handleNotification', () => { - const data = { - ci_status: 'running', - title: 'title', - pipeline: { details: { status: { label: 'running-label' } } }, - }; - - beforeEach(() => { - spyOn(notify, 'notifyMe'); - - vm.mr.ciStatus = 'failed'; - vm.mr.gitlabLogo = 'logo.png'; - }); - - it('should call notifyMe', () => { - vm.handleNotification(data); - - expect(notify.notifyMe).toHaveBeenCalledWith( - 'Pipeline running-label', - 'Pipeline running-label for "title"', - 'logo.png', - ); - }); - - it('should not call notifyMe if the status has not changed', () => { - vm.mr.ciStatus = data.ci_status; - - vm.handleNotification(data); - - expect(notify.notifyMe).not.toHaveBeenCalled(); - }); - - it('should not notify if no pipeline provided', () => { - vm.handleNotification({ - ...data, - pipeline: undefined, - }); - - expect(notify.notifyMe).not.toHaveBeenCalled(); - }); - }); - - describe('resumePolling', () => { - it('should call stopTimer on pollingInterval', () => - waitForPromises().then(() => { - spyOn(vm.pollingInterval, 'resume'); - - vm.resumePolling(); - - expect(vm.pollingInterval.resume).toHaveBeenCalled(); - })); - }); - - describe('stopPolling', () => { - it('should call stopTimer on pollingInterval', () => - waitForPromises().then(() => { - spyOn(vm.pollingInterval, 'stopTimer'); - - vm.stopPolling(); - - expect(vm.pollingInterval.stopTimer).toHaveBeenCalled(); - })); - }); - }); - - describe('rendering relatedLinks', () => { - beforeEach(done => { - vm.mr.relatedLinks = { - assignToMe: null, - closing: ` - - Close - - `, - mentioned: '', - }; - Vue.nextTick(done); - }); - - it('renders if there are relatedLinks', () => { - expect(vm.$el.querySelector('.close-related-link')).toBeDefined(); - }); - - it('does not render if state is nothingToMerge', done => { - vm.mr.state = stateKey.nothingToMerge; - Vue.nextTick(() => { - expect(vm.$el.querySelector('.close-related-link')).toBeNull(); - done(); - }); - }); - }); - - describe('rendering source branch removal status', () => { - it('renders when user cannot remove branch and branch should be removed', done => { - vm.mr.canRemoveSourceBranch = false; - vm.mr.shouldRemoveSourceBranch = true; - vm.mr.state = 'readyToMerge'; - - vm.$nextTick(() => { - const tooltip = vm.$el.querySelector('.fa-question-circle'); - - expect(vm.$el.textContent).toContain('Deletes source branch'); - expect(tooltip.getAttribute('data-original-title')).toBe( - 'A user with write access to the source branch selected this option', - ); - - done(); - }); - }); - - it('does not render in merged state', done => { - vm.mr.canRemoveSourceBranch = false; - vm.mr.shouldRemoveSourceBranch = true; - vm.mr.state = 'merged'; - - vm.$nextTick(() => { - expect(vm.$el.textContent).toContain('The source branch has been deleted'); - expect(vm.$el.textContent).not.toContain('Deletes source branch'); - - done(); - }); - }); - }); - - describe('rendering deployments', () => { - const changes = [ - { - path: 'index.html', - external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/index.html', - }, - { - path: 'imgs/gallery.html', - external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/imgs/gallery.html', - }, - { - path: 'about/', - external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/about/', - }, - ]; - const deploymentMockData = { - id: 15, - name: 'review/diplo', - url: '/root/acets-review-apps/environments/15', - stop_url: '/root/acets-review-apps/environments/15/stop', - metrics_url: '/root/acets-review-apps/environments/15/deployments/1/metrics', - metrics_monitoring_url: '/root/acets-review-apps/environments/15/metrics', - external_url: 'http://diplo.', - external_url_formatted: 'diplo.', - deployed_at: '2017-03-22T22:44:42.258Z', - deployed_at_formatted: 'Mar 22, 2017 10:44pm', - changes, - status: SUCCESS, - }; - - beforeEach(done => { - vm.mr.deployments.push( - { - ...deploymentMockData, - }, - { - ...deploymentMockData, - id: deploymentMockData.id + 1, - }, - ); - - vm.$nextTick(done); - }); - - it('renders multiple deployments', () => { - expect(vm.$el.querySelectorAll('.deploy-heading').length).toBe(2); - }); - - it('renders dropdpown with multiple file changes', () => { - expect( - vm.$el - .querySelector('.js-mr-wigdet-deployment-dropdown') - .querySelectorAll('.js-filtered-dropdown-result').length, - ).toEqual(changes.length); - }); - }); - - describe('pipeline for target branch after merge', () => { - describe('with information for target branch pipeline', () => { - beforeEach(done => { - vm.mr.state = 'merged'; - vm.mr.mergePipeline = { - id: 127, - user: { - id: 1, - name: 'Administrator', - username: 'root', - state: 'active', - avatar_url: null, - web_url: 'http://localhost:3000/root', - status_tooltip_html: null, - path: '/root', - }, - active: true, - coverage: null, - source: 'push', - created_at: '2018-10-22T11:41:35.186Z', - updated_at: '2018-10-22T11:41:35.433Z', - path: '/root/ci-web-terminal/pipelines/127', - flags: { - latest: true, - stuck: true, - auto_devops: false, - yaml_errors: false, - retryable: false, - cancelable: true, - failure_reason: false, - }, - details: { - status: { - icon: 'status_pending', - text: 'pending', - label: 'pending', - group: 'pending', - tooltip: 'pending', - has_details: true, - details_path: '/root/ci-web-terminal/pipelines/127', - illustration: null, - favicon: - '/assets/ci_favicons/favicon_status_pending-5bdf338420e5221ca24353b6bff1c9367189588750632e9a871b7af09ff6a2ae.png', - }, - duration: null, - finished_at: null, - stages: [ - { - name: 'test', - title: 'test: pending', - status: { - icon: 'status_pending', - text: 'pending', - label: 'pending', - group: 'pending', - tooltip: 'pending', - has_details: true, - details_path: '/root/ci-web-terminal/pipelines/127#test', - illustration: null, - favicon: - '/assets/ci_favicons/favicon_status_pending-5bdf338420e5221ca24353b6bff1c9367189588750632e9a871b7af09ff6a2ae.png', - }, - path: '/root/ci-web-terminal/pipelines/127#test', - dropdown_path: '/root/ci-web-terminal/pipelines/127/stage.json?stage=test', - }, - ], - artifacts: [], - manual_actions: [], - scheduled_actions: [], - }, - ref: { - name: 'master', - path: '/root/ci-web-terminal/commits/master', - tag: false, - branch: true, - }, - commit: { - id: 'aa1939133d373c94879becb79d91828a892ee319', - short_id: 'aa193913', - title: "Merge branch 'master-test' into 'master'", - created_at: '2018-10-22T11:41:33.000Z', - parent_ids: [ - '4622f4dd792468993003caf2e3be978798cbe096', - '76598df914cdfe87132d0c3c40f80db9fa9396a4', - ], - message: - "Merge branch 'master-test' into 'master'\n\nUpdate .gitlab-ci.yml\n\nSee merge request root/ci-web-terminal!1", - author_name: 'Administrator', - author_email: 'admin@example.com', - authored_date: '2018-10-22T11:41:33.000Z', - committer_name: 'Administrator', - committer_email: 'admin@example.com', - committed_date: '2018-10-22T11:41:33.000Z', - author: { - id: 1, - name: 'Administrator', - username: 'root', - state: 'active', - avatar_url: null, - web_url: 'http://localhost:3000/root', - status_tooltip_html: null, - path: '/root', - }, - author_gravatar_url: null, - commit_url: - 'http://localhost:3000/root/ci-web-terminal/commit/aa1939133d373c94879becb79d91828a892ee319', - commit_path: '/root/ci-web-terminal/commit/aa1939133d373c94879becb79d91828a892ee319', - }, - cancel_path: '/root/ci-web-terminal/pipelines/127/cancel', - }; - vm.$nextTick(done); - }); - - it('renders pipeline block', () => { - expect(vm.$el.querySelector('.js-post-merge-pipeline')).not.toBeNull(); - }); - - describe('with post merge deployments', () => { - beforeEach(done => { - vm.mr.postMergeDeployments = [ - { - id: 15, - name: 'review/diplo', - url: '/root/acets-review-apps/environments/15', - stop_url: '/root/acets-review-apps/environments/15/stop', - metrics_url: '/root/acets-review-apps/environments/15/deployments/1/metrics', - metrics_monitoring_url: '/root/acets-review-apps/environments/15/metrics', - external_url: 'http://diplo.', - external_url_formatted: 'diplo.', - deployed_at: '2017-03-22T22:44:42.258Z', - deployed_at_formatted: 'Mar 22, 2017 10:44pm', - changes: [ - { - path: 'index.html', - external_url: - 'http://root-master-patch-91341.volatile-watch.surge.sh/index.html', - }, - { - path: 'imgs/gallery.html', - external_url: - 'http://root-master-patch-91341.volatile-watch.surge.sh/imgs/gallery.html', - }, - { - path: 'about/', - external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/about/', - }, - ], - status: 'success', - }, - ]; - - vm.$nextTick(done); - }); - - it('renders post deployment information', () => { - expect(vm.$el.querySelector('.js-post-deployment')).not.toBeNull(); - }); - }); - }); - - describe('without information for target branch pipeline', () => { - beforeEach(done => { - vm.mr.state = 'merged'; - - vm.$nextTick(done); - }); - - it('does not render pipeline block', () => { - expect(vm.$el.querySelector('.js-post-merge-pipeline')).toBeNull(); - }); - }); - - describe('when state is not merged', () => { - beforeEach(done => { - vm.mr.state = 'archived'; - - vm.$nextTick(done); - }); - - it('does not render pipeline block', () => { - expect(vm.$el.querySelector('.js-post-merge-pipeline')).toBeNull(); - }); - - it('does not render post deployment information', () => { - expect(vm.$el.querySelector('.js-post-deployment')).toBeNull(); - }); - }); - }); - - it('should not suggest pipelines', () => { - vm.mr.mergeRequestAddCiConfigPath = null; - - expect(vm.shouldSuggestPipelines).toBeFalsy(); - }); - }); - - describe('given suggestPipeline feature flag is enabled', () => { - beforeEach(() => { - gon.features = { suggestPipeline: true }; - createComponent(); - }); - - it('should suggest pipelines when none exist', () => { - vm.mr.mergeRequestAddCiConfigPath = 'some/path'; - vm.mr.hasCI = false; - - expect(vm.shouldSuggestPipelines).toBeTruthy(); - }); - - it('should not suggest pipelines when they exist', () => { - vm.mr.mergeRequestAddCiConfigPath = null; - vm.mr.hasCI = false; - - expect(vm.shouldSuggestPipelines).toBeFalsy(); - }); - - it('should not suggest pipelines hasCI is true', () => { - vm.mr.mergeRequestAddCiConfigPath = 'some/path'; - vm.mr.hasCI = true; - - expect(vm.shouldSuggestPipelines).toBeFalsy(); - }); - }); -}); diff --git a/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb b/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb index 4ba5726732c..8b93ef86eba 100644 --- a/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb +++ b/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb @@ -124,28 +124,28 @@ describe Gitlab::SidekiqConfig::CliMethods do name: 'a', feature_category: :category_a, has_external_dependencies: false, - latency_sensitive: false, + urgency: :default, resource_boundary: :cpu }, { name: 'a:2', feature_category: :category_a, has_external_dependencies: false, - latency_sensitive: true, + urgency: :high, resource_boundary: :none }, { name: 'b', feature_category: :category_b, has_external_dependencies: true, - latency_sensitive: true, + urgency: :high, resource_boundary: :memory }, { name: 'c', feature_category: :category_c, has_external_dependencies: false, - latency_sensitive: false, + urgency: :none, resource_boundary: :memory } ] @@ -166,12 +166,12 @@ describe Gitlab::SidekiqConfig::CliMethods do 'has_external_dependencies=true|has_external_dependencies=false' | %w(a a:2 b c) 'has_external_dependencies!=true' | %w(a a:2 c) - # latency_sensitive - 'latency_sensitive=true' | %w(a:2 b) - 'latency_sensitive=false' | %w(a c) - 'latency_sensitive=true,false' | %w(a a:2 b c) - 'latency_sensitive=true|latency_sensitive=false' | %w(a a:2 b c) - 'latency_sensitive!=true' | %w(a c) + # urgency + 'urgency=high' | %w(a:2 b) + 'urgency=default' | %w(a) + 'urgency=high,default,none' | %w(a a:2 b c) + 'urgency=default|urgency=none' | %w(a c) + 'urgency!=high' | %w(a c) # name 'name=a' | %w(a) @@ -186,8 +186,8 @@ describe Gitlab::SidekiqConfig::CliMethods do 'resource_boundary!=memory,cpu' | %w(a:2) # combinations - 'feature_category=category_a&latency_sensitive=true' | %w(a:2) - 'feature_category=category_a&latency_sensitive=true|feature_category=category_c' | %w(a:2 c) + 'feature_category=category_a&urgency=high' | %w(a:2) + 'feature_category=category_a&urgency=high|feature_category=category_c' | %w(a:2 c) end with_them do diff --git a/spec/lib/gitlab/sidekiq_config/worker_spec.rb b/spec/lib/gitlab/sidekiq_config/worker_spec.rb index fcdce8f9432..71fafbf0656 100644 --- a/spec/lib/gitlab/sidekiq_config/worker_spec.rb +++ b/spec/lib/gitlab/sidekiq_config/worker_spec.rb @@ -11,7 +11,7 @@ describe Gitlab::SidekiqConfig::Worker do get_feature_category: attributes[:feature_category], get_weight: attributes[:weight], get_worker_resource_boundary: attributes[:resource_boundary], - latency_sensitive_worker?: attributes[:latency_sensitive], + get_urgency: attributes[:urgency], worker_has_external_dependencies?: attributes[:has_external_dependencies], idempotent?: attributes[:idempotent] ) @@ -47,7 +47,7 @@ describe Gitlab::SidekiqConfig::Worker do describe 'delegations' do [ :feature_category_not_owned?, :get_feature_category, :get_weight, - :get_worker_resource_boundary, :latency_sensitive_worker?, :queue, + :get_worker_resource_boundary, :get_urgency, :queue, :queue_namespace, :worker_has_external_dependencies? ].each do |meth| it "delegates #{meth} to the worker class" do @@ -88,7 +88,7 @@ describe Gitlab::SidekiqConfig::Worker do attributes_a = { feature_category: :source_code_management, has_external_dependencies: false, - latency_sensitive: false, + urgency: :default, resource_boundary: :memory, weight: 2, idempotent: true @@ -97,7 +97,7 @@ describe Gitlab::SidekiqConfig::Worker do attributes_b = { feature_category: :not_owned, has_external_dependencies: true, - latency_sensitive: true, + urgency: :high, resource_boundary: :unknown, weight: 3, idempotent: false diff --git a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb index f294d7f7fcd..bd04d30f85f 100644 --- a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb +++ b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb @@ -11,7 +11,7 @@ describe Gitlab::SidekiqLogging::StructuredLogger do let(:job) do { "class" => "TestWorker", - "args" => [1234, 'hello'], + "args" => [1234, 'hello', { 'key' => 'value' }], "retry" => false, "queue" => "cronjob:test_queue", "queue_namespace" => "cronjob", @@ -30,6 +30,7 @@ describe Gitlab::SidekiqLogging::StructuredLogger do let(:clock_thread_cputime_end) { 1.333333799 } let(:start_payload) do job.except('error_backtrace', 'error_class', 'error_message').merge( + 'args' => %w(1234 hello {"key"=>"value"}), 'message' => 'TestWorker JID-da883554ee4fe414012f5f42: start', 'job_status' => 'start', 'pid' => Process.pid, @@ -99,13 +100,27 @@ describe Gitlab::SidekiqLogging::StructuredLogger do end end + it 'does not modify the job' do + Timecop.freeze(timestamp) do + job_copy = job.deep_dup + + allow(logger).to receive(:info) + allow(subject).to receive(:log_job_start).and_call_original + allow(subject).to receive(:log_job_done).and_call_original + + subject.call(job, 'test_queue') do + expect(job).to eq(job_copy) + end + end + end + context 'when the job args are bigger than the maximum allowed' do it 'keeps args from the front until they exceed the limit' do Timecop.freeze(timestamp) do half_limit = Gitlab::Utils::LogLimitedArray::MAXIMUM_ARRAY_LENGTH / 2 job['args'] = [1, 2, 'a' * half_limit, 'b' * half_limit, 3] - expected_args = job['args'].take(3) + ['...'] + expected_args = job['args'].take(3).map(&:to_s) + ['...'] expect(logger).to receive(:info).with(start_payload.merge('args' => expected_args)).ordered expect(logger).to receive(:info).with(end_payload.merge('args' => expected_args)).ordered diff --git a/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb b/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb index daee2c0bbd0..689c7e40727 100644 --- a/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb +++ b/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb @@ -9,7 +9,7 @@ describe Gitlab::SidekiqMiddleware::ClientMetrics do let(:queue) { :test } let(:worker_class) { worker.class } let(:job) { {} } - let(:default_labels) { { queue: queue.to_s, boundary: "", external_dependencies: "no", feature_category: "", latency_sensitive: "no" } } + let(:default_labels) { { queue: queue.to_s, boundary: "", external_dependencies: "no", feature_category: "", urgency: "default" } } shared_examples "a metrics client middleware" do context "with mocked prometheus" do @@ -46,17 +46,17 @@ describe Gitlab::SidekiqMiddleware::ClientMetrics do it_behaves_like "a metrics client middleware" do let(:worker) { TestNonAttributedWorker.new } - let(:labels) { default_labels } + let(:labels) { default_labels.merge(urgency: "") } end end context "when workers are attributed" do - def create_attributed_worker_class(latency_sensitive, external_dependencies, resource_boundary, category) + def create_attributed_worker_class(urgency, external_dependencies, resource_boundary, category) klass = Class.new do include Sidekiq::Worker include WorkerAttributes - latency_sensitive_worker! if latency_sensitive + urgency urgency if urgency worker_has_external_dependencies! if external_dependencies worker_resource_boundary resource_boundary unless resource_boundary == :unknown feature_category category unless category.nil? @@ -64,17 +64,24 @@ describe Gitlab::SidekiqMiddleware::ClientMetrics do stub_const("TestAttributedWorker", klass) end - let(:latency_sensitive) { false } + let(:urgency) { nil } let(:external_dependencies) { false } let(:resource_boundary) { :unknown } let(:feature_category) { nil } - let(:worker_class) { create_attributed_worker_class(latency_sensitive, external_dependencies, resource_boundary, feature_category) } + let(:worker_class) { create_attributed_worker_class(urgency, external_dependencies, resource_boundary, feature_category) } let(:worker) { worker_class.new } - context "latency sensitive" do + context "high urgency" do it_behaves_like "a metrics client middleware" do - let(:latency_sensitive) { true } - let(:labels) { default_labels.merge(latency_sensitive: "yes") } + let(:urgency) { :high } + let(:labels) { default_labels.merge(urgency: "high") } + end + end + + context "no urgency" do + it_behaves_like "a metrics client middleware" do + let(:urgency) { :none } + let(:labels) { default_labels.merge(urgency: "none") } end end @@ -108,11 +115,11 @@ describe Gitlab::SidekiqMiddleware::ClientMetrics do context "combined" do it_behaves_like "a metrics client middleware" do - let(:latency_sensitive) { true } + let(:urgency) { :high } let(:external_dependencies) { true } let(:resource_boundary) { :cpu } let(:feature_category) { :authentication } - let(:labels) { default_labels.merge(latency_sensitive: "yes", external_dependencies: "yes", boundary: "cpu", feature_category: "authentication") } + let(:labels) { default_labels.merge(urgency: "high", external_dependencies: "yes", boundary: "cpu", feature_category: "authentication") } end end end diff --git a/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb b/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb index 65a961b34f8..47442f4ee86 100644 --- a/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb +++ b/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb @@ -11,7 +11,7 @@ describe Gitlab::SidekiqMiddleware::ServerMetrics do let(:job) { {} } let(:job_status) { :done } let(:labels_with_job_status) { labels.merge(job_status: job_status.to_s) } - let(:default_labels) { { queue: queue.to_s, boundary: "", external_dependencies: "no", feature_category: "", latency_sensitive: "no" } } + let(:default_labels) { { queue: queue.to_s, boundary: "", external_dependencies: "no", feature_category: "", urgency: "default" } } shared_examples "a metrics middleware" do context "with mocked prometheus" do @@ -130,34 +130,34 @@ describe Gitlab::SidekiqMiddleware::ServerMetrics do include Sidekiq::Worker end let(:worker) { TestNonAttributedWorker.new } - let(:labels) { default_labels } + let(:labels) { default_labels.merge(urgency: "") } it_behaves_like "a metrics middleware" end context "when workers are attributed" do - def create_attributed_worker_class(latency_sensitive, external_dependencies, resource_boundary, category) + def create_attributed_worker_class(urgency, external_dependencies, resource_boundary, category) Class.new do include Sidekiq::Worker include WorkerAttributes - latency_sensitive_worker! if latency_sensitive + urgency urgency if urgency worker_has_external_dependencies! if external_dependencies worker_resource_boundary resource_boundary unless resource_boundary == :unknown feature_category category unless category.nil? end end - let(:latency_sensitive) { false } + let(:urgency) { nil } let(:external_dependencies) { false } let(:resource_boundary) { :unknown } let(:feature_category) { nil } - let(:worker_class) { create_attributed_worker_class(latency_sensitive, external_dependencies, resource_boundary, feature_category) } + let(:worker_class) { create_attributed_worker_class(urgency, external_dependencies, resource_boundary, feature_category) } let(:worker) { worker_class.new } - context "latency sensitive" do - let(:latency_sensitive) { true } - let(:labels) { default_labels.merge(latency_sensitive: "yes") } + context "high urgency" do + let(:urgency) { :high } + let(:labels) { default_labels.merge(urgency: "high") } it_behaves_like "a metrics middleware" end @@ -191,11 +191,11 @@ describe Gitlab::SidekiqMiddleware::ServerMetrics do end context "combined" do - let(:latency_sensitive) { true } + let(:urgency) { :none } let(:external_dependencies) { true } let(:resource_boundary) { :cpu } let(:feature_category) { :authentication } - let(:labels) { default_labels.merge(latency_sensitive: "yes", external_dependencies: "yes", boundary: "cpu", feature_category: "authentication") } + let(:labels) { default_labels.merge(urgency: "none", external_dependencies: "yes", boundary: "cpu", feature_category: "authentication") } it_behaves_like "a metrics middleware" end diff --git a/spec/models/concerns/avatarable_spec.rb b/spec/models/concerns/avatarable_spec.rb index 100953549ea..96e867dbc97 100644 --- a/spec/models/concerns/avatarable_spec.rb +++ b/spec/models/concerns/avatarable_spec.rb @@ -15,7 +15,7 @@ describe Avatarable do end describe '#update' do - let(:validator) { project._validators[:avatar].detect { |v| v.is_a?(FileSizeValidator) } } + let(:validator) { project.class.validators_on(:avatar).find { |v| v.is_a?(FileSizeValidator) } } context 'when avatar changed' do it 'validates the file size' do diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index be5479cfc11..8ed7abc968b 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -192,16 +192,17 @@ describe WikiPage do expect(subject).not_to be_valid expect(subject.errors[:title]).to contain_exactly( - "exceeds the limit of #{max_title} bytes for page titles" + "exceeds the limit of #{max_title} bytes" ) end it 'rejects directories exceeding the limit' do - subject.title = invalid_directory + '/foo' + subject.title = "#{invalid_directory}/#{invalid_directory}2/foo" expect(subject).not_to be_valid expect(subject.errors[:title]).to contain_exactly( - "exceeds the limit of #{max_directory} bytes for directory names" + "exceeds the limit of #{max_directory} bytes for directory name \"#{invalid_directory}\"", + "exceeds the limit of #{max_directory} bytes for directory name \"#{invalid_directory}2\"" ) end @@ -210,8 +211,8 @@ describe WikiPage do expect(subject).not_to be_valid expect(subject.errors[:title]).to contain_exactly( - "exceeds the limit of #{max_title} bytes for page titles", - "exceeds the limit of #{max_directory} bytes for directory names" + "exceeds the limit of #{max_title} bytes", + "exceeds the limit of #{max_directory} bytes for directory name \"#{invalid_directory}\"" ) end end diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb index b1a65ded9ef..97dc3899d3f 100644 --- a/spec/requests/api/repositories_spec.rb +++ b/spec/requests/api/repositories_spec.rb @@ -19,7 +19,7 @@ describe API::Repositories do it 'returns the repository tree' do get api(route, current_user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an Array @@ -108,7 +108,7 @@ describe API::Repositories do it 'returns blob attributes as json' do get api(route, current_user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['size']).to eq(111) expect(json_response['encoding']).to eq("base64") expect(Base64.decode64(json_response['content']).lines.first).to eq("class Commit\n") @@ -167,7 +167,7 @@ describe API::Repositories do get api(route, current_user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" end @@ -231,7 +231,7 @@ describe API::Repositories do it 'returns the repository archive' do get api(route, current_user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) type, params = workhorse_send_data @@ -242,7 +242,7 @@ describe API::Repositories do it 'returns the repository archive archive.zip' do get api("/projects/#{project.id}/repository/archive.zip", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) type, params = workhorse_send_data @@ -253,7 +253,7 @@ describe API::Repositories do it 'returns the repository archive archive.tar.bz2' do get api("/projects/#{project.id}/repository/archive.tar.bz2", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) type, params = workhorse_send_data @@ -314,7 +314,7 @@ describe API::Repositories do }).and_call_original get api(route, current_user), params: { from: 'master', to: 'feature' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['commits']).to be_present expect(json_response['diffs']).to be_present end @@ -325,7 +325,7 @@ describe API::Repositories do }).and_call_original get api(route, current_user), params: { from: 'master', to: 'feature', straight: false } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['commits']).to be_present expect(json_response['diffs']).to be_present end @@ -336,7 +336,7 @@ describe API::Repositories do }).and_call_original get api(route, current_user), params: { from: 'master', to: 'feature', straight: true } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['commits']).to be_present expect(json_response['diffs']).to be_present end @@ -344,7 +344,7 @@ describe API::Repositories do it "compares tags" do get api(route, current_user), params: { from: 'v1.0.0', to: 'v1.1.0' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['commits']).to be_present expect(json_response['diffs']).to be_present end @@ -352,7 +352,7 @@ describe API::Repositories do it "compares commits" do get api(route, current_user), params: { from: sample_commit.id, to: sample_commit.parent_id } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['commits']).to be_empty expect(json_response['diffs']).to be_empty expect(json_response['compare_same_ref']).to be_falsey @@ -361,7 +361,7 @@ describe API::Repositories do it "compares commits in reverse order" do get api(route, current_user), params: { from: sample_commit.parent_id, to: sample_commit.id } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['commits']).to be_present expect(json_response['diffs']).to be_present end @@ -369,7 +369,7 @@ describe API::Repositories do it "compares same refs" do get api(route, current_user), params: { from: 'master', to: 'master' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['commits']).to be_empty expect(json_response['diffs']).to be_empty expect(json_response['compare_same_ref']).to be_truthy @@ -380,7 +380,7 @@ describe API::Repositories do get api(route, current_user), params: { from: 'master', to: 'feature' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['commits']).to be_present expect(json_response['diffs']).to be_present expect(json_response['diffs'].first['diff']).to be_empty @@ -389,13 +389,13 @@ describe API::Repositories do it "returns a 404 when from ref is unknown" do get api(route, current_user), params: { from: 'unknown_ref', to: 'master' } - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it "returns a 404 when to ref is unknown" do get api(route, current_user), params: { from: 'master', to: 'unknown_ref' } - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -433,7 +433,7 @@ describe API::Repositories do it 'returns valid data' do get api(route, current_user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an Array @@ -450,7 +450,7 @@ describe API::Repositories do it 'returns the repository contribuors sorted by commits desc' do get api(route, current_user), params: { order_by: 'commits', sort: 'desc' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('contributors') expect(json_response.first['commits']).to be > json_response.last['commits'] end @@ -460,7 +460,7 @@ describe API::Repositories do it 'returns the repository contribuors sorted by name asc case insensitive' do get api(route, current_user), params: { order_by: 'name', sort: 'asc' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('contributors') expect(json_response.first['name'].downcase).to be < json_response.last['name'].downcase end diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb index e9657c903e9..e76ab8d409b 100644 --- a/spec/requests/api/runner_spec.rb +++ b/spec/requests/api/runner_spec.rb @@ -22,7 +22,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns 400 error' do post api('/runners') - expect(response).to have_gitlab_http_status 400 + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -30,7 +30,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns 403 error' do post api('/runners'), params: { token: 'invalid' } - expect(response).to have_gitlab_http_status 403 + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -40,7 +40,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do runner = Ci::Runner.first - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(json_response['id']).to eq(runner.id) expect(json_response['token']).to eq(runner.token) expect(runner.run_untagged).to be true @@ -55,7 +55,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'creates project runner' do post api('/runners'), params: { token: project.runners_token } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(project.runners.size).to eq(1) runner = Ci::Runner.first expect(runner.token).not_to eq(registration_token) @@ -70,7 +70,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'creates a group runner' do post api('/runners'), params: { token: group.runners_token } - expect(response).to have_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(group.runners.reload.size).to eq(1) runner = Ci::Runner.first expect(runner.token).not_to eq(registration_token) @@ -87,7 +87,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do description: 'server.hostname' } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(Ci::Runner.first.description).to eq('server.hostname') end end @@ -99,7 +99,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do tag_list: 'tag1, tag2' } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(Ci::Runner.first.tag_list.sort).to eq(%w(tag1 tag2)) end end @@ -113,7 +113,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do tag_list: ['tag'] } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(Ci::Runner.first.run_untagged).to be false expect(Ci::Runner.first.tag_list.sort).to eq(['tag']) end @@ -126,7 +126,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do run_untagged: false } - expect(response).to have_gitlab_http_status 400 + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['message']).to include( 'tags_list' => ['can not be empty when runner is not allowed to pick untagged jobs']) end @@ -140,7 +140,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do locked: true } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(Ci::Runner.first.locked).to be true end end @@ -153,7 +153,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do active: true } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(Ci::Runner.first.active).to be true end end @@ -165,7 +165,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do active: false } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(Ci::Runner.first.active).to be false end end @@ -179,7 +179,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do access_level: 'ref_protected' } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(Ci::Runner.first.ref_protected?).to be true end end @@ -191,7 +191,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do access_level: 'not_protected' } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(Ci::Runner.first.ref_protected?).to be false end end @@ -204,7 +204,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do maximum_timeout: 9000 } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(Ci::Runner.first.maximum_timeout).to eq(9000) end @@ -215,7 +215,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do maximum_timeout: '' } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(Ci::Runner.first.maximum_timeout).to be_nil end end @@ -231,7 +231,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do info: { param => value } } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(Ci::Runner.first.read_attribute(param.to_sym)).to eq(value) end end @@ -242,7 +242,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do params: { token: registration_token }, headers: { 'X-Forwarded-For' => '123.111.123.111' } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(Ci::Runner.first.ip_address).to eq('123.111.123.111') end end @@ -252,7 +252,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns 400 error' do delete api('/runners') - expect(response).to have_gitlab_http_status 400 + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -260,7 +260,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns 403 error' do delete api('/runners'), params: { token: 'invalid' } - expect(response).to have_gitlab_http_status 403 + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -270,7 +270,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'deletes Runner' do delete api('/runners'), params: { token: runner.token } - expect(response).to have_gitlab_http_status 204 + expect(response).to have_gitlab_http_status(:no_content) expect(Ci::Runner.count).to eq(0) end @@ -296,7 +296,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns 403 error' do post api('/runners/verify'), params: { token: 'invalid-token' } - expect(response).to have_gitlab_http_status 403 + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -304,7 +304,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'verifies Runner credentials' do post api('/runners/verify'), params: { token: runner.token } - expect(response).to have_gitlab_http_status 200 + expect(response).to have_gitlab_http_status(:ok) end end end @@ -361,7 +361,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when runner sends version in User-Agent' do context 'for stable version' do it 'gives 204 and set X-GitLab-Last-Update' do - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) expect(response.header).to have_key('X-GitLab-Last-Update') end end @@ -370,7 +370,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do let(:last_update) { runner.ensure_runner_queue_value } it 'gives 204 and set the same X-GitLab-Last-Update' do - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) expect(response.header['X-GitLab-Last-Update']).to eq(last_update) end end @@ -380,7 +380,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do let(:new_update) { runner.tick_runner_queue } it 'gives 204 and set a new X-GitLab-Last-Update' do - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) expect(response.header['X-GitLab-Last-Update']).to eq(new_update) end end @@ -388,19 +388,19 @@ describe API::Runner, :clean_gitlab_redis_shared_state do context 'when beta version is sent' do let(:user_agent) { 'gitlab-runner 9.0.0~beta.167.g2b2bacc (master; go1.7.4; linux/amd64)' } - it { expect(response).to have_gitlab_http_status(204) } + it { expect(response).to have_gitlab_http_status(:no_content) } end context 'when pre-9-0 version is sent' do let(:user_agent) { 'gitlab-ci-multi-runner 1.6.0 (1-6-stable; go1.6.3; linux/amd64)' } - it { expect(response).to have_gitlab_http_status(204) } + it { expect(response).to have_gitlab_http_status(:no_content) } end context 'when pre-9-0 beta version is sent' do let(:user_agent) { 'gitlab-ci-multi-runner 1.6.0~beta.167.g2b2bacc (master; go1.6.3; linux/amd64)' } - it { expect(response).to have_gitlab_http_status(204) } + it { expect(response).to have_gitlab_http_status(:no_content) } end end end @@ -409,7 +409,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns 400 error' do post api('/jobs/request') - expect(response).to have_gitlab_http_status 400 + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -417,7 +417,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns 403 error' do post api('/jobs/request'), params: { token: 'invalid' } - expect(response).to have_gitlab_http_status 403 + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -429,7 +429,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns 204 error' do request_job - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) expect(response.header['X-GitLab-Last-Update']).to eq(update_value) end end @@ -516,7 +516,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'picks a job' do request_job info: { platform: :darwin } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(response.headers).not_to have_key('X-GitLab-Last-Update') expect(runner.reload.platform).to eq('darwin') expect(json_response['id']).to eq(job.id) @@ -541,7 +541,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do request_job info: { platform: :darwin } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['id']).to eq(job.id) end @@ -551,7 +551,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'sets branch as ref_type' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['git_info']['ref_type']).to eq('tag') end @@ -563,7 +563,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'specifies refspecs' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['git_info']['refspecs']).to include("+refs/tags/#{job.ref}:refs/tags/#{job.ref}") end end @@ -576,7 +576,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'specifies refspecs' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['git_info']['refspecs']) .to contain_exactly('+refs/tags/*:refs/tags/*', '+refs/heads/*:refs/remotes/origin/*') end @@ -592,7 +592,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'gives 204' do request_job(job_age: job_age) - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) end end @@ -602,7 +602,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'picks a job' do request_job(job_age: job_age) - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) end end end @@ -611,7 +611,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'sets tag as ref_type' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['git_info']['ref_type']).to eq('branch') end @@ -623,7 +623,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'specifies refspecs' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['git_info']['refspecs']).to include("+refs/heads/#{job.ref}:refs/remotes/origin/#{job.ref}") end end @@ -636,7 +636,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'specifies refspecs' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['git_info']['refspecs']) .to contain_exactly('+refs/tags/*:refs/tags/*', '+refs/heads/*:refs/remotes/origin/*') end @@ -651,7 +651,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'sets branch as ref_type' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['git_info']['ref_type']).to eq('branch') end @@ -663,7 +663,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns the overwritten git depth for merge request refspecs' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['git_info']['depth']).to eq(1) end end @@ -680,7 +680,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it "updates provided Runner's parameter" do request_job info: { param => value } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(runner.reload.read_attribute(param.to_sym)).to eq(value) end end @@ -691,7 +691,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do params: { token: runner.token }, headers: { 'User-Agent' => user_agent, 'X-Forwarded-For' => '123.222.123.222' } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(runner.reload.ip_address).to eq('123.222.123.222') end @@ -700,7 +700,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do params: { token: runner.token }, headers: { 'User-Agent' => user_agent, 'X-Forwarded-For' => '123.222.123.222, 127.0.0.1' } - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) expect(runner.reload.ip_address).to eq('123.222.123.222') end @@ -713,7 +713,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns a conflict' do request_job - expect(response).to have_gitlab_http_status(409) + expect(response).to have_gitlab_http_status(:conflict) expect(response.headers).not_to have_key('X-GitLab-Last-Update') end end @@ -731,7 +731,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns dependent jobs' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['id']).to eq(test_job.id) expect(json_response['dependencies'].count).to eq(2) expect(json_response['dependencies']).to include( @@ -751,7 +751,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns dependent jobs' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['id']).to eq(test_job.id) expect(json_response['dependencies'].count).to eq(1) expect(json_response['dependencies']).to include( @@ -777,7 +777,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns dependent jobs' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['id']).to eq(test_job.id) expect(json_response['dependencies'].count).to eq(1) expect(json_response['dependencies'][0]).to include('id' => job2.id, 'name' => job2.name, 'token' => job2.token) @@ -801,7 +801,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns an empty array' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['id']).to eq(empty_dependencies_job.id) expect(json_response['dependencies'].count).to eq(0) end @@ -820,7 +820,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'picks job' do request_job - expect(response).to have_gitlab_http_status 201 + expect(response).to have_gitlab_http_status(:created) end end @@ -854,7 +854,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns variables for triggers' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['variables']).to include(*expected_variables) end end @@ -919,7 +919,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'contains info about timeout taken from project' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['runner_info']).to include({ 'timeout' => 1234 }) end @@ -929,7 +929,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'contains info about timeout overridden by runner' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['runner_info']).to include({ 'timeout' => 1000 }) end end @@ -940,7 +940,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'contains info about timeout not overridden by runner' do request_job - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['runner_info']).to include({ 'timeout' => 1234 }) end end @@ -965,7 +965,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns the image ports' do request_job - expect(response).to have_http_status(:created) + expect(response).to have_gitlab_http_status(:created) expect(json_response).to include( 'id' => job.id, 'image' => a_hash_including('name' => 'ruby', 'ports' => [{ 'number' => 80, 'protocol' => 'http', 'name' => 'default_port' }]), @@ -989,7 +989,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns the service ports' do request_job - expect(response).to have_http_status(:created) + expect(response).to have_gitlab_http_status(:created) expect(json_response).to include( 'id' => job.id, 'image' => a_hash_including('name' => 'ruby'), @@ -1089,7 +1089,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do update_job(state: 'success', trace: 'BUILD TRACE UPDATED') job.reload - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(job.trace.raw).to eq 'BUILD TRACE UPDATED' expect(job.job_artifacts_trace.open.read).to eq 'BUILD TRACE UPDATED' end @@ -1133,7 +1133,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'responds with forbidden' do update_job - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -1147,7 +1147,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do update_job(state: 'success', trace: 'BUILD TRACE UPDATED') job.reload - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) expect(response.header['Job-Status']).to eq 'failed' expect(job.trace.raw).to eq 'Job failed' expect(job).to be_failed @@ -1461,7 +1461,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'succeeds' do subject - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response.media_type).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE) expect(json_response['TempPath']).to eq(JobArtifactUploader.workhorse_local_upload_path) expect(json_response['RemoteObject']).to be_nil @@ -1481,7 +1481,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'succeeds' do subject - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response.media_type).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE) expect(json_response).not_to have_key('TempPath') expect(json_response['RemoteObject']).to have_key('ID') @@ -1509,7 +1509,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'fails to post' do authorize_artifacts_with_token_in_params(filesize: sample_max_size.megabytes.to_i) - expect(response).to have_gitlab_http_status(413) + expect(response).to have_gitlab_http_status(:payload_too_large) end end @@ -1557,7 +1557,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'authorizes posting artifacts to running job' do authorize_artifacts_with_token_in_headers - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response.media_type).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE) expect(json_response['TempPath']).not_to be_nil end @@ -1567,7 +1567,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do authorize_artifacts_with_token_in_headers(filesize: 100) - expect(response).to have_gitlab_http_status(413) + expect(response).to have_gitlab_http_status(:payload_too_large) end end @@ -1575,7 +1575,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'fails to authorize artifacts posting' do authorize_artifacts(token: job.project.runners_token) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -1591,7 +1591,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'responds with forbidden' do authorize_artifacts(token: 'invalid', filesize: 100 ) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -1632,14 +1632,14 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'responds with forbidden' do upload_artifacts(file_upload, headers_with_token) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end context 'when job is running' do shared_examples 'successful artifacts upload' do it 'updates successfully' do - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) end end @@ -1678,7 +1678,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do let(:remote_id) { 'invalid id' } it 'responds with bad request' do - expect(response).to have_gitlab_http_status(500) + expect(response).to have_gitlab_http_status(:internal_server_error) expect(json_response['message']).to eq("Missing file") end end @@ -1689,7 +1689,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'responds with forbidden' do upload_artifacts(file_upload, headers.merge(API::Helpers::Runner::JOB_TOKEN_HEADER => job.project.runners_token)) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end end @@ -1700,7 +1700,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do upload_artifacts(file_upload, headers_with_token) - expect(response).to have_gitlab_http_status(413) + expect(response).to have_gitlab_http_status(:payload_too_large) end end @@ -1708,7 +1708,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'fails to post artifacts without file' do post api("/jobs/#{job.id}/artifacts"), params: {}, headers: headers_with_token - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -1716,7 +1716,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'fails to post artifacts without GitLab-Workhorse' do post api("/jobs/#{job.id}/artifacts"), params: { token: job.token }, headers: {} - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -1750,7 +1750,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do let(:expire_in) { '7 days' } it 'updates when specified' do - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(job.reload.artifacts_expire_at).to be_within(5.minutes).of(7.days.from_now) end end @@ -1759,7 +1759,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do let(:expire_in) { nil } it 'ignores if not specified' do - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(job.reload.artifacts_expire_at).to be_nil end @@ -1768,7 +1768,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do let(:default_artifacts_expire_in) { '5 days' } it 'sets to application default' do - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(job.reload.artifacts_expire_at).to be_within(5.minutes).of(5.days.from_now) end end @@ -1777,7 +1777,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do let(:default_artifacts_expire_in) { '0' } it 'does not set expire_in' do - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(job.reload.artifacts_expire_at).to be_nil end end @@ -1812,7 +1812,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do end it 'stores artifacts and artifacts metadata' do - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(stored_artifacts_file.filename).to eq(artifacts.original_filename) expect(stored_metadata_file.filename).to eq(metadata.original_filename) expect(stored_artifacts_size).to eq(artifacts.size) @@ -1827,7 +1827,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do end it 'is expected to respond with bad request' do - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'does not store metadata' do @@ -1843,7 +1843,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'stores junit test report' do upload_artifacts(file_upload, headers_with_token, params) - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(job.reload.job_artifacts_archive).not_to be_nil end end @@ -1854,7 +1854,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns an error' do upload_artifacts(file_upload, headers_with_token, params) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(job.reload.job_artifacts_archive).to be_nil end end @@ -1868,7 +1868,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'stores junit test report' do upload_artifacts(file_upload, headers_with_token, params) - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(job.reload.job_artifacts_junit).not_to be_nil end end @@ -1880,7 +1880,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns an error' do upload_artifacts(file_upload, headers_with_token, params) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(job.reload.job_artifacts_junit).to be_nil end end @@ -1894,7 +1894,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'stores metrics_referee data' do upload_artifacts(file_upload, headers_with_token, params) - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(job.reload.job_artifacts_metrics_referee).not_to be_nil end end @@ -1906,7 +1906,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns an error' do upload_artifacts(file_upload, headers_with_token, params) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(job.reload.job_artifacts_metrics_referee).to be_nil end end @@ -1920,7 +1920,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'stores network_referee data' do upload_artifacts(file_upload, headers_with_token, params) - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(job.reload.job_artifacts_network_referee).not_to be_nil end end @@ -1932,7 +1932,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'returns an error' do upload_artifacts(file_upload, headers_with_token, params) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(job.reload.job_artifacts_network_referee).to be_nil end end @@ -2013,7 +2013,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it' "fails to post artifacts for outside of tmp path"' do upload_artifacts(file_upload, headers_with_token) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -2055,7 +2055,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do end it 'download artifacts' do - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response.headers.to_h).to include download_headers end end @@ -2070,7 +2070,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do end it 'uses workhorse send-url' do - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response.headers.to_h).to include( 'Gitlab-Workhorse-Send-Data' => /send-url:/) end @@ -2082,7 +2082,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do end it 'receive redirect for downloading artifacts' do - expect(response).to have_gitlab_http_status(302) + expect(response).to have_gitlab_http_status(:found) expect(response.headers).to include('Location') end end @@ -2097,7 +2097,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do end it 'responds with forbidden' do - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end end @@ -2106,7 +2106,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do it 'responds with not found' do download_artifact - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb index c54487a68fe..70094ef4388 100644 --- a/spec/requests/api/runners_spec.rb +++ b/spec/requests/api/runners_spec.rb @@ -32,7 +32,7 @@ describe API::Runners do it 'returns response status and headers' do get api('/runners', user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers end @@ -51,7 +51,7 @@ describe API::Runners do get api('/runners?scope=paused', user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to match_array [ @@ -61,7 +61,7 @@ describe API::Runners do it 'avoids filtering if scope is invalid' do get api('/runners?scope=unknown', user) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'filters runners by type' do @@ -76,7 +76,7 @@ describe API::Runners do it 'does not filter by invalid type' do get api('/runners?type=bogus', user) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'filters runners by status' do @@ -92,7 +92,7 @@ describe API::Runners do it 'does not filter by invalid status' do get api('/runners?status=bogus', user) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'filters runners by tag_list' do @@ -111,7 +111,7 @@ describe API::Runners do it 'does not return runners' do get api('/runners') - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end end @@ -122,7 +122,7 @@ describe API::Runners do it 'returns response status and headers' do get api('/runners/all', admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers end @@ -141,7 +141,7 @@ describe API::Runners do get api('/runners/all?scope=shared', admin) shared = json_response.all? { |r| r['is_shared'] } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an Array expect(json_response[0]).to have_key('ip_address') @@ -151,7 +151,7 @@ describe API::Runners do it 'filters runners by scope' do get api('/runners/all?scope=specific', admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to match_array [ @@ -163,7 +163,7 @@ describe API::Runners do it 'avoids filtering if scope is invalid' do get api('/runners/all?scope=unknown', admin) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'filters runners by type' do @@ -178,7 +178,7 @@ describe API::Runners do it 'does not filter by invalid type' do get api('/runners/all?type=bogus', admin) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'filters runners by status' do @@ -194,7 +194,7 @@ describe API::Runners do it 'does not filter by invalid status' do get api('/runners/all?status=bogus', admin) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'filters runners by tag_list' do @@ -213,7 +213,7 @@ describe API::Runners do it 'does not return runners list' do get api('/runners/all', user) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end end @@ -222,7 +222,7 @@ describe API::Runners do it 'does not return runners' do get api('/runners') - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end end @@ -233,7 +233,7 @@ describe API::Runners do it "returns runner's details" do get api("/runners/#{shared_runner.id}", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['description']).to eq(shared_runner.description) expect(json_response['maximum_timeout']).to be_nil end @@ -247,7 +247,7 @@ describe API::Runners do expect do delete api("/runners/#{unused_project_runner.id}", admin) - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) end.to change { Ci::Runner.project_type.count }.by(-1) end end @@ -255,7 +255,7 @@ describe API::Runners do it "returns runner's details" do get api("/runners/#{project_runner.id}", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['description']).to eq(project_runner.description) end @@ -269,7 +269,7 @@ describe API::Runners do it 'returns 404 if runner does not exists' do get api('/runners/0', admin) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -278,7 +278,7 @@ describe API::Runners do it "returns runner's details" do get api("/runners/#{project_runner.id}", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['description']).to eq(project_runner.description) end end @@ -287,7 +287,7 @@ describe API::Runners do it "returns runner's details" do get api("/runners/#{shared_runner.id}", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['description']).to eq(shared_runner.description) end end @@ -297,7 +297,7 @@ describe API::Runners do it "does not return project runner's details" do get api("/runners/#{project_runner.id}", user2) - expect(response).to have_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -305,7 +305,7 @@ describe API::Runners do it "does not return project runner's details" do get api("/runners/#{project_runner.id}") - expect(response).to have_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end end @@ -318,7 +318,7 @@ describe API::Runners do description = shared_runner.description update_runner(shared_runner.id, admin, description: "#{description}_updated") - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(shared_runner.reload.description).to eq("#{description}_updated") end @@ -326,14 +326,14 @@ describe API::Runners do active = shared_runner.active update_runner(shared_runner.id, admin, active: !active) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(shared_runner.reload.active).to eq(!active) end it 'runner tag list' do update_runner(shared_runner.id, admin, tag_list: ['ruby2.1', 'pgsql', 'mysql']) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(shared_runner.reload.tag_list).to include('ruby2.1', 'pgsql', 'mysql') end @@ -342,28 +342,28 @@ describe API::Runners do update_runner(shared_runner.id, admin, tag_list: ['ruby2.1', 'pgsql', 'mysql']) update_runner(shared_runner.id, admin, run_untagged: 'false') - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(shared_runner.reload.run_untagged?).to be(false) end it 'runner unlocked flag' do update_runner(shared_runner.id, admin, locked: 'true') - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(shared_runner.reload.locked?).to be(true) end it 'runner access level' do update_runner(shared_runner.id, admin, access_level: 'ref_protected') - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(shared_runner.reload.ref_protected?).to be_truthy end it 'runner maximum timeout' do update_runner(shared_runner.id, admin, maximum_timeout: 1234) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(shared_runner.reload.maximum_timeout).to eq(1234) end @@ -371,7 +371,7 @@ describe API::Runners do put api("/runners/#{shared_runner.id}", admin) shared_runner.reload - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -390,7 +390,7 @@ describe API::Runners do maximum_timeout: 1234) shared_runner.reload - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(shared_runner.description).to eq("#{description}_updated") expect(shared_runner.active).to eq(!active) expect(shared_runner.tag_list).to include('ruby2.1', 'pgsql', 'mysql') @@ -411,7 +411,7 @@ describe API::Runners do update_runner(project_runner.id, admin, description: 'test') project_runner.reload - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(project_runner.description).to eq('test') expect(project_runner.description).not_to eq(description) expect(project_runner.ensure_runner_queue_value) @@ -422,7 +422,7 @@ describe API::Runners do it 'returns 404 if runner does not exists' do update_runner(0, admin, description: 'test') - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end def update_runner(id, user, args) @@ -435,7 +435,7 @@ describe API::Runners do it 'does not update runner' do put api("/runners/#{shared_runner.id}", user), params: { description: 'test' } - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -443,7 +443,7 @@ describe API::Runners do it 'does not update project runner without access to it' do put api("/runners/#{project_runner.id}", user2), params: { description: 'test' } - expect(response).to have_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end it 'updates project runner with access to it' do @@ -451,7 +451,7 @@ describe API::Runners do put api("/runners/#{project_runner.id}", admin), params: { description: 'test' } project_runner.reload - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(project_runner.description).to eq('test') expect(project_runner.description).not_to eq(description) end @@ -462,7 +462,7 @@ describe API::Runners do it 'does not delete project runner' do put api("/runners/#{project_runner.id}") - expect(response).to have_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end end @@ -474,7 +474,7 @@ describe API::Runners do expect do delete api("/runners/#{shared_runner.id}", admin) - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) end.to change { Ci::Runner.instance_type.count }.by(-1) end @@ -488,7 +488,7 @@ describe API::Runners do expect do delete api("/runners/#{project_runner.id}", admin) - expect(response).to have_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) end.to change { Ci::Runner.project_type.count }.by(-1) end end @@ -496,7 +496,7 @@ describe API::Runners do it 'returns 404 if runner does not exists' do delete api('/runners/0', admin) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -504,40 +504,40 @@ describe API::Runners do context 'when runner is shared' do it 'does not delete runner' do delete api("/runners/#{shared_runner.id}", user) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end context 'when runner is not shared' do it 'does not delete runner without access to it' do delete api("/runners/#{project_runner.id}", user2) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end it 'does not delete project runner with more than one associated project' do delete api("/runners/#{two_projects_runner.id}", user) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end it 'deletes project runner for one owned project' do expect do delete api("/runners/#{project_runner.id}", user) - expect(response).to have_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) end.to change { Ci::Runner.project_type.count }.by(-1) end it 'does not delete group runner with maintainer access' do delete api("/runners/#{group_runner.id}", group_maintainer) - expect(response).to have_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end it 'deletes group runner with owner access' do expect do delete api("/runners/#{group_runner.id}", user) - expect(response).to have_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) end.to change { Ci::Runner.group_type.count }.by(-1) end @@ -551,7 +551,7 @@ describe API::Runners do it 'does not delete project runner' do delete api("/runners/#{project_runner.id}") - expect(response).to have_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end end @@ -569,7 +569,7 @@ describe API::Runners do it 'return jobs' do get api("/runners/#{shared_runner.id}/jobs", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an(Array) @@ -581,7 +581,7 @@ describe API::Runners do it 'return jobs' do get api("/runners/#{project_runner.id}/jobs", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an(Array) @@ -593,7 +593,7 @@ describe API::Runners do it 'return filtered jobs' do get api("/runners/#{project_runner.id}/jobs?status=failed", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an(Array) @@ -607,7 +607,7 @@ describe API::Runners do it 'return jobs in descending order' do get api("/runners/#{project_runner.id}/jobs?order_by=id", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an(Array) @@ -620,7 +620,7 @@ describe API::Runners do it 'return jobs sorted in ascending order' do get api("/runners/#{project_runner.id}/jobs?order_by=id&sort=asc", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an(Array) @@ -634,7 +634,7 @@ describe API::Runners do it 'return 400' do get api("/runners/#{project_runner.id}/jobs?status=non-existing", admin) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -642,7 +642,7 @@ describe API::Runners do it 'return 400' do get api("/runners/#{project_runner.id}/jobs?order_by=non-existing", admin) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -650,7 +650,7 @@ describe API::Runners do it 'return 400' do get api("/runners/#{project_runner.id}/jobs?sort=non-existing", admin) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end end @@ -659,7 +659,7 @@ describe API::Runners do it 'returns 404' do get api('/runners/0/jobs', admin) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end end @@ -670,7 +670,7 @@ describe API::Runners do it 'returns 403' do get api("/runners/#{shared_runner.id}/jobs", user) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -678,7 +678,7 @@ describe API::Runners do it 'return jobs' do get api("/runners/#{project_runner.id}/jobs", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an(Array) @@ -690,7 +690,7 @@ describe API::Runners do it 'return filtered jobs' do get api("/runners/#{project_runner.id}/jobs?status=failed", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an(Array) @@ -703,7 +703,7 @@ describe API::Runners do it 'return 400' do get api("/runners/#{project_runner.id}/jobs?status=non-existing", user) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end end @@ -712,7 +712,7 @@ describe API::Runners do it 'returns 404' do get api('/runners/0/jobs', user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end end @@ -721,7 +721,7 @@ describe API::Runners do it 'does not return jobs' do get api("/runners/#{project_runner.id}/jobs", user2) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -729,7 +729,7 @@ describe API::Runners do it 'does not return jobs' do get api("/runners/#{project_runner.id}/jobs") - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end end @@ -739,7 +739,7 @@ describe API::Runners do it 'returns response status and headers' do get api('/runners/all', admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers end @@ -756,7 +756,7 @@ describe API::Runners do it 'filters runners by scope' do get api("/projects/#{project.id}/runners?scope=specific", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to match_array [ @@ -767,7 +767,7 @@ describe API::Runners do it 'avoids filtering if scope is invalid' do get api("/projects/#{project.id}/runners?scope=unknown", user) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'filters runners by type' do @@ -782,7 +782,7 @@ describe API::Runners do it 'does not filter by invalid type' do get api("/projects/#{project.id}/runners?type=bogus", user) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'filters runners by status' do @@ -798,7 +798,7 @@ describe API::Runners do it 'does not filter by invalid status' do get api("/projects/#{project.id}/runners?status=bogus", user) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'filters runners by tag_list' do @@ -817,7 +817,7 @@ describe API::Runners do it "does not return project's runners" do get api("/projects/#{project.id}/runners", user2) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -825,7 +825,7 @@ describe API::Runners do it "does not return project's runners" do get api("/projects/#{project.id}/runners") - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end end @@ -838,14 +838,14 @@ describe API::Runners do expect do post api("/projects/#{project.id}/runners", user), params: { runner_id: project_runner2.id } end.to change { project.runners.count }.by(+1) - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) end it 'avoids changes when enabling already enabled runner' do expect do post api("/projects/#{project.id}/runners", user), params: { runner_id: project_runner.id } end.to change { project.runners.count }.by(0) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'does not enable locked runner' do @@ -855,19 +855,19 @@ describe API::Runners do post api("/projects/#{project.id}/runners", user), params: { runner_id: project_runner2.id } end.to change { project.runners.count }.by(0) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end it 'does not enable shared runner' do post api("/projects/#{project.id}/runners", user), params: { runner_id: shared_runner.id } - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end it 'does not enable group runner' do post api("/projects/#{project.id}/runners", user), params: { runner_id: group_runner.id } - expect(response).to have_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end context 'user is admin' do @@ -878,7 +878,7 @@ describe API::Runners do expect do post api("/projects/#{project.id}/runners", admin), params: { runner_id: new_project_runner.id } end.to change { project.runners.count }.by(+1) - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) end end @@ -888,14 +888,14 @@ describe API::Runners do end.to change { project.runners.count }.by(1) expect(shared_runner.reload).not_to be_instance_type - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) end end it 'raises an error when no runner_id param is provided' do post api("/projects/#{project.id}/runners", admin) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -905,7 +905,7 @@ describe API::Runners do it 'does not enable runner without access to' do post api("/projects/#{project.id}/runners", user), params: { runner_id: new_project_runner.id } - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -913,7 +913,7 @@ describe API::Runners do it 'does not enable runner' do post api("/projects/#{project.id}/runners", user2) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -921,7 +921,7 @@ describe API::Runners do it 'does not enable runner' do post api("/projects/#{project.id}/runners") - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end end @@ -933,7 +933,7 @@ describe API::Runners do expect do delete api("/projects/#{project.id}/runners/#{two_projects_runner.id}", user) - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) end.to change { project.runners.count }.by(-1) end @@ -947,14 +947,14 @@ describe API::Runners do expect do delete api("/projects/#{project.id}/runners/#{project_runner.id}", user) end.to change { project.runners.count }.by(0) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end it 'returns 404 is runner is not found' do delete api("/projects/#{project.id}/runners/0", user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -962,7 +962,7 @@ describe API::Runners do it "does not disable project's runner" do delete api("/projects/#{project.id}/runners/#{project_runner.id}", user2) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -970,7 +970,7 @@ describe API::Runners do it "does not disable project's runner" do delete api("/projects/#{project.id}/runners/#{project_runner.id}") - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end end diff --git a/spec/requests/api/search_spec.rb b/spec/requests/api/search_spec.rb index 04794b2ba58..6ff5fbd7925 100644 --- a/spec/requests/api/search_spec.rb +++ b/spec/requests/api/search_spec.rb @@ -9,7 +9,7 @@ describe API::Search do let_it_be(:repo_project) { create(:project, :public, :repository, group: group) } shared_examples 'response is correct' do |schema:, size: 1| - it { expect(response).to have_gitlab_http_status(200) } + it { expect(response).to have_gitlab_http_status(:ok) } it { expect(response).to match_response_schema(schema) } it { expect(response).to include_limited_pagination_headers } it { expect(json_response.size).to eq(size) } @@ -20,7 +20,7 @@ describe API::Search do it 'returns 401 error' do get api('/search'), params: { scope: 'projects', search: 'awesome' } - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end @@ -28,7 +28,7 @@ describe API::Search do it 'returns 400 error' do get api('/search', user), params: { scope: 'unsupported', search: 'awesome' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -36,7 +36,7 @@ describe API::Search do it 'returns 400 error' do get api('/search', user), params: { search: 'awesome' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -115,7 +115,7 @@ describe API::Search do end it 'returns 400 error' do - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end end @@ -147,7 +147,7 @@ describe API::Search do it 'returns 401 error' do get api("/groups/#{group.id}/search"), params: { scope: 'projects', search: 'awesome' } - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end @@ -155,7 +155,7 @@ describe API::Search do it 'returns 400 error' do get api("/groups/#{group.id}/search", user), params: { scope: 'unsupported', search: 'awesome' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -163,7 +163,7 @@ describe API::Search do it 'returns 400 error' do get api("/groups/#{group.id}/search", user), params: { search: 'awesome' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -171,7 +171,7 @@ describe API::Search do it 'returns 404 error' do get api('/groups/0/search', user), params: { scope: 'issues', search: 'awesome' } - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -181,7 +181,7 @@ describe API::Search do get api("/groups/#{private_group.id}/search", user), params: { scope: 'issues', search: 'awesome' } - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -254,7 +254,7 @@ describe API::Search do end it 'returns 400 error' do - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end end @@ -277,7 +277,7 @@ describe API::Search do it 'returns 401 error' do get api("/projects/#{project.id}/search"), params: { scope: 'issues', search: 'awesome' } - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end @@ -285,7 +285,7 @@ describe API::Search do it 'returns 400 error' do get api("/projects/#{project.id}/search", user), params: { scope: 'unsupported', search: 'awesome' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -293,7 +293,7 @@ describe API::Search do it 'returns 400 error' do get api("/projects/#{project.id}/search", user), params: { search: 'awesome' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end @@ -301,7 +301,7 @@ describe API::Search do it 'returns 404 error' do get api('/projects/0/search', user), params: { scope: 'issues', search: 'awesome' } - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -311,7 +311,7 @@ describe API::Search do get api("/projects/#{project.id}/search", user), params: { scope: 'issues', search: 'awesome' } - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -383,7 +383,7 @@ describe API::Search do end it 'returns 400 error' do - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end end @@ -436,7 +436,7 @@ describe API::Search do it 'by filename' do get api("/projects/#{repo_project.id}/search", user), params: { scope: 'blobs', search: 'mon filename:PROCESS.md' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response.size).to eq(2) expect(json_response.first['path']).to eq('PROCESS.md') expect(json_response.first['filename']).to eq('PROCESS.md') @@ -445,21 +445,21 @@ describe API::Search do it 'by path' do get api("/projects/#{repo_project.id}/search", user), params: { scope: 'blobs', search: 'mon path:markdown' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response.size).to eq(8) end it 'by extension' do get api("/projects/#{repo_project.id}/search", user), params: { scope: 'blobs', search: 'mon extension:md' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response.size).to eq(11) end it 'by ref' do get api("/projects/#{repo_project.id}/search", user), params: { scope: 'blobs', search: 'This file is used in tests for ci_environments_status', ref: 'pages-deploy' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response.size).to eq(1) end end diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb index 323164f26f0..906ffce25bf 100644 --- a/spec/requests/api/services_spec.rb +++ b/spec/requests/api/services_spec.rb @@ -14,14 +14,14 @@ describe API::Services do it 'returns authentication error when unauthenticated' do get api("/projects/#{project.id}/services") - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end it "returns error when authenticated but user is not a project owner" do project.add_developer(user2) get api("/projects/#{project.id}/services", user2) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end context 'project with services' do @@ -32,7 +32,7 @@ describe API::Services do get api("/projects/#{project.id}/services", user) aggregate_failures 'expect successful response with all active services' do - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response).to be_an Array expect(json_response.count).to eq(1) expect(json_response.first['slug']).to eq('emails-on-push') @@ -49,7 +49,7 @@ describe API::Services do it "updates #{service} settings" do put api("/projects/#{project.id}/services/#{dashed_service}", user), params: service_attrs - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) current_service = project.services.first events = current_service.event_names.empty? ? ["foo"].freeze : current_service.event_names @@ -61,7 +61,7 @@ describe API::Services do put api("/projects/#{project.id}/services/#{dashed_service}?#{query_strings}", user), params: service_attrs - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['slug']).to eq(dashed_service) events.each do |event| next if event == "foo" @@ -103,7 +103,7 @@ describe API::Services do it "deletes #{service}" do delete api("/projects/#{project.id}/services/#{dashed_service}", user) - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) project.send(service_method).reload expect(project.send(service_method).activated?).to be_falsey end @@ -117,13 +117,13 @@ describe API::Services do it 'returns authentication error when unauthenticated' do get api("/projects/#{project.id}/services/#{dashed_service}") - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end it "returns all properties of service #{service}" do get api("/projects/#{project.id}/services/#{dashed_service}", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['properties'].keys).to match_array(service_instance.api_field_names) end @@ -131,7 +131,7 @@ describe API::Services do project.add_developer(user2) get api("/projects/#{project.id}/services/#{dashed_service}", user2) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end end @@ -144,7 +144,7 @@ describe API::Services do it 'returns a not found message' do post api("/projects/#{project.id}/services/idonotexist/trigger") - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response["error"]).to eq("404 Not Found") end end @@ -163,7 +163,7 @@ describe API::Services do it 'when the service is inactive' do post api("/projects/#{project.id}/services/#{service_name}/trigger"), params: params - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -178,7 +178,7 @@ describe API::Services do it 'returns status 200' do post api("/projects/#{project.id}/services/#{service_name}/trigger"), params: params - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) end end @@ -186,7 +186,7 @@ describe API::Services do it 'returns a generic 404' do post api("/projects/404/services/#{service_name}/trigger"), params: params - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response["message"]).to eq("404 Service Not Found") end end @@ -206,7 +206,7 @@ describe API::Services do it 'returns status 200' do post api("/projects/#{project.id}/services/#{service_name}/trigger"), params: { token: 'token', text: 'help' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['response_type']).to eq("ephemeral") end end @@ -228,7 +228,7 @@ describe API::Services do it 'accepts a username for update' do put api("/projects/#{project.id}/services/#{service_name}", user), params: params.merge(username: 'new_username') - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['properties']['username']).to eq('new_username') end end @@ -253,14 +253,14 @@ describe API::Services do it 'accepts branches_to_be_notified for update' do put api("/projects/#{project.id}/services/#{service_name}", user), params: params.merge(branches_to_be_notified: 'all') - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['properties']['branches_to_be_notified']).to eq('all') end it 'accepts notify_only_broken_pipelines for update' do put api("/projects/#{project.id}/services/#{service_name}", user), params: params.merge(notify_only_broken_pipelines: true) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['properties']['notify_only_broken_pipelines']).to eq(true) end end diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb index 1a6bd4e6c0d..4a8b8f70dff 100644 --- a/spec/requests/api/settings_spec.rb +++ b/spec/requests/api/settings_spec.rb @@ -11,7 +11,7 @@ describe API::Settings, 'Settings' do it "returns application settings" do get api("/application/settings", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response).to be_an Hash expect(json_response['default_projects_limit']).to eq(42) expect(json_response['password_authentication_enabled_for_web']).to be_truthy @@ -91,7 +91,7 @@ describe API::Settings, 'Settings' do snippet_size_limit: 5 } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['default_ci_config_path']).to eq('debian/salsa-ci.yml') expect(json_response['default_projects_limit']).to eq(3) expect(json_response['default_project_creation']).to eq(::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) @@ -132,7 +132,7 @@ describe API::Settings, 'Settings' do put api("/application/settings", admin), params: { performance_bar_allowed_group_id: group.full_path } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['performance_bar_allowed_group_id']).to eq(group.id) end @@ -143,7 +143,7 @@ describe API::Settings, 'Settings' do performance_bar_allowed_group_id: group.full_path } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['performance_bar_allowed_group_id']).to be_nil end @@ -151,7 +151,7 @@ describe API::Settings, 'Settings' do put api("/application/settings", admin), params: { allow_local_requests_from_hooks_and_services: true } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['allow_local_requests_from_hooks_and_services']).to eq(true) end @@ -173,7 +173,7 @@ describe API::Settings, 'Settings' do it 'includes the attributes in the API' do get api("/application/settings", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) attribute_names.each do |attribute| expect(json_response.keys).to include(attribute) end @@ -182,7 +182,7 @@ describe API::Settings, 'Settings' do it 'allows updating the settings' do put api("/application/settings", admin), params: settings - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) settings.each do |attribute, value| expect(ApplicationSetting.current.public_send(attribute)).to eq(value) end @@ -205,7 +205,7 @@ describe API::Settings, 'Settings' do it "includes the attributes in the API" do get api("/application/settings", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) attribute_names.each do |attribute| expect(json_response.keys).to include(attribute) end @@ -214,7 +214,7 @@ describe API::Settings, 'Settings' do it "allows updating the settings" do put api("/application/settings", admin), params: settings - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) settings.each do |attribute, value| expect(ApplicationSetting.current.public_send(attribute)).to eq(value) end @@ -224,7 +224,7 @@ describe API::Settings, 'Settings' do it "returns a blank parameter error message" do put api("/application/settings", admin), params: { snowplow_enabled: true } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response["error"]).to eq("snowplow_collector_hostname is missing") end @@ -233,7 +233,7 @@ describe API::Settings, 'Settings' do snowplow_collector_hostname: nil }) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) message = json_response["message"] expect(message["snowplow_collector_hostname"]).to include("can't be blank") end @@ -257,7 +257,7 @@ describe API::Settings, 'Settings' do it 'includes attributes in the API' do get api("/application/settings", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) exposed_attributes.each do |attribute| expect(json_response.keys).to include(attribute) end @@ -266,7 +266,7 @@ describe API::Settings, 'Settings' do it 'does not include sensitive attributes in the API' do get api("/application/settings", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) sensitive_attributes.each do |attribute| expect(json_response.keys).not_to include(attribute) end @@ -275,7 +275,7 @@ describe API::Settings, 'Settings' do it 'allows updating the settings' do put api("/application/settings", admin), params: settings - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) settings.each do |attribute, value| expect(ApplicationSetting.current.public_send(attribute)).to eq(value) end @@ -287,7 +287,7 @@ describe API::Settings, 'Settings' do it 'does not update the settings' do put api("/application/settings", admin), params: settings - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['error']).to include('eks_account_id is missing') expect(json_response['error']).to include('eks_access_key_id is missing') expect(json_response['error']).to include('eks_secret_access_key is missing') @@ -299,7 +299,7 @@ describe API::Settings, 'Settings' do it "returns a blank parameter error message" do put api("/application/settings", admin), params: { plantuml_enabled: true } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['error']).to eq('plantuml_url is missing') end end @@ -314,7 +314,7 @@ describe API::Settings, 'Settings' do asset_proxy_whitelist: ['example.com', '*.example.com'] } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['asset_proxy_enabled']).to be(true) expect(json_response['asset_proxy_url']).to eq('http://assets.example.com') expect(json_response['asset_proxy_secret_key']).to be_nil @@ -327,7 +327,7 @@ describe API::Settings, 'Settings' do asset_proxy_whitelist: 'example.com, *.example.com' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['asset_proxy_whitelist']).to eq(['example.com', '*.example.com', 'localhost']) end end @@ -340,7 +340,7 @@ describe API::Settings, 'Settings' do domain_blacklist: [] } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) message = json_response["message"] expect(message["domain_blacklist"]).to eq(["Domain blacklist cannot be empty if Blacklist is enabled."]) end @@ -352,7 +352,7 @@ describe API::Settings, 'Settings' do domain_blacklist: ['domain1.com', 'domain2.com'] } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['domain_blacklist_enabled']).to be(true) expect(json_response['domain_blacklist']).to eq(['domain1.com', 'domain2.com']) end @@ -364,7 +364,7 @@ describe API::Settings, 'Settings' do domain_blacklist: 'domain3.com, *.domain4.com' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['domain_blacklist_enabled']).to be(true) expect(json_response['domain_blacklist']).to eq(['domain3.com', '*.domain4.com']) end @@ -374,7 +374,7 @@ describe API::Settings, 'Settings' do it "returns a blank parameter error message" do put api("/application/settings", admin), params: { sourcegraph_enabled: true } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['error']).to eq('sourcegraph_url is missing') end end diff --git a/spec/requests/api/sidekiq_metrics_spec.rb b/spec/requests/api/sidekiq_metrics_spec.rb index 438b1475c54..705ae29d5d8 100644 --- a/spec/requests/api/sidekiq_metrics_spec.rb +++ b/spec/requests/api/sidekiq_metrics_spec.rb @@ -9,21 +9,21 @@ describe API::SidekiqMetrics do it 'defines the `queue_metrics` endpoint' do get api('/sidekiq/queue_metrics', admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response).to be_a Hash end it 'defines the `process_metrics` endpoint' do get api('/sidekiq/process_metrics', admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['processes']).to be_an Array end it 'defines the `job_stats` endpoint' do get api('/sidekiq/job_stats', admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response).to be_a Hash expect(json_response['jobs']).to be_a Hash expect(json_response['jobs'].keys) @@ -34,7 +34,7 @@ describe API::SidekiqMetrics do it 'defines the `compound_metrics` endpoint' do get api('/sidekiq/compound_metrics', admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response).to be_a Hash expect(json_response['queues']).to be_a Hash expect(json_response['processes']).to be_an Array diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb index cb2a0adc092..d399c2b3f1c 100644 --- a/spec/requests/api/snippets_spec.rb +++ b/spec/requests/api/snippets_spec.rb @@ -13,7 +13,7 @@ describe API::Snippets do get api("/snippets/", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an Array expect(json_response.map { |snippet| snippet['id']} ).to contain_exactly( @@ -30,7 +30,7 @@ describe API::Snippets do get api("/snippets/", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an Array expect(json_response.size).to eq(0) @@ -41,7 +41,7 @@ describe API::Snippets do get api("/snippets/") - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end it 'does not return snippets related to a project with disable feature visibility' do @@ -73,7 +73,7 @@ describe API::Snippets do it 'returns all snippets with public visibility from all users' do get api("/snippets/public", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an Array expect(json_response.map { |snippet| snippet['id']} ).to contain_exactly( @@ -95,13 +95,13 @@ describe API::Snippets do it 'requires authentication' do get api("/snippets/#{snippet.id}", nil) - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end it 'returns raw text' do get api("/snippets/#{snippet.id}/raw", author) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response.content_type).to eq 'text/plain' expect(response.body).to eq(snippet.content) end @@ -117,14 +117,14 @@ describe API::Snippets do get api("/snippets/#{snippet.id}/raw", author) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response['message']).to eq('404 Snippet Not Found') end it 'hides private snippets from ordinary users' do get api("/snippets/#{snippet.id}/raw", user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'shows internal snippets to ordinary users' do @@ -132,7 +132,7 @@ describe API::Snippets do get api("/snippets/#{internal_snippet.id}/raw", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) end end @@ -145,13 +145,13 @@ describe API::Snippets do it 'requires authentication' do get api("/snippets/#{private_snippet.id}", nil) - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end it 'returns snippet json' do get api("/snippets/#{private_snippet.id}", author) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['title']).to eq(private_snippet.title) expect(json_response['description']).to eq(private_snippet.description) @@ -162,19 +162,19 @@ describe API::Snippets do it 'shows private snippets to an admin' do get api("/snippets/#{private_snippet.id}", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) end it 'hides private snippets from an ordinary user' do get api("/snippets/#{private_snippet.id}", user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'shows internal snippets to an ordinary user' do get api("/snippets/#{internal_snippet.id}", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) end it 'returns 404 for invalid snippet id' do @@ -182,7 +182,7 @@ describe API::Snippets do get api("/snippets/#{private_snippet.id}", admin) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response['message']).to eq('404 Snippet Not Found') end end @@ -208,7 +208,7 @@ describe API::Snippets do subject end.to change { PersonalSnippet.count }.by(1) - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['title']).to eq(params[:title]) expect(json_response['description']).to eq(params[:description]) expect(json_response['file_name']).to eq(params[:file_name]) @@ -259,7 +259,7 @@ describe API::Snippets do post api("/snippets/", user), params: params - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end context 'when the snippet is spam' do @@ -285,7 +285,7 @@ describe API::Snippets do expect { create_snippet(visibility: 'public') } .not_to change { Snippet.count } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['message']).to eq({ "error" => "Spam detected" }) end @@ -311,7 +311,7 @@ describe API::Snippets do put api("/snippets/#{snippet.id}", user), params: { content: new_content, description: new_description, visibility: 'internal' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) snippet.reload expect(snippet.content).to eq(new_content) expect(snippet.description).to eq(new_description) @@ -334,21 +334,21 @@ describe API::Snippets do it 'returns 404 for invalid snippet id' do put api("/snippets/1234", user), params: { title: 'foo' } - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response['message']).to eq('404 Snippet Not Found') end it "returns 404 for another user's snippet" do put api("/snippets/#{snippet.id}", other_user), params: { title: 'fubar' } - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response['message']).to eq('404 Snippet Not Found') end it 'returns 400 for missing parameters' do put api("/snippets/1234", user) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end context 'when the snippet is spam' do @@ -378,7 +378,7 @@ describe API::Snippets do expect { update_snippet(title: 'Foo') } .not_to change { snippet.reload.title } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['message']).to eq({ "error" => "Spam detected" }) end @@ -410,14 +410,14 @@ describe API::Snippets do expect do delete api("/snippets/#{public_snippet.id}", user) - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) end.to change { PersonalSnippet.count }.by(-1) end it 'returns 404 for invalid snippet id' do delete api("/snippets/1234", user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response['message']).to eq('404 Snippet Not Found') end @@ -434,7 +434,7 @@ describe API::Snippets do it 'exposes known attributes' do get api("/snippets/#{snippet.id}/user_agent_detail", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['user_agent']).to eq(user_agent_detail.user_agent) expect(json_response['ip_address']).to eq(user_agent_detail.ip_address) expect(json_response['akismet_submitted']).to eq(user_agent_detail.submitted) @@ -443,7 +443,7 @@ describe API::Snippets do it "returns unauthorized for non-admin users" do get api("/snippets/#{snippet.id}/user_agent_detail", user) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end end diff --git a/spec/requests/api/statistics_spec.rb b/spec/requests/api/statistics_spec.rb index 91fc4d4c123..f03c1e9ca64 100644 --- a/spec/requests/api/statistics_spec.rb +++ b/spec/requests/api/statistics_spec.rb @@ -25,7 +25,7 @@ describe API::Statistics, 'Statistics' do it "returns authentication error" do get api(path, nil) - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end @@ -35,7 +35,7 @@ describe API::Statistics, 'Statistics' do it "returns forbidden error" do get api(path, user) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -45,7 +45,7 @@ describe API::Statistics, 'Statistics' do it 'matches the response schema' do get api(path, admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('statistics') end diff --git a/spec/requests/api/submodules_spec.rb b/spec/requests/api/submodules_spec.rb index 064392fb185..2604dc18005 100644 --- a/spec/requests/api/submodules_spec.rb +++ b/spec/requests/api/submodules_spec.rb @@ -33,7 +33,7 @@ describe API::Submodules do it 'returns 401' do put api(route(submodule)), params: params - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end @@ -41,7 +41,7 @@ describe API::Submodules do it 'returns 403' do put api(route(submodule), guest), params: params - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -49,19 +49,19 @@ describe API::Submodules do it 'returns 400 if params is missing' do put api(route(submodule), user) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'returns 400 if branch is missing' do put api(route(submodule), user), params: params.except(:branch) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'returns 400 if commit_sha is missing' do put api(route(submodule), user), params: params.except(:commit_sha) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'returns the commit' do @@ -69,7 +69,7 @@ describe API::Submodules do put api(route(submodule), user), params: params - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['message']).to eq commit_message expect(json_response['author_name']).to eq user.name expect(json_response['committer_name']).to eq user.name @@ -89,7 +89,7 @@ describe API::Submodules do put api(route(encoded_submodule), user), params: params - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['id']).to eq project.repository.commit(branch).id expect(project.repository.blob_at(branch, submodule).id).to eq commit_sha end diff --git a/spec/requests/api/suggestions_spec.rb b/spec/requests/api/suggestions_spec.rb index 5b07e598b8d..df3f72e3447 100644 --- a/spec/requests/api/suggestions_spec.rb +++ b/spec/requests/api/suggestions_spec.rb @@ -40,7 +40,7 @@ describe API::Suggestions do put api(url, user), params: { id: suggestion.id } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response) .to include('id', 'from_line', 'to_line', 'appliable', 'applied', 'from_content', 'to_content') @@ -57,7 +57,7 @@ describe API::Suggestions do put api(url, user), params: { id: suggestion.id } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response).to eq({ 'message' => 'Suggestion is not appliable' }) end end @@ -74,7 +74,7 @@ describe API::Suggestions do put api(url, user), params: { id: suggestion.id } - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) expect(json_response).to eq({ 'message' => '403 Forbidden' }) end end diff --git a/spec/requests/api/system_hooks_spec.rb b/spec/requests/api/system_hooks_spec.rb index 79790b1e999..50015d2e2c3 100644 --- a/spec/requests/api/system_hooks_spec.rb +++ b/spec/requests/api/system_hooks_spec.rb @@ -18,7 +18,7 @@ describe API::SystemHooks do it "returns authentication error" do get api("/hooks") - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end @@ -26,7 +26,7 @@ describe API::SystemHooks do it "returns forbidden error" do get api("/hooks", user) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -34,7 +34,7 @@ describe API::SystemHooks do it "returns an array of hooks" do get api("/hooks", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an Array expect(json_response.first['url']).to eq(hook.url) @@ -56,13 +56,13 @@ describe API::SystemHooks do it "responds with 400 if url not given" do post api("/hooks", admin) - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it "responds with 400 if url is invalid" do post api("/hooks", admin), params: { url: 'hp://mep.mep' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it "does not create new hook without url" do @@ -76,7 +76,7 @@ describe API::SystemHooks do post api('/hooks', admin), params: { url: 'http://mep.mep' } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['enable_ssl_verification']).to be true expect(json_response['push_events']).to be false expect(json_response['tag_push_events']).to be false @@ -95,7 +95,7 @@ describe API::SystemHooks do merge_requests_events: true } - expect(response).to have_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['enable_ssl_verification']).to be false expect(json_response['push_events']).to be true expect(json_response['tag_push_events']).to be true @@ -106,13 +106,13 @@ describe API::SystemHooks do describe "GET /hooks/:id" do it "returns hook by id" do get api("/hooks/#{hook.id}", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['event_name']).to eq('project_create') end it "returns 404 on failure" do get api("/hooks/404", admin) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -121,14 +121,14 @@ describe API::SystemHooks do expect do delete api("/hooks/#{hook.id}", admin) - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) end.to change { SystemHook.count }.by(-1) end it 'returns 404 if the system hook does not exist' do delete api('/hooks/12345', admin) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it_behaves_like '412 response' do diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb index f3ee1dc8435..d6e867ee407 100644 --- a/spec/workers/every_sidekiq_worker_spec.rb +++ b/spec/workers/every_sidekiq_worker_spec.rb @@ -71,30 +71,30 @@ describe 'Every Sidekiq worker' do # concurrency, so that each job can consume a large amounts of memory. For this reason, on # GitLab.com, when a large number of memory-bound jobs arrive at once, we let them queue up # rather than scaling the hardware to meet the SLO. For this reason, memory-bound, - # latency-sensitive jobs are explicitly discouraged and disabled. - it 'is (exclusively) memory-bound or latency-sentitive, not both', :aggregate_failures do - latency_sensitive_workers = workers_without_defaults - .select(&:latency_sensitive_worker?) + # high urgency jobs are explicitly discouraged and disabled. + it 'is (exclusively) memory-bound or high urgency, not both', :aggregate_failures do + high_urgency_workers = workers_without_defaults + .select { |worker| worker.get_urgency == :high } - latency_sensitive_workers.each do |worker| - expect(worker.get_worker_resource_boundary).not_to eq(:memory), "#{worker.inspect} cannot be both memory-bound and latency sensitive" + high_urgency_workers.each do |worker| + expect(worker.get_worker_resource_boundary).not_to eq(:memory), "#{worker.inspect} cannot be both memory-bound and high urgency" end end - # In high traffic installations, such as GitLab.com, `latency_sensitive` workers run in a - # dedicated fleet. In order to ensure short queue times, `latency_sensitive` jobs have strict + # In high traffic installations, such as GitLab.com, `urgency :high` workers run in a + # dedicated fleet. In order to ensure short queue times, `urgency :high` jobs have strict # SLOs in order to ensure throughput. However, when a worker depends on an external service, # such as a user's k8s cluster or a third-party internet service, we cannot guarantee latency, # and therefore throughput. An outage to an 3rd party service could therefore impact throughput - # on other latency_sensitive jobs, leading to degradation through the GitLab application. - # Please see doc/development/sidekiq_style_guide.md#Jobs-with-External-Dependencies for more + # on other high urgency jobs, leading to degradation through the GitLab application. + # Please see doc/development/sidekiq_style_guide.md#jobs-with-external-dependencies for more # details. - it 'has (exclusively) external dependencies or is latency-sentitive, not both', :aggregate_failures do - latency_sensitive_workers = workers_without_defaults - .select(&:latency_sensitive_worker?) + it 'has (exclusively) external dependencies or is high urgency, not both', :aggregate_failures do + high_urgency_workers = workers_without_defaults + .select { |worker| worker.get_urgency == :high } - latency_sensitive_workers.each do |worker| - expect(worker.worker_has_external_dependencies?).to be_falsey, "#{worker.inspect} cannot have both external dependencies and be latency sensitive" + high_urgency_workers.each do |worker| + expect(worker.worker_has_external_dependencies?).to be_falsey, "#{worker.inspect} cannot have both external dependencies and be high urgency" end end end -- cgit v1.2.3