snapimage 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/.gitignore +2 -0
  2. data/bin/snapimage_generate_config +9 -11
  3. data/bin/snapimage_server +1 -1
  4. data/lib/snapimage.rb +12 -12
  5. data/lib/snapimage/config.rb +2 -9
  6. data/lib/snapimage/exceptions.rb +7 -10
  7. data/lib/snapimage/rack/request.rb +1 -6
  8. data/lib/snapimage/rack/request_file.rb +3 -6
  9. data/lib/snapimage/rack/response.rb +13 -13
  10. data/lib/snapimage/server.rb +24 -28
  11. data/lib/snapimage/version.rb +1 -1
  12. data/spec/acceptance/delete_resource_images_spec.rb +166 -166
  13. data/spec/acceptance/list_resource_images_spec.rb +158 -158
  14. data/spec/acceptance/modify_spec.rb +165 -165
  15. data/spec/acceptance/sync_spec.rb +237 -237
  16. data/spec/acceptance/upload_spec.rb +28 -189
  17. data/spec/snapimage/config_spec.rb +5 -13
  18. data/spec/snapimage/image/image_name_utils_spec.rb +113 -113
  19. data/spec/snapimage/image/image_spec.rb +55 -55
  20. data/spec/snapimage/rack/request_file_spec.rb +0 -11
  21. data/spec/snapimage/rack/request_spec.rb +6 -25
  22. data/spec/snapimage/server_actions/server_actions.authorize_spec.rb +56 -56
  23. data/spec/snapimage/server_actions/server_actions.generate_image_spec.rb +146 -146
  24. data/spec/snapimage/server_actions/server_actions.sync_resource_spec.rb +81 -81
  25. data/spec/snapimage/server_spec.rb +57 -20
  26. data/spec/snapimage/storage/storage_server.local_spec.rb +150 -150
  27. data/spec/snapimage/storage/storage_server_spec.rb +83 -83
  28. data/spec/snapimage/storage/storage_spec.rb +42 -42
  29. data/spec/support/assets/config.json +2 -6
  30. data/spec/support/assets/config.yml +2 -9
  31. metadata +4 -4
data/.gitignore CHANGED
@@ -17,3 +17,5 @@ test/tmp
17
17
  test/version_tmp
18
18
  tmp
19
19
  /vendor/bundle
20
+ /storage
21
+ snapimage_config.yml
@@ -4,15 +4,15 @@ require "optparse"
4
4
 
5
5
  options = {
6
6
  file: "snapimage_config.yml",
7
+ size: 10485760,
7
8
  force: false
8
9
  }
9
10
 
10
11
  optparse = OptionParser.new do |opts|
11
- opts.banner = "Usage: snapimage_generate_config local_root public_url [options]"
12
+ opts.banner = "Usage: snapimage_generate_config local_root [options]"
12
13
 
13
14
  opts.separator ""
14
15
  opts.separator "local_root\tPath to the directory where the images will be stored"
15
- opts.separator "public_url\tURL at which the images will accessible from"
16
16
 
17
17
  opts.separator ""
18
18
  opts.separator "Options:"
@@ -21,6 +21,10 @@ optparse = OptionParser.new do |opts|
21
21
  options[:file] = file
22
22
  end
23
23
 
24
+ opts.on("-s", "--size SIZE", "Max file size in bytes (Default: 10485760)") do |size|
25
+ options[:size] = size.to_i
26
+ end
27
+
24
28
  opts.on("--force", "Overwrites the file if it exists") do
25
29
  options[:force] = true
26
30
  end
@@ -32,13 +36,12 @@ optparse = OptionParser.new do |opts|
32
36
  end
33
37
  optparse.parse!
34
38
 
35
- unless ARGV.length == 2
39
+ unless ARGV.length == 1
36
40
  puts optparse.help
37
41
  exit
38
42
  end
39
43
 
40
44
  local_root = ARGV[0]
41
- public_url = ARGV[1]
42
45
 
43
46
  if !options[:force] && File.exists?(options[:file])
44
47
  puts "File '#{options[:file]}' already exists. Use --force if you want to overwrite."
@@ -50,13 +53,8 @@ end
50
53
 
51
54
  File.open(options[:file], "w") do |f|
52
55
  f.write(<<-EOF
53
- primary_storage_server: "local"
54
- storage_servers:
55
- -
56
- name: "local"
57
- type: "LOCAL"
58
- local_root: "#{local_root}"
59
- public_url: "#{public_url}"
56
+ directory: "#{local_root}"
57
+ max_file_size: #{options[:size]}
60
58
  EOF
61
59
  )
62
60
  end
@@ -10,7 +10,7 @@ optparse = OptionParser.new do |opts|
10
10
  opts.banner = "Usage: snapimage_server config [options]"
11
11
 
12
12
  opts.on("-p", "--port PORT", "Set the port (Default: 54321)") do |port|
13
- options[:port] = port
13
+ options[:port] = port.to_i
14
14
  end
15
15
 
16
16
  opts.on("--path PATH", "Set the URL path of the SnapImage API Server (Default: /snapimage_api)") do |path|
@@ -3,23 +3,23 @@ require "yaml"
3
3
  require "json"
4
4
  require "fileutils"
5
5
  require "digest/sha1"
6
- require "open-uri"
7
- require "RMagick"
6
+ #require "open-uri"
7
+ #require "RMagick"
8
8
  require "snapimage/version"
9
9
  require "snapimage/exceptions"
10
10
  require "snapimage/rack/request_file"
11
11
  require "snapimage/rack/request"
12
12
  require "snapimage/rack/response"
13
- require "snapimage/image/image"
14
- require "snapimage/image/image_name_utils"
15
- require "snapimage/storage/storage_server"
16
- require "snapimage/storage/storage_server.local"
17
- require "snapimage/storage/storage"
13
+ #require "snapimage/image/image"
14
+ #require "snapimage/image/image_name_utils"
15
+ #require "snapimage/storage/storage_server"
16
+ #require "snapimage/storage/storage_server.local"
17
+ #require "snapimage/storage/storage"
18
18
  require "snapimage/config"
19
- require "snapimage/server_actions/server_actions.authorize"
20
- require "snapimage/server_actions/server_actions.generate_image"
21
- require "snapimage/server_actions/server_actions.sync_resource"
22
- require "snapimage/server_actions/server_actions.delete_resource_images"
23
- require "snapimage/server_actions/server_actions.list_resource_images"
19
+ #require "snapimage/server_actions/server_actions.authorize"
20
+ #require "snapimage/server_actions/server_actions.generate_image"
21
+ #require "snapimage/server_actions/server_actions.sync_resource"
22
+ #require "snapimage/server_actions/server_actions.delete_resource_images"
23
+ #require "snapimage/server_actions/server_actions.list_resource_images"
24
24
  require "snapimage/server"
25
25
  require "snapimage/middleware"
@@ -9,14 +9,11 @@ module SnapImage
9
9
  end
10
10
 
11
11
  def validate_config
12
- raise SnapImage::InvalidConfig, 'Missing "primary_storage_server"' unless @config["primary_storage_server"]
13
- raise SnapImage::InvalidConfig, 'Missing "storage_servers"' unless @config["storage_servers"]
14
- raise SnapImage::InvalidConfig, '"storage_servers" must be an array' unless @config["storage_servers"].is_a? Array
12
+ raise SnapImage::InvalidConfig, 'Missing "directory"' unless @config["directory"]
15
13
  end
16
14
 
17
15
  def set_config_defaults
18
- @config["max_width"] ||= 1024
19
- @config["max_height"] ||= 2048
16
+ @config["max_file_size"] ||= 10485760 # 10MB
20
17
  end
21
18
 
22
19
  def get_config
@@ -43,9 +40,5 @@ module SnapImage
43
40
  def [](key)
44
41
  get_config[key]
45
42
  end
46
-
47
- def storage
48
- @storage ||= SnapImage::Storage.new(get_config["storage_servers"], get_config["primary_storage_server"], get_config["max_width"], get_config["max_height"])
49
- end
50
43
  end
51
44
  end
@@ -1,25 +1,22 @@
1
1
  module SnapImage
2
2
  # Configuration.
3
3
  class InvalidConfig < StandardError; end
4
- class InvalidStorageConfig < StandardError; end
5
4
  class UnknownConfigType < StandardError; end
6
5
  class MissingConfig < StandardError; end
7
6
 
8
7
  # Authorization.
9
- class AuthorizationRequired < StandardError; end
10
- class AuthorizationFailed < StandardError; end
8
+ #class AuthorizationRequired < StandardError; end
9
+ #class AuthorizationFailed < StandardError; end
11
10
 
12
11
  # Request.
13
12
  class BadRequest < StandardError; end
14
- class ActionNotImplemented < StandardError; end
13
+ #class ActionNotImplemented < StandardError; end
14
+ class InvalidFilename < StandardError; end
15
+ class InvalidDirectory < StandardError; end
16
+ class FileTooLarge < StandardError; end
15
17
 
16
18
  # Files.
17
19
  class UnknownFileType < StandardError; end
18
- class FileDoesNotExist < StandardError; end
20
+ #class FileDoesNotExist < StandardError; end
19
21
 
20
- # Images.
21
- class InvalidImageIdentifier < StandardError; end
22
-
23
- # Resources.
24
- class InvalidResourceIdentifier < StandardError; end
25
22
  end
@@ -1,12 +1,7 @@
1
1
  module SnapImage
2
2
  class Request < Rack::Request
3
3
  def bad_request?
4
- !(self.post? && self.POST["json"] && self.json["action"] && self.json["resource_identifier"])
5
- end
6
-
7
- # NOTE: Call bad_request? first to make sure there is json to parse.
8
- def json
9
- @json ||= JSON.parse(self.POST["json"])
4
+ !(self.post? && self.POST["file"] && self.POST["directory"])
10
5
  end
11
6
 
12
7
  # Returns a SnapImage::RequestFile which encapsulates the file that Rack
@@ -12,15 +12,12 @@ module SnapImage
12
12
  @file = file
13
13
  end
14
14
 
15
- def file
15
+ def tempfile
16
16
  @file[:tempfile]
17
17
  end
18
18
 
19
- def type
20
- return @type if @type
21
- @type = File.extname(@file[:filename])[1..-1]
22
- @type = "jpg" if type == "jpeg"
23
- @type
19
+ def filename
20
+ @file[:filename]
24
21
  end
25
22
  end
26
23
  end
@@ -18,30 +18,30 @@ module SnapImage
18
18
  @json = { status_code: 400, message: "Bad Request" }
19
19
  end
20
20
 
21
- def set_authorization_required
22
- @json = { status_code: 401, message: "Authorization Required" }
23
- end
21
+ #def set_authorization_required
22
+ #@json = { status_code: 401, message: "Authorization Required" }
23
+ #end
24
+
25
+ #def set_authorization_failed
26
+ #@json = { status_code: 402, message: "Authorization Failed" }
27
+ #end
24
28
 
25
- def set_authorization_failed
26
- @json = { status_code: 402, message: "Authorization Failed" }
29
+ def set_invalid_filename
30
+ @json = { status_code: 403, message: "Invalid Filename" }
27
31
  end
28
32
 
29
- def set_invalid_image_identifier
30
- @json = { status_code: 403, message: "Invalid Image Identifier" }
33
+ def set_invalid_directory
34
+ @json = { status_code: 404, message: "Invalid Directory" }
31
35
  end
32
36
 
33
- def set_invalid_resource_identifier
34
- @json = { status_code: 404, message: "Invalid Resource Identifier" }
37
+ def set_file_too_large
38
+ @json = { status_code: 405, message: "File Too Large" }
35
39
  end
36
40
 
37
41
  def set_internal_server_error
38
42
  @json = { status_code: 500, message: "Internal Server Error" }
39
43
  end
40
44
 
41
- def set_not_implemented
42
- @json = { status_code: 501, message: "Not Implemented" }
43
- end
44
-
45
45
  def finish
46
46
  self.body = [@template.gsub(/{{json}}/, @json.to_json)]
47
47
  self["Content-Type"] = @content_type
@@ -1,14 +1,13 @@
1
1
  module SnapImage
2
2
  class Server
3
- ACTIONS = ["generate_image", "sync_resource", "delete_resource_images", "list_resource_images"]
4
- RESOURCE_ID_REGEXP = /^[a-z0-9_-]+(\/[a-z0-9_-]+)*$/
3
+ DIRECTORY_REGEXP = /^[a-z0-9_-]+(\/[a-z0-9_-]+)*$/
4
+ FILENAME_REGEXP = /^[a-z0-9_-]+[.](gif|jpg|jpeg|png)$/
5
5
 
6
6
  # Arguments:
7
7
  # * request:: Rack::Request
8
8
  def initialize(request, config)
9
9
  @request = request
10
10
  @config = config
11
- @storage = @config.storage
12
11
  end
13
12
 
14
13
  # Handles the request and returns a Rack::Response.
@@ -16,35 +15,32 @@ module SnapImage
16
15
  @response = SnapImage::Response.new
17
16
  begin
18
17
  raise SnapImage::BadRequest if @request.bad_request?
19
- raise SnapImage::InvalidResourceIdentifier unless !!@request.json["resource_identifier"].match(SnapImage::Server::RESOURCE_ID_REGEXP)
20
- @response.content_type = @request.json["response_content_type"] if @request.json["response_content_type"]
21
- @response.template = @request.json["response_template"] if @request.json["response_template"]
22
- action = @request.json["action"]
23
- raise SnapImage::ActionNotImplemented unless ACTIONS.include?(action)
24
- @response = get_action_class(action).new(@config, @request, @response).call
18
+ raise SnapImage::InvalidFilename unless @request.file.filename =~ SnapImage::Server::FILENAME_REGEXP
19
+ raise SnapImage::InvalidDirectory unless @request["directory"] =~ SnapImage::Server::DIRECTORY_REGEXP
20
+ raise SnapImage::FileTooLarge if @request.file.tempfile.size > @config["max_file_size"]
21
+ directory = File.join(@config["directory"], @request["directory"])
22
+ file_path = File.join(directory, @request.file.filename)
23
+ # Make sure the directory exists.
24
+ FileUtils.mkdir_p(directory)
25
+ # Save the file.
26
+ File.open(file_path, "wb") { |f| f.write(@request.file.tempfile.read) } unless File.exists?(file_path)
27
+ @response.set_success
25
28
  rescue SnapImage::BadRequest
26
29
  @response.set_bad_request
27
- rescue SnapImage::ActionNotImplemented
28
- @response.set_not_implemented
29
- rescue SnapImage::AuthorizationRequired
30
- @response.set_authorization_required
31
- rescue SnapImage::AuthorizationFailed
32
- @response.set_authorization_failed
33
- rescue SnapImage::InvalidImageIdentifier
34
- @response.set_invalid_image_identifier
35
- rescue SnapImage::InvalidResourceIdentifier
36
- @response.set_invalid_resource_identifier
37
- #rescue
38
- #@response.set_internal_server_error
30
+ #rescue SnapImage::AuthorizationRequired
31
+ #@response.set_authorization_required
32
+ #rescue SnapImage::AuthorizationFailed
33
+ #@response.set_authorization_failed
34
+ rescue SnapImage::InvalidFilename
35
+ @response.set_invalid_filename
36
+ rescue SnapImage::InvalidDirectory
37
+ @response.set_invalid_directory
38
+ rescue SnapImage::FileTooLarge
39
+ @response.set_file_too_large
40
+ rescue
41
+ @response.set_internal_server_error
39
42
  end
40
43
  @response.finish
41
44
  end
42
-
43
- private
44
-
45
- def get_action_class(action)
46
- klassname = action.split("_").map { |t| t.capitalize }.join("")
47
- SnapImage::ServerActions.const_get(klassname)
48
- end
49
45
  end
50
46
  end
@@ -1,3 +1,3 @@
1
1
  module SnapImage
2
- VERSION = "0.0.6"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -1,166 +1,166 @@
1
- require "spec_helper"
2
- require "rack/test"
3
-
4
- describe "Delete Resource Images" do
5
- include Rack::Test::Methods
6
-
7
- before do
8
- @local_root = File.join(RSpec.root, "storage")
9
- @image_path = File.join(RSpec.root, "support/assets/stub-300x200.png")
10
- @resource_id_1 = "abc/123"
11
- @resource_id_2 = "abc/456"
12
- end
13
-
14
- after do
15
- FileUtils.rm_rf(@local_root)
16
- end
17
-
18
- context "without security tokens" do
19
- def app
20
- app = Proc.new do |env|
21
- [200, {}, ""]
22
- end
23
- SnapImage::Middleware.new(
24
- app,
25
- path: "/snapimage_api",
26
- config: {
27
- "primary_storage_server" => "local",
28
- "storage_servers" => [
29
- {
30
- "name" => "local",
31
- "type" => "LOCAL",
32
- "local_root" => File.join(RSpec.root, "storage"),
33
- "public_url" => "//example.com/images"
34
- }
35
- ]
36
- }
37
- )
38
- end
39
-
40
- before do
41
- # Store some images.
42
- json = { action: "generate_image", resource_identifier: @resource_id_1 }.to_json
43
- post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
44
- @url_1 = JSON.parse(last_response.body)["image_url"]
45
- post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
46
- @url_2 = JSON.parse(last_response.body)["image_url"]
47
-
48
- json = { action: "generate_image", resource_identifier: @resource_id_2 }.to_json
49
- post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
50
- @url_3 = JSON.parse(last_response.body)["image_url"]
51
- post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
52
- @url_4 = JSON.parse(last_response.body)["image_url"]
53
-
54
- json = {
55
- action: "delete_resource_images",
56
- resource_identifier: @resource_id_1
57
- }.to_json
58
- post "/snapimage_api", "json" => json
59
- end
60
-
61
- it "is successful" do
62
- last_response.should be_successful
63
- last_response["Content-Type"].should eq "text/json"
64
- json = JSON.parse(last_response.body)
65
- json["status_code"].should eq 200
66
- json["message"].should eq "Delete Resource Images Successful"
67
- json["deleted_image_urls"].size.should eq 2
68
- json["deleted_image_urls"].include?(@url_1).should be_true
69
- json["deleted_image_urls"].include?(@url_2).should be_true
70
- end
71
-
72
- it "deletes the resource" do
73
- File.exists?(File.join(@local_root, @resource_id_1)).should be_false
74
- end
75
-
76
- it "does not delete other resources" do
77
- File.exists?(File.join(@local_root, @resource_id_2)).should be_true
78
- end
79
- end
80
-
81
- context "with security tokens" do
82
- def app
83
- app = Proc.new do |env|
84
- [200, {}, ""]
85
- end
86
- SnapImage::Middleware.new(
87
- app,
88
- path: "/snapimage_api",
89
- config: {
90
- "security_salt" => "123456789",
91
- "primary_storage_server" => "local",
92
- "storage_servers" => [
93
- {
94
- "name" => "local",
95
- "type" => "LOCAL",
96
- "local_root" => File.join(RSpec.root, "storage"),
97
- "public_url" => "//example.com/images"
98
- }
99
- ]
100
- }
101
- )
102
- end
103
-
104
- before do
105
- @client_security_token_1 = Digest::SHA1.hexdigest("client:#{Time.now.strftime("%Y-%m-%d")}:123456789:#{@resource_id_1}")
106
- @client_security_token_2 = Digest::SHA2.hexdigest("client:#{Time.now.strftime("%Y-%m-%d")}:223456789:#{@resource_id_2}")
107
- @server_security_token = Digest::SHA1.hexdigest("server:#{Time.now.strftime("%Y-%m-%d")}:123456789:#{@resource_id_1}")
108
-
109
- # Store some images.
110
- json = {
111
- action: "generate_image",
112
- resource_identifier: @resource_id_1,
113
- client_security_token: @client_security_token_1
114
- }.to_json
115
- post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
116
- @url_1 = JSON.parse(last_response.body)["image_url"]
117
- post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
118
- @url_2 = JSON.parse(last_response.body)["image_url"]
119
-
120
- json = {
121
- action: "generate_image",
122
- resource_identifier: @resource_id_2,
123
- client_security_token: @client_security_token_2
124
- }.to_json
125
- post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
126
- @url_3 = JSON.parse(last_response.body)["image_url"]
127
- post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
128
- @url_4 = JSON.parse(last_response.body)["image_url"]
129
-
130
- @options = { action: "delete_resource_images", resource_identifier: @resource_id_1 }
131
- end
132
-
133
- it "requires authorization when no security token is provided" do
134
- request_json = @options.to_json
135
- post "/snapimage_api", "json" => request_json
136
- last_response.should be_successful
137
- last_response["content-type"].should eq "text/json"
138
- json = JSON.parse(last_response.body)
139
- json["status_code"].should eq 401
140
- json["message"].should eq "Authorization Required"
141
- end
142
-
143
- it "fails authorization when the security token is invalid" do
144
- request_json = @options.merge!({"server_security_token" => "abc"}).to_json
145
- post "/snapimage_api", "json" => request_json
146
- last_response.should be_successful
147
- last_response["content-type"].should eq "text/json"
148
- json = JSON.parse(last_response.body)
149
- json["status_code"].should eq 402
150
- json["message"].should eq "Authorization Failed"
151
- end
152
-
153
- it "deletes successfully" do
154
- request_json = @options.merge!({"server_security_token" => @server_security_token}).to_json
155
- post "/snapimage_api", "json" => request_json
156
- last_response.should be_successful
157
- last_response["Content-Type"].should eq "text/json"
158
- json = JSON.parse(last_response.body)
159
- json["status_code"].should eq 200
160
- json["message"].should eq "Delete Resource Images Successful"
161
- json["deleted_image_urls"].size.should eq 2
162
- json["deleted_image_urls"].include?(@url_1).should be_true
163
- json["deleted_image_urls"].include?(@url_2).should be_true
164
- end
165
- end
166
- end
1
+ #require "spec_helper"
2
+ #require "rack/test"
3
+
4
+ #describe "Delete Resource Images" do
5
+ #include Rack::Test::Methods
6
+
7
+ #before do
8
+ #@local_root = File.join(RSpec.root, "storage")
9
+ #@image_path = File.join(RSpec.root, "support/assets/stub-300x200.png")
10
+ #@resource_id_1 = "abc/123"
11
+ #@resource_id_2 = "abc/456"
12
+ #end
13
+
14
+ #after do
15
+ #FileUtils.rm_rf(@local_root)
16
+ #end
17
+
18
+ #context "without security tokens" do
19
+ #def app
20
+ #app = Proc.new do |env|
21
+ #[200, {}, ""]
22
+ #end
23
+ #SnapImage::Middleware.new(
24
+ #app,
25
+ #path: "/snapimage_api",
26
+ #config: {
27
+ #"primary_storage_server" => "local",
28
+ #"storage_servers" => [
29
+ #{
30
+ #"name" => "local",
31
+ #"type" => "LOCAL",
32
+ #"local_root" => File.join(RSpec.root, "storage"),
33
+ #"public_url" => "//example.com/images"
34
+ #}
35
+ #]
36
+ #}
37
+ #)
38
+ #end
39
+
40
+ #before do
41
+ ## Store some images.
42
+ #json = { action: "generate_image", resource_identifier: @resource_id_1 }.to_json
43
+ #post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
44
+ #@url_1 = JSON.parse(last_response.body)["image_url"]
45
+ #post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
46
+ #@url_2 = JSON.parse(last_response.body)["image_url"]
47
+
48
+ #json = { action: "generate_image", resource_identifier: @resource_id_2 }.to_json
49
+ #post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
50
+ #@url_3 = JSON.parse(last_response.body)["image_url"]
51
+ #post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
52
+ #@url_4 = JSON.parse(last_response.body)["image_url"]
53
+
54
+ #json = {
55
+ #action: "delete_resource_images",
56
+ #resource_identifier: @resource_id_1
57
+ #}.to_json
58
+ #post "/snapimage_api", "json" => json
59
+ #end
60
+
61
+ #it "is successful" do
62
+ #last_response.should be_successful
63
+ #last_response["Content-Type"].should eq "text/json"
64
+ #json = JSON.parse(last_response.body)
65
+ #json["status_code"].should eq 200
66
+ #json["message"].should eq "Delete Resource Images Successful"
67
+ #json["deleted_image_urls"].size.should eq 2
68
+ #json["deleted_image_urls"].include?(@url_1).should be_true
69
+ #json["deleted_image_urls"].include?(@url_2).should be_true
70
+ #end
71
+
72
+ #it "deletes the resource" do
73
+ #File.exists?(File.join(@local_root, @resource_id_1)).should be_false
74
+ #end
75
+
76
+ #it "does not delete other resources" do
77
+ #File.exists?(File.join(@local_root, @resource_id_2)).should be_true
78
+ #end
79
+ #end
80
+
81
+ #context "with security tokens" do
82
+ #def app
83
+ #app = Proc.new do |env|
84
+ #[200, {}, ""]
85
+ #end
86
+ #SnapImage::Middleware.new(
87
+ #app,
88
+ #path: "/snapimage_api",
89
+ #config: {
90
+ #"security_salt" => "123456789",
91
+ #"primary_storage_server" => "local",
92
+ #"storage_servers" => [
93
+ #{
94
+ #"name" => "local",
95
+ #"type" => "LOCAL",
96
+ #"local_root" => File.join(RSpec.root, "storage"),
97
+ #"public_url" => "//example.com/images"
98
+ #}
99
+ #]
100
+ #}
101
+ #)
102
+ #end
103
+
104
+ #before do
105
+ #@client_security_token_1 = Digest::SHA1.hexdigest("client:#{Time.now.strftime("%Y-%m-%d")}:123456789:#{@resource_id_1}")
106
+ #@client_security_token_2 = Digest::SHA2.hexdigest("client:#{Time.now.strftime("%Y-%m-%d")}:223456789:#{@resource_id_2}")
107
+ #@server_security_token = Digest::SHA1.hexdigest("server:#{Time.now.strftime("%Y-%m-%d")}:123456789:#{@resource_id_1}")
108
+
109
+ ## Store some images.
110
+ #json = {
111
+ #action: "generate_image",
112
+ #resource_identifier: @resource_id_1,
113
+ #client_security_token: @client_security_token_1
114
+ #}.to_json
115
+ #post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
116
+ #@url_1 = JSON.parse(last_response.body)["image_url"]
117
+ #post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
118
+ #@url_2 = JSON.parse(last_response.body)["image_url"]
119
+
120
+ #json = {
121
+ #action: "generate_image",
122
+ #resource_identifier: @resource_id_2,
123
+ #client_security_token: @client_security_token_2
124
+ #}.to_json
125
+ #post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
126
+ #@url_3 = JSON.parse(last_response.body)["image_url"]
127
+ #post "/snapimage_api", "file" => Rack::Test::UploadedFile.new(@image_path, "image/png"), "json" => json
128
+ #@url_4 = JSON.parse(last_response.body)["image_url"]
129
+
130
+ #@options = { action: "delete_resource_images", resource_identifier: @resource_id_1 }
131
+ #end
132
+
133
+ #it "requires authorization when no security token is provided" do
134
+ #request_json = @options.to_json
135
+ #post "/snapimage_api", "json" => request_json
136
+ #last_response.should be_successful
137
+ #last_response["content-type"].should eq "text/json"
138
+ #json = JSON.parse(last_response.body)
139
+ #json["status_code"].should eq 401
140
+ #json["message"].should eq "Authorization Required"
141
+ #end
142
+
143
+ #it "fails authorization when the security token is invalid" do
144
+ #request_json = @options.merge!({"server_security_token" => "abc"}).to_json
145
+ #post "/snapimage_api", "json" => request_json
146
+ #last_response.should be_successful
147
+ #last_response["content-type"].should eq "text/json"
148
+ #json = JSON.parse(last_response.body)
149
+ #json["status_code"].should eq 402
150
+ #json["message"].should eq "Authorization Failed"
151
+ #end
152
+
153
+ #it "deletes successfully" do
154
+ #request_json = @options.merge!({"server_security_token" => @server_security_token}).to_json
155
+ #post "/snapimage_api", "json" => request_json
156
+ #last_response.should be_successful
157
+ #last_response["Content-Type"].should eq "text/json"
158
+ #json = JSON.parse(last_response.body)
159
+ #json["status_code"].should eq 200
160
+ #json["message"].should eq "Delete Resource Images Successful"
161
+ #json["deleted_image_urls"].size.should eq 2
162
+ #json["deleted_image_urls"].include?(@url_1).should be_true
163
+ #json["deleted_image_urls"].include?(@url_2).should be_true
164
+ #end
165
+ #end
166
+ #end