imgix 3.1.1 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,6 +3,27 @@
3
3
  require 'test_helper'
4
4
 
5
5
  class PathTest < Imgix::Test
6
+ def test_prefix_with_arg_warns
7
+ prefix_warn = "Warning: `Client::prefix' will take zero arguments " \
8
+ "in the next major version.\n"
9
+
10
+ assert_output(nil, prefix_warn) {
11
+ Imgix::Client.new(
12
+ domain: 'test.imgix.net',
13
+ include_library_param: false
14
+ ).prefix("")
15
+ }
16
+
17
+ # `new_prefix' is a placeholder until the bump, when it will become
18
+ # `prefix`.
19
+ assert_output(nil, nil) {
20
+ Imgix::Client.new(
21
+ domain: 'test.imgix.net',
22
+ include_library_param: false
23
+ ).new_prefix
24
+ }
25
+ end
26
+
6
27
  def test_creating_a_path
7
28
  path = client.path('/images/demo.png')
8
29
  assert_equal 'https://demo.imgix.net/images/demo.png?s=2c7c157eaf23b06a0deb2f60b81938c4', path.to_url
@@ -14,7 +35,12 @@ class PathTest < Imgix::Test
14
35
  def test_signing_path_with_param
15
36
  url = 'https://demo.imgix.net/images/demo.png?w=200&s=da421114ca238d1f4a927b889f67c34e'
16
37
  path = client.path('/images/demo.png')
17
- path.width = 200
38
+
39
+ assert_output(nil, "Warning: `Path.width=' has been deprecated and " \
40
+ "will be removed in the next major version (along " \
41
+ "with all parameter `ALIASES`).\n") {
42
+ path.width = 200
43
+ }
18
44
 
19
45
  assert_equal url, path.to_url
20
46
 
@@ -22,13 +48,23 @@ class PathTest < Imgix::Test
22
48
  assert_equal url, path.to_url(w: 200)
23
49
 
24
50
  path = client.path('/images/demo.png')
25
- assert_equal url, path.width(200).to_url
51
+
52
+ assert_output(nil, "Warning: `Path.width' has been deprecated and " \
53
+ "will be removed in the next major version (along " \
54
+ "with all parameter `ALIASES`).\n") {
55
+ assert_equal url, path.width(200).to_url
56
+ }
26
57
  end
27
58
 
28
59
  def test_resetting_defaults
29
60
  url = 'https://demo.imgix.net/images/demo.png?w=200&s=da421114ca238d1f4a927b889f67c34e'
30
61
  path = client.path('/images/demo.png')
31
- path.height = 300
62
+
63
+ assert_output(nil, "Warning: `Path.height=' has been deprecated and " \
64
+ "will be removed in the next major version (along " \
65
+ "with all parameter `ALIASES`).\n") {
66
+ path.height = 300
67
+ }
32
68
 
33
69
  assert_equal url, path.defaults.to_url(w: 200)
34
70
  end
@@ -40,7 +76,21 @@ class PathTest < Imgix::Test
40
76
  assert_equal url, path.to_url(h: 200, w: 200)
41
77
 
42
78
  path = client.path('/images/demo.png')
43
- assert_equal url, path.height(200).width(200).to_url
79
+
80
+ assert_output(nil, "Warning: `Path.height' has been deprecated and " \
81
+ "will be removed in the next major version (along " \
82
+ "with all parameter `ALIASES`).\n") {
83
+ path.height(200)
84
+ }
85
+
86
+
87
+ assert_output(nil, "Warning: `Path.width' has been deprecated and " \
88
+ "will be removed in the next major version (along " \
89
+ "with all parameter `ALIASES`).\n") {
90
+ path.width(200)
91
+ }
92
+
93
+ assert_equal url, path.to_url
44
94
  end
45
95
 
46
96
  def test_path_with_multi_value_param_safely_encoded
@@ -1,25 +1,70 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class PurgeTest < Imgix::Test
4
6
  def test_runtime_error_without_api_key
5
- assert_raises(RuntimeError) {
6
- Imgix::Client.new(host: 'demo.imgix.net', include_library_param: false)
7
- .purge('https://demo.imgix.net/images/demo.png')
8
- }
7
+ assert_raises(RuntimeError) do
8
+ mock_client(api_key: nil).purge(mock_image)
9
+ end
10
+ end
11
+
12
+ def test_purger_version_warns
13
+ stub_request(:post, endpoint).with(body: body).to_return(status: 200)
14
+
15
+ assert_output(nil, deprecation_warning) do
16
+ mock_client(api_key: '10adc394').purge('/images/demo.png')
17
+ end
9
18
  end
10
-
19
+
11
20
  def test_successful_purge
