skylab_studio 1.0.6 → 1.0.8
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 +202 -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: 8dcea80a2765d6d89b736dbdaf420595a284c66b1c2319bdb537e6dce55d6c29
|
4
|
+
data.tar.gz: 26870d180ef19254df91ce67ffeb150564c6a144ccbc8965414c48938f687486
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b01781324fb9c33b8720b54d218ed0c60f346069b04ac646e720b641c85316ef140d96821d69f1054c73a997445a0c1cc4adbf56be3c2f3a765e42c7354ea6d4
|
7
|
+
data.tar.gz: e78732d764037a41fad813879db50e04defe51ac4eb2eadd1c437693f5e8e58489c5795d135f0c4e81a3d3a4c2d17b024d2897e6733603ec5d81d8a8f41cfef6
|
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,123 @@ 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
|
133
|
+
|
134
|
+
def delete_photo(photo_id)
|
135
|
+
validate_argument_presence nil, :photo_id
|
132
136
|
|
133
|
-
SkylabStudio::Request.new(@configuration).
|
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 = []
|
198
|
+
|
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
|
145
213
|
|
146
|
-
|
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
|
230
|
+
end
|
231
|
+
|
232
|
+
def validate_hmac_headers(secret_key, job_json_string, request_timestamp, signature)
|
233
|
+
message = "#{request_timestamp}:#{job_json_string}".encode('utf-8')
|
234
|
+
|
235
|
+
# Create the HMAC signature using SHA-256
|
236
|
+
hmac_digest = OpenSSL::HMAC.digest('sha256', secret_key.encode('utf-8'), message)
|
237
|
+
generated_sig = Base64.strict_encode64(hmac_digest).force_encoding('utf-8')
|
238
|
+
|
239
|
+
# Compare the provided signature with the generated signature
|
240
|
+
signature == generated_sig
|
147
241
|
end
|
148
242
|
|
149
243
|
private
|
@@ -157,7 +251,6 @@ module SkylabStudio
|
|
157
251
|
end
|
158
252
|
|
159
253
|
def upload_photo(photo_path, id, model = 'job')
|
160
|
-
res = {}
|
161
254
|
valid_exts_to_check = %w[.jpg .jpeg .png .webp]
|
162
255
|
|
163
256
|
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 +260,7 @@ module SkylabStudio
|
|
167
260
|
raise 'Invalid file size: must be no larger than 27MB' if file_size > 27 * 1024 * 1024
|
168
261
|
|
169
262
|
photo_name = File.basename(photo_path)
|
263
|
+
photo_ext = File.extname(photo_name)
|
170
264
|
headers = {}
|
171
265
|
md5hash = ''
|
172
266
|
|
@@ -178,10 +272,10 @@ module SkylabStudio
|
|
178
272
|
end
|
179
273
|
|
180
274
|
# model - either job or profile (job_id/profile_id)
|
181
|
-
photo_data = { "#{model}_id"
|
275
|
+
photo_data = { "#{model}_id": id, name: "#{photo_name}#{photo_ext}", path: photo_path, 'use_cache_upload': false }
|
182
276
|
|
183
277
|
if model == 'job'
|
184
|
-
job_type = get_job(id
|
278
|
+
job_type = get_job(id)['type']
|
185
279
|
|
186
280
|
headers = { 'X-Amz-Tagging' => 'job=photo&api=true' } if job_type == 'regular'
|
187
281
|
end
|
@@ -213,7 +307,7 @@ module SkylabStudio
|
|
213
307
|
uri = URI(upload_url)
|
214
308
|
request = Net::HTTP::Put.new(uri, headers)
|
215
309
|
request.body = data
|
216
|
-
upload_photo_resp = Net::HTTP.start(uri.hostname) {|http| http.request(request) }
|
310
|
+
upload_photo_resp = Net::HTTP.start(uri.hostname) { |http| http.request(request) }
|
217
311
|
|
218
312
|
unless upload_photo_resp
|
219
313
|
puts 'First upload attempt failed, retrying...'
|
@@ -221,7 +315,7 @@ module SkylabStudio
|
|
221
315
|
# Retry upload
|
222
316
|
|
223
317
|
while retry_count < 3
|
224
|
-
upload_photo_resp = Net::HTTP.start(uri.hostname) {|http| http.request(request) }
|
318
|
+
upload_photo_resp = Net::HTTP.start(uri.hostname) { |http| http.request(request) }
|
225
319
|
if upload_photo_resp
|
226
320
|
break # Upload was successful, exit the loop
|
227
321
|
elsif retry_count == 2 # Check if retry count is 2 (0-based indexing)
|
@@ -241,6 +335,70 @@ module SkylabStudio
|
|
241
335
|
photo_response_json
|
242
336
|
end
|
243
337
|
|
338
|
+
def download_image_async(image_url)
|
339
|
+
raise "Invalid retouchedUrl: \"#{image_url}\" - Please ensure the job is complete" unless image_url.start_with?('http', 'https')
|
340
|
+
|
341
|
+
begin
|
342
|
+
uri = URI(image_url)
|
343
|
+
response = Net::HTTP.get_response(uri)
|
344
|
+
|
345
|
+
if response.is_a?(Net::HTTPSuccess)
|
346
|
+
response.body
|
347
|
+
|
348
|
+
else
|
349
|
+
puts "Error downloading image: #{response.message}"
|
350
|
+
nil
|
351
|
+
end
|
352
|
+
rescue StandardError => e
|
353
|
+
puts "Error downloading image: #{e.message}"
|
354
|
+
nil
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
def download_bg_images(profile)
|
359
|
+
temp_bgs = []
|
360
|
+
|
361
|
+
bg_photos = profile['photos'].select { |photo| photo['jobId'].nil? }
|
362
|
+
|
363
|
+
bg_photos.each do |bg|
|
364
|
+
bg_buffer = download_image_async(bg['originalUrl'])
|
365
|
+
bg_image = Vips::Image.new_from_buffer(bg_buffer, '')
|
366
|
+
temp_bgs << bg_image
|
367
|
+
end
|
368
|
+
|
369
|
+
temp_bgs
|
370
|
+
end
|
371
|
+
|
372
|
+
def download_replaced_background_image(file_name, input_image, output_path, profile: nil, bgs: nil)
|
373
|
+
output_file_type = profile&.[]('outputFileType') || 'png'
|
374
|
+
|
375
|
+
bgs = download_bg_images(profile) if bgs.nil? && !profile.nil? && profile&.[]('photos')&.any?
|
376
|
+
|
377
|
+
alpha_channel = input_image[3]
|
378
|
+
rgb_channel = input_image[0..2]
|
379
|
+
rgb_cutout = rgb_channel.bandjoin(alpha_channel)
|
380
|
+
|
381
|
+
if bgs&.any?
|
382
|
+
bgs.each_with_index do |bg_image, i|
|
383
|
+
new_file_name = if i.zero?
|
384
|
+
"#{File.basename(file_name,
|
385
|
+
'.*')}.#{output_file_type}"
|
386
|
+
else
|
387
|
+
"#{File.basename(file_name,
|
388
|
+
'.*')} (#{i + 1}).#{output_file_type}"
|
389
|
+
end
|
390
|
+
resized_bg_image = bg_image.thumbnail_image(input_image.width, height: input_image.height, crop: :centre)
|
391
|
+
result_image = resized_bg_image.composite2(rgb_cutout, :over)
|
392
|
+
result_image.write_to_file(File.join(output_path, new_file_name))
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
true
|
397
|
+
rescue StandardError => e
|
398
|
+
error_msg = "Error downloading background image: #{e.message}"
|
399
|
+
raise error_msg
|
400
|
+
end
|
401
|
+
|
244
402
|
def validate_argument_presence(options, key)
|
245
403
|
raise SkylabStudio::ClientNilArgument, "#{key} cannot be nil" if options.is_a?(Hash) && options[key].nil?
|
246
404
|
|
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.8
|
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-
|
11
|
+
date: 2024-04-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|