tinify 1.2.0 → 1.5.1

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.
data/lib/tinify/client.rb CHANGED
@@ -4,11 +4,21 @@ require "json"
4
4
  module Tinify
5
5
  class Client
6
6
  API_ENDPOINT = "https://api.tinify.com".freeze
7
+
8
+ RETRY_COUNT = 1
9
+ RETRY_DELAY = 500
10
+
7
11
  USER_AGENT = "Tinify/#{VERSION} Ruby/#{RUBY_VERSION}p#{RUBY_PATCHLEVEL} (#{defined?(RUBY_ENGINE) ? RUBY_ENGINE : "unknown"})".freeze
12
+
8
13
  CA_BUNDLE = File.expand_path("../../data/cacert.pem", __FILE__).freeze
9
14
 
10
- def initialize(key, app_identifier = nil)
11
- @client = HTTPClient.new
15
+ def initialize(key, app_identifier = nil, proxy = nil)
16
+ begin
17
+ @client = HTTPClient.new(proxy)
18
+ rescue ArgumentError => err
19
+ raise ConnectionError.new("Invalid proxy: #{err.message}")
20
+ end
21
+
12
22
  @client.base_url = API_ENDPOINT
13
23
  @client.default_header = { "User-Agent" => [USER_AGENT, app_identifier].compact.join(" ") }
14
24
 
@@ -19,7 +29,8 @@ module Tinify
19
29
  @client.ssl_config.add_trust_ca(CA_BUNDLE)
20
30
  end
21
31
 
22
- def request(method, url, body = nil, header = {})
32
+ def request(method, url, body = nil)
33
+ header = {}
23
34
  if Hash === body
24
35
  if body.empty?
25
36
  body = nil
@@ -29,26 +40,31 @@ module Tinify
29
40
  end
30
41
  end
31
42
 
32
- begin
33
- response = @client.request(method, url, body: body, header: header)
34
- rescue HTTPClient::TimeoutError => err
35
- raise ConnectionError.new("Timeout while connecting")
36
- rescue StandardError => err
37
- raise ConnectionError.new("Error while connecting: #{err.message}")
38
- end
43
+ RETRY_COUNT.downto(0) do |retries|
44
+ sleep RETRY_DELAY / 1000.0 if retries < RETRY_COUNT
39
45
 
40
- if count = response.headers["Compression-Count"]
41
- Tinify.compression_count = count.to_i
42
- end
46
+ begin
47
+ response = @client.request(method, url, body: body, header: header)
48
+ rescue HTTPClient::TimeoutError => err
49
+ next if retries > 0
50
+ raise ConnectionError.new("Timeout while connecting")
51
+ rescue StandardError => err
52
+ next if retries > 0
53
+ raise ConnectionError.new("Error while connecting: #{err.message}")
54
+ end
55
+
56
+ if count = response.headers["Compression-Count"]
57
+ Tinify.compression_count = count.to_i
58
+ end
59
+
60
+ return response if response.ok?
43
61
 
44
- if response.ok?
45
- response
46
- else
47
62
  details = begin
48
63
  JSON.parse(response.body)
49
64
  rescue StandardError => err
50
- { "message" => "Error while parsing response: #{err.message}", "error" => "ParseError" }
65
+ {"message" => "Error while parsing response: #{err.message}", "error" => "ParseError"}
51
66
  end
67
+ next if retries > 0 and response.status >= 500
52
68
  raise Error.create(details["message"], details["error"], response.status)
53
69
  end
54
70
  end
data/lib/tinify/error.rb CHANGED
@@ -14,12 +14,14 @@ module Tinify
14
14
  end
15
15
  end
16
16
 
17
+ attr_reader :status
18
+
17
19
  def initialize(message, type = self.class.name.split("::").last, status = nil)
18
20
  @message, @type, @status = message, type, status
19
21
  end
20
22
 
21
23
  def message
22
- if @status
24
+ if status
23
25
  "#{@message} (HTTP #{@status}/#{@type})"
24
26
  else
25
27
  "#{@message}"
data/lib/tinify/source.rb CHANGED
@@ -20,6 +20,11 @@ module Tinify
20
20
  @url, @commands = url.freeze, commands.freeze
21
21
  end
22
22
 
23
+ def preserve(*options)
24
+ options = Array(options).flatten
25
+ self.class.new(@url, @commands.merge(preserve: options))
26
+ end
27
+
23
28
  def resize(options)
