diff options
author | Z.J. van de Weg <git@zjvandeweg.nl> | 2017-05-25 13:57:22 +0200 |
---|---|---|
committer | Z.J. van de Weg <git@zjvandeweg.nl> | 2017-05-25 13:57:22 +0200 |
commit | 7ec89692858a207691489aed566af7785a923895 (patch) | |
tree | dfad4c6ea77f322b68db974102c5ec54fe0366f6 /spec | |
parent | 2f62af684e127010cffd81e027f469dcde3bc9b2 (diff) | |
parent | 78de1c059ac588df4ba1ef352b28e5b1c6102804 (diff) | |
download | gitlab-ce-7ec89692858a207691489aed566af7785a923895.tar.gz |
Merge branch 'master' into zj-realtime-env-list
Diffstat (limited to 'spec')
181 files changed, 2162 insertions, 1119 deletions
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index d40aae04fc3..3f99e2ff596 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/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb index 2dbb89219d0..3270ea059fa 100644 --- a/spec/controllers/import/gitlab_controller_spec.rb +++ b/spec/controllers/import/gitlab_controller_spec.rb @@ -174,7 +174,7 @@ 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) } 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/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index 62938a56bb4..7bdb4879afd 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -15,11 +15,11 @@ describe Projects::EnvironmentsController do 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 @@ -89,6 +89,9 @@ describe Projects::EnvironmentsController do create(:environment, project: project, name: 'staging-1.0/review', state: :available) + create(:environment, project: project, + name: 'staging-1.0/zzz', + state: :available) end context 'when using default format' do @@ -103,7 +106,7 @@ describe Projects::EnvironmentsController do end context 'when using JSON format' do - it 'responds with JSON' do + it 'sorts the subfolders lexicographically' do get :folder, namespace_id: project.namespace, project_id: project, id: 'staging-1.0', @@ -113,6 +116,8 @@ describe Projects::EnvironmentsController do expect(response).not_to render_template 'folder' expect(json_response['environments'][0]) .to include('name' => 'staging-1.0/review') + expect(json_response['environments'][1]) + .to include('name' => 'staging-1.0/zzz') end end end diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index f0dc6df15ee..587a5820c6f 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 @@ -357,8 +357,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 @@ -1173,13 +1172,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/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index a8be6768a47..4f6fc6691be 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -226,6 +226,50 @@ describe ProjectsController do end end + describe '#transfer' do + render_views + + let(:project) { create(:project) } + let(:admin) { create(:admin) } + let(:new_namespace) { create(:namespace) } + + it 'updates namespace' do + sign_in(admin) + + put :transfer, + namespace_id: project.namespace.path, + new_namespace_id: new_namespace.id, + id: project.path, + format: :js + + project.reload + + expect(project.namespace).to eq(new_namespace) + 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 = project.namespace + + put :transfer, + namespace_id: old_namespace.path, + new_namespace_id: nil, + id: project.path, + format: :js + + project.reload + + 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 + end + describe "#destroy" do let(:admin) { create(:admin) } 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 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/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 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/atom/dashboard_issues_spec.rb b/spec/features/atom/dashboard_issues_spec.rb index 9ea325ab41b..711c8a710f3 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..1df058b023c 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..a61231ea254 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..fae5aaa52bd 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/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..740f60c05cc 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 @@ -66,6 +65,38 @@ describe 'Copy as GFM', feature: true, js: true do GFM ) + aggregate_failures('an accidentally selected empty element') do + gfm = '# Heading1' + + html = <<-HTML.strip_heredoc + <h1>Heading1</h1> + + <h2></h2> + HTML + + output_gfm = html_to_gfm(html) + 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 + <li class="note"> + <div class="md"> + <p> + Test comment with <strong>Markdown!</strong> + </p> + </div> + </li> + + <li class="note"></li> + HTML + + output_gfm = html_to_gfm(html) + expect(output_gfm.strip).to eq(gfm.strip) + end + verify( 'InlineDiffFilter', @@ -352,7 +383,6 @@ describe 'Copy as GFM', feature: true, js: true do <<-GFM.strip_heredoc, - Nested - - Lists GFM @@ -375,7 +405,6 @@ describe 'Copy as GFM', feature: true, js: true do <<-GFM.strip_heredoc, 1. Nested - 1. Numbered lists GFM @@ -479,7 +508,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 +550,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..b416bbd3c79 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 @@ -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 @@ -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 @@ -73,7 +72,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 +95,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 +139,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/activity_spec.rb b/spec/features/dashboard/activity_spec.rb index c977f266296..0764044260e 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/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/issues_spec.rb b/spec/features/dashboard/issues_spec.rb index 7a132dba1e9..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 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/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/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index f1789fc9d43..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 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/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/activity_spec.rb b/spec/features/groups/activity_spec.rb index 3b481cba424..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 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 45f57845c74..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 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 @@ -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/groups/show_spec.rb b/spec/features/groups/show_spec.rb index fb39693e8ca..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 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/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..7958ad7e24f 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 @@ -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/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/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/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/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)) 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/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/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..b1dc81a606a 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 @@ -28,11 +26,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) @@ -44,7 +40,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 +53,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 +66,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 +79,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 +91,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 +109,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 +124,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 +136,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..aad522ee26e 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 @@ -124,9 +124,11 @@ 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 + wait_for_requests expect(page).to have_css(".diffs .notes[data-discussion-id='#{outdated_diff_note.discussion_id}']") end @@ -144,7 +146,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..be8b1423c20 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 @@ -88,32 +88,29 @@ 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 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 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,17 +132,16 @@ 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 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 +159,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 +180,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/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/features/projects/activity/rss_spec.rb b/spec/features/projects/activity/rss_spec.rb index b47c6d431eb..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 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/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/commit/rss_spec.rb b/spec/features/projects/commit/rss_spec.rb index 6e0e1916f87..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 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/compare_spec.rb b/spec/features/projects/compare_spec.rb index b2a3b111c9e..4162f2579d1 100644 --- a/spec/features/projects/compare_spec.rb +++ b/spec/features/projects/compare_spec.rb @@ -52,8 +52,12 @@ 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_ajax - dropdown.find_all("a[data-ref=\"#{selection}\"]", visible: true).last.click + 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 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/guest_navigation_menu_spec.rb b/spec/features/projects/guest_navigation_menu_spec.rb index 726469daba4..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(".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,60 @@ 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!( + issues_access_level: ProjectFeature::DISABLED, + 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' + expect(page).to have_selector '.project-show-customize_workflow' + 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!(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!(issues_access_level: ProjectFeature::PRIVATE) + + visit namespace_project_path(project.namespace, project) + + expect(page).to have_selector '.issues-list' + end + end end 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/issues/rss_spec.rb b/spec/features/projects/issues/rss_spec.rb index 71429f00095..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 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/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/main/rss_spec.rb b/spec/features/projects/main/rss_spec.rb index b1a3af612a1..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 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/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 1211b17b3d8..f40e1bc4930 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -2,10 +2,9 @@ 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) } + 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 +31,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 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/tree/rss_spec.rb b/spec/features/projects/tree/rss_spec.rb index 9ac51997d65..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 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/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/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/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/rss_spec.rb b/spec/features/users/rss_spec.rb index 14564abb16d..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 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/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/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/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/javascripts/copy_as_gfm_spec.js b/spec/javascripts/copy_as_gfm_spec.js new file mode 100644 index 00000000000..ded450749d3 --- /dev/null +++ b/spec/javascripts/copy_as_gfm_spec.js @@ -0,0 +1,49 @@ +import '~/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(); + }); + }); + }); +})(); 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..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,6 +2,8 @@ import Vue from 'vue'; import eventHub from '~/filtered_search/event_hub'; import RecentSearchesDropdownContent from '~/filtered_search/components/recent_searches_dropdown_content'; +import '~/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 0d8bdf4c8e7..f7708301b6e 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 a68e315e3e4..bb02abdeea2 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 7c7def3470d..8688332782d 100644 --- a/spec/javascripts/filtered_search/filtered_search_manager_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_manager_spec.js @@ -80,6 +80,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 9561580c839..e4a15c83c23 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 @@ import '~/filtered_search/filtered_search_token_keys'; import '~/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'); 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(); }); }); 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); + }); + }); +}); 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); + }); + }); +}); diff --git a/spec/javascripts/raven/index_spec.js b/spec/javascripts/raven/index_spec.js index b5662cd0331..a503a54029f 100644 --- a/spec/javascripts/raven/index_spec.js +++ b/spec/javascripts/raven/index_spec.js @@ -2,25 +2,23 @@ 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 revision = 'revision'; let indexReturnValue; beforeEach(() => { - sentryDsn = 'sentryDsn'; - currentUserId = 'currentUserId'; - gitlabUrl = 'gitlabUrl'; - isProduction = 'isProduction'; - window.gon = { sentry_dsn: sentryDsn, current_user_id: currentUserId, gitlab_url: gitlabUrl, + revision, }; process.env.NODE_ENV = isProduction; + process.env.HEAD_COMMIT_SHA = revision; spyOn(RavenConfig, 'init'); @@ -33,6 +31,10 @@ describe('RavenConfig options', () => { currentUserId, whitelistUrls: [gitlabUrl], isProduction, + release: revision, + tags: { + revision, + }, }); }); diff --git a/spec/javascripts/raven/raven_config_spec.js b/spec/javascripts/raven/raven_config_spec.js index a2d720760fc..c82658b9262 100644 --- a/spec/javascripts/raven/raven_config_spec.js +++ b/spec/javascripts/raven/raven_config_spec.js @@ -25,17 +25,11 @@ describe('RavenConfig', () => { }); describe('init', () => { - let options; + const options = { + currentUserId: 1, + }; beforeEach(() => { - options = { - sentryDsn: '//sentryDsn', - ravenAssetUrl: '//ravenAssetUrl', - currentUserId: 1, - whitelistUrls: ['//gitlabUrl'], - isProduction: true, - }; - spyOn(RavenConfig, 'configure'); spyOn(RavenConfig, 'bindRavenErrors'); spyOn(RavenConfig, 'setUser'); @@ -62,30 +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, - }; - ravenConfig = jasmine.createSpyObj('ravenConfig', ['shouldSendSample']); raven = jasmine.createSpyObj('raven', ['install']); @@ -100,6 +92,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, @@ -118,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, @@ -144,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; 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); }); 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'); 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('<pre data-math-style="inline">some code</pre><div data-math>and</div>').to_html + expect(result).to eq('<pre data-math-style="inline" class="code math js-render-math">some code</pre><div data-math>and</div>') + end + + it "keeps content when no data-math-style found" do + result = filter('<pre>some code</pre><div data-math>and</div>').to_html + expect(result).to eq('<pre>some code</pre><div data-math>and</div>') + 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 + <pre class="code" data-math-style="inline">something</pre> + <code class="code" data-math-style="inline">something</code> + <div class="code" data-math-style="inline">something</div> + HTML + + output = <<-HTML + <pre data-math-style="inline">something</pre> + <code data-math-style="inline">something</code> + <div>something</div> + HTML + + expect(filter(html).to_html).to eq(output) + end + it 'removes `rel` attribute from `a` elements' do act = %q{<a href="#" rel="nofollow">Link</a>} exp = %q{<a href="#">Link</a>} 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('<pre data-math-style="display" class="code math js-render-math"><code>eta_x gamma</code></pre>') + expect(render(input, context)).to include('<p><code data-math-style="inline" class="code math js-render-math">2+2</code> is 4</p>') + end + end end def render(*args) diff --git a/spec/lib/gitlab/backup/manager_spec.rb b/spec/lib/gitlab/backup/manager_spec.rb index c59ff7fb290..1c3d2547fec 100644 --- a/spec/lib/gitlab/backup/manager_spec.rb +++ b/spec/lib/gitlab/backup/manager_spec.rb @@ -24,8 +24,9 @@ describe Backup::Manager, lib: true do describe '#remove_old' do let(:files) do [ - '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', @@ -58,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 @@ -74,19 +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 timestamp' do + it 'removes matching files with a human-readable versioned timestamp' do 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]) end it 'removes matching files without a human-readable timestamp' do - 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 'does not remove files that are not old enough' do @@ -94,11 +101,11 @@ describe Backup::Manager, lib: true do 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[6]) 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 @@ -117,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 @@ -150,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' ] ) @@ -187,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 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/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 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/lib/gitlab/etag_caching/router_spec.rb b/spec/lib/gitlab/etag_caching/router_spec.rb index 582ea85a1d6..0418fc0a1e2 100644 --- a/spec/lib/gitlab/etag_caching/router_spec.rb +++ b/spec/lib/gitlab/etag_caching/router_spec.rb @@ -83,11 +83,22 @@ describe Gitlab::EtagCaching::Router do ) result = described_class.match(env) - expect(result).to be_present + expect(result.name).to eq 'environments' 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 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 diff --git a/spec/lib/gitlab/regex_spec.rb b/spec/lib/gitlab/regex_spec.rb index 72e947f2cc2..a7d1283acb8 100644 --- a/spec/lib/gitlab/regex_spec.rb +++ b/spec/lib/gitlab/regex_spec.rb @@ -2,9 +2,377 @@ 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::<VERSION>.#{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') } diff --git a/spec/migrations/upate_retried_for_ci_builds_spec.rb b/spec/migrations/update_retried_for_ci_builds_spec.rb index 5cdb8a3c7da..3742b4dafe5 100644 --- a/spec/migrations/upate_retried_for_ci_builds_spec.rb +++ b/spec/migrations/update_retried_for_ci_builds_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20170503004427_upate_retried_for_ci_build.rb') +require Rails.root.join('db', 'post_migrate', '20170503004427_update_retried_for_ci_build.rb') -describe UpateRetriedForCiBuild, truncate: true do +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') } 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/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/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/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 ce870fcc1d3..da915c49d3c 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 @@ -1214,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 @@ -1223,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 @@ -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 @@ -1536,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/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 8624616316c..312302afdbb 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 diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 6a15830a15c..aabdac4bb75 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -440,6 +440,22 @@ 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 '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 + 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) 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| 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/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/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 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) 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/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 diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb index 29ccce59c53..b957517c715 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].first).to eq 'Please select a new namespace for your project.' } end context 'disallow transfering of project with tags' do diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index 7a9cd7553b1..5a7cfaff7fb 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 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/features/rss_shared_examples.rb b/spec/support/features/rss_shared_examples.rb index 9a3b0a731ad..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 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 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 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 diff --git a/spec/validators/dynamic_path_validator_spec.rb b/spec/validators/dynamic_path_validator_spec.rb index b114bfc1bca..03e23781d1b 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::<VERSION>.#{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_namespace_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_namespace_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_namespace_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_namespace_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_namespace_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_namespace_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 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 |