skylab_studio 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f99a61b73fab6e35ba741ca1c841822634c163b1542e96008f4a6126c7fc7e1e
4
- data.tar.gz: 41cf785d1ff581766b3ba7fc05bd262648cbf0dde78daaabe3558c09e176dd9a
3
+ metadata.gz: 549e0ebc3cedf74a848a299346f93ce8b77c6d8813383f7993c82e755fbf4d88
4
+ data.tar.gz: 32825398b0428f26bf8548b40a4eae238d24b97709ce408b021c343901a99835
5
5
  SHA512:
6
- metadata.gz: 06ca0fa9eb3a14c85c463abfe59b275a612181ffbfe1db9c5f3b61fda266911372446ecdf1db3c0666376b972ca7dec5147dec1ea6e14fdf3862bbd4df0f4855
7
- data.tar.gz: 1aaaf67aeb7be27fd165a7b75d324db4408188b238d0b06eda13ff1f18dbd52969b09ee230ddac8b10422033f4da0b5c728d9687f82891fb578be087d15dec75
6
+ metadata.gz: af7021375c6030fcf977ff50fd85f1a55947ff7d6a0f4c122b0d8dd55ed4265dc5cccfcb020f04636cda76310910fd09fc1dbcda2b0477937b761185d36f7e63
7
+ data.tar.gz: c5cac2e61a900dd0460e477c6c8ecf5a83d2ae3e69fb0503b780e71550f3c79f25e67e83cc49fdfd6dd7663ac4e558da0521eea7e2bd9d9b17f52aa8f92baf5f
@@ -1,9 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'error'
2
4
  require 'fileutils'
3
5
  require 'digest'
4
6
  require 'open-uri'
5
7
  require 'base64'
6
8
  require 'net/http'
9
+ require 'vips'
10
+ require 'concurrent'
7
11
 
8
12
  module SkylabStudio
9
13
  class ClientNilArgument < Error; end
@@ -30,8 +34,8 @@ module SkylabStudio
30
34
  @configuration = SkylabStudio::Config.new(settings)
31
35
  end
32
36
 
33
- def list_jobs(options = {})
34
- SkylabStudio::Request.new(@configuration).get(:jobs, options)
37
+ def list_jobs()
38
+ SkylabStudio::Request.new(@configuration).get(:jobs)
35
39
  end
36
40
 
37
41
  def create_job(options = {})
@@ -41,10 +45,10 @@ module SkylabStudio
41
45
  SkylabStudio::Request.new(@configuration).post(:jobs, options)
42
46
  end
43
47
 
44
- def get_job(options = {})
45
- validate_argument_presence options, :id
48
+ def get_job(job_id)
49
+ validate_argument_presence nil, :job_id
46
50
 
47
- SkylabStudio::Request.new(@configuration).get("jobs/#{options[:id]}", options)
51
+ SkylabStudio::Request.new(@configuration).get("jobs/#{job_id}")
48
52
  end
49
53
 
50
54
  def get_job_by_name(options = {})
@@ -53,11 +57,10 @@ module SkylabStudio
53
57
  SkylabStudio::Request.new(@configuration).get('jobs/find_by_name', options)
54
58
  end
55
59
 
56
- def update_job(options = {})
57
- validate_argument_presence options, :id
58
- validate_argument_presence options, :job
60
+ def update_job(job_id, options = {})
61
+ validate_argument_presence nil, :job_id
59
62
 
60
- SkylabStudio::Request.new(@configuration).patch("jobs/#{options[:id]}", options)
63
+ SkylabStudio::Request.new(@configuration).patch("jobs/#{job_id}", options)
61
64
  end
62
65
 
63
66
  def queue_job(options = {})
@@ -66,20 +69,20 @@ module SkylabStudio
66
69
  SkylabStudio::Request.new(@configuration).post("jobs/#{options[:id]}/queue", options)
67
70
  end
68
71
 
69
- def fetch_jobs_in_front(options = {})
70
- SkylabStudio::Request.new(@configuration).get("jobs/#{options[:id]}/jobs_in_front", options)
72
+ def fetch_jobs_in_front(job_id)
73
+ SkylabStudio::Request.new(@configuration).get("jobs/#{job_id}/jobs_in_front")
71
74
  end
72
75
 
73
- def delete_job(options = {})
74
- validate_argument_presence options, :id
76
+ def delete_job(job_id)
77
+ validate_argument_presence nil, :job_id
75
78
 
76
- SkylabStudio::Request.new(@configuration).delete("jobs/#{options[:id]}")
79
+ SkylabStudio::Request.new(@configuration).delete("jobs/#{job_id}")
77
80
  end
78
81
 
79
- def cancel_job(options = {})
80
- validate_argument_presence options, :id
82
+ def cancel_job(job_id)
83
+ validate_argument_presence nil, :job_id
81
84
 
82
- SkylabStudio::Request.new(@configuration).post("jobs/#{options[:id]}/cancel", options)
85
+ SkylabStudio::Request.new(@configuration).post("jobs/#{job_id}/cancel", nil)
83
86
  end
84
87
 
85
88
  def list_profiles(options = {})
@@ -92,17 +95,16 @@ module SkylabStudio
92
95
  SkylabStudio::Request.new(@configuration).post(:profiles, options)
93
96
  end
94
97
 
95
- def get_profile(options = {})
96
- validate_argument_presence options, :id
98
+ def get_profile(profile_id)
99
+ validate_argument_presence nil, :profile_id
97
100
 
98
- SkylabStudio::Request.new(@configuration).get("profiles/#{options[:id]}", options)
101
+ SkylabStudio::Request.new(@configuration).get("profiles/#{profile_id}")
99
102
  end
100
103
 
101
- def update_profile(options = {})
102
- validate_argument_presence options, :id
103
- validate_argument_presence options, :profile
104
+ def update_profile(profile_id, options = {})
105
+ validate_argument_presence nil, :profile_id
104
106
 
105
- SkylabStudio::Request.new(@configuration).patch("profiles/#{options[:id]}", options)
107
+ SkylabStudio::Request.new(@configuration).patch("profiles/#{profile_id}", options)
106
108
  end
107
109
 
108
110
  def upload_job_photo(photo_path = nil, job_id = nil)
@@ -119,31 +121,112 @@ module SkylabStudio
119
121
  upload_photo(photo_path, profile_id, 'profile')
120
122
  end
121
123
 
122
- def get_photo(options = {})
123
- validate_argument_presence options, :id
124
+ def get_photo(photo_id)
125
+ validate_argument_presence nil, :photo_id
124
126
 
125
- SkylabStudio::Request.new(@configuration).get("photos/#{options[:id]}", options)
127
+ SkylabStudio::Request.new(@configuration).get("photos/#{photo_id}")
126
128
  end
127
129
 
128
- def get_job_photos(job_identifier, value)
129
- {
130
- "job_#{job_identifier}".to_sym => value
131
- }
130
+ def get_job_photos(job_id)
131
+ SkylabStudio::Request.new(@configuration).get('photos/list_for_job', { job_id: job_id })
132
+ end
132
133
 
133
- SkylabStudio::Request.new(@configuration).get('phtos/list_for_job', options)
134
+ def delete_photo(photo_id)
135
+ validate_argument_presence nil, :photo_id
136
+
137
+ SkylabStudio::Request.new(@configuration).delete("photos/#{photo_id}")
134
138
  end
135
139
 
136
- def update_photo(options = {})
137
- validate_argument_presence options, :id
138
- validate_argument_presence options, :photo
140
+ def download_photo(photo_id, output_path, profile: nil, options: {})
141
+ file_name = ''
142
+
143
+ unless Dir.exist?(output_path)
144
+ # Must be a file path - separate output_path and file_name
145
+ file_name = File.basename(output_path)
146
+ output_path = File.dirname(output_path) || ''
147
+ end
139
148
 
140
- SkylabStudio::Request.new(@configuration).patch("photos/#{options[:id]}", options)
149
+ begin
150
+ photo = get_photo(photo_id)
151
+ profile_id = photo['job']['profileId']
152
+
153
+ file_name = photo['name'] if file_name.empty?
154
+
155
+ profile ||= get_profile(profile_id)
156
+
157
+ is_extract = profile['enableExtract'].to_s == 'true'
158
+ replace_background = profile['replaceBackground'].to_s == 'true'
159
+ is_dual_file_output = profile['dualFileOutput'].to_s == 'true'
160
+ profile['enableStripPngMetadata'].to_s
161
+ bgs = options[:bgs]
162
+
163
+ # Load output image
164
+ image_buffer = download_image_async(photo['retouchedUrl'])
165
+ image = Vips::Image.new_from_buffer(image_buffer, '')
166
+
167
+ if is_extract # Output extract image
168
+ png_file_name = "#{File.basename(file_name, '.*')}.png"
169
+
170
+ # Dual File Output will provide an image in the format specified in the outputFileType field
171
+ # and an extracted image as a PNG.
172
+ image.write_to_file(File.join(output_path, png_file_name)) if is_dual_file_output
173
+
174
+ download_replaced_background_image(file_name, image, output_path, profile: profile, bgs: bgs) if replace_background
175
+
176
+ # Regular Extract output
177
+ image.write_to_file(File.join(output_path, png_file_name)) unless is_dual_file_output || replace_background
178
+ else # Non-extracted regular image output
179
+ image.write_to_file(File.join(output_path, file_name))
180
+ end
181
+
182
+ puts "Successfully downloaded: #{file_name}"
183
+ [file_name, true]
184
+ rescue StandardError => e
185
+ error_msg = "Failed to download photo id: #{photo_id} - #{e}"
186
+ raise error_msg if options[:return_on_error].nil?
187
+
188
+ [file_name, false]
189
+ end
141
190
  end
142
191
 
143
- def delete_photo(options = {})
144
- validate_argument_presence options, :id
192
+ def download_all_photos(photos_list, profile, output_path)
193
+ raise 'Invalid output path' unless Dir.exist?(output_path)
194
+
195
+ success_photos = []
196
+ errored_photos = []
197
+ bgs = []
145
198
 
146
- SkylabStudio::Request.new(@configuration).delete("photos/#{options[:id]}")
199
+ begin
200
+ profile = get_profile(profile['id'])
201
+ bgs = download_bg_images(profile) if profile && profile['photos']&.any?
202
+
203
+ photo_ids = photos_list.map { |photo| photo['id'].to_s }.compact
204
+
205
+ pool = Concurrent::FixedThreadPool.new(@configuration.settings[:max_download_concurrency])
206
+ download_tasks = []
207
+ photo_options = { return_on_error: true, bgs: bgs }
208
+ photo_ids.each do |photo_id|
209
+ download_tasks << Concurrent::Future.execute(executor: pool) do
210
+ download_photo(photo_id.to_i, output_path, profile: profile, options: photo_options)
211
+ end
212
+ end
213
+
214
+ # Wait for all download tasks to complete
215
+ results = download_tasks.map(&:value)
216
+ results.each do |result|
217
+ if result[1]
218
+ success_photos << result[0]
219
+ else
220
+ errored_photos << result[0]
221
+ end
222
+ end
223
+
224
+ { success_photos: success_photos, errored_photos: errored_photos }
225
+ rescue StandardError => e
226
+ warn e
227
+
228
+ { success_photos: success_photos, errored_photos: errored_photos }
229
+ end
147
230
  end
148
231
 
149
232
  private
@@ -157,7 +240,6 @@ module SkylabStudio
157
240
  end
158
241
 
159
242
  def upload_photo(photo_path, id, model = 'job')
160
- res = {}
161
243
  valid_exts_to_check = %w[.jpg .jpeg .png .webp]
162
244
 
163
245
  raise 'Invalid file type: must be of type jpg/jpeg/png/webp' unless valid_exts_to_check.any? { |ext| photo_path.downcase.end_with?(ext) }
@@ -167,6 +249,7 @@ module SkylabStudio
167
249
  raise 'Invalid file size: must be no larger than 27MB' if file_size > 27 * 1024 * 1024
168
250
 
169
251
  photo_name = File.basename(photo_path)
252
+ photo_ext = File.extname(photo_name)
170
253
  headers = {}
171
254
  md5hash = ''
172
255
 
@@ -178,10 +261,10 @@ module SkylabStudio
178
261
  end
179
262
 
180
263
  # model - either job or profile (job_id/profile_id)
181
- photo_data = { "#{model}_id" => id, name: photo_name, 'use_cache_upload' => false }
264
+ photo_data = { "#{model}_id": id, name: "#{photo_name}#{photo_ext}", path: photo_path, 'use_cache_upload': false }
182
265
 
183
266
  if model == 'job'
184
- job_type = get_job(id: id)['type']
267
+ job_type = get_job(id)['type']
185
268
 
186
269
  headers = { 'X-Amz-Tagging' => 'job=photo&api=true' } if job_type == 'regular'
187
270
  end
@@ -213,7 +296,7 @@ module SkylabStudio
213
296
  uri = URI(upload_url)
