acts_as_api 0.3.6 → 0.3.7
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/History.txt +4 -0
- data/Rakefile +10 -9
- data/acts_as_api.gemspec +4 -5
- data/lib/acts_as_api/base.rb +16 -4
- data/lib/acts_as_api/responder.rb +10 -5
- data/lib/acts_as_api/version.rb +1 -1
- data/spec/controllers/respond_with_users_controller_spec.rb +92 -3
- data/spec/models/active_record_spec.rb +1 -0
- data/spec/models/mongoid_spec.rb +2 -1
- data/spec/models/vanilla_ruby_spec.rb +31 -0
- data/spec/rails_app/app/controllers/application_controller.rb +8 -0
- data/spec/rails_app/app/controllers/respond_with_users_controller.rb +15 -8
- data/spec/rails_app/app/controllers/users_controller.rb +13 -12
- data/spec/rails_app/app/models/mongo_user.rb +24 -0
- data/spec/rails_app/app/models/user.rb +73 -48
- data/spec/rails_app/app/models/vanilla_profile.rb +16 -0
- data/spec/rails_app/app/models/vanilla_task.rb +16 -0
- data/spec/rails_app/app/models/vanilla_untouched.rb +2 -0
- data/spec/rails_app/app/models/vanilla_user.rb +176 -0
- data/spec/rails_app/config/routes.rb +11 -3
- data/spec/support/controller_examples.rb +37 -2
- data/spec/support/model_examples/callbacks.rb +38 -0
- data/spec/support/simple_fixtures.rb +25 -1
- metadata +16 -4
data/History.txt
CHANGED
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
require 'rspec/core'
|
3
3
|
require 'rspec/core/rake_task'
|
4
|
-
require 'rake/rdoctask'
|
4
|
+
#require 'rake/rdoctask'
|
5
5
|
|
6
6
|
Bundler::GemHelper.install_tasks
|
7
7
|
|
@@ -22,13 +22,14 @@ end
|
|
22
22
|
|
23
23
|
gemspec = Gem::Specification.load("acts_as_api.gemspec")
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
rdoc.
|
28
|
-
rdoc.
|
29
|
-
rdoc.options
|
30
|
-
rdoc.
|
31
|
-
rdoc.rdoc_files.include(
|
32
|
-
|
25
|
+
# causes crash in travis ci
|
26
|
+
#Rake::RDocTask.new do |rdoc|
|
27
|
+
# rdoc.rdoc_dir = 'doc'
|
28
|
+
# rdoc.title = "#{gemspec.name} #{gemspec.version}"
|
29
|
+
# rdoc.options += gemspec.rdoc_options
|
30
|
+
# rdoc.options << '--line-numbers' << '--inline-source'
|
31
|
+
# rdoc.rdoc_files.include(gemspec.extra_rdoc_files)
|
32
|
+
# rdoc.rdoc_files.include('README.rdoc')
|
33
|
+
#end
|
33
34
|
|
34
35
|
#bundle exec rocco examples/introduction/index.rb -t examples/introduction/layout.mustache
|
data/acts_as_api.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# encoding: utf-8
|
2
2
|
$:.push File.expand_path("../lib", __FILE__)
|
3
3
|
require "acts_as_api/version"
|
4
4
|
|
@@ -15,11 +15,10 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.add_dependency('activemodel','>= 3.0.0')
|
16
16
|
s.add_dependency('activesupport','>= 3.0.0')
|
17
17
|
s.add_dependency('rack','>= 1.1.0')
|
18
|
-
|
18
|
+
|
19
19
|
s.add_development_dependency('rails', ['>= 3.0.0'])
|
20
20
|
s.add_development_dependency('mongoid', ['>= 2.0.0'])
|
21
|
-
|
22
|
-
s.has_rdoc = true
|
21
|
+
|
23
22
|
s.rdoc_options = ['--main', 'README.rdoc', '--charset=UTF-8']
|
24
23
|
s.extra_rdoc_files = ['README.rdoc']
|
25
24
|
|
@@ -27,4 +26,4 @@ Gem::Specification.new do |s|
|
|
27
26
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
28
27
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
29
28
|
s.require_paths = ["lib"]
|
30
|
-
end
|
29
|
+
end
|
data/lib/acts_as_api/base.rb
CHANGED
@@ -42,12 +42,13 @@ module ActsAsApi
|
|
42
42
|
yield attributes
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
class_attribute "api_accessible_#{api_template}".to_sym
|
46
|
+
send "api_accessible_#{api_template}=", attributes
|
46
47
|
end
|
47
48
|
|
48
49
|
# Returns an array of all the attributes that have been made accessible to the api response.
|
49
50
|
def api_accessible_attributes(api_template)
|
50
|
-
|
51
|
+
begin send "api_accessible_#{api_template}".to_sym rescue nil end
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
@@ -57,10 +58,21 @@ module ActsAsApi
|
|
57
58
|
# Will raise an exception if the passed api template is not defined for the model
|
58
59
|
def as_api_response(api_template)
|
59
60
|
api_attributes = self.class.api_accessible_attributes(api_template)
|
60
|
-
|
61
61
|
raise ActsAsApi::TemplateNotFoundError.new("acts_as_api template :#{api_template.to_s} was not found for model #{self.class}") if api_attributes.nil?
|
62
|
+
|
63
|
+
before_api_response(api_template) if respond_to? :before_api_response
|
62
64
|
|
63
|
-
|
65
|
+
response_hash = if respond_to? :around_api_response
|
66
|
+
around_api_response api_template do
|
67
|
+
api_attributes.to_response_hash(self)
|
68
|
+
end
|
69
|
+
else
|
70
|
+
api_attributes.to_response_hash(self)
|
71
|
+
end
|
72
|
+
|
73
|
+
after_api_response(api_template) if respond_to? :after_api_response
|
74
|
+
|
75
|
+
response_hash
|
64
76
|
end
|
65
77
|
|
66
78
|
end
|
@@ -31,10 +31,15 @@ module ActsAsApi
|
|
31
31
|
super(controller, resources, options)
|
32
32
|
end
|
33
33
|
|
34
|
-
# Overrides the base implementation of
|
35
|
-
# the render_for_api method.
|
36
|
-
def
|
37
|
-
|
34
|
+
# Overrides the base implementation of display, replacing it with
|
35
|
+
# the render_for_api method whenever api_template is specified.
|
36
|
+
def display(resource, given_options={})
|
37
|
+
if api_template.nil? || !resource.respond_to?(:as_api_response)
|
38
|
+
controller.render given_options.merge!(options).merge!(format => resource)
|
39
|
+
else
|
40
|
+
controller.render_for_api api_template, given_options.merge!(options).merge!(format => resource)
|
41
|
+
end
|
38
42
|
end
|
43
|
+
|
39
44
|
end
|
40
|
-
end
|
45
|
+
end
|
data/lib/acts_as_api/version.rb
CHANGED
@@ -3,17 +3,18 @@ require 'spec_helper'
|
|
3
3
|
describe RespondWithUsersController do
|
4
4
|
|
5
5
|
context "using active record", :orm => :active_record do
|
6
|
-
|
6
|
+
|
7
7
|
before(:each) do
|
8
8
|
setup_active_record_models
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
after(:each) do
|
12
12
|
clean_up_active_record_models
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
# see spec/support/controller_examples.rb
|
16
16
|
it_behaves_like "a controller with ActsAsApi responses"
|
17
|
+
|
17
18
|
end
|
18
19
|
|
19
20
|
context "using mongoid", :orm => :mongoid do
|
@@ -30,4 +31,92 @@ describe RespondWithUsersController do
|
|
30
31
|
it_behaves_like "a controller with ActsAsApi responses"
|
31
32
|
end
|
32
33
|
|
34
|
+
|
35
|
+
describe "default ActionController::Responder behavior" do
|
36
|
+
|
37
|
+
context 'json responses' do
|
38
|
+
|
39
|
+
context "creating valid models" do
|
40
|
+
|
41
|
+
before(:each) do
|
42
|
+
post :create, :user => { :first_name => "Luke", :last_name => "Skywalker" }, :api_template => :name_only, :format => 'json', :orm => :active_record
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return HTTP 201 status" do
|
46
|
+
response.code.should == "201"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should contain the specified attributes" do
|
50
|
+
response_body_json["user"].should have_key("first_name")
|
51
|
+
response_body_json["user"].should have_key("last_name")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should contain the specified values" do
|
55
|
+
response_body_json["user"]["first_name"].should eql("Luke")
|
56
|
+
response_body_json["user"]["last_name"].should eql("Skywalker")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "creating invalid models" do
|
61
|
+
|
62
|
+
before(:each) do
|
63
|
+
post :create, :user => {}, :api_template => :name_only, :format => 'json', :orm => :active_record
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should return HTTP 422 status" do
|
67
|
+
response.code.should == "422"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should return errors as json" do
|
71
|
+
response_body_json['first_name'].should include("can't be blank")
|
72
|
+
response_body_json['last_name'].should include("can't be blank")
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'xml responses' do
|
80
|
+
|
81
|
+
context "creating valid models" do
|
82
|
+
|
83
|
+
before(:each) do
|
84
|
+
post :create, :user => { :first_name => "Luke", :last_name => "Skywalker" }, :api_template => :name_only, :format => 'xml', :orm => :active_record
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should return HTTP 201 status" do
|
88
|
+
response.code.should == "201"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should include HTTP Location header" do
|
92
|
+
response.headers["Location"].should == user_url(User.last)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should contain the specified attributes" do
|
96
|
+
response_body.should have_selector("user > first-name")
|
97
|
+
response_body.should have_selector("user > last-name")
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
context "creating invalid models" do
|
103
|
+
|
104
|
+
before(:each) do
|
105
|
+
post :create, :user => {}, :api_template => :name_only, :format => 'xml', :orm => :active_record
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should return HTTP 422 status" do
|
109
|
+
response.code.should == "422"
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should return errors as json" do
|
113
|
+
response_body.should have_selector("errors > error")
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
|
33
122
|
end
|
@@ -23,6 +23,7 @@ describe ActiveRecord, :orm => "active_record" do
|
|
23
23
|
it_supports "creating a sub hash in the api template"
|
24
24
|
it_supports "trying to render an api template that is not defined"
|
25
25
|
it_supports "untouched models"
|
26
|
+
it_supports "defining a model callback"
|
26
27
|
end
|
27
28
|
|
28
29
|
end
|
data/spec/models/mongoid_spec.rb
CHANGED
@@ -22,7 +22,8 @@ describe Mongoid, :orm => "mongoid" do
|
|
22
22
|
it_supports "listing attributes in the api template"
|
23
23
|
it_supports "creating a sub hash in the api template"
|
24
24
|
it_supports "trying to render an api template that is not defined"
|
25
|
-
it_supports "untouched models"
|
25
|
+
it_supports "untouched models"
|
26
|
+
it_supports "defining a model callback"
|
26
27
|
end
|
27
28
|
|
28
29
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Class, :orm => "vanilla" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
setup_roflscale_models
|
7
|
+
end
|
8
|
+
|
9
|
+
after(:each) do
|
10
|
+
clean_up_roflscale_models
|
11
|
+
end
|
12
|
+
|
13
|
+
describe :act_as_api do
|
14
|
+
# deactivated as I won't implement a fake association model just for specs ;)
|
15
|
+
# it_supports "including an association in the api template"
|
16
|
+
it_supports "calling a closure in the api template"
|
17
|
+
it_supports "conditional if statements"
|
18
|
+
it_supports "conditional unless statements"
|
19
|
+
it_supports "acts_as_api is enabled"
|
20
|
+
it_supports "extending a given api template"
|
21
|
+
it_supports "calling a method in the api template"
|
22
|
+
it_supports "renaming"
|
23
|
+
it_supports "listing attributes in the api template"
|
24
|
+
it_supports "creating a sub hash in the api template"
|
25
|
+
it_supports "trying to render an api template that is not defined"
|
26
|
+
# deactivated as acts_as_api won't get mixed into any class
|
27
|
+
# it_supports "untouched models"
|
28
|
+
it_supports "defining a model callback"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -3,14 +3,6 @@ class RespondWithUsersController < ApplicationController
|
|
3
3
|
respond_to :json, :xml
|
4
4
|
|
5
5
|
self.responder = ActsAsApi::Responder
|
6
|
-
|
7
|
-
before_filter do
|
8
|
-
if params[:orm] == :active_record
|
9
|
-
@user_model = User
|
10
|
-
elsif params[:orm] == :mongoid
|
11
|
-
@user_model = MongoUser
|
12
|
-
end
|
13
|
-
end
|
14
6
|
|
15
7
|
def index
|
16
8
|
@users = @user_model.all
|
@@ -23,4 +15,19 @@ class RespondWithUsersController < ApplicationController
|
|
23
15
|
respond_with @user, :api_template => params[:api_template].to_sym, :root => :user
|
24
16
|
end
|
25
17
|
|
18
|
+
def show_default
|
19
|
+
@user = @user_model.find(params[:id])
|
20
|
+
respond_with @user
|
21
|
+
end
|
22
|
+
|
23
|
+
def create
|
24
|
+
@user = @user_model.new(params[:user])
|
25
|
+
|
26
|
+
if @user.save
|
27
|
+
respond_with @user, :api_template => params[:api_template]
|
28
|
+
else
|
29
|
+
respond_with @user
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
26
33
|
end
|
@@ -1,13 +1,5 @@
|
|
1
1
|
class UsersController < ApplicationController
|
2
|
-
|
3
|
-
before_filter do
|
4
|
-
if params[:orm] == :active_record
|
5
|
-
@user_model = User
|
6
|
-
elsif params[:orm] == :mongoid
|
7
|
-
@user_model = MongoUser
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
2
|
+
|
11
3
|
def index
|
12
4
|
@users = @user_model.all
|
13
5
|
|
@@ -16,7 +8,7 @@ class UsersController < ApplicationController
|
|
16
8
|
format.json { render_for_api params[:api_template].to_sym, :json => @users, :root => :users }
|
17
9
|
end
|
18
10
|
end
|
19
|
-
|
11
|
+
|
20
12
|
def show
|
21
13
|
@user = @user_model.find(params[:id])
|
22
14
|
|
@@ -25,6 +17,15 @@ class UsersController < ApplicationController
|
|
25
17
|
format.xml { render_for_api params[:api_template].to_sym, :xml => @user, :root => :user }
|
26
18
|
format.json { render_for_api params[:api_template].to_sym, :json => @user, :root => :user }
|
27
19
|
end
|
28
|
-
end
|
29
|
-
|
20
|
+
end
|
21
|
+
|
22
|
+
def show_default
|
23
|
+
@user = @user_model.find(params[:id])
|
24
|
+
respond_to do |format|
|
25
|
+
format.xml { render :xml => @user }
|
26
|
+
format.json { render :json => @user }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
30
31
|
end
|
@@ -119,6 +119,30 @@ class MongoUser
|
|
119
119
|
t.add :last_name, :unless => lambda{|u| nil }
|
120
120
|
end
|
121
121
|
|
122
|
+
def before_api_response(api_response)
|
123
|
+
@before_api_response_called = true
|
124
|
+
end
|
125
|
+
|
126
|
+
def before_api_response_called?
|
127
|
+
!!@before_api_response_called
|
128
|
+
end
|
129
|
+
|
130
|
+
def after_api_response(api_response)
|
131
|
+
@after_api_response_called = true
|
132
|
+
end
|
133
|
+
|
134
|
+
def after_api_response_called?
|
135
|
+
!!@after_api_response_called
|
136
|
+
end
|
137
|
+
|
138
|
+
def skip_api_response=(should_skip)
|
139
|
+
@skip_api_response = should_skip
|
140
|
+
end
|
141
|
+
|
142
|
+
def around_api_response(api_response)
|
143
|
+
@skip_api_response ? { :skipped => true } : yield
|
144
|
+
end
|
145
|
+
|
122
146
|
def over_thirty?
|
123
147
|
age > 30
|
124
148
|
end
|
@@ -1,123 +1,148 @@
|
|
1
1
|
class User < ActiveRecord::Base
|
2
|
+
validates :first_name, :last_name, :presence => true
|
2
3
|
|
3
4
|
has_many :tasks
|
4
|
-
|
5
|
+
|
5
6
|
has_one :profile
|
6
|
-
|
7
|
+
|
7
8
|
acts_as_api
|
8
|
-
|
9
|
+
|
9
10
|
api_accessible :name_only do |t|
|
10
11
|
t.add :first_name
|
11
12
|
t.add :last_name
|
12
13
|
end
|
13
|
-
|
14
|
+
|
14
15
|
api_accessible :only_full_name do |t|
|
15
16
|
t.add :full_name
|
16
17
|
end
|
17
|
-
|
18
|
+
|
18
19
|
api_accessible :rename_last_name do |t|
|
19
20
|
t.add :last_name, :as => :family_name
|
20
21
|
end
|
21
|
-
|
22
|
+
|
22
23
|
api_accessible :rename_full_name do |t|
|
23
24
|
t.add :full_name, :as => :other_full_name
|
24
|
-
end
|
25
|
-
|
25
|
+
end
|
26
|
+
|
26
27
|
api_accessible :with_former_value do |t|
|
27
28
|
t.add :first_name
|
28
|
-
t.add :last_name
|
29
|
+
t.add :last_name
|
29
30
|
end
|
30
|
-
|
31
|
+
|
31
32
|
api_accessible :age_and_first_name, :extend => :with_former_value do |t|
|
32
33
|
t.add :age
|
33
34
|
t.remove :last_name
|
34
35
|
end
|
35
|
-
|
36
|
+
|
36
37
|
api_accessible :calling_a_proc do |t|
|
37
38
|
t.add Proc.new{|model| model.full_name.upcase }, :as => :all_caps_name
|
38
39
|
t.add Proc.new{|model| Time.now.class.to_s }, :as => :without_param
|
39
|
-
end
|
40
|
-
|
40
|
+
end
|
41
|
+
|
41
42
|
api_accessible :calling_a_lambda do |t|
|
42
43
|
t.add lambda{|model| model.full_name.upcase }, :as => :all_caps_name
|
43
44
|
t.add lambda{|model| Time.now.class.to_s }, :as => :without_param
|
44
45
|
end
|
45
|
-
api_accessible :include_tasks do |t|
|
46
|
+
api_accessible :include_tasks do |t|
|
46
47
|
t.add :tasks
|
47
48
|
end
|
48
|
-
|
49
|
-
api_accessible :include_profile do |t|
|
49
|
+
|
50
|
+
api_accessible :include_profile do |t|
|
50
51
|
t.add :profile
|
51
|
-
end
|
52
|
-
|
52
|
+
end
|
53
|
+
|
53
54
|
api_accessible :other_sub_template do |t|
|
54
55
|
t.add :first_name
|
55
56
|
t.add :tasks, :template => :other_template
|
56
57
|
end
|
57
|
-
|
58
|
-
api_accessible :include_completed_tasks do |t|
|
58
|
+
|
59
|
+
api_accessible :include_completed_tasks do |t|
|
59
60
|
t.add "tasks.completed.all", :as => :completed_tasks
|
60
61
|
end
|
61
|
-
|
62
|
-
api_accessible :sub_node do |t|
|
62
|
+
|
63
|
+
api_accessible :sub_node do |t|
|
63
64
|
t.add Hash[:foo => :say_something], :as => :sub_nodes
|
64
65
|
end
|
65
|
-
|
66
|
-
api_accessible :nested_sub_node do |t|
|
66
|
+
|
67
|
+
api_accessible :nested_sub_node do |t|
|
67
68
|
t.add Hash[:foo, Hash[:bar, :last_name]], :as => :sub_nodes
|
68
69
|
end
|
69
|
-
|
70
|
-
api_accessible :nested_sub_hash do |t|
|
70
|
+
|
71
|
+
api_accessible :nested_sub_hash do |t|
|
71
72
|
t.add :sub_hash
|
72
73
|
end
|
73
|
-
|
74
|
-
api_accessible :if_over_thirty do |t|
|
74
|
+
|
75
|
+
api_accessible :if_over_thirty do |t|
|
75
76
|
t.add :first_name
|
76
|
-
t.add :last_name, :if => :over_thirty?
|
77
|
-
end
|
77
|
+
t.add :last_name, :if => :over_thirty?
|
78
|
+
end
|
78
79
|
|
79
|
-
api_accessible :if_returns_nil do |t|
|
80
|
+
api_accessible :if_returns_nil do |t|
|
80
81
|
t.add :first_name
|
81
82
|
t.add :last_name, :if => :return_nil
|
82
83
|
end
|
83
|
-
|
84
|
-
api_accessible :if_over_thirty_proc do |t|
|
84
|
+
|
85
|
+
api_accessible :if_over_thirty_proc do |t|
|
85
86
|
t.add :first_name
|
86
87
|
t.add :last_name, :if => lambda{|u| u.over_thirty? }
|
87
|
-
end
|
88
|
+
end
|
88
89
|
|
89
|
-
api_accessible :if_returns_nil_proc do |t|
|
90
|
+
api_accessible :if_returns_nil_proc do |t|
|
90
91
|
t.add :first_name
|
91
92
|
t.add :last_name, :if => lambda{|u| nil }
|
92
93
|
end
|
93
|
-
|
94
|
-
api_accessible :unless_under_thirty do |t|
|
94
|
+
|
95
|
+
api_accessible :unless_under_thirty do |t|
|
95
96
|
t.add :first_name
|
96
|
-
t.add :last_name, :unless => :under_thirty?
|
97
|
-
end
|
97
|
+
t.add :last_name, :unless => :under_thirty?
|
98
|
+
end
|
98
99
|
|
99
|
-
api_accessible :unless_returns_nil do |t|
|
100
|
+
api_accessible :unless_returns_nil do |t|
|
100
101
|
t.add :first_name
|
101
102
|
t.add :last_name, :unless => :return_nil
|
102
103
|
end
|
103
|
-
|
104
|
-
api_accessible :unless_under_thirty_proc do |t|
|
104
|
+
|
105
|
+
api_accessible :unless_under_thirty_proc do |t|
|
105
106
|
t.add :first_name
|
106
107
|
t.add :last_name, :unless => lambda{|u| u.under_thirty? }
|
107
|
-
end
|
108
|
+
end
|
108
109
|
|
109
|
-
api_accessible :unless_returns_nil_proc do |t|
|
110
|
+
api_accessible :unless_returns_nil_proc do |t|
|
110
111
|
t.add :first_name
|
111
112
|
t.add :last_name, :unless => lambda{|u| nil }
|
112
|
-
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def before_api_response(api_response)
|
116
|
+
@before_api_response_called = true
|
117
|
+
end
|
118
|
+
|
119
|
+
def before_api_response_called?
|
120
|
+
!!@before_api_response_called
|
121
|
+
end
|
122
|
+
|
123
|
+
def after_api_response(api_response)
|
124
|
+
@after_api_response_called = true
|
125
|
+
end
|
126
|
+
|
127
|
+
def after_api_response_called?
|
128
|
+
!!@after_api_response_called
|
129
|
+
end
|
130
|
+
|
131
|
+
def skip_api_response=(should_skip)
|
132
|
+
@skip_api_response = should_skip
|
133
|
+
end
|
134
|
+
|
135
|
+
def around_api_response(api_response)
|
136
|
+
@skip_api_response ? { :skipped => true } : yield
|
137
|
+
end
|
113
138
|
|
114
139
|
def over_thirty?
|
115
140
|
age > 30
|
116
141
|
end
|
117
|
-
|
142
|
+
|
118
143
|
def under_thirty?
|
119
144
|
age < 30
|
120
|
-
end
|
145
|
+
end
|
121
146
|
|
122
147
|
def return_nil
|
123
148
|
nil
|
@@ -130,7 +155,7 @@ class User < ActiveRecord::Base
|
|
130
155
|
def say_something
|
131
156
|
"something"
|
132
157
|
end
|
133
|
-
|
158
|
+
|
134
159
|
def sub_hash
|
135
160
|
{
|
136
161
|
:foo => "bar",
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class VanillaProfile
|
2
|
+
extend ActsAsApi::Base
|
3
|
+
|
4
|
+
attr_accessor :user, :avatar, :homepage, :created_at, :updated_at
|
5
|
+
|
6
|
+
def initialize(opts)
|
7
|
+
opts.each do |k,v|
|
8
|
+
self.send :"#{k}=", v
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def model_name
|
13
|
+
'profile'
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class VanillaTask
|
2
|
+
extend ActsAsApi::Base
|
3
|
+
|
4
|
+
attr_accessor :user, :heading, :description, :time_spent, :done, :created_at, :updated_at
|
5
|
+
|
6
|
+
def initialize(opts)
|
7
|
+
opts.each do |k,v|
|
8
|
+
self.send :"#{k}=", v
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def model_name
|
13
|
+
'task'
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
class VanillaUser
|
2
|
+
extend ActsAsApi::Base
|
3
|
+
|
4
|
+
attr_accessor :profile, :tasks, :first_name, :last_name, :age, :active, :created_at, :updated_at
|
5
|
+
|
6
|
+
|
7
|
+
def initialize(opts)
|
8
|
+
@tasks = []
|
9
|
+
opts.each do |k,v|
|
10
|
+
self.send :"#{k}=", v
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def model_name
|
15
|
+
'user'
|
16
|
+
end
|
17
|
+
|
18
|
+
acts_as_api
|
19
|
+
|
20
|
+
api_accessible :name_only do |t|
|
21
|
+
t.add :first_name
|
22
|
+
t.add :last_name
|
23
|
+
end
|
24
|
+
|
25
|
+
api_accessible :only_full_name do |t|
|
26
|
+
t.add :full_name
|
27
|
+
end
|
28
|
+
|
29
|
+
api_accessible :rename_last_name do |t|
|
30
|
+
t.add :last_name, :as => :family_name
|
31
|
+
end
|
32
|
+
|
33
|
+
api_accessible :rename_full_name do |t|
|
34
|
+
t.add :full_name, :as => :other_full_name
|
35
|
+
end
|
36
|
+
|
37
|
+
api_accessible :with_former_value do |t|
|
38
|
+
t.add :first_name
|
39
|
+
t.add :last_name
|
40
|
+
end
|
41
|
+
|
42
|
+
api_accessible :age_and_first_name, :extend => :with_former_value do |t|
|
43
|
+
t.add :age
|
44
|
+
t.remove :last_name
|
45
|
+
end
|
46
|
+
|
47
|
+
api_accessible :calling_a_proc do |t|
|
48
|
+
t.add Proc.new{|model| model.full_name.upcase }, :as => :all_caps_name
|
49
|
+
t.add Proc.new{|model| Time.now.class.to_s }, :as => :without_param
|
50
|
+
end
|
51
|
+
|
52
|
+
api_accessible :calling_a_lambda do |t|
|
53
|
+
t.add lambda{|model| model.full_name.upcase }, :as => :all_caps_name
|
54
|
+
t.add lambda{|model| Time.now.class.to_s }, :as => :without_param
|
55
|
+
end
|
56
|
+
api_accessible :include_tasks do |t|
|
57
|
+
t.add :tasks
|
58
|
+
end
|
59
|
+
|
60
|
+
api_accessible :include_profile do |t|
|
61
|
+
t.add :profile
|
62
|
+
end
|
63
|
+
|
64
|
+
api_accessible :other_sub_template do |t|
|
65
|
+
t.add :first_name
|
66
|
+
t.add :tasks, :template => :other_template
|
67
|
+
end
|
68
|
+
|
69
|
+
api_accessible :include_completed_tasks do |t|
|
70
|
+
t.add "tasks.completed.all", :as => :completed_tasks
|
71
|
+
end
|
72
|
+
|
73
|
+
api_accessible :sub_node do |t|
|
74
|
+
t.add Hash[:foo => :say_something], :as => :sub_nodes
|
75
|
+
end
|
76
|
+
|
77
|
+
api_accessible :nested_sub_node do |t|
|
78
|
+
t.add Hash[:foo, Hash[:bar, :last_name]], :as => :sub_nodes
|
79
|
+
end
|
80
|
+
|
81
|
+
api_accessible :nested_sub_hash do |t|
|
82
|
+
t.add :sub_hash
|
83
|
+
end
|
84
|
+
|
85
|
+
api_accessible :if_over_thirty do |t|
|
86
|
+
t.add :first_name
|
87
|
+
t.add :last_name, :if => :over_thirty?
|
88
|
+
end
|
89
|
+
|
90
|
+
api_accessible :if_returns_nil do |t|
|
91
|
+
t.add :first_name
|
92
|
+
t.add :last_name, :if => :return_nil
|
93
|
+
end
|
94
|
+
|
95
|
+
api_accessible :if_over_thirty_proc do |t|
|
96
|
+
t.add :first_name
|
97
|
+
t.add :last_name, :if => lambda{|u| u.over_thirty? }
|
98
|
+
end
|
99
|
+
|
100
|
+
api_accessible :if_returns_nil_proc do |t|
|
101
|
+
t.add :first_name
|
102
|
+
t.add :last_name, :if => lambda{|u| nil }
|
103
|
+
end
|
104
|
+
|
105
|
+
api_accessible :unless_under_thirty do |t|
|
106
|
+
t.add :first_name
|
107
|
+
t.add :last_name, :unless => :under_thirty?
|
108
|
+
end
|
109
|
+
|
110
|
+
api_accessible :unless_returns_nil do |t|
|
111
|
+
t.add :first_name
|
112
|
+
t.add :last_name, :unless => :return_nil
|
113
|
+
end
|
114
|
+
|
115
|
+
api_accessible :unless_under_thirty_proc do |t|
|
116
|
+
t.add :first_name
|
117
|
+
t.add :last_name, :unless => lambda{|u| u.under_thirty? }
|
118
|
+
end
|
119
|
+
|
120
|
+
api_accessible :unless_returns_nil_proc do |t|
|
121
|
+
t.add :first_name
|
122
|
+
t.add :last_name, :unless => lambda{|u| nil }
|
123
|
+
end
|
124
|
+
|
125
|
+
def before_api_response(api_response)
|
126
|
+
@before_api_response_called = true
|
127
|
+
end
|
128
|
+
|
129
|
+
def before_api_response_called?
|
130
|
+
!!@before_api_response_called
|
131
|
+
end
|
132
|
+
|
133
|
+
def after_api_response(api_response)
|
134
|
+
@after_api_response_called = true
|
135
|
+
end
|
136
|
+
|
137
|
+
def after_api_response_called?
|
138
|
+
!!@after_api_response_called
|
139
|
+
end
|
140
|
+
|
141
|
+
def skip_api_response=(should_skip)
|
142
|
+
@skip_api_response = should_skip
|
143
|
+
end
|
144
|
+
|
145
|
+
def around_api_response(api_response)
|
146
|
+
@skip_api_response ? { :skipped => true } : yield
|
147
|
+
end
|
148
|
+
|
149
|
+
def over_thirty?
|
150
|
+
age > 30
|
151
|
+
end
|
152
|
+
|
153
|
+
def under_thirty?
|
154
|
+
age < 30
|
155
|
+
end
|
156
|
+
|
157
|
+
def return_nil
|
158
|
+
nil
|
159
|
+
end
|
160
|
+
|
161
|
+
def full_name
|
162
|
+
'' << first_name.to_s << ' ' << last_name.to_s
|
163
|
+
end
|
164
|
+
|
165
|
+
def say_something
|
166
|
+
"something"
|
167
|
+
end
|
168
|
+
|
169
|
+
def sub_hash
|
170
|
+
{
|
171
|
+
:foo => "bar",
|
172
|
+
:hello => "world"
|
173
|
+
}
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
@@ -1,7 +1,15 @@
|
|
1
1
|
RailsApp::Application.routes.draw do
|
2
2
|
|
3
|
-
resources :users
|
4
|
-
|
5
|
-
|
3
|
+
resources :users do
|
4
|
+
member do
|
5
|
+
get 'show_default'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
resources :respond_with_users do
|
10
|
+
member do
|
11
|
+
get 'show_default'
|
12
|
+
end
|
13
|
+
end
|
6
14
|
|
7
15
|
end
|
@@ -44,8 +44,28 @@ shared_examples_for "a controller with ActsAsApi responses" do
|
|
44
44
|
|
45
45
|
end
|
46
46
|
|
47
|
-
|
47
|
+
describe 'get a user without specifying an api template' do
|
48
|
+
|
49
|
+
before(:each) do
|
50
|
+
get :show_default, :format => 'xml', :id => @luke.id, :orm => @orm_for_testing
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should respond with HTTP 200" do
|
54
|
+
response.code.should == "200"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should render the model with standard to_xml" do
|
58
|
+
# TODO: figure out how to compare xml generated by mongo models.
|
59
|
+
|
60
|
+
# This line works fine with ActiveRecord, but not Mongoid:
|
61
|
+
# response.body.should == @luke.to_xml
|
62
|
+
|
63
|
+
response.body.length.should == @luke.to_xml.length
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
48
67
|
|
68
|
+
end
|
49
69
|
|
50
70
|
describe 'json responses' do
|
51
71
|
|
@@ -124,6 +144,22 @@ shared_examples_for "a controller with ActsAsApi responses" do
|
|
124
144
|
|
125
145
|
end
|
126
146
|
|
147
|
+
describe 'get a user without specifying an api template' do
|
148
|
+
|
149
|
+
before(:each) do
|
150
|
+
get :show_default, :format => 'json', :id => @luke.id, :orm => @orm_for_testing
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should respond with HTTP 200" do
|
154
|
+
response.code.should == "200"
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should render the model with to_json" do
|
158
|
+
response.body.should == @luke.to_json
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
127
163
|
end
|
128
164
|
|
129
165
|
describe 'Rails 3 default style json responses' do
|
@@ -242,5 +278,4 @@ shared_examples_for "a controller with ActsAsApi responses" do
|
|
242
278
|
end
|
243
279
|
end
|
244
280
|
|
245
|
-
|
246
281
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
shared_examples_for "defining a model callback" do
|
2
|
+
|
3
|
+
describe "for a" do
|
4
|
+
|
5
|
+
describe "around_api_response" do
|
6
|
+
|
7
|
+
it "skips rendering if not yielded" do
|
8
|
+
@luke.skip_api_response = true
|
9
|
+
@luke.as_api_response(:name_only).keys.should include(:skipped)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "renders if yielded" do
|
13
|
+
@luke.as_api_response(:name_only).keys.should_not include(:skipped)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "before_api_response" do
|
19
|
+
|
20
|
+
it "is called properly" do
|
21
|
+
@luke.as_api_response(:name_only)
|
22
|
+
@luke.before_api_response_called?.should eql(true)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "after_api_response" do
|
28
|
+
|
29
|
+
it "is called properly" do
|
30
|
+
@luke.as_api_response(:name_only)
|
31
|
+
@luke.after_api_response_called?.should eql(true)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -21,7 +21,7 @@ module SimpleFixtures
|
|
21
21
|
def clean_up_active_record_models
|
22
22
|
@user_model.delete_all
|
23
23
|
@task_model.delete_all
|
24
|
-
end
|
24
|
+
end
|
25
25
|
|
26
26
|
def setup_mongoid_models
|
27
27
|
@orm_for_testing = :mongoid
|
@@ -49,6 +49,30 @@ module SimpleFixtures
|
|
49
49
|
@user_model.delete_all
|
50
50
|
end
|
51
51
|
|
52
|
+
def setup_roflscale_models
|
53
|
+
@orm_for_testing = :vanilla
|
54
|
+
@user_model = VanillaUser
|
55
|
+
@task_model = VanillaTask
|
56
|
+
@profile_model = VanillaProfile
|
57
|
+
@untouched_model = VanillaUntouched
|
58
|
+
|
59
|
+
@luke = @user_model.new({ :first_name => 'Luke', :last_name => 'Skywalker', :age => 25, :active => true })
|
60
|
+
@han = @user_model.new({ :first_name => 'Han', :last_name => 'Solo', :age => 35, :active => true })
|
61
|
+
@leia = @user_model.new({ :first_name => 'Princess', :last_name => 'Leia', :age => 25, :active => false })
|
62
|
+
|
63
|
+
@luke.profile = @profile_model.new({ :user => @luke, :avatar => 'picard.jpg', :homepage => 'lukasarts.com' })
|
64
|
+
|
65
|
+
@destroy_deathstar = @task_model.new({ :user => @luke, :heading => "Destroy Deathstar", :description => "XWing, Shoot, BlowUp", :time_spent => 30, :done => true })
|
66
|
+
@study_with_yoda = @task_model.new({ :user => @luke, :heading => "Study with Yoda", :description => "Jedi Stuff, ya know", :time_spent => 60, :done => true })
|
67
|
+
@win_rebellion = @task_model.new({ :user => @luke, :heading => "Win Rebellion", :description => "no idea yet...", :time_spent => 180, :done => false })
|
68
|
+
|
69
|
+
@luke.tasks << @destroy_deathstar << @study_with_yoda << @win_rebellion
|
70
|
+
end
|
71
|
+
|
72
|
+
def clean_up_roflscale_models
|
73
|
+
# nothing to do ;)
|
74
|
+
end
|
75
|
+
|
52
76
|
end
|
53
77
|
|
54
78
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 7
|
10
|
+
version: 0.3.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Christian B\xC3\xA4uerlein"
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-06-13 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -134,6 +134,7 @@ files:
|
|
134
134
|
- spec/controllers/users_controller_spec.rb
|
135
135
|
- spec/models/active_record_spec.rb
|
136
136
|
- spec/models/mongoid_spec.rb
|
137
|
+
- spec/models/vanilla_ruby_spec.rb
|
137
138
|
- spec/rails_app/.gitignore
|
138
139
|
- spec/rails_app/Rakefile
|
139
140
|
- spec/rails_app/app/controllers/application_controller.rb
|
@@ -148,6 +149,10 @@ files:
|
|
148
149
|
- spec/rails_app/app/models/task.rb
|
149
150
|
- spec/rails_app/app/models/untouched.rb
|
150
151
|
- spec/rails_app/app/models/user.rb
|
152
|
+
- spec/rails_app/app/models/vanilla_profile.rb
|
153
|
+
- spec/rails_app/app/models/vanilla_task.rb
|
154
|
+
- spec/rails_app/app/models/vanilla_untouched.rb
|
155
|
+
- spec/rails_app/app/models/vanilla_user.rb
|
151
156
|
- spec/rails_app/app/views/layouts/application.html.erb
|
152
157
|
- spec/rails_app/config.ru
|
153
158
|
- spec/rails_app/config/application.rb
|
@@ -191,6 +196,7 @@ files:
|
|
191
196
|
- spec/support/controller_examples.rb
|
192
197
|
- spec/support/it_supports.rb
|
193
198
|
- spec/support/model_examples/associations.rb
|
199
|
+
- spec/support/model_examples/callbacks.rb
|
194
200
|
- spec/support/model_examples/closures.rb
|
195
201
|
- spec/support/model_examples/conditional_if.rb
|
196
202
|
- spec/support/model_examples/conditional_unless.rb
|
@@ -244,6 +250,7 @@ test_files:
|
|
244
250
|
- spec/controllers/users_controller_spec.rb
|
245
251
|
- spec/models/active_record_spec.rb
|
246
252
|
- spec/models/mongoid_spec.rb
|
253
|
+
- spec/models/vanilla_ruby_spec.rb
|
247
254
|
- spec/rails_app/.gitignore
|
248
255
|
- spec/rails_app/Rakefile
|
249
256
|
- spec/rails_app/app/controllers/application_controller.rb
|
@@ -258,6 +265,10 @@ test_files:
|
|
258
265
|
- spec/rails_app/app/models/task.rb
|
259
266
|
- spec/rails_app/app/models/untouched.rb
|
260
267
|
- spec/rails_app/app/models/user.rb
|
268
|
+
- spec/rails_app/app/models/vanilla_profile.rb
|
269
|
+
- spec/rails_app/app/models/vanilla_task.rb
|
270
|
+
- spec/rails_app/app/models/vanilla_untouched.rb
|
271
|
+
- spec/rails_app/app/models/vanilla_user.rb
|
261
272
|
- spec/rails_app/app/views/layouts/application.html.erb
|
262
273
|
- spec/rails_app/config.ru
|
263
274
|
- spec/rails_app/config/application.rb
|
@@ -301,6 +312,7 @@ test_files:
|
|
301
312
|
- spec/support/controller_examples.rb
|
302
313
|
- spec/support/it_supports.rb
|
303
314
|
- spec/support/model_examples/associations.rb
|
315
|
+
- spec/support/model_examples/callbacks.rb
|
304
316
|
- spec/support/model_examples/closures.rb
|
305
317
|
- spec/support/model_examples/conditional_if.rb
|
306
318
|
- spec/support/model_examples/conditional_unless.rb
|