resizor 0.0.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/.gitignore +3 -0
- data/Gemfile +4 -0
- data/README.rdoc +44 -0
- data/Rakefile +9 -0
- data/lib/generators/resizor/USAGE +5 -0
- data/lib/generators/resizor/resizor_generator.rb +31 -0
- data/lib/generators/resizor/templates/resizor_migration.rb.erb +26 -0
- data/lib/resizor/asset.rb +125 -0
- data/lib/resizor/connection.rb +78 -0
- data/lib/resizor/railtie.rb +73 -0
- data/lib/resizor/resizor.rb +19 -0
- data/lib/resizor/version.rb +3 -0
- data/lib/resizor.rb +7 -0
- data/resizor.gemspec +24 -0
- data/test/asset_test.rb +96 -0
- data/test/database.yml +3 -0
- data/test/integration_test.rb +102 -0
- data/test/resizor_test.rb +66 -0
- data/test/test_helper.rb +50 -0
- metadata +133 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
=Resizor
|
2
|
+
|
3
|
+
For use with http://resizor.com
|
4
|
+
|
5
|
+
Inspired by Thoughtbot's Paperclip
|
6
|
+
|
7
|
+
== Usage
|
8
|
+
|
9
|
+
Add resizor to your Gemfile
|
10
|
+
|
11
|
+
gem 'resizor'
|
12
|
+
|
13
|
+
Install resizor gem
|
14
|
+
|
15
|
+
$ bundle install
|
16
|
+
|
17
|
+
Add a initializer to RAILS_ROOT/config/initializers/resizor.rb
|
18
|
+
|
19
|
+
Resizor.configure do |config|
|
20
|
+
config.api_key = 'my-api-key'
|
21
|
+
end
|
22
|
+
|
23
|
+
Add Resizor fields to your model
|
24
|
+
|
25
|
+
$ rails generate resizor MyModel image
|
26
|
+
|
27
|
+
Add has_resizor_asset to MyModel
|
28
|
+
|
29
|
+
class MyModel < ActiveRecord::Base
|
30
|
+
has_resizor_asset :image
|
31
|
+
|
32
|
+
...
|
33
|
+
end
|
34
|
+
|
35
|
+
Add a file field to the form for MyModel
|
36
|
+
|
37
|
+
<%= f.label :image %>
|
38
|
+
<%= f.file_field :image %>
|
39
|
+
|
40
|
+
Now you can resize your uploaded images on the fly
|
41
|
+
|
42
|
+
<% if my_model.image? %>
|
43
|
+
<img src="<%= my_model.image.url(:size => 'c200x300') %>">
|
44
|
+
<% end %>
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
class ResizorGenerator < ActiveRecord::Generators::Base
|
4
|
+
desc "Create a migration to add resizor-specific fields to your model."
|
5
|
+
|
6
|
+
argument :asset_names, :required => true, :type => :array, :desc => "The names of the asset(s) to add.",
|
7
|
+
:banner => "asset_one asset_two asset_three ..."
|
8
|
+
|
9
|
+
def self.source_root
|
10
|
+
@source_root ||= File.expand_path('../templates', __FILE__)
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate_migration
|
14
|
+
migration_template "resizor_migration.rb.erb", "db/migrate/#{migration_file_name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def migration_name
|
20
|
+
"add_resizor_#{asset_names.join("_")}_to_#{name.underscore}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def migration_file_name
|
24
|
+
"#{migration_name}.rb"
|
25
|
+
end
|
26
|
+
|
27
|
+
def migration_class_name
|
28
|
+
migration_name.camelize
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
<% asset_names.each do |asset| -%>
|
4
|
+
add_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_resizor_id, :string
|
5
|
+
add_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_name, :string
|
6
|
+
|
7
|
+
# Uncomment below for meta data columns
|
8
|
+
# add_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_mime_type, :string
|
9
|
+
# add_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_size, :integer
|
10
|
+
# add_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_width, :integer
|
11
|
+
# add_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_height, :integer
|
12
|
+
<% end -%>
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
<% asset_names.each do |asset| -%>
|
17
|
+
remove_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_resizor_id
|
18
|
+
remove_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_name
|
19
|
+
|
20
|
+
# remove_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_mime_type
|
21
|
+
# remove_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_size
|
22
|
+
# remove_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_width
|
23
|
+
# remove_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_height
|
24
|
+
<% end -%>
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module Resizor
|
2
|
+
class Asset
|
3
|
+
attr_accessor :id, :name, :mime_type, :size, :width, :height, :path
|
4
|
+
|
5
|
+
def initialize(options={})
|
6
|
+
options.each { |k,v| send "#{k}=".to_sym, v }
|
7
|
+
end
|
8
|
+
|
9
|
+
def url(options={})
|
10
|
+
options = {:size => '200', :format => 'jpg'}.merge(options)
|
11
|
+
"#{Resizor.api_url}/assets/#{id}.#{options[:format]}?size=#{options[:size]}&token=#{resize_token_for(options)}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def resize_token_for(options={})
|
15
|
+
options = {:size => '200', :format => 'jpg'}.merge(options)
|
16
|
+
Digest::SHA1.hexdigest("#{Resizor.api_key}-#{id}-#{options[:size]}-#{options[:format]}")
|
17
|
+
end
|
18
|
+
|
19
|
+
def save_to_resizor
|
20
|
+
if path && File.exists?(path)
|
21
|
+
ret = Resizor.post('/assets.json', :file => File.open(path))
|
22
|
+
if ret.code == 201
|
23
|
+
@id = ret.body['asset']['id']
|
24
|
+
@name = "#{ret.body['asset']['name']}.#{ret.body['asset']['extension']}"
|
25
|
+
@mime_type = ret.body['asset']['mime_type']
|
26
|
+
@size = ret.body['asset']['file_size']
|
27
|
+
@width = ret.body['asset']['width']
|
28
|
+
@height = ret.body['asset']['height']
|
29
|
+
else
|
30
|
+
return false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
return true
|
34
|
+
end
|
35
|
+
|
36
|
+
def destroy
|
37
|
+
ret = Resizor.delete("/assets/#{id}.json")
|
38
|
+
if ret.code == 200
|
39
|
+
return true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class AttachedAsset < Resizor::Asset
|
45
|
+
|
46
|
+
attr_accessor :attachment_name, :instance, :file
|
47
|
+
|
48
|
+
def initialize(attachment_name, instance, options = {})
|
49
|
+
@attachment_name = attachment_name
|
50
|
+
@instance = instance
|
51
|
+
@options = options
|
52
|
+
@id = instance_read("resizor_id")
|
53
|
+
@name = instance_read("name")
|
54
|
+
@mime_type = instance_read("mime_type")
|
55
|
+
@size = instance_read("size")
|
56
|
+
@width = instance_read("width")
|
57
|
+
@height = instance_read("height")
|
58
|
+
end
|
59
|
+
|
60
|
+
def assign in_file
|
61
|
+
if in_file.is_a?(Resizor::Asset)
|
62
|
+
@id = in_file.id
|
63
|
+
@name = in_file.name
|
64
|
+
@mime_type = in_file.mime_type
|
65
|
+
@size = in_file.size
|
66
|
+
@width = in_file.width
|
67
|
+
@height = in_file.height
|
68
|
+
else
|
69
|
+
@file = in_file
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def save
|
74
|
+
if file
|
75
|
+
@path = File.join(Dir.tmpdir, file.original_filename)
|
76
|
+
if file.is_a?(Tempfile)
|
77
|
+
FileUtils.move(file.local_path, @path)
|
78
|
+
else
|
79
|
+
File.open(@path, 'wb') { |f| f.write(file.read) }
|
80
|
+
end
|
81
|
+
if save_to_resizor
|
82
|
+
File.unlink(@path)
|
83
|
+
else
|
84
|
+
instance.errors[attachment_name.to_sym] << "can't be saved"
|
85
|
+
return false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
instance_write(:resizor_id, @id)
|
89
|
+
instance_write(:name, @name)
|
90
|
+
instance_write(:mime_type, @mime_type)
|
91
|
+
instance_write(:size, @size)
|
92
|
+
instance_write(:width, @width)
|
93
|
+
instance_write(:height, @height)
|
94
|
+
return true
|
95
|
+
end
|
96
|
+
|
97
|
+
def delete
|
98
|
+
destroy
|
99
|
+
end
|
100
|
+
|
101
|
+
def destroy
|
102
|
+
if ret = super
|
103
|
+
instance_write(:resizor_id, nil)
|
104
|
+
instance_write(:name, nil)
|
105
|
+
instance_write(:mime_type, nil)
|
106
|
+
instance_write(:size, nil)
|
107
|
+
instance_write(:width, nil)
|
108
|
+
instance_write(:height, nil)
|
109
|
+
end
|
110
|
+
ret
|
111
|
+
end
|
112
|
+
|
113
|
+
protected
|
114
|
+
def instance_write(_attr, value)
|
115
|
+
setter = :"#{attachment_name}_#{_attr}="
|
116
|
+
self.instance_variable_set("@#{_attr.to_s.chop}", value)
|
117
|
+
instance.send(setter, value) if instance.respond_to?(setter)
|
118
|
+
end
|
119
|
+
|
120
|
+
def instance_read(_attr)
|
121
|
+
getter = :"#{attachment_name}_#{_attr}"
|
122
|
+
instance.send(getter) if instance.respond_to?(getter)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
module Resizor
|
3
|
+
class Connection
|
4
|
+
attr_accessor :api_host, :api_port, :api_key
|
5
|
+
|
6
|
+
def initialize(options={})
|
7
|
+
@api_host = options[:api_host] || options['api_host'] || 'http://resizor.com'
|
8
|
+
@api_port = options[:api_port] || options['api_port'] || 80
|
9
|
+
@api_key = options[:api_key] || options['api_key']
|
10
|
+
end
|
11
|
+
|
12
|
+
def get(request_uri, params={}, append_api_key=true)
|
13
|
+
params[:api_key] = @api_key if append_api_key
|
14
|
+
query = make_query(params)
|
15
|
+
do_request do
|
16
|
+
make_response_for resource[request_uri + '?' + query].get
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def post(request_uri, params={}, append_api_key=true)
|
21
|
+
params[:api_key] = @api_key if append_api_key
|
22
|
+
do_request do
|
23
|
+
make_response_for resource[request_uri].post params
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete(request_uri, params={}, append_api_key=true)
|
28
|
+
params[:api_key] = @api_key if append_api_key
|
29
|
+
query = make_query(params)
|
30
|
+
do_request do
|
31
|
+
make_response_for resource[request_uri + '?' + query].delete
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def api_url
|
36
|
+
@api_url ||= "http://#{@api_host}:#{@api_port}"
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def resource
|
42
|
+
@resource ||= RestClient::Resource.new(api_url)
|
43
|
+
end
|
44
|
+
|
45
|
+
def make_query(params)
|
46
|
+
params.collect {|key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join("=") }.join("&")
|
47
|
+
end
|
48
|
+
|
49
|
+
def make_response_for(http_response)
|
50
|
+
Resizor::Response.new(http_response.code, http_response.body)
|
51
|
+
end
|
52
|
+
|
53
|
+
def do_request(&block)
|
54
|
+
begin
|
55
|
+
yield
|
56
|
+
rescue RestClient::Exception => e
|
57
|
+
Resizor::Response.new(e.http_code, e.http_body)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Response
|
63
|
+
attr_accessor :code, :body, :format
|
64
|
+
def initialize(_code, _body, _format = 'json')
|
65
|
+
@code = _code
|
66
|
+
@format = _format
|
67
|
+
@body = if @format == 'json'
|
68
|
+
if defined?(ActiveSupport::JSON)
|
69
|
+
ActiveSupport::JSON.decode(_body)
|
70
|
+
else
|
71
|
+
JSON.parse(_body)
|
72
|
+
end
|
73
|
+
else
|
74
|
+
_body
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'resizor.rb'
|
2
|
+
|
3
|
+
module Resizor
|
4
|
+
if defined?(Rails::Railtie)
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
initializer 'resizor.insert_into_active_record' do
|
7
|
+
ActiveSupport.on_load :active_record do
|
8
|
+
Resizor::Railtie.insert
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Railtie
|
15
|
+
def self.insert
|
16
|
+
ActiveRecord::Base.send(:include, Resizor)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class << self
|
21
|
+
def included base
|
22
|
+
base.extend ClassMethods
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
def has_resizor_asset name, options = {}
|
28
|
+
include InstanceMethods
|
29
|
+
|
30
|
+
write_inheritable_attribute(:resizor_assets, {}) if resizor_assets.nil?
|
31
|
+
resizor_assets[name] = options
|
32
|
+
|
33
|
+
before_save :save_attached_files_for_resizor
|
34
|
+
before_destroy :delete_attached_files_on_resizor
|
35
|
+
|
36
|
+
define_method name do |*args|
|
37
|
+
asset_for(name)
|
38
|
+
end
|
39
|
+
|
40
|
+
define_method "#{name}=" do |file|
|
41
|
+
asset_for(name).assign(file)
|
42
|
+
end
|
43
|
+
|
44
|
+
define_method "#{name}?" do
|
45
|
+
!asset_for(name).file.nil? || !asset_for(name).id.nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
def resizor_assets
|
51
|
+
read_inheritable_attribute(:resizor_assets)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module InstanceMethods
|
56
|
+
def asset_for name
|
57
|
+
@resizor_assets ||= {}
|
58
|
+
@resizor_assets[name] ||= Resizor::AttachedAsset.new(name, self, self.class.resizor_assets[name])
|
59
|
+
end
|
60
|
+
|
61
|
+
def save_attached_files_for_resizor
|
62
|
+
self.class.resizor_assets.each do |name, options|
|
63
|
+
asset_for(name).send(:save)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def delete_attached_files_on_resizor
|
68
|
+
self.class.resizor_assets.each do |name, options|
|
69
|
+
asset_for(name).send(:destroy)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'restclient'
|
2
|
+
require 'forwardable'
|
3
|
+
require 'json' unless defined?(ActiveSupport::JSON)
|
4
|
+
|
5
|
+
module Resizor
|
6
|
+
extend self
|
7
|
+
extend Forwardable
|
8
|
+
attr_reader :connection
|
9
|
+
def_delegators :connection, :get, :post, :delete, :api_url, :api_key
|
10
|
+
|
11
|
+
def configure
|
12
|
+
yield @connection = Connection.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def connection
|
16
|
+
raise "Not connected. Please setup Resizor configuration first." unless @connection
|
17
|
+
@connection
|
18
|
+
end
|
19
|
+
end
|
data/lib/resizor.rb
ADDED
data/resizor.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/resizor/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "resizor"
|
6
|
+
s.version = Resizor::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Winston Design"]
|
9
|
+
s.email = ["hello@resizor.com"]
|
10
|
+
s.homepage = "http://github.org/winstondesign/resizor-gem"
|
11
|
+
s.summary = "Client for Resizor.com API"
|
12
|
+
s.description = "Lets you easily interface with Resizor.com's REST API. Includes Rails helpers."
|
13
|
+
|
14
|
+
s.required_rubygems_version = ">= 1.3.6"
|
15
|
+
|
16
|
+
s.add_development_dependency "bundler", ">= 1.0.0"
|
17
|
+
|
18
|
+
s.add_dependency(%q<rest-client>, [">= 1.4"])
|
19
|
+
s.add_dependency(%q<json>, [">= 1.2"])
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
23
|
+
s.require_path = 'lib'
|
24
|
+
end
|
data/test/asset_test.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
|
3
|
+
class AssetTest < Test::Unit::TestCase
|
4
|
+
context "A Asset" do
|
5
|
+
setup do
|
6
|
+
setup_resizor
|
7
|
+
@asset = Resizor::Asset.new(:id => 10,
|
8
|
+
:name => 'my_file.jpg',
|
9
|
+
:mime_type => 'image/jpeg',
|
10
|
+
:width => 200,
|
11
|
+
:height => 300,
|
12
|
+
:size => 123456)
|
13
|
+
end
|
14
|
+
should "have assigned attributes" do
|
15
|
+
assert_equal @asset.id, 10
|
16
|
+
assert_equal @asset.name, 'my_file.jpg'
|
17
|
+
assert_equal @asset.mime_type, 'image/jpeg'
|
18
|
+
assert_equal @asset.width, 200
|
19
|
+
assert_equal @asset.height, 300
|
20
|
+
assert_equal @asset.size, 123456
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'generate url for size c200x300' do
|
24
|
+
assert_equal 'http://resizor.test:80/assets/10.jpg?size=c200x300&token=b8bb7c4c7c4fc1006c904f011f32f50f69730e5e', @asset.url(:size => 'c200x300')
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'generate url for size c200x300 format png' do
|
28
|
+
assert_equal 'http://resizor.test:80/assets/10.png?size=c200x300&token=0cf27070e89c44a40aee85decca2cd2d98af1dc2', @asset.url(:size => 'c200x300', :format => 'png')
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'generate resize token for size c200x300 and format jpg' do
|
32
|
+
assert_equal 'b8bb7c4c7c4fc1006c904f011f32f50f69730e5e', @asset.resize_token_for(:size => 'c200x300', :format => 'jpg')
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when saving to resizor' do
|
36
|
+
setup do
|
37
|
+
@jpg_file = Tempfile.new('image.jpg')
|
38
|
+
@asset.path = @jpg_file.path
|
39
|
+
end
|
40
|
+
teardown { @jpg_file.unlink }
|
41
|
+
|
42
|
+
context 'on success' do
|
43
|
+
setup do
|
44
|
+
stub_http_request(:post, "resizor.test/assets.json").
|
45
|
+
with { |request|
|
46
|
+
request.body.include?("Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg")
|
47
|
+
}.
|
48
|
+
to_return(:status => 201,
|
49
|
+
:body => '{"asset": { "id":1, "name":"i", "extension":"jpg", "mime_type":"image/jpeg", "height":7, "width":8, "file_size":9, "created_at":"2010-10-23T13:07:25Z"}}')
|
50
|
+
@asset.save_to_resizor
|
51
|
+
end
|
52
|
+
|
53
|
+
should 'make create call to Resizor on save with file' do
|
54
|
+
assert_requested(:post, "resizor.test/assets.json",
|
55
|
+
:times => 1) { |request|
|
56
|
+
request.body.include?("Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg")
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
should 'assign data for new assets as attributes' do
|
61
|
+
assert_equal 1, @asset.id
|
62
|
+
assert_equal 'i.jpg', @asset.name
|
63
|
+
assert_equal 'image/jpeg', @asset.mime_type
|
64
|
+
assert_equal 7, @asset.height
|
65
|
+
assert_equal 8, @asset.width
|
66
|
+
assert_equal 9, @asset.size
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'on failure' do
|
71
|
+
should 'return false' do
|
72
|
+
stub_http_request(:post, "resizor.test/assets.json").to_return(:status => 422)
|
73
|
+
assert !@asset.save_to_resizor
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when destroying an asset' do
|
79
|
+
should 'make delete call to Resizor on destroy' do
|
80
|
+
stub_http_request(:delete, "resizor.test/assets/10.json?api_key=test-api-key").to_return(:status => 200)
|
81
|
+
@asset.destroy
|
82
|
+
assert_requested :delete, "resizor.test/assets/10.json?api_key=test-api-key", :times => 1
|
83
|
+
end
|
84
|
+
|
85
|
+
should 'return true on success' do
|
86
|
+
stub_http_request(:delete, "resizor.test/assets/10.json?api_key=test-api-key").to_return(:status => 200)
|
87
|
+
assert @asset.destroy
|
88
|
+
end
|
89
|
+
|
90
|
+
should 'return false on failure' do
|
91
|
+
stub_http_request(:delete, "resizor.test/assets/10.json?api_key=test-api-key").to_return(:status => 404)
|
92
|
+
assert !@asset.destroy
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/test/database.yml
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
|
3
|
+
class IntegrationTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context 'Including Resizor in a Rails project' do
|
6
|
+
setup do
|
7
|
+
setup_resizor
|
8
|
+
end
|
9
|
+
|
10
|
+
should 'add has_resizor_asset to ActiveRecord::Base' do
|
11
|
+
assert ActiveRecord::Base.methods.include?('has_resizor_asset')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'A ActiveRecord model that has_resizor_asset' do
|
16
|
+
setup do
|
17
|
+
build_model
|
18
|
+
@item = Item.new(:name => 'my test item')
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with a file attached' do
|
22
|
+
setup do
|
23
|
+
@image_fixture_path = File.join(File.dirname(__FILE__), 'fixtures', 'image.jpg')
|
24
|
+
File.open(@image_fixture_path, 'w') {|f| f.write('JPEG data') }
|
25
|
+
@file = File.new(@image_fixture_path, 'rb')
|
26
|
+
@item.image = @file
|
27
|
+
stub_http_request(:post, "resizor.test/assets.json").
|
28
|
+
with { |request| request.body.include?("Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg") }.
|
29
|
+
to_return(:status => 201, :body => '{"asset": { "id":1, "name":"i", "extension":"jpg", "mime_type":"image/jpeg", "height":7, "width":8, "file_size":9, "created_at":"2010-10-23T13:07:25Z"}}')
|
30
|
+
stub_http_request(:delete, "resizor.test/assets/1.json?api_key=test-api-key").to_return(:status => 200)
|
31
|
+
end
|
32
|
+
|
33
|
+
teardown { File.unlink(@image_fixture_path) }
|
34
|
+
|
35
|
+
should 'save attached asset to Resizor on save' do
|
36
|
+
assert @item.save
|
37
|
+
assert_requested(:post, "resizor.test/assets.json", :times => 1) do |request|
|
38
|
+
request.body.include?("Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
should 'set assigned resizor data to asset fields' do
|
43
|
+
@item.save
|
44
|
+
@item.reload
|
45
|
+
assert_equal '1', @item.image_resizor_id
|
46
|
+
assert_equal 'i.jpg', @item.image_name
|
47
|
+
assert_equal 'image/jpeg', @item.image_mime_type
|
48
|
+
assert_equal 9, @item.image_size
|
49
|
+
assert_equal 8, @item.image_width
|
50
|
+
assert_equal 7, @item.image_height
|
51
|
+
end
|
52
|
+
|
53
|
+
should 'copy attributes when another resizor asset is assigned to asset attribute' do
|
54
|
+
@item.save
|
55
|
+
@another_item = Item.create(:name => 'The second item')
|
56
|
+
@another_item.image = @item.image
|
57
|
+
@another_item.save
|
58
|
+
assert_equal @item.image_resizor_id, @another_item.image_resizor_id
|
59
|
+
assert_equal @item.image_name, @another_item.image_name
|
60
|
+
assert_equal @item.image_mime_type, @another_item.image_mime_type
|
61
|
+
assert_equal @item.image_size, @another_item.image_size
|
62
|
+
assert_equal @item.image_width, @another_item.image_width
|
63
|
+
assert_equal @item.image_height, @another_item.image_height
|
64
|
+
end
|
65
|
+
|
66
|
+
should 'return true for #image?' do
|
67
|
+
@item.save
|
68
|
+
assert @item.image?
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
should 'clear asset fields when assets is deleted' do
|
73
|
+
@item.save
|
74
|
+
assert @item.image.destroy
|
75
|
+
[:image_resizor_id, :image_name, :image_mime_type, :image_size, :image_width, :image_height].each do |_attr|
|
76
|
+
assert_nil @item.send(_attr)
|
77
|
+
end
|
78
|
+
assert_requested :delete, "resizor.test/assets/1.json?api_key=test-api-key", :times => 1
|
79
|
+
end
|
80
|
+
|
81
|
+
should 'delete resizor asset when model instance is deleted' do
|
82
|
+
@item.save
|
83
|
+
@item.reload
|
84
|
+
assert @item.destroy
|
85
|
+
assert_requested :delete, "resizor.test/assets/1.json?api_key=test-api-key", :times => 1
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
should 'should work with no attachment set' do
|
91
|
+
assert_nothing_raised do
|
92
|
+
@item.save
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
should 'return false when no attachment is set' do
|
97
|
+
@item.save
|
98
|
+
assert !@item.image?
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
|
3
|
+
class ResizorTest < Test::Unit::TestCase
|
4
|
+
context 'When Resizor gem is not setup it' do
|
5
|
+
setup do
|
6
|
+
Resizor.instance_variable_set("@connection", nil)
|
7
|
+
end
|
8
|
+
|
9
|
+
['get', 'post', 'delete'].each do |m|
|
10
|
+
should "raise error for #{m}" do
|
11
|
+
exception = assert_raise(RuntimeError) { Resizor.send(m, nil) }
|
12
|
+
assert_equal 'Not connected. Please setup Resizor configuration first.', exception.message
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'When Resizor gem has been setup it' do
|
18
|
+
setup { setup_resizor }
|
19
|
+
should 'return a API url' do
|
20
|
+
assert_equal 'http://resizor.test:80', Resizor.api_url
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'make a GET request to Resizor server with API key' do
|
24
|
+
stub_http_request(:get, "resizor.test:80/assets.json?api_key=test-api-key").to_return(:body => '{"a": "123"}')
|
25
|
+
Resizor.get('/assets.json').tap do |r|
|
26
|
+
assert_equal 200, r.code
|
27
|
+
assert_equal Hash['a', '123'], r.body
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'make a POST request to Resizor server with API key' do
|
32
|
+
stub_http_request(:post, "resizor.test:80/assets.json").with(:body => 'api_key=test-api-key').to_return(:body => '{"a": "123"}', :status => 201)
|
33
|
+
Resizor.post('/assets.json').tap do |r|
|
34
|
+
assert_equal 201, r.code
|
35
|
+
assert_equal Hash['a', '123'], r.body
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
should 'make a DELETE request to Resizor server with API key' do
|
40
|
+
stub_http_request(:delete, "resizor.test:80/assets/1.json?api_key=test-api-key")
|
41
|
+
Resizor.delete('/assets/1.json').tap do |r|
|
42
|
+
assert_equal 200, r.code
|
43
|
+
assert_equal nil, r.body
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
should 'add params along with API key when generating GET URL' do
|
48
|
+
stub_http_request(:get, "resizor.test:80/assets.json?api_key=test-api-key&id=1")
|
49
|
+
Resizor.get('/assets.json', :id => 1)
|
50
|
+
assert_requested :get, "resizor.test:80/assets.json?api_key=test-api-key&id=1"
|
51
|
+
end
|
52
|
+
|
53
|
+
should 'add params along with API key when generating POST URL' do
|
54
|
+
stub_http_request(:post, "resizor.test:80/assets.json").with(:body => 'api_key=test-api-key&id=1')
|
55
|
+
Resizor.post('/assets.json', :id => 1)
|
56
|
+
assert_requested :post, "resizor.test:80/assets.json"
|
57
|
+
end
|
58
|
+
|
59
|
+
should 'add params along with API key when generating DELETE URL' do
|
60
|
+
stub_http_request(:delete, "resizor.test:80/assets.json?api_key=test-api-key&id=1")
|
61
|
+
Resizor.delete('/assets.json', :id => 1)
|
62
|
+
assert_requested :delete, "resizor.test:80/assets.json?api_key=test-api-key&id=1"
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'test/unit'
|
6
|
+
require 'shoulda'
|
7
|
+
require 'resizor'
|
8
|
+
|
9
|
+
gem 'activerecord', '~>3.0.0'
|
10
|
+
require 'active_record'
|
11
|
+
|
12
|
+
require 'webmock/test_unit'
|
13
|
+
include WebMock::API
|
14
|
+
|
15
|
+
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
|
16
|
+
ActiveRecord::Base.logger = ActiveSupport::BufferedLogger.new(File.dirname(__FILE__) + "/debug.log")
|
17
|
+
ActiveRecord::Base.establish_connection(config['test'])
|
18
|
+
|
19
|
+
ActiveRecord::Base.send(:include, Resizor)
|
20
|
+
|
21
|
+
def build_model
|
22
|
+
ActiveRecord::Base.connection.create_table :items, :force => true do |t|
|
23
|
+
t.column :name, :string
|
24
|
+
t.column :image_resizor_id, :string
|
25
|
+
t.column :image_name, :string
|
26
|
+
t.column :image_mime_type, :string
|
27
|
+
t.column :image_size, :integer
|
28
|
+
t.column :image_width, :integer
|
29
|
+
t.column :image_height, :integer
|
30
|
+
end
|
31
|
+
Object.send(:remove_const, "Item") rescue nil
|
32
|
+
Object.const_set("Item", Class.new(ActiveRecord::Base))
|
33
|
+
Item.class_eval do
|
34
|
+
has_resizor_asset :image
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def setup_resizor
|
39
|
+
Resizor.configure do |config|
|
40
|
+
config.api_host = 'resizor.test'
|
41
|
+
config.api_key = 'test-api-key'
|
42
|
+
end
|
43
|
+
Resizor::Railtie.insert
|
44
|
+
end
|
45
|
+
|
46
|
+
class File
|
47
|
+
def original_filename
|
48
|
+
File.basename(self.path)
|
49
|
+
end
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: resizor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Winston Design
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-11-16 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: bundler
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 23
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 0
|
33
|
+
- 0
|
34
|
+
version: 1.0.0
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rest-client
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 7
|
46
|
+
segments:
|
47
|
+
- 1
|
48
|
+
- 4
|
49
|
+
version: "1.4"
|
50
|
+
type: :runtime
|
51
|
+
version_requirements: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: json
|
54
|
+
prerelease: false
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 11
|
61
|
+
segments:
|
62
|
+
- 1
|
63
|
+
- 2
|
64
|
+
version: "1.2"
|
65
|
+
type: :runtime
|
66
|
+
version_requirements: *id003
|
67
|
+
description: Lets you easily interface with Resizor.com's REST API. Includes Rails helpers.
|
68
|
+
email:
|
69
|
+
- hello@resizor.com
|
70
|
+
executables: []
|
71
|
+
|
72
|
+
extensions: []
|
73
|
+
|
74
|
+
extra_rdoc_files: []
|
75
|
+
|
76
|
+
files:
|
77
|
+
- .gitignore
|
78
|
+
- Gemfile
|
79
|
+
- README.rdoc
|
80
|
+
- Rakefile
|
81
|
+
- lib/generators/resizor/USAGE
|
82
|
+
- lib/generators/resizor/resizor_generator.rb
|
83
|
+
- lib/generators/resizor/templates/resizor_migration.rb.erb
|
84
|
+
- lib/resizor.rb
|
85
|
+
- lib/resizor/asset.rb
|
86
|
+
- lib/resizor/connection.rb
|
87
|
+
- lib/resizor/railtie.rb
|
88
|
+
- lib/resizor/resizor.rb
|
89
|
+
- lib/resizor/version.rb
|
90
|
+
- resizor.gemspec
|
91
|
+
- test/asset_test.rb
|
92
|
+
- test/database.yml
|
93
|
+
- test/integration_test.rb
|
94
|
+
- test/resizor_test.rb
|
95
|
+
- test/test_helper.rb
|
96
|
+
has_rdoc: true
|
97
|
+
homepage: http://github.org/winstondesign/resizor-gem
|
98
|
+
licenses: []
|
99
|
+
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
hash: 3
|
111
|
+
segments:
|
112
|
+
- 0
|
113
|
+
version: "0"
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
hash: 23
|
120
|
+
segments:
|
121
|
+
- 1
|
122
|
+
- 3
|
123
|
+
- 6
|
124
|
+
version: 1.3.6
|
125
|
+
requirements: []
|
126
|
+
|
127
|
+
rubyforge_project:
|
128
|
+
rubygems_version: 1.3.7
|
129
|
+
signing_key:
|
130
|
+
specification_version: 3
|
131
|
+
summary: Client for Resizor.com API
|
132
|
+
test_files: []
|
133
|
+
|