summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouwe Maan <douwe@selenight.nl>2017-05-02 17:42:37 -0500
committerDouwe Maan <douwe@selenight.nl>2017-05-04 08:50:12 -0500
commit0f58eb6bde35009b69ef871534d9ff80fc38bbf7 (patch)
tree0a5065d9fc05822a81a9379f5a6a64f8105f9503
parent4faa65d8381f3e1e45bdf3a9bc9785b588891b66 (diff)
downloadgitlab-ce-dm-artifact-blob-viewer.tar.gz
Add artifact file page that uses the blob viewerdm-artifact-blob-viewer
-rw-r--r--app/assets/javascripts/dispatcher.js3
-rw-r--r--app/controllers/projects/artifacts_controller.rb28
-rw-r--r--app/helpers/blob_helper.rb6
-rw-r--r--app/helpers/gitlab_routing_helper.rb2
-rw-r--r--app/models/ci/artifact_blob.rb35
-rw-r--r--app/views/projects/artifacts/_tree_file.html.haml9
-rw-r--r--app/views/projects/artifacts/file.html.haml33
-rw-r--r--changelogs/unreleased/dm-artifact-blob-viewer.yml4
-rw-r--r--config/routes/project.rb1
-rw-r--r--features/project/builds/artifacts.feature3
-rw-r--r--features/steps/project/builds/artifacts.rb15
-rw-r--r--lib/gitlab/ci/build/artifacts/metadata/entry.rb6
-rw-r--r--spec/controllers/projects/artifacts_controller_spec.rb188
-rw-r--r--spec/features/projects/artifacts/file_spec.rb59
-rw-r--r--spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb11
-rw-r--r--spec/models/ci/artifact_blob_spec.rb44
-rw-r--r--spec/requests/projects/artifacts_controller_spec.rb117
17 files changed, 425 insertions, 139 deletions
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 0bdce52cc89..7e469153106 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -344,6 +344,9 @@ const ShortcutsBlob = require('./shortcuts_blob');
case 'projects:artifacts:browse':
new BuildArtifacts();
break;
+ case 'projects:artifacts:file':
+ new BlobViewer();
+ break;
case 'help:index':
gl.VersionCheckImage.bindErrorEvent($('img.js-version-status-badge'));
break;
diff --git a/app/controllers/projects/artifacts_controller.rb b/app/controllers/projects/artifacts_controller.rb
index a13588b4218..1224e9503c9 100644
--- a/app/controllers/projects/artifacts_controller.rb
+++ b/app/controllers/projects/artifacts_controller.rb
@@ -1,11 +1,13 @@
class Projects::ArtifactsController < Projects::ApplicationController
include ExtractsPath
+ include RendersBlob
layout 'project'
before_action :authorize_read_build!
before_action :authorize_update_build!, only: [:keep]
before_action :extract_ref_name_and_path
before_action :validate_artifacts!
+ before_action :set_path_and_entry, only: [:file, :raw]
def download
if artifacts_file.file_storage?
@@ -24,15 +26,24 @@ class Projects::ArtifactsController < Projects::ApplicationController
end
def file
- entry = build.artifacts_metadata_entry(params[:path])
+ blob = @entry.blob
+ override_max_blob_size(blob)
- if entry.exists?
- send_artifacts_entry(build, entry)
- else
- render_404
+ respond_to do |format|
+ format.html do
+ render 'file'
+ end
+
+ format.json do
+ render_blob_json(blob)
+ end
end
end
+ def raw
+ send_artifacts_entry(build, @entry)
+ end
+
def keep
build.keep_artifacts!
redirect_to namespace_project_build_path(project.namespace, project, build)
@@ -81,4 +92,11 @@ class Projects::ArtifactsController < Projects::ApplicationController
def artifacts_file
@artifacts_file ||= build.artifacts_file
end
+
+ def set_path_and_entry
+ @path = params[:path]
+ @entry = build.artifacts_metadata_entry(@path)
+
+ render_404 unless @entry.exists?
+ end
end
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 37b6f4ad5cc..af430270ae4 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -119,7 +119,9 @@ module BlobHelper
end
def blob_raw_url
- if @snippet
+ if @build && @entry
+ raw_namespace_project_build_artifacts_path(@project.namespace, @project, @build, path: @entry.path)
+ elsif @snippet
if @snippet.project_id
raw_namespace_project_snippet_path(@project.namespace, @project, @snippet)
else
@@ -250,6 +252,8 @@ module BlobHelper
case viewer.blob.external_storage
when :lfs
'it is stored in LFS'
+ when :build_artifact
+ 'it is stored as a job artifact'
else
'it is stored externally'
end
diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb
index e9b7cbbad6a..1336c676134 100644
--- a/app/helpers/gitlab_routing_helper.rb
+++ b/app/helpers/gitlab_routing_helper.rb
@@ -208,6 +208,8 @@ module GitlabRoutingHelper
browse_namespace_project_build_artifacts_path(*args)
when 'file'
file_namespace_project_build_artifacts_path(*args)
+ when 'raw'
+ raw_namespace_project_build_artifacts_path(*args)
end
end
diff --git a/app/models/ci/artifact_blob.rb b/app/models/ci/artifact_blob.rb
new file mode 100644
index 00000000000..b35febc9ac5
--- /dev/null
+++ b/app/models/ci/artifact_blob.rb
@@ -0,0 +1,35 @@
+module Ci
+ class ArtifactBlob
+ include BlobLike
+
+ attr_reader :entry
+
+ def initialize(entry)
+ @entry = entry
+ end
+
+ delegate :name, :path, to: :entry
+
+ def id
+ Digest::SHA1.hexdigest(path)
+ end
+
+ def size
+ entry.metadata[:size]
+ end
+
+ def data
+ "Build artifact #{path}"
+ end
+
+ def mode
+ entry.metadata[:mode]
+ end
+
+ def external_storage
+ :build_artifact
+ end
+
+ alias_method :external_size, :size
+ end
+end
diff --git a/app/views/projects/artifacts/_tree_file.html.haml b/app/views/projects/artifacts/_tree_file.html.haml
index 36fb4c998c9..ce7e25d774b 100644
--- a/app/views/projects/artifacts/_tree_file.html.haml
+++ b/app/views/projects/artifacts/_tree_file.html.haml
@@ -1,9 +1,10 @@
- path_to_file = file_namespace_project_build_artifacts_path(@project.namespace, @project, @build, path: file.path)
%tr.tree-item{ 'data-link' => path_to_file }
+ - blob = file.blob
%td.tree-item-file-name
- = tree_icon('file', '664', file.name)
- %span.str-truncated
- = link_to file.name, path_to_file
+ = tree_icon('file', blob.mode, blob.name)
+ = link_to path_to_file do
+ %span.str-truncated= blob.name
%td
- = number_to_human_size(file.metadata[:size], precision: 2)
+ = number_to_human_size(blob.size, precision: 2)
diff --git a/app/views/projects/artifacts/file.html.haml b/app/views/projects/artifacts/file.html.haml
new file mode 100644
index 00000000000..d8da83b9a80
--- /dev/null
+++ b/app/views/projects/artifacts/file.html.haml
@@ -0,0 +1,33 @@
+- page_title @path, 'Artifacts', "#{@build.name} (##{@build.id})", 'Jobs'
+= render "projects/pipelines/head"
+
+= render "projects/builds/header", show_controls: false
+
+#tree-holder.tree-holder
+ .nav-block
+ %ul.breadcrumb.repo-breadcrumb
+ %li
+ = link_to 'Artifacts', browse_namespace_project_build_artifacts_path(@project.namespace, @project, @build)
+ - path_breadcrumbs do |title, path|
+ - title = truncate(title, length: 40)
+ %li
+ - if path == @path
+ = link_to file_namespace_project_build_artifacts_path(@project.namespace, @project, @build, path) do
+ %strong= title
+ - else
+ = link_to title, browse_namespace_project_build_artifacts_path(@project.namespace, @project, @build, path)
+
+
+ %article.file-holder
+ - blob = @entry.blob
+ .js-file-title.file-title-flex-parent
+ = render 'projects/blob/header_content', blob: blob
+
+ .file-actions.hidden-xs
+ = render 'projects/blob/viewer_switcher', blob: blob
+
+ .btn-group{ role: "group" }<
+ = copy_blob_source_button(blob)
+ = open_raw_blob_button(blob)
+
+ = render 'projects/blob/content', blob: blob
diff --git a/changelogs/unreleased/dm-artifact-blob-viewer.yml b/changelogs/unreleased/dm-artifact-blob-viewer.yml
new file mode 100644
index 00000000000..38f5cbb73e1
--- /dev/null
+++ b/changelogs/unreleased/dm-artifact-blob-viewer.yml
@@ -0,0 +1,4 @@
+---
+title: Add artifact file page that uses the blob viewer
+merge_request:
+author:
diff --git a/config/routes/project.rb b/config/routes/project.rb
index a15e365cc2f..5aba469b6e4 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -183,6 +183,7 @@ constraints(ProjectUrlConstrainer.new) do
get :download
get :browse, path: 'browse(/*path)', format: false
get :file, path: 'file/*path', format: false
+ get :raw, path: 'raw/*path', format: false
post :keep
end
end
diff --git a/features/project/builds/artifacts.feature b/features/project/builds/artifacts.feature
index 09094d638c9..5abc24949cf 100644
--- a/features/project/builds/artifacts.feature
+++ b/features/project/builds/artifacts.feature
@@ -46,13 +46,14 @@ Feature: Project Builds Artifacts
And I navigate to parent directory of directory with invalid name
Then I should not see directory with invalid name on the list
+ @javascript
Scenario: I download a single file from build artifacts
Given recent build has artifacts available
And recent build has artifacts metadata available
When I visit recent build details page
And I click artifacts browse button
And I click a link to file within build artifacts
- Then download of a file extracted from build artifacts should start
+ Then I see a download link
@javascript
Scenario: I click on a row in an artifacts table
diff --git a/features/steps/project/builds/artifacts.rb b/features/steps/project/builds/artifacts.rb
index 3ec5c8e2f4f..eec375b0532 100644
--- a/features/steps/project/builds/artifacts.rb
+++ b/features/steps/project/builds/artifacts.rb
@@ -3,6 +3,7 @@ class Spinach::Features::ProjectBuildsArtifacts < Spinach::FeatureSteps
include SharedProject
include SharedBuilds
include RepoHelpers
+ include WaitForAjax
step 'I click artifacts download button' do
click_link 'Download'
@@ -78,19 +79,11 @@ class Spinach::Features::ProjectBuildsArtifacts < Spinach::FeatureSteps
step 'I click a link to file within build artifacts' do
page.within('.tree-table') { find_link('ci_artifacts.txt').click }
+ wait_for_ajax
end
- step 'download of a file extracted from build artifacts should start' do
- send_data = response_headers[Gitlab::Workhorse::SEND_DATA_HEADER]
-
- expect(send_data).to start_with('artifacts-entry:')
-
- base64_params = send_data.sub(/\Aartifacts\-entry:/, '')
- params = JSON.parse(Base64.urlsafe_decode64(base64_params))
-
- expect(params.keys).to eq(%w(Archive Entry))
- expect(params['Archive']).to end_with('build_artifacts.zip')
- expect(params['Entry']).to eq(Base64.encode64('ci_artifacts.txt'))
+ step 'I see a download link' do
+ expect(page).to have_link 'download it'
end
step 'I click a first row within build artifacts table' do
diff --git a/lib/gitlab/ci/build/artifacts/metadata/entry.rb b/lib/gitlab/ci/build/artifacts/metadata/entry.rb
index 6f799c2f031..2e073334abc 100644
--- a/lib/gitlab/ci/build/artifacts/metadata/entry.rb
+++ b/lib/gitlab/ci/build/artifacts/metadata/entry.rb
@@ -37,6 +37,12 @@ module Gitlab
!directory?
end
+ def blob
+ return unless file?
+
+ @blob ||= Blob.decorate(::Ci::ArtifactBlob.new(self), nil)
+ end
+
def has_parent?
nodes > 0
end
diff --git a/spec/controllers/projects/artifacts_controller_spec.rb b/spec/controllers/projects/artifacts_controller_spec.rb
new file mode 100644
index 00000000000..eff9fab8da2
--- /dev/null
+++ b/spec/controllers/projects/artifacts_controller_spec.rb
@@ -0,0 +1,188 @@
+require 'spec_helper'
+
+describe Projects::ArtifactsController do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository) }
+
+ let(:pipeline) do
+ create(:ci_pipeline,
+ project: project,
+ sha: project.commit.sha,
+ ref: project.default_branch,
+ status: 'success')
+ end
+
+ let(:build) { create(:ci_build, :success, :artifacts, pipeline: pipeline) }
+
+ before do
+ project.team << [user, :developer]
+
+ sign_in(user)
+ end
+
+ describe 'GET download' do
+ it 'sends the artifacts file' do
+ expect(controller).to receive(:send_file).with(build.artifacts_file.path, disposition: 'attachment').and_call_original
+
+ get :download, namespace_id: project.namespace, project_id: project, build_id: build
+ end
+ end
+
+ describe 'GET browse' do
+ context 'when the directory exists' do
+ it 'renders the browse view' do
+ get :browse, namespace_id: project.namespace, project_id: project, build_id: build, path: 'other_artifacts_0.1.2'
+
+ expect(response).to render_template('projects/artifacts/browse')
+ end
+ end
+
+ context 'when the directory does not exist' do
+ it 'responds Not Found' do
+ get :browse, namespace_id: project.namespace, project_id: project, build_id: build, path: 'unknown'
+
+ expect(response).to be_not_found
+ end
+ end
+ end
+
+ describe 'GET file' do
+ context 'when the file exists' do
+ it 'renders the file view' do
+ get :file, namespace_id: project.namespace, project_id: project, build_id: build, path: 'ci_artifacts.txt'
+
+ expect(response).to render_template('projects/artifacts/file')
+ end
+ end
+
+ context 'when the file does not exist' do
+ it 'responds Not Found' do
+ get :file, namespace_id: project.namespace, project_id: project, build_id: build, path: 'unknown'
+
+ expect(response).to be_not_found
+ end
+ end
+ end
+
+ describe 'GET raw' do
+ context 'when the file exists' do
+ it 'serves the file using workhorse' do
+ get :raw, namespace_id: project.namespace, project_id: project, build_id: build, path: 'ci_artifacts.txt'
+
+ send_data = response.headers[Gitlab::Workhorse::SEND_DATA_HEADER]
+
+ expect(send_data).to start_with('artifacts-entry:')
+
+ base64_params = send_data.sub(/\Aartifacts\-entry:/, '')
+ params = JSON.parse(Base64.urlsafe_decode64(base64_params))
+
+ expect(params.keys).to eq(%w(Archive Entry))
+ expect(params['Archive']).to end_with('build_artifacts.zip')
+ expect(params['Entry']).to eq(Base64.encode64('ci_artifacts.txt'))
+ end
+ end
+
+ context 'when the file does not exist' do
+ it 'responds Not Found' do
+ get :raw, namespace_id: project.namespace, project_id: project, build_id: build, path: 'unknown'
+
+ expect(response).to be_not_found
+ end
+ end
+ end
+
+ describe 'GET latest_succeeded' do
+ def params_from_ref(ref = pipeline.ref, job = build.name, path = 'browse')
+ {
+ namespace_id: project.namespace,
+ project_id: project,
+ ref_name_and_path: File.join(ref, path),
+ job: job
+ }
+ end
+
+ context 'cannot find the build' do
+ shared_examples 'not found' do
+ it { expect(response).to have_http_status(:not_found) }
+ end
+
+ context 'has no such ref' do
+ before do
+ get :latest_succeeded, params_from_ref('TAIL', build.name)
+ end
+
+ it_behaves_like 'not found'
+ end
+
+ context 'has no such build' do
+ before do
+ get :latest_succeeded, params_from_ref(pipeline.ref, 'NOBUILD')
+ end
+
+ it_behaves_like 'not found'
+ end
+
+ context 'has no path' do
+ before do
+ get :latest_succeeded, params_from_ref(pipeline.sha, build.name, '')
+ end
+
+ it_behaves_like 'not found'
+ end
+ end
+
+ context 'found the build and redirect' do
+ shared_examples 'redirect to the build' do
+ it 'redirects' do
+ path = browse_namespace_project_build_artifacts_path(
+ project.namespace,
+ project,
+ build)
+
+ expect(response).to redirect_to(path)
+ end
+ end
+
+ context 'with regular branch' do
+ before do
+ pipeline.update(ref: 'master',
+ sha: project.commit('master').sha)
+
+ get :latest_succeeded, params_from_ref('master')
+ end
+
+ it_behaves_like 'redirect to the build'
+ end
+
+ context 'with branch name containing slash' do
+ before do
+ pipeline.update(ref: 'improve/awesome',
+ sha: project.commit('improve/awesome').sha)
+
+ get :latest_succeeded, params_from_ref('improve/awesome')
+ end
+
+ it_behaves_like 'redirect to the build'
+ end
+
+ context 'with branch name and path containing slashes' do
+ before do
+ pipeline.update(ref: 'improve/awesome',
+ sha: project.commit('improve/awesome').sha)
+
+ get :latest_succeeded, params_from_ref('improve/awesome', build.name, 'file/README.md')
+ end
+
+ it 'redirects' do
+ path = file_namespace_project_build_artifacts_path(
+ project.namespace,
+ project,
+ build,
+ 'README.md')
+
+ expect(response).to redirect_to(path)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/artifacts/file_spec.rb b/spec/features/projects/artifacts/file_spec.rb
new file mode 100644
index 00000000000..74308a7e8dd
--- /dev/null
+++ b/spec/features/projects/artifacts/file_spec.rb
@@ -0,0 +1,59 @@
+require 'spec_helper'
+
+feature 'Artifact file', :js, feature: true do
+ let(:project) { create(:project, :public) }
+ let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') }
+ let(:build) { create(:ci_build, :artifacts, pipeline: pipeline) }
+
+ def visit_file(path)
+ visit file_namespace_project_build_artifacts_path(project.namespace, project, build, path)
+ end
+
+ context 'Text file' do
+ before do
+ visit_file('other_artifacts_0.1.2/doc_sample.txt')
+
+ wait_for_ajax
+ end
+
+ it 'displays an error' do
+ aggregate_failures do
+ # shows an error message
+ expect(page).to have_content('The source could not be displayed because it is stored as a job artifact. You can download it instead.')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+ end
+ end
+ end
+
+ context 'JPG file' do
+ before do
+ visit_file('rails_sample.jpg')
+
+ wait_for_ajax
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows rendered image
+ expect(page).to have_selector('.image_file img')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb b/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb
index abc93e1b44a..3b905611467 100644
--- a/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb
+++ b/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb
@@ -135,6 +135,17 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do
subject { |example| path(example).nodes }
it { is_expected.to eq 4 }
end
+
+ describe '#blob' do
+ let(:file_entry) { |example| path(example) }
+ subject { file_entry.blob }
+
+ it 'returns a blob representing the entry data' do
+ expect(subject).to be_a(Blob)
+ expect(subject.path).to eq(file_entry.path)
+ expect(subject.size).to eq(file_entry.metadata[:size])
+ end
+ end
end
describe 'non-existent/', path: 'non-existent/' do
diff --git a/spec/models/ci/artifact_blob_spec.rb b/spec/models/ci/artifact_blob_spec.rb
new file mode 100644
index 00000000000..968593d7e9b
--- /dev/null
+++ b/spec/models/ci/artifact_blob_spec.rb
@@ -0,0 +1,44 @@
+require 'spec_helper'
+
+describe Ci::ArtifactBlob, models: true do
+ let(:build) { create(:ci_build, :artifacts) }
+ let(:entry) { build.artifacts_metadata_entry('other_artifacts_0.1.2/another-subdirectory/banana_sample.gif') }
+
+ subject { described_class.new(entry) }
+
+ describe '#id' do
+ it 'returns a hash of the path' do
+ expect(subject.id).to eq(Digest::SHA1.hexdigest(entry.path))
+ end
+ end
+
+ describe '#name' do
+ it 'returns the entry name' do
+ expect(subject.name).to eq(entry.name)
+ end
+ end
+
+ describe '#path' do
+ it 'returns the entry path' do
+ expect(subject.path).to eq(entry.path)
+ end
+ end
+
+ describe '#size' do
+ it 'returns the entry size' do
+ expect(subject.size).to eq(entry.metadata[:size])
+ end
+ end
+
+ describe '#mode' do
+ it 'returns the entry mode' do
+ expect(subject.mode).to eq(entry.metadata[:mode])
+ end
+ end
+
+ describe '#external_storage' do
+ it 'returns :build_artifact' do
+ expect(subject.external_storage).to eq(:build_artifact)
+ end
+ end
+end
diff --git a/spec/requests/projects/artifacts_controller_spec.rb b/spec/requests/projects/artifacts_controller_spec.rb
deleted file mode 100644
index d20866c0d44..00000000000
--- a/spec/requests/projects/artifacts_controller_spec.rb
+++ /dev/null
@@ -1,117 +0,0 @@
-require 'spec_helper'
-
-describe Projects::ArtifactsController do
- let(:user) { create(:user) }
- let(:project) { create(:project, :repository) }
-
- let(:pipeline) do
- create(:ci_pipeline,
- project: project,
- sha: project.commit.sha,
- ref: project.default_branch,
- status: 'success')
- end
-
- let(:build) { create(:ci_build, :success, :artifacts, pipeline: pipeline) }
-
- describe 'GET /:project/builds/artifacts/:ref_name/browse?job=name' do
- before do
- project.team << [user, :developer]
-
- login_as(user)
- end
-
- def path_from_ref(
- ref = pipeline.ref, job = build.name, path = 'browse')
- latest_succeeded_namespace_project_artifacts_path(
- project.namespace,
- project,
- [ref, path].join('/'),
- job: job)
- end
-
- context 'cannot find the build' do
- shared_examples 'not found' do
- it { expect(response).to have_http_status(:not_found) }
- end
-
- context 'has no such ref' do
- before do
- get path_from_ref('TAIL', build.name)
- end
-
- it_behaves_like 'not found'
- end
-
- context 'has no such build' do
- before do
- get path_from_ref(pipeline.ref, 'NOBUILD')
- end
-
- it_behaves_like 'not found'
- end
-
- context 'has no path' do
- before do
- get path_from_ref(pipeline.sha, build.name, '')
- end
-
- it_behaves_like 'not found'
- end
- end
-
- context 'found the build and redirect' do
- shared_examples 'redirect to the build' do
- it 'redirects' do
- path = browse_namespace_project_build_artifacts_path(
- project.namespace,
- project,
- build)
-
- expect(response).to redirect_to(path)
- end
- end
-
- context 'with regular branch' do
- before do
- pipeline.update(ref: 'master',
- sha: project.commit('master').sha)
-
- get path_from_ref('master')
- end
-
- it_behaves_like 'redirect to the build'
- end
-
- context 'with branch name containing slash' do
- before do
- pipeline.update(ref: 'improve/awesome',
- sha: project.commit('improve/awesome').sha)
-
- get path_from_ref('improve/awesome')
- end
-
- it_behaves_like 'redirect to the build'
- end
-
- context 'with branch name and path containing slashes' do
- before do
- pipeline.update(ref: 'improve/awesome',
- sha: project.commit('improve/awesome').sha)
-
- get path_from_ref('improve/awesome', build.name, 'file/README.md')
- end
-
- it 'redirects' do
- path = file_namespace_project_build_artifacts_path(
- project.namespace,
- project,
- build,
- 'README.md')
-
- expect(response).to redirect_to(path)
- end
- end
- end
- end
-end