24
29
  self.class.new(@url, @commands.merge(resize: options))
25
30
  end
@@ -1,3 +1,3 @@
1
1
  module Tinify
2
- VERSION = "1.2.0"
2
+ VERSION = "1.5.1"
3
3
  end
data/lib/tinify.rb CHANGED
@@ -10,8 +10,9 @@ require "thread"
10
10
 
11
11
  module Tinify
12
12
  class << self
13
- attr_accessor :key
14
- attr_accessor :app_identifier
13
+ attr_reader :key
14
+ attr_reader :app_identifier
15
+ attr_reader :proxy
15
16
  attr_accessor :compression_count
16
17
 
17
18
  def key=(key)
@@ -24,6 +25,11 @@ module Tinify
24
25
  @client = nil
25
26
  end
26
27
 
28
+ def proxy=(proxy)
29
+ @proxy = proxy
30
+ @client = nil
31
+ end
32
+
27
33
  def from_file(path)
28
34
  Source.from_file(path)
29
35
  end
@@ -38,6 +44,9 @@ module Tinify
38
44
 
39
45
  def validate!
40
46
  client.request(:post, "/shrink")
47
+ rescue AccountError => err
48
+ return true if err.status == 429
49
+ raise err
41
50
  rescue ClientError
42
51
  true
43
52
  end
@@ -45,10 +54,10 @@ module Tinify
45
54
  @@mutex = Mutex.new
46
55
 
47
56
  def client
48
- raise AccountError.new("Provide an API key with Tinify.key = ...") unless @key
57
+ raise AccountError.new("Provide an API key with Tinify.key = ...") unless key
49
58
  return @client if @client
50
59
  @@mutex.synchronize do
51
- @client ||= Client.new(@key, @app_identifier).freeze
60
+ @client ||= Client.new(key, app_identifier, proxy).freeze
52
61
  end
53
62
  end
54
63
  end
Binary file
data/test/helper.rb CHANGED
@@ -6,6 +6,7 @@ require "tinify"
6
6
  module TestHelpers
7
7
  def before_setup
8
8
  Tinify.key = nil
9
+ Tinify.proxy = nil
9
10
  super
10
11
  end
11
12
 
data/test/integration.rb CHANGED
@@ -7,32 +7,73 @@ require "minitest/autorun"
7
7
 
8
8
  describe "client integration" do
9
9
  Tinify.key = ENV["TINIFY_KEY"]
10
+ Tinify.proxy = ENV["TINIFY_PROXY"]
10
11
 
11
12
  unoptimized_path = File.expand_path("../examples/voormedia.png", __FILE__)
12
13
  optimized = Tinify.from_file(unoptimized_path)
13
14
 
14
15
  it "should compress from file" do
15
- Tempfile.open("optimized.png") do |file|
16
+ Tempfile.open("optimized.png", encoding: "binary") do |file|
16
17
  optimized.to_file(file.path)
17
- assert_operator file.size, :>, 0
18
- assert_operator file.size, :<, 1500
18
+
19
+ size = file.size
20
+ contents = file.read
21
+
22
+ assert_operator size, :>, 1000
23
+ assert_operator size, :<, 1500
24
+
25
+ # width == 137
26
+ assert_includes contents, "\0\0\0\x89".force_encoding("binary")
27
+ refute_includes contents, "Copyright Voormedia".force_encoding("binary")
19
28
  end
20
29
  end
21
30
 
22
31
  it "should compress from url" do
23
32
  source = Tinify.from_url("https://raw.githubusercontent.com/tinify/tinify-ruby/master/test/examples/voormedia.png")
24
- Tempfile.open("optimized.png") do |file|
33
+ Tempfile.open("optimized.png", encoding: "binary") do |file|
25
34
  source.to_file(file.path)
26
- assert_operator file.size, :>, 0
27
- assert_operator file.size, :<, 1500
35
+
36
+ size = file.size
37
+ contents = file.read
38
+
39
+ assert_operator size, :>, 1000
40
+ assert_operator size, :<, 1500
41
+
42
+ # width == 137
43
+ assert_includes contents, "\0\0\0\x89".force_encoding("binary")
44
+ refute_includes contents, "Copyright Voormedia".force_encoding("binary")
28
45
  end
29
46
  end
30
47
 
31
48
  it "should resize" do
