mugshot 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|