Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ PATH
beyond_api (0.24.2.pre)
activesupport (~> 7.0)
faraday (~> 2.10.0)
faraday-multipart
faraday-retry
zeitwerk

Expand Down Expand Up @@ -42,6 +43,8 @@ GEM
faraday (2.10.1)
faraday-net_http (>= 2.0, < 3.2)
logger
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (3.1.1)
net-http
faraday-retry (2.2.1)
Expand All @@ -56,6 +59,7 @@ GEM
logger (1.6.0)
method_source (1.1.0)
minitest (5.24.1)
multipart-post (2.4.1)
net-http (0.4.1)
uri
parallel (1.26.2)
Expand Down
1 change: 1 addition & 0 deletions beyond_api.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Gem::Specification.new do |spec|

spec.add_dependency 'activesupport', '~> 7.0'
spec.add_dependency 'faraday', '~> 2.10.0'
spec.add_dependency 'faraday-multipart'
spec.add_dependency 'faraday-retry'
spec.add_dependency 'zeitwerk'

Expand Down
1 change: 1 addition & 0 deletions lib/beyond_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'active_support/all'
require 'faraday'
require 'faraday/retry'
require 'faraday/multipart'
require 'forwardable'
require 'json'
require 'zeitwerk'
Expand Down
22 changes: 22 additions & 0 deletions lib/beyond_api/concerns/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,27 @@ def delete(path, params = {})
handle_request { agent.delete(path, parse_request(params)) }
end

def upload_file(path, file_path, params = {})
handle_request do
agent.post(path) do |request|
request.headers['Content-Type'] = Utils.file_content_type(file_path)
request.params = parse_request(params)
request.body = File.binread(file_path)
end
end
end

def upload_files(path, body, params = {})
handle_request do
agent.post(path) do |request|
request.headers['Content-Type'] = 'multipart/form-data'
request.options[:params_encoder] = Faraday::FlatParamsEncoder
request.params = parse_request(params)
request.body = body
end
end
end

private

def parse_request(hash)
Expand Down Expand Up @@ -59,6 +80,7 @@ def agent
# Request options
faraday.request :json # Encode request bodies as JSON
faraday.request :retry, BeyondApi.configuration.retry_options
faraday.request :multipart, { flat_encode: true }
# Response options
faraday.response :json, content_type: 'application/json'
faraday.response :logger, *logger_config { |logger| apply_filters(logger) }
Expand Down
38 changes: 38 additions & 0 deletions lib/beyond_api/services/product_management/image.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,44 @@ class Image < BaseService
def all(id, params = {})
get("products/#{id}/images", params)
end

# Upload an image and add it to a product. The body of the request must contain the content of the image.
# The maximum image size is 7000 × 7000 px, and the maximum file size per image is 8 MB.
#
# @see https://developer.epages.com/beyond-docs/#upload_product_image
#
# @param id [String] the product UUID
# @param id [String] the image path
# @param id [String] the image file name
#
# @return [Hash]
#
# @example
# client.upload('4125b993-49fc-47c8-b9b3-76d8871e4e06', '/home/epages/file.png', 'file.png')
def upload(product_id, image_path, image_name)
upload_file("products/#{product_id}/images", image_path, file_name: image_name)
end

# Upload up to 10 images and add them to a product. The body of the request must contain the content of the images.
# The maximum image size is 7000 × 7000px, and the maximum file size per image is 8 MB.
#
# @see https://developer.epages.com/beyond-docs/#upload_multiple_product_images
#
# @param id [String] the product UUID
# @param id [Array] an array of strings containing the path of each image
# @param id [Array] an array of strings containing the file name of each image
#
# @return [Hash]
#
# @example
# image_paths = ['/home/epages/file1.png', '/home/epages/file2.png']
# image_names = ['file1.png', 'file2.png']
# client.upload('4125b993-49fc-47c8-b9b3-76d8871e4e06', image_paths, image_names)
def upload_multiple(product_id, image_paths, image_names)
upload_files("products/#{product_id}/images",
{ image: Utils.faraday_file_parts(image_paths) }, # body
{ file_name: Utils.encode_filenames(image_names) }) # params
end
end
end
end
10 changes: 10 additions & 0 deletions lib/beyond_api/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,15 @@ def self.file_content_type(file_path)
def self.camelize_keys(hash)
hash.deep_transform_keys { |key| key.to_s.camelize(:lower) }
end

def self.faraday_file_parts(file_paths)
file_paths.map do |file_path|
Faraday::FilePart.new(File.open(file_path), Utils.file_content_type(file_path))
end
end

def self.encode_filenames(filenames)
filenames.map { |e| URI.encode_www_form([e]) }
end
end
end
21 changes: 20 additions & 1 deletion spec/beyond_api/services/product_management/image_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

RSpec.describe BeyondApi::ProductManagement::Image, vcr: true do
RSpec.describe BeyondApi::ProductManagement::Image, vcr: { match_requests_on: [:method, :uri] } do
let(:client) { described_class.new(api_url: ENV.fetch('API_URL', nil), access_token: beyond_access_token) }

describe '.all' do
Expand All @@ -12,4 +12,23 @@
expect(response[:page]).to be_kind_of(Hash)
end
end

describe '.upload' do
it 'uploads an image' do
response = client.upload('4bf6d53d-dfb2-4468-b6f9-f6e6265bc0bc',
'spec/files/image1.png',
'new-image.png')

expect(response).not_to be nil
expect(response.dig(:links, :data, :href)).to include('new-image.png')
end

it 'uploads multiple images' do
response = client.upload_multiple('4bf6d53d-dfb2-4468-b6f9-f6e6265bc0bc',
['spec/files/image2.png', 'spec/files/image3.png'],
['new-image2.png', 'new-image3.png'])
expect(response).not_to be nil
expect(response.dig(:embedded, :images)).to be_kind_of(Array)
end
end
end
Binary file added spec/files/image3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading