mugshot 0.3.1 → 0.4.0
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/features/convert_image_format.feature +22 -0
- data/features/crop_image.feature +5 -5
- data/features/define_image_quality.feature +8 -0
- data/features/resize_image.feature +22 -0
- data/features/retrieve_image_with_any_name.feature +9 -0
- data/features/set_background.feature +7 -0
- data/features/step_definitions/all_steps.rb +65 -14
- data/features/support/env.rb +24 -7
- data/features/support/files/test-with_75%_of_compression.jpg +0 -0
- data/features/support/files/test.gif +0 -0
- data/features/support/files/test.png +0 -0
- data/features/support/files/with_alpha_channel-with_a_red_background.jpg +0 -0
- data/features/support/files/with_alpha_channel.png +0 -0
- data/features/upload_image.feature +21 -0
- data/lib/mugshot/application.rb +30 -24
- data/lib/mugshot/fs_storage.rb +1 -0
- data/lib/mugshot/http_storage.rb +25 -0
- data/lib/mugshot/image.rb +28 -12
- data/lib/mugshot/magick_factory.rb +12 -0
- data/lib/mugshot/storage.rb +1 -0
- data/lib/mugshot.rb +7 -11
- data/spec/files/firefox_png.png +0 -0
- data/spec/files/test_png.png +0 -0
- data/spec/mugshot/application_spec.rb +59 -42
- data/spec/mugshot/http_storage_spec.rb +33 -0
- data/spec/mugshot/image_spec.rb +31 -38
- data/spec/mugshot/magick_factory_spec.rb +13 -0
- data/spec/spec.opts +1 -4
- data/spec/spec_helper.rb +18 -6
- metadata +126 -48
- data/features/retrieve_resized_image.feature +0 -10
- data/features/retrieve_resized_image_keeping_aspect_ratio.feature +0 -22
- data/lib/mugshot/proxy.rb +0 -32
- data/spec/mugshot/proxy_spec.rb +0 -67
- /data/features/support/files/{test.crop.300x200.jpg → test-cropped_to_300x200.jpg} +0 -0
- /data/features/support/files/{test.200x.jpg → test-resized_to_200x.jpg} +0 -0
- /data/features/support/files/{test.200x200.jpg → test-resized_to_200x200.jpg} +0 -0
- /data/features/support/files/{test.x200.jpg → test-resized_to_x200.jpg} +0 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
Feature: Convert Image Format
|
2
|
+
|
3
|
+
Scenario: Convert image to gif
|
4
|
+
Given an image
|
5
|
+
|
6
|
+
When I ask for it with format gif
|
7
|
+
|
8
|
+
Then I should get it with format gif
|
9
|
+
|
10
|
+
Scenario: Convert image to jpg
|
11
|
+
Given an image
|
12
|
+
|
13
|
+
When I ask for it with format jpg
|
14
|
+
|
15
|
+
Then I should get it with format jpg
|
16
|
+
|
17
|
+
Scenario: Convert image to png
|
18
|
+
Given an image
|
19
|
+
|
20
|
+
When I ask for it with format png
|
21
|
+
|
22
|
+
Then I should get it with format png
|
data/features/crop_image.feature
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
Feature: Crop image
|
2
2
|
|
3
|
-
Scenario: Crop image
|
4
|
-
|
3
|
+
Scenario: Crop image
|
4
|
+
Given an image
|
5
|
+
|
6
|
+
When I ask for it cropped to 300x200
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
Then I should get the 300x200 cropped image
|
8
|
+
Then I should get it cropped to 300x200
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Feature: Resize image
|
2
|
+
|
3
|
+
Scenario: Resize image
|
4
|
+
Given an image
|
5
|
+
|
6
|
+
When I ask for it resized to 200x200
|
7
|
+
|
8
|
+
Then I should get it resized to 200x200
|
9
|
+
|
10
|
+
Scenario: Resize image giving only width
|
11
|
+
Given an image
|
12
|
+
|
13
|
+
When I ask for it resized to 200x
|
14
|
+
|
15
|
+
Then I should get it resized to 200x
|
16
|
+
|
17
|
+
Scenario: Resized image giving only height
|
18
|
+
Given an image
|
19
|
+
|
20
|
+
When I ask for it resized to x200
|
21
|
+
|
22
|
+
Then I should get it resized to x200
|
@@ -1,35 +1,86 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
Given /^(a|an) (.*)Storage$/ do |_, storage_name|
|
3
|
+
case storage_name
|
4
|
+
when 'FS' then CucumberWorld.storage = Mugshot::FSStorage.new('/tmp/mugshot/cucumber')
|
5
|
+
when 'HTTP' then CucumberWorld.storage = Mugshot::HTTPStorage.new
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
Given /^an image$/ do
|
10
|
+
Given "a jpg image test"
|
11
|
+
end
|
12
|
+
|
13
|
+
Given /^a (.*) image (.*)$/ do |ext, name|
|
14
|
+
@image = {
|
15
|
+
:name => name,
|
16
|
+
:ext => ext,
|
17
|
+
:filename => "#{name.gsub(' ', '_')}.#{ext}"}
|
18
|
+
|
19
|
+
@image[:id] = write_image(@image[:filename])
|
20
|
+
end
|
21
|
+
|
2
22
|
When /^I upload an image$/ do
|
3
23
|
post '/', "file" => Rack::Test::UploadedFile.new("features/support/files/test.jpg", "image/jpeg")
|
4
24
|
@image_id = last_response.body
|
5
25
|
end
|
6
26
|
|
7
|
-
When /^I ask for
|
8
|
-
get "
|
9
|
-
@retrieved_image = last_response.body
|
27
|
+
When /^I ask for it$/ do
|
28
|
+
get "/#{@image_id}/any_name.jpg"
|
29
|
+
@retrieved_image = Magick::Image.from_blob(last_response.body).first
|
30
|
+
end
|
31
|
+
|
32
|
+
When /^I ask for an image that doesn't exist$/ do
|
33
|
+
get "/nonexistant_id/any_name.jpg"
|
34
|
+
end
|
35
|
+
|
36
|
+
When /^I ask for it resized to (.*)$/ do |size|
|
37
|
+
get "/resize/#{size}/#{@image[:id]}/any_name.jpg"
|
38
|
+
@retrieved_image = Magick::Image.from_blob(last_response.body).first
|
39
|
+
end
|
40
|
+
|
41
|
+
When /^I ask for it cropped to (.*)$/ do |size|
|
42
|
+
get "/crop/#{size}/#{@image[:id]}/any_name.jpg"
|
43
|
+
@retrieved_image = Magick::Image.from_blob(last_response.body).first
|
44
|
+
end
|
45
|
+
|
46
|
+
When /^I ask for it with (\d*)% of compression$/ do |compression|
|
47
|
+
get "/quality/#{compression}/#{@image[:id]}/any_name.jpg"
|
48
|
+
@retrieved_image = Magick::Image.from_blob(last_response.body).first
|
49
|
+
end
|
50
|
+
|
51
|
+
When /^I ask for it with format (.*)$/ do |format|
|
52
|
+
get "/#{@image[:id]}/any_name.#{format}"
|
53
|
+
@retrieved_image = Magick::Image.from_blob(last_response.body).first
|
54
|
+
end
|
55
|
+
|
56
|
+
When /^I ask for it with the name "(.*)"$/ do |name|
|
57
|
+
get "/#{@image[:id]}/#{name}.jpg"
|
58
|
+
@images_by_name[name] = Magick::Image.from_blob(last_response.body).first
|
10
59
|
end
|
11
60
|
|
12
|
-
When /^I ask for a (.*)
|
13
|
-
get "/
|
61
|
+
When /^I ask for it with a (.*) background$/ do |color|
|
62
|
+
get "/background/#{color}/#{@image[:id]}/img.jpg"
|
63
|
+
@retrieved_image = Magick::Image.from_blob(last_response.body).first
|
14
64
|
end
|
15
65
|
|
16
|
-
|
17
|
-
|
18
|
-
@retrieved_image = last_response.body
|
66
|
+
Then /^I should get it$/ do
|
67
|
+
@retrieved_image.should be_same_image_as("test.jpg")
|
19
68
|
end
|
20
69
|
|
21
70
|
Then /^I should get a (\d+) response$/ do |response_code|
|
22
71
|
last_response.status.should == response_code.to_i
|
23
72
|
end
|
24
73
|
|
25
|
-
Then /^I should get
|
26
|
-
@retrieved_image.should be_same_image_as("test.#{
|
74
|
+
Then /^I should get it with format (.*)$/ do |expected_format|
|
75
|
+
@retrieved_image.should be_same_image_as("test.#{expected_format}")
|
27
76
|
end
|
28
77
|
|
29
|
-
Then /^I should get
|
30
|
-
@retrieved_image.should be_same_image_as("
|
78
|
+
Then /^I should get it (.*)$/ do |name|
|
79
|
+
@retrieved_image.should be_same_image_as("#{@image[:name].gsub(' ', '_')}-#{name.underscore.gsub(' ', '_')}.jpg")
|
31
80
|
end
|
32
81
|
|
33
|
-
Then /^
|
34
|
-
@
|
82
|
+
Then /^all of them should be the same$/ do
|
83
|
+
@images_by_name.values.each do |img|
|
84
|
+
img.should be_same_image_as("test.jpg")
|
85
|
+
end
|
35
86
|
end
|
data/features/support/env.rb
CHANGED
@@ -1,32 +1,49 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
require "rubygems"
|
3
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..'))
|
4
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
|
2
5
|
require 'mugshot'
|
3
6
|
|
4
7
|
require 'rack/test'
|
5
|
-
require '
|
6
|
-
|
8
|
+
require 'rspec/expectations'
|
7
9
|
require 'pp'
|
8
10
|
|
11
|
+
require 'RMagick'
|
12
|
+
|
9
13
|
module CucumberWorld
|
14
|
+
include Rspec::Matchers
|
10
15
|
include Rack::Test::Methods
|
16
|
+
|
17
|
+
mattr_accessor :storage
|
11
18
|
|
12
19
|
def app
|
13
|
-
Mugshot::Application.new(
|
20
|
+
Mugshot::Application.new(storage)
|
21
|
+
end
|
22
|
+
|
23
|
+
def write_image(filename)
|
24
|
+
Mugshot::FSStorage.new('/tmp/mugshot/cucumber').
|
25
|
+
write(IO.read(File.expand_path(filename, "features/support/files/")))
|
14
26
|
end
|
15
27
|
end
|
16
28
|
World(CucumberWorld)
|
17
29
|
|
30
|
+
Before do
|
31
|
+
@images_by_name = HashWithIndifferentAccess.new
|
32
|
+
CucumberWorld.storage = Mugshot::FSStorage.new('/tmp/mugshot/cucumber')
|
33
|
+
end
|
34
|
+
|
18
35
|
After do
|
19
36
|
require 'fileutils'
|
20
37
|
FileUtils.rm_rf("/tmp/mugshot/cucumber")
|
21
38
|
end
|
22
39
|
|
23
|
-
|
24
|
-
match do |
|
25
|
-
|
26
|
-
expected = Magick::Image.read(File.expand_path(__FILE__ + "/../files/#{expected_filename}")).first
|
40
|
+
Rspec::Matchers.define :be_same_image_as do |expected|
|
41
|
+
match do |actual|
|
42
|
+
expected = Magick::Image.read(File.expand_path(__FILE__ + "/../files/#{expected}")).first if expected.is_a?(String)
|
27
43
|
|
28
44
|
actual.columns == expected.columns &&
|
29
45
|
actual.rows == expected.rows &&
|
30
46
|
actual.difference(expected)[1] < 0.01
|
31
47
|
end
|
32
48
|
end
|
49
|
+
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Feature: Upload Image
|
2
|
+
|
3
|
+
Scenario: Filesystem storage
|
4
|
+
Given an FSStorage
|
5
|
+
|
6
|
+
When I upload an image
|
7
|
+
And I ask for it
|
8
|
+
|
9
|
+
Then I should get it
|
10
|
+
|
11
|
+
Scenario: HTTP storage
|
12
|
+
Given an HTTPStorage
|
13
|
+
|
14
|
+
When I upload an image
|
15
|
+
|
16
|
+
Then I should get a 405 response
|
17
|
+
|
18
|
+
Scenario: Image wasn't uploaded
|
19
|
+
When I ask for an image that doesn't exist
|
20
|
+
|
21
|
+
Then I should get a 404 response
|
data/lib/mugshot/application.rb
CHANGED
@@ -3,6 +3,8 @@ require 'sinatra/base'
|
|
3
3
|
|
4
4
|
class Mugshot::Application < Sinatra::Base
|
5
5
|
|
6
|
+
VALID_OPERATIONS = %w[background crop resize quality]
|
7
|
+
|
6
8
|
set :static, true
|
7
9
|
set :public, ::File.expand_path(::File.join(::File.dirname(__FILE__), "public"))
|
8
10
|
|
@@ -15,28 +17,18 @@ class Mugshot::Application < Sinatra::Base
|
|
15
17
|
end
|
16
18
|
|
17
19
|
post '/?' do
|
18
|
-
@storage.write(params['file'][:tempfile].read)
|
19
|
-
|
20
|
-
|
21
|
-
get '/:size/:id.:format' do |size, id, format|
|
22
|
-
image = @storage.read(id)
|
23
|
-
halt 404 if image.blank?
|
24
|
-
|
25
|
-
image.resize!(size)
|
26
|
-
|
27
|
-
begin
|
28
|
-
send_image(image, format.to_sym)
|
29
|
-
ensure
|
30
|
-
image.destroy!
|
31
|
-
end
|
20
|
+
id = @storage.write(params['file'][:tempfile].read)
|
21
|
+
halt 405 if id.blank?
|
22
|
+
id
|
32
23
|
end
|
33
24
|
|
34
|
-
get '
|
25
|
+
get '/*/?:id/:name.:format' do |splat, id, _, format|
|
35
26
|
image = @storage.read(id)
|
36
27
|
halt 404 if image.blank?
|
37
28
|
|
38
29
|
begin
|
39
|
-
process_operations(image,
|
30
|
+
process_operations(image, @default_operations)
|
31
|
+
process_operations(image, operations_from_splat(splat))
|
40
32
|
send_image(image, format.to_sym)
|
41
33
|
ensure
|
42
34
|
image.destroy!
|
@@ -45,23 +37,37 @@ class Mugshot::Application < Sinatra::Base
|
|
45
37
|
|
46
38
|
protected
|
47
39
|
|
48
|
-
def initialize(
|
49
|
-
|
40
|
+
def initialize(opts)
|
41
|
+
opts = {:storage => opts} if opts.kind_of?(Mugshot::Storage)
|
42
|
+
opts.to_options!
|
43
|
+
|
44
|
+
@storage = opts.delete(:storage)
|
45
|
+
|
46
|
+
@default_operations = opts
|
50
47
|
end
|
51
48
|
|
52
49
|
private
|
53
50
|
|
54
|
-
def
|
55
|
-
operations =
|
56
|
-
|
57
|
-
|
58
|
-
|
51
|
+
def operations_from_splat(splat)
|
52
|
+
operations = []
|
53
|
+
begin
|
54
|
+
operations = Hash[*splat.split('/')]
|
55
|
+
operations.assert_valid_keys(VALID_OPERATIONS)
|
56
|
+
rescue
|
57
|
+
halt 404
|
59
58
|
end
|
59
|
+
operations
|
60
60
|
end
|
61
61
|
|
62
|
+
def process_operations(image, operations)
|
63
|
+
operations.each do |op, op_params|
|
64
|
+
image.send("#{op}!", op_params.to_s)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
62
68
|
def send_image(image, format)
|
63
69
|
content_type format
|
64
70
|
response['Content-Disposition'] = 'inline'
|
65
|
-
image.to_blob
|
71
|
+
image.to_blob(:format => format)
|
66
72
|
end
|
67
73
|
end
|
data/lib/mugshot/fs_storage.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'net/http'
|
5
|
+
|
6
|
+
class Mugshot::HTTPStorage < Mugshot::Storage
|
7
|
+
def write(bin)
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def read(id)
|
12
|
+
url = URI.parse(@url_resolver.call(id))
|
13
|
+
res = Net::HTTP.start(url.host, url.port) {|http| http.get(url.path)}
|
14
|
+
|
15
|
+
return nil unless res.code.to_i == 200
|
16
|
+
|
17
|
+
Mugshot::Image.new(res.body)
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def initialize(&block)
|
23
|
+
@url_resolver = block
|
24
|
+
end
|
25
|
+
end
|
data/lib/mugshot/image.rb
CHANGED
@@ -1,17 +1,13 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
require 'RMagick'
|
2
3
|
class Mugshot::Image
|
3
4
|
|
4
|
-
def
|
5
|
-
@
|
6
|
-
end
|
7
|
-
|
8
|
-
def height
|
9
|
-
@image.rows
|
5
|
+
def background!(color)
|
6
|
+
@background_color = color
|
10
7
|
end
|
11
8
|
|
12
9
|
def resize!(size)
|
13
10
|
w, h = parse_size(size)
|
14
|
-
|
15
11
|
if [w, h].include?(nil)
|
16
12
|
@image.resize_to_fit! w, h
|
17
13
|
else
|
@@ -27,28 +23,48 @@ class Mugshot::Image
|
|
27
23
|
self
|
28
24
|
end
|
29
25
|
|
26
|
+
def quality!(quality)
|
27
|
+
@quality = quality.to_i
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
30
31
|
def destroy!
|
31
32
|
@image.destroy!
|
32
33
|
self
|
33
34
|
end
|
34
35
|
|
35
36
|
def to_blob(opts = {})
|
37
|
+
opts.merge!(:quality => @quality)
|
38
|
+
|
39
|
+
set_background(@background_color) if !!@background_color
|
40
|
+
|
36
41
|
@image.strip!
|
37
42
|
@image.to_blob do
|
38
|
-
self.format = opts[:format].to_s if opts
|
43
|
+
self.format = opts[:format].to_s if opts.include?(:format)
|
39
44
|
self.quality = opts[:quality] if opts[:quality].present?
|
40
45
|
end
|
41
46
|
end
|
42
47
|
|
43
48
|
protected
|
44
|
-
|
45
|
-
|
46
|
-
|
49
|
+
def initialize(file_or_blob)
|
50
|
+
if file_or_blob.is_a?(File)
|
51
|
+
@image = Magick::Image.read(file_or_blob).first
|
52
|
+
else
|
53
|
+
@image = Magick::Image.from_blob(file_or_blob).first
|
54
|
+
end
|
55
|
+
|
56
|
+
# initialize attrs
|
57
|
+
@background_color = @quality = nil
|
47
58
|
end
|
48
59
|
|
49
60
|
private
|
50
|
-
|
51
61
|
def parse_size(size)
|
52
62
|
size.to_s.split("x").map{|i| i.blank? ? nil : i.to_i}
|
53
63
|
end
|
64
|
+
|
65
|
+
def set_background(color)
|
66
|
+
@image = Mugshot::MagickFactory.
|
67
|
+
create_canvas(@image.columns, @image.rows, color).
|
68
|
+
composite(@image, Magick::NorthWestGravity, Magick::OverCompositeOp)
|
69
|
+
end
|
54
70
|
end
|
data/lib/mugshot/storage.rb
CHANGED
data/lib/mugshot.rb
CHANGED
@@ -1,15 +1,11 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
require
|
3
|
-
require 'fileutils'
|
4
|
-
require 'uuid'
|
5
|
-
require 'active_support'
|
6
|
-
require 'RMagick'
|
2
|
+
require "active_support/core_ext"
|
7
3
|
|
8
4
|
module Mugshot
|
5
|
+
autoload :Image, "mugshot/image"
|
6
|
+
autoload :Storage, "mugshot/storage"
|
7
|
+
autoload :FSStorage, "mugshot/fs_storage"
|
8
|
+
autoload :Application, "mugshot/application"
|
9
|
+
autoload :HTTPStorage, "mugshot/http_storage"
|
10
|
+
autoload :MagickFactory, "mugshot/magick_factory"
|
9
11
|
end
|
10
|
-
|
11
|
-
require 'mugshot/image'
|
12
|
-
require 'mugshot/storage'
|
13
|
-
require 'mugshot/fs_storage'
|
14
|
-
require 'mugshot/application'
|
15
|
-
require 'mugshot/proxy'
|
Binary file
|
Binary file
|
@@ -3,17 +3,42 @@ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
|
3
3
|
|
4
4
|
describe Mugshot::Application do
|
5
5
|
before :each do
|
6
|
-
@storage =
|
6
|
+
@storage = stub(Mugshot::Storage, :null_object => true)
|
7
|
+
@image = stub(Mugshot::Image, :null_object => true)
|
8
|
+
@storage.stub!(:read).with("image_id").and_return(@image)
|
9
|
+
|
7
10
|
def app
|
8
11
|
Mugshot::Application.new(@storage)
|
9
12
|
end
|
10
13
|
end
|
11
14
|
|
15
|
+
describe "default values" do
|
16
|
+
it "should accept default value for quality" do
|
17
|
+
def app
|
18
|
+
Mugshot::Application.new(:storage => @storage, :quality => 42)
|
19
|
+
end
|
20
|
+
|
21
|
+
@image.should_receive(:quality!).with("42")
|
22
|
+
|
23
|
+
get "/image_id/any_name.jpg"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should accept default value for background" do
|
27
|
+
def app
|
28
|
+
Mugshot::Application.new(:storage => @storage, :background => :blue)
|
29
|
+
end
|
30
|
+
|
31
|
+
@image.should_receive(:background!).with("blue")
|
32
|
+
|
33
|
+
get "/image_id/any_name.jpg"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
12
37
|
describe "POST /" do
|
13
38
|
it "should create image" do
|
14
39
|
file_read = nil
|
15
40
|
File.open("spec/files/test.jpg") {|f| file_read = f.read}
|
16
|
-
@storage.should_receive(:write).with(file_read)
|
41
|
+
@storage.should_receive(:write).with(file_read).and_return("batata")
|
17
42
|
|
18
43
|
post "/", "file" => Rack::Test::UploadedFile.new("spec/files/test.jpg", "image/jpeg")
|
19
44
|
|
@@ -27,71 +52,63 @@ describe Mugshot::Application do
|
|
27
52
|
|
28
53
|
last_response.body.should == "batata"
|
29
54
|
end
|
30
|
-
end
|
31
55
|
|
32
|
-
|
33
|
-
|
34
|
-
@image = mock(Mugshot::Image, :null_object => true)
|
35
|
-
@storage.stub!(:read).with("image_id").and_return(@image)
|
36
|
-
end
|
56
|
+
it "should halt 405 when storage doesn't allow writing to" do
|
57
|
+
@storage.stub!(:write).and_return(nil)
|
37
58
|
|
38
|
-
|
39
|
-
|
59
|
+
post "/", "file" => Rack::Test::UploadedFile.new("spec/files/test.jpg", "image/jpeg")
|
60
|
+
|
61
|
+
last_response.status.should == 405
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "GET /:ops/:ops_params/:id/:name.:format" do
|
66
|
+
it "should perform operations on image" do
|
67
|
+
@image.should_receive(:resize!).with("140x140")
|
68
|
+
@image.should_receive(:crop!).with("140x105")
|
69
|
+
@image.should_receive(:quality!).with("70")
|
70
|
+
@image.should_receive(:background!).with("red")
|
40
71
|
|
41
|
-
|
72
|
+
get "/background/red/resize/140x140/crop/140x105/quality/70/image_id/any_name.jpg"
|
42
73
|
end
|
43
74
|
|
44
75
|
it "should return image" do
|
45
76
|
@image.stub!(:to_blob).and_return("image data")
|
46
77
|
|
47
|
-
|
78
|
+
get "/crop/140x105/image_id/any_name.jpg"
|
48
79
|
|
49
80
|
last_response.should be_ok
|
50
81
|
last_response.body.should == "image data"
|
51
82
|
end
|
52
83
|
|
84
|
+
it "should destroy image" do
|
85
|
+
@image.should_receive(:destroy!)
|
86
|
+
get "/image_id/any_name.jpg"
|
87
|
+
end
|
88
|
+
|
53
89
|
it "should halt 404 when image doesn't exist" do
|
54
90
|
@storage.stub!(:read).with("image_id").and_return(nil)
|
55
91
|
|
56
|
-
|
92
|
+
get "/crop/140x105/image_id/any_name.jpg"
|
57
93
|
|
58
94
|
last_response.should be_not_found
|
59
95
|
last_response.body.should be_empty
|
60
96
|
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe "GET /:size/:id.:format" do
|
64
|
-
def perform_get
|
65
|
-
get "/200x200/image_id.jpg"
|
66
|
-
end
|
67
|
-
|
68
|
-
it_should_behave_like 'any GET image'
|
69
|
-
|
70
|
-
it "should resize image" do
|
71
|
-
@image.should_receive(:resize!).with("200x200")
|
72
|
-
|
73
|
-
perform_get
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
describe "GET /:ops/:ops_params/:id.:format" do
|
78
|
-
def perform_get
|
79
|
-
get "/crop/140x105/image_id.jpg"
|
80
|
-
end
|
81
97
|
|
82
|
-
|
98
|
+
it "should halt 404 on operations that are not allowed" do
|
99
|
+
@image.should_not_receive(:operation!)
|
83
100
|
|
84
|
-
|
85
|
-
@image.should_receive(:resize!).with("140x140")
|
86
|
-
@image.should_receive(:crop!).with("140x105")
|
101
|
+
get "/operation/140x105/image_id/any_name.jpg"
|
87
102
|
|
88
|
-
|
103
|
+
last_response.should be_not_found
|
104
|
+
last_response.body.should be_empty
|
89
105
|
end
|
106
|
+
|
107
|
+
it "should halt 404 on URL with invalid operation/param pair" do
|
108
|
+
get "/140x105/image_id/any_name.jpg"
|
90
109
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
get "/operation/140x105/image_id.jpg"
|
110
|
+
last_response.should be_not_found
|
111
|
+
last_response.body.should be_empty
|
95
112
|
end
|
96
113
|
end
|
97
114
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
4
|
+
require 'fakeweb'
|
5
|
+
|
6
|
+
describe Mugshot::HTTPStorage do
|
7
|
+
before :each do
|
8
|
+
@storage = Mugshot::HTTPStorage.new{|id| "http://foo.com:123/any/#{id}/abc.jpg"}
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'reading' do
|
12
|
+
before :each do
|
13
|
+
FakeWeb.register_uri(:get, 'http://foo.com:123/any/image_id/abc.jpg', :body => "blob")
|
14
|
+
FakeWeb.register_uri(:get, 'http://foo.com:123/any/does_not_exist/abc.jpg', :status => 404)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return image" do
|
18
|
+
Mugshot::Image.should_receive(:new).with("blob").and_return("image")
|
19
|
+
|
20
|
+
@storage.read("image_id").should == "image"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return nil if image does not exist in the other mugshot" do
|
24
|
+
@storage.read("does_not_exist").should be_nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'writing' do
|
29
|
+
it "should return nil" do
|
30
|
+
@storage.write('').should be_nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/spec/mugshot/image_spec.rb
CHANGED
@@ -3,59 +3,51 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
3
3
|
|
4
4
|
describe Mugshot::Image do
|
5
5
|
before :each do
|
6
|
-
@magick_image = mock(Magick::Image)
|
7
|
-
|
6
|
+
@magick_image = mock(Magick::Image, :null_object => true, :columns => 100, :rows => 100)
|
7
|
+
@magick_image.instance_eval do # TODO: Explain it
|
8
|
+
def to_blob(&block)
|
9
|
+
block.call if block.present?
|
10
|
+
return 'blob_data'
|
11
|
+
end
|
12
|
+
end
|
8
13
|
|
14
|
+
Magick::Image.stub!(:read).and_return([@magick_image])
|
15
|
+
|
9
16
|
@image = Mugshot::Image.new(File.open("spec/files/test.jpg"))
|
10
17
|
end
|
11
|
-
|
12
|
-
it '
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@image.width.should == 100
|
17
|
-
@image.height.should == 200
|
18
|
+
|
19
|
+
it 'can be initialized with blob' do
|
20
|
+
Magick::Image.should_receive(:from_blob).and_return([@magick_image])
|
21
|
+
Mugshot::Image.new("blob")
|
18
22
|
end
|
19
23
|
|
20
24
|
describe "to blob" do
|
21
|
-
before(:each) do
|
22
|
-
@magick_image.stub!(:strip!)
|
23
|
-
@magick_image.instance_eval do
|
24
|
-
def to_blob(&block)
|
25
|
-
block.call if block.present?
|
26
|
-
return 'blob_data'
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
25
|
it 'should return image as a blob using default options' do
|
32
26
|
@image.to_blob.should == 'blob_data'
|
33
27
|
end
|
34
28
|
|
35
|
-
it 'should return image as a blob using quality' do
|
36
|
-
@image.should_receive(:quality=).with(75)
|
37
|
-
@magick_image.instance_eval do
|
38
|
-
def to_blob(&block)
|
39
|
-
yield
|
40
|
-
return 'blob_data'
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
@image.to_blob(:quality => 75).should == 'blob_data'
|
45
|
-
end
|
46
|
-
|
47
29
|
it 'should return image as a blob using format' do
|
48
30
|
@image.should_receive(:format=).with('png')
|
49
|
-
@magick_image.instance_eval do
|
50
|
-
def to_blob(&block)
|
51
|
-
yield
|
52
|
-
return 'blob_data'
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
31
|
@image.to_blob(:format => :png).should == 'blob_data'
|
57
32
|
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should return image as a blob using quality' do
|
36
|
+
@image.should_receive(:quality=).with(75)
|
58
37
|
|
38
|
+
@image.quality!("75")
|
39
|
+
@image.to_blob
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should set background for transparent images' do
|
43
|
+
canvas = mock(Magick::Image)
|
44
|
+
Mugshot::MagickFactory.stub!(:create_canvas).and_return(canvas)
|
45
|
+
canvas.should_receive(:composite).
|
46
|
+
with(@magick_image, Magick::NorthWestGravity, Magick::OverCompositeOp).
|
47
|
+
and_return(@magick_image)
|
48
|
+
|
49
|
+
@image.background!("gray")
|
50
|
+
@image.to_blob
|
59
51
|
end
|
60
52
|
|
61
53
|
it "should resize image to given width and height" do
|
@@ -84,3 +76,4 @@ describe Mugshot::Image do
|
|
84
76
|
end
|
85
77
|
|
86
78
|
end
|
79
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
3
|
+
|
4
|
+
describe Mugshot::MagickFactory do
|
5
|
+
|
6
|
+
it "should create a canvas given columns, rows and background color" do
|
7
|
+
canvas = Mugshot::MagickFactory.create_canvas(100, 200, 'red')
|
8
|
+
canvas.columns.should == 100
|
9
|
+
canvas.rows.should == 200
|
10
|
+
canvas.background_color == 'red'
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
data/spec/spec.opts
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,17 +1,29 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
require "rubygems"
|
2
3
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
4
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
|
-
|
5
|
-
require 'rubygems'
|
6
5
|
require 'mugshot'
|
7
6
|
|
8
|
-
require '
|
9
|
-
require '
|
7
|
+
require 'rspec'
|
8
|
+
require 'rspec/autorun'
|
10
9
|
require 'rack/test'
|
11
10
|
require 'pp'
|
12
11
|
|
13
|
-
|
12
|
+
def in_editor?
|
13
|
+
ENV.has_key?('TM_MODE') || ENV.has_key?('EMACS') || ENV.has_key?('VIM')
|
14
|
+
end
|
15
|
+
|
16
|
+
# Requires supporting files with custom matchers and macros, etc,
|
17
|
+
# in ./support/ and its subdirectories.
|
18
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
14
19
|
|
15
|
-
|
20
|
+
Rspec.configure do |config|
|
21
|
+
require 'rspec/expectations'
|
22
|
+
config.include Rspec::Matchers
|
16
23
|
config.include Rack::Test::Methods
|
24
|
+
|
25
|
+
config.mock_framework = :rspec
|
26
|
+
config.filter_run :focused => true
|
27
|
+
config.run_all_when_everything_filtered = true
|
28
|
+
config.color_enabled = !in_editor?
|
17
29
|
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mugshot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 4
|
8
|
+
- 0
|
9
|
+
version: 0.4.0
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- "Cain\xC3\xA3 Nunes"
|
@@ -12,79 +17,137 @@ autorequire:
|
|
12
17
|
bindir: bin
|
13
18
|
cert_chain: []
|
14
19
|
|
15
|
-
date: 2010-
|
20
|
+
date: 2010-03-01 00:00:00 -03:00
|
16
21
|
default_executable:
|
17
22
|
dependencies:
|
18
23
|
- !ruby/object:Gem::Dependency
|
19
24
|
name: activesupport
|
20
|
-
|
21
|
-
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
prerelease: false
|
26
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
27
|
requirements:
|
24
|
-
- -
|
28
|
+
- - ~>
|
25
29
|
- !ruby/object:Gem::Version
|
26
|
-
|
27
|
-
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 3
|
33
|
+
- 5
|
34
|
+
version: 2.3.5
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
28
37
|
- !ruby/object:Gem::Dependency
|
29
38
|
name: sinatra
|
30
|
-
|
31
|
-
|
32
|
-
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
33
41
|
requirements:
|
34
42
|
- - ">="
|
35
43
|
- !ruby/object:Gem::Version
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
- 9
|
47
|
+
- 4
|
36
48
|
version: 0.9.4
|
37
|
-
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
38
51
|
- !ruby/object:Gem::Dependency
|
39
52
|
name: rmagick
|
40
|
-
|
41
|
-
|
42
|
-
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
43
55
|
requirements:
|
44
56
|
- - ">="
|
45
57
|
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 2
|
60
|
+
- 12
|
61
|
+
- 2
|
46
62
|
version: 2.12.2
|
47
|
-
|
63
|
+
type: :runtime
|
64
|
+
version_requirements: *id003
|
48
65
|
- !ruby/object:Gem::Dependency
|
49
66
|
name: uuid
|
50
|
-
|
51
|
-
|
52
|
-
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
prerelease: false
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
69
|
requirements:
|
54
70
|
- - ">="
|
55
71
|
- !ruby/object:Gem::Version
|
72
|
+
segments:
|
73
|
+
- 2
|
74
|
+
- 0
|
75
|
+
- 2
|
56
76
|
version: 2.0.2
|
57
|
-
|
77
|
+
type: :runtime
|
78
|
+
version_requirements: *id004
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: blankslate
|
81
|
+
prerelease: false
|
82
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
segments:
|
87
|
+
- 2
|
88
|
+
- 1
|
89
|
+
- 2
|
90
|
+
- 3
|
91
|
+
version: 2.1.2.3
|
92
|
+
type: :runtime
|
93
|
+
version_requirements: *id005
|
58
94
|
- !ruby/object:Gem::Dependency
|
59
95
|
name: rspec
|
96
|
+
prerelease: false
|
97
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
segments:
|
102
|
+
- 2
|
103
|
+
- 0
|
104
|
+
- 0
|
105
|
+
- a8
|
106
|
+
version: 2.0.0.a8
|
60
107
|
type: :development
|
61
|
-
|
62
|
-
|
108
|
+
version_requirements: *id006
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
name: rcov
|
111
|
+
prerelease: false
|
112
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
63
113
|
requirements:
|
64
114
|
- - ">="
|
65
115
|
- !ruby/object:Gem::Version
|
66
|
-
|
67
|
-
|
116
|
+
segments:
|
117
|
+
- 0
|
118
|
+
- 9
|
119
|
+
- 8
|
120
|
+
version: 0.9.8
|
121
|
+
type: :development
|
122
|
+
version_requirements: *id007
|
68
123
|
- !ruby/object:Gem::Dependency
|
69
124
|
name: cucumber
|
70
|
-
|
71
|
-
|
72
|
-
version_requirements: !ruby/object:Gem::Requirement
|
125
|
+
prerelease: false
|
126
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
73
127
|
requirements:
|
74
128
|
- - ">="
|
75
129
|
- !ruby/object:Gem::Version
|
130
|
+
segments:
|
131
|
+
- 0
|
132
|
+
- 6
|
133
|
+
- 2
|
76
134
|
version: 0.6.2
|
77
|
-
|
135
|
+
type: :development
|
136
|
+
version_requirements: *id008
|
78
137
|
- !ruby/object:Gem::Dependency
|
79
138
|
name: rack-test
|
80
|
-
|
81
|
-
|
82
|
-
version_requirements: !ruby/object:Gem::Requirement
|
139
|
+
prerelease: false
|
140
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
83
141
|
requirements:
|
84
142
|
- - ">="
|
85
143
|
- !ruby/object:Gem::Version
|
144
|
+
segments:
|
145
|
+
- 0
|
146
|
+
- 5
|
147
|
+
- 1
|
86
148
|
version: 0.5.1
|
87
|
-
|
149
|
+
type: :development
|
150
|
+
version_requirements: *id009
|
88
151
|
description: Dead simple image server
|
89
152
|
email:
|
90
153
|
- cainanunes@gmail.com
|
@@ -102,8 +165,9 @@ files:
|
|
102
165
|
- lib/mugshot.rb
|
103
166
|
- lib/mugshot/application.rb
|
104
167
|
- lib/mugshot/fs_storage.rb
|
168
|
+
- lib/mugshot/http_storage.rb
|
105
169
|
- lib/mugshot/image.rb
|
106
|
-
- lib/mugshot/
|
170
|
+
- lib/mugshot/magick_factory.rb
|
107
171
|
- lib/mugshot/public/crossdomain.xml
|
108
172
|
- lib/mugshot/storage.rb
|
109
173
|
- LICENSE
|
@@ -121,37 +185,51 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
121
185
|
requirements:
|
122
186
|
- - ">="
|
123
187
|
- !ruby/object:Gem::Version
|
188
|
+
segments:
|
189
|
+
- 0
|
124
190
|
version: "0"
|
125
|
-
version:
|
126
191
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
192
|
requirements:
|
128
193
|
- - ">="
|
129
194
|
- !ruby/object:Gem::Version
|
195
|
+
segments:
|
196
|
+
- 0
|
130
197
|
version: "0"
|
131
|
-
version:
|
132
198
|
requirements: []
|
133
199
|
|
134
200
|
rubyforge_project:
|
135
|
-
rubygems_version: 1.3.
|
201
|
+
rubygems_version: 1.3.6
|
136
202
|
signing_key:
|
137
203
|
specification_version: 3
|
138
204
|
summary: Dead simple image server
|
139
205
|
test_files:
|
140
|
-
- spec/
|
206
|
+
- spec/files/firefox_png.png
|
207
|
+
- spec/files/test.jpg
|
208
|
+
- spec/files/test_png.png
|
209
|
+
- spec/mugshot/application_spec.rb
|
141
210
|
- spec/mugshot/fs_storage_spec.rb
|
142
|
-
- spec/mugshot/
|
211
|
+
- spec/mugshot/http_storage_spec.rb
|
143
212
|
- spec/mugshot/image_spec.rb
|
144
|
-
- spec/mugshot/
|
145
|
-
- spec/spec_helper.rb
|
146
|
-
- spec/files/test.jpg
|
213
|
+
- spec/mugshot/magick_factory_spec.rb
|
147
214
|
- spec/spec.opts
|
148
|
-
-
|
215
|
+
- spec/spec_helper.rb
|
216
|
+
- spec/test.html
|
217
|
+
- features/convert_image_format.feature
|
149
218
|
- features/crop_image.feature
|
150
|
-
- features/
|
219
|
+
- features/define_image_quality.feature
|
220
|
+
- features/resize_image.feature
|
221
|
+
- features/retrieve_image_with_any_name.feature
|
222
|
+
- features/set_background.feature
|
223
|
+
- features/step_definitions/all_steps.rb
|
151
224
|
- features/support/env.rb
|
152
|
-
- features/support/files/test.
|
153
|
-
- features/support/files/test.
|
154
|
-
- features/support/files/test.
|
225
|
+
- features/support/files/test-cropped_to_300x200.jpg
|
226
|
+
- features/support/files/test-resized_to_200x.jpg
|
227
|
+
- features/support/files/test-resized_to_200x200.jpg
|
228
|
+
- features/support/files/test-resized_to_x200.jpg
|
229
|
+
- features/support/files/test-with_75%_of_compression.jpg
|
230
|
+
- features/support/files/test.gif
|
155
231
|
- features/support/files/test.jpg
|
156
|
-
- features/support/files/test.
|
157
|
-
- features/
|
232
|
+
- features/support/files/test.png
|
233
|
+
- features/support/files/with_alpha_channel-with_a_red_background.jpg
|
234
|
+
- features/support/files/with_alpha_channel.png
|
235
|
+
- features/upload_image.feature
|
@@ -1,10 +0,0 @@
|
|
1
|
-
Feature: Retrieve resized image
|
2
|
-
|
3
|
-
Scenario: Successful retrieval of resized image
|
4
|
-
When I upload an image
|
5
|
-
And I ask for the 200x200 resized image
|
6
|
-
Then I should get the 200x200 resized image
|
7
|
-
|
8
|
-
Scenario: Image doesn't exist
|
9
|
-
When I ask for a 200x200 resized image that doesn't exist
|
10
|
-
Then I should get a 404 response
|
@@ -1,22 +0,0 @@
|
|
1
|
-
Feature: Retrieve resized image keeping aspect ratio
|
2
|
-
|
3
|
-
Scenario: Successful retrieval of resized image from given width
|
4
|
-
When I upload an image
|
5
|
-
And I ask for the 200x resized image
|
6
|
-
|
7
|
-
Then I should get the 200x resized image keeping the aspect ratio
|
8
|
-
|
9
|
-
Scenario: Successful retrieval of resized image from given height
|
10
|
-
When I upload an image
|
11
|
-
And I ask for the x200 resized image
|
12
|
-
|
13
|
-
Then I should get the x200 resized image keeping the aspect ratio
|
14
|
-
|
15
|
-
Scenario: Image doesn't exist
|
16
|
-
When I ask for a 200x resized image that doesn't exist
|
17
|
-
|
18
|
-
Then I should get a 404 response
|
19
|
-
|
20
|
-
When I ask for a x200 resized image that doesn't exist
|
21
|
-
|
22
|
-
Then I should get a 404 response
|
data/lib/mugshot/proxy.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
require 'sinatra/base'
|
3
|
-
require 'net/http'
|
4
|
-
|
5
|
-
class Mugshot::Proxy < Sinatra::Base
|
6
|
-
get '/*' do
|
7
|
-
url = URI.parse "#{@host}/#{params[:splat]}"
|
8
|
-
res = Net::HTTP.start(url.host, url.port) {|http|
|
9
|
-
http.get(url.path)
|
10
|
-
}
|
11
|
-
|
12
|
-
status res.code.to_i
|
13
|
-
|
14
|
-
headers_hash = {}
|
15
|
-
res.each_header do |k,v|
|
16
|
-
headers_hash[k] = v unless k.to_s =~ /status/i
|
17
|
-
end
|
18
|
-
headers headers_hash
|
19
|
-
|
20
|
-
res.body
|
21
|
-
end
|
22
|
-
|
23
|
-
before do
|
24
|
-
halt 405 unless request.get?
|
25
|
-
end
|
26
|
-
|
27
|
-
protected
|
28
|
-
|
29
|
-
def initialize(host)
|
30
|
-
@host = host
|
31
|
-
end
|
32
|
-
end
|
data/spec/mugshot/proxy_spec.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
3
|
-
|
4
|
-
describe Mugshot::Proxy do
|
5
|
-
before :each do
|
6
|
-
def app
|
7
|
-
Mugshot::Proxy.new("http://localhost:9292")
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
describe 'GET /*' do
|
12
|
-
before :each do
|
13
|
-
@http = stub(Net::HTTP, :null_object => true)
|
14
|
-
@res = stub(Net::HTTPResponse, :null_object => true)
|
15
|
-
@http.stub!(:get).with('/request/path').and_return(@res)
|
16
|
-
Net::HTTP.stub!(:start).with("localhost", 9292).and_yield(@http)
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'should proxy the request to configured host' do
|
20
|
-
@res.stub!(:body).and_return('body')
|
21
|
-
|
22
|
-
get '/request/path'
|
23
|
-
|
24
|
-
last_response.body.should == 'body'
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'should return original response headers' do
|
28
|
-
@res.stub!(:each_header)\
|
29
|
-
.and_yield('content-type', 'image/jpg')\
|
30
|
-
.and_yield('cache-control', 'public, max-age=31557600')
|
31
|
-
|
32
|
-
get '/request/path'
|
33
|
-
|
34
|
-
last_response.headers['content-type'].should == 'image/jpg'
|
35
|
-
last_response.headers['cache-control'].should == 'public, max-age=31557600'
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'should return original status' do
|
39
|
-
@res.stub!(:code).and_return('404')
|
40
|
-
|
41
|
-
get '/request/path'
|
42
|
-
|
43
|
-
last_response.status.should == 404
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'should not return status header' do
|
47
|
-
@res.stub!(:each_header).and_yield('status', '200')
|
48
|
-
|
49
|
-
get '/request/path'
|
50
|
-
|
51
|
-
last_response.headers.should_not include('status')
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe 'other methods' do
|
56
|
-
it 'should not be allowed' do
|
57
|
-
post '/request/path'
|
58
|
-
last_response.status.should == 405
|
59
|
-
|
60
|
-
put '/request/path'
|
61
|
-
last_response.status.should == 405
|
62
|
-
|
63
|
-
delete '/request/path'
|
64
|
-
last_response.status.should == 405
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|