skylab_studio 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/skylab_studio/client.rb +191 -44
- data/lib/skylab_studio/config.rb +5 -2
- data/lib/skylab_studio/version.rb +1 -1
- data/spec/lib/skylab_studio/client_spec.rb +28 -50
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 549e0ebc3cedf74a848a299346f93ce8b77c6d8813383f7993c82e755fbf4d88
|
4
|
+
data.tar.gz: 32825398b0428f26bf8548b40a4eae238d24b97709ce408b021c343901a99835
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af7021375c6030fcf977ff50fd85f1a55947ff7d6a0f4c122b0d8dd55ed4265dc5cccfcb020f04636cda76310910fd09fc1dbcda2b0477937b761185d36f7e63
|
7
|
+
data.tar.gz: c5cac2e61a900dd0460e477c6c8ecf5a83d2ae3e69fb0503b780e71550f3c79f25e67e83cc49fdfd6dd7663ac4e558da0521eea7e2bd9d9b17f52aa8f92baf5f
|
data/lib/skylab_studio/client.rb
CHANGED
@@ -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(
|
34
|
-
SkylabStudio::Request.new(@configuration).get(:jobs
|
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(
|
45
|
-
validate_argument_presence
|
48
|
+
def get_job(job_id)
|
49
|
+
validate_argument_presence nil, :job_id
|
46
50
|
|
47
|
-
SkylabStudio::Request.new(@configuration).get("jobs/#{
|
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
|
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/#{
|
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(
|
70
|
-
SkylabStudio::Request.new(@configuration).get("jobs/#{
|
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(
|
74
|
-
validate_argument_presence
|
76
|
+
def delete_job(job_id)
|
77
|
+
validate_argument_presence nil, :job_id
|
75
78
|
|
76
|
-
SkylabStudio::Request.new(@configuration).delete("jobs/#{
|
79
|
+
SkylabStudio::Request.new(@configuration).delete("jobs/#{job_id}")
|
77
80
|
end
|
78
81
|
|
79
|
-
def cancel_job(
|
80
|
-
validate_argument_presence
|
82
|
+
def cancel_job(job_id)
|
83
|
+
validate_argument_presence nil, :job_id
|
81
84
|
|
82
|
-
SkylabStudio::Request.new(@configuration).post("jobs/#{
|
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(
|
96
|
-
validate_argument_presence
|
98
|
+
def get_profile(profile_id)
|
99
|
+
validate_argument_presence nil, :profile_id
|
97
100
|
|
98
|
-
SkylabStudio::Request.new(@configuration).get("profiles/#{
|
101
|
+
SkylabStudio::Request.new(@configuration).get("profiles/#{profile_id}")
|
99
102
|
end
|
100
103
|
|
101
|
-
def update_profile(options = {})
|
102
|
-
validate_argument_presence
|
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/#{
|
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(
|
123
|
-
validate_argument_presence
|
124
|
+
def get_photo(photo_id)
|
125
|
+
validate_argument_presence nil, :photo_id
|
124
126
|
|
125
|
-
SkylabStudio::Request.new(@configuration).get("photos/#{
|
127
|
+
SkylabStudio::Request.new(@configuration).get("photos/#{photo_id}")
|
126
128
|
end
|
127
129
|
|
128
|
-
def get_job_photos(
|
129
|
-
{
|
130
|
-
|
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
|
-
|
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
|
137
|
-
|
138
|
-
|
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
|
-
|
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
|
144
|
-
|
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
|
-
|
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"
|
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
|
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
|
|
data/lib/skylab_studio/config.rb
CHANGED
@@ -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'
|
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
|
|
@@ -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(
|
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(
|
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(
|
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(
|
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:
|
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
|
-
|
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 = {
|
159
|
+
expected_response = { id: id, photo: {} }.to_json
|
171
160
|
|
172
|
-
subject.upload_job_photo(photo_path, id).
|
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:
|
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
|
-
|
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 = {
|
190
|
+
expected_response = { id: id, photo: {} }.to_json
|
198
191
|
|
199
|
-
subject.upload_profile_photo(photo_path, 1).
|
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(
|
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(
|
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.
|
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-
|
11
|
+
date: 2024-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|