diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 07:08:36 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 07:08:36 +0000 |
commit | 48aff82709769b098321c738f3444b9bdaa694c6 (patch) | |
tree | e00c7c43e2d9b603a5a6af576b1685e400410dee /spec/presenters | |
parent | 879f5329ee916a948223f8f43d77fba4da6cd028 (diff) | |
download | gitlab-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.rb | 17 | ||||
-rw-r--r-- | spec/presenters/event_presenter_spec.rb | 30 | ||||
-rw-r--r-- | spec/presenters/label_presenter_spec.rb | 14 | ||||
-rw-r--r-- | spec/presenters/merge_request_presenter_spec.rb | 21 | ||||
-rw-r--r-- | spec/presenters/packages/detail/package_presenter_spec.rb | 2 | ||||
-rw-r--r-- | spec/presenters/project_presenter_spec.rb | 51 | ||||
-rw-r--r-- | spec/presenters/projects/prometheus/alert_presenter_spec.rb | 346 | ||||
-rw-r--r-- | spec/presenters/release_presenter_spec.rb | 8 | ||||
-rw-r--r-- | spec/presenters/sentry_error_presenter_spec.rb | 8 | ||||
-rw-r--r-- | spec/presenters/snippet_blob_presenter_spec.rb | 122 | ||||
-rw-r--r-- | spec/presenters/snippet_presenter_spec.rb | 21 |
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 |