12
- stub_request(:post, "https://api.imgix.com/v2/image/purger").
13
- with(
14
- body: {"url"=>"https://demo.imgix.net/images/demo.png"}).
15
- to_return(status: 200)
16
-
17
- Imgix::Client.new(host: 'demo.imgix.net', api_key: '10adc394')
18
- .purge('/images/demo.png')
19
-
20
- assert_requested :post, 'https://api.imgix.com/v2/image/purger',
21
- body: 'url=https%3A%2F%2Fdemo.imgix.net%2Fimages%2Fdemo.png',
22
- headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'Basic MTBhZGMzOTQ6', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>"imgix rb-#{ Imgix::VERSION}"},
21
+ stub_request(:post, endpoint).with(body: body).to_return(status: 200)
22
+
23
+ mock_client(api_key: '10adc394').purge('/images/demo.png')
24
+
25
+ assert_requested(
26
+ :post,
27
+ endpoint,
28
+ body: 'url=https%3A%2F%2Fdemo.imgix.net%2Fimages%2Fdemo.png',
29
+ headers: mock_headers,
23
30
  times: 1
31
+ )
32
+ end
33
+
34
+ private
35
+
36
+ def mock_client(api_key: '')
37
+ Imgix::Client.new(
38
+ domain: 'demo.imgix.net',
39
+ api_key: api_key,
40
+ include_library_param: false
41
+ )
42
+ end
43
+
44
+ def mock_headers
45
+ {
46
+ 'Accept' => '*/*',
47
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
48
+ 'Authorization' => 'Basic MTBhZGMzOTQ6',
49
+ 'Content-Type' => 'application/x-www-form-urlencoded',
50
+ 'User-Agent' => "imgix rb-#{Imgix::VERSION}"
51
+ }
52
+ end
53
+
54
+ def mock_image
55
+ 'https://demo.imgix.net/images/demo.png'
56
+ end
57
+
58
+ def endpoint
59
+ 'https://api.imgix.com/v2/image/purger'
60
+ end
61
+
62
+ def body
63
+ { 'url' => mock_image }
64
+ end
65
+
66
+ def deprecation_warning
67
+ "Warning: Your `api_key` will no longer work after upgrading to\n" \
68
+ "imgix-rb version >= 4.0.0.\n"
24
69
  end
