cornerstone 0.0.1 → 0.0.5

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.
Files changed (177) hide show
  1. data/.gitignore +6 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +23 -0
  4. data/Gemfile.lock +168 -0
  5. data/Guardfile +22 -0
  6. data/README.rdoc +4 -1
  7. data/Rakefile +11 -1
  8. data/TODO +11 -0
  9. data/VERSION +1 -0
  10. data/app/assets/images/.gitkeep +0 -0
  11. data/app/assets/javascripts/.gitkeep +0 -0
  12. data/app/assets/javascripts/cornerstone.js +11 -0
  13. data/app/assets/javascripts/cornerstone/discussions.js +2 -0
  14. data/app/assets/javascripts/cornerstone/help.js +2 -0
  15. data/app/assets/stylesheets/.gitkeep +0 -0
  16. data/app/assets/stylesheets/cornerstone.css +8 -0
  17. data/app/assets/stylesheets/cornerstone/discussions.css +4 -0
  18. data/app/assets/stylesheets/cornerstone/help.css +4 -0
  19. data/app/controllers/.gitkeep +0 -0
  20. data/app/controllers/cornerstone/admin/application_controller.rb +7 -0
  21. data/app/controllers/cornerstone/admin/articles_controller.rb +61 -0
  22. data/app/controllers/cornerstone/admin/categories_controller.rb +46 -0
  23. data/app/controllers/cornerstone/admin/discussions_controller.rb +32 -0
  24. data/app/controllers/cornerstone/application_controller.rb +6 -0
  25. data/app/controllers/cornerstone/discussions_controller.rb +58 -0
  26. data/app/controllers/cornerstone/help_controller.rb +11 -0
  27. data/app/controllers/cornerstone/posts_controller.rb +66 -0
  28. data/app/helpers/.gitkeep +0 -0
  29. data/app/helpers/cornerstone/application_helper.rb +5 -0
  30. data/app/helpers/cornerstone/discussions_helper.rb +16 -0
  31. data/app/helpers/cornerstone/help_helper.rb +4 -0
  32. data/app/mailers/cornerstone/cornerstone_mailer.rb +31 -0
  33. data/app/models/.gitkeep +0 -0
  34. data/app/models/cornerstone/article.rb +20 -0
  35. data/app/models/cornerstone/category.rb +45 -0
  36. data/app/models/cornerstone/discussion.rb +90 -0
  37. data/app/models/cornerstone/post.rb +103 -0
  38. data/app/models/cornerstone/post_observer.rb +23 -0
  39. data/app/views/.gitkeep +0 -0
  40. data/app/views/cornerstone/admin/articles/_article.html.erb +9 -0
  41. data/app/views/cornerstone/admin/articles/_form.html.erb +22 -0
  42. data/app/views/cornerstone/admin/articles/edit.html.erb +7 -0
  43. data/app/views/cornerstone/admin/articles/index.html.erb +25 -0
  44. data/app/views/cornerstone/admin/articles/new.html.erb +6 -0
  45. data/app/views/cornerstone/admin/articles/show.html.erb +4 -0
  46. data/app/views/cornerstone/admin/categories/_category.html.erb +12 -0
  47. data/app/views/cornerstone/admin/categories/_form.html.erb +17 -0
  48. data/app/views/cornerstone/admin/categories/edit.html.erb +6 -0
  49. data/app/views/cornerstone/admin/categories/index.html.erb +11 -0
  50. data/app/views/cornerstone/admin/categories/new.html.erb +6 -0
  51. data/app/views/cornerstone/admin/discussions/edit.html.erb +7 -0
  52. data/app/views/cornerstone/cornerstone_mailer/new_discussion.html.erb +14 -0
  53. data/app/views/cornerstone/cornerstone_mailer/new_discussion.text.erb +5 -0
  54. data/app/views/cornerstone/cornerstone_mailer/new_discussion_user.html.erb +7 -0
  55. data/app/views/cornerstone/cornerstone_mailer/new_post.html.erb +7 -0
  56. data/app/views/cornerstone/cornerstone_mailer/new_post.text.erb +8 -0
  57. data/app/views/cornerstone/discussions/_discussion.html.erb +12 -0
  58. data/app/views/cornerstone/discussions/_discussion_category.html.erb +14 -0
  59. data/app/views/cornerstone/discussions/_form.html.erb +33 -0
  60. data/app/views/cornerstone/discussions/_latest_discussion.html.erb +4 -0
  61. data/app/views/cornerstone/discussions/categorical_index.html.erb +27 -0
  62. data/app/views/cornerstone/discussions/index.html.erb +25 -0
  63. data/app/views/cornerstone/discussions/new.html.erb +6 -0
  64. data/app/views/cornerstone/discussions/show.html.erb +19 -0
  65. data/app/views/cornerstone/help/index.html.erb +7 -0
  66. data/app/views/cornerstone/posts/_fields.html.erb +44 -0
  67. data/app/views/cornerstone/posts/_form.html.erb +19 -0
  68. data/app/views/cornerstone/posts/_post.html.erb +17 -0
  69. data/app/views/cornerstone/posts/edit.html.erb +9 -0
  70. data/app/views/cornerstone/shared/_errors.html.erb +11 -0
  71. data/app/views/cornerstone/shared/_flash_messages.html.erb +15 -0
  72. data/app/views/layouts/cornerstone/application.html.erb +16 -0
  73. data/config/cucumber.yml +8 -0
  74. data/config/locales/cornerstone.action_mailer.en.yml +9 -0
  75. data/config/routes.rb +24 -0
  76. data/cornerstone-0.0.1.gem +0 -0
  77. data/cornerstone.gemspec +33 -0
  78. data/db/migrate/20110723004024_create_cornerstone_discussions.rb +17 -0
  79. data/db/migrate/20110804190853_create_cornerstone_categories.rb +15 -0
  80. data/db/migrate/20110809233551_create_cornerstone_posts.rb +13 -0
  81. data/db/migrate/20111006172857_create_cornerstone_articles.rb +12 -0
  82. data/lib/cornerstone.rb +6 -0
  83. data/lib/cornerstone/acts_as_cornerstone_user.rb +79 -0
  84. data/lib/cornerstone/config.rb +33 -0
  85. data/lib/cornerstone/controller_additions.rb +25 -0
  86. data/lib/cornerstone/engine.rb +8 -1
  87. data/lib/cornerstone/exceptions.rb +16 -0
  88. data/lib/cornerstone/helpers.rb +35 -0
  89. data/lib/tasks/cucumber.rake +65 -0
  90. data/lib/templates/cornerstone_config.rb +31 -0
  91. data/script/cucumber +10 -0
  92. data/script/rails +7 -0
  93. data/spec/controllers/cornerstone/admin/articles_controller_spec.rb +250 -0
  94. data/spec/controllers/cornerstone/admin/categories_controller_spec.rb +205 -0
  95. data/spec/controllers/cornerstone/admin/discussions_controller_spec.rb +95 -0
  96. data/spec/controllers/cornerstone/application_controller_spec.rb +34 -0
  97. data/spec/controllers/cornerstone/discussions_controller_spec.rb +157 -0
  98. data/spec/controllers/cornerstone/help_controller_spec.rb +20 -0
  99. data/spec/controllers/cornerstone/posts_controller_spec.rb +212 -0
  100. data/spec/dummy/Rakefile +7 -0
  101. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  102. data/spec/dummy/app/assets/javascripts/tester.js +2 -0
  103. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  104. data/spec/dummy/app/assets/stylesheets/tester.css +4 -0
  105. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  106. data/spec/dummy/app/controllers/tester_controller.rb +7 -0
  107. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  108. data/spec/dummy/app/helpers/tester_helper.rb +6 -0
  109. data/spec/dummy/app/mailers/.gitkeep +0 -0
  110. data/spec/dummy/app/models/.gitkeep +0 -0
  111. data/spec/dummy/app/models/user.rb +23 -0
  112. data/spec/dummy/app/views/devise/confirmations/new.html.erb +12 -0
  113. data/spec/dummy/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  114. data/spec/dummy/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  115. data/spec/dummy/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  116. data/spec/dummy/app/views/devise/passwords/edit.html.erb +16 -0
  117. data/spec/dummy/app/views/devise/passwords/new.html.erb +12 -0
  118. data/spec/dummy/app/views/devise/registrations/edit.html.erb +29 -0
  119. data/spec/dummy/app/views/devise/registrations/new.html.erb +22 -0
  120. data/spec/dummy/app/views/devise/sessions/new.html.erb +19 -0
  121. data/spec/dummy/app/views/devise/shared/_links.erb +25 -0
  122. data/spec/dummy/app/views/devise/unlocks/new.html.erb +12 -0
  123. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  124. data/spec/dummy/app/views/tester/index.html.erb +14 -0
  125. data/spec/dummy/config.ru +4 -0
  126. data/spec/dummy/config/application.rb +42 -0
  127. data/spec/dummy/config/boot.rb +10 -0
  128. data/spec/dummy/config/database.yml +28 -0
  129. data/spec/dummy/config/environment.rb +5 -0
  130. data/spec/dummy/config/environments/development.rb +31 -0
  131. data/spec/dummy/config/environments/production.rb +54 -0
  132. data/spec/dummy/config/environments/test.rb +39 -0
  133. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  134. data/spec/dummy/config/initializers/cornerstone_config.rb +30 -0
  135. data/spec/dummy/config/initializers/devise.rb +204 -0
  136. data/spec/dummy/config/initializers/inflections.rb +10 -0
  137. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  138. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  139. data/spec/dummy/config/initializers/session_store.rb +8 -0
  140. data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
  141. data/spec/dummy/config/locales/devise.en.yml +53 -0
  142. data/spec/dummy/config/locales/en.yml +5 -0
  143. data/spec/dummy/config/routes.rb +65 -0
  144. data/spec/dummy/db/migrate/20110724011421_create_user.rb +11 -0
  145. data/spec/dummy/db/migrate/20110724194307_devise_create_users.rb +41 -0
  146. data/spec/dummy/db/migrate/20110804174004_add_name_to_user.rb +5 -0
  147. data/spec/dummy/db/schema.rb +76 -0
  148. data/spec/dummy/log/.gitkeep +0 -0
  149. data/spec/dummy/public/404.html +26 -0
  150. data/spec/dummy/public/422.html +26 -0
  151. data/spec/dummy/public/500.html +26 -0
  152. data/spec/dummy/public/favicon.ico +0 -0
  153. data/spec/dummy/script/rails +6 -0
  154. data/spec/dummy/test/functional/tester_controller_test.rb +9 -0
  155. data/spec/dummy/test/unit/helpers/tester_helper_test.rb +4 -0
  156. data/spec/fixtures/cornerstone/cornerstone_mailer/new_discussion +3 -0
  157. data/spec/lib/cornerstone/acts_as_cornerstone_user_spec.rb +56 -0
  158. data/spec/lib/cornerstone/helpers_spec.rb +32 -0
  159. data/spec/mailers/cornerstone/cornerstone_mailer_spec.rb +55 -0
  160. data/spec/models/cornerstone/article_spec.rb +25 -0
  161. data/spec/models/cornerstone/category_spec.rb +97 -0
  162. data/spec/models/cornerstone/discussion_spec.rb +243 -0
  163. data/spec/models/cornerstone/post_observer_spec.rb +65 -0
  164. data/spec/models/cornerstone/post_spec.rb +210 -0
  165. data/spec/requests/emails_spec.rb +51 -0
  166. data/spec/requests/interact_discussions_spec.rb +103 -0
  167. data/spec/requests/manage_articles_spec.rb +59 -0
  168. data/spec/requests/manage_categories_spec.rb +64 -0
  169. data/spec/requests/view_home_spec.rb +26 -0
  170. data/spec/spec_helper.rb +40 -0
  171. data/spec/support/devise.rb +4 -0
  172. data/spec/support/factories.rb +62 -0
  173. data/spec/support/general_helper_methods.rb +20 -0
  174. data/spec/support/mailer_macros.rb +15 -0
  175. data/spec/support/mass_assignment.rb +46 -0
  176. data/tmp/log/development.log +0 -0
  177. 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
+