cornerstone 0.0.1 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/.rspec +1 -0
- data/Gemfile +23 -0
- data/Gemfile.lock +168 -0
- data/Guardfile +22 -0
- data/README.rdoc +4 -1
- data/Rakefile +11 -1
- data/TODO +11 -0
- data/VERSION +1 -0
- data/app/assets/images/.gitkeep +0 -0
- data/app/assets/javascripts/.gitkeep +0 -0
- data/app/assets/javascripts/cornerstone.js +11 -0
- data/app/assets/javascripts/cornerstone/discussions.js +2 -0
- data/app/assets/javascripts/cornerstone/help.js +2 -0
- data/app/assets/stylesheets/.gitkeep +0 -0
- data/app/assets/stylesheets/cornerstone.css +8 -0
- data/app/assets/stylesheets/cornerstone/discussions.css +4 -0
- data/app/assets/stylesheets/cornerstone/help.css +4 -0
- data/app/controllers/.gitkeep +0 -0
- data/app/controllers/cornerstone/admin/application_controller.rb +7 -0
- data/app/controllers/cornerstone/admin/articles_controller.rb +61 -0
- data/app/controllers/cornerstone/admin/categories_controller.rb +46 -0
- data/app/controllers/cornerstone/admin/discussions_controller.rb +32 -0
- data/app/controllers/cornerstone/application_controller.rb +6 -0
- data/app/controllers/cornerstone/discussions_controller.rb +58 -0
- data/app/controllers/cornerstone/help_controller.rb +11 -0
- data/app/controllers/cornerstone/posts_controller.rb +66 -0
- data/app/helpers/.gitkeep +0 -0
- data/app/helpers/cornerstone/application_helper.rb +5 -0
- data/app/helpers/cornerstone/discussions_helper.rb +16 -0
- data/app/helpers/cornerstone/help_helper.rb +4 -0
- data/app/mailers/cornerstone/cornerstone_mailer.rb +31 -0
- data/app/models/.gitkeep +0 -0
- data/app/models/cornerstone/article.rb +20 -0
- data/app/models/cornerstone/category.rb +45 -0
- data/app/models/cornerstone/discussion.rb +90 -0
- data/app/models/cornerstone/post.rb +103 -0
- data/app/models/cornerstone/post_observer.rb +23 -0
- data/app/views/.gitkeep +0 -0
- data/app/views/cornerstone/admin/articles/_article.html.erb +9 -0
- data/app/views/cornerstone/admin/articles/_form.html.erb +22 -0
- data/app/views/cornerstone/admin/articles/edit.html.erb +7 -0
- data/app/views/cornerstone/admin/articles/index.html.erb +25 -0
- data/app/views/cornerstone/admin/articles/new.html.erb +6 -0
- data/app/views/cornerstone/admin/articles/show.html.erb +4 -0
- data/app/views/cornerstone/admin/categories/_category.html.erb +12 -0
- data/app/views/cornerstone/admin/categories/_form.html.erb +17 -0
- data/app/views/cornerstone/admin/categories/edit.html.erb +6 -0
- data/app/views/cornerstone/admin/categories/index.html.erb +11 -0
- data/app/views/cornerstone/admin/categories/new.html.erb +6 -0
- data/app/views/cornerstone/admin/discussions/edit.html.erb +7 -0
- data/app/views/cornerstone/cornerstone_mailer/new_discussion.html.erb +14 -0
- data/app/views/cornerstone/cornerstone_mailer/new_discussion.text.erb +5 -0
- data/app/views/cornerstone/cornerstone_mailer/new_discussion_user.html.erb +7 -0
- data/app/views/cornerstone/cornerstone_mailer/new_post.html.erb +7 -0
- data/app/views/cornerstone/cornerstone_mailer/new_post.text.erb +8 -0
- data/app/views/cornerstone/discussions/_discussion.html.erb +12 -0
- data/app/views/cornerstone/discussions/_discussion_category.html.erb +14 -0
- data/app/views/cornerstone/discussions/_form.html.erb +33 -0
- data/app/views/cornerstone/discussions/_latest_discussion.html.erb +4 -0
- data/app/views/cornerstone/discussions/categorical_index.html.erb +27 -0
- data/app/views/cornerstone/discussions/index.html.erb +25 -0
- data/app/views/cornerstone/discussions/new.html.erb +6 -0
- data/app/views/cornerstone/discussions/show.html.erb +19 -0
- data/app/views/cornerstone/help/index.html.erb +7 -0
- data/app/views/cornerstone/posts/_fields.html.erb +44 -0
- data/app/views/cornerstone/posts/_form.html.erb +19 -0
- data/app/views/cornerstone/posts/_post.html.erb +17 -0
- data/app/views/cornerstone/posts/edit.html.erb +9 -0
- data/app/views/cornerstone/shared/_errors.html.erb +11 -0
- data/app/views/cornerstone/shared/_flash_messages.html.erb +15 -0
- data/app/views/layouts/cornerstone/application.html.erb +16 -0
- data/config/cucumber.yml +8 -0
- data/config/locales/cornerstone.action_mailer.en.yml +9 -0
- data/config/routes.rb +24 -0
- data/cornerstone-0.0.1.gem +0 -0
- data/cornerstone.gemspec +33 -0
- data/db/migrate/20110723004024_create_cornerstone_discussions.rb +17 -0
- data/db/migrate/20110804190853_create_cornerstone_categories.rb +15 -0
- data/db/migrate/20110809233551_create_cornerstone_posts.rb +13 -0
- data/db/migrate/20111006172857_create_cornerstone_articles.rb +12 -0
- data/lib/cornerstone.rb +6 -0
- data/lib/cornerstone/acts_as_cornerstone_user.rb +79 -0
- data/lib/cornerstone/config.rb +33 -0
- data/lib/cornerstone/controller_additions.rb +25 -0
- data/lib/cornerstone/engine.rb +8 -1
- data/lib/cornerstone/exceptions.rb +16 -0
- data/lib/cornerstone/helpers.rb +35 -0
- data/lib/tasks/cucumber.rake +65 -0
- data/lib/templates/cornerstone_config.rb +31 -0
- data/script/cucumber +10 -0
- data/script/rails +7 -0
- data/spec/controllers/cornerstone/admin/articles_controller_spec.rb +250 -0
- data/spec/controllers/cornerstone/admin/categories_controller_spec.rb +205 -0
- data/spec/controllers/cornerstone/admin/discussions_controller_spec.rb +95 -0
- data/spec/controllers/cornerstone/application_controller_spec.rb +34 -0
- data/spec/controllers/cornerstone/discussions_controller_spec.rb +157 -0
- data/spec/controllers/cornerstone/help_controller_spec.rb +20 -0
- data/spec/controllers/cornerstone/posts_controller_spec.rb +212 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +9 -0
- data/spec/dummy/app/assets/javascripts/tester.js +2 -0
- data/spec/dummy/app/assets/stylesheets/application.css +7 -0
- data/spec/dummy/app/assets/stylesheets/tester.css +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/tester_controller.rb +7 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/helpers/tester_helper.rb +6 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/user.rb +23 -0
- data/spec/dummy/app/views/devise/confirmations/new.html.erb +12 -0
- data/spec/dummy/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
- data/spec/dummy/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
- data/spec/dummy/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
- data/spec/dummy/app/views/devise/passwords/edit.html.erb +16 -0
- data/spec/dummy/app/views/devise/passwords/new.html.erb +12 -0
- data/spec/dummy/app/views/devise/registrations/edit.html.erb +29 -0
- data/spec/dummy/app/views/devise/registrations/new.html.erb +22 -0
- data/spec/dummy/app/views/devise/sessions/new.html.erb +19 -0
- data/spec/dummy/app/views/devise/shared/_links.erb +25 -0
- data/spec/dummy/app/views/devise/unlocks/new.html.erb +12 -0
- data/spec/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/dummy/app/views/tester/index.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +42 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +28 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +31 -0
- data/spec/dummy/config/environments/production.rb +54 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cornerstone_config.rb +30 -0
- data/spec/dummy/config/initializers/devise.rb +204 -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/initializers/wrap_parameters.rb +12 -0
- data/spec/dummy/config/locales/devise.en.yml +53 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +65 -0
- data/spec/dummy/db/migrate/20110724011421_create_user.rb +11 -0
- data/spec/dummy/db/migrate/20110724194307_devise_create_users.rb +41 -0
- data/spec/dummy/db/migrate/20110804174004_add_name_to_user.rb +5 -0
- data/spec/dummy/db/schema.rb +76 -0
- data/spec/dummy/log/.gitkeep +0 -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/script/rails +6 -0
- data/spec/dummy/test/functional/tester_controller_test.rb +9 -0
- data/spec/dummy/test/unit/helpers/tester_helper_test.rb +4 -0
- data/spec/fixtures/cornerstone/cornerstone_mailer/new_discussion +3 -0
- data/spec/lib/cornerstone/acts_as_cornerstone_user_spec.rb +56 -0
- data/spec/lib/cornerstone/helpers_spec.rb +32 -0
- data/spec/mailers/cornerstone/cornerstone_mailer_spec.rb +55 -0
- data/spec/models/cornerstone/article_spec.rb +25 -0
- data/spec/models/cornerstone/category_spec.rb +97 -0
- data/spec/models/cornerstone/discussion_spec.rb +243 -0
- data/spec/models/cornerstone/post_observer_spec.rb +65 -0
- data/spec/models/cornerstone/post_spec.rb +210 -0
- data/spec/requests/emails_spec.rb +51 -0
- data/spec/requests/interact_discussions_spec.rb +103 -0
- data/spec/requests/manage_articles_spec.rb +59 -0
- data/spec/requests/manage_categories_spec.rb +64 -0
- data/spec/requests/view_home_spec.rb +26 -0
- data/spec/spec_helper.rb +40 -0
- data/spec/support/devise.rb +4 -0
- data/spec/support/factories.rb +62 -0
- data/spec/support/general_helper_methods.rb +20 -0
- data/spec/support/mailer_macros.rb +15 -0
- data/spec/support/mass_assignment.rb +46 -0
- data/tmp/log/development.log +0 -0
- metadata +301 -20
@@ -0,0 +1,243 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cornerstone::Discussion do
|
4
|
+
|
5
|
+
# == ACCESSIBILITY == #
|
6
|
+
context "Accessibility:" do
|
7
|
+
before do
|
8
|
+
@discussion = Factory(:discussion_w_user)
|
9
|
+
end
|
10
|
+
{:status => "Closed", :reply_count => 5}.each do |attr, value|
|
11
|
+
it "should not let me assign the ##{attr}" do
|
12
|
+
@discussion.should_not allow_mass_assignment_of(attr => value)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# == SCOPES == #
|
18
|
+
context "Scopes:" do
|
19
|
+
describe "#default" do
|
20
|
+
it "should not return private discussions" do
|
21
|
+
@discussion = Factory(:discussion_w_user, :privte => true)
|
22
|
+
Cornerstone::Discussion.all.size.should == 0
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#latest_for_category" do
|
27
|
+
before do
|
28
|
+
@target_cat = Factory(:category, :name => "Target Category")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should return the youngest discussions for the given category" do
|
32
|
+
d = Factory(:discussion_no_user, :category => @target_cat)
|
33
|
+
Cornerstone::Discussion.latest_for_category(@target_cat).should == [d]
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should not return the latest discussion for a different category" do
|
37
|
+
d = Factory(:discussion_w_user, :category => @target_cat,
|
38
|
+
:created_at => 3.hours.ago)
|
39
|
+
Factory(:discussion_w_user)
|
40
|
+
Cornerstone::Discussion.latest_for_category(@target_cat).should == [d]
|
41
|
+
end
|
42
|
+
|
43
|
+
it "provides the given number of results if available" do
|
44
|
+
6.times {Factory(:discussion_w_user, :category => @target_cat)}
|
45
|
+
Cornerstone::Discussion.latest_for_category(@target_cat, 5).size.should == 5
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
# == VALIDATIONS == #
|
52
|
+
|
53
|
+
context "validations" do
|
54
|
+
|
55
|
+
before do
|
56
|
+
@discussion = Factory.build(:discussion)
|
57
|
+
end
|
58
|
+
|
59
|
+
[:subject, :category].each do |attr|
|
60
|
+
it "requires a #{attr}" do
|
61
|
+
@discussion.send("#{attr}=", nil)
|
62
|
+
@discussion.should have(1).error_on(attr)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
it "#subject should be 50 characters or less" do
|
67
|
+
@discussion.subject = random_alphanumeric(51)
|
68
|
+
@discussion.should have(1).error_on(:subject)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should only include the hard coded status types" do
|
72
|
+
@discussion.status = "wiggles"
|
73
|
+
@discussion.should have(1).error_on(:status)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
# == CALLBACKS == #
|
79
|
+
context "Callbacks:" do
|
80
|
+
describe "Counter Cache" do
|
81
|
+
before do
|
82
|
+
@category = Factory(:category, :item_count => 1)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "is increased when a discussion is created" do
|
86
|
+
@category.item_count.should == 1
|
87
|
+
@discussion = Factory(:discussion_no_user, :category => @category)
|
88
|
+
@category.reload
|
89
|
+
@category.item_count.should == 2
|
90
|
+
end
|
91
|
+
|
92
|
+
it "is decreased when a discussion is deleted" do
|
93
|
+
@discussion = Factory(:discussion_no_user, :category => @category)
|
94
|
+
@category.reload
|
95
|
+
@category.item_count.should == 2
|
96
|
+
@discussion.destroy
|
97
|
+
@category.reload
|
98
|
+
@category.item_count.should == 1
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "#set_latest_discussion" do
|
103
|
+
before do
|
104
|
+
@category = Factory(:category)
|
105
|
+
end
|
106
|
+
|
107
|
+
pending "only updates on create"
|
108
|
+
|
109
|
+
context "with no current user" do
|
110
|
+
it "sets its category's latest discussion author name" do
|
111
|
+
@discussion = Factory(:discussion, :category => @category)
|
112
|
+
@post = Factory(:post_no_user, :name => "Joe Dinglebat",
|
113
|
+
:discussion => @discussion)
|
114
|
+
@category.reload
|
115
|
+
@category.latest_discussion_author.should == "Joe Dinglebat"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "with a current user" do
|
120
|
+
it "sets its category's latest discussion author name" do
|
121
|
+
@user = Factory(:user, :name => "Joe Jingleheimershmeidt")
|
122
|
+
@discussion = Factory(:discussion, :category => @category)
|
123
|
+
@post = Factory(:post_w_user, :user => @user, :discussion => @discussion)
|
124
|
+
@category.reload
|
125
|
+
@category.latest_discussion_author.should == "Joe Jingleheimershmeidt"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
it "sets its category's latest discussion date" do
|
130
|
+
time = 1.hour.from_now
|
131
|
+
Time.stub(:now) {time}
|
132
|
+
@discussion = Factory(:discussion_no_user, :category => @category)
|
133
|
+
@category.reload
|
134
|
+
@category.latest_discussion_date.should.to_s == time.to_s
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# == CLASS METHODS == #
|
141
|
+
|
142
|
+
# == INSTANCE METHODS == #
|
143
|
+
context "Instance Methods:" do
|
144
|
+
describe "#author_name" do
|
145
|
+
it "returns the first post's author name" do
|
146
|
+
@user = Factory(:user, :name => "Joe Jingleheimershmeidt")
|
147
|
+
@discussion = Factory(:discussion_w_user, :user => @user)
|
148
|
+
@discussion.author_name.should == "Joe Jingleheimershmeidt"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
describe "#closed?" do
|
152
|
+
it "returns true if the status is the last in the list" do
|
153
|
+
@discussion = Factory(:discussion_no_user, :status => Cornerstone::Discussion::STATUS.last)
|
154
|
+
@discussion.closed?.should == true
|
155
|
+
end
|
156
|
+
it "returns false if the status is not the last in the list" do
|
157
|
+
@discussion = Factory(:discussion_no_user, :status => Cornerstone::Discussion::STATUS.first)
|
158
|
+
@discussion.closed?.should == false
|
159
|
+
end
|
160
|
+
end
|
161
|
+
describe "#created_by" do
|
162
|
+
before do
|
163
|
+
@user = Factory(:user)
|
164
|
+
end
|
165
|
+
it "returns true if the user is a cornerstone admin" do
|
166
|
+
@user.stub(:cornerstone_admin?) {true}
|
167
|
+
@discussion = Factory(:discussion_w_user, :user => @user)
|
168
|
+
@discussion.created_by?(@user).should == true
|
169
|
+
end
|
170
|
+
it "returns nil if there is no user" do
|
171
|
+
@discussion = Factory(:discussion_no_user, :user => nil)
|
172
|
+
@user.stub(:cornerstone_admin?) {false}
|
173
|
+
@discussion.created_by?(@user).should == nil
|
174
|
+
end
|
175
|
+
it "returns false if given nil" do
|
176
|
+
@discussion = Factory(:discussion_w_user, :user => @user)
|
177
|
+
@discussion.created_by?(nil).should == false
|
178
|
+
end
|
179
|
+
it "returns true if the user created the discussion" do
|
180
|
+
@user.stub(:cornerstone_admin?) {false}
|
181
|
+
@discussion = Factory(:discussion_w_user, :user => @user)
|
182
|
+
@discussion.created_by?(@user).should == true
|
183
|
+
end
|
184
|
+
it "returns false if the user did not create the discussion" do
|
185
|
+
@discussion = Factory(:discussion_w_user, :user => @user)
|
186
|
+
@user2 = Factory(:user)
|
187
|
+
@user.stub(:cornerstone_admin?) {false}
|
188
|
+
@user2.stub(:cornerstone_admin?) {false}
|
189
|
+
@discussion.created_by?(@user2).should == false
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "#participants" do
|
194
|
+
before do
|
195
|
+
@user = Factory(:user)
|
196
|
+
@discussion = Factory(:discussion_w_user, :user => @user)
|
197
|
+
@post2 = Factory(:post, :discussion => @discussion,
|
198
|
+
:name => "Jim",
|
199
|
+
:email => "jim@bob.com")
|
200
|
+
end
|
201
|
+
|
202
|
+
it "returns an array of participants from all of the posts" do
|
203
|
+
result = [[@user.name, @user.email],
|
204
|
+
[@post2.name, @post2.email]]
|
205
|
+
@discussion.participants.should == result
|
206
|
+
end
|
207
|
+
|
208
|
+
it "does not include any duplicates" do
|
209
|
+
post3 = Factory(:post, :discussion => @discussion,
|
210
|
+
:name => "Jim",
|
211
|
+
:email => "jim@bob.com")
|
212
|
+
post4 = Factory(:post, :discussion => @discussion, :user => @user)
|
213
|
+
result = [[@user.name, @user.email],
|
214
|
+
[@post2.name, @post2.email]]
|
215
|
+
@discussion.participants.should == result
|
216
|
+
end
|
217
|
+
|
218
|
+
it "does not include 'exclude_email' when given" do
|
219
|
+
@discussion.participants("jim@bob.com").should == [[@user.name, @user.email]]
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
describe "#participant_email_list" do
|
224
|
+
before do
|
225
|
+
@user = Factory(:user)
|
226
|
+
@discussion = Factory(:discussion_w_user, :user => @user)
|
227
|
+
@post2 = Factory(:post, :discussion => @discussion,
|
228
|
+
:name => "Jim",
|
229
|
+
:email => "jim@bob.com")
|
230
|
+
end
|
231
|
+
it "returns a string of names and email addresses suitable for the mailer" do
|
232
|
+
result = "#{@user.name} <#{@user.email}>, #{@post2.name} <#{@post2.email}>"
|
233
|
+
@discussion.participants_email_list.should == result
|
234
|
+
end
|
235
|
+
it "does not include 'exclude_email' when given" do
|
236
|
+
result = "#{@user.name} <#{@user.email}>"
|
237
|
+
@discussion.participants_email_list("jim@bob.com").should == result
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|
242
|
+
|
243
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cornerstone::PostObserver do
|
4
|
+
describe "#after_create" do
|
5
|
+
|
6
|
+
context "new discussion" do
|
7
|
+
it "sends the new discussion email to admins" do
|
8
|
+
discussion = Factory(:discussion_w_user)
|
9
|
+
post = discussion.posts.first
|
10
|
+
@observer = Cornerstone::PostObserver.instance
|
11
|
+
|
12
|
+
mailer = mock("mailer")
|
13
|
+
Cornerstone::CornerstoneMailer.should_receive(:new_discussion)
|
14
|
+
.with(post, discussion) {mailer}
|
15
|
+
mailer.should_receive(:deliver)
|
16
|
+
|
17
|
+
@observer.after_create(post)
|
18
|
+
end
|
19
|
+
it "sends the new discussion email to the user" do
|
20
|
+
discussion = Factory(:discussion_w_user)
|
21
|
+
post = discussion.posts.first
|
22
|
+
@observer = Cornerstone::PostObserver.instance
|
23
|
+
|
24
|
+
mailer = mock("mailer")
|
25
|
+
Cornerstone::CornerstoneMailer.should_receive(:new_discussion_user)
|
26
|
+
.with(post, discussion) {mailer}
|
27
|
+
mailer.should_receive(:deliver)
|
28
|
+
|
29
|
+
@observer.after_create(post)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "existing discussion" do
|
34
|
+
before do
|
35
|
+
@discussion = Factory(:discussion_w_user)
|
36
|
+
@post = Factory(:post_w_user, :discussion => @discussion)
|
37
|
+
end
|
38
|
+
it "sends the new post email" do
|
39
|
+
@observer = Cornerstone::PostObserver.instance
|
40
|
+
|
41
|
+
mailer = mock("mailer")
|
42
|
+
Cornerstone::CornerstoneMailer.should_receive(:new_post)
|
43
|
+
.with(@discussion.posts.first.author_name,
|
44
|
+
@discussion.posts.first.author_email,
|
45
|
+
@post, @discussion) {mailer}
|
46
|
+
mailer.should_receive(:deliver)
|
47
|
+
|
48
|
+
@observer.after_create(@post)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "sends the new post email to multiple customers" do
|
52
|
+
@observer = Cornerstone::PostObserver.instance
|
53
|
+
|
54
|
+
post2 = Factory(:post_w_user, :discussion => @discussion)
|
55
|
+
|
56
|
+
mailer = mock("mailer")
|
57
|
+
mailer.stub(:deliver)
|
58
|
+
Cornerstone::CornerstoneMailer.should_receive(:new_post).twice {mailer}
|
59
|
+
|
60
|
+
@observer.after_create(post2)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cornerstone::Post do
|
4
|
+
|
5
|
+
# == ACCESSIBILITY == #
|
6
|
+
|
7
|
+
# == SCOPES == #
|
8
|
+
|
9
|
+
# == VALIDATIONS == #
|
10
|
+
|
11
|
+
context "validations" do
|
12
|
+
|
13
|
+
context "without a user" do
|
14
|
+
before do
|
15
|
+
@post = Factory.build(:post_no_user)
|
16
|
+
end
|
17
|
+
|
18
|
+
[:name, :email].each do |attr|
|
19
|
+
it "requires a #{attr.to_s}" do
|
20
|
+
@post.send("#{attr}=", nil)
|
21
|
+
@post.should have(1).errors_on(attr)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "#name should be 50 characters or less" do
|
26
|
+
@post.name = random_alphanumeric(51)
|
27
|
+
@post.should have(1).errors_on(:name)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "allows valid emails" do
|
31
|
+
@post.email = "youhoo@yahoo.ca"
|
32
|
+
@post.should be_valid
|
33
|
+
end
|
34
|
+
|
35
|
+
it "does not allow misformed emails" do
|
36
|
+
@post.email = "notval@id.email@@.com"
|
37
|
+
@post.should have(1).errors_on(:email)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with a user" do
|
43
|
+
before do
|
44
|
+
@post = Factory.build(:post_w_user)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "does not require a name" do
|
48
|
+
@post.name = nil
|
49
|
+
@post.should have(0).errors_on(:name)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "does not require an email" do
|
53
|
+
@post.email = nil
|
54
|
+
@post.should have(0).errors_on(:email)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
context "regarless of user present" do
|
60
|
+
before do
|
61
|
+
@post = Factory.build(:post)
|
62
|
+
end
|
63
|
+
|
64
|
+
[:body].each do |attr|
|
65
|
+
it "requires a #{attr}" do
|
66
|
+
@post.send("#{attr}=", nil)
|
67
|
+
@post.should have(1).error_on(attr)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it "#body should be 3000 characters or less" do
|
72
|
+
@post.body = random_alphanumeric(3001)
|
73
|
+
@post.should have(1).error_on(:body)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# == CALL BACKS == #
|
80
|
+
context "Call Backs:" do
|
81
|
+
describe "Counter Cache" do
|
82
|
+
before do
|
83
|
+
@discussion = Factory(:discussion_w_user)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "has a reply count of 0 when first created including first post" do
|
87
|
+
# factory creates post with discussion in callback
|
88
|
+
@discussion.reply_count.should == 0
|
89
|
+
end
|
90
|
+
|
91
|
+
it "is increased when the second post is created" do
|
92
|
+
@discussion.reply_count.should == 0
|
93
|
+
@post = Factory(:post_no_user, :discussion => @discussion)
|
94
|
+
@discussion.reload
|
95
|
+
@discussion.reply_count.should == 1
|
96
|
+
end
|
97
|
+
|
98
|
+
it "is decreased when a post is deleted" do
|
99
|
+
@post = Factory(:post_w_user, :discussion => @discussion)
|
100
|
+
2.times {Factory(:post_no_user, :discussion => @discussion)}
|
101
|
+
@discussion.reload
|
102
|
+
@discussion.reply_count.should == 3
|
103
|
+
@post.destroy
|
104
|
+
@discussion.reload
|
105
|
+
@discussion.reply_count.should == 2
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "#set_latest_post" do
|
111
|
+
before do
|
112
|
+
@discussion = Factory(:discussion)
|
113
|
+
end
|
114
|
+
|
115
|
+
pending "only updates on create"
|
116
|
+
|
117
|
+
context "with no current user" do
|
118
|
+
it "sets its discussion's latest post author name" do
|
119
|
+
@post = Factory(:post_no_user, :name => "Joe Dinglebat",
|
120
|
+
:discussion => @discussion)
|
121
|
+
@discussion.reload
|
122
|
+
@discussion.latest_post_author.should == "Joe Dinglebat"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "with a current user" do
|
127
|
+
it "sets its discussion's latest post author name" do
|
128
|
+
@user = Factory(:user, :name => "Joe Jingleheimershmeidt")
|
129
|
+
@post = Factory(:post_w_user, :user => @user, :discussion => @discussion)
|
130
|
+
@discussion.reload
|
131
|
+
@discussion.latest_post_author.should == "Joe Jingleheimershmeidt"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
it "sets its category's latest discussion date" do
|
136
|
+
time = 1.hour.from_now
|
137
|
+
Time.stub(:now) {time}
|
138
|
+
@post = Factory(:post_no_user, :discussion => @discussion)
|
139
|
+
@discussion.reload
|
140
|
+
@discussion.latest_post_date.should.to_s == time.to_s
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# == CLASS METHODS == #
|
147
|
+
|
148
|
+
# == INSTANCE METHODS == #
|
149
|
+
context "Instance Methods:" do
|
150
|
+
describe "#author_name" do
|
151
|
+
it "returns the name if there is no user" do
|
152
|
+
@post = Factory(:post_no_user, :name => "Jim Bob")
|
153
|
+
@post.author_name.should == "Jim Bob"
|
154
|
+
end
|
155
|
+
it "returns the user's name"do
|
156
|
+
user = Factory(:user, :name => "Alice Wundersmut")
|
157
|
+
@post = Factory(:post_w_user, :user => user)
|
158
|
+
@post.author_name.should == "Alice Wundersmut"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe "#author_email" do
|
163
|
+
it "returns the email if there is no user" do
|
164
|
+
@post = Factory(:post_no_user, :email => "jim@bob.com")
|
165
|
+
@post.author_email.should == "jim@bob.com"
|
166
|
+
end
|
167
|
+
it "returns the user's name"do
|
168
|
+
user = Factory(:user, :email => "alice@wundersmut.com")
|
169
|
+
@post = Factory(:post_w_user, :user => user)
|
170
|
+
@post.author_email.should == "alice@wundersmut.com"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe "#created_by" do
|
175
|
+
before do
|
176
|
+
@user = Factory(:user)
|
177
|
+
end
|
178
|
+
it "returns true if the user is a cornerstone admin" do
|
179
|
+
@user.stub(:cornerstone_admin?) {true}
|
180
|
+
@post = Factory(:post_w_user, :user => @user)
|
181
|
+
@post.created_by?(@user).should == true
|
182
|
+
end
|
183
|
+
it "returns nil if there is no user" do
|
184
|
+
@post = Factory(:post_no_user, :user => nil)
|
185
|
+
@user.stub(:cornerstone_admin?) {false}
|
186
|
+
@post.created_by?(@user).should == nil
|
187
|
+
end
|
188
|
+
it "returns false if given nil" do
|
189
|
+
@post = Factory(:post_w_user, :user => @user)
|
190
|
+
@post.created_by?(nil).should == false
|
191
|
+
end
|
192
|
+
it "returns true if the user created the post" do
|
193
|
+
@user.stub(:cornerstone_admin?) {false}
|
194
|
+
@post = Factory(:post_w_user, :user => @user)
|
195
|
+
@post.created_by?(@user).should == true
|
196
|
+
end
|
197
|
+
it "returns false if the user did not create the post" do
|
198
|
+
@post = Factory(:post_w_user, :user => @user)
|
199
|
+
@user2 = Factory(:user)
|
200
|
+
@user.stub(:cornerstone_admin?) {false}
|
201
|
+
@user2.stub(:cornerstone_admin?) {false}
|
202
|
+
@post.created_by?(@user2).should == false
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
210
|
+
|