From c0632f1463f9d9b9afd67df3d216511463a1cc8e Mon Sep 17 00:00:00 2001 From: James Clark Date: Fri, 7 Apr 2017 23:21:16 +0100 Subject: Hide clone panel and file list when user is only a guest Fixes gitlab-org/gitlab-ce#17489 Fix test finding two of the same element Capybara will raise an exception because it finds two elements that match .nav-links. This means this test would fail, even if the page meets the conditions for passing the test. Add more tests for guest access --- .../projects/guest_navigation_menu_spec.rb | 49 +++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/features/projects/guest_navigation_menu_spec.rb b/spec/features/projects/guest_navigation_menu_spec.rb index 726469daba4..89bed711bfe 100644 --- a/spec/features/projects/guest_navigation_menu_spec.rb +++ b/spec/features/projects/guest_navigation_menu_spec.rb @@ -13,7 +13,7 @@ describe "Guest navigation menu" do it "shows allowed tabs only" do visit namespace_project_path(project.namespace, project) - within(".nav-links") do + within(".layout-nav") do expect(page).to have_content 'Project' expect(page).to have_content 'Issues' expect(page).to have_content 'Wiki' @@ -23,4 +23,51 @@ describe "Guest navigation menu" do expect(page).not_to have_content 'Merge Requests' end end + + it "does not show fork button" do + visit namespace_project_path(project.namespace, project) + + within(".count-buttons") do + expect(page).not_to have_link 'Fork' + end + end + + it "does not show clone path" do + visit namespace_project_path(project.namespace, project) + + within(".project-repo-buttons") do + expect(page).not_to have_selector '.project-clone-holder' + end + end + + describe 'project landing page' do + before do + project.project_feature.update_attribute("issues_access_level", ProjectFeature::DISABLED) + project.project_feature.update_attribute("wiki_access_level", ProjectFeature::DISABLED) + end + + it "does not show the project file list landing page" do + visit namespace_project_path(project.namespace, project) + expect(page).not_to have_selector '.project-stats' + expect(page).not_to have_selector '.project-last-commit' + expect(page).not_to have_selector '.project-show-files' + end + + it "shows the customize workflow when issues and wiki are disabled" do + visit namespace_project_path(project.namespace, project) + expect(page).to have_selector '.project-show-customize_workflow' + end + + it "shows the wiki when enabled" do + project.project_feature.update_attribute("wiki_access_level", ProjectFeature::PRIVATE) + visit namespace_project_path(project.namespace, project) + expect(page).to have_selector '.project-show-wiki' + end + + it "shows the issues when enabled" do + project.project_feature.update_attribute("issues_access_level", ProjectFeature::PRIVATE) + visit namespace_project_path(project.namespace, project) + expect(page).to have_selector '.issues-list' + end + end end -- cgit v1.2.1 From a72bc1031b91c7de88711b0fc94cd6e8895ead30 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Mon, 8 May 2017 17:13:11 -0500 Subject: Add spec --- spec/features/issues/form_spec.rb | 16 ++++++++++++++++ spec/features/issues/issue_sidebar_spec.rb | 10 ++++++++++ 2 files changed, 26 insertions(+) (limited to 'spec') diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb index 87adce3cddd..7d13690f284 100644 --- a/spec/features/issues/form_spec.rb +++ b/spec/features/issues/form_spec.rb @@ -23,6 +23,22 @@ describe 'New/edit issue', feature: true, js: true do visit new_namespace_project_issue_path(project.namespace, project) end + describe 'single assignee' do + it 'hides assignee after selection' do + click_button 'Unassigned' + + page.within('.dropdown-menu-user') do + click_link user.name + end + + # TODO: Figure out a better way to wait for dropdown CSS hide + # animation to complete + sleep 0.3 + + expect(page.find('.dropdown-menu-user', visible: false)).not_to be_visible + end + end + describe 'multiple assignees' do before do click_button 'Unassigned' diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb index 0de0f93089a..dd8c46f1044 100644 --- a/spec/features/issues/issue_sidebar_spec.rb +++ b/spec/features/issues/issue_sidebar_spec.rb @@ -57,6 +57,16 @@ feature 'Issue Sidebar', feature: true do expect(page.find('.dropdown-menu-user-link.is-active')).to have_content(user.name) end end + + context 'single assignee' do + it 'hides assignee after selection' do + page.within('.dropdown-menu-user') do + click_link user.name + end + + expect(page.find('.block.assignee .selectbox', visible: false)).not_to be_visible + end + end end context 'as a allowed user' do -- cgit v1.2.1 From 0b06ba0b06982e4f318c7a72b4f91ac6158e673b Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Tue, 9 May 2017 11:11:53 -0500 Subject: Fix issue spec --- spec/features/issues_spec.rb | 4 ---- 1 file changed, 4 deletions(-) (limited to 'spec') diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index 5285dda361b..396a923082d 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -465,8 +465,6 @@ describe 'Issues', feature: true do click_link 'Edit' click_link @user.name - find('.dropdown-menu-toggle').click - page.within '.value .author' do expect(page).to have_content @user.name end @@ -474,8 +472,6 @@ describe 'Issues', feature: true do click_link 'Edit' click_link @user.name - find('.dropdown-menu-toggle').click - page.within '.value .assign-yourself' do expect(page).to have_content "No assignee" end -- cgit v1.2.1 From f154a9ecec2aaf35a10cff3d6131e5f93523c95f Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Tue, 9 May 2017 14:14:14 -0500 Subject: Fix sidebar spec --- spec/features/boards/sidebar_spec.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'spec') diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb index 7c53d2b47d9..a5ef280a60f 100644 --- a/spec/features/boards/sidebar_spec.rb +++ b/spec/features/boards/sidebar_spec.rb @@ -115,7 +115,6 @@ describe 'Issue Boards', feature: true, js: true do click_link 'Unassigned' end - find('.dropdown-menu-toggle').click wait_for_vue_resource expect(page).to have_content('No assignee') -- cgit v1.2.1 From 999f71f33289cd024f2a2b8f8f2371c6a479f110 Mon Sep 17 00:00:00 2001 From: winh Date: Tue, 9 May 2017 15:31:46 +0200 Subject: Handle Promise rejections in RecentSearchesService spec (!11206) --- .../services/recent_searches_service_spec.js | 52 +++++++++++++--------- 1 file changed, 30 insertions(+), 22 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/filtered_search/services/recent_searches_service_spec.js b/spec/javascripts/filtered_search/services/recent_searches_service_spec.js index 31fa478804a..c293c0afa97 100644 --- a/spec/javascripts/filtered_search/services/recent_searches_service_spec.js +++ b/spec/javascripts/filtered_search/services/recent_searches_service_spec.js @@ -1,6 +1,5 @@ -/* eslint-disable promise/catch-or-return */ - import RecentSearchesService from '~/filtered_search/services/recent_searches_service'; +import RecentSearchesServiceError from '~/filtered_search/services/recent_searches_service_error'; import AccessorUtilities from '~/lib/utils/accessor'; describe('RecentSearchesService', () => { @@ -22,11 +21,9 @@ describe('RecentSearchesService', () => { fetchItemsPromise .then((items) => { expect(items).toEqual([]); - done(); }) - .catch((err) => { - done.fail('Shouldn\'t reject with empty localStorage key', err); - }); + .then(done) + .catch(done.fail); }); it('should reject when unable to parse', (done) => { @@ -34,19 +31,24 @@ describe('RecentSearchesService', () => { const fetchItemsPromise = service.fetch(); fetchItemsPromise + .then(done.fail) .catch((error) => { expect(error).toEqual(jasmine.any(SyntaxError)); - done(); - }); + }) + .then(done) + .catch(done.fail); }); it('should reject when service is unavailable', (done) => { RecentSearchesService.isAvailable.and.returnValue(false); - service.fetch().catch((error) => { - expect(error).toEqual(jasmine.any(Error)); - done(); - }); + service.fetch() + .then(done.fail) + .catch((error) => { + expect(error).toEqual(jasmine.any(Error)); + }) + .then(done) + .catch(done.fail); }); it('should return items from localStorage', (done) => { @@ -56,8 +58,9 @@ describe('RecentSearchesService', () => { fetchItemsPromise .then((items) => { expect(items).toEqual(['foo', 'bar']); - done(); - }); + }) + .then(done) + .catch(done.fail); }); describe('if .isAvailable returns `false`', () => { @@ -65,12 +68,17 @@ describe('RecentSearchesService', () => { RecentSearchesService.isAvailable.and.returnValue(false); spyOn(window.localStorage, 'getItem'); - - RecentSearchesService.prototype.fetch(); }); - it('should not call .getItem', () => { - expect(window.localStorage.getItem).not.toHaveBeenCalled(); + it('should not call .getItem', (done) => { + RecentSearchesService.prototype.fetch() + .then(done.fail) + .catch((err) => { + expect(err).toEqual(new RecentSearchesServiceError()); + expect(window.localStorage.getItem).not.toHaveBeenCalled(); + }) + .then(done) + .catch(done.fail); }); }); }); @@ -105,11 +113,11 @@ describe('RecentSearchesService', () => { RecentSearchesService.isAvailable.and.returnValue(true); spyOn(JSON, 'stringify').and.returnValue(searchesString); - - RecentSearchesService.prototype.save.call(recentSearchesService); }); it('should call .setItem', () => { + RecentSearchesService.prototype.save.call(recentSearchesService); + expect(window.localStorage.setItem).toHaveBeenCalledWith(localStorageKey, searchesString); }); }); @@ -117,11 +125,11 @@ describe('RecentSearchesService', () => { describe('if .isAvailable returns `false`', () => { beforeEach(() => { RecentSearchesService.isAvailable.and.returnValue(false); - - RecentSearchesService.prototype.save(); }); it('should not call .setItem', () => { + RecentSearchesService.prototype.save(); + expect(window.localStorage.setItem).not.toHaveBeenCalled(); }); }); -- cgit v1.2.1 From be646ba0759b86686608faff6ff8b656922e7107 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Thu, 11 May 2017 12:09:12 -0500 Subject: Add helper to disable css animation in rspec --- spec/disable_css_animation.js | 15 ++++++++++++++ spec/disable_css_animation_helper.rb | 9 +++++++++ spec/features/issues/form_spec.rb | 39 ++---------------------------------- 3 files changed, 26 insertions(+), 37 deletions(-) create mode 100644 spec/disable_css_animation.js create mode 100644 spec/disable_css_animation_helper.rb (limited to 'spec') diff --git a/spec/disable_css_animation.js b/spec/disable_css_animation.js new file mode 100644 index 00000000000..b26676d2e98 --- /dev/null +++ b/spec/disable_css_animation.js @@ -0,0 +1,15 @@ +/* eslint-disable */ +// Disable eslint because capybara does not know es6 + +var disableAnimationStyles = '-webkit-transition: none !important;' + + '-moz-transition: none !important;' + + '-ms-transition: none !important;' + + '-o-transition: none !important;' + + 'transition: none !important;' + +window.onload = function() { + var animationStyles = document.createElement('style'); + animationStyles.type = 'text/css'; + animationStyles.innerHTML = '* {' + disableAnimationStyles + '}'; + document.head.appendChild(animationStyles); +}; diff --git a/spec/disable_css_animation_helper.rb b/spec/disable_css_animation_helper.rb new file mode 100644 index 00000000000..1cc69ff55c8 --- /dev/null +++ b/spec/disable_css_animation_helper.rb @@ -0,0 +1,9 @@ +Capybara.register_driver :poltergeist do |app| + opts = { + extensions: ["#{Rails.root}/spec/disable_css_animation.js"] # or wherever + } + + Capybara::Poltergeist::Driver.new(app, opts) +end + +Capybara.javascript_driver = :poltergeist diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb index 7d13690f284..a12a946b1bb 100644 --- a/spec/features/issues/form_spec.rb +++ b/spec/features/issues/form_spec.rb @@ -1,4 +1,5 @@ require 'rails_helper' +require 'disable_css_animation_helper' describe 'New/edit issue', feature: true, js: true do include GitlabRoutingHelper @@ -33,48 +34,12 @@ describe 'New/edit issue', feature: true, js: true do # TODO: Figure out a better way to wait for dropdown CSS hide # animation to complete - sleep 0.3 + # sleep 0.3 expect(page.find('.dropdown-menu-user', visible: false)).not_to be_visible end end - describe 'multiple assignees' do - before do - click_button 'Unassigned' - end - - it 'unselects other assignees when unassigned is selected' do - page.within '.dropdown-menu-user' do - click_link user2.name - end - - page.within '.dropdown-menu-user' do - click_link 'Unassigned' - end - - page.within '.js-assignee-search' do - expect(page).to have_content 'Unassigned' - end - - expect(find('input[name="issue[assignee_ids][]"]', visible: false).value).to match('0') - end - - it 'toggles assign to me when current user is selected and unselected' do - page.within '.dropdown-menu-user' do - click_link user.name - end - - expect(find('a', text: 'Assign to me', visible: false)).not_to be_visible - - page.within '.dropdown-menu-user' do - click_link user.name - end - - expect(find('a', text: 'Assign to me')).to be_visible - end - end - it 'allows user to create new issue' do fill_in 'issue_title', with: 'title' fill_in 'issue_description', with: 'title' -- cgit v1.2.1 From 9740f6a77a1fb7b24f8a9f319fc5deeb7cfe5ca2 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Thu, 11 May 2017 16:20:20 -0500 Subject: Add additional EE check --- spec/features/issues/form_spec.rb | 4 ---- 1 file changed, 4 deletions(-) (limited to 'spec') diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb index a12a946b1bb..12a89ad723f 100644 --- a/spec/features/issues/form_spec.rb +++ b/spec/features/issues/form_spec.rb @@ -32,10 +32,6 @@ describe 'New/edit issue', feature: true, js: true do click_link user.name end - # TODO: Figure out a better way to wait for dropdown CSS hide - # animation to complete - # sleep 0.3 - expect(page.find('.dropdown-menu-user', visible: false)).not_to be_visible end end -- cgit v1.2.1 From 477be05661d2cd3a550510f898d8d1d222d1598f Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 12 May 2017 09:27:21 +0100 Subject: Fixed issue boards not filtering when URL params are encoded Closes #32084 --- spec/javascripts/lib/utils/common_utils_spec.js | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'spec') diff --git a/spec/javascripts/lib/utils/common_utils_spec.js b/spec/javascripts/lib/utils/common_utils_spec.js index 5eb147ed888..42a9067ade5 100644 --- a/spec/javascripts/lib/utils/common_utils_spec.js +++ b/spec/javascripts/lib/utils/common_utils_spec.js @@ -41,6 +41,16 @@ require('~/lib/utils/common_utils'); const paramsArray = gl.utils.getUrlParamsArray(); expect(paramsArray[0][0] !== '?').toBe(true); }); + + it('should decode params', () => { + history.pushState('', '', '?label_name%5B%5D=test'); + + expect( + gl.utils.getUrlParamsArray()[0], + ).toBe('label_name[]=test'); + + history.pushState('', '', '?'); + }); }); describe('gl.utils.handleLocationHash', () => { -- cgit v1.2.1 From 28ebd70641493d9628961e1833bbb62be5cd36df Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Fri, 12 May 2017 12:59:08 -0500 Subject: Remove unnecessary comment --- spec/disable_css_animation_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/disable_css_animation_helper.rb b/spec/disable_css_animation_helper.rb index 1cc69ff55c8..ef3967c8fa6 100644 --- a/spec/disable_css_animation_helper.rb +++ b/spec/disable_css_animation_helper.rb @@ -1,6 +1,6 @@ Capybara.register_driver :poltergeist do |app| opts = { - extensions: ["#{Rails.root}/spec/disable_css_animation.js"] # or wherever + extensions: ["#{Rails.root}/spec/disable_css_animation.js"] } Capybara::Poltergeist::Driver.new(app, opts) -- cgit v1.2.1 From acffc062133e5793ac08b9529ab54689557766d4 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 12 May 2017 14:43:06 -0500 Subject: Specify explicitly whether a blob viewer should be loaded asynchronously --- spec/helpers/blob_helper_spec.rb | 3 ++- spec/models/blob_viewer/base_spec.rb | 21 ++++----------------- spec/models/blob_viewer/server_side_spec.rb | 16 ++++++++++++++++ spec/views/projects/blob/_viewer.html.haml_spec.rb | 10 +++++----- 4 files changed, 27 insertions(+), 23 deletions(-) (limited to 'spec') diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb index 1b4393e6167..b8f9828df5a 100644 --- a/spec/helpers/blob_helper_spec.rb +++ b/spec/helpers/blob_helper_spec.rb @@ -116,10 +116,11 @@ describe BlobHelper do let(:viewer_class) do Class.new(BlobViewer::Base) do + include BlobViewer::ServerSide + self.max_size = 1.megabyte self.absolute_max_size = 5.megabytes self.type = :rich - self.client_side = false end end diff --git a/spec/models/blob_viewer/base_spec.rb b/spec/models/blob_viewer/base_spec.rb index a6641970e1b..b3dc3252963 100644 --- a/spec/models/blob_viewer/base_spec.rb +++ b/spec/models/blob_viewer/base_spec.rb @@ -7,11 +7,12 @@ describe BlobViewer::Base, model: true do let(:viewer_class) do Class.new(described_class) do + include BlobViewer::ServerSide + self.extensions = %w(pdf) self.binary = true self.max_size = 1.megabyte self.absolute_max_size = 5.megabytes - self.client_side = false end end @@ -38,10 +39,10 @@ describe BlobViewer::Base, model: true do context 'when the file type is supported' do before do - viewer_class.file_type = :license + viewer_class.file_types = %i(license) viewer_class.binary = false end - + context 'when the binaryness matches' do let(:blob) { fake_blob(path: 'LICENSE', binary: false) } @@ -172,19 +173,5 @@ describe BlobViewer::Base, model: true do end end end - - context 'when the viewer is server side but the blob is stored externally' do - let(:project) { build(:empty_project, lfs_enabled: true) } - - let(:blob) { fake_blob(path: 'file.pdf', lfs: true) } - - before do - allow(Gitlab.config.lfs).to receive(:enabled).and_return(true) - end - - it 'return :server_side_but_stored_externally' do - expect(viewer.render_error).to eq(:server_side_but_stored_externally) - end - end end end diff --git a/spec/models/blob_viewer/server_side_spec.rb b/spec/models/blob_viewer/server_side_spec.rb index ddca9b79390..f047953d540 100644 --- a/spec/models/blob_viewer/server_side_spec.rb +++ b/spec/models/blob_viewer/server_side_spec.rb @@ -22,4 +22,20 @@ describe BlobViewer::ServerSide, model: true do subject.prepare! end end + + describe '#render_error' do + context 'when the blob is stored externally' do + let(:project) { build(:empty_project, lfs_enabled: true) } + + let(:blob) { fake_blob(path: 'file.pdf', lfs: true) } + + before do + allow(Gitlab.config.lfs).to receive(:enabled).and_return(true) + end + + it 'return :server_side_but_stored_externally' do + expect(subject.render_error).to eq(:server_side_but_stored_externally) + end + end + end end diff --git a/spec/views/projects/blob/_viewer.html.haml_spec.rb b/spec/views/projects/blob/_viewer.html.haml_spec.rb index 08018767624..611cb4cb224 100644 --- a/spec/views/projects/blob/_viewer.html.haml_spec.rb +++ b/spec/views/projects/blob/_viewer.html.haml_spec.rb @@ -12,7 +12,7 @@ describe 'projects/blob/_viewer.html.haml', :view do self.partial_name = 'text' self.max_size = 1.megabyte self.absolute_max_size = 5.megabytes - self.client_side = false + self.load_async = true end end @@ -35,9 +35,9 @@ describe 'projects/blob/_viewer.html.haml', :view do render partial: 'projects/blob/viewer', locals: { viewer: viewer } end - context 'when the viewer is server side' do + context 'when the viewer is loaded asynchronously' do before do - viewer_class.client_side = false + viewer_class.load_async = true end context 'when there is no render error' do @@ -65,9 +65,9 @@ describe 'projects/blob/_viewer.html.haml', :view do end end - context 'when the viewer is client side' do + context 'when the viewer is loaded synchronously' do before do - viewer_class.client_side = true + viewer_class.load_async = false end context 'when there is no render error' do -- cgit v1.2.1 From 9f933953896d4a1ca7ee40ce3fef4ead4b73ab65 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Wed, 10 May 2017 10:04:25 +0200 Subject: Do not schedule pipelines if the user can't When the owner of a pipelines schedule was either blocked or was removed from the project, the pipeline schedular would still schedule the pipeline. This would than fail however, given the user had no access to the project and it contents. However, a better way to handle it would be to not schedule it at all. Furthermore, from now on, such schedules will be deactivated so the schedule worker can ignore it on the next runs. --- spec/workers/pipeline_schedule_worker_spec.rb | 51 +++++++++++++++++---------- 1 file changed, 32 insertions(+), 19 deletions(-) (limited to 'spec') diff --git a/spec/workers/pipeline_schedule_worker_spec.rb b/spec/workers/pipeline_schedule_worker_spec.rb index 91d5a16993f..9c650354d72 100644 --- a/spec/workers/pipeline_schedule_worker_spec.rb +++ b/spec/workers/pipeline_schedule_worker_spec.rb @@ -11,40 +11,53 @@ describe PipelineScheduleWorker do end before do - project.add_master(user) - stub_ci_pipeline_to_return_yaml_file - end - context 'when there is a scheduled pipeline within next_run_at' do - let(:next_run_at) { 2.days.ago } + pipeline_schedule.update_column(:next_run_at, 1.day.ago) + end + context 'when the schedule is runnable by the user' do before do - pipeline_schedule.update_column(:next_run_at, next_run_at) + project.add_master(user) end - it 'creates a new pipeline' do - expect { subject }.to change { project.pipelines.count }.by(1) - end + context 'when there is a scheduled pipeline within next_run_at' do + it 'creates a new pipeline' do + expect { subject }.to change { project.pipelines.count }.by(1) + end - it 'updates the next_run_at field' do - subject + it 'updates the next_run_at field' do + subject + + expect(pipeline_schedule.reload.next_run_at).to be > Time.now + end - expect(pipeline_schedule.reload.next_run_at).to be > Time.now + it 'sets the schedule on the pipeline' do + subject + + expect(project.pipelines.last.pipeline_schedule).to eq(pipeline_schedule) + end end - it 'sets the schedule on the pipeline' do - subject - expect(project.pipelines.last.pipeline_schedule).to eq(pipeline_schedule) + context 'inactive schedule' do + before do + pipeline_schedule.deactivate! + end + + it 'does not creates a new pipeline' do + expect { subject }.not_to change { project.pipelines.count } + end end end - context 'inactive schedule' do - before do - pipeline_schedule.update(active: false) + context 'when the schedule is not runnable by the user' do + it 'deactivates the schedule' do + subject + + expect(pipeline_schedule.reload.active).to be_falsy end - it 'does not creates a new pipeline' do + it 'does not schedule a pipeline' do expect { subject }.not_to change { project.pipelines.count } end end -- cgit v1.2.1 From 268b1c79e9b25061718215afe0897d952a92a967 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Mon, 15 May 2017 12:39:56 +0300 Subject: [Spec optimization] Joining one-line 'it' blocks --- spec/services/ci/create_pipeline_service_spec.rb | 14 ++++---- spec/services/issues/close_service_spec.rb | 14 +++++--- .../services/merge_requests/create_service_spec.rb | 10 +++--- .../services/merge_requests/update_service_spec.rb | 38 +++++++++++++--------- 4 files changed, 46 insertions(+), 30 deletions(-) (limited to 'spec') diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index 1ff1438ba06..b536103ed65 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -27,12 +27,14 @@ describe Ci::CreatePipelineService, services: true do ) end - it { expect(pipeline).to be_kind_of(Ci::Pipeline) } - it { expect(pipeline).to be_valid } - it { expect(pipeline).to eq(project.pipelines.last) } - it { expect(pipeline).to have_attributes(user: user) } - it { expect(pipeline).to have_attributes(status: 'pending') } - it { expect(pipeline.builds.first).to be_kind_of(Ci::Build) } + it 'creates a pipeline' do + expect(pipeline).to be_kind_of(Ci::Pipeline) + expect(pipeline).to be_valid + expect(pipeline).to eq(project.pipelines.last) + expect(pipeline).to have_attributes(user: user) + expect(pipeline).to have_attributes(status: 'pending') + expect(pipeline.builds.first).to be_kind_of(Ci::Build) + end context '#update_merge_requests_head_pipeline' do it 'updates head pipeline of each merge request' do diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb index 51840531711..0a1f41719f7 100644 --- a/spec/services/issues/close_service_spec.rb +++ b/spec/services/issues/close_service_spec.rb @@ -51,8 +51,10 @@ describe Issues::CloseService, services: true do end end - it { expect(issue).to be_valid } - it { expect(issue).to be_closed } + it 'closes the issue' do + expect(issue).to be_valid + expect(issue).to be_closed + end it 'sends email to user2 about assign of new issue' do email = ActionMailer::Base.deliveries.last @@ -96,9 +98,11 @@ describe Issues::CloseService, services: true do described_class.new(project, user).close_issue(issue) end - it { expect(issue).to be_valid } - it { expect(issue).to be_opened } - it { expect(todo.reload).to be_pending } + it 'closes the issue' do + expect(issue).to be_valid + expect(issue).to be_opened + expect(todo.reload).to be_pending + end end end end diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb index 41752f1a01a..b70e9d534a4 100644 --- a/spec/services/merge_requests/create_service_spec.rb +++ b/spec/services/merge_requests/create_service_spec.rb @@ -27,10 +27,12 @@ describe MergeRequests::CreateService, services: true do @merge_request = service.execute end - it { expect(@merge_request).to be_valid } - it { expect(@merge_request.title).to eq('Awesome merge_request') } - it { expect(@merge_request.assignee).to be_nil } - it { expect(@merge_request.merge_params['force_remove_source_branch']).to eq('1') } + it 'creates an MR' do + expect(@merge_request).to be_valid + expect(@merge_request.title).to eq('Awesome merge_request') + expect(@merge_request.assignee).to be_nil + expect(@merge_request.merge_params['force_remove_source_branch']).to eq('1') + end it 'executes hooks with default action' do expect(service).to have_received(:execute_hooks).with(@merge_request) diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index 2c8fbb46e75..860a7798857 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -59,14 +59,16 @@ describe MergeRequests::UpdateService, services: true do end end - it { expect(@merge_request).to be_valid } - it { expect(@merge_request.title).to eq('New title') } - it { expect(@merge_request.assignee).to eq(user2) } - it { expect(@merge_request).to be_closed } - it { expect(@merge_request.labels.count).to eq(1) } - it { expect(@merge_request.labels.first.title).to eq(label.name) } - it { expect(@merge_request.target_branch).to eq('target') } - it { expect(@merge_request.merge_params['force_remove_source_branch']).to eq('1') } + it 'mathces base expectations' do + expect(@merge_request).to be_valid + expect(@merge_request.title).to eq('New title') + expect(@merge_request.assignee).to eq(user2) + expect(@merge_request).to be_closed + expect(@merge_request.labels.count).to eq(1) + expect(@merge_request.labels.first.title).to eq(label.name) + expect(@merge_request.target_branch).to eq('target') + expect(@merge_request.merge_params['force_remove_source_branch']).to eq('1') + end it 'executes hooks with update action' do expect(service).to have_received(:execute_hooks). @@ -148,9 +150,11 @@ describe MergeRequests::UpdateService, services: true do end end - it { expect(@merge_request).to be_valid } - it { expect(@merge_request.state).to eq('merged') } - it { expect(@merge_request.merge_error).to be_nil } + it 'merges the MR' do + expect(@merge_request).to be_valid + expect(@merge_request.state).to eq('merged') + expect(@merge_request.merge_error).to be_nil + end end context 'with finished pipeline' do @@ -167,8 +171,10 @@ describe MergeRequests::UpdateService, services: true do end end - it { expect(@merge_request).to be_valid } - it { expect(@merge_request.state).to eq('merged') } + it 'merges the MR' do + expect(@merge_request).to be_valid + expect(@merge_request.state).to eq('merged') + end end context 'with active pipeline' do @@ -202,8 +208,10 @@ describe MergeRequests::UpdateService, services: true do end end - it { expect(@merge_request.state).to eq('opened') } - it { expect(@merge_request.merge_error).not_to be_nil } + it 'does not merge the MR' do + expect(@merge_request.state).to eq('opened') + expect(@merge_request.merge_error).not_to be_nil + end end context 'MR can not be merged when note sha != MR sha' do -- cgit v1.2.1 From b0a163208c1b428fc9f5adad6489f8a3ab884a2b Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 15 May 2017 10:03:34 -0500 Subject: Rename BlobViewer max_size to overridable_max_size and absolute_max_size to max_size --- spec/helpers/blob_helper_spec.rb | 4 +-- spec/models/blob_viewer/base_spec.rb | 40 +++++++++++----------- spec/views/projects/blob/_viewer.html.haml_spec.rb | 4 +-- 3 files changed, 24 insertions(+), 24 deletions(-) (limited to 'spec') diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb index b8f9828df5a..41b5df12522 100644 --- a/spec/helpers/blob_helper_spec.rb +++ b/spec/helpers/blob_helper_spec.rb @@ -118,8 +118,8 @@ describe BlobHelper do Class.new(BlobViewer::Base) do include BlobViewer::ServerSide - self.max_size = 1.megabyte - self.absolute_max_size = 5.megabytes + self.overridable_max_size = 1.megabyte + self.max_size = 5.megabytes self.type = :rich end end diff --git a/spec/models/blob_viewer/base_spec.rb b/spec/models/blob_viewer/base_spec.rb index b3dc3252963..92fbf64a6b7 100644 --- a/spec/models/blob_viewer/base_spec.rb +++ b/spec/models/blob_viewer/base_spec.rb @@ -11,8 +11,8 @@ describe BlobViewer::Base, model: true do self.extensions = %w(pdf) self.binary = true - self.max_size = 1.megabyte - self.absolute_max_size = 5.megabytes + self.overridable_max_size = 1.megabyte + self.max_size = 5.megabytes end end @@ -69,45 +69,45 @@ describe BlobViewer::Base, model: true do end end - describe '#too_large?' do - context 'when the blob size is larger than the max size' do + describe '#exceeds_overridable_max_size?' do + context 'when the blob size is larger than the overridable max size' do let(:blob) { fake_blob(path: 'file.pdf', size: 2.megabytes) } it 'returns true' do - expect(viewer.too_large?).to be_truthy + expect(viewer.exceeds_overridable_max_size?).to be_truthy end end - context 'when the blob size is smaller than the max size' do + context 'when the blob size is smaller than the overridable max size' do let(:blob) { fake_blob(path: 'file.pdf', size: 10.kilobytes) } it 'returns false' do - expect(viewer.too_large?).to be_falsey + expect(viewer.exceeds_overridable_max_size?).to be_falsey end end end - describe '#absolutely_too_large?' do - context 'when the blob size is larger than the absolute max size' do + describe '#exceeds_max_size?' do + context 'when the blob size is larger than the max size' do let(:blob) { fake_blob(path: 'file.pdf', size: 10.megabytes) } it 'returns true' do - expect(viewer.absolutely_too_large?).to be_truthy + expect(viewer.exceeds_max_size?).to be_truthy end end - context 'when the blob size is smaller than the absolute max size' do + context 'when the blob size is smaller than the max size' do let(:blob) { fake_blob(path: 'file.pdf', size: 2.megabytes) } it 'returns false' do - expect(viewer.absolutely_too_large?).to be_falsey + expect(viewer.exceeds_max_size?).to be_falsey end end end describe '#can_override_max_size?' do - context 'when the blob size is larger than the max size' do - context 'when the blob size is larger than the absolute max size' do + context 'when the blob size is larger than the overridable max size' do + context 'when the blob size is larger than the max size' do let(:blob) { fake_blob(path: 'file.pdf', size: 10.megabytes) } it 'returns false' do @@ -115,7 +115,7 @@ describe BlobViewer::Base, model: true do end end - context 'when the blob size is smaller than the absolute max size' do + context 'when the blob size is smaller than the max size' do let(:blob) { fake_blob(path: 'file.pdf', size: 2.megabytes) } it 'returns true' do @@ -124,7 +124,7 @@ describe BlobViewer::Base, model: true do end end - context 'when the blob size is smaller than the max size' do + context 'when the blob size is smaller than the overridable max size' do let(:blob) { fake_blob(path: 'file.pdf', size: 10.kilobytes) } it 'returns false' do @@ -139,7 +139,7 @@ describe BlobViewer::Base, model: true do viewer.override_max_size = true end - context 'when the blob size is larger than the absolute max size' do + context 'when the blob size is larger than the max size' do let(:blob) { fake_blob(path: 'file.pdf', size: 10.megabytes) } it 'returns :too_large' do @@ -147,7 +147,7 @@ describe BlobViewer::Base, model: true do end end - context 'when the blob size is smaller than the absolute max size' do + context 'when the blob size is smaller than the max size' do let(:blob) { fake_blob(path: 'file.pdf', size: 2.megabytes) } it 'returns nil' do @@ -157,7 +157,7 @@ describe BlobViewer::Base, model: true do end context 'when the max size is not overridden' do - context 'when the blob size is larger than the max size' do + context 'when the blob size is larger than the overridable max size' do let(:blob) { fake_blob(path: 'file.pdf', size: 2.megabytes) } it 'returns :too_large' do @@ -165,7 +165,7 @@ describe BlobViewer::Base, model: true do end end - context 'when the blob size is smaller than the max size' do + context 'when the blob size is smaller than the overridable max size' do let(:blob) { fake_blob(path: 'file.pdf', size: 10.kilobytes) } it 'returns nil' do diff --git a/spec/views/projects/blob/_viewer.html.haml_spec.rb b/spec/views/projects/blob/_viewer.html.haml_spec.rb index 611cb4cb224..c6b0ed8da3c 100644 --- a/spec/views/projects/blob/_viewer.html.haml_spec.rb +++ b/spec/views/projects/blob/_viewer.html.haml_spec.rb @@ -10,8 +10,8 @@ describe 'projects/blob/_viewer.html.haml', :view do include BlobViewer::Rich self.partial_name = 'text' - self.max_size = 1.megabyte - self.absolute_max_size = 5.megabytes + self.overridable_max_size = 1.megabyte + self.max_size = 5.megabytes self.load_async = true end end -- cgit v1.2.1 From ed7bec31cf874de8e4923674d732618fcf654c76 Mon Sep 17 00:00:00 2001 From: Bryce Johnson Date: Fri, 12 May 2017 21:15:27 -0400 Subject: Clean up UI and styles. --- spec/features/projects/pipeline_schedules_spec.rb | 5 +++ .../interval_pattern_input_spec.js | 42 ---------------------- 2 files changed, 5 insertions(+), 42 deletions(-) (limited to 'spec') diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index fe9f94db574..a97ec25bd16 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -70,6 +70,11 @@ feature 'Pipeline Schedules', :feature do describe 'POST /projects/pipeline_schedules/new', js: true do let(:visit_page) { visit_new_pipeline_schedule } + it 'sets defaults for timezone and target branch' do + expect(page).to have_button('master') + expect(page).to have_button('UTC') + end + it 'it creates a new scheduled pipeline' do fill_in_schedule_form save_pipeline_schedule diff --git a/spec/javascripts/pipeline_schedules/interval_pattern_input_spec.js b/spec/javascripts/pipeline_schedules/interval_pattern_input_spec.js index 08fa6ca9057..845b371d90c 100644 --- a/spec/javascripts/pipeline_schedules/interval_pattern_input_spec.js +++ b/spec/javascripts/pipeline_schedules/interval_pattern_input_spec.js @@ -36,20 +36,6 @@ describe('Interval Pattern Input Component', function () { expect(this.intervalPatternComponent.initialCronInterval).toBe(this.initialCronInterval); }); - it('sets showUnsetWarning to false', function (done) { - Vue.nextTick(() => { - expect(this.intervalPatternComponent.showUnsetWarning).toBe(false); - done(); - }); - }); - - it('does not render showUnsetWarning', function (done) { - Vue.nextTick(() => { - expect(this.intervalPatternComponent.$el.outerHTML).not.toContain('Schedule not yet set'); - done(); - }); - }); - it('sets isEditable to true', function (done) { Vue.nextTick(() => { expect(this.intervalPatternComponent.isEditable).toBe(true); @@ -72,20 +58,6 @@ describe('Interval Pattern Input Component', function () { expect(this.intervalPatternComponent).toBeDefined(); }); - it('sets showUnsetWarning to false', function (done) { - Vue.nextTick(() => { - expect(this.intervalPatternComponent.showUnsetWarning).toBe(false); - done(); - }); - }); - - it('does not render showUnsetWarning', function (done) { - Vue.nextTick(() => { - expect(this.intervalPatternComponent.$el.outerHTML).not.toContain('Schedule not yet set'); - done(); - }); - }); - it('sets isEditable to false', function (done) { Vue.nextTick(() => { expect(this.intervalPatternComponent.isEditable).toBe(false); @@ -113,20 +85,6 @@ describe('Interval Pattern Input Component', function () { expect(this.intervalPatternComponent.initialCronInterval).toBe(defaultInitialCronInterval); }); - it('sets showUnsetWarning to true', function (done) { - Vue.nextTick(() => { - expect(this.intervalPatternComponent.showUnsetWarning).toBe(true); - done(); - }); - }); - - it('renders showUnsetWarning to true', function (done) { - Vue.nextTick(() => { - expect(this.intervalPatternComponent.$el.outerHTML).toContain('Schedule not yet set'); - done(); - }); - }); - it('sets isEditable to true', function (done) { Vue.nextTick(() => { expect(this.intervalPatternComponent.isEditable).toBe(true); -- cgit v1.2.1 From 0ddd1d52fdf64301caa391795cee91700b85fd81 Mon Sep 17 00:00:00 2001 From: Pawel Chojnacki Date: Mon, 15 May 2017 12:16:58 +0200 Subject: Due to DB rounding timestamp to 1s resolution - freeze date on non fractional time --- .../prometheus/queries/deployment_query_spec.rb | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'spec') diff --git a/spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb b/spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb index cc7d7e57f06..d957dd932c4 100644 --- a/spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb +++ b/spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb @@ -8,27 +8,28 @@ describe Gitlab::Prometheus::Queries::DeploymentQuery, lib: true do subject { described_class.new(client) } around do |example| - Timecop.freeze { example.run } + time_without_subsecond_values = Time.local(2008, 9, 1, 12, 0, 0) + Timecop.freeze(time_without_subsecond_values) { example.run } end it 'sends appropriate queries to prometheus' do - start_time_matcher = be_within(0.5).of((deployment.created_at - 30.minutes).to_f) - stop_time_matcher = be_within(0.5).of((deployment.created_at + 30.minutes).to_f) - created_at_matcher = be_within(0.5).of(deployment.created_at.to_f) + start_time = (deployment.created_at - 30.minutes).to_f + stop_time = (deployment.created_at + 30.minutes).to_f + created_at = deployment.created_at.to_f expect(client).to receive(:query_range).with('avg(container_memory_usage_bytes{container_name!="POD",environment="environment-slug"}) / 2^20', - start: start_time_matcher, stop: stop_time_matcher) + start: start_time, stop: stop_time) expect(client).to receive(:query).with('avg(avg_over_time(container_memory_usage_bytes{container_name!="POD",environment="environment-slug"}[30m]))', - time: created_at_matcher) + time: created_at) expect(client).to receive(:query).with('avg(avg_over_time(container_memory_usage_bytes{container_name!="POD",environment="environment-slug"}[30m]))', - time: stop_time_matcher) + time: stop_time) expect(client).to receive(:query_range).with('avg(rate(container_cpu_usage_seconds_total{container_name!="POD",environment="environment-slug"}[2m])) * 100', - start: start_time_matcher, stop: stop_time_matcher) + start: start_time, stop: stop_time) expect(client).to receive(:query).with('avg(rate(container_cpu_usage_seconds_total{container_name!="POD",environment="environment-slug"}[30m])) * 100', - time: created_at_matcher) + time: created_at) expect(client).to receive(:query).with('avg(rate(container_cpu_usage_seconds_total{container_name!="POD",environment="environment-slug"}[30m])) * 100', - time: stop_time_matcher) + time: stop_time) expect(subject.query(deployment.id)).to eq(memory_values: nil, memory_before: nil, memory_after: nil, cpu_values: nil, cpu_before: nil, cpu_after: nil) -- cgit v1.2.1 From dadd74b5749444259f9216a012645f3deddfde2d Mon Sep 17 00:00:00 2001 From: Bryce Johnson Date: Mon, 15 May 2017 15:51:20 -0400 Subject: Use classes to select dropdown buttons. --- spec/features/projects/pipeline_schedules_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'spec') diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index a97ec25bd16..03a30bfb996 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -123,12 +123,12 @@ feature 'Pipeline Schedules', :feature do end def select_timezone - click_button 'Select a timezone' + find('.js-timezone-dropdown').click click_link 'American Samoa' end def select_target_branch - click_button 'Select target branch' + find('.js-target-branch-dropdown').click click_link 'master' end -- cgit v1.2.1 From a6c0eb54dc23931aaa6dd5630bee036c62f86ff5 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Mon, 15 May 2017 15:04:09 +0300 Subject: Invalidate cache for issue and MR counters more granularly --- spec/models/user_spec.rb | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'spec') diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index f2c059010f4..e6e7774431e 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1777,4 +1777,32 @@ describe User, models: true do expect(user.preferred_language).to eq('en') end end + + context '#invalidate_issue_cache_counts' do + let(:user) { build_stubbed(:user) } + + it 'invalidates cache for issue counter' do + cache_mock = double + + expect(cache_mock).to receive(:delete).with(['users', user.id, 'assigned_open_issues_count']) + + allow(Rails).to receive(:cache).and_return(cache_mock) + + user.invalidate_issue_cache_counts + end + end + + context '#invalidate_merge_request_cache_counts' do + let(:user) { build_stubbed(:user) } + + it 'invalidates cache for Merge Request counter' do + cache_mock = double + + expect(cache_mock).to receive(:delete).with(['users', user.id, 'assigned_open_merge_requests_count']) + + allow(Rails).to receive(:cache).and_return(cache_mock) + + user.invalidate_merge_request_cache_counts + end + end end -- cgit v1.2.1 From 1fe6beae47d99271b50c473082c4bac6daa0d0a3 Mon Sep 17 00:00:00 2001 From: Jacopo Date: Thu, 20 Apr 2017 16:07:06 +0200 Subject: Notes: Warning message should go away once resolved Flash error messages disappear(`fadeOut`) automatically after any successful request --- spec/javascripts/notes_spec.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'spec') diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js index be4605a5b89..ae59ee787a8 100644 --- a/spec/javascripts/notes_spec.js +++ b/spec/javascripts/notes_spec.js @@ -14,6 +14,7 @@ import '~/notes'; gl.utils = gl.utils || {}; describe('Notes', function() { + const FLASH_TYPE_ALERT = 'alert'; var commentsTemplate = 'issues/issue_with_comment.html.raw'; preloadFixtures(commentsTemplate); @@ -460,5 +461,33 @@ import '~/notes'; expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeTruthy(); }); }); + + describe('appendFlash', () => { + beforeEach(() => { + this.notes = new Notes(); + }); + + it('shows a flash message', () => { + this.notes.addFlash('Error message', FLASH_TYPE_ALERT, this.notes.parentTimeline); + + expect(document.querySelectorAll('.flash-alert').length).toBe(1); + }); + }); + + describe('clearFlash', () => { + beforeEach(() => { + $(document).off('ajax:success'); + this.notes = new Notes(); + }); + + it('removes all the associated flash messages', () => { + this.notes.addFlash('Error message 1', FLASH_TYPE_ALERT, this.notes.parentTimeline); + this.notes.addFlash('Error message 2', FLASH_TYPE_ALERT, this.notes.parentTimeline); + + this.notes.clearFlash(); + + expect(document.querySelectorAll('.flash-alert').length).toBe(0); + }); + }); }); }).call(window); -- cgit v1.2.1 From 5b0e086946155aa45b46ebf5010403af40634377 Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Tue, 16 May 2017 19:52:17 +1100 Subject: Add an ability to cancel attaching file and redesign attaching files UI --- .../uploads/user_uploads_file_to_note_spec.rb | 76 +++++++++++++++++++--- spec/support/dropzone_helper.rb | 40 +++++++++--- 2 files changed, 98 insertions(+), 18 deletions(-) (limited to 'spec') diff --git a/spec/features/uploads/user_uploads_file_to_note_spec.rb b/spec/features/uploads/user_uploads_file_to_note_spec.rb index 0c160dd74b4..8f03024ea06 100644 --- a/spec/features/uploads/user_uploads_file_to_note_spec.rb +++ b/spec/features/uploads/user_uploads_file_to_note_spec.rb @@ -5,18 +5,78 @@ feature 'User uploads file to note', feature: true do let(:user) { create(:user) } let(:project) { create(:empty_project, creator: user, namespace: user.namespace) } + let(:issue) { create(:issue, project: project, author: user) } - scenario 'they see the attached file', js: true do - issue = create(:issue, project: project, author: user) - + before do login_as(user) visit namespace_project_issue_path(project.namespace, project, issue) + end + + context 'before uploading' do + it 'shows "Attach a file" button', js: true do + expect(page).to have_button('Attach a file') + expect(page).not_to have_selector('.uploading-progress-container', visible: true) + end + end + + context 'uploading is in progress' do + it 'shows "Cancel" button on uploading', js: true do + dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')], 0, false) + + expect(page).to have_button('Cancel') + end + + it 'cancels uploading on clicking to "Cancel" button', js: true do + dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')], 0, false) + + click_button 'Cancel' + + expect(page).to have_button('Attach a file') + expect(page).not_to have_button('Cancel') + expect(page).not_to have_selector('.uploading-progress-container', visible: true) + end + + it 'shows "Attaching a file" message on uploading 1 file', js: true do + dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')], 0, false) + + expect(page).to have_selector('.attaching-file-message', visible: true, text: 'Attaching a file -') + end + + it 'shows "Attaching 2 files" message on uploading 2 file', js: true do + dropzone_file([Rails.root.join('spec', 'fixtures', 'video_sample.mp4'), + Rails.root.join('spec', 'fixtures', 'dk.png')], 0, false) + + expect(page).to have_selector('.attaching-file-message', visible: true, text: 'Attaching 2 files -') + end + + it 'shows error message, "retry" and "attach a new file" link a if file is too big', js: true do + dropzone_file([Rails.root.join('spec', 'fixtures', 'video_sample.mp4')], 0.01) + + error_text = 'File is too big (0.06MiB). Max filesize: 0.01MiB.' + + expect(page).to have_selector('.uploading-error-message', visible: true, text: error_text) + expect(page).to have_selector('.retry-uploading-link', visible: true, text: 'Try again') + expect(page).to have_selector('.attach-new-file', visible: true, text: 'attach a new file') + expect(page).not_to have_button('Attach a file') + end + end + + context 'uploading is complete' do + it 'shows "Attach a file" button on uploading complete', js: true do + dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')]) + wait_for_ajax + + expect(page).to have_button('Attach a file') + expect(page).not_to have_selector('.uploading-progress-container', visible: true) + end - dropzone_file(Rails.root.join('spec', 'fixtures', 'dk.png')) - click_button 'Comment' - wait_for_ajax + scenario 'they see the attached file', js: true do + dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')]) + click_button 'Comment' + wait_for_ajax - expect(find('a.no-attachment-icon img[alt="dk"]')['src']) - .to match(%r{/#{project.full_path}/uploads/\h{32}/dk\.png$}) + expect(find('a.no-attachment-icon img[alt="dk"]')['src']) + .to match(%r{/#{project.full_path}/uploads/\h{32}/dk\.png$}) + end end end diff --git a/spec/support/dropzone_helper.rb b/spec/support/dropzone_helper.rb index 984ec7d2741..02fdeb08afe 100644 --- a/spec/support/dropzone_helper.rb +++ b/spec/support/dropzone_helper.rb @@ -6,32 +6,52 @@ module DropzoneHelper # Dropzone events to perform the actual upload. # # This method waits for the upload to complete before returning. - def dropzone_file(file_path) + # max_file_size is an optional parameter. + # If it's not 0, then it used in dropzone.maxFilesize parameter. + # wait_for_queuecomplete is an optional parameter. + # If it's 'false', then the helper will NOT wait for backend response + # It lets to test behaviors while AJAX is processing. + def dropzone_file(files, max_file_size = 0, wait_for_queuecomplete = true) # Generate a fake file input that Capybara can attach to page.execute_script <<-JS.strip_heredoc + $('#fakeFileInput').remove(); var fakeFileInput = window.$('').attr( - {id: 'fakeFileInput', type: 'file'} + {id: 'fakeFileInput', type: 'file', multiple: true} ).appendTo('body'); window._dropzoneComplete = false; JS - # Attach the file to the fake input selector with Capybara - attach_file('fakeFileInput', file_path) + # Attach files to the fake input selector with Capybara + attach_file('fakeFileInput', files) # Manually trigger a Dropzone "drop" event with the fake input's file list page.execute_script <<-JS.strip_heredoc - var fileList = [$('#fakeFileInput')[0].files[0]]; - var e = jQuery.Event('drop', { dataTransfer : { files : fileList } }); - var dropzone = $('.div-dropzone')[0].dropzone; + dropzone.options.autoProcessQueue = false; + + if (#{max_file_size} > 0) { + dropzone.options.maxFilesize = #{max_file_size}; + } + dropzone.on('queuecomplete', function() { window._dropzoneComplete = true; }); - dropzone.listeners[0].events.drop(e); + + var fileList = [$('#fakeFileInput')[0].files]; + + $.map(fileList, function(file){ + var e = jQuery.Event('drop', { dataTransfer : { files : file } }); + + dropzone.listeners[0].events.drop(e); + }); + + dropzone.processQueue(); JS - # Wait until Dropzone's fired `queuecomplete` - loop until page.evaluate_script('window._dropzoneComplete === true') + if wait_for_queuecomplete + # Wait until Dropzone's fired `queuecomplete` + loop until page.evaluate_script('window._dropzoneComplete === true') + end end end -- cgit v1.2.1 From 2e89eb6a494fa44d254939ea22c20cc557105ee2 Mon Sep 17 00:00:00 2001 From: Winnie Hellmann Date: Tue, 16 May 2017 10:32:53 +0000 Subject: Replace broken autocomplete field for new tags with dropdown --- spec/features/tags/master_creates_tag_spec.rb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/features/tags/master_creates_tag_spec.rb b/spec/features/tags/master_creates_tag_spec.rb index ca25c696f75..af25eebed13 100644 --- a/spec/features/tags/master_creates_tag_spec.rb +++ b/spec/features/tags/master_creates_tag_spec.rb @@ -51,10 +51,24 @@ feature 'Master creates tag', feature: true do end end + scenario 'opens dropdown for ref', js: true do + click_link 'New tag' + ref_row = find('.form-group:nth-of-type(2) .col-sm-10') + page.within ref_row do + ref_input = find('[name="ref"]', visible: false) + expect(ref_input.value).to eq 'master' + expect(find('.dropdown-toggle-text')).to have_content 'master' + + find('.js-branch-select').trigger('click') + + expect(find('.dropdown-menu')).to have_content 'empty-branch' + end + end + def create_tag_in_form(tag:, ref:, message: nil, desc: nil) click_link 'New tag' fill_in 'tag_name', with: tag - fill_in 'ref', with: ref + find('#ref', visible: false).set(ref) fill_in 'message', with: message unless message.nil? fill_in 'release_description', with: desc unless desc.nil? click_button 'Create tag' -- cgit v1.2.1 From 3f6121f2f57fab49326a2082a14dae249a91ac9d Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Wed, 10 May 2017 20:29:00 -0300 Subject: Returns new_blob_path only when user can push_code to project --- spec/serializers/merge_request_entity_spec.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'spec') diff --git a/spec/serializers/merge_request_entity_spec.rb b/spec/serializers/merge_request_entity_spec.rb index bb6e83ae4bd..b75c73e78c2 100644 --- a/spec/serializers/merge_request_entity_spec.rb +++ b/spec/serializers/merge_request_entity_spec.rb @@ -65,6 +65,23 @@ describe MergeRequestEntity do .to eq(resource.merge_commit_message(include_description: true)) end + describe 'new_blob_path' do + context 'when user can push to project' do + it 'returns path' do + project.add_developer(user) + + expect(subject[:new_blob_path]) + .to eq("/#{resource.project.full_path}/new/#{resource.source_branch}") + end + end + + context 'when user cannot push to project' do + it 'returns nil' do + expect(subject[:new_blob_path]).to be_nil + end + end + end + describe 'diff_head_sha' do before do allow(resource).to receive(:diff_head_sha) { 'sha' } -- cgit v1.2.1 From a2dbb69331ad13c77986bc2c4ed64298d5bc1388 Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Wed, 10 May 2017 20:35:19 -0300 Subject: Add new_blob_path to MR json schema --- spec/fixtures/api/schemas/entities/merge_request.json | 1 + 1 file changed, 1 insertion(+) (limited to 'spec') diff --git a/spec/fixtures/api/schemas/entities/merge_request.json b/spec/fixtures/api/schemas/entities/merge_request.json index 0a7e0e2d5f2..e5df3e7b6d1 100644 --- a/spec/fixtures/api/schemas/entities/merge_request.json +++ b/spec/fixtures/api/schemas/entities/merge_request.json @@ -86,6 +86,7 @@ "email_patches_path": { "type": "string" }, "plain_diff_path": { "type": "string" }, "status_path": { "type": "string" }, + "new_blob_path": { "type": "string" }, "merge_check_path": { "type": "string" }, "ci_environments_status_path": { "type": "string" }, "merge_commit_message_with_description": { "type": "string" }, -- cgit v1.2.1 From 9f8000790426e6c013dcb828c997a7dd72f5e3e1 Mon Sep 17 00:00:00 2001 From: Fatih Acet Date: Fri, 12 May 2017 14:47:58 +0300 Subject: MRWidget: Fix specs and address WIP comments. --- .../components/states/mr_widget_nothing_to_merge_spec.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js index d40c67b189d..0d632c7f4e5 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js @@ -4,14 +4,26 @@ import nothingToMergeComponent from '~/vue_merge_request_widget/components/state describe('MRWidgetNothingToMerge', () => { describe('template', () => { const Component = Vue.extend(nothingToMergeComponent); + const newBlobPath = '/foo'; const vm = new Component({ el: document.createElement('div'), + propsData: { + mr: { newBlobPath }, + }, }); + it('should have correct elements', () => { expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy(); - expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy(); - expect(vm.$el.innerText).toContain('There is nothing to merge from source branch into target branch.'); + expect(vm.$el.querySelector('a').href).toContain(newBlobPath); + expect(vm.$el.innerText).toContain("Currently there are no changes in this merge request's source branch"); expect(vm.$el.innerText).toContain('Please push new commits or use a different branch.'); }); + + it('should not show new blob link if there is no link available', () => { + vm.mr.newBlobPath = null; + Vue.nextTick(() => { + expect(vm.$el.querySelector('a')).toEqual(null); + }); + }); }); }); -- cgit v1.2.1 From 48a4a934c47dbfd43e03aa61e177c936b0d8d016 Mon Sep 17 00:00:00 2001 From: Fatih Acet Date: Tue, 16 May 2017 15:11:27 +0300 Subject: Address MR comments. --- .../vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js index 0d632c7f4e5..a8a02fa6b66 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js @@ -15,7 +15,7 @@ describe('MRWidgetNothingToMerge', () => { it('should have correct elements', () => { expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy(); expect(vm.$el.querySelector('a').href).toContain(newBlobPath); - expect(vm.$el.innerText).toContain("Currently there are no changes in this merge request's source branch"); + expect(vm.$el.innerText).toContain('Currently there are no changes in this merge request\'s source branch'); expect(vm.$el.innerText).toContain('Please push new commits or use a different branch.'); }); -- cgit v1.2.1 From 1fd83f972cf5ce73b3e46fd2df5ffb07889b1fd1 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 15 May 2017 15:11:45 +0000 Subject: Merge branch 'bvl-rename-build-events-to-job-events' into 'master' Rename `build_events` to `job_events` Closes #31620 See merge request !11287 --- spec/factories/project_hooks.rb | 2 +- .../projects/settings/integration_settings_spec.rb | 2 + spec/lib/gitlab/import_export/project.json | 36 +++++------ .../gitlab/import_export/relation_factory_spec.rb | 2 +- .../gitlab/import_export/safe_model_attributes.yml | 4 +- ...migrate_build_events_to_pipeline_events_spec.rb | 74 ---------------------- spec/requests/api/project_hooks_spec.rb | 4 +- spec/requests/api/v3/project_hooks_spec.rb | 4 +- 8 files changed, 28 insertions(+), 100 deletions(-) delete mode 100644 spec/migrations/migrate_build_events_to_pipeline_events_spec.rb (limited to 'spec') diff --git a/spec/factories/project_hooks.rb b/spec/factories/project_hooks.rb index 0210e871a63..cd754ea235f 100644 --- a/spec/factories/project_hooks.rb +++ b/spec/factories/project_hooks.rb @@ -14,7 +14,7 @@ FactoryGirl.define do issues_events true confidential_issues_events true note_events true - build_events true + job_events true pipeline_events true wiki_page_events true end diff --git a/spec/features/projects/settings/integration_settings_spec.rb b/spec/features/projects/settings/integration_settings_spec.rb index 7909234556e..d3232f0cc16 100644 --- a/spec/features/projects/settings/integration_settings_spec.rb +++ b/spec/features/projects/settings/integration_settings_spec.rb @@ -52,6 +52,7 @@ feature 'Integration settings', feature: true do fill_in 'hook_url', with: url check 'Tag push events' check 'Enable SSL verification' + check 'Job events' click_button 'Add webhook' @@ -59,6 +60,7 @@ feature 'Integration settings', feature: true do expect(page).to have_content('SSL Verification: enabled') expect(page).to have_content('Push Events') expect(page).to have_content('Tag Push Events') + expect(page).to have_content('Job events') end scenario 'edit existing webhook' do diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json index fdbb6a0556d..e3599d6fe59 100644 --- a/spec/lib/gitlab/import_export/project.json +++ b/spec/lib/gitlab/import_export/project.json @@ -6997,7 +6997,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "TeamcityService", "category": "ci", "default": false, @@ -7041,7 +7041,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "RedmineService", "category": "issue_tracker", "default": false, @@ -7063,7 +7063,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "PushoverService", "category": "common", "default": false, @@ -7085,7 +7085,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "PivotalTrackerService", "category": "common", "default": false, @@ -7108,7 +7108,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "JiraService", "category": "issue_tracker", "default": false, @@ -7130,7 +7130,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "IrkerService", "category": "common", "default": false, @@ -7174,7 +7174,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "GemnasiumService", "category": "common", "default": false, @@ -7196,7 +7196,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "FlowdockService", "category": "common", "default": false, @@ -7218,7 +7218,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "ExternalWikiService", "category": "common", "default": false, @@ -7240,7 +7240,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "EmailsOnPushService", "category": "common", "default": false, @@ -7262,7 +7262,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "DroneCiService", "category": "ci", "default": false, @@ -7284,7 +7284,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "CustomIssueTrackerService", "category": "issue_tracker", "default": false, @@ -7306,7 +7306,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "CampfireService", "category": "common", "default": false, @@ -7328,7 +7328,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "BuildkiteService", "category": "ci", "default": false, @@ -7350,7 +7350,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "BambooService", "category": "ci", "default": false, @@ -7372,7 +7372,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "AssemblaService", "category": "common", "default": false, @@ -7394,7 +7394,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "type": "AssemblaService", "category": "common", "default": false, @@ -7416,7 +7416,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "job_events": true, "category": "common", "default": false, "wiki_page_events": true, diff --git a/spec/lib/gitlab/import_export/relation_factory_spec.rb b/spec/lib/gitlab/import_export/relation_factory_spec.rb index 744fed44925..5417c7534ea 100644 --- a/spec/lib/gitlab/import_export/relation_factory_spec.rb +++ b/spec/lib/gitlab/import_export/relation_factory_spec.rb @@ -33,7 +33,7 @@ describe Gitlab::ImportExport::RelationFactory, lib: true do 'tag_push_events' => false, 'note_events' => true, 'enable_ssl_verification' => true, - 'build_events' => false, + 'job_events' => false, 'wiki_page_events' => true, 'token' => token } diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml index 2b95f76e045..c22fba11225 100644 --- a/spec/lib/gitlab/import_export/safe_model_attributes.yml +++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml @@ -292,7 +292,7 @@ Service: - tag_push_events - note_events - pipeline_events -- build_events +- job_events - category - default - wiki_page_events @@ -312,7 +312,7 @@ ProjectHook: - note_events - pipeline_events - enable_ssl_verification -- build_events +- job_events - wiki_page_events - token - group_id diff --git a/spec/migrations/migrate_build_events_to_pipeline_events_spec.rb b/spec/migrations/migrate_build_events_to_pipeline_events_spec.rb deleted file mode 100644 index 57eb03e3c80..00000000000 --- a/spec/migrations/migrate_build_events_to_pipeline_events_spec.rb +++ /dev/null @@ -1,74 +0,0 @@ -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20170301205640_migrate_build_events_to_pipeline_events.rb') - -# This migration uses multiple threads, and thus different transactions. This -# means data created in this spec may not be visible to some threads. To work -# around this we use the TRUNCATE cleaning strategy. -describe MigrateBuildEventsToPipelineEvents, truncate: true do - let(:migration) { described_class.new } - let(:project_with_pipeline_service) { create(:empty_project) } - let(:project_with_build_service) { create(:empty_project) } - - before do - ActiveRecord::Base.connection.execute <<-SQL - INSERT INTO services (properties, build_events, pipeline_events, type) - VALUES - ('{"notify_only_broken_builds":true}', true, false, 'SlackService') - , ('{"notify_only_broken_builds":true}', true, false, 'MattermostService') - , ('{"notify_only_broken_builds":true}', true, false, 'HipchatService') - ; - SQL - - ActiveRecord::Base.connection.execute <<-SQL - INSERT INTO services - (properties, build_events, pipeline_events, type, project_id) - VALUES - ('{"notify_only_broken_builds":true}', true, false, - 'BuildsEmailService', #{project_with_pipeline_service.id}) - , ('{"notify_only_broken_pipelines":true}', false, true, - 'PipelinesEmailService', #{project_with_pipeline_service.id}) - , ('{"notify_only_broken_builds":true}', true, false, - 'BuildsEmailService', #{project_with_build_service.id}) - ; - SQL - end - - describe '#up' do - before do - silence_migration = Module.new do - # rubocop:disable Rails/Delegate - def execute(query) - connection.execute(query) - end - end - - migration.extend(silence_migration) - migration.up - end - - it 'migrates chat service properly' do - [SlackService, MattermostService, HipchatService].each do |service| - expect(service.count).to eq(1) - - verify_service_record(service.first) - end - end - - it 'migrates pipelines email service only if it has none before' do - Project.find_each do |project| - pipeline_service_count = - project.services.where(type: 'PipelinesEmailService').count - - expect(pipeline_service_count).to eq(1) - - verify_service_record(project.pipelines_email_service) - end - end - - def verify_service_record(service) - expect(service.notify_only_broken_pipelines).to be(true) - expect(service.build_events).to be(false) - expect(service.pipeline_events).to be(true) - end - end -end diff --git a/spec/requests/api/project_hooks_spec.rb b/spec/requests/api/project_hooks_spec.rb index aee0e17a153..0f9330b062d 100644 --- a/spec/requests/api/project_hooks_spec.rb +++ b/spec/requests/api/project_hooks_spec.rb @@ -60,7 +60,7 @@ describe API::ProjectHooks, 'ProjectHooks' do expect(json_response['merge_requests_events']).to eq(hook.merge_requests_events) expect(json_response['tag_push_events']).to eq(hook.tag_push_events) expect(json_response['note_events']).to eq(hook.note_events) - expect(json_response['job_events']).to eq(hook.build_events) + expect(json_response['job_events']).to eq(hook.job_events) expect(json_response['pipeline_events']).to eq(hook.pipeline_events) expect(json_response['wiki_page_events']).to eq(hook.wiki_page_events) expect(json_response['enable_ssl_verification']).to eq(hook.enable_ssl_verification) @@ -148,7 +148,7 @@ describe API::ProjectHooks, 'ProjectHooks' do expect(json_response['merge_requests_events']).to eq(hook.merge_requests_events) expect(json_response['tag_push_events']).to eq(hook.tag_push_events) expect(json_response['note_events']).to eq(hook.note_events) - expect(json_response['job_events']).to eq(hook.build_events) + expect(json_response['job_events']).to eq(hook.job_events) expect(json_response['pipeline_events']).to eq(hook.pipeline_events) expect(json_response['wiki_page_events']).to eq(hook.wiki_page_events) expect(json_response['enable_ssl_verification']).to eq(hook.enable_ssl_verification) diff --git a/spec/requests/api/v3/project_hooks_spec.rb b/spec/requests/api/v3/project_hooks_spec.rb index a3a4c77d09d..1969d1c7f2b 100644 --- a/spec/requests/api/v3/project_hooks_spec.rb +++ b/spec/requests/api/v3/project_hooks_spec.rb @@ -58,7 +58,7 @@ describe API::ProjectHooks, 'ProjectHooks' do expect(json_response['merge_requests_events']).to eq(hook.merge_requests_events) expect(json_response['tag_push_events']).to eq(hook.tag_push_events) expect(json_response['note_events']).to eq(hook.note_events) - expect(json_response['build_events']).to eq(hook.build_events) + expect(json_response['build_events']).to eq(hook.job_events) expect(json_response['pipeline_events']).to eq(hook.pipeline_events) expect(json_response['wiki_page_events']).to eq(hook.wiki_page_events) expect(json_response['enable_ssl_verification']).to eq(hook.enable_ssl_verification) @@ -143,7 +143,7 @@ describe API::ProjectHooks, 'ProjectHooks' do expect(json_response['merge_requests_events']).to eq(hook.merge_requests_events) expect(json_response['tag_push_events']).to eq(hook.tag_push_events) expect(json_response['note_events']).to eq(hook.note_events) - expect(json_response['build_events']).to eq(hook.build_events) + expect(json_response['build_events']).to eq(hook.job_events) expect(json_response['pipeline_events']).to eq(hook.pipeline_events) expect(json_response['wiki_page_events']).to eq(hook.wiki_page_events) expect(json_response['enable_ssl_verification']).to eq(hook.enable_ssl_verification) -- cgit v1.2.1 From cf09c826a534d782de9cee4d28d3cdfa504099e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Thu, 11 May 2017 17:26:51 -0300 Subject: Re-enable gitaly migration for ref_name_for_sha after bugfixes --- spec/lib/gitlab/git/repository_spec.rb | 25 +++++++++++++++++++++++++ spec/models/repository_spec.rb | 33 ++++++++++++++------------------- 2 files changed, 39 insertions(+), 19 deletions(-) (limited to 'spec') diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index fea186fd4f4..53d492b8f74 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -26,6 +26,7 @@ describe Gitlab::Git::Repository, seed_helper: true do context 'with gitaly enabled' do before { stub_gitaly } + after { Gitlab::GitalyClient.clear_stubs! } it 'gets the branch name from GitalyClient' do expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name) @@ -120,6 +121,7 @@ describe Gitlab::Git::Repository, seed_helper: true do context 'with gitaly enabled' do before { stub_gitaly } + after { Gitlab::GitalyClient.clear_stubs! } it 'gets the branch names from GitalyClient' do expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names) @@ -157,6 +159,7 @@ describe Gitlab::Git::Repository, seed_helper: true do context 'with gitaly enabled' do before { stub_gitaly } + after { Gitlab::GitalyClient.clear_stubs! } it 'gets the tag names from GitalyClient' do expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names) @@ -1046,6 +1049,28 @@ describe Gitlab::Git::Repository, seed_helper: true do end end + describe '#ref_name_for_sha' do + let(:ref_path) { 'refs/heads' } + let(:sha) { repository.find_branch('master').dereferenced_target.id } + let(:ref_name) { 'refs/heads/master' } + + it 'returns the ref name for the given sha' do + expect(repository.ref_name_for_sha(ref_path, sha)).to eq(ref_name) + end + + it "returns an empty name if the ref doesn't exist" do + expect(repository.ref_name_for_sha(ref_path, "000000")).to eq("") + end + + it "raise an exception if the ref is empty" do + expect { repository.ref_name_for_sha(ref_path, "") }.to raise_error(ArgumentError) + end + + it "raise an exception if the ref is nil" do + expect { repository.ref_name_for_sha(ref_path, nil) }.to raise_error(ArgumentError) + end + end + describe '#find_commits' do it 'should return a return a collection of commits' do commits = repository.find_commits diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 61b748429d7..718b7d5e86b 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -110,22 +110,11 @@ describe Repository, models: true do end describe '#ref_name_for_sha' do - context 'ref found' do - it 'returns the ref' do - allow_any_instance_of(Gitlab::Popen).to receive(:popen). - and_return(["b8d95eb4969eefacb0a58f6a28f6803f8070e7b9 commit\trefs/environments/production/77\n", 0]) + it 'returns the ref' do + allow(repository.raw_repository).to receive(:ref_name_for_sha). + and_return('refs/environments/production/77') - expect(repository.ref_name_for_sha('bla', '0' * 40)).to eq 'refs/environments/production/77' - end - end - - context 'ref not found' do - it 'returns nil' do - allow_any_instance_of(Gitlab::Popen).to receive(:popen). - and_return(["", 0]) - - expect(repository.ref_name_for_sha('bla', '0' * 40)).to eq nil - end + expect(repository.ref_name_for_sha('bla', '0' * 40)).to eq 'refs/environments/production/77' end end @@ -1917,12 +1906,18 @@ describe Repository, models: true do describe '#is_ancestor?' do context 'Gitaly is_ancestor feature enabled' do - it "asks Gitaly server if it's an ancestor" do - commit = repository.commit - expect(repository.raw_repository).to receive(:is_ancestor?).and_call_original + let(:commit) { repository.commit } + let(:ancestor) { commit.parents.first } + + before do + allow(Gitlab::GitalyClient).to receive(:enabled?).and_return(true) allow(Gitlab::GitalyClient).to receive(:feature_enabled?).with(:is_ancestor).and_return(true) + end + + it "asks Gitaly server if it's an ancestor" do + expect_any_instance_of(Gitlab::GitalyClient::Commit).to receive(:is_ancestor).with(ancestor.id, commit.id) - expect(repository.is_ancestor?(commit.id, commit.id)).to be true + repository.is_ancestor?(ancestor.id, commit.id) end end end -- cgit v1.2.1 From f3cbb0a4503fca0420d8d5b276d011391ce31f6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Thu, 27 Apr 2017 17:04:59 -0300 Subject: Clean import of shared examples for protected branches/tags --- .../protected_branches/access_control_ce_spec.rb | 91 ---------------------- spec/features/protected_branches_spec.rb | 1 - .../protected_tags/access_control_ce_spec.rb | 47 ----------- spec/features/protected_tags_spec.rb | 1 - .../access_control_ce_shared_examples.rb | 91 ++++++++++++++++++++++ .../access_control_ce_shared_examples.rb | 47 +++++++++++ 6 files changed, 138 insertions(+), 140 deletions(-) delete mode 100644 spec/features/protected_branches/access_control_ce_spec.rb delete mode 100644 spec/features/protected_tags/access_control_ce_spec.rb create mode 100644 spec/support/protected_branches/access_control_ce_shared_examples.rb create mode 100644 spec/support/protected_tags/access_control_ce_shared_examples.rb (limited to 'spec') diff --git a/spec/features/protected_branches/access_control_ce_spec.rb b/spec/features/protected_branches/access_control_ce_spec.rb deleted file mode 100644 index 7fda4ade665..00000000000 --- a/spec/features/protected_branches/access_control_ce_spec.rb +++ /dev/null @@ -1,91 +0,0 @@ -RSpec.shared_examples "protected branches > access control > CE" do - ProtectedBranch::PushAccessLevel.human_access_levels.each do |(access_type_id, access_type_name)| - it "allows creating protected branches that #{access_type_name} can push to" do - visit namespace_project_protected_branches_path(project.namespace, project) - - set_protected_branch_name('master') - - within('.new_protected_branch') do - allowed_to_push_button = find(".js-allowed-to-push") - - unless allowed_to_push_button.text == access_type_name - allowed_to_push_button.trigger('click') - within(".dropdown.open .dropdown-menu") { click_on access_type_name } - end - end - - click_on "Protect" - - expect(ProtectedBranch.count).to eq(1) - expect(ProtectedBranch.last.push_access_levels.map(&:access_level)).to eq([access_type_id]) - end - - it "allows updating protected branches so that #{access_type_name} can push to them" do - visit namespace_project_protected_branches_path(project.namespace, project) - - set_protected_branch_name('master') - - click_on "Protect" - - expect(ProtectedBranch.count).to eq(1) - - within(".protected-branches-list") do - find(".js-allowed-to-push").click - - within('.js-allowed-to-push-container') do - expect(first("li")).to have_content("Roles") - click_on access_type_name - end - end - - wait_for_ajax - - expect(ProtectedBranch.last.push_access_levels.map(&:access_level)).to include(access_type_id) - end - end - - ProtectedBranch::MergeAccessLevel.human_access_levels.each do |(access_type_id, access_type_name)| - it "allows creating protected branches that #{access_type_name} can merge to" do - visit namespace_project_protected_branches_path(project.namespace, project) - - set_protected_branch_name('master') - - within('.new_protected_branch') do - allowed_to_merge_button = find(".js-allowed-to-merge") - - unless allowed_to_merge_button.text == access_type_name - allowed_to_merge_button.click - within(".dropdown.open .dropdown-menu") { click_on access_type_name } - end - end - - click_on "Protect" - - expect(ProtectedBranch.count).to eq(1) - expect(ProtectedBranch.last.merge_access_levels.map(&:access_level)).to eq([access_type_id]) - end - - it "allows updating protected branches so that #{access_type_name} can merge to them" do - visit namespace_project_protected_branches_path(project.namespace, project) - - set_protected_branch_name('master') - - click_on "Protect" - - expect(ProtectedBranch.count).to eq(1) - - within(".protected-branches-list") do - find(".js-allowed-to-merge").click - - within('.js-allowed-to-merge-container') do - expect(first("li")).to have_content("Roles") - click_on access_type_name - end - end - - wait_for_ajax - - expect(ProtectedBranch.last.merge_access_levels.map(&:access_level)).to include(access_type_id) - end - end -end diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb index fc9b293c393..884d1bbb10c 100644 --- a/spec/features/protected_branches_spec.rb +++ b/spec/features/protected_branches_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -Dir["./spec/features/protected_branches/*.rb"].sort.each { |f| require f } feature 'Projected Branches', feature: true, js: true do let(:user) { create(:user, :admin) } diff --git a/spec/features/protected_tags/access_control_ce_spec.rb b/spec/features/protected_tags/access_control_ce_spec.rb deleted file mode 100644 index 12622cd548a..00000000000 --- a/spec/features/protected_tags/access_control_ce_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -RSpec.shared_examples "protected tags > access control > CE" do - ProtectedTag::CreateAccessLevel.human_access_levels.each do |(access_type_id, access_type_name)| - it "allows creating protected tags that #{access_type_name} can create" do - visit namespace_project_protected_tags_path(project.namespace, project) - - set_protected_tag_name('master') - - within('.js-new-protected-tag') do - allowed_to_create_button = find(".js-allowed-to-create") - - unless allowed_to_create_button.text == access_type_name - allowed_to_create_button.trigger('click') - find('.create_access_levels-container .dropdown-menu li', match: :first) - within('.create_access_levels-container .dropdown-menu') { click_on access_type_name } - end - end - - click_on "Protect" - - expect(ProtectedTag.count).to eq(1) - expect(ProtectedTag.last.create_access_levels.map(&:access_level)).to eq([access_type_id]) - end - - it "allows updating protected tags so that #{access_type_name} can create them" do - visit namespace_project_protected_tags_path(project.namespace, project) - - set_protected_tag_name('master') - - click_on "Protect" - - expect(ProtectedTag.count).to eq(1) - - within(".protected-tags-list") do - find(".js-allowed-to-create").click - - within('.js-allowed-to-create-container') do - expect(first("li")).to have_content("Roles") - click_on access_type_name - end - end - - wait_for_ajax - - expect(ProtectedTag.last.create_access_levels.map(&:access_level)).to include(access_type_id) - end - end -end diff --git a/spec/features/protected_tags_spec.rb b/spec/features/protected_tags_spec.rb index e68448467b0..66236dbc7fc 100644 --- a/spec/features/protected_tags_spec.rb +++ b/spec/features/protected_tags_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -Dir["./spec/features/protected_tags/*.rb"].sort.each { |f| require f } feature 'Projected Tags', feature: true, js: true do let(:user) { create(:user, :admin) } diff --git a/spec/support/protected_branches/access_control_ce_shared_examples.rb b/spec/support/protected_branches/access_control_ce_shared_examples.rb new file mode 100644 index 00000000000..7fda4ade665 --- /dev/null +++ b/spec/support/protected_branches/access_control_ce_shared_examples.rb @@ -0,0 +1,91 @@ +RSpec.shared_examples "protected branches > access control > CE" do + ProtectedBranch::PushAccessLevel.human_access_levels.each do |(access_type_id, access_type_name)| + it "allows creating protected branches that #{access_type_name} can push to" do + visit namespace_project_protected_branches_path(project.namespace, project) + + set_protected_branch_name('master') + + within('.new_protected_branch') do + allowed_to_push_button = find(".js-allowed-to-push") + + unless allowed_to_push_button.text == access_type_name + allowed_to_push_button.trigger('click') + within(".dropdown.open .dropdown-menu") { click_on access_type_name } + end + end + + click_on "Protect" + + expect(ProtectedBranch.count).to eq(1) + expect(ProtectedBranch.last.push_access_levels.map(&:access_level)).to eq([access_type_id]) + end + + it "allows updating protected branches so that #{access_type_name} can push to them" do + visit namespace_project_protected_branches_path(project.namespace, project) + + set_protected_branch_name('master') + + click_on "Protect" + + expect(ProtectedBranch.count).to eq(1) + + within(".protected-branches-list") do + find(".js-allowed-to-push").click + + within('.js-allowed-to-push-container') do + expect(first("li")).to have_content("Roles") + click_on access_type_name + end + end + + wait_for_ajax + + expect(ProtectedBranch.last.push_access_levels.map(&:access_level)).to include(access_type_id) + end + end + + ProtectedBranch::MergeAccessLevel.human_access_levels.each do |(access_type_id, access_type_name)| + it "allows creating protected branches that #{access_type_name} can merge to" do + visit namespace_project_protected_branches_path(project.namespace, project) + + set_protected_branch_name('master') + + within('.new_protected_branch') do + allowed_to_merge_button = find(".js-allowed-to-merge") + + unless allowed_to_merge_button.text == access_type_name + allowed_to_merge_button.click + within(".dropdown.open .dropdown-menu") { click_on access_type_name } + end + end + + click_on "Protect" + + expect(ProtectedBranch.count).to eq(1) + expect(ProtectedBranch.last.merge_access_levels.map(&:access_level)).to eq([access_type_id]) + end + + it "allows updating protected branches so that #{access_type_name} can merge to them" do + visit namespace_project_protected_branches_path(project.namespace, project) + + set_protected_branch_name('master') + + click_on "Protect" + + expect(ProtectedBranch.count).to eq(1) + + within(".protected-branches-list") do + find(".js-allowed-to-merge").click + + within('.js-allowed-to-merge-container') do + expect(first("li")).to have_content("Roles") + click_on access_type_name + end + end + + wait_for_ajax + + expect(ProtectedBranch.last.merge_access_levels.map(&:access_level)).to include(access_type_id) + end + end +end diff --git a/spec/support/protected_tags/access_control_ce_shared_examples.rb b/spec/support/protected_tags/access_control_ce_shared_examples.rb new file mode 100644 index 00000000000..12622cd548a --- /dev/null +++ b/spec/support/protected_tags/access_control_ce_shared_examples.rb @@ -0,0 +1,47 @@ +RSpec.shared_examples "protected tags > access control > CE" do + ProtectedTag::CreateAccessLevel.human_access_levels.each do |(access_type_id, access_type_name)| + it "allows creating protected tags that #{access_type_name} can create" do + visit namespace_project_protected_tags_path(project.namespace, project) + + set_protected_tag_name('master') + + within('.js-new-protected-tag') do + allowed_to_create_button = find(".js-allowed-to-create") + + unless allowed_to_create_button.text == access_type_name + allowed_to_create_button.trigger('click') + find('.create_access_levels-container .dropdown-menu li', match: :first) + within('.create_access_levels-container .dropdown-menu') { click_on access_type_name } + end + end + + click_on "Protect" + + expect(ProtectedTag.count).to eq(1) + expect(ProtectedTag.last.create_access_levels.map(&:access_level)).to eq([access_type_id]) + end + + it "allows updating protected tags so that #{access_type_name} can create them" do + visit namespace_project_protected_tags_path(project.namespace, project) + + set_protected_tag_name('master') + + click_on "Protect" + + expect(ProtectedTag.count).to eq(1) + + within(".protected-tags-list") do + find(".js-allowed-to-create").click + + within('.js-allowed-to-create-container') do + expect(first("li")).to have_content("Roles") + click_on access_type_name + end + end + + wait_for_ajax + + expect(ProtectedTag.last.create_access_levels.map(&:access_level)).to include(access_type_id) + end + end +end -- cgit v1.2.1 From b8b6de4c759ba85caaf7ff4ea26abceeba23bcf4 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 16 May 2017 18:42:06 +0000 Subject: Make `gfm_auto_complete` into a module and fix up tech debt --- spec/features/projects/gfm_autocomplete_load_spec.rb | 2 +- spec/javascripts/gfm_auto_complete_spec.js | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'spec') diff --git a/spec/features/projects/gfm_autocomplete_load_spec.rb b/spec/features/projects/gfm_autocomplete_load_spec.rb index dd9622f16a0..67bc9142356 100644 --- a/spec/features/projects/gfm_autocomplete_load_spec.rb +++ b/spec/features/projects/gfm_autocomplete_load_spec.rb @@ -10,7 +10,7 @@ describe 'GFM autocomplete loading', feature: true, js: true do end it 'does not load on project#show' do - expect(evaluate_script('gl.GfmAutoComplete.dataSources')).to eq({}) + expect(evaluate_script('gl.GfmAutoComplete')).to eq(nil) end it 'loads on new issue page' do diff --git a/spec/javascripts/gfm_auto_complete_spec.js b/spec/javascripts/gfm_auto_complete_spec.js index 5dfa4008fbd..d0f15c902b5 100644 --- a/spec/javascripts/gfm_auto_complete_spec.js +++ b/spec/javascripts/gfm_auto_complete_spec.js @@ -1,13 +1,15 @@ /* eslint no-param-reassign: "off" */ -require('~/gfm_auto_complete'); +import GfmAutoComplete from '~/gfm_auto_complete'; + require('vendor/jquery.caret'); require('vendor/jquery.atwho'); -const global = window.gl || (window.gl = {}); -const GfmAutoComplete = global.GfmAutoComplete; - describe('GfmAutoComplete', function () { + const gfmAutoCompleteCallbacks = GfmAutoComplete.prototype.getDefaultCallbacks.call({ + fetchData: () => {}, + }); + describe('DefaultOptions.sorter', function () { describe('assets loading', function () { beforeEach(function () { @@ -16,7 +18,7 @@ describe('GfmAutoComplete', function () { this.atwhoInstance = { setting: {} }; this.items = []; - this.sorterValue = GfmAutoComplete.DefaultOptions.sorter + this.sorterValue = gfmAutoCompleteCallbacks.sorter .call(this.atwhoInstance, '', this.items); }); @@ -38,7 +40,7 @@ describe('GfmAutoComplete', function () { it('should enable highlightFirst if alwaysHighlightFirst is set', function () { const atwhoInstance = { setting: { alwaysHighlightFirst: true } }; - GfmAutoComplete.DefaultOptions.sorter.call(atwhoInstance); + gfmAutoCompleteCallbacks.sorter.call(atwhoInstance); expect(atwhoInstance.setting.highlightFirst).toBe(true); }); @@ -46,7 +48,7 @@ describe('GfmAutoComplete', function () { it('should enable highlightFirst if a query is present', function () { const atwhoInstance = { setting: {} }; - GfmAutoComplete.DefaultOptions.sorter.call(atwhoInstance, 'query'); + gfmAutoCompleteCallbacks.sorter.call(atwhoInstance, 'query'); expect(atwhoInstance.setting.highlightFirst).toBe(true); }); @@ -58,7 +60,7 @@ describe('GfmAutoComplete', function () { const items = []; const searchKey = 'searchKey'; - GfmAutoComplete.DefaultOptions.sorter.call(atwhoInstance, query, items, searchKey); + gfmAutoCompleteCallbacks.sorter.call(atwhoInstance, query, items, searchKey); expect($.fn.atwho.default.callbacks.sorter).toHaveBeenCalledWith(query, items, searchKey); }); @@ -67,7 +69,7 @@ describe('GfmAutoComplete', function () { describe('DefaultOptions.matcher', function () { const defaultMatcher = (context, flag, subtext) => ( - GfmAutoComplete.DefaultOptions.matcher.call(context, flag, subtext) + gfmAutoCompleteCallbacks.matcher.call(context, flag, subtext) ); const flagsUseDefaultMatcher = ['@', '#', '!', '~', '%']; -- cgit v1.2.1 From a1d44a9ec98674f8404a14bcccbee242fbe1acdb Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Tue, 16 May 2017 13:55:59 -0500 Subject: Fix rubocop --- spec/features/issues/form_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'spec') diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb index 70f362a4743..7bac9d6db74 100644 --- a/spec/features/issues/form_spec.rb +++ b/spec/features/issues/form_spec.rb @@ -27,7 +27,7 @@ describe 'New/edit issue', :feature, :js do describe 'single assignee' do it 'hides assignee after selection' do click_button 'Unassigned' - + wait_for_ajax end @@ -154,7 +154,7 @@ describe 'New/edit issue', :feature, :js do it 'correctly updates the selected user when changing assignee' do click_button 'Unassigned' - + wait_for_ajax page.within '.dropdown-menu-user' do @@ -233,4 +233,4 @@ describe 'New/edit issue', :feature, :js do JS page.evaluate_script(js) end -end \ No newline at end of file +end -- cgit v1.2.1 From 7d07012994be8014da1ce9e4d1857b220322ba41 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Tue, 16 May 2017 14:51:15 -0500 Subject: Fix form spec --- spec/features/issues/form_spec.rb | 20 ++++++++------------ spec/features/issues/issue_sidebar_spec.rb | 10 ---------- 2 files changed, 8 insertions(+), 22 deletions(-) (limited to 'spec') diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb index 7bac9d6db74..5c0907e26df 100644 --- a/spec/features/issues/form_spec.rb +++ b/spec/features/issues/form_spec.rb @@ -25,7 +25,7 @@ describe 'New/edit issue', :feature, :js do end describe 'single assignee' do - it 'hides assignee after selection' do + before do click_button 'Unassigned' wait_for_ajax @@ -36,14 +36,12 @@ describe 'New/edit issue', :feature, :js do click_link user2.name end + click_button user2.name + page.within '.dropdown-menu-user' do click_link 'Unassigned' end - page.within '.js-assignee-search' do - expect(page).to have_content 'Unassigned' - end - expect(find('input[name="issue[assignee_ids][]"]', visible: false).value).to match('0') end @@ -54,6 +52,8 @@ describe 'New/edit issue', :feature, :js do expect(find('a', text: 'Assign to me', visible: false)).not_to be_visible + click_button user.name + page.within('.dropdown-menu-user') do click_link user.name end @@ -161,18 +161,14 @@ describe 'New/edit issue', :feature, :js do click_link user.name end - expect(find('input[name="issue[assignee_ids][]"]', visible: false).value).to match(user.id.to_s) - expect(find('.dropdown-menu-user a.is-active').first(:xpath, '..')['data-user-id']).to eq(user.id.to_s) - # check the ::before pseudo element to ensure checkmark icon is present - expect(before_for_selector('.dropdown-menu-selectable a.is-active')).not_to eq('') - expect(before_for_selector('.dropdown-menu-selectable a:not(.is-active)')).to eq('') + expect(find('.js-assignee-search')).to have_content(user.name) + click_button user.name page.within '.dropdown-menu-user' do click_link user2.name end - expect(find('input[name="issue[assignee_ids][]"]', visible: false).value).to match(user2.id.to_s) - expect(find('.dropdown-menu-user a.is-active').first(:xpath, '..')['data-user-id']).to eq(user2.id.to_s) + expect(find('.js-assignee-search')).to have_content(user2.name) end end diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb index dd8c46f1044..0de0f93089a 100644 --- a/spec/features/issues/issue_sidebar_spec.rb +++ b/spec/features/issues/issue_sidebar_spec.rb @@ -57,16 +57,6 @@ feature 'Issue Sidebar', feature: true do expect(page.find('.dropdown-menu-user-link.is-active')).to have_content(user.name) end end - - context 'single assignee' do - it 'hides assignee after selection' do - page.within('.dropdown-menu-user') do - click_link user.name - end - - expect(page.find('.block.assignee .selectbox', visible: false)).not_to be_visible - end - end end context 'as a allowed user' do -- cgit v1.2.1 From 072de2c2ad8185d607ae64ba3bec320f4de83130 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 16 May 2017 13:54:41 -0700 Subject: Disable Sidekiq in spec to prevent transient build failures --- .../merge_requests/merge_immediately_with_pipeline_spec.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'spec') diff --git a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb index 5820784f8e7..545841bca4e 100644 --- a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb +++ b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb @@ -34,11 +34,13 @@ feature 'Merge immediately', :feature, :js do page.within '.mr-widget-body' do find('.dropdown-toggle').click - click_link 'Merge immediately' + Sidekiq::Testing.fake! do + click_link 'Merge immediately' - expect(find('.accept-merge-request.btn-info')).to have_content('Merge in progress') + expect(find('.accept-merge-request.btn-info')).to have_content('Merge in progress') - wait_for_ajax + wait_for_ajax + end end end end -- cgit v1.2.1 From 283f968ef2826914d1ab7b1ddb59ad1cbe441ff0 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 16 May 2017 16:01:51 -0500 Subject: update frontend specs to use ES module syntax --- spec/javascripts/abuse_reports_spec.js | 4 ++-- spec/javascripts/activities_spec.js | 6 +++--- spec/javascripts/ajax_loading_spinner_spec.js | 8 ++++---- spec/javascripts/awards_handler_spec.js | 2 +- spec/javascripts/behaviors/autosize_spec.js | 2 +- spec/javascripts/behaviors/quick_submit_spec.js | 2 +- spec/javascripts/behaviors/requires_input_spec.js | 2 +- spec/javascripts/blob/create_branch_dropdown_spec.js | 6 +++--- spec/javascripts/blob/target_branch_dropdown_spec.js | 6 +++--- spec/javascripts/boards/board_card_spec.js | 8 ++++---- spec/javascripts/boards/board_new_issue_spec.js | 4 ++-- spec/javascripts/commits_spec.js | 6 +++--- spec/javascripts/datetime_utility_spec.js | 2 +- spec/javascripts/diff_comments_store_spec.js | 6 +++--- spec/javascripts/extensions/array_spec.js | 2 +- spec/javascripts/filtered_search/dropdown_user_spec.js | 8 ++++---- spec/javascripts/filtered_search/dropdown_utils_spec.js | 8 ++++---- .../filtered_search_dropdown_manager_spec.js | 8 ++++---- .../filtered_search/filtered_search_manager_spec.js | 15 +++++++-------- .../filtered_search/filtered_search_token_keys_spec.js | 4 ++-- .../filtered_search/filtered_search_tokenizer_spec.js | 6 +++--- .../filtered_search_visual_tokens_spec.js | 4 ++-- spec/javascripts/gfm_auto_complete_spec.js | 4 ++-- spec/javascripts/gl_dropdown_spec.js | 6 +++--- spec/javascripts/gl_field_errors_spec.js | 2 +- spec/javascripts/gl_form_spec.js | 10 +++++----- spec/javascripts/header_spec.js | 4 ++-- spec/javascripts/helpers/class_spec_helper_spec.js | 2 +- spec/javascripts/issuable_spec.js | 4 ++-- spec/javascripts/issue_spec.js | 2 +- spec/javascripts/labels_issue_sidebar_spec.js | 16 ++++++++-------- spec/javascripts/lib/utils/common_utils_spec.js | 2 +- spec/javascripts/lib/utils/text_utility_spec.js | 2 +- spec/javascripts/line_highlighter_spec.js | 2 +- spec/javascripts/merge_request_spec.js | 2 +- spec/javascripts/merge_request_tabs_spec.js | 16 ++++++++-------- spec/javascripts/new_branch_spec.js | 2 +- spec/javascripts/pager_spec.js | 2 +- spec/javascripts/pretty_time_spec.js | 2 +- spec/javascripts/project_title_spec.js | 10 +++++----- spec/javascripts/search_autocomplete_spec.js | 8 ++++---- spec/javascripts/shortcuts_issuable_spec.js | 4 ++-- spec/javascripts/signin_tabs_memoizer_spec.js | 2 +- spec/javascripts/smart_interval_spec.js | 2 +- spec/javascripts/syntax_highlight_spec.js | 2 +- spec/javascripts/todos_spec.js | 4 ++-- spec/javascripts/u2f/authenticate_spec.js | 10 +++++----- spec/javascripts/u2f/register_spec.js | 10 +++++----- spec/javascripts/version_check_image_spec.js | 5 ++--- spec/javascripts/visibility_select_spec.js | 2 +- spec/javascripts/zen_mode_spec.js | 2 +- 51 files changed, 129 insertions(+), 131 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/abuse_reports_spec.js b/spec/javascripts/abuse_reports_spec.js index 76b370b345b..069d857eab6 100644 --- a/spec/javascripts/abuse_reports_spec.js +++ b/spec/javascripts/abuse_reports_spec.js @@ -1,5 +1,5 @@ -require('~/lib/utils/text_utility'); -require('~/abuse_reports'); +import '~/lib/utils/text_utility'; +import '~/abuse_reports'; ((global) => { describe('Abuse Reports', () => { diff --git a/spec/javascripts/activities_spec.js b/spec/javascripts/activities_spec.js index e6a6fc36ca1..b6e7b4717d5 100644 --- a/spec/javascripts/activities_spec.js +++ b/spec/javascripts/activities_spec.js @@ -1,8 +1,8 @@ /* eslint-disable no-unused-expressions, no-prototype-builtins, no-new, no-shadow, max-len */ -require('vendor/jquery.endless-scroll.js'); -require('~/pager'); -require('~/activities'); +import 'vendor/jquery.endless-scroll.js'; +import '~/pager'; +import '~/activities'; (() => { window.gon || (window.gon = {}); diff --git a/spec/javascripts/ajax_loading_spinner_spec.js b/spec/javascripts/ajax_loading_spinner_spec.js index a68bccb16f4..1518ae68b0d 100644 --- a/spec/javascripts/ajax_loading_spinner_spec.js +++ b/spec/javascripts/ajax_loading_spinner_spec.js @@ -1,7 +1,7 @@ -require('~/extensions/array'); -require('jquery'); -require('jquery-ujs'); -require('~/ajax_loading_spinner'); +import '~/extensions/array'; +import 'jquery'; +import 'jquery-ujs'; +import '~/ajax_loading_spinner'; describe('Ajax Loading Spinner', () => { const fixtureTemplate = 'static/ajax_loading_spinner.html.raw'; diff --git a/spec/javascripts/awards_handler_spec.js b/spec/javascripts/awards_handler_spec.js index 68ad5f66676..3fc03324d16 100644 --- a/spec/javascripts/awards_handler_spec.js +++ b/spec/javascripts/awards_handler_spec.js @@ -3,7 +3,7 @@ import Cookies from 'js-cookie'; import AwardsHandler from '~/awards_handler'; -require('~/lib/utils/common_utils'); +import '~/lib/utils/common_utils'; (function() { var awardsHandler, lazyAssert, urlRoot, openAndWaitForEmojiMenu; diff --git a/spec/javascripts/behaviors/autosize_spec.js b/spec/javascripts/behaviors/autosize_spec.js index 3deaf258cae..67afba19190 100644 --- a/spec/javascripts/behaviors/autosize_spec.js +++ b/spec/javascripts/behaviors/autosize_spec.js @@ -1,6 +1,6 @@ /* eslint-disable space-before-function-paren, no-var, comma-dangle, no-return-assign, max-len */ -require('~/behaviors/autosize'); +import '~/behaviors/autosize'; (function() { describe('Autosize behavior', function() { diff --git a/spec/javascripts/behaviors/quick_submit_spec.js b/spec/javascripts/behaviors/quick_submit_spec.js index 4820ce41ade..f56b99f8a16 100644 --- a/spec/javascripts/behaviors/quick_submit_spec.js +++ b/spec/javascripts/behaviors/quick_submit_spec.js @@ -1,6 +1,6 @@ /* eslint-disable space-before-function-paren, no-var, no-return-assign, comma-dangle, jasmine/no-spec-dupes, new-cap, max-len */ -require('~/behaviors/quick_submit'); +import '~/behaviors/quick_submit'; (function() { describe('Quick Submit behavior', function() { diff --git a/spec/javascripts/behaviors/requires_input_spec.js b/spec/javascripts/behaviors/requires_input_spec.js index 3a84013a2ed..f9fa814b801 100644 --- a/spec/javascripts/behaviors/requires_input_spec.js +++ b/spec/javascripts/behaviors/requires_input_spec.js @@ -1,6 +1,6 @@ /* eslint-disable space-before-function-paren, no-var */ -require('~/behaviors/requires_input'); +import '~/behaviors/requires_input'; (function() { describe('requiresInput', function() { diff --git a/spec/javascripts/blob/create_branch_dropdown_spec.js b/spec/javascripts/blob/create_branch_dropdown_spec.js index 9f0d373cb81..6dbaa47c544 100644 --- a/spec/javascripts/blob/create_branch_dropdown_spec.js +++ b/spec/javascripts/blob/create_branch_dropdown_spec.js @@ -1,6 +1,6 @@ -require('~/gl_dropdown'); -require('~/blob/create_branch_dropdown'); -require('~/blob/target_branch_dropdown'); +import '~/gl_dropdown'; +import '~/blob/create_branch_dropdown'; +import '~/blob/target_branch_dropdown'; describe('CreateBranchDropdown', () => { const fixtureTemplate = 'static/target_branch_dropdown.html.raw'; diff --git a/spec/javascripts/blob/target_branch_dropdown_spec.js b/spec/javascripts/blob/target_branch_dropdown_spec.js index 76ed3dc1a2d..99c9537d2ec 100644 --- a/spec/javascripts/blob/target_branch_dropdown_spec.js +++ b/spec/javascripts/blob/target_branch_dropdown_spec.js @@ -1,6 +1,6 @@ -require('~/gl_dropdown'); -require('~/blob/create_branch_dropdown'); -require('~/blob/target_branch_dropdown'); +import '~/gl_dropdown'; +import '~/blob/create_branch_dropdown'; +import '~/blob/target_branch_dropdown'; describe('TargetBranchDropdown', () => { const fixtureTemplate = 'static/target_branch_dropdown.html.raw'; diff --git a/spec/javascripts/boards/board_card_spec.js b/spec/javascripts/boards/board_card_spec.js index 376e706d1db..ad5d725cf1b 100644 --- a/spec/javascripts/boards/board_card_spec.js +++ b/spec/javascripts/boards/board_card_spec.js @@ -8,11 +8,11 @@ import Vue from 'vue'; import '~/boards/models/assignee'; -require('~/boards/models/list'); -require('~/boards/models/label'); -require('~/boards/stores/boards_store'); +import '~/boards/models/list'; +import '~/boards/models/label'; +import '~/boards/stores/boards_store'; const boardCard = require('~/boards/components/board_card').default; -require('./mock_data'); +import './mock_data'; describe('Issue card', () => { let vm; diff --git a/spec/javascripts/boards/board_new_issue_spec.js b/spec/javascripts/boards/board_new_issue_spec.js index 4999933c0c1..45d12e252c4 100644 --- a/spec/javascripts/boards/board_new_issue_spec.js +++ b/spec/javascripts/boards/board_new_issue_spec.js @@ -6,8 +6,8 @@ import Vue from 'vue'; import boardNewIssue from '~/boards/components/board_new_issue'; -require('~/boards/models/list'); -require('./mock_data'); +import '~/boards/models/list'; +import './mock_data'; describe('Issue boards new issue form', () => { let vm; diff --git a/spec/javascripts/commits_spec.js b/spec/javascripts/commits_spec.js index 05260760c43..187db7485a5 100644 --- a/spec/javascripts/commits_spec.js +++ b/spec/javascripts/commits_spec.js @@ -1,8 +1,8 @@ /* global CommitsList */ -require('vendor/jquery.endless-scroll'); -require('~/pager'); -require('~/commits'); +import 'vendor/jquery.endless-scroll'; +import '~/pager'; +import '~/commits'; (() => { // TODO: remove this hack! diff --git a/spec/javascripts/datetime_utility_spec.js b/spec/javascripts/datetime_utility_spec.js index d5eec10be42..e347c980c78 100644 --- a/spec/javascripts/datetime_utility_spec.js +++ b/spec/javascripts/datetime_utility_spec.js @@ -1,4 +1,4 @@ -require('~/lib/utils/datetime_utility'); +import '~/lib/utils/datetime_utility'; (() => { describe('Date time utils', () => { diff --git a/spec/javascripts/diff_comments_store_spec.js b/spec/javascripts/diff_comments_store_spec.js index 66ece7e4f41..d6fc6b56b82 100644 --- a/spec/javascripts/diff_comments_store_spec.js +++ b/spec/javascripts/diff_comments_store_spec.js @@ -1,9 +1,9 @@ /* eslint-disable jasmine/no-global-setup, dot-notation, jasmine/no-expect-in-setup-teardown, max-len */ /* global CommentsStore */ -require('~/diff_notes/models/discussion'); -require('~/diff_notes/models/note'); -require('~/diff_notes/stores/comments'); +import '~/diff_notes/models/discussion'; +import '~/diff_notes/models/note'; +import '~/diff_notes/stores/comments'; function createDiscussion(noteId = 1, resolved = true) { CommentsStore.create({ diff --git a/spec/javascripts/extensions/array_spec.js b/spec/javascripts/extensions/array_spec.js index 4b871fe967d..b1b81b4efc2 100644 --- a/spec/javascripts/extensions/array_spec.js +++ b/spec/javascripts/extensions/array_spec.js @@ -1,6 +1,6 @@ /* eslint-disable space-before-function-paren, no-var */ -require('~/extensions/array'); +import '~/extensions/array'; (function() { describe('Array extensions', function() { diff --git a/spec/javascripts/filtered_search/dropdown_user_spec.js b/spec/javascripts/filtered_search/dropdown_user_spec.js index 3f92fe4701e..0d8bdf4c8e7 100644 --- a/spec/javascripts/filtered_search/dropdown_user_spec.js +++ b/spec/javascripts/filtered_search/dropdown_user_spec.js @@ -1,7 +1,7 @@ -require('~/filtered_search/dropdown_utils'); -require('~/filtered_search/filtered_search_tokenizer'); -require('~/filtered_search/filtered_search_dropdown'); -require('~/filtered_search/dropdown_user'); +import '~/filtered_search/dropdown_utils'; +import '~/filtered_search/filtered_search_tokenizer'; +import '~/filtered_search/filtered_search_dropdown'; +import '~/filtered_search/dropdown_user'; describe('Dropdown User', () => { describe('getSearchInput', () => { diff --git a/spec/javascripts/filtered_search/dropdown_utils_spec.js b/spec/javascripts/filtered_search/dropdown_utils_spec.js index c820c955172..a68e315e3e4 100644 --- a/spec/javascripts/filtered_search/dropdown_utils_spec.js +++ b/spec/javascripts/filtered_search/dropdown_utils_spec.js @@ -1,7 +1,7 @@ -require('~/extensions/array'); -require('~/filtered_search/dropdown_utils'); -require('~/filtered_search/filtered_search_tokenizer'); -require('~/filtered_search/filtered_search_dropdown_manager'); +import '~/extensions/array'; +import '~/filtered_search/dropdown_utils'; +import '~/filtered_search/filtered_search_tokenizer'; +import '~/filtered_search/filtered_search_dropdown_manager'; describe('Dropdown Utils', () => { describe('getEscapedText', () => { diff --git a/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js b/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js index 17bf8932489..c92a147b937 100644 --- a/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js @@ -1,7 +1,7 @@ -require('~/extensions/array'); -require('~/filtered_search/filtered_search_visual_tokens'); -require('~/filtered_search/filtered_search_tokenizer'); -require('~/filtered_search/filtered_search_dropdown_manager'); +import '~/extensions/array'; +import '~/filtered_search/filtered_search_visual_tokens'; +import '~/filtered_search/filtered_search_tokenizer'; +import '~/filtered_search/filtered_search_dropdown_manager'; describe('Filtered Search Dropdown Manager', () => { describe('addWordToInput', () => { diff --git a/spec/javascripts/filtered_search/filtered_search_manager_spec.js b/spec/javascripts/filtered_search/filtered_search_manager_spec.js index 063d547d00c..7c7def3470d 100644 --- a/spec/javascripts/filtered_search/filtered_search_manager_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_manager_spec.js @@ -1,14 +1,13 @@ import * as recentSearchesStoreSrc from '~/filtered_search/stores/recent_searches_store'; import RecentSearchesService from '~/filtered_search/services/recent_searches_service'; import RecentSearchesServiceError from '~/filtered_search/services/recent_searches_service_error'; - -require('~/lib/utils/url_utility'); -require('~/lib/utils/common_utils'); -require('~/filtered_search/filtered_search_token_keys'); -require('~/filtered_search/filtered_search_tokenizer'); -require('~/filtered_search/filtered_search_dropdown_manager'); -require('~/filtered_search/filtered_search_manager'); -const FilteredSearchSpecHelper = require('../helpers/filtered_search_spec_helper'); +import '~/lib/utils/url_utility'; +import '~/lib/utils/common_utils'; +import '~/filtered_search/filtered_search_token_keys'; +import '~/filtered_search/filtered_search_tokenizer'; +import '~/filtered_search/filtered_search_dropdown_manager'; +import '~/filtered_search/filtered_search_manager'; +import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper'; describe('Filtered Search Manager', () => { let input; diff --git a/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js b/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js index 6f9fa434c35..1a7631994b4 100644 --- a/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js @@ -1,5 +1,5 @@ -require('~/extensions/array'); -require('~/filtered_search/filtered_search_token_keys'); +import '~/extensions/array'; +import '~/filtered_search/filtered_search_token_keys'; describe('Filtered Search Token Keys', () => { describe('get', () => { diff --git a/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js b/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js index 3e2e577f115..9561580c839 100644 --- a/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js @@ -1,6 +1,6 @@ -require('~/extensions/array'); -require('~/filtered_search/filtered_search_token_keys'); -require('~/filtered_search/filtered_search_tokenizer'); +import '~/extensions/array'; +import '~/filtered_search/filtered_search_token_keys'; +import '~/filtered_search/filtered_search_tokenizer'; describe('Filtered Search Tokenizer', () => { describe('processTokens', () => { diff --git a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js index 8b750561eb7..c5fa2b17106 100644 --- a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js @@ -1,7 +1,7 @@ import AjaxCache from '~/lib/utils/ajax_cache'; -require('~/filtered_search/filtered_search_visual_tokens'); -const FilteredSearchSpecHelper = require('../helpers/filtered_search_spec_helper'); +import '~/filtered_search/filtered_search_visual_tokens'; +import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper'; describe('Filtered Search Visual Tokens', () => { let tokensContainer; diff --git a/spec/javascripts/gfm_auto_complete_spec.js b/spec/javascripts/gfm_auto_complete_spec.js index d0f15c902b5..ad0c7264616 100644 --- a/spec/javascripts/gfm_auto_complete_spec.js +++ b/spec/javascripts/gfm_auto_complete_spec.js @@ -2,8 +2,8 @@ import GfmAutoComplete from '~/gfm_auto_complete'; -require('vendor/jquery.caret'); -require('vendor/jquery.atwho'); +import 'vendor/jquery.caret'; +import 'vendor/jquery.atwho'; describe('GfmAutoComplete', function () { const gfmAutoCompleteCallbacks = GfmAutoComplete.prototype.getDefaultCallbacks.call({ diff --git a/spec/javascripts/gl_dropdown_spec.js b/spec/javascripts/gl_dropdown_spec.js index 8f90ed69e64..3292590b9ed 100644 --- a/spec/javascripts/gl_dropdown_spec.js +++ b/spec/javascripts/gl_dropdown_spec.js @@ -1,8 +1,8 @@ /* eslint-disable comma-dangle, no-param-reassign, no-unused-expressions, max-len */ -require('~/gl_dropdown'); -require('~/lib/utils/common_utils'); -require('~/lib/utils/url_utility'); +import '~/gl_dropdown'; +import '~/lib/utils/common_utils'; +import '~/lib/utils/url_utility'; (() => { const NON_SELECTABLE_CLASSES = '.divider, .separator, .dropdown-header, .dropdown-menu-empty-link'; diff --git a/spec/javascripts/gl_field_errors_spec.js b/spec/javascripts/gl_field_errors_spec.js index 733023481f5..fa24aa426b6 100644 --- a/spec/javascripts/gl_field_errors_spec.js +++ b/spec/javascripts/gl_field_errors_spec.js @@ -1,6 +1,6 @@ /* eslint-disable space-before-function-paren, arrow-body-style */ -require('~/gl_field_errors'); +import '~/gl_field_errors'; ((global) => { preloadFixtures('static/gl_field_errors.html.raw'); diff --git a/spec/javascripts/gl_form_spec.js b/spec/javascripts/gl_form_spec.js index 5ed18d0a76b..0c7b0950a7d 100644 --- a/spec/javascripts/gl_form_spec.js +++ b/spec/javascripts/gl_form_spec.js @@ -1,9 +1,9 @@ -/* global autosize */ +import autosize from 'vendor/autosize'; +import '~/gl_form'; +import '~/lib/utils/text_utility'; +import '~/lib/utils/common_utils'; -window.autosize = require('vendor/autosize'); -require('~/gl_form'); -require('~/lib/utils/text_utility'); -require('~/lib/utils/common_utils'); +window.autosize = autosize; describe('GLForm', () => { const global = window.gl || (window.gl = {}); diff --git a/spec/javascripts/header_spec.js b/spec/javascripts/header_spec.js index b5dde5525e5..0e01934d3a3 100644 --- a/spec/javascripts/header_spec.js +++ b/spec/javascripts/header_spec.js @@ -1,7 +1,7 @@ /* eslint-disable space-before-function-paren, no-var */ -require('~/header'); -require('~/lib/utils/text_utility'); +import '~/header'; +import '~/lib/utils/text_utility'; (function() { describe('Header', function() { diff --git a/spec/javascripts/helpers/class_spec_helper_spec.js b/spec/javascripts/helpers/class_spec_helper_spec.js index a1cfc8ba820..686b8eaed31 100644 --- a/spec/javascripts/helpers/class_spec_helper_spec.js +++ b/spec/javascripts/helpers/class_spec_helper_spec.js @@ -1,6 +1,6 @@ /* global ClassSpecHelper */ -require('./class_spec_helper'); +import './class_spec_helper'; describe('ClassSpecHelper', () => { describe('itShouldBeAStaticMethod', function () { diff --git a/spec/javascripts/issuable_spec.js b/spec/javascripts/issuable_spec.js index 26d87cc5931..49fa2cb8367 100644 --- a/spec/javascripts/issuable_spec.js +++ b/spec/javascripts/issuable_spec.js @@ -1,7 +1,7 @@ /* global Issuable */ -require('~/lib/utils/url_utility'); -require('~/issuable'); +import '~/lib/utils/url_utility'; +import '~/issuable'; (() => { const BASE_URL = '/user/project/issues?scope=all&state=closed'; diff --git a/spec/javascripts/issue_spec.js b/spec/javascripts/issue_spec.js index 763f5ee9e50..df97a100b0d 100644 --- a/spec/javascripts/issue_spec.js +++ b/spec/javascripts/issue_spec.js @@ -1,7 +1,7 @@ /* eslint-disable space-before-function-paren, one-var, one-var-declaration-per-line, no-use-before-define, comma-dangle, max-len */ import Issue from '~/issue'; -require('~/lib/utils/text_utility'); +import '~/lib/utils/text_utility'; describe('Issue', function() { let $boxClosed, $boxOpen, $btnClose, $btnReopen; diff --git a/spec/javascripts/labels_issue_sidebar_spec.js b/spec/javascripts/labels_issue_sidebar_spec.js index 53aba191b19..c99f379b871 100644 --- a/spec/javascripts/labels_issue_sidebar_spec.js +++ b/spec/javascripts/labels_issue_sidebar_spec.js @@ -2,14 +2,14 @@ /* global IssuableContext */ /* global LabelsSelect */ -require('~/gl_dropdown'); -require('select2'); -require('vendor/jquery.nicescroll'); -require('~/api'); -require('~/create_label'); -require('~/issuable_context'); -require('~/users_select'); -require('~/labels_select'); +import '~/gl_dropdown'; +import 'select2'; +import 'vendor/jquery.nicescroll'; +import '~/api'; +import '~/create_label'; +import '~/issuable_context'; +import '~/users_select'; +import '~/labels_select'; (() => { let saveLabelCount = 0; diff --git a/spec/javascripts/lib/utils/common_utils_spec.js b/spec/javascripts/lib/utils/common_utils_spec.js index 42a9067ade5..e9bffd74d90 100644 --- a/spec/javascripts/lib/utils/common_utils_spec.js +++ b/spec/javascripts/lib/utils/common_utils_spec.js @@ -1,6 +1,6 @@ /* eslint-disable promise/catch-or-return */ -require('~/lib/utils/common_utils'); +import '~/lib/utils/common_utils'; (() => { describe('common_utils', () => { diff --git a/spec/javascripts/lib/utils/text_utility_spec.js b/spec/javascripts/lib/utils/text_utility_spec.js index daef9b93fa5..ca1b1b7cc3c 100644 --- a/spec/javascripts/lib/utils/text_utility_spec.js +++ b/spec/javascripts/lib/utils/text_utility_spec.js @@ -1,4 +1,4 @@ -require('~/lib/utils/text_utility'); +import '~/lib/utils/text_utility'; describe('text_utility', () => { describe('gl.text.getTextWidth', () => { diff --git a/spec/javascripts/line_highlighter_spec.js b/spec/javascripts/line_highlighter_spec.js index b1b08989028..aee274641e8 100644 --- a/spec/javascripts/line_highlighter_spec.js +++ b/spec/javascripts/line_highlighter_spec.js @@ -1,7 +1,7 @@ /* eslint-disable space-before-function-paren, no-var, no-param-reassign, quotes, prefer-template, no-else-return, new-cap, dot-notation, no-return-assign, comma-dangle, no-new, one-var, one-var-declaration-per-line, jasmine/no-spec-dupes, no-underscore-dangle, max-len */ /* global LineHighlighter */ -require('~/line_highlighter'); +import '~/line_highlighter'; (function() { describe('LineHighlighter', function() { diff --git a/spec/javascripts/merge_request_spec.js b/spec/javascripts/merge_request_spec.js index fd97dced870..1173fa40947 100644 --- a/spec/javascripts/merge_request_spec.js +++ b/spec/javascripts/merge_request_spec.js @@ -1,7 +1,7 @@ /* eslint-disable space-before-function-paren, no-return-assign */ /* global MergeRequest */ -require('~/merge_request'); +import '~/merge_request'; (function() { describe('MergeRequest', function() { diff --git a/spec/javascripts/merge_request_tabs_spec.js b/spec/javascripts/merge_request_tabs_spec.js index 254a41db160..ce0335787b7 100644 --- a/spec/javascripts/merge_request_tabs_spec.js +++ b/spec/javascripts/merge_request_tabs_spec.js @@ -1,13 +1,13 @@ /* eslint-disable no-var, comma-dangle, object-shorthand */ -require('~/merge_request_tabs'); -require('~/commit/pipelines/pipelines_bundle.js'); -require('~/breakpoints'); -require('~/lib/utils/common_utils'); -require('~/diff'); -require('~/single_file_diff'); -require('~/files_comment_button'); -require('vendor/jquery.scrollTo'); +import '~/merge_request_tabs'; +import '~/commit/pipelines/pipelines_bundle.js'; +import '~/breakpoints'; +import '~/lib/utils/common_utils'; +import '~/diff'; +import '~/single_file_diff'; +import '~/files_comment_button'; +import 'vendor/jquery.scrollTo'; (function () { // TODO: remove this hack! diff --git a/spec/javascripts/new_branch_spec.js b/spec/javascripts/new_branch_spec.js index 90a429beeca..c57f44dae17 100644 --- a/spec/javascripts/new_branch_spec.js +++ b/spec/javascripts/new_branch_spec.js @@ -1,7 +1,7 @@ /* eslint-disable space-before-function-paren, one-var, no-var, one-var-declaration-per-line, no-return-assign, quotes, max-len */ /* global NewBranchForm */ -require('~/new_branch_form'); +import '~/new_branch_form'; (function() { describe('Branch', function() { diff --git a/spec/javascripts/pager_spec.js b/spec/javascripts/pager_spec.js index d966226909b..1d3e1263371 100644 --- a/spec/javascripts/pager_spec.js +++ b/spec/javascripts/pager_spec.js @@ -1,6 +1,6 @@ /* global fixture */ -require('~/pager'); +import '~/pager'; describe('pager', () => { const Pager = window.Pager; diff --git a/spec/javascripts/pretty_time_spec.js b/spec/javascripts/pretty_time_spec.js index a4662cfb557..de99e7e3894 100644 --- a/spec/javascripts/pretty_time_spec.js +++ b/spec/javascripts/pretty_time_spec.js @@ -1,4 +1,4 @@ -require('~/lib/utils/pretty_time'); +import '~/lib/utils/pretty_time'; (() => { const prettyTime = gl.utils.prettyTime; diff --git a/spec/javascripts/project_title_spec.js b/spec/javascripts/project_title_spec.js index 5c51e855401..9f6e7e918ff 100644 --- a/spec/javascripts/project_title_spec.js +++ b/spec/javascripts/project_title_spec.js @@ -1,11 +1,11 @@ /* eslint-disable space-before-function-paren, no-unused-expressions, no-return-assign, no-param-reassign, no-var, new-cap, wrap-iife, no-unused-vars, quotes, jasmine/no-expect-in-setup-teardown, max-len */ /* global Project */ -require('select2/select2.js'); -require('~/gl_dropdown'); -require('~/api'); -require('~/project_select'); -require('~/project'); +import 'select2/select2.js'; +import '~/gl_dropdown'; +import '~/api'; +import '~/project_select'; +import '~/project'; (function() { describe('Project Title', function() { diff --git a/spec/javascripts/search_autocomplete_spec.js b/spec/javascripts/search_autocomplete_spec.js index fa52a8a0dd2..a53f58b5d0d 100644 --- a/spec/javascripts/search_autocomplete_spec.js +++ b/spec/javascripts/search_autocomplete_spec.js @@ -1,9 +1,9 @@ /* eslint-disable space-before-function-paren, max-len, no-var, one-var, one-var-declaration-per-line, no-unused-expressions, consistent-return, no-param-reassign, default-case, no-return-assign, comma-dangle, object-shorthand, prefer-template, quotes, new-parens, vars-on-top, new-cap, max-len */ -require('~/gl_dropdown'); -require('~/search_autocomplete'); -require('~/lib/utils/common_utils'); -require('vendor/fuzzaldrin-plus'); +import '~/gl_dropdown'; +import '~/search_autocomplete'; +import '~/lib/utils/common_utils'; +import 'vendor/fuzzaldrin-plus'; (function() { var addBodyAttributes, assertLinks, dashboardIssuesPath, dashboardMRsPath, groupIssuesPath, groupMRsPath, groupName, mockDashboardOptions, mockGroupOptions, mockProjectOptions, projectIssuesPath, projectMRsPath, projectName, userId, widget; diff --git a/spec/javascripts/shortcuts_issuable_spec.js b/spec/javascripts/shortcuts_issuable_spec.js index 757b8d595a4..3515dfbc60b 100644 --- a/spec/javascripts/shortcuts_issuable_spec.js +++ b/spec/javascripts/shortcuts_issuable_spec.js @@ -1,8 +1,8 @@ /* eslint-disable space-before-function-paren, no-return-assign, no-var, quotes */ /* global ShortcutsIssuable */ -require('~/copy_as_gfm'); -require('~/shortcuts_issuable'); +import '~/copy_as_gfm'; +import '~/shortcuts_issuable'; (function() { describe('ShortcutsIssuable', function() { diff --git a/spec/javascripts/signin_tabs_memoizer_spec.js b/spec/javascripts/signin_tabs_memoizer_spec.js index 5b4f5933b34..0a32797c3e2 100644 --- a/spec/javascripts/signin_tabs_memoizer_spec.js +++ b/spec/javascripts/signin_tabs_memoizer_spec.js @@ -1,6 +1,6 @@ import AccessorUtilities from '~/lib/utils/accessor'; -require('~/signin_tabs_memoizer'); +import '~/signin_tabs_memoizer'; ((global) => { describe('SigninTabsMemoizer', () => { diff --git a/spec/javascripts/smart_interval_spec.js b/spec/javascripts/smart_interval_spec.js index 4366ec2a5b8..7833bf3fb04 100644 --- a/spec/javascripts/smart_interval_spec.js +++ b/spec/javascripts/smart_interval_spec.js @@ -1,4 +1,4 @@ -require('~/smart_interval'); +import '~/smart_interval'; (() => { const DEFAULT_MAX_INTERVAL = 100; diff --git a/spec/javascripts/syntax_highlight_spec.js b/spec/javascripts/syntax_highlight_spec.js index cea223bd243..946f98379ce 100644 --- a/spec/javascripts/syntax_highlight_spec.js +++ b/spec/javascripts/syntax_highlight_spec.js @@ -1,6 +1,6 @@ /* eslint-disable space-before-function-paren, no-var, no-return-assign, quotes */ -require('~/syntax_highlight'); +import '~/syntax_highlight'; (function() { describe('Syntax Highlighter', function() { diff --git a/spec/javascripts/todos_spec.js b/spec/javascripts/todos_spec.js index 66e4fbd6304..cd74aba4a4e 100644 --- a/spec/javascripts/todos_spec.js +++ b/spec/javascripts/todos_spec.js @@ -1,5 +1,5 @@ -require('~/todos'); -require('~/lib/utils/common_utils'); +import '~/todos'; +import '~/lib/utils/common_utils'; describe('Todos', () => { preloadFixtures('todos/todos.html.raw'); diff --git a/spec/javascripts/u2f/authenticate_spec.js b/spec/javascripts/u2f/authenticate_spec.js index af2d02b6b29..a160c86308d 100644 --- a/spec/javascripts/u2f/authenticate_spec.js +++ b/spec/javascripts/u2f/authenticate_spec.js @@ -2,11 +2,11 @@ /* global MockU2FDevice */ /* global U2FAuthenticate */ -require('~/u2f/authenticate'); -require('~/u2f/util'); -require('~/u2f/error'); -require('vendor/u2f'); -require('./mock_u2f_device'); +import '~/u2f/authenticate'; +import '~/u2f/util'; +import '~/u2f/error'; +import 'vendor/u2f'; +import './mock_u2f_device'; (function() { describe('U2FAuthenticate', function() { diff --git a/spec/javascripts/u2f/register_spec.js b/spec/javascripts/u2f/register_spec.js index 3960759f7cb..a445c80f2af 100644 --- a/spec/javascripts/u2f/register_spec.js +++ b/spec/javascripts/u2f/register_spec.js @@ -2,11 +2,11 @@ /* global MockU2FDevice */ /* global U2FRegister */ -require('~/u2f/register'); -require('~/u2f/util'); -require('~/u2f/error'); -require('vendor/u2f'); -require('./mock_u2f_device'); +import '~/u2f/register'; +import '~/u2f/util'; +import '~/u2f/error'; +import 'vendor/u2f'; +import './mock_u2f_device'; (function() { describe('U2FRegister', function() { diff --git a/spec/javascripts/version_check_image_spec.js b/spec/javascripts/version_check_image_spec.js index 83ffeca253a..9637bd0414a 100644 --- a/spec/javascripts/version_check_image_spec.js +++ b/spec/javascripts/version_check_image_spec.js @@ -1,6 +1,5 @@ -const ClassSpecHelper = require('./helpers/class_spec_helper'); -const VersionCheckImage = require('~/version_check_image'); -require('jquery'); +import VersionCheckImage from '~/version_check_image'; +import ClassSpecHelper from './helpers/class_spec_helper'; describe('VersionCheckImage', function () { describe('bindErrorEvent', function () { diff --git a/spec/javascripts/visibility_select_spec.js b/spec/javascripts/visibility_select_spec.js index b26ed41f27a..c2eaea7c2ed 100644 --- a/spec/javascripts/visibility_select_spec.js +++ b/spec/javascripts/visibility_select_spec.js @@ -1,4 +1,4 @@ -require('~/visibility_select'); +import '~/visibility_select'; (() => { const VisibilitySelect = gl.VisibilitySelect; diff --git a/spec/javascripts/zen_mode_spec.js b/spec/javascripts/zen_mode_spec.js index 99515f2e5f2..4399c8b2025 100644 --- a/spec/javascripts/zen_mode_spec.js +++ b/spec/javascripts/zen_mode_spec.js @@ -3,7 +3,7 @@ /* global Mousetrap */ /* global ZenMode */ -require('~/zen_mode'); +import '~/zen_mode'; (function() { var enterZen, escapeKeydown, exitZen; -- cgit v1.2.1 From fc4cabca090e69be2ad7742deaed366f48065e66 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 16 May 2017 16:02:06 -0500 Subject: update test_bundle to use ES module syntax --- spec/javascripts/test_bundle.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js index 0464b5d2329..13827a26571 100644 --- a/spec/javascripts/test_bundle.js +++ b/spec/javascripts/test_bundle.js @@ -1,13 +1,15 @@ -// enable test fixtures -require('jasmine-jquery'); +import $ from 'jquery'; +import _ from 'underscore'; +import 'jasmine-jquery'; +import '~/commons'; +// enable test fixtures jasmine.getFixtures().fixturesPath = '/base/spec/javascripts/fixtures'; jasmine.getJSONFixtures().fixturesPath = '/base/spec/javascripts/fixtures'; -// include common libraries -require('~/commons/index.js'); -window.$ = window.jQuery = require('jquery'); -window._ = require('underscore'); +// globalize common libraries +window.$ = window.jQuery = $; +window._ = _; // stub expected globals window.gl = window.gl || {}; -- cgit v1.2.1 From 6b09ecbb5c3295404429fedc8e826ca9c1e92273 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 16 May 2017 14:11:35 -0700 Subject: Wait for all Vue resources to finish in merge immediately spec --- spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb index 545841bca4e..c102722d6db 100644 --- a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb +++ b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb @@ -39,7 +39,7 @@ feature 'Merge immediately', :feature, :js do expect(find('.accept-merge-request.btn-info')).to have_content('Merge in progress') - wait_for_ajax + wait_for_vue_resource end end end -- cgit v1.2.1 From f68a3f3f4b2c24f39c626b49f78255d632cb1420 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 16 May 2017 16:16:36 -0500 Subject: fix implicit window object reference within gl_form_spec --- spec/javascripts/gl_form_spec.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/gl_form_spec.js b/spec/javascripts/gl_form_spec.js index 0c7b0950a7d..837feacec1d 100644 --- a/spec/javascripts/gl_form_spec.js +++ b/spec/javascripts/gl_form_spec.js @@ -27,7 +27,7 @@ describe('GLForm', () => { $.prototype.off.calls.reset(); $.prototype.on.calls.reset(); $.prototype.css.calls.reset(); - autosize.calls.reset(); + window.autosize.calls.reset(); done(); }); }); @@ -51,7 +51,7 @@ describe('GLForm', () => { }); it('should autosize the textarea', () => { - expect(autosize).toHaveBeenCalledWith(jasmine.any(Object)); + expect(window.autosize).toHaveBeenCalledWith(jasmine.any(Object)); }); it('should set the resize css property to vertical', () => { @@ -81,7 +81,7 @@ describe('GLForm', () => { spyOn($.prototype, 'data'); spyOn($.prototype, 'outerHeight').and.returnValue(200); spyOn(window, 'outerHeight').and.returnValue(400); - spyOn(autosize, 'destroy'); + spyOn(window.autosize, 'destroy'); this.glForm.destroyAutosize(); }); @@ -95,7 +95,7 @@ describe('GLForm', () => { }); it('should call autosize destroy', () => { - expect(autosize.destroy).toHaveBeenCalledWith(this.textarea); + expect(window.autosize.destroy).toHaveBeenCalledWith(this.textarea); }); it('should set the data-height attribute', () => { @@ -114,9 +114,9 @@ describe('GLForm', () => { it('should return undefined if the data-height equals the outerHeight', () => { spyOn($.prototype, 'outerHeight').and.returnValue(200); spyOn($.prototype, 'data').and.returnValue(200); - spyOn(autosize, 'destroy'); + spyOn(window.autosize, 'destroy'); expect(this.glForm.destroyAutosize()).toBeUndefined(); - expect(autosize.destroy).not.toHaveBeenCalled(); + expect(window.autosize.destroy).not.toHaveBeenCalled(); }); }); }); -- cgit v1.2.1 From 337acf4be340960efc1b97e2bf298314f9ea16bf Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 16 May 2017 16:57:05 -0500 Subject: fix eslint failures --- spec/javascripts/activities_spec.js | 2 +- spec/javascripts/boards/board_card_spec.js | 2 +- spec/javascripts/merge_request_tabs_spec.js | 2 +- spec/javascripts/project_title_spec.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/activities_spec.js b/spec/javascripts/activities_spec.js index b6e7b4717d5..e8c5f721423 100644 --- a/spec/javascripts/activities_spec.js +++ b/spec/javascripts/activities_spec.js @@ -1,6 +1,6 @@ /* eslint-disable no-unused-expressions, no-prototype-builtins, no-new, no-shadow, max-len */ -import 'vendor/jquery.endless-scroll.js'; +import 'vendor/jquery.endless-scroll'; import '~/pager'; import '~/activities'; diff --git a/spec/javascripts/boards/board_card_spec.js b/spec/javascripts/boards/board_card_spec.js index ad5d725cf1b..447b244c71f 100644 --- a/spec/javascripts/boards/board_card_spec.js +++ b/spec/javascripts/boards/board_card_spec.js @@ -11,7 +11,7 @@ import '~/boards/models/assignee'; import '~/boards/models/list'; import '~/boards/models/label'; import '~/boards/stores/boards_store'; -const boardCard = require('~/boards/components/board_card').default; +import boardCard from '~/boards/components/board_card'; import './mock_data'; describe('Issue card', () => { diff --git a/spec/javascripts/merge_request_tabs_spec.js b/spec/javascripts/merge_request_tabs_spec.js index ce0335787b7..3d1706aab68 100644 --- a/spec/javascripts/merge_request_tabs_spec.js +++ b/spec/javascripts/merge_request_tabs_spec.js @@ -1,7 +1,7 @@ /* eslint-disable no-var, comma-dangle, object-shorthand */ import '~/merge_request_tabs'; -import '~/commit/pipelines/pipelines_bundle.js'; +import '~/commit/pipelines/pipelines_bundle'; import '~/breakpoints'; import '~/lib/utils/common_utils'; import '~/diff'; diff --git a/spec/javascripts/project_title_spec.js b/spec/javascripts/project_title_spec.js index 9f6e7e918ff..3dba2e817ff 100644 --- a/spec/javascripts/project_title_spec.js +++ b/spec/javascripts/project_title_spec.js @@ -1,7 +1,7 @@ /* eslint-disable space-before-function-paren, no-unused-expressions, no-return-assign, no-param-reassign, no-var, new-cap, wrap-iife, no-unused-vars, quotes, jasmine/no-expect-in-setup-teardown, max-len */ /* global Project */ -import 'select2/select2.js'; +import 'select2/select2'; import '~/gl_dropdown'; import '~/api'; import '~/project_select'; -- cgit v1.2.1 From 83f8a91cb51b1f21b864789b88fbf85fd1497709 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 16 May 2017 17:06:34 -0500 Subject: refactor instances of CJS module.exports to ES module syntax --- spec/javascripts/helpers/class_spec_helper.js | 4 +--- spec/javascripts/helpers/filtered_search_spec_helper.js | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/helpers/class_spec_helper.js b/spec/javascripts/helpers/class_spec_helper.js index 61db27a8fcc..7a60d33b471 100644 --- a/spec/javascripts/helpers/class_spec_helper.js +++ b/spec/javascripts/helpers/class_spec_helper.js @@ -1,4 +1,4 @@ -class ClassSpecHelper { +export default class ClassSpecHelper { static itShouldBeAStaticMethod(base, method) { return it('should be a static method', () => { expect(Object.prototype.hasOwnProperty.call(base, method)).toBeTruthy(); @@ -7,5 +7,3 @@ class ClassSpecHelper { } window.ClassSpecHelper = ClassSpecHelper; - -module.exports = ClassSpecHelper; diff --git a/spec/javascripts/helpers/filtered_search_spec_helper.js b/spec/javascripts/helpers/filtered_search_spec_helper.js index b8d4a93b1ab..0d7092a2357 100644 --- a/spec/javascripts/helpers/filtered_search_spec_helper.js +++ b/spec/javascripts/helpers/filtered_search_spec_helper.js @@ -1,4 +1,4 @@ -class FilteredSearchSpecHelper { +export default class FilteredSearchSpecHelper { static createFilterVisualTokenHTML(name, value, isSelected) { return FilteredSearchSpecHelper.createFilterVisualToken(name, value, isSelected).outerHTML; } @@ -53,5 +53,3 @@ class FilteredSearchSpecHelper { `; } } - -module.exports = FilteredSearchSpecHelper; -- cgit v1.2.1 From 0385f9efc2a7844b0900958281296eb444b5070c Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Wed, 17 May 2017 13:36:19 +0200 Subject: Sort environments folders when opening them Fixes gitlab-org/gitlab-ce#30814 --- spec/controllers/projects/environments_controller_spec.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'spec') diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index c0f8c36a018..e783c60452f 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -84,6 +84,9 @@ describe Projects::EnvironmentsController do create(:environment, project: project, name: 'staging-1.0/review', state: :available) + create(:environment, project: project, + name: 'staging-1.0/preview', + state: :available) end context 'when using default format' do @@ -107,6 +110,8 @@ describe Projects::EnvironmentsController do expect(response).to be_ok expect(response).not_to render_template 'folder' expect(json_response['environments'][0]) + .to include('name' => 'staging-1.0/preview') + expect(json_response['environments'][1]) .to include('name' => 'staging-1.0/review') end end -- cgit v1.2.1 From 63da91725e25ac6b3abc6a345f063d9436b06442 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Wed, 10 May 2017 18:39:17 +0200 Subject: Improve pipeline size for query limit test The pipeline was quite meagre in both stages and the number of groups. This has been improved. Performance is not yet optimal, but to limit this from sliding further this slippery slope, a hard limit has been set. --- .../projects/pipelines_controller_spec.rb | 38 +++++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'spec') diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index fb4a4721a58..c880da1e36a 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -38,7 +38,7 @@ describe Projects::PipelinesController do end describe 'GET show JSON' do - let!(:pipeline) { create(:ci_pipeline_with_one_job, project: project) } + let(:pipeline) { create(:ci_pipeline_with_one_job, project: project) } it 'returns the pipeline' do get_pipeline_json @@ -49,20 +49,48 @@ describe Projects::PipelinesController do expect(json_response['details']).to have_key 'stages' end - context 'when the pipeline has multiple jobs' do + context 'when the pipeline has multiple stages and groups' do + before do + RequestStore.begin! + + create_build('build', 0, 'build') + create_build('test', 1, 'rspec 0') + create_build('deploy', 2, 'production') + create_build('post deploy', 3, 'pages 0') + end + + after do + RequestStore.end! + RequestStore.clear! + end + + let(:project) { create(:project) } + let(:pipeline) do + create(:ci_empty_pipeline, project: project, user: user, sha: project.commit.id) + end + it 'does not perform N + 1 queries' do control_count = ActiveRecord::QueryRecorder.new { get_pipeline_json }.count - create(:ci_build, pipeline: pipeline) + create_build('test', 1, 'rspec 1') + create_build('test', 1, 'spinach 0') + create_build('test', 1, 'spinach 1') + create_build('test', 1, 'audit') + create_build('post deploy', 3, 'pages 1') + create_build('post deploy', 3, 'pages 2') - # The plus 2 is needed to group and sort - expect { get_pipeline_json }.not_to exceed_query_limit(control_count + 2) + new_count = ActiveRecord::QueryRecorder.new { get_pipeline_json }.count + expect(new_count).to be_within(12).of(control_count) end end def get_pipeline_json get :show, namespace_id: project.namespace, project_id: project, id: pipeline, format: :json end + + def create_build(stage, stage_idx, name) + create(:ci_build, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name) + end end describe 'GET stages.json' do -- cgit v1.2.1 From 831d6f5f777370e4ad424211df24e2f5bd380445 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 16 May 2017 22:51:56 -0700 Subject: Properly handle container registry redirects to fix metadata stored on a S3 backend The previous behavior would include the Authorization header, which would make fetching an S3 blob fail quietly. Closes #22403 Update sh-fix-container-registry-s3-redirects.yml --- spec/lib/container_registry/blob_spec.rb | 2 +- spec/lib/container_registry/client_spec.rb | 39 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 spec/lib/container_registry/client_spec.rb (limited to 'spec') diff --git a/spec/lib/container_registry/blob_spec.rb b/spec/lib/container_registry/blob_spec.rb index f06e5fd54a2..ab010c6dfeb 100644 --- a/spec/lib/container_registry/blob_spec.rb +++ b/spec/lib/container_registry/blob_spec.rb @@ -98,7 +98,7 @@ describe ContainerRegistry::Blob do context 'for a valid address' do before do stub_request(:get, location). - with(headers: { 'Authorization' => nil }). + with { |request| !request.headers.include?('Authorization') }. to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, diff --git a/spec/lib/container_registry/client_spec.rb b/spec/lib/container_registry/client_spec.rb new file mode 100644 index 00000000000..ec03b533383 --- /dev/null +++ b/spec/lib/container_registry/client_spec.rb @@ -0,0 +1,39 @@ +# coding: utf-8 +require 'spec_helper' + +describe ContainerRegistry::Client do + let(:token) { '12345' } + let(:options) { { token: token } } + let(:client) { described_class.new("http://container-registry", options) } + + describe '#blob' do + it 'GET /v2/:name/blobs/:digest' do + stub_request(:get, "http://container-registry/v2/group/test/blobs/sha256:0123456789012345"). + with(headers: { + 'Accept' => 'application/octet-stream', + 'Authorization' => "bearer #{token}" + }). + to_return(status: 200, body: "Blob") + + expect(client.blob('group/test', 'sha256:0123456789012345')).to eq('Blob') + end + + it 'follows 307 redirect for GET /v2/:name/blobs/:digest' do + stub_request(:get, "http://container-registry/v2/group/test/blobs/sha256:0123456789012345"). + with(headers: { + 'Accept' => 'application/octet-stream', + 'Authorization' => "bearer #{token}" + }). + to_return(status: 307, body: "", headers: { Location: 'http://redirected' }) + # We should probably use hash_excluding here, but that requires an update to WebMock: + # https://github.com/bblimke/webmock/blob/master/lib/webmock/matchers/hash_excluding_matcher.rb + stub_request(:get, "http://redirected/"). + with { |request| !request.headers.include?('Authorization') }. + to_return(status: 200, body: "Successfully redirected") + + response = client.blob('group/test', 'sha256:0123456789012345') + + expect(response).to eq('Successfully redirected') + end + end +end -- cgit v1.2.1 From de9e559d4495560095adfa03ea6489ea51f6f2f4 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Wed, 17 May 2017 15:26:52 +0000 Subject: Fix unassigned checkmark --- spec/features/dashboard/issues_spec.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'spec') diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb index 86c7954e60c..7a132dba1e9 100644 --- a/spec/features/dashboard/issues_spec.rb +++ b/spec/features/dashboard/issues_spec.rb @@ -26,9 +26,20 @@ RSpec.describe 'Dashboard Issues', feature: true do expect(page).not_to have_content(other_issue.title) end + it 'shows checkmark when unassigned is selected for assignee', js: true do + find('.js-assignee-search').click + find('li', text: 'Unassigned').click + find('.js-assignee-search').click + + expect(find('li[data-user-id="0"] a.is-active')).to be_visible + end + it 'shows issues when current user is author', js: true do find('#assignee_id', visible: false).set('') find('.js-author-search', match: :first).click + + expect(find('li[data-user-id="null"] a.is-active')).to be_visible + find('.dropdown-menu-author li a', match: :first, text: current_user.to_reference).click find('.js-author-search', match: :first).click -- cgit v1.2.1 From c5a13781fad254e1984cf03f5487350e60f665e5 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 16 May 2017 18:44:54 -0500 Subject: Use same last commit widget on project homepage and tree view --- spec/views/projects/_last_commit.html.haml_spec.rb | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 spec/views/projects/_last_commit.html.haml_spec.rb (limited to 'spec') diff --git a/spec/views/projects/_last_commit.html.haml_spec.rb b/spec/views/projects/_last_commit.html.haml_spec.rb deleted file mode 100644 index eea1695b171..00000000000 --- a/spec/views/projects/_last_commit.html.haml_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'spec_helper' - -describe 'projects/_last_commit', :view do - let(:project) { create(:project, :repository) } - - context 'when there is a pipeline present for the commit' do - context 'when pipeline is blocked' do - let!(:pipeline) do - create(:ci_pipeline, :blocked, project: project, - sha: project.commit.id) - end - - it 'shows correct pipeline badge' do - render 'projects/last_commit', commit: project.commit, - project: project, - ref: :master - - expect(rendered).to have_text "blocked #{project.commit.short_id}" - end - end - end -end -- cgit v1.2.1 From d3b24a7638de71ee1286200978e0b6d0b33d0753 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 17 May 2017 09:23:00 -0500 Subject: Show last commit for current tree on tree page --- spec/views/projects/tree/show.html.haml_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'spec') diff --git a/spec/views/projects/tree/show.html.haml_spec.rb b/spec/views/projects/tree/show.html.haml_spec.rb index 835a93e620e..33eba3e6d3d 100644 --- a/spec/views/projects/tree/show.html.haml_spec.rb +++ b/spec/views/projects/tree/show.html.haml_spec.rb @@ -21,11 +21,11 @@ describe 'projects/tree/show' do let(:tree) { repository.tree(commit.id, path) } before do + assign(:id, File.join(ref, path)) assign(:ref, ref) - assign(:commit, commit) - assign(:id, commit.id) - assign(:tree, tree) assign(:path, path) + assign(:last_commit, commit) + assign(:tree, tree) end it 'displays correctly' do -- cgit v1.2.1 From afef4a6676543dc8552a89c2ed7e76fae1efe834 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 17 May 2017 19:25:31 +0300 Subject: Add spec for last commit info when browsing repository files Signed-off-by: Dmitriy Zaporozhets --- spec/features/projects/files/browse_files_spec.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'spec') diff --git a/spec/features/projects/files/browse_files_spec.rb b/spec/features/projects/files/browse_files_spec.rb index 70e96efd557..4166aec1956 100644 --- a/spec/features/projects/files/browse_files_spec.rb +++ b/spec/features/projects/files/browse_files_spec.rb @@ -31,4 +31,16 @@ feature 'user browses project', feature: true, js: true do expect(page).to have_content 'oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897' expect(page).to have_content 'size 1575078' end + + scenario 'can see last commit for current directory' do + last_commit = project.repository.last_commit_for_path(project.default_branch, 'files') + + click_link 'files' + wait_for_ajax + + page.within('.blob-commit-info') do + expect(page).to have_content last_commit.short_id + expect(page).to have_content last_commit.author_name + end + end end -- cgit v1.2.1 From d1bce8ea75df00970f3d4a67587ceb64bf4ec905 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 17 May 2017 18:00:13 +0000 Subject: Add auxiliary blob viewer for CHANGELOG --- spec/models/blob_viewer/changelog_spec.rb | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 spec/models/blob_viewer/changelog_spec.rb (limited to 'spec') diff --git a/spec/models/blob_viewer/changelog_spec.rb b/spec/models/blob_viewer/changelog_spec.rb new file mode 100644 index 00000000000..9066c5a05ac --- /dev/null +++ b/spec/models/blob_viewer/changelog_spec.rb @@ -0,0 +1,27 @@ +require 'spec_helper' + +describe BlobViewer::Changelog, model: true do + include FakeBlobHelpers + + let(:project) { create(:project, :repository) } + let(:blob) { fake_blob(path: 'CHANGELOG') } + subject { described_class.new(blob) } + + describe '#render_error' do + context 'when there are no tags' do + before do + allow(project.repository).to receive(:tag_count).and_return(0) + end + + it 'returns :no_tags' do + expect(subject.render_error).to eq(:no_tags) + end + end + + context 'when there are tags' do + it 'returns nil' do + expect(subject.render_error).to be_nil + end + end + end +end -- cgit v1.2.1 From 24b105e2e1339fd65cc43727e550edb004277383 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 17 May 2017 11:27:30 -0500 Subject: Add auxiliary blob viewers to dependency files --- spec/features/projects/blobs/blob_show_spec.rb | 38 +++++++++++++++++++++++++- spec/models/blob_viewer/composer_json_spec.rb | 25 +++++++++++++++++ spec/models/blob_viewer/gemspec_spec.rb | 25 +++++++++++++++++ spec/models/blob_viewer/package_json_spec.rb | 25 +++++++++++++++++ spec/models/blob_viewer/podspec_json_spec.rb | 25 +++++++++++++++++ spec/models/blob_viewer/podspec_spec.rb | 25 +++++++++++++++++ 6 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 spec/models/blob_viewer/composer_json_spec.rb create mode 100644 spec/models/blob_viewer/gemspec_spec.rb create mode 100644 spec/models/blob_viewer/package_json_spec.rb create mode 100644 spec/models/blob_viewer/podspec_json_spec.rb create mode 100644 spec/models/blob_viewer/podspec_spec.rb (limited to 'spec') diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb index 9888624a509..c95003f3226 100644 --- a/spec/features/projects/blobs/blob_show_spec.rb +++ b/spec/features/projects/blobs/blob_show_spec.rb @@ -423,7 +423,43 @@ feature 'File blob', :js, feature: true do expect(page).to have_content('This project is licensed under the MIT License.') # shows a learn more link - expect(page).to have_link('Learn more about this license', 'http://choosealicense.com/licenses/mit/') + expect(page).to have_link('Learn more', 'http://choosealicense.com/licenses/mit/') + end + end + end + + context '*.gemspec' do + before do + project.add_master(project.creator) + + Files::CreateService.new( + project, + project.creator, + start_branch: 'master', + branch_name: 'master', + commit_message: "Add activerecord.gemspec", + file_path: 'activerecord.gemspec', + file_content: <<-SPEC.strip_heredoc + Gem::Specification.new do |s| + s.platform = Gem::Platform::RUBY + s.name = "activerecord" + end + SPEC + ).execute + + visit_blob('activerecord.gemspec') + end + + it 'displays an auxiliary viewer' do + aggregate_failures do + # shows license + expect(page).to have_content('This project manages its dependencies using RubyGems and defines a gem named activerecord.') + + # shows a link to the gem + expect(page).to have_link('activerecord', 'https://rubygems.org/gems/activerecord') + + # shows a learn more link + expect(page).to have_link('Learn more', 'http://choosealicense.com/licenses/mit/') end end end diff --git a/spec/models/blob_viewer/composer_json_spec.rb b/spec/models/blob_viewer/composer_json_spec.rb new file mode 100644 index 00000000000..df4f1f4815c --- /dev/null +++ b/spec/models/blob_viewer/composer_json_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe BlobViewer::ComposerJson, model: true do + include FakeBlobHelpers + + let(:project) { build(:project) } + let(:data) do + <<-SPEC.strip_heredoc + { + "name": "laravel/laravel", + "homepage": "https://laravel.com/" + } + SPEC + end + let(:blob) { fake_blob(path: 'composer.json', data: data) } + subject { described_class.new(blob) } + + describe '#package_name' do + it 'returns the package name' do + expect(subject).to receive(:prepare!) + + expect(subject.package_name).to eq('laravel/laravel') + end + end +end diff --git a/spec/models/blob_viewer/gemspec_spec.rb b/spec/models/blob_viewer/gemspec_spec.rb new file mode 100644 index 00000000000..81e932de290 --- /dev/null +++ b/spec/models/blob_viewer/gemspec_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe BlobViewer::Gemspec, model: true do + include FakeBlobHelpers + + let(:project) { build(:project) } + let(:data) do + <<-SPEC.strip_heredoc + Gem::Specification.new do |s| + s.platform = Gem::Platform::RUBY + s.name = "activerecord" + end + SPEC + end + let(:blob) { fake_blob(path: 'activerecord.gemspec', data: data) } + subject { described_class.new(blob) } + + describe '#package_name' do + it 'returns the package name' do + expect(subject).to receive(:prepare!) + + expect(subject.package_name).to eq('activerecord') + end + end +end diff --git a/spec/models/blob_viewer/package_json_spec.rb b/spec/models/blob_viewer/package_json_spec.rb new file mode 100644 index 00000000000..5c9a9c81963 --- /dev/null +++ b/spec/models/blob_viewer/package_json_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe BlobViewer::PackageJson, model: true do + include FakeBlobHelpers + + let(:project) { build(:project) } + let(:data) do + <<-SPEC.strip_heredoc + { + "name": "module-name", + "version": "10.3.1" + } + SPEC + end + let(:blob) { fake_blob(path: 'package.json', data: data) } + subject { described_class.new(blob) } + + describe '#package_name' do + it 'returns the package name' do + expect(subject).to receive(:prepare!) + + expect(subject.package_name).to eq('module-name') + end + end +end diff --git a/spec/models/blob_viewer/podspec_json_spec.rb b/spec/models/blob_viewer/podspec_json_spec.rb new file mode 100644 index 00000000000..42a00940bc5 --- /dev/null +++ b/spec/models/blob_viewer/podspec_json_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe BlobViewer::PodspecJson, model: true do + include FakeBlobHelpers + + let(:project) { build(:project) } + let(:data) do + <<-SPEC.strip_heredoc + { + "name": "AFNetworking", + "version": "2.0.0" + } + SPEC + end + let(:blob) { fake_blob(path: 'AFNetworking.podspec.json', data: data) } + subject { described_class.new(blob) } + + describe '#package_name' do + it 'returns the package name' do + expect(subject).to receive(:prepare!) + + expect(subject.package_name).to eq('AFNetworking') + end + end +end diff --git a/spec/models/blob_viewer/podspec_spec.rb b/spec/models/blob_viewer/podspec_spec.rb new file mode 100644 index 00000000000..6c9f0f42d53 --- /dev/null +++ b/spec/models/blob_viewer/podspec_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe BlobViewer::Podspec, model: true do + include FakeBlobHelpers + + let(:project) { build(:project) } + let(:data) do + <<-SPEC.strip_heredoc + Pod::Spec.new do |spec| + spec.name = 'Reachability' + spec.version = '3.1.0' + end + SPEC + end + let(:blob) { fake_blob(path: 'Reachability.podspec', data: data) } + subject { described_class.new(blob) } + + describe '#package_name' do + it 'returns the package name' do + expect(subject).to receive(:prepare!) + + expect(subject.package_name).to eq('Reachability') + end + end +end -- cgit v1.2.1 From 925945f01b1dcaf7b288afd7be53175a04eaecad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Fri, 17 Mar 2017 16:36:46 -0300 Subject: Incorporate Gitaly's local_branches operation into repo code --- spec/lib/gitlab/git/branch_spec.rb | 45 +++++++++++++++++++++++++++++++ spec/lib/gitlab/git/repository_spec.rb | 32 ++++++++++++++++++++-- spec/lib/gitlab/gitaly_client/ref_spec.rb | 30 +++++++++++++++++++++ spec/support/matchers/gitaly_matchers.rb | 6 +++++ 4 files changed, 111 insertions(+), 2 deletions(-) (limited to 'spec') diff --git a/spec/lib/gitlab/git/branch_spec.rb b/spec/lib/gitlab/git/branch_spec.rb index cdf1b8beee3..9eac7660cd1 100644 --- a/spec/lib/gitlab/git/branch_spec.rb +++ b/spec/lib/gitlab/git/branch_spec.rb @@ -7,6 +7,51 @@ describe Gitlab::Git::Branch, seed_helper: true do it { is_expected.to be_kind_of Array } + describe 'initialize' do + let(:commit_id) { 'f00' } + let(:commit_subject) { "My commit".force_encoding('ASCII-8BIT') } + let(:committer) do + Gitaly::FindLocalBranchCommitAuthor.new( + name: generate(:name), + email: generate(:email), + date: Google::Protobuf::Timestamp.new(seconds: 123) + ) + end + let(:author) do + Gitaly::FindLocalBranchCommitAuthor.new( + name: generate(:name), + email: generate(:email), + date: Google::Protobuf::Timestamp.new(seconds: 456) + ) + end + let(:gitaly_branch) do + Gitaly::FindLocalBranchResponse.new( + name: 'foo', commit_id: commit_id, commit_subject: commit_subject, + commit_author: author, commit_committer: committer + ) + end + let(:attributes) do + { + id: commit_id, + message: commit_subject, + authored_date: Time.at(author.date.seconds), + author_name: author.name, + author_email: author.email, + committed_date: Time.at(committer.date.seconds), + committer_name: committer.name, + committer_email: committer.email + } + end + let(:branch) { described_class.new(repository, 'foo', gitaly_branch) } + + it 'parses Gitaly::FindLocalBranchResponse correctly' do + expect(Gitlab::Git::Commit).to receive(:decorate). + with(hash_including(attributes)).and_call_original + + expect(branch.dereferenced_target.message.encoding).to be(Encoding::UTF_8) + end + end + describe '#size' do subject { super().size } it { is_expected.to eq(SeedRepo::Repo::BRANCHES.size) } diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index fea186fd4f4..3506ba15506 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -26,6 +26,7 @@ describe Gitlab::Git::Repository, seed_helper: true do context 'with gitaly enabled' do before { stub_gitaly } + after { Gitlab::GitalyClient.clear_stubs! } it 'gets the branch name from GitalyClient' do expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name) @@ -120,6 +121,7 @@ describe Gitlab::Git::Repository, seed_helper: true do context 'with gitaly enabled' do before { stub_gitaly } + after { Gitlab::GitalyClient.clear_stubs! } it 'gets the branch names from GitalyClient' do expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names) @@ -157,6 +159,7 @@ describe Gitlab::Git::Repository, seed_helper: true do context 'with gitaly enabled' do before { stub_gitaly } + after { Gitlab::GitalyClient.clear_stubs! } it 'gets the tag names from GitalyClient' do expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names) @@ -1080,7 +1083,9 @@ describe Gitlab::Git::Repository, seed_helper: true do ref = double() allow(ref).to receive(:name) { 'bad-branch' } allow(ref).to receive(:target) { raise Rugged::ReferenceError } - allow(repository.rugged).to receive(:branches) { [ref] } + branches = double() + allow(branches).to receive(:each) { [ref].each } + allow(repository.rugged).to receive(:branches) { branches } end it 'should return empty branches' do @@ -1264,7 +1269,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe '#local_branches' do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git')) end after(:all) do @@ -1279,6 +1284,29 @@ describe Gitlab::Git::Repository, seed_helper: true do expect(@repo.local_branches.any? { |branch| branch.name == 'remote_branch' }).to eq(false) expect(@repo.local_branches.any? { |branch| branch.name == 'local_branch' }).to eq(true) end + + context 'with gitaly enabled' do + before { stub_gitaly } + after { Gitlab::GitalyClient.clear_stubs! } + + it 'gets the branches from GitalyClient' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches). + and_return([]) + @repo.local_branches + end + + it 'wraps GRPC not found' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches). + and_raise(GRPC::NotFound) + expect { @repo.local_branches }.to raise_error(Gitlab::Git::Repository::NoRepository) + end + + it 'wraps GRPC exceptions' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches). + and_raise(GRPC::Unknown) + expect { @repo.local_branches }.to raise_error(Gitlab::Git::CommandError) + end + end end def create_remote_branch(remote_name, branch_name, source_branch_name) diff --git a/spec/lib/gitlab/gitaly_client/ref_spec.rb b/spec/lib/gitlab/gitaly_client/ref_spec.rb index 255f23e6270..d8cd2dcbd2a 100644 --- a/spec/lib/gitlab/gitaly_client/ref_spec.rb +++ b/spec/lib/gitlab/gitaly_client/ref_spec.rb @@ -9,6 +9,13 @@ describe Gitlab::GitalyClient::Ref do allow(Gitlab.config.gitaly).to receive(:enabled).and_return(true) end + after do + # When we say `expect_any_instance_of(Gitaly::Ref::Stub)` a double is created, + # and because GitalyClient shares stubs these will get passed from example to + # example, which will cause an error, so we clean the stubs after each example. + Gitlab::GitalyClient.clear_stubs! + end + describe '#branch_names' do it 'sends a find_all_branch_names message' do expect_any_instance_of(Gitaly::Ref::Stub). @@ -38,4 +45,27 @@ describe Gitlab::GitalyClient::Ref do client.default_branch_name end end + + describe '#local_branches' do + it 'sends a find_local_branches message' do + expect_any_instance_of(Gitaly::Ref::Stub). + to receive(:find_local_branches).with(gitaly_request_with_repo_path(repo_path)). + and_return([]) + + client.local_branches + end + + it 'parses and sends the sort parameter' do + expect_any_instance_of(Gitaly::Ref::Stub). + to receive(:find_local_branches). + with(gitaly_request_with_params(sort_by: :UPDATED_DESC)). + and_return([]) + + client.local_branches(sort_by: 'updated_desc') + end + + it 'raises an argument error if an invalid sort_by parameter is passed' do + expect { client.local_branches(sort_by: 'invalid_sort') }.to raise_error(ArgumentError) + end + end end diff --git a/spec/support/matchers/gitaly_matchers.rb b/spec/support/matchers/gitaly_matchers.rb index 65dbc01f6e4..ed14bcec9f2 100644 --- a/spec/support/matchers/gitaly_matchers.rb +++ b/spec/support/matchers/gitaly_matchers.rb @@ -1,3 +1,9 @@ RSpec::Matchers.define :gitaly_request_with_repo_path do |path| match { |actual| actual.repository.path == path } end + +RSpec::Matchers.define :gitaly_request_with_params do |params| + match do |actual| + params.reduce(true) { |r, (key, val)| r && actual.send(key) == val } + end +end -- cgit v1.2.1 From 8d4cc9cbe07d96ee34dd2559e34b38b712c3b3b4 Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Wed, 17 May 2017 17:01:19 -0700 Subject: Fixes #32474 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Older namespace records may be both `type == ‘Group` AND `owner_id` is not null. --- spec/models/user_spec.rb | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'spec') diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index e6e7774431e..6a15830a15c 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -929,10 +929,20 @@ describe User, models: true do end context 'with a group route matching the given path' do - let!(:group) { create(:group, path: 'group_path') } + context 'when the group namespace has an owner_id (legacy data)' do + let!(:group) { create(:group, path: 'group_path', owner: user) } - it 'returns nil' do - expect(User.find_by_full_path('group_path')).to eq(nil) + it 'returns nil' do + expect(User.find_by_full_path('group_path')).to eq(nil) + end + end + + context 'when the group namespace does not have an owner_id' do + let!(:group) { create(:group, path: 'group_path') } + + it 'returns nil' do + expect(User.find_by_full_path('group_path')).to eq(nil) + end end end end -- cgit v1.2.1 From 027ad1381e509236b789c58ee7b3d057dd5517b5 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Wed, 17 May 2017 14:58:47 -0500 Subject: Fix linking to unresolved/expanded diff note Fix https://gitlab.com/gitlab-org/gitlab-ce/issues/32424 Bug introduced in https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/11327 --- spec/features/merge_requests/diffs_spec.rb | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'spec') diff --git a/spec/features/merge_requests/diffs_spec.rb b/spec/features/merge_requests/diffs_spec.rb index 7dee3b852ca..4860a2a7498 100644 --- a/spec/features/merge_requests/diffs_spec.rb +++ b/spec/features/merge_requests/diffs_spec.rb @@ -20,6 +20,34 @@ feature 'Diffs URL', js: true, feature: true do end end + context 'when linking to note' do + describe 'with unresolved note' do + let(:note) { create :diff_note_on_merge_request, project: project, noteable: merge_request } + let(:fragment) { "#note_#{note.id}" } + + before do + visit "#{diffs_namespace_project_merge_request_path(project.namespace, project, merge_request)}#{fragment}" + end + + it 'shows expanded note' do + expect(page).to have_selector(fragment, visible: true) + end + end + + describe 'with resolved note' do + let(:note) { create :diff_note_on_merge_request, :resolved, project: project, noteable: merge_request } + let(:fragment) { "#note_#{note.id}" } + + before do + visit "#{diffs_namespace_project_merge_request_path(project.namespace, project, merge_request)}#{fragment}" + end + + it 'shows expanded note' do + expect(page).to have_selector(fragment, visible: true) + end + end + end + context 'when merge request has overflow' do it 'displays warning' do allow(Commit).to receive(:max_diff_options).and_return(max_files: 3) -- cgit v1.2.1 From f21a31559031c283cbc9cf99a11e98fa519ca0e5 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Thu, 18 May 2017 02:46:44 -0500 Subject: Fix missing .original-note-content and trailing new line edge case Fix https://gitlab.com/gitlab-org/gitlab-ce/issues/32449 --- spec/features/issues/note_polling_spec.rb | 101 ++++++++++++++++++++---------- spec/javascripts/notes_spec.js | 60 +++++++++++++++--- 2 files changed, 120 insertions(+), 41 deletions(-) (limited to 'spec') diff --git a/spec/features/issues/note_polling_spec.rb b/spec/features/issues/note_polling_spec.rb index 58b3215f14c..da81fa4e367 100644 --- a/spec/features/issues/note_polling_spec.rb +++ b/spec/features/issues/note_polling_spec.rb @@ -18,58 +18,93 @@ feature 'Issue notes polling', :feature, :js do end describe 'updates' do - let(:user) { create(:user) } - let(:note_text) { "Hello World" } - let(:updated_text) { "Bye World" } - let!(:existing_note) { create(:note, noteable: issue, project: project, author: user, note: note_text) } + context 'when from own user' do + let(:user) { create(:user) } + let(:note_text) { "Hello World" } + let(:updated_text) { "Bye World" } + let!(:existing_note) { create(:note, noteable: issue, project: project, author: user, note: note_text) } - before do - login_as(user) - visit namespace_project_issue_path(project.namespace, project, issue) - end + before do + login_as(user) + visit namespace_project_issue_path(project.namespace, project, issue) + end - it 'displays the updated content' do - expect(page).to have_selector("#note_#{existing_note.id}", text: note_text) + it 'has .original-note-content to compare against' do + expect(page).to have_selector("#note_#{existing_note.id}", text: note_text) + expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", visible: false) - update_note(existing_note, updated_text) + update_note(existing_note, updated_text) - expect(page).to have_selector("#note_#{existing_note.id}", text: updated_text) - end + expect(page).to have_selector("#note_#{existing_note.id}", text: updated_text) + expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", visible: false) + end - it 'when editing but have not changed anything, and an update comes in, show the updated content in the textarea' do - find("#note_#{existing_note.id} .js-note-edit").click + it 'displays the updated content' do + expect(page).to have_selector("#note_#{existing_note.id}", text: note_text) - expect(page).to have_field("note[note]", with: note_text) + update_note(existing_note, updated_text) - update_note(existing_note, updated_text) + expect(page).to have_selector("#note_#{existing_note.id}", text: updated_text) + end - expect(page).to have_field("note[note]", with: updated_text) - end + it 'when editing but have not changed anything, and an update comes in, show the updated content in the textarea' do + find("#note_#{existing_note.id} .js-note-edit").click - it 'when editing but you changed some things, and an update comes in, show a warning' do - find("#note_#{existing_note.id} .js-note-edit").click + expect(page).to have_field("note[note]", with: note_text) - expect(page).to have_field("note[note]", with: note_text) + update_note(existing_note, updated_text) - find("#note_#{existing_note.id} .js-note-text").set('something random') + expect(page).to have_field("note[note]", with: updated_text) + end - update_note(existing_note, updated_text) + it 'when editing but you changed some things, and an update comes in, show a warning' do + find("#note_#{existing_note.id} .js-note-edit").click - expect(page).to have_selector(".alert") - end + expect(page).to have_field("note[note]", with: note_text) + + find("#note_#{existing_note.id} .js-note-text").set('something random') + + update_note(existing_note, updated_text) - it 'when editing but you changed some things, an update comes in, and you press cancel, show the updated content' do - find("#note_#{existing_note.id} .js-note-edit").click + expect(page).to have_selector(".alert") + end + + it 'when editing but you changed some things, an update comes in, and you press cancel, show the updated content' do + find("#note_#{existing_note.id} .js-note-edit").click + + expect(page).to have_field("note[note]", with: note_text) + + find("#note_#{existing_note.id} .js-note-text").set('something random') + + update_note(existing_note, updated_text) + + find("#note_#{existing_note.id} .note-edit-cancel").click + + expect(page).to have_selector("#note_#{existing_note.id}", text: updated_text) + end + end - expect(page).to have_field("note[note]", with: note_text) + context 'when from another user' do + let(:user1) { create(:user) } + let(:user2) { create(:user) } + let(:note_text) { "Hello World" } + let(:updated_text) { "Bye World" } + let!(:existing_note) { create(:note, noteable: issue, project: project, author: user1, note: note_text) } - find("#note_#{existing_note.id} .js-note-text").set('something random') + before do + login_as(user2) + visit namespace_project_issue_path(project.namespace, project, issue) + end - update_note(existing_note, updated_text) + it 'has .original-note-content to compare against' do + expect(page).to have_selector("#note_#{existing_note.id}", text: note_text) + expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", visible: false) - find("#note_#{existing_note.id} .note-edit-cancel").click + update_note(existing_note, updated_text) - expect(page).to have_selector("#note_#{existing_note.id}", text: updated_text) + expect(page).to have_selector("#note_#{existing_note.id}", text: updated_text) + expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", visible: false) + end end end diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js index 87745ea9817..7f12dea5277 100644 --- a/spec/javascripts/notes_spec.js +++ b/spec/javascripts/notes_spec.js @@ -99,8 +99,6 @@ import '~/notes'; notes = jasmine.createSpyObj('notes', [ 'refresh', - 'isNewNote', - 'isUpdatedNote', 'collapseLongCommitList', 'updateNotesCount', 'putConflictEditWarningInPlace' @@ -110,13 +108,15 @@ import '~/notes'; notes.updatedNotesTrackingMap = {}; spyOn(gl.utils, 'localTimeAgo'); + spyOn(Notes, 'isNewNote').and.callThrough(); + spyOn(Notes, 'isUpdatedNote').and.callThrough(); spyOn(Notes, 'animateAppendNote').and.callThrough(); spyOn(Notes, 'animateUpdateNote').and.callThrough(); }); describe('when adding note', () => { it('should call .animateAppendNote', () => { - notes.isNewNote.and.returnValue(true); + Notes.isNewNote.and.returnValue(true); Notes.prototype.renderNote.call(notes, note, null, $notesList); expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, $notesList); @@ -125,7 +125,8 @@ import '~/notes'; describe('when note was edited', () => { it('should call .animateUpdateNote', () => { - notes.isUpdatedNote.and.returnValue(true); + Notes.isNewNote.and.returnValue(false); + Notes.isUpdatedNote.and.returnValue(true); const $note = $('
'); $notesList.find.and.returnValue($note); Notes.prototype.renderNote.call(notes, note, null, $notesList); @@ -135,7 +136,8 @@ import '~/notes'; describe('while editing', () => { it('should update textarea if nothing has been touched', () => { - notes.isUpdatedNote.and.returnValue(true); + Notes.isNewNote.and.returnValue(false); + Notes.isUpdatedNote.and.returnValue(true); const $note = $(`
initial
@@ -147,7 +149,8 @@ import '~/notes'; }); it('should call .putConflictEditWarningInPlace', () => { - notes.isUpdatedNote.and.returnValue(true); + Notes.isNewNote.and.returnValue(false); + Notes.isUpdatedNote.and.returnValue(true); const $note = $(`
initial
@@ -161,6 +164,47 @@ import '~/notes'; }); }); + describe('isUpdatedNote', () => { + it('should consider same note text as the same', () => { + const result = Notes.isUpdatedNote( + { + note: 'initial' + }, + $(`
+
initial
+
`) + ); + + expect(result).toEqual(false); + }); + + it('should consider same note with trailing newline as the same', () => { + const result = Notes.isUpdatedNote( + { + note: 'initial\n' + }, + $(`
+
initial\n
+
`) + ); + + expect(result).toEqual(false); + }); + + it('should consider different notes as different', () => { + const result = Notes.isUpdatedNote( + { + note: 'foo' + }, + $(`
+
bar
+
`) + ); + + expect(result).toEqual(true); + }); + }); + describe('renderDiscussionNote', () => { let discussionContainer; let note; @@ -180,15 +224,15 @@ import '~/notes'; row = jasmine.createSpyObj('row', ['prevAll', 'first', 'find']); notes = jasmine.createSpyObj('notes', [ - 'isNewNote', 'isParallelView', 'updateNotesCount', ]); notes.note_ids = []; spyOn(gl.utils, 'localTimeAgo'); + spyOn(Notes, 'isNewNote'); spyOn(Notes, 'animateAppendNote'); - notes.isNewNote.and.returnValue(true); + Notes.isNewNote.and.returnValue(true); notes.isParallelView.and.returnValue(false); row.prevAll.and.returnValue(row); row.first.and.returnValue(row); -- cgit v1.2.1 From 628cc84891228895daa19d7b1300fc032cb26910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Wed, 10 May 2017 17:19:48 +0200 Subject: Factorize TestEvent#copy_repo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- spec/factories/projects.rb | 2 +- spec/support/test_env.rb | 15 +++------------ 2 files changed, 4 insertions(+), 13 deletions(-) (limited to 'spec') diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 3580752a805..357ea6b3f7f 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -172,7 +172,7 @@ FactoryGirl.define do path { 'forked-gitlabhq' } after :create do |project| - TestEnv.copy_forked_repo_with_submodules(project) + TestEnv.copy_repo(project, copy_fork: true) end end diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb index 9bf9dc5d4b2..f319c9634e3 100644 --- a/spec/support/test_env.rb +++ b/spec/support/test_env.rb @@ -170,13 +170,13 @@ module TestEnv end end - def copy_repo(project) - base_repo_path = File.expand_path(factory_repo_path_bare) + def copy_repo(project, copy_fork: false) + base_repo_path = File.expand_path(copy_fork ? forked_repo_path_bare : factory_repo_path_bare) target_repo_path = File.expand_path(project.repository_storage_path + "/#{project.full_path}.git") FileUtils.mkdir_p(target_repo_path) FileUtils.cp_r("#{base_repo_path}/.", target_repo_path) FileUtils.chmod_R 0755, target_repo_path - set_repo_refs(target_repo_path, BRANCH_SHA) + set_repo_refs(target_repo_path, copy_fork ? FORKED_BRANCH_SHA : BRANCH_SHA) end def repos_path @@ -191,15 +191,6 @@ module TestEnv Gitlab.config.pages.path end - def copy_forked_repo_with_submodules(project) - base_repo_path = File.expand_path(forked_repo_path_bare) - target_repo_path = File.expand_path(project.repository_storage_path + "/#{project.full_path}.git") - FileUtils.mkdir_p(target_repo_path) - FileUtils.cp_r("#{base_repo_path}/.", target_repo_path) - FileUtils.chmod_R 0755, target_repo_path - set_repo_refs(target_repo_path, FORKED_BRANCH_SHA) - end - # When no cached assets exist, manually hit the root path to create them # # Otherwise they'd be created by the first test, often timing out and -- cgit v1.2.1 From 7e56ac8f434a327282401796ffd43a46eb08e94c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Wed, 10 May 2017 17:31:50 +0200 Subject: If TestEnv#set_repo_refs fails, clean test repos and retry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sometimes, new references are not retrieved when a `git fetch` is called in a bare repos. The easiest solution is to cleanup the test repos and retry in this case. This only happens when a new ref is added to TestEnv::BRANCH_SHA or TestEnv::FORKED_BRANCH_SHA. Signed-off-by: Rémy Coutable --- spec/factories/projects.rb | 12 +++++++++--- spec/support/test_env.rb | 48 ++++++++++++++++++++++++---------------------- 2 files changed, 34 insertions(+), 26 deletions(-) (limited to 'spec') diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 357ea6b3f7f..7a76f5f8afc 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -60,7 +60,9 @@ FactoryGirl.define do trait :test_repo do after :create do |project| - TestEnv.copy_repo(project) + TestEnv.copy_repo(project, + bare_repo: TestEnv.factory_repo_path_bare, + refs: TestEnv::BRANCH_SHA) end end @@ -139,7 +141,9 @@ FactoryGirl.define do end after :create do |project, evaluator| - TestEnv.copy_repo(project) + TestEnv.copy_repo(project, + bare_repo: TestEnv.factory_repo_path_bare, + refs: TestEnv::BRANCH_SHA) if evaluator.create_template args = evaluator.create_template @@ -172,7 +176,9 @@ FactoryGirl.define do path { 'forked-gitlabhq' } after :create do |project| - TestEnv.copy_repo(project, copy_fork: true) + TestEnv.copy_repo(project, + bare_repo: TestEnv.forked_repo_path_bare, + refs: TestEnv::FORKED_BRANCH_SHA) end end diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb index f319c9634e3..d53edb36138 100644 --- a/spec/support/test_env.rb +++ b/spec/support/test_env.rb @@ -155,14 +155,14 @@ module TestEnv FORKED_BRANCH_SHA) end - def setup_repo(repo_path, repo_path_bare, repo_name, branch_sha) + def setup_repo(repo_path, repo_path_bare, repo_name, refs) clone_url = "https://gitlab.com/gitlab-org/#{repo_name}.git" unless File.directory?(repo_path) system(*%W(#{Gitlab.config.git.bin_path} clone -q #{clone_url} #{repo_path})) end - set_repo_refs(repo_path, branch_sha) + set_repo_refs(repo_path, refs) unless File.directory?(repo_path_bare) # We must copy bare repositories because we will push to them. @@ -170,13 +170,12 @@ module TestEnv end end - def copy_repo(project, copy_fork: false) - base_repo_path = File.expand_path(copy_fork ? forked_repo_path_bare : factory_repo_path_bare) + def copy_repo(project, bare_repo:, refs:) target_repo_path = File.expand_path(project.repository_storage_path + "/#{project.full_path}.git") FileUtils.mkdir_p(target_repo_path) - FileUtils.cp_r("#{base_repo_path}/.", target_repo_path) + FileUtils.cp_r("#{File.expand_path(bare_repo)}/.", target_repo_path) FileUtils.chmod_R 0755, target_repo_path - set_repo_refs(target_repo_path, copy_fork ? FORKED_BRANCH_SHA : BRANCH_SHA) + set_repo_refs(target_repo_path, refs) end def repos_path @@ -202,16 +201,20 @@ module TestEnv Capybara.current_session.visit '/' end + def factory_repo_path_bare + "#{factory_repo_path}_bare" + end + + def forked_repo_path_bare + "#{forked_repo_path}_bare" + end + private def factory_repo_path @factory_repo_path ||= Rails.root.join('tmp', 'tests', factory_repo_name) end - def factory_repo_path_bare - "#{factory_repo_path}_bare" - end - def factory_repo_name 'gitlab-test' end @@ -220,10 +223,6 @@ module TestEnv @forked_repo_path ||= Rails.root.join('tmp', 'tests', forked_repo_name) end - def forked_repo_path_bare - "#{forked_repo_path}_bare" - end - def forked_repo_name 'gitlab-test-fork' end @@ -235,19 +234,22 @@ module TestEnv end def set_repo_refs(repo_path, branch_sha) - instructions = branch_sha.map {|branch, sha| "update refs/heads/#{branch}\x00#{sha}\x00" }.join("\x00") << "\x00" + instructions = branch_sha.map { |branch, sha| "update refs/heads/#{branch}\x00#{sha}\x00" }.join("\x00") << "\x00" update_refs = %W(#{Gitlab.config.git.bin_path} update-ref --stdin -z) reset = proc do - IO.popen(update_refs, "w") {|io| io.write(instructions) } - $?.success? + Dir.chdir(repo_path) do + IO.popen(update_refs, "w") { |io| io.write(instructions) } + $?.success? + end end - Dir.chdir(repo_path) do - # Try to reset without fetching to avoid using the network. - unless reset.call - raise 'Could not fetch test seed repository.' unless system(*%W(#{Gitlab.config.git.bin_path} fetch origin)) - raise 'The fetched test seed does not contain the required revision.' unless reset.call - end + # Try to reset without fetching to avoid using the network. + unless reset.call + raise 'Could not fetch test seed repository.' unless system(*%W(#{Gitlab.config.git.bin_path} -C #{repo_path} fetch origin)) + + # Before we used Git clone's --mirror option, bare repos could end up + # with missing refs, clearing them and retrying should fix the issue. + cleanup && init unless reset.call end end end -- cgit v1.2.1 From ba441bb6f48d8d01d60a88ca5407f38eea4a58e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Wed, 10 May 2017 17:33:50 +0200 Subject: Shorten the last two commit SHA, because CONSISTENCY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- spec/support/test_env.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'spec') diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb index d53edb36138..b168098edea 100644 --- a/spec/support/test_env.rb +++ b/spec/support/test_env.rb @@ -40,8 +40,8 @@ module TestEnv 'wip' => 'b9238ee', 'csv' => '3dd0896', 'v1.1.0' => 'b83d6e3', - 'add-ipython-files' => '6d85bb69', - 'add-pdf-file' => 'e774ebd3' + 'add-ipython-files' => '6d85bb6', + 'add-pdf-file' => 'e774ebd' }.freeze # gitlab-test-fork is a fork of gitlab-fork, but we don't necessarily -- cgit v1.2.1 From ed86faebe1de0d7bb364341f8a36b4aac0757d0c Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Thu, 18 May 2017 16:18:26 +0300 Subject: Fix: Deleting an invited member causes 500 error --- spec/factories/group_members.rb | 6 ++++++ spec/factories/project_members.rb | 6 ++++++ .../members/authorized_destroy_service_spec.rb | 21 +++++++++++++++++++++ 3 files changed, 33 insertions(+) (limited to 'spec') diff --git a/spec/factories/group_members.rb b/spec/factories/group_members.rb index 080b2e75ea1..32cbfe28a60 100644 --- a/spec/factories/group_members.rb +++ b/spec/factories/group_members.rb @@ -10,5 +10,11 @@ FactoryGirl.define do trait(:master) { access_level GroupMember::MASTER } trait(:owner) { access_level GroupMember::OWNER } trait(:access_request) { requested_at Time.now } + + trait(:invited) do + user_id nil + invite_token 'xxx' + invite_email 'email@email.com' + end end end diff --git a/spec/factories/project_members.rb b/spec/factories/project_members.rb index d62799a5a47..fe4518caadf 100644 --- a/spec/factories/project_members.rb +++ b/spec/factories/project_members.rb @@ -9,5 +9,11 @@ FactoryGirl.define do trait(:developer) { access_level ProjectMember::DEVELOPER } trait(:master) { access_level ProjectMember::MASTER } trait(:access_request) { requested_at Time.now } + + trait(:invited) do + user_id nil + invite_token 'xxx' + invite_email 'email@email.com' + end end end diff --git a/spec/services/members/authorized_destroy_service_spec.rb b/spec/services/members/authorized_destroy_service_spec.rb index ab440d18e9f..8a6732faa19 100644 --- a/spec/services/members/authorized_destroy_service_spec.rb +++ b/spec/services/members/authorized_destroy_service_spec.rb @@ -10,6 +10,27 @@ describe Members::AuthorizedDestroyService, services: true do Issue.assigned_to(user).count + MergeRequest.assigned_to(user).count end + context 'Invited users' do + # Regression spec for issue: https://gitlab.com/gitlab-org/gitlab-ce/issues/32504 + it 'destroys invited project member' do + project.team << [member_user, :developer] + + member = create :project_member, :invited, project: project + + expect { described_class.new(member, member_user).execute } + .to change { Member.count }.from(2).to(1) + end + + it 'destroys invited group member' do + group.add_developer(member_user) + + member = create :group_member, :invited, group: group + + expect { described_class.new(member, member_user).execute } + .to change { Member.count }.from(2).to(1) + end + end + context 'Group member' do it "unassigns issues and merge requests" do group.add_developer(member_user) -- cgit v1.2.1 From 1ede99571b1d65c146757267e8104ecbc026f6ff Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 18 May 2017 09:11:23 -0500 Subject: Fix inaccurate code comment --- spec/features/projects/blobs/blob_show_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb index c95003f3226..fc242082278 100644 --- a/spec/features/projects/blobs/blob_show_spec.rb +++ b/spec/features/projects/blobs/blob_show_spec.rb @@ -452,7 +452,7 @@ feature 'File blob', :js, feature: true do it 'displays an auxiliary viewer' do aggregate_failures do - # shows license + # shows names of dependency manager and package expect(page).to have_content('This project manages its dependencies using RubyGems and defines a gem named activerecord.') # shows a link to the gem -- cgit v1.2.1 From 110f5a16547865156c5cae10d0d6171dab442029 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 18 May 2017 10:47:18 -0500 Subject: Catch all URI errors in ExternalLinkFilter --- spec/lib/banzai/filter/external_link_filter_spec.rb | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'spec') diff --git a/spec/lib/banzai/filter/external_link_filter_spec.rb b/spec/lib/banzai/filter/external_link_filter_spec.rb index 6f6c215be87..0f8ec8de7a0 100644 --- a/spec/lib/banzai/filter/external_link_filter_spec.rb +++ b/spec/lib/banzai/filter/external_link_filter_spec.rb @@ -55,6 +55,13 @@ describe Banzai::Filter::ExternalLinkFilter, lib: true do expect(doc.to_html).to eq(expected) end + + it 'skips improperly formatted mailtos' do + doc = filter %q(

Email

) + expected = %q(

Email

) + + expect(doc.to_html).to eq(expected) + end end context 'for links with a username' do -- cgit v1.2.1 From d900f19dfa15073e43150f9fab6495ad09ca6f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Thu, 18 May 2017 18:25:50 +0200 Subject: Enable the RSpec/EmptyExampleGroup cop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- spec/features/issues_spec.rb | 16 ---------------- spec/models/project_snippet_spec.rb | 3 --- spec/models/protected_branch_spec.rb | 3 --- spec/routing/routing_spec.rb | 37 ++++++++++++++++++++++++++---------- 4 files changed, 27 insertions(+), 32 deletions(-) (limited to 'spec') diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index da369a6f111..06ed2dbac64 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -30,13 +30,6 @@ describe 'Issues', feature: true do it 'opens new issue popup' do expect(page).to have_content("Issue ##{issue.iid}") end - - describe 'fill in' do - before do - fill_in 'issue_title', with: 'bug 345' - fill_in 'issue_description', with: 'bug description' - end - end end describe 'Editing issue assignee' do @@ -557,15 +550,6 @@ describe 'Issues', feature: true do expect(page).to have_content milestone.title end end - - describe 'removing assignee' do - let(:user2) { create(:user) } - - before do - issue.assignees << user2 - issue.save - end - end end describe 'new issue' do diff --git a/spec/models/project_snippet_spec.rb b/spec/models/project_snippet_spec.rb index d9d7c0b0aaa..5fe4885eeb4 100644 --- a/spec/models/project_snippet_spec.rb +++ b/spec/models/project_snippet_spec.rb @@ -5,9 +5,6 @@ describe ProjectSnippet, models: true do it { is_expected.to belong_to(:project) } end - describe "Mass assignment" do - end - describe "Validation" do it { is_expected.to validate_presence_of(:project) } end diff --git a/spec/models/protected_branch_spec.rb b/spec/models/protected_branch_spec.rb index 179a443c43d..ca347cf92c9 100644 --- a/spec/models/protected_branch_spec.rb +++ b/spec/models/protected_branch_spec.rb @@ -7,9 +7,6 @@ describe ProtectedBranch, models: true do it { is_expected.to belong_to(:project) } end - describe "Mass assignment" do - end - describe 'Validation' do it { is_expected.to validate_presence_of(:project) } it { is_expected.to validate_presence_of(:name) } diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb index 9f6defe1450..abacc50a371 100644 --- a/spec/routing/routing_spec.rb +++ b/spec/routing/routing_spec.rb @@ -249,17 +249,34 @@ describe RootController, 'routing' do end end -# new_user_session GET /users/sign_in(.:format) devise/sessions#new -# user_session POST /users/sign_in(.:format) devise/sessions#create -# destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy -# user_omniauth_authorize /users/auth/:provider(.:format) omniauth_callbacks#passthru -# user_omniauth_callback /users/auth/:action/callback(.:format) omniauth_callbacks#(?-mix:(?!)) -# user_password POST /users/password(.:format) devise/passwords#create -# new_user_password GET /users/password/new(.:format) devise/passwords#new -# edit_user_password GET /users/password/edit(.:format) devise/passwords#edit -# PUT /users/password(.:format) devise/passwords#update describe "Authentication", "routing" do - # pending + it "GET /users/sign_in" do + expect(get("/users/sign_in")).to route_to('sessions#new') + end + + it "POST /users/sign_in" do + expect(post("/users/sign_in")).to route_to('sessions#create') + end + + it "DELETE /users/sign_out" do + expect(delete("/users/sign_out")).to route_to('sessions#destroy') + end + + it "POST /users/password" do + expect(post("/users/password")).to route_to('passwords#create') + end + + it "GET /users/password/new" do + expect(get("/users/password/new")).to route_to('passwords#new') + end + + it "GET /users/password/edit" do + expect(get("/users/password/edit")).to route_to('passwords#edit') + end + + it "PUT /users/password" do + expect(put("/users/password")).to route_to('passwords#update') + end end describe "Groups", "routing" do -- cgit v1.2.1 From 3396edcea054f97c41b334b2800760817a47ba0a Mon Sep 17 00:00:00 2001 From: Ruben Davila Date: Thu, 18 May 2017 11:49:11 -0500 Subject: Remove Services count from usage ping payload. This query was timing out and is blocking the sync of usage data for GitLab.com --- spec/lib/gitlab/usage_data_spec.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'spec') diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index 2c46920456b..b47e1b56fa9 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -50,7 +50,6 @@ describe Gitlab::UsageData do pages_domains protected_branches releases - services snippets todos uploads -- cgit v1.2.1 From bdf5b6adc34ae2856bddea62ce449fa452aee761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Thu, 18 May 2017 18:56:26 +0200 Subject: Enable the RSpec/ExpectOutput cop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- spec/bin/changelog_spec.rb | 4 +--- spec/tasks/gitlab/gitaly_rake_spec.rb | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 14 deletions(-) (limited to 'spec') diff --git a/spec/bin/changelog_spec.rb b/spec/bin/changelog_spec.rb index 7f4298db59f..91aff0db7cc 100644 --- a/spec/bin/changelog_spec.rb +++ b/spec/bin/changelog_spec.rb @@ -46,9 +46,7 @@ describe 'bin/changelog' do it 'parses -h' do expect do - $stdout = StringIO.new - - described_class.parse(%w[foo -h bar]) + expect { described_class.parse(%w[foo -h bar]) }.to output.to_stdout end.to raise_error(SystemExit) end diff --git a/spec/tasks/gitlab/gitaly_rake_spec.rb b/spec/tasks/gitlab/gitaly_rake_spec.rb index f035504320b..4a636decafd 100644 --- a/spec/tasks/gitlab/gitaly_rake_spec.rb +++ b/spec/tasks/gitlab/gitaly_rake_spec.rb @@ -84,24 +84,24 @@ describe 'gitlab:gitaly namespace rake task' do } allow(Gitlab.config.repositories).to receive(:storages).and_return(config) - orig_stdout = $stdout - $stdout = StringIO.new - - header = '' + expected_output = '' Timecop.freeze do - header = <<~TOML + expected_output = <<~TOML # Gitaly storage configuration generated from #{Gitlab.config.source} on #{Time.current.to_s(:long)} # This is in TOML format suitable for use in Gitaly's config.toml file. + [[storage]] + name = "default" + path = "/path/to/default" + [[storage]] + name = "nfs_01" + path = "/path/to/nfs_01" TOML - run_rake_task('gitlab:gitaly:storage_config') end - output = $stdout.string - $stdout = orig_stdout - - expect(output).to include(header) + expect { run_rake_task('gitlab:gitaly:storage_config')}. + to output(expected_output).to_stdout - parsed_output = TOML.parse(output) + parsed_output = TOML.parse(expected_output) config.each do |name, params| expect(parsed_output['storage']).to include({ 'name' => name, 'path' => params['path'] }) end -- cgit v1.2.1 From 11f82de1efc087ee812764764e31161347e593cb Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Thu, 18 May 2017 10:30:17 -0700 Subject: Add test that fails without the fix --- spec/controllers/groups_controller_spec.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'spec') diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb index 15dae3231ca..0392315b62f 100644 --- a/spec/controllers/groups_controller_spec.rb +++ b/spec/controllers/groups_controller_spec.rb @@ -250,6 +250,19 @@ describe GroupsController do end end + describe 'ensure_canonical_path' do + context 'when the old group path is a substring of the scheme or host' do + let(:redirect_route) { group.redirect_routes.create(path: 'http') } + + it 'does not modify the requested host' do + get :issues, id: redirect_route.path + + expect(response).to redirect_to(issues_group_path(group.to_param)) + expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) + end + end + end + def group_moved_message(redirect_route, group) "Group '#{redirect_route.path}' was moved to '#{group.full_path}'. Please update any links and bookmarks that may still have the old path." end -- cgit v1.2.1 From 4b9c952d358b55aecd19fa3c3c6cedc91d823bba Mon Sep 17 00:00:00 2001 From: Kushal Pandya Date: Thu, 18 May 2017 18:05:01 +0000 Subject: Fix ability to edit diff notes multiple times --- spec/javascripts/notes_spec.js | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'spec') diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js index 7f12dea5277..d3494aaa94f 100644 --- a/spec/javascripts/notes_spec.js +++ b/spec/javascripts/notes_spec.js @@ -79,6 +79,47 @@ import '~/notes'; }); }); + describe('updateNote', () => { + let sampleComment; + let noteEntity; + let $form; + let $notesContainer; + + beforeEach(() => { + this.notes = new Notes('', []); + window.gon.current_username = 'root'; + window.gon.current_user_fullname = 'Administrator'; + sampleComment = 'foo'; + noteEntity = { + id: 1234, + html: `
  • +
    ${sampleComment}
    +
  • `, + note: sampleComment, + valid: true + }; + $form = $('form.js-main-target-form'); + $notesContainer = $('ul.main-notes-list'); + $form.find('textarea.js-note-text').val(sampleComment); + }); + + it('updates note and resets edit form', () => { + const deferred = $.Deferred(); + spyOn($, 'ajax').and.returnValue(deferred.promise()); + spyOn(this.notes, 'revertNoteEditForm'); + + $('.js-comment-button').click(); + deferred.resolve(noteEntity); + + const $targetNote = $notesContainer.find(`#note_${noteEntity.id}`); + const updatedNote = Object.assign({}, noteEntity); + updatedNote.note = 'bar'; + this.notes.updateNote(updatedNote, $targetNote); + + expect(this.notes.revertNoteEditForm).toHaveBeenCalledWith($targetNote); + }); + }); + describe('renderNote', () => { let notes; let note; -- cgit v1.2.1 From abc82a2508d102bb30789bce4a8b4ba56011683a Mon Sep 17 00:00:00 2001 From: Toon Claes Date: Thu, 18 May 2017 21:06:38 +0200 Subject: Fix ProjectCacheWorker for plain READMEs The ProjectCacheWorker refreshes cache periodically, but it runs outside Rails context. So include the ActionView helpers so the `content_tag` method is available. --- spec/workers/project_cache_worker_spec.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'spec') diff --git a/spec/workers/project_cache_worker_spec.rb b/spec/workers/project_cache_worker_spec.rb index c23ffdf99c0..a4ba5f7c943 100644 --- a/spec/workers/project_cache_worker_spec.rb +++ b/spec/workers/project_cache_worker_spec.rb @@ -45,6 +45,18 @@ describe ProjectCacheWorker do worker.perform(project.id, %w(readme)) end + + context 'with plain readme' do + it 'refreshes the method caches' do + allow(MarkupHelper).to receive(:gitlab_markdown?).and_return(false) + allow(MarkupHelper).to receive(:plain?).and_return(true) + + expect_any_instance_of(Repository).to receive(:refresh_method_caches). + with(%i(readme)). + and_call_original + worker.perform(project.id, %w(readme)) + end + end end end -- cgit v1.2.1 From de33a5bd535d6f4a1dc6cbdb2bd1b208ab6475e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Thu, 18 May 2017 15:33:43 -0400 Subject: Prevent errors from non-functional notify_post_receive endpoint --- spec/requests/api/internal_spec.rb | 161 +++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 80 deletions(-) (limited to 'spec') diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb index 2ceb4648ece..cf232e7ff69 100644 --- a/spec/requests/api/internal_spec.rb +++ b/spec/requests/api/internal_spec.rb @@ -466,86 +466,87 @@ describe API::Internal do end end - describe 'POST /notify_post_receive' do - let(:valid_params) do - { project: project.repository.path, secret_token: secret_token } - end - - let(:valid_wiki_params) do - { project: project.wiki.repository.path, secret_token: secret_token } - end - - before do - allow(Gitlab.config.gitaly).to receive(:enabled).and_return(true) - end - - it "calls the Gitaly client with the project's repository" do - expect(Gitlab::GitalyClient::Notifications). - to receive(:new).with(gitlab_git_repository_with(path: project.repository.path)). - and_call_original - expect_any_instance_of(Gitlab::GitalyClient::Notifications). - to receive(:post_receive) - - post api("/internal/notify_post_receive"), valid_params - - expect(response).to have_http_status(200) - end - - it "calls the Gitaly client with the wiki's repository if it's a wiki" do - expect(Gitlab::GitalyClient::Notifications). - to receive(:new).with(gitlab_git_repository_with(path: project.wiki.repository.path)). - and_call_original - expect_any_instance_of(Gitlab::GitalyClient::Notifications). - to receive(:post_receive) - - post api("/internal/notify_post_receive"), valid_wiki_params - - expect(response).to have_http_status(200) - end - - it "returns 500 if the gitaly call fails" do - expect_any_instance_of(Gitlab::GitalyClient::Notifications). - to receive(:post_receive).and_raise(GRPC::Unavailable) - - post api("/internal/notify_post_receive"), valid_params - - expect(response).to have_http_status(500) - end - - context 'with a gl_repository parameter' do - let(:valid_params) do - { gl_repository: "project-#{project.id}", secret_token: secret_token } - end - - let(:valid_wiki_params) do - { gl_repository: "wiki-#{project.id}", secret_token: secret_token } - end - - it "calls the Gitaly client with the project's repository" do - expect(Gitlab::GitalyClient::Notifications). - to receive(:new).with(gitlab_git_repository_with(path: project.repository.path)). - and_call_original - expect_any_instance_of(Gitlab::GitalyClient::Notifications). - to receive(:post_receive) - - post api("/internal/notify_post_receive"), valid_params - - expect(response).to have_http_status(200) - end - - it "calls the Gitaly client with the wiki's repository if it's a wiki" do - expect(Gitlab::GitalyClient::Notifications). - to receive(:new).with(gitlab_git_repository_with(path: project.wiki.repository.path)). - and_call_original - expect_any_instance_of(Gitlab::GitalyClient::Notifications). - to receive(:post_receive) - - post api("/internal/notify_post_receive"), valid_wiki_params - - expect(response).to have_http_status(200) - end - end - end + # TODO: Uncomment when the end-point is reenabled + # describe 'POST /notify_post_receive' do + # let(:valid_params) do + # { project: project.repository.path, secret_token: secret_token } + # end + # + # let(:valid_wiki_params) do + # { project: project.wiki.repository.path, secret_token: secret_token } + # end + # + # before do + # allow(Gitlab.config.gitaly).to receive(:enabled).and_return(true) + # end + # + # it "calls the Gitaly client with the project's repository" do + # expect(Gitlab::GitalyClient::Notifications). + # to receive(:new).with(gitlab_git_repository_with(path: project.repository.path)). + # and_call_original + # expect_any_instance_of(Gitlab::GitalyClient::Notifications). + # to receive(:post_receive) + # + # post api("/internal/notify_post_receive"), valid_params + # + # expect(response).to have_http_status(200) + # end + # + # it "calls the Gitaly client with the wiki's repository if it's a wiki" do + # expect(Gitlab::GitalyClient::Notifications). + # to receive(:new).with(gitlab_git_repository_with(path: project.wiki.repository.path)). + # and_call_original + # expect_any_instance_of(Gitlab::GitalyClient::Notifications). + # to receive(:post_receive) + # + # post api("/internal/notify_post_receive"), valid_wiki_params + # + # expect(response).to have_http_status(200) + # end + # + # it "returns 500 if the gitaly call fails" do + # expect_any_instance_of(Gitlab::GitalyClient::Notifications). + # to receive(:post_receive).and_raise(GRPC::Unavailable) + # + # post api("/internal/notify_post_receive"), valid_params + # + # expect(response).to have_http_status(500) + # end + # + # context 'with a gl_repository parameter' do + # let(:valid_params) do + # { gl_repository: "project-#{project.id}", secret_token: secret_token } + # end + # + # let(:valid_wiki_params) do + # { gl_repository: "wiki-#{project.id}", secret_token: secret_token } + # end + # + # it "calls the Gitaly client with the project's repository" do + # expect(Gitlab::GitalyClient::Notifications). + # to receive(:new).with(gitlab_git_repository_with(path: project.repository.path)). + # and_call_original + # expect_any_instance_of(Gitlab::GitalyClient::Notifications). + # to receive(:post_receive) + # + # post api("/internal/notify_post_receive"), valid_params + # + # expect(response).to have_http_status(200) + # end + # + # it "calls the Gitaly client with the wiki's repository if it's a wiki" do + # expect(Gitlab::GitalyClient::Notifications). + # to receive(:new).with(gitlab_git_repository_with(path: project.wiki.repository.path)). + # and_call_original + # expect_any_instance_of(Gitlab::GitalyClient::Notifications). + # to receive(:post_receive) + # + # post api("/internal/notify_post_receive"), valid_wiki_params + # + # expect(response).to have_http_status(200) + # end + # end + # end def project_with_repo_path(path) double().tap do |fake_project| -- cgit v1.2.1 From f62f0c258d89465bea514e5127ea1effdeb3b35d Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Thu, 18 May 2017 20:08:32 +0000 Subject: Fixes for the rename reserved paths helpers --- .../v1/rename_base_spec.rb | 9 ++++++++ .../v1/rename_namespaces_spec.rb | 27 +++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb index 64bc5fc0429..a3ab4e3dd9e 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb @@ -107,6 +107,15 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase do expect(new_path).to eq('the-path0') end + it "doesn't rename routes that start with a similar name" do + other_namespace = create(:namespace, path: 'the-path-but-not-really') + project = create(:empty_project, path: 'the-project', namespace: other_namespace) + + subject.rename_path_for_routable(migration_namespace(namespace)) + + expect(project.route.reload.path).to eq('the-path-but-not-really/the-project') + end + context "the-path namespace -> subgroup -> the-path0 project" do it "updates the route of the project correctly" do subgroup = create(:group, path: "subgroup", parent: namespace) diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb index ec444942804..c56fded7516 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb @@ -137,7 +137,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do end describe "#rename_namespace" do - let(:namespace) { create(:namespace, path: 'the-path') } + let(:namespace) { create(:group, name: 'the-path') } it 'renames paths & routes for the namespace' do expect(subject).to receive(:rename_path_for_routable). @@ -177,6 +177,31 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do subject.rename_namespace(namespace) end + + it "doesn't rename users for other namespaces" do + expect(subject).not_to receive(:rename_user) + + subject.rename_namespace(namespace) + end + + it 'renames the username of a namespace for a user' do + user = create(:user, username: 'the-path') + + expect(subject).to receive(:rename_user).with('the-path', 'the-path0') + + subject.rename_namespace(user.namespace) + end + end + + describe '#rename_user' do + it 'renames a username' do + subject = described_class.new([], migration) + user = create(:user, username: 'broken') + + subject.rename_user('broken', 'broken0') + + expect(user.reload.username).to eq('broken0') + end end describe '#rename_namespaces' do -- cgit v1.2.1 From 3c668fa04fd7e0a1d925e9666eb727ed3e83d145 Mon Sep 17 00:00:00 2001 From: Bryce Johnson Date: Sat, 15 Apr 2017 19:38:07 -0400 Subject: Consolidate user avatar Vue logic --- .../merge_requests/diff_notes_avatars_spec.rb | 2 +- spec/javascripts/boards/issue_card_spec.js | 2 +- spec/javascripts/pipelines/pipeline_url_spec.js | 2 +- .../vue_shared/components/commit_spec.js | 2 +- .../components/pipelines_table_row_spec.js | 4 +- .../components/user_avatar_image_spec.js | 60 ++++++++++++++++++++++ .../vue_shared/components/user_avatar_link_spec.js | 58 +++++++++++++++++++++ .../components/user_avatar_size_mixin_spec.js | 37 +++++++++++++ .../vue_shared/components/user_avatar_svg_spec.js | 35 +++++++++++++ 9 files changed, 196 insertions(+), 6 deletions(-) create mode 100644 spec/javascripts/vue_shared/components/user_avatar_image_spec.js create mode 100644 spec/javascripts/vue_shared/components/user_avatar_link_spec.js create mode 100644 spec/javascripts/vue_shared/components/user_avatar_size_mixin_spec.js create mode 100644 spec/javascripts/vue_shared/components/user_avatar_svg_spec.js (limited to 'spec') diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb index b2e170513c4..ccf047d3efa 100644 --- a/spec/features/merge_requests/diff_notes_avatars_spec.rb +++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb @@ -91,7 +91,7 @@ feature 'Diff note avatars', feature: true, js: true do page.within find("[id='#{position.line_code(project.repository)}']") do find('.diff-notes-collapse').click - expect(first('img.js-diff-comment-avatar')["title"]).to eq("#{note.author.name}: #{note.note.truncate(17)}") + expect(first('img.js-diff-comment-avatar')["data-original-title"]).to eq("#{note.author.name}: #{note.note.truncate(17)}") end end diff --git a/spec/javascripts/boards/issue_card_spec.js b/spec/javascripts/boards/issue_card_spec.js index fddde799d01..bd9b4fbfdd3 100644 --- a/spec/javascripts/boards/issue_card_spec.js +++ b/spec/javascripts/boards/issue_card_spec.js @@ -129,7 +129,7 @@ describe('Issue card component', () => { it('sets title', () => { expect( - component.$el.querySelector('.card-assignee a').getAttribute('title'), + component.$el.querySelector('.card-assignee img').getAttribute('data-original-title'), ).toContain(`Assigned to ${user.name}`); }); diff --git a/spec/javascripts/pipelines/pipeline_url_spec.js b/spec/javascripts/pipelines/pipeline_url_spec.js index 53931d67ad7..0bcc3905702 100644 --- a/spec/javascripts/pipelines/pipeline_url_spec.js +++ b/spec/javascripts/pipelines/pipeline_url_spec.js @@ -60,7 +60,7 @@ describe('Pipeline Url Component', () => { expect( component.$el.querySelector('.js-pipeline-url-user').getAttribute('href'), ).toEqual(mockData.pipeline.user.web_url); - expect(image.getAttribute('title')).toEqual(mockData.pipeline.user.name); + expect(image.getAttribute('data-original-title')).toEqual(mockData.pipeline.user.name); expect(image.getAttribute('src')).toEqual(mockData.pipeline.user.avatar_url); }); diff --git a/spec/javascripts/vue_shared/components/commit_spec.js b/spec/javascripts/vue_shared/components/commit_spec.js index 242010ba688..0638483e7aa 100644 --- a/spec/javascripts/vue_shared/components/commit_spec.js +++ b/spec/javascripts/vue_shared/components/commit_spec.js @@ -86,7 +86,7 @@ describe('Commit component', () => { it('Should render the author avatar with title and alt attributes', () => { expect( - component.$el.querySelector('.commit-title .avatar-image-container img').getAttribute('title'), + component.$el.querySelector('.commit-title .avatar-image-container img').getAttribute('data-original-title'), ).toContain(props.author.username); expect( component.$el.querySelector('.commit-title .avatar-image-container img').getAttribute('alt'), diff --git a/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js b/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js index 14280751053..286118917e8 100644 --- a/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js +++ b/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js @@ -79,7 +79,7 @@ describe('Pipelines Table Row', () => { ).toEqual(pipeline.user.web_url); expect( - component.$el.querySelector('td:nth-child(2) img').getAttribute('title'), + component.$el.querySelector('td:nth-child(2) img').getAttribute('data-original-title'), ).toEqual(pipeline.user.name); }); }); @@ -102,7 +102,7 @@ describe('Pipelines Table Row', () => { } const commitAuthorLink = commitAuthorElement.getAttribute('href'); - const commitAuthorName = commitAuthorElement.querySelector('img.avatar').getAttribute('title'); + const commitAuthorName = commitAuthorElement.querySelector('img.avatar').getAttribute('data-original-title'); return { commitAuthorElement, commitAuthorLink, commitAuthorName }; }; diff --git a/spec/javascripts/vue_shared/components/user_avatar_image_spec.js b/spec/javascripts/vue_shared/components/user_avatar_image_spec.js new file mode 100644 index 00000000000..0b5ec736b1e --- /dev/null +++ b/spec/javascripts/vue_shared/components/user_avatar_image_spec.js @@ -0,0 +1,60 @@ +import Vue from 'vue'; +import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue'; + +const UserAvatarImageComponent = Vue.extend(UserAvatarImage); + +describe('User Avatar Image Component', function () { + describe('Initialization', function () { + beforeEach(function () { + this.propsData = { + size: 99, + imgSrc: 'myavatarurl.com', + imgAlt: 'mydisplayname', + cssClasses: 'myextraavatarclass', + tooltipText: 'tooltip text', + tooltipPlacement: 'bottom', + }; + + this.userAvatarImage = new UserAvatarImageComponent({ + propsData: this.propsData, + }).$mount(); + + this.imageElement = this.userAvatarImage.$el.outerHTML; + }); + + it('should return a defined Vue component', function () { + expect(this.userAvatarImage).toBeDefined(); + }); + + it('should have as a child element', function () { + const componentImgTag = this.userAvatarImage.$el.outerHTML; + expect(componentImgTag).toContain(' { + expect(this.userAvatarImage[key]).toBeDefined(); + }); + }); + + it('should properly compute tooltipContainer', function () { + expect(this.userAvatarImage.tooltipContainer).toBe('body'); + }); + + it('should properly render tooltipContainer', function () { + expect(this.imageElement).toContain('data-container="body"'); + }); + + it('should properly compute avatarSizeClass', function () { + expect(this.userAvatarImage.avatarSizeClass).toBe('s99'); + }); + + it('should properly compute imgCssClasses', function () { + expect(this.userAvatarImage.imgCssClasses).toBe('avatar s99 myextraavatarclass'); + }); + + it('should properly render imgCssClasses', function () { + expect(this.imageElement).toContain('avatar s99 myextraavatarclass'); + }); + }); +}); diff --git a/spec/javascripts/vue_shared/components/user_avatar_link_spec.js b/spec/javascripts/vue_shared/components/user_avatar_link_spec.js new file mode 100644 index 00000000000..770daa9f0de --- /dev/null +++ b/spec/javascripts/vue_shared/components/user_avatar_link_spec.js @@ -0,0 +1,58 @@ +import Vue from 'vue'; +import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue'; + +describe('User Avatar Link Component', function () { + beforeEach(function () { + this.propsData = { + linkHref: 'myavatarurl.com', + imgSize: 99, + imgSrc: 'myavatarurl.com', + imgAlt: 'mydisplayname', + imgCssClasses: 'myextraavatarclass', + tooltipText: 'tooltip text', + tooltipPlacement: 'bottom', + }; + + const UserAvatarLinkComponent = Vue.extend(UserAvatarLink); + + this.userAvatarLink = new UserAvatarLinkComponent({ + propsData: this.propsData, + }).$mount(); + + this.userAvatarImage = this.userAvatarLink.$children[0]; + }); + + it('should return a defined Vue component', function () { + expect(this.userAvatarLink).toBeDefined(); + }); + + it('should have user-avatar-image registered as child component', function () { + expect(this.userAvatarLink.$options.components.userAvatarImage).toBeDefined(); + }); + + it('user-avatar-link should have user-avatar-image as child component', function () { + expect(this.userAvatarImage).toBeDefined(); + }); + + it('should render as a child element', function () { + const componentLinkTag = this.userAvatarLink.$el.outerHTML; + expect(componentLinkTag).toContain(' as a child element', function () { + const componentImgTag = this.userAvatarLink.$el.outerHTML; + expect(componentImgTag).toContain(' { + expect(this.userAvatarLink[key]).toBeDefined(); + }); + }); + + it('should include props in the rendered output', function () { + _.each(this.propsData, (val) => { + expect(this.userAvatarLink.$el.outerHTML).toContain(val); + }); + }); +}); diff --git a/spec/javascripts/vue_shared/components/user_avatar_size_mixin_spec.js b/spec/javascripts/vue_shared/components/user_avatar_size_mixin_spec.js new file mode 100644 index 00000000000..b37813cdb3d --- /dev/null +++ b/spec/javascripts/vue_shared/components/user_avatar_size_mixin_spec.js @@ -0,0 +1,37 @@ +import Vue from 'vue'; +import UserAvatarSizeMixin from '~/vue_shared/components/user_avatar/user_avatar_size_mixin'; + +describe('User Avatar Size Mixin', () => { + beforeEach(() => { + this.vueInstance = new Vue({ + data: { + size: 99, + }, + mixins: [UserAvatarSizeMixin], + }); + }); + + describe('#avatarSizeClass', () => { + it('should be a defined computed value', () => { + expect(this.vueInstance.avatarSizeClass).toBeDefined(); + }); + + it('should correctly transform size into the class name', () => { + expect(this.vueInstance.avatarSizeClass).toBe('s99'); + }); + }); + + describe('#avatarSizeStylesMap', () => { + it('should be a defined computed value', () => { + expect(this.vueInstance.avatarSizeStylesMap).toBeDefined(); + }); + + it('should return a correctly formatted styles width', () => { + expect(this.vueInstance.avatarSizeStylesMap.width).toBe('99px'); + }); + + it('should return a correctly formatted styles height', () => { + expect(this.vueInstance.avatarSizeStylesMap.height).toBe('99px'); + }); + }); +}); diff --git a/spec/javascripts/vue_shared/components/user_avatar_svg_spec.js b/spec/javascripts/vue_shared/components/user_avatar_svg_spec.js new file mode 100644 index 00000000000..809886c5dbd --- /dev/null +++ b/spec/javascripts/vue_shared/components/user_avatar_svg_spec.js @@ -0,0 +1,35 @@ +import Vue from 'vue'; +import UserAvatarSvg from '~/vue_shared/components/user_avatar/user_avatar_svg.vue'; +import avatarSvg from 'icons/_icon_random.svg'; + +const UserAvatarSvgComponent = Vue.extend(UserAvatarSvg); + +describe('User Avatar Svg Component', function () { + describe('Initialization', function () { + beforeEach(function () { + this.propsData = { + size: 99, + svg: avatarSvg, + }; + + this.userAvatarSvg = new UserAvatarSvgComponent({ + propsData: this.propsData, + }).$mount(); + }); + + it('should return a defined Vue component', function () { + expect(this.userAvatarSvg).toBeDefined(); + }); + + it('should have as a child element', function () { + expect(this.userAvatarSvg.$el.tagName).toEqual('svg'); + expect(this.userAvatarSvg.$el.innerHTML).toContain(' { + expect(this.userAvatarSvg[key]).toBeDefined(); + }); + }); + }); +}); -- cgit v1.2.1 From b73959a94bcace3d0af7819f7621b308980c49d9 Mon Sep 17 00:00:00 2001 From: Bryce Johnson Date: Wed, 17 May 2017 11:22:26 -0400 Subject: Fixes per feedback on user avatar components. --- .../components/user_avatar_image_spec.js | 26 ++++++--------- .../vue_shared/components/user_avatar_link_spec.js | 12 ++----- .../components/user_avatar_size_mixin_spec.js | 37 ---------------------- .../vue_shared/components/user_avatar_svg_spec.js | 6 ---- 4 files changed, 12 insertions(+), 69 deletions(-) delete mode 100644 spec/javascripts/vue_shared/components/user_avatar_size_mixin_spec.js (limited to 'spec') diff --git a/spec/javascripts/vue_shared/components/user_avatar_image_spec.js b/spec/javascripts/vue_shared/components/user_avatar_image_spec.js index 0b5ec736b1e..8daa7610274 100644 --- a/spec/javascripts/vue_shared/components/user_avatar_image_spec.js +++ b/spec/javascripts/vue_shared/components/user_avatar_image_spec.js @@ -18,8 +18,6 @@ describe('User Avatar Image Component', function () { this.userAvatarImage = new UserAvatarImageComponent({ propsData: this.propsData, }).$mount(); - - this.imageElement = this.userAvatarImage.$el.outerHTML; }); it('should return a defined Vue component', function () { @@ -27,14 +25,7 @@ describe('User Avatar Image Component', function () { }); it('should have as a child element', function () { - const componentImgTag = this.userAvatarImage.$el.outerHTML; - expect(componentImgTag).toContain(' { - expect(this.userAvatarImage[key]).toBeDefined(); - }); + expect(this.userAvatarImage.$el.tagName).toBe('IMG'); }); it('should properly compute tooltipContainer', function () { @@ -42,19 +33,22 @@ describe('User Avatar Image Component', function () { }); it('should properly render tooltipContainer', function () { - expect(this.imageElement).toContain('data-container="body"'); + expect(this.userAvatarImage.$el.getAttribute('data-container')).toBe('body'); }); it('should properly compute avatarSizeClass', function () { expect(this.userAvatarImage.avatarSizeClass).toBe('s99'); }); - it('should properly compute imgCssClasses', function () { - expect(this.userAvatarImage.imgCssClasses).toBe('avatar s99 myextraavatarclass'); - }); + it('should properly render img css', function () { + const classList = this.userAvatarImage.$el.classList; + const containsAvatar = classList.contains('avatar'); + const containsSizeClass = classList.contains('s99'); + const containsCustomClass = classList.contains('myextraavatarclass'); - it('should properly render imgCssClasses', function () { - expect(this.imageElement).toContain('avatar s99 myextraavatarclass'); + expect(containsAvatar).toBe(true); + expect(containsSizeClass).toBe(true); + expect(containsCustomClass).toBe(true); }); }); }); diff --git a/spec/javascripts/vue_shared/components/user_avatar_link_spec.js b/spec/javascripts/vue_shared/components/user_avatar_link_spec.js index 770daa9f0de..52e450e9ba5 100644 --- a/spec/javascripts/vue_shared/components/user_avatar_link_spec.js +++ b/spec/javascripts/vue_shared/components/user_avatar_link_spec.js @@ -35,13 +35,11 @@ describe('User Avatar Link Component', function () { }); it('should render as a child element', function () { - const componentLinkTag = this.userAvatarLink.$el.outerHTML; - expect(componentLinkTag).toContain(' as a child element', function () { - const componentImgTag = this.userAvatarLink.$el.outerHTML; - expect(componentImgTag).toContain(' { - expect(this.userAvatarLink.$el.outerHTML).toContain(val); - }); - }); }); diff --git a/spec/javascripts/vue_shared/components/user_avatar_size_mixin_spec.js b/spec/javascripts/vue_shared/components/user_avatar_size_mixin_spec.js deleted file mode 100644 index b37813cdb3d..00000000000 --- a/spec/javascripts/vue_shared/components/user_avatar_size_mixin_spec.js +++ /dev/null @@ -1,37 +0,0 @@ -import Vue from 'vue'; -import UserAvatarSizeMixin from '~/vue_shared/components/user_avatar/user_avatar_size_mixin'; - -describe('User Avatar Size Mixin', () => { - beforeEach(() => { - this.vueInstance = new Vue({ - data: { - size: 99, - }, - mixins: [UserAvatarSizeMixin], - }); - }); - - describe('#avatarSizeClass', () => { - it('should be a defined computed value', () => { - expect(this.vueInstance.avatarSizeClass).toBeDefined(); - }); - - it('should correctly transform size into the class name', () => { - expect(this.vueInstance.avatarSizeClass).toBe('s99'); - }); - }); - - describe('#avatarSizeStylesMap', () => { - it('should be a defined computed value', () => { - expect(this.vueInstance.avatarSizeStylesMap).toBeDefined(); - }); - - it('should return a correctly formatted styles width', () => { - expect(this.vueInstance.avatarSizeStylesMap.width).toBe('99px'); - }); - - it('should return a correctly formatted styles height', () => { - expect(this.vueInstance.avatarSizeStylesMap.height).toBe('99px'); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/user_avatar_svg_spec.js b/spec/javascripts/vue_shared/components/user_avatar_svg_spec.js index 809886c5dbd..b8d639ffbec 100644 --- a/spec/javascripts/vue_shared/components/user_avatar_svg_spec.js +++ b/spec/javascripts/vue_shared/components/user_avatar_svg_spec.js @@ -25,11 +25,5 @@ describe('User Avatar Svg Component', function () { expect(this.userAvatarSvg.$el.tagName).toEqual('svg'); expect(this.userAvatarSvg.$el.innerHTML).toContain(' { - expect(this.userAvatarSvg[key]).toBeDefined(); - }); - }); }); }); -- cgit v1.2.1 From 7a7e9288d4dea50a9797b3f624bf8174fa7060d4 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 18 May 2017 15:48:42 -0500 Subject: Stop MR conflict code from blowing up when branches are missing --- spec/services/merge_requests/conflicts/list_service_spec.rb | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'spec') diff --git a/spec/services/merge_requests/conflicts/list_service_spec.rb b/spec/services/merge_requests/conflicts/list_service_spec.rb index e8a305d6130..23982b9e6e1 100644 --- a/spec/services/merge_requests/conflicts/list_service_spec.rb +++ b/spec/services/merge_requests/conflicts/list_service_spec.rb @@ -25,6 +25,13 @@ describe MergeRequests::Conflicts::ListService do expect(conflicts_service(merge_request).can_be_resolved_in_ui?).to be_falsey end + it 'returns a falsey value when one of the MR branches is missing' do + merge_request = create_merge_request('conflict-resolvable') + merge_request.project.repository.rm_branch(merge_request.author, 'conflict-resolvable') + + expect(conflicts_service(merge_request).can_be_resolved_in_ui?).to be_falsey + end + it 'returns a falsey value when the MR has a missing ref after a force push' do merge_request = create_merge_request('conflict-resolvable') service = conflicts_service(merge_request) -- cgit v1.2.1 From 1f9a9629dbd954520e15e436352316cfdc24d362 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Thu, 18 May 2017 20:53:15 +0000 Subject: Fix clicking disabled clipboard button toolip --- spec/javascripts/blob/viewer/index_spec.js | 31 ++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/blob/viewer/index_spec.js b/spec/javascripts/blob/viewer/index_spec.js index 13f122b68b2..af04e7c1e72 100644 --- a/spec/javascripts/blob/viewer/index_spec.js +++ b/spec/javascripts/blob/viewer/index_spec.js @@ -83,25 +83,48 @@ describe('Blob viewer', () => { }); describe('copy blob button', () => { + let copyButton; + + beforeEach(() => { + copyButton = document.querySelector('.js-copy-blob-source-btn'); + }); + it('disabled on load', () => { expect( - document.querySelector('.js-copy-blob-source-btn').classList.contains('disabled'), + copyButton.classList.contains('disabled'), ).toBeTruthy(); }); it('has tooltip when disabled', () => { expect( - document.querySelector('.js-copy-blob-source-btn').getAttribute('data-original-title'), + copyButton.getAttribute('data-original-title'), ).toBe('Switch to the source to copy it to the clipboard'); }); + it('is blurred when clicked and disabled', () => { + spyOn(copyButton, 'blur'); + + copyButton.click(); + + expect(copyButton.blur).toHaveBeenCalled(); + }); + + it('is not blurred when clicked and not disabled', () => { + spyOn(copyButton, 'blur'); + + copyButton.classList.remove('disabled'); + copyButton.click(); + + expect(copyButton.blur).not.toHaveBeenCalled(); + }); + it('enables after switching to simple view', (done) => { document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click(); setTimeout(() => { expect($.ajax).toHaveBeenCalled(); expect( - document.querySelector('.js-copy-blob-source-btn').classList.contains('disabled'), + copyButton.classList.contains('disabled'), ).toBeFalsy(); done(); @@ -115,7 +138,7 @@ describe('Blob viewer', () => { expect($.ajax).toHaveBeenCalled(); expect( - document.querySelector('.js-copy-blob-source-btn').getAttribute('data-original-title'), + copyButton.getAttribute('data-original-title'), ).toBe('Copy source to clipboard'); done(); -- cgit v1.2.1 From e8841e8dbc6a14af3ce98b7033136249dd9de265 Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Thu, 18 May 2017 17:14:48 -0300 Subject: Drop merge_check endpoint and use only MR show instead --- spec/controllers/projects/merge_requests_controller_spec.rb | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'spec') diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index 0b3492a8fed..7fe2f190790 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -119,6 +119,15 @@ describe Projects::MergeRequestsController do expect(response).to match_response_schema('entities/merge_request') end end + + context 'number of queries' do + it 'verifies number of queries' do + recorded = ActiveRecord::QueryRecorder.new { go(format: :json) } + + expect(recorded.count).to be_within(1).of(94) + expect(recorded.cached_count).to eq(0) + end + end end describe "as diff" do -- cgit v1.2.1 From f9785dcec34c4205732871523f95b9743db00965 Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Thu, 18 May 2017 12:56:39 -0700 Subject: Fix ensure_canonical_path for top level routes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don’t replace a substring of the path if it is part of the top level route. E.g. When redirecting from `/groups/ups` to `/groups/foo`, be careful not to do `/grofoo/ups`. Projects are unaffected by this issue, but I am grouping the `#ensure_canonical_path` tests similar to the group and user tests. --- spec/controllers/groups_controller_spec.rb | 229 +++++++++++++++--------- spec/controllers/projects_controller_spec.rb | 199 +++++++++++---------- spec/controllers/users_controller_spec.rb | 253 +++++++++++++-------------- 3 files changed, 369 insertions(+), 312 deletions(-) (limited to 'spec') diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb index 0392315b62f..993654fddaa 100644 --- a/spec/controllers/groups_controller_spec.rb +++ b/spec/controllers/groups_controller_spec.rb @@ -84,26 +84,6 @@ describe GroupsController do expect(assigns(:issues)).to eq [issue_2, issue_1] end end - - context 'when requesting the canonical path with different casing' do - it 'redirects to the correct casing' do - get :issues, id: group.to_param.upcase - - expect(response).to redirect_to(issues_group_path(group.to_param)) - expect(controller).not_to set_flash[:notice] - end - end - - context 'when requesting a redirected path' do - let(:redirect_route) { group.redirect_routes.create(path: 'old-path') } - - it 'redirects to the canonical path' do - get :issues, id: redirect_route.path - - expect(response).to redirect_to(issues_group_path(group.to_param)) - expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) - end - end end describe 'GET #merge_requests' do @@ -129,26 +109,6 @@ describe GroupsController do expect(assigns(:merge_requests)).to eq [merge_request_2, merge_request_1] end end - - context 'when requesting the canonical path with different casing' do - it 'redirects to the correct casing' do - get :merge_requests, id: group.to_param.upcase - - expect(response).to redirect_to(merge_requests_group_path(group.to_param)) - expect(controller).not_to set_flash[:notice] - end - end - - context 'when requesting a redirected path' do - let(:redirect_route) { group.redirect_routes.create(path: 'old-path') } - - it 'redirects to the canonical path' do - get :merge_requests, id: redirect_route.path - - expect(response).to redirect_to(merge_requests_group_path(group.to_param)) - expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) - end - end end describe 'DELETE #destroy' do @@ -178,30 +138,6 @@ describe GroupsController do expect(response).to redirect_to(root_path) end - - context 'when requesting the canonical path with different casing' do - it 'does not 404' do - delete :destroy, id: group.to_param.upcase - - expect(response).not_to have_http_status(404) - end - - it 'does not redirect to the correct casing' do - delete :destroy, id: group.to_param.upcase - - expect(response).not_to redirect_to(group_path(group.to_param)) - end - end - - context 'when requesting a redirected path' do - let(:redirect_route) { group.redirect_routes.create(path: 'old-path') } - - it 'returns not found' do - delete :destroy, id: redirect_route.path - - expect(response).to have_http_status(404) - end - end end end @@ -224,41 +160,166 @@ describe GroupsController do expect(assigns(:group).errors).not_to be_empty expect(assigns(:group).path).not_to eq('new_path') end + end + + describe '#ensure_canonical_path' do + before do + sign_in(user) + end + + context 'for a GET request' do + context 'when requesting groups at the root path' do + before do + allow(request).to receive(:original_fullpath).and_return("/#{group_full_path}") + get :show, id: group_full_path + end - context 'when requesting the canonical path with different casing' do - it 'does not 404' do - post :update, id: group.to_param.upcase, group: { path: 'new_path' } + context 'when requesting the canonical path with different casing' do + let(:group_full_path) { group.to_param.upcase } - expect(response).not_to have_http_status(404) + it 'redirects to the correct casing' do + expect(response).to redirect_to(group) + expect(controller).not_to set_flash[:notice] + end + end + + context 'when requesting a redirected path' do + let(:redirect_route) { group.redirect_routes.create(path: 'old-path') } + let(:group_full_path) { redirect_route.path } + + it 'redirects to the canonical path' do + expect(response).to redirect_to(group) + expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) + end + + context 'when the old group path is a substring of the scheme or host' do + let(:redirect_route) { group.redirect_routes.create(path: 'http') } + + it 'does not modify the requested host' do + expect(response).to redirect_to(group) + expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) + end + end + + context 'when the old group path is substring of groups' do + # I.e. /groups/oups should not become /grfoo/oups + let(:redirect_route) { group.redirect_routes.create(path: 'oups') } + + it 'does not modify the /groups part of the path' do + expect(response).to redirect_to(group) + expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) + end + end + end end - it 'does not redirect to the correct casing' do - post :update, id: group.to_param.upcase, group: { path: 'new_path' } + context 'when requesting groups under the /groups path' do + context 'when requesting the canonical path with different casing' do + it 'redirects to the correct casing' do + get :issues, id: group.to_param.upcase - expect(response).not_to redirect_to(group_path(group.to_param)) + expect(response).to redirect_to(issues_group_path(group.to_param)) + expect(controller).not_to set_flash[:notice] + end + end + + context 'when requesting a redirected path' do + let(:redirect_route) { group.redirect_routes.create(path: 'old-path') } + + it 'redirects to the canonical path' do + get :issues, id: redirect_route.path + + expect(response).to redirect_to(issues_group_path(group.to_param)) + expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) + end + + context 'when the old group path is a substring of the scheme or host' do + let(:redirect_route) { group.redirect_routes.create(path: 'http') } + + it 'does not modify the requested host' do + get :issues, id: redirect_route.path + + expect(response).to redirect_to(issues_group_path(group.to_param)) + expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) + end + end + + context 'when the old group path is substring of groups' do + # I.e. /groups/oups should not become /grfoo/oups + let(:redirect_route) { group.redirect_routes.create(path: 'oups') } + + it 'does not modify the /groups part of the path' do + get :issues, id: redirect_route.path + + expect(response).to redirect_to(issues_group_path(group.to_param)) + expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) + end + end + + context 'when the old group path is substring of groups plus the new path' do + # I.e. /groups/oups/oup should not become /grfoos + let(:redirect_route) { group.redirect_routes.create(path: 'oups/oup') } + + it 'does not modify the /groups part of the path' do + get :issues, id: redirect_route.path + + expect(response).to redirect_to(issues_group_path(group.to_param)) + expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) + end + end + end end end - context 'when requesting a redirected path' do - let(:redirect_route) { group.redirect_routes.create(path: 'old-path') } + context 'for a POST request' do + context 'when requesting the canonical path with different casing' do + it 'does not 404' do + post :update, id: group.to_param.upcase, group: { path: 'new_path' } + + expect(response).not_to have_http_status(404) + end + + it 'does not redirect to the correct casing' do + post :update, id: group.to_param.upcase, group: { path: 'new_path' } + + expect(response).not_to have_http_status(301) + end + end + + context 'when requesting a redirected path' do + let(:redirect_route) { group.redirect_routes.create(path: 'old-path') } - it 'returns not found' do - post :update, id: redirect_route.path, group: { path: 'new_path' } + it 'returns not found' do + post :update, id: redirect_route.path, group: { path: 'new_path' } - expect(response).to have_http_status(404) + expect(response).to have_http_status(404) + end end end - end - describe 'ensure_canonical_path' do - context 'when the old group path is a substring of the scheme or host' do - let(:redirect_route) { group.redirect_routes.create(path: 'http') } + context 'for a DELETE request' do + context 'when requesting the canonical path with different casing' do + it 'does not 404' do + delete :destroy, id: group.to_param.upcase - it 'does not modify the requested host' do - get :issues, id: redirect_route.path + expect(response).not_to have_http_status(404) + end - expect(response).to redirect_to(issues_group_path(group.to_param)) - expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) + it 'does not redirect to the correct casing' do + delete :destroy, id: group.to_param.upcase + + expect(response).not_to have_http_status(301) + end + end + + context 'when requesting a redirected path' do + let(:redirect_route) { group.redirect_routes.create(path: 'old-path') } + + it 'returns not found' do + delete :destroy, id: redirect_route.path + + expect(response).to have_http_status(404) + end end end end diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index e230944d52e..a8be6768a47 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -169,27 +169,6 @@ describe ProjectsController do end end - context "when requested with case sensitive namespace and project path" do - context "when there is a match with the same casing" do - it "loads the project" do - get :show, namespace_id: public_project.namespace, id: public_project - - expect(assigns(:project)).to eq(public_project) - expect(response).to have_http_status(200) - end - end - - context "when there is a match with different casing" do - it "redirects to the normalized path" do - get :show, namespace_id: public_project.namespace, id: public_project.path.upcase - - expect(assigns(:project)).to eq(public_project) - expect(response).to redirect_to("/#{public_project.full_path}") - expect(controller).not_to set_flash[:notice] - end - end - end - context "when the url contains .atom" do let(:public_project_with_dot_atom) { build(:empty_project, :public, name: 'my.atom', path: 'my.atom') } @@ -219,17 +198,6 @@ describe ProjectsController do expect(response).to redirect_to(namespace_project_path) end end - - context 'when requesting a redirected path' do - let!(:redirect_route) { public_project.redirect_routes.create!(path: "foo/bar") } - - it 'redirects to the canonical path' do - get :show, namespace_id: 'foo', id: 'bar' - - expect(response).to redirect_to(public_project) - expect(controller).to set_flash[:notice].to(project_moved_message(redirect_route, public_project)) - end - end end describe "#update" do @@ -256,34 +224,6 @@ describe ProjectsController do expect(assigns(:repository).path).to eq(project.repository.path) expect(response).to have_http_status(302) end - - context 'when requesting the canonical path' do - it "is case-insensitive" do - controller.instance_variable_set(:@project, project) - - put :update, - namespace_id: 'FOo', - id: 'baR', - project: project_params - - expect(project.repository.path).to include(new_path) - expect(assigns(:repository).path).to eq(project.repository.path) - expect(response).to have_http_status(302) - end - end - - context 'when requesting a redirected path' do - let!(:redirect_route) { project.redirect_routes.create!(path: "foo/bar") } - - it 'returns not found' do - put :update, - namespace_id: 'foo', - id: 'bar', - project: project_params - - expect(response).to have_http_status(404) - end - end end describe "#destroy" do @@ -319,31 +259,6 @@ describe ProjectsController do expect(merge_request.reload.state).to eq('closed') end end - - context 'when requesting the canonical path' do - it "is case-insensitive" do - controller.instance_variable_set(:@project, project) - sign_in(admin) - - orig_id = project.id - delete :destroy, namespace_id: project.namespace, id: project.path.upcase - - expect { Project.find(orig_id) }.to raise_error(ActiveRecord::RecordNotFound) - expect(response).to have_http_status(302) - expect(response).to redirect_to(dashboard_projects_path) - end - end - - context 'when requesting a redirected path' do - let!(:redirect_route) { project.redirect_routes.create!(path: "foo/bar") } - - it 'returns not found' do - sign_in(admin) - delete :destroy, namespace_id: 'foo', id: 'bar' - - expect(response).to have_http_status(404) - end - end end describe 'PUT #new_issue_address' do @@ -465,17 +380,6 @@ describe ProjectsController do expect(parsed_body["Tags"]).to include("v1.0.0") expect(parsed_body["Commits"]).to include("123456") end - - context 'when requesting a redirected path' do - let!(:redirect_route) { public_project.redirect_routes.create!(path: "foo/bar") } - - it 'redirects to the canonical path' do - get :refs, namespace_id: 'foo', id: 'bar' - - expect(response).to redirect_to(refs_namespace_project_path(namespace_id: public_project.namespace, id: public_project)) - expect(controller).to set_flash[:notice].to(project_moved_message(redirect_route, public_project)) - end - end end describe 'POST #preview_markdown' do @@ -488,6 +392,109 @@ describe ProjectsController do end end + describe '#ensure_canonical_path' do + before do + sign_in(user) + end + + context 'for a GET request' do + context 'when requesting the canonical path' do + context "with exactly matching casing" do + it "loads the project" do + get :show, namespace_id: public_project.namespace, id: public_project + + expect(assigns(:project)).to eq(public_project) + expect(response).to have_http_status(200) + end + end + + context "with different casing" do + it "redirects to the normalized path" do + get :show, namespace_id: public_project.namespace, id: public_project.path.upcase + + expect(assigns(:project)).to eq(public_project) + expect(response).to redirect_to("/#{public_project.full_path}") + expect(controller).not_to set_flash[:notice] + end + end + end + + context 'when requesting a redirected path' do + let!(:redirect_route) { public_project.redirect_routes.create!(path: "foo/bar") } + + it 'redirects to the canonical path' do + get :show, namespace_id: 'foo', id: 'bar' + + expect(response).to redirect_to(public_project) + expect(controller).to set_flash[:notice].to(project_moved_message(redirect_route, public_project)) + end + + it 'redirects to the canonical path (testing non-show action)' do + get :refs, namespace_id: 'foo', id: 'bar' + + expect(response).to redirect_to(refs_namespace_project_path(namespace_id: public_project.namespace, id: public_project)) + expect(controller).to set_flash[:notice].to(project_moved_message(redirect_route, public_project)) + end + end + end + + context 'for a POST request' do + context 'when requesting the canonical path with different casing' do + it 'does not 404' do + post :toggle_star, namespace_id: public_project.namespace, id: public_project.path.upcase + + expect(response).not_to have_http_status(404) + end + + it 'does not redirect to the correct casing' do + post :toggle_star, namespace_id: public_project.namespace, id: public_project.path.upcase + + expect(response).not_to have_http_status(301) + end + end + + context 'when requesting a redirected path' do + let!(:redirect_route) { public_project.redirect_routes.create!(path: "foo/bar") } + + it 'returns not found' do + post :toggle_star, namespace_id: 'foo', id: 'bar' + + expect(response).to have_http_status(404) + end + end + end + + context 'for a DELETE request' do + before do + sign_in(create(:admin)) + end + + context 'when requesting the canonical path with different casing' do + it 'does not 404' do + delete :destroy, namespace_id: project.namespace, id: project.path.upcase + + expect(response).not_to have_http_status(404) + end + + it 'does not redirect to the correct casing' do + delete :destroy, namespace_id: project.namespace, id: project.path.upcase + + expect(response).not_to have_http_status(301) + end + end + + context 'when requesting a redirected path' do + let!(:redirect_route) { project.redirect_routes.create!(path: "foo/bar") } + + it 'returns not found' do + delete :destroy, namespace_id: 'foo', id: 'bar' + + expect(response).to have_http_status(404) + end + end + end + end + def project_moved_message(redirect_route, project) "Project '#{redirect_route.path}' was moved to '#{project.full_path}'. Please update any links and bookmarks that may still have the old path." end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 1d61719f1d0..d33e2ba1e53 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -53,40 +53,6 @@ describe UsersController do end end - context 'when requesting the canonical path' do - let(:user) { create(:user, username: 'CamelCaseUser') } - - before { sign_in(user) } - - context 'with exactly matching casing' do - it 'responds with success' do - get :show, username: user.username - - expect(response).to be_success - end - end - - context 'with different casing' do - it 'redirects to the correct casing' do - get :show, username: user.username.downcase - - expect(response).to redirect_to(user) - expect(controller).not_to set_flash[:notice] - end - end - end - - context 'when requesting a redirected path' do - let(:redirect_route) { user.namespace.redirect_routes.create(path: 'old-username') } - - it 'redirects to the canonical path' do - get :show, username: redirect_route.path - - expect(response).to redirect_to(user) - expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) - end - end - context 'when a user by that username does not exist' do context 'when logged out' do it 'redirects to login page' do @@ -131,40 +97,6 @@ describe UsersController do expect(assigns(:contributions_calendar).projects.count).to eq(2) end end - - context 'when requesting the canonical path' do - let(:user) { create(:user, username: 'CamelCaseUser') } - - before { sign_in(user) } - - context 'with exactly matching casing' do - it 'responds with success' do - get :calendar, username: user.username - - expect(response).to be_success - end - end - - context 'with different casing' do - it 'redirects to the correct casing' do - get :calendar, username: user.username.downcase - - expect(response).to redirect_to(user_calendar_path(user)) - expect(controller).not_to set_flash[:notice] - end - end - end - - context 'when requesting a redirected path' do - let(:redirect_route) { user.namespace.redirect_routes.create(path: 'old-username') } - - it 'redirects to the canonical path' do - get :calendar, username: redirect_route.path - - expect(response).to redirect_to(user_calendar_path(user)) - expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) - end - end end describe 'GET #calendar_activities' do @@ -187,38 +119,6 @@ describe UsersController do get :calendar_activities, username: user.username expect(response).to render_template('calendar_activities') end - - context 'when requesting the canonical path' do - let(:user) { create(:user, username: 'CamelCaseUser') } - - context 'with exactly matching casing' do - it 'responds with success' do - get :calendar_activities, username: user.username - - expect(response).to be_success - end - end - - context 'with different casing' do - it 'redirects to the correct casing' do - get :calendar_activities, username: user.username.downcase - - expect(response).to redirect_to(user_calendar_activities_path(user)) - expect(controller).not_to set_flash[:notice] - end - end - end - - context 'when requesting a redirected path' do - let(:redirect_route) { user.namespace.redirect_routes.create(path: 'old-username') } - - it 'redirects to the canonical path' do - get :calendar_activities, username: redirect_route.path - - expect(response).to redirect_to(user_calendar_activities_path(user)) - expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) - end - end end describe 'GET #snippets' do @@ -241,38 +141,6 @@ describe UsersController do expect(JSON.parse(response.body)).to have_key('html') end end - - context 'when requesting the canonical path' do - let(:user) { create(:user, username: 'CamelCaseUser') } - - context 'with exactly matching casing' do - it 'responds with success' do - get :snippets, username: user.username - - expect(response).to be_success - end - end - - context 'with different casing' do - it 'redirects to the correct casing' do - get :snippets, username: user.username.downcase - - expect(response).to redirect_to(user_snippets_path(user)) - expect(controller).not_to set_flash[:notice] - end - end - end - - context 'when requesting a redirected path' do - let(:redirect_route) { user.namespace.redirect_routes.create(path: 'old-username') } - - it 'redirects to the canonical path' do - get :snippets, username: redirect_route.path - - expect(response).to redirect_to(user_snippets_path(user)) - expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) - end - end end describe 'GET #exists' do @@ -321,6 +189,127 @@ describe UsersController do end end + describe '#ensure_canonical_path' do + before do + sign_in(user) + end + + context 'for a GET request' do + context 'when requesting users at the root path' do + context 'when requesting the canonical path' do + let(:user) { create(:user, username: 'CamelCaseUser') } + + context 'with exactly matching casing' do + it 'responds with success' do + get :show, username: user.username + + expect(response).to be_success + end + end + + context 'with different casing' do + it 'redirects to the correct casing' do + get :show, username: user.username.downcase + + expect(response).to redirect_to(user) + expect(controller).not_to set_flash[:notice] + end + end + end + + context 'when requesting a redirected path' do + let(:redirect_route) { user.namespace.redirect_routes.create(path: 'old-path') } + + it 'redirects to the canonical path' do + get :show, username: redirect_route.path + + expect(response).to redirect_to(user) + expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) + end + + context 'when the old path is a substring of the scheme or host' do + let(:redirect_route) { user.namespace.redirect_routes.create(path: 'http') } + + it 'does not modify the requested host' do + get :show, username: redirect_route.path + + expect(response).to redirect_to(user) + expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) + end + end + + context 'when the old path is substring of users' do + let(:redirect_route) { user.namespace.redirect_routes.create(path: 'ser') } + + it 'redirects to the canonical path' do + get :show, username: redirect_route.path + + expect(response).to redirect_to(user) + expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) + end + end + end + end + + context 'when requesting users under the /users path' do + context 'when requesting the canonical path' do + let(:user) { create(:user, username: 'CamelCaseUser') } + + context 'with exactly matching casing' do + it 'responds with success' do + get :projects, username: user.username + + expect(response).to be_success + end + end + + context 'with different casing' do + it 'redirects to the correct casing' do + get :projects, username: user.username.downcase + + expect(response).to redirect_to(user_projects_path(user)) + expect(controller).not_to set_flash[:notice] + end + end + end + + context 'when requesting a redirected path' do + let(:redirect_route) { user.namespace.redirect_routes.create(path: 'old-path') } + + it 'redirects to the canonical path' do + get :projects, username: redirect_route.path + + expect(response).to redirect_to(user_projects_path(user)) + expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) + end + + context 'when the old path is a substring of the scheme or host' do + let(:redirect_route) { user.namespace.redirect_routes.create(path: 'http') } + + it 'does not modify the requested host' do + get :projects, username: redirect_route.path + + expect(response).to redirect_to(user_projects_path(user)) + expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) + end + end + + context 'when the old path is substring of users' do + let(:redirect_route) { user.namespace.redirect_routes.create(path: 'ser') } + + # I.e. /users/ser should not become /ufoos/ser + it 'does not modify the /users part of the path' do + get :projects, username: redirect_route.path + + expect(response).to redirect_to(user_projects_path(user)) + expect(controller).to set_flash[:notice].to(user_moved_message(redirect_route, user)) + end + end + end + end + end + end + def user_moved_message(redirect_route, user) "User '#{redirect_route.path}' was moved to '#{user.full_path}'. Please update any links and bookmarks that may still have the old path." end -- cgit v1.2.1 From 7efa0aa02c1590b943028ef12056717b0b078e28 Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Thu, 18 May 2017 19:23:46 -0300 Subject: Remove unnecessary initial request --- spec/javascripts/vue_mr_widget/mr_widget_options_spec.js | 1 - 1 file changed, 1 deletion(-) (limited to 'spec') diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js index 22ee7dcf0e7..e7adb54dc95 100644 --- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js +++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js @@ -227,7 +227,6 @@ describe('mrWidgetOptions', () => { describe('handleMounted', () => { it('should call required methods to do the initial kick-off', () => { - spyOn(vm, 'checkStatus'); spyOn(vm, 'initDeploymentsPolling'); spyOn(vm, 'setFavicon'); -- cgit v1.2.1 From a355bcac4ba2fda77032f1cb7d88579f77a0ebe6 Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Thu, 18 May 2017 20:05:47 -0300 Subject: Stop loading MergeRequestEntity data on sidebar request --- spec/fixtures/api/schemas/entities/merge_request.json | 1 - spec/fixtures/api/schemas/entities/merge_request_basic.json | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'spec') diff --git a/spec/fixtures/api/schemas/entities/merge_request.json b/spec/fixtures/api/schemas/entities/merge_request.json index e5df3e7b6d1..4afbb87453e 100644 --- a/spec/fixtures/api/schemas/entities/merge_request.json +++ b/spec/fixtures/api/schemas/entities/merge_request.json @@ -3,7 +3,6 @@ "properties" : { "id": { "type": "integer" }, "iid": { "type": "integer" }, - "assignee_id": { "type": ["integer", "null"] }, "author_id": { "type": "integer" }, "description": { "type": ["string", "null"] }, "lock_version": { "type": ["string", "null"] }, diff --git a/spec/fixtures/api/schemas/entities/merge_request_basic.json b/spec/fixtures/api/schemas/entities/merge_request_basic.json index ea6364b878c..6b14188582a 100644 --- a/spec/fixtures/api/schemas/entities/merge_request_basic.json +++ b/spec/fixtures/api/schemas/entities/merge_request_basic.json @@ -8,7 +8,8 @@ "total_time_spent": { "type": "integer" }, "human_time_estimate": { "type": ["string", "null"] }, "human_total_time_spent": { "type": ["string", "null"] }, - "merge_error": { "type": ["string", "null"] } + "merge_error": { "type": ["string", "null"] }, + "assignee_id": { "type": ["integer", "null"] } }, "additionalProperties": false } -- cgit v1.2.1 From 92cdf78dcfa435673593088659790a5848152b9e Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Thu, 18 May 2017 21:15:17 -0300 Subject: Fix Karma expect --- spec/javascripts/vue_mr_widget/mr_widget_options_spec.js | 1 - 1 file changed, 1 deletion(-) (limited to 'spec') diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js index e7adb54dc95..bdc18243a15 100644 --- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js +++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js @@ -232,7 +232,6 @@ describe('mrWidgetOptions', () => { vm.handleMounted(); - expect(vm.checkStatus).toHaveBeenCalled(); expect(vm.setFavicon).toHaveBeenCalled(); expect(vm.initDeploymentsPolling).toHaveBeenCalled(); }); -- cgit v1.2.1 From 4070d58af75d74cad12247e2da095d5a8b92dc1f Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 18 May 2017 20:17:27 -0500 Subject: Don't copy empty elements that were not selected on purpose as GFM --- spec/features/copy_as_gfm_spec.rb | 3 --- 1 file changed, 3 deletions(-) (limited to 'spec') diff --git a/spec/features/copy_as_gfm_spec.rb b/spec/features/copy_as_gfm_spec.rb index be615519a09..b6c51569bdc 100644 --- a/spec/features/copy_as_gfm_spec.rb +++ b/spec/features/copy_as_gfm_spec.rb @@ -51,7 +51,6 @@ describe 'Copy as GFM', feature: true, js: true do To see how GitLab looks please see the [features page on our website](https://about.gitlab.com/features/). - - Manage Git repositories with fine grained access controls that keep your code secure - Perform code reviews and enhance collaboration with merge requests @@ -352,7 +351,6 @@ describe 'Copy as GFM', feature: true, js: true do <<-GFM.strip_heredoc, - Nested - - Lists GFM @@ -375,7 +373,6 @@ describe 'Copy as GFM', feature: true, js: true do <<-GFM.strip_heredoc, 1. Nested - 1. Numbered lists GFM -- cgit v1.2.1 From df5c3f364a3d415e35a2da462f044b08b854285b Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Thu, 18 May 2017 23:31:03 +0200 Subject: Rename users that had their namespace renamed --- .../rename_users_with_renamed_namespace_spec.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 spec/migrations/rename_users_with_renamed_namespace_spec.rb (limited to 'spec') diff --git a/spec/migrations/rename_users_with_renamed_namespace_spec.rb b/spec/migrations/rename_users_with_renamed_namespace_spec.rb new file mode 100644 index 00000000000..aefa539094f --- /dev/null +++ b/spec/migrations/rename_users_with_renamed_namespace_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20170518200835_rename_users_with_renamed_namespace.rb') + +describe RenameUsersWithRenamedNamespace, truncate: true do + it 'renames a user that had his namespace renamed to the namespace path' do + other_user = create(:user, username: 'kodingu') + + user = create(:user, username: "Users0") + user.update_attribute(:username, 'Users') + user1 = create(:user, username: "import0") + user1.update_attribute(:username, 'import') + + described_class.new.up + + expect(user.reload.username).to eq('Users0') + expect(user1.reload.username).to eq('import0') + expect(other_user.reload.username).to eq('kodingu') + end +end -- cgit v1.2.1 From 2792695cfa357c5d269dc3218195c33f5bc15d0a Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Thu, 18 May 2017 11:36:00 +0000 Subject: Make sorting difference clearer --- spec/controllers/projects/environments_controller_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'spec') diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index e783c60452f..93dbedae2b2 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -85,7 +85,7 @@ describe Projects::EnvironmentsController do name: 'staging-1.0/review', state: :available) create(:environment, project: project, - name: 'staging-1.0/preview', + name: 'staging-1.0/zzz', state: :available) end @@ -101,7 +101,7 @@ describe Projects::EnvironmentsController do end context 'when using JSON format' do - it 'responds with JSON' do + it 'responds with with a sorted JSON' do get :folder, namespace_id: project.namespace, project_id: project, id: 'staging-1.0', @@ -110,9 +110,9 @@ describe Projects::EnvironmentsController do expect(response).to be_ok expect(response).not_to render_template 'folder' expect(json_response['environments'][0]) - .to include('name' => 'staging-1.0/preview') - expect(json_response['environments'][1]) .to include('name' => 'staging-1.0/review') + expect(json_response['environments'][1]) + .to include('name' => 'staging-1.0/zzz') end end end -- cgit v1.2.1 From 3496476205a7361a39e714eb9df7ad321b525ea2 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 18 May 2017 12:56:02 -0500 Subject: Remove readme project_view option --- spec/migrations/migrate_user_project_view_spec.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/migrations/migrate_user_project_view_spec.rb b/spec/migrations/migrate_user_project_view_spec.rb index dacaa834aa9..70f8e0d6082 100644 --- a/spec/migrations/migrate_user_project_view_spec.rb +++ b/spec/migrations/migrate_user_project_view_spec.rb @@ -5,7 +5,12 @@ require Rails.root.join('db', 'post_migrate', '20170406142253_migrate_user_proje describe MigrateUserProjectView do let(:migration) { described_class.new } - let!(:user) { create(:user, project_view: 'readme') } + let!(:user) { create(:user) } + + before do + # 0 is the numeric value for the old 'readme' option + user.update_column(:project_view, 0) + end describe '#up' do it 'updates project view setting with new value' do -- cgit v1.2.1 From 9a15b112377e305bd55e2c539786aee7db569e29 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Fri, 19 May 2017 09:20:51 +0000 Subject: Fixes the 500 for custom apearance header logo and logo --- spec/controllers/uploads_controller_spec.rb | 40 +++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'spec') diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb index 7dedfe160a6..8000c9dec61 100644 --- a/spec/controllers/uploads_controller_spec.rb +++ b/spec/controllers/uploads_controller_spec.rb @@ -473,5 +473,45 @@ describe UploadsController do end end end + + context 'Appearance' do + context 'when viewing a custom header logo' do + let!(:appearance) { create :appearance, header_logo: fixture_file_upload(Rails.root.join('spec/fixtures/dk.png'), 'image/png') } + + context 'when not signed in' do + it 'responds with status 200' do + get :show, model: 'appearance', mounted_as: 'header_logo', id: appearance.id, filename: 'dk.png' + + expect(response).to have_http_status(200) + end + + it_behaves_like 'content not cached without revalidation' do + subject do + get :show, model: 'appearance', mounted_as: 'header_logo', id: appearance.id, filename: 'dk.png' + response + end + end + end + end + + context 'when viewing a custom logo' do + let!(:appearance) { create :appearance, logo: fixture_file_upload(Rails.root.join('spec/fixtures/dk.png'), 'image/png') } + + context 'when not signed in' do + it 'responds with status 200' do + get :show, model: 'appearance', mounted_as: 'logo', id: appearance.id, filename: 'dk.png' + + expect(response).to have_http_status(200) + end + + it_behaves_like 'content not cached without revalidation' do + subject do + get :show, model: 'appearance', mounted_as: 'logo', id: appearance.id, filename: 'dk.png' + response + end + end + end + end + end end end -- cgit v1.2.1 From 29c268ee4e21470cb7bbf13ce16b527b516225cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Fri, 19 May 2017 12:15:49 +0200 Subject: Enable RSpec profiling only if RSPEC_PROFILING_POSTGRES_URL is not empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- spec/spec_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e2d5928e5b2..a58f4e664b7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -10,7 +10,7 @@ require 'shoulda/matchers' require 'rspec/retry' rspec_profiling_is_configured = - ENV['RSPEC_PROFILING_POSTGRES_URL'] || + ENV['RSPEC_PROFILING_POSTGRES_URL'].present? || ENV['RSPEC_PROFILING'] branch_can_be_profiled = ENV['GITLAB_DATABASE'] == 'postgresql' && -- cgit v1.2.1 From 84f8cd1718857b4ee75fa6bd4b2fdb4879846bcf Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Fri, 19 May 2017 12:17:13 +0200 Subject: Fix incorrectly renamed routes --- spec/migrations/fix_wrongly_renamed_routes_spec.rb | 73 ++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 spec/migrations/fix_wrongly_renamed_routes_spec.rb (limited to 'spec') diff --git a/spec/migrations/fix_wrongly_renamed_routes_spec.rb b/spec/migrations/fix_wrongly_renamed_routes_spec.rb new file mode 100644 index 00000000000..148290b0e7d --- /dev/null +++ b/spec/migrations/fix_wrongly_renamed_routes_spec.rb @@ -0,0 +1,73 @@ +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20170518231126_fix_wrongly_renamed_routes.rb') + +describe FixWronglyRenamedRoutes, truncate: true do + let(:subject) { described_class.new } + let(:broken_namespace) do + namespace = create(:group, name: 'apiis') + namespace.route.update_attribute(:path, 'api0is') + namespace + end + + describe '#wrongly_renamed' do + it "includes routes that have names that don't match their namespace" do + broken_namespace + _other_namespace = create(:group, name: 'api0') + + expect(subject.wrongly_renamed.map(&:id)) + .to contain_exactly(broken_namespace.route.id) + end + end + + describe "#paths_and_corrections" do + it 'finds the wrong path and gets the correction from the namespace' do + broken_namespace + namespace = create(:group, name: 'uploads-test') + namespace.route.update_attribute(:path, 'uploads0-test') + + expected_result = [ + { 'namespace_path' => 'apiis', 'path' => 'api0is' }, + { 'namespace_path' => 'uploads-test', 'path' => 'uploads0-test' } + ] + + expect(subject.paths_and_corrections).to include(*expected_result) + end + end + + describe '#routes_in_namespace_query' do + it 'includes only the required routes' do + namespace = create(:group, path: 'hello') + project = create(:empty_project, namespace: namespace) + _other_namespace = create(:group, path: 'hello0') + + result = Route.where(subject.routes_in_namespace_query('hello')) + + expect(result).to contain_exactly(namespace.route, project.route) + end + end + + describe '#up' do + let(:broken_project) do + project = create(:empty_project, namespace: broken_namespace, path: 'broken-project') + project.route.update_attribute(:path, 'api0is/broken-project') + project + end + + it 'renames incorrectly named routes' do + broken_project + + subject.up + + expect(broken_project.route.reload.path).to eq('apiis/broken-project') + expect(broken_namespace.route.reload.path).to eq('apiis') + end + + it "doesn't touch namespaces that look like something that should be renamed" do + namespace = create(:group, path: 'api0') + + subject.up + + expect(namespace.route.reload.path).to eq('api0') + end + end +end -- cgit v1.2.1 From 3e08713c7975dc738b32e8b0e17651fbe3802ec2 Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Thu, 18 May 2017 22:30:51 -0300 Subject: Remove route --- spec/routing/project_routing_spec.rb | 5 ----- 1 file changed, 5 deletions(-) (limited to 'spec') diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index 50e96d56191..d5400bbaaf1 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -243,7 +243,6 @@ describe 'project routing' do # diffs_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/diffs(.:format) projects/merge_requests#diffs # commits_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/commits(.:format) projects/merge_requests#commits # merge_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/merge(.:format) projects/merge_requests#merge - # merge_check_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/merge_check(.:format) projects/merge_requests#merge_check # ci_status_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/ci_status(.:format) projects/merge_requests#ci_status # toggle_subscription_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/toggle_subscription(.:format) projects/merge_requests#toggle_subscription # branch_from_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/branch_from(.:format) projects/merge_requests#branch_from @@ -272,10 +271,6 @@ describe 'project routing' do ) end - it 'to #merge_check' do - expect(get('/gitlab/gitlabhq/merge_requests/1/merge_check')).to route_to('projects/merge_requests#merge_check', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') - end - it 'to #branch_from' do expect(get('/gitlab/gitlabhq/merge_requests/branch_from')).to route_to('projects/merge_requests#branch_from', namespace_id: 'gitlab', project_id: 'gitlabhq') end -- cgit v1.2.1 From b3cf3d046b8a319c0dbca7cb9aeaea027c080e6f Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Fri, 19 May 2017 10:19:04 -0300 Subject: Make sure fixture creation does not affect query count test --- spec/controllers/projects/merge_requests_controller_spec.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index 7fe2f190790..f0dc6df15ee 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -122,9 +122,12 @@ describe Projects::MergeRequestsController do context 'number of queries' do it 'verifies number of queries' do + # pre-create objects + merge_request + recorded = ActiveRecord::QueryRecorder.new { go(format: :json) } - expect(recorded.count).to be_within(1).of(94) + expect(recorded.count).to be_within(1).of(51) expect(recorded.cached_count).to eq(0) end end -- cgit v1.2.1 From 72d42944067d3137f4e9fdb6790835f26f15d73f Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Thu, 18 May 2017 14:52:40 -0500 Subject: Fix specs --- spec/features/merge_requests/form_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/features/merge_requests/form_spec.rb b/spec/features/merge_requests/form_spec.rb index f8518f450dc..00ef1ffdddc 100644 --- a/spec/features/merge_requests/form_spec.rb +++ b/spec/features/merge_requests/form_spec.rb @@ -90,7 +90,7 @@ describe 'New/edit merge request', feature: true, js: true do page.within '.issuable-meta' do merge_request = MergeRequest.find_by(source_branch: 'fix') - expect(page).to have_text("Merge Request #{merge_request.to_reference}") + expect(page).to have_text("Merge request #{merge_request.to_reference}") # compare paths because the host differ in test expect(find_link(merge_request.to_reference)[:href]) .to end_with(merge_request_path(merge_request)) -- cgit v1.2.1 From 682cfbb4dc328a8ffa597ddbb337673ed5dc844f Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Fri, 19 May 2017 01:37:53 -0500 Subject: Fix system note comparison and standardize note setup Fix https://gitlab.com/gitlab-org/gitlab-ce/issues/32551 --- spec/features/issues/note_polling_spec.rb | 24 ++++++++++++++++++++---- spec/javascripts/notes_spec.js | 1 + 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'spec') diff --git a/spec/features/issues/note_polling_spec.rb b/spec/features/issues/note_polling_spec.rb index da81fa4e367..80f57906506 100644 --- a/spec/features/issues/note_polling_spec.rb +++ b/spec/features/issues/note_polling_spec.rb @@ -31,12 +31,12 @@ feature 'Issue notes polling', :feature, :js do it 'has .original-note-content to compare against' do expect(page).to have_selector("#note_#{existing_note.id}", text: note_text) - expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", visible: false) + expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", count: 1, visible: false) update_note(existing_note, updated_text) expect(page).to have_selector("#note_#{existing_note.id}", text: updated_text) - expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", visible: false) + expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", count: 1, visible: false) end it 'displays the updated content' do @@ -98,12 +98,28 @@ feature 'Issue notes polling', :feature, :js do it 'has .original-note-content to compare against' do expect(page).to have_selector("#note_#{existing_note.id}", text: note_text) - expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", visible: false) + expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", count: 1, visible: false) update_note(existing_note, updated_text) expect(page).to have_selector("#note_#{existing_note.id}", text: updated_text) - expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", visible: false) + expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", count: 1, visible: false) + end + end + + context 'system notes' do + let(:user) { create(:user) } + let(:note_text) { "Some system note" } + let!(:system_note) { create(:system_note, noteable: issue, project: project, author: user, note: note_text) } + + before do + login_as(user) + visit namespace_project_issue_path(project.namespace, project, issue) + end + + it 'has .original-note-content to compare against' do + expect(page).to have_selector("#note_#{system_note.id}", text: note_text) + expect(page).to have_selector("#note_#{system_note.id} .original-note-content", count: 1, visible: false) end end end diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js index d3494aaa94f..025f08ee332 100644 --- a/spec/javascripts/notes_spec.js +++ b/spec/javascripts/notes_spec.js @@ -139,6 +139,7 @@ import '~/notes'; ]); notes = jasmine.createSpyObj('notes', [ + 'setupNewNote', 'refresh', 'collapseLongCommitList', 'updateNotesCount', -- cgit v1.2.1 From 51913c32bab12ec366cc3c529f2ed3d6699ee25e Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Fri, 19 May 2017 17:22:45 +0200 Subject: Simpler way of renaming users --- spec/migrations/rename_users_with_renamed_namespace_spec.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/migrations/rename_users_with_renamed_namespace_spec.rb b/spec/migrations/rename_users_with_renamed_namespace_spec.rb index aefa539094f..1e9aab3d9a1 100644 --- a/spec/migrations/rename_users_with_renamed_namespace_spec.rb +++ b/spec/migrations/rename_users_with_renamed_namespace_spec.rb @@ -2,8 +2,9 @@ require 'spec_helper' require Rails.root.join('db', 'post_migrate', '20170518200835_rename_users_with_renamed_namespace.rb') describe RenameUsersWithRenamedNamespace, truncate: true do - it 'renames a user that had his namespace renamed to the namespace path' do + it 'renames a user that had their namespace renamed to the namespace path' do other_user = create(:user, username: 'kodingu') + other_user1 = create(:user, username: 'api0') user = create(:user, username: "Users0") user.update_attribute(:username, 'Users') @@ -14,6 +15,8 @@ describe RenameUsersWithRenamedNamespace, truncate: true do expect(user.reload.username).to eq('Users0') expect(user1.reload.username).to eq('import0') + expect(other_user.reload.username).to eq('kodingu') + expect(other_user1.reload.username).to eq('api0') end end -- cgit v1.2.1 From 49697bc8df613dfe8e88f5f7cd8eae57e26c786f Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Thu, 18 May 2017 16:23:05 -0700 Subject: Refactor to more robust implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to avoid string manipulation or modify route params (to make them unambiguous for `url_for`), we are accepting a behavior change: When being redirected to the canonical path for a group, if you requested a group show path starting with `/groups/…` then you’ll now be redirected to the group at root `/…`. --- .../groups/milestones_controller_spec.rb | 135 ++++++++++++++++++++- spec/controllers/groups_controller_spec.rb | 41 ++++++- .../controllers/projects/labels_controller_spec.rb | 70 +++++++++++ spec/support/milestone_tabs_examples.rb | 2 +- 4 files changed, 239 insertions(+), 9 deletions(-) (limited to 'spec') diff --git a/spec/controllers/groups/milestones_controller_spec.rb b/spec/controllers/groups/milestones_controller_spec.rb index 7cf2996ffd0..f3263bc177d 100644 --- a/spec/controllers/groups/milestones_controller_spec.rb +++ b/spec/controllers/groups/milestones_controller_spec.rb @@ -21,7 +21,6 @@ describe Groups::MilestonesController do sign_in(user) group.add_owner(user) project.team << [user, :master] - controller.instance_variable_set(:@group, group) end it_behaves_like 'milestone tabs' @@ -29,7 +28,7 @@ describe Groups::MilestonesController do describe "#create" do it "creates group milestone with Chinese title" do post :create, - group_id: group.id, + group_id: group.to_param, milestone: { project_ids: [project.id, project2.id], title: title } expect(response).to redirect_to(group_milestone_path(group, title.to_slug.to_s, title: title)) @@ -37,9 +36,139 @@ describe Groups::MilestonesController do end it "redirects to new when there are no project ids" do - post :create, group_id: group.id, milestone: { title: title, project_ids: [""] } + post :create, group_id: group.to_param, milestone: { title: title, project_ids: [""] } expect(response).to render_template :new expect(assigns(:milestone).errors).not_to be_nil end end + + describe '#ensure_canonical_path' do + before do + sign_in(user) + end + + context 'for a GET request' do + context 'when requesting the canonical path' do + context 'non-show path' do + context 'with exactly matching casing' do + it 'does not redirect' do + get :index, group_id: group.to_param + + expect(response).not_to have_http_status(301) + end + end + + context 'with different casing' do + it 'redirects to the correct casing' do + get :index, group_id: group.to_param.upcase + + expect(response).to redirect_to(group_milestones_path(group.to_param)) + expect(controller).not_to set_flash[:notice] + end + end + end + + context 'show path' do + context 'with exactly matching casing' do + it 'does not redirect' do + get :show, group_id: group.to_param, id: title + + expect(response).not_to have_http_status(301) + end + end + + context 'with different casing' do + it 'redirects to the correct casing' do + get :show, group_id: group.to_param.upcase, id: title + + expect(response).to redirect_to(group_milestone_path(group.to_param, title)) + expect(controller).not_to set_flash[:notice] + end + end + end + end + + context 'when requesting a redirected path' do + let(:redirect_route) { group.redirect_routes.create(path: 'old-path') } + + it 'redirects to the canonical path' do + get :merge_requests, group_id: redirect_route.path, id: title + + expect(response).to redirect_to(merge_requests_group_milestone_path(group.to_param, title)) + expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) + end + + context 'when the old group path is a substring of the scheme or host' do + let(:redirect_route) { group.redirect_routes.create(path: 'http') } + + it 'does not modify the requested host' do + get :merge_requests, group_id: redirect_route.path, id: title + + expect(response).to redirect_to(merge_requests_group_milestone_path(group.to_param, title)) + expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) + end + end + + context 'when the old group path is substring of groups' do + # I.e. /groups/oups should not become /grfoo/oups + let(:redirect_route) { group.redirect_routes.create(path: 'oups') } + + it 'does not modify the /groups part of the path' do + get :merge_requests, group_id: redirect_route.path, id: title + + expect(response).to redirect_to(merge_requests_group_milestone_path(group.to_param, title)) + expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) + end + end + + context 'when the old group path is substring of groups plus the new path' do + # I.e. /groups/oups/oup should not become /grfoos + let(:redirect_route) { group.redirect_routes.create(path: 'oups/oup') } + + it 'does not modify the /groups part of the path' do + get :merge_requests, group_id: redirect_route.path, id: title + + expect(response).to redirect_to(merge_requests_group_milestone_path(group.to_param, title)) + expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group)) + end + end + end + end + end + + context 'for a non-GET request' do + context 'when requesting the canonical path with different casing' do + it 'does not 404' do + post :create, + group_id: group.to_param, + milestone: { project_ids: [project.id, project2.id], title: title } + + expect(response).not_to have_http_status(404) + end + + it 'does not redirect to the correct casing' do + post :create, + group_id: group.to_param, + milestone: { project_ids: [project.id, project2.id], title: title } + + expect(response).not_to have_http_status(301) + end + end + + context 'when requesting a redirected path' do + let(:redirect_route) { group.redirect_routes.create(path: 'old-path') } + + it 'returns not found' do + post :create, + group_id: redirect_route.path, + milestone: { project_ids: [project.id, project2.id], title: title } + + expect(response).to have_http_status(404) + end + end + end + + def group_moved_message(redirect_route, group) + "Group '#{redirect_route.path}' was moved to '#{group.full_path}'. Please update any links and bookmarks that may still have the old path." + end end diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb index 993654fddaa..4626f1ebc29 100644 --- a/spec/controllers/groups_controller_spec.rb +++ b/spec/controllers/groups_controller_spec.rb @@ -214,12 +214,43 @@ describe GroupsController do end context 'when requesting groups under the /groups path' do - context 'when requesting the canonical path with different casing' do - it 'redirects to the correct casing' do - get :issues, id: group.to_param.upcase + context 'when requesting the canonical path' do + context 'non-show path' do + context 'with exactly matching casing' do + it 'does not redirect' do + get :issues, id: group.to_param + + expect(response).not_to have_http_status(301) + end + end - expect(response).to redirect_to(issues_group_path(group.to_param)) - expect(controller).not_to set_flash[:notice] + context 'with different casing' do + it 'redirects to the correct casing' do + get :issues, id: group.to_param.upcase + + expect(response).to redirect_to(issues_group_path(group.to_param)) + expect(controller).not_to set_flash[:notice] + end + end + end + + context 'show path' do + context 'with exactly matching casing' do + it 'does not redirect' do + get :show, id: group.to_param + + expect(response).not_to have_http_status(301) + end + end + + context 'with different casing' do + it 'redirects to the correct casing at the root path' do + get :show, id: group.to_param.upcase + + expect(response).to redirect_to(group) + expect(controller).not_to set_flash[:notice] + end + end end end diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb index 05999431d8f..130b0b744b5 100644 --- a/spec/controllers/projects/labels_controller_spec.rb +++ b/spec/controllers/projects/labels_controller_spec.rb @@ -157,4 +157,74 @@ describe Projects::LabelsController do end end end + + describe '#ensure_canonical_path' do + before do + sign_in(user) + end + + context 'for a GET request' do + context 'when requesting the canonical path' do + context 'non-show path' do + context 'with exactly matching casing' do + it 'does not redirect' do + get :index, namespace_id: project.namespace, project_id: project.to_param + + expect(response).not_to have_http_status(301) + end + end + + context 'with different casing' do + it 'redirects to the correct casing' do + get :index, namespace_id: project.namespace, project_id: project.to_param.upcase + + expect(response).to redirect_to(namespace_project_labels_path(project.namespace, project)) + expect(controller).not_to set_flash[:notice] + end + end + end + end + + context 'when requesting a redirected path' do + let!(:redirect_route) { project.redirect_routes.create(path: project.full_path + 'old') } + + it 'redirects to the canonical path' do + get :index, namespace_id: project.namespace, project_id: project.to_param + 'old' + + expect(response).to redirect_to(namespace_project_labels_path(project.namespace, project)) + expect(controller).to set_flash[:notice].to(project_moved_message(redirect_route, project)) + end + end + end + end + + context 'for a non-GET request' do + context 'when requesting the canonical path with different casing' do + it 'does not 404' do + post :generate, namespace_id: project.namespace, project_id: project + + expect(response).not_to have_http_status(404) + end + + it 'does not redirect to the correct casing' do + post :generate, namespace_id: project.namespace, project_id: project + + expect(response).not_to have_http_status(301) + end + end + + context 'when requesting a redirected path' do + let!(:redirect_route) { project.redirect_routes.create(path: project.full_path + 'old') } + + it 'returns not found' do + post :generate, namespace_id: project.namespace, project_id: project.to_param + 'old' + + expect(response).to have_http_status(404) + end + end + end + + def project_moved_message(redirect_route, project) + "Project '#{redirect_route.path}' was moved to '#{project.full_path}'. Please update any links and bookmarks that may still have the old path." + end end diff --git a/spec/support/milestone_tabs_examples.rb b/spec/support/milestone_tabs_examples.rb index c69f8e11008..4ad8b0a16e1 100644 --- a/spec/support/milestone_tabs_examples.rb +++ b/spec/support/milestone_tabs_examples.rb @@ -1,7 +1,7 @@ shared_examples 'milestone tabs' do def go(path, extra_params = {}) params = if milestone.is_a?(GlobalMilestone) - { group_id: group.id, id: milestone.safe_title, title: milestone.title } + { group_id: group.to_param, id: milestone.safe_title, title: milestone.title } else { namespace_id: project.namespace.to_param, project_id: project, id: milestone.iid } end -- cgit v1.2.1 From a4014a4cc840681e4ed2aa496ad50600e1ac983c Mon Sep 17 00:00:00 2001 From: Kushal Pandya Date: Fri, 19 May 2017 17:08:07 +0000 Subject: Refine MR widget styling for buttons and info text --- .../vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js index 74df99415c9..d043ad38b8b 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js @@ -80,7 +80,7 @@ describe('MRWidgetReadyToMerge', () => { }); describe('mergeButtonClass', () => { - const defaultClass = 'btn btn-success accept-merge-request'; + const defaultClass = 'btn btn-small btn-success accept-merge-request'; const failedClass = `${defaultClass} btn-danger`; const inActionClass = `${defaultClass} btn-info`; -- cgit v1.2.1 From 49ded5c1fa31abf004d85f369e8b464879bbd781 Mon Sep 17 00:00:00 2001 From: Ruben Davila Date: Fri, 19 May 2017 13:35:08 -0500 Subject: Bugfix: don't redirect to JSON endpoints after sign in --- .../controllers/projects/issues_controller_spec.rb | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'spec') diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index 1f79e72495a..04afd07c59e 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -156,6 +156,32 @@ describe Projects::IssuesController do end end + describe 'Redirect after sign in' do + context 'with an AJAX request' do + it 'does not store the visited URL' do + xhr :get, + :show, + format: :json, + namespace_id: project.namespace, + project_id: project, + id: issue.iid + + expect(session['user_return_to']).to be_blank + end + end + + context 'without an AJAX request' do + it 'stores the visited URL' do + get :show, + namespace_id: project.namespace.to_param, + project_id: project, + id: issue.iid + + expect(session['user_return_to']).to eq("/#{project.namespace.to_param}/#{project.to_param}/issues/#{issue.iid}") + end + end + end + describe 'PUT #update' do before do sign_in(user) -- cgit v1.2.1 From f71a9de14d118fb14666df9f78365779308312e1 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Fri, 19 May 2017 20:42:05 +0200 Subject: Exclude manual actions from cancelable jobs scope --- spec/models/ci/pipeline_spec.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'spec') diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 157d17fbb68..56b24ce62f3 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -854,6 +854,16 @@ describe Ci::Pipeline, models: true do end end end + + context 'when there is a manual action present in the pipeline' do + before do + create(:ci_build, :manual, pipeline: pipeline) + end + + it 'is not cancelable' do + expect(pipeline).not_to be_cancelable + end + end end describe '#cancel_running' do -- cgit v1.2.1 From fa04b50b3c84e69765df7a0c9a182d9709ade398 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Fri, 19 May 2017 21:13:57 +0100 Subject: Read HEAD commit and use as releases value --- spec/javascripts/raven/index_spec.js | 19 ++++++++++--------- spec/javascripts/raven/raven_config_spec.js | 16 +++++++--------- 2 files changed, 17 insertions(+), 18 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/raven/index_spec.js b/spec/javascripts/raven/index_spec.js index b5662cd0331..e8fe6b32c43 100644 --- a/spec/javascripts/raven/index_spec.js +++ b/spec/javascripts/raven/index_spec.js @@ -2,18 +2,14 @@ import RavenConfig from '~/raven/raven_config'; import index from '~/raven/index'; describe('RavenConfig options', () => { - let sentryDsn; - let currentUserId; - let gitlabUrl; - let isProduction; + const sentryDsn = 'sentryDsn'; + const currentUserId = 'currentUserId'; + const gitlabUrl = 'gitlabUrl'; + const isProduction = 'isProduction'; + const headCommitSHA = 'headCommitSHA'; let indexReturnValue; beforeEach(() => { - sentryDsn = 'sentryDsn'; - currentUserId = 'currentUserId'; - gitlabUrl = 'gitlabUrl'; - isProduction = 'isProduction'; - window.gon = { sentry_dsn: sentryDsn, current_user_id: currentUserId, @@ -21,6 +17,7 @@ describe('RavenConfig options', () => { }; process.env.NODE_ENV = isProduction; + process.env.HEAD_COMMIT_SHA = headCommitSHA; spyOn(RavenConfig, 'init'); @@ -33,6 +30,10 @@ describe('RavenConfig options', () => { currentUserId, whitelistUrls: [gitlabUrl], isProduction, + release: headCommitSHA, + tags: { + HEAD_COMMIT_SHA: headCommitSHA, + }, }); }); diff --git a/spec/javascripts/raven/raven_config_spec.js b/spec/javascripts/raven/raven_config_spec.js index a2d720760fc..d2f4f9ac6fb 100644 --- a/spec/javascripts/raven/raven_config_spec.js +++ b/spec/javascripts/raven/raven_config_spec.js @@ -25,17 +25,9 @@ describe('RavenConfig', () => { }); describe('init', () => { - let options; + const options = {}; beforeEach(() => { - options = { - sentryDsn: '//sentryDsn', - ravenAssetUrl: '//ravenAssetUrl', - currentUserId: 1, - whitelistUrls: ['//gitlabUrl'], - isProduction: true, - }; - spyOn(RavenConfig, 'configure'); spyOn(RavenConfig, 'bindRavenErrors'); spyOn(RavenConfig, 'setUser'); @@ -84,6 +76,10 @@ describe('RavenConfig', () => { sentryDsn: '//sentryDsn', whitelistUrls: ['//gitlabUrl'], isProduction: true, + release: 'release', + tags: { + HEAD_COMMIT_SHA: 'headCommitSha', + }, }; ravenConfig = jasmine.createSpyObj('ravenConfig', ['shouldSendSample']); @@ -100,6 +96,8 @@ describe('RavenConfig', () => { it('should call Raven.config', () => { expect(Raven.config).toHaveBeenCalledWith(options.sentryDsn, { + release: options.release, + tags: options.tags, whitelistUrls: options.whitelistUrls, environment: 'production', ignoreErrors: ravenConfig.IGNORE_ERRORS, -- cgit v1.2.1 From 035b7cc0b339c5693697108bee17891cb4d41e68 Mon Sep 17 00:00:00 2001 From: Winnie Hellmann Date: Fri, 19 May 2017 21:22:46 +0000 Subject: Add users endpoint to frontend API class --- spec/javascripts/api_spec.js | 281 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 spec/javascripts/api_spec.js (limited to 'spec') diff --git a/spec/javascripts/api_spec.js b/spec/javascripts/api_spec.js new file mode 100644 index 00000000000..867322ce8ae --- /dev/null +++ b/spec/javascripts/api_spec.js @@ -0,0 +1,281 @@ +import Api from '~/api'; + +describe('Api', () => { + const dummyApiVersion = 'v3000'; + const dummyUrlRoot = 'http://host.invalid'; + const dummyGon = { + api_version: dummyApiVersion, + relative_url_root: dummyUrlRoot, + }; + const dummyResponse = 'hello from outer space!'; + const sendDummyResponse = () => { + const deferred = $.Deferred(); + deferred.resolve(dummyResponse); + return deferred.promise(); + }; + let originalGon; + + beforeEach(() => { + originalGon = window.gon; + window.gon = dummyGon; + }); + + afterEach(() => { + window.gon = originalGon; + }); + + describe('buildUrl', () => { + it('adds URL root and fills in API version', () => { + const input = '/api/:version/foo/bar'; + const expectedOutput = `${dummyUrlRoot}/api/${dummyApiVersion}/foo/bar`; + + const builtUrl = Api.buildUrl(input); + + expect(builtUrl).toEqual(expectedOutput); + }); + }); + + describe('group', () => { + it('fetches a group', (done) => { + const groupId = '123456'; + const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}.json`; + spyOn(jQuery, 'ajax').and.callFake((request) => { + expect(request.url).toEqual(expectedUrl); + expect(request.dataType).toEqual('json'); + return sendDummyResponse(); + }); + + Api.group(groupId, (response) => { + expect(response).toBe(dummyResponse); + done(); + }); + }); + }); + + describe('groups', () => { + it('fetches groups', (done) => { + const query = 'dummy query'; + const options = { unused: 'option' }; + const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups.json`; + const expectedData = Object.assign({ + search: query, + per_page: 20, + }, options); + spyOn(jQuery, 'ajax').and.callFake((request) => { + expect(request.url).toEqual(expectedUrl); + expect(request.dataType).toEqual('json'); + expect(request.data).toEqual(expectedData); + return sendDummyResponse(); + }); + + Api.groups(query, options, (response) => { + expect(response).toBe(dummyResponse); + done(); + }); + }); + }); + + describe('namespaces', () => { + it('fetches namespaces', (done) => { + const query = 'dummy query'; + const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/namespaces.json`; + const expectedData = { + search: query, + per_page: 20, + }; + spyOn(jQuery, 'ajax').and.callFake((request) => { + expect(request.url).toEqual(expectedUrl); + expect(request.dataType).toEqual('json'); + expect(request.data).toEqual(expectedData); + return sendDummyResponse(); + }); + + Api.namespaces(query, (response) => { + expect(response).toBe(dummyResponse); + done(); + }); + }); + }); + + describe('projects', () => { + it('fetches projects', (done) => { + const query = 'dummy query'; + const options = { unused: 'option' }; + const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects.json?simple=true`; + const expectedData = Object.assign({ + search: query, + per_page: 20, + membership: true, + }, options); + spyOn(jQuery, 'ajax').and.callFake((request) => { + expect(request.url).toEqual(expectedUrl); + expect(request.dataType).toEqual('json'); + expect(request.data).toEqual(expectedData); + return sendDummyResponse(); + }); + + Api.projects(query, options, (response) => { + expect(response).toBe(dummyResponse); + done(); + }); + }); + }); + + describe('newLabel', () => { + it('creates a new label', (done) => { + const namespace = 'some namespace'; + const project = 'some project'; + const labelData = { some: 'data' }; + const expectedUrl = `${dummyUrlRoot}/${namespace}/${project}/labels`; + const expectedData = { + label: labelData, + }; + spyOn(jQuery, 'ajax').and.callFake((request) => { + expect(request.url).toEqual(expectedUrl); + expect(request.dataType).toEqual('json'); + expect(request.type).toEqual('POST'); + expect(request.data).toEqual(expectedData); + return sendDummyResponse(); + }); + + Api.newLabel(namespace, project, labelData, (response) => { + expect(response).toBe(dummyResponse); + done(); + }); + }); + }); + + describe('groupProjects', () => { + it('fetches group projects', (done) => { + const groupId = '123456'; + const query = 'dummy query'; + const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}/projects.json`; + const expectedData = { + search: query, + per_page: 20, + }; + spyOn(jQuery, 'ajax').and.callFake((request) => { + expect(request.url).toEqual(expectedUrl); + expect(request.dataType).toEqual('json'); + expect(request.data).toEqual(expectedData); + return sendDummyResponse(); + }); + + Api.groupProjects(groupId, query, (response) => { + expect(response).toBe(dummyResponse); + done(); + }); + }); + }); + + describe('licenseText', () => { + it('fetches a license text', (done) => { + const licenseKey = "driver's license"; + const data = { unused: 'option' }; + const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/licenses/${licenseKey}`; + spyOn(jQuery, 'ajax').and.callFake((request) => { + expect(request.url).toEqual(expectedUrl); + expect(request.data).toEqual(data); + return sendDummyResponse(); + }); + + Api.licenseText(licenseKey, data, (response) => { + expect(response).toBe(dummyResponse); + done(); + }); + }); + }); + + describe('gitignoreText', () => { + it('fetches a gitignore text', (done) => { + const gitignoreKey = 'ignore git'; + const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/gitignores/${gitignoreKey}`; + spyOn(jQuery, 'get').and.callFake((url, callback) => { + expect(url).toEqual(expectedUrl); + callback(dummyResponse); + }); + + Api.gitignoreText(gitignoreKey, (response) => { + expect(response).toBe(dummyResponse); + done(); + }); + }); + }); + + describe('gitlabCiYml', () => { + it('fetches a .gitlab-ci.yml', (done) => { + const gitlabCiYmlKey = 'Y CI ML'; + const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/gitlab_ci_ymls/${gitlabCiYmlKey}`; + spyOn(jQuery, 'get').and.callFake((url, callback) => { + expect(url).toEqual(expectedUrl); + callback(dummyResponse); + }); + + Api.gitlabCiYml(gitlabCiYmlKey, (response) => { + expect(response).toBe(dummyResponse); + done(); + }); + }); + }); + + describe('dockerfileYml', () => { + it('fetches a Dockerfile', (done) => { + const dockerfileYmlKey = 'a giant whale'; + const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/dockerfiles/${dockerfileYmlKey}`; + spyOn(jQuery, 'get').and.callFake((url, callback) => { + expect(url).toEqual(expectedUrl); + callback(dummyResponse); + }); + + Api.dockerfileYml(dockerfileYmlKey, (response) => { + expect(response).toBe(dummyResponse); + done(); + }); + }); + }); + + describe('issueTemplate', () => { + it('fetches an issue template', (done) => { + const namespace = 'some namespace'; + const project = 'some project'; + const templateKey = 'template key'; + const templateType = 'template type'; + const expectedUrl = `${dummyUrlRoot}/${namespace}/${project}/templates/${templateType}/${templateKey}`; + spyOn(jQuery, 'ajax').and.callFake((request) => { + expect(request.url).toEqual(expectedUrl); + return sendDummyResponse(); + }); + + Api.issueTemplate(namespace, project, templateKey, templateType, (error, response) => { + expect(error).toBe(null); + expect(response).toBe(dummyResponse); + done(); + }); + }); + }); + + describe('users', () => { + it('fetches users', (done) => { + const query = 'dummy query'; + const options = { unused: 'option' }; + const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/users.json`; + const expectedData = Object.assign({ + search: query, + per_page: 20, + }, options); + spyOn(jQuery, 'ajax').and.callFake((request) => { + expect(request.url).toEqual(expectedUrl); + expect(request.dataType).toEqual('json'); + expect(request.data).toEqual(expectedData); + return sendDummyResponse(); + }); + + Api.users(query, options) + .then((response) => { + expect(response).toBe(dummyResponse); + }) + .then(done) + .catch(done.fail); + }); + }); +}); -- cgit v1.2.1 From 28ffb4bf2fd7544722b596ad3339a149ae9a46d2 Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Fri, 19 May 2017 22:51:52 -0300 Subject: Handle transient MR query count spec --- spec/controllers/projects/merge_requests_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index f0dc6df15ee..457e07334b9 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -127,7 +127,7 @@ describe Projects::MergeRequestsController do recorded = ActiveRecord::QueryRecorder.new { go(format: :json) } - expect(recorded.count).to be_within(1).of(51) + expect(recorded.count).to be_within(5).of(50) expect(recorded.cached_count).to eq(0) end end -- cgit v1.2.1 From ef73fe300c047d659c5bb665f200531efa95ac0b Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Sun, 21 May 2017 13:38:03 +0100 Subject: Use Gitlab::REVISION over reading HEAD sha from git --- spec/javascripts/raven/index_spec.js | 9 ++++---- spec/javascripts/raven/raven_config_spec.js | 36 ++++++++++++++--------------- 2 files changed, 22 insertions(+), 23 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/raven/index_spec.js b/spec/javascripts/raven/index_spec.js index e8fe6b32c43..a503a54029f 100644 --- a/spec/javascripts/raven/index_spec.js +++ b/spec/javascripts/raven/index_spec.js @@ -6,7 +6,7 @@ describe('RavenConfig options', () => { const currentUserId = 'currentUserId'; const gitlabUrl = 'gitlabUrl'; const isProduction = 'isProduction'; - const headCommitSHA = 'headCommitSHA'; + const revision = 'revision'; let indexReturnValue; beforeEach(() => { @@ -14,10 +14,11 @@ describe('RavenConfig options', () => { sentry_dsn: sentryDsn, current_user_id: currentUserId, gitlab_url: gitlabUrl, + revision, }; process.env.NODE_ENV = isProduction; - process.env.HEAD_COMMIT_SHA = headCommitSHA; + process.env.HEAD_COMMIT_SHA = revision; spyOn(RavenConfig, 'init'); @@ -30,9 +31,9 @@ describe('RavenConfig options', () => { currentUserId, whitelistUrls: [gitlabUrl], isProduction, - release: headCommitSHA, + release: revision, tags: { - HEAD_COMMIT_SHA: headCommitSHA, + revision, }, }); }); diff --git a/spec/javascripts/raven/raven_config_spec.js b/spec/javascripts/raven/raven_config_spec.js index d2f4f9ac6fb..b31a7c28ebe 100644 --- a/spec/javascripts/raven/raven_config_spec.js +++ b/spec/javascripts/raven/raven_config_spec.js @@ -25,7 +25,9 @@ describe('RavenConfig', () => { }); describe('init', () => { - const options = {}; + const options = { + currentUserId: 1, + }; beforeEach(() => { spyOn(RavenConfig, 'configure'); @@ -54,34 +56,28 @@ describe('RavenConfig', () => { it('should not call setUser if there is no current user ID', () => { RavenConfig.setUser.calls.reset(); - RavenConfig.init({ - sentryDsn: '//sentryDsn', - ravenAssetUrl: '//ravenAssetUrl', - currentUserId: undefined, - whitelistUrls: ['//gitlabUrl'], - isProduction: true, - }); + options.currentUserId = undefined; + + RavenConfig.init(options); expect(RavenConfig.setUser).not.toHaveBeenCalled(); }); }); describe('configure', () => { - let options; let raven; let ravenConfig; + const options = { + sentryDsn: '//sentryDsn', + whitelistUrls: ['//gitlabUrl'], + isProduction: true, + release: 'revision', + tags: { + revision: 'revision', + }, + }; beforeEach(() => { - options = { - sentryDsn: '//sentryDsn', - whitelistUrls: ['//gitlabUrl'], - isProduction: true, - release: 'release', - tags: { - HEAD_COMMIT_SHA: 'headCommitSha', - }, - }; - ravenConfig = jasmine.createSpyObj('ravenConfig', ['shouldSendSample']); raven = jasmine.createSpyObj('raven', ['install']); @@ -116,6 +112,8 @@ describe('RavenConfig', () => { RavenConfig.configure.call(ravenConfig); expect(Raven.config).toHaveBeenCalledWith(options.sentryDsn, { + release: options.release, + tags: options.tags, whitelistUrls: options.whitelistUrls, environment: 'development', ignoreErrors: ravenConfig.IGNORE_ERRORS, -- cgit v1.2.1 From c102656736ad4d8ea24b66b93a76234cff11e4bb Mon Sep 17 00:00:00 2001 From: winh Date: Tue, 16 May 2017 12:01:23 +0200 Subject: Extract Cache class from AjaxCache --- spec/javascripts/lib/utils/cache_spec.js | 65 ++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 spec/javascripts/lib/utils/cache_spec.js (limited to 'spec') diff --git a/spec/javascripts/lib/utils/cache_spec.js b/spec/javascripts/lib/utils/cache_spec.js new file mode 100644 index 00000000000..2fe02a7592c --- /dev/null +++ b/spec/javascripts/lib/utils/cache_spec.js @@ -0,0 +1,65 @@ +import Cache from '~/lib/utils/cache'; + +describe('Cache', () => { + const dummyKey = 'just some key'; + const dummyValue = 'more than a value'; + let cache; + + beforeEach(() => { + cache = new Cache(); + }); + + describe('get', () => { + it('return cached data', () => { + cache.internalStorage[dummyKey] = dummyValue; + + expect(cache.get(dummyKey)).toBe(dummyValue); + }); + + it('returns undefined for missing data', () => { + expect(cache.internalStorage[dummyKey]).toBe(undefined); + expect(cache.get(dummyKey)).toBe(undefined); + }); + }); + + describe('hasData', () => { + it('return true for cached data', () => { + cache.internalStorage[dummyKey] = dummyValue; + + expect(cache.hasData(dummyKey)).toBe(true); + }); + + it('returns false for missing data', () => { + expect(cache.internalStorage[dummyKey]).toBe(undefined); + expect(cache.hasData(dummyKey)).toBe(false); + }); + }); + + describe('remove', () => { + it('removes data from cache', () => { + cache.internalStorage[dummyKey] = dummyValue; + + cache.remove(dummyKey); + + expect(cache.internalStorage[dummyKey]).toBe(undefined); + }); + + it('does nothing for missing data', () => { + expect(cache.internalStorage[dummyKey]).toBe(undefined); + + cache.remove(dummyKey); + + expect(cache.internalStorage[dummyKey]).toBe(undefined); + }); + + it('does not remove wrong data', () => { + cache.internalStorage[dummyKey] = dummyValue; + cache.internalStorage[dummyKey + dummyKey] = dummyValue + dummyValue; + + cache.remove(dummyKey); + + expect(cache.internalStorage[dummyKey]).toBe(undefined); + expect(cache.internalStorage[dummyKey + dummyKey]).toBe(dummyValue + dummyValue); + }); + }); +}); -- cgit v1.2.1 From 2b0dd7183a51dc91f722e216b6fe4ca6e427a1b9 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Mon, 22 May 2017 10:49:44 +0200 Subject: Change pipelines schedules help page path --- spec/features/projects/pipeline_schedules_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index 03a30bfb996..1211b17b3d8 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -38,7 +38,7 @@ feature 'Pipeline Schedules', :feature do end it 'creates a new scheduled pipeline' do - click_link 'New Schedule' + click_link 'New schedule' expect(page).to have_content('Schedule a new pipeline') end -- cgit v1.2.1 From 5d63a3939551116cd277ab4d32743146490a5e68 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 22 May 2017 17:55:58 +0800 Subject: Add a test to ensure this works on MySQL --- spec/migrations/update_retried_for_ci_builds_spec.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 spec/migrations/update_retried_for_ci_builds_spec.rb (limited to 'spec') diff --git a/spec/migrations/update_retried_for_ci_builds_spec.rb b/spec/migrations/update_retried_for_ci_builds_spec.rb new file mode 100644 index 00000000000..5cdb8a3c7da --- /dev/null +++ b/spec/migrations/update_retried_for_ci_builds_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20170503004427_upate_retried_for_ci_build.rb') + +describe UpateRetriedForCiBuild, truncate: true do + let(:pipeline) { create(:ci_pipeline) } + let!(:build_old) { create(:ci_build, pipeline: pipeline, name: 'test') } + let!(:build_new) { create(:ci_build, pipeline: pipeline, name: 'test') } + + before do + described_class.new.up + end + + it 'updates ci_builds.is_retried' do + expect(build_old.reload).to be_retried + expect(build_new.reload).not_to be_retried + end +end -- cgit v1.2.1 From cbafe24a1fef2c13925490453cb97c3831d03169 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 22 May 2017 18:42:14 +0800 Subject: Respect the typo as rubocop said --- spec/migrations/upate_retried_for_ci_builds_spec.rb | 17 +++++++++++++++++ spec/migrations/update_retried_for_ci_builds_spec.rb | 17 ----------------- 2 files changed, 17 insertions(+), 17 deletions(-) create mode 100644 spec/migrations/upate_retried_for_ci_builds_spec.rb delete mode 100644 spec/migrations/update_retried_for_ci_builds_spec.rb (limited to 'spec') diff --git a/spec/migrations/upate_retried_for_ci_builds_spec.rb b/spec/migrations/upate_retried_for_ci_builds_spec.rb new file mode 100644 index 00000000000..5cdb8a3c7da --- /dev/null +++ b/spec/migrations/upate_retried_for_ci_builds_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20170503004427_upate_retried_for_ci_build.rb') + +describe UpateRetriedForCiBuild, truncate: true do + let(:pipeline) { create(:ci_pipeline) } + let!(:build_old) { create(:ci_build, pipeline: pipeline, name: 'test') } + let!(:build_new) { create(:ci_build, pipeline: pipeline, name: 'test') } + + before do + described_class.new.up + end + + it 'updates ci_builds.is_retried' do + expect(build_old.reload).to be_retried + expect(build_new.reload).not_to be_retried + end +end diff --git a/spec/migrations/update_retried_for_ci_builds_spec.rb b/spec/migrations/update_retried_for_ci_builds_spec.rb deleted file mode 100644 index 5cdb8a3c7da..00000000000 --- a/spec/migrations/update_retried_for_ci_builds_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20170503004427_upate_retried_for_ci_build.rb') - -describe UpateRetriedForCiBuild, truncate: true do - let(:pipeline) { create(:ci_pipeline) } - let!(:build_old) { create(:ci_build, pipeline: pipeline, name: 'test') } - let!(:build_new) { create(:ci_build, pipeline: pipeline, name: 'test') } - - before do - described_class.new.up - end - - it 'updates ci_builds.is_retried' do - expect(build_old.reload).to be_retried - expect(build_new.reload).not_to be_retried - end -end -- cgit v1.2.1 From b3095251c4bd620e85cb22f9fc8b8c75bcbed4d4 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 23 May 2017 00:25:26 +0800 Subject: Make sure that Arel.sql would work for update_column_in_batches --- spec/lib/gitlab/database/migration_helpers_spec.rb | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'spec') diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index dfa3ae9142e..bd5ac6142be 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -247,6 +247,14 @@ describe Gitlab::Database::MigrationHelpers, lib: true do expect(Project.where(archived: true).count).to eq(1) end end + + context 'when the value is Arel.sql (Arel::Nodes::SqlLiteral)' do + it 'updates the value as a SQL expression' do + model.update_column_in_batches(:projects, :star_count, Arel.sql('1+1')) + + expect(Project.sum(:star_count)).to eq(2 * Project.count) + end + end end describe '#add_column_with_default' do -- cgit v1.2.1 From 42604d4c33e6098ba696d464c9a7b3d16656bf54 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 9 May 2017 10:09:20 -0500 Subject: Prevent project transfer if a new group is not selected --- spec/controllers/projects_controller_spec.rb | 45 +++++++++++++++++++++++++ spec/services/projects/transfer_service_spec.rb | 1 + 2 files changed, 46 insertions(+) (limited to 'spec') diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index a8be6768a47..f117598555b 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -226,6 +226,51 @@ describe ProjectsController do end end + describe '#transfer' do + render_views + + subject(:project) { create(:project) } + let(:admin) { create(:admin) } + let(:new_namespace) { create(:namespace) } + + it 'updates namespace' do + controller.instance_variable_set(:@project, project) + sign_in(admin) + + put :transfer, + namespace_id: project.namespace.id, + new_namespace_id: new_namespace.id, + id: project.id, + format: :js + + project.reload + + expect(project.namespace.id).to eq(new_namespace.id) + expect(response).to have_http_status(200) + end + + context 'when new namespace is empty' do + it 'project namespace is not changed' do + controller.instance_variable_set(:@project, project) + sign_in(admin) + + old_namespace_id = project.namespace.id + + put :transfer, + namespace_id: old_namespace_id, + new_namespace_id: nil, + id: project.id, + format: :js + + project.reload + + expect(project.namespace.id).to eq(old_namespace_id) + expect(response).to have_http_status(200) + expect(flash[:alert]).to eq 'Please select a namespace to transfer the project to' + end + end + end + describe "#destroy" do let(:admin) { create(:admin) } diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb index 29ccce59c53..5c872047bdf 100644 --- a/spec/services/projects/transfer_service_spec.rb +++ b/spec/services/projects/transfer_service_spec.rb @@ -26,6 +26,7 @@ describe Projects::TransferService, services: true do it { expect(@result).to eq false } it { expect(project.namespace).to eq(user.namespace) } + it { expect(project.errors.messages[:new_namespace][0]).to eq 'Please select a namespace to transfer the project to' } end context 'disallow transfering of project with tags' do -- cgit v1.2.1 From fbde5e33134df144208840f977a74f346acf450a Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 16 May 2017 11:41:50 -0500 Subject: Renamed some messages and refactored the project_edit class to a function --- spec/controllers/projects_controller_spec.rb | 2 +- spec/services/projects/transfer_service_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'spec') diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index f117598555b..5f9c747634c 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -266,7 +266,7 @@ describe ProjectsController do expect(project.namespace.id).to eq(old_namespace_id) expect(response).to have_http_status(200) - expect(flash[:alert]).to eq 'Please select a namespace to transfer the project to' + expect(flash[:alert]).to eq 'Please select a new namespace for your project.' end end end diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb index 5c872047bdf..2bddb6f3e42 100644 --- a/spec/services/projects/transfer_service_spec.rb +++ b/spec/services/projects/transfer_service_spec.rb @@ -26,7 +26,7 @@ describe Projects::TransferService, services: true do it { expect(@result).to eq false } it { expect(project.namespace).to eq(user.namespace) } - it { expect(project.errors.messages[:new_namespace][0]).to eq 'Please select a namespace to transfer the project to' } + it { expect(project.errors.messages[:new_namespace][0]).to eq 'Please select a new namespace for your project.' } end context 'disallow transfering of project with tags' do -- cgit v1.2.1 From 921c2be44af6a5a2af2b6e17945f0301c8158214 Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Fri, 19 May 2017 17:51:07 -0300 Subject: Add transient head_pipeline_of to pipeline factories --- .../projects/merge_requests_controller_spec.rb | 7 +++---- spec/factories/ci/pipelines.rb | 9 +++++++++ spec/features/cycle_analytics_spec.rb | 3 +-- .../merge_when_pipeline_succeeds_spec.rb | 4 ++-- .../only_allow_merge_if_build_succeeds_spec.rb | 4 +--- spec/features/merge_requests/widget_spec.rb | 18 +++++++----------- spec/lib/gitlab/cycle_analytics/events_spec.rb | 10 ++++------ spec/models/cycle_analytics/test_spec.rb | 3 +-- spec/models/merge_request_spec.rb | 8 +++----- spec/requests/projects/cycle_analytics_events_spec.rb | 3 +-- .../merge_when_pipeline_succeeds_service_spec.rb | 12 ++++-------- spec/services/merge_requests/update_service_spec.rb | 11 ++++++----- 12 files changed, 42 insertions(+), 50 deletions(-) (limited to 'spec') diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index 0b3492a8fed..86ca74a898a 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -345,8 +345,7 @@ describe Projects::MergeRequestsController do end before do - pipeline = create(:ci_empty_pipeline, project: project, sha: merge_request.diff_head_sha, ref: merge_request.source_branch) - merge_request.update(head_pipeline: pipeline) + create(:ci_empty_pipeline, project: project, sha: merge_request.diff_head_sha, ref: merge_request.source_branch, head_pipeline_of: merge_request) end it 'returns :merge_when_pipeline_succeeds' do @@ -1161,13 +1160,13 @@ describe Projects::MergeRequestsController do let!(:pipeline) do create(:ci_pipeline, project: merge_request.source_project, ref: merge_request.source_branch, - sha: merge_request.diff_head_sha) + sha: merge_request.diff_head_sha, + head_pipeline_of: merge_request) end let(:status) { pipeline.detailed_status(double('user')) } before do - merge_request.update(head_pipeline: pipeline) get_pipeline_status end diff --git a/spec/factories/ci/pipelines.rb b/spec/factories/ci/pipelines.rb index 561fbc8e247..361c5b9a49e 100644 --- a/spec/factories/ci/pipelines.rb +++ b/spec/factories/ci/pipelines.rb @@ -20,6 +20,15 @@ FactoryGirl.define do end end + # Persist merge request head_pipeline_id + # on pipeline factories to avoid circular references + transient { head_pipeline_of nil } + + after(:create) do |pipeline, evaluator| + merge_request = evaluator.head_pipeline_of + merge_request&.update(head_pipeline: pipeline) + end + factory :ci_pipeline do transient { config nil } diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb index cbeb73d9cae..1c829e91c20 100644 --- a/spec/features/cycle_analytics_spec.rb +++ b/spec/features/cycle_analytics_spec.rb @@ -7,7 +7,7 @@ feature 'Cycle Analytics', feature: true, js: true do let(:issue) { create(:issue, project: project, created_at: 2.days.ago) } let(:milestone) { create(:milestone, project: project) } let(:mr) { create_merge_request_closing_issue(issue, commit_message: "References #{issue.to_reference}") } - let(:pipeline) { create(:ci_empty_pipeline, status: 'created', project: project, ref: mr.source_branch, sha: mr.source_branch_sha) } + let(:pipeline) { create(:ci_empty_pipeline, status: 'created', project: project, ref: mr.source_branch, sha: mr.source_branch_sha, head_pipeline_of: mr) } context 'as an allowed user' do context 'when project is new' do @@ -33,7 +33,6 @@ feature 'Cycle Analytics', feature: true, js: true do context "when there's cycle analytics data" do before do allow_any_instance_of(Gitlab::ReferenceExtractor).to receive(:issues).and_return([issue]) - mr.update(head_pipeline: pipeline) project.add_master(user) create_cycle diff --git a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb index 11b6f0c0a64..e08721b4724 100644 --- a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb +++ b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb @@ -13,12 +13,12 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do let(:pipeline) do create(:ci_pipeline, project: project, sha: merge_request.diff_head_sha, - ref: merge_request.source_branch) + ref: merge_request.source_branch, + head_pipeline_of: merge_request) end before do project.add_master(user) - merge_request.update(head_pipeline_id: pipeline.id) end context 'when there is active pipeline for merge request' do diff --git a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb index cdda0542c51..63a4f4d90b4 100644 --- a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb +++ b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb @@ -28,11 +28,9 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu project: project, sha: merge_request.diff_head_sha, ref: merge_request.source_branch, - status: status) + status: status, head_pipeline_of: merge_request) end - before { merge_request.update(head_pipeline: pipeline) } - context 'when merge requests can only be merged if the pipeline succeeds' do before do project.update_attribute(:only_allow_merge_if_pipeline_succeeds, true) diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb index ae799584c0f..9b182cc05b9 100644 --- a/spec/features/merge_requests/widget_spec.rb +++ b/spec/features/merge_requests/widget_spec.rb @@ -88,11 +88,10 @@ describe 'Merge request', :feature, :js do sha: merge_request.diff_head_sha, ref: merge_request.source_branch, status: 'failed', - statuses: [commit_status]) + statuses: [commit_status], + head_pipeline_of: merge_request) create(:ci_build, :pending, pipeline: pipeline) - merge_request.update(head_pipeline: pipeline) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) end @@ -105,15 +104,13 @@ describe 'Merge request', :feature, :js do context 'when merge request is in the blocked pipeline state' do before do - pipeline = create( + create( :ci_pipeline, project: project, sha: merge_request.diff_head_sha, ref: merge_request.source_branch, - status: :manual - ) - - merge_request.update(head_pipeline: pipeline) + status: :manual, + head_pipeline_of: merge_request) visit namespace_project_merge_request_path(project.namespace, project, @@ -135,11 +132,10 @@ describe 'Merge request', :feature, :js do sha: merge_request.diff_head_sha, ref: merge_request.source_branch, status: 'pending', - statuses: [commit_status]) + statuses: [commit_status], + head_pipeline_of: merge_request) create(:ci_build, :pending, pipeline: pipeline) - merge_request.update(head_pipeline: pipeline) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) end diff --git a/spec/lib/gitlab/cycle_analytics/events_spec.rb b/spec/lib/gitlab/cycle_analytics/events_spec.rb index 3610a0354e8..a1b3fe8509e 100644 --- a/spec/lib/gitlab/cycle_analytics/events_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/events_spec.rb @@ -126,12 +126,11 @@ describe 'cycle analytics events' do create(:ci_pipeline, ref: merge_request.source_branch, sha: merge_request.diff_head_sha, - project: context.project) + project: context.project, + head_pipeline_of: merge_request) end before do - merge_request.update(head_pipeline: pipeline) - create(:ci_build, pipeline: pipeline, status: :success, author: user) create(:ci_build, pipeline: pipeline, status: :success, author: user) @@ -224,12 +223,11 @@ describe 'cycle analytics events' do create(:ci_pipeline, ref: merge_request.source_branch, sha: merge_request.diff_head_sha, - project: context.project) + project: context.project, + head_pipeline_of: merge_request) end before do - merge_request.update(head_pipeline: pipeline) - create(:ci_build, pipeline: pipeline, status: :success, author: user) create(:ci_build, pipeline: pipeline, status: :success, author: user) diff --git a/spec/models/cycle_analytics/test_spec.rb b/spec/models/cycle_analytics/test_spec.rb index d0b919efcf9..fd58bd1d6ad 100644 --- a/spec/models/cycle_analytics/test_spec.rb +++ b/spec/models/cycle_analytics/test_spec.rb @@ -13,8 +13,7 @@ describe 'CycleAnalytics#test', feature: true do data_fn: lambda do |context| issue = context.create(:issue, project: context.project) merge_request = context.create_merge_request_closing_issue(issue) - pipeline = context.create(:ci_pipeline, ref: merge_request.source_branch, sha: merge_request.diff_head_sha, project: context.project) - merge_request.update(head_pipeline: pipeline) + pipeline = context.create(:ci_pipeline, ref: merge_request.source_branch, sha: merge_request.diff_head_sha, project: context.project, head_pipeline_of: merge_request) { pipeline: pipeline, issue: issue } end, start_time_conditions: [["pipeline is started", -> (context, data) { data[:pipeline].run! }]], diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index ce870fcc1d3..0e05f719499 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -718,8 +718,7 @@ describe MergeRequest, models: true do describe '#head_pipeline' do describe 'when the source project exists' do it 'returns the latest pipeline' do - pipeline = create(:ci_empty_pipeline, project: subject.source_project, ref: 'master', status: 'running', sha: "123abc") - subject.update(head_pipeline: pipeline) + pipeline = create(:ci_empty_pipeline, project: subject.source_project, ref: 'master', status: 'running', sha: "123abc", head_pipeline_of: subject) expect(subject.head_pipeline).to eq(pipeline) end @@ -1396,9 +1395,8 @@ describe MergeRequest, models: true do project: project, ref: merge_request.source_branch, sha: merge_request.diff_head_sha, - status: status) - - merge_request.update(head_pipeline: pipeline) + status: status, + head_pipeline_of: merge_request) pipeline end diff --git a/spec/requests/projects/cycle_analytics_events_spec.rb b/spec/requests/projects/cycle_analytics_events_spec.rb index d92daa345b3..d4d3c9478a0 100644 --- a/spec/requests/projects/cycle_analytics_events_spec.rb +++ b/spec/requests/projects/cycle_analytics_events_spec.rb @@ -121,8 +121,7 @@ describe 'cycle analytics events', api: true do issue.update(milestone: milestone) mr = create_merge_request_closing_issue(issue, commit_message: "References #{issue.to_reference}") - pipeline = create(:ci_empty_pipeline, status: 'created', project: project, ref: mr.source_branch, sha: mr.source_branch_sha) - mr.update(head_pipeline_id: pipeline.id) + pipeline = create(:ci_empty_pipeline, status: 'created', project: project, ref: mr.source_branch, sha: mr.source_branch_sha, head_pipeline_of: mr) pipeline.run create(:ci_build, pipeline: pipeline, status: :success, author: user) diff --git a/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb b/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb index 3ef5135e6a3..f17db70faf6 100644 --- a/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb +++ b/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb @@ -79,11 +79,8 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do context 'when triggered by pipeline with valid ref and sha' do let(:triggering_pipeline) do create(:ci_pipeline, project: project, ref: merge_request_ref, - sha: merge_request_head, status: 'success') - end - - before do - mr_merge_if_green_enabled.update(head_pipeline: triggering_pipeline) + sha: merge_request_head, status: 'success', + head_pipeline_of: mr_merge_if_green_enabled) end it "merges all merge requests with merge when the pipeline succeeds enabled" do @@ -125,11 +122,10 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do let(:conflict_pipeline) do create(:ci_pipeline, project: project, ref: mr_conflict.source_branch, - sha: mr_conflict.diff_head_sha, status: 'success') + sha: mr_conflict.diff_head_sha, status: 'success', + head_pipeline_of: mr_conflict) end - before { mr_conflict.update(head_pipeline: conflict_pipeline) } - it 'does not merge the merge request' do expect(MergeWorker).not_to receive(:perform_async) diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index 860a7798857..d371fc68312 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -180,12 +180,13 @@ describe MergeRequests::UpdateService, services: true do context 'with active pipeline' do before do service_mock = double - pipeline = create(:ci_pipeline_with_one_job, + create( + :ci_pipeline_with_one_job, project: project, - ref: merge_request.source_branch, - sha: merge_request.diff_head_sha) - - merge_request.update(head_pipeline: pipeline) + ref: merge_request.source_branch, + sha: merge_request.diff_head_sha, + head_pipeline_of: merge_request + ) expect(MergeRequests::MergeWhenPipelineSucceedsService).to receive(:new).with(project, user). and_return(service_mock) -- cgit v1.2.1 From 33961ee418e861a021d7f70bdb1540de9d159b95 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Mon, 22 May 2017 19:24:27 +0200 Subject: Add Etag caching for Pipeline#Show action Due to a typo this was not actually the case. Now that is fixed and performance should improve because of this. --- spec/lib/gitlab/etag_caching/router_spec.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'spec') diff --git a/spec/lib/gitlab/etag_caching/router_spec.rb b/spec/lib/gitlab/etag_caching/router_spec.rb index 5ae4a19263c..46a238b17f4 100644 --- a/spec/lib/gitlab/etag_caching/router_spec.rb +++ b/spec/lib/gitlab/etag_caching/router_spec.rb @@ -77,6 +77,17 @@ describe Gitlab::EtagCaching::Router do expect(result).to be_blank end + it 'matches pipeline#show endpoint' do + env = build_env( + '/my-group/my-project/pipelines/2.json' + ) + + result = described_class.match(env) + + expect(result).to be_present + expect(result.name).to eq 'project_pipeline' + end + def build_env(path) { 'PATH_INFO' => path } end -- cgit v1.2.1 From 336635f283eab06c561134f2147a3bd1983090e1 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Mon, 22 May 2017 20:22:50 +0200 Subject: Test the ExpireJobCacheWorker and related changes These were untested by the cherry picked commit. --- spec/models/commit_status_spec.rb | 10 ++++++++ spec/workers/expire_job_cache_worker_spec.rb | 31 +++++++++++++++++++++++ spec/workers/expire_pipeline_cache_worker_spec.rb | 2 ++ 3 files changed, 43 insertions(+) create mode 100644 spec/workers/expire_job_cache_worker_spec.rb (limited to 'spec') diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index 6947affcc1e..c50b8bf7b13 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -36,6 +36,16 @@ describe CommitStatus, :models do it { is_expected.to eq(commit_status.user) } end + describe 'status state machine' do + let!(:commit_status) { create(:commit_status, :running, project: project) } + + it 'invalidates the cache after a transition' do + expect(ExpireJobCacheWorker).to receive(:perform_async).with(commit_status.id) + + commit_status.success! + end + end + describe '#started?' do subject { commit_status.started? } diff --git a/spec/workers/expire_job_cache_worker_spec.rb b/spec/workers/expire_job_cache_worker_spec.rb new file mode 100644 index 00000000000..1b614342a18 --- /dev/null +++ b/spec/workers/expire_job_cache_worker_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +describe ExpireJobCacheWorker do + set(:pipeline) { create(:ci_empty_pipeline) } + let(:project) { pipeline.project } + subject { described_class.new } + + describe '#perform' do + context 'with a job in the pipeline' do + let(:job) { create(:ci_build, pipeline: pipeline) } + + it 'invalidates Etag caching for the job path' do + pipeline_path = "/#{project.full_path}/pipelines/#{pipeline.id}.json" + job_path = "/#{project.full_path}/builds/#{job.id}.json" + + expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(pipeline_path) + expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(job_path) + + subject.perform(job.id) + end + end + + context 'when there is no job in the pipeline' do + it 'does not change the etag store' do + expect(Gitlab::EtagCaching::Store).not_to receive(:new) + + subject.perform(9999) + end + end + end +end diff --git a/spec/workers/expire_pipeline_cache_worker_spec.rb b/spec/workers/expire_pipeline_cache_worker_spec.rb index ceba604dea2..28e5b706803 100644 --- a/spec/workers/expire_pipeline_cache_worker_spec.rb +++ b/spec/workers/expire_pipeline_cache_worker_spec.rb @@ -10,9 +10,11 @@ describe ExpirePipelineCacheWorker do it 'invalidates Etag caching for project pipelines path' do pipelines_path = "/#{project.full_path}/pipelines.json" new_mr_pipelines_path = "/#{project.full_path}/merge_requests/new.json" + pipeline_path = "/#{project.full_path}/pipelines/#{pipeline.id}.json" expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(pipelines_path) expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(new_mr_pipelines_path) + expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(pipeline_path) subject.perform(pipeline.id) end -- cgit v1.2.1 From acd573f1e612f446d6994b891cf65d189950faff Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Thu, 18 May 2017 11:22:02 -0500 Subject: minor adjustments to the specs --- spec/controllers/projects_controller_spec.rb | 19 +++++++++---------- spec/services/projects/transfer_service_spec.rb | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'spec') diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index 5f9c747634c..4f6fc6691be 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -229,23 +229,22 @@ describe ProjectsController do describe '#transfer' do render_views - subject(:project) { create(:project) } + let(:project) { create(:project) } let(:admin) { create(:admin) } let(:new_namespace) { create(:namespace) } it 'updates namespace' do - controller.instance_variable_set(:@project, project) sign_in(admin) put :transfer, - namespace_id: project.namespace.id, + namespace_id: project.namespace.path, new_namespace_id: new_namespace.id, - id: project.id, + id: project.path, format: :js project.reload - expect(project.namespace.id).to eq(new_namespace.id) + expect(project.namespace).to eq(new_namespace) expect(response).to have_http_status(200) end @@ -254,18 +253,18 @@ describe ProjectsController do controller.instance_variable_set(:@project, project) sign_in(admin) - old_namespace_id = project.namespace.id + old_namespace = project.namespace put :transfer, - namespace_id: old_namespace_id, + namespace_id: old_namespace.path, new_namespace_id: nil, - id: project.id, + id: project.path, format: :js project.reload - expect(project.namespace.id).to eq(old_namespace_id) - expect(response).to have_http_status(200) + expect(project.namespace).to eq(old_namespace) + expect(response).to have_http_status(200) expect(flash[:alert]).to eq 'Please select a new namespace for your project.' end end diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb index 2bddb6f3e42..b957517c715 100644 --- a/spec/services/projects/transfer_service_spec.rb +++ b/spec/services/projects/transfer_service_spec.rb @@ -26,7 +26,7 @@ describe Projects::TransferService, services: true do it { expect(@result).to eq false } it { expect(project.namespace).to eq(user.namespace) } - it { expect(project.errors.messages[:new_namespace][0]).to eq 'Please select a new namespace for your project.' } + it { expect(project.errors.messages[:new_namespace].first).to eq 'Please select a new namespace for your project.' } end context 'disallow transfering of project with tags' do -- cgit v1.2.1 From 92ec0ae0a7997aa841106432a319be51b2d446a0 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 22 May 2017 23:33:08 +0200 Subject: Fix migrations for older PostgreSQL versions - Do not care about error when creating index on PostgreSQL - Test against PostgreSQL 9.2 --- spec/migrations/upate_retried_for_ci_builds_spec.rb | 17 ----------------- spec/migrations/update_retried_for_ci_builds_spec.rb | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 17 deletions(-) delete mode 100644 spec/migrations/upate_retried_for_ci_builds_spec.rb create mode 100644 spec/migrations/update_retried_for_ci_builds_spec.rb (limited to 'spec') diff --git a/spec/migrations/upate_retried_for_ci_builds_spec.rb b/spec/migrations/upate_retried_for_ci_builds_spec.rb deleted file mode 100644 index 5cdb8a3c7da..00000000000 --- a/spec/migrations/upate_retried_for_ci_builds_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20170503004427_upate_retried_for_ci_build.rb') - -describe UpateRetriedForCiBuild, truncate: true do - let(:pipeline) { create(:ci_pipeline) } - let!(:build_old) { create(:ci_build, pipeline: pipeline, name: 'test') } - let!(:build_new) { create(:ci_build, pipeline: pipeline, name: 'test') } - - before do - described_class.new.up - end - - it 'updates ci_builds.is_retried' do - expect(build_old.reload).to be_retried - expect(build_new.reload).not_to be_retried - end -end diff --git a/spec/migrations/update_retried_for_ci_builds_spec.rb b/spec/migrations/update_retried_for_ci_builds_spec.rb new file mode 100644 index 00000000000..3742b4dafe5 --- /dev/null +++ b/spec/migrations/update_retried_for_ci_builds_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20170503004427_update_retried_for_ci_build.rb') + +describe UpdateRetriedForCiBuild, truncate: true do + let(:pipeline) { create(:ci_pipeline) } + let!(:build_old) { create(:ci_build, pipeline: pipeline, name: 'test') } + let!(:build_new) { create(:ci_build, pipeline: pipeline, name: 'test') } + + before do + described_class.new.up + end + + it 'updates ci_builds.is_retried' do + expect(build_old.reload).to be_retried + expect(build_new.reload).not_to be_retried + end +end -- cgit v1.2.1 From 2338785ec9fcacc43ba2098ab1485fca292c06cc Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Wed, 17 May 2017 15:25:13 -0300 Subject: Use wait_for_requests to wait all JS request --- spec/features/admin/admin_labels_spec.rb | 4 +- spec/features/admin/admin_users_spec.rb | 2 +- spec/features/auto_deploy_spec.rb | 2 +- spec/features/boards/add_issues_modal_spec.rb | 14 ++-- spec/features/boards/boards_spec.rb | 77 +++++++++++----------- spec/features/boards/issue_ordering_spec.rb | 27 ++++---- spec/features/boards/keyboard_shortcut_spec.rb | 4 +- spec/features/boards/modal_filter_spec.rb | 28 ++++---- spec/features/boards/new_issue_spec.rb | 10 ++- spec/features/boards/sidebar_spec.rb | 46 +++++++------ spec/features/boards/sub_group_project_spec.rb | 6 +- spec/features/calendar_spec.rb | 10 +-- spec/features/copy_as_gfm_spec.rb | 4 +- spec/features/cycle_analytics_spec.rb | 8 +-- .../dashboard/datetime_on_tooltips_spec.rb | 4 +- spec/features/dashboard/groups_list_spec.rb | 6 +- spec/features/dashboard/milestone_filter_spec.rb | 10 ++- .../project_member_activity_index_spec.rb | 2 +- spec/features/expand_collapse_diffs_spec.rb | 16 ++--- spec/features/explore/groups_list_spec.rb | 6 +- spec/features/gitlab_flavored_markdown_spec.rb | 2 - spec/features/groups/issues_spec.rb | 2 +- spec/features/issues/award_emoji_spec.rb | 16 ++--- spec/features/issues/award_spec.rb | 8 +-- .../features/issues/bulk_assignment_labels_spec.rb | 8 +-- .../issues/create_branch_merge_request_spec.rb | 4 +- .../issues/filtered_search/dropdown_author_spec.rb | 2 +- .../issues/filtered_search/filter_issues_spec.rb | 10 +-- spec/features/issues/form_spec.rb | 7 +- spec/features/issues/gfm_autocomplete_spec.rb | 10 +-- spec/features/issues/issue_sidebar_spec.rb | 6 +- spec/features/issues/notes_on_issues_spec.rb | 2 +- spec/features/issues/update_issues_spec.rb | 4 +- .../issues/user_uses_slash_commands_spec.rb | 2 +- spec/features/issues_spec.rb | 12 ++-- spec/features/merge_requests/closes_issues_spec.rb | 4 +- spec/features/merge_requests/conflicts_spec.rb | 22 +++---- spec/features/merge_requests/create_new_mr_spec.rb | 4 +- .../merge_requests/deleted_source_branch_spec.rb | 2 +- .../merge_requests/diff_notes_avatars_spec.rb | 12 ++-- .../merge_requests/filter_merge_requests_spec.rb | 2 +- .../merge_immediately_with_pipeline_spec.rb | 2 +- .../merge_requests/mini_pipeline_graph_spec.rb | 2 +- .../only_allow_merge_if_build_succeeds_spec.rb | 20 +++--- spec/features/merge_requests/pipelines_spec.rb | 2 +- .../merge_requests/update_merge_requests_spec.rb | 4 +- .../merge_requests/user_posts_diff_notes_spec.rb | 6 +- .../merge_requests/user_posts_notes_spec.rb | 4 +- .../user_uses_slash_commands_spec.rb | 4 +- spec/features/merge_requests/versions_spec.rb | 6 +- .../merge_requests/widget_deployments_spec.rb | 4 +- spec/features/merge_requests/widget_spec.rb | 16 ++--- spec/features/milestones/milestones_spec.rb | 6 +- spec/features/projects/artifacts/file_spec.rb | 4 +- spec/features/projects/blobs/blob_show_spec.rb | 8 +-- spec/features/projects/blobs/edit_spec.rb | 2 +- spec/features/projects/blobs/user_create_spec.rb | 2 +- spec/features/projects/commit/cherry_pick_spec.rb | 4 +- .../projects/commit/mini_pipeline_graph_spec.rb | 2 +- spec/features/projects/compare_spec.rb | 2 +- spec/features/projects/features_visibility_spec.rb | 12 ++-- spec/features/projects/files/browse_files_spec.rb | 4 +- .../projects/files/dockerfile_dropdown_spec.rb | 4 +- .../projects/files/find_file_keyboard_spec.rb | 2 +- .../projects/files/gitignore_dropdown_spec.rb | 4 +- .../projects/files/gitlab_ci_yml_dropdown_spec.rb | 4 +- .../project_owner_creates_license_file_spec.rb | 2 +- ...to_create_license_file_in_empty_project_spec.rb | 2 +- spec/features/projects/files/undo_template_spec.rb | 2 +- spec/features/projects/issuable_templates_spec.rb | 14 ++-- .../projects/labels/update_prioritization_spec.rb | 10 +-- spec/features/projects/members/group_links_spec.rb | 6 +- ...master_adds_member_with_expiration_date_spec.rb | 2 +- spec/features/projects/pipeline_schedules_spec.rb | 1 - spec/features/projects/pipelines/pipelines_spec.rb | 16 ++--- spec/features/projects/ref_switcher_spec.rb | 6 +- spec/features/projects/snippets/show_spec.rb | 10 +-- spec/features/projects/view_on_env_spec.rb | 12 ++-- spec/features/search_spec.rb | 8 +-- spec/features/snippets/create_snippet_spec.rb | 4 +- .../snippets/notes_on_personal_snippets_spec.rb | 2 +- spec/features/snippets/public_snippets_spec.rb | 2 +- spec/features/snippets/show_spec.rb | 10 +-- spec/features/task_lists_spec.rb | 17 ++--- spec/features/todos/todos_filtering_spec.rb | 8 +-- spec/features/todos/todos_spec.rb | 6 +- spec/features/u2f_spec.rb | 2 +- .../uploads/user_uploads_file_to_note_spec.rb | 4 +- spec/features/users/projects_spec.rb | 2 +- spec/features/users/snippets_spec.rb | 6 +- spec/features/users_spec.rb | 8 +-- spec/spec_helper.rb | 1 - .../issuable_slash_commands_shared_examples.rb | 4 +- .../access_control_ce_shared_examples.rb | 4 +- .../access_control_ce_shared_examples.rb | 2 +- spec/support/snippets_shared_examples.rb | 2 +- spec/support/target_branch_helpers.rb | 2 +- spec/support/time_tracking_shared_examples.rb | 8 +-- spec/support/wait_for_ajax.rb | 18 ----- spec/support/wait_for_requests.rb | 38 +++++++++-- spec/support/wait_for_vue_resource.rb | 19 ------ 101 files changed, 381 insertions(+), 436 deletions(-) delete mode 100644 spec/support/wait_for_ajax.rb delete mode 100644 spec/support/wait_for_vue_resource.rb (limited to 'spec') diff --git a/spec/features/admin/admin_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb index fa3d9ee25c0..a9251db13e5 100644 --- a/spec/features/admin/admin_labels_spec.rb +++ b/spec/features/admin/admin_labels_spec.rb @@ -34,11 +34,11 @@ RSpec.describe 'admin issues labels' do page.within '.labels' do page.all('.btn-remove').each do |remove| remove.click - wait_for_ajax + wait_for_requests end end - wait_for_ajax + wait_for_requests expect(page).to have_content("There are no labels yet") expect(page).not_to have_content('bug') diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb index c5b1ef1295c..12cf59f42b0 100644 --- a/spec/features/admin/admin_users_spec.rb +++ b/spec/features/admin/admin_users_spec.rb @@ -277,7 +277,7 @@ describe "Admin::Users", feature: true do page.within(first('.group_member')) do find('.btn-remove').click end - wait_for_ajax + wait_for_requests expect(page).not_to have_selector('.group_member') end diff --git a/spec/features/auto_deploy_spec.rb b/spec/features/auto_deploy_spec.rb index 6c7423e4922..1cf7396bbac 100644 --- a/spec/features/auto_deploy_spec.rb +++ b/spec/features/auto_deploy_spec.rb @@ -46,7 +46,7 @@ describe 'Auto deploy' do within '.gitlab-ci-yml-selector' do click_on 'OpenShift' end - wait_for_ajax + wait_for_requests click_button 'Commit changes' expect(page).to have_content('New Merge Request From auto-deploy into master') diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb index 505e0b5c355..32ac265814f 100644 --- a/spec/features/boards/add_issues_modal_spec.rb +++ b/spec/features/boards/add_issues_modal_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' describe 'Issue Boards add issue modal', :feature, :js do - include WaitForVueResource - let(:project) { create(:empty_project, :public) } let(:board) { create(:board, project: project) } let(:user) { create(:user) } @@ -19,13 +17,13 @@ describe 'Issue Boards add issue modal', :feature, :js do login_as(user) visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests end it 'resets filtered search state' do visit namespace_project_board_path(project.namespace, project, board, search: 'testing') - wait_for_vue_resource + wait_for_requests click_button('Add issues') @@ -74,7 +72,7 @@ describe 'Issue Boards add issue modal', :feature, :js do before do click_button('Add issues') - wait_for_vue_resource + wait_for_requests end it 'loads issues' do @@ -107,7 +105,7 @@ describe 'Issue Boards add issue modal', :feature, :js do click_button('Add issues') - wait_for_vue_resource + wait_for_requests page.within('.add-issues-modal') do expect(find('.add-issues-footer')).not_to have_button(planning.title) @@ -122,7 +120,7 @@ describe 'Issue Boards add issue modal', :feature, :js do find('.form-control').native.send_keys(issue.title) find('.form-control').native.send_keys(:enter) - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.card', count: 1) end @@ -133,7 +131,7 @@ describe 'Issue Boards add issue modal', :feature, :js do find('.form-control').native.send_keys('testing search') find('.form-control').native.send_keys(:enter) - wait_for_vue_resource + wait_for_requests expect(page).not_to have_selector('.card') expect(page).not_to have_content("You haven't added any issues to your project yet") diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 18585488e26..ba27db23ced 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' describe 'Issue Boards', feature: true, js: true do - include WaitForVueResource include DragTo let(:project) { create(:empty_project, :public) } @@ -19,7 +18,7 @@ describe 'Issue Boards', feature: true, js: true do context 'no lists' do before do visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.board', count: 2) end @@ -46,7 +45,7 @@ describe 'Issue Boards', feature: true, js: true do page.within(find('.board-blank-state')) do click_button('Add default lists') end - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.board', count: 3) @@ -84,7 +83,7 @@ describe 'Issue Boards', feature: true, js: true do before do visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.board', count: 3) expect(find('.board:nth-child(1)')).to have_selector('.card') @@ -117,7 +116,7 @@ describe 'Issue Boards', feature: true, js: true do find('.filtered-search').set(issue8.title) find('.filtered-search').native.send_keys(:enter) - wait_for_vue_resource + wait_for_requests expect(find('.board:nth-child(1)')).to have_selector('.card', count: 0) expect(find('.board:nth-child(2)')).to have_selector('.card', count: 0) @@ -128,7 +127,7 @@ describe 'Issue Boards', feature: true, js: true do find('.filtered-search').set(issue5.title) find('.filtered-search').native.send_keys(:enter) - wait_for_vue_resource + wait_for_requests expect(find('.board:nth-child(1)')).to have_selector('.card', count: 1) expect(find('.board:nth-child(2)')).to have_selector('.card', count: 0) @@ -140,20 +139,20 @@ describe 'Issue Boards', feature: true, js: true do find('.board-delete').click end - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.board', count: 2) end it 'removes checkmark in new list dropdown after deleting' do click_button 'Add list' - wait_for_ajax + wait_for_requests page.within(find('.board:nth-child(1)')) do find('.board-delete').click end - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.board', count: 2) end @@ -164,7 +163,7 @@ describe 'Issue Boards', feature: true, js: true do end visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests page.within(find('.board', match: :first)) do expect(page.find('.board-header')).to have_content('58') @@ -172,13 +171,13 @@ describe 'Issue Boards', feature: true, js: true do expect(page).to have_content('Showing 20 of 58 issues') evaluate_script("document.querySelectorAll('.board .board-list')[0].scrollTop = document.querySelectorAll('.board .board-list')[0].scrollHeight") - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.card', count: 40) expect(page).to have_content('Showing 40 of 58 issues') evaluate_script("document.querySelectorAll('.board .board-list')[0].scrollTop = document.querySelectorAll('.board .board-list')[0].scrollHeight") - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.card', count: 58) expect(page).to have_content('Showing all issues') @@ -188,7 +187,7 @@ describe 'Issue Boards', feature: true, js: true do context 'closed' do it 'shows list of closed issues' do wait_for_board_cards(3, 1) - wait_for_ajax + wait_for_requests end it 'moves issue to closed' do @@ -272,7 +271,7 @@ describe 'Issue Boards', feature: true, js: true do context 'new list' do it 'shows all labels in new list dropdown' do click_button 'Add list' - wait_for_ajax + wait_for_requests page.within('.dropdown-menu-issues-board-new') do expect(page).to have_content(planning.title) @@ -283,52 +282,52 @@ describe 'Issue Boards', feature: true, js: true do it 'creates new list for label' do click_button 'Add list' - wait_for_ajax + wait_for_requests page.within('.dropdown-menu-issues-board-new') do click_link testing.title end - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.board', count: 4) end it 'creates new list for Backlog label' do click_button 'Add list' - wait_for_ajax + wait_for_requests page.within('.dropdown-menu-issues-board-new') do click_link backlog.title end - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.board', count: 4) end it 'creates new list for Closed label' do click_button 'Add list' - wait_for_ajax + wait_for_requests page.within('.dropdown-menu-issues-board-new') do click_link closed.title end - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.board', count: 4) end it 'keeps dropdown open after adding new list' do click_button 'Add list' - wait_for_ajax + wait_for_requests page.within('.dropdown-menu-issues-board-new') do click_link closed.title end - wait_for_vue_resource + wait_for_requests expect(page).to have_css('#js-add-list.open') end @@ -336,7 +335,7 @@ describe 'Issue Boards', feature: true, js: true do it 'creates new list from a new label' do click_button 'Add list' - wait_for_ajax + wait_for_requests click_link 'Create new label' @@ -346,8 +345,8 @@ describe 'Issue Boards', feature: true, js: true do click_button 'Create' - wait_for_ajax - wait_for_vue_resource + wait_for_requests + wait_for_requests expect(page).to have_selector('.board', count: 4) end @@ -360,7 +359,7 @@ describe 'Issue Boards', feature: true, js: true do click_filter_link(user2.username) submit_filter - wait_for_vue_resource + wait_for_requests wait_for_board_cards(1, 1) wait_for_empty_boards((2..3)) end @@ -370,7 +369,7 @@ describe 'Issue Boards', feature: true, js: true do click_filter_link(user.username) submit_filter - wait_for_vue_resource + wait_for_requests wait_for_board_cards(1, 1) wait_for_empty_boards((2..3)) @@ -381,7 +380,7 @@ describe 'Issue Boards', feature: true, js: true do click_filter_link(milestone.title) submit_filter - wait_for_vue_resource + wait_for_requests wait_for_board_cards(1, 1) wait_for_board_cards(2, 0) wait_for_board_cards(3, 0) @@ -392,7 +391,7 @@ describe 'Issue Boards', feature: true, js: true do click_filter_link(testing.title) submit_filter - wait_for_vue_resource + wait_for_requests wait_for_board_cards(1, 1) wait_for_empty_boards((2..3)) end @@ -407,7 +406,7 @@ describe 'Issue Boards', feature: true, js: true do wait_for_board_cards(1, 1) wait_for_empty_boards((2..3)) - wait_for_vue_resource + wait_for_requests page.within(find('.board', match: :first)) do expect(page.find('.board-header')).to have_content('1') @@ -442,7 +441,7 @@ describe 'Issue Boards', feature: true, js: true do click_filter_link(testing.title) submit_filter - wait_for_vue_resource + wait_for_requests page.within(find('.board', match: :first)) do expect(page.find('.board-header')).to have_content('51') @@ -470,7 +469,7 @@ describe 'Issue Boards', feature: true, js: true do submit_filter - wait_for_vue_resource + wait_for_requests wait_for_board_cards(1, 1) wait_for_empty_boards((2..3)) @@ -481,14 +480,14 @@ describe 'Issue Boards', feature: true, js: true do expect(page).to have_selector('.card', count: 8) expect(find('.card', match: :first)).to have_content(bug.title) click_button(bug.title) - wait_for_vue_resource + wait_for_requests end page.within('.tokens-container') do expect(page).to have_content(bug.title) end - wait_for_vue_resource + wait_for_requests wait_for_board_cards(1, 1) wait_for_empty_boards((2..3)) @@ -500,12 +499,12 @@ describe 'Issue Boards', feature: true, js: true do click_button(bug.title) end - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.card', count: 1) end - wait_for_vue_resource + wait_for_requests end end end @@ -513,7 +512,7 @@ describe 'Issue Boards', feature: true, js: true do context 'keyboard shortcuts' do before do visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests end it 'allows user to use keyboard shortcuts' do @@ -526,7 +525,7 @@ describe 'Issue Boards', feature: true, js: true do before do logout visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests end it 'displays lists' do @@ -550,7 +549,7 @@ describe 'Issue Boards', feature: true, js: true do logout login_as(user_guest) visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests end it 'does not show create new list' do diff --git a/spec/features/boards/issue_ordering_spec.rb b/spec/features/boards/issue_ordering_spec.rb index bfa2a72a256..6c40cb2c9eb 100644 --- a/spec/features/boards/issue_ordering_spec.rb +++ b/spec/features/boards/issue_ordering_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' describe 'Issue Boards', :feature, :js do - include WaitForVueResource include DragTo let(:project) { create(:empty_project, :public) } @@ -24,7 +23,7 @@ describe 'Issue Boards', :feature, :js do before do visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.board', count: 2) end @@ -38,7 +37,7 @@ describe 'Issue Boards', :feature, :js do it 'moves un-ordered issue to top of list' do drag(from_index: 3, to_index: 0) - wait_for_vue_resource + wait_for_requests page.within(first('.board')) do expect(first('.card')).to have_content(issue4.title) @@ -49,7 +48,7 @@ describe 'Issue Boards', :feature, :js do context 'ordering in list' do before do visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.board', count: 2) end @@ -57,7 +56,7 @@ describe 'Issue Boards', :feature, :js do it 'moves from middle to top' do drag(from_index: 1, to_index: 0) - wait_for_vue_resource + wait_for_requests expect(first('.card')).to have_content(issue2.title) end @@ -65,7 +64,7 @@ describe 'Issue Boards', :feature, :js do it 'moves from middle to bottom' do drag(from_index: 1, to_index: 2) - wait_for_vue_resource + wait_for_requests expect(all('.card').last).to have_content(issue2.title) end @@ -73,7 +72,7 @@ describe 'Issue Boards', :feature, :js do it 'moves from top to bottom' do drag(from_index: 0, to_index: 2) - wait_for_vue_resource + wait_for_requests expect(all('.card').last).to have_content(issue3.title) end @@ -81,7 +80,7 @@ describe 'Issue Boards', :feature, :js do it 'moves from bottom to top' do drag(from_index: 2, to_index: 0) - wait_for_vue_resource + wait_for_requests expect(first('.card')).to have_content(issue1.title) end @@ -89,7 +88,7 @@ describe 'Issue Boards', :feature, :js do it 'moves from top to middle' do drag(from_index: 0, to_index: 1) - wait_for_vue_resource + wait_for_requests expect(first('.card')).to have_content(issue2.title) end @@ -97,7 +96,7 @@ describe 'Issue Boards', :feature, :js do it 'moves from bottom to middle' do drag(from_index: 2, to_index: 1) - wait_for_vue_resource + wait_for_requests expect(all('.card').last).to have_content(issue2.title) end @@ -112,7 +111,7 @@ describe 'Issue Boards', :feature, :js do before do visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.board', count: 3) end @@ -120,7 +119,7 @@ describe 'Issue Boards', :feature, :js do it 'moves to top of another list' do drag(list_from_index: 0, list_to_index: 1) - wait_for_vue_resource + wait_for_requests expect(first('.board')).to have_selector('.card', count: 2) expect(all('.board')[1]).to have_selector('.card', count: 4) @@ -133,7 +132,7 @@ describe 'Issue Boards', :feature, :js do it 'moves to bottom of another list' do drag(list_from_index: 0, list_to_index: 1, to_index: 2) - wait_for_vue_resource + wait_for_requests expect(first('.board')).to have_selector('.card', count: 2) expect(all('.board')[1]).to have_selector('.card', count: 4) @@ -146,7 +145,7 @@ describe 'Issue Boards', :feature, :js do it 'moves to index of another list' do drag(list_from_index: 0, list_to_index: 1, to_index: 1) - wait_for_vue_resource + wait_for_requests expect(first('.board')).to have_selector('.card', count: 2) expect(all('.board')[1]).to have_selector('.card', count: 4) diff --git a/spec/features/boards/keyboard_shortcut_spec.rb b/spec/features/boards/keyboard_shortcut_spec.rb index a9cc6c49f8e..c2167ba12cd 100644 --- a/spec/features/boards/keyboard_shortcut_spec.rb +++ b/spec/features/boards/keyboard_shortcut_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' describe 'Issue Boards shortcut', feature: true, js: true do - include WaitForVueResource - let(:project) { create(:empty_project) } before do @@ -17,6 +15,6 @@ describe 'Issue Boards shortcut', feature: true, js: true do find('body').native.send_keys('gb') expect(page).to have_selector('.boards-list') - wait_for_vue_resource + wait_for_requests end end diff --git a/spec/features/boards/modal_filter_spec.rb b/spec/features/boards/modal_filter_spec.rb index e1367c675e5..ce132bfd979 100644 --- a/spec/features/boards/modal_filter_spec.rb +++ b/spec/features/boards/modal_filter_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' describe 'Issue Boards add issue modal filtering', :feature, :js do - include WaitForVueResource - let(:project) { create(:empty_project, :public) } let(:board) { create(:board, project: project) } let(:planning) { create(:label, project: project, name: 'Planning') } @@ -24,7 +22,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do find('.form-control').native.send_keys('testing empty state') find('.form-control').native.send_keys(:enter) - wait_for_vue_resource + wait_for_requests expect(page).to have_content('There are no issues to show.') end @@ -38,7 +36,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do submit_filter page.within('.add-issues-modal') do - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.card', count: 0) @@ -48,7 +46,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do click_button('Add issues') page.within('.add-issues-modal') do - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.card', count: 1) end @@ -62,13 +60,13 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do submit_filter page.within('.add-issues-modal') do - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.card', count: 0) find('.clear-search').click - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.card', count: 1) end @@ -89,7 +87,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do submit_filter page.within('.add-issues-modal') do - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.js-visual-token', text: user2.username) expect(page).to have_selector('.card', count: 1) @@ -112,7 +110,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do submit_filter page.within('.add-issues-modal') do - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.js-visual-token', text: 'none') expect(page).to have_selector('.card', count: 1) @@ -125,7 +123,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do submit_filter page.within('.add-issues-modal') do - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.js-visual-token', text: user2.username) expect(page).to have_selector('.card', count: 1) @@ -147,7 +145,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do submit_filter page.within('.add-issues-modal') do - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.js-visual-token', text: 'upcoming') expect(page).to have_selector('.card', count: 0) @@ -160,7 +158,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do submit_filter page.within('.add-issues-modal') do - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.js-visual-token', text: milestone.name) expect(page).to have_selector('.card', count: 1) @@ -182,7 +180,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do submit_filter page.within('.add-issues-modal') do - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.js-visual-token', text: 'none') expect(page).to have_selector('.card', count: 1) @@ -195,7 +193,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do submit_filter page.within('.add-issues-modal') do - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.js-visual-token', text: label.title) expect(page).to have_selector('.card', count: 1) @@ -205,7 +203,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do def visit_board visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests click_button('Add issues') end diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb index f04a1a89e96..0e98f994018 100644 --- a/spec/features/boards/new_issue_spec.rb +++ b/spec/features/boards/new_issue_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' describe 'Issue Boards new issue', feature: true, js: true do - include WaitForVueResource - let(:project) { create(:empty_project, :public) } let(:board) { create(:board, project: project) } let!(:list) { create(:list, board: board, position: 0) } @@ -15,7 +13,7 @@ describe 'Issue Boards new issue', feature: true, js: true do login_as(user) visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.board', count: 2) end @@ -60,7 +58,7 @@ describe 'Issue Boards new issue', feature: true, js: true do click_button 'Submit issue' end - wait_for_vue_resource + wait_for_requests page.within(first('.board .board-issue-count')) do expect(page).to have_content('1') @@ -77,7 +75,7 @@ describe 'Issue Boards new issue', feature: true, js: true do click_button 'Submit issue' end - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.issue-boards-sidebar') end @@ -86,7 +84,7 @@ describe 'Issue Boards new issue', feature: true, js: true do context 'unauthorized user' do before do visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests end it 'does not display new issue button' do diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb index 4667be49fe6..34f4d765117 100644 --- a/spec/features/boards/sidebar_spec.rb +++ b/spec/features/boards/sidebar_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' describe 'Issue Boards', feature: true, js: true do - include WaitForVueResource - let(:user) { create(:user) } let(:user2) { create(:user) } let(:project) { create(:empty_project, :public) } @@ -25,7 +23,7 @@ describe 'Issue Boards', feature: true, js: true do login_as(user) visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests end after do @@ -74,7 +72,7 @@ describe 'Issue Boards', feature: true, js: true do click_button 'Remove from board' end - wait_for_vue_resource + wait_for_requests page.within(first('.board')) do expect(page).to have_selector('.card', count: 1) @@ -88,12 +86,12 @@ describe 'Issue Boards', feature: true, js: true do page.within('.assignee') do click_link 'Edit' - wait_for_ajax + wait_for_requests page.within('.dropdown-menu-user') do click_link user.name - wait_for_vue_resource + wait_for_requests end expect(page).to have_content(user.name) @@ -109,13 +107,13 @@ describe 'Issue Boards', feature: true, js: true do page.within('.assignee') do click_link 'Edit' - wait_for_ajax + wait_for_requests page.within('.dropdown-menu-user') do click_link 'Unassigned' end - wait_for_vue_resource + wait_for_requests expect(page).to have_content('No assignee') end @@ -131,7 +129,7 @@ describe 'Issue Boards', feature: true, js: true do click_button 'assign yourself' - wait_for_vue_resource + wait_for_requests expect(page).to have_content(user.name) end @@ -145,12 +143,12 @@ describe 'Issue Boards', feature: true, js: true do page.within('.assignee') do click_link 'Edit' - wait_for_ajax + wait_for_requests page.within('.dropdown-menu-user') do click_link user.name - wait_for_vue_resource + wait_for_requests end expect(page).to have_content(user.name) @@ -162,7 +160,7 @@ describe 'Issue Boards', feature: true, js: true do page.within('.assignee') do click_link 'Edit' - + expect(find('.dropdown-menu')).to have_selector('.is-active') end end @@ -175,11 +173,11 @@ describe 'Issue Boards', feature: true, js: true do page.within('.milestone') do click_link 'Edit' - wait_for_ajax + wait_for_requests click_link milestone.title - wait_for_vue_resource + wait_for_requests page.within('.value') do expect(page).to have_content(milestone.title) @@ -193,11 +191,11 @@ describe 'Issue Boards', feature: true, js: true do page.within('.milestone') do click_link 'Edit' - wait_for_ajax + wait_for_requests click_link "No Milestone" - wait_for_vue_resource + wait_for_requests page.within('.value') do expect(page).not_to have_content(milestone.title) @@ -215,7 +213,7 @@ describe 'Issue Boards', feature: true, js: true do click_button Date.today.day - wait_for_vue_resource + wait_for_requests expect(page).to have_content(Date.today.to_s(:medium)) end @@ -229,11 +227,11 @@ describe 'Issue Boards', feature: true, js: true do page.within('.labels') do click_link 'Edit' - wait_for_ajax + wait_for_requests click_link bug.title - wait_for_vue_resource + wait_for_requests find('.dropdown-menu-close-icon').click @@ -253,12 +251,12 @@ describe 'Issue Boards', feature: true, js: true do page.within('.labels') do click_link 'Edit' - wait_for_ajax + wait_for_requests click_link bug.title click_link regression.title - wait_for_vue_resource + wait_for_requests find('.dropdown-menu-close-icon').click @@ -280,11 +278,11 @@ describe 'Issue Boards', feature: true, js: true do page.within('.labels') do click_link 'Edit' - wait_for_ajax + wait_for_requests click_link stretch.title - wait_for_vue_resource + wait_for_requests find('.dropdown-menu-close-icon').click @@ -305,7 +303,7 @@ describe 'Issue Boards', feature: true, js: true do page.within('.subscription') do click_button 'Subscribe' - wait_for_ajax + wait_for_requests expect(page).to have_content("Unsubscribe") end end diff --git a/spec/features/boards/sub_group_project_spec.rb b/spec/features/boards/sub_group_project_spec.rb index 6cd7fddd288..4cd05010a93 100644 --- a/spec/features/boards/sub_group_project_spec.rb +++ b/spec/features/boards/sub_group_project_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' describe 'Sub-group project issue boards', :feature, :js do - include WaitForVueResource - let(:group) { create(:group) } let(:nested_group_1) { create(:group, parent: group) } let(:project) { create(:empty_project, group: nested_group_1) } @@ -18,7 +16,7 @@ describe 'Sub-group project issue boards', :feature, :js do login_as(user) visit namespace_project_board_path(project.namespace, project, board) - wait_for_vue_resource + wait_for_requests end it 'creates new label from sidebar' do @@ -35,7 +33,7 @@ describe 'Sub-group project issue boards', :feature, :js do click_button 'Create' - wait_for_ajax + wait_for_requests end page.within '.labels' do diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb index 496faf87a16..1b6d8439f92 100644 --- a/spec/features/calendar_spec.rb +++ b/spec/features/calendar_spec.rb @@ -74,7 +74,7 @@ feature 'Contributions Calendar', :feature, :js do describe 'calendar day selection' do before do visit user.username - wait_for_ajax + wait_for_requests end it 'displays calendar' do @@ -86,7 +86,7 @@ feature 'Contributions Calendar', :feature, :js do before do cells[0].click - wait_for_ajax + wait_for_requests @first_day_activities = selected_day_activities end @@ -97,7 +97,7 @@ feature 'Contributions Calendar', :feature, :js do describe 'select another calendar day' do before do cells[1].click - wait_for_ajax + wait_for_requests end it 'displays different calendar day activities' do @@ -108,7 +108,7 @@ feature 'Contributions Calendar', :feature, :js do describe 'deselect calendar day' do before do cells[0].click - wait_for_ajax + wait_for_requests end it 'hides calendar day activities' do @@ -122,7 +122,7 @@ feature 'Contributions Calendar', :feature, :js do shared_context 'visit user page' do before do visit user.username - wait_for_ajax + wait_for_requests end end diff --git a/spec/features/copy_as_gfm_spec.rb b/spec/features/copy_as_gfm_spec.rb index be615519a09..43ea36c3cdd 100644 --- a/spec/features/copy_as_gfm_spec.rb +++ b/spec/features/copy_as_gfm_spec.rb @@ -479,7 +479,7 @@ describe 'Copy as GFM', feature: true, js: true do context 'from a blob' do before do visit namespace_project_blob_path(project.namespace, project, File.join('master', 'files/ruby/popen.rb')) - wait_for_ajax + wait_for_requests end context 'selecting one word of text' do @@ -521,7 +521,7 @@ describe 'Copy as GFM', feature: true, js: true do context 'from a GFM code block' do before do visit namespace_project_blob_path(project.namespace, project, File.join('markdown', 'doc/api/users.md')) - wait_for_ajax + wait_for_requests end context 'selecting one word of text' do diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb index cbeb73d9cae..dd15eb1496f 100644 --- a/spec/features/cycle_analytics_spec.rb +++ b/spec/features/cycle_analytics_spec.rb @@ -17,7 +17,7 @@ feature 'Cycle Analytics', feature: true, js: true do login_as(user) visit namespace_project_cycle_analytics_path(project.namespace, project) - wait_for_ajax + wait_for_requests end it 'shows introductory message' do @@ -73,7 +73,7 @@ feature 'Cycle Analytics', feature: true, js: true do project.team << [user, :master] login_as(user) visit namespace_project_cycle_analytics_path(project.namespace, project) - wait_for_ajax + wait_for_requests end it 'shows the content in Spanish' do @@ -96,7 +96,7 @@ feature 'Cycle Analytics', feature: true, js: true do login_as(guest) visit namespace_project_cycle_analytics_path(project.namespace, project) - wait_for_ajax + wait_for_requests end it 'needs permissions to see restricted stages' do @@ -140,6 +140,6 @@ feature 'Cycle Analytics', feature: true, js: true do def click_stage(stage_name) find('.stage-nav li', text: stage_name).click - wait_for_ajax + wait_for_requests end end diff --git a/spec/features/dashboard/datetime_on_tooltips_spec.rb b/spec/features/dashboard/datetime_on_tooltips_spec.rb index 0e9e3f78be2..1793e323588 100644 --- a/spec/features/dashboard/datetime_on_tooltips_spec.rb +++ b/spec/features/dashboard/datetime_on_tooltips_spec.rb @@ -15,7 +15,7 @@ feature 'Tooltips on .timeago dates', feature: true, js: true do login_as user visit user_path(user) - wait_for_ajax() + wait_for_requests() page.find('.js-timeago').hover end @@ -32,7 +32,7 @@ feature 'Tooltips on .timeago dates', feature: true, js: true do login_as user visit user_snippets_path(user) - wait_for_ajax() + wait_for_requests() page.find('.js-timeago.snippet-created-ago').hover end diff --git a/spec/features/dashboard/groups_list_spec.rb b/spec/features/dashboard/groups_list_spec.rb index 52b4d82e856..b0e2953dda2 100644 --- a/spec/features/dashboard/groups_list_spec.rb +++ b/spec/features/dashboard/groups_list_spec.rb @@ -23,7 +23,7 @@ describe 'Dashboard Groups page', js: true, feature: true do it 'filters groups' do fill_in 'filter_groups', with: group.name - wait_for_ajax + wait_for_requests expect(page).to have_content(group.full_name) expect(page).not_to have_content(nested_group.full_name) @@ -32,10 +32,10 @@ describe 'Dashboard Groups page', js: true, feature: true do it 'resets search when user cleans the input' do fill_in 'filter_groups', with: group.name - wait_for_ajax + wait_for_requests fill_in 'filter_groups', with: "" - wait_for_ajax + wait_for_requests expect(page).to have_content(group.full_name) expect(page).to have_content(nested_group.full_name) diff --git a/spec/features/dashboard/milestone_filter_spec.rb b/spec/features/dashboard/milestone_filter_spec.rb index d60a002a8d7..b5b92c36895 100644 --- a/spec/features/dashboard/milestone_filter_spec.rb +++ b/spec/features/dashboard/milestone_filter_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe 'Dashboard > milestone filter', :feature, :js do - include WaitForAjax - let(:user) { create(:user) } let(:project) { create(:project, name: 'test', namespace: user.namespace) } let(:milestone) { create(:milestone, title: "v1.0", project: project) } @@ -28,14 +26,14 @@ describe 'Dashboard > milestone filter', :feature, :js do before do find(milestone_select).click - wait_for_ajax + wait_for_requests page.within('.dropdown-content') do click_link 'v1.0' end find(milestone_select).click - wait_for_ajax + wait_for_requests end it 'shows issues with Milestone v1.0' do @@ -48,9 +46,9 @@ describe 'Dashboard > milestone filter', :feature, :js do # open & close dropdown find('.dropdown-menu-close').click - + expect(find('.milestone-filter')).not_to have_selector('.dropdown.open') - + find(milestone_select).click expect(find('.dropdown-content')).to have_selector('a.is-active', count: 1) diff --git a/spec/features/dashboard/project_member_activity_index_spec.rb b/spec/features/dashboard/project_member_activity_index_spec.rb index 16c214ae060..cdf919af9b5 100644 --- a/spec/features/dashboard/project_member_activity_index_spec.rb +++ b/spec/features/dashboard/project_member_activity_index_spec.rb @@ -11,7 +11,7 @@ feature 'Project member activity', feature: true, js: true do def visit_activities_and_wait_with_event(event_type) Event.create(project: project, author_id: user.id, action: event_type) visit activity_namespace_project_path(project.namespace, project) - wait_for_ajax + wait_for_requests end subject { page.find(".event-title").text } diff --git a/spec/features/expand_collapse_diffs_spec.rb b/spec/features/expand_collapse_diffs_spec.rb index 76c77e0bc5f..0cb75538311 100644 --- a/spec/features/expand_collapse_diffs_spec.rb +++ b/spec/features/expand_collapse_diffs_spec.rb @@ -36,7 +36,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do visit namespace_project_commit_path(project.namespace, project, project.commit(branch), anchor: "#{large_diff[:id]}_0_1") execute_script('window.location.reload()') - wait_for_ajax + wait_for_requests expect(large_diff).to have_selector('.code') expect(large_diff).not_to have_selector('.nothing-here-block') @@ -50,7 +50,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do visit namespace_project_commit_path(project.namespace, project, project.commit(branch), anchor: large_diff[:id]) execute_script('window.location.reload()') - wait_for_ajax + wait_for_requests expect(large_diff).to have_selector('.code') expect(large_diff).not_to have_selector('.nothing-here-block') @@ -94,7 +94,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do context 'expanding a diff for a renamed file' do before do large_diff_renamed.find('.click-to-expand').click - wait_for_ajax + wait_for_requests end it 'shows the old content' do @@ -116,7 +116,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do find('.js-file-title', match: :first) # Click `large_diff.md` title all('.diff-toggle-caret')[1].click - wait_for_ajax + wait_for_requests end it 'makes a request to get the content' do @@ -139,7 +139,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do large_diff.find('.add-diff-note').click large_diff.find('.note-textarea').send_keys comment_text large_diff.find_button('Comment').click - wait_for_ajax + wait_for_requests end it 'adds the comment' do @@ -160,7 +160,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do find('.js-file-title', match: :first) # Click `large_diff.md` title all('.diff-toggle-caret')[1].click - wait_for_ajax + wait_for_requests end it 'shows the diff content' do @@ -216,7 +216,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do expect(page).to have_no_content('No longer a symlink') find('.click-to-expand').click - wait_for_ajax + wait_for_requests expect(page).to have_content('No longer a symlink') end @@ -273,7 +273,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do expect(page).to have_content('too_large_image.jpg') find('.note-textarea') - wait_for_ajax + wait_for_requests execute_script('window.ajaxUris = []; $(document).ajaxSend(function(event, xhr, settings) { ajaxUris.push(settings.url) });') end diff --git a/spec/features/explore/groups_list_spec.rb b/spec/features/explore/groups_list_spec.rb index 9828cb179a7..d4284ed099b 100644 --- a/spec/features/explore/groups_list_spec.rb +++ b/spec/features/explore/groups_list_spec.rb @@ -23,7 +23,7 @@ describe 'Explore Groups page', :js, :feature do it 'filters groups' do fill_in 'filter_groups', with: group.name - wait_for_ajax + wait_for_requests expect(page).to have_content(group.full_name) expect(page).not_to have_content(public_group.full_name) @@ -32,10 +32,10 @@ describe 'Explore Groups page', :js, :feature do it 'resets search when user cleans the input' do fill_in 'filter_groups', with: group.name - wait_for_ajax + wait_for_requests fill_in 'filter_groups', with: "" - wait_for_ajax + wait_for_requests expect(page).to have_content(group.full_name) expect(page).to have_content(public_group.full_name) diff --git a/spec/features/gitlab_flavored_markdown_spec.rb b/spec/features/gitlab_flavored_markdown_spec.rb index 005a029a393..55092412340 100644 --- a/spec/features/gitlab_flavored_markdown_spec.rb +++ b/spec/features/gitlab_flavored_markdown_spec.rb @@ -49,8 +49,6 @@ describe "GitLab Flavored Markdown", feature: true do end describe "for issues", feature: true, js: true do - include WaitForVueResource - before do @other_issue = create(:issue, author: @user, diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb index 45f57845c74..aa2e9632d6c 100644 --- a/spec/features/groups/issues_spec.rb +++ b/spec/features/groups/issues_spec.rb @@ -33,7 +33,7 @@ feature 'Group issues page', feature: true do it 'filters by only group users' do click_button('Assignee') - wait_for_ajax + wait_for_requests expect(find('.dropdown-menu-assignee')).to have_link(user.name) expect(find('.dropdown-menu-assignee')).not_to have_link(user2.name) diff --git a/spec/features/issues/award_emoji_spec.rb b/spec/features/issues/award_emoji_spec.rb index 853632614c4..81ae54c7a10 100644 --- a/spec/features/issues/award_emoji_spec.rb +++ b/spec/features/issues/award_emoji_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' describe 'Awards Emoji', feature: true do - include WaitForVueResource - let!(:project) { create(:project, :public) } let!(:user) { create(:user) } let(:issue) do @@ -22,7 +20,7 @@ describe 'Awards Emoji', feature: true do # The `heart_tip` emoji is not valid anymore so we need to skip validation issue.award_emoji.build(user: user, name: 'heart_tip').save!(validate: false) visit namespace_project_issue_path(project.namespace, project, issue) - wait_for_vue_resource + wait_for_requests end # Regression test: https://gitlab.com/gitlab-org/gitlab-ce/issues/29529 @@ -36,19 +34,19 @@ describe 'Awards Emoji', feature: true do before do visit namespace_project_issue_path(project.namespace, project, issue) - wait_for_vue_resource + wait_for_requests end it 'increments the thumbsdown emoji', js: true do find('[data-name="thumbsdown"]').click - wait_for_ajax + wait_for_requests expect(thumbsdown_emoji).to have_text("1") end context 'click the thumbsup emoji' do it 'increments the thumbsup emoji', js: true do find('[data-name="thumbsup"]').click - wait_for_ajax + wait_for_requests expect(thumbsup_emoji).to have_text("1") end @@ -60,7 +58,7 @@ describe 'Awards Emoji', feature: true do context 'click the thumbsdown emoji' do it 'increments the thumbsdown emoji', js: true do find('[data-name="thumbsdown"]').click - wait_for_ajax + wait_for_requests expect(thumbsdown_emoji).to have_text("1") end @@ -113,7 +111,7 @@ describe 'Awards Emoji', feature: true do click_button 'Comment' end - wait_for_ajax + wait_for_requests end def thumbsup_emoji @@ -143,6 +141,6 @@ describe 'Awards Emoji', feature: true do find('[data-name="smiley"]').click end - wait_for_ajax + wait_for_requests end end diff --git a/spec/features/issues/award_spec.rb b/spec/features/issues/award_spec.rb index 08e3f99e29f..fcf22dd5033 100644 --- a/spec/features/issues/award_spec.rb +++ b/spec/features/issues/award_spec.rb @@ -6,12 +6,10 @@ feature 'Issue awards', js: true, feature: true do let(:issue) { create(:issue, project: project) } describe 'logged in' do - include WaitForVueResource - before do login_as(user) visit namespace_project_issue_path(project.namespace, project, issue) - wait_for_vue_resource + wait_for_requests end it 'adds award to issue' do @@ -41,11 +39,9 @@ feature 'Issue awards', js: true, feature: true do end describe 'logged out' do - include WaitForVueResource - before do visit namespace_project_issue_path(project.namespace, project, issue) - wait_for_vue_resource + wait_for_requests end it 'does not see award menu button' do diff --git a/spec/features/issues/bulk_assignment_labels_spec.rb b/spec/features/issues/bulk_assignment_labels_spec.rb index 1de50d6d77e..0a6f645b27e 100644 --- a/spec/features/issues/bulk_assignment_labels_spec.rb +++ b/spec/features/issues/bulk_assignment_labels_spec.rb @@ -306,7 +306,7 @@ feature 'Issues > Labels bulk assignment', feature: true do page.within('.issues_bulk_update') do click_button 'Labels' - wait_for_ajax + wait_for_requests expect(find('.dropdown-menu-labels li', text: 'bug')).to have_css('.is-active') expect(find('.dropdown-menu-labels li', text: 'feature')).to have_css('.is-indeterminate') @@ -349,7 +349,7 @@ feature 'Issues > Labels bulk assignment', feature: true do def open_milestone_dropdown(items = []) page.within('.issues_bulk_update') do click_button 'Milestone' - wait_for_ajax + wait_for_requests items.map do |item| click_link item end @@ -359,7 +359,7 @@ feature 'Issues > Labels bulk assignment', feature: true do def open_labels_dropdown(items = [], unmark = false) page.within('.issues_bulk_update') do click_button 'Labels' - wait_for_ajax + wait_for_requests items.map do |item| click_link item end @@ -392,6 +392,6 @@ feature 'Issues > Labels bulk assignment', feature: true do def update_issues click_button 'Update issues' - wait_for_ajax + wait_for_requests end end diff --git a/spec/features/issues/create_branch_merge_request_spec.rb b/spec/features/issues/create_branch_merge_request_spec.rb index 44c19275ae5..1d7d8d291b2 100644 --- a/spec/features/issues/create_branch_merge_request_spec.rb +++ b/spec/features/issues/create_branch_merge_request_spec.rb @@ -16,7 +16,7 @@ feature 'Create Branch/Merge Request Dropdown on issue page', feature: true, js: select_dropdown_option('create-mr') - wait_for_ajax + wait_for_requests expect(page).to have_content("created branch 1-cherry-coloured-funk") expect(page).to have_content("mentioned in merge request !1") @@ -32,7 +32,7 @@ feature 'Create Branch/Merge Request Dropdown on issue page', feature: true, js: select_dropdown_option('create-branch') - wait_for_ajax + wait_for_requests expect(page).to have_selector('.dropdown-toggle-text ', text: '1-cherry-coloured-funk') expect(current_path).to eq namespace_project_tree_path(project.namespace, project, '1-cherry-coloured-funk') diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb index 0579d6c80ab..b29177bed06 100644 --- a/spec/features/issues/filtered_search/dropdown_author_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb @@ -16,7 +16,7 @@ describe 'Dropdown author', js: true, feature: true do end sleep 0.5 - wait_for_ajax + wait_for_requests end def dropdown_author_size diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb index a8f4e2d7e10..03ff1cffb3f 100644 --- a/spec/features/issues/filtered_search/filter_issues_spec.rb +++ b/spec/features/issues/filtered_search/filter_issues_spec.rb @@ -761,7 +761,7 @@ describe 'Filter issues', js: true, feature: true do sort_toggle.click find('.filtered-search-wrapper .dropdown-menu li a', text: 'Oldest updated').click - wait_for_ajax + wait_for_requests expect(find('.issues-list .issue:first-of-type .issue-title-text a')).to have_content(old_issue.title) end @@ -778,17 +778,17 @@ describe 'Filter issues', js: true, feature: true do it 'open state' do find('.issues-state-filters a', text: 'Closed').click - wait_for_ajax + wait_for_requests find('.issues-state-filters a', text: 'Open').click - wait_for_ajax + wait_for_requests expect(page).to have_selector('.issues-list .issue', count: 4) end it 'closed state' do find('.issues-state-filters a', text: 'Closed').click - wait_for_ajax + wait_for_requests expect(page).to have_selector('.issues-list .issue', count: 1) expect(find('.issues-list .issue:first-of-type .issue-title-text a')).to have_content(closed_issue.title) @@ -796,7 +796,7 @@ describe 'Filter issues', js: true, feature: true do it 'all state' do find('.issues-state-filters a', text: 'All').click - wait_for_ajax + wait_for_requests expect(page).to have_selector('.issues-list .issue', count: 5) end diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb index 5c0907e26df..65d854d0896 100644 --- a/spec/features/issues/form_spec.rb +++ b/spec/features/issues/form_spec.rb @@ -3,7 +3,6 @@ require 'rails_helper' describe 'New/edit issue', :feature, :js do include GitlabRoutingHelper include ActionView::Helpers::JavaScriptHelper - include WaitForAjax let!(:project) { create(:project) } let!(:user) { create(:user)} @@ -28,7 +27,7 @@ describe 'New/edit issue', :feature, :js do before do click_button 'Unassigned' - wait_for_ajax + wait_for_requests end it 'unselects other assignees when unassigned is selected' do @@ -69,7 +68,7 @@ describe 'New/edit issue', :feature, :js do expect(find('a', text: 'Assign to me')).to be_visible click_button 'Unassigned' - wait_for_ajax + wait_for_requests page.within '.dropdown-menu-user' do click_link user2.name @@ -155,7 +154,7 @@ describe 'New/edit issue', :feature, :js do it 'correctly updates the selected user when changing assignee' do click_button 'Unassigned' - wait_for_ajax + wait_for_requests page.within '.dropdown-menu-user' do click_link user.name diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb index ad29911248f..350473437a8 100644 --- a/spec/features/issues/gfm_autocomplete_spec.rb +++ b/spec/features/issues/gfm_autocomplete_spec.rb @@ -11,7 +11,7 @@ feature 'GFM autocomplete', feature: true, js: true do login_as(user) visit namespace_project_issue_path(project.namespace, project, issue) - wait_for_ajax + wait_for_requests end it 'opens autocomplete menu when field starts with text' do @@ -40,7 +40,7 @@ feature 'GFM autocomplete', feature: true, js: true do expect(page).to have_selector('.atwho-container') - wait_for_ajax + wait_for_requests expect(find('#at-view-58')).not_to have_selector('.cur:first-of-type') end @@ -80,7 +80,7 @@ feature 'GFM autocomplete', feature: true, js: true do expect(page).to have_selector('.atwho-container') - wait_for_ajax + wait_for_requests expect(find('#at-view-64')).to have_selector('.cur:first-of-type') end @@ -93,7 +93,7 @@ feature 'GFM autocomplete', feature: true, js: true do expect(page).to have_selector('.atwho-container') - wait_for_ajax + wait_for_requests expect(find('#at-view-64')).to have_content(user.name) end @@ -106,7 +106,7 @@ feature 'GFM autocomplete', feature: true, js: true do expect(page).to have_selector('.atwho-container') - wait_for_ajax + wait_for_requests expect(find('#at-view-58')).to have_selector('.cur:first-of-type') end diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb index 0de0f93089a..99ad8013023 100644 --- a/spec/features/issues/issue_sidebar_spec.rb +++ b/spec/features/issues/issue_sidebar_spec.rb @@ -23,7 +23,7 @@ feature 'Issue Sidebar', feature: true do find('.block.assignee .edit-link').click - wait_for_ajax + wait_for_requests end it 'shows author in assignee dropdown' do @@ -37,7 +37,7 @@ feature 'Issue Sidebar', feature: true do find('.dropdown-input-field').native.send_keys user2.name sleep 1 # Required to wait for end of input delay - wait_for_ajax + wait_for_requests expect(page).to have_content(user2.name) end @@ -48,7 +48,7 @@ feature 'Issue Sidebar', feature: true do click_button 'assign yourself' - wait_for_ajax + wait_for_requests find('.block.assignee .edit-link').click diff --git a/spec/features/issues/notes_on_issues_spec.rb b/spec/features/issues/notes_on_issues_spec.rb index a4035324d2b..15c817cabac 100644 --- a/spec/features/issues/notes_on_issues_spec.rb +++ b/spec/features/issues/notes_on_issues_spec.rb @@ -15,7 +15,7 @@ describe 'Create notes on issues', :js, :feature do fill_in 'note[note]', with: note_text click_button 'Comment' - wait_for_ajax + wait_for_requests end it 'creates a note with reference and cross references the issue' do diff --git a/spec/features/issues/update_issues_spec.rb b/spec/features/issues/update_issues_spec.rb index b250fa2ed3c..0911f1db9ba 100644 --- a/spec/features/issues/update_issues_spec.rb +++ b/spec/features/issues/update_issues_spec.rb @@ -108,11 +108,11 @@ feature 'Multiple issue updating from issues#index', feature: true do def click_update_assignee_button find('.js-update-assignee').click - wait_for_ajax + wait_for_requests end def click_update_issues_button find('.update_selected_issues').click - wait_for_ajax + wait_for_requests end end diff --git a/spec/features/issues/user_uses_slash_commands_spec.rb b/spec/features/issues/user_uses_slash_commands_spec.rb index 4cd6c1171ac..d14c319707c 100644 --- a/spec/features/issues/user_uses_slash_commands_spec.rb +++ b/spec/features/issues/user_uses_slash_commands_spec.rb @@ -18,7 +18,7 @@ feature 'Issues > User uses slash commands', feature: true, js: true do end after do - wait_for_ajax + wait_for_requests end describe 'adding a due date from note' do diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index 06ed2dbac64..eecc565d2bd 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -377,7 +377,7 @@ describe 'Issues', feature: true do previous_token = find('input#issue_email').value find('.incoming-email-token-reset').trigger('click') - wait_for_ajax + wait_for_requests expect(page).to have_no_field('issue_email', with: previous_token) new_token = project1.new_issue_address(@user.reload) @@ -423,7 +423,7 @@ describe 'Issues', feature: true do expect(page).to have_content 'No assignee' end - # wait_for_ajax does not work with vue-resource at the moment + # wait_for_requests does not work with vue-resource at the moment sleep 1 expect(issue.reload.assignees).to be_empty @@ -661,7 +661,7 @@ describe 'Issues', feature: true do click_button date.day end - wait_for_ajax + wait_for_requests expect(find('.value').text).to have_content date.strftime('%b %-d, %Y') end @@ -677,7 +677,7 @@ describe 'Issues', feature: true do click_button date.day end - wait_for_ajax + wait_for_requests expect(page).to have_no_content 'No due date' @@ -689,8 +689,6 @@ describe 'Issues', feature: true do end describe 'title issue#show', js: true do - include WaitForVueResource - it 'updates the title', js: true do issue = create(:issue, author: @user, assignees: [@user], project: project, title: 'new title') @@ -700,7 +698,7 @@ describe 'Issues', feature: true do issue.update(title: "updated title") - wait_for_vue_resource + wait_for_requests expect(page).to have_text("updated title") end end diff --git a/spec/features/merge_requests/closes_issues_spec.rb b/spec/features/merge_requests/closes_issues_spec.rb index ee0880a1e2f..e627618042a 100644 --- a/spec/features/merge_requests/closes_issues_spec.rb +++ b/spec/features/merge_requests/closes_issues_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'Merge Request closing issues message', feature: true, js: true do - include WaitForAjax - let(:user) { create(:user) } let(:project) { create(:project, :public) } let(:issue_1) { create(:issue, project: project)} @@ -25,7 +23,7 @@ feature 'Merge Request closing issues message', feature: true, js: true do login_as user visit namespace_project_merge_request_path(project.namespace, project, merge_request) - wait_for_ajax + wait_for_requests end context 'not closing or mentioning any issue' do diff --git a/spec/features/merge_requests/conflicts_spec.rb b/spec/features/merge_requests/conflicts_spec.rb index 04b7593ce68..7f669565085 100644 --- a/spec/features/merge_requests/conflicts_spec.rb +++ b/spec/features/merge_requests/conflicts_spec.rb @@ -23,13 +23,13 @@ feature 'Merge request conflict resolution', js: true, feature: true do end click_button 'Commit conflict resolution' - wait_for_ajax + wait_for_requests expect(page).to have_content('All merge conflicts were resolved') merge_request.reload_diff click_on 'Changes' - wait_for_ajax + wait_for_requests within find('.diff-file', text: 'files/ruby/popen.rb') do expect(page).to have_selector('.line_content.new', text: "vars = { 'PWD' => path }") @@ -53,23 +53,23 @@ feature 'Merge request conflict resolution', js: true, feature: true do within find('.files-wrapper .diff-file', text: 'files/ruby/popen.rb') do click_button 'Edit inline' - wait_for_ajax + wait_for_requests execute_script('ace.edit($(".files-wrapper .diff-file pre")[0]).setValue("One morning");') end within find('.files-wrapper .diff-file', text: 'files/ruby/regex.rb') do click_button 'Edit inline' - wait_for_ajax + wait_for_requests execute_script('ace.edit($(".files-wrapper .diff-file pre")[1]).setValue("Gregor Samsa woke from troubled dreams");') end click_button 'Commit conflict resolution' - wait_for_ajax + wait_for_requests expect(page).to have_content('All merge conflicts were resolved') merge_request.reload_diff click_on 'Changes' - wait_for_ajax + wait_for_requests expect(page).to have_content('One morning') expect(page).to have_content('Gregor Samsa woke from troubled dreams') @@ -126,21 +126,21 @@ feature 'Merge request conflict resolution', js: true, feature: true do it 'conflicts are resolved in Edit inline mode' do within find('.files-wrapper .diff-file', text: 'files/markdown/ruby-style-guide.md') do - wait_for_ajax + wait_for_requests execute_script('ace.edit($(".files-wrapper .diff-file pre")[0]).setValue("Gregor Samsa woke from troubled dreams");') end click_button 'Commit conflict resolution' - wait_for_ajax + wait_for_requests expect(page).to have_content('All merge conflicts were resolved') merge_request.reload_diff click_on 'Changes' - wait_for_ajax + wait_for_requests click_link 'Expand all' - wait_for_ajax + wait_for_requests expect(page).to have_content('Gregor Samsa woke from troubled dreams') end @@ -171,7 +171,7 @@ feature 'Merge request conflict resolution', js: true, feature: true do it 'shows an error if the conflicts page is visited directly' do visit current_url + '/conflicts' - wait_for_ajax + wait_for_requests expect(find('#conflicts')).to have_content('Please try to resolve them locally.') end diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb index f1b3e7f158c..82987c768d1 100644 --- a/spec/features/merge_requests/create_new_mr_spec.rb +++ b/spec/features/merge_requests/create_new_mr_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'Create New Merge Request', feature: true, js: true do - include WaitForVueResource - let(:user) { create(:user) } let(:project) { create(:project, :public) } @@ -146,7 +144,7 @@ feature 'Create New Merge Request', feature: true, js: true do page.within('.merge-request') do click_link 'Pipelines' - wait_for_vue_resource + wait_for_requests expect(page).to have_content "##{pipeline.id}" end diff --git a/spec/features/merge_requests/deleted_source_branch_spec.rb b/spec/features/merge_requests/deleted_source_branch_spec.rb index 01e5e4f3a05..1723fb7d365 100644 --- a/spec/features/merge_requests/deleted_source_branch_spec.rb +++ b/spec/features/merge_requests/deleted_source_branch_spec.rb @@ -32,7 +32,7 @@ describe 'Deleted source branch', feature: true, js: true do end click_on 'Changes' - wait_for_ajax + wait_for_requests expect(page).to have_selector('.diffs.tab-pane .nothing-here-block') expect(page).to have_content('Source branch does not exist.') diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb index ccf047d3efa..854e2d1758f 100644 --- a/spec/features/merge_requests/diff_notes_avatars_spec.rb +++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb @@ -60,7 +60,7 @@ feature 'Diff note avatars', feature: true, js: true do click_button 'Comment' - wait_for_ajax + wait_for_requests end visit namespace_project_merge_request_path(project.namespace, project, merge_request) @@ -76,7 +76,7 @@ feature 'Diff note avatars', feature: true, js: true do before do visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, view: view) - wait_for_ajax + wait_for_requests end it 'shows note avatar' do @@ -114,7 +114,7 @@ feature 'Diff note avatars', feature: true, js: true do find('.js-note-delete').click end - wait_for_ajax + wait_for_requests page.within find("[id='#{position.line_code(project.repository)}']") do expect(page).not_to have_selector('img.js-diff-comment-avatar') @@ -129,7 +129,7 @@ feature 'Diff note avatars', feature: true, js: true do click_button 'Comment' - wait_for_ajax + wait_for_requests end page.within find("[id='#{position.line_code(project.repository)}']") do @@ -148,7 +148,7 @@ feature 'Diff note avatars', feature: true, js: true do find('.js-comment-button').trigger 'click' - wait_for_ajax + wait_for_requests end end @@ -166,7 +166,7 @@ feature 'Diff note avatars', feature: true, js: true do visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, view: view) - wait_for_ajax + wait_for_requests end it 'shows extra comment count' do diff --git a/spec/features/merge_requests/filter_merge_requests_spec.rb b/spec/features/merge_requests/filter_merge_requests_spec.rb index 2da60e9f4ad..1e26b3d601e 100644 --- a/spec/features/merge_requests/filter_merge_requests_spec.rb +++ b/spec/features/merge_requests/filter_merge_requests_spec.rb @@ -289,7 +289,7 @@ describe 'Filter merge requests', feature: true do page.within '.dropdown-menu-sort' do click_link 'Oldest created' end - wait_for_ajax + wait_for_requests page.within '.mr-list' do expect(page).to have_content('Frontend') diff --git a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb index c102722d6db..c1d4d508e57 100644 --- a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb +++ b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb @@ -39,7 +39,7 @@ feature 'Merge immediately', :feature, :js do expect(find('.accept-merge-request.btn-info')).to have_content('Merge in progress') - wait_for_vue_resource + wait_for_requests end end end diff --git a/spec/features/merge_requests/mini_pipeline_graph_spec.rb b/spec/features/merge_requests/mini_pipeline_graph_spec.rb index 5b2798af32f..51e7467c14c 100644 --- a/spec/features/merge_requests/mini_pipeline_graph_spec.rb +++ b/spec/features/merge_requests/mini_pipeline_graph_spec.rb @@ -56,7 +56,7 @@ feature 'Mini Pipeline Graph', :js, :feature do before do toggle.click - wait_for_ajax + wait_for_requests end it 'should open when toggle is clicked' do diff --git a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb index cdda0542c51..763de93f942 100644 --- a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb +++ b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'Only allow merge requests to be merged if the pipeline succeeds', feature: true, js: true do - include WaitForVueResource - let(:merge_request) { create(:merge_request_with_diffs) } let(:project) { merge_request.target_project } @@ -16,7 +14,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - wait_for_vue_resource + wait_for_requests expect(page).to have_button 'Merge' end @@ -44,7 +42,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'does not allow to merge immediately' do visit_merge_request(merge_request) - wait_for_vue_resource + wait_for_requests expect(page).to have_button 'Merge when pipeline succeeds' expect(page).not_to have_button 'Select merge moment' @@ -57,7 +55,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'does not allow MR to be merged' do visit_merge_request(merge_request) - wait_for_vue_resource + wait_for_requests expect(page).to have_css('button[disabled="disabled"]', text: 'Merge') expect(page).to have_content('Please retry the job or push a new commit to fix the failure.') @@ -70,7 +68,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'does not allow MR to be merged' do visit_merge_request(merge_request) - wait_for_vue_resource + wait_for_requests expect(page).not_to have_button 'Merge' expect(page).to have_content('Please retry the job or push a new commit to fix the failure.') @@ -83,7 +81,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - wait_for_vue_resource + wait_for_requests expect(page).to have_button 'Merge' end @@ -95,7 +93,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - wait_for_vue_resource + wait_for_requests expect(page).to have_button 'Merge' end @@ -113,7 +111,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged immediately' do visit_merge_request(merge_request) - wait_for_vue_resource + wait_for_requests expect(page).to have_button 'Merge when pipeline succeeds' @@ -128,7 +126,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - wait_for_vue_resource + wait_for_requests expect(page).to have_button 'Merge' end @@ -140,7 +138,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - wait_for_vue_resource + wait_for_requests expect(page).to have_button 'Merge' end diff --git a/spec/features/merge_requests/pipelines_spec.rb b/spec/features/merge_requests/pipelines_spec.rb index 99e283ac181..4c76004cb93 100644 --- a/spec/features/merge_requests/pipelines_spec.rb +++ b/spec/features/merge_requests/pipelines_spec.rb @@ -26,7 +26,7 @@ feature 'Pipelines for Merge Requests', feature: true, js: true do page.within('.merge-request-tabs') do click_link('Pipelines') end - wait_for_ajax + wait_for_requests expect(page).to have_selector('.pipeline-actions') end diff --git a/spec/features/merge_requests/update_merge_requests_spec.rb b/spec/features/merge_requests/update_merge_requests_spec.rb index 9ecc998785b..4ef59a8aeb8 100644 --- a/spec/features/merge_requests/update_merge_requests_spec.rb +++ b/spec/features/merge_requests/update_merge_requests_spec.rb @@ -107,7 +107,7 @@ feature 'Multiple merge requests updating from merge_requests#index', feature: t def change_assignee(text) find('#check_all_issues').click find('.js-update-assignee').click - wait_for_ajax + wait_for_requests page.within '.dropdown-menu-user' do click_link text @@ -125,6 +125,6 @@ feature 'Multiple merge requests updating from merge_requests#index', feature: t def click_update_merge_requests_button find('.update_selected_issues').click - wait_for_ajax + wait_for_requests end end diff --git a/spec/features/merge_requests/user_posts_diff_notes_spec.rb b/spec/features/merge_requests/user_posts_diff_notes_spec.rb index 7756202e3f5..14bc549c9f9 100644 --- a/spec/features/merge_requests/user_posts_diff_notes_spec.rb +++ b/spec/features/merge_requests/user_posts_diff_notes_spec.rb @@ -73,7 +73,7 @@ feature 'Merge requests > User posts diff notes', :js do context 'with an unfolded line' do before(:each) do find('.js-unfold', match: :first).click - wait_for_ajax + wait_for_requests end # The first `.js-unfold` unfolds upwards, therefore the first @@ -122,7 +122,7 @@ feature 'Merge requests > User posts diff notes', :js do context 'with an unfolded line' do before(:each) do find('.js-unfold', match: :first).click - wait_for_ajax + wait_for_requests end # The first `.js-unfold` unfolds upwards, therefore the first @@ -213,7 +213,7 @@ feature 'Merge requests > User posts diff notes', :js do write_comment_on_line(line_holder, diff_side) click_button 'Comment' - wait_for_ajax + wait_for_requests assert_comment_persistence(line_holder, asset_form_reset: asset_form_reset) end diff --git a/spec/features/merge_requests/user_posts_notes_spec.rb b/spec/features/merge_requests/user_posts_notes_spec.rb index 7fc0e2ce6ec..06de072257a 100644 --- a/spec/features/merge_requests/user_posts_notes_spec.rb +++ b/spec/features/merge_requests/user_posts_notes_spec.rb @@ -98,7 +98,7 @@ describe 'Merge requests > User posts notes', :js do find('.btn-save').click end - wait_for_ajax + wait_for_requests find('.note').hover find('.js-note-edit').click @@ -139,7 +139,7 @@ describe 'Merge requests > User posts notes', :js do find('.js-note-attachment-delete').click is_expected.not_to have_css('.note-attachment') is_expected.not_to have_css('.current-note-edit-form') - wait_for_ajax + wait_for_requests end end end diff --git a/spec/features/merge_requests/user_uses_slash_commands_spec.rb b/spec/features/merge_requests/user_uses_slash_commands_spec.rb index f0ad57eb92f..0e64a3e1a4b 100644 --- a/spec/features/merge_requests/user_uses_slash_commands_spec.rb +++ b/spec/features/merge_requests/user_uses_slash_commands_spec.rb @@ -21,7 +21,7 @@ feature 'Merge Requests > User uses slash commands', feature: true, js: true do end after do - wait_for_ajax + wait_for_requests end describe 'toggling the WIP prefix in the title from note' do @@ -160,7 +160,7 @@ feature 'Merge Requests > User uses slash commands', feature: true, js: true do it 'changes target branch from a note' do write_note("message start \n/target_branch merge-test\n message end.") - wait_for_ajax + wait_for_requests expect(page).not_to have_content('/target_branch') expect(page).to have_content('message start') expect(page).to have_content('message end.') diff --git a/spec/features/merge_requests/versions_spec.rb b/spec/features/merge_requests/versions_spec.rb index 2b5b803946c..aef8ef20938 100644 --- a/spec/features/merge_requests/versions_spec.rb +++ b/spec/features/merge_requests/versions_spec.rb @@ -75,7 +75,7 @@ feature 'Merge Request versions', js: true, feature: true do find(".js-comment-button").click end - wait_for_ajax + wait_for_requests expect(page).to have_content("Typo, please fix") end @@ -126,7 +126,7 @@ feature 'Merge Request versions', js: true, feature: true do outdated_diff_note = create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: position) visit current_url - wait_for_ajax + wait_for_requests expect(page).to have_css(".diffs .notes[data-discussion-id='#{outdated_diff_note.discussion_id}']") end @@ -144,7 +144,7 @@ feature 'Merge Request versions', js: true, feature: true do find(".js-comment-button").click end - wait_for_ajax + wait_for_requests expect(page).to have_content("Typo, please fix") end diff --git a/spec/features/merge_requests/widget_deployments_spec.rb b/spec/features/merge_requests/widget_deployments_spec.rb index 8370499f6ed..118ecd9cba5 100644 --- a/spec/features/merge_requests/widget_deployments_spec.rb +++ b/spec/features/merge_requests/widget_deployments_spec.rb @@ -18,7 +18,7 @@ feature 'Widget Deployments Header', feature: true, js: true do end scenario 'displays that the environment is deployed' do - wait_for_ajax + wait_for_requests expect(page).to have_content("Deployed to #{environment.name}") expect(find('.js-deploy-time')['data-title']).to eq(deployment.created_at.to_time.in_time_zone.to_s(:medium)) @@ -34,7 +34,7 @@ feature 'Widget Deployments Header', feature: true, js: true do end background do - wait_for_ajax + wait_for_requests end scenario 'does show stop button' do diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb index ae799584c0f..27ec3f29b48 100644 --- a/spec/features/merge_requests/widget_spec.rb +++ b/spec/features/merge_requests/widget_spec.rb @@ -27,7 +27,7 @@ describe 'Merge request', :feature, :js do it 'shows widget status after creating new merge request' do click_button 'Submit merge request' - wait_for_ajax + wait_for_requests expect(page).to have_selector('.accept-merge-request') expect(find('.accept-merge-request')['disabled']).not_to be(true) @@ -48,7 +48,7 @@ describe 'Merge request', :feature, :js do end it 'shows environments link' do - wait_for_ajax + wait_for_requests page.within('.mr-widget-heading') do expect(page).to have_content("Deployed to #{environment.name}") @@ -58,7 +58,7 @@ describe 'Merge request', :feature, :js do it 'shows green accept merge request button' do # Wait for the `ci_status` and `merge_check` requests - wait_for_ajax + wait_for_requests expect(page).to have_selector('.accept-merge-request') expect(find('.accept-merge-request')['disabled']).not_to be(true) end @@ -76,7 +76,7 @@ describe 'Merge request', :feature, :js do it 'has danger button while waiting for external CI status' do # Wait for the `ci_status` and `merge_check` requests - wait_for_ajax + wait_for_requests expect(page).to have_selector('.accept-merge-request.btn-danger') end end @@ -98,7 +98,7 @@ describe 'Merge request', :feature, :js do it 'has danger button when not succeeded' do # Wait for the `ci_status` and `merge_check` requests - wait_for_ajax + wait_for_requests expect(page).to have_selector('.accept-merge-request.btn-danger') end end @@ -145,7 +145,7 @@ describe 'Merge request', :feature, :js do it 'has info button when MWBS button' do # Wait for the `ci_status` and `merge_check` requests - wait_for_ajax + wait_for_requests expect(page).to have_selector('.accept-merge-request.btn-info') end end @@ -163,7 +163,7 @@ describe 'Merge request', :feature, :js do it 'shows information about the merge error' do # Wait for the `ci_status` and `merge_check` requests - wait_for_ajax + wait_for_requests page.within('.mr-widget-body') do expect(page).to have_content('Something went wrong') @@ -184,7 +184,7 @@ describe 'Merge request', :feature, :js do it 'shows information about the merge error' do # Wait for the `ci_status` and `merge_check` requests - wait_for_ajax + wait_for_requests page.within('.mr-widget-body') do expect(page).to have_content('Something went wrong') diff --git a/spec/features/milestones/milestones_spec.rb b/spec/features/milestones/milestones_spec.rb index 9eec3d7f270..b3dfd6d0e81 100644 --- a/spec/features/milestones/milestones_spec.rb +++ b/spec/features/milestones/milestones_spec.rb @@ -78,7 +78,7 @@ describe 'Milestone draggable', feature: true, js: true do scroll_into_view('.milestone-content') drag_to(selector: '.issues-sortable-list', list_to_index: 1) - wait_for_ajax + wait_for_requests end def create_and_drag_merge_request(params = {}) @@ -87,12 +87,12 @@ describe 'Milestone draggable', feature: true, js: true do visit namespace_project_milestone_path(project.namespace, project, milestone) page.find("a[href='#tab-merge-requests']").click - wait_for_ajax + wait_for_requests scroll_into_view('.milestone-content') drag_to(selector: '.merge_requests-sortable-list', list_to_index: 1) - wait_for_ajax + wait_for_requests end def scroll_into_view(selector) diff --git a/spec/features/projects/artifacts/file_spec.rb b/spec/features/projects/artifacts/file_spec.rb index 74308a7e8dd..25db908d917 100644 --- a/spec/features/projects/artifacts/file_spec.rb +++ b/spec/features/projects/artifacts/file_spec.rb @@ -13,7 +13,7 @@ feature 'Artifact file', :js, feature: true do before do visit_file('other_artifacts_0.1.2/doc_sample.txt') - wait_for_ajax + wait_for_requests end it 'displays an error' do @@ -37,7 +37,7 @@ feature 'Artifact file', :js, feature: true do before do visit_file('rails_sample.jpg') - wait_for_ajax + wait_for_requests end it 'displays the blob' do diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb index fc242082278..82cfbfda157 100644 --- a/spec/features/projects/blobs/blob_show_spec.rb +++ b/spec/features/projects/blobs/blob_show_spec.rb @@ -6,7 +6,7 @@ feature 'File blob', :js, feature: true do def visit_blob(path, fragment = nil) visit namespace_project_blob_path(project.namespace, project, File.join('master', path), anchor: fragment) - wait_for_ajax + wait_for_requests end context 'Ruby file' do @@ -61,7 +61,7 @@ feature 'File blob', :js, feature: true do before do find('.js-blob-viewer-switch-btn[data-viewer=simple]').click - wait_for_ajax + wait_for_requests end it 'displays the blob using the simple viewer' do @@ -82,7 +82,7 @@ feature 'File blob', :js, feature: true do before do find('.js-blob-viewer-switch-btn[data-viewer=rich]').click - wait_for_ajax + wait_for_requests end it 'displays the blob using the rich viewer' do @@ -170,7 +170,7 @@ feature 'File blob', :js, feature: true do before do find('.js-blob-viewer-switcher .js-blob-viewer-switch-btn[data-viewer=simple]').click - wait_for_ajax + wait_for_requests end it 'displays an error' do diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb index cc5b1a7e734..1a38997450d 100644 --- a/spec/features/projects/blobs/edit_spec.rb +++ b/spec/features/projects/blobs/edit_spec.rb @@ -18,7 +18,7 @@ feature 'Editing file blob', feature: true, js: true do end def edit_and_commit - wait_for_ajax + wait_for_requests find('.js-edit-blob').click execute_script('ace.edit("editor").setValue("class NextFeature\nend\n")') click_button 'Commit changes' diff --git a/spec/features/projects/blobs/user_create_spec.rb b/spec/features/projects/blobs/user_create_spec.rb index d805450e095..4b6c55f5f44 100644 --- a/spec/features/projects/blobs/user_create_spec.rb +++ b/spec/features/projects/blobs/user_create_spec.rb @@ -15,7 +15,7 @@ feature 'New blob creation', feature: true, js: true do end def edit_file - wait_for_ajax + wait_for_requests fill_in 'file_name', with: 'feature.rb' execute_script("ace.edit('editor').setValue('#{content}')") end diff --git a/spec/features/projects/commit/cherry_pick_spec.rb b/spec/features/projects/commit/cherry_pick_spec.rb index fa67d390c47..bc7ca0ddd38 100644 --- a/spec/features/projects/commit/cherry_pick_spec.rb +++ b/spec/features/projects/commit/cherry_pick_spec.rb @@ -72,11 +72,11 @@ describe 'Cherry-pick Commits' do click_button 'master' end - wait_for_ajax + wait_for_requests page.within('#modal-cherry-pick-commit .dropdown-menu') do find('.dropdown-input input').set('feature') - wait_for_ajax + wait_for_requests click_link "feature" end diff --git a/spec/features/projects/commit/mini_pipeline_graph_spec.rb b/spec/features/projects/commit/mini_pipeline_graph_spec.rb index 98c0f2c63b0..f2de195eb7f 100644 --- a/spec/features/projects/commit/mini_pipeline_graph_spec.rb +++ b/spec/features/projects/commit/mini_pipeline_graph_spec.rb @@ -32,7 +32,7 @@ feature 'Mini Pipeline Graph in Commit View', :js, :feature do it 'should show the builds list when stage is clicked' do first('.mini-pipeline-graph-dropdown-toggle').click - wait_for_ajax + wait_for_requests page.within '.js-builds-dropdown-list' do expect(page).to have_selector('.ci-status-icon-running') diff --git a/spec/features/projects/compare_spec.rb b/spec/features/projects/compare_spec.rb index b2a3b111c9e..294a63a5c6d 100644 --- a/spec/features/projects/compare_spec.rb +++ b/spec/features/projects/compare_spec.rb @@ -53,7 +53,7 @@ describe "Compare", js: true do dropdown = find(".js-compare-#{dropdown_type}-dropdown") dropdown.find(".compare-dropdown-toggle").click dropdown.fill_in("Filter by Git revision", with: selection) - wait_for_ajax + wait_for_requests dropdown.find_all("a[data-ref=\"#{selection}\"]", visible: true).last.click end end diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb index 4533a6fb144..c49648f54bd 100644 --- a/spec/features/projects/features_visibility_spec.rb +++ b/spec/features/projects/features_visibility_spec.rb @@ -21,17 +21,17 @@ describe 'Edit Project Settings', feature: true do select 'Disabled', from: "project_project_feature_attributes_#{tool_name}_access_level" click_button 'Save changes' - wait_for_ajax + wait_for_requests expect(page).not_to have_selector(".shortcuts-#{shortcut_name}") select 'Everyone with access', from: "project_project_feature_attributes_#{tool_name}_access_level" click_button 'Save changes' - wait_for_ajax + wait_for_requests expect(page).to have_selector(".shortcuts-#{shortcut_name}") select 'Only team members', from: "project_project_feature_attributes_#{tool_name}_access_level" click_button 'Save changes' - wait_for_ajax + wait_for_requests expect(page).to have_selector(".shortcuts-#{shortcut_name}") sleep 0.1 @@ -169,7 +169,7 @@ describe 'Edit Project Settings', feature: true do select "Disabled", from: "project_project_feature_attributes_wiki_access_level" click_button "Save changes" - wait_for_ajax + wait_for_requests visit namespace_project_path(project.namespace, project) @@ -182,7 +182,7 @@ describe 'Edit Project Settings', feature: true do select "Disabled", from: "project_project_feature_attributes_wiki_access_level" click_button "Save changes" - wait_for_ajax + wait_for_requests visit activity_namespace_project_path(project.namespace, project) @@ -223,7 +223,7 @@ describe 'Edit Project Settings', feature: true do def save_changes_and_check_activity_tab click_button "Save changes" - wait_for_ajax + wait_for_requests visit activity_namespace_project_path(project.namespace, project) diff --git a/spec/features/projects/files/browse_files_spec.rb b/spec/features/projects/files/browse_files_spec.rb index 4166aec1956..c0a9327249c 100644 --- a/spec/features/projects/files/browse_files_spec.rb +++ b/spec/features/projects/files/browse_files_spec.rb @@ -24,7 +24,7 @@ feature 'user browses project', feature: true, js: true do click_link 'files' click_link 'lfs' click_link 'lfs_object.iso' - wait_for_ajax + wait_for_requests expect(page).not_to have_content 'Download (1.5 MB)' expect(page).to have_content 'version https://git-lfs.github.com/spec/v1' @@ -36,7 +36,7 @@ feature 'user browses project', feature: true, js: true do last_commit = project.repository.last_commit_for_path(project.default_branch, 'files') click_link 'files' - wait_for_ajax + wait_for_requests page.within('.blob-commit-info') do expect(page).to have_content last_commit.short_id diff --git a/spec/features/projects/files/dockerfile_dropdown_spec.rb b/spec/features/projects/files/dockerfile_dropdown_spec.rb index 548131c7cd4..93909e91d05 100644 --- a/spec/features/projects/files/dockerfile_dropdown_spec.rb +++ b/spec/features/projects/files/dockerfile_dropdown_spec.rb @@ -19,14 +19,14 @@ feature 'User wants to add a Dockerfile file', feature: true do scenario 'user can pick a Dockerfile file from the dropdown', js: true do find('.js-dockerfile-selector').click - wait_for_ajax + wait_for_requests within '.dockerfile-selector' do find('.dropdown-input-field').set('HTTPd') find('.dropdown-content li', text: 'HTTPd').click end - wait_for_ajax + wait_for_requests expect(page).to have_css('.dockerfile-selector .dropdown-toggle-text', text: 'HTTPd') expect(page).to have_content('COPY ./ /usr/local/apache2/htdocs/') diff --git a/spec/features/projects/files/find_file_keyboard_spec.rb b/spec/features/projects/files/find_file_keyboard_spec.rb index e7a6749d8ac..ee42bcaec4b 100644 --- a/spec/features/projects/files/find_file_keyboard_spec.rb +++ b/spec/features/projects/files/find_file_keyboard_spec.rb @@ -10,7 +10,7 @@ feature 'Find file keyboard shortcuts', feature: true, js: true do visit namespace_project_find_file_path(project.namespace, project, project.repository.root_ref) - wait_for_ajax + wait_for_requests end it 'opens file when pressing enter key' do diff --git a/spec/features/projects/files/gitignore_dropdown_spec.rb b/spec/features/projects/files/gitignore_dropdown_spec.rb index e59428f8b24..e9f49453121 100644 --- a/spec/features/projects/files/gitignore_dropdown_spec.rb +++ b/spec/features/projects/files/gitignore_dropdown_spec.rb @@ -15,12 +15,12 @@ feature 'User wants to add a .gitignore file', feature: true do scenario 'user can pick a .gitignore file from the dropdown', js: true do find('.js-gitignore-selector').click - wait_for_ajax + wait_for_requests within '.gitignore-selector' do find('.dropdown-input-field').set('rails') find('.dropdown-content li', text: 'Rails').click end - wait_for_ajax + wait_for_requests expect(page).to have_css('.gitignore-selector .dropdown-toggle-text', text: 'Rails') expect(page).to have_content('/.bundle') diff --git a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb index 85b66b93fba..031b89d0499 100644 --- a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb +++ b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb @@ -15,12 +15,12 @@ feature 'User wants to add a .gitlab-ci.yml file', feature: true do scenario 'user can pick a template from the dropdown', js: true do find('.js-gitlab-ci-yml-selector').click - wait_for_ajax + wait_for_requests within '.gitlab-ci-yml-selector' do find('.dropdown-input-field').set('Jekyll') find('.dropdown-content li', text: 'Jekyll').click end - wait_for_ajax + wait_for_requests expect(page).to have_css('.gitlab-ci-yml-selector .dropdown-toggle-text', text: 'Jekyll') expect(page).to have_content('This file is a template, and might need editing before it works on your project') diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb index 249830921ac..8d410cc3f2e 100644 --- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb +++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb @@ -63,7 +63,7 @@ feature 'project owner creates a license file', feature: true, js: true do page.within('.js-license-selector-wrap') do click_button 'Apply a license template' click_link template - wait_for_ajax + wait_for_requests end end end diff --git a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb index 70a41886985..8e197bccabf 100644 --- a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb +++ b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb @@ -40,7 +40,7 @@ feature 'project owner sees a link to create a license file in empty project', f page.within('.js-license-selector-wrap') do click_button 'Apply a license template' click_link template - wait_for_ajax + wait_for_requests end end end diff --git a/spec/features/projects/files/undo_template_spec.rb b/spec/features/projects/files/undo_template_spec.rb index cd3af0b7d29..de10eec0557 100644 --- a/spec/features/projects/files/undo_template_spec.rb +++ b/spec/features/projects/files/undo_template_spec.rb @@ -57,7 +57,7 @@ end def select_file_template(template_selector_selector, template_name) find(template_selector_selector).click find('.dropdown-content li', text: template_name).click - wait_for_ajax + wait_for_requests end def select_file_template_type(template_type) diff --git a/spec/features/projects/issuable_templates_spec.rb b/spec/features/projects/issuable_templates_spec.rb index fa5e30075e3..3076c863dcb 100644 --- a/spec/features/projects/issuable_templates_spec.rb +++ b/spec/features/projects/issuable_templates_spec.rb @@ -34,14 +34,14 @@ feature 'issuable templates', feature: true, js: true do scenario 'user selects "bug" template' do select_template 'bug' - wait_for_ajax + wait_for_requests assert_template save_changes end scenario 'user selects "bug" template and then "no template"' do select_template 'bug' - wait_for_ajax + wait_for_requests select_option 'No template' assert_template('') save_changes('') @@ -49,7 +49,7 @@ feature 'issuable templates', feature: true, js: true do scenario 'user selects "bug" template, edits description and then selects "reset template"' do select_template 'bug' - wait_for_ajax + wait_for_requests find_field('issue_description').send_keys(description_addition) assert_template(template_content + description_addition) select_option 'Reset template' @@ -61,7 +61,7 @@ feature 'issuable templates', feature: true, js: true do start_height = page.evaluate_script('$(".markdown-area").outerHeight()') select_template 'test' - wait_for_ajax + wait_for_requests end_height = page.evaluate_script('$(".markdown-area").outerHeight()') @@ -88,7 +88,7 @@ feature 'issuable templates', feature: true, js: true do scenario 'user selects "bug" template' do select_template 'bug' - wait_for_ajax + wait_for_requests assert_template("#{template_content}") save_changes end @@ -111,7 +111,7 @@ feature 'issuable templates', feature: true, js: true do scenario 'user selects "feature-proposal" template' do select_template 'feature-proposal' - wait_for_ajax + wait_for_requests assert_template save_changes end @@ -143,7 +143,7 @@ feature 'issuable templates', feature: true, js: true do context 'template exists in target project' do scenario 'user selects template' do select_template 'feature-proposal' - wait_for_ajax + wait_for_requests assert_template save_changes end diff --git a/spec/features/projects/labels/update_prioritization_spec.rb b/spec/features/projects/labels/update_prioritization_spec.rb index 836f81fb16d..34fafe072a3 100644 --- a/spec/features/projects/labels/update_prioritization_spec.rb +++ b/spec/features/projects/labels/update_prioritization_spec.rb @@ -24,7 +24,7 @@ feature 'Prioritize labels', feature: true do page.within('.other-labels') do all('.js-toggle-priority')[1].click - wait_for_ajax + wait_for_requests expect(page).not_to have_content('feature') end @@ -43,7 +43,7 @@ feature 'Prioritize labels', feature: true do expect(page).to have_content('feature') first('.js-toggle-priority').click - wait_for_ajax + wait_for_requests expect(page).not_to have_content('bug') end @@ -59,7 +59,7 @@ feature 'Prioritize labels', feature: true do page.within('.other-labels') do first('.js-toggle-priority').click - wait_for_ajax + wait_for_requests expect(page).not_to have_content('bug') end @@ -78,7 +78,7 @@ feature 'Prioritize labels', feature: true do expect(page).to have_content('bug') first('.js-toggle-priority').click - wait_for_ajax + wait_for_requests expect(page).not_to have_content('bug') end @@ -107,7 +107,7 @@ feature 'Prioritize labels', feature: true do end refresh - wait_for_ajax + wait_for_requests page.within('.prioritized-labels') do expect(first('li')).to have_content('feature') diff --git a/spec/features/projects/members/group_links_spec.rb b/spec/features/projects/members/group_links_spec.rb index ab2b089db2e..3d253f01484 100644 --- a/spec/features/projects/members/group_links_spec.rb +++ b/spec/features/projects/members/group_links_spec.rb @@ -20,7 +20,7 @@ feature 'Projects > Members > Anonymous user sees members', feature: true, js: t click_link 'Guest' end - wait_for_ajax + wait_for_requests visit namespace_project_settings_members_path(project.namespace, project) @@ -31,7 +31,7 @@ feature 'Projects > Members > Anonymous user sees members', feature: true, js: t tomorrow = Date.today + 3 fill_in "member_expires_at_#{group.id}", with: tomorrow.strftime("%F") - wait_for_ajax + wait_for_requests page.within(find('li.group_member')) do expect(page).to have_content('Expires in') @@ -42,7 +42,7 @@ feature 'Projects > Members > Anonymous user sees members', feature: true, js: t page.within(first('.group_member')) do find('.btn-remove').click end - wait_for_ajax + wait_for_requests expect(page).not_to have_selector('.group_member') end diff --git a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb index 19d14ad9af4..1e6f15d8258 100644 --- a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb +++ b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb @@ -38,7 +38,7 @@ feature 'Projects > Members > Master adds member with expiration date', feature: page.within "#project_member_#{new_member.project_members.first.id}" do find('.js-access-expiration-date').set date.to_s(:medium) - wait_for_ajax + wait_for_requests expect(page).to have_content('Expires in 3 days') end end diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index 03a30bfb996..137d06c2a53 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -2,7 +2,6 @@ require 'spec_helper' feature 'Pipeline Schedules', :feature do include PipelineSchedulesHelper - include WaitForAjax let!(:project) { create(:project) } let!(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project) } diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 5f82cf2f5e5..a97a92aa64f 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe 'Pipelines', :feature, :js do - include WaitForVueResource - let(:project) { create(:empty_project) } context 'when user is logged in' do @@ -54,7 +52,7 @@ describe 'Pipelines', :feature, :js do context 'header tabs' do before do visit namespace_project_pipelines_path(project.namespace, project) - wait_for_vue_resource + wait_for_requests end it 'shows a tab for All pipelines and count' do @@ -106,7 +104,7 @@ describe 'Pipelines', :feature, :js do context 'when canceling' do before do find('.js-pipelines-cancel-button').click - wait_for_vue_resource + wait_for_requests end it 'indicated that pipelines was canceled' do @@ -136,7 +134,7 @@ describe 'Pipelines', :feature, :js do context 'when retrying' do before do find('.js-pipelines-retry-button').click - wait_for_vue_resource + wait_for_requests end it 'shows running pipeline that is not retryable' do @@ -356,14 +354,14 @@ describe 'Pipelines', :feature, :js do it 'should render pagination' do visit namespace_project_pipelines_path(project.namespace, project) - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.gl-pagination') end it 'should render second page of pipelines' do visit namespace_project_pipelines_path(project.namespace, project, page: '2') - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('.gl-pagination .page', count: 2) end @@ -392,7 +390,7 @@ describe 'Pipelines', :feature, :js do create(:generic_commit_status, pipeline: pipeline, stage: 'external', name: 'jenkins', stage_idx: 3) visit namespace_project_pipeline_path(project.namespace, project, pipeline) - wait_for_vue_resource + wait_for_requests end it 'shows a graph with grouped stages' do @@ -507,6 +505,6 @@ describe 'Pipelines', :feature, :js do def visit_project_pipelines(**query) visit namespace_project_pipelines_path(project.namespace, project, query) - wait_for_vue_resource + wait_for_requests end end diff --git a/spec/features/projects/ref_switcher_spec.rb b/spec/features/projects/ref_switcher_spec.rb index 881ad7910dd..04414490571 100644 --- a/spec/features/projects/ref_switcher_spec.rb +++ b/spec/features/projects/ref_switcher_spec.rb @@ -12,12 +12,12 @@ feature 'Ref switcher', feature: true, js: true do it 'allow user to change ref by enter key' do click_button 'master' - wait_for_ajax + wait_for_requests page.within '.project-refs-form' do input = find('input[type="search"]') input.set 'binary' - wait_for_ajax + wait_for_requests expect(find('.dropdown-content ul')).to have_selector('li', count: 6) @@ -31,7 +31,7 @@ feature 'Ref switcher', feature: true, js: true do it "user selects ref with special characters" do click_button 'master' - wait_for_ajax + wait_for_requests page.within '.project-refs-form' do page.fill_in 'Search branches and tags', with: "'test'" diff --git a/spec/features/projects/snippets/show_spec.rb b/spec/features/projects/snippets/show_spec.rb index cedf3778c7e..b844e60e5d5 100644 --- a/spec/features/projects/snippets/show_spec.rb +++ b/spec/features/projects/snippets/show_spec.rb @@ -17,7 +17,7 @@ feature 'Project snippet', :js, feature: true do before do visit namespace_project_snippet_path(project.namespace, project, snippet) - wait_for_ajax + wait_for_requests end it 'displays the blob' do @@ -48,7 +48,7 @@ feature 'Project snippet', :js, feature: true do before do visit namespace_project_snippet_path(project.namespace, project, snippet) - wait_for_ajax + wait_for_requests end it 'displays the blob using the rich viewer' do @@ -78,7 +78,7 @@ feature 'Project snippet', :js, feature: true do before do find('.js-blob-viewer-switch-btn[data-viewer=simple]').click - wait_for_ajax + wait_for_requests end it 'displays the blob using the simple viewer' do @@ -99,7 +99,7 @@ feature 'Project snippet', :js, feature: true do before do find('.js-blob-viewer-switch-btn[data-viewer=rich]').click - wait_for_ajax + wait_for_requests end it 'displays the blob using the rich viewer' do @@ -120,7 +120,7 @@ feature 'Project snippet', :js, feature: true do before do visit namespace_project_snippet_path(project.namespace, project, snippet, anchor: 'L1') - wait_for_ajax + wait_for_requests end it 'displays the blob using the simple viewer' do diff --git a/spec/features/projects/view_on_env_spec.rb b/spec/features/projects/view_on_env_spec.rb index b7a41ca54e6..640f1376548 100644 --- a/spec/features/projects/view_on_env_spec.rb +++ b/spec/features/projects/view_on_env_spec.rb @@ -54,7 +54,7 @@ describe 'View on environment', js: true do visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) - wait_for_ajax + wait_for_requests end it 'has a "View on env" button' do @@ -70,7 +70,7 @@ describe 'View on environment', js: true do visit namespace_project_compare_path(project.namespace, project, from: 'master', to: branch_name) - wait_for_ajax + wait_for_requests end it 'has a "View on env" button' do @@ -84,7 +84,7 @@ describe 'View on environment', js: true do visit namespace_project_compare_path(project.namespace, project, from: 'master', to: sha) - wait_for_ajax + wait_for_requests end it 'has a "View on env" button' do @@ -98,7 +98,7 @@ describe 'View on environment', js: true do visit namespace_project_blob_path(project.namespace, project, File.join(branch_name, file_path)) - wait_for_ajax + wait_for_requests end it 'has a "View on env" button' do @@ -112,7 +112,7 @@ describe 'View on environment', js: true do visit namespace_project_blob_path(project.namespace, project, File.join(sha, file_path)) - wait_for_ajax + wait_for_requests end it 'has a "View on env" button' do @@ -126,7 +126,7 @@ describe 'View on environment', js: true do visit namespace_project_commit_path(project.namespace, project, sha) - wait_for_ajax + wait_for_requests end it 'has a "View on env" button' do diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb index 2fda7758407..7834807b1f1 100644 --- a/spec/features/search_spec.rb +++ b/spec/features/search_spec.rb @@ -28,7 +28,7 @@ describe "Search", feature: true do it 'shows group name after filtering' do find('.js-search-group-dropdown').trigger('click') - wait_for_ajax + wait_for_requests page.within '.search-holder' do click_link group.name @@ -39,7 +39,7 @@ describe "Search", feature: true do it 'filters by group projects after filtering by group' do find('.js-search-group-dropdown').trigger('click') - wait_for_ajax + wait_for_requests page.within '.search-holder' do click_link group.name @@ -49,7 +49,7 @@ describe "Search", feature: true do page.within('.project-filter') do find('.js-search-project-dropdown').trigger('click') - wait_for_ajax + wait_for_requests expect(page).to have_link(group_project.name_with_namespace) end @@ -58,7 +58,7 @@ describe "Search", feature: true do it 'shows project name after filtering' do page.within('.project-filter') do find('.js-search-project-dropdown').trigger('click') - wait_for_ajax + wait_for_requests click_link project.name_with_namespace end diff --git a/spec/features/snippets/create_snippet_spec.rb b/spec/features/snippets/create_snippet_spec.rb index 9409c323288..31a2d4ae984 100644 --- a/spec/features/snippets/create_snippet_spec.rb +++ b/spec/features/snippets/create_snippet_spec.rb @@ -13,7 +13,7 @@ feature 'Create Snippet', :js, feature: true do end click_button 'Create snippet' - wait_for_ajax + wait_for_requests expect(page).to have_content('My Snippet Title') expect(page).to have_content('Hello World!') @@ -27,7 +27,7 @@ feature 'Create Snippet', :js, feature: true do end click_button 'Create snippet' - wait_for_ajax + wait_for_requests expect(page).to have_content('My Snippet Title') expect(page).to have_content('snippet+file+name') diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb index 698eb46573f..f7afc174019 100644 --- a/spec/features/snippets/notes_on_personal_snippets_spec.rb +++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb @@ -93,7 +93,7 @@ describe 'Comments on personal snippets', :js, feature: true do click_on 'Remove comment' end - wait_for_ajax + wait_for_requests expect(page).not_to have_selector("#notes-list li#note_#{snippet_notes[0].id}") end diff --git a/spec/features/snippets/public_snippets_spec.rb b/spec/features/snippets/public_snippets_spec.rb index 2df483818c3..afd945a8555 100644 --- a/spec/features/snippets/public_snippets_spec.rb +++ b/spec/features/snippets/public_snippets_spec.rb @@ -5,7 +5,7 @@ feature 'Public Snippets', :js, feature: true do public_snippet = create(:personal_snippet, :public) visit snippet_path(public_snippet) - wait_for_ajax + wait_for_requests expect(page).to have_content(public_snippet.content) end diff --git a/spec/features/snippets/show_spec.rb b/spec/features/snippets/show_spec.rb index e36cf547f80..95fc1d2bb62 100644 --- a/spec/features/snippets/show_spec.rb +++ b/spec/features/snippets/show_spec.rb @@ -11,7 +11,7 @@ feature 'Snippet', :js, feature: true do before do visit snippet_path(snippet) - wait_for_ajax + wait_for_requests end it 'displays the blob' do @@ -42,7 +42,7 @@ feature 'Snippet', :js, feature: true do before do visit snippet_path(snippet) - wait_for_ajax + wait_for_requests end it 'displays the blob using the rich viewer' do @@ -72,7 +72,7 @@ feature 'Snippet', :js, feature: true do before do find('.js-blob-viewer-switch-btn[data-viewer=simple]').click - wait_for_ajax + wait_for_requests end it 'displays the blob using the simple viewer' do @@ -93,7 +93,7 @@ feature 'Snippet', :js, feature: true do before do find('.js-blob-viewer-switch-btn[data-viewer=rich]').click - wait_for_ajax + wait_for_requests end it 'displays the blob using the rich viewer' do @@ -114,7 +114,7 @@ feature 'Snippet', :js, feature: true do before do visit snippet_path(snippet, anchor: 'L1') - wait_for_ajax + wait_for_requests end it 'displays the blob using the simple viewer' do diff --git a/spec/features/task_lists_spec.rb b/spec/features/task_lists_spec.rb index 8bd13caf2b0..563e65d3cc5 100644 --- a/spec/features/task_lists_spec.rb +++ b/spec/features/task_lists_spec.rb @@ -64,13 +64,11 @@ feature 'Task Lists', feature: true do describe 'for Issues', feature: true do describe 'multiple tasks', js: true do - include WaitForVueResource - let!(:issue) { create(:issue, description: markdown, author: user, project: project) } it 'renders' do visit_issue(project, issue) - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('ul.task-list', count: 1) expect(page).to have_selector('li.task-list-item', count: 6) @@ -79,7 +77,7 @@ feature 'Task Lists', feature: true do it 'contains the required selectors' do visit_issue(project, issue) - wait_for_vue_resource + wait_for_requests expect(page).to have_selector(".wiki .task-list .task-list-item .task-list-item-checkbox") expect(page).to have_selector('a.btn-close') @@ -87,14 +85,14 @@ feature 'Task Lists', feature: true do it 'is only editable by author' do visit_issue(project, issue) - wait_for_vue_resource + wait_for_requests expect(page).to have_selector(".wiki .task-list .task-list-item .task-list-item-checkbox") logout(:user) login_as(user2) visit current_path - wait_for_vue_resource + wait_for_requests expect(page).to have_selector(".wiki .task-list .task-list-item .task-list-item-checkbox") end @@ -106,13 +104,11 @@ feature 'Task Lists', feature: true do end describe 'single incomplete task', js: true do - include WaitForVueResource - let!(:issue) { create(:issue, description: singleIncompleteMarkdown, author: user, project: project) } it 'renders' do visit_issue(project, issue) - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('ul.task-list', count: 1) expect(page).to have_selector('li.task-list-item', count: 1) @@ -127,12 +123,11 @@ feature 'Task Lists', feature: true do end describe 'single complete task', js: true do - include WaitForVueResource let!(:issue) { create(:issue, description: singleCompleteMarkdown, author: user, project: project) } it 'renders' do visit_issue(project, issue) - wait_for_vue_resource + wait_for_requests expect(page).to have_selector('ul.task-list', count: 1) expect(page).to have_selector('li.task-list-item', count: 1) diff --git a/spec/features/todos/todos_filtering_spec.rb b/spec/features/todos/todos_filtering_spec.rb index f32e70c2c3f..bbfa4e08379 100644 --- a/spec/features/todos/todos_filtering_spec.rb +++ b/spec/features/todos/todos_filtering_spec.rb @@ -28,7 +28,7 @@ describe 'Dashboard > User filters todos', feature: true, js: true do click_link project_1.name_with_namespace end - wait_for_ajax + wait_for_requests expect(page).to have_content project_1.name_with_namespace expect(page).not_to have_content project_2.name_with_namespace @@ -43,7 +43,7 @@ describe 'Dashboard > User filters todos', feature: true, js: true do click_link user_1.name end - wait_for_ajax + wait_for_requests expect(find('.todos-list')).to have_content 'merge request' expect(find('.todos-list')).not_to have_content 'issue' @@ -90,7 +90,7 @@ describe 'Dashboard > User filters todos', feature: true, js: true do click_link 'Issue' end - wait_for_ajax + wait_for_requests expect(find('.todos-list')).to have_content issue.to_reference expect(find('.todos-list')).not_to have_content merge_request.to_reference @@ -132,7 +132,7 @@ describe 'Dashboard > User filters todos', feature: true, js: true do click_link name end - wait_for_ajax + wait_for_requests end def expect_to_see_action(action_name) diff --git a/spec/features/todos/todos_spec.rb b/spec/features/todos/todos_spec.rb index 55b3e3d9424..bb4b2aed0e3 100644 --- a/spec/features/todos/todos_spec.rb +++ b/spec/features/todos/todos_spec.rb @@ -64,7 +64,7 @@ describe 'Dashboard Todos', feature: true do before do within first('.todo') do click_link 'Done' - wait_for_ajax + wait_for_requests click_link 'Undo' end end @@ -309,9 +309,9 @@ describe 'Dashboard Todos', feature: true do def mark_all_and_undo find('.js-todos-mark-all').trigger('click') - wait_for_ajax + wait_for_requests find('.js-todos-undo-all').trigger('click') - wait_for_ajax + wait_for_requests end end end diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb index 544d2dcb87f..2fed8067042 100644 --- a/spec/features/u2f_spec.rb +++ b/spec/features/u2f_spec.rb @@ -6,7 +6,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do def manage_two_factor_authentication click_on 'Manage two-factor authentication' expect(page).to have_content("Setup new U2F device") - wait_for_ajax + wait_for_requests end def register_u2f_device(u2f_device = nil, name: 'My device') diff --git a/spec/features/uploads/user_uploads_file_to_note_spec.rb b/spec/features/uploads/user_uploads_file_to_note_spec.rb index 8f03024ea06..9332d3b88d2 100644 --- a/spec/features/uploads/user_uploads_file_to_note_spec.rb +++ b/spec/features/uploads/user_uploads_file_to_note_spec.rb @@ -64,7 +64,7 @@ feature 'User uploads file to note', feature: true do context 'uploading is complete' do it 'shows "Attach a file" button on uploading complete', js: true do dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')]) - wait_for_ajax + wait_for_requests expect(page).to have_button('Attach a file') expect(page).not_to have_selector('.uploading-progress-container', visible: true) @@ -73,7 +73,7 @@ feature 'User uploads file to note', feature: true do scenario 'they see the attached file', js: true do dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')]) click_button 'Comment' - wait_for_ajax + wait_for_requests expect(find('a.no-attachment-icon img[alt="dk"]')['src']) .to match(%r{/#{project.full_path}/uploads/\h{32}/dk\.png$}) diff --git a/spec/features/users/projects_spec.rb b/spec/features/users/projects_spec.rb index 373b64808f8..67ce4b44464 100644 --- a/spec/features/users/projects_spec.rb +++ b/spec/features/users/projects_spec.rb @@ -16,7 +16,7 @@ describe 'Projects tab on a user profile', :feature, :js do click_link('Personal projects') end - wait_for_ajax + wait_for_requests end it 'paginates results' do diff --git a/spec/features/users/snippets_spec.rb b/spec/features/users/snippets_spec.rb index 4efbd672322..2e388115633 100644 --- a/spec/features/users/snippets_spec.rb +++ b/spec/features/users/snippets_spec.rb @@ -11,7 +11,7 @@ describe 'Snippets tab on a user profile', feature: true, js: true do allow(Snippet).to receive(:default_per_page).and_return(1) visit user_path(user) page.within('.user-profile-nav') { click_link 'Snippets' } - wait_for_ajax + wait_for_requests end it_behaves_like 'paginated snippets', remote: true @@ -27,7 +27,7 @@ describe 'Snippets tab on a user profile', feature: true, js: true do login_as(:user) visit user_path(user) page.within('.user-profile-nav') { click_link 'Snippets' } - wait_for_ajax + wait_for_requests expect(page).to have_selector('.snippet-row', count: 2) @@ -38,7 +38,7 @@ describe 'Snippets tab on a user profile', feature: true, js: true do it 'contains only public snippets of a user when a user is not logged in' do visit user_path(user) page.within('.user-profile-nav') { click_link 'Snippets' } - wait_for_ajax + wait_for_requests expect(page).to have_selector('.snippet-row', count: 1) expect(page).to have_content(public_snippet.title) diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb index c43feadc808..fbe078bd136 100644 --- a/spec/features/users_spec.rb +++ b/spec/features/users_spec.rb @@ -78,25 +78,25 @@ feature 'Users', feature: true, js: true do scenario 'doesn\'t show an error border if the username is available' do fill_in username_input, with: 'new-user' - wait_for_ajax + wait_for_requests expect(find('.username')).not_to have_css '.gl-field-error-outline' end scenario 'does not show an error border if the username contains dots (.)' do fill_in username_input, with: 'new.user.username' - wait_for_ajax + wait_for_requests expect(find('.username')).not_to have_css '.gl-field-error-outline' end scenario 'shows an error border if the username already exists' do fill_in username_input, with: user.username - wait_for_ajax + wait_for_requests expect(find('.username')).to have_css '.gl-field-error-outline' end scenario 'shows an error border if the username contains special characters' do fill_in username_input, with: 'new$user!username' - wait_for_ajax + wait_for_requests expect(find('.username')).to have_css '.gl-field-error-outline' end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a58f4e664b7..51571ddebe9 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -44,7 +44,6 @@ RSpec.configure do |config| config.include LoginHelpers, type: :feature config.include SearchHelpers, type: :feature config.include WaitForRequests, :js - config.include WaitForAjax, :js config.include StubConfiguration config.include EmailHelpers, type: :mailer config.include TestEnv diff --git a/spec/support/features/issuable_slash_commands_shared_examples.rb b/spec/support/features/issuable_slash_commands_shared_examples.rb index ad46b163cd6..fa82dc5e9f9 100644 --- a/spec/support/features/issuable_slash_commands_shared_examples.rb +++ b/spec/support/features/issuable_slash_commands_shared_examples.rb @@ -22,7 +22,7 @@ shared_examples 'issuable record that supports slash commands in its description after do # Ensure all outstanding Ajax requests are complete to avoid database deadlocks - wait_for_ajax + wait_for_requests end describe "new #{issuable_type}", js: true do @@ -58,7 +58,7 @@ shared_examples 'issuable record that supports slash commands in its description expect(page).not_to have_content '/label ~bug' expect(page).not_to have_content '/milestone %"ASAP"' - wait_for_ajax + wait_for_requests issuable.reload note = issuable.notes.user.first diff --git a/spec/support/protected_branches/access_control_ce_shared_examples.rb b/spec/support/protected_branches/access_control_ce_shared_examples.rb index 7fda4ade665..287d6bb13c3 100644 --- a/spec/support/protected_branches/access_control_ce_shared_examples.rb +++ b/spec/support/protected_branches/access_control_ce_shared_examples.rb @@ -38,7 +38,7 @@ RSpec.shared_examples "protected branches > access control > CE" do end end - wait_for_ajax + wait_for_requests expect(ProtectedBranch.last.push_access_levels.map(&:access_level)).to include(access_type_id) end @@ -83,7 +83,7 @@ RSpec.shared_examples "protected branches > access control > CE" do end end - wait_for_ajax + wait_for_requests expect(ProtectedBranch.last.merge_access_levels.map(&:access_level)).to include(access_type_id) end diff --git a/spec/support/protected_tags/access_control_ce_shared_examples.rb b/spec/support/protected_tags/access_control_ce_shared_examples.rb index 12622cd548a..1d11512ef82 100644 --- a/spec/support/protected_tags/access_control_ce_shared_examples.rb +++ b/spec/support/protected_tags/access_control_ce_shared_examples.rb @@ -39,7 +39,7 @@ RSpec.shared_examples "protected tags > access control > CE" do end end - wait_for_ajax + wait_for_requests expect(ProtectedTag.last.create_access_levels.map(&:access_level)).to include(access_type_id) end diff --git a/spec/support/snippets_shared_examples.rb b/spec/support/snippets_shared_examples.rb index 57dfff3471f..85f0facd5c3 100644 --- a/spec/support/snippets_shared_examples.rb +++ b/spec/support/snippets_shared_examples.rb @@ -7,7 +7,7 @@ RSpec.shared_examples 'paginated snippets' do |remote: false| context 'clicking on the link to the second page' do before do click_link('2') - wait_for_ajax if remote + wait_for_requests if remote end it 'shows the remaining snippets' do diff --git a/spec/support/target_branch_helpers.rb b/spec/support/target_branch_helpers.rb index 3ee8f0f657e..01d1c53fe6c 100644 --- a/spec/support/target_branch_helpers.rb +++ b/spec/support/target_branch_helpers.rb @@ -1,7 +1,7 @@ module TargetBranchHelpers def select_branch(name) first('button.js-target-branch').click - wait_for_ajax + wait_for_requests all('a[data-group="Branches"]').find do |el| el.text == name end.click diff --git a/spec/support/time_tracking_shared_examples.rb b/spec/support/time_tracking_shared_examples.rb index 84ef46ffa27..b407b8097d2 100644 --- a/spec/support/time_tracking_shared_examples.rb +++ b/spec/support/time_tracking_shared_examples.rb @@ -8,7 +8,7 @@ shared_examples 'issuable time tracker' do it 'updates the sidebar component when estimate is added' do submit_time('/estimate 3w 1d 1h') - wait_for_ajax + wait_for_requests page.within '.time-tracking-estimate-only-pane' do expect(page).to have_content '3w 1d 1h' end @@ -17,7 +17,7 @@ shared_examples 'issuable time tracker' do it 'updates the sidebar component when spent is added' do submit_time('/spend 3w 1d 1h') - wait_for_ajax + wait_for_requests page.within '.time-tracking-spend-only-pane' do expect(page).to have_content '3w 1d 1h' end @@ -27,7 +27,7 @@ shared_examples 'issuable time tracker' do submit_time('/estimate 3w 1d 1h') submit_time('/spend 3w 1d 1h') - wait_for_ajax + wait_for_requests page.within '.time-tracking-comparison-pane' do expect(page).to have_content '3w 1d 1h' end @@ -81,5 +81,5 @@ end def submit_time(slash_command) fill_in 'note[note]', with: slash_command find('.js-comment-submit-button').trigger('click') - wait_for_ajax + wait_for_requests end diff --git a/spec/support/wait_for_ajax.rb b/spec/support/wait_for_ajax.rb deleted file mode 100644 index 508de2ee8e1..00000000000 --- a/spec/support/wait_for_ajax.rb +++ /dev/null @@ -1,18 +0,0 @@ -module WaitForAjax - def wait_for_ajax - Timeout.timeout(Capybara.default_max_wait_time) do - loop until finished_all_ajax_requests? - end - end - - def finished_all_ajax_requests? - return true unless javascript_test? - return true if page.evaluate_script('typeof jQuery === "undefined"') - - page.evaluate_script('jQuery.active').zero? - end - - def javascript_test? - Capybara.current_driver == Capybara.javascript_driver - end -end diff --git a/spec/support/wait_for_requests.rb b/spec/support/wait_for_requests.rb index d41e83ae128..05ec9026141 100644 --- a/spec/support/wait_for_requests.rb +++ b/spec/support/wait_for_requests.rb @@ -1,21 +1,31 @@ -require_relative './wait_for_ajax' -require_relative './wait_for_vue_resource' +require_relative './wait_for_requests' module WaitForRequests extend self - include WaitForAjax - include WaitForVueResource # This is inspired by http://www.salsify.com/blog/engineering/tearing-capybara-ajax-tests - def wait_for_requests_complete + def block_and_wait_for_requests_complete Gitlab::Testing::RequestBlockerMiddleware.block_requests! - wait_for('pending AJAX requests complete') do + wait_for('pending requests complete') do Gitlab::Testing::RequestBlockerMiddleware.num_active_requests.zero? end ensure Gitlab::Testing::RequestBlockerMiddleware.allow_requests! end + def wait_for_requests + wait_for('JS requests') { finished_all_requests? } + end + + private + + def finished_all_requests? + return true unless javascript_test? + + finished_all_ajax_requests? && + finished_all_vue_resource_requests? + end + # Waits until the passed block returns true def wait_for(condition_name, max_wait_time: Capybara.default_max_wait_time, polling_interval: 0.01) wait_until = Time.now + max_wait_time.seconds @@ -28,10 +38,24 @@ module WaitForRequests end end end + + def finished_all_vue_resource_requests? + page.evaluate_script('window.activeVueResources || 0').zero? + end + + def finished_all_ajax_requests? + return true if page.evaluate_script('typeof jQuery === "undefined"') + + page.evaluate_script('jQuery.active').zero? + end + + def javascript_test? + Capybara.current_driver == Capybara.javascript_driver + end end RSpec.configure do |config| config.after(:each, :js) do - wait_for_requests_complete + block_and_wait_for_requests_complete end end diff --git a/spec/support/wait_for_vue_resource.rb b/spec/support/wait_for_vue_resource.rb deleted file mode 100644 index 3bb3d9c2e51..00000000000 --- a/spec/support/wait_for_vue_resource.rb +++ /dev/null @@ -1,19 +0,0 @@ -module WaitForVueResource - def wait_for_vue_resource(spinner: true) - Timeout.timeout(Capybara.default_max_wait_time) do - loop until finished_all_vue_resource_requests? - end - end - - private - - def finished_all_vue_resource_requests? - return true unless javascript_test? - - page.evaluate_script('window.activeVueResources || 0').zero? - end - - def javascript_test? - Capybara.current_driver == Capybara.javascript_driver - end -end -- cgit v1.2.1 From 4731ae75c6aaeac76ae9ca549453ff8536b445e5 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 23 May 2017 08:52:23 +0200 Subject: Fix propagate service spec transient failure --- spec/services/projects/propagate_service_template_spec.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'spec') diff --git a/spec/services/projects/propagate_service_template_spec.rb b/spec/services/projects/propagate_service_template_spec.rb index 90eff3bbc1e..8a6a9f09f74 100644 --- a/spec/services/projects/propagate_service_template_spec.rb +++ b/spec/services/projects/propagate_service_template_spec.rb @@ -71,14 +71,18 @@ describe Projects::PropagateServiceTemplate, services: true do end describe 'bulk update' do - it 'creates services for all projects' do - project_total = 5 + let(:project_total) { 5 } + + before do stub_const 'Projects::PropagateServiceTemplate::BATCH_SIZE', 3 project_total.times { create(:empty_project) } - expect { described_class.propagate(service_template) }. - to change { Service.count }.by(project_total + 1) + described_class.propagate(service_template) + end + + it 'creates services for all projects' do + expect(Service.all.reload.count).to eq(project_total + 2) end end -- cgit v1.2.1 From 719e30c53d1d0690fa9e96fa488047e0a68d00a2 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Tue, 23 May 2017 10:04:47 +0300 Subject: Fix review comment --- .../projects/guest_navigation_menu_spec.rb | 39 +++++++++++++--------- 1 file changed, 24 insertions(+), 15 deletions(-) (limited to 'spec') diff --git a/spec/features/projects/guest_navigation_menu_spec.rb b/spec/features/projects/guest_navigation_menu_spec.rb index 89bed711bfe..b91c3eff478 100644 --- a/spec/features/projects/guest_navigation_menu_spec.rb +++ b/spec/features/projects/guest_navigation_menu_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe "Guest navigation menu" do +describe 'Guest navigation menu' do let(:project) { create(:empty_project, :private, public_builds: false) } let(:guest) { create(:user) } @@ -10,10 +10,10 @@ describe "Guest navigation menu" do login_as(guest) end - it "shows allowed tabs only" do + it 'shows allowed tabs only' do visit namespace_project_path(project.namespace, project) - within(".layout-nav") do + within('.layout-nav') do expect(page).to have_content 'Project' expect(page).to have_content 'Issues' expect(page).to have_content 'Wiki' @@ -24,49 +24,58 @@ describe "Guest navigation menu" do end end - it "does not show fork button" do + it 'does not show fork button' do visit namespace_project_path(project.namespace, project) - within(".count-buttons") do + within('.count-buttons') do expect(page).not_to have_link 'Fork' end end - it "does not show clone path" do + it 'does not show clone path' do visit namespace_project_path(project.namespace, project) - within(".project-repo-buttons") do + within('.project-repo-buttons') do expect(page).not_to have_selector '.project-clone-holder' end end describe 'project landing page' do before do - project.project_feature.update_attribute("issues_access_level", ProjectFeature::DISABLED) - project.project_feature.update_attribute("wiki_access_level", ProjectFeature::DISABLED) + project.project_feature.update!( + issues_access_level: ProjectFeature::DISABLED, + wiki_access_level: ProjectFeature::DISABLED + ) end - it "does not show the project file list landing page" do + it 'does not show the project file list landing page' do visit namespace_project_path(project.namespace, project) + expect(page).not_to have_selector '.project-stats' expect(page).not_to have_selector '.project-last-commit' expect(page).not_to have_selector '.project-show-files' + expect(page).to have_selector '.project-show-customize_workflow' end - it "shows the customize workflow when issues and wiki are disabled" do + it 'shows the customize workflow when issues and wiki are disabled' do visit namespace_project_path(project.namespace, project) + expect(page).to have_selector '.project-show-customize_workflow' end - it "shows the wiki when enabled" do - project.project_feature.update_attribute("wiki_access_level", ProjectFeature::PRIVATE) + it 'shows the wiki when enabled' do + project.project_feature.update!(wiki_access_level: ProjectFeature::PRIVATE) + visit namespace_project_path(project.namespace, project) + expect(page).to have_selector '.project-show-wiki' end - it "shows the issues when enabled" do - project.project_feature.update_attribute("issues_access_level", ProjectFeature::PRIVATE) + it 'shows the issues when enabled' do + project.project_feature.update!(issues_access_level: ProjectFeature::PRIVATE) + visit namespace_project_path(project.namespace, project) + expect(page).to have_selector '.issues-list' end end -- cgit v1.2.1 From d7f9b408bf330ec53d641525dd4905f9344bf4e0 Mon Sep 17 00:00:00 2001 From: winh Date: Tue, 16 May 2017 12:56:28 +0200 Subject: Add frontend UsersCache class (!11404) --- spec/javascripts/lib/utils/users_cache_spec.js | 136 +++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 spec/javascripts/lib/utils/users_cache_spec.js (limited to 'spec') diff --git a/spec/javascripts/lib/utils/users_cache_spec.js b/spec/javascripts/lib/utils/users_cache_spec.js new file mode 100644 index 00000000000..ec6ea35952b --- /dev/null +++ b/spec/javascripts/lib/utils/users_cache_spec.js @@ -0,0 +1,136 @@ +import Api from '~/api'; +import UsersCache from '~/lib/utils/users_cache'; + +describe('UsersCache', () => { + const dummyUsername = 'win'; + const dummyUser = 'has a farm'; + + beforeEach(() => { + UsersCache.internalStorage = { }; + }); + + describe('get', () => { + it('returns undefined for empty cache', () => { + expect(UsersCache.internalStorage).toEqual({ }); + + const user = UsersCache.get(dummyUsername); + + expect(user).toBe(undefined); + }); + + it('returns undefined for missing user', () => { + UsersCache.internalStorage['no body'] = 'no data'; + + const user = UsersCache.get(dummyUsername); + + expect(user).toBe(undefined); + }); + + it('returns matching user', () => { + UsersCache.internalStorage[dummyUsername] = dummyUser; + + const user = UsersCache.get(dummyUsername); + + expect(user).toBe(dummyUser); + }); + }); + + describe('hasData', () => { + it('returns false for empty cache', () => { + expect(UsersCache.internalStorage).toEqual({ }); + + expect(UsersCache.hasData(dummyUsername)).toBe(false); + }); + + it('returns false for missing user', () => { + UsersCache.internalStorage['no body'] = 'no data'; + + expect(UsersCache.hasData(dummyUsername)).toBe(false); + }); + + it('returns true for matching user', () => { + UsersCache.internalStorage[dummyUsername] = dummyUser; + + expect(UsersCache.hasData(dummyUsername)).toBe(true); + }); + }); + + describe('remove', () => { + it('does nothing if cache is empty', () => { + expect(UsersCache.internalStorage).toEqual({ }); + + UsersCache.remove(dummyUsername); + + expect(UsersCache.internalStorage).toEqual({ }); + }); + + it('does nothing if cache contains no matching data', () => { + UsersCache.internalStorage['no body'] = 'no data'; + + UsersCache.remove(dummyUsername); + + expect(UsersCache.internalStorage['no body']).toBe('no data'); + }); + + it('removes matching data', () => { + UsersCache.internalStorage[dummyUsername] = dummyUser; + + UsersCache.remove(dummyUsername); + + expect(UsersCache.internalStorage).toEqual({ }); + }); + }); + + describe('retrieve', () => { + let apiSpy; + + beforeEach(() => { + spyOn(Api, 'users').and.callFake((query, options) => apiSpy(query, options)); + }); + + it('stores and returns data from API call if cache is empty', (done) => { + apiSpy = (query, options) => { + expect(query).toBe(''); + expect(options).toEqual({ username: dummyUsername }); + return Promise.resolve([dummyUser]); + }; + + UsersCache.retrieve(dummyUsername) + .then((user) => { + expect(user).toBe(dummyUser); + expect(UsersCache.internalStorage[dummyUsername]).toBe(dummyUser); + }) + .then(done) + .catch(done.fail); + }); + + it('returns undefined if Ajax call fails and cache is empty', (done) => { + const dummyError = new Error('server exploded'); + apiSpy = (query, options) => { + expect(query).toBe(''); + expect(options).toEqual({ username: dummyUsername }); + return Promise.reject(dummyError); + }; + + UsersCache.retrieve(dummyUsername) + .then(user => fail(`Received unexpected user: ${JSON.stringify(user)}`)) + .catch((error) => { + expect(error).toBe(dummyError); + }) + .then(done) + .catch(done.fail); + }); + + it('makes no Ajax call if matching data exists', (done) => { + UsersCache.internalStorage[dummyUsername] = dummyUser; + apiSpy = () => fail(new Error('expected no Ajax call!')); + + UsersCache.retrieve(dummyUsername) + .then((user) => { + expect(user).toBe(dummyUser); + }) + .then(done) + .catch(done.fail); + }); + }); +}); -- cgit v1.2.1 From 5c83d3aff2401aa134ec1bf23013ba9e47109b48 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Mon, 22 May 2017 08:24:08 +0200 Subject: Improve test wording --- spec/controllers/projects/environments_controller_spec.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'spec') diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index 93dbedae2b2..20f99b209eb 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -1,25 +1,25 @@ require 'spec_helper' describe Projects::EnvironmentsController do - let(:user) { create(:user) } - let(:project) { create(:empty_project) } + set(:user) { create(:user) } + set(:project) { create(:empty_project) } - let(:environment) do + set(:environment) do create(:environment, name: 'production', project: project) end before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end describe 'GET index' do - context 'when standardrequest has been made' do + context 'when a request for the HTML is made' do it 'responds with status code 200' do get :index, environment_params - expect(response).to be_ok + expect(response).to have_http_status(:ok) end end @@ -101,7 +101,7 @@ describe Projects::EnvironmentsController do end context 'when using JSON format' do - it 'responds with with a sorted JSON' do + it 'sorts the subfolders lexicographically' do get :folder, namespace_id: project.namespace, project_id: project, id: 'staging-1.0', -- cgit v1.2.1 From 6fe2744d2359ac765a70ca0c766e75de90ca39b9 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Tue, 23 May 2017 11:15:05 +0200 Subject: Add tests for removing old backups with the new timestamp --- spec/lib/gitlab/backup/manager_spec.rb | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'spec') diff --git a/spec/lib/gitlab/backup/manager_spec.rb b/spec/lib/gitlab/backup/manager_spec.rb index c59ff7fb290..be8ee961a2b 100644 --- a/spec/lib/gitlab/backup/manager_spec.rb +++ b/spec/lib/gitlab/backup/manager_spec.rb @@ -24,6 +24,8 @@ describe Backup::Manager, lib: true do describe '#remove_old' do let(:files) do [ + '1495528448_2017_05_23_9.3.0-pre_gitlab_backup.tar', + '1495528448_2017_05_23_9.3.0_gitlab_backup.tar', '1451606400_2016_01_01_gitlab_backup.tar', '1451520000_2015_12_31_gitlab_backup.tar', '1450742400_2015_12_22_gitlab_backup.tar', @@ -37,7 +39,7 @@ describe Backup::Manager, lib: true do allow(Dir).to receive(:chdir).and_yield allow(Dir).to receive(:glob).and_return(files) allow(FileUtils).to receive(:rm) - allow(Time).to receive(:now).and_return(Time.utc(2016)) + allow(Time).to receive(:now).and_return(Time.utc(2017)) end context 'when keep_time is zero' do @@ -79,26 +81,31 @@ describe Backup::Manager, lib: true do subject.remove_old end - it 'removes matching files with a human-readable timestamp' do + it 'removes matching files with a human-readable versioned timestamp' do + expect(FileUtils).to have_received(:rm).with(files[0]) expect(FileUtils).to have_received(:rm).with(files[1]) - expect(FileUtils).to have_received(:rm).with(files[2]) end - it 'removes matching files without a human-readable timestamp' do + it 'removes matching files with a human-readable non-versioned timestamp' do expect(FileUtils).to have_received(:rm).with(files[3]) expect(FileUtils).to have_received(:rm).with(files[4]) end + it 'removes matching files without a human-readable timestamp' do + expect(FileUtils).to have_received(:rm).with(files[5]) + expect(FileUtils).to have_received(:rm).with(files[6]) + end + it 'does not remove files that are not old enough' do expect(FileUtils).not_to have_received(:rm).with(files[0]) end it 'does not remove non-matching files' do - expect(FileUtils).not_to have_received(:rm).with(files[5]) + expect(FileUtils).not_to have_received(:rm).with(files[7]) end it 'prints a done message' do - expect(progress).to have_received(:puts).with('done. (4 removed)') + expect(progress).to have_received(:puts).with('done. (5 removed)') end end -- cgit v1.2.1 From a74b7d90a84758e623c2eb8cca95175377a61523 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Mon, 17 Apr 2017 19:59:55 +0800 Subject: Add feature test with unicode trace Squashed commit of the following: commit 43e5bba774e9e383dd55c665e82f6fcfc4ebfc4f Author: Shinya Maeda Date: Mon Apr 17 17:28:44 2017 +0900 Add fix commit 09610eebdf22ad048812bb86022504b2ad917e19 Author: Shinya Maeda Date: Mon Apr 17 17:03:49 2017 +0900 Add trace test --- .../controllers/projects/builds_controller_spec.rb | 57 ++++++---------------- spec/factories/ci/builds.rb | 10 ++++ 2 files changed, 25 insertions(+), 42 deletions(-) (limited to 'spec') diff --git a/spec/controllers/projects/builds_controller_spec.rb b/spec/controllers/projects/builds_controller_spec.rb index 3ce23c17cdc..f41503fd34e 100644 --- a/spec/controllers/projects/builds_controller_spec.rb +++ b/spec/controllers/projects/builds_controller_spec.rb @@ -144,6 +144,8 @@ describe Projects::BuildsController do it 'returns a trace' do expect(response).to have_http_status(:ok) + expect(json_response['id']).to eq build.id + expect(json_response['status']).to eq build.status expect(json_response['html']).to eq('BUILD TRACE') end end @@ -153,10 +155,23 @@ describe Projects::BuildsController do it 'returns no traces' do expect(response).to have_http_status(:ok) + expect(json_response['id']).to eq build.id + expect(json_response['status']).to eq build.status expect(json_response['html']).to be_nil end end + context 'when build has a trace with ANSI sequence and Unicode' do + let(:build) { create(:ci_build, :unicode_trace, pipeline: pipeline) } + + it 'returns a trace with Unicode' do + expect(response).to have_http_status(:ok) + expect(json_response['id']).to eq build.id + expect(json_response['status']).to eq build.status + expect(json_response['html']).to include("ヾ(´༎ຶД༎ຶ`)ノ") + end + end + def get_trace get :trace, namespace_id: project.namespace, project_id: project, @@ -185,48 +200,6 @@ describe Projects::BuildsController do end end - describe 'GET trace.json' do - let(:pipeline) { create(:ci_pipeline, project: project) } - let(:build) { create(:ci_build, pipeline: pipeline) } - let(:user) { create(:user) } - - context 'when user is logged in as developer' do - before do - project.add_developer(user) - sign_in(user) - - get_trace - end - - it 'traces build log' do - expect(response).to have_http_status(:ok) - expect(json_response['id']).to eq build.id - expect(json_response['status']).to eq build.status - end - end - - context 'when user is logged in as non member' do - before do - sign_in(user) - - get_trace - end - - it 'traces build log' do - expect(response).to have_http_status(:ok) - expect(json_response['id']).to eq build.id - expect(json_response['status']).to eq build.status - end - end - - def get_trace - get :trace, namespace_id: project.namespace, - project_id: project, - id: build.id, - format: :json - end - end - describe 'POST retry' do before do project.add_developer(user) diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb index 78ddd8d5584..f5e99fdf00b 100644 --- a/spec/factories/ci/builds.rb +++ b/spec/factories/ci/builds.rb @@ -128,6 +128,16 @@ FactoryGirl.define do end end + trait :unicode_trace do + after(:create) do |build, evaluator| + trace = File.binread( + File.expand_path( + Rails.root.join('spec/fixtures/trace/ansi-sequence-and-unicode'))) + + build.trace.set(trace) + end + end + trait :erased do erased_at Time.now erased_by factory: :user -- cgit v1.2.1 From 4ee79839cf3cc81d21a3488f837eec8497508a21 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Tue, 23 May 2017 13:34:22 +0200 Subject: Fix tests --- spec/lib/gitlab/backup/manager_spec.rb | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'spec') diff --git a/spec/lib/gitlab/backup/manager_spec.rb b/spec/lib/gitlab/backup/manager_spec.rb index be8ee961a2b..1c3d2547fec 100644 --- a/spec/lib/gitlab/backup/manager_spec.rb +++ b/spec/lib/gitlab/backup/manager_spec.rb @@ -24,10 +24,9 @@ describe Backup::Manager, lib: true do describe '#remove_old' do let(:files) do [ - '1495528448_2017_05_23_9.3.0-pre_gitlab_backup.tar', - '1495528448_2017_05_23_9.3.0_gitlab_backup.tar', - '1451606400_2016_01_01_gitlab_backup.tar', - '1451520000_2015_12_31_gitlab_backup.tar', + '1451606400_2016_01_01_1.2.3_gitlab_backup.tar', + '1451520000_2015_12_31_4.5.6_gitlab_backup.tar', + '1451510000_2015_12_30_gitlab_backup.tar', '1450742400_2015_12_22_gitlab_backup.tar', '1449878400_gitlab_backup.tar', '1449014400_gitlab_backup.tar', @@ -39,7 +38,7 @@ describe Backup::Manager, lib: true do allow(Dir).to receive(:chdir).and_yield allow(Dir).to receive(:glob).and_return(files) allow(FileUtils).to receive(:rm) - allow(Time).to receive(:now).and_return(Time.utc(2017)) + allow(Time).to receive(:now).and_return(Time.utc(2016)) end context 'when keep_time is zero' do @@ -60,6 +59,7 @@ describe Backup::Manager, lib: true do context 'when there are no files older than keep_time' do before do + # Set to 30 days allow(Gitlab.config.backup).to receive(:keep_time).and_return(2592000) subject.remove_old @@ -76,24 +76,24 @@ describe Backup::Manager, lib: true do context 'when keep_time is set to remove files' do before do + # Set to 1 second allow(Gitlab.config.backup).to receive(:keep_time).and_return(1) subject.remove_old end it 'removes matching files with a human-readable versioned timestamp' do - expect(FileUtils).to have_received(:rm).with(files[0]) expect(FileUtils).to have_received(:rm).with(files[1]) end it 'removes matching files with a human-readable non-versioned timestamp' do + expect(FileUtils).to have_received(:rm).with(files[2]) expect(FileUtils).to have_received(:rm).with(files[3]) - expect(FileUtils).to have_received(:rm).with(files[4]) end it 'removes matching files without a human-readable timestamp' do + expect(FileUtils).to have_received(:rm).with(files[4]) expect(FileUtils).to have_received(:rm).with(files[5]) - expect(FileUtils).to have_received(:rm).with(files[6]) end it 'does not remove files that are not old enough' do @@ -101,7 +101,7 @@ describe Backup::Manager, lib: true do end it 'does not remove non-matching files' do - expect(FileUtils).not_to have_received(:rm).with(files[7]) + expect(FileUtils).not_to have_received(:rm).with(files[6]) end it 'prints a done message' do @@ -124,10 +124,11 @@ describe Backup::Manager, lib: true do expect(FileUtils).to have_received(:rm).with(files[2]) expect(FileUtils).to have_received(:rm).with(files[3]) expect(FileUtils).to have_received(:rm).with(files[4]) + expect(FileUtils).to have_received(:rm).with(files[5]) end it 'sets the correct removed count' do - expect(progress).to have_received(:puts).with('done. (3 removed)') + expect(progress).to have_received(:puts).with('done. (4 removed)') end it 'prints the error from file that could not be removed' do @@ -157,7 +158,7 @@ describe Backup::Manager, lib: true do before do allow(Dir).to receive(:glob).and_return( [ - '1451606400_2016_01_01_gitlab_backup.tar', + '1451606400_2016_01_01_1.2.3_gitlab_backup.tar', '1451520000_2015_12_31_gitlab_backup.tar' ] ) @@ -194,21 +195,21 @@ describe Backup::Manager, lib: true do before do allow(Dir).to receive(:glob).and_return( [ - '1451606400_2016_01_01_gitlab_backup.tar' + '1451606400_2016_01_01_1.2.3_gitlab_backup.tar' ] ) allow(File).to receive(:exist?).and_return(true) allow(Kernel).to receive(:system).and_return(true) allow(YAML).to receive(:load_file).and_return(gitlab_version: Gitlab::VERSION) - stub_env('BACKUP', '1451606400_2016_01_01') + stub_env('BACKUP', '1451606400_2016_01_01_1.2.3') end it 'unpacks the file' do subject.unpack expect(Kernel).to have_received(:system) - .with("tar", "-xf", "1451606400_2016_01_01_gitlab_backup.tar") + .with("tar", "-xf", "1451606400_2016_01_01_1.2.3_gitlab_backup.tar") expect(progress).to have_received(:puts).with(a_string_matching('done')) end end -- cgit v1.2.1 From 681f3296448c12a3dc53392647b794b51f1ec817 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Tue, 23 May 2017 11:35:54 -0500 Subject: Port EE changes --- .../recent_searches_dropdown_content_spec.js | 4 ++++ .../filtered_search/dropdown_user_spec.js | 2 +- .../filtered_search/dropdown_utils_spec.js | 21 +++++++++++++++------ .../filtered_search_manager_spec.js | 1 + .../filtered_search_tokenizer_spec.js | 22 ++++++++++++---------- 5 files changed, 33 insertions(+), 17 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js b/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js index d0f09a561d5..0ebb867b851 100644 --- a/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js +++ b/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js @@ -2,6 +2,8 @@ import Vue from 'vue'; import eventHub from '~/filtered_search/event_hub'; import RecentSearchesDropdownContent from '~/filtered_search/components/recent_searches_dropdown_content'; +require('~/filtered_search/filtered_search_token_keys'); + const createComponent = (propsData) => { const Component = Vue.extend(RecentSearchesDropdownContent); @@ -17,12 +19,14 @@ const trimMarkupWhitespace = text => text.replace(/(\n|\s)+/gm, ' ').trim(); describe('RecentSearchesDropdownContent', () => { const propsDataWithoutItems = { items: [], + allowedKeys: gl.FilteredSearchTokenKeys.getKeys(), }; const propsDataWithItems = { items: [ 'foo', 'author:@root label:~foo bar', ], + allowedKeys: gl.FilteredSearchTokenKeys.getKeys(), }; let vm; diff --git a/spec/javascripts/filtered_search/dropdown_user_spec.js b/spec/javascripts/filtered_search/dropdown_user_spec.js index 3f92fe4701e..95cee9a9b51 100644 --- a/spec/javascripts/filtered_search/dropdown_user_spec.js +++ b/spec/javascripts/filtered_search/dropdown_user_spec.js @@ -12,7 +12,7 @@ describe('Dropdown User', () => { spyOn(gl.DropdownUser.prototype, 'getProjectId').and.callFake(() => {}); spyOn(gl.DropdownUtils, 'getSearchInput').and.callFake(() => {}); - dropdownUser = new gl.DropdownUser(); + dropdownUser = new gl.DropdownUser(null, null, null, gl.FilteredSearchTokenKeys); }); it('should not return the double quote found in value', () => { diff --git a/spec/javascripts/filtered_search/dropdown_utils_spec.js b/spec/javascripts/filtered_search/dropdown_utils_spec.js index c820c955172..ea3c6010577 100644 --- a/spec/javascripts/filtered_search/dropdown_utils_spec.js +++ b/spec/javascripts/filtered_search/dropdown_utils_spec.js @@ -122,6 +122,7 @@ describe('Dropdown Utils', () => { describe('filterHint', () => { let input; + let allowedKeys; beforeEach(() => { setFixtures(` @@ -133,30 +134,38 @@ describe('Dropdown Utils', () => { `); input = document.getElementById('test'); + allowedKeys = gl.FilteredSearchTokenKeys.getKeys(); }); + function config() { + return { + input, + allowedKeys, + }; + } + it('should filter', () => { input.value = 'l'; - let updatedItem = gl.DropdownUtils.filterHint(input, { + let updatedItem = gl.DropdownUtils.filterHint(config(), { hint: 'label', }); expect(updatedItem.droplab_hidden).toBe(false); input.value = 'o'; - updatedItem = gl.DropdownUtils.filterHint(input, { + updatedItem = gl.DropdownUtils.filterHint(config(), { hint: 'label', }); expect(updatedItem.droplab_hidden).toBe(true); }); it('should return droplab_hidden false when item has no hint', () => { - const updatedItem = gl.DropdownUtils.filterHint(input, {}, ''); + const updatedItem = gl.DropdownUtils.filterHint(config(), {}, ''); expect(updatedItem.droplab_hidden).toBe(false); }); it('should allow multiple if item.type is array', () => { input.value = 'label:~first la'; - const updatedItem = gl.DropdownUtils.filterHint(input, { + const updatedItem = gl.DropdownUtils.filterHint(config(), { hint: 'label', type: 'array', }); @@ -165,12 +174,12 @@ describe('Dropdown Utils', () => { it('should prevent multiple if item.type is not array', () => { input.value = 'milestone:~first mile'; - let updatedItem = gl.DropdownUtils.filterHint(input, { + let updatedItem = gl.DropdownUtils.filterHint(config(), { hint: 'milestone', }); expect(updatedItem.droplab_hidden).toBe(true); - updatedItem = gl.DropdownUtils.filterHint(input, { + updatedItem = gl.DropdownUtils.filterHint(config(), { hint: 'milestone', type: 'string', }); diff --git a/spec/javascripts/filtered_search/filtered_search_manager_spec.js b/spec/javascripts/filtered_search/filtered_search_manager_spec.js index 063d547d00c..158a19a3864 100644 --- a/spec/javascripts/filtered_search/filtered_search_manager_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_manager_spec.js @@ -81,6 +81,7 @@ describe('Filtered Search Manager', () => { expect(RecentSearchesService.isAvailable).toHaveBeenCalled(); expect(recentSearchesStoreSrc.default).toHaveBeenCalledWith({ isLocalStorageAvailable, + allowedKeys: gl.FilteredSearchTokenKeys.getKeys(), }); }); diff --git a/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js b/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js index 3e2e577f115..616c3d080f6 100644 --- a/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js @@ -3,9 +3,11 @@ require('~/filtered_search/filtered_search_token_keys'); require('~/filtered_search/filtered_search_tokenizer'); describe('Filtered Search Tokenizer', () => { + const allowedKeys = gl.FilteredSearchTokenKeys.getKeys(); + describe('processTokens', () => { it('returns for input containing only search value', () => { - const results = gl.FilteredSearchTokenizer.processTokens('searchTerm'); + const results = gl.FilteredSearchTokenizer.processTokens('searchTerm', allowedKeys); expect(results.searchToken).toBe('searchTerm'); expect(results.tokens.length).toBe(0); expect(results.lastToken).toBe(results.searchToken); @@ -13,7 +15,7 @@ describe('Filtered Search Tokenizer', () => { it('returns for input containing only tokens', () => { const results = gl.FilteredSearchTokenizer - .processTokens('author:@root label:~"Very Important" milestone:%v1.0 assignee:none'); + .processTokens('author:@root label:~"Very Important" milestone:%v1.0 assignee:none', allowedKeys); expect(results.searchToken).toBe(''); expect(results.tokens.length).toBe(4); expect(results.tokens[3]).toBe(results.lastToken); @@ -37,7 +39,7 @@ describe('Filtered Search Tokenizer', () => { it('returns for input starting with search value and ending with tokens', () => { const results = gl.FilteredSearchTokenizer - .processTokens('searchTerm anotherSearchTerm milestone:none'); + .processTokens('searchTerm anotherSearchTerm milestone:none', allowedKeys); expect(results.searchToken).toBe('searchTerm anotherSearchTerm'); expect(results.tokens.length).toBe(1); expect(results.tokens[0]).toBe(results.lastToken); @@ -48,7 +50,7 @@ describe('Filtered Search Tokenizer', () => { it('returns for input starting with tokens and ending with search value', () => { const results = gl.FilteredSearchTokenizer - .processTokens('assignee:@user searchTerm'); + .processTokens('assignee:@user searchTerm', allowedKeys); expect(results.searchToken).toBe('searchTerm'); expect(results.tokens.length).toBe(1); @@ -60,7 +62,7 @@ describe('Filtered Search Tokenizer', () => { it('returns for input containing search value wrapped between tokens', () => { const results = gl.FilteredSearchTokenizer - .processTokens('author:@root label:~"Won\'t fix" searchTerm anotherSearchTerm milestone:none'); + .processTokens('author:@root label:~"Won\'t fix" searchTerm anotherSearchTerm milestone:none', allowedKeys); expect(results.searchToken).toBe('searchTerm anotherSearchTerm'); expect(results.tokens.length).toBe(3); @@ -81,7 +83,7 @@ describe('Filtered Search Tokenizer', () => { it('returns for input containing search value in between tokens', () => { const results = gl.FilteredSearchTokenizer - .processTokens('author:@root searchTerm assignee:none anotherSearchTerm label:~Doing'); + .processTokens('author:@root searchTerm assignee:none anotherSearchTerm label:~Doing', allowedKeys); expect(results.searchToken).toBe('searchTerm anotherSearchTerm'); expect(results.tokens.length).toBe(3); expect(results.tokens[2]).toBe(results.lastToken); @@ -100,14 +102,14 @@ describe('Filtered Search Tokenizer', () => { }); it('returns search value for invalid tokens', () => { - const results = gl.FilteredSearchTokenizer.processTokens('fake:token'); + const results = gl.FilteredSearchTokenizer.processTokens('fake:token', allowedKeys); expect(results.lastToken).toBe('fake:token'); expect(results.searchToken).toBe('fake:token'); expect(results.tokens.length).toEqual(0); }); it('returns search value and token for mix of valid and invalid tokens', () => { - const results = gl.FilteredSearchTokenizer.processTokens('label:real fake:token'); + const results = gl.FilteredSearchTokenizer.processTokens('label:real fake:token', allowedKeys); expect(results.tokens.length).toEqual(1); expect(results.tokens[0].key).toBe('label'); expect(results.tokens[0].value).toBe('real'); @@ -117,13 +119,13 @@ describe('Filtered Search Tokenizer', () => { }); it('returns search value for invalid symbols', () => { - const results = gl.FilteredSearchTokenizer.processTokens('std::includes'); + const results = gl.FilteredSearchTokenizer.processTokens('std::includes', allowedKeys); expect(results.lastToken).toBe('std::includes'); expect(results.searchToken).toBe('std::includes'); }); it('removes duplicated values', () => { - const results = gl.FilteredSearchTokenizer.processTokens('label:~foo label:~foo'); + const results = gl.FilteredSearchTokenizer.processTokens('label:~foo label:~foo', allowedKeys); expect(results.tokens.length).toBe(1); expect(results.tokens[0].key).toBe('label'); expect(results.tokens[0].value).toBe('foo'); -- cgit v1.2.1 From b3b30c947e4eda1f163436709aad35529284e82d Mon Sep 17 00:00:00 2001 From: Bryce Johnson Date: Tue, 23 May 2017 14:32:21 -0400 Subject: Test for next_run_at in the view. --- spec/features/projects/pipeline_schedules_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index 1211b17b3d8..a521222fc9c 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -5,7 +5,7 @@ feature 'Pipeline Schedules', :feature do include WaitForAjax let!(:project) { create(:project) } - let!(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project) } + let!(:pipeline_schedule) { create(:ci_pipeline_schedule, :nightly, project: project ) } let!(:pipeline) { create(:ci_pipeline, pipeline_schedule: pipeline_schedule) } let(:scope) { nil } let!(:user) { create(:user) } @@ -32,6 +32,7 @@ feature 'Pipeline Schedules', :feature do it 'displays the required information description' do page.within('.pipeline-schedule-table-row') do expect(page).to have_content('pipeline schedule') + expect(page).to have_content(pipeline_schedule.real_next_run.strftime('%b %d, %Y')) expect(page).to have_link('master') expect(page).to have_link("##{pipeline.id}") end -- cgit v1.2.1 From 850b99830ef34c3dad83cf08f2390dd67567b945 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 23 May 2017 14:56:05 -0500 Subject: Add spec --- spec/features/copy_as_gfm_spec.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'spec') diff --git a/spec/features/copy_as_gfm_spec.rb b/spec/features/copy_as_gfm_spec.rb index b6c51569bdc..3ed7d5710ab 100644 --- a/spec/features/copy_as_gfm_spec.rb +++ b/spec/features/copy_as_gfm_spec.rb @@ -65,6 +65,19 @@ describe 'Copy as GFM', feature: true, js: true do GFM ) + aggregate_failures('an accidentally selected empty element') do + gfm = '# Heading1' + + html = <<-HTML.strip_heredoc +

    Heading1

    + +

    + HTML + + output_gfm = html_to_gfm(html) + expect(output_gfm.strip).to eq(gfm.strip) + end + verify( 'InlineDiffFilter', -- cgit v1.2.1 From 6127192783171f6fc2b64c674dd21d0544b62707 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 23 May 2017 15:32:04 -0500 Subject: Add spec --- spec/javascripts/copy_as_gfm_spec.js | 49 ++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 spec/javascripts/copy_as_gfm_spec.js (limited to 'spec') diff --git a/spec/javascripts/copy_as_gfm_spec.js b/spec/javascripts/copy_as_gfm_spec.js new file mode 100644 index 00000000000..1a850bb56ab --- /dev/null +++ b/spec/javascripts/copy_as_gfm_spec.js @@ -0,0 +1,49 @@ +require('~/copy_as_gfm'); + +(() => { + describe('gl.CopyAsGFM', () => { + describe('gl.CopyAsGFM.pasteGFM', () => { + function callPasteGFM() { + const e = { + originalEvent: { + clipboardData: { + getData(mimeType) { + // When GFM code is copied, we put the regular plain text + // on the clipboard as `text/plain`, and the GFM as `text/x-gfm`. + // This emulates the behavior of `getData` with that data. + if (mimeType === 'text/plain') { + return 'code'; + } + if (mimeType === 'text/x-gfm') { + return '`code`'; + } + return null; + }, + }, + }, + preventDefault() {}, + }; + + window.gl.CopyAsGFM.pasteGFM(e); + } + + it('wraps pasted code when not already in code tags', () => { + spyOn(window.gl.utils, 'insertText').and.callFake((el, textFunc) => { + const insertedText = textFunc('This is code: ', ''); + expect(insertedText).toEqual('`code`'); + }); + + callPasteGFM(); + }); + + it('does not wrap pasted code when already in code tags', () => { + spyOn(window.gl.utils, 'insertText').and.callFake((el, textFunc) => { + const insertedText = textFunc('This is code: `', '`'); + expect(insertedText).toEqual('code'); + }); + + callPasteGFM(); + }); + }); + }); +})(); -- cgit v1.2.1 From 468f91686c065fe99b1eb744bb4d4645181341c8 Mon Sep 17 00:00:00 2001 From: Fatih Acet Date: Wed, 24 May 2017 00:01:06 +0300 Subject: MRWidget: Change order of if blocks to determine widget state properly. --- spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js b/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js index 9a331d99865..179e42a7cc4 100644 --- a/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js +++ b/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js @@ -25,6 +25,12 @@ describe('getStateKey', () => { context.canBeMerged = true; expect(bound()).toEqual('readyToMerge'); + context.canMerge = false; + expect(bound()).toEqual('notAllowedToMerge'); + + context.mergeWhenPipelineSucceeds = true; + expect(bound()).toEqual('mergeWhenPipelineSucceeds'); + context.hasSHAChanged = true; expect(bound()).toEqual('shaMismatch'); @@ -38,12 +44,6 @@ describe('getStateKey', () => { context.isPipelineFailed = true; expect(bound()).toEqual('pipelineFailed'); - context.canMerge = false; - expect(bound()).toEqual('notAllowedToMerge'); - - context.mergeWhenPipelineSucceeds = true; - expect(bound()).toEqual('mergeWhenPipelineSucceeds'); - data.work_in_progress = true; expect(bound()).toEqual('workInProgress'); -- cgit v1.2.1 From ab91f76e8b275d0fc1d78b38b95d4b2cd8e73bdb Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 21 May 2017 15:38:33 -0500 Subject: Add system note with link to diff comparison when MR discussion becomes outdated --- spec/features/merge_requests/versions_spec.rb | 2 + spec/lib/gitlab/diff/position_tracer_spec.rb | 315 +++++++++++++++------ spec/models/diff_discussion_spec.rb | 7 +- spec/models/merge_request_spec.rb | 36 ++- .../notes/diff_position_update_service_spec.rb | 20 +- spec/services/system_note_service_spec.rb | 31 ++ 6 files changed, 318 insertions(+), 93 deletions(-) (limited to 'spec') diff --git a/spec/features/merge_requests/versions_spec.rb b/spec/features/merge_requests/versions_spec.rb index 2b5b803946c..764035e57f0 100644 --- a/spec/features/merge_requests/versions_spec.rb +++ b/spec/features/merge_requests/versions_spec.rb @@ -124,6 +124,8 @@ feature 'Merge Request versions', js: true, feature: true do diff_refs: merge_request_diff3.compare_with(merge_request_diff1.head_commit_sha).diff_refs ) outdated_diff_note = create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: position) + outdated_diff_note.position = outdated_diff_note.original_position + outdated_diff_note.save! visit current_url wait_for_ajax diff --git a/spec/lib/gitlab/diff/position_tracer_spec.rb b/spec/lib/gitlab/diff/position_tracer_spec.rb index 4d202a76e1b..93d30b90937 100644 --- a/spec/lib/gitlab/diff/position_tracer_spec.rb +++ b/spec/lib/gitlab/diff/position_tracer_spec.rb @@ -61,9 +61,10 @@ describe Gitlab::Diff::PositionTracer, lib: true do let(:old_diff_refs) { raise NotImplementedError } let(:new_diff_refs) { raise NotImplementedError } + let(:change_diff_refs) { raise NotImplementedError } let(:old_position) { raise NotImplementedError } - let(:position_tracer) { described_class.new(repository: project.repository, old_diff_refs: old_diff_refs, new_diff_refs: new_diff_refs) } + let(:position_tracer) { described_class.new(project: project, old_diff_refs: old_diff_refs, new_diff_refs: new_diff_refs) } subject { position_tracer.trace(old_position) } def diff_refs(base_commit, head_commit) @@ -77,16 +78,40 @@ describe Gitlab::Diff::PositionTracer, lib: true do Gitlab::Diff::Position.new(attrs) end - def expect_new_position(attrs, new_position = subject) - if attrs.nil? - expect(new_position).to be_nil - else - expect(new_position).not_to be_nil + def expect_new_position(attrs, result = subject) + aggregate_failures("expect new position #{attrs.inspect}") do + if attrs.nil? + expect(result[:outdated]).to be_truthy + else + expect(result[:outdated]).to be_falsey - expect(new_position.diff_refs).to eq(new_diff_refs) + new_position = result[:position] + expect(new_position).not_to be_nil - attrs.each do |attr, value| - expect(new_position.send(attr)).to eq(value) + expect(new_position.diff_refs).to eq(new_diff_refs) + + attrs.each do |attr, value| + expect(new_position.send(attr)).to eq(value) + end + end + end + end + + def expect_change_position(attrs, result = subject) + aggregate_failures("expect change position #{attrs.inspect}") do + expect(result[:outdated]).to be_truthy + + change_position = result[:position] + if attrs.nil? || attrs.empty? + expect(change_position).to be_nil + else + expect(change_position).not_to be_nil + + expect(change_position.diff_refs).to eq(change_diff_refs) + + attrs.each do |attr, value| + expect(change_position.send(attr)).to eq(value) + end end end end @@ -395,6 +420,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do context "when that line was changed between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, create_file_commit) } let(:new_diff_refs) { diff_refs(initial_commit, update_line_commit) } + let(:change_diff_refs) { diff_refs(create_file_commit, update_line_commit) } let(:old_position) { position(new_path: file_name, new_line: 2) } # old diff: @@ -407,14 +433,20 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 2 + BB # 3 + C - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 2, + new_line: nil + ) end end context "when that line was deleted between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, update_line_commit) } let(:new_diff_refs) { diff_refs(initial_commit, delete_line_commit) } + let(:change_diff_refs) { diff_refs(update_line_commit, delete_line_commit) } let(:old_position) { position(new_path: file_name, new_line: 3) } # old diff: @@ -426,8 +458,13 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 1 + A # 2 + BB - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 3, + new_line: nil + ) end end end @@ -512,6 +549,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do context "when that line was changed between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, create_file_commit) } let(:new_diff_refs) { diff_refs(create_file_commit, update_line_commit) } + let(:change_diff_refs) { diff_refs(create_file_commit, update_line_commit) } let(:old_position) { position(new_path: file_name, new_line: 2) } # old diff: @@ -525,14 +563,20 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 2 + BB # 3 3 C - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 2, + new_line: nil + ) end end context "when that line was deleted between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, move_line_commit) } let(:new_diff_refs) { diff_refs(move_line_commit, delete_line_commit) } + let(:change_diff_refs) { diff_refs(move_line_commit, delete_line_commit) } let(:old_position) { position(new_path: file_name, new_line: 3) } # old diff: @@ -545,8 +589,13 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 2 2 A # 3 - C - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 3, + new_line: nil + ) end end end @@ -558,6 +607,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do context "when the file's content was unchanged between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, delete_line_commit) } let(:new_diff_refs) { diff_refs(delete_line_commit, rename_file_commit) } + let(:change_diff_refs) { diff_refs(initial_commit, delete_line_commit) } let(:old_position) { position(new_path: file_name, new_line: 2) } # old diff: @@ -569,8 +619,13 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 1 1 BB # 2 2 A - it "returns nil since the line doesn't exist in the new diffs anymore" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: nil, + new_line: 2 + ) end end @@ -628,6 +683,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do context "when that line was changed between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, delete_line_commit) } let(:new_diff_refs) { diff_refs(delete_line_commit, update_line_again_commit) } + let(:change_diff_refs) { diff_refs(delete_line_commit, update_line_again_commit) } let(:old_position) { position(new_path: file_name, new_line: 2) } # old diff: @@ -640,28 +696,13 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 2 - A # 2 + AA - it "returns nil" do - expect(subject).to be_nil - end - end - - context "when that line was deleted between the old and the new diff" do - let(:old_diff_refs) { diff_refs(initial_commit, delete_line_commit) } - let(:new_diff_refs) { diff_refs(delete_line_commit, delete_line_again_commit) } - let(:old_position) { position(new_path: file_name, new_line: 1) } - - # old diff: - # 1 + BB - # 2 + A - # - # new diff: - # file_name -> new_file_name - # 1 - BB - # 2 - A - # 1 + AA - - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: new_file_name, + old_line: 2, + new_line: nil + ) end end end @@ -673,6 +714,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do context "when the file's content was unchanged between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, delete_line_commit) } let(:new_diff_refs) { diff_refs(delete_line_commit, delete_file_commit) } + let(:change_diff_refs) { diff_refs(delete_line_commit, delete_file_commit) } let(:old_position) { position(new_path: file_name, new_line: 2) } # old diff: @@ -683,8 +725,13 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 1 - BB # 2 - A - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 2, + new_line: nil + ) end end @@ -692,6 +739,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do context "when that line was unchanged between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, move_line_commit) } let(:new_diff_refs) { diff_refs(delete_line_commit, delete_file_commit) } + let(:change_diff_refs) { diff_refs(move_line_commit, delete_file_commit) } let(:old_position) { position(new_path: file_name, new_line: 2) } # old diff: @@ -703,14 +751,20 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 1 - BB # 2 - A - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 2, + new_line: nil + ) end end context "when that line was moved between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, update_line_commit) } let(:new_diff_refs) { diff_refs(move_line_commit, delete_file_commit) } + let(:change_diff_refs) { diff_refs(update_line_commit, delete_file_commit) } let(:old_position) { position(new_path: file_name, new_line: 2) } # old diff: @@ -723,14 +777,20 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 2 - A # 3 - C - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 2, + new_line: nil + ) end end context "when that line was changed between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, create_file_commit) } let(:new_diff_refs) { diff_refs(update_line_commit, delete_file_commit) } + let(:change_diff_refs) { diff_refs(create_file_commit, delete_file_commit) } let(:old_position) { position(new_path: file_name, new_line: 2) } # old diff: @@ -743,14 +803,20 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 2 - BB # 3 - C - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 2, + new_line: nil + ) end end context "when that line was deleted between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, move_line_commit) } let(:new_diff_refs) { diff_refs(delete_line_commit, delete_file_commit) } + let(:change_diff_refs) { diff_refs(move_line_commit, delete_file_commit) } let(:old_position) { position(new_path: file_name, new_line: 3) } # old diff: @@ -762,8 +828,13 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 1 - BB # 2 - A - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 3, + new_line: nil + ) end end end @@ -775,6 +846,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do context "when the file's content was unchanged between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, create_file_commit) } let(:new_diff_refs) { diff_refs(create_file_commit, create_second_file_commit) } + let(:change_diff_refs) { diff_refs(initial_commit, create_file_commit) } let(:old_position) { position(new_path: file_name, new_line: 2) } # old diff: @@ -787,8 +859,13 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 2 2 B # 3 3 C - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: nil, + new_line: 2 + ) end end @@ -796,6 +873,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do context "when that line was unchanged between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, create_file_commit) } let(:new_diff_refs) { diff_refs(update_line_commit, update_second_file_line_commit) } + let(:change_diff_refs) { diff_refs(initial_commit, update_line_commit) } let(:old_position) { position(new_path: file_name, new_line: 1) } # old diff: @@ -808,14 +886,20 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 2 2 BB # 3 3 C - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: nil, + new_line: 1 + ) end end context "when that line was moved between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, update_line_commit) } let(:new_diff_refs) { diff_refs(move_line_commit, move_second_file_line_commit) } + let(:change_diff_refs) { diff_refs(initial_commit, move_line_commit) } let(:old_position) { position(new_path: file_name, new_line: 2) } # old diff: @@ -828,14 +912,20 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 2 2 A # 3 3 C - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: nil, + new_line: 1 + ) end end context "when that line was changed between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, create_file_commit) } let(:new_diff_refs) { diff_refs(update_line_commit, update_second_file_line_commit) } + let(:change_diff_refs) { diff_refs(create_file_commit, update_second_file_line_commit) } let(:old_position) { position(new_path: file_name, new_line: 2) } # old diff: @@ -848,14 +938,20 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 2 2 BB # 3 3 C - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 2, + new_line: nil + ) end end context "when that line was deleted between the old and the new diff" do let(:old_diff_refs) { diff_refs(initial_commit, move_line_commit) } let(:new_diff_refs) { diff_refs(delete_line_commit, delete_second_file_line_commit) } + let(:change_diff_refs) { diff_refs(move_line_commit, delete_second_file_line_commit) } let(:old_position) { position(new_path: file_name, new_line: 3) } # old diff: @@ -867,8 +963,13 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 1 1 BB # 2 2 A - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 3, + new_line: nil + ) end end end @@ -957,6 +1058,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do context "when that line was changed or deleted between the old and the new diff" do let(:old_diff_refs) { diff_refs(create_file_commit, move_line_commit) } let(:new_diff_refs) { diff_refs(initial_commit, create_file_commit) } + let(:change_diff_refs) { diff_refs(move_line_commit, create_file_commit) } let(:old_position) { position(old_path: file_name, new_path: file_name, new_line: 1) } # old diff: @@ -970,8 +1072,13 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 2 + B # 3 + C - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 1, + new_line: nil + ) end end end @@ -980,6 +1087,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do context "when the position pointed at a deleted line in the old diff" do let(:old_diff_refs) { diff_refs(create_file_commit, update_line_commit) } let(:new_diff_refs) { diff_refs(initial_commit, update_line_commit) } + let(:change_diff_refs) { diff_refs(create_file_commit, initial_commit) } let(:old_position) { position(old_path: file_name, new_path: file_name, old_line: 2) } # old diff: @@ -993,8 +1101,13 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 2 + BB # 3 + C - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 2, + new_line: nil + ) end end @@ -1076,6 +1189,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do context "when that line was changed or deleted between the old and the new diff" do let(:old_diff_refs) { diff_refs(create_file_commit, move_line_commit) } let(:new_diff_refs) { diff_refs(initial_commit, delete_line_commit) } + let(:change_diff_refs) { diff_refs(move_line_commit, delete_line_commit) } let(:old_position) { position(old_path: file_name, new_path: file_name, old_line: 3, new_line: 3) } # old diff: @@ -1088,8 +1202,13 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 1 + A # 2 + B - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 3, + new_line: nil + ) end end end @@ -1182,6 +1301,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do context "when that line was changed or deleted between the old and the new diff" do let(:old_diff_refs) { diff_refs(create_file_commit, move_line_commit) } let(:new_diff_refs) { diff_refs(create_file_commit, update_line_commit) } + let(:change_diff_refs) { diff_refs(move_line_commit, update_line_commit) } let(:old_position) { position(old_path: file_name, new_path: file_name, new_line: 1) } # old diff: @@ -1196,8 +1316,13 @@ describe Gitlab::Diff::PositionTracer, lib: true do # 2 + BB # 3 3 C - it "returns nil" do - expect(subject).to be_nil + it "returns the position of the change" do + expect_change_position( + old_path: file_name, + new_path: file_name, + old_line: 1, + new_line: nil + ) end end end @@ -1239,7 +1364,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do describe "typical use scenarios" do let(:second_branch_name) { "#{branch_name}-2" } - def expect_positions(old_attrs, new_attrs) + def expect_new_positions(old_attrs, new_attrs) old_positions = old_attrs.map do |old_attrs| position(old_attrs) end @@ -1248,8 +1373,14 @@ describe Gitlab::Diff::PositionTracer, lib: true do position_tracer.trace(old_position) end - new_positions.zip(new_attrs).each do |new_position, new_attrs| - expect_new_position(new_attrs, new_position) + aggregate_failures do + new_positions.zip(new_attrs).each do |new_position, new_attrs| + if new_attrs&.delete(:change) + expect_change_position(new_attrs, new_position) + else + expect_new_position(new_attrs, new_position) + end + end end end @@ -1330,6 +1461,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do describe "simple push of new commit" do let(:old_diff_refs) { diff_refs(create_file_commit, update_file_commit) } let(:new_diff_refs) { diff_refs(create_file_commit, update_file_again_commit) } + let(:change_diff_refs) { diff_refs(update_file_commit, update_file_again_commit) } # old diff: # 1 1 A @@ -1368,14 +1500,14 @@ describe Gitlab::Diff::PositionTracer, lib: true do { old_path: file_name, new_path: file_name, old_line: 1, new_line: 1 }, { old_path: file_name, old_line: 2 }, { old_path: file_name, new_path: file_name, old_line: 3, new_line: 3 }, - { old_path: file_name, old_line: 4, new_line: 4 }, - nil, + { new_path: file_name, new_line: 4, change: true }, + { new_path: file_name, old_line: 3, change: true }, { old_path: file_name, new_path: file_name, old_line: 5, new_line: 5 }, - { old_path: file_name, old_line: 6 }, + { new_path: file_name, old_line: 5, change: true }, { new_path: file_name, new_line: 7 } ] - expect_positions(old_position_attrs, new_position_attrs) + expect_new_positions(old_position_attrs, new_position_attrs) end end @@ -1402,6 +1534,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do let(:old_diff_refs) { diff_refs(create_file_commit, update_file_commit) } let(:new_diff_refs) { diff_refs(create_file_commit, second_create_file_commit) } + let(:change_diff_refs) { diff_refs(update_file_commit, second_create_file_commit) } # old diff: # 1 1 A @@ -1440,20 +1573,21 @@ describe Gitlab::Diff::PositionTracer, lib: true do { old_path: file_name, new_path: file_name, old_line: 1, new_line: 1 }, { old_path: file_name, old_line: 2 }, { old_path: file_name, new_path: file_name, old_line: 3, new_line: 3 }, - { old_path: file_name, old_line: 4, new_line: 4 }, - nil, + { new_path: file_name, new_line: 4, change: true }, + { old_path: file_name, old_line: 3, change: true }, { old_path: file_name, new_path: file_name, old_line: 5, new_line: 5 }, - { old_path: file_name, old_line: 6 }, + { old_path: file_name, old_line: 5, change: true }, { new_path: file_name, new_line: 7 } ] - expect_positions(old_position_attrs, new_position_attrs) + expect_new_positions(old_position_attrs, new_position_attrs) end end describe "force push to delete last commit" do let(:old_diff_refs) { diff_refs(create_file_commit, update_file_again_commit) } let(:new_diff_refs) { diff_refs(create_file_commit, update_file_commit) } + let(:change_diff_refs) { diff_refs(update_file_again_commit, update_file_commit) } # old diff: # 1 1 A @@ -1492,16 +1626,16 @@ describe Gitlab::Diff::PositionTracer, lib: true do new_position_attrs = [ { old_path: file_name, new_path: file_name, old_line: 1, new_line: 1 }, { old_path: file_name, old_line: 2 }, - nil, + { old_path: file_name, old_line: 2, change: true }, { old_path: file_name, new_path: file_name, old_line: 3, new_line: 2 }, - { old_path: file_name, old_line: 4 }, + { old_path: file_name, old_line: 4, change: true }, { old_path: file_name, new_path: file_name, old_line: 5, new_line: 4 }, - { old_path: file_name, new_path: file_name, old_line: 6, new_line: 5 }, - nil, + { new_path: file_name, new_line: 5, change: true }, + { old_path: file_name, old_line: 6, change: true }, { new_path: file_name, new_line: 6 } ] - expect_positions(old_position_attrs, new_position_attrs) + expect_new_positions(old_position_attrs, new_position_attrs) end end @@ -1567,6 +1701,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do let(:old_diff_refs) { diff_refs(create_file_commit, update_file_again_commit) } let(:new_diff_refs) { diff_refs(create_file_commit, overwrite_update_file_again_commit) } + let(:change_diff_refs) { diff_refs(update_file_again_commit, overwrite_update_file_again_commit) } # old diff: # 1 1 A @@ -1618,7 +1753,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do { new_path: file_name, new_line: 10 }, # + G ] - expect_positions(old_position_attrs, new_position_attrs) + expect_new_positions(old_position_attrs, new_position_attrs) end end @@ -1643,6 +1778,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do let(:old_diff_refs) { diff_refs(create_file_commit, update_file_again_commit) } let(:new_diff_refs) { diff_refs(create_file_commit, merge_commit) } + let(:change_diff_refs) { diff_refs(update_file_again_commit, merge_commit) } # old diff: # 1 1 A @@ -1694,13 +1830,14 @@ describe Gitlab::Diff::PositionTracer, lib: true do { new_path: file_name, new_line: 10 }, # + G ] - expect_positions(old_position_attrs, new_position_attrs) + expect_new_positions(old_position_attrs, new_position_attrs) end end describe "changing target branch" do let(:old_diff_refs) { diff_refs(create_file_commit, update_file_again_commit) } let(:new_diff_refs) { diff_refs(update_file_commit, update_file_again_commit) } + let(:change_diff_refs) { diff_refs(create_file_commit, update_file_commit) } # old diff: # 1 1 A @@ -1739,7 +1876,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do new_position_attrs = [ { old_path: file_name, new_path: file_name, old_line: 1, new_line: 1 }, - nil, + { old_path: file_name, old_line: 2, change: true }, { new_path: file_name, new_line: 2 }, { old_path: file_name, new_path: file_name, old_line: 2, new_line: 3 }, { new_path: file_name, new_line: 4 }, @@ -1749,7 +1886,7 @@ describe Gitlab::Diff::PositionTracer, lib: true do { new_path: file_name, new_line: 7 } ] - expect_positions(old_position_attrs, new_position_attrs) + expect_new_positions(old_position_attrs, new_position_attrs) end end end diff --git a/spec/models/diff_discussion_spec.rb b/spec/models/diff_discussion_spec.rb index 81f338745b1..45b2f6e4beb 100644 --- a/spec/models/diff_discussion_spec.rb +++ b/spec/models/diff_discussion_spec.rb @@ -48,7 +48,7 @@ describe DiffDiscussion, model: true do end it 'returns the diff ID for the version to show' do - expect(diff_id: merge_request_diff1.id) + expect(subject.merge_request_version_params).to eq(diff_id: merge_request_diff1.id) end end @@ -65,6 +65,11 @@ describe DiffDiscussion, model: true do let(:diff_note) { create(:diff_note_on_merge_request, noteable: merge_request, project: project, position: position) } + before do + diff_note.position = diff_note.original_position + diff_note.save! + end + it 'returns the diff ID and start sha of the versions to compare' do expect(subject.merge_request_version_params).to eq(diff_id: merge_request_diff3.id, start_sha: merge_request_diff1.head_commit_sha) end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 0e05f719499..da915c49d3c 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -1213,7 +1213,7 @@ describe MergeRequest, models: true do expect(Notes::DiffPositionUpdateService).to receive(:new).with( subject.project, - nil, + subject.author, old_diff_refs: old_diff_refs, new_diff_refs: commit.diff_refs, paths: note.position.paths @@ -1222,7 +1222,7 @@ describe MergeRequest, models: true do expect_any_instance_of(Notes::DiffPositionUpdateService).to receive(:execute).with(note) expect_any_instance_of(DiffNote).to receive(:save).once - subject.reload_diff + subject.reload_diff(subject.author) end end @@ -1534,4 +1534,36 @@ describe MergeRequest, models: true do end end end + + describe '#version_params_for' do + subject { create(:merge_request, importing: true) } + let(:project) { subject.project } + let!(:merge_request_diff1) { subject.merge_request_diffs.create(head_commit_sha: '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9') } + let!(:merge_request_diff2) { subject.merge_request_diffs.create(head_commit_sha: nil) } + let!(:merge_request_diff3) { subject.merge_request_diffs.create(head_commit_sha: '5937ac0a7beb003549fc5fd26fc247adbce4a52e') } + + context 'when the diff refs are for an older merge request version' do + let(:diff_refs) { merge_request_diff1.diff_refs } + + it 'returns the diff ID for the version to show' do + expect(subject.version_params_for(diff_refs)).to eq(diff_id: merge_request_diff1.id) + end + end + + context 'when the diff refs are for a comparison between merge request versions' do + let(:diff_refs) { merge_request_diff3.compare_with(merge_request_diff1.head_commit_sha).diff_refs } + + it 'returns the diff ID and start sha of the versions to compare' do + expect(subject.version_params_for(diff_refs)).to eq(diff_id: merge_request_diff3.id, start_sha: merge_request_diff1.head_commit_sha) + end + end + + context 'when the diff refs are not for a merge request version' do + let(:diff_refs) { project.commit(sample_commit.id).diff_refs } + + it 'returns nil' do + expect(subject.version_params_for(diff_refs)).to be_nil + end + end + end end diff --git a/spec/services/notes/diff_position_update_service_spec.rb b/spec/services/notes/diff_position_update_service_spec.rb index d73ae51fbc3..380c296fd3a 100644 --- a/spec/services/notes/diff_position_update_service_spec.rb +++ b/spec/services/notes/diff_position_update_service_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' describe Notes::DiffPositionUpdateService, services: true do let(:project) { create(:project, :repository) } + let(:current_user) { project.owner } let(:create_commit) { project.commit("913c66a37b4a45b9769037c55c2d238bd0942d2e") } let(:modify_commit) { project.commit("874797c3a73b60d2187ed6e2fcabd289ff75171e") } let(:edit_commit) { project.commit("570e7b2abdd848b95f2f578043fc23bd6f6fd24d") } @@ -25,7 +26,7 @@ describe Notes::DiffPositionUpdateService, services: true do subject do described_class.new( project, - nil, + current_user, old_diff_refs: old_diff_refs, new_diff_refs: new_diff_refs, paths: [path] @@ -170,6 +171,23 @@ describe Notes::DiffPositionUpdateService, services: true do expect(note.original_position).to eq(old_position) expect(note.position).to eq(old_position) end + + it 'sets the change position' do + subject.execute(note) + + change_position = note.change_position + expect(change_position.start_sha).to eq(old_diff_refs.head_sha) + expect(change_position.head_sha).to eq(new_diff_refs.head_sha) + expect(change_position.old_line).to eq(9) + expect(change_position.new_line).to be_nil + end + + it 'creates a system note' do + expect(SystemNoteService).to receive(:diff_discussion_outdated).with( + note.to_discussion, project, current_user, instance_of(Gitlab::Diff::Position)) + + subject.execute(note) + end end end end diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index 7a9cd7553b1..c737a1f82a3 100644 --- a/spec/services/system_note_service_spec.rb +++ b/spec/services/system_note_service_spec.rb @@ -1034,4 +1034,35 @@ describe SystemNoteService, services: true do expect(subject.note).to eq 'resolved all discussions' end end + + describe '.diff_discussion_outdated' do + let(:discussion) { create(:diff_note_on_merge_request).to_discussion } + let(:merge_request) { discussion.noteable } + let(:project) { merge_request.source_project } + let(:change_position) { discussion.position } + + def reloaded_merge_request + MergeRequest.find(merge_request.id) + end + + subject { described_class.diff_discussion_outdated(discussion, project, author, change_position) } + + it_behaves_like 'a system note' do + let(:expected_noteable) { discussion.first_note.noteable } + let(:action) { 'outdated' } + end + + it 'creates a new note in the discussion' do + # we need to completely rebuild the merge request object, or the `@discussions` on the merge request are not reloaded. + expect { subject }.to change { reloaded_merge_request.discussions.first.notes.size }.by(1) + end + + it 'links to the diff in the system note' do + expect(subject.note).to include('version 1') + + diff_id = merge_request.merge_request_diff.id + line_code = change_position.line_code(project.repository) + expect(subject.note).to include(diffs_namespace_project_merge_request_url(project.namespace, project, merge_request, diff_id: diff_id, anchor: line_code)) + end + end end -- cgit v1.2.1 From 6e698b254ecddf23a866d9e98a885912102ccbce Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 22 May 2017 15:56:20 -0500 Subject: Fix specs --- spec/features/merge_requests/discussion_spec.rb | 2 +- spec/helpers/notes_helper_spec.rb | 8 +++++++- spec/lib/gitlab/import_export/safe_model_attributes.yml | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'spec') diff --git a/spec/features/merge_requests/discussion_spec.rb b/spec/features/merge_requests/discussion_spec.rb index f59d0faa274..1a09cc54c2e 100644 --- a/spec/features/merge_requests/discussion_spec.rb +++ b/spec/features/merge_requests/discussion_spec.rb @@ -43,7 +43,7 @@ feature 'Merge Request Discussions', feature: true do it 'shows a link to the outdated diff' do within(".discussion[data-discussion-id='#{outdated_discussion.id}']") do path = diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, diff_id: old_merge_request_diff.id, anchor: outdated_discussion.line_code) - expect(page).to have_link('an outdated diff', href: path) + expect(page).to have_link('an old version of the diff', href: path) end end end diff --git a/spec/helpers/notes_helper_spec.rb b/spec/helpers/notes_helper_spec.rb index 099146678ae..355a4845afb 100644 --- a/spec/helpers/notes_helper_spec.rb +++ b/spec/helpers/notes_helper_spec.rb @@ -92,7 +92,13 @@ describe NotesHelper do ) end - let(:discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project, position: position).to_discussion } + let(:diff_note) { create(:diff_note_on_merge_request, noteable: merge_request, project: project, position: position) } + let(:discussion) { diff_note.to_discussion } + + before do + diff_note.position = diff_note.original_position + diff_note.save! + end it 'returns the diff version comparison path with the line code' do expect(helper.discussion_path(discussion)).to eq(diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, diff_id: merge_request_diff3, start_sha: merge_request_diff1.head_commit_sha, anchor: discussion.line_code)) diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml index c22fba11225..96054c996fd 100644 --- a/spec/lib/gitlab/import_export/safe_model_attributes.yml +++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml @@ -54,6 +54,7 @@ Note: - type - position - original_position +- change_position - resolved_at - resolved_by_id - discussion_id -- cgit v1.2.1 From 4345bb8c507a11af694617187dea14284f48fb96 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 19 May 2017 19:46:40 -0500 Subject: Fix ambiguous routing issues by teaching router about reserved words --- spec/lib/gitlab/path_regex_spec.rb | 384 +++++++++++++++++++++ spec/lib/gitlab/regex_spec.rb | 24 -- spec/models/namespace_spec.rb | 6 +- .../project_services/kubernetes_service_spec.rb | 4 +- spec/requests/api/users_spec.rb | 4 +- spec/routing/project_routing_spec.rb | 4 + spec/validators/dynamic_path_validator_spec.rb | 250 ++------------ 7 files changed, 420 insertions(+), 256 deletions(-) create mode 100644 spec/lib/gitlab/path_regex_spec.rb (limited to 'spec') diff --git a/spec/lib/gitlab/path_regex_spec.rb b/spec/lib/gitlab/path_regex_spec.rb new file mode 100644 index 00000000000..1eea710c80b --- /dev/null +++ b/spec/lib/gitlab/path_regex_spec.rb @@ -0,0 +1,384 @@ +# coding: utf-8 +require 'spec_helper' + +describe Gitlab::PathRegex, lib: true do + # Pass in a full path to remove the format segment: + # `/ci/lint(.:format)` -> `/ci/lint` + def without_format(path) + path.split('(', 2)[0] + end + + # Pass in a full path and get the last segment before a wildcard + # That's not a parameter + # `/*namespace_id/:project_id/builds/artifacts/*ref_name_and_path` + # -> 'builds/artifacts' + def path_before_wildcard(path) + path = path.gsub(STARTING_WITH_NAMESPACE, "") + path_segments = path.split('/').reject(&:empty?) + wildcard_index = path_segments.index { |segment| parameter?(segment) } + + segments_before_wildcard = path_segments[0..wildcard_index - 1] + + segments_before_wildcard.join('/') + end + + def parameter?(segment) + segment =~ /[*:]/ + end + + # If the path is reserved. Then no conflicting paths can# be created for any + # route using this reserved word. + # + # Both `builds/artifacts` & `build` are covered by reserving the word + # `build` + def wildcards_include?(path) + described_class::PROJECT_WILDCARD_ROUTES.include?(path) || + described_class::PROJECT_WILDCARD_ROUTES.include?(path.split('/').first) + end + + def failure_message(missing_words, constant_name, migration_helper) + missing_words = Array(missing_words) + <<-MSG + Found new routes that could cause conflicts with existing namespaced routes + for groups or projects. + + Add <#{missing_words.join(', ')}> to `Gitlab::PathRegex::#{constant_name} + to make sure no projects or namespaces can be created with those paths. + + To rename any existing records with those paths you can use the + `Gitlab::Database::RenameReservedpathsMigration::.#{migration_helper}` + migration helper. + + Make sure to make a note of the renamed records in the release blog post. + + MSG + end + + let(:all_routes) do + route_set = Rails.application.routes + routes_collection = route_set.routes + routes_array = routes_collection.routes + routes_array.map { |route| route.path.spec.to_s } + end + + let(:routes_without_format) { all_routes.map { |path| without_format(path) } } + + # Routes not starting with `/:` or `/*` + # all routes not starting with a param + let(:routes_not_starting_in_wildcard) { routes_without_format.select { |p| p !~ %r{^/[:*]} } } + + let(:top_level_words) do + routes_not_starting_in_wildcard.map do |route| + route.split('/')[1] + end.compact.uniq + end + + # All routes that start with a namespaced path, that have 1 or more + # path-segments before having another wildcard parameter. + # - Starting with paths: + # - `/*namespace_id/:project_id/` + # - `/*namespace_id/:id/` + # - Followed by one or more path-parts not starting with `:` or `*` + # - Followed by a path-part that includes a wildcard parameter `*` + # At the time of writing these routes match: http://rubular.com/r/Rv2pDE5Dvw + STARTING_WITH_NAMESPACE = %r{^/\*namespace_id/:(project_)?id} + NON_PARAM_PARTS = %r{[^:*][a-z\-_/]*} + ANY_OTHER_PATH_PART = %r{[a-z\-_/:]*} + WILDCARD_SEGMENT = %r{\*} + let(:namespaced_wildcard_routes) do + routes_without_format.select do |p| + p =~ %r{#{STARTING_WITH_NAMESPACE}/#{NON_PARAM_PARTS}/#{ANY_OTHER_PATH_PART}#{WILDCARD_SEGMENT}} + end + end + + # This will return all paths that are used in a namespaced route + # before another wildcard path: + # + # /*namespace_id/:project_id/builds/artifacts/*ref_name_and_path + # /*namespace_id/:project_id/info/lfs/objects/*oid + # /*namespace_id/:project_id/commits/*id + # /*namespace_id/:project_id/builds/:build_id/artifacts/file/*path + # -> ['builds/artifacts', 'info/lfs/objects', 'commits', 'artifacts/file'] + let(:all_wildcard_paths) do + namespaced_wildcard_routes.map do |route| + path_before_wildcard(route) + end.uniq + end + + STARTING_WITH_GROUP = %r{^/groups/\*(group_)?id/} + let(:group_routes) do + routes_without_format.select do |path| + path =~ STARTING_WITH_GROUP + end + end + + let(:paths_after_group_id) do + group_routes.map do |route| + route.gsub(STARTING_WITH_GROUP, '').split('/').first + end.uniq + end + + describe 'TOP_LEVEL_ROUTES' do + it 'includes all the top level namespaces' do + failure_block = lambda do + missing_words = top_level_words - described_class::TOP_LEVEL_ROUTES + failure_message(missing_words, 'TOP_LEVEL_ROUTES', 'rename_root_paths') + end + + expect(described_class::TOP_LEVEL_ROUTES) + .to include(*top_level_words), failure_block + end + end + + describe 'GROUP_ROUTES' do + it "don't contain a second wildcard" do + failure_block = lambda do + missing_words = paths_after_group_id - described_class::GROUP_ROUTES + failure_message(missing_words, 'GROUP_ROUTES', 'rename_child_paths') + end + + expect(described_class::GROUP_ROUTES) + .to include(*paths_after_group_id), failure_block + end + end + + describe 'PROJECT_WILDCARD_ROUTES' do + it 'includes all paths that can be used after a namespace/project path' do + aggregate_failures do + all_wildcard_paths.each do |path| + expect(wildcards_include?(path)) + .to be(true), failure_message(path, 'PROJECT_WILDCARD_ROUTES', 'rename_wildcard_paths') + end + end + end + end + + describe '.root_namespace_path_regex' do + subject { described_class.root_namespace_path_regex } + + it 'rejects top level routes' do + expect(subject).not_to match('admin/') + expect(subject).not_to match('api/') + expect(subject).not_to match('.well-known/') + end + + it 'accepts project wildcard routes' do + expect(subject).to match('blob/') + expect(subject).to match('edit/') + expect(subject).to match('wikis/') + end + + it 'accepts group routes' do + expect(subject).to match('activity/') + expect(subject).to match('group_members/') + expect(subject).to match('subgroups/') + end + + it 'is not case sensitive' do + expect(subject).not_to match('Users/') + end + + it 'does not allow extra slashes' do + expect(subject).not_to match('/blob/') + expect(subject).not_to match('blob//') + end + end + + describe '.full_namespace_path_regex' do + subject { described_class.full_namespace_path_regex } + + context 'at the top level' do + context 'when the final level' do + it 'rejects top level routes' do + expect(subject).not_to match('admin/') + expect(subject).not_to match('api/') + expect(subject).not_to match('.well-known/') + end + + it 'accepts project wildcard routes' do + expect(subject).to match('blob/') + expect(subject).to match('edit/') + expect(subject).to match('wikis/') + end + + it 'accepts group routes' do + expect(subject).to match('activity/') + expect(subject).to match('group_members/') + expect(subject).to match('subgroups/') + end + end + + context 'when more levels follow' do + it 'rejects top level routes' do + expect(subject).not_to match('admin/more/') + expect(subject).not_to match('api/more/') + expect(subject).not_to match('.well-known/more/') + end + + it 'accepts project wildcard routes' do + expect(subject).to match('blob/more/') + expect(subject).to match('edit/more/') + expect(subject).to match('wikis/more/') + expect(subject).to match('environments/folders/') + expect(subject).to match('info/lfs/objects/') + end + + it 'accepts group routes' do + expect(subject).to match('activity/more/') + expect(subject).to match('group_members/more/') + expect(subject).to match('subgroups/more/') + end + end + end + + context 'at the second level' do + context 'when the final level' do + it 'accepts top level routes' do + expect(subject).to match('root/admin/') + expect(subject).to match('root/api/') + expect(subject).to match('root/.well-known/') + end + + it 'rejects project wildcard routes' do + expect(subject).not_to match('root/blob/') + expect(subject).not_to match('root/edit/') + expect(subject).not_to match('root/wikis/') + expect(subject).not_to match('root/environments/folders/') + expect(subject).not_to match('root/info/lfs/objects/') + end + + it 'rejects group routes' do + expect(subject).not_to match('root/activity/') + expect(subject).not_to match('root/group_members/') + expect(subject).not_to match('root/subgroups/') + end + end + + context 'when more levels follow' do + it 'accepts top level routes' do + expect(subject).to match('root/admin/more/') + expect(subject).to match('root/api/more/') + expect(subject).to match('root/.well-known/more/') + end + + it 'rejects project wildcard routes' do + expect(subject).not_to match('root/blob/more/') + expect(subject).not_to match('root/edit/more/') + expect(subject).not_to match('root/wikis/more/') + expect(subject).not_to match('root/environments/folders/more/') + expect(subject).not_to match('root/info/lfs/objects/more/') + end + + it 'rejects group routes' do + expect(subject).not_to match('root/activity/more/') + expect(subject).not_to match('root/group_members/more/') + expect(subject).not_to match('root/subgroups/more/') + end + end + end + + it 'is not case sensitive' do + expect(subject).not_to match('root/Blob/') + end + + it 'does not allow extra slashes' do + expect(subject).not_to match('/root/admin/') + expect(subject).not_to match('root/admin//') + end + end + + describe '.project_path_regex' do + subject { described_class.project_path_regex } + + it 'accepts top level routes' do + expect(subject).to match('admin/') + expect(subject).to match('api/') + expect(subject).to match('.well-known/') + end + + it 'rejects project wildcard routes' do + expect(subject).not_to match('blob/') + expect(subject).not_to match('edit/') + expect(subject).not_to match('wikis/') + expect(subject).not_to match('environments/folders/') + expect(subject).not_to match('info/lfs/objects/') + end + + it 'accepts group routes' do + expect(subject).to match('activity/') + expect(subject).to match('group_members/') + expect(subject).to match('subgroups/') + end + + it 'is not case sensitive' do + expect(subject).not_to match('Blob/') + end + + it 'does not allow extra slashes' do + expect(subject).not_to match('/admin/') + expect(subject).not_to match('admin//') + end + end + + describe '.full_project_path_regex' do + subject { described_class.full_project_path_regex } + + it 'accepts top level routes' do + expect(subject).to match('root/admin/') + expect(subject).to match('root/api/') + expect(subject).to match('root/.well-known/') + end + + it 'rejects project wildcard routes' do + expect(subject).not_to match('root/blob/') + expect(subject).not_to match('root/edit/') + expect(subject).not_to match('root/wikis/') + expect(subject).not_to match('root/environments/folders/') + expect(subject).not_to match('root/info/lfs/objects/') + end + + it 'accepts group routes' do + expect(subject).to match('root/activity/') + expect(subject).to match('root/group_members/') + expect(subject).to match('root/subgroups/') + end + + it 'is not case sensitive' do + expect(subject).not_to match('root/Blob/') + end + + it 'does not allow extra slashes' do + expect(subject).not_to match('/root/admin/') + expect(subject).not_to match('root/admin//') + end + end + + describe '.namespace_format_regex' do + subject { described_class.namespace_format_regex } + + it { is_expected.to match('gitlab-ce') } + it { is_expected.to match('gitlab_git') } + it { is_expected.to match('_underscore.js') } + it { is_expected.to match('100px.com') } + it { is_expected.to match('gitlab.org') } + it { is_expected.not_to match('?gitlab') } + it { is_expected.not_to match('git lab') } + it { is_expected.not_to match('gitlab.git') } + it { is_expected.not_to match('gitlab.org.') } + it { is_expected.not_to match('gitlab.org/') } + it { is_expected.not_to match('/gitlab.org') } + it { is_expected.not_to match('gitlab git') } + end + + describe '.project_path_format_regex' do + subject { described_class.project_path_format_regex } + + it { is_expected.to match('gitlab-ce') } + it { is_expected.to match('gitlab_git') } + it { is_expected.to match('_underscore.js') } + it { is_expected.to match('100px.com') } + it { is_expected.not_to match('?gitlab') } + it { is_expected.not_to match('git lab') } + it { is_expected.not_to match('gitlab.git') } + end +end diff --git a/spec/lib/gitlab/regex_spec.rb b/spec/lib/gitlab/regex_spec.rb index 72e947f2cc2..0bee892fe0c 100644 --- a/spec/lib/gitlab/regex_spec.rb +++ b/spec/lib/gitlab/regex_spec.rb @@ -2,18 +2,6 @@ require 'spec_helper' describe Gitlab::Regex, lib: true do - describe '.project_path_regex' do - subject { described_class.project_path_regex } - - it { is_expected.to match('gitlab-ce') } - it { is_expected.to match('gitlab_git') } - it { is_expected.to match('_underscore.js') } - it { is_expected.to match('100px.com') } - it { is_expected.not_to match('?gitlab') } - it { is_expected.not_to match('git lab') } - it { is_expected.not_to match('gitlab.git') } - end - describe '.project_name_regex' do subject { described_class.project_name_regex } @@ -44,16 +32,4 @@ describe Gitlab::Regex, lib: true do it { is_expected.not_to match('9foo') } it { is_expected.not_to match('foo-') } end - - describe '.full_namespace_regex' do - subject { described_class.full_namespace_regex } - - it { is_expected.to match('gitlab.org') } - it { is_expected.to match('gitlab.org/gitlab-git') } - it { is_expected.not_to match('gitlab.org.') } - it { is_expected.not_to match('gitlab.org/') } - it { is_expected.not_to match('/gitlab.org') } - it { is_expected.not_to match('gitlab.git') } - it { is_expected.not_to match('gitlab git') } - end end diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 8624616316c..ff5e7c350aa 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -37,7 +37,7 @@ describe Namespace, models: true do it 'rejects nested paths' do parent = create(:group, :nested, path: 'environments') - namespace = build(:project, path: 'folders', namespace: parent) + namespace = build(:group, path: 'folders', parent: parent) expect(namespace).not_to be_valid end @@ -238,8 +238,8 @@ describe Namespace, models: true do end context 'in sub-groups' do - let(:parent) { create(:namespace, path: 'parent') } - let(:child) { create(:namespace, parent: parent, path: 'child') } + let(:parent) { create(:group, path: 'parent') } + let(:child) { create(:group, parent: parent, path: 'child') } let!(:project) { create(:project_empty_repo, namespace: child) } let(:path_in_dir) { File.join(repository_storage_path, 'parent', 'child') } let(:deleted_path) { File.join('parent', "child+#{child.id}+deleted") } diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb index c1c2f2a7219..8c0a8f657cb 100644 --- a/spec/models/project_services/kubernetes_service_spec.rb +++ b/spec/models/project_services/kubernetes_service_spec.rb @@ -100,7 +100,7 @@ describe KubernetesService, models: true, caching: true do it 'sets the namespace to the default' do expect(kube_namespace).not_to be_nil - expect(kube_namespace[:placeholder]).to match(/\A#{Gitlab::Regex::PATH_REGEX_STR}-\d+\z/) + expect(kube_namespace[:placeholder]).to match(/\A#{Gitlab::PathRegex::PATH_REGEX_STR}-\d+\z/) end end end @@ -187,7 +187,7 @@ describe KubernetesService, models: true, caching: true do kube_namespace = subject.predefined_variables.find { |h| h[:key] == 'KUBE_NAMESPACE' } expect(kube_namespace).not_to be_nil - expect(kube_namespace[:value]).to match(/\A#{Gitlab::Regex::PATH_REGEX_STR}-\d+\z/) + expect(kube_namespace[:value]).to match(/\A#{Gitlab::PathRegex::PATH_REGEX_STR}-\d+\z/) end end end diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 4919ad19833..a2503dbeb69 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -287,7 +287,7 @@ describe API::Users do expect(json_response['message']['projects_limit']). to eq(['must be greater than or equal to 0']) expect(json_response['message']['username']). - to eq([Gitlab::Regex.namespace_regex_message]) + to eq([Gitlab::PathRegex.namespace_format_message]) end it "is not available for non admin users" do @@ -459,7 +459,7 @@ describe API::Users do expect(json_response['message']['projects_limit']). to eq(['must be greater than or equal to 0']) expect(json_response['message']['username']). - to eq([Gitlab::Regex.namespace_regex_message]) + to eq([Gitlab::PathRegex.namespace_format_message]) end it 'returns 400 if provider is missing for identity update' do diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index d5400bbaaf1..a391c046f92 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -462,6 +462,8 @@ describe 'project routing' do expect(get('/gitlab/gitlabhq/blob/master/app/models/compare.rb')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/compare.rb') expect(get('/gitlab/gitlabhq/blob/master/app/models/diff.js')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/diff.js') expect(get('/gitlab/gitlabhq/blob/master/files.scss')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss') + expect(get('/gitlab/gitlabhq/blob/master/blob/index.js')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/blob/index.js') + expect(get('/gitlab/gitlabhq/blob/blob/master/blob/index.js')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'blob/master/blob/index.js') end end @@ -470,6 +472,8 @@ describe 'project routing' do it 'to #show' do expect(get('/gitlab/gitlabhq/tree/master/app/models/project.rb')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb') expect(get('/gitlab/gitlabhq/tree/master/files.scss')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss') + expect(get('/gitlab/gitlabhq/tree/master/tree/files')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/tree/files') + expect(get('/gitlab/gitlabhq/tree/tree/master/tree/files')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'tree/master/tree/files') end end diff --git a/spec/validators/dynamic_path_validator_spec.rb b/spec/validators/dynamic_path_validator_spec.rb index b114bfc1bca..5f998e78f07 100644 --- a/spec/validators/dynamic_path_validator_spec.rb +++ b/spec/validators/dynamic_path_validator_spec.rb @@ -3,246 +3,46 @@ require 'spec_helper' describe DynamicPathValidator do let(:validator) { described_class.new(attributes: [:path]) } - # Pass in a full path to remove the format segment: - # `/ci/lint(.:format)` -> `/ci/lint` - def without_format(path) - path.split('(', 2)[0] - end - - # Pass in a full path and get the last segment before a wildcard - # That's not a parameter - # `/*namespace_id/:project_id/builds/artifacts/*ref_name_and_path` - # -> 'builds/artifacts' - def path_before_wildcard(path) - path = path.gsub(STARTING_WITH_NAMESPACE, "") - path_segments = path.split('/').reject(&:empty?) - wildcard_index = path_segments.index { |segment| parameter?(segment) } - - segments_before_wildcard = path_segments[0..wildcard_index - 1] - - segments_before_wildcard.join('/') - end - - def parameter?(segment) - segment =~ /[*:]/ - end - - # If the path is reserved. Then no conflicting paths can# be created for any - # route using this reserved word. - # - # Both `builds/artifacts` & `build` are covered by reserving the word - # `build` - def wildcards_include?(path) - described_class::WILDCARD_ROUTES.include?(path) || - described_class::WILDCARD_ROUTES.include?(path.split('/').first) - end - - def failure_message(missing_words, constant_name, migration_helper) - missing_words = Array(missing_words) - <<-MSG - Found new routes that could cause conflicts with existing namespaced routes - for groups or projects. + describe '#path_valid_for_record?' do + context 'for project' do + it 'calls valid_project_path?' do + project = build(:project, path: 'activity') - Add <#{missing_words.join(', ')}> to `DynamicPathValidator::#{constant_name} - to make sure no projects or namespaces can be created with those paths. + expect(described_class).to receive(:valid_project_path?).with(project.full_path).and_call_original - To rename any existing records with those paths you can use the - `Gitlab::Database::RenameReservedpathsMigration::.#{migration_helper}` - migration helper. - - Make sure to make a note of the renamed records in the release blog post. - - MSG - end - - let(:all_routes) do - Rails.application.routes.routes.routes. - map { |r| r.path.spec.to_s } - end - - let(:routes_without_format) { all_routes.map { |path| without_format(path) } } - - # Routes not starting with `/:` or `/*` - # all routes not starting with a param - let(:routes_not_starting_in_wildcard) { routes_without_format.select { |p| p !~ %r{^/[:*]} } } - - let(:top_level_words) do - routes_not_starting_in_wildcard.map do |route| - route.split('/')[1] - end.compact.uniq - end - - # All routes that start with a namespaced path, that have 1 or more - # path-segments before having another wildcard parameter. - # - Starting with paths: - # - `/*namespace_id/:project_id/` - # - `/*namespace_id/:id/` - # - Followed by one or more path-parts not starting with `:` or `*` - # - Followed by a path-part that includes a wildcard parameter `*` - # At the time of writing these routes match: http://rubular.com/r/Rv2pDE5Dvw - STARTING_WITH_NAMESPACE = %r{^/\*namespace_id/:(project_)?id} - NON_PARAM_PARTS = %r{[^:*][a-z\-_/]*} - ANY_OTHER_PATH_PART = %r{[a-z\-_/:]*} - WILDCARD_SEGMENT = %r{\*} - let(:namespaced_wildcard_routes) do - routes_without_format.select do |p| - p =~ %r{#{STARTING_WITH_NAMESPACE}/#{NON_PARAM_PARTS}/#{ANY_OTHER_PATH_PART}#{WILDCARD_SEGMENT}} - end - end - - # This will return all paths that are used in a namespaced route - # before another wildcard path: - # - # /*namespace_id/:project_id/builds/artifacts/*ref_name_and_path - # /*namespace_id/:project_id/info/lfs/objects/*oid - # /*namespace_id/:project_id/commits/*id - # /*namespace_id/:project_id/builds/:build_id/artifacts/file/*path - # -> ['builds/artifacts', 'info/lfs/objects', 'commits', 'artifacts/file'] - let(:all_wildcard_paths) do - namespaced_wildcard_routes.map do |route| - path_before_wildcard(route) - end.uniq - end - - STARTING_WITH_GROUP = %r{^/groups/\*(group_)?id/} - let(:group_routes) do - routes_without_format.select do |path| - path =~ STARTING_WITH_GROUP - end - end - - let(:paths_after_group_id) do - group_routes.map do |route| - route.gsub(STARTING_WITH_GROUP, '').split('/').first - end.uniq - end - - describe 'TOP_LEVEL_ROUTES' do - it 'includes all the top level namespaces' do - failure_block = lambda do - missing_words = top_level_words - described_class::TOP_LEVEL_ROUTES - failure_message(missing_words, 'TOP_LEVEL_ROUTES', 'rename_root_paths') + expect(validator.path_valid_for_record?(project, 'activity')).to be_truthy end - - expect(described_class::TOP_LEVEL_ROUTES) - .to include(*top_level_words), failure_block end - end - describe 'GROUP_ROUTES' do - it "don't contain a second wildcard" do - failure_block = lambda do - missing_words = paths_after_group_id - described_class::GROUP_ROUTES - failure_message(missing_words, 'GROUP_ROUTES', 'rename_child_paths') - end + context 'for group' do + it 'calls valid_group_path?' do + group = build(:group, :nested, path: 'activity') - expect(described_class::GROUP_ROUTES) - .to include(*paths_after_group_id), failure_block - end - end + expect(described_class).to receive(:valid_group_path?).with(group.full_path).and_call_original - describe 'WILDCARD_ROUTES' do - it 'includes all paths that can be used after a namespace/project path' do - aggregate_failures do - all_wildcard_paths.each do |path| - expect(wildcards_include?(path)) - .to be(true), failure_message(path, 'WILDCARD_ROUTES', 'rename_wildcard_paths') - end + expect(validator.path_valid_for_record?(group, 'activity')).to be_falsey end end - end - describe '.without_reserved_wildcard_paths_regex' do - subject { described_class.without_reserved_wildcard_paths_regex } + context 'for user' do + it 'calls valid_user_path?' do + user = build(:user, username: 'activity') - it 'rejects paths starting with a reserved top level' do - expect(subject).not_to match('dashboard/hello/world') - expect(subject).not_to match('dashboard') - end + expect(described_class).to receive(:valid_user_path?).with(user.full_path).and_call_original - it 'matches valid paths with a toplevel word in a different place' do - expect(subject).to match('parent/dashboard/project-path') - end - - it 'rejects paths containing a wildcard reserved word' do - expect(subject).not_to match('hello/edit') - expect(subject).not_to match('hello/edit/in-the-middle') - expect(subject).not_to match('foo/bar1/refs/master/logs_tree') - end - - it 'matches valid paths' do - expect(subject).to match('parent/child/project-path') - end - end - - describe '.regex_excluding_child_paths' do - let(:subject) { described_class.without_reserved_child_paths_regex } - - it 'rejects paths containing a child reserved word' do - expect(subject).not_to match('hello/group_members') - expect(subject).not_to match('hello/activity/in-the-middle') - expect(subject).not_to match('foo/bar1/refs/master/logs_tree') - end - - it 'allows a child path on the top level' do - expect(subject).to match('activity/foo') - expect(subject).to match('avatar') - end - end - - describe ".valid?" do - it 'is not case sensitive' do - expect(described_class.valid?("Users")).to be_falsey - end - - it "isn't valid when the top level is reserved" do - test_path = 'u/should-be-a/reserved-word' - - expect(described_class.valid?(test_path)).to be_falsey - end - - it "isn't valid if any of the path segments is reserved" do - test_path = 'the-wildcard/wikis/is-not-allowed' - - expect(described_class.valid?(test_path)).to be_falsey - end - - it "is valid if the path doesn't contain reserved words" do - test_path = 'there-are/no-wildcards/in-this-path' - - expect(described_class.valid?(test_path)).to be_truthy - end - - it 'allows allows a child path on the last spot' do - test_path = 'there/can-be-a/project-called/labels' - - expect(described_class.valid?(test_path)).to be_truthy - end - - it 'rejects a child path somewhere else' do - test_path = 'there/can-be-no/labels/group' - - expect(described_class.valid?(test_path)).to be_falsey + expect(validator.path_valid_for_record?(user, 'activity')).to be_truthy + end end - it 'rejects paths that are in an incorrect format' do - test_path = 'incorrect/format.git' - - expect(described_class.valid?(test_path)).to be_falsey - end - end + context 'for user namespace' do + it 'calls valid_user_path?' do + user = create(:user, username: 'activity') + namespace = user.namespace - describe '#path_reserved_for_record?' do - it 'reserves a sub-group named activity' do - group = build(:group, :nested, path: 'activity') + expect(described_class).to receive(:valid_user_path?).with(namespace.full_path).and_call_original - expect(validator.path_reserved_for_record?(group, 'activity')).to be_truthy - end - - it "doesn't reserve a project called activity" do - project = build(:project, path: 'activity') - - expect(validator.path_reserved_for_record?(project, 'activity')).to be_falsey + expect(validator.path_valid_for_record?(namespace, 'activity')).to be_truthy + end end end @@ -252,7 +52,7 @@ describe DynamicPathValidator do validator.validate_each(group, :path, "Path with spaces, and comma's!") - expect(group.errors[:path]).to include(Gitlab::Regex.namespace_regex_message) + expect(group.errors[:path]).to include(Gitlab::PathRegex.namespace_format_message) end it 'adds a message when the path is not in the correct format' do -- cgit v1.2.1 From ed16c351c5acdf1ad2e401e72490320d06af6e91 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 22 May 2017 13:31:05 -0500 Subject: Fix specs --- .../import/bitbucket_controller_spec.rb | 21 +++++---- spec/controllers/import/gitlab_controller_spec.rb | 23 +++++----- .../v1/rename_namespaces_spec.rb | 52 +++++++++++----------- .../githubish_import_controller_shared_examples.rb | 16 +++++-- 4 files changed, 63 insertions(+), 49 deletions(-) (limited to 'spec') diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb index 010e3180ea4..0be7bc6a045 100644 --- a/spec/controllers/import/bitbucket_controller_spec.rb +++ b/spec/controllers/import/bitbucket_controller_spec.rb @@ -133,9 +133,13 @@ describe Import::BitbucketController do end context "when a namespace with the Bitbucket user's username already exists" do - let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) } + let!(:existing_namespace) { create(:group, name: other_username) } context "when the namespace is owned by the GitLab user" do + before do + existing_namespace.add_owner(user) + end + it "takes the existing namespace" do expect(Gitlab::BitbucketImport::ProjectCreator). to receive(:new).with(bitbucket_repo, bitbucket_repo.name, existing_namespace, user, access_params). @@ -146,11 +150,6 @@ describe Import::BitbucketController do end context "when the namespace is not owned by the GitLab user" do - before do - existing_namespace.owner = create(:user) - existing_namespace.save - end - it "doesn't create a project" do expect(Gitlab::BitbucketImport::ProjectCreator). not_to receive(:new) @@ -202,10 +201,14 @@ describe Import::BitbucketController do end context 'user has chosen an existing nested namespace and name for the project' do - let(:parent_namespace) { create(:namespace, name: 'foo', owner: user) } - let(:nested_namespace) { create(:namespace, name: 'bar', parent: parent_namespace, owner: user) } + let(:parent_namespace) { create(:group, name: 'foo', owner: user) } + let(:nested_namespace) { create(:group, name: 'bar', parent: parent_namespace) } let(:test_name) { 'test_name' } + before do + nested_namespace.add_owner(user) + end + it 'takes the selected namespace and name' do expect(Gitlab::BitbucketImport::ProjectCreator). to receive(:new).with(bitbucket_repo, test_name, nested_namespace, user, access_params). @@ -248,7 +251,7 @@ describe Import::BitbucketController do context 'user has chosen existent and non-existent nested namespaces and name for the project' do let(:test_name) { 'test_name' } - let!(:parent_namespace) { create(:namespace, name: 'foo', owner: user) } + let!(:parent_namespace) { create(:group, name: 'foo', owner: user) } it 'takes the selected namespace and name' do expect(Gitlab::BitbucketImport::ProjectCreator). diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb index 2dbb89219d0..3afd09063d7 100644 --- a/spec/controllers/import/gitlab_controller_spec.rb +++ b/spec/controllers/import/gitlab_controller_spec.rb @@ -108,9 +108,13 @@ describe Import::GitlabController do end context "when a namespace with the GitLab.com user's username already exists" do - let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) } + let!(:existing_namespace) { create(:group, name: other_username) } context "when the namespace is owned by the GitLab server user" do + before do + existing_namespace.add_owner(user) + end + it "takes the existing namespace" do expect(Gitlab::GitlabImport::ProjectCreator). to receive(:new).with(gitlab_repo, existing_namespace, user, access_params). @@ -121,11 +125,6 @@ describe Import::GitlabController do end context "when the namespace is not owned by the GitLab server user" do - before do - existing_namespace.owner = create(:user) - existing_namespace.save - end - it "doesn't create a project" do expect(Gitlab::GitlabImport::ProjectCreator). not_to receive(:new) @@ -174,10 +173,14 @@ describe Import::GitlabController do end end end - + context 'user has chosen an existing nested namespace for the project' do - let(:parent_namespace) { create(:namespace, name: 'foo', owner: user) } - let(:nested_namespace) { create(:namespace, name: 'bar', parent: parent_namespace, owner: user) } + let(:parent_namespace) { create(:group, name: 'foo', owner: user) } + let(:nested_namespace) { create(:group, name: 'bar', parent: parent_namespace) } + + before do + nested_namespace.add_owner(user) + end it 'takes the selected namespace and name' do expect(Gitlab::GitlabImport::ProjectCreator). @@ -221,7 +224,7 @@ describe Import::GitlabController do context 'user has chosen existent and non-existent nested namespaces and name for the project' do let(:test_name) { 'test_name' } - let!(:parent_namespace) { create(:namespace, name: 'foo', owner: user) } + let!(:parent_namespace) { create(:group, name: 'foo', owner: user) } it 'takes the selected namespace and name' do expect(Gitlab::GitlabImport::ProjectCreator). diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb index c56fded7516..ce2b5d620fd 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb @@ -18,8 +18,8 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do let(:subject) { described_class.new(['parent/the-Path'], migration) } it 'includes the namespace' do - parent = create(:namespace, path: 'parent') - child = create(:namespace, path: 'the-path', parent: parent) + parent = create(:group, path: 'parent') + child = create(:group, path: 'the-path', parent: parent) found_ids = subject.namespaces_for_paths(type: :child). map(&:id) @@ -30,13 +30,13 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do context 'for child namespaces' do it 'only returns child namespaces with the correct path' do - _root_namespace = create(:namespace, path: 'THE-path') - _other_path = create(:namespace, + _root_namespace = create(:group, path: 'THE-path') + _other_path = create(:group, path: 'other', - parent: create(:namespace)) - namespace = create(:namespace, + parent: create(:group)) + namespace = create(:group, path: 'the-path', - parent: create(:namespace)) + parent: create(:group)) found_ids = subject.namespaces_for_paths(type: :child). map(&:id) @@ -45,13 +45,13 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do end it 'has no namespaces that look the same' do - _root_namespace = create(:namespace, path: 'THE-path') - _similar_path = create(:namespace, + _root_namespace = create(:group, path: 'THE-path') + _similar_path = create(:group, path: 'not-really-the-path', - parent: create(:namespace)) - namespace = create(:namespace, + parent: create(:group)) + namespace = create(:group, path: 'the-path', - parent: create(:namespace)) + parent: create(:group)) found_ids = subject.namespaces_for_paths(type: :child). map(&:id) @@ -62,11 +62,11 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do context 'for top levelnamespaces' do it 'only returns child namespaces with the correct path' do - root_namespace = create(:namespace, path: 'the-path') - _other_path = create(:namespace, path: 'other') - _child_namespace = create(:namespace, + root_namespace = create(:group, path: 'the-path') + _other_path = create(:group, path: 'other') + _child_namespace = create(:group, path: 'the-path', - parent: create(:namespace)) + parent: create(:group)) found_ids = subject.namespaces_for_paths(type: :top_level). map(&:id) @@ -75,11 +75,11 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do end it 'has no namespaces that just look the same' do - root_namespace = create(:namespace, path: 'the-path') - _similar_path = create(:namespace, path: 'not-really-the-path') - _child_namespace = create(:namespace, + root_namespace = create(:group, path: 'the-path') + _similar_path = create(:group, path: 'not-really-the-path') + _child_namespace = create(:group, path: 'the-path', - parent: create(:namespace)) + parent: create(:group)) found_ids = subject.namespaces_for_paths(type: :top_level). map(&:id) @@ -124,10 +124,10 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do describe "#child_ids_for_parent" do it "collects child ids for all levels" do - parent = create(:namespace) - first_child = create(:namespace, parent: parent) - second_child = create(:namespace, parent: parent) - third_child = create(:namespace, parent: second_child) + parent = create(:group) + first_child = create(:group, parent: parent) + second_child = create(:group, parent: parent) + third_child = create(:group, parent: second_child) all_ids = [parent.id, first_child.id, second_child.id, third_child.id] collected_ids = subject.child_ids_for_parent(parent, ids: [parent.id]) @@ -205,9 +205,9 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do end describe '#rename_namespaces' do - let!(:top_level_namespace) { create(:namespace, path: 'the-path') } + let!(:top_level_namespace) { create(:group, path: 'the-path') } let!(:child_namespace) do - create(:namespace, path: 'the-path', parent: create(:namespace)) + create(:group, path: 'the-path', parent: create(:group)) end it 'renames top level namespaces the namespace' do diff --git a/spec/support/controllers/githubish_import_controller_shared_examples.rb b/spec/support/controllers/githubish_import_controller_shared_examples.rb index c59b30c772d..d6b40db09ce 100644 --- a/spec/support/controllers/githubish_import_controller_shared_examples.rb +++ b/spec/support/controllers/githubish_import_controller_shared_examples.rb @@ -209,9 +209,13 @@ shared_examples 'a GitHub-ish import controller: POST create' do end context 'user has chosen a namespace and name for the project' do - let(:test_namespace) { create(:namespace, name: 'test_namespace', owner: user) } + let(:test_namespace) { create(:group, name: 'test_namespace') } let(:test_name) { 'test_name' } + before do + test_namespace.add_owner(user) + end + it 'takes the selected namespace and name' do expect(Gitlab::GithubImport::ProjectCreator). to receive(:new).with(provider_repo, test_name, test_namespace, user, access_params, type: provider). @@ -230,10 +234,14 @@ shared_examples 'a GitHub-ish import controller: POST create' do end context 'user has chosen an existing nested namespace and name for the project' do - let(:parent_namespace) { create(:namespace, name: 'foo', owner: user) } - let(:nested_namespace) { create(:namespace, name: 'bar', parent: parent_namespace, owner: user) } + let(:parent_namespace) { create(:group, name: 'foo', owner: user) } + let(:nested_namespace) { create(:group, name: 'bar', parent: parent_namespace) } let(:test_name) { 'test_name' } + before do + nested_namespace.add_owner(user) + end + it 'takes the selected namespace and name' do expect(Gitlab::GithubImport::ProjectCreator). to receive(:new).with(provider_repo, test_name, nested_namespace, user, access_params, type: provider). @@ -276,7 +284,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do context 'user has chosen existent and non-existent nested namespaces and name for the project' do let(:test_name) { 'test_name' } - let!(:parent_namespace) { create(:namespace, name: 'foo', owner: user) } + let!(:parent_namespace) { create(:group, name: 'foo', owner: user) } it 'takes the selected namespace and name' do expect(Gitlab::GithubImport::ProjectCreator). -- cgit v1.2.1 From b0498c176fa134761d899c9b369be12f1ca789c5 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 22 May 2017 20:08:33 -0500 Subject: Remove changes that are not absolutely necessary --- .../import/bitbucket_controller_spec.rb | 21 +- spec/controllers/import/gitlab_controller_spec.rb | 21 +- .../v1/rename_namespaces_spec.rb | 52 +-- spec/lib/gitlab/path_regex_spec.rb | 384 -------------------- spec/lib/gitlab/regex_spec.rb | 392 +++++++++++++++++++++ spec/models/namespace_spec.rb | 4 +- .../project_services/kubernetes_service_spec.rb | 4 +- spec/requests/api/users_spec.rb | 4 +- .../githubish_import_controller_shared_examples.rb | 16 +- spec/validators/dynamic_path_validator_spec.rb | 14 +- 10 files changed, 453 insertions(+), 459 deletions(-) delete mode 100644 spec/lib/gitlab/path_regex_spec.rb (limited to 'spec') diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb index 0be7bc6a045..010e3180ea4 100644 --- a/spec/controllers/import/bitbucket_controller_spec.rb +++ b/spec/controllers/import/bitbucket_controller_spec.rb @@ -133,13 +133,9 @@ describe Import::BitbucketController do end context "when a namespace with the Bitbucket user's username already exists" do - let!(:existing_namespace) { create(:group, name: other_username) } + let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) } context "when the namespace is owned by the GitLab user" do - before do - existing_namespace.add_owner(user) - end - it "takes the existing namespace" do expect(Gitlab::BitbucketImport::ProjectCreator). to receive(:new).with(bitbucket_repo, bitbucket_repo.name, existing_namespace, user, access_params). @@ -150,6 +146,11 @@ describe Import::BitbucketController do end context "when the namespace is not owned by the GitLab user" do + before do + existing_namespace.owner = create(:user) + existing_namespace.save + end + it "doesn't create a project" do expect(Gitlab::BitbucketImport::ProjectCreator). not_to receive(:new) @@ -201,14 +202,10 @@ describe Import::BitbucketController do end context 'user has chosen an existing nested namespace and name for the project' do - let(:parent_namespace) { create(:group, name: 'foo', owner: user) } - let(:nested_namespace) { create(:group, name: 'bar', parent: parent_namespace) } + let(:parent_namespace) { create(:namespace, name: 'foo', owner: user) } + let(:nested_namespace) { create(:namespace, name: 'bar', parent: parent_namespace, owner: user) } let(:test_name) { 'test_name' } - before do - nested_namespace.add_owner(user) - end - it 'takes the selected namespace and name' do expect(Gitlab::BitbucketImport::ProjectCreator). to receive(:new).with(bitbucket_repo, test_name, nested_namespace, user, access_params). @@ -251,7 +248,7 @@ describe Import::BitbucketController do context 'user has chosen existent and non-existent nested namespaces and name for the project' do let(:test_name) { 'test_name' } - let!(:parent_namespace) { create(:group, name: 'foo', owner: user) } + let!(:parent_namespace) { create(:namespace, name: 'foo', owner: user) } it 'takes the selected namespace and name' do expect(Gitlab::BitbucketImport::ProjectCreator). diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb index 3afd09063d7..3270ea059fa 100644 --- a/spec/controllers/import/gitlab_controller_spec.rb +++ b/spec/controllers/import/gitlab_controller_spec.rb @@ -108,13 +108,9 @@ describe Import::GitlabController do end context "when a namespace with the GitLab.com user's username already exists" do - let!(:existing_namespace) { create(:group, name: other_username) } + let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) } context "when the namespace is owned by the GitLab server user" do - before do - existing_namespace.add_owner(user) - end - it "takes the existing namespace" do expect(Gitlab::GitlabImport::ProjectCreator). to receive(:new).with(gitlab_repo, existing_namespace, user, access_params). @@ -125,6 +121,11 @@ describe Import::GitlabController do end context "when the namespace is not owned by the GitLab server user" do + before do + existing_namespace.owner = create(:user) + existing_namespace.save + end + it "doesn't create a project" do expect(Gitlab::GitlabImport::ProjectCreator). not_to receive(:new) @@ -175,12 +176,8 @@ describe Import::GitlabController do end context 'user has chosen an existing nested namespace for the project' do - let(:parent_namespace) { create(:group, name: 'foo', owner: user) } - let(:nested_namespace) { create(:group, name: 'bar', parent: parent_namespace) } - - before do - nested_namespace.add_owner(user) - end + let(:parent_namespace) { create(:namespace, name: 'foo', owner: user) } + let(:nested_namespace) { create(:namespace, name: 'bar', parent: parent_namespace, owner: user) } it 'takes the selected namespace and name' do expect(Gitlab::GitlabImport::ProjectCreator). @@ -224,7 +221,7 @@ describe Import::GitlabController do context 'user has chosen existent and non-existent nested namespaces and name for the project' do let(:test_name) { 'test_name' } - let!(:parent_namespace) { create(:group, name: 'foo', owner: user) } + let!(:parent_namespace) { create(:namespace, name: 'foo', owner: user) } it 'takes the selected namespace and name' do expect(Gitlab::GitlabImport::ProjectCreator). diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb index ce2b5d620fd..c56fded7516 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb @@ -18,8 +18,8 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do let(:subject) { described_class.new(['parent/the-Path'], migration) } it 'includes the namespace' do - parent = create(:group, path: 'parent') - child = create(:group, path: 'the-path', parent: parent) + parent = create(:namespace, path: 'parent') + child = create(:namespace, path: 'the-path', parent: parent) found_ids = subject.namespaces_for_paths(type: :child). map(&:id) @@ -30,13 +30,13 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do context 'for child namespaces' do it 'only returns child namespaces with the correct path' do - _root_namespace = create(:group, path: 'THE-path') - _other_path = create(:group, + _root_namespace = create(:namespace, path: 'THE-path') + _other_path = create(:namespace, path: 'other', - parent: create(:group)) - namespace = create(:group, + parent: create(:namespace)) + namespace = create(:namespace, path: 'the-path', - parent: create(:group)) + parent: create(:namespace)) found_ids = subject.namespaces_for_paths(type: :child). map(&:id) @@ -45,13 +45,13 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do end it 'has no namespaces that look the same' do - _root_namespace = create(:group, path: 'THE-path') - _similar_path = create(:group, + _root_namespace = create(:namespace, path: 'THE-path') + _similar_path = create(:namespace, path: 'not-really-the-path', - parent: create(:group)) - namespace = create(:group, + parent: create(:namespace)) + namespace = create(:namespace, path: 'the-path', - parent: create(:group)) + parent: create(:namespace)) found_ids = subject.namespaces_for_paths(type: :child). map(&:id) @@ -62,11 +62,11 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do context 'for top levelnamespaces' do it 'only returns child namespaces with the correct path' do - root_namespace = create(:group, path: 'the-path') - _other_path = create(:group, path: 'other') - _child_namespace = create(:group, + root_namespace = create(:namespace, path: 'the-path') + _other_path = create(:namespace, path: 'other') + _child_namespace = create(:namespace, path: 'the-path', - parent: create(:group)) + parent: create(:namespace)) found_ids = subject.namespaces_for_paths(type: :top_level). map(&:id) @@ -75,11 +75,11 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do end it 'has no namespaces that just look the same' do - root_namespace = create(:group, path: 'the-path') - _similar_path = create(:group, path: 'not-really-the-path') - _child_namespace = create(:group, + root_namespace = create(:namespace, path: 'the-path') + _similar_path = create(:namespace, path: 'not-really-the-path') + _child_namespace = create(:namespace, path: 'the-path', - parent: create(:group)) + parent: create(:namespace)) found_ids = subject.namespaces_for_paths(type: :top_level). map(&:id) @@ -124,10 +124,10 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do describe "#child_ids_for_parent" do it "collects child ids for all levels" do - parent = create(:group) - first_child = create(:group, parent: parent) - second_child = create(:group, parent: parent) - third_child = create(:group, parent: second_child) + parent = create(:namespace) + first_child = create(:namespace, parent: parent) + second_child = create(:namespace, parent: parent) + third_child = create(:namespace, parent: second_child) all_ids = [parent.id, first_child.id, second_child.id, third_child.id] collected_ids = subject.child_ids_for_parent(parent, ids: [parent.id]) @@ -205,9 +205,9 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do end describe '#rename_namespaces' do - let!(:top_level_namespace) { create(:group, path: 'the-path') } + let!(:top_level_namespace) { create(:namespace, path: 'the-path') } let!(:child_namespace) do - create(:group, path: 'the-path', parent: create(:group)) + create(:namespace, path: 'the-path', parent: create(:namespace)) end it 'renames top level namespaces the namespace' do diff --git a/spec/lib/gitlab/path_regex_spec.rb b/spec/lib/gitlab/path_regex_spec.rb deleted file mode 100644 index 1eea710c80b..00000000000 --- a/spec/lib/gitlab/path_regex_spec.rb +++ /dev/null @@ -1,384 +0,0 @@ -# coding: utf-8 -require 'spec_helper' - -describe Gitlab::PathRegex, lib: true do - # Pass in a full path to remove the format segment: - # `/ci/lint(.:format)` -> `/ci/lint` - def without_format(path) - path.split('(', 2)[0] - end - - # Pass in a full path and get the last segment before a wildcard - # That's not a parameter - # `/*namespace_id/:project_id/builds/artifacts/*ref_name_and_path` - # -> 'builds/artifacts' - def path_before_wildcard(path) - path = path.gsub(STARTING_WITH_NAMESPACE, "") - path_segments = path.split('/').reject(&:empty?) - wildcard_index = path_segments.index { |segment| parameter?(segment) } - - segments_before_wildcard = path_segments[0..wildcard_index - 1] - - segments_before_wildcard.join('/') - end - - def parameter?(segment) - segment =~ /[*:]/ - end - - # If the path is reserved. Then no conflicting paths can# be created for any - # route using this reserved word. - # - # Both `builds/artifacts` & `build` are covered by reserving the word - # `build` - def wildcards_include?(path) - described_class::PROJECT_WILDCARD_ROUTES.include?(path) || - described_class::PROJECT_WILDCARD_ROUTES.include?(path.split('/').first) - end - - def failure_message(missing_words, constant_name, migration_helper) - missing_words = Array(missing_words) - <<-MSG - Found new routes that could cause conflicts with existing namespaced routes - for groups or projects. - - Add <#{missing_words.join(', ')}> to `Gitlab::PathRegex::#{constant_name} - to make sure no projects or namespaces can be created with those paths. - - To rename any existing records with those paths you can use the - `Gitlab::Database::RenameReservedpathsMigration::.#{migration_helper}` - migration helper. - - Make sure to make a note of the renamed records in the release blog post. - - MSG - end - - let(:all_routes) do - route_set = Rails.application.routes - routes_collection = route_set.routes - routes_array = routes_collection.routes - routes_array.map { |route| route.path.spec.to_s } - end - - let(:routes_without_format) { all_routes.map { |path| without_format(path) } } - - # Routes not starting with `/:` or `/*` - # all routes not starting with a param - let(:routes_not_starting_in_wildcard) { routes_without_format.select { |p| p !~ %r{^/[:*]} } } - - let(:top_level_words) do - routes_not_starting_in_wildcard.map do |route| - route.split('/')[1] - end.compact.uniq - end - - # All routes that start with a namespaced path, that have 1 or more - # path-segments before having another wildcard parameter. - # - Starting with paths: - # - `/*namespace_id/:project_id/` - # - `/*namespace_id/:id/` - # - Followed by one or more path-parts not starting with `:` or `*` - # - Followed by a path-part that includes a wildcard parameter `*` - # At the time of writing these routes match: http://rubular.com/r/Rv2pDE5Dvw - STARTING_WITH_NAMESPACE = %r{^/\*namespace_id/:(project_)?id} - NON_PARAM_PARTS = %r{[^:*][a-z\-_/]*} - ANY_OTHER_PATH_PART = %r{[a-z\-_/:]*} - WILDCARD_SEGMENT = %r{\*} - let(:namespaced_wildcard_routes) do - routes_without_format.select do |p| - p =~ %r{#{STARTING_WITH_NAMESPACE}/#{NON_PARAM_PARTS}/#{ANY_OTHER_PATH_PART}#{WILDCARD_SEGMENT}} - end - end - - # This will return all paths that are used in a namespaced route - # before another wildcard path: - # - # /*namespace_id/:project_id/builds/artifacts/*ref_name_and_path - # /*namespace_id/:project_id/info/lfs/objects/*oid - # /*namespace_id/:project_id/commits/*id - # /*namespace_id/:project_id/builds/:build_id/artifacts/file/*path - # -> ['builds/artifacts', 'info/lfs/objects', 'commits', 'artifacts/file'] - let(:all_wildcard_paths) do - namespaced_wildcard_routes.map do |route| - path_before_wildcard(route) - end.uniq - end - - STARTING_WITH_GROUP = %r{^/groups/\*(group_)?id/} - let(:group_routes) do - routes_without_format.select do |path| - path =~ STARTING_WITH_GROUP - end - end - - let(:paths_after_group_id) do - group_routes.map do |route| - route.gsub(STARTING_WITH_GROUP, '').split('/').first - end.uniq - end - - describe 'TOP_LEVEL_ROUTES' do - it 'includes all the top level namespaces' do - failure_block = lambda do - missing_words = top_level_words - described_class::TOP_LEVEL_ROUTES - failure_message(missing_words, 'TOP_LEVEL_ROUTES', 'rename_root_paths') - end - - expect(described_class::TOP_LEVEL_ROUTES) - .to include(*top_level_words), failure_block - end - end - - describe 'GROUP_ROUTES' do - it "don't contain a second wildcard" do - failure_block = lambda do - missing_words = paths_after_group_id - described_class::GROUP_ROUTES - failure_message(missing_words, 'GROUP_ROUTES', 'rename_child_paths') - end - - expect(described_class::GROUP_ROUTES) - .to include(*paths_after_group_id), failure_block - end - end - - describe 'PROJECT_WILDCARD_ROUTES' do - it 'includes all paths that can be used after a namespace/project path' do - aggregate_failures do - all_wildcard_paths.each do |path| - expect(wildcards_include?(path)) - .to be(true), failure_message(path, 'PROJECT_WILDCARD_ROUTES', 'rename_wildcard_paths') - end - end - end - end - - describe '.root_namespace_path_regex' do - subject { described_class.root_namespace_path_regex } - - it 'rejects top level routes' do - expect(subject).not_to match('admin/') - expect(subject).not_to match('api/') - expect(subject).not_to match('.well-known/') - end - - it 'accepts project wildcard routes' do - expect(subject).to match('blob/') - expect(subject).to match('edit/') - expect(subject).to match('wikis/') - end - - it 'accepts group routes' do - expect(subject).to match('activity/') - expect(subject).to match('group_members/') - expect(subject).to match('subgroups/') - end - - it 'is not case sensitive' do - expect(subject).not_to match('Users/') - end - - it 'does not allow extra slashes' do - expect(subject).not_to match('/blob/') - expect(subject).not_to match('blob//') - end - end - - describe '.full_namespace_path_regex' do - subject { described_class.full_namespace_path_regex } - - context 'at the top level' do - context 'when the final level' do - it 'rejects top level routes' do - expect(subject).not_to match('admin/') - expect(subject).not_to match('api/') - expect(subject).not_to match('.well-known/') - end - - it 'accepts project wildcard routes' do - expect(subject).to match('blob/') - expect(subject).to match('edit/') - expect(subject).to match('wikis/') - end - - it 'accepts group routes' do - expect(subject).to match('activity/') - expect(subject).to match('group_members/') - expect(subject).to match('subgroups/') - end - end - - context 'when more levels follow' do - it 'rejects top level routes' do - expect(subject).not_to match('admin/more/') - expect(subject).not_to match('api/more/') - expect(subject).not_to match('.well-known/more/') - end - - it 'accepts project wildcard routes' do - expect(subject).to match('blob/more/') - expect(subject).to match('edit/more/') - expect(subject).to match('wikis/more/') - expect(subject).to match('environments/folders/') - expect(subject).to match('info/lfs/objects/') - end - - it 'accepts group routes' do - expect(subject).to match('activity/more/') - expect(subject).to match('group_members/more/') - expect(subject).to match('subgroups/more/') - end - end - end - - context 'at the second level' do - context 'when the final level' do - it 'accepts top level routes' do - expect(subject).to match('root/admin/') - expect(subject).to match('root/api/') - expect(subject).to match('root/.well-known/') - end - - it 'rejects project wildcard routes' do - expect(subject).not_to match('root/blob/') - expect(subject).not_to match('root/edit/') - expect(subject).not_to match('root/wikis/') - expect(subject).not_to match('root/environments/folders/') - expect(subject).not_to match('root/info/lfs/objects/') - end - - it 'rejects group routes' do - expect(subject).not_to match('root/activity/') - expect(subject).not_to match('root/group_members/') - expect(subject).not_to match('root/subgroups/') - end - end - - context 'when more levels follow' do - it 'accepts top level routes' do - expect(subject).to match('root/admin/more/') - expect(subject).to match('root/api/more/') - expect(subject).to match('root/.well-known/more/') - end - - it 'rejects project wildcard routes' do - expect(subject).not_to match('root/blob/more/') - expect(subject).not_to match('root/edit/more/') - expect(subject).not_to match('root/wikis/more/') - expect(subject).not_to match('root/environments/folders/more/') - expect(subject).not_to match('root/info/lfs/objects/more/') - end - - it 'rejects group routes' do - expect(subject).not_to match('root/activity/more/') - expect(subject).not_to match('root/group_members/more/') - expect(subject).not_to match('root/subgroups/more/') - end - end - end - - it 'is not case sensitive' do - expect(subject).not_to match('root/Blob/') - end - - it 'does not allow extra slashes' do - expect(subject).not_to match('/root/admin/') - expect(subject).not_to match('root/admin//') - end - end - - describe '.project_path_regex' do - subject { described_class.project_path_regex } - - it 'accepts top level routes' do - expect(subject).to match('admin/') - expect(subject).to match('api/') - expect(subject).to match('.well-known/') - end - - it 'rejects project wildcard routes' do - expect(subject).not_to match('blob/') - expect(subject).not_to match('edit/') - expect(subject).not_to match('wikis/') - expect(subject).not_to match('environments/folders/') - expect(subject).not_to match('info/lfs/objects/') - end - - it 'accepts group routes' do - expect(subject).to match('activity/') - expect(subject).to match('group_members/') - expect(subject).to match('subgroups/') - end - - it 'is not case sensitive' do - expect(subject).not_to match('Blob/') - end - - it 'does not allow extra slashes' do - expect(subject).not_to match('/admin/') - expect(subject).not_to match('admin//') - end - end - - describe '.full_project_path_regex' do - subject { described_class.full_project_path_regex } - - it 'accepts top level routes' do - expect(subject).to match('root/admin/') - expect(subject).to match('root/api/') - expect(subject).to match('root/.well-known/') - end - - it 'rejects project wildcard routes' do - expect(subject).not_to match('root/blob/') - expect(subject).not_to match('root/edit/') - expect(subject).not_to match('root/wikis/') - expect(subject).not_to match('root/environments/folders/') - expect(subject).not_to match('root/info/lfs/objects/') - end - - it 'accepts group routes' do - expect(subject).to match('root/activity/') - expect(subject).to match('root/group_members/') - expect(subject).to match('root/subgroups/') - end - - it 'is not case sensitive' do - expect(subject).not_to match('root/Blob/') - end - - it 'does not allow extra slashes' do - expect(subject).not_to match('/root/admin/') - expect(subject).not_to match('root/admin//') - end - end - - describe '.namespace_format_regex' do - subject { described_class.namespace_format_regex } - - it { is_expected.to match('gitlab-ce') } - it { is_expected.to match('gitlab_git') } - it { is_expected.to match('_underscore.js') } - it { is_expected.to match('100px.com') } - it { is_expected.to match('gitlab.org') } - it { is_expected.not_to match('?gitlab') } - it { is_expected.not_to match('git lab') } - it { is_expected.not_to match('gitlab.git') } - it { is_expected.not_to match('gitlab.org.') } - it { is_expected.not_to match('gitlab.org/') } - it { is_expected.not_to match('/gitlab.org') } - it { is_expected.not_to match('gitlab git') } - end - - describe '.project_path_format_regex' do - subject { described_class.project_path_format_regex } - - it { is_expected.to match('gitlab-ce') } - it { is_expected.to match('gitlab_git') } - it { is_expected.to match('_underscore.js') } - it { is_expected.to match('100px.com') } - it { is_expected.not_to match('?gitlab') } - it { is_expected.not_to match('git lab') } - it { is_expected.not_to match('gitlab.git') } - end -end diff --git a/spec/lib/gitlab/regex_spec.rb b/spec/lib/gitlab/regex_spec.rb index 0bee892fe0c..a7d1283acb8 100644 --- a/spec/lib/gitlab/regex_spec.rb +++ b/spec/lib/gitlab/regex_spec.rb @@ -2,6 +2,386 @@ require 'spec_helper' describe Gitlab::Regex, lib: true do + # Pass in a full path to remove the format segment: + # `/ci/lint(.:format)` -> `/ci/lint` + def without_format(path) + path.split('(', 2)[0] + end + + # Pass in a full path and get the last segment before a wildcard + # That's not a parameter + # `/*namespace_id/:project_id/builds/artifacts/*ref_name_and_path` + # -> 'builds/artifacts' + def path_before_wildcard(path) + path = path.gsub(STARTING_WITH_NAMESPACE, "") + path_segments = path.split('/').reject(&:empty?) + wildcard_index = path_segments.index { |segment| parameter?(segment) } + + segments_before_wildcard = path_segments[0..wildcard_index - 1] + + segments_before_wildcard.join('/') + end + + def parameter?(segment) + segment =~ /[*:]/ + end + + # If the path is reserved. Then no conflicting paths can# be created for any + # route using this reserved word. + # + # Both `builds/artifacts` & `build` are covered by reserving the word + # `build` + def wildcards_include?(path) + described_class::PROJECT_WILDCARD_ROUTES.include?(path) || + described_class::PROJECT_WILDCARD_ROUTES.include?(path.split('/').first) + end + + def failure_message(missing_words, constant_name, migration_helper) + missing_words = Array(missing_words) + <<-MSG + Found new routes that could cause conflicts with existing namespaced routes + for groups or projects. + + Add <#{missing_words.join(', ')}> to `Gitlab::Regex::#{constant_name} + to make sure no projects or namespaces can be created with those paths. + + To rename any existing records with those paths you can use the + `Gitlab::Database::RenameReservedpathsMigration::.#{migration_helper}` + migration helper. + + Make sure to make a note of the renamed records in the release blog post. + + MSG + end + + let(:all_routes) do + route_set = Rails.application.routes + routes_collection = route_set.routes + routes_array = routes_collection.routes + routes_array.map { |route| route.path.spec.to_s } + end + + let(:routes_without_format) { all_routes.map { |path| without_format(path) } } + + # Routes not starting with `/:` or `/*` + # all routes not starting with a param + let(:routes_not_starting_in_wildcard) { routes_without_format.select { |p| p !~ %r{^/[:*]} } } + + let(:top_level_words) do + routes_not_starting_in_wildcard.map do |route| + route.split('/')[1] + end.compact.uniq + end + + # All routes that start with a namespaced path, that have 1 or more + # path-segments before having another wildcard parameter. + # - Starting with paths: + # - `/*namespace_id/:project_id/` + # - `/*namespace_id/:id/` + # - Followed by one or more path-parts not starting with `:` or `*` + # - Followed by a path-part that includes a wildcard parameter `*` + # At the time of writing these routes match: http://rubular.com/r/Rv2pDE5Dvw + STARTING_WITH_NAMESPACE = %r{^/\*namespace_id/:(project_)?id} + NON_PARAM_PARTS = %r{[^:*][a-z\-_/]*} + ANY_OTHER_PATH_PART = %r{[a-z\-_/:]*} + WILDCARD_SEGMENT = %r{\*} + let(:namespaced_wildcard_routes) do + routes_without_format.select do |p| + p =~ %r{#{STARTING_WITH_NAMESPACE}/#{NON_PARAM_PARTS}/#{ANY_OTHER_PATH_PART}#{WILDCARD_SEGMENT}} + end + end + + # This will return all paths that are used in a namespaced route + # before another wildcard path: + # + # /*namespace_id/:project_id/builds/artifacts/*ref_name_and_path + # /*namespace_id/:project_id/info/lfs/objects/*oid + # /*namespace_id/:project_id/commits/*id + # /*namespace_id/:project_id/builds/:build_id/artifacts/file/*path + # -> ['builds/artifacts', 'info/lfs/objects', 'commits', 'artifacts/file'] + let(:all_wildcard_paths) do + namespaced_wildcard_routes.map do |route| + path_before_wildcard(route) + end.uniq + end + + STARTING_WITH_GROUP = %r{^/groups/\*(group_)?id/} + let(:group_routes) do + routes_without_format.select do |path| + path =~ STARTING_WITH_GROUP + end + end + + let(:paths_after_group_id) do + group_routes.map do |route| + route.gsub(STARTING_WITH_GROUP, '').split('/').first + end.uniq + end + + describe 'TOP_LEVEL_ROUTES' do + it 'includes all the top level namespaces' do + failure_block = lambda do + missing_words = top_level_words - described_class::TOP_LEVEL_ROUTES + failure_message(missing_words, 'TOP_LEVEL_ROUTES', 'rename_root_paths') + end + + expect(described_class::TOP_LEVEL_ROUTES) + .to include(*top_level_words), failure_block + end + end + + describe 'GROUP_ROUTES' do + it "don't contain a second wildcard" do + failure_block = lambda do + missing_words = paths_after_group_id - described_class::GROUP_ROUTES + failure_message(missing_words, 'GROUP_ROUTES', 'rename_child_paths') + end + + expect(described_class::GROUP_ROUTES) + .to include(*paths_after_group_id), failure_block + end + end + + describe 'PROJECT_WILDCARD_ROUTES' do + it 'includes all paths that can be used after a namespace/project path' do + aggregate_failures do + all_wildcard_paths.each do |path| + expect(wildcards_include?(path)) + .to be(true), failure_message(path, 'PROJECT_WILDCARD_ROUTES', 'rename_wildcard_paths') + end + end + end + end + + describe '.root_namespace_path_regex' do + subject { described_class.root_namespace_path_regex } + + it 'rejects top level routes' do + expect(subject).not_to match('admin/') + expect(subject).not_to match('api/') + expect(subject).not_to match('.well-known/') + end + + it 'accepts project wildcard routes' do + expect(subject).to match('blob/') + expect(subject).to match('edit/') + expect(subject).to match('wikis/') + end + + it 'accepts group routes' do + expect(subject).to match('activity/') + expect(subject).to match('group_members/') + expect(subject).to match('subgroups/') + end + + it 'is not case sensitive' do + expect(subject).not_to match('Users/') + end + + it 'does not allow extra slashes' do + expect(subject).not_to match('/blob/') + expect(subject).not_to match('blob//') + end + end + + describe '.full_namespace_path_regex' do + subject { described_class.full_namespace_path_regex } + + context 'at the top level' do + context 'when the final level' do + it 'rejects top level routes' do + expect(subject).not_to match('admin/') + expect(subject).not_to match('api/') + expect(subject).not_to match('.well-known/') + end + + it 'accepts project wildcard routes' do + expect(subject).to match('blob/') + expect(subject).to match('edit/') + expect(subject).to match('wikis/') + end + + it 'accepts group routes' do + expect(subject).to match('activity/') + expect(subject).to match('group_members/') + expect(subject).to match('subgroups/') + end + end + + context 'when more levels follow' do + it 'rejects top level routes' do + expect(subject).not_to match('admin/more/') + expect(subject).not_to match('api/more/') + expect(subject).not_to match('.well-known/more/') + end + + it 'accepts project wildcard routes' do + expect(subject).to match('blob/more/') + expect(subject).to match('edit/more/') + expect(subject).to match('wikis/more/') + expect(subject).to match('environments/folders/') + expect(subject).to match('info/lfs/objects/') + end + + it 'accepts group routes' do + expect(subject).to match('activity/more/') + expect(subject).to match('group_members/more/') + expect(subject).to match('subgroups/more/') + end + end + end + + context 'at the second level' do + context 'when the final level' do + it 'accepts top level routes' do + expect(subject).to match('root/admin/') + expect(subject).to match('root/api/') + expect(subject).to match('root/.well-known/') + end + + it 'rejects project wildcard routes' do + expect(subject).not_to match('root/blob/') + expect(subject).not_to match('root/edit/') + expect(subject).not_to match('root/wikis/') + expect(subject).not_to match('root/environments/folders/') + expect(subject).not_to match('root/info/lfs/objects/') + end + + it 'rejects group routes' do + expect(subject).not_to match('root/activity/') + expect(subject).not_to match('root/group_members/') + expect(subject).not_to match('root/subgroups/') + end + end + + context 'when more levels follow' do + it 'accepts top level routes' do + expect(subject).to match('root/admin/more/') + expect(subject).to match('root/api/more/') + expect(subject).to match('root/.well-known/more/') + end + + it 'rejects project wildcard routes' do + expect(subject).not_to match('root/blob/more/') + expect(subject).not_to match('root/edit/more/') + expect(subject).not_to match('root/wikis/more/') + expect(subject).not_to match('root/environments/folders/more/') + expect(subject).not_to match('root/info/lfs/objects/more/') + end + + it 'rejects group routes' do + expect(subject).not_to match('root/activity/more/') + expect(subject).not_to match('root/group_members/more/') + expect(subject).not_to match('root/subgroups/more/') + end + end + end + + it 'is not case sensitive' do + expect(subject).not_to match('root/Blob/') + end + + it 'does not allow extra slashes' do + expect(subject).not_to match('/root/admin/') + expect(subject).not_to match('root/admin//') + end + end + + describe '.project_path_regex' do + subject { described_class.project_path_regex } + + it 'accepts top level routes' do + expect(subject).to match('admin/') + expect(subject).to match('api/') + expect(subject).to match('.well-known/') + end + + it 'rejects project wildcard routes' do + expect(subject).not_to match('blob/') + expect(subject).not_to match('edit/') + expect(subject).not_to match('wikis/') + expect(subject).not_to match('environments/folders/') + expect(subject).not_to match('info/lfs/objects/') + end + + it 'accepts group routes' do + expect(subject).to match('activity/') + expect(subject).to match('group_members/') + expect(subject).to match('subgroups/') + end + + it 'is not case sensitive' do + expect(subject).not_to match('Blob/') + end + + it 'does not allow extra slashes' do + expect(subject).not_to match('/admin/') + expect(subject).not_to match('admin//') + end + end + + describe '.full_project_path_regex' do + subject { described_class.full_project_path_regex } + + it 'accepts top level routes' do + expect(subject).to match('root/admin/') + expect(subject).to match('root/api/') + expect(subject).to match('root/.well-known/') + end + + it 'rejects project wildcard routes' do + expect(subject).not_to match('root/blob/') + expect(subject).not_to match('root/edit/') + expect(subject).not_to match('root/wikis/') + expect(subject).not_to match('root/environments/folders/') + expect(subject).not_to match('root/info/lfs/objects/') + end + + it 'accepts group routes' do + expect(subject).to match('root/activity/') + expect(subject).to match('root/group_members/') + expect(subject).to match('root/subgroups/') + end + + it 'is not case sensitive' do + expect(subject).not_to match('root/Blob/') + end + + it 'does not allow extra slashes' do + expect(subject).not_to match('/root/admin/') + expect(subject).not_to match('root/admin//') + end + end + + describe '.namespace_regex' do + subject { described_class.namespace_regex } + + it { is_expected.to match('gitlab-ce') } + it { is_expected.to match('gitlab_git') } + it { is_expected.to match('_underscore.js') } + it { is_expected.to match('100px.com') } + it { is_expected.to match('gitlab.org') } + it { is_expected.not_to match('?gitlab') } + it { is_expected.not_to match('git lab') } + it { is_expected.not_to match('gitlab.git') } + it { is_expected.not_to match('gitlab.org.') } + it { is_expected.not_to match('gitlab.org/') } + it { is_expected.not_to match('/gitlab.org') } + it { is_expected.not_to match('gitlab git') } + end + + describe '.project_path_format_regex' do + subject { described_class.project_path_format_regex } + + it { is_expected.to match('gitlab-ce') } + it { is_expected.to match('gitlab_git') } + it { is_expected.to match('_underscore.js') } + it { is_expected.to match('100px.com') } + it { is_expected.not_to match('?gitlab') } + it { is_expected.not_to match('git lab') } + it { is_expected.not_to match('gitlab.git') } + end + describe '.project_name_regex' do subject { described_class.project_name_regex } @@ -32,4 +412,16 @@ describe Gitlab::Regex, lib: true do it { is_expected.not_to match('9foo') } it { is_expected.not_to match('foo-') } end + + describe '.full_namespace_regex' do + subject { described_class.full_namespace_regex } + + it { is_expected.to match('gitlab.org') } + it { is_expected.to match('gitlab.org/gitlab-git') } + it { is_expected.not_to match('gitlab.org.') } + it { is_expected.not_to match('gitlab.org/') } + it { is_expected.not_to match('/gitlab.org') } + it { is_expected.not_to match('gitlab.git') } + it { is_expected.not_to match('gitlab git') } + end end diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index ff5e7c350aa..312302afdbb 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -238,8 +238,8 @@ describe Namespace, models: true do end context 'in sub-groups' do - let(:parent) { create(:group, path: 'parent') } - let(:child) { create(:group, parent: parent, path: 'child') } + let(:parent) { create(:namespace, path: 'parent') } + let(:child) { create(:namespace, parent: parent, path: 'child') } let!(:project) { create(:project_empty_repo, namespace: child) } let(:path_in_dir) { File.join(repository_storage_path, 'parent', 'child') } let(:deleted_path) { File.join('parent', "child+#{child.id}+deleted") } diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb index 8c0a8f657cb..c1c2f2a7219 100644 --- a/spec/models/project_services/kubernetes_service_spec.rb +++ b/spec/models/project_services/kubernetes_service_spec.rb @@ -100,7 +100,7 @@ describe KubernetesService, models: true, caching: true do it 'sets the namespace to the default' do expect(kube_namespace).not_to be_nil - expect(kube_namespace[:placeholder]).to match(/\A#{Gitlab::PathRegex::PATH_REGEX_STR}-\d+\z/) + expect(kube_namespace[:placeholder]).to match(/\A#{Gitlab::Regex::PATH_REGEX_STR}-\d+\z/) end end end @@ -187,7 +187,7 @@ describe KubernetesService, models: true, caching: true do kube_namespace = subject.predefined_variables.find { |h| h[:key] == 'KUBE_NAMESPACE' } expect(kube_namespace).not_to be_nil - expect(kube_namespace[:value]).to match(/\A#{Gitlab::PathRegex::PATH_REGEX_STR}-\d+\z/) + expect(kube_namespace[:value]).to match(/\A#{Gitlab::Regex::PATH_REGEX_STR}-\d+\z/) end end end diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index a2503dbeb69..4919ad19833 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -287,7 +287,7 @@ describe API::Users do expect(json_response['message']['projects_limit']). to eq(['must be greater than or equal to 0']) expect(json_response['message']['username']). - to eq([Gitlab::PathRegex.namespace_format_message]) + to eq([Gitlab::Regex.namespace_regex_message]) end it "is not available for non admin users" do @@ -459,7 +459,7 @@ describe API::Users do expect(json_response['message']['projects_limit']). to eq(['must be greater than or equal to 0']) expect(json_response['message']['username']). - to eq([Gitlab::PathRegex.namespace_format_message]) + to eq([Gitlab::Regex.namespace_regex_message]) end it 'returns 400 if provider is missing for identity update' do diff --git a/spec/support/controllers/githubish_import_controller_shared_examples.rb b/spec/support/controllers/githubish_import_controller_shared_examples.rb index d6b40db09ce..c59b30c772d 100644 --- a/spec/support/controllers/githubish_import_controller_shared_examples.rb +++ b/spec/support/controllers/githubish_import_controller_shared_examples.rb @@ -209,13 +209,9 @@ shared_examples 'a GitHub-ish import controller: POST create' do end context 'user has chosen a namespace and name for the project' do - let(:test_namespace) { create(:group, name: 'test_namespace') } + let(:test_namespace) { create(:namespace, name: 'test_namespace', owner: user) } let(:test_name) { 'test_name' } - before do - test_namespace.add_owner(user) - end - it 'takes the selected namespace and name' do expect(Gitlab::GithubImport::ProjectCreator). to receive(:new).with(provider_repo, test_name, test_namespace, user, access_params, type: provider). @@ -234,14 +230,10 @@ shared_examples 'a GitHub-ish import controller: POST create' do end context 'user has chosen an existing nested namespace and name for the project' do - let(:parent_namespace) { create(:group, name: 'foo', owner: user) } - let(:nested_namespace) { create(:group, name: 'bar', parent: parent_namespace) } + let(:parent_namespace) { create(:namespace, name: 'foo', owner: user) } + let(:nested_namespace) { create(:namespace, name: 'bar', parent: parent_namespace, owner: user) } let(:test_name) { 'test_name' } - before do - nested_namespace.add_owner(user) - end - it 'takes the selected namespace and name' do expect(Gitlab::GithubImport::ProjectCreator). to receive(:new).with(provider_repo, test_name, nested_namespace, user, access_params, type: provider). @@ -284,7 +276,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do context 'user has chosen existent and non-existent nested namespaces and name for the project' do let(:test_name) { 'test_name' } - let!(:parent_namespace) { create(:group, name: 'foo', owner: user) } + let!(:parent_namespace) { create(:namespace, name: 'foo', owner: user) } it 'takes the selected namespace and name' do expect(Gitlab::GithubImport::ProjectCreator). diff --git a/spec/validators/dynamic_path_validator_spec.rb b/spec/validators/dynamic_path_validator_spec.rb index 5f998e78f07..03e23781d1b 100644 --- a/spec/validators/dynamic_path_validator_spec.rb +++ b/spec/validators/dynamic_path_validator_spec.rb @@ -15,31 +15,31 @@ describe DynamicPathValidator do end context 'for group' do - it 'calls valid_group_path?' do + it 'calls valid_namespace_path?' do group = build(:group, :nested, path: 'activity') - expect(described_class).to receive(:valid_group_path?).with(group.full_path).and_call_original + expect(described_class).to receive(:valid_namespace_path?).with(group.full_path).and_call_original expect(validator.path_valid_for_record?(group, 'activity')).to be_falsey end end context 'for user' do - it 'calls valid_user_path?' do + it 'calls valid_namespace_path?' do user = build(:user, username: 'activity') - expect(described_class).to receive(:valid_user_path?).with(user.full_path).and_call_original + expect(described_class).to receive(:valid_namespace_path?).with(user.full_path).and_call_original expect(validator.path_valid_for_record?(user, 'activity')).to be_truthy end end context 'for user namespace' do - it 'calls valid_user_path?' do + it 'calls valid_namespace_path?' do user = create(:user, username: 'activity') namespace = user.namespace - expect(described_class).to receive(:valid_user_path?).with(namespace.full_path).and_call_original + expect(described_class).to receive(:valid_namespace_path?).with(namespace.full_path).and_call_original expect(validator.path_valid_for_record?(namespace, 'activity')).to be_truthy end @@ -52,7 +52,7 @@ describe DynamicPathValidator do validator.validate_each(group, :path, "Path with spaces, and comma's!") - expect(group.errors[:path]).to include(Gitlab::PathRegex.namespace_format_message) + expect(group.errors[:path]).to include(Gitlab::Regex.namespace_regex_message) end it 'adds a message when the path is not in the correct format' do -- cgit v1.2.1 From 6b8fac9de471646b36a822e2b18e1b3a97965288 Mon Sep 17 00:00:00 2001 From: Simon Knox Date: Wed, 17 May 2017 19:50:40 +1000 Subject: add loading spinner to sidebar assignees store isFetching state to indicate if assignees has initial data --- spec/javascripts/sidebar/sidebar_assignees_spec.js | 12 ++++++++++++ spec/javascripts/sidebar/sidebar_store_spec.js | 5 +++++ 2 files changed, 17 insertions(+) (limited to 'spec') diff --git a/spec/javascripts/sidebar/sidebar_assignees_spec.js b/spec/javascripts/sidebar/sidebar_assignees_spec.js index 865951b2ad7..929ba75e67d 100644 --- a/spec/javascripts/sidebar/sidebar_assignees_spec.js +++ b/spec/javascripts/sidebar/sidebar_assignees_spec.js @@ -43,4 +43,16 @@ describe('sidebar assignees', () => { expect(SidebarMediator.prototype.assignYourself).toHaveBeenCalled(); expect(this.mediator.store.assignees.length).toEqual(1); }); + + it('hides assignees until fetched', (done) => { + component = new SidebarAssigneeComponent().$mount(this.sidebarAssigneesEl); + const currentAssignee = this.sidebarAssigneesEl.querySelector('.value'); + expect(currentAssignee).toBe(null); + + component.store.isFetching.assignees = false; + Vue.nextTick(() => { + expect(component.$el.querySelector('.value')).toBeVisible(); + done(); + }); + }); }); diff --git a/spec/javascripts/sidebar/sidebar_store_spec.js b/spec/javascripts/sidebar/sidebar_store_spec.js index 29facf483b5..b3fa156eb64 100644 --- a/spec/javascripts/sidebar/sidebar_store_spec.js +++ b/spec/javascripts/sidebar/sidebar_store_spec.js @@ -35,6 +35,10 @@ describe('Sidebar store', () => { SidebarStore.singleton = null; }); + it('has default isFetching values', () => { + expect(this.store.isFetching.assignees).toBe(true); + }); + it('adds a new assignee', () => { this.store.addAssignee(assignee); expect(this.store.assignees.length).toEqual(1); @@ -67,6 +71,7 @@ describe('Sidebar store', () => { }; this.store.setAssigneeData(users); + expect(this.store.isFetching.assignees).toBe(false); expect(this.store.assignees.length).toEqual(3); }); -- cgit v1.2.1 From 3ca932844316f567f9ed091d7185ad9fafc27c51 Mon Sep 17 00:00:00 2001 From: Jarka Kadlecova Date: Tue, 9 May 2017 14:14:24 +0200 Subject: Fix LaTeX formatting for AsciiDoc wiki --- .../projects/wiki/user_creates_wiki_page_spec.rb | 34 ++++++++++++++++++++++ .../ascii_doc_post_processing_filter_spec.rb | 15 ++++++++++ spec/lib/banzai/filter/sanitization_filter_spec.rb | 16 ++++++++++ spec/lib/gitlab/asciidoc_spec.rb | 25 ++++++++++++++++ 4 files changed, 90 insertions(+) create mode 100644 spec/lib/banzai/filter/ascii_doc_post_processing_filter_spec.rb (limited to 'spec') diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb index 5c502ce4fb5..8912d575878 100644 --- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb @@ -28,6 +28,40 @@ feature 'Projects > Wiki > User creates wiki page', js: true, feature: true do expect(page).to have_content("Last edited by #{user.name}") expect(page).to have_content('My awesome wiki!') end + + scenario 'creates ASCII wiki with LaTeX blocks' do + stub_application_setting(plantuml_url: 'http://localhost', plantuml_enabled: true) + + ascii_content = <<~MD + :stem: latexmath + + [stem] + ++++ + \sqrt{4} = 2 + ++++ + + another part + + [latexmath] + ++++ + \beta_x \gamma + ++++ + + stem:[2+2] is 4 + MD + + find('#wiki_format option[value=asciidoc]').select_option + fill_in :wiki_content, with: ascii_content + + page.within '.wiki-form' do + click_button 'Create page' + end + + page.within '.wiki' do + expect(page).to have_selector('.katex', count: 3) + expect(page).to have_content('2+2 is 4') + end + end end context 'when wiki is not empty' do diff --git a/spec/lib/banzai/filter/ascii_doc_post_processing_filter_spec.rb b/spec/lib/banzai/filter/ascii_doc_post_processing_filter_spec.rb new file mode 100644 index 00000000000..33b812ef425 --- /dev/null +++ b/spec/lib/banzai/filter/ascii_doc_post_processing_filter_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe Banzai::Filter::AsciiDocPostProcessingFilter, lib: true do + include FilterSpecHelper + + it "adds class for elements with data-math-style" do + result = filter('
    some code
    and
    ').to_html + expect(result).to eq('
    some code
    and
    ') + end + + it "keeps content when no data-math-style found" do + result = filter('
    some code
    and
    ').to_html + expect(result).to eq('
    some code
    and
    ') + end +end diff --git a/spec/lib/banzai/filter/sanitization_filter_spec.rb b/spec/lib/banzai/filter/sanitization_filter_spec.rb index fdbc65b5e00..fb7862f49a2 100644 --- a/spec/lib/banzai/filter/sanitization_filter_spec.rb +++ b/spec/lib/banzai/filter/sanitization_filter_spec.rb @@ -97,6 +97,22 @@ describe Banzai::Filter::SanitizationFilter, lib: true do expect(filter(act).to_html).to eq exp end + it 'allows `data-math-style` attribute on `code` and `pre` elements' do + html = <<-HTML +
    something
    + something +
    something
    + HTML + + output = <<-HTML +
    something
    + something +
    something
    + HTML + + expect(filter(html).to_html).to eq(output) + end + it 'removes `rel` attribute from `a` elements' do act = %q{
    Link} exp = %q{Link} diff --git a/spec/lib/gitlab/asciidoc_spec.rb b/spec/lib/gitlab/asciidoc_spec.rb index 2c7ebb15fd7..43d52b941ab 100644 --- a/spec/lib/gitlab/asciidoc_spec.rb +++ b/spec/lib/gitlab/asciidoc_spec.rb @@ -70,6 +70,31 @@ module Gitlab expect(output).to include('rel="nofollow noreferrer noopener"') end end + + context 'LaTex code' do + it 'adds class js-render-math to the output' do + input = <<~MD + :stem: latexmath + + [stem] + ++++ + \sqrt{4} = 2 + ++++ + + another part + + [latexmath] + ++++ + \beta_x \gamma + ++++ + + stem:[2+2] is 4 + MD + + expect(render(input, context)).to include('
    eta_x gamma
    ') + expect(render(input, context)).to include('

    2+2 is 4

    ') + end + end end def render(*args) -- cgit v1.2.1 From 7598cf62b8d19df546a0d9b65c3ae63ce9bc6ada Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Wed, 24 May 2017 09:19:08 -0500 Subject: Use import instead of require --- spec/javascripts/copy_as_gfm_spec.js | 2 +- .../filtered_search/components/recent_searches_dropdown_content_spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/copy_as_gfm_spec.js b/spec/javascripts/copy_as_gfm_spec.js index 1a850bb56ab..ded450749d3 100644 --- a/spec/javascripts/copy_as_gfm_spec.js +++ b/spec/javascripts/copy_as_gfm_spec.js @@ -1,4 +1,4 @@ -require('~/copy_as_gfm'); +import '~/copy_as_gfm'; (() => { describe('gl.CopyAsGFM', () => { diff --git a/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js b/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js index 0ebb867b851..79447787fc9 100644 --- a/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js +++ b/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js @@ -2,7 +2,7 @@ import Vue from 'vue'; import eventHub from '~/filtered_search/event_hub'; import RecentSearchesDropdownContent from '~/filtered_search/components/recent_searches_dropdown_content'; -require('~/filtered_search/filtered_search_token_keys'); +import '~/filtered_search/filtered_search_token_keys'; const createComponent = (propsData) => { const Component = Vue.extend(RecentSearchesDropdownContent); -- cgit v1.2.1 From 0bf339f0ed2f91a805e99fc7483572ad7d22093a Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 24 May 2017 10:10:10 -0500 Subject: Address review --- spec/models/concerns/discussion_on_diff_spec.rb | 26 +++++++++++++++++++++++++ spec/services/system_note_service_spec.rb | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/models/concerns/discussion_on_diff_spec.rb b/spec/models/concerns/discussion_on_diff_spec.rb index 8571e85627c..f3e148f95f0 100644 --- a/spec/models/concerns/discussion_on_diff_spec.rb +++ b/spec/models/concerns/discussion_on_diff_spec.rb @@ -21,4 +21,30 @@ describe DiscussionOnDiff, model: true do end end end + + describe '#line_code_in_diffs' do + context 'when the discussion is active in the diff' do + let(:diff_refs) { subject.position.diff_refs } + + it 'returns the current line code' do + expect(subject.line_code_in_diffs(diff_refs)).to eq(subject.line_code) + end + end + + context 'when the discussion was created in the diff' do + let(:diff_refs) { subject.original_position.diff_refs } + + it 'returns the original line code' do + expect(subject.line_code_in_diffs(diff_refs)).to eq(subject.original_line_code) + end + end + + context 'when the discussion is unrelated to the diff' do + let(:diff_refs) { subject.project.commit(RepoHelpers.sample_commit.id).diff_refs } + + it 'returns nil' do + expect(subject.line_code_in_diffs(diff_refs)).to be_nil + end + end + end end diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index c737a1f82a3..5a7cfaff7fb 100644 --- a/spec/services/system_note_service_spec.rb +++ b/spec/services/system_note_service_spec.rb @@ -1049,7 +1049,7 @@ describe SystemNoteService, services: true do it_behaves_like 'a system note' do let(:expected_noteable) { discussion.first_note.noteable } - let(:action) { 'outdated' } + let(:action) { 'outdated' } end it 'creates a new note in the discussion' do -- cgit v1.2.1 From f14bb942538c28850d4d971be48a0acfb06e1ad3 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 23 May 2017 14:58:39 -0500 Subject: Add spec --- spec/features/copy_as_gfm_spec.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'spec') diff --git a/spec/features/copy_as_gfm_spec.rb b/spec/features/copy_as_gfm_spec.rb index 9318c56112b..740f60c05cc 100644 --- a/spec/features/copy_as_gfm_spec.rb +++ b/spec/features/copy_as_gfm_spec.rb @@ -78,6 +78,25 @@ describe 'Copy as GFM', feature: true, js: true do expect(output_gfm.strip).to eq(gfm.strip) end + aggregate_failures('an accidentally selected other element') do + gfm = 'Test comment with **Markdown!**' + + html = <<-HTML.strip_heredoc +
  • +
    +

    + Test comment with Markdown! +

    +
    +
  • + +
  • + HTML + + output_gfm = html_to_gfm(html) + expect(output_gfm.strip).to eq(gfm.strip) + end + verify( 'InlineDiffFilter', -- cgit v1.2.1 From 3713a57fe8c40bfccaa668d081caccb92354b1da Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Tue, 23 May 2017 14:09:19 +0200 Subject: add rss_token attribute to user model --- spec/models/user_spec.rb | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'spec') diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 6a15830a15c..c395469f699 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -440,6 +440,13 @@ describe User, models: true do end end + describe 'rss token' do + it 'has rss token' do + user = create(:user) + expect(user.rss_token).not_to be_blank + end + end + describe '#recently_sent_password_reset?' do it 'is false when reset_password_sent_at is nil' do user = build_stubbed(:user, reset_password_sent_at: nil) -- cgit v1.2.1 From ff8ecbca17234897b26ea8de5caecaef1667d12d Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Tue, 23 May 2017 14:09:45 +0200 Subject: rake task to reset all rss tokens --- spec/tasks/tokens_spec.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'spec') diff --git a/spec/tasks/tokens_spec.rb b/spec/tasks/tokens_spec.rb index 19036c7677c..b84137eb365 100644 --- a/spec/tasks/tokens_spec.rb +++ b/spec/tasks/tokens_spec.rb @@ -18,4 +18,10 @@ describe 'tokens rake tasks' do expect { run_rake_task('tokens:reset_all_email') }.to change { user.reload.incoming_email_token } end end + + describe 'reset_all_rss task' do + it 'invokes create_hooks task' do + expect { run_rake_task('tokens:reset_all_rss') }.to change { user.reload.rss_token } + end + end end -- cgit v1.2.1 From c1b5c8069e18f76313925d7a7a267cb203d51f9d Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Tue, 23 May 2017 14:11:24 +0200 Subject: add missing spec for incoming email token presence --- spec/models/user_spec.rb | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'spec') diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index c395469f699..ca2b872729f 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -440,6 +440,13 @@ describe User, models: true do end end + describe 'ensure incoming email token' do + it 'has incoming email token' do + user = create(:user) + expect(user.incoming_email_token).not_to be_blank + end + end + describe 'rss token' do it 'has rss token' do user = create(:user) -- cgit v1.2.1 From 6efe9c2f14a5d9d324931ae9e86f9d4e3356f256 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Tue, 23 May 2017 15:59:33 +0200 Subject: atom links with rss token instead of private token --- spec/controllers/application_controller_spec.rb | 36 ++++++++++++++++++++++ spec/features/atom/dashboard_issues_spec.rb | 15 ++++++--- spec/features/atom/dashboard_spec.rb | 9 +++++- spec/features/atom/issues_spec.rb | 23 +++++++++++--- spec/features/atom/users_spec.rb | 9 +++++- spec/features/dashboard/activity_spec.rb | 6 ++-- spec/features/dashboard/issues_spec.rb | 4 +-- spec/features/dashboard/projects_spec.rb | 2 +- spec/features/dashboard_issues_spec.rb | 4 +-- spec/features/groups/activity_spec.rb | 8 ++--- spec/features/groups/issues_spec.rb | 8 ++--- spec/features/groups/show_spec.rb | 4 +-- .../issues/filtered_search/filter_issues_spec.rb | 8 ++--- spec/features/projects/activity/rss_spec.rb | 4 +-- spec/features/projects/commit/rss_spec.rb | 8 ++--- spec/features/projects/issues/rss_spec.rb | 8 ++--- spec/features/projects/main/rss_spec.rb | 4 +-- spec/features/projects/tree/rss_spec.rb | 4 +-- spec/features/users/rss_spec.rb | 4 +-- spec/helpers/rss_helper_spec.rb | 8 ++--- spec/support/features/rss_shared_examples.rb | 24 +++++++-------- 21 files changed, 136 insertions(+), 64 deletions(-) (limited to 'spec') diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index d40aae04fc3..57ab43969ef 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -99,6 +99,42 @@ describe ApplicationController do end end + describe '#authenticate_user_from_rss_token' do + describe "authenticating a user from an rss token" do + controller(described_class) do + def index + render text: 'authenticated' + end + end + + context "when the 'rss_token' param is populated with the rss token" do + context 'when the request format is atom' do + it "logs the user in" do + get :index, rss_token: user.rss_token, format: :atom + expect(response).to have_http_status 200 + expect(response.body).to eq 'authenticated' + end + end + + context 'when the request format is not atom' do + it "doesn't log the user in" do + get :index, rss_token: user.rss_token + expect(response.status).not_to have_http_status 200 + expect(response.body).not_to eq 'authenticated' + end + end + end + + context "when the 'rss_token' param is populated with an invalid rss token" do + it "doesn't log the user" do + get :index, rss_token: "token" + expect(response.status).not_to eq 200 + expect(response.body).not_to eq 'authenticated' + end + end + end + end + describe '#route_not_found' do it 'renders 404 if authenticated' do allow(controller).to receive(:current_user).and_return(user) diff --git a/spec/features/atom/dashboard_issues_spec.rb b/spec/features/atom/dashboard_issues_spec.rb index 9ea325ab41b..10511c602f5 100644 --- a/spec/features/atom/dashboard_issues_spec.rb +++ b/spec/features/atom/dashboard_issues_spec.rb @@ -20,13 +20,20 @@ describe "Dashboard Issues Feed", feature: true do expect(body).to have_selector('title', text: "#{user.name} issues") end + it "renders atom feed via rss token" do + visit issues_dashboard_path(:atom, rss_token: user.rss_token) + + expect(response_headers['Content-Type']).to have_content('application/atom+xml') + expect(body).to have_selector('title', text: "#{user.name} issues") + end + it "renders atom feed with url parameters" do - visit issues_dashboard_path(:atom, private_token: user.private_token, state: 'opened', assignee_id: user.id) + visit issues_dashboard_path(:atom, rss_token: user.rss_token, state: 'opened', assignee_id: user.id) link = find('link[type="application/atom+xml"]') params = CGI.parse(URI.parse(link[:href]).query) - expect(params).to include('private_token' => [user.private_token]) + expect(params).to include('rss_token' => [user.rss_token]) expect(params).to include('state' => ['opened']) expect(params).to include('assignee_id' => [user.id.to_s]) end @@ -35,7 +42,7 @@ describe "Dashboard Issues Feed", feature: true do let!(:issue2) { create(:issue, author: user, assignees: [assignee], project: project2, description: 'test desc') } it "renders issue fields" do - visit issues_dashboard_path(:atom, private_token: user.private_token) + visit issues_dashboard_path(:atom, rss_token: user.rss_token) entry = find(:xpath, "//feed/entry[contains(summary/text(),'#{issue2.title}')]") @@ -58,7 +65,7 @@ describe "Dashboard Issues Feed", feature: true do end it "renders issue label and milestone info" do - visit issues_dashboard_path(:atom, private_token: user.private_token) + visit issues_dashboard_path(:atom, rss_token: user.rss_token) entry = find(:xpath, "//feed/entry[contains(summary/text(),'#{issue1.title}')]") diff --git a/spec/features/atom/dashboard_spec.rb b/spec/features/atom/dashboard_spec.rb index 746df36bb25..af9036ba10d 100644 --- a/spec/features/atom/dashboard_spec.rb +++ b/spec/features/atom/dashboard_spec.rb @@ -11,6 +11,13 @@ describe "Dashboard Feed", feature: true do end end + context "projects atom feed via rss token" do + it "renders projects atom feed" do + visit dashboard_projects_path(:atom, rss_token: user.rss_token) + expect(body).to have_selector('feed title') + end + end + context 'feed content' do let(:project) { create(:project) } let(:issue) { create(:issue, project: project, author: user, description: '') } @@ -20,7 +27,7 @@ describe "Dashboard Feed", feature: true do project.team << [user, :master] issue_event(issue, user) note_event(note, user) - visit dashboard_projects_path(:atom, private_token: user.private_token) + visit dashboard_projects_path(:atom, rss_token: user.rss_token) end it "has issue opened event" do diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb index 4f6754ad541..c0ebd3e4a7d 100644 --- a/spec/features/atom/issues_spec.rb +++ b/spec/features/atom/issues_spec.rb @@ -43,25 +43,40 @@ describe 'Issues Feed', feature: true do end end + context 'when authenticated via rss token' do + it 'renders atom feed' do + visit namespace_project_issues_path(project.namespace, project, :atom, + rss_token: user.rss_token) + + expect(response_headers['Content-Type']). + to have_content('application/atom+xml') + expect(body).to have_selector('title', text: "#{project.name} issues") + expect(body).to have_selector('author email', text: issue.author_public_email) + expect(body).to have_selector('assignees assignee email', text: issue.assignees.first.public_email) + expect(body).to have_selector('assignee email', text: issue.assignees.first.public_email) + expect(body).to have_selector('entry summary', text: issue.title) + end + end + it "renders atom feed with url parameters for project issues" do visit namespace_project_issues_path(project.namespace, project, - :atom, private_token: user.private_token, state: 'opened', assignee_id: user.id) + :atom, rss_token: user.rss_token, state: 'opened', assignee_id: user.id) link = find('link[type="application/atom+xml"]') params = CGI.parse(URI.parse(link[:href]).query) - expect(params).to include('private_token' => [user.private_token]) + expect(params).to include('rss_token' => [user.rss_token]) expect(params).to include('state' => ['opened']) expect(params).to include('assignee_id' => [user.id.to_s]) end it "renders atom feed with url parameters for group issues" do - visit issues_group_path(group, :atom, private_token: user.private_token, state: 'opened', assignee_id: user.id) + visit issues_group_path(group, :atom, rss_token: user.rss_token, state: 'opened', assignee_id: user.id) link = find('link[type="application/atom+xml"]') params = CGI.parse(URI.parse(link[:href]).query) - expect(params).to include('private_token' => [user.private_token]) + expect(params).to include('rss_token' => [user.rss_token]) expect(params).to include('state' => ['opened']) expect(params).to include('assignee_id' => [user.id.to_s]) end diff --git a/spec/features/atom/users_spec.rb b/spec/features/atom/users_spec.rb index 7a2987e815d..a4a40535aee 100644 --- a/spec/features/atom/users_spec.rb +++ b/spec/features/atom/users_spec.rb @@ -11,6 +11,13 @@ describe "User Feed", feature: true do end end + context 'user atom feed via rss token' do + it "renders user atom feed" do + visit user_path(user, :atom, rss_token: user.rss_token) + expect(body).to have_selector('feed title') + end + end + context 'feed content' do let(:project) { create(:project) } let(:issue) do @@ -40,7 +47,7 @@ describe "User Feed", feature: true do issue_event(issue, user) note_event(note, user) merge_request_event(merge_request, user) - visit user_path(user, :atom, private_token: user.private_token) + visit user_path(user, :atom, rss_token: user.rss_token) end it 'has issue opened event' do diff --git a/spec/features/dashboard/activity_spec.rb b/spec/features/dashboard/activity_spec.rb index c977f266296..6411ab1bf2a 100644 --- a/spec/features/dashboard/activity_spec.rb +++ b/spec/features/dashboard/activity_spec.rb @@ -5,7 +5,7 @@ RSpec.describe 'Dashboard Activity', feature: true do login_as(create :user) visit activity_dashboard_path end - - it_behaves_like "it has an RSS button with current_user's private token" - it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + + it_behaves_like "it has an RSS button with current_user's rss token" + it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" end diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb index 7a132dba1e9..30a2180a9e8 100644 --- a/spec/features/dashboard/issues_spec.rb +++ b/spec/features/dashboard/issues_spec.rb @@ -62,6 +62,6 @@ RSpec.describe 'Dashboard Issues', feature: true do expect(page).to have_content(other_issue.title) end - it_behaves_like "it has an RSS button with current_user's private token" - it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + it_behaves_like "it has an RSS button with current_user's rss token" + it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" end diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index f1789fc9d43..fb8e3ac0a04 100644 --- a/spec/features/dashboard/projects_spec.rb +++ b/spec/features/dashboard/projects_spec.rb @@ -31,5 +31,5 @@ RSpec.describe 'Dashboard Projects', feature: true do end end - it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" end diff --git a/spec/features/dashboard_issues_spec.rb b/spec/features/dashboard_issues_spec.rb index ad60fb2c74f..1c53f6dff06 100644 --- a/spec/features/dashboard_issues_spec.rb +++ b/spec/features/dashboard_issues_spec.rb @@ -53,10 +53,10 @@ describe "Dashboard Issues filtering", feature: true, js: true do auto_discovery_link = find('link[type="application/atom+xml"]', visible: false) auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query) - expect(params).to include('private_token' => [user.private_token]) + expect(params).to include('rss_token' => [user.rss_token]) expect(params).to include('milestone_title' => ['']) expect(params).to include('assignee_id' => [user.id.to_s]) - expect(auto_discovery_params).to include('private_token' => [user.private_token]) + expect(auto_discovery_params).to include('rss_token' => [user.rss_token]) expect(auto_discovery_params).to include('milestone_title' => ['']) expect(auto_discovery_params).to include('assignee_id' => [user.id.to_s]) end diff --git a/spec/features/groups/activity_spec.rb b/spec/features/groups/activity_spec.rb index 3b481cba424..6b46d431cf2 100644 --- a/spec/features/groups/activity_spec.rb +++ b/spec/features/groups/activity_spec.rb @@ -11,8 +11,8 @@ feature 'Group activity page', feature: true do visit path end - it_behaves_like "it has an RSS button with current_user's private token" - it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + it_behaves_like "it has an RSS button with current_user's rss token" + it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" end context 'when signed out' do @@ -20,7 +20,7 @@ feature 'Group activity page', feature: true do visit path end - it_behaves_like "it has an RSS button without a private token" - it_behaves_like "an autodiscoverable RSS feed without a private token" + it_behaves_like "it has an RSS button without an rss token" + it_behaves_like "an autodiscoverable RSS feed without an rss token" end end diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb index aa2e9632d6c..d333e031996 100644 --- a/spec/features/groups/issues_spec.rb +++ b/spec/features/groups/issues_spec.rb @@ -12,15 +12,15 @@ feature 'Group issues page', feature: true do context 'when signed in' do let(:user) { user_in_group } - it_behaves_like "it has an RSS button with current_user's private token" - it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + it_behaves_like "it has an RSS button with current_user's rss token" + it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" end context 'when signed out' do let(:user) { nil } - it_behaves_like "it has an RSS button without a private token" - it_behaves_like "an autodiscoverable RSS feed without a private token" + it_behaves_like "it has an RSS button without an rss token" + it_behaves_like "an autodiscoverable RSS feed without an rss token" end end diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb index fb39693e8ca..2d5b2d004d7 100644 --- a/spec/features/groups/show_spec.rb +++ b/spec/features/groups/show_spec.rb @@ -11,7 +11,7 @@ feature 'Group show page', feature: true do visit path end - it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" end context 'when signed out' do @@ -19,6 +19,6 @@ feature 'Group show page', feature: true do visit path end - it_behaves_like "an autodiscoverable RSS feed without a private token" + it_behaves_like "an autodiscoverable RSS feed without an rss token" end end diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb index 03ff1cffb3f..7958ad7e24f 100644 --- a/spec/features/issues/filtered_search/filter_issues_spec.rb +++ b/spec/features/issues/filtered_search/filter_issues_spec.rb @@ -810,10 +810,10 @@ describe 'Filter issues', js: true, feature: true do auto_discovery_link = find('link[type="application/atom+xml"]', visible: false) auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query) - expect(params).to include('private_token' => [user.private_token]) + expect(params).to include('rss_token' => [user.rss_token]) expect(params).to include('milestone_title' => [milestone.title]) expect(params).to include('assignee_id' => [user.id.to_s]) - expect(auto_discovery_params).to include('private_token' => [user.private_token]) + expect(auto_discovery_params).to include('rss_token' => [user.rss_token]) expect(auto_discovery_params).to include('milestone_title' => [milestone.title]) expect(auto_discovery_params).to include('assignee_id' => [user.id.to_s]) end @@ -825,10 +825,10 @@ describe 'Filter issues', js: true, feature: true do auto_discovery_link = find('link[type="application/atom+xml"]', visible: false) auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query) - expect(params).to include('private_token' => [user.private_token]) + expect(params).to include('rss_token' => [user.rss_token]) expect(params).to include('milestone_title' => [milestone.title]) expect(params).to include('assignee_id' => [user.id.to_s]) - expect(auto_discovery_params).to include('private_token' => [user.private_token]) + expect(auto_discovery_params).to include('rss_token' => [user.rss_token]) expect(auto_discovery_params).to include('milestone_title' => [milestone.title]) expect(auto_discovery_params).to include('assignee_id' => [user.id.to_s]) end diff --git a/spec/features/projects/activity/rss_spec.rb b/spec/features/projects/activity/rss_spec.rb index b47c6d431eb..769ce1a8c43 100644 --- a/spec/features/projects/activity/rss_spec.rb +++ b/spec/features/projects/activity/rss_spec.rb @@ -16,7 +16,7 @@ feature 'Project Activity RSS' do visit path end - it_behaves_like "it has an RSS button with current_user's private token" + it_behaves_like "it has an RSS button with current_user's rss token" end context 'when signed out' do @@ -24,6 +24,6 @@ feature 'Project Activity RSS' do visit path end - it_behaves_like "it has an RSS button without a private token" + it_behaves_like "it has an RSS button without an rss token" end end diff --git a/spec/features/projects/commit/rss_spec.rb b/spec/features/projects/commit/rss_spec.rb index 6e0e1916f87..b9522e806df 100644 --- a/spec/features/projects/commit/rss_spec.rb +++ b/spec/features/projects/commit/rss_spec.rb @@ -12,8 +12,8 @@ feature 'Project Commits RSS' do visit path end - it_behaves_like "it has an RSS button with current_user's private token" - it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + it_behaves_like "it has an RSS button with current_user's rss token" + it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" end context 'when signed out' do @@ -21,7 +21,7 @@ feature 'Project Commits RSS' do visit path end - it_behaves_like "it has an RSS button without a private token" - it_behaves_like "an autodiscoverable RSS feed without a private token" + it_behaves_like "it has an RSS button without an rss token" + it_behaves_like "an autodiscoverable RSS feed without an rss token" end end diff --git a/spec/features/projects/issues/rss_spec.rb b/spec/features/projects/issues/rss_spec.rb index 71429f00095..5c06f2b74f2 100644 --- a/spec/features/projects/issues/rss_spec.rb +++ b/spec/features/projects/issues/rss_spec.rb @@ -16,8 +16,8 @@ feature 'Project Issues RSS' do visit path end - it_behaves_like "it has an RSS button with current_user's private token" - it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + it_behaves_like "it has an RSS button with current_user's rss token" + it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" end context 'when signed out' do @@ -25,7 +25,7 @@ feature 'Project Issues RSS' do visit path end - it_behaves_like "it has an RSS button without a private token" - it_behaves_like "an autodiscoverable RSS feed without a private token" + it_behaves_like "it has an RSS button without an rss token" + it_behaves_like "an autodiscoverable RSS feed without an rss token" end end diff --git a/spec/features/projects/main/rss_spec.rb b/spec/features/projects/main/rss_spec.rb index b1a3af612a1..2de0eb1db09 100644 --- a/spec/features/projects/main/rss_spec.rb +++ b/spec/features/projects/main/rss_spec.rb @@ -12,7 +12,7 @@ feature 'Project RSS' do visit path end - it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" end context 'when signed out' do @@ -20,6 +20,6 @@ feature 'Project RSS' do visit path end - it_behaves_like "an autodiscoverable RSS feed without a private token" + it_behaves_like "an autodiscoverable RSS feed without an rss token" end end diff --git a/spec/features/projects/tree/rss_spec.rb b/spec/features/projects/tree/rss_spec.rb index 9ac51997d65..a697ab2c885 100644 --- a/spec/features/projects/tree/rss_spec.rb +++ b/spec/features/projects/tree/rss_spec.rb @@ -12,7 +12,7 @@ feature 'Project Tree RSS' do visit path end - it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" end context 'when signed out' do @@ -20,6 +20,6 @@ feature 'Project Tree RSS' do visit path end - it_behaves_like "an autodiscoverable RSS feed without a private token" + it_behaves_like "an autodiscoverable RSS feed without an rss token" end end diff --git a/spec/features/users/rss_spec.rb b/spec/features/users/rss_spec.rb index 14564abb16d..8eaf34734fe 100644 --- a/spec/features/users/rss_spec.rb +++ b/spec/features/users/rss_spec.rb @@ -9,7 +9,7 @@ feature 'User RSS' do visit path end - it_behaves_like "it has an RSS button with current_user's private token" + it_behaves_like "it has an RSS button with current_user's rss token" end context 'when signed out' do @@ -17,6 +17,6 @@ feature 'User RSS' do visit path end - it_behaves_like "it has an RSS button without a private token" + it_behaves_like "it has an RSS button without an rss token" end end diff --git a/spec/helpers/rss_helper_spec.rb b/spec/helpers/rss_helper_spec.rb index f3f174f3d14..269e1057e8d 100644 --- a/spec/helpers/rss_helper_spec.rb +++ b/spec/helpers/rss_helper_spec.rb @@ -3,17 +3,17 @@ require 'spec_helper' describe RssHelper do describe '#rss_url_options' do context 'when signed in' do - it "includes the current_user's private_token" do + it "includes the current_user's rss_token" do current_user = create(:user) allow(helper).to receive(:current_user).and_return(current_user) - expect(helper.rss_url_options).to include private_token: current_user.private_token + expect(helper.rss_url_options).to include rss_token: current_user.rss_token end end context 'when signed out' do - it "does not have a private_token" do + it "does not have an rss_token" do allow(helper).to receive(:current_user).and_return(nil) - expect(helper.rss_url_options[:private_token]).to be_nil + expect(helper.rss_url_options[:rss_token]).to be_nil end end end diff --git a/spec/support/features/rss_shared_examples.rb b/spec/support/features/rss_shared_examples.rb index 9a3b0a731ad..e33dd575072 100644 --- a/spec/support/features/rss_shared_examples.rb +++ b/spec/support/features/rss_shared_examples.rb @@ -1,23 +1,23 @@ -shared_examples "an autodiscoverable RSS feed with current_user's private token" do - it "has an RSS autodiscovery link tag with current_user's private token" do - expect(page).to have_css("link[type*='atom+xml'][href*='private_token=#{Thread.current[:current_user].private_token}']", visible: false) +shared_examples "an autodiscoverable RSS feed with current_user's rss token" do + it "has an RSS autodiscovery link tag with current_user's rss token" do + expect(page).to have_css("link[type*='atom+xml'][href*='rss_token=#{Thread.current[:current_user].rss_token}']", visible: false) end end -shared_examples "it has an RSS button with current_user's private token" do - it "shows the RSS button with current_user's private token" do - expect(page).to have_css("a:has(.fa-rss)[href*='private_token=#{Thread.current[:current_user].private_token}']") +shared_examples "it has an RSS button with current_user's rss token" do + it "shows the RSS button with current_user's rss token" do + expect(page).to have_css("a:has(.fa-rss)[href*='rss_token=#{Thread.current[:current_user].rss_token}']") end end -shared_examples "an autodiscoverable RSS feed without a private token" do - it "has an RSS autodiscovery link tag without a private token" do - expect(page).to have_css("link[type*='atom+xml']:not([href*='private_token'])", visible: false) +shared_examples "an autodiscoverable RSS feed without an rss token" do + it "has an RSS autodiscovery link tag without an rss token" do + expect(page).to have_css("link[type*='atom+xml']:not([href*='rss_token'])", visible: false) end end -shared_examples "it has an RSS button without a private token" do - it "shows the RSS button without a private token" do - expect(page).to have_css("a:has(.fa-rss):not([href*='private_token'])") +shared_examples "it has an RSS button without an rss token" do + it "shows the RSS button without an rss token" do + expect(page).to have_css("a:has(.fa-rss):not([href*='rss_token'])") end end -- cgit v1.2.1 From dfc2542f55953815f703d743635d6faf2523d1a1 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Tue, 23 May 2017 22:20:53 +0200 Subject: use full caps RSS instead of rss --- spec/controllers/application_controller_spec.rb | 6 +++--- spec/features/atom/dashboard_issues_spec.rb | 2 +- spec/features/atom/dashboard_spec.rb | 2 +- spec/features/atom/issues_spec.rb | 2 +- spec/features/atom/users_spec.rb | 2 +- spec/features/dashboard/activity_spec.rb | 4 ++-- spec/features/dashboard/issues_spec.rb | 4 ++-- spec/features/dashboard/projects_spec.rb | 2 +- spec/features/groups/activity_spec.rb | 8 ++++---- spec/features/groups/issues_spec.rb | 8 ++++---- spec/features/groups/show_spec.rb | 4 ++-- spec/features/projects/activity/rss_spec.rb | 4 ++-- spec/features/projects/commit/rss_spec.rb | 8 ++++---- spec/features/projects/issues/rss_spec.rb | 8 ++++---- spec/features/projects/main/rss_spec.rb | 4 ++-- spec/features/projects/tree/rss_spec.rb | 4 ++-- spec/features/users/rss_spec.rb | 4 ++-- spec/support/features/rss_shared_examples.rb | 16 ++++++++-------- 18 files changed, 46 insertions(+), 46 deletions(-) (limited to 'spec') diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 57ab43969ef..3f99e2ff596 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -100,14 +100,14 @@ describe ApplicationController do end describe '#authenticate_user_from_rss_token' do - describe "authenticating a user from an rss token" do + describe "authenticating a user from an RSS token" do controller(described_class) do def index render text: 'authenticated' end end - context "when the 'rss_token' param is populated with the rss token" do + context "when the 'rss_token' param is populated with the RSS token" do context 'when the request format is atom' do it "logs the user in" do get :index, rss_token: user.rss_token, format: :atom @@ -125,7 +125,7 @@ describe ApplicationController do end end - context "when the 'rss_token' param is populated with an invalid rss token" do + context "when the 'rss_token' param is populated with an invalid RSS token" do it "doesn't log the user" do get :index, rss_token: "token" expect(response.status).not_to eq 200 diff --git a/spec/features/atom/dashboard_issues_spec.rb b/spec/features/atom/dashboard_issues_spec.rb index 10511c602f5..711c8a710f3 100644 --- a/spec/features/atom/dashboard_issues_spec.rb +++ b/spec/features/atom/dashboard_issues_spec.rb @@ -20,7 +20,7 @@ describe "Dashboard Issues Feed", feature: true do expect(body).to have_selector('title', text: "#{user.name} issues") end - it "renders atom feed via rss token" do + it "renders atom feed via RSS token" do visit issues_dashboard_path(:atom, rss_token: user.rss_token) expect(response_headers['Content-Type']).to have_content('application/atom+xml') diff --git a/spec/features/atom/dashboard_spec.rb b/spec/features/atom/dashboard_spec.rb index af9036ba10d..1df058b023c 100644 --- a/spec/features/atom/dashboard_spec.rb +++ b/spec/features/atom/dashboard_spec.rb @@ -11,7 +11,7 @@ describe "Dashboard Feed", feature: true do end end - context "projects atom feed via rss token" do + context "projects atom feed via RSS token" do it "renders projects atom feed" do visit dashboard_projects_path(:atom, rss_token: user.rss_token) expect(body).to have_selector('feed title') diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb index c0ebd3e4a7d..a61231ea254 100644 --- a/spec/features/atom/issues_spec.rb +++ b/spec/features/atom/issues_spec.rb @@ -43,7 +43,7 @@ describe 'Issues Feed', feature: true do end end - context 'when authenticated via rss token' do + context 'when authenticated via RSS token' do it 'renders atom feed' do visit namespace_project_issues_path(project.namespace, project, :atom, rss_token: user.rss_token) diff --git a/spec/features/atom/users_spec.rb b/spec/features/atom/users_spec.rb index a4a40535aee..fae5aaa52bd 100644 --- a/spec/features/atom/users_spec.rb +++ b/spec/features/atom/users_spec.rb @@ -11,7 +11,7 @@ describe "User Feed", feature: true do end end - context 'user atom feed via rss token' do + context 'user atom feed via RSS token' do it "renders user atom feed" do visit user_path(user, :atom, rss_token: user.rss_token) expect(body).to have_selector('feed title') diff --git a/spec/features/dashboard/activity_spec.rb b/spec/features/dashboard/activity_spec.rb index 6411ab1bf2a..0764044260e 100644 --- a/spec/features/dashboard/activity_spec.rb +++ b/spec/features/dashboard/activity_spec.rb @@ -6,6 +6,6 @@ RSpec.describe 'Dashboard Activity', feature: true do visit activity_dashboard_path end - it_behaves_like "it has an RSS button with current_user's rss token" - it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" + it_behaves_like "it has an RSS button with current_user's RSS token" + it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token" end diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb index 30a2180a9e8..2346a9ec2ed 100644 --- a/spec/features/dashboard/issues_spec.rb +++ b/spec/features/dashboard/issues_spec.rb @@ -62,6 +62,6 @@ RSpec.describe 'Dashboard Issues', feature: true do expect(page).to have_content(other_issue.title) end - it_behaves_like "it has an RSS button with current_user's rss token" - it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" + it_behaves_like "it has an RSS button with current_user's RSS token" + it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token" end diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index fb8e3ac0a04..01351548a99 100644 --- a/spec/features/dashboard/projects_spec.rb +++ b/spec/features/dashboard/projects_spec.rb @@ -31,5 +31,5 @@ RSpec.describe 'Dashboard Projects', feature: true do end end - it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" + it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token" end diff --git a/spec/features/groups/activity_spec.rb b/spec/features/groups/activity_spec.rb index 6b46d431cf2..81f9c103e95 100644 --- a/spec/features/groups/activity_spec.rb +++ b/spec/features/groups/activity_spec.rb @@ -11,8 +11,8 @@ feature 'Group activity page', feature: true do visit path end - it_behaves_like "it has an RSS button with current_user's rss token" - it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" + it_behaves_like "it has an RSS button with current_user's RSS token" + it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token" end context 'when signed out' do @@ -20,7 +20,7 @@ feature 'Group activity page', feature: true do visit path end - it_behaves_like "it has an RSS button without an rss token" - it_behaves_like "an autodiscoverable RSS feed without an rss token" + it_behaves_like "it has an RSS button without an RSS token" + it_behaves_like "an autodiscoverable RSS feed without an RSS token" end end diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb index d333e031996..d6b88542ef7 100644 --- a/spec/features/groups/issues_spec.rb +++ b/spec/features/groups/issues_spec.rb @@ -12,15 +12,15 @@ feature 'Group issues page', feature: true do context 'when signed in' do let(:user) { user_in_group } - it_behaves_like "it has an RSS button with current_user's rss token" - it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" + it_behaves_like "it has an RSS button with current_user's RSS token" + it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token" end context 'when signed out' do let(:user) { nil } - it_behaves_like "it has an RSS button without an rss token" - it_behaves_like "an autodiscoverable RSS feed without an rss token" + it_behaves_like "it has an RSS button without an RSS token" + it_behaves_like "an autodiscoverable RSS feed without an RSS token" end end diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb index 2d5b2d004d7..d3c49c37374 100644 --- a/spec/features/groups/show_spec.rb +++ b/spec/features/groups/show_spec.rb @@ -11,7 +11,7 @@ feature 'Group show page', feature: true do visit path end - it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" + it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token" end context 'when signed out' do @@ -19,6 +19,6 @@ feature 'Group show page', feature: true do visit path end - it_behaves_like "an autodiscoverable RSS feed without an rss token" + it_behaves_like "an autodiscoverable RSS feed without an RSS token" end end diff --git a/spec/features/projects/activity/rss_spec.rb b/spec/features/projects/activity/rss_spec.rb index 769ce1a8c43..3c1de5c09b2 100644 --- a/spec/features/projects/activity/rss_spec.rb +++ b/spec/features/projects/activity/rss_spec.rb @@ -16,7 +16,7 @@ feature 'Project Activity RSS' do visit path end - it_behaves_like "it has an RSS button with current_user's rss token" + it_behaves_like "it has an RSS button with current_user's RSS token" end context 'when signed out' do @@ -24,6 +24,6 @@ feature 'Project Activity RSS' do visit path end - it_behaves_like "it has an RSS button without an rss token" + it_behaves_like "it has an RSS button without an RSS token" end end diff --git a/spec/features/projects/commit/rss_spec.rb b/spec/features/projects/commit/rss_spec.rb index b9522e806df..03b6d560c96 100644 --- a/spec/features/projects/commit/rss_spec.rb +++ b/spec/features/projects/commit/rss_spec.rb @@ -12,8 +12,8 @@ feature 'Project Commits RSS' do visit path end - it_behaves_like "it has an RSS button with current_user's rss token" - it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" + it_behaves_like "it has an RSS button with current_user's RSS token" + it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token" end context 'when signed out' do @@ -21,7 +21,7 @@ feature 'Project Commits RSS' do visit path end - it_behaves_like "it has an RSS button without an rss token" - it_behaves_like "an autodiscoverable RSS feed without an rss token" + it_behaves_like "it has an RSS button without an RSS token" + it_behaves_like "an autodiscoverable RSS feed without an RSS token" end end diff --git a/spec/features/projects/issues/rss_spec.rb b/spec/features/projects/issues/rss_spec.rb index 5c06f2b74f2..f6852192aef 100644 --- a/spec/features/projects/issues/rss_spec.rb +++ b/spec/features/projects/issues/rss_spec.rb @@ -16,8 +16,8 @@ feature 'Project Issues RSS' do visit path end - it_behaves_like "it has an RSS button with current_user's rss token" - it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" + it_behaves_like "it has an RSS button with current_user's RSS token" + it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token" end context 'when signed out' do @@ -25,7 +25,7 @@ feature 'Project Issues RSS' do visit path end - it_behaves_like "it has an RSS button without an rss token" - it_behaves_like "an autodiscoverable RSS feed without an rss token" + it_behaves_like "it has an RSS button without an RSS token" + it_behaves_like "an autodiscoverable RSS feed without an RSS token" end end diff --git a/spec/features/projects/main/rss_spec.rb b/spec/features/projects/main/rss_spec.rb index 2de0eb1db09..53966229a2a 100644 --- a/spec/features/projects/main/rss_spec.rb +++ b/spec/features/projects/main/rss_spec.rb @@ -12,7 +12,7 @@ feature 'Project RSS' do visit path end - it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" + it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token" end context 'when signed out' do @@ -20,6 +20,6 @@ feature 'Project RSS' do visit path end - it_behaves_like "an autodiscoverable RSS feed without an rss token" + it_behaves_like "an autodiscoverable RSS feed without an RSS token" end end diff --git a/spec/features/projects/tree/rss_spec.rb b/spec/features/projects/tree/rss_spec.rb index a697ab2c885..9bf59c4139c 100644 --- a/spec/features/projects/tree/rss_spec.rb +++ b/spec/features/projects/tree/rss_spec.rb @@ -12,7 +12,7 @@ feature 'Project Tree RSS' do visit path end - it_behaves_like "an autodiscoverable RSS feed with current_user's rss token" + it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token" end context 'when signed out' do @@ -20,6 +20,6 @@ feature 'Project Tree RSS' do visit path end - it_behaves_like "an autodiscoverable RSS feed without an rss token" + it_behaves_like "an autodiscoverable RSS feed without an RSS token" end end diff --git a/spec/features/users/rss_spec.rb b/spec/features/users/rss_spec.rb index 8eaf34734fe..dbd5f66b55e 100644 --- a/spec/features/users/rss_spec.rb +++ b/spec/features/users/rss_spec.rb @@ -9,7 +9,7 @@ feature 'User RSS' do visit path end - it_behaves_like "it has an RSS button with current_user's rss token" + it_behaves_like "it has an RSS button with current_user's RSS token" end context 'when signed out' do @@ -17,6 +17,6 @@ feature 'User RSS' do visit path end - it_behaves_like "it has an RSS button without an rss token" + it_behaves_like "it has an RSS button without an RSS token" end end diff --git a/spec/support/features/rss_shared_examples.rb b/spec/support/features/rss_shared_examples.rb index e33dd575072..1cbb4134995 100644 --- a/spec/support/features/rss_shared_examples.rb +++ b/spec/support/features/rss_shared_examples.rb @@ -1,23 +1,23 @@ -shared_examples "an autodiscoverable RSS feed with current_user's rss token" do - it "has an RSS autodiscovery link tag with current_user's rss token" do +shared_examples "an autodiscoverable RSS feed with current_user's RSS token" do + it "has an RSS autodiscovery link tag with current_user's RSS token" do expect(page).to have_css("link[type*='atom+xml'][href*='rss_token=#{Thread.current[:current_user].rss_token}']", visible: false) end end -shared_examples "it has an RSS button with current_user's rss token" do - it "shows the RSS button with current_user's rss token" do +shared_examples "it has an RSS button with current_user's RSS token" do + it "shows the RSS button with current_user's RSS token" do expect(page).to have_css("a:has(.fa-rss)[href*='rss_token=#{Thread.current[:current_user].rss_token}']") end end -shared_examples "an autodiscoverable RSS feed without an rss token" do - it "has an RSS autodiscovery link tag without an rss token" do +shared_examples "an autodiscoverable RSS feed without an RSS token" do + it "has an RSS autodiscovery link tag without an RSS token" do expect(page).to have_css("link[type*='atom+xml']:not([href*='rss_token'])", visible: false) end end -shared_examples "it has an RSS button without an rss token" do - it "shows the RSS button without an rss token" do +shared_examples "it has an RSS button without an RSS token" do + it "shows the RSS button without an RSS token" do expect(page).to have_css("a:has(.fa-rss):not([href*='rss_token'])") end end -- cgit v1.2.1 From 2f277d10ac574fbe6b19d22799bd32daf49de56b Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Tue, 23 May 2017 22:47:05 +0200 Subject: ensure rss token on read we do this on attribute read since migrating all existing users is not a feasible solution. --- spec/models/user_spec.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'spec') diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index ca2b872729f..aabdac4bb75 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -448,9 +448,11 @@ describe User, models: true do end describe 'rss token' do - it 'has rss token' do - user = create(:user) - expect(user.rss_token).not_to be_blank + it 'ensures an rss token on read' do + user = create(:user, rss_token: nil) + rss_token = user.rss_token + expect(rss_token).not_to be_blank + expect(user.reload.rss_token).to eq rss_token end end -- cgit v1.2.1 From 4cd6fc6e3b7198903900b39c0ff3d9dbae216b21 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Wed, 24 May 2017 09:10:45 +0200 Subject: create User#rss_token in user factory explicitely otherwise we'll have to use `user.reload` in the specs to get the current rss_token value. --- spec/factories/users.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'spec') diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 33fa80772ff..e60fe713bc3 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -8,6 +8,10 @@ FactoryGirl.define do confirmation_token { nil } can_create_group true + before(:create) do |user| + user.ensure_rss_token + end + trait :admin do admin true end -- cgit v1.2.1 From 6dc2ade49ccc45c29c3fe05d6ccc4811fd198aea Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Tue, 23 May 2017 17:02:05 +0200 Subject: user can reset his rss token on the account page --- spec/features/profile_spec.rb | 15 +++++++++++++++ spec/routing/routing_spec.rb | 4 ++++ 2 files changed, 19 insertions(+) (limited to 'spec') diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb index e63feb14b7e..7df628fd7a0 100644 --- a/spec/features/profile_spec.rb +++ b/spec/features/profile_spec.rb @@ -47,6 +47,21 @@ describe 'Profile account page', feature: true do end end + describe 'when I reset RSS token' do + before do + visit profile_account_path + end + + it 'resets RSS token' do + previous_token = find("#rss-token").value + + click_link('Reset RSS token') + + expect(page).to have_content 'RSS token was successfully reset' + expect(find('#rss-token').value).not_to eq(previous_token) + end + end + describe 'when I reset incoming email token' do before do allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true) diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb index abacc50a371..a62af13cf0c 100644 --- a/spec/routing/routing_spec.rb +++ b/spec/routing/routing_spec.rb @@ -151,6 +151,10 @@ describe ProfilesController, "routing" do expect(put("/profile/reset_private_token")).to route_to('profiles#reset_private_token') end + it "to #reset_rss_token" do + expect(put("/profile/reset_rss_token")).to route_to('profiles#reset_rss_token') + end + it "to #show" do expect(get("/profile")).to route_to('profiles#show') end -- cgit v1.2.1 From 710e35378a55d1ff0cdb164f844a9e152c04b3df Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Thu, 25 May 2017 07:12:36 +0000 Subject: Use non-global jQuery reference within raven bundle --- spec/javascripts/raven/raven_config_spec.js | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/raven/raven_config_spec.js b/spec/javascripts/raven/raven_config_spec.js index b31a7c28ebe..c82658b9262 100644 --- a/spec/javascripts/raven/raven_config_spec.js +++ b/spec/javascripts/raven/raven_config_spec.js @@ -140,24 +140,6 @@ describe('RavenConfig', () => { }); }); - describe('bindRavenErrors', () => { - let $document; - let $; - - beforeEach(() => { - $document = jasmine.createSpyObj('$document', ['on']); - $ = jasmine.createSpy('$').and.returnValue($document); - - window.$ = $; - - RavenConfig.bindRavenErrors(); - }); - - it('should call .on', function () { - expect($document.on).toHaveBeenCalledWith('ajaxError.raven', RavenConfig.handleRavenErrors); - }); - }); - describe('handleRavenErrors', () => { let event; let req; -- cgit v1.2.1 From 4497ca87c488806e5df313a23f187242716727e3 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Sun, 21 May 2017 12:53:35 +0000 Subject: Fix transient error clicking dropdown items in compare_spec.rb --- spec/features/projects/compare_spec.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/features/projects/compare_spec.rb b/spec/features/projects/compare_spec.rb index 294a63a5c6d..a8e00d434e8 100644 --- a/spec/features/projects/compare_spec.rb +++ b/spec/features/projects/compare_spec.rb @@ -52,8 +52,10 @@ describe "Compare", js: true do def select_using_dropdown(dropdown_type, selection) dropdown = find(".js-compare-#{dropdown_type}-dropdown") dropdown.find(".compare-dropdown-toggle").click + dropdown.find('.dropdown-menu') dropdown.fill_in("Filter by Git revision", with: selection) wait_for_requests - dropdown.find_all("a[data-ref=\"#{selection}\"]", visible: true).last.click + dropdown.find("a[data-ref=\"#{selection}\"]", match: :first) + dropdown.all("a[data-ref=\"#{selection}\"]").last.click end end -- cgit v1.2.1 From d3655fe56f42e7d1821d783b274154a6f69c59c5 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Wed, 24 May 2017 08:47:25 +0000 Subject: Add review comments to compare_spec.rb --- spec/features/projects/compare_spec.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'spec') diff --git a/spec/features/projects/compare_spec.rb b/spec/features/projects/compare_spec.rb index a8e00d434e8..4162f2579d1 100644 --- a/spec/features/projects/compare_spec.rb +++ b/spec/features/projects/compare_spec.rb @@ -52,9 +52,11 @@ describe "Compare", js: true do def select_using_dropdown(dropdown_type, selection) dropdown = find(".js-compare-#{dropdown_type}-dropdown") dropdown.find(".compare-dropdown-toggle").click + # find input before using to wait for the inputs visiblity dropdown.find('.dropdown-menu') dropdown.fill_in("Filter by Git revision", with: selection) wait_for_requests + # find before all to wait for the items visiblity dropdown.find("a[data-ref=\"#{selection}\"]", match: :first) dropdown.all("a[data-ref=\"#{selection}\"]").last.click end -- cgit v1.2.1