Commit fce9c57a authored by Bob Van Landuyt's avatar Bob Van Landuyt

Merge branch '323195-add-more-blob-attributes' into 'master'

Add more attributes to the blob GraphQL API

See merge request gitlab-org/gitlab!61155
parents 9866b3f2 0ed51041
...@@ -32,6 +32,15 @@ module Types ...@@ -32,6 +32,15 @@ module Types
field :web_path, GraphQL::STRING_TYPE, null: true, field :web_path, GraphQL::STRING_TYPE, null: true,
description: 'Web path of the blob.' description: 'Web path of the blob.'
field :ide_edit_path, GraphQL::STRING_TYPE, null: true,
description: 'Web path to edit this blob in the Web IDE.'
field :fork_and_edit_path, GraphQL::STRING_TYPE, null: true,
description: 'Web path to edit this blob using a forked project.'
field :ide_fork_and_edit_path, GraphQL::STRING_TYPE, null: true,
description: 'Web path to edit this blob in the Web IDE using a forked project.'
field :size, GraphQL::INT_TYPE, null: true, field :size, GraphQL::INT_TYPE, null: true,
description: 'Size (in bytes) of the blob.' description: 'Size (in bytes) of the blob.'
...@@ -53,6 +62,9 @@ module Types ...@@ -53,6 +62,9 @@ module Types
field :raw_path, GraphQL::STRING_TYPE, null: true, field :raw_path, GraphQL::STRING_TYPE, null: true,
description: 'Web path to download the raw blob.' description: 'Web path to download the raw blob.'
field :external_storage_url, GraphQL::STRING_TYPE, null: true,
description: 'Web path to download the raw blob via external storage, if enabled.'
field :replace_path, GraphQL::STRING_TYPE, null: true, field :replace_path, GraphQL::STRING_TYPE, null: true,
description: 'Web path to replace the blob content.' description: 'Web path to replace the blob content.'
...@@ -72,6 +84,10 @@ module Types ...@@ -72,6 +84,10 @@ module Types
null: true, null: true,
calls_gitaly: true calls_gitaly: true
field :can_modify_blob, GraphQL::BOOLEAN_TYPE, null: true, method: :can_modify_blob?,
calls_gitaly: true,
description: 'Whether the current user can modify the blob.'
def raw_text_blob def raw_text_blob
object.data unless object.binary? object.data unless object.binary?
end end
......
# frozen_string_literal: true # frozen_string_literal: true
class BlobPresenter < Gitlab::View::Presenter::Delegated class BlobPresenter < Gitlab::View::Presenter::Delegated
include ApplicationHelper
include BlobHelper
include DiffHelper
include TreeHelper
include ChecksCollaboration
presents :blob presents :blob
def highlight(to: nil, plain: nil) def highlight(to: nil, plain: nil)
...@@ -40,6 +46,28 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated ...@@ -40,6 +46,28 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
url_helpers.project_create_blob_path(project, ref_qualified_path) url_helpers.project_create_blob_path(project, ref_qualified_path)
end end
def fork_and_edit_path
fork_path_for_current_user(project, edit_blob_path)
end
def ide_fork_and_edit_path
fork_path_for_current_user(project, ide_edit_path)
end
def can_modify_blob?
super(blob, project, blob.commit_id)
end
def ide_edit_path
super(project, blob.commit_id, blob.path)
end
def external_storage_url
return unless static_objects_external_storage_enabled?
external_storage_url_or_path(url_helpers.project_raw_url(project, ref_qualified_path))
end
private private
def url_helpers def url_helpers
......
---
title: Add more attributes to the blob GraphQL API
merge_request: 61155
author:
type: added
...@@ -11831,9 +11831,14 @@ Returns [`Tree`](#tree). ...@@ -11831,9 +11831,14 @@ Returns [`Tree`](#tree).
| Name | Type | Description | | Name | Type | Description |
| ---- | ---- | ----------- | | ---- | ---- | ----------- |
| <a id="repositoryblobcanmodifyblob"></a>`canModifyBlob` | [`Boolean`](#boolean) | Whether the current user can modify the blob. |
| <a id="repositoryblobeditblobpath"></a>`editBlobPath` | [`String`](#string) | Web path to edit the blob in the old-style editor. | | <a id="repositoryblobeditblobpath"></a>`editBlobPath` | [`String`](#string) | Web path to edit the blob in the old-style editor. |
| <a id="repositoryblobexternalstorageurl"></a>`externalStorageUrl` | [`String`](#string) | Web path to download the raw blob via external storage, if enabled. |
| <a id="repositoryblobfiletype"></a>`fileType` | [`String`](#string) | The expected format of the blob based on the extension. | | <a id="repositoryblobfiletype"></a>`fileType` | [`String`](#string) | The expected format of the blob based on the extension. |
| <a id="repositoryblobforkandeditpath"></a>`forkAndEditPath` | [`String`](#string) | Web path to edit this blob using a forked project. |
| <a id="repositoryblobid"></a>`id` | [`ID!`](#id) | ID of the blob. | | <a id="repositoryblobid"></a>`id` | [`ID!`](#id) | ID of the blob. |
| <a id="repositoryblobideeditpath"></a>`ideEditPath` | [`String`](#string) | Web path to edit this blob in the Web IDE. |
| <a id="repositoryblobideforkandeditpath"></a>`ideForkAndEditPath` | [`String`](#string) | Web path to edit this blob in the Web IDE using a forked project. |
| <a id="repositorybloblfsoid"></a>`lfsOid` | [`String`](#string) | LFS OID of the blob. | | <a id="repositorybloblfsoid"></a>`lfsOid` | [`String`](#string) | LFS OID of the blob. |
| <a id="repositoryblobmode"></a>`mode` | [`String`](#string) | Blob mode. | | <a id="repositoryblobmode"></a>`mode` | [`String`](#string) | Blob mode. |
| <a id="repositoryblobname"></a>`name` | [`String`](#string) | Blob name. | | <a id="repositoryblobname"></a>`name` | [`String`](#string) | Blob name. |
......
...@@ -25,7 +25,12 @@ RSpec.describe Types::Repository::BlobType do ...@@ -25,7 +25,12 @@ RSpec.describe Types::Repository::BlobType do
:replace_path, :replace_path,
:simple_viewer, :simple_viewer,
:rich_viewer, :rich_viewer,
:plain_data :plain_data,
:can_modify_blob,
:ide_edit_path,
:external_storage_url,
:fork_and_edit_path,
:ide_fork_and_edit_path
) )
end end
end end
...@@ -4,11 +4,12 @@ require 'spec_helper' ...@@ -4,11 +4,12 @@ require 'spec_helper'
RSpec.describe BlobPresenter do RSpec.describe BlobPresenter do
let_it_be(:project) { create(:project, :repository) } let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { project.owner }
let(:repository) { project.repository } let(:repository) { project.repository }
let(:blob) { repository.blob_at('HEAD', 'files/ruby/regex.rb') } let(:blob) { repository.blob_at('HEAD', 'files/ruby/regex.rb') }
subject(:presenter) { described_class.new(blob) } subject(:presenter) { described_class.new(blob, current_user: user) }
describe '#web_url' do describe '#web_url' do
it { expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/-/blob/#{blob.commit_id}/#{blob.path}") } it { expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/-/blob/#{blob.commit_id}/#{blob.path}") }
...@@ -30,6 +31,42 @@ RSpec.describe BlobPresenter do ...@@ -30,6 +31,42 @@ RSpec.describe BlobPresenter do
it { expect(presenter.replace_path).to eq("/#{project.full_path}/-/create/#{blob.commit_id}/#{blob.path}") } it { expect(presenter.replace_path).to eq("/#{project.full_path}/-/create/#{blob.commit_id}/#{blob.path}") }
end end
describe '#ide_edit_path' do
it { expect(presenter.ide_edit_path).to eq("/-/ide/project/#{project.full_path}/edit/HEAD/-/files/ruby/regex.rb") }
end
describe '#fork_and_edit_path' do
it 'generates expected URI + query' do
uri = URI.parse(presenter.fork_and_edit_path)
query = Rack::Utils.parse_query(uri.query)
expect(uri.path).to eq("/#{project.full_path}/-/forks")
expect(query).to include('continue[to]' => presenter.edit_blob_path, 'namespace_key' => user.namespace_id.to_s)
end
context 'current_user is nil' do
let(:user) { nil }
it { expect(presenter.fork_and_edit_path).to be_nil }
end
end
describe '#ide_fork_and_edit_path' do
it 'generates expected URI + query' do
uri = URI.parse(presenter.ide_fork_and_edit_path)
query = Rack::Utils.parse_query(uri.query)
expect(uri.path).to eq("/#{project.full_path}/-/forks")
expect(query).to include('continue[to]' => presenter.ide_edit_path, 'namespace_key' => user.namespace_id.to_s)
end
context 'current_user is nil' do
let(:user) { nil }
it { expect(presenter.ide_fork_and_edit_path).to be_nil }
end
end
context 'given a Gitlab::Graphql::Representation::TreeEntry' do context 'given a Gitlab::Graphql::Representation::TreeEntry' do
let(:blob) { Gitlab::Graphql::Representation::TreeEntry.new(super(), repository) } let(:blob) { Gitlab::Graphql::Representation::TreeEntry.new(super(), repository) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment