diff options
Diffstat (limited to 'spec/presenters')
-rw-r--r-- | spec/presenters/ci/pipeline_presenter_spec.rb | 17 | ||||
-rw-r--r-- | spec/presenters/event_presenter_spec.rb | 30 | ||||
-rw-r--r-- | spec/presenters/merge_request_presenter_spec.rb | 21 | ||||
-rw-r--r-- | spec/presenters/projects/prometheus/alert_presenter_spec.rb | 346 | ||||
-rw-r--r-- | spec/presenters/sentry_error_presenter_spec.rb | 8 | ||||
-rw-r--r-- | spec/presenters/snippet_blob_presenter_spec.rb | 92 | ||||
-rw-r--r-- | spec/presenters/snippet_presenter_spec.rb | 21 |
7 files changed, 112 insertions, 423 deletions
diff --git a/spec/presenters/ci/pipeline_presenter_spec.rb b/spec/presenters/ci/pipeline_presenter_spec.rb index 18f79bc930c..5cb9d340e06 100644 --- a/spec/presenters/ci/pipeline_presenter_spec.rb +++ b/spec/presenters/ci/pipeline_presenter_spec.rb @@ -5,17 +5,20 @@ require 'spec_helper' RSpec.describe Ci::PipelinePresenter do include Gitlab::Routing - let(:user) { create(:user) } + let_it_be(:user) { create(:user) } + let_it_be_with_reload(:project) { create(:project, :test_repo) } + let_it_be_with_reload(:pipeline) { create(:ci_pipeline, project: project) } let(:current_user) { user } - let(:project) { create(:project, :test_repo) } - let(:pipeline) { create(:ci_pipeline, project: project) } subject(:presenter) do described_class.new(pipeline) end - before do + before_all do project.add_developer(user) + end + + before do allow(presenter).to receive(:current_user) { current_user } end @@ -184,8 +187,8 @@ RSpec.describe Ci::PipelinePresenter do describe '#all_related_merge_request_text' do subject { presenter.all_related_merge_request_text } - let(:mr_1) { create(:merge_request) } - let(:mr_2) { create(:merge_request) } + let_it_be(:mr_1) { create(:merge_request) } + let_it_be(:mr_2) { create(:merge_request) } context 'with zero related merge requests (branch pipeline)' do it { is_expected.to eq('No related merge requests found.') } @@ -242,7 +245,7 @@ RSpec.describe Ci::PipelinePresenter do end context 'permissions' do - let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline, source_project: project) } + let_it_be_with_refind(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline, source_project: project) } let(:pipeline) { merge_request.all_pipelines.take } shared_examples 'private merge requests' do diff --git a/spec/presenters/event_presenter_spec.rb b/spec/presenters/event_presenter_spec.rb index 6798be21d28..5a67fd92c9d 100644 --- a/spec/presenters/event_presenter_spec.rb +++ b/spec/presenters/event_presenter_spec.rb @@ -38,4 +38,34 @@ RSpec.describe EventPresenter do it { is_expected.to eq([project, target]) } end end + + describe '#target_type_name' do + it 'returns design for a design event' do + expect(build(:design_event).present).to have_attributes(target_type_name: 'design') + end + + it 'returns project for a project event' do + expect(build(:project_created_event).present).to have_attributes(target_type_name: 'project') + end + + it 'returns milestone for a milestone event' do + expect(group_event.present).to have_attributes(target_type_name: 'milestone') + end + end + + describe '#note_target_type_name' do + it 'returns design for an event on a comment on a design' do + expect(build(:event, :commented, :for_design).present) + .to have_attributes(note_target_type_name: 'design') + end + + it 'returns nil for an event without a target' do + expect(build(:event).present).to have_attributes(note_target_type_name: be_nil) + end + + it 'returns issue for an issue comment event' do + expect(build(:event, :commented, target: build(:note_on_issue)).present) + .to have_attributes(note_target_type_name: 'issue') + end + end end diff --git a/spec/presenters/merge_request_presenter_spec.rb b/spec/presenters/merge_request_presenter_spec.rb index f1e581efd44..76b77ee0de2 100644 --- a/spec/presenters/merge_request_presenter_spec.rb +++ b/spec/presenters/merge_request_presenter_spec.rb @@ -3,9 +3,9 @@ require 'spec_helper' RSpec.describe MergeRequestPresenter do - let(:resource) { create(:merge_request, source_project: project) } - let(:project) { create(:project) } - let(:user) { create(:user) } + let_it_be(:project) { create(:project, :repository) } + let_it_be(:resource) { create(:merge_request, source_project: project) } + let_it_be(:user) { create(:user) } describe '#ci_status' do subject { described_class.new(resource).ci_status } @@ -73,8 +73,6 @@ RSpec.describe MergeRequestPresenter do end describe '#conflict_resolution_path' do - let(:project) { create :project } - let(:user) { create :user } let(:presenter) { described_class.new(resource, current_user: user) } let(:path) { presenter.conflict_resolution_path } @@ -107,18 +105,21 @@ RSpec.describe MergeRequestPresenter do end context 'issues links' do - let(:project) { create(:project, :private, :repository, creator: user, namespace: user.namespace) } - let(:issue_a) { create(:issue, project: project) } - let(:issue_b) { create(:issue, project: project) } + let_it_be(:project) { create(:project, :private, :repository, creator: user, namespace: user.namespace) } + let_it_be(:issue_a) { create(:issue, project: project) } + let_it_be(:issue_b) { create(:issue, project: project) } - let(:resource) do + let_it_be(:resource) do create(:merge_request, source_project: project, target_project: project, description: "Fixes #{issue_a.to_reference} Related #{issue_b.to_reference}") end - before do + before_all do project.add_developer(user) + end + + before do allow(resource.project).to receive(:default_branch) .and_return(resource.target_branch) resource.cache_merge_request_closes_issues! diff --git a/spec/presenters/projects/prometheus/alert_presenter_spec.rb b/spec/presenters/projects/prometheus/alert_presenter_spec.rb deleted file mode 100644 index 98dba28829e..00000000000 --- a/spec/presenters/projects/prometheus/alert_presenter_spec.rb +++ /dev/null @@ -1,346 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Projects::Prometheus::AlertPresenter do - include Gitlab::Routing.url_helpers - - let_it_be(:project, reload: true) { create(:project) } - - let(:presenter) { described_class.new(alert) } - let(:payload) { {} } - let(:alert) { create(:alerting_alert, project: project, payload: payload) } - - shared_context 'gitlab alert' do - let(:gitlab_alert) { create(:prometheus_alert, project: project) } - let(:metric_id) { gitlab_alert.prometheus_metric_id } - - let(:alert) do - create(:alerting_alert, project: project, metric_id: metric_id, payload: payload) - end - end - - describe '#project_full_path' do - subject { presenter.project_full_path } - - it { is_expected.to eq(project.full_path) } - end - - describe '#start_time' do - subject { presenter.start_time } - - let(:starts_at) { '2020-10-31T14:02:04Z' } - - before do - payload['startsAt'] = starts_at - end - - context 'with valid utc datetime' do - it { is_expected.to eq('31 October 2020, 2:02PM (UTC)') } - - context 'with admin time zone not UTC' do - before do - allow(Time).to receive(:zone).and_return(ActiveSupport::TimeZone.new('Perth')) - end - - it { is_expected.to eq('31 October 2020, 2:02PM (UTC)') } - end - end - - context 'with invalid datetime' do - let(:starts_at) { 'invalid' } - - it { is_expected.to be_nil } - end - end - - describe '#issue_summary_markdown' do - let(:markdown_line_break) { ' ' } - - subject { presenter.issue_summary_markdown } - - context 'without default payload' do - it do - is_expected.to eq( - <<~MARKDOWN.chomp - **Start time:** #{presenter.start_time} - - MARKDOWN - ) - end - end - - context 'with optional attributes' do - before do - payload['annotations'] = { - 'title' => 'Alert Title', - 'foo' => 'value1', - 'bar' => 'value2', - 'description' => 'Alert Description', - 'monitoring_tool' => 'monitoring_tool_name', - 'service' => 'service_name', - 'hosts' => ['http://localhost:3000', 'http://localhost:3001'] - } - payload['generatorURL'] = 'http://host?g0.expr=query' - end - - it do - is_expected.to eq( - <<~MARKDOWN.chomp - **Start time:** #{presenter.start_time}#{markdown_line_break} - **full_query:** `query`#{markdown_line_break} - **Service:** service_name#{markdown_line_break} - **Monitoring tool:** monitoring_tool_name#{markdown_line_break} - **Hosts:** http://localhost:3000 http://localhost:3001 - - MARKDOWN - ) - end - end - - context 'when hosts is a string' do - before do - payload['annotations'] = { 'hosts' => 'http://localhost:3000' } - end - - it do - is_expected.to eq( - <<~MARKDOWN.chomp - **Start time:** #{presenter.start_time}#{markdown_line_break} - **Hosts:** http://localhost:3000 - - MARKDOWN - ) - end - end - - context 'with embedded metrics' do - let(:starts_at) { '2018-03-12T09:06:00Z' } - - shared_examples_for 'markdown with metrics embed' do - let(:embed_regex) { /\n\[\]\(#{Regexp.quote(presenter.metrics_dashboard_url)}\)\z/ } - - context 'without a starting time available' do - around do |example| - Timecop.freeze(starts_at) { example.run } - end - - before do - payload.delete('startsAt') - end - - it { is_expected.to match(embed_regex) } - end - - context 'with a starting time available' do - it { is_expected.to match(embed_regex) } - end - end - - context 'for gitlab-managed prometheus alerts' do - include_context 'gitlab-managed prometheus alert attributes' - - let(:alert) do - create(:alerting_alert, project: project, metric_id: prometheus_metric_id, payload: payload) - end - - it_behaves_like 'markdown with metrics embed' - end - - context 'for alerts from a self-managed prometheus' do - include_context 'self-managed prometheus alert attributes' - - it_behaves_like 'markdown with metrics embed' - - context 'without y_label' do - let(:y_label) { title } - - before do - payload['annotations'].delete('gitlab_y_label') - end - - it_behaves_like 'markdown with metrics embed' - end - - context 'when not enough information is present for an embed' do - shared_examples_for 'does not include an embed' do - it { is_expected.not_to match(/\[\]\(.+\)/) } - end - - context 'without title' do - before do - payload['annotations'].delete('title') - end - - it_behaves_like 'does not include an embed' - end - - context 'without environment' do - before do - payload['labels'].delete('gitlab_environment_name') - end - - it_behaves_like 'does not include an embed' - end - - context 'without full_query' do - before do - payload.delete('generatorURL') - end - - it_behaves_like 'does not include an embed' - end - end - end - end - end - - describe '#show_performance_dashboard_link?' do - subject { presenter.show_performance_dashboard_link? } - - it { is_expected.to be_falsey } - - context 'with gitlab alert' do - include_context 'gitlab alert' - - it { is_expected.to eq(true) } - end - end - - describe '#show_incident_issues_link?' do - subject { presenter.show_incident_issues_link? } - - it { is_expected.to be_falsey } - - context 'create issue setting enabled' do - before do - create(:project_incident_management_setting, project: project, create_issue: true) - end - - it { is_expected.to eq(true) } - end - end - - describe '#details_url' do - subject { presenter.details_url } - - it { is_expected.to eq(nil) } - - context 'alert management alert present' do - let_it_be(:am_alert) { create(:alert_management_alert, project: project) } - let(:alert) { create(:alerting_alert, project: project, payload: payload, am_alert: am_alert) } - - it { is_expected.to eq("http://localhost/#{project.full_path}/-/alert_management/#{am_alert.iid}/details") } - end - end - - context 'with gitlab alert' do - include_context 'gitlab alert' - - describe '#full_title' do - let(:query_title) do - "#{gitlab_alert.title} #{gitlab_alert.computed_operator} #{gitlab_alert.threshold} for 5 minutes" - end - - let(:expected_subject) do - "#{alert.environment.name}: #{query_title}" - end - - subject { presenter.full_title } - - it { is_expected.to eq(expected_subject) } - end - - describe '#metric_query' do - subject { presenter.metric_query } - - it { is_expected.to eq(gitlab_alert.full_query) } - end - - describe '#environment_name' do - subject { presenter.environment_name } - - it { is_expected.to eq(alert.environment.name) } - end - - describe '#performance_dashboard_link' do - let(:expected_link) { metrics_project_environment_url(project, alert.environment) } - - subject { presenter.performance_dashboard_link } - - it { is_expected.to eq(expected_link) } - end - - describe '#incident_issues_link' do - let(:expected_link) { project_issues_url(project, label_name: described_class::INCIDENT_LABEL_NAME) } - - subject { presenter.incident_issues_link } - - it { is_expected.to eq(expected_link) } - end - end - - context 'without gitlab alert' do - describe '#full_title' do - subject { presenter.full_title } - - context 'with title' do - let(:title) { 'some title' } - - before do - expect(alert).to receive(:title).and_return(title) - end - - it { is_expected.to eq(title) } - end - - context 'without title' do - it { is_expected.to eq('') } - end - end - - describe '#metric_query' do - subject { presenter.metric_query } - - it { is_expected.to be_nil } - end - - describe '#environment_name' do - subject { presenter.environment_name } - - it { is_expected.to be_nil } - end - - describe '#performance_dashboard_link' do - let(:expected_link) { metrics_project_environments_url(project) } - - subject { presenter.performance_dashboard_link } - - it { is_expected.to eq(expected_link) } - end - end - - describe '#metrics_dashboard_url' do - subject { presenter.metrics_dashboard_url } - - context 'for a non-prometheus alert' do - it { is_expected.to be_nil } - end - - context 'for a self-managed prometheus alert' do - include_context 'self-managed prometheus alert attributes' - - let(:prometheus_payload) { payload } - - it { is_expected.to eq(dashboard_url_for_alert) } - end - - context 'for a gitlab-managed prometheus alert' do - include_context 'gitlab-managed prometheus alert attributes' - - let(:prometheus_payload) { payload } - - it { is_expected.to eq(dashboard_url_for_alert) } - end - end -end diff --git a/spec/presenters/sentry_error_presenter_spec.rb b/spec/presenters/sentry_error_presenter_spec.rb index af9e7c8a2b2..86e43be1fa7 100644 --- a/spec/presenters/sentry_error_presenter_spec.rb +++ b/spec/presenters/sentry_error_presenter_spec.rb @@ -26,4 +26,12 @@ RSpec.describe SentryErrorPresenter do expect(count).to eq error.frequency.first[1] end end + + describe '#project_id' do + subject { presenter.project_id } + + it 'returns a global ID of the correct type' do + expect(subject).to eq(Gitlab::GlobalId.build(model_name: 'SentryProject', id: error.project_id).to_s) + end + end end diff --git a/spec/presenters/snippet_blob_presenter_spec.rb b/spec/presenters/snippet_blob_presenter_spec.rb index 915f43fe572..d7268c79a2c 100644 --- a/spec/presenters/snippet_blob_presenter_spec.rb +++ b/spec/presenters/snippet_blob_presenter_spec.rb @@ -3,70 +3,75 @@ require 'spec_helper' RSpec.describe SnippetBlobPresenter do + let_it_be(:snippet) { create(:personal_snippet, :repository) } + + let(:branch) { snippet.default_branch } + let(:blob) { snippet.blobs.first } + describe '#rich_data' do + let(:data_endpoint_url) { "/-/snippets/#{snippet.id}/raw/#{branch}/#{file}" } + before do allow_next_instance_of(described_class) do |instance| allow(instance).to receive(:current_user).and_return(nil) end + + blob.name = File.basename(file) + blob.path = file end - subject { described_class.new(snippet.blob).rich_data } + subject { described_class.new(blob).rich_data } context 'with PersonalSnippet' do - let(:snippet) { create(:personal_snippet, :repository) } - context 'when blob is binary' do - it 'returns the HTML associated with the binary' do - allow(snippet).to receive(:blob).and_return(snippet.repository.blob_at('master', 'files/images/logo-black.png')) + let(:file) { 'files/images/logo-black.png' } + let(:blob) { blob_at(file) } + it 'returns the HTML associated with the binary' do expect(subject).to include('file-content image_file') end end context 'with markdown format' do - let(:snippet) { create(:personal_snippet, file_name: 'test.md', content: '*foo*') } + let(:file) { 'README.md' } + let(:blob) { blob_at(file) } it 'returns rich markdown content' do - expected = <<~HTML - <div class="file-content md"> - <p data-sourcepos="1:1-1:5" dir="auto"><em>foo</em></p> - </div> - HTML - - expect(subject).to eq(expected) + expect(subject).to include('file-content md') end end context 'with notebook format' do - let(:snippet) { create(:personal_snippet, file_name: 'test.ipynb') } + let(:file) { 'test.ipynb' } it 'returns rich notebook content' do - expect(subject.strip).to eq %Q(<div class="file-content" data-endpoint="/-/snippets/#{snippet.id}/raw" id="js-notebook-viewer"></div>) + expect(subject.strip).to eq %Q(<div class="file-content" data-endpoint="#{data_endpoint_url}" id="js-notebook-viewer"></div>) end end context 'with openapi format' do - let(:snippet) { create(:personal_snippet, file_name: 'openapi.yml') } + let(:file) { 'openapi.yml' } it 'returns rich openapi content' do - expect(subject).to eq %Q(<div class="file-content" data-endpoint="/-/snippets/#{snippet.id}/raw" id="js-openapi-viewer"></div>\n) + expect(subject).to eq %Q(<div class="file-content" data-endpoint="#{data_endpoint_url}" id="js-openapi-viewer"></div>\n) end end context 'with svg format' do - let(:snippet) { create(:personal_snippet, file_name: 'test.svg') } + let(:file) { 'files/images/wm.svg' } + let(:blob) { blob_at(file) } it 'returns rich svg content' do result = Nokogiri::HTML::DocumentFragment.parse(subject) image_tag = result.search('img').first - expect(image_tag.attr('src')).to include("data:#{snippet.blob.mime_type};base64") - expect(image_tag.attr('alt')).to eq('test.svg') + expect(image_tag.attr('src')).to include("data:#{blob.mime_type};base64") + expect(image_tag.attr('alt')).to eq(File.basename(file)) end end context 'with other format' do - let(:snippet) { create(:personal_snippet, file_name: 'test') } + let(:file) { 'test' } it 'does not return no rich content' do expect(subject).to be_nil @@ -76,36 +81,41 @@ RSpec.describe SnippetBlobPresenter do end describe '#plain_data' do - let(:snippet) { build(:personal_snippet) } + let(:blob) { blob_at(file) } - subject { described_class.new(snippet.blob).plain_data } + subject { described_class.new(blob).plain_data } - it 'returns nil when the snippet blob is binary' do - allow(snippet.blob).to receive(:binary?).and_return(true) + context 'when blob is binary' do + let(:file) { 'files/images/logo-black.png' } - expect(subject).to be_nil + it 'returns nil' do + expect(subject).to be_nil + end end - it 'returns plain content when snippet file is markup' do - snippet.file_name = 'test.md' - snippet.content = '*foo*' + context 'when blob is markup' do + let(:file) { 'README.md' } - expect(subject).to eq '<span id="LC1" class="line" lang="markdown"><span class="ge">*foo*</span></span>' + it 'returns plain content' do + expect(subject).to include('<span id="LC1" class="line" lang="markdown">') + end end - it 'returns highlighted syntax content' do - snippet.file_name = 'test.rb' - snippet.content = 'class Foo;end' + context 'when blob has syntax' do + let(:file) { 'files/ruby/regex.rb' } - expect(subject) - .to eq '<span id="LC1" class="line" lang="ruby"><span class="k">class</span> <span class="nc">Foo</span><span class="p">;</span><span class="k">end</span></span>' + it 'returns highlighted syntax content' do + expect(subject) + .to include '<span id="LC1" class="line" lang="ruby"><span class="k">module</span> <span class="nn">Gitlab</span>' + end end - it 'returns plain text highlighted content' do - snippet.file_name = 'test' - snippet.content = 'foo' + context 'when blob has plain data' do + let(:file) { 'LICENSE' } - expect(subject).to eq '<span id="LC1" class="line" lang="plaintext">foo</span>' + it 'returns plain text highlighted content' do + expect(subject).to include('<span id="LC1" class="line" lang="plaintext">The MIT License (MIT)</span>') + end end end @@ -179,4 +189,8 @@ RSpec.describe SnippetBlobPresenter do end end end + + def blob_at(path) + snippet.repository.blob_at(branch, path) + end end diff --git a/spec/presenters/snippet_presenter_spec.rb b/spec/presenters/snippet_presenter_spec.rb index 681564ed2b0..66c6ba8fa0e 100644 --- a/spec/presenters/snippet_presenter_spec.rb +++ b/spec/presenters/snippet_presenter_spec.rb @@ -163,25 +163,4 @@ RSpec.describe SnippetPresenter do end end end - - describe '#blobs' do - let(:snippet) { personal_snippet } - - subject { presenter.blobs } - - context 'when snippet does not have a repository' do - it 'returns an array with one SnippetBlob' do - expect(subject.size).to eq(1) - expect(subject.first).to eq(snippet.blob) - end - end - - context 'when snippet has a repository' do - let(:snippet) { create(:snippet, :repository, author: user) } - - it 'returns an array with all repository blobs' do - expect(subject).to match_array(snippet.blobs) - end - end - end end |