acts_as_api 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +10 -0
- data/Gemfile +12 -0
- data/History.txt +8 -0
- data/README.rdoc +29 -225
- data/Rakefile +20 -28
- data/acts_as_api.gemspec +31 -0
- data/examples/introduction/docco.css +186 -0
- data/examples/introduction/index.html +340 -0
- data/examples/introduction/index.rb +132 -0
- data/examples/introduction/layout.mustache +64 -0
- data/lib/acts_as_api.rb +11 -25
- data/lib/acts_as_api/api_template.rb +14 -0
- data/lib/acts_as_api/base.rb +61 -56
- data/lib/acts_as_api/config.rb +34 -0
- data/lib/acts_as_api/rails_renderer.rb +15 -0
- data/lib/acts_as_api/rendering.rb +11 -8
- data/lib/acts_as_api/version.rb +4 -0
- data/spec/controllers/respond_with_users_controller_spec.rb +5 -0
- data/spec/controllers/users_controller_spec.rb +161 -0
- data/spec/models/base_spec.rb +437 -0
- data/spec/rails_app/.gitignore +4 -0
- data/spec/rails_app/Rakefile +7 -0
- data/spec/rails_app/app/controllers/application_controller.rb +3 -0
- data/spec/rails_app/app/controllers/respond_with_users_controller.rb +15 -0
- data/spec/rails_app/app/controllers/users_controller.rb +21 -0
- data/spec/rails_app/app/helpers/application_helper.rb +2 -0
- data/spec/rails_app/app/models/task.rb +3 -0
- data/spec/rails_app/app/models/untouched.rb +2 -0
- data/spec/rails_app/app/models/user.rb +69 -0
- data/spec/rails_app/app/views/layouts/application.html.erb +14 -0
- data/spec/rails_app/config.ru +4 -0
- data/spec/rails_app/config/application.rb +42 -0
- data/spec/rails_app/config/boot.rb +6 -0
- data/spec/rails_app/config/database.yml +23 -0
- data/spec/rails_app/config/environment.rb +5 -0
- data/spec/rails_app/config/environments/development.rb +26 -0
- data/spec/rails_app/config/environments/production.rb +49 -0
- data/spec/rails_app/config/environments/test.rb +35 -0
- data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails_app/config/initializers/inflections.rb +10 -0
- data/spec/rails_app/config/initializers/mime_types.rb +5 -0
- data/spec/rails_app/config/initializers/secret_token.rb +7 -0
- data/spec/rails_app/config/initializers/session_store.rb +8 -0
- data/spec/rails_app/config/locales/en.yml +5 -0
- data/spec/rails_app/config/routes.rb +7 -0
- data/spec/rails_app/db/migrate/20110214201640_create_tables.rb +35 -0
- data/spec/rails_app/db/schema.rb +34 -0
- data/spec/rails_app/db/seeds.rb +7 -0
- data/spec/rails_app/lib/tasks/.gitkeep +0 -0
- data/spec/rails_app/public/404.html +26 -0
- data/spec/rails_app/public/422.html +26 -0
- data/spec/rails_app/public/500.html +26 -0
- data/spec/rails_app/public/favicon.ico +0 -0
- data/spec/rails_app/public/images/rails.png +0 -0
- data/spec/rails_app/public/index.html +239 -0
- data/spec/rails_app/public/javascripts/application.js +2 -0
- data/spec/rails_app/public/javascripts/controls.js +965 -0
- data/spec/rails_app/public/javascripts/dragdrop.js +974 -0
- data/spec/rails_app/public/javascripts/effects.js +1123 -0
- data/spec/rails_app/public/javascripts/prototype.js +6001 -0
- data/spec/rails_app/public/javascripts/rails.js +191 -0
- data/spec/rails_app/public/robots.txt +5 -0
- data/spec/rails_app/public/stylesheets/.gitkeep +0 -0
- data/spec/rails_app/script/rails +6 -0
- data/spec/spec_helper.rb +12 -13
- data/spec/support/api_test_helpers.rb +23 -0
- metadata +137 -35
- data/Manifest.txt +0 -15
- data/script/console +0 -10
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/spec/acts_as_api_spec.rb +0 -87
- data/tasks/rspec.rake +0 -21
@@ -0,0 +1,64 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
5
|
+
<title>acts_as_api</title>
|
6
|
+
<link rel="stylesheet" href="./docco.css">
|
7
|
+
<link href="http://fonts.googleapis.com/css?family=Copse:regular" rel="stylesheet" type="text/css" >
|
8
|
+
<style>
|
9
|
+
h1, h2, h3, h4, h5 {
|
10
|
+
font-family: 'Copse', serif;
|
11
|
+
font-style: normal;
|
12
|
+
font-weight: 700;
|
13
|
+
text-shadow: none;
|
14
|
+
text-decoration: none;
|
15
|
+
text-transform: none;
|
16
|
+
letter-spacing: 0em;
|
17
|
+
word-spacing: 0em;
|
18
|
+
line-height: 1.2;
|
19
|
+
}
|
20
|
+
</style>
|
21
|
+
</head>
|
22
|
+
<body>
|
23
|
+
<div id='container'>
|
24
|
+
<div id="background"></div>
|
25
|
+
{{#sources?}}
|
26
|
+
<div id="jump_to">
|
27
|
+
Jump To …
|
28
|
+
<div id="jump_wrapper">
|
29
|
+
<div id="jump_page">
|
30
|
+
{{#sources}}
|
31
|
+
<a class="source" href="{{ url }}">{{ basename }}</a>
|
32
|
+
{{/sources}}
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
{{/sources?}}
|
37
|
+
<table cellspacing=0 cellpadding=0>
|
38
|
+
<thead>
|
39
|
+
<tr>
|
40
|
+
<th class=docs>
|
41
|
+
<h1>acts_as_api</h1>
|
42
|
+
<p>Makes creating XML/JSON responses in Rails 3 easy and fun.</p>
|
43
|
+
</th>
|
44
|
+
<th class=code></th>
|
45
|
+
</tr>
|
46
|
+
</thead>
|
47
|
+
<tbody>
|
48
|
+
{{#sections}}
|
49
|
+
<tr id='section-{{ section_id }}'>
|
50
|
+
<td class=docs>
|
51
|
+
<div class="pilwrap">
|
52
|
+
<a class="pilcrow" href="#section-{{ section_id }}">¶</a>
|
53
|
+
</div>
|
54
|
+
{{{ docs }}}
|
55
|
+
</td>
|
56
|
+
<td class=code>
|
57
|
+
<div class='highlight'><pre>{{{ code }}}</pre></div>
|
58
|
+
</td>
|
59
|
+
</tr>
|
60
|
+
{{/sections}}
|
61
|
+
</table>
|
62
|
+
</div>
|
63
|
+
<a href="https://github.com/fabrik42/acts_as_api"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://assets1.github.com/img/7afbc8b248c68eb468279e8c17986ad46549fb71?repo=&url=http%3A%2F%2Fs3.amazonaws.com%2Fgithub%2Fribbons%2Fforkme_right_darkblue_121621.png&path=" alt="Fork me on GitHub"></a>
|
64
|
+
</body>
|
data/lib/acts_as_api.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
require
|
1
|
+
require 'set'
|
2
|
+
require 'active_model'
|
3
|
+
require 'active_support/core_ext/class'
|
2
4
|
|
3
5
|
$:.unshift(File.dirname(__FILE__)) unless
|
4
6
|
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
5
|
-
|
6
|
-
require "acts_as_api/
|
7
|
-
require "acts_as_api/
|
8
|
-
require "acts_as_api/array"
|
7
|
+
|
8
|
+
require "acts_as_api/array"
|
9
|
+
require "acts_as_api/rails_renderer"
|
9
10
|
|
10
11
|
# acts_as_api is a gem that aims to make the construction of JSON and XML
|
11
12
|
# responses in rails 3 easy and fun.
|
@@ -16,26 +17,10 @@ require "acts_as_api/array"
|
|
16
17
|
# acts_as_api uses the default serializers of your rails app and doesn't
|
17
18
|
# force you into more dependencies.
|
18
19
|
module ActsAsApi
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
ACCEPTED_API_FORMATS = [:xml, :json]
|
24
|
-
|
25
|
-
# Holds references to formats that need
|
26
|
-
# to get added an additional root node
|
27
|
-
# with the name of the model.
|
28
|
-
ADD_ROOT_NODE_FOR = [:json]
|
29
|
-
|
30
|
-
# Holds formats that should be dasherized
|
31
|
-
DASHERIZE_FOR = [:xml]
|
32
|
-
|
33
|
-
# The default name of a root node of a response
|
34
|
-
# if no root paramter is passed in render_for_api
|
35
|
-
# and the gem is not able to determine a root name
|
36
|
-
# automatically
|
37
|
-
DEFAULT_ROOT = :record
|
38
|
-
|
20
|
+
autoload :Config, "acts_as_api/config"
|
21
|
+
autoload :ApiTemplate, "acts_as_api/api_template"
|
22
|
+
autoload :Base, "acts_as_api/base"
|
23
|
+
autoload :Rendering, "acts_as_api/rendering"
|
39
24
|
end
|
40
25
|
|
41
26
|
# Attach ourselves to active record
|
@@ -46,4 +31,5 @@ end
|
|
46
31
|
# Attach ourselves to the action controller of rails
|
47
32
|
if defined?(ActionController::Base)
|
48
33
|
ActionController::Base.send :include, ActsAsApi::Rendering
|
34
|
+
ActsAsApi::RailsRenderer.setup
|
49
35
|
end
|
data/lib/acts_as_api/base.rb
CHANGED
@@ -16,6 +16,10 @@ module ActsAsApi
|
|
16
16
|
extend ActsAsApi::Base::ClassMethods
|
17
17
|
end
|
18
18
|
|
19
|
+
if block_given?
|
20
|
+
yield ActsAsApi::Config
|
21
|
+
end
|
22
|
+
|
19
23
|
end
|
20
24
|
|
21
25
|
module ClassMethods
|
@@ -28,12 +32,28 @@ module ActsAsApi
|
|
28
32
|
# *Note*: There is only whitelisting for api accessible attributes.
|
29
33
|
# So once the model acts as api, you have to determine all attributes here that should
|
30
34
|
# be contained in the api responses.
|
31
|
-
def
|
35
|
+
def api_accessible_deprecated(api_templates)
|
32
36
|
api_templates.each do |api_template, attributes|
|
33
37
|
write_inheritable_attribute("api_accessible_#{api_template}".to_sym, Set.new(attributes) + (api_accessible_attributes(api_template) || []))
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
41
|
+
def api_accessible(api_template, options = {}, &block)
|
42
|
+
|
43
|
+
# return api_accessible_deprecated([api_template]) if api_template.is_a? Hash
|
44
|
+
|
45
|
+
|
46
|
+
attributes = api_accessible_attributes(api_template) || ApiTemplate.new
|
47
|
+
|
48
|
+
attributes.merge!(api_accessible_attributes(options[:extend])) if options[:extend]
|
49
|
+
|
50
|
+
if block_given?
|
51
|
+
yield attributes
|
52
|
+
end
|
53
|
+
|
54
|
+
write_inheritable_attribute("api_accessible_#{api_template}".to_sym, attributes)
|
55
|
+
end
|
56
|
+
|
37
57
|
# Returns an array of all the attributes that have been made accessible to the api response.
|
38
58
|
def api_accessible_attributes(api_template)
|
39
59
|
read_inheritable_attribute("api_accessible_#{api_template}".to_sym)
|
@@ -52,82 +72,67 @@ module ActsAsApi
|
|
52
72
|
|
53
73
|
return api_output if api_attributes.nil?
|
54
74
|
|
55
|
-
|
56
|
-
|
57
|
-
case attribute
|
58
|
-
when Symbol
|
59
|
-
|
60
|
-
if self.respond_to?(attribute)
|
61
|
-
out = send attribute
|
62
|
-
|
63
|
-
if out.respond_to?(:as_api_response)
|
64
|
-
out = out.send(:as_api_response, api_template)
|
65
|
-
end
|
66
|
-
|
67
|
-
api_output[attribute] = out
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
when String
|
72
|
-
# go up the call chain
|
73
|
-
out = self
|
74
|
-
attribute.split(".").each do |method|
|
75
|
-
out = out.send(method.to_sym)
|
76
|
-
end
|
77
|
-
api_output[attribute] = out
|
78
|
-
|
79
|
-
when Hash
|
80
|
-
|
81
|
-
queue = []
|
82
|
-
queue << { :parent => api_output, :item => attribute}
|
75
|
+
queue = []
|
76
|
+
queue << { :parent => api_output, :item => api_attributes}
|
83
77
|
|
84
|
-
|
78
|
+
until queue.empty? do
|
85
79
|
|
86
|
-
|
80
|
+
leaf = queue.pop
|
87
81
|
|
88
|
-
|
82
|
+
leaf[:item].each do |k,v|
|
89
83
|
|
90
|
-
|
91
|
-
|
84
|
+
case v
|
85
|
+
when Symbol
|
92
86
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
if out.respond_to?(:as_api_response)
|
97
|
-
out = out.send(:as_api_response, api_template)
|
98
|
-
end
|
99
|
-
|
100
|
-
leaf[:parent][k] = out
|
87
|
+
if self.respond_to?(v)
|
88
|
+
out = send v
|
101
89
|
|
90
|
+
if out.respond_to?(:as_api_response)
|
91
|
+
out = out.send(:as_api_response, api_template)
|
102
92
|
end
|
103
93
|
|
104
|
-
when String
|
105
|
-
# go up the call chain
|
106
|
-
out = self
|
107
|
-
v.split(".").each do |method|
|
108
|
-
out = out.send(method.to_sym)
|
109
|
-
end
|
110
94
|
leaf[:parent][k] = out
|
111
95
|
|
112
|
-
when Hash
|
113
|
-
leaf[:parent][k] ||= {}
|
114
|
-
queue << { :parent => leaf[:parent][k], :item => v}
|
115
96
|
end
|
116
97
|
|
98
|
+
when Proc
|
99
|
+
|
100
|
+
out = v.call(self)
|
101
|
+
|
102
|
+
if out.respond_to?(:as_api_response)
|
103
|
+
out = out.send(:as_api_response, api_template)
|
104
|
+
end
|
105
|
+
|
106
|
+
leaf[:parent][k] = out
|
107
|
+
|
108
|
+
when String
|
109
|
+
# go up the call chain
|
110
|
+
out = self
|
111
|
+
v.split(".").each do |method|
|
112
|
+
out = out.send(method.to_sym)
|
113
|
+
end
|
114
|
+
|
115
|
+
if out.respond_to?(:as_api_response)
|
116
|
+
out = out.send(:as_api_response, api_template)
|
117
|
+
end
|
118
|
+
|
119
|
+
leaf[:parent][k] = out
|
120
|
+
|
121
|
+
when Hash
|
122
|
+
leaf[:parent][k] ||= {}
|
123
|
+
queue << { :parent => leaf[:parent][k], :item => v}
|
117
124
|
end
|
118
125
|
|
119
126
|
end
|
120
127
|
|
121
128
|
end
|
122
129
|
|
123
|
-
|
130
|
+
api_output
|
124
131
|
|
125
|
-
|
132
|
+
end
|
126
133
|
|
127
134
|
end
|
128
135
|
|
129
136
|
end
|
130
|
-
|
131
|
-
|
137
|
+
|
132
138
|
end
|
133
|
-
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ActsAsApi
|
2
|
+
|
3
|
+
module Config
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
# The accepted response formats
|
8
|
+
# Default is <tt>[:xml, :json]</tt>
|
9
|
+
attr_accessor_with_default :accepted_api_formats, [:xml, :json] # :nodoc:
|
10
|
+
|
11
|
+
# Holds formats that should be dasherized
|
12
|
+
# Default is <tt>[:xml]</tt>
|
13
|
+
attr_accessor_with_default :dasherize_for, [:xml]
|
14
|
+
|
15
|
+
# Holds references to formats that need
|
16
|
+
# to get added an additional root node
|
17
|
+
# with the name of the model.
|
18
|
+
attr_accessor_with_default :add_root_node_for, [:json]
|
19
|
+
|
20
|
+
# The default name of a root node of a response
|
21
|
+
# if no root paramter is passed in render_for_api
|
22
|
+
# and the gem is not able to determine a root name
|
23
|
+
# automatically
|
24
|
+
attr_accessor_with_default :default_root, :record
|
25
|
+
|
26
|
+
attr_accessor_with_default :allow_jsonp_callback, false
|
27
|
+
|
28
|
+
attr_accessor_with_default :add_http_status_to_jsonp_response, true
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ActsAsApi
|
2
|
+
# Contains rails specific renderers used by acts_as_api
|
3
|
+
module RailsRenderer
|
4
|
+
|
5
|
+
def self.setup
|
6
|
+
ActionController.add_renderer :acts_as_api_jsonp do |json, options|
|
7
|
+
json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str)
|
8
|
+
json = "#{options[:callback]}(#{json}, #{response.status})" unless options[:callback].blank?
|
9
|
+
self.content_type ||= Mime::JSON
|
10
|
+
self.response_body = json
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -13,7 +13,7 @@ module ActsAsApi
|
|
13
13
|
# extract the api format and model
|
14
14
|
api_format_options = {}
|
15
15
|
|
16
|
-
ActsAsApi::
|
16
|
+
ActsAsApi::Config.accepted_api_formats.each do |item|
|
17
17
|
if render_options.has_key?(item)
|
18
18
|
api_format_options[item] = render_options[item]
|
19
19
|
render_options.delete item
|
@@ -28,13 +28,12 @@ module ActsAsApi
|
|
28
28
|
# set the params to render
|
29
29
|
output_params = render_options
|
30
30
|
|
31
|
-
|
32
31
|
api_root_name = nil
|
33
32
|
|
34
33
|
if !output_params[:root].nil?
|
35
|
-
|
36
34
|
api_root_name = output_params[:root].to_s
|
37
|
-
|
35
|
+
elsif api_model.respond_to?(:collection_name)
|
36
|
+
api_root_name = api_model.collection_name
|
38
37
|
elsif api_model.respond_to?(:model_name)
|
39
38
|
api_root_name = api_model.model_name
|
40
39
|
elsif api_model.is_a?(Array) && !api_model.empty? && api_model.first.class.respond_to?(:model_name)
|
@@ -42,7 +41,7 @@ module ActsAsApi
|
|
42
41
|
elsif api_model.class.respond_to?(:model_name)
|
43
42
|
api_root_name = api_model.class.model_name
|
44
43
|
else
|
45
|
-
api_root_name = ActsAsApi::
|
44
|
+
api_root_name = ActsAsApi::Config.default_root.to_s
|
46
45
|
end
|
47
46
|
|
48
47
|
api_root_name = api_root_name.underscore.tr('/', '_')
|
@@ -51,7 +50,7 @@ module ActsAsApi
|
|
51
50
|
api_root_name = api_root_name.pluralize
|
52
51
|
end
|
53
52
|
|
54
|
-
api_root_name = api_root_name.dasherize if ActsAsApi::
|
53
|
+
api_root_name = api_root_name.dasherize if ActsAsApi::Config.dasherize_for.include? api_format.to_sym
|
55
54
|
|
56
55
|
output_params[:root] = api_root_name
|
57
56
|
|
@@ -60,17 +59,21 @@ module ActsAsApi
|
|
60
59
|
|
61
60
|
api_response = api_model.as_api_response(api_template)
|
62
61
|
|
63
|
-
if meta_hash or ActsAsApi::
|
62
|
+
if meta_hash or ActsAsApi::Config.add_root_node_for.include? api_format
|
64
63
|
api_response = { api_root_name.to_sym => api_response}
|
65
64
|
end
|
66
65
|
|
67
66
|
api_response = meta_hash.merge api_response if meta_hash
|
67
|
+
|
68
|
+
if ActsAsApi::Config.allow_jsonp_callback && params[:callback]
|
69
|
+
output_params[:callback] = params[:callback]
|
70
|
+
api_format = :acts_as_api_jsonp if ActsAsApi::Config.add_http_status_to_jsonp_response
|
71
|
+
end
|
68
72
|
|
69
73
|
# create the Hash as response
|
70
74
|
output_params[api_format] = api_response
|
71
75
|
|
72
76
|
render output_params
|
73
|
-
|
74
77
|
end
|
75
78
|
|
76
79
|
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
describe UsersController do
|
4
|
+
|
5
|
+
include ApiTestHelpers
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@luke = User.create({ :first_name => 'Luke', :last_name => 'Skywalker', :age => 25, :active => true })
|
9
|
+
@han = User.create({ :first_name => 'Han', :last_name => 'Solo', :age => 35, :active => true })
|
10
|
+
@leia = User.create({ :first_name => 'Princess', :last_name => 'Leia', :age => 25, :active => false })
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:each) do
|
14
|
+
User.delete_all
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'xml responses' do
|
18
|
+
|
19
|
+
describe 'get all users' do
|
20
|
+
|
21
|
+
before(:each) do
|
22
|
+
get :index, :format => 'xml', :api_template => :name_only
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have a root node named users" do
|
26
|
+
response_body.should have_selector("users")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should contain all users" do
|
30
|
+
response_body.should have_selector("users > user") do |users|
|
31
|
+
users.size.should eql(3)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should contain the specified attributes" do
|
36
|
+
response_body.should have_selector("users > user > first-name")
|
37
|
+
response_body.should have_selector("users > user > last-name")
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'get a single user' do
|
43
|
+
|
44
|
+
before(:each) do
|
45
|
+
get :show, :format => 'xml', :api_template => :name_only, :id => @luke.id
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should have a root node named user" do
|
49
|
+
response_body.should have_selector("user")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should contain the specified attributes" do
|
53
|
+
response_body.should have_selector("user > first-name")
|
54
|
+
response_body.should have_selector("user > last-name")
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
describe 'json responses' do
|
63
|
+
|
64
|
+
describe 'get all users' do
|
65
|
+
|
66
|
+
before(:each) do
|
67
|
+
get :index, :format => 'json', :api_template => :name_only
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should have a root node named users" do
|
71
|
+
response_body_json.should have_key("users")
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should contain all users" do
|
75
|
+
response_body_json["users"].should be_a(Array)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should contain the specified attributes" do
|
79
|
+
response_body_json["users"].first.should have_key("first_name")
|
80
|
+
response_body_json["users"].first.should have_key("last_name")
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should contain the specified values" do
|
84
|
+
response_body_json["users"].first["first_name"].should eql("Luke")
|
85
|
+
response_body_json["users"].first["last_name"].should eql("Skywalker")
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'get a single user' do
|
91
|
+
|
92
|
+
before(:each) do
|
93
|
+
get :show, :format => 'json', :api_template => :name_only, :id => @luke.id
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should have a root node named user" do
|
97
|
+
response_body_json.should have_key("user")
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should contain the specified attributes" do
|
101
|
+
response_body_json["user"].should have_key("first_name")
|
102
|
+
response_body_json["user"].should have_key("last_name")
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should contain the specified values" do
|
106
|
+
response_body_json["user"]["first_name"].should eql("Luke")
|
107
|
+
response_body_json["user"]["last_name"].should eql("Skywalker")
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
describe 'jsonp responses with callback' do
|
116
|
+
|
117
|
+
it "should be disabled by default" do
|
118
|
+
@callback = "mycallback"
|
119
|
+
get :index, :format => 'json', :api_template => :name_only, :callback => @callback
|
120
|
+
response_body_jsonp(@callback).should be_nil
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "enabled jsonp callbacks" do
|
124
|
+
|
125
|
+
before(:each) do
|
126
|
+
@callback = "mycallback"
|
127
|
+
|
128
|
+
User.acts_as_api do |config|
|
129
|
+
config.allow_jsonp_callback = true
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe 'get all users' do
|
134
|
+
|
135
|
+
before(:each) do
|
136
|
+
get :index, :format => 'json', :api_template => :name_only, :callback => @callback
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should wrap the response in the callback" do
|
140
|
+
response_body_jsonp(@callback).should_not be_nil
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
describe 'get a single user' do
|
146
|
+
|
147
|
+
before(:each) do
|
148
|
+
get :show, :format => 'json', :api_template => :name_only, :id => @luke.id, :callback => @callback
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should wrap the response in the callback" do
|
152
|
+
response_body_jsonp(@callback).should_not be_nil
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
end
|