puffer 0.0.1 → 0.0.2
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/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +130 -0
- data/Rakefile +3 -2
- data/VERSION +1 -0
- data/app/views/layouts/puffer.html.erb +38 -0
- data/app/views/puffer/_form.html.erb +19 -0
- data/app/views/puffer/associated/_many.html.erb +56 -0
- data/app/views/puffer/associated/_one.html.erb +47 -0
- data/app/views/puffer/associated/many.rjs +1 -0
- data/app/views/puffer/associated/one.rjs +1 -0
- data/app/views/puffer/association/_many.html.erb +7 -0
- data/app/views/puffer/association/_one.html.erb +16 -0
- data/app/views/puffer/edit.html.erb +20 -0
- data/app/views/puffer/index.html.erb +83 -0
- data/app/views/puffer/new.html.erb +18 -0
- data/app/views/puffer/show.html.erb +29 -0
- data/app/views/puffer/toggle.rjs +1 -0
- data/autotest/discover.rb +2 -0
- data/puffer.gemspec +217 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/admin/categories_controller.rb +3 -0
- data/spec/dummy/app/controllers/admin/posts_controller.rb +3 -0
- data/spec/dummy/app/controllers/admin/profiles_controller.rb +3 -0
- data/spec/dummy/app/controllers/admin/tags_controller.rb +3 -0
- data/spec/dummy/app/controllers/admin/users_controller.rb +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/category.rb +4 -0
- data/spec/dummy/app/models/post.rb +7 -0
- data/spec/dummy/app/models/post_category.rb +4 -0
- data/spec/dummy/app/models/profile.rb +5 -0
- data/spec/dummy/app/models/tag.rb +3 -0
- data/spec/dummy/app/models/tagging.rb +4 -0
- data/spec/dummy/app/models/user.rb +4 -0
- data/spec/dummy/app/views/admin/users/index.html.erb +0 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +45 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +26 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +35 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +81 -0
- data/spec/dummy/db/migrate/20100930132559_create_admin_users.rb +14 -0
- data/spec/dummy/db/migrate/20100930132656_create_admin_posts.rb +15 -0
- data/spec/dummy/db/migrate/20100930132726_create_admin_categories.rb +13 -0
- data/spec/dummy/db/migrate/20100930132837_create_post_categories.rb +14 -0
- data/spec/dummy/db/migrate/20100930133425_create_admin_profiles.rb +16 -0
- data/spec/dummy/db/migrate/20101011155830_create_tags.rb +13 -0
- data/spec/dummy/db/migrate/20101011160326_create_taggings.rb +16 -0
- data/spec/dummy/db/schema.rb +68 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/javascripts/application.js +2 -0
- data/spec/dummy/public/javascripts/controls.js +965 -0
- data/spec/dummy/public/javascripts/dragdrop.js +974 -0
- data/spec/dummy/public/javascripts/effects.js +1123 -0
- data/spec/dummy/public/javascripts/prototype.js +6001 -0
- data/spec/dummy/public/javascripts/rails.js +175 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/fabricators/categories_fabricator.rb +3 -0
- data/spec/fabricators/posts_fabricator.rb +8 -0
- data/spec/fabricators/profiles_fabricator.rb +9 -0
- data/spec/fabricators/tags_fabricator.rb +3 -0
- data/spec/fabricators/users_fabricator.rb +12 -0
- data/spec/integration/navigation_spec.rb +9 -0
- data/spec/lib/params_spec.rb +119 -0
- data/spec/lib/render_fallback_spec.rb +17 -0
- data/spec/lib/resource/routing_spec.rb +67 -0
- data/spec/lib/resource_spec.rb +198 -0
- data/spec/puffer_spec.rb +7 -0
- data/spec/spec_helper.rb +34 -0
- metadata +283 -26
@@ -0,0 +1,175 @@
|
|
1
|
+
(function() {
|
2
|
+
// Technique from Juriy Zaytsev
|
3
|
+
// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
|
4
|
+
function isEventSupported(eventName) {
|
5
|
+
var el = document.createElement('div');
|
6
|
+
eventName = 'on' + eventName;
|
7
|
+
var isSupported = (eventName in el);
|
8
|
+
if (!isSupported) {
|
9
|
+
el.setAttribute(eventName, 'return;');
|
10
|
+
isSupported = typeof el[eventName] == 'function';
|
11
|
+
}
|
12
|
+
el = null;
|
13
|
+
return isSupported;
|
14
|
+
}
|
15
|
+
|
16
|
+
function isForm(element) {
|
17
|
+
return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
|
18
|
+
}
|
19
|
+
|
20
|
+
function isInput(element) {
|
21
|
+
if (Object.isElement(element)) {
|
22
|
+
var name = element.nodeName.toUpperCase()
|
23
|
+
return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
|
24
|
+
}
|
25
|
+
else return false
|
26
|
+
}
|
27
|
+
|
28
|
+
var submitBubbles = isEventSupported('submit'),
|
29
|
+
changeBubbles = isEventSupported('change')
|
30
|
+
|
31
|
+
if (!submitBubbles || !changeBubbles) {
|
32
|
+
// augment the Event.Handler class to observe custom events when needed
|
33
|
+
Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
|
34
|
+
function(init, element, eventName, selector, callback) {
|
35
|
+
init(element, eventName, selector, callback)
|
36
|
+
// is the handler being attached to an element that doesn't support this event?
|
37
|
+
if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
|
38
|
+
(!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
|
39
|
+
// "submit" => "emulated:submit"
|
40
|
+
this.eventName = 'emulated:' + this.eventName
|
41
|
+
}
|
42
|
+
}
|
43
|
+
)
|
44
|
+
}
|
45
|
+
|
46
|
+
if (!submitBubbles) {
|
47
|
+
// discover forms on the page by observing focus events which always bubble
|
48
|
+
document.on('focusin', 'form', function(focusEvent, form) {
|
49
|
+
// special handler for the real "submit" event (one-time operation)
|
50
|
+
if (!form.retrieve('emulated:submit')) {
|
51
|
+
form.on('submit', function(submitEvent) {
|
52
|
+
var emulated = form.fire('emulated:submit', submitEvent, true)
|
53
|
+
// if custom event received preventDefault, cancel the real one too
|
54
|
+
if (emulated.returnValue === false) submitEvent.preventDefault()
|
55
|
+
})
|
56
|
+
form.store('emulated:submit', true)
|
57
|
+
}
|
58
|
+
})
|
59
|
+
}
|
60
|
+
|
61
|
+
if (!changeBubbles) {
|
62
|
+
// discover form inputs on the page
|
63
|
+
document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
|
64
|
+
// special handler for real "change" events
|
65
|
+
if (!input.retrieve('emulated:change')) {
|
66
|
+
input.on('change', function(changeEvent) {
|
67
|
+
input.fire('emulated:change', changeEvent, true)
|
68
|
+
})
|
69
|
+
input.store('emulated:change', true)
|
70
|
+
}
|
71
|
+
})
|
72
|
+
}
|
73
|
+
|
74
|
+
function handleRemote(element) {
|
75
|
+
var method, url, params;
|
76
|
+
|
77
|
+
var event = element.fire("ajax:before");
|
78
|
+
if (event.stopped) return false;
|
79
|
+
|
80
|
+
if (element.tagName.toLowerCase() === 'form') {
|
81
|
+
method = element.readAttribute('method') || 'post';
|
82
|
+
url = element.readAttribute('action');
|
83
|
+
params = element.serialize();
|
84
|
+
} else {
|
85
|
+
method = element.readAttribute('data-method') || 'get';
|
86
|
+
url = element.readAttribute('href');
|
87
|
+
params = {};
|
88
|
+
}
|
89
|
+
|
90
|
+
new Ajax.Request(url, {
|
91
|
+
method: method,
|
92
|
+
parameters: params,
|
93
|
+
evalScripts: true,
|
94
|
+
|
95
|
+
onComplete: function(request) { element.fire("ajax:complete", request); },
|
96
|
+
onSuccess: function(request) { element.fire("ajax:success", request); },
|
97
|
+
onFailure: function(request) { element.fire("ajax:failure", request); }
|
98
|
+
});
|
99
|
+
|
100
|
+
element.fire("ajax:after");
|
101
|
+
}
|
102
|
+
|
103
|
+
function handleMethod(element) {
|
104
|
+
var method = element.readAttribute('data-method'),
|
105
|
+
url = element.readAttribute('href'),
|
106
|
+
csrf_param = $$('meta[name=csrf-param]')[0],
|
107
|
+
csrf_token = $$('meta[name=csrf-token]')[0];
|
108
|
+
|
109
|
+
var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
|
110
|
+
element.parentNode.insert(form);
|
111
|
+
|
112
|
+
if (method !== 'post') {
|
113
|
+
var field = new Element('input', { type: 'hidden', name: '_method', value: method });
|
114
|
+
form.insert(field);
|
115
|
+
}
|
116
|
+
|
117
|
+
if (csrf_param) {
|
118
|
+
var param = csrf_param.readAttribute('content'),
|
119
|
+
token = csrf_token.readAttribute('content'),
|
120
|
+
field = new Element('input', { type: 'hidden', name: param, value: token });
|
121
|
+
form.insert(field);
|
122
|
+
}
|
123
|
+
|
124
|
+
form.submit();
|
125
|
+
}
|
126
|
+
|
127
|
+
|
128
|
+
document.on("click", "*[data-confirm]", function(event, element) {
|
129
|
+
var message = element.readAttribute('data-confirm');
|
130
|
+
if (!confirm(message)) event.stop();
|
131
|
+
});
|
132
|
+
|
133
|
+
document.on("click", "a[data-remote]", function(event, element) {
|
134
|
+
if (event.stopped) return;
|
135
|
+
handleRemote(element);
|
136
|
+
event.stop();
|
137
|
+
});
|
138
|
+
|
139
|
+
document.on("click", "a[data-method]", function(event, element) {
|
140
|
+
if (event.stopped) return;
|
141
|
+
handleMethod(element);
|
142
|
+
event.stop();
|
143
|
+
});
|
144
|
+
|
145
|
+
document.on("submit", function(event) {
|
146
|
+
var element = event.findElement(),
|
147
|
+
message = element.readAttribute('data-confirm');
|
148
|
+
if (message && !confirm(message)) {
|
149
|
+
event.stop();
|
150
|
+
return false;
|
151
|
+
}
|
152
|
+
|
153
|
+
var inputs = element.select("input[type=submit][data-disable-with]");
|
154
|
+
inputs.each(function(input) {
|
155
|
+
input.disabled = true;
|
156
|
+
input.writeAttribute('data-original-value', input.value);
|
157
|
+
input.value = input.readAttribute('data-disable-with');
|
158
|
+
});
|
159
|
+
|
160
|
+
var element = event.findElement("form[data-remote]");
|
161
|
+
if (element) {
|
162
|
+
handleRemote(element);
|
163
|
+
event.stop();
|
164
|
+
}
|
165
|
+
});
|
166
|
+
|
167
|
+
document.on("ajax:after", "form", function(event, element) {
|
168
|
+
var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
|
169
|
+
inputs.each(function(input) {
|
170
|
+
input.value = input.readAttribute('data-original-value');
|
171
|
+
input.removeAttribute('data-original-value');
|
172
|
+
input.disabled = false;
|
173
|
+
});
|
174
|
+
});
|
175
|
+
})();
|
File without changes
|
@@ -0,0 +1,6 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
|
+
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
6
|
+
require 'rails/commands'
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Fabricator :user do
|
2
|
+
email {Forgery::Internet.email_address}
|
3
|
+
password '123456'
|
4
|
+
end
|
5
|
+
|
6
|
+
Fabricator :user_with_profile, :from => :user do
|
7
|
+
profile! { Fabricate :profile }
|
8
|
+
end
|
9
|
+
|
10
|
+
Fabricator :user_with_profile_and_tags, :from => :user do
|
11
|
+
profile! { Fabricate :profile_with_tags }
|
12
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Params" do
|
4
|
+
|
5
|
+
include RSpec::Rails::RequestExampleGroup
|
6
|
+
|
7
|
+
=begin
|
8
|
+
params_examples = [
|
9
|
+
[:admin_users_url, true, [], [:profile, :posts]]
|
10
|
+
]
|
11
|
+
|
12
|
+
params_examples.each do |(url, plural, ancestors, children)|
|
13
|
+
describe "GET #{url}" do
|
14
|
+
it "should set proper params" do
|
15
|
+
get send(url)
|
16
|
+
|
17
|
+
request.params[:plural].should == plural
|
18
|
+
request.params[:ancestors].should == ancestors
|
19
|
+
request.params[:children].should == children
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
=end
|
24
|
+
|
25
|
+
before :each do
|
26
|
+
@resource = mock(Puffer::Resource, :collection => [], :member => nil, :template => {:nothing => true})
|
27
|
+
Puffer::Resource.stub(:new) {@resource}
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "GET /admin/users" do
|
31
|
+
it "should set proper params" do
|
32
|
+
get admin_users_url
|
33
|
+
|
34
|
+
request.params[:plural].should be_true
|
35
|
+
request.params[:ancestors].should == []
|
36
|
+
request.params[:children].should == [:profile, :posts]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "GET /admin/users/1/profile" do
|
41
|
+
it "should set proper params" do
|
42
|
+
get admin_user_profile_url(1)
|
43
|
+
|
44
|
+
request.params[:plural].should be_false
|
45
|
+
request.params[:ancestors].should == [:users]
|
46
|
+
request.params[:children].should == [:tags]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "get /admin/users/1/posts" do
|
51
|
+
it "should set proper params" do
|
52
|
+
get admin_user_posts_url(1)
|
53
|
+
|
54
|
+
request.params[:plural].should be_true
|
55
|
+
request.params[:ancestors].should == [:users]
|
56
|
+
request.params[:children].should == [:categories, :tags]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "GET /admin/users/1/posts/1/categories" do
|
61
|
+
it "should set proper params" do
|
62
|
+
get admin_user_post_categories_url(1, 1)
|
63
|
+
|
64
|
+
request.params[:plural].should be_true
|
65
|
+
request.params[:ancestors].should == [:users, :posts]
|
66
|
+
request.params[:children].should == []
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "GET /profiles" do
|
71
|
+
it "should set proper params" do
|
72
|
+
get admin_profiles_url
|
73
|
+
|
74
|
+
request.params[:plural].should be_true
|
75
|
+
request.params[:ancestors].should == []
|
76
|
+
request.params[:children].should == [:tags]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "GET /posts" do
|
81
|
+
it "should set proper params" do
|
82
|
+
get admin_posts_url
|
83
|
+
|
84
|
+
request.params[:plural].should be_true
|
85
|
+
request.params[:ancestors].should == []
|
86
|
+
request.params[:children].should == [:user, :categories]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "GET /admin/posts/1/categories" do
|
91
|
+
it "should set proper params" do
|
92
|
+
get admin_post_categories_url(1)
|
93
|
+
|
94
|
+
request.params[:plural].should be_true
|
95
|
+
request.params[:ancestors].should == [:posts]
|
96
|
+
request.params[:children].should == []
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "GET /categories" do
|
101
|
+
it "should set proper params" do
|
102
|
+
get admin_categories_url
|
103
|
+
|
104
|
+
request.params[:plural].should be_true
|
105
|
+
request.params[:ancestors].should == []
|
106
|
+
request.params[:children].should == [:posts]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "GET /admin/categories/1/posts" do
|
111
|
+
it "should set proper params" do
|
112
|
+
get admin_category_posts_url(1)
|
113
|
+
|
114
|
+
request.params[:plural].should be_true
|
115
|
+
request.params[:ancestors].should == [:categories]
|
116
|
+
request.params[:children].should == []
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Rendering" do
|
4
|
+
|
5
|
+
include RSpec::Rails::RequestExampleGroup
|
6
|
+
|
7
|
+
it "should render native temptate if exists" do
|
8
|
+
get admin_users_url
|
9
|
+
response.should render_template('admin/users/index')
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should fallback to puffer template if native not exists" do
|
13
|
+
get admin_posts_url
|
14
|
+
response.should render_template('puffer/index')
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Puffer::Resource do
|
4
|
+
|
5
|
+
include RSpec::Rails::RequestExampleGroup
|
6
|
+
|
7
|
+
it "regular path" do
|
8
|
+
@category = Fabricate :category
|
9
|
+
@mock_category = mock_model Category, :id => 42
|
10
|
+
|
11
|
+
get admin_category_path(@category)
|
12
|
+
resource = Puffer::Resource.new request.params.merge(:controller => 'admin/categories', :action => 'show'), request
|
13
|
+
|
14
|
+
resource.index_path.should == admin_categories_path
|
15
|
+
resource.path.should == admin_category_path(@category)
|
16
|
+
resource.path(@mock_category).should == admin_category_path(@mock_category)
|
17
|
+
resource.new_path.should == new_admin_category_path
|
18
|
+
resource.edit_path.should == edit_admin_category_path(@category)
|
19
|
+
resource.edit_path(@mock_category).should == edit_admin_category_path(@mock_category)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "plural path" do
|
23
|
+
@post = Fabricate :post_with_categories
|
24
|
+
@category = @post.categories.first
|
25
|
+
@mock_category = mock_model Category, :id => 42
|
26
|
+
|
27
|
+
get admin_post_category_path(@post, @category)
|
28
|
+
resource = Puffer::Resource.new request.params.merge(:controller => 'admin/categories', :action => 'show'), request
|
29
|
+
|
30
|
+
resource.index_path.should == admin_post_categories_path(@post)
|
31
|
+
resource.path.should == admin_post_category_path(@post, @category)
|
32
|
+
resource.path(@mock_category).should == admin_post_category_path(@post, @mock_category)
|
33
|
+
resource.new_path.should == new_admin_post_category_path(@post)
|
34
|
+
resource.edit_path.should == edit_admin_post_category_path(@post, @category)
|
35
|
+
resource.edit_path(@mock_category).should == edit_admin_post_category_path(@post, @mock_category)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "singular path" do
|
39
|
+
@user = Fabricate :user_with_profile
|
40
|
+
@profile = @user.profile
|
41
|
+
|
42
|
+
get admin_user_profile_path(@user)
|
43
|
+
resource = Puffer::Resource.new request.params.merge(:controller => 'admin/profiles', :action => 'show'), request
|
44
|
+
|
45
|
+
resource.index_path.should == admin_user_profile_path(@user)
|
46
|
+
resource.path.should == admin_user_profile_path(@user)
|
47
|
+
resource.new_path.should == new_admin_user_profile_path(@user)
|
48
|
+
resource.edit_path.should == edit_admin_user_profile_path(@user)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "singular parent path" do
|
52
|
+
@user = Fabricate :user_with_profile_and_tags
|
53
|
+
@tag = @user.profile.tags.first
|
54
|
+
@mock_tag = mock_model Tag, :id => 42
|
55
|
+
|
56
|
+
get admin_user_profile_tag_path(@user, @tag)
|
57
|
+
resource = Puffer::Resource.new request.params.merge(:controller => 'admin/tags', :action => 'show'), request
|
58
|
+
|
59
|
+
resource.index_path.should == admin_user_profile_tags_path(@user)
|
60
|
+
resource.path.should == admin_user_profile_tag_path(@user, @tag)
|
61
|
+
resource.path(@mock_tag).should == admin_user_profile_tag_path(@user, @mock_tag)
|
62
|
+
resource.new_path.should == new_admin_user_profile_tag_path(@user)
|
63
|
+
resource.edit_path.should == edit_admin_user_profile_tag_path(@user, @tag)
|
64
|
+
resource.edit_path(@mock_tag).should == edit_admin_user_profile_tag_path(@user, @mock_tag)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Puffer::Resource do
|
4
|
+
|
5
|
+
def default_params
|
6
|
+
ActiveSupport::HashWithIndifferentAccess.new(:controller => 'admin/categories', :action => 'index', :plural => true, :ancestors => [], :children => [])
|
7
|
+
end
|
8
|
+
|
9
|
+
def plain_params
|
10
|
+
ActiveSupport::HashWithIndifferentAccess.new(:plural => true, :ancestors => [], :children => [])
|
11
|
+
end
|
12
|
+
|
13
|
+
it "no tree" do
|
14
|
+
resource = Puffer::Resource.new default_params
|
15
|
+
resource.parent.should be_nil
|
16
|
+
resource.children.should be_empty
|
17
|
+
end
|
18
|
+
|
19
|
+
it "full tree" do
|
20
|
+
resource = Puffer::Resource.new default_params.merge(:ancestors => [:posts], :children => [:users, :posts])
|
21
|
+
resource.parent.should_not be_nil
|
22
|
+
resource.ancestors.count.should == 1
|
23
|
+
resource.children.count.should == 2
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#parent" do
|
27
|
+
|
28
|
+
it "common params" do
|
29
|
+
resource = Puffer::Resource.new default_params.merge(:ancestors => [:users, :posts], :user_id => 37, :post_id => 42)
|
30
|
+
parent = resource.parent
|
31
|
+
|
32
|
+
parent.params.should == plain_params.merge(:ancestors => [:users], :user_id => 37, :id => 42)
|
33
|
+
parent.controller_name.should == 'posts'
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#children" do
|
39
|
+
|
40
|
+
it "common params" do
|
41
|
+
resource = Puffer::Resource.new default_params.merge(:controller => 'admin/posts', :ancestors => [:users], :children => [:categories], :user_id => 37)
|
42
|
+
child = resource.children.first
|
43
|
+
|
44
|
+
child.params.should == plain_params.merge(:ancestors => [:users, :posts], :user_id => 37)
|
45
|
+
child.controller_name.should == 'categories'
|
46
|
+
end
|
47
|
+
|
48
|
+
it "plural params" do
|
49
|
+
resource = Puffer::Resource.new default_params.merge(:controller => 'admin/users', :children => [:profile])
|
50
|
+
child = resource.children.first
|
51
|
+
|
52
|
+
child.params.should == plain_params.merge(:ancestors => [:users], :plural => false)
|
53
|
+
child.controller_name.should == 'profiles'
|
54
|
+
end
|
55
|
+
|
56
|
+
it "params with :id" do
|
57
|
+
resource = Puffer::Resource.new default_params.merge(:controller => 'admin/posts', :ancestors => [:users], :children => [:categories], :user_id => 37, :id => 42)
|
58
|
+
child = resource.children.first
|
59
|
+
|
60
|
+
child.params.should == plain_params.merge(:ancestors => [:users, :posts], :user_id => 37, :post_id => 42)
|
61
|
+
child.controller_name.should == 'categories'
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#collection" do
|
67
|
+
|
68
|
+
before :all do
|
69
|
+
@post = Fabricate :post_with_categories
|
70
|
+
@category = Fabricate :category
|
71
|
+
@user = Fabricate :user_with_profile_and_tags
|
72
|
+
end
|
73
|
+
|
74
|
+
it "no parent" do
|
75
|
+
resource = Puffer::Resource.new default_params
|
76
|
+
|
77
|
+
resource.collection.should == Category.limit(30).all
|
78
|
+
end
|
79
|
+
|
80
|
+
it "plural parent" do
|
81
|
+
resource = Puffer::Resource.new default_params.merge(:ancestors => [:posts], :post_id => 42)
|
82
|
+
|
83
|
+
Post.stub(:find).with(42) {@post}
|
84
|
+
resource.collection.should == @post.categories.limit(30).all
|
85
|
+
end
|
86
|
+
|
87
|
+
it "singular parent" do
|
88
|
+
resource = Puffer::Resource.new default_params.merge(:controller => 'admin/tags', :ancestors => [:users, :profile], :user_id => 42)
|
89
|
+
|
90
|
+
User.stub(:find).with(42) {@user}
|
91
|
+
resource.collection.should == @user.profile.tags.limit(30).all
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "#member" do
|
97
|
+
|
98
|
+
before :all do
|
99
|
+
@post = Fabricate :post_with_categories
|
100
|
+
@category = Fabricate :category
|
101
|
+
@user = Fabricate :user_with_profile_and_tags
|
102
|
+
end
|
103
|
+
|
104
|
+
it "no parent" do
|
105
|
+
resource = Puffer::Resource.new default_params.merge(:id => 42)
|
106
|
+
|
107
|
+
Category.stub(:find).with(42) {@category}
|
108
|
+
resource.member.should == @category
|
109
|
+
end
|
110
|
+
|
111
|
+
it "plural parent" do
|
112
|
+
resource = Puffer::Resource.new default_params.merge(:ancestors => [:posts], :post_id => 42, :id => 37)
|
113
|
+
|
114
|
+
@categories = @post.categories
|
115
|
+
|
116
|
+
Post.stub(:find).with(42) {@post}
|
117
|
+
@categories.stub(:find).with(37) {@category}
|
118
|
+
resource.member.should == @category
|
119
|
+
end
|
120
|
+
|
121
|
+
it "singular" do
|
122
|
+
resource = Puffer::Resource.new default_params.merge(:controller => 'admin/profiles', :plural => false, :ancestors => [:users], :user_id => 42)
|
123
|
+
|
124
|
+
@profile = @user.profile
|
125
|
+
|
126
|
+
User.stub(:find).with(42) {@user}
|
127
|
+
@user.stub(:profile) {@profile}
|
128
|
+
|
129
|
+
resource.member.should == @profile
|
130
|
+
end
|
131
|
+
|
132
|
+
it "singular parent" do
|
133
|
+
resource = Puffer::Resource.new default_params.merge(:controller => 'admin/tags', :ancestors => [:users, :profile], :user_id => 42, :id => 37)
|
134
|
+
|
135
|
+
@profile = @user.profile
|
136
|
+
@tag = @profile.tags.first
|
137
|
+
|
138
|
+
User.stub(:find).with(42) {@user}
|
139
|
+
@user.stub(:profile) {@profile}
|
140
|
+
@profile.tags.stub(:find).with(37) {@tag}
|
141
|
+
|
142
|
+
resource.member.should == @tag
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "#new_member" do
|
148
|
+
|
149
|
+
before :all do
|
150
|
+
@post = Fabricate :post_with_categories
|
151
|
+
@category = Fabricate :category
|
152
|
+
@user = Fabricate :user_with_profile_and_tags
|
153
|
+
end
|
154
|
+
|
155
|
+
it "no parent" do
|
156
|
+
resource = Puffer::Resource.new default_params
|
157
|
+
|
158
|
+
Category.stub(:new) {@category}
|
159
|
+
resource.new_member.should == @category
|
160
|
+
end
|
161
|
+
|
162
|
+
it "plural parent" do
|
163
|
+
resource = Puffer::Resource.new default_params.merge(:ancestors => [:posts], :post_id => 42)
|
164
|
+
|
165
|
+
@categories = @post.categories
|
166
|
+
|
167
|
+
Post.stub(:find).with(42) {@post}
|
168
|
+
@categories.stub(:new) {@category}
|
169
|
+
resource.new_member.should == @category
|
170
|
+
end
|
171
|
+
|
172
|
+
it "singular" do
|
173
|
+
resource = Puffer::Resource.new default_params.merge(:controller => 'admin/profiles', :plural => false, :ancestors => [:users], :user_id => 42)
|
174
|
+
|
175
|
+
@profile = @user.profile
|
176
|
+
|
177
|
+
User.stub(:find).with(42) {@user}
|
178
|
+
@user.stub(:build_profile) {@profile}
|
179
|
+
|
180
|
+
resource.new_member.should == @profile
|
181
|
+
end
|
182
|
+
|
183
|
+
it "singular parent" do
|
184
|
+
resource = Puffer::Resource.new default_params.merge(:controller => 'admin/tags', :ancestors => [:users, :profile], :user_id => 42)
|
185
|
+
|
186
|
+
@profile = @user.profile
|
187
|
+
@tag = @profile.tags.first
|
188
|
+
|
189
|
+
User.stub(:find).with(42) {@user}
|
190
|
+
@user.stub(:profile) {@profile}
|
191
|
+
@profile.tags.stub(:new) {@tag}
|
192
|
+
|
193
|
+
resource.new_member.should == @tag
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|