32
- Tempfile.open("resized.png") do |file|
49
+ Tempfile.open("optimized.png", encoding: "binary") do |file|
33
50
  optimized.resize(method: "fit", width: 50, height: 20).to_file(file.path)
34
- assert_operator file.size, :>, 0
35
- assert_operator file.size, :<, 800
51
+
52
+ size = file.size
53
+ contents = file.read
54
+
55
+ assert_operator size, :>, 500
56
+ assert_operator size, :<, 1000
57
+
58
+ # width == 50
59
+ assert_includes contents, "\0\0\0\x32".force_encoding("binary")
60
+ refute_includes contents, "Copyright Voormedia".force_encoding("binary")
61
+ end
62
+ end
63
+
64
+ it "should preserve metadata" do
65
+ Tempfile.open("optimized.png", encoding: "binary") do |file|
66
+ optimized.preserve(:copyright, :creation).to_file(file.path)
67
+
68
+ size = file.size
69
+ contents = file.read
70
+
71
+ assert_operator size, :>, 1000
72
+ assert_operator size, :<, 2000
73
+
74
+ # width == 137
75
+ assert_includes contents, "\0\0\0\x89".force_encoding("binary")
76
+ assert_includes contents, "Copyright Voormedia".force_encoding("binary")
36
77
  end
37
78
  end
38
79
  end
@@ -1,6 +1,9 @@
1
1
  require File.expand_path("../helper", __FILE__)
2
2
 
3
3
  describe Tinify::Client do
4
+ Tinify::Client.send(:remove_const, :RETRY_DELAY)
5
+ Tinify::Client.const_set(:RETRY_DELAY, 10)
6
+
4
7
  subject do
5
8
  Tinify::Client.new("key")
6
9
  end
@@ -82,9 +85,33 @@ describe Tinify::Client do
82
85
  headers: { "User-Agent" => "#{Tinify::Client::USER_AGENT} TestApp/0.1" }
83
86
  end
84
87
  end
88
+
89
+ describe "with proxy" do
90
+ subject do
91
+ Tinify::Client.new("key", nil, "http://user:pass@localhost:8080")
92
+ end
93
+
94
+ it "should issue request with proxy authorization" do
95
+ subject.request(:get, "/")
96
+ assert_requested :get, "https://api:key@api.tinify.com",
97
+ headers: { "Proxy-Authorization" => "Basic dXNlcjpwYXNz" }
98
+ end
99
+ end
85
100
  end
86
101
 
87
- describe "with timeout" do
102
+ describe "with timeout once" do
103
+ before do
104
+ stub_request(:get, "https://api:key@api.tinify.com").to_timeout
105
+ .then.to_return(status: 201)
106
+ end
107
+
108
+ it "should return response" do
109
+ response = subject.request(:get, "/")
110
+ assert_equal "", response.body
111
+ end
112
+ end
113
+
114
+ describe "with timeout repeatedly" do
88
115
  before do
89
116
  stub_request(:get, "https://api:key@api.tinify.com").to_timeout
90
117
  end
@@ -102,7 +129,20 @@ describe Tinify::Client do
102
129
  end
103
130
  end
104
131
 
105
- describe "with socket error" do
132
+ describe "with socket error once" do
133
+ before do
134
+ stub_request(:get, "https://api:key@api.tinify.com")
135
+ .to_raise(SocketError.new("nodename nor servname provided"))
136
+ .then.to_return(status: 201)
137
+ end
138
+
139
+ it "should return response" do
140
+ response = subject.request(:get, "/")
141
+ assert_equal "", response.body
142
+ end
143
+ end
144
+
145
+ describe "with socket error repeatedly" do
106
146
  before do
107
147
  stub_request(:get, "https://api:key@api.tinify.com").to_raise(SocketError.new("nodename nor servname provided"))
108
148
  end
@@ -120,7 +160,20 @@ describe Tinify::Client do
120
160
  end
121
161
  end
122
162
 
123
- describe "with unexpected error" do
163
+ describe "with unexpected error once" do
164
+ before do
165
+ stub_request(:get, "https://api:key@api.tinify.com")
166
+ .to_raise("some error")
167
+ .then.to_return(status: 201)
168
+ end
169
+
170
+ it "should return response" do
171
+ response = subject.request(:get, "/")
172
+ assert_equal "", response.body
173
+ end
174
+ end
175
+
176
+ describe "with unexpected error repeatedly" do
124
177
  before do
125
178
  stub_request(:get, "https://api:key@api.tinify.com").to_raise("some error")
126
179
  end
@@ -138,7 +191,21 @@ describe Tinify::Client do
138
191
  end
139
192
  end
140
193
 
141
- describe "with server error" do
194
+ describe "with server error once" do
195
+ before do
196
+ stub_request(:get, "https://api:key@api.tinify.com").to_return(
197
+ status: 584,
198
+ body: '{"error":"InternalServerError","message":"Oops!"}'
199
+ ).then.to_return(status: 201)
200
+ end
201
+
202
+ it "should return response" do
203
+ response = subject.request(:get, "/")
204
+ assert_equal "", response.body
205
+ end
206
+ end
207
+
208
+ describe "with server error repeatedly" do
142
209
  before do
143
210
  stub_request(:get, "https://api:key@api.tinify.com").to_return(
144
211
  status: 584,
@@ -159,8 +226,21 @@ describe Tinify::Client do
159
226
  end
160
227
  end
161
228
 
229
+ describe "with bad server response once" do
230
+ before do
231
+ stub_request(:get, "https://api:key@api.tinify.com").to_return(
232
+ status: 543,
233
+ body: '<!-- this is not json -->'
234
+ ).then.to_return(status: 201)
235
+ end
162
236
 
163
- describe "with bad server response" do
237
+ it "should return response" do
238
+ response = subject.request(:get, "/")
239
+ assert_equal "", response.body
240
+ end
241
+ end
242
+
243
+ describe "with bad server response repeatedly" do
164
244
  before do
165
245
  stub_request(:get, "https://api:key@api.tinify.com").to_return(
166
246
  status: 543,
@@ -186,7 +266,7 @@ describe Tinify::Client do
186
266
  stub_request(:get, "https://api:key@api.tinify.com").to_return(
187
267
  status: 492,
188
268
  body: '{"error":"BadRequest","message":"Oops!"}'
189
- )
269
+ ).then.to_return(status: 201)
190
270
  end
191
271
 
192
272
  it "should raise client error" do
@@ -202,12 +282,13 @@ describe Tinify::Client do
202
282
  end
203
283
  end
204
284
 
285
+
205
286
  describe "with bad credentials" do
206
287
  before do
207
288
  stub_request(:get, "https://api:key@api.tinify.com").to_return(
208
289
  status: 401,
209
290
  body: '{"error":"Unauthorized","message":"Oops!"}'
210
- )
291
+ ).then.to_return(status: 201)
211
292
  end
212
293
 
213
294
  it "should raise account error" do
@@ -7,10 +7,10 @@ describe Tinify::Source do
7
7
  before do
8
8
  Tinify.key = "invalid"
9
9
 
10
- stub_request(:post, "https://api:invalid@api.tinify.com/shrink").to_return(
11
- status: 401,
12
- body: '{"error":"Unauthorized","message":"Credentials are invalid"}'
13
- )
10
+ stub_request(:post, "https://api:invalid@api.tinify.com/shrink")
11
+ .to_return(
12
+ status: 401,
13
+ body: '{"error":"Unauthorized","message":"Credentials are invalid"}')
14
14
  end
15
15
 
16
16
  describe "from_file" do
@@ -41,42 +41,22 @@ describe Tinify::Source do
41
41
  describe "with valid api key" do
42
42
  before do
43
43
  Tinify.key = "valid"
44
-
45
- stub_request(:post, "https://api:valid@api.tinify.com/shrink")
46
- .to_return(
47
- status: 201,
48
- headers: { Location: "https://api.tinify.com/some/location" },
49
- body: '{}'
50
- )
51
-
52
- stub_request(:get, "https://api:valid@api.tinify.com/some/location").to_return(
53
- status: 200,
54
- body: "compressed file"
55
- )
56
-
57
- stub_request(:get, "https://api:valid@api.tinify.com/some/location").with(
58
- body: '{"resize":{"width":400}}'
59
- ).to_return(
60
- status: 200,
61
- body: "small file"
62
- )
63
-
64
- stub_request(:post, "https://api:valid@api.tinify.com/some/location").with(
65
- body: '{"store":{"service":"s3"}}'
66
- ).to_return(
67
- status: 200,
68
- headers: { Location: "https://bucket.s3.amazonaws.com/example" }
69
- )
70
-
71
- stub_request(:post, "https://api:valid@api.tinify.com/some/location").with(
72
- body: '{"resize":{"width":400},"store":{"service":"s3"}}'
73
- ).to_return(
74
- status: 200,
75
- headers: { Location: "https://bucket.s3.amazonaws.com/example" }
76
- )
77
44
  end
