diff --git a/api/app/controllers/spree/api/images_controller.rb b/api/app/controllers/spree/api/images_controller.rb index c18a9b757d1..9bb51fe2edb 100644 --- a/api/app/controllers/spree/api/images_controller.rb +++ b/api/app/controllers/spree/api/images_controller.rb @@ -15,13 +15,23 @@ def show def create authorize! :create, Image - @image = scope.images.create(image_params) + + @image = scope.images.build(image_params.except(:attachment)) + @image.attachment = prepared_attachment + @image.save + respond_with(@image, status: 201, default_template: :show) end def update @image = scope.images.accessible_by(current_ability, :update).find(params[:id]) - @image.update(image_params) + if image_params[:attachment].present? + @image.assign_attributes(image_params.except(:attachment)) + @image.attachment = prepared_attachment + @image.save + else + @image.update image_params + end respond_with(@image, default_template: :show) end @@ -44,6 +54,17 @@ def scope Spree::Variant.find(params[:variant_id]) end end + + def prepared_attachment + uri = URI.parse image_params[:attachment] + if uri.is_a? URI::HTTP + URI.open(image_params[:attachment]) + else + image_params[:attachment] + end + rescue URI::InvalidURIError + image_params[:attachment] + end end end end diff --git a/api/openapi/api.oas2.yml b/api/openapi/api.oas2.yml index 60ea5f155ac..c109c0cdc2e 100644 --- a/api/openapi/api.oas2.yml +++ b/api/openapi/api.oas2.yml @@ -5885,6 +5885,7 @@ definitions: type: string attachment: type: string + description: 'This field can be used to pass an image URL. When used in this manner, the image undergoes the standard post upload processing via paperclip.' position: type: integer viewable_type: diff --git a/api/spec/requests/spree/api/images_controller_spec.rb b/api/spec/requests/spree/api/images_controller_spec.rb index 6465005058d..c42a9a5e7d8 100644 --- a/api/spec/requests/spree/api/images_controller_spec.rb +++ b/api/spec/requests/spree/api/images_controller_spec.rb @@ -32,6 +32,22 @@ module Spree end.to change(Image, :count).by(1) end + it 'can upload a new image from a valid URL' do + expect do + post spree.api_product_images_path(product.id), params: { + image: { + attachment: 'https://github.com/solidusio/brand/raw/1827e7afb7ebcf5a1fc9cf7bf6cf9d277183ef11/PNG/solidus-logo-dark.png', + viewable_type: 'Spree::Variant', + viewable_id: product.master.to_param, + alt: 'just a test' + }, + } + expect(response.status).to eq(201) + expect(json_response).to have_attributes(attributes) + expect(json_response[:alt]).to eq('just a test') + end.to change(Image, :count).by(1) + end + context "working with an existing product image" do let!(:product_image) { product.master.images.create!(attachment: image('thinking-cat.jpg')) } @@ -69,6 +85,20 @@ module Spree expect(product_image.reload.position).to eq(2) end + it "can update image URL" do + expect(product_image.position).to eq(1) + put spree.api_variant_image_path(product.master.id, product_image), params: { + image: { + position: 2, + attachment: 'https://github.com/solidusio/brand/raw/1827e7afb7ebcf5a1fc9cf7bf6cf9d277183ef11/PNG/solidus-logo-dark.png' + }, + } + expect(response.status).to eq(200) + expect(json_response).to have_attributes(attributes) + expect(product_image.reload.position).to eq(2) + expect(product_image.reload.attachment_height).to eq(420) + end + it "can delete an image" do delete spree.api_variant_image_path(product.master.id, product_image) expect(response.status).to eq(204)