25
- end
70
+ end
@@ -1,314 +1,755 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module SrcsetTest
6
+ RESOLUTIONS = [
7
+ 100, 116, 135, 156, 181, 210, 244, 283,
8
+ 328, 380, 441, 512, 594, 689, 799, 927,
9
+ 1075, 1247, 1446, 1678, 1946, 2257, 2619,
10
+ 3038, 3524, 4087, 4741, 5500, 6380, 7401, 8192
11
+ ].freeze
12
+
13
+ DPR_QUALITY = [75, 50, 35, 23, 20].freeze
14
+
15
+ DOMAIN = 'testing.imgix.net'
16
+ TOKEN = 'MYT0KEN'
17
+ JPG_PATH = 'image.jpg'
18
+
19
+ def mock_client
20
+ Imgix::Client.new(
21
+ host: DOMAIN,
22
+ include_library_param: false
23
+ ).path(JPG_PATH)
24
+ end
25
+
26
+ def mock_signed_client
27
+ Imgix::Client.new(
28
+ host: DOMAIN,
29
+ secure_url_token: TOKEN,
30
+ include_library_param: false
31
+ ).path(JPG_PATH)
32
+ end
33
+
34
+ def signature_base(params)
35
+ TOKEN + '/' + JPG_PATH + params
36
+ end
37
+
38
+ def get_sig_from(src)
39
+ src.slice(src.index('s=') + 2, src.length)
40
+ end
41
+
42
+ def get_params_from(src)
43
+ src[src.index('?')..src.index('s=') - 2]
44
+ end
45
+
46
+ def get_expected_signature(src)
47
+ # Ensure signature param exists.
48
+ assert_includes src, 's='
49
+
50
+ params = get_params_from(src)
51
+ signature_base = signature_base(params)
52
+
53
+ Digest::MD5.hexdigest(signature_base)
54
+ end
55
+
56
+ class SrcsetDefault < Imgix::Test
57
+ include SrcsetTest
58
+
59
+ def test_no_parameters
60
+ srcset = path.to_srcset
61
+
62
+ expected_number_of_pairs = 31
63
+ assert_equal expected_number_of_pairs, srcset.split(',').length
64
+ end
65
+
66
+ def test_srcset_pair_values
67
+ resolutions = RESOLUTIONS
68
+ srcset = path.to_srcset
69
+ srclist = srcset.split(',').map do |srcset_split|
70
+ srcset_split.split(' ')[1].to_i
71
+ end
72
+
73
+ for i in 0..srclist.length - 1
74
+ assert_equal(srclist[i], resolutions[i])
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ def path
81
+ @client ||= mock_signed_client
82
+ end
83
+ end
84
+
85
+ class SrcsetGivenWidth < Imgix::Test
86
+ include SrcsetTest
87
+
88
+ def test_srcset_in_dpr_form
89
+ device_pixel_ratio = 1
90
+
91
+ srcset.split(',').map do |src|
92
+ ratio = src.split(' ')[1]
93
+ assert_equal "#{device_pixel_ratio}x", ratio
94
+ device_pixel_ratio += 1
95
+ end
96
+ end
97
+
98
+ def test_srcset_has_dpr_params
99
+ i = 1
100
+ srcset.split(',').map do |srcset_split|
101
+ src = srcset_split.split(' ')[0]
102
+ assert_includes src, "dpr=#{i}"
103
+ i += 1
104
+ end
105
+ end
106
+
107
+ def test_srcset_signs_urls
108
+ srcset.split(',').map do |srcset_split|
109
+ src = srcset_split.split(' ')[0]
110
+ expected_signature = get_expected_signature(src)
111
+
112
+ assert_includes src, expected_signature
113
+ end
114
+ end
115
+
116
+ def test_srcset_has_variable_qualities
117
+ i = 0
118
+ srcset.split(',').map do |src|
119
+ assert_includes src, "q=#{DPR_QUALITY[i]}"
120
+ i += 1
121
+ end
122
+ end
123
+
124
+ def test_srcset_respects_overriding_quality
125
+ quality_override = 100
126
+ srcset = mock_signed_client.to_srcset(w: 100, q: quality_override)
127
+
128
+ srcset.split(',').map do |src|
129
+ assert_includes src, "q=#{quality_override}"
130
+ end
131
+ end
132
+
133
+ def test_disable_variable_quality
134
+ srcset = mock_signed_client.to_srcset(
135
+ w: 100,
136
+ options: { disable_variable_quality: true }
137
+ )
138
+
139
+ srcset.split(',').map do |src|
140
+ assert(not(src.include?('q=')))
141
+ end
142
+ end
143
+
144
+ def test_respects_quality_param_when_disabled
145
+ quality_override = 100
146
+ srcset = mock_signed_client.to_srcset(
147
+ w: 100, q: 100,
148
+ options: { disable_variable_quality: true }
149
+ )
150
+
151
+ srcset.split(',').map do |src|
152
+ assert_includes src, "q=#{quality_override}"
153
+ end
154
+ end
155
+
156
+ private
157
+
158
+ def srcset
159
+ @client ||= mock_signed_client.to_srcset(w: 100)
160
+ end
161
+ end
162
+
163
+ class SrcsetGivenHeight < Imgix::Test
164
+ include SrcsetTest
165
+
166
+ def test_srcset_generates_width_pairs
167
+ expected_number_of_pairs = 31
168
+ assert_equal expected_number_of_pairs, srcset.split(',').length
169
+ end
170
+
171
+ def test_srcset_pair_values
172
+ resolutions = RESOLUTIONS
173
+ srclist = srcset.split(',').map do |srcset_split|
174
+ srcset_split.split(' ')[1].to_i
175
+ end
176
+
177
+ for i in 0..srclist.length - 1
178
+ assert_equal(srclist[i], resolutions[i])
179
+ end
180
+ end
181
+
182
+ def test_srcset_respects_height_parameter
183
+ srcset.split(',').map do |src|
184
+ assert_includes src, 'h='
185
+ end
186
+ end
187
+
188
+ def test_srcset_within_bounds
189
+ min, *max = srcset.split(',')
190
+
191
+ # parse out the width descriptor as an integer
192
+ min = min.split(' ')[1].to_i
193
+ max = max[max.length - 1].split(' ')[1].to_i
194
+
195
+ assert_operator min, :>=, 100
196
+ assert_operator max, :<=, 8192
197
+ end
198
+
199
+ # a 17% testing threshold is used to account for rounding
200
+ def test_srcset_iterates_17_percent
201
+ increment_allowed = 0.17
202
+
203
+ # create an array of widths
204
+ widths = srcset.split(',').map do |src|
205
+ src.split(' ')[1].to_i
206
+ end
207
+
208
+ prev = widths[0]
209
+
210
+ for i in 1..widths.length - 1
211
+ element = widths[i]
212
+ assert_operator (element.to_f / prev.to_f), :<, (1 + increment_allowed)
213
+ prev = element
214
+ end
215
+ end
216
+
217
+ def test_srcset_signs_urls
218
+ srcset.split(',').map do |srcset_split|
219
+ src = srcset_split.split(' ')[0]
220
+ expected_signature = get_expected_signature(src)
221
+
222
+ assert_includes src, expected_signature
223
+ end
224
+ end
225
+
226
+ private
227
+
228
+ def srcset
229
+ @client ||= mock_signed_client.to_srcset(h: 100)
230
+ end
231
+ end
232
+
233
+ class SrcsetGivenWidthAndHeight < Imgix::Test
234
+ include SrcsetTest
235
+
236
+ def test_srcset_in_dpr_form
237
+ device_pixel_ratio = 1
238
+ srcset.split(',').map do |src|
239
+ ratio = src.split(' ')[1]
240
+ assert_equal "#{device_pixel_ratio}x", ratio
241
+ device_pixel_ratio += 1
242
+ end
243
+ end
244
+
245
+ def test_srcset_has_dpr_params
246
+ i = 1
247
+ srcset.split(',').map do |srcset_split|
248
+ src = srcset_split.split(' ')[0]
249
+ assert_includes src, "dpr=#{i}"
250
+ i += 1
251
+ end
252
+ end
253
+
254
+ def test_srcset_signs_urls
255
+ srcset.split(',').map do |srcset_split|
256
+ src = srcset_split.split(' ')[0]
257
+ expected_signature = get_expected_signature(src)
258
+
259
+ assert_includes src, expected_signature
260
+ end
261
+ end
262
+
263
+ def test_srcset_has_variable_qualities
264
+ i = 0
265
+ srcset.split(',').map do |src|
266
+ assert_includes src, "q=#{DPR_QUALITY[i]}"
267
+ i += 1
268
+ end
269
+ end
270
+
271
+ def test_srcset_respects_overriding_quality
272
+ quality_override = 100
273
+ srcset = mock_signed_client.to_srcset(w: 100, h: 100, q: quality_override)
274
+
275
+ srcset.split(',').map do |src|
276
+ assert_includes src, "q=#{quality_override}"
277
+ end
278
+ end
279
+
280
+ def test_disable_variable_quality
281
+ srcset = mock_signed_client.to_srcset(
282
+ w: 100, h: 100,
283
+ options: { disable_variable_quality: true }
284
+ )
285
+
286
+ srcset.split(',').map do |src|
287
+ assert(not(src.include?('q=')))
288
+ end
289
+ end
290
+
291
+ def test_respects_quality_param_when_disabled
292
+ quality_override = 100
293
+ srcset = mock_signed_client.to_srcset(
294
+ w: 100, h: 100, q: 100,
295
+ options: { disable_variable_quality: true }
296
+ )
297
+
298
+ srcset.split(',').map do |src|
299
+ assert_includes src, "q=#{quality_override}"
300
+ end
301
+ end
302
+
303
+ private
304
+
305
+ def srcset
306
+ @client ||= mock_signed_client.to_srcset(w: 100, h: 100)
307
+ end
308
+ end
309
+
310
+ class SrcsetGivenAspectRatio < Imgix::Test
311
+ include SrcsetTest
312
+
313
+ def test_srcset_generates_width_pairs
314
+ expected_number_of_pairs = 31
315
+ assert_equal expected_number_of_pairs, srcset.split(',').length
316
+ end
317
+
318
+ def test_srcset_pair_values
319
+ srclist = srcset.split(',').map do |srcset_split|
320
+ srcset_split.split(' ')[1].to_i
321
+ end
322
+
323
+ for i in 0..srclist.length - 1
324
+ assert_equal(srclist[i], RESOLUTIONS[i])
325
+ end
326
+ end
327
+
328
+ def test_srcset_within_bounds
329
+ min, *max = srcset.split(',')
330
+
331
+ # parse out the width descriptor as an integer
332
+ min = min.split(' ')[1].to_i
333
+ max = max[max.length - 1].split(' ')[1].to_i
334
+
335
+ assert_operator min, :>=, 100
336
+ assert_operator max, :<=, 8192
337
+ end
338
+
339
+ # a 17% testing threshold is used to account for rounding
340
+ def test_srcset_iterates_17_percent
341
+ increment_allowed = 0.17
342
+
343
+ # create an array of widths
344
+ widths = srcset.split(',').map do |src|
345
+ src.split(' ')[1].to_i
346
+ end
347
+
348
+ prev = widths[0]
349
+
350
+ for i in 1..widths.length - 1
351
+ element = widths[i]
352
+ assert_operator (element.to_f / prev.to_f), :<, (1 + increment_allowed)
353
+ prev = element
354
+ end
355
+ end
356
+
357
+ def test_srcset_signs_urls
358
+ srcset.split(',').map do |srcset_split|
359
+ src = srcset_split.split(' ')[0]
360
+ expected_signature = get_expected_signature(src)
361
+
362
+ assert_includes src, expected_signature
363
+ end
364
+ end
365
+
366
+ private
367
+
368
+ def srcset
369
+ @client ||= mock_signed_client.to_srcset(ar: '3:2')
370
+ end
371
+ end
372
+
373
+ class SrcsetGivenAspectRatioAndHeight < Imgix::Test
374
+ include SrcsetTest
375
+
376
+ def test_srcset_in_dpr_form
377
+ device_pixel_ratio = 1
378
+
379
+ srcset.split(',').map do |src|
380
+ ratio = src.split(' ')[1]
381
+ assert_equal "#{device_pixel_ratio}x", ratio
382
+ device_pixel_ratio += 1
383
+ end
384
+ end
385
+
386
+ def test_srcset_has_dpr_params
387
+ i = 1
388
+ srcset.split(',').map do |srcset_split|
389
+ src = srcset_split.split(' ')[0]
390
+ assert_includes src, "dpr=#{i}"
391
+ i += 1
392
+ end
393
+ end
394
+
395
+ def test_srcset_signs_urls
396
+ srcset.split(',').map do |srcset_split|
397
+ src = srcset_split.split(' ')[0]
398
+ expected_signature = get_expected_signature(src)
399
+
400
+ assert_includes src, expected_signature
401
+ end
402
+ end
403
+
404
+ def test_srcset_has_variable_qualities
405
+ i = 0
406
+ srcset.split(',').map do |src|
407
+ assert_includes src, "q=#{DPR_QUALITY[i]}"
408
+ i += 1
409
+ end
410
+ end
4
411
 
