responders 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/CHANGELOG.rdoc +5 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +44 -0
- data/Rakefile +44 -0
- data/lib/generators/USAGE +11 -0
- data/lib/generators/responders_controller_generator.rb +15 -0
- data/lib/generators/responders_install_generator.rb +14 -0
- data/lib/generators/templates/controller.rb +53 -0
- data/lib/responders.rb +4 -0
- data/lib/responders/flash_responder.rb +102 -0
- data/lib/responders/http_cache_responder.rb +33 -0
- data/lib/responders/version.rb +3 -0
- data/test/flash_responder_test.rb +116 -0
- data/test/http_cache_responder_test.rb +104 -0
- data/test/test_helper.rb +49 -0
- metadata +68 -0
data/CHANGELOG.rdoc
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2009 Plataforma Tecnologia. http://blog.plataformatec.com.br
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
== Responders
|
2
|
+
|
3
|
+
A set of responders to dry up your Rails 3 app:
|
4
|
+
|
5
|
+
* FlashResponder - Sets the flash based on the controller action and resource status.
|
6
|
+
For instance, if you do: respond_with(@post) on a POST request and the resource @post
|
7
|
+
does not contain errors, it will automatically set the flash message to
|
8
|
+
"Post was successfully created" as long as you configure your I18n file:
|
9
|
+
|
10
|
+
flash:
|
11
|
+
actions:
|
12
|
+
create:
|
13
|
+
success: "{resource_name} was successfully created"
|
14
|
+
update:
|
15
|
+
success: "{resource_name} was successfully updated"
|
16
|
+
|
17
|
+
In case the resource contains errors, you should use the failure key on I18n. This is
|
18
|
+
useful to dry up flash messages from your controllers. If you need a specific message
|
19
|
+
for a controller, let's say, for PostsController, you can also do:
|
20
|
+
|
21
|
+
flash:
|
22
|
+
posts:
|
23
|
+
create:
|
24
|
+
success: "Your post was created and will be published soon"
|
25
|
+
|
26
|
+
* HttpCacheResponder - Automatically adds Last-Modified headers to API requests. This
|
27
|
+
allows clients to easily query the server if a resource changed and if the client tries
|
28
|
+
to retrieve a resource that has not been modified, it returns not_modified status.
|
29
|
+
|
30
|
+
== Generator
|
31
|
+
|
32
|
+
This gem also includes a responders controller generator, so your scaffold can be customized to use respond_with instead of default respond_to blocks just by configuring your environment:
|
33
|
+
|
34
|
+
config.generators do |g|
|
35
|
+
g.scaffold_controller = :responders_controller
|
36
|
+
end
|
37
|
+
|
38
|
+
== Bugs and Feedback
|
39
|
+
|
40
|
+
If you discover any bugs or want to drop a line, feel free to create an issue on GitHub.
|
41
|
+
|
42
|
+
http://github.com/plataformatec/responders/issues
|
43
|
+
|
44
|
+
MIT License. Copyright 2009 Plataforma Tecnologia. http://blog.plataformatec.com.br
|
data/Rakefile
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
require File.join(File.dirname(__FILE__), 'lib', 'responders', 'version')
|
7
|
+
|
8
|
+
desc 'Default: run unit tests'
|
9
|
+
task :default => :test
|
10
|
+
|
11
|
+
desc 'Test Responders'
|
12
|
+
Rake::TestTask.new(:test) do |t|
|
13
|
+
t.libs << 'lib'
|
14
|
+
t.libs << 'test'
|
15
|
+
t.pattern = 'test/**/*_test.rb'
|
16
|
+
t.verbose = true
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'Generate documentation for Responders'
|
20
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
21
|
+
rdoc.rdoc_dir = 'rdoc'
|
22
|
+
rdoc.title = 'Responders'
|
23
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
24
|
+
rdoc.rdoc_files.include('README.rdoc')
|
25
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'jeweler'
|
30
|
+
Jeweler::Tasks.new do |s|
|
31
|
+
s.name = "responders"
|
32
|
+
s.version = Responders::VERSION
|
33
|
+
s.summary = "A set of Rails 3 responders to dry up your application"
|
34
|
+
s.email = "contact@plataformatec.com.br"
|
35
|
+
s.homepage = "http://github.com/plataformatec/responders"
|
36
|
+
s.description = "A set of Rails 3 responders to dry up your application"
|
37
|
+
s.authors = ['José Valim']
|
38
|
+
s.files = FileList["[A-Z]*", "lib/**/*", "init.rb"]
|
39
|
+
end
|
40
|
+
|
41
|
+
Jeweler::GemcutterTasks.new
|
42
|
+
rescue LoadError
|
43
|
+
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install jeweler"
|
44
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Description:
|
2
|
+
Stubs out a scaffolded controller and its views. Different from rails
|
3
|
+
scaffold_controller, it uses respond_with instead of respond_to blocks.
|
4
|
+
Pass the model name, either CamelCased or under_scored. The controller
|
5
|
+
name is retrieved as a pluralized version of the model name.
|
6
|
+
|
7
|
+
To create a controller within a module, specify the model name as a
|
8
|
+
path like 'parent_module/controller_name'.
|
9
|
+
|
10
|
+
This generates a controller class in app/controllers and invokes helper,
|
11
|
+
template engine and test framework generators.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
|
2
|
+
|
3
|
+
module Rails
|
4
|
+
module Generators
|
5
|
+
class RespondersControllerGenerator < ScaffoldControllerGenerator
|
6
|
+
def self.source_root
|
7
|
+
@source_root ||= File.expand_path("templates", File.dirname(__FILE__))
|
8
|
+
end
|
9
|
+
protected
|
10
|
+
def flash?
|
11
|
+
!ApplicationController.responder.ancestors.include?(Responders::FlashResponder)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class RespondersInstallGenerator < Rails::Generators::Base
|
2
|
+
desc "Creates an initializer file with default responder configuration"
|
3
|
+
|
4
|
+
def create_responder_initializer
|
5
|
+
create_file "config/initializers/responders.rb", <<-FILE
|
6
|
+
class #{Rails.application.class.name}Responder
|
7
|
+
include FlashResponder
|
8
|
+
include HttpCacheResponder
|
9
|
+
end
|
10
|
+
|
11
|
+
ApplicationController.responder = #{Rails.application.class.name}Responder
|
12
|
+
FILE
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class <%= controller_class_name %>Controller < ApplicationController
|
2
|
+
<% unless options[:singleton] -%>
|
3
|
+
# GET /<%= table_name %>
|
4
|
+
# GET /<%= table_name %>.xml
|
5
|
+
def index
|
6
|
+
@<%= table_name %> = <%= orm_class.all(class_name) %>
|
7
|
+
respond_with(@<%= table_name %>)
|
8
|
+
end
|
9
|
+
<% end -%>
|
10
|
+
|
11
|
+
# GET /<%= table_name %>/1
|
12
|
+
# GET /<%= table_name %>/1.xml
|
13
|
+
def show
|
14
|
+
@<%= file_name %> = <%= orm_class.find(class_name, "params[:id]") %>
|
15
|
+
respond_with(@<%= file_name %>)
|
16
|
+
end
|
17
|
+
|
18
|
+
# GET /<%= table_name %>/new
|
19
|
+
# GET /<%= table_name %>/new.xml
|
20
|
+
def new
|
21
|
+
@<%= file_name %> = <%= orm_class.build(class_name) %>
|
22
|
+
respond_with(@<%= file_name %>)
|
23
|
+
end
|
24
|
+
|
25
|
+
# GET /<%= table_name %>/1/edit
|
26
|
+
def edit
|
27
|
+
@<%= file_name %> = <%= orm_class.find(class_name, "params[:id]") %>
|
28
|
+
end
|
29
|
+
|
30
|
+
# POST /<%= table_name %>
|
31
|
+
# POST /<%= table_name %>.xml
|
32
|
+
def create
|
33
|
+
@<%= file_name %> = <%= orm_class.build(class_name, "params[:#{file_name}]") %>
|
34
|
+
<%= "flash[:notice] = '#{class_name} was successfully created.' if " if flash? %>@<%= orm_instance.save %>
|
35
|
+
respond_with(@<%= file_name %>)
|
36
|
+
end
|
37
|
+
|
38
|
+
# PUT /<%= table_name %>/1
|
39
|
+
# PUT /<%= table_name %>/1.xml
|
40
|
+
def update
|
41
|
+
@<%= file_name %> = <%= orm_class.find(class_name, "params[:id]") %>
|
42
|
+
<%= "flash[:notice] = '#{class_name} was successfully updated.' if " if flash? %>@<%= orm_instance.update_attributes("params[:#{file_name}]") %>
|
43
|
+
respond_with(@<%= file_name %>)
|
44
|
+
end
|
45
|
+
|
46
|
+
# DELETE /<%= table_name %>/1
|
47
|
+
# DELETE /<%= table_name %>/1.xml
|
48
|
+
def destroy
|
49
|
+
@<%= file_name %> = <%= orm_class.find(class_name, "params[:id]") %>
|
50
|
+
@<%= orm_instance.destroy %>
|
51
|
+
respond_with(@<%= file_name %>)
|
52
|
+
end
|
53
|
+
end
|
data/lib/responders.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
module Responders
|
2
|
+
# Responder to automatically set flash messages based on I18n API. It checks for
|
3
|
+
# message based on the current action, but also allows defaults to be set, using
|
4
|
+
# the following order:
|
5
|
+
#
|
6
|
+
# flash.controller_name.action_name.status
|
7
|
+
# flash.actions.action_name.status
|
8
|
+
#
|
9
|
+
# So, if you have a CarsController, create action, it will check for:
|
10
|
+
#
|
11
|
+
# flash.cars.create.status
|
12
|
+
# flash.actions.create.status
|
13
|
+
#
|
14
|
+
# The statuses can be :success (when the object can be created, updated
|
15
|
+
# or destroyed with success) or :failure (when the objecy cannot be created
|
16
|
+
# or updated).
|
17
|
+
#
|
18
|
+
# The resource_name given is available as interpolation option, this means you can set:
|
19
|
+
#
|
20
|
+
# flash:
|
21
|
+
# actions:
|
22
|
+
# create:
|
23
|
+
# success: "Hooray! {{resource_name}} was successfully created!"
|
24
|
+
#
|
25
|
+
# But sometimes, flash messages are not that simple. Going back
|
26
|
+
# to cars example, you might want to say the brand of the car when it's
|
27
|
+
# updated. Well, that's easy also:
|
28
|
+
#
|
29
|
+
# flash:
|
30
|
+
# cars:
|
31
|
+
# update:
|
32
|
+
# success: "Hooray! You just tuned your {{car_brand}}!"
|
33
|
+
#
|
34
|
+
# Since :car_name is not available for interpolation by default, you have
|
35
|
+
# to overwrite interpolation_options in your controller.
|
36
|
+
#
|
37
|
+
# def interpolation_options
|
38
|
+
# { :car_brand => @car.brand }
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# Then you will finally have:
|
42
|
+
#
|
43
|
+
# 'Hooray! You just tuned your Aston Martin!'
|
44
|
+
#
|
45
|
+
# If your controller is namespaced, for example Admin::CarsController,
|
46
|
+
# the messages will be checked in the following order:
|
47
|
+
#
|
48
|
+
# flash.admin.cars.create.status
|
49
|
+
# flash.admin.actions.create.status
|
50
|
+
# flash.cars.create.status
|
51
|
+
# flash.actions.create.status
|
52
|
+
#
|
53
|
+
module FlashResponder
|
54
|
+
def initialize(controller, resources, options={})
|
55
|
+
super
|
56
|
+
@flash = options.delete(:flash)
|
57
|
+
end
|
58
|
+
|
59
|
+
def navigation_behavior(error)
|
60
|
+
super
|
61
|
+
|
62
|
+
unless get? || @flash == false
|
63
|
+
status = has_errors? ? :failure : :success
|
64
|
+
return if controller.send(:flash)[status].present?
|
65
|
+
|
66
|
+
resource_name = if resource.class.respond_to?(:human_name)
|
67
|
+
resource.class.human_name
|
68
|
+
else
|
69
|
+
resource.class.name.underscore.humanize
|
70
|
+
end
|
71
|
+
|
72
|
+
options = {
|
73
|
+
:default => flash_defaults_by_namespace(status),
|
74
|
+
:resource_name => resource_name,
|
75
|
+
:resource_sym => resource_name.downcase
|
76
|
+
}
|
77
|
+
|
78
|
+
if controller.respond_to?(:interpolation_options, true)
|
79
|
+
options.merge!(controller.send(:interpolation_options))
|
80
|
+
end
|
81
|
+
|
82
|
+
message = ::I18n.t options[:default].shift, options
|
83
|
+
controller.send(:flash)[status] = message unless message.blank?
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
protected
|
88
|
+
|
89
|
+
def flash_defaults_by_namespace(status)
|
90
|
+
defaults = []
|
91
|
+
slices = controller.controller_path.split('/')
|
92
|
+
|
93
|
+
while slices.size > 0
|
94
|
+
defaults << :"flash.#{slices.fill(controller.controller_name, -1).join('.')}.#{controller.action_name}.#{status}"
|
95
|
+
defaults << :"flash.#{slices.fill(:actions, -1).join('.')}.#{controller.action_name}.#{status}"
|
96
|
+
slices.shift
|
97
|
+
end
|
98
|
+
|
99
|
+
defaults << ""
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Responders
|
2
|
+
# Set HTTP Last-Modified headers based on the given resource. It's used only
|
3
|
+
# on API behavior (to_format) and is useful for a client to check in the server
|
4
|
+
# if a resource changed after a specific date or not.
|
5
|
+
#
|
6
|
+
# This is not usually not used in html requests because pages contains a lot
|
7
|
+
# information besides the resource information, as current_user, flash messages,
|
8
|
+
# widgets... that are better handled with other strategies, as fragment caches and
|
9
|
+
# the digest of the body.
|
10
|
+
#
|
11
|
+
module HttpCacheResponder
|
12
|
+
def initialize(controller, resources, options={})
|
13
|
+
super
|
14
|
+
@http_cache = options.delete(:http_cache)
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_format
|
18
|
+
if get? && @http_cache != false && controller.response.last_modified.nil?
|
19
|
+
timestamp = resources.flatten.map do |resource|
|
20
|
+
resource.updated_at.utc if resource.respond_to?(:updated_at)
|
21
|
+
end.compact.max
|
22
|
+
|
23
|
+
controller.response.last_modified = timestamp if timestamp
|
24
|
+
if request.fresh?(controller.response)
|
25
|
+
head :not_modified
|
26
|
+
return
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class Address
|
4
|
+
attr_accessor :errors
|
5
|
+
def self.human_name; 'Address'; end
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@errors = {}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class FlashResponder < ActionController::Responder
|
13
|
+
include Responders::FlashResponder
|
14
|
+
end
|
15
|
+
|
16
|
+
class AddressesController < ApplicationController
|
17
|
+
before_filter :set_resource
|
18
|
+
self.responder = FlashResponder
|
19
|
+
|
20
|
+
def action
|
21
|
+
options = params.slice(:flash)
|
22
|
+
flash[:success] = "Flash is set" if params[:set_flash]
|
23
|
+
respond_with(@resource, options)
|
24
|
+
end
|
25
|
+
alias :new :action
|
26
|
+
alias :create :action
|
27
|
+
alias :update :action
|
28
|
+
alias :destroy :action
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def interpolation_options
|
33
|
+
{ :reference => 'Ocean Avenue' }
|
34
|
+
end
|
35
|
+
|
36
|
+
def set_resource
|
37
|
+
@resource = Address.new
|
38
|
+
@resource.errors[:fail] = true if params[:fail]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module Admin
|
43
|
+
class AddressesController < ::AddressesController
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class FlashResponderTest < ActionController::TestCase
|
48
|
+
tests AddressesController
|
49
|
+
|
50
|
+
def setup
|
51
|
+
@controller.stubs(:polymorphic_url).returns("/")
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_sets_success_flash_message_on_non_get_requests
|
55
|
+
post :create
|
56
|
+
assert_equal "Resource created with success", flash[:success]
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_sets_failure_flash_message_on_not_get_requests
|
60
|
+
post :create, :fail => true
|
61
|
+
assert_equal "Resource could not be created", flash[:failure]
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_does_not_set_flash_message_on_get_requests
|
65
|
+
get :new
|
66
|
+
assert flash.empty?
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_sets_flash_message_for_the_current_controller
|
70
|
+
put :update, :fail => true
|
71
|
+
assert_equal "Oh no! We could not update your address!", flash[:failure]
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_sets_flash_message_with_resource_name
|
75
|
+
put :update
|
76
|
+
assert_equal "Nice! Address was updated with success!", flash[:success]
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_sets_flash_message_with_interpolation_options
|
80
|
+
delete :destroy
|
81
|
+
assert_equal "Successfully deleted the address at Ocean Avenue", flash[:success]
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_does_not_set_flash_if_flash_false_is_given
|
85
|
+
post :create, :flash => false
|
86
|
+
assert flash.empty?
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_does_not_overwrite_the_flash_if_already_set
|
90
|
+
post :create, :set_flash => true
|
91
|
+
assert_equal "Flash is set", flash[:success]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class NamespacedFlashResponderTest < ActionController::TestCase
|
96
|
+
tests Admin::AddressesController
|
97
|
+
|
98
|
+
def setup
|
99
|
+
@controller.stubs(:polymorphic_url).returns("/")
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_sets_the_flash_message_based_on_the_current_controller
|
103
|
+
put :update
|
104
|
+
assert_equal "Admin updated address with success", flash[:success]
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_sets_the_flash_message_based_on_namespace_actions
|
108
|
+
post :create
|
109
|
+
assert_equal "Admin created address with success", flash[:success]
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_fallbacks_to_non_namespaced_controller_flash_message
|
113
|
+
delete :destroy
|
114
|
+
assert_equal "Successfully deleted the address at Ocean Avenue", flash[:success]
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class HttpCacheResponder < ActionController::Responder
|
4
|
+
include Responders::HttpCacheResponder
|
5
|
+
end
|
6
|
+
|
7
|
+
class HttpCacheController < ApplicationController
|
8
|
+
self.responder = HttpCacheResponder
|
9
|
+
|
10
|
+
def single
|
11
|
+
options = params.slice(:http_cache)
|
12
|
+
response.last_modified = Time.utc(2008) if params[:last_modified]
|
13
|
+
respond_with(Model.new(Time.utc(2009)), options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def collection
|
17
|
+
respond_with [Model.new(Time.utc(2009)), Model.new(Time.utc(2008))]
|
18
|
+
end
|
19
|
+
|
20
|
+
def empty
|
21
|
+
respond_with []
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class HttpCacheResponderTest < ActionController::TestCase
|
26
|
+
tests HttpCacheController
|
27
|
+
|
28
|
+
def setup
|
29
|
+
@request.accept = "application/xml"
|
30
|
+
@controller.stubs(:polymorphic_url).returns("/")
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_last_modified_at_is_set_with_single_resource_on_get
|
34
|
+
get :single
|
35
|
+
assert_equal Time.utc(2009).httpdate, @response.headers["Last-Modified"]
|
36
|
+
assert_equal "<xml />", @response.body
|
37
|
+
assert_equal 200, @response.status
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_returns_not_modified_if_return_is_cache_is_still_valid
|
41
|
+
@request.env["HTTP_IF_MODIFIED_SINCE"] = Time.utc(2009, 6).httpdate
|
42
|
+
get :single
|
43
|
+
assert_equal 304, @response.status
|
44
|
+
assert_equal " ", @response.body
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_refreshes_last_modified_if_cache_is_expired
|
48
|
+
@request.env["HTTP_IF_MODIFIED_SINCE"] = Time.utc(2008, 6).httpdate
|
49
|
+
get :single
|
50
|
+
assert_equal Time.utc(2009).httpdate, @response.headers["Last-Modified"]
|
51
|
+
assert_equal "<xml />", @response.body
|
52
|
+
assert_equal 200, @response.status
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_does_not_set_cache_unless_get_requests
|
56
|
+
put :single
|
57
|
+
assert_nil @response.headers["Last-Modified"]
|
58
|
+
assert_equal 200, @response.status
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_does_not_use_cache_unless_get_requests
|
62
|
+
@request.env["HTTP_IF_MODIFIED_SINCE"] = Time.utc(2009, 6).httpdate
|
63
|
+
put :single
|
64
|
+
assert_equal 200, @response.status
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_does_not_set_cache_if_http_cache_is_false
|
68
|
+
get :single, :http_cache => false
|
69
|
+
assert_nil @response.headers["Last-Modified"]
|
70
|
+
assert_equal 200, @response.status
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_does_not_use_cache_if_http_cache_is_false
|
74
|
+
@request.env["HTTP_IF_MODIFIED_SINCE"] = Time.utc(2009, 6).httpdate
|
75
|
+
get :single, :http_cache => false
|
76
|
+
assert_equal 200, @response.status
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_does_not_set_cache_if_last_modified_already_set_in_response
|
80
|
+
get :single, :last_modified => true
|
81
|
+
assert_equal Time.utc(2008).httpdate, @response.headers["Last-Modified"]
|
82
|
+
assert_equal 200, @response.status
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_does_not_use_cache_if_last_modified_already_set_in_response
|
86
|
+
@request.env["HTTP_IF_MODIFIED_SINCE"] = Time.utc(2009, 6).httpdate
|
87
|
+
get :single, :last_modified => true
|
88
|
+
assert_equal 200, @response.status
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_collection_chooses_the_latest_timestamp
|
92
|
+
get :collection
|
93
|
+
assert_equal Time.utc(2009).httpdate, @response.headers["Last-Modified"]
|
94
|
+
assert_match /xml/, @response.body
|
95
|
+
assert_equal 200, @response.status
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_work_with_an_empty_array
|
99
|
+
get :empty
|
100
|
+
assert_nil @response.headers["Last-Modified"]
|
101
|
+
assert_match /xml/, @response.body
|
102
|
+
assert_equal 200, @response.status
|
103
|
+
end
|
104
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
begin
|
4
|
+
gem "test-unit"
|
5
|
+
rescue LoadError
|
6
|
+
end
|
7
|
+
|
8
|
+
begin
|
9
|
+
gem "ruby-debug"
|
10
|
+
require 'ruby-debug'
|
11
|
+
rescue LoadError
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'test/unit'
|
15
|
+
require 'mocha'
|
16
|
+
|
17
|
+
# Configure Rails
|
18
|
+
ENV["RAILS_ENV"] = "test"
|
19
|
+
RAILS_ROOT = "anywhere"
|
20
|
+
|
21
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../../rails/vendor/gems/environment")
|
22
|
+
require 'active_support'
|
23
|
+
require 'action_controller'
|
24
|
+
require 'action_controller/testing/test_case'
|
25
|
+
|
26
|
+
class ApplicationController < ActionController::Base
|
27
|
+
respond_to :html, :xml
|
28
|
+
end
|
29
|
+
|
30
|
+
# Add IR to load path and load the main file
|
31
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
32
|
+
require 'responders'
|
33
|
+
|
34
|
+
I18n.load_path << File.join(File.dirname(__FILE__), 'locales', 'en.yml')
|
35
|
+
I18n.reload!
|
36
|
+
|
37
|
+
ActionController::Base.view_paths = File.join(File.dirname(__FILE__), 'views')
|
38
|
+
|
39
|
+
ActionController::Routing::Routes.draw do |map|
|
40
|
+
map.connect 'admin/:action', :controller => "admin/addresses"
|
41
|
+
map.connect ':controller/:action/:id'
|
42
|
+
map.connect ':controller/:action'
|
43
|
+
end
|
44
|
+
|
45
|
+
class Model < Struct.new(:updated_at)
|
46
|
+
def to_xml(*args)
|
47
|
+
"<xml />"
|
48
|
+
end
|
49
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: responders
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.1"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "Jos\xC3\xA9 Valim"
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-04 00:00:00 -02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A set of Rails 3 responders to dry up your application
|
17
|
+
email: contact@plataformatec.com.br
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- CHANGELOG.rdoc
|
26
|
+
- MIT-LICENSE
|
27
|
+
- README.rdoc
|
28
|
+
- Rakefile
|
29
|
+
- lib/generators/USAGE
|
30
|
+
- lib/generators/responders_controller_generator.rb
|
31
|
+
- lib/generators/responders_install_generator.rb
|
32
|
+
- lib/generators/templates/controller.rb
|
33
|
+
- lib/responders.rb
|
34
|
+
- lib/responders/flash_responder.rb
|
35
|
+
- lib/responders/http_cache_responder.rb
|
36
|
+
- lib/responders/version.rb
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://github.com/plataformatec/responders
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --charset=UTF-8
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.3.5
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: A set of Rails 3 responders to dry up your application
|
65
|
+
test_files:
|
66
|
+
- test/flash_responder_test.rb
|
67
|
+
- test/http_cache_responder_test.rb
|
68
|
+
- test/test_helper.rb
|