diff --git a/app/graphql/resolvers/blobs_resolver.rb b/app/graphql/resolvers/blobs_resolver.rb
index 0b8180dbce70e17b26ee63f8b960f17797c76a16..546eeb76ff53f42c156742588973bb1c11011c7d 100644
--- a/app/graphql/resolvers/blobs_resolver.rb
+++ b/app/graphql/resolvers/blobs_resolver.rb
@@ -17,6 +17,10 @@ class BlobsResolver < BaseResolver
required: false,
default_value: nil,
description: 'Commit ref to get the blobs from. Default value is HEAD.'
+ argument :ref_type, Types::RefTypeEnum,
+ required: false,
+ default_value: nil,
+ description: 'Type of ref.'
# We fetch blobs from Gitaly efficiently but it still scales O(N) with the
# number of paths being fetched, so apply a scaling limit to that.
@@ -24,7 +28,7 @@ def self.resolver_complexity(args, child_complexity:)
super + (args[:paths] || []).size
end
- def resolve(paths:, ref:)
+ def resolve(paths:, ref:, ref_type:)
authorize!(repository.container)
return [] if repository.empty?
@@ -32,7 +36,13 @@ def resolve(paths:, ref:)
ref ||= repository.root_ref
validate_ref(ref)
- repository.blobs_at(paths.map { |path| [ref, path] })
+ ref = ExtractsRef.qualify_ref(ref, ref_type)
+
+ repository.blobs_at(paths.map { |path| [ref, path] }).tap do |blobs|
+ blobs.each do |blob|
+ blob.ref_type = ref_type
+ end
+ end
end
private
diff --git a/app/graphql/resolvers/last_commit_resolver.rb b/app/graphql/resolvers/last_commit_resolver.rb
index 00c43bdfee647e61b462d185fcbe2a53932e3275..acf7826ab1388070d4797c8b45f307b7b393b5ce 100644
--- a/app/graphql/resolvers/last_commit_resolver.rb
+++ b/app/graphql/resolvers/last_commit_resolver.rb
@@ -11,7 +11,8 @@ class LastCommitResolver < BaseResolver
def resolve(**args)
# Ensure merge commits can be returned by sending nil to Gitaly instead of '/'
path = tree.path == '/' ? nil : tree.path
- commit = Gitlab::Git::Commit.last_for_path(tree.repository, tree.sha, path, literal_pathspec: true)
+ commit = Gitlab::Git::Commit.last_for_path(tree.repository,
+ ExtractsRef.qualify_ref(tree.sha, tree.ref_type), path, literal_pathspec: true)
::Commit.new(commit, tree.repository.project) if commit
end
diff --git a/app/graphql/resolvers/paginated_tree_resolver.rb b/app/graphql/resolvers/paginated_tree_resolver.rb
index 8fd80b1a9b99b438974165bc4efb8cec97f7eda4..de48fbafb044c3b04a9e66e2acabff5cb08782bd 100644
--- a/app/graphql/resolvers/paginated_tree_resolver.rb
+++ b/app/graphql/resolvers/paginated_tree_resolver.rb
@@ -18,6 +18,9 @@ class PaginatedTreeResolver < BaseResolver
argument :ref, GraphQL::Types::String,
required: false,
description: 'Commit ref to get the tree for. Default value is HEAD.'
+ argument :ref_type, Types::RefTypeEnum,
+ required: false,
+ description: 'Type of ref.'
alias_method :repository, :object
@@ -25,7 +28,6 @@ def resolve(**args)
return if repository.empty?
cursor = args.delete(:after)
- args[:ref] ||= :head
pagination_params = {
limit: @field.max_page_size || 100,
@@ -33,9 +35,11 @@ def resolve(**args)
}
tree = repository.tree(
- args[:ref], args[:path], recursive: args[:recursive],
- skip_flat_paths: false,
- pagination_params: pagination_params
+ args[:ref].presence || :head,
+ args[:path], recursive: args[:recursive],
+ skip_flat_paths: false,
+ pagination_params: pagination_params,
+ ref_type: args[:ref_type]
)
next_cursor = tree.cursor&.next_cursor
diff --git a/app/graphql/resolvers/tree_resolver.rb b/app/graphql/resolvers/tree_resolver.rb
index 553f9aa6cd97c42f20cc44ac8bb78ece7eee8c91..6b88f120d1bc2032acc0c66c215dbbc52dfee8fb 100644
--- a/app/graphql/resolvers/tree_resolver.rb
+++ b/app/graphql/resolvers/tree_resolver.rb
@@ -17,14 +17,18 @@ class TreeResolver < BaseResolver
argument :ref, GraphQL::Types::String,
required: false,
description: 'Commit ref to get the tree for. Default value is HEAD.'
+ argument :ref_type, Types::RefTypeEnum,
+ required: false,
+ description: 'Type of ref.'
alias_method :repository, :object
def resolve(**args)
return unless repository.exists?
- args[:ref] ||= :head
- repository.tree(args[:ref], args[:path], recursive: args[:recursive])
+ ref = (args[:ref].presence || :head)
+
+ repository.tree(ref, args[:path], recursive: args[:recursive], ref_type: args[:ref_type])
end
end
end
diff --git a/app/graphql/types/ref_type_enum.rb b/app/graphql/types/ref_type_enum.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f56d4cd512accaeaec5370c81bbad531a6e32194
--- /dev/null
+++ b/app/graphql/types/ref_type_enum.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Types
+ class RefTypeEnum < BaseEnum
+ graphql_name 'RefType'
+ description 'Type of ref'
+
+ value 'HEADS', description: 'Ref type for branches.', value: 'heads'
+ value 'TAGS', description: 'Ref type for tags.', value: 'tags'
+ end
+end
diff --git a/app/models/blob.rb b/app/models/blob.rb
index e6496e21175fb59fbeba93db41b23b9556324579..7c88833b19dcd315cb554ee661ae8238037d23c7 100644
--- a/app/models/blob.rb
+++ b/app/models/blob.rb
@@ -71,6 +71,7 @@ class Blob < SimpleDelegator
].freeze
attr_reader :container
+ attr_accessor :ref_type
delegate :repository, to: :container, allow_nil: true
delegate :project, to: :repository, allow_nil: true
diff --git a/app/models/repository.rb b/app/models/repository.rb
index acb795f174dc053729110b80b852b371862eaa97..b21df6baf0e69b353a8292863cbfcec788e434cb 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -691,7 +691,7 @@ def head_tree(skip_flat_paths: true)
@head_tree ||= Tree.new(self, root_ref, nil, skip_flat_paths: skip_flat_paths)
end
- def tree(sha = :head, path = nil, recursive: false, skip_flat_paths: true, pagination_params: nil)
+ def tree(sha = :head, path = nil, recursive: false, skip_flat_paths: true, pagination_params: nil, ref_type: nil)
if sha == :head
return if empty? || root_ref.nil?
@@ -699,10 +699,11 @@ def tree(sha = :head, path = nil, recursive: false, skip_flat_paths: true, pagin
return head_tree(skip_flat_paths: skip_flat_paths)
else
sha = head_commit.sha
+ ref_type = nil
end
end
- Tree.new(self, sha, path, recursive: recursive, skip_flat_paths: skip_flat_paths, pagination_params: pagination_params)
+ Tree.new(self, sha, path, recursive: recursive, skip_flat_paths: skip_flat_paths, pagination_params: pagination_params, ref_type: ref_type)
end
def blob_at_branch(branch_name, path)
diff --git a/app/models/tree.rb b/app/models/tree.rb
index c6adf5c263ccae5ceb530854bf619a35e0338944..8622eb793c16ec0e60decb6f9d010189400adb74 100644
--- a/app/models/tree.rb
+++ b/app/models/tree.rb
@@ -3,17 +3,25 @@
class Tree
include Gitlab::Utils::StrongMemoize
- attr_accessor :repository, :sha, :path, :entries, :cursor
+ attr_accessor :repository, :sha, :path, :entries, :cursor, :ref_type
- def initialize(repository, sha, path = '/', recursive: false, skip_flat_paths: true, pagination_params: nil)
+ def initialize(
+ repository, sha, path = '/', recursive: false, skip_flat_paths: true, pagination_params: nil,
+ ref_type: nil)
path = '/' if path.blank?
@repository = repository
@sha = sha
@path = path
-
+ @ref_type = ExtractsRef.ref_type(ref_type)
git_repo = @repository.raw_repository
- @entries, @cursor = Gitlab::Git::Tree.where(git_repo, @sha, @path, recursive, skip_flat_paths, pagination_params)
+
+ ref = ExtractsRef.qualify_ref(@sha, ref_type)
+
+ @entries, @cursor = Gitlab::Git::Tree.where(git_repo, ref, @path, recursive, skip_flat_paths, pagination_params)
+ @entries.each do |entry|
+ entry.ref_type = self.ref_type
+ end
end
def readme_path
diff --git a/app/presenters/blob_presenter.rb b/app/presenters/blob_presenter.rb
index f25436c54bedefb41b10fd1f6d3095f5c26a22e4..cd473152b41c144af98fe21e2913463ea854fa39 100644
--- a/app/presenters/blob_presenter.rb
+++ b/app/presenters/blob_presenter.rb
@@ -56,23 +56,23 @@ def raw_plain_data
end
def web_url
- url_helpers.project_blob_url(project, ref_qualified_path)
+ url_helpers.project_blob_url(*path_params)
end
def web_path
- url_helpers.project_blob_path(project, ref_qualified_path)
+ url_helpers.project_blob_path(*path_params)
end
def edit_blob_path
- url_helpers.project_edit_blob_path(project, ref_qualified_path)
+ url_helpers.project_edit_blob_path(*path_params)
end
def raw_path
- url_helpers.project_raw_path(project, ref_qualified_path)
+ url_helpers.project_raw_path(*path_params)
end
def replace_path
- url_helpers.project_update_blob_path(project, ref_qualified_path)
+ url_helpers.project_update_blob_path(*path_params)
end
def pipeline_editor_path
@@ -164,6 +164,18 @@ def project_blob_path_root
private
+ def path_params
+ if ref_type.present?
+ [project, ref_qualified_path, { ref_type: ref_type }]
+ else
+ [project, ref_qualified_path]
+ end
+ end
+
+ def ref_type
+ blob.ref_type
+ end
+
def url_helpers
Gitlab::Routing.url_helpers
end
@@ -179,7 +191,12 @@ def project
end
def ref_qualified_path
- File.join(blob.commit_id, blob.path)
+ # If `ref_type` is present the commit_id will include the ref qualifier e.g. `refs/heads/`.
+ # We only accept/return unqualified refs so we need to remove the qualifier from the `commit_id`.
+
+ commit_id = ExtractsRef.unqualify_ref(blob.commit_id, ref_type)
+
+ File.join(commit_id, blob.path)
end
def load_all_blob_data
diff --git a/app/presenters/tree_entry_presenter.rb b/app/presenters/tree_entry_presenter.rb
index 0b313d81360190194a53ee4822576d1947d1e2a0..3f4a9f13c36338d1d1a556a8ce96c04917e2a503 100644
--- a/app/presenters/tree_entry_presenter.rb
+++ b/app/presenters/tree_entry_presenter.rb
@@ -4,10 +4,23 @@ class TreeEntryPresenter < Gitlab::View::Presenter::Delegated
presents nil, as: :tree
def web_url
- Gitlab::Routing.url_helpers.project_tree_url(tree.repository.project, File.join(tree.commit_id, tree.path))
+ Gitlab::Routing.url_helpers.project_tree_url(tree.repository.project, ref_qualified_path,
+ ref_type: tree.ref_type)
end
def web_path
- Gitlab::Routing.url_helpers.project_tree_path(tree.repository.project, File.join(tree.commit_id, tree.path))
+ Gitlab::Routing.url_helpers.project_tree_path(tree.repository.project, ref_qualified_path,
+ ref_type: tree.ref_type)
+ end
+
+ private
+
+ def ref_qualified_path
+ # If `ref_type` is present the commit_id will include the ref qualifier e.g. `refs/heads/`.
+ # We only accept/return unqualified refs so we need to remove the qualifier from the `commit_id`.
+
+ commit_id = ExtractsRef.unqualify_ref(tree.commit_id, ref_type)
+
+ File.join(commit_id, tree.path)
end
end
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index c6e1363b50544bf78c5b0542ce1d45040041eb4f..ae4cf7765a8fe196682d211eac19a5ab32d34427 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -21689,6 +21689,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| ---- | ---- | ----------- |
| `paths` | [`[String!]!`](#string) | Array of desired blob paths. |
| `ref` | [`String`](#string) | Commit ref to get the blobs from. Default value is HEAD. |
+| `refType` | [`RefType`](#reftype) | Type of ref. |
##### `Repository.branchNames`
@@ -21733,6 +21734,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| `path` | [`String`](#string) | Path to get the tree for. Default value is the root of the repository. |
| `recursive` | [`Boolean`](#boolean) | Used to get a recursive tree. Default is false. |
| `ref` | [`String`](#string) | Commit ref to get the tree for. Default value is HEAD. |
+| `refType` | [`RefType`](#reftype) | Type of ref. |
##### `Repository.tree`
@@ -21747,6 +21749,7 @@ Returns [`Tree`](#tree).
| `path` | [`String`](#string) | Path to get the tree for. Default value is the root of the repository. |
| `recursive` | [`Boolean`](#boolean) | Used to get a recursive tree. Default is false. |
| `ref` | [`String`](#string) | Commit ref to get the tree for. Default value is HEAD. |
+| `refType` | [`RefType`](#reftype) | Type of ref. |
### `RepositoryBlob`
@@ -26000,6 +26003,15 @@ Project member relation.
| `INVITED_GROUPS` | Invited Groups members. |
| `SHARED_INTO_ANCESTORS` | Shared Into Ancestors members. |
+### `RefType`
+
+Type of ref.
+
+| Value | Description |
+| ----- | ----------- |
+| `HEADS` | Ref type for branches. |
+| `TAGS` | Ref type for tags. |
+
### `RegistryState`
State of a Geo registry.
diff --git a/lib/extracts_ref.rb b/lib/extracts_ref.rb
index 5f73b474956d474e0b44c7bd3217e7d44e321adc..49ec564eb8d64a830bc5aa99ef05fa0808580f5a 100644
--- a/lib/extracts_ref.rb
+++ b/lib/extracts_ref.rb
@@ -7,6 +7,28 @@ module ExtractsRef
InvalidPathError = Class.new(StandardError)
BRANCH_REF_TYPE = 'heads'
TAG_REF_TYPE = 'tags'
+ REF_TYPES = [BRANCH_REF_TYPE, TAG_REF_TYPE].freeze
+
+ def self.ref_type(type)
+ return unless REF_TYPES.include?(type)
+
+ type
+ end
+
+ def self.qualify_ref(ref, type)
+ validated_type = ref_type(type)
+ return ref unless validated_type
+
+ %(refs/#{validated_type}/#{ref})
+ end
+
+ def self.unqualify_ref(ref, type)
+ validated_type = ref_type(type)
+ return ref unless validated_type
+
+ ref.sub(%r{^refs/#{validated_type}/}, '')
+ end
+
# Given a string containing both a Git tree-ish, such as a branch or tag, and
# a filesystem path joined by forward slashes, attempts to separate the two.
#
@@ -60,7 +82,6 @@ def extract_ref(id)
#
# If the :id parameter appears to be requesting a specific response format,
# that will be handled as well.
- #
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def assign_ref_vars
@id, @ref, @path = extract_ref_path
@@ -70,7 +91,7 @@ def assign_ref_vars
return unless @ref.present?
@commit = if ref_type
- @fully_qualified_ref = %(refs/#{ref_type}/#{@ref})
+ @fully_qualified_ref = ExtractsRef.qualify_ref(@ref, ref_type)
@repo.commit(@fully_qualified_ref)
else
@repo.commit(@ref)
@@ -90,9 +111,7 @@ def extract_ref_path
end
def ref_type
- return unless params[:ref_type].present?
-
- params[:ref_type] == TAG_REF_TYPE ? TAG_REF_TYPE : BRANCH_REF_TYPE
+ ExtractsRef.ref_type(params[:ref_type])
end
private
@@ -156,6 +175,7 @@ def repository_container
raise NotImplementedError
end
+ # deprecated in favor of ExtractsRef::RequestedRef
def ambiguous_ref?(project, ref)
return false unless ref
return true if project.repository.ambiguous_ref?(ref)
diff --git a/lib/gitlab/git/tree.rb b/lib/gitlab/git/tree.rb
index e437f99dab39862aa90c4879d7f0cb5e54725d4d..df3d8165ef2c9e8076fb94e9bd837f65bd07b74d 100644
--- a/lib/gitlab/git/tree.rb
+++ b/lib/gitlab/git/tree.rb
@@ -6,7 +6,7 @@ class Tree
include Gitlab::EncodingHelper
extend Gitlab::Git::WrapsGitalyErrors
- attr_accessor :id, :type, :mode, :commit_id, :submodule_url
+ attr_accessor :id, :type, :mode, :commit_id, :submodule_url, :ref_type
attr_writer :name, :path, :flat_path
class << self
diff --git a/spec/graphql/resolvers/blobs_resolver_spec.rb b/spec/graphql/resolvers/blobs_resolver_spec.rb
index 26eb6dc0abe310f998c1b2bcd07329cc86ce8892..0d725f00d43193fa37c4d7c50608a38249843d63 100644
--- a/spec/graphql/resolvers/blobs_resolver_spec.rb
+++ b/spec/graphql/resolvers/blobs_resolver_spec.rb
@@ -2,8 +2,9 @@
require 'spec_helper'
-RSpec.describe Resolvers::BlobsResolver do
+RSpec.describe Resolvers::BlobsResolver, feature_category: :source_code_management do
include GraphqlHelpers
+ include RepoHelpers
describe '.resolver_complexity' do
it 'adds one per path being resolved' do
@@ -59,15 +60,89 @@
end
end
- context 'specifying a different ref' do
+ context 'when specifying a branch ref' do
let(:ref) { 'add-pdf-file' }
+ let(:args) { { paths: paths, ref: ref, ref_type: ref_type } }
let(:paths) { ['files/pdf/test.pdf', 'README.md'] }
- it 'returns the specified blobs for that ref' do
- is_expected.to contain_exactly(
- have_attributes(path: 'files/pdf/test.pdf'),
- have_attributes(path: 'README.md')
- )
+ context 'and no ref_type is specified' do
+ let(:ref_type) { nil }
+
+ it 'returns the specified blobs for that ref' do
+ is_expected.to contain_exactly(
+ have_attributes(path: 'files/pdf/test.pdf'),
+ have_attributes(path: 'README.md')
+ )
+ end
+
+ context 'and a tag with the same name exists' do
+ let(:ref) { SecureRandom.uuid }
+
+ before do
+ project.repository.create_branch(ref)
+ create_file_in_repo(project, ref, ref, 'branch_file', 'Test file', commit_message: 'Add new content')
+ project.repository.add_tag(project.owner, sample_commit.id, ref)
+ end
+
+ it 'returns the specified blobs for the tag' do
+ is_expected.to contain_exactly(
+ have_attributes(path: 'README.md')
+ )
+ end
+ end
+ end
+
+ context 'and ref_type is for branches' do
+ let(:args) { { paths: paths, ref: ref, ref_type: 'heads' } }
+
+ it 'returns nothing' do
+ is_expected.to contain_exactly(
+ have_attributes(path: 'files/pdf/test.pdf'),
+ have_attributes(path: 'README.md')
+ )
+ end
+ end
+
+ context 'and ref_type is for tags' do
+ let(:args) { { paths: paths, ref: ref, ref_type: 'tags' } }
+
+ it 'returns nothing' do
+ is_expected.to be_empty
+ end
+ end
+ end
+
+ context 'when specifying a tag ref' do
+ let(:ref) { 'v1.0.0' }
+
+ let(:args) { { paths: paths, ref: ref, ref_type: ref_type } }
+
+ context 'and no ref_type is specified' do
+ let(:ref_type) { nil }
+
+ it 'returns the specified blobs for that ref' do
+ is_expected.to contain_exactly(
+ have_attributes(path: 'README.md')
+ )
+ end
+ end
+
+ context 'and ref_type is for tags' do
+ let(:ref_type) { 'tags' }
+
+ it 'returns the specified blobs for that ref' do
+ is_expected.to contain_exactly(
+ have_attributes(path: 'README.md')
+ )
+ end
+ end
+
+ context 'and ref_type is for branches' do
+ let(:ref_type) { 'heads' }
+
+ it 'returns nothing' do
+ is_expected.to be_empty
+ end
end
end
diff --git a/spec/graphql/resolvers/last_commit_resolver_spec.rb b/spec/graphql/resolvers/last_commit_resolver_spec.rb
index 5ac6ad59864611a8424a40243ff8543c1b0a0300..82bbdd4487c5802e0c1dc89faadc171d7e7588f1 100644
--- a/spec/graphql/resolvers/last_commit_resolver_spec.rb
+++ b/spec/graphql/resolvers/last_commit_resolver_spec.rb
@@ -61,5 +61,29 @@
expect(commit).to be_nil
end
end
+
+ context 'when the ref is ambiguous' do
+ let(:ambiguous_ref) { 'v1.0.0' }
+
+ before do
+ project.repository.create_branch(ambiguous_ref)
+ end
+
+ context 'when tree is for a tag' do
+ let(:tree) { repository.tree(ambiguous_ref, ref_type: 'tags') }
+
+ it 'resolves commit' do
+ expect(commit.id).to eq(repository.find_tag(ambiguous_ref).dereferenced_target.id)
+ end
+ end
+
+ context 'when tree is for a branch' do
+ let(:tree) { repository.tree(ambiguous_ref, ref_type: 'heads') }
+
+ it 'resolves commit' do
+ expect(commit.id).to eq(repository.find_branch(ambiguous_ref).target)
+ end
+ end
+ end
end
end
diff --git a/spec/lib/extracts_ref_spec.rb b/spec/lib/extracts_ref_spec.rb
index 93a09bf5a0a7d266e6314d79bb1d30d1f69f1656..ac403ad642a3fe2b7485ab44eb1d1116d9dc5b1e 100644
--- a/spec/lib/extracts_ref_spec.rb
+++ b/spec/lib/extracts_ref_spec.rb
@@ -57,5 +57,64 @@
end
end
+ describe '#ref_type' do
+ let(:params) { ActionController::Parameters.new(ref_type: 'heads') }
+
+ it 'delegates to .ref_type' do
+ expect(described_class).to receive(:ref_type).with('heads')
+ ref_type
+ end
+ end
+
+ describe '.ref_type' do
+ subject { described_class.ref_type(ref_type) }
+
+ context 'when ref_type is nil' do
+ let(:ref_type) { nil }
+
+ it { is_expected.to eq(nil) }
+ end
+
+ context 'when ref_type is heads' do
+ let(:ref_type) { 'heads' }
+
+ it { is_expected.to eq('heads') }
+ end
+
+ context 'when ref_type is tags' do
+ let(:ref_type) { 'tags' }
+
+ it { is_expected.to eq('tags') }
+ end
+
+ context 'when ref_type is invalid' do
+ let(:ref_type) { 'invalid' }
+
+ it { is_expected.to eq(nil) }
+ end
+ end
+
+ describe '.qualify_ref' do
+ subject { described_class.qualify_ref(ref, ref_type) }
+
+ context 'when ref_type is nil' do
+ let(:ref_type) { nil }
+
+ it { is_expected.to eq(ref) }
+ end
+
+ context 'when ref_type valid' do
+ let(:ref_type) { 'heads' }
+
+ it { is_expected.to eq("refs/#{ref_type}/#{ref}") }
+ end
+
+ context 'when ref_type is invalid' do
+ let(:ref_type) { 'invalid' }
+
+ it { is_expected.to eq(ref) }
+ end
+ end
+
it_behaves_like 'extracts refs'
end
diff --git a/spec/presenters/blob_presenter_spec.rb b/spec/presenters/blob_presenter_spec.rb
index f10150b819af9065ea7488bcf051a184f550a067..e776716bd2d724b8d6ad0bc5fe2d5aef12bec29e 100644
--- a/spec/presenters/blob_presenter_spec.rb
+++ b/spec/presenters/blob_presenter_spec.rb
@@ -31,6 +31,32 @@
it { expect(presenter.replace_path).to eq("/#{project.full_path}/-/update/#{blob.commit_id}/#{blob.path}") }
end
+ context 'when blob has ref_type' do
+ before do
+ blob.ref_type = 'heads'
+ end
+
+ describe '#web_url' do
+ it { expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/-/blob/#{blob.commit_id}/#{blob.path}?ref_type=heads") }
+ end
+
+ describe '#web_path' do
+ it { expect(presenter.web_path).to eq("/#{project.full_path}/-/blob/#{blob.commit_id}/#{blob.path}?ref_type=heads") }
+ end
+
+ describe '#edit_blob_path' do
+ it { expect(presenter.edit_blob_path).to eq("/#{project.full_path}/-/edit/#{blob.commit_id}/#{blob.path}?ref_type=heads") }
+ end
+
+ describe '#raw_path' do
+ it { expect(presenter.raw_path).to eq("/#{project.full_path}/-/raw/#{blob.commit_id}/#{blob.path}?ref_type=heads") }
+ end
+
+ describe '#replace_path' do
+ it { expect(presenter.replace_path).to eq("/#{project.full_path}/-/update/#{blob.commit_id}/#{blob.path}?ref_type=heads") }
+ end
+ end
+
describe '#can_current_user_push_to_branch' do
let(:branch_exists) { true }
diff --git a/spec/presenters/tree_entry_presenter_spec.rb b/spec/presenters/tree_entry_presenter_spec.rb
index de84f36c5e6144fbf4a0a6d8c12e561e8225ad0e..0abf372b70458ec9bfa4c19779abbc3e837143f2 100644
--- a/spec/presenters/tree_entry_presenter_spec.rb
+++ b/spec/presenters/tree_entry_presenter_spec.rb
@@ -17,4 +17,20 @@
describe '#web_path' do
it { expect(presenter.web_path).to eq("/#{project.full_path}/-/tree/#{tree.commit_id}/#{tree.path}") }
end
+
+ context 'when blob has ref_type' do
+ before do
+ tree.ref_type = 'heads'
+ end
+
+ describe '.web_url' do
+ it { expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/-/tree/#{tree.commit_id}/#{tree.path}?ref_type=heads") }
+ end
+
+ describe '#web_path' do
+ it {
+ expect(presenter.web_path).to eq("/#{project.full_path}/-/tree/#{tree.commit_id}/#{tree.path}?ref_type=heads")
+ }
+ end
+ end
end