[GraphQL] Add create direct upload mutation

This commit is contained in:
Paul Chavard 2019-09-17 18:11:34 +02:00
parent 9e1ede2a51
commit 4231b81727
5 changed files with 151 additions and 1 deletions

View file

@ -1,4 +1,4 @@
module Mutations
class BaseMutation < GraphQL::Schema::Mutation
class BaseMutation < GraphQL::Schema::RelayClassicMutation
end
end

View file

@ -0,0 +1,41 @@
module Mutations
class CreateDirectUpload < Mutations::BaseMutation
description "File information required to prepare a direct upload"
argument :dossier_id, ID, "Dossier ID", required: true, loads: Types::DossierType
argument :filename, String, "Original file name", required: true
argument :byte_size, Int, "File size (bytes)", required: true
argument :checksum, String, "MD5 file checksum as base64", required: true
argument :content_type, String, "File content type", required: true
class DirectUpload < Types::BaseObject
description "Represents direct upload credentials"
field :url, String, "Upload URL", null: false
field :headers, String, "HTTP request headers (JSON-encoded)", null: false
field :blob_id, ID, "Created blob record ID", null: false
field :signed_blob_id, ID, "Created blob record signed ID", null: false
end
field :direct_upload, DirectUpload, null: false
def resolve(filename:, byte_size:, checksum:, content_type:, dossier:)
blob = ActiveStorage::Blob.create_before_direct_upload!(
filename: filename,
byte_size: byte_size,
checksum: checksum,
content_type: content_type
)
{
direct_upload: {
url: blob.service_url_for_direct_upload,
# NOTE: we pass headers as JSON since they have no schema
headers: blob.service_headers_for_direct_upload.to_json,
blob_id: blob.id,
signed_blob_id: blob.signed_id
}
}
end
end
end

View file

@ -40,6 +40,52 @@ GeoJSON coordinates
"""
scalar Coordinates
"""
Autogenerated input type of CreateDirectUpload
"""
input CreateDirectUploadInput {
"""
File size (bytes)
"""
byteSize: Int!
"""
MD5 file checksum as base64
"""
checksum: String!
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
File content type
"""
contentType: String!
"""
Dossier ID
"""
dossierId: ID!
"""
Original file name
"""
filename: String!
}
"""
Autogenerated return type of CreateDirectUpload
"""
type CreateDirectUploadPayload {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
directUpload: DirectUpload!
}
type DateChamp implements Champ {
id: ID!
label: String!
@ -131,6 +177,31 @@ enum DemarcheState {
publiee
}
"""
Represents direct upload credentials
"""
type DirectUpload {
"""
Created blob record ID
"""
blobId: ID!
"""
HTTP request headers (JSON-encoded)
"""
headers: String!
"""
Created blob record signed ID
"""
signedBlobId: ID!
"""
Upload URL
"""
url: String!
}
"""
Un dossier
"""
@ -324,6 +395,10 @@ type MultipleDropDownListChamp implements Champ {
}
type Mutation {
"""
File information required to prepare a direct upload
"""
createDirectUpload(input: CreateDirectUploadInput!): CreateDirectUploadPayload
}
"""

View file

@ -1,4 +1,5 @@
module Types
class MutationType < Types::BaseObject
field :create_direct_upload, mutation: Mutations::CreateDirectUpload
end
end

View file

@ -166,6 +166,39 @@ describe API::V2::GraphqlController do
expect(gql_data[:dossier][:champs][0][:id]).to eq(dossier.champs[0].type_de_champ.to_typed_id)
end
end
context "mutations" do
context 'createDirectUpload' do
let(:query) do
"mutation {
createDirectUpload(input: {
dossierId: \"#{dossier.to_typed_id}\",
filename: \"hello.png\",
byteSize: 1234,
checksum: \"qwerty1234\",
contentType: \"image/png\"
}) {
directUpload {
url
headers
blobId
signedBlobId
}
}
}"
end
it "should initiate a direct upload" do
expect(gql_errors).to eq(nil)
data = gql_data[:createDirectUpload][:directUpload]
expect(data[:url]).not_to be_nil
expect(data[:headers]).not_to be_nil
expect(data[:blobId]).not_to be_nil
expect(data[:signedBlobId]).not_to be_nil
end
end
end
end
context "when not authenticated" do