214
297
  request = Net::HTTP::Put.new(uri, headers)
215
298
  request.body = data
216
- upload_photo_resp = Net::HTTP.start(uri.hostname) {|http| http.request(request) }
299
+ upload_photo_resp = Net::HTTP.start(uri.hostname) { |http| http.request(request) }
217
300
 
218
301
  unless upload_photo_resp
219
302
  puts 'First upload attempt failed, retrying...'
@@ -221,7 +304,7 @@ module SkylabStudio
221
304
  # Retry upload
222
305
 
223
306
  while retry_count < 3
224
- upload_photo_resp = Net::HTTP.start(uri.hostname) {|http| http.request(request) }
307
+ upload_photo_resp = Net::HTTP.start(uri.hostname) { |http| http.request(request) }
225
308
  if upload_photo_resp
226
309
  break # Upload was successful, exit the loop
227
310
  elsif retry_count == 2 # Check if retry count is 2 (0-based indexing)
@@ -241,6 +324,70 @@ module SkylabStudio
241
324
  photo_response_json
242
325
  end
243
326
 
327
+ def download_image_async(image_url)
328
+ raise "Invalid retouchedUrl: \"#{image_url}\" - Please ensure the job is complete" unless image_url.start_with?('http', 'https')
329
+
330
+ begin
331
+ uri = URI(image_url)
332
+ response = Net::HTTP.get_response(uri)
333
+
334
+ if response.is_a?(Net::HTTPSuccess)
335
+ response.body
336
+
337
+ else
338
+ puts "Error downloading image: #{response.message}"
339
+ nil
340
+ end
341
+ rescue StandardError => e
342
+ puts "Error downloading image: #{e.message}"
343
+ nil
344
+ end
345
+ end
346
+
347
+ def download_bg_images(profile)
348
+ temp_bgs = []
349
+
350
+ bg_photos = profile['photos'].select { |photo| photo['jobId'].nil? }
351
+
352
+ bg_photos.each do |bg|
353
+ bg_buffer = download_image_async(bg['originalUrl'])
354
+ bg_image = Vips::Image.new_from_buffer(bg_buffer, '')
355
+ temp_bgs << bg_image
356
+ end
357
+
358
+ temp_bgs
359
+ end
360
+
361
+ def download_replaced_background_image(file_name, input_image, output_path, profile: nil, bgs: nil)
362
+ output_file_type = profile&.[]('outputFileType') || 'png'
363
+
364
+ bgs = download_bg_images(profile) if bgs.nil? && !profile.nil? && profile&.[]('photos')&.any?
365
+
366
+ alpha_channel = input_image[3]
367
+ rgb_channel = input_image[0..2]
368
+ rgb_cutout = rgb_channel.bandjoin(alpha_channel)
369
+
370
+ if bgs&.any?
371
+ bgs.each_with_index do |bg_image, i|
372
+ new_file_name = if i.zero?
373
+ "#{File.basename(file_name,
374
+ '.*')}.#{output_file_type}"
375
+ else
376
+ "#{File.basename(file_name,
377
+ '.*')} (#{i + 1}).#{output_file_type}"
378
+ end
379
+ resized_bg_image = bg_image.thumbnail_image(input_image.width, height: input_image.height, crop: :centre)
380
+ result_image = resized_bg_image.composite2(rgb_cutout, :over)
381
+ result_image.write_to_file(File.join(output_path, new_file_name))
382
+ end
383
+ end
384
+
385
+ true
386
+ rescue StandardError => e
387
+ error_msg = "Error downloading background image: #{e.message}"
388
+ raise error_msg
389
+ end
390
+
244
391
  def validate_argument_presence(options, key)
245
392
  raise SkylabStudio::ClientNilArgument, "#{key} cannot be nil" if options.is_a?(Hash) && options[key].nil?
246
393
 
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'version'
2
4
 
3
5
  module SkylabStudio
4
6
  class Config
5
7
  attr_accessor :settings
6
8
 
7
- DEFAULT_URL = 'https://studio.skylabtech.ai'.freeze
9
+ DEFAULT_URL = 'https://studio.skylabtech.ai'
8
10
 
9
11
  def self.defaults
10
12
  source = URI.parse(DEFAULT_URL)
@@ -17,7 +19,8 @@ module SkylabStudio
17
19
  port: source.port,
18
20
  api_version: 'v1',
19
21
  debug: true,
20
- client_stub: "ruby-#{VERSION}"
22
+ client_stub: "ruby-#{VERSION}",
23
+ max_download_concurrency: 5
21
24
  }
22
25
  end
23
26
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SkylabStudio
4
- VERSION = '1.0.6'
4
+ VERSION = '1.0.7'
5
5
  end
@@ -48,13 +48,13 @@ RSpec.describe SkylabStudio::Client do
48
48
 
49
49
  describe '#get_job' do
50
50
  it 'should raise error with no id' do
51
- expect { subject.get_job }.to raise_error(SkylabStudio::ClientNilArgument)
51
+ expect { subject.get_job }.to raise_error(ArgumentError)
52
52
  end
53
53
 
54
54
  it 'should return response' do
55
55
  SkylabStudio::Request.any_instance.stub(:get).and_return(true)
56
56
 
57
- subject.get_job(id: 123).should eq(true)
57
+ subject.get_job(123).should eq(true)
58
58
  end
59
59
  end
60
60
 
@@ -62,12 +62,7 @@ RSpec.describe SkylabStudio::Client do
62
62
  it 'should return response' do
63
63
  SkylabStudio::Request.any_instance.stub(:patch).and_return(true)
64
64
 
65
- subject.update_job(
66
- id: 1,
67
- job: {
68
- profile_id: 2
69
- }
70
- ).should eq(true)
65
+ subject.update_job(1, { profile_id: 2 }).should eq(true)
71
66
  end
72
67
  end
73
68
 
@@ -75,9 +70,7 @@ RSpec.describe SkylabStudio::Client do
75
70
  it 'should return response' do
76
71
  SkylabStudio::Request.any_instance.stub(:delete).and_return(true)
77
72
 
78
- subject.delete_job(
79
- id: 1
80
- ).should eq(true)
73
+ subject.delete_job(1).should eq(true)
81
74
  end
82
75
  end
83
76
 
@@ -95,9 +88,7 @@ RSpec.describe SkylabStudio::Client do
95
88
  it 'should return response' do
96
89
  SkylabStudio::Request.any_instance.stub(:post).and_return(true)
97
90
 
98
- subject.cancel_job(
99
- id: 1
100
- ).should eq(true)
91
+ subject.cancel_job(1).should eq(true)
101
92
  end
102
93
  end
103
94
 
@@ -123,13 +114,13 @@ RSpec.describe SkylabStudio::Client do
123
114
 
124
115
  describe '#get_profile' do
125
116
  it 'should raise error with no id' do
126
- expect { subject.get_profile }.to raise_error(SkylabStudio::ClientNilArgument)
117
+ expect { subject.get_profile }.to raise_error(ArgumentError)
127
118
  end
128
119
 
129
120
  it 'should return response' do
130
121
  SkylabStudio::Request.any_instance.stub(:get).and_return(true)
131
122
 
132
- subject.get_profile(id: 123).should eq(true)
123
+ subject.get_profile(123).should eq(true)
133
124
  end
134
125
  end
135
126
 
@@ -137,12 +128,7 @@ RSpec.describe SkylabStudio::Client do
137
128
  it 'should return response' do
138
129
  SkylabStudio::Request.any_instance.stub(:patch).and_return(true)
139
130
 
140
- subject.update_profile(
141
- id: 1,
142
- profile: {
143
- name: 'Bar'
144
- }
145
- ).should eq(true)
131
+ subject.update_profile(1, { name: 'Bar' } ).should eq(true)
146
132
  end
147
133
  end
148
134
 
@@ -152,24 +138,27 @@ RSpec.describe SkylabStudio::Client do
152
138
  .to_return(status: 200, body: { id: 1, photo: {} }.to_json, headers: {})
153
139
 
154
140
  stub_request(:get, 'https://studio.skylabtech.ai/api/public/v1/photos/upload_url')
155
- .to_return(status: 200, body: '', headers: {})
141
+ .to_return(status: 200, body: { url: 'http://test.test/' }.to_json, headers: {})
156
142
 
157
143
  stub_request(:get, 'https://studio.skylabtech.ai/api/public/v1/jobs/1')
158
- .to_return(status: 200, body: '', headers: {})
144
+ .to_return(status: 200, body: {}.to_json, headers: {})
159
145
 
160
146
  stub_request(:delete, 'https://studio.skylabtech.ai/api/public/v1/photos/1')
161
147
  .to_return(status: 200, body: { id: 1 }.to_json, headers: {})
