summaryrefslogtreecommitdiff
path: root/spec/presenters
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-10-21 07:08:36 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-10-21 07:08:36 +0000
commit48aff82709769b098321c738f3444b9bdaa694c6 (patch)
treee00c7c43e2d9b603a5a6af576b1685e400410dee /spec/presenters
parent879f5329ee916a948223f8f43d77fba4da6cd028 (diff)
downloadgitlab-ce-48aff82709769b098321c738f3444b9bdaa694c6.tar.gz
Add latest changes from gitlab-org/gitlab@13-5-stable-eev13.5.0-rc42
Diffstat (limited to 'spec/presenters')
-rw-r--r--spec/presenters/ci/pipeline_presenter_spec.rb17
-rw-r--r--spec/presenters/event_presenter_spec.rb30
-rw-r--r--spec/presenters/label_presenter_spec.rb14
-rw-r--r--spec/presenters/merge_request_presenter_spec.rb21
-rw-r--r--spec/presenters/packages/detail/package_presenter_spec.rb2
-rw-r--r--spec/presenters/project_presenter_spec.rb51
-rw-r--r--spec/presenters/projects/prometheus/alert_presenter_spec.rb346
-rw-r--r--spec/presenters/release_presenter_spec.rb8
-rw-r--r--spec/presenters/sentry_error_presenter_spec.rb8
-rw-r--r--spec/presenters/snippet_blob_presenter_spec.rb122
-rw-r--r--spec/presenters/snippet_presenter_spec.rb21
11 files changed, 185 insertions, 455 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/label_presenter_spec.rb b/spec/presenters/label_presenter_spec.rb
index cb6e991bd8e..44c68a6102f 100644
--- a/spec/presenters/label_presenter_spec.rb
+++ b/spec/presenters/label_presenter_spec.rb
@@ -91,4 +91,18 @@ RSpec.describe LabelPresenter do
it { is_expected.to eq(label.project.name) }
end
end
+
+ describe '#subject_full_name' do
+ context 'with group label' do
+ subject { group_label.subject_full_name }
+
+ it { is_expected.to eq(group_label.group.full_name) }
+ end
+
+ context 'with project label' do
+ subject { label.subject_full_name }
+
+ it { is_expected.to eq(label.project.full_name) }
+ 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/packages/detail/package_presenter_spec.rb b/spec/presenters/packages/detail/package_presenter_spec.rb
index 3a13aca6c7a..8ece27e9b5f 100644
--- a/spec/presenters/packages/detail/package_presenter_spec.rb
+++ b/spec/presenters/packages/detail/package_presenter_spec.rb
@@ -76,7 +76,7 @@ RSpec.describe ::Packages::Detail::PackagePresenter do
context 'with conan metadata' do
let(:package) { create(:conan_package, project: project) }
- let(:expected_package_details) { super().merge(conan_metadatum: package.conan_metadatum) }
+ let(:expected_package_details) { super().merge(conan_metadatum: package.conan_metadatum, conan_package_name: package.name, name: package.conan_recipe) }
it 'returns conan_metadatum' do
expect(presenter.detail_view).to eq expected_package_details
diff --git a/spec/presenters/project_presenter_spec.rb b/spec/presenters/project_presenter_spec.rb
index 4b4d8ee85db..b7fee5253f8 100644
--- a/spec/presenters/project_presenter_spec.rb
+++ b/spec/presenters/project_presenter_spec.rb
@@ -38,14 +38,33 @@ RSpec.describe ProjectPresenter do
context 'when repository is empty' do
let_it_be(:project) { create(:project_empty_repo, :public) }
- it 'returns activity if user has repository access' do
+ it 'returns wiki if user has repository access and can read wiki, which exists' do
+ allow(project).to receive(:wiki_repository_exists?).and_return(true)
allow(presenter).to receive(:can?).with(nil, :download_code, project).and_return(true)
+ allow(presenter).to receive(:can?).with(nil, :read_wiki, project).and_return(true)
+ allow(presenter).to receive(:can?).with(nil, :read_issue, project).and_return(false)
+
+ expect(presenter.default_view).to eq('wiki')
+ end
+
+ it 'returns activity if user has repository access and can read wiki, which does not exist' do
+ allow(presenter).to receive(:can?).with(nil, :download_code, project).and_return(true)
+ allow(presenter).to receive(:can?).with(nil, :read_wiki, project).and_return(true)
+ allow(presenter).to receive(:can?).with(nil, :read_issue, project).and_return(false)
expect(presenter.default_view).to eq('activity')
end
- it 'returns activity if user does not have repository access' do
- allow(project).to receive(:can?).with(nil, :download_code, project).and_return(false)
+ it 'returns issues if user does not have repository access, but can read issues' do
+ allow(presenter).to receive(:can?).with(nil, :download_code, project).and_return(false)
+ allow(presenter).to receive(:can?).with(nil, :read_issue, project).and_call_original
+
+ expect(presenter.default_view).to eq('projects/issues/issues')
+ end
+
+ it 'returns activity if user can read neither wiki nor issues' do
+ allow(presenter).to receive(:can?).with(nil, :download_code, project).and_return(false)
+ allow(presenter).to receive(:can?).with(nil, :read_issue, project).and_return(false)
expect(presenter.default_view).to eq('activity')
end
@@ -61,8 +80,18 @@ RSpec.describe ProjectPresenter do
expect(presenter.default_view).to eq('files')
end
- it 'returns activity if user does not have repository access' do
+ it 'returns wiki if user does not have repository access and can read wiki, which exists' do
+ allow(project).to receive(:wiki_repository_exists?).and_return(true)
allow(presenter).to receive(:can?).with(nil, :download_code, project).and_return(false)
+ allow(presenter).to receive(:can?).with(nil, :read_wiki, project).and_return(true)
+
+ expect(presenter.default_view).to eq('wiki')
+ end
+
+ it 'returns activity if user does not have repository or wiki access' do
+ allow(presenter).to receive(:can?).with(nil, :download_code, project).and_return(false)
+ allow(presenter).to receive(:can?).with(nil, :read_issue, project).and_return(false)
+ allow(presenter).to receive(:can?).with(nil, :read_wiki, project).and_return(false)
expect(presenter.default_view).to eq('activity')
end
@@ -96,22 +125,25 @@ RSpec.describe ProjectPresenter do
allow(presenter).to receive(:can?).with(user, :download_code, project).and_return(false)
end
- it 'returns wiki if the user has the right policy' do
+ it 'returns wiki if the user has the right policy and the wiki exists' do
+ allow(project).to receive(:wiki_repository_exists?).and_return(true)
allow(presenter).to receive(:can?).with(user, :read_wiki, project).and_return(true)
expect(presenter.default_view).to eq('wiki')
end
- it 'returns customize_workflow if the user does not have the right policy' do
+ it 'returns activity if the user does not have the right policy' do
allow(presenter).to receive(:can?).with(user, :read_wiki, project).and_return(false)
+ allow(presenter).to receive(:can?).with(user, :read_issue, project).and_return(false)
- expect(presenter.default_view).to eq('customize_workflow')
+ expect(presenter.default_view).to eq('activity')
end
end
context 'with issues as a feature available' do
it 'return issues' do
allow(presenter).to receive(:can?).with(user, :download_code, project).and_return(false)
+ allow(presenter).to receive(:can?).with(user, :read_issue, project).and_return(true)
allow(presenter).to receive(:can?).with(user, :read_wiki, project).and_return(false)
expect(presenter.default_view).to eq('projects/issues/issues')
@@ -119,12 +151,13 @@ RSpec.describe ProjectPresenter do
end
context 'with no activity, no wikies and no issues' do
- it 'returns customize_workflow as default' do
+ it 'returns activity as default' do
project.project_feature.update_attribute(:issues_access_level, 0)
allow(presenter).to receive(:can?).with(user, :download_code, project).and_return(false)
allow(presenter).to receive(:can?).with(user, :read_wiki, project).and_return(false)
+ allow(presenter).to receive(:can?).with(user, :read_issue, project).and_return(false)
- expect(presenter.default_view).to eq('customize_workflow')
+ expect(presenter.default_view).to eq('activity')
end
end
end
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/release_presenter_spec.rb b/spec/presenters/release_presenter_spec.rb
index 5577b3ad2e8..eb4d755205b 100644
--- a/spec/presenters/release_presenter_spec.rb
+++ b/spec/presenters/release_presenter_spec.rb
@@ -57,14 +57,6 @@ RSpec.describe ReleasePresenter do
it 'returns its own url' do
is_expected.to match /#{project_release_url(project, release)}/
end
-
- context 'when release_show_page feature flag is disabled' do
- before do
- stub_feature_flags(release_show_page: false)
- end
-
- it { is_expected.to be_nil }
- end
end
describe '#merge_requests_url' do
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..83fe37effc0 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
@@ -115,40 +125,42 @@ RSpec.describe SnippetBlobPresenter do
let_it_be(:personal_snippet) { create(:personal_snippet, :repository, author: user) }
let_it_be(:project_snippet) { create(:project_snippet, :repository, project: project, author: user) }
+ let(:blob) { snippet.blobs.first }
+
before do
project.add_developer(user)
end
describe '#raw_path' do
- subject { described_class.new(snippet.blobs.first, current_user: user).raw_path }
+ subject { described_class.new(blob, current_user: user).raw_path }
it_behaves_like 'snippet blob raw path'
- context 'with snippet_multiple_files feature disabled' do
- before do
- stub_feature_flags(snippet_multiple_files: false)
- end
+ context 'with a snippet without a repository' do
+ let(:personal_snippet) { build(:personal_snippet, author: user, id: 1) }
+ let(:project_snippet) { build(:project_snippet, project: project, author: user, id: 1) }
+ let(:blob) { snippet.blob }
context 'with ProjectSnippet' do
let(:snippet) { project_snippet }
- it 'returns the raw path' do
- expect(subject).to eq "/#{snippet.project.full_path}/-/snippets/#{snippet.id}/raw"
+ it 'returns the raw project snippet path' do
+ expect(subject).to eq("/#{project_snippet.project.full_path}/-/snippets/#{project_snippet.id}/raw")
end
end
context 'with PersonalSnippet' do
let(:snippet) { personal_snippet }
- it 'returns the raw path' do
- expect(subject).to eq "/-/snippets/#{snippet.id}/raw"
+ it 'returns the raw personal snippet path' do
+ expect(subject).to eq("/-/snippets/#{personal_snippet.id}/raw")
end
end
end
end
describe '#raw_url' do
- subject { described_class.new(snippet.blobs.first, current_user: user).raw_url }
+ subject { described_class.new(blob, current_user: user).raw_url }
before do
stub_default_url_options(host: 'test.host')
@@ -156,10 +168,10 @@ RSpec.describe SnippetBlobPresenter do
it_behaves_like 'snippet blob raw url'
- context 'with snippet_multiple_files feature disabled' do
- before do
- stub_feature_flags(snippet_multiple_files: false)
- end
+ context 'with a snippet without a repository' do
+ let(:personal_snippet) { build(:personal_snippet, author: user, id: 1) }
+ let(:project_snippet) { build(:project_snippet, project: project, author: user, id: 1) }
+ let(:blob) { snippet.blob }
context 'with ProjectSnippet' do
let(:snippet) { project_snippet }
@@ -179,4 +191,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