diff options
Diffstat (limited to 'spec')
26 files changed, 659 insertions, 377 deletions
diff --git a/spec/controllers/concerns/page_limiter_spec.rb b/spec/controllers/concerns/page_limiter_spec.rb new file mode 100644 index 00000000000..9ac94b7e740 --- /dev/null +++ b/spec/controllers/concerns/page_limiter_spec.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true + +require 'spec_helper' + +class PageLimiterSpecController < ApplicationController + include PageLimiter + + before_action do + limit_pages 200 + end + + def index + head :ok + end +end + +describe PageLimiter do + let(:controller_class) do + PageLimiterSpecController + end + + let(:instance) do + controller_class.new + end + + before do + allow(instance).to receive(:params) do + { + controller: "explore/projects", + action: "index" + } + end + + allow(instance).to receive(:request) do + double(:request, user_agent: "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)") + end + end + + describe "#limit_pages" do + using RSpec::Parameterized::TableSyntax + + where(:max_page, :actual_page, :result) do + 2 | 1 | nil + 2 | 2 | nil + 2 | 3 | PageLimiter::PageOutOfBoundsError + nil | 1 | PageLimiter::PageLimitNotANumberError + 0 | 1 | PageLimiter::PageLimitNotSensibleError + -1 | 1 | PageLimiter::PageLimitNotSensibleError + end + + with_them do + subject { instance.limit_pages(max_page) } + + before do + allow(instance).to receive(:params) { { page: actual_page.to_s } } + end + + it "returns the expected result" do + if result == PageLimiter::PageOutOfBoundsError + expect(instance).to receive(:record_page_limit_interception) + expect { subject }.to raise_error(result) + elsif result&.superclass == PageLimiter::PageLimiterError + expect { subject }.to raise_error(result) + else + expect(subject).to eq(result) + end + end + end + end + + describe "#default_page_out_of_bounds_response" do + subject { instance.send(:default_page_out_of_bounds_response) } + + after do + subject + end + + it "returns a bad_request header" do + expect(instance).to receive(:head).with(:bad_request) + end + end + + describe "#record_page_limit_interception" do + subject { instance.send(:record_page_limit_interception) } + + it "records a metric counter" do + expect(Gitlab::Metrics).to receive(:counter).with( + :gitlab_page_out_of_bounds, + controller: "explore/projects", + action: "index", + bot: true + ) + + subject + end + end +end diff --git a/spec/controllers/explore/projects_controller_spec.rb b/spec/controllers/explore/projects_controller_spec.rb index 6752d2b8ebd..6f68de52845 100644 --- a/spec/controllers/explore/projects_controller_spec.rb +++ b/spec/controllers/explore/projects_controller_spec.rb @@ -59,6 +59,79 @@ describe Explore::ProjectsController do end end + shared_examples "blocks high page numbers" do + let(:page_limit) { 200 } + + context "page number is too high" do + [:index, :trending, :starred].each do |endpoint| + describe "GET #{endpoint}" do + render_views + + before do + get endpoint, params: { page: page_limit + 1 } + end + + it { is_expected.to respond_with(:bad_request) } + it { is_expected.to render_template("explore/projects/page_out_of_bounds") } + + it "assigns the page number" do + expect(assigns[:max_page_number]).to eq(page_limit.to_s) + end + end + + describe "GET #{endpoint}.json" do + render_views + + before do + get endpoint, params: { page: page_limit + 1 }, format: :json + end + + it { is_expected.to respond_with(:bad_request) } + end + + describe "metrics recording" do + after do + get endpoint, params: { page: page_limit + 1 } + end + + it "records the interception" do + expect(Gitlab::Metrics).to receive(:counter).with( + :gitlab_page_out_of_bounds, + controller: "explore/projects", + action: endpoint.to_s, + bot: false + ) + end + end + end + end + + context "page number is acceptable" do + [:index, :trending, :starred].each do |endpoint| + describe "GET #{endpoint}" do + render_views + + before do + get endpoint, params: { page: page_limit } + end + + it { is_expected.to respond_with(:success) } + it { is_expected.to render_template("explore/projects/#{endpoint}") } + end + + describe "GET #{endpoint}.json" do + render_views + + before do + get endpoint, params: { page: page_limit }, format: :json + end + + it { is_expected.to respond_with(:success) } + end + end + end + end + context 'when user is signed in' do let(:user) { create(:user) } @@ -67,6 +140,7 @@ describe Explore::ProjectsController do end include_examples 'explore projects' + include_examples "blocks high page numbers" context 'user preference sorting' do let(:project) { create(:project) } @@ -79,6 +153,7 @@ describe Explore::ProjectsController do context 'when user is not signed in' do include_examples 'explore projects' + include_examples "blocks high page numbers" context 'user preference sorting' do let(:project) { create(:project) } diff --git a/spec/factories/project_error_tracking_settings.rb b/spec/factories/project_error_tracking_settings.rb index 7af881f4214..5d3fb284eef 100644 --- a/spec/factories/project_error_tracking_settings.rb +++ b/spec/factories/project_error_tracking_settings.rb @@ -3,7 +3,7 @@ FactoryBot.define do factory :project_error_tracking_setting, class: 'ErrorTracking::ProjectErrorTrackingSetting' do project - api_url { 'https://gitlab.com/api/0/projects/sentry-org/sentry-project' } + api_url { 'https://sentrytest.gitlab.com/api/0/projects/sentry-org/sentry-project' } enabled { true } token { 'access_token_123' } project_name { 'Sentry Project' } diff --git a/spec/features/error_tracking/user_sees_error_details_spec.rb b/spec/features/error_tracking/user_sees_error_details_spec.rb new file mode 100644 index 00000000000..6f72c44c689 --- /dev/null +++ b/spec/features/error_tracking/user_sees_error_details_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'View error details page', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do + include_context 'sentry error tracking context feature' + + context 'with current user as project owner' do + before do + sign_in(project.owner) + + visit details_project_error_tracking_index_path(project, issue_id: issue_id) + end + + it_behaves_like 'error tracking show page' + end + + context 'with current user as project guest' do + let_it_be(:user) { create(:user) } + + before do + project.add_guest(user) + sign_in(user) + + visit details_project_error_tracking_index_path(project, issue_id: issue_id) + end + + it 'renders not found' do + expect(page).to have_content('Page Not Found') + end + end +end diff --git a/spec/features/error_tracking/user_sees_error_index_spec.rb b/spec/features/error_tracking/user_sees_error_index_spec.rb new file mode 100644 index 00000000000..842e4a2e8b5 --- /dev/null +++ b/spec/features/error_tracking/user_sees_error_index_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'View error index page', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do + include_context 'sentry error tracking context feature' + + let_it_be(:issues_response_body) { fixture_file('sentry/issues_sample_response.json') } + let_it_be(:issues_response) { JSON.parse(issues_response_body) } + let(:issues_api_url) { "#{sentry_api_urls.issues_url}?limit=20&query=is:unresolved" } + + before do + stub_request(:get, issues_api_url).with( + headers: { 'Authorization' => 'Bearer access_token_123' } + ).to_return(status: 200, body: issues_response_body, headers: { 'Content-Type' => 'application/json' }) + end + + context 'with current user as project owner' do + before do + sign_in(project.owner) + + visit project_error_tracking_index_path(project) + end + + it_behaves_like 'error tracking index page' + end + + # A bug caused the detail link to be broken for all users but the project owner + context 'with current user as project maintainer' do + let_it_be(:user) { create(:user) } + + before do + project.add_maintainer(user) + sign_in(user) + + visit project_error_tracking_index_path(project) + end + + it_behaves_like 'error tracking index page' + end + + context 'with error tracking settings disabled' do + before do + project_error_tracking_settings.update(enabled: false) + sign_in(project.owner) + + visit project_error_tracking_index_path(project) + end + + it 'renders call to action' do + expect(page).to have_content('Enable error tracking') + end + end + + context 'with current user as project guest' do + let_it_be(:user) { create(:user) } + + before do + project.add_guest(user) + sign_in(user) + + visit project_error_tracking_index_path(project) + end + + it 'renders not found' do + expect(page).to have_content('Page Not Found') + end + end +end diff --git a/spec/fixtures/sentry/issue_sample_response.json b/spec/fixtures/sentry/issue_sample_response.json index a320a21de34..43d55f584b8 100644 --- a/spec/fixtures/sentry/issue_sample_response.json +++ b/spec/fixtures/sentry/issue_sample_response.json @@ -38,7 +38,7 @@ }, "firstSeen": "2018-11-06T21:19:55Z", "hasSeen": false, - "id": "503504", + "id": "11", "isBookmarked": false, "isPublic": false, "isSubscribed": true, @@ -72,232 +72,64 @@ "shortId": "PUMP-STATION-1", "stats": { "24h": [ - [ - 1541451600.0, - 557 - ], - [ - 1541455200.0, - 473 - ], - [ - 1541458800.0, - 914 - ], - [ - 1541462400.0, - 991 - ], - [ - 1541466000.0, - 925 - ], - [ - 1541469600.0, - 881 - ], - [ - 1541473200.0, - 182 - ], - [ - 1541476800.0, - 490 - ], - [ - 1541480400.0, - 820 - ], - [ - 1541484000.0, - 322 - ], - [ - 1541487600.0, - 836 - ], - [ - 1541491200.0, - 565 - ], - [ - 1541494800.0, - 758 - ], - [ - 1541498400.0, - 880 - ], - [ - 1541502000.0, - 677 - ], - [ - 1541505600.0, - 381 - ], - [ - 1541509200.0, - 814 - ], - [ - 1541512800.0, - 329 - ], - [ - 1541516400.0, - 446 - ], - [ - 1541520000.0, - 731 - ], - [ - 1541523600.0, - 111 - ], - [ - 1541527200.0, - 926 - ], - [ - 1541530800.0, - 772 - ], - [ - 1541534400.0, - 400 - ], - [ - 1541538000.0, - 943 - ] + [1541451600.0, 557], + [1541455200.0, 473], + [1541458800.0, 914], + [1541462400.0, 991], + [1541466000.0, 925], + [1541469600.0, 881], + [1541473200.0, 182], + [1541476800.0, 490], + [1541480400.0, 820], + [1541484000.0, 322], + [1541487600.0, 836], + [1541491200.0, 565], + [1541494800.0, 758], + [1541498400.0, 880], + [1541502000.0, 677], + [1541505600.0, 381], + [1541509200.0, 814], + [1541512800.0, 329], + [1541516400.0, 446], + [1541520000.0, 731], + [1541523600.0, 111], + [1541527200.0, 926], + [1541530800.0, 772], + [1541534400.0, 400], + [1541538000.0, 943] ], "30d": [ - [ - 1538870400.0, - 565 - ], - [ - 1538956800.0, - 12862 - ], - [ - 1539043200.0, - 15617 - ], - [ - 1539129600.0, - 10809 - ], - [ - 1539216000.0, - 15065 - ], - [ - 1539302400.0, - 12927 - ], - [ - 1539388800.0, - 12994 - ], - [ - 1539475200.0, - 13139 - ], - [ - 1539561600.0, - 11838 - ], - [ - 1539648000.0, - 12088 - ], - [ - 1539734400.0, - 12338 - ], - [ - 1539820800.0, - 12768 - ], - [ - 1539907200.0, - 12816 - ], - [ - 1539993600.0, - 15356 - ], - [ - 1540080000.0, - 10910 - ], - [ - 1540166400.0, - 12306 - ], - [ - 1540252800.0, - 12912 - ], - [ - 1540339200.0, - 14700 - ], - [ - 1540425600.0, - 11890 - ], - [ - 1540512000.0, - 11684 - ], - [ - 1540598400.0, - 13510 - ], - [ - 1540684800.0, - 12625 - ], - [ - 1540771200.0, - 12811 - ], - [ - 1540857600.0, - 13180 - ], - [ - 1540944000.0, - 14651 - ], - [ - 1541030400.0, - 14161 - ], - [ - 1541116800.0, - 12612 - ], - [ - 1541203200.0, - 14316 - ], - [ - 1541289600.0, - 14742 - ], - [ - 1541376000.0, - 12505 - ], - [ - 1541462400.0, - 14180 - ] + [1538870400.0, 565], + [1538956800.0, 12862], + [1539043200.0, 15617], + [1539129600.0, 10809], + [1539216000.0, 15065], + [1539302400.0, 12927], + [1539388800.0, 12994], + [1539475200.0, 13139], + [1539561600.0, 11838], + [1539648000.0, 12088], + [1539734400.0, 12338], + [1539820800.0, 12768], + [1539907200.0, 12816], + [1539993600.0, 15356], + [1540080000.0, 10910], + [1540166400.0, 12306], + [1540252800.0, 12912], + [1540339200.0, 14700], + [1540425600.0, 11890], + [1540512000.0, 11684], + [1540598400.0, 13510], + [1540684800.0, 12625], + [1540771200.0, 12811], + [1540857600.0, 13180], + [1540944000.0, 14651], + [1541030400.0, 14161], + [1541116800.0, 12612], + [1541203200.0, 14316], + [1541289600.0, 14742], + [1541376000.0, 12505], + [1541462400.0, 14180] ] }, "status": "unresolved", diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb index a775c69335e..2f91ab3afb3 100644 --- a/spec/helpers/markup_helper_spec.rb +++ b/spec/helpers/markup_helper_spec.rb @@ -138,10 +138,20 @@ describe MarkupHelper do describe 'without redacted attribute' do it 'renders the markdown value' do expect(Banzai).to receive(:render_field).with(commit, attribute, {}).and_call_original + expect(Banzai).to receive(:post_process) helper.markdown_field(commit, attribute) end end + + context 'when post_process is false' do + it 'does not run Markdown post processing' do + expect(Banzai).to receive(:render_field).with(commit, attribute, {}).and_call_original + expect(Banzai).not_to receive(:post_process) + + helper.markdown_field(commit, attribute, post_process: false) + end + end end describe '#link_to_markdown_field' do @@ -565,6 +575,14 @@ describe MarkupHelper do expect(doc.content).to eq "foo 😉\nbar 😀" end + + it 'does not post-process truncated text', :request_store do + object = create_object("hello \n\n [Test](README.md)") + + expect do + first_line_in_markdown(object, attribute, nil, project: project) + end.not_to change { Gitlab::GitalyClient.get_request_count } + end end context 'when the asked attribute can be redacted' do diff --git a/spec/lib/gitlab/gpg_spec.rb b/spec/lib/gitlab/gpg_spec.rb index 27a3010eeed..fac2dbfab71 100644 --- a/spec/lib/gitlab/gpg_spec.rb +++ b/spec/lib/gitlab/gpg_spec.rb @@ -208,8 +208,8 @@ describe Gitlab::Gpg do allow(FileUtils).to receive(:remove_entry).with(any_args).and_call_original end - it "tries for #{seconds}" do - expect(Retriable).to receive(:retriable).with(a_hash_including(max_elapsed_time: seconds)) + it "tries for #{seconds} or 15 times" do + expect(Retriable).to receive(:retriable).with(a_hash_including(max_elapsed_time: seconds, tries: 15)) described_class.using_tmp_keychain {} end diff --git a/spec/lib/gitlab/kubernetes/kube_client_spec.rb b/spec/lib/gitlab/kubernetes/kube_client_spec.rb index e08981a3415..729c2b04930 100644 --- a/spec/lib/gitlab/kubernetes/kube_client_spec.rb +++ b/spec/lib/gitlab/kubernetes/kube_client_spec.rb @@ -229,20 +229,30 @@ describe Gitlab::Kubernetes::KubeClient do end end - describe 'extensions API group' do - let(:api_groups) { ['apis/extensions'] } + describe '#get_deployments' do let(:extensions_client) { client.extensions_client } + let(:apps_client) { client.apps_client } - describe '#get_deployments' do - include_examples 'redirection not allowed', 'get_deployments' - include_examples 'dns rebinding not allowed', 'get_deployments' + include_examples 'redirection not allowed', 'get_deployments' + include_examples 'dns rebinding not allowed', 'get_deployments' - it 'delegates to the extensions client' do - expect(client).to delegate_method(:get_deployments).to(:extensions_client) + it 'delegates to the extensions client' do + expect(extensions_client).to receive(:get_deployments) + + client.get_deployments + end + + context 'extensions does not have deployments for Kubernetes 1.16+ clusters' do + before do + WebMock + .stub_request(:get, api_url + '/apis/extensions/v1beta1') + .to_return(kube_response(kube_1_16_extensions_v1beta1_discovery_body)) end - it 'responds to the method' do - expect(client).to respond_to :get_deployments + it 'delegates to the apps client' do + expect(apps_client).to receive(:get_deployments) + + client.get_deployments end end end diff --git a/spec/lib/sentry/client/issue_spec.rb b/spec/lib/sentry/client/issue_spec.rb index 061ebcfdc06..2762c5b5cb9 100644 --- a/spec/lib/sentry/client/issue_spec.rb +++ b/spec/lib/sentry/client/issue_spec.rb @@ -8,7 +8,7 @@ describe Sentry::Client::Issue do let(:token) { 'test-token' } let(:sentry_url) { 'https://sentrytest.gitlab.com/api/0' } let(:client) { Sentry::Client.new(sentry_url, token) } - let(:issue_id) { 503504 } + let(:issue_id) { 11 } describe '#list_issues' do shared_examples 'issues have correct return type' do |klass| @@ -243,7 +243,7 @@ describe Sentry::Client::Issue do end it 'has a correct external URL' do - expect(subject.external_url).to eq('https://sentrytest.gitlab.com/api/0/issues/503504') + expect(subject.external_url).to eq('https://sentrytest.gitlab.com/api/0/issues/11') end it 'issue has a correct external base url' do diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index e4a7d62eb02..19b15a6c6e2 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -686,7 +686,7 @@ describe Notify do let(:project_snippet) { create(:project_snippet, project: project) } let(:project_snippet_note) { create(:note_on_project_snippet, project: project, noteable: project_snippet) } - subject { described_class.note_project_snippet_email(project_snippet_note.author_id, project_snippet_note.id) } + subject { described_class.note_snippet_email(project_snippet_note.author_id, project_snippet_note.id) } it_behaves_like 'appearance header and footer enabled' it_behaves_like 'appearance header and footer not enabled' @@ -696,10 +696,20 @@ describe Notify do end it_behaves_like 'a user cannot unsubscribe through footer link' - it 'has the correct subject and body' do + it 'has the correct subject' do is_expected.to have_referable_subject(project_snippet, reply: true) + end + + it 'has the correct body' do is_expected.to have_body_text project_snippet_note.note end + + it 'links to the project snippet' do + target_url = project_snippet_url(project, + project_snippet_note.noteable, + { anchor: "note_#{project_snippet_note.id}" }) + is_expected.to have_body_text target_url + end end describe 'project was moved' do @@ -1650,15 +1660,23 @@ describe Notify do let(:personal_snippet) { create(:personal_snippet) } let(:personal_snippet_note) { create(:note_on_personal_snippet, noteable: personal_snippet) } - subject { described_class.note_personal_snippet_email(personal_snippet_note.author_id, personal_snippet_note.id) } + subject { described_class.note_snippet_email(personal_snippet_note.author_id, personal_snippet_note.id) } it_behaves_like 'a user cannot unsubscribe through footer link' it_behaves_like 'appearance header and footer enabled' it_behaves_like 'appearance header and footer not enabled' - it 'has the correct subject and body' do + it 'has the correct subject' do is_expected.to have_referable_subject(personal_snippet, reply: true) + end + + it 'has the correct body' do is_expected.to have_body_text personal_snippet_note.note end + + it 'links to the personal snippet' do + target_url = gitlab_snippet_url(personal_snippet_note.noteable) + is_expected.to have_body_text target_url + end end end diff --git a/spec/models/concerns/project_features_compatibility_spec.rb b/spec/models/concerns/project_features_compatibility_spec.rb index 1fe176ab5af..8346c4ad4cc 100644 --- a/spec/models/concerns/project_features_compatibility_spec.rb +++ b/spec/models/concerns/project_features_compatibility_spec.rb @@ -4,8 +4,8 @@ require 'spec_helper' describe ProjectFeaturesCompatibility do let(:project) { create(:project) } - let(:features_except_repository) { %w(issues wiki builds merge_requests snippets) } - let(:features) { features_except_repository + ['repository'] } + let(:features_enabled) { %w(issues wiki builds merge_requests snippets) } + let(:features) { features_enabled + %w(repository pages) } # We had issues_enabled, snippets_enabled, builds_enabled, merge_requests_enabled and issues_enabled fields on projects table # All those fields got moved to a new table called project_feature and are now integers instead of booleans @@ -13,37 +13,53 @@ describe ProjectFeaturesCompatibility do # So we can keep it compatible it "converts fields from 'true' to ProjectFeature::ENABLED" do - features_except_repository.each do |feature| + features_enabled.each do |feature| project.update_attribute("#{feature}_enabled".to_sym, "true") expect(project.project_feature.public_send("#{feature}_access_level")).to eq(ProjectFeature::ENABLED) end end it "converts fields from 'false' to ProjectFeature::DISABLED" do - features_except_repository.each do |feature| + features_enabled.each do |feature| project.update_attribute("#{feature}_enabled".to_sym, "false") expect(project.project_feature.public_send("#{feature}_access_level")).to eq(ProjectFeature::DISABLED) end end it "converts fields from true to ProjectFeature::ENABLED" do - features_except_repository.each do |feature| + features_enabled.each do |feature| project.update_attribute("#{feature}_enabled".to_sym, true) expect(project.project_feature.public_send("#{feature}_access_level")).to eq(ProjectFeature::ENABLED) end end it "converts fields from false to ProjectFeature::DISABLED" do - features_except_repository.each do |feature| + features_enabled.each do |feature| project.update_attribute("#{feature}_enabled".to_sym, false) expect(project.project_feature.public_send("#{feature}_access_level")).to eq(ProjectFeature::DISABLED) end end - it "accepts private as ProjectFeature::PRIVATE" do - features.each do |feature| - project.update!("#{feature}_access_level".to_sym => 'private') - expect(project.project_feature.public_send("#{feature}_access_level")).to eq(ProjectFeature::PRIVATE) + describe "access levels" do + using RSpec::Parameterized::TableSyntax + + where(:access_level, :expected_result) do + 'disabled' | ProjectFeature::DISABLED + 'private' | ProjectFeature::PRIVATE + 'enabled' | ProjectFeature::ENABLED + 'public' | ProjectFeature::PUBLIC + end + + with_them do + it "accepts access level" do + features.each do |feature| + # Only pages as public access level + next if feature != 'pages' && access_level == 'public' + + project.update!("#{feature}_access_level".to_sym => access_level) + expect(project.project_feature.public_send("#{feature}_access_level")).to eq(expected_result) + end + end end end end diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index a6d9ecaa7c5..12a74632bb8 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -718,12 +718,12 @@ describe Note do end describe '#noteable_ability_name' do - it 'returns project_snippet for a project snippet note' do - expect(build(:note_on_project_snippet).noteable_ability_name).to eq('project_snippet') + it 'returns snippet for a project snippet note' do + expect(build(:note_on_project_snippet).noteable_ability_name).to eq('snippet') end - it 'returns personal_snippet for a personal snippet note' do - expect(build(:note_on_personal_snippet).noteable_ability_name).to eq('personal_snippet') + it 'returns snippet for a personal snippet note' do + expect(build(:note_on_personal_snippet).noteable_ability_name).to eq('snippet') end it 'returns merge_request for an MR note' do diff --git a/spec/policies/global_policy_spec.rb b/spec/policies/global_policy_spec.rb index f715ecae347..77727c6d13b 100644 --- a/spec/policies/global_policy_spec.rb +++ b/spec/policies/global_policy_spec.rb @@ -307,21 +307,21 @@ describe GlobalPolicy do end end - describe 'create_personal_snippet' do + describe 'create_snippet' do context 'when anonymous' do let(:current_user) { nil } - it { is_expected.not_to be_allowed(:create_personal_snippet) } + it { is_expected.not_to be_allowed(:create_snippet) } end context 'regular user' do - it { is_expected.to be_allowed(:create_personal_snippet) } + it { is_expected.to be_allowed(:create_snippet) } end context 'when external' do let(:current_user) { build(:user, :external) } - it { is_expected.not_to be_allowed(:create_personal_snippet) } + it { is_expected.not_to be_allowed(:create_snippet) } end end end diff --git a/spec/policies/note_policy_spec.rb b/spec/policies/note_policy_spec.rb index 5aee66275d4..2619bb2fe3c 100644 --- a/spec/policies/note_policy_spec.rb +++ b/spec/policies/note_policy_spec.rb @@ -54,6 +54,27 @@ describe NotePolicy do end end + context 'when the noteable is a personal snippet' do + let(:noteable) { create(:personal_snippet, :public) } + let(:note) { create(:note, noteable: noteable, author: user) } + + it 'can edit note' do + expect(policy).to be_allowed(:admin_note) + expect(policy).to be_allowed(:resolve_note) + expect(policy).to be_allowed(:read_note) + end + + context 'when it is private' do + let(:noteable) { create(:personal_snippet, :private) } + + it 'can not edit nor read the note' do + expect(policy).to be_disallowed(:admin_note) + expect(policy).to be_disallowed(:resolve_note) + expect(policy).to be_disallowed(:read_note) + end + end + end + context 'when the project is public' do context 'when the note author is not a project member' do it 'can edit a note' do @@ -79,26 +100,6 @@ describe NotePolicy do end end - context 'when the noteable is a personal snippet' do - let(:noteable) { create(:personal_snippet, :public) } - - it 'can edit note' do - expect(policy).to be_allowed(:admin_note) - expect(policy).to be_allowed(:resolve_note) - expect(policy).to be_allowed(:read_note) - end - - context 'when it is private' do - let(:noteable) { create(:personal_snippet, :private) } - - it 'can not edit nor read the note' do - expect(policy).to be_disallowed(:admin_note) - expect(policy).to be_disallowed(:resolve_note) - expect(policy).to be_disallowed(:read_note) - end - end - end - context 'when a discussion is confidential' do before do issue.update_attribute(:confidential, true) diff --git a/spec/policies/personal_snippet_policy_spec.rb b/spec/policies/personal_snippet_policy_spec.rb index 0abdf7382be..a6b76620c29 100644 --- a/spec/policies/personal_snippet_policy_spec.rb +++ b/spec/policies/personal_snippet_policy_spec.rb @@ -10,8 +10,8 @@ describe PersonalSnippetPolicy do let(:author_permissions) do [ - :update_personal_snippet, - :admin_personal_snippet + :update_snippet, + :admin_snippet ] end @@ -24,7 +24,7 @@ describe PersonalSnippetPolicy do subject { permissions(admin_user) } it do - is_expected.to be_allowed(:read_personal_snippet) + is_expected.to be_allowed(:read_snippet) is_expected.to be_allowed(:create_note) is_expected.to be_allowed(:award_emoji) is_expected.to be_allowed(*author_permissions) @@ -39,7 +39,7 @@ describe PersonalSnippetPolicy do subject { permissions(nil) } it do - is_expected.to be_allowed(:read_personal_snippet) + is_expected.to be_allowed(:read_snippet) is_expected.to be_disallowed(:create_note) is_expected.to be_disallowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) @@ -50,7 +50,7 @@ describe PersonalSnippetPolicy do subject { permissions(regular_user) } it do - is_expected.to be_allowed(:read_personal_snippet) + is_expected.to be_allowed(:read_snippet) is_expected.to be_allowed(:create_note) is_expected.to be_allowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) @@ -61,7 +61,7 @@ describe PersonalSnippetPolicy do subject { permissions(snippet.author) } it do - is_expected.to be_allowed(:read_personal_snippet) + is_expected.to be_allowed(:read_snippet) is_expected.to be_allowed(:create_note) is_expected.to be_allowed(:award_emoji) is_expected.to be_allowed(*author_permissions) @@ -78,7 +78,7 @@ describe PersonalSnippetPolicy do subject { permissions(nil) } it do - is_expected.to be_disallowed(:read_personal_snippet) + is_expected.to be_disallowed(:read_snippet) is_expected.to be_disallowed(:create_note) is_expected.to be_disallowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) @@ -89,7 +89,7 @@ describe PersonalSnippetPolicy do subject { permissions(regular_user) } it do - is_expected.to be_allowed(:read_personal_snippet) + is_expected.to be_allowed(:read_snippet) is_expected.to be_allowed(:create_note) is_expected.to be_allowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) @@ -100,7 +100,7 @@ describe PersonalSnippetPolicy do subject { permissions(external_user) } it do - is_expected.to be_disallowed(:read_personal_snippet) + is_expected.to be_disallowed(:read_snippet) is_expected.to be_disallowed(:create_note) is_expected.to be_disallowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) @@ -111,7 +111,7 @@ describe PersonalSnippetPolicy do subject { permissions(snippet.author) } it do - is_expected.to be_allowed(:read_personal_snippet) + is_expected.to be_allowed(:read_snippet) is_expected.to be_allowed(:create_note) is_expected.to be_allowed(:award_emoji) is_expected.to be_allowed(*author_permissions) @@ -128,7 +128,7 @@ describe PersonalSnippetPolicy do subject { permissions(nil) } it do - is_expected.to be_disallowed(:read_personal_snippet) + is_expected.to be_disallowed(:read_snippet) is_expected.to be_disallowed(:create_note) is_expected.to be_disallowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) @@ -139,7 +139,7 @@ describe PersonalSnippetPolicy do subject { permissions(regular_user) } it do - is_expected.to be_disallowed(:read_personal_snippet) + is_expected.to be_disallowed(:read_snippet) is_expected.to be_disallowed(:create_note) is_expected.to be_disallowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) @@ -150,7 +150,7 @@ describe PersonalSnippetPolicy do subject { permissions(external_user) } it do - is_expected.to be_disallowed(:read_personal_snippet) + is_expected.to be_disallowed(:read_snippet) is_expected.to be_disallowed(:create_note) is_expected.to be_disallowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) @@ -161,7 +161,7 @@ describe PersonalSnippetPolicy do subject { permissions(snippet.author) } it do - is_expected.to be_allowed(:read_personal_snippet) + is_expected.to be_allowed(:read_snippet) is_expected.to be_allowed(:create_note) is_expected.to be_allowed(:award_emoji) is_expected.to be_allowed(*author_permissions) diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index e47204c774b..1a4b8315fde 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -17,7 +17,7 @@ describe ProjectPolicy do %i[ read_project read_board read_list read_wiki read_issue read_project_for_iids read_issue_iid read_label - read_milestone read_project_snippet read_project_member read_note + read_milestone read_snippet read_project_member read_note create_project create_issue create_note upload_file create_merge_request_in award_emoji read_release ] @@ -25,7 +25,7 @@ describe ProjectPolicy do let(:base_reporter_permissions) do %i[ - download_code fork_project create_project_snippet update_issue + download_code fork_project create_snippet update_issue admin_issue admin_label admin_list read_commit_status read_build read_container_image read_pipeline read_environment read_deployment read_merge_request download_wiki_code read_sentry_issue @@ -48,8 +48,8 @@ describe ProjectPolicy do let(:base_maintainer_permissions) do %i[ - push_to_delete_protected_branch update_project_snippet - admin_project_snippet admin_project_member admin_note admin_wiki admin_project + push_to_delete_protected_branch update_snippet + admin_snippet admin_project_member admin_note admin_wiki admin_project admin_commit_status admin_build admin_container_image admin_pipeline admin_environment admin_deployment destroy_release add_cluster daily_statistics diff --git a/spec/policies/project_snippet_policy_spec.rb b/spec/policies/project_snippet_policy_spec.rb index 374636874ee..b55d565a57c 100644 --- a/spec/policies/project_snippet_policy_spec.rb +++ b/spec/policies/project_snippet_policy_spec.rb @@ -12,8 +12,8 @@ describe ProjectSnippetPolicy do let(:author) { other_user } let(:author_permissions) do [ - :update_project_snippet, - :admin_project_snippet + :update_snippet, + :admin_snippet ] end @@ -26,7 +26,7 @@ describe ProjectSnippetPolicy do end it do - expect_allowed(:read_project_snippet, :create_note) + expect_allowed(:read_snippet, :create_note) expect_disallowed(*author_permissions) end end @@ -38,8 +38,8 @@ describe ProjectSnippetPolicy do context 'not snippet author' do it do - expect_allowed(:read_project_snippet, :create_note) - expect_disallowed(:admin_project_snippet) + expect_allowed(:read_snippet, :create_note) + expect_disallowed(:admin_snippet) end end end @@ -53,7 +53,7 @@ describe ProjectSnippetPolicy do end it do - expect_allowed(:read_project_snippet, :create_note) + expect_allowed(:read_snippet, :create_note) expect_allowed(*author_permissions) end end @@ -64,15 +64,15 @@ describe ProjectSnippetPolicy do end it do - expect_allowed(:read_project_snippet, :create_note) - expect_disallowed(:admin_project_snippet) + expect_allowed(:read_snippet, :create_note) + expect_disallowed(:admin_snippet) end end context 'not a project member' do it do - expect_allowed(:read_project_snippet, :create_note) - expect_disallowed(:admin_project_snippet) + expect_allowed(:read_snippet, :create_note) + expect_disallowed(:admin_snippet) end end end @@ -85,7 +85,7 @@ describe ProjectSnippetPolicy do let(:current_user) { nil } it do - expect_allowed(:read_project_snippet) + expect_allowed(:read_snippet) expect_disallowed(*author_permissions) end end @@ -94,7 +94,7 @@ describe ProjectSnippetPolicy do let(:current_user) { regular_user } it do - expect_allowed(:read_project_snippet, :create_note) + expect_allowed(:read_snippet, :create_note) expect_disallowed(*author_permissions) end @@ -105,7 +105,7 @@ describe ProjectSnippetPolicy do let(:current_user) { external_user } it do - expect_allowed(:read_project_snippet, :create_note) + expect_allowed(:read_snippet, :create_note) expect_disallowed(*author_permissions) end @@ -115,7 +115,7 @@ describe ProjectSnippetPolicy do end it do - expect_allowed(:read_project_snippet, :create_note) + expect_allowed(:read_snippet, :create_note) expect_disallowed(*author_permissions) end end @@ -129,7 +129,7 @@ describe ProjectSnippetPolicy do let(:current_user) { nil } it do - expect_disallowed(:read_project_snippet) + expect_disallowed(:read_snippet) expect_disallowed(*author_permissions) end end @@ -138,7 +138,7 @@ describe ProjectSnippetPolicy do let(:current_user) { regular_user } it do - expect_allowed(:read_project_snippet, :create_note) + expect_allowed(:read_snippet, :create_note) expect_disallowed(*author_permissions) end @@ -149,7 +149,7 @@ describe ProjectSnippetPolicy do let(:current_user) { external_user } it do - expect_disallowed(:read_project_snippet, :create_note) + expect_disallowed(:read_snippet, :create_note) expect_disallowed(*author_permissions) end @@ -159,7 +159,7 @@ describe ProjectSnippetPolicy do end it do - expect_allowed(:read_project_snippet, :create_note) + expect_allowed(:read_snippet, :create_note) expect_disallowed(*author_permissions) end end @@ -173,7 +173,7 @@ describe ProjectSnippetPolicy do let(:current_user) { nil } it do - expect_disallowed(:read_project_snippet) + expect_disallowed(:read_snippet) expect_disallowed(*author_permissions) end end @@ -182,7 +182,7 @@ describe ProjectSnippetPolicy do let(:current_user) { regular_user } it do - expect_disallowed(:read_project_snippet, :create_note) + expect_disallowed(:read_snippet, :create_note) expect_disallowed(*author_permissions) end @@ -193,7 +193,7 @@ describe ProjectSnippetPolicy do let(:current_user) { external_user } it do - expect_disallowed(:read_project_snippet, :create_note) + expect_disallowed(:read_snippet, :create_note) expect_disallowed(*author_permissions) end @@ -203,7 +203,7 @@ describe ProjectSnippetPolicy do end it do - expect_allowed(:read_project_snippet, :create_note) + expect_allowed(:read_snippet, :create_note) expect_disallowed(*author_permissions) end end @@ -214,7 +214,7 @@ describe ProjectSnippetPolicy do let(:current_user) { create(:admin) } it do - expect_allowed(:read_project_snippet, :create_note) + expect_allowed(:read_snippet, :create_note) expect_allowed(*author_permissions) end end diff --git a/spec/presenters/snippet_presenter_spec.rb b/spec/presenters/snippet_presenter_spec.rb index 87f2220979c..e2117905559 100644 --- a/spec/presenters/snippet_presenter_spec.rb +++ b/spec/presenters/snippet_presenter_spec.rb @@ -62,8 +62,8 @@ describe SnippetPresenter do context 'with PersonalSnippet' do let(:snippet) { personal_snippet } - it 'checks read_personal_snippet' do - expect(presenter).to receive(:can?).with(user, :read_personal_snippet, snippet) + it 'checks read_snippet' do + expect(presenter).to receive(:can?).with(user, :read_snippet, snippet) subject end @@ -72,8 +72,8 @@ describe SnippetPresenter do context 'with ProjectSnippet' do let(:snippet) { project_snippet } - it 'checks read_project_snippet ' do - expect(presenter).to receive(:can?).with(user, :read_project_snippet, snippet) + it 'checks read_snippet ' do + expect(presenter).to receive(:can?).with(user, :read_snippet, snippet) subject end @@ -86,8 +86,8 @@ describe SnippetPresenter do context 'with PersonalSnippet' do let(:snippet) { personal_snippet } - it 'checks update_personal_snippet' do - expect(presenter).to receive(:can?).with(user, :update_personal_snippet, snippet) + it 'checks update_snippet' do + expect(presenter).to receive(:can?).with(user, :update_snippet, snippet) subject end @@ -96,8 +96,8 @@ describe SnippetPresenter do context 'with ProjectSnippet' do let(:snippet) { project_snippet } - it 'checks update_project_snippet ' do - expect(presenter).to receive(:can?).with(user, :update_project_snippet, snippet) + it 'checks update_snippet ' do + expect(presenter).to receive(:can?).with(user, :update_snippet, snippet) subject end @@ -110,8 +110,8 @@ describe SnippetPresenter do context 'with PersonalSnippet' do let(:snippet) { personal_snippet } - it 'checks admin_personal_snippet' do - expect(presenter).to receive(:can?).with(user, :admin_personal_snippet, snippet) + it 'checks admin_snippet' do + expect(presenter).to receive(:can?).with(user, :admin_snippet, snippet) subject end @@ -120,8 +120,8 @@ describe SnippetPresenter do context 'with ProjectSnippet' do let(:snippet) { project_snippet } - it 'checks admin_project_snippet ' do - expect(presenter).to receive(:can?).with(user, :admin_project_snippet, snippet) + it 'checks admin_snippet ' do + expect(presenter).to receive(:can?).with(user, :admin_snippet, snippet) subject end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index fce49d0248c..62cc6ee086b 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -1394,6 +1394,7 @@ describe API::Projects do expect(json_response['jobs_enabled']).to be_present expect(json_response['snippets_enabled']).to be_present expect(json_response['snippets_access_level']).to be_present + expect(json_response['pages_access_level']).to be_present expect(json_response['repository_access_level']).to be_present expect(json_response['issues_access_level']).to be_present expect(json_response['merge_requests_access_level']).to be_present @@ -2230,6 +2231,16 @@ describe API::Projects do expect(json_response['builds_access_level']).to eq('private') end + it 'updates pages_access_level' do + project_param = { pages_access_level: 'private' } + + put api("/projects/#{project3.id}", user), params: project_param + + expect(response).to have_gitlab_http_status(:ok) + + expect(json_response['pages_access_level']).to eq('private') + end + it 'updates build_git_strategy' do project_param = { build_git_strategy: 'clone' } diff --git a/spec/services/projects/update_pages_service_spec.rb b/spec/services/projects/update_pages_service_spec.rb index e8db243c472..714256d9b08 100644 --- a/spec/services/projects/update_pages_service_spec.rb +++ b/spec/services/projects/update_pages_service_spec.rb @@ -176,35 +176,6 @@ describe Projects::UpdatePagesService do describe 'maximum pages artifacts size' do let(:metadata) { spy('metadata') } - shared_examples 'pages size limit is' do |size_limit| - context "when size is below the limit" do - before do - allow(metadata).to receive(:total_size).and_return(size_limit - 1.megabyte) - end - - it 'updates pages correctly' do - subject.execute - - expect(deploy_status.description).not_to be_present - expect(project.pages_metadatum).to be_deployed - end - end - - context "when size is above the limit" do - before do - allow(metadata).to receive(:total_size).and_return(size_limit + 1.megabyte) - end - - it 'limits the maximum size of gitlab pages' do - subject.execute - - expect(deploy_status.description) - .to match(/artifacts for pages are too large/) - expect(deploy_status).to be_script_failure - end - end - end - before do file = fixture_file_upload('spec/fixtures/pages.zip') metafile = fixture_file_upload('spec/fixtures/pages.zip.meta') diff --git a/spec/support/helpers/kubernetes_helpers.rb b/spec/support/helpers/kubernetes_helpers.rb index 89360b55de2..77acad31d62 100644 --- a/spec/support/helpers/kubernetes_helpers.rb +++ b/spec/support/helpers/kubernetes_helpers.rb @@ -27,7 +27,10 @@ module KubernetesHelpers WebMock.stub_request(:get, api_url + '/api/v1').to_return(kube_response(kube_v1_discovery_body)) WebMock .stub_request(:get, api_url + '/apis/extensions/v1beta1') - .to_return(kube_response(kube_v1beta1_discovery_body)) + .to_return(kube_response(kube_extensions_v1beta1_discovery_body)) + WebMock + .stub_request(:get, api_url + '/apis/apps/v1') + .to_return(kube_response(kube_apps_v1_discovery_body)) WebMock .stub_request(:get, api_url + '/apis/rbac.authorization.k8s.io/v1') .to_return(kube_response(kube_v1_rbac_authorization_discovery_body)) @@ -275,15 +278,33 @@ module KubernetesHelpers } end - def kube_v1beta1_discovery_body + # From Kubernetes 1.16+ Deployments are no longer served from apis/extensions + def kube_1_16_extensions_v1beta1_discovery_body + { + "kind" => "APIResourceList", + "resources" => [ + { "name" => "ingresses", "namespaced" => true, "kind" => "Deployment" } + ] + } + end + + def kube_extensions_v1beta1_discovery_body { "kind" => "APIResourceList", "resources" => [ - { "name" => "pods", "namespaced" => true, "kind" => "Pod" }, { "name" => "deployments", "namespaced" => true, "kind" => "Deployment" }, - { "name" => "secrets", "namespaced" => true, "kind" => "Secret" }, - { "name" => "serviceaccounts", "namespaced" => true, "kind" => "ServiceAccount" }, - { "name" => "services", "namespaced" => true, "kind" => "Service" } + { "name" => "ingresses", "namespaced" => true, "kind" => "Ingress" } + ] + } + end + + # Yes, deployments are defined in both apis/extensions/v1beta1 and apis/v1 + # (for Kubernetes < 1.16). This matches what Kubenetes API server returns. + def kube_apps_v1_discovery_body + { + "kind" => "APIResourceList", + "resources" => [ + { "name" => "deployments", "namespaced" => true, "kind" => "Deployment" } ] } end diff --git a/spec/support/shared_contexts/features/error_tracking_shared_context.rb b/spec/support/shared_contexts/features/error_tracking_shared_context.rb new file mode 100644 index 00000000000..3da6e2b13bb --- /dev/null +++ b/spec/support/shared_contexts/features/error_tracking_shared_context.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +shared_context 'sentry error tracking context feature' do + include ReactiveCachingHelpers + + let_it_be(:project) { create(:project) } + let_it_be(:project_error_tracking_settings) { create(:project_error_tracking_setting, project: project) } + let_it_be(:issue_response_body) { fixture_file('sentry/issue_sample_response.json') } + let_it_be(:issue_response) { JSON.parse(issue_response_body) } + let_it_be(:event_response_body) { fixture_file('sentry/issue_latest_event_sample_response.json') } + let_it_be(:event_response) { JSON.parse(event_response_body) } + let(:sentry_api_urls) { Sentry::ApiUrls.new(project_error_tracking_settings.api_url) } + let(:issue_id) { issue_response['id'] } + + before do + request_headers = { 'Authorization' => 'Bearer access_token_123', 'Content-Type' => 'application/json' } + response_headers = { 'Content-Type' => 'application/json' } + issue_url = sentry_api_urls.issue_url(issue_id).to_s + stub_request(:get, issue_url) + .with(headers: request_headers) + .to_return(status: 200, body: issue_response_body, headers: response_headers) + event_url = sentry_api_urls.issue_latest_event_url(issue_id).to_s + stub_request(:get, event_url) + .with(headers: request_headers) + .to_return(status: 200, body: event_response_body, headers: response_headers) + end +end diff --git a/spec/support/shared_contexts/policies/project_policy_shared_context.rb b/spec/support/shared_contexts/policies/project_policy_shared_context.rb index 480c5a0fda0..29a64e9b559 100644 --- a/spec/support/shared_contexts/policies/project_policy_shared_context.rb +++ b/spec/support/shared_contexts/policies/project_policy_shared_context.rb @@ -13,7 +13,7 @@ RSpec.shared_context 'ProjectPolicy context' do %i[ read_project read_board read_list read_wiki read_issue read_project_for_iids read_issue_iid read_label - read_milestone read_project_snippet read_project_member read_note + read_milestone read_snippet read_project_member read_note create_project create_issue create_note upload_file create_merge_request_in award_emoji ] @@ -21,7 +21,7 @@ RSpec.shared_context 'ProjectPolicy context' do let(:base_reporter_permissions) do %i[ - download_code fork_project create_project_snippet update_issue + download_code fork_project create_snippet update_issue admin_issue admin_label admin_list read_commit_status read_build read_container_image read_pipeline read_environment read_deployment read_merge_request download_wiki_code read_sentry_issue read_prometheus @@ -45,8 +45,8 @@ RSpec.shared_context 'ProjectPolicy context' do let(:base_maintainer_permissions) do %i[ - push_to_delete_protected_branch update_project_snippet - admin_project_snippet admin_project_member admin_note admin_wiki admin_project + push_to_delete_protected_branch update_snippet + admin_snippet admin_project_member admin_note admin_wiki admin_project admin_commit_status admin_build admin_container_image admin_pipeline admin_environment admin_deployment destroy_release add_cluster daily_statistics diff --git a/spec/support/shared_examples/features/error_tracking_shared_example.rb b/spec/support/shared_examples/features/error_tracking_shared_example.rb new file mode 100644 index 00000000000..f53adece864 --- /dev/null +++ b/spec/support/shared_examples/features/error_tracking_shared_example.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +shared_examples 'error tracking index page' do + it 'renders the error index page' do + within('div.js-title-container') do + expect(page).to have_content(project.namespace.name) + expect(page).to have_content(project.name) + end + + within('div.error-list') do + expect(page).to have_content('Error') + expect(page).to have_content('Events') + expect(page).to have_content('Users') + expect(page).to have_content('Last Seen') + end + end + + it 'loads the error show page on click' do + click_on issues_response[0]['title'] + + wait_for_requests + + expect(page).to have_content('Error Details') + end + + it 'renders the error index data' do + Timecop.freeze(2020, 01, 01, 12, 0, 0) do + within('div.error-list') do + expect(page).to have_content(issues_response[0]['title']) + expect(page).to have_content(issues_response[0]['count'].to_s) + expect(page).to have_content(issues_response[0]['last_seen']) + expect(page).to have_content('1 year ago') + end + end + end +end + +shared_examples 'expanded stack trace context' do |selected_line: nil, expected_line: 1| + it 'expands the stack trace context' do + within('div.stacktrace') do + find("div.file-holder:nth-child(#{selected_line}) svg.ic-chevron-right").click if selected_line + + expanded_line = find("div.file-holder:nth-child(#{expected_line})") + expect(expanded_line).to have_css('svg.ic-chevron-down') + + event_response['entries'][0]['data']['values'][0]['stacktrace']['frames'][-expected_line]['context'].each do |context| + expect(page).to have_content(context[0]) + end + end + end +end + +shared_examples 'error tracking show page' do + it 'renders the error details' do + release_short_version = issue_response['firstRelease']['shortVersion'] + + Timecop.freeze(2020, 01, 01, 12, 0, 0) do + expect(page).to have_content('1 month ago by raven.scripts.runner in main') + expect(page).to have_content(issue_response['metadata']['title']) + expect(page).to have_content('level: error') + expect(page).to have_content('Error Details') + expect(page).to have_content('GitLab Issue: https://gitlab.com/gitlab-org/gitlab/issues/1') + expect(page).to have_content("Sentry event: https://sentrytest.gitlab.com/sentry-org/sentry-project/issues/#{issue_id}") + expect(page).to have_content("First seen: 1 year ago (2018-11-06 9:19:55PM UTC) Release: #{release_short_version}") + expect(page).to have_content('Events: 1') + expect(page).to have_content('Users: 0') + end + end + + it 'renders the stack trace heading' do + expect(page).to have_content('Stack trace') + end + + it 'renders the stack trace' do + event_response['entries'][0]['data']['values'][0]['stacktrace']['frames'].each do |frame| + expect(frame['filename']).not_to be_nil + expect(page).to have_content(frame['filename']) + end + end + + # The first line is expanded by default if no line is selected + it_behaves_like 'expanded stack trace context', selected_line: nil, expected_line: 1 + it_behaves_like 'expanded stack trace context', selected_line: 8, expected_line: 8 +end diff --git a/spec/support/shared_examples/finders/snippet_visibility_shared_examples.rb b/spec/support/shared_examples/finders/snippet_visibility_shared_examples.rb index e2089ee623a..98ab141ab26 100644 --- a/spec/support/shared_examples/finders/snippet_visibility_shared_examples.rb +++ b/spec/support/shared_examples/finders/snippet_visibility_shared_examples.rb @@ -234,8 +234,8 @@ RSpec.shared_examples 'snippet visibility' do end context "For #{params[:project_type]} project and #{params[:user_type]} users" do - it 'agrees with the read_project_snippet policy' do - expect(can?(user, :read_project_snippet, snippet)).to eq(outcome) + it 'agrees with the read_snippet policy' do + expect(can?(user, :read_snippet, snippet)).to eq(outcome) end it 'returns proper outcome' do @@ -297,8 +297,8 @@ RSpec.shared_examples 'snippet visibility' do let!(:snippet) { create(:personal_snippet, visibility_level: snippet_visibility, author: author) } context "For personal and #{params[:snippet_visibility]} snippets with #{params[:user_type]} user" do - it 'agrees with read_personal_snippet policy' do - expect(can?(user, :read_personal_snippet, snippet)).to eq(outcome) + it 'agrees with read_snippet policy' do + expect(can?(user, :read_snippet, snippet)).to eq(outcome) end it 'returns proper outcome' do |