162
148
 
163
- allow_any_instance_of(Net::HTTPSuccess).to receive(:body) { { id: 1 }.to_json }
149
+ stub_request(:put, /.*/)
150
+ .to_return(status: 200, body: {}.to_json, headers: {})
151
+
152
+ # allow_any_instance_of(Net::HTTPSuccess).to receive(:body) { { id: 1 }.to_json }
164
153
  end
165
154
 
166
155
  it 'should return response' do
167
156
  photo_path = "#{File.expand_path('../../', File.dirname(__FILE__))}/test-portrait-1.JPG"
168
157
  id = 1
169
158
 
170
- expected_response = { "id" => id }
159
+ expected_response = { id: id, photo: {} }.to_json
171
160
 
172
- subject.upload_job_photo(photo_path, id).should eq(expected_response)
161
+ expect(subject.upload_job_photo(photo_path, id).to_json).to eq(expected_response)
173
162
  end
174
163
  end
175
164
 
@@ -179,49 +168,40 @@ RSpec.describe SkylabStudio::Client do
179
168
  .to_return(status: 200, body: { id: 1, photo: {} }.to_json, headers: {})
180
169
 
181
170
  stub_request(:get, 'https://studio.skylabtech.ai/api/public/v1/photos/upload_url')
182
- .to_return(status: 200, body: '', headers: {})
171
+ .to_return(status: 200, body: { url: 'http://test.test/' }.to_json, headers: {})
172
+
173
+ stub_request(:get, 'https://studio.skylabtech.ai/api/public/v1/profiles/upload_url')
174
+ .to_return(status: 200, body: { url: 'http://test.test/' }.to_json, headers: {})
183
175
 
184
176
  stub_request(:get, 'https://studio.skylabtech.ai/api/public/v1/jobs/1')
185
- .to_return(status: 200, body: '', headers: {})
177
+ .to_return(status: 200, body: {}.to_json, headers: {})
186
178
 
187
179
  stub_request(:delete, 'https://studio.skylabtech.ai/api/public/v1/photos/1')
188
180
  .to_return(status: 200, body: { id: 1 }.to_json, headers: {})
189
181
 
190
- allow_any_instance_of(Net::HTTPSuccess).to receive(:body) { { id: 1 }.to_json }
182
+ stub_request(:put, /.*/)
183
+ .to_return(status: 200, body: {}.to_json, headers: {})
191
184
  end
192
185
 
193
186
  it 'should return response' do
194
187
  photo_path = "#{File.expand_path('../../', File.dirname(__FILE__))}/test-portrait-1.JPG"
195
188
  id = 1
196
189
 
197
- expected_response = { "id" => id }
190
+ expected_response = { id: id, photo: {} }.to_json
198
191
 
199
- subject.upload_profile_photo(photo_path, 1).should eq(expected_response)
192
+ expect(subject.upload_profile_photo(photo_path, 1).to_json).to eq(expected_response)
200
193
  end
201
194
  end
202
195
 
203
196
  describe '#get_photo' do
204
197
  it 'should raise error with no id' do
205
- expect { subject.get_photo }.to raise_error(SkylabStudio::ClientNilArgument)
198
+ expect { subject.get_photo }.to raise_error(ArgumentError)
206
199
  end
207
200
 
208
201
  it 'should return response' do
209
202
  SkylabStudio::Request.any_instance.stub(:get).and_return(true)
210
203
 
211
- subject.get_photo(id: 123).should eq(true)
212
- end
213
- end
214
-
215
- describe '#update_photo' do
216
- it 'should return response' do
217
- SkylabStudio::Request.any_instance.stub(:patch).and_return(true)
218
-
219
- subject.update_photo(
220
- id: 1,
221
- photo: {
222
- name: 'Bar'
223
- }
224
- ).should eq(true)
204
+ subject.get_photo(123).should eq(true)
225
205
  end
226
206
  end
227
207
 
@@ -229,9 +209,7 @@ RSpec.describe SkylabStudio::Client do
229
209
  it 'should return response' do
230
210
  SkylabStudio::Request.any_instance.stub(:delete).and_return(true)
231
211
 
232
- subject.delete_photo(
233
- id: 1
234
- ).should eq(true)
212
+ subject.delete_photo(1).should eq(true)
235
213
  end
236
214
  end
237
215
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skylab_studio
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Lam
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-20 00:00:00.000000000 Z
11
+ date: 2024-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec