Add files argument to snippet update mutation

In this commit we add the new `files` param
to the snippet update mutation. At some point,
this field will replace the existing `content`
and `file_name` in the same mutation.
parent d3c5b084
......@@ -30,12 +30,16 @@ module Mutations
description: 'The visibility level of the snippet',
required: false
argument :files, [Types::Snippets::FileInputType],
description: 'The snippet files to update',
required: false
def resolve(args)
snippet = authorized_find!(id: args.delete(:id))
result = ::Snippets::UpdateService.new(snippet.project,
context[:current_user],
args).execute(snippet)
context[:current_user],
update_params(args)).execute(snippet)
snippet = result.payload[:snippet]
{
......@@ -47,7 +51,15 @@ module Mutations
private
def ability_name
"update"
'update'
end
def update_params(args)
args.tap do |update_args|
# We need to rename `files` into `snippet_files` because
# it's the expected key param
update_args[:snippet_files] = update_args.delete(:files)&.map(&:to_h)
end
end
end
end
......
---
title: Add files argument to snippet update mutation
merge_request: 34514
author:
type: changed
......@@ -11710,6 +11710,41 @@ type SnippetEdge {
node: Snippet
}
"""
Type of a snippet file input action
"""
enum SnippetFileInputActionEnum {
create
delete
move
update
}
"""
Represents an action to perform over a snippet file
"""
input SnippetFileInputType {
"""
Type of input action
"""
action: SnippetFileInputActionEnum!
"""
Snippet file content
"""
content: String
"""
Path of the snippet file
"""
filePath: String!
"""
Previous path of the snippet file
"""
previousPath: String
}
type SnippetPermissions {
"""
Indicates the user can perform `admin_snippet` on this resource
......@@ -12903,6 +12938,11 @@ input UpdateSnippetInput {
"""
fileName: String
"""
The snippet files to update
"""
files: [SnippetFileInputType!]
"""
The global id of the snippet to update
"""
......
......@@ -34567,6 +34567,100 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "ENUM",
"name": "SnippetFileInputActionEnum",
"description": "Type of a snippet file input action",
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": [
{
"name": "create",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "update",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "delete",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "move",
"description": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"possibleTypes": null
},
{
"kind": "INPUT_OBJECT",
"name": "SnippetFileInputType",
"description": "Represents an action to perform over a snippet file",
"fields": null,
"inputFields": [
{
"name": "action",
"description": "Type of input action",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "SnippetFileInputActionEnum",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "previousPath",
"description": "Previous path of the snippet file",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "filePath",
"description": "Path of the snippet file",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "content",
"description": "Snippet file content",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
}
],
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "SnippetPermissions",
......@@ -38089,6 +38183,24 @@
},
"defaultValue": null
},
{
"name": "files",
"description": "The snippet files to update",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "SnippetFileInputType",
"ofType": null
}
}
},
"defaultValue": null
},
{
"name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.",
......@@ -16,8 +16,8 @@ describe 'Updating a Snippet' do
let(:current_user) { snippet.author }
let(:snippet_gid) { GitlabSchema.id_from_object(snippet).to_s }
let(:mutation) do
variables = {
let(:mutation_vars) do
{
id: snippet_gid,
content: updated_content,
description: updated_description,
......@@ -25,8 +25,9 @@ describe 'Updating a Snippet' do
file_name: updated_file_name,
title: updated_title
}
graphql_mutation(:update_snippet, variables)
end
let(:mutation) do
graphql_mutation(:update_snippet, mutation_vars)
end
def mutation_response
......@@ -101,7 +102,6 @@ describe 'Updating a Snippet' do
end
it_behaves_like 'graphql update actions'
it_behaves_like 'when the snippet is not found'
end
......@@ -148,4 +148,40 @@ describe 'Updating a Snippet' do
it_behaves_like 'when the snippet is not found'
end
context 'when using the files params' do
let!(:snippet) { create(:personal_snippet, :private, :repository) }
let(:updated_content) { 'updated_content' }
let(:updated_file) { 'CHANGELOG' }
let(:deleted_file) { 'README' }
let(:mutation_vars) do
{
id: snippet_gid,
files: [
{ action: :update, filePath: updated_file, content: updated_content },
{ action: :delete, filePath: deleted_file }
]
}
end
it 'updates the Snippet' do
blob_to_update = blob_at(updated_file)
expect(blob_to_update.data).not_to eq updated_content
blob_to_delete = blob_at(deleted_file)
expect(blob_to_delete).to be_present
post_graphql_mutation(mutation, current_user: current_user)
blob_to_update = blob_at(updated_file)
expect(blob_to_update.data).to eq updated_content
blob_to_delete = blob_at(deleted_file)
expect(blob_to_delete).to be_nil
end
def blob_at(filename)
snippet.repository.blob_at('HEAD', filename)
end
end
end
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