5
- class SrcsetDefault < Imgix::Test
6
- def test_no_parameters
7
- srcset = path.to_srcset()
8
- expected_number_of_pairs = 31
9
- assert_equal expected_number_of_pairs, srcset.split(',').length
10
- end
11
-
12
- def test_srcset_pair_values
13
- resolutions = [100, 116, 134, 156, 182, 210, 244, 282,
14
- 328, 380, 442, 512, 594, 688, 798, 926,
15
- 1074, 1246, 1446, 1678, 1946, 2258, 2618,
16
- 3038, 3524, 4088, 4742, 5500, 6380, 7400, 8192]
17
- srcset = path.to_srcset()
18
- srclist = srcset.split(',').map { |srcset_split|
19
- srcset_split.split(' ')[1].to_i
20
- }
21
-
22
- for i in 0..srclist.length-1 do
23
- assert_equal(srclist[i], resolutions[i])
24
- end
25
- end
26
-
27
- private
28
- def path
29
- @client ||= Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg')
30
- end
31
- end
32
-
33
- class SrcsetGivenWidth < Imgix::Test
34
- def test_srcset_in_dpr_form
35
- device_pixel_ratio = 1
36
-
37
- srcset.split(',').map { |src|
38
- ratio = src.split(' ')[1]
39
- assert_equal ("#{device_pixel_ratio}x"), ratio
40
- device_pixel_ratio += 1
41
- }
42
- end
43
-
44
- def test_srcset_has_dpr_params
45
- i = 1
46
- srcset.split(',').map { |srcset_split|
47
- src = srcset_split.split(' ')[0]
48
- assert_includes src, "dpr=#{i}"
49
- i += 1
50
- }
51
- end
52
-
53
- def test_srcset_signs_urls
54
- srcset.split(',').map { |srcset_split|
55
- src = srcset_split.split(' ')[0]
56
- assert_includes src, 's='
57
-
58
- # parses out all parameters except for 's=...'
59
- params = src[src.index('?')..src.index('s=')-2]
60
-
61
- # parses out the 's=...' parameter
62
- generated_signature = src.slice(src.index('s=')+2, src.length)
63
-
64
- signature_base = 'MYT0KEN' + '/image.jpg' + params;
65
- expected_signature = Digest::MD5.hexdigest(signature_base)
66
-
67
- assert_equal expected_signature, generated_signature
68
- }
69
- end
70
-
71
- private
72
- def srcset
73
- @client ||= Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(w:100)
74
- end
75
- end
76
-
77
- class SrcsetGivenHeight < Imgix::Test
78
- def test_srcset_generates_width_pairs
79
- expected_number_of_pairs = 31
80
- assert_equal expected_number_of_pairs, srcset.split(',').length
81
- end
82
-
83
- def test_srcset_pair_values
84
- resolutions = [100, 116, 134, 156, 182, 210, 244, 282,
85
- 328, 380, 442, 512, 594, 688, 798, 926,
86
- 1074, 1246, 1446, 1678, 1946, 2258, 2618,
87
- 3038, 3524, 4088, 4742, 5500, 6380, 7400, 8192]
88
- srclist = srcset.split(',').map { |srcset_split|
89
- srcset_split.split(' ')[1].to_i
90
- }
91
-
92
- for i in 0..srclist.length-1 do
93
- assert_equal(srclist[i], resolutions[i])
94
- end
95
- end
96
-
97
- def test_srcset_respects_height_parameter
98
- srcset.split(',').map { |src|
99
- assert_includes src, 'h='
100
- }
101
- end
102
-
103
- def test_srcset_within_bounds
104
- min, *max = srcset.split(',')
105
-
106
- # parse out the width descriptor as an integer
107
- min = min.split(' ')[1].to_i
108
- max = max[max.length-1].split(' ')[1].to_i
109
-
110
- assert_operator min, :>=, 100
111
- assert_operator max, :<=, 8192
112
- end
113
-
114
- def test_srcset_iterates_18_percent
115
- increment_allowed = 0.18
116
-
117
- # create an array of widths
118
- widths = srcset.split(',').map { |src|
119
- src.split(' ')[1].to_i
120
- }
121
-
122
- prev = widths[0]
123
-
124
- for i in 1..widths.length-1 do
125
- element = widths[i]
126
- assert_operator (element / prev), :<, (1 + increment_allowed)
127
- prev = element
128
- end
129
- end
130
-
131
- def test_srcset_signs_urls
132
- srcset.split(',').map { |srcset_split|
133
- src = srcset_split.split(' ')[0]
134
- assert_includes src, 's='
135
-
136
- # parses out all parameters except for 's=...'
137
- params = src[src.index('?')..src.index('s=')-2]
138
-
139
- # parses out the 's=...' parameter
140
- generated_signature = src.slice(src.index('s=')+2, src.length)
141
-
142
- signature_base = 'MYT0KEN' + '/image.jpg' + params;
143
- expected_signature = Digest::MD5.hexdigest(signature_base)
144
-
145
- assert_equal expected_signature, generated_signature
146
- }
147
- end
148
-
149
- private
150
- def srcset
151
- @client ||= Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(h:100)
152
- end
153
- end
154
-
155
- class SrcsetGivenWidthAndHeight < Imgix::Test
156
- def test_srcset_in_dpr_form
157
- device_pixel_ratio = 1
158
-
159
- srcset.split(',').map { |src|
160
- ratio = src.split(' ')[1]
161
- assert_equal ("#{device_pixel_ratio}x"), ratio
162
- device_pixel_ratio += 1
163
- }
164
- end
165
-
166
- def test_srcset_has_dpr_params
167
- i = 1
168
- srcset.split(',').map { |srcset_split|
169
- src = srcset_split.split(' ')[0]
170
- assert_includes src, "dpr=#{i}"
171
- i += 1
172
- }
173
- end
174
-
175
- def test_srcset_signs_urls
176
- srcset.split(',').map { |srcset_split|
177
- src = srcset_split.split(' ')[0]
178
- assert_includes src, 's='
179
-
180
- # parses out all parameters except for 's=...'
181
- params = src[src.index('?')..src.index('s=')-2]
182
-
183
- # parses out the 's=...' parameter
184
- generated_signature = src.slice(src.index('s=')+2, src.length)
185
-
186
- signature_base = 'MYT0KEN' + '/image.jpg' + params;
187
- expected_signature = Digest::MD5.hexdigest(signature_base)
188
-
189
- assert_equal expected_signature, generated_signature
190
- }
191
- end
192
-
193
- private
194
- def srcset
195
- @client ||= Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(w:100,h:100)
196
- end
197
- end
198
-
199
- class SrcsetGivenAspectRatio < Imgix::Test
200
- def test_srcset_generates_width_pairs
201
- expected_number_of_pairs = 31
202
- assert_equal expected_number_of_pairs, srcset.split(',').length
203
- end
204
-
205
- def test_srcset_pair_values
206
- resolutions = [100, 116, 134, 156, 182, 210, 244, 282,
207
- 328, 380, 442, 512, 594, 688, 798, 926,
208
- 1074, 1246, 1446, 1678, 1946, 2258, 2618,
209
- 3038, 3524, 4088, 4742, 5500, 6380, 7400, 8192]
210
- srclist = srcset.split(',').map { |srcset_split|
211
- srcset_split.split(' ')[1].to_i
212
- }
213
-
214
- for i in 0..srclist.length-1 do
215
- assert_equal(srclist[i], resolutions[i])
216
- end
217
- end
218
-
219
- def test_srcset_within_bounds
220
- min, *max = srcset.split(',')
221
-
222
- # parse out the width descriptor as an integer
223
- min = min.split(' ')[1].to_i
224
- max = max[max.length-1].split(' ')[1].to_i
225
-
226
- assert_operator min, :>=, 100
227
- assert_operator max, :<=, 8192
228
- end
229
-
230
- def test_srcset_iterates_18_percent
231
- increment_allowed = 0.18
232
-
233
- # create an array of widths
234
- widths = srcset.split(',').map { |src|
235
- src.split(' ')[1].to_i
236
- }
237
-
238
- prev = widths[0]
239
-
240
- for i in 1..widths.length-1 do
241
- element = widths[i]
242
- assert_operator (element / prev), :<, (1 + increment_allowed)
243
- prev = element
244
- end
245
- end
246
-
247
- def test_srcset_signs_urls
248
- srcset.split(',').map { |srcset_split|
249
- src = srcset_split.split(' ')[0]
250
- assert_includes src, 's='
251
-
252
- # parses out all parameters except for 's=...'
253
- params = src[src.index('?')..src.index('s=')-2]
254
-
255
- # parses out the 's=...' parameter
256
- generated_signature = src.slice(src.index('s=')+2, src.length)
257
-
258
- signature_base = 'MYT0KEN' + '/image.jpg' + params;
259
- expected_signature = Digest::MD5.hexdigest(signature_base)
260
-
261
- assert_equal expected_signature, generated_signature
262
- }
263
- end
264
-
265
- private
266
- def srcset
267
- @client ||= Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(ar:'3:2')
268
- end
269
- end
270
-
271
- class SrcsetGivenAspectRatioAndHeight < Imgix::Test
272
- def test_srcset_in_dpr_form
273
- device_pixel_ratio = 1
274
-
275
- srcset.split(',').map { |src|
276
- ratio = src.split(' ')[1]
277
- assert_equal ("#{device_pixel_ratio}x"), ratio
278
- device_pixel_ratio += 1
279
- }
280
- end
281
-
282
- def test_srcset_has_dpr_params
283
- i = 1
284
- srcset.split(',').map { |srcset_split|
285
- src = srcset_split.split(' ')[0]
286
- assert_includes src, "dpr=#{i}"
287
- i += 1
288
- }
289
- end
290
-
291
- def test_srcset_signs_urls
292
- srcset.split(',').map { |srcset_split|
293
- src = srcset_split.split(' ')[0]
294
- assert_includes src, 's='
295
-
296
- # parses out all parameters except for 's=...'
297
- params = src[src.index('?')..src.index('s=')-2]
298
-
299
- # parses out the 's=...' parameter
300
- generated_signature = src.slice(src.index('s=')+2, src.length)
301
-
302
- signature_base = 'MYT0KEN' + '/image.jpg' + params;
303
- expected_signature = Digest::MD5.hexdigest(signature_base)
304
-
305
- assert_equal expected_signature, generated_signature
306
- }
307
- end
308
-
309
- private
310
- def srcset
311
- @client ||= Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset({h:100,ar:'3:2'})
312
- end
313
- end
314
- end
412
+ def test_srcset_respects_overriding_quality
413
+ quality_override = 100
414
+ srcset = mock_signed_client.to_srcset(
415
+ w: 100, ar: '3:2', q: quality_override
416
+ )
417
+
418
+ srcset.split(',').map do |src|
419
+ assert_includes src, "q=#{quality_override}"
420
+ end
421
+ end
422
+
423
+ def test_disable_variable_quality
424
+ srcset = mock_signed_client.to_srcset(
425
+ w: 100, ar: '3:2',
426
+ options: { disable_variable_quality: true }
427
+ )
428
+
429
+ srcset.split(',').map do |src|
430
+ assert(not(src.include?('q=')))
431
+ end
432
+ end
433
+
434
+ def test_respects_quality_param_when_disabled
435
+ quality_override = 100
436
+ srcset = mock_signed_client.to_srcset(
437
+ w: 100, h: 100, q: 100,
438
+ options: { disable_variable_quality: true }
439
+ )
440
+
441
+ srcset.split(',').map do |src|
442
+ assert_includes src, "q=#{quality_override}"
443
+ end
444
+ end
445
+
446
+ private
447
+
448
+ def srcset
449
+ @client ||= mock_signed_client.to_srcset({ h: 100, ar: '3:2' })
450
+ end
451
+ end
452
+
453
+ class SrcsetWidthTolerance < Imgix::Test
454
+ include SrcsetTest
455
+
456
+ def test_srcset_generates_width_pairs
457
+ expected_number_of_pairs = 15
458
+ assert_equal expected_number_of_pairs, srcset.split(',').length
459
+ end
460
+
461
+ def test_srcset_pair_values
462
+ resolutions = [100, 140, 196, 274, 384,
463
+ 538, 753, 1054, 1476, 2066,
464
+ 2893, 4050, 5669, 7937, 8192]
465
+
466
+ srclist = srcset.split(',').map do |srcset_split|
467
+ srcset_split.split(' ')[1].to_i
468
+ end
469
+
470
+ for i in 0..srclist.length - 1
471
+ assert_equal(srclist[i], resolutions[i])
472
+ end
473
+ end
474
+
475
+ def test_srcset_within_bounds
476
+ min, *max = srcset.split(',')
477
+
478
+ # parse out the width descriptor as an integer
479
+ min = min.split(' ')[1].to_i
480
+ max = max[max.length - 1].split(' ')[1].to_i
481
+ assert_operator min, :>=, 100
482
+ assert_operator max, :<=, 8192
483
+ end
484
+
485
+ # a 41% testing threshold is used to account for rounding
486
+ def test_srcset_iterates_41_percent
487
+ increment_allowed = 0.41
488
+
489
+ # create an array of widths
490
+ widths = srcset.split(',').map do |src|
491
+ src.split(' ')[1].to_i
492
+ end
493
+
494
+ prev = widths[0]
495
+
496
+ for i in 1..widths.length - 1
497
+ element = widths[i]
498
+ assert_operator (element.to_f / prev.to_f), :<, (1 + increment_allowed)
499
+ prev = element
500
+ end
501
+ end
502
+
503
+ def test_invalid_tolerance_emits_error
504
+ assert_raises(ArgumentError) do
505
+ mock_client.to_srcset(options: { width_tolerance: 'abc' })
506
+ end
507
+ end
508
+
509
+ def test_negative_tolerance_emits_error
510
+ assert_raises(ArgumentError) do
511
+ mock_client.to_srcset(options: { width_tolerance: -0.10 })
512
+ end
513
+ end
514
+
515
+ def test_with_param_after
516
+ srcset = mock_signed_client.to_srcset(
517
+ options: { width_tolerance: 0.20 },
518
+ h: 1000, fit: 'clip'
519
+ )
520
+
521
+ assert_includes(srcset, 'h=')
522
+ assert(not(srcset.include?('width_tolerance=')))
523
+ end
524
+
525
+ def test_with_param_before
526
+ srcset = mock_signed_client.to_srcset(
527
+ h: 1000, fit: 'clip',
528
+ options: { width_tolerance: 0.20 }
529
+ )
530
+
531
+ assert_includes(srcset, 'h=')
532
+ assert(not(srcset.include?('width_tolerance=')))
533
+ end
534
+
535
+ private
536
+
537
+ def srcset
538
+ @client ||= mock_signed_client.to_srcset(
539
+ options: { width_tolerance: 0.20 }
540
+ )
541
+ end
542
+ end
543
+
544
+ class SrcsetCustomWidths < Imgix::Test
545
+ include SrcsetTest
546
+
547
+ def test_srcset_generates_width_pairs
548
+ expected_number_of_pairs = 4
549
+ assert_equal expected_number_of_pairs, srcset.split(',').length
550
+ end
551
+
552
+ def test_srcset_pair_values
553
+ resolutions = [100, 500, 1000, 1800]
554
+ srclist = srcset.split(',').map do |srcset_split|
555
+ srcset_split.split(' ')[1].to_i
556
+ end
557
+
558
+ for i in 0..srclist.length - 1
559
+ assert_equal(srclist[i], resolutions[i])
560
+ end
561
+ end
562
+
563
+ def test_srcset_within_bounds
564
+ min, *max = srcset.split(',')
565
+
566
+ # parse out the width descriptor as an integer
567
+ min = min.split(' ')[1].to_i
568
+ max = max[max.length - 1].split(' ')[1].to_i
569
+
570
+ assert_operator min, :>=, @widths[0]
571
+ assert_operator max, :<=, @widths[-1]
572
+ end
573
+
574
+ def test_invalid_widths_input_emits_error
575
+ assert_raises(ArgumentError) do
576
+ mock_client.to_srcset(options: { widths: 'abc' })
577
+ end
578
+ end
579
+
580
+ def test_non_integer_array_emits_error
581
+ assert_raises(ArgumentError) do
582
+ mock_client.to_srcset(options: { widths: [100, 200, false] })
583
+ end
584
+ end
585
+
586
+ def test_negative_integer_array_emits_error
587
+ assert_raises(ArgumentError) do
588
+ mock_client.to_srcset(options: { widths: [100, 200, -100] })
589
+ end
590
+ end
591
+
592
+ def test_with_param_after
593
+ srcset = mock_signed_client.to_srcset(
594
+ options: { widths: [100, 200, 300] },
595
+ h: 1000, fit: 'clip'
596
+ )
597
+
598
+ assert_includes(srcset, 'h=')
599
+ assert(not(srcset.include?('widths=')))
600
+ end
601
+
602
+ def test_with_param_before
603
+ srcset = mock_client.to_srcset(
604
+ h: 1000, fit: 'clip',
605
+ options: { widths: [100, 200, 300] }
606
+ )
607
+ assert_includes(srcset, 'h=')
608
+ assert(not(srcset.include?('widths=')))
609
+ end
610
+
611
+ private
612
+
613
+ def srcset
614
+ @widths = [100, 500, 1000, 1800]
615
+ @client ||= mock_signed_client.to_srcset(options: { widths: @widths })
616
+ end
617
+ end
618
+
619
+ class SrcsetMinMaxWidths < Imgix::Test
620
+ include SrcsetTest
621
+
622
+ def test_srcset_generates_width_pairs
623
+ expected_number_of_pairs = 11
624
+ assert_equal expected_number_of_pairs, srcset.split(',').length
625
+ end
626
+
627
+ def test_srcset_pair_values
628
+ resolutions = [500, 580, 673, 780, 905, 1050,
629
+ 1218, 1413, 1639, 1901, 2000]
630
+ srclist = srcset.split(',').map do |srcset_split|
631
+ srcset_split.split(' ')[1].to_i
632
+ end
633
+
634
+ for i in 0..srclist.length - 1
635
+ assert_equal(srclist[i], resolutions[i])
636
+ end
637
+ end
638
+
639
+ def test_srcset_within_bounds
640
+ min, *max = srcset.split(',')
641
+
642
+ # parse out the width descriptor as an integer
643
+ min = min.split(' ')[1].to_i
644
+ max = max[max.length - 1].split(' ')[1].to_i
645
+
646
+ assert_operator min, :>=, @MIN
647
+ assert_operator max, :<=, @MAX
648
+ end
649
+
650
+ # a 41% testing threshold is used to account for rounding
651
+ def test_with_custom_width_tolerance
652
+ srcset = mock_client.to_srcset(
653
+ options: { min_width: 500, max_width: 2000, width_tolerance: 0.20 }
654
+ )
655
+
656
+ increment_allowed = 0.41
657
+
658
+ # create an array of widths
659
+ widths = srcset.split(',').map do |src|
660
+ src.split(' ')[1].to_i
661
+ end
662
+
663
+ prev = widths[0]
664
+
665
+ for i in 1..widths.length - 1
666
+ element = widths[i]
667
+ assert_operator (element.to_f / prev.to_f), :<, (1 + increment_allowed)
668
+ prev = element
669
+ end
670
+ end
671
+
672
+ def test_invalid_min_emits_error
673
+ assert_raises(ArgumentError) do
674
+ mock_client.to_srcset(options: { min_width: 'abc' })
675
+ end
676
+ end
677
+
678
+ def test_negative_max_emits_error
679
+ assert_raises(ArgumentError) do
680
+ mock_client.to_srcset(options: { max_width: -100 })
681
+ end
682
+ end
683
+
684
+ def test_with_param_after
685
+ srcset = mock_client.to_srcset(
686
+ options: { min_width: 500, max_width: 2000 },
687
+ h: 1000, fit: 'clip'
688
+ )
689
+
690
+ assert_includes(srcset, 'h=')
691
+ assert(not(srcset.include?('min_width=')))
692
+ assert(not(srcset.include?('max_width=')))
693
+ end
694
+
695
+ def test_with_param_before
696
+ srcset = mock_client.to_srcset(
697
+ h: 1000, fit: 'clip',
698
+ options: { min_width: 500, max_width: 2000 }
699
+ )
700
+
701
+ assert_includes(srcset, 'h=')
702
+ assert(not(srcset.include?('min_width=')))
703
+ assert(not(srcset.include?('max_width=')))
704
+ end
705
+
706
+ def test_only_min
707
+ min_width = 1000
708
+ max_width = 8192
709
+ srcset = mock_client.to_srcset(options: { min_width: min_width })
710
+
711
+ min, *max = srcset.split(',')
712
+
713
+ # parse out the width descriptor as an integer
714
+ min = min.split(' ')[1].to_i
715
+ max = max[max.length - 1].split(' ')[1].to_i
716
+
717
+ assert_operator min, :>=, min_width
718
+ assert_operator max, :<=, max_width
719
+ end
720
+
721
+ def test_only_max
722
+ min_width = 100
723
+ max_width = 1000
724
+ srcset = mock_client.to_srcset(options: { max_width: max_width })
725
+ min, *max = srcset.split(',')
726
+
727
+ # parse out the width descriptor as an integer
728
+ min = min.split(' ')[1].to_i
729
+ max = max[max.length - 1].split(' ')[1].to_i
730
+
731
+ assert_operator min, :>=, min_width
732
+ assert_operator max, :<=, max_width
733
+ end
734
+
735
+ def test_max_as_100
736
+ srcset = mock_client.to_srcset(options: { max_width: 100 })
737
+ assert_equal(srcset, 'https://testing.imgix.net/image.jpg?w=100 100w')
738
+ end
739
+
740
+ def test_min_as_8192
741
+ srcset = mock_client.to_srcset(options: { min_width: 8192 })
742
+ assert_equal(srcset, 'https://testing.imgix.net/image.jpg?w=8192 8192w')
743
+ end
744
+
745
+ private
746
+
747
+ def srcset
748
+ @MIN = 500
749
+ @MAX = 2000
750
+ @client ||= mock_client.to_srcset(
751
+ options: { min_width: @MIN, max_width: @MAX }
752
+ )
753
+ end
754
+ end
755
+ end