78
45
 
79
46
  describe "from_file" do
47
+ before do
48
+ stub_request(:post, "https://api:valid@api.tinify.com/shrink")
49
+ .to_return(
50
+ status: 201,
51
+ headers: { Location: "https://api.tinify.com/some/location" },
52
+ body: '{}')
53
+
54
+ stub_request(:get, "https://api:valid@api.tinify.com/some/location")
55
+ .to_return(
56
+ status: 200,
57
+ body: "compressed file")
58
+ end
59
+
80
60
  it "should return source" do
81
61
  assert_kind_of Tinify::Source, Tinify::Source.from_file(dummy_file)
82
62
  end
@@ -87,6 +67,19 @@ describe Tinify::Source do
87
67
  end
88
68
 
89
69
  describe "from_buffer" do
70
+ before do
71
+ stub_request(:post, "https://api:valid@api.tinify.com/shrink")
72
+ .to_return(
73
+ status: 201,
74
+ headers: { Location: "https://api.tinify.com/some/location" },
75
+ body: '{}')
76
+
77
+ stub_request(:get, "https://api:valid@api.tinify.com/some/location")
78
+ .to_return(
79
+ status: 200,
80
+ body: "compressed file")
81
+ end
82
+
90
83
  it "should return source" do
91
84
  assert_kind_of Tinify::Source, Tinify::Source.from_buffer("png file")
92
85
  end
@@ -103,20 +96,18 @@ describe Tinify::Source do
103
96
  .to_return(
104
97
  status: 201,
105
98
  headers: { Location: "https://api.tinify.com/some/location" },
106
- body: '{}'
107
- )
99
+ body: '{}')
108
100
 
109
101
  stub_request(:post, "https://api:valid@api.tinify.com/shrink")
110
102
  .with(body: '{"source":{"url":"file://wrong"}}')
111
103
  .to_return(
112
104
  status: 400,
113
- body: '{"error":"Source not found","message":"Cannot parse URL"}'
114
- )
105
+ body: '{"error":"Source not found","message":"Cannot parse URL"}')
115
106
 
116
- stub_request(:get, "https://api:valid@api.tinify.com/some/location").to_return(
117
- status: 200,
118
- body: "compressed file"
119
- )
107
+ stub_request(:get, "https://api:valid@api.tinify.com/some/location")
108
+ .to_return(
109
+ status: 200,
110
+ body: "compressed file")
120
111
  end
121
112
 
122
113
  it "should return source" do
@@ -135,12 +126,84 @@ describe Tinify::Source do
135
126
  end
136
127
 
137
128
  describe "result" do
129
+ before do
130
+ stub_request(:post, "https://api:valid@api.tinify.com/shrink")
131
+ .to_return(
132
+ status: 201,
133
+ headers: { Location: "https://api.tinify.com/some/location" },
134
+ body: '{}')
135
+
136
+ stub_request(:get, "https://api:valid@api.tinify.com/some/location")
137
+ .to_return(
138
+ status: 200,
139
+ body: "compressed file")
140
+ end
141
+
138
142
  it "should return result" do
139
143
  assert_kind_of Tinify::Result, Tinify::Source.from_buffer("png file").result
140
144
  end
141
145
  end
142
146
 
147
+ describe "preserve" do
148
+ before do
149
+ stub_request(:post, "https://api:valid@api.tinify.com/shrink")
150
+ .to_return(
151
+ status: 201,
152
+ headers: { Location: "https://api.tinify.com/some/location" },
153
+ body: '{}')
154
+
155
+ stub_request(:get, "https://api:valid@api.tinify.com/some/location")
156
+ .with(
157
+ body: '{"preserve":["copyright","location"]}')
158
+ .to_return(
159
+ status: 200,
160
+ body: "copyrighted file")
161
+ end
162
+
163
+ it "should return source" do
164
+ source = Tinify::Source.from_buffer("png file").preserve(:copyright, :location)
165
+ assert_kind_of Tinify::Source, source
166
+ end
167
+
168
+ it "should return source with data" do
169
+ source = Tinify::Source.from_buffer("png file").preserve(:copyright, :location)
170
+ assert_equal "copyrighted file", source.to_buffer
171
+ end
172
+
173
+ it "should return source with data for array" do
174
+ source = Tinify::Source.from_buffer("png file").preserve([:copyright, :location])
175
+ assert_equal "copyrighted file", source.to_buffer
176
+ end
177
+
178
+ it "should include other options if set" do
179
+ stub_request(:get, "https://api:valid@api.tinify.com/some/location")
180
+ .with(
181
+ body: '{"resize":{"width":400},"preserve":["copyright","location"]}')
182
+ .to_return(
183
+ status: 200,
184
+ body: "copyrighted resized file")
185
+
186
+ source = Tinify::Source.from_buffer("png file").resize(width: 400).preserve(:copyright, :location)
187
+ assert_equal "copyrighted resized file", source.to_buffer
188
+ end
189
+ end
190
+
143
191
  describe "resize" do
192
+ before do
193
+ stub_request(:post, "https://api:valid@api.tinify.com/shrink")
194
+ .to_return(
195
+ status: 201,
196
+ headers: { Location: "https://api.tinify.com/some/location" },
197
+ body: '{}')
198
+
199
+ stub_request(:get, "https://api:valid@api.tinify.com/some/location")
200
+ .with(
201
+ body: '{"resize":{"width":400}}')
202
+ .to_return(
203
+ status: 200,
204
+ body: "small file")
205
+ end
206
+
144
207
  it "should return source" do
145
208
  assert_kind_of Tinify::Source, Tinify::Source.from_buffer("png file").resize(width: 400)
146
209
  end
@@ -151,6 +214,22 @@ describe Tinify::Source do
151
214
  end
152
215
 
153
216
  describe "store" do
217
+ before do
218
+ stub_request(:post, "https://api:valid@api.tinify.com/shrink")
219
+ .to_return(
220
+ status: 201,
221
+ headers: { Location: "https://api.tinify.com/some/location" },
222
+ body: '{}'
223
+ )
224
+
225
+ stub_request(:post, "https://api:valid@api.tinify.com/some/location")
226
+ .with(
227
+ body: '{"store":{"service":"s3"}}')
228
+ .to_return(
229
+ status: 200,
230
+ headers: { Location: "https://bucket.s3.amazonaws.com/example" })
231
+ end
232
+
154
233
  it "should return result meta" do
155
234
  assert_kind_of Tinify::ResultMeta, Tinify::Source.from_buffer("png file").store(service: "s3")
156
235
  end
@@ -160,19 +239,52 @@ describe Tinify::Source do
160
239
  assert_equal "https://bucket.s3.amazonaws.com/example", result.location
161
240
  end
162
241
 
163
- it "should include resize options if set" do
242
+ it "should include other options if set" do
243
+ stub_request(:post, "https://api:valid@api.tinify.com/some/location")
244
+ .with(
245
+ body: '{"resize":{"width":400},"store":{"service":"s3"}}')
246
+ .to_return(
247
+ status: 200,
248
+ headers: { Location: "https://bucket.s3.amazonaws.com/example" })
249
+
164
250
  result = Tinify::Source.from_buffer("png file").resize(width: 400).store(service: "s3")
165
251
  assert_equal "https://bucket.s3.amazonaws.com/example", result.location
166
252
  end
167
253
  end
168
254
 
169
255
  describe "to_buffer" do
256
+ before do
257
+ stub_request(:post, "https://api:valid@api.tinify.com/shrink")
258
+ .to_return(
259
+ status: 201,
260
+ headers: { Location: "https://api.tinify.com/some/location" },
261
+ body: '{}')
262
+
263
+ stub_request(:get, "https://api:valid@api.tinify.com/some/location").to_return(
264
+ status: 200,
265
+ body: "compressed file"
266
+ )
267
+ end
268
+
170
269
  it "should return image data" do
171
270
  assert_equal "compressed file", Tinify::Source.from_buffer("png file").to_buffer
172
271
  end
173
272
  end
174
273
 
175
274
  describe "to_file" do
275
+ before do
276
+ stub_request(:post, "https://api:valid@api.tinify.com/shrink")
277
+ .to_return(
278
+ status: 201,
279
+ headers: { Location: "https://api.tinify.com/some/location" },
280
+ body: '{}')
281
+
282
+ stub_request(:get, "https://api:valid@api.tinify.com/some/location").to_return(
283
+ status: 200,
284
+ body: "compressed file"
285
+ )
286
+ end
287
+
176
288
  it "should store image data" do
177
289
  begin
178
290
  tmp = Tempfile.open("foo")