proclaim 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +9 -0
  3. data/README.md +91 -10
  4. data/Rakefile +1 -1
  5. data/VERSION +1 -1
  6. data/app/assets/javascripts/proclaim/comments_handler.js.coffee +3 -0
  7. data/app/assets/stylesheets/proclaim/subscriptions.css.scss +33 -0
  8. data/app/controllers/proclaim/comments_controller.rb +3 -1
  9. data/app/controllers/proclaim/posts_controller.rb +10 -6
  10. data/app/controllers/proclaim/subscriptions_controller.rb +31 -14
  11. data/app/helpers/proclaim/application_helper.rb +3 -8
  12. data/app/models/proclaim/comment.rb +1 -0
  13. data/app/models/proclaim/post.rb +2 -0
  14. data/app/models/proclaim/subscription.rb +7 -6
  15. data/app/policies/proclaim/image_policy.rb +1 -1
  16. data/app/policies/proclaim/subscription_policy.rb +10 -6
  17. data/app/views/layouts/proclaim/subscription_mailer.html.erb +34 -4
  18. data/app/views/proclaim/posts/edit.html.erb +3 -1
  19. data/app/views/proclaim/posts/index.html.erb +2 -0
  20. data/app/views/proclaim/posts/new.html.erb +3 -1
  21. data/app/views/proclaim/posts/show.html.erb +3 -1
  22. data/app/views/proclaim/subscription_mailer/welcome_email.html.erb +9 -7
  23. data/app/views/proclaim/subscriptions/_form.html.erb +7 -2
  24. data/app/views/proclaim/subscriptions/index.html.erb +89 -0
  25. data/app/views/proclaim/subscriptions/new.html.erb +3 -1
  26. data/app/views/proclaim/subscriptions/show.html.erb +26 -0
  27. data/config/routes.rb +2 -6
  28. data/db/migrate/20150123115226_add_name_to_subscriptions.rb +7 -0
  29. data/lib/generators/proclaim/templates/initialize_proclaim.rb +19 -0
  30. data/lib/proclaim.rb +93 -0
  31. data/lib/proclaim/engine.rb +18 -0
  32. data/lib/proclaim/version.rb +1 -1
  33. data/test/controllers/proclaim/subscriptions_controller_test.rb +76 -21
  34. data/test/dummy/db/schema.rb +4 -3
  35. data/test/factories/proclaim/subscription.rb +1 -0
  36. data/test/integration/with_javascript/post_subscription_test.rb +29 -0
  37. data/test/integration/without_javascript/blog_subscription_test.rb +29 -2
  38. data/test/integration/without_javascript/manage_subscriptions_test.rb +37 -0
  39. data/test/integration/without_javascript/unsubscribe_test.rb +6 -6
  40. data/test/mailers/proclaim/subscription_mailer_test.rb +10 -6
  41. data/test/models/proclaim/subscription_test.rb +5 -0
  42. data/test/policies/proclaim/image_policy_test.rb +83 -0
  43. data/test/policies/proclaim/post_policy_test.rb +11 -0
  44. data/test/policies/proclaim/subscription_policy_test.rb +27 -15
  45. data/test/unit/proclaim/new_comment_callback_test.rb +62 -0
  46. data/test/unit/proclaim/new_subscription_callback_test.rb +62 -0
  47. data/test/unit/proclaim/post_published_callback_test.rb +74 -0
  48. metadata +15 -5
  49. data/app/views/proclaim/subscriptions/subscribed.html.erb +0 -7
  50. data/app/views/proclaim/subscriptions/unsubscribe.html.erb +0 -7
  51. data/app/views/proclaim/subscriptions/unsubscribed.html.erb +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c804948c26e92b6c025b23e0b436ff0f2ce3063
4
- data.tar.gz: 4a38e087429d2f5a122b5d16a7d21145b0912b26
3
+ metadata.gz: 1a4fb217ab74d5f76f8c5b04aafe1bb4d328e41e
4
+ data.tar.gz: 164386ed38ec2c67e27e1b0565cf4bef4353b04b
5
5
  SHA512:
6
- metadata.gz: 1cd62bc9af70f115ba3765d5370b426d7030d36fba5fd78800ac23ca2b0f769f2d41d07078c5b2542d64c77b0b59149c9a0a54b39f9ce6879c2c48e028f13129
7
- data.tar.gz: 3021330ed8024b80122d5080b3dd01f9681794d44890eac4c310f3409114ea9dced85e2d308efff6294c02a91884eb9a40bce5d43af1720ab65407707871457c
6
+ metadata.gz: 13f1c62fa387363bca3c295c5f28f15360f98ab553bb3cad58a535334098082635adce8d72f5767226e469dff2454129d627e0e754e4e06c92698a3398b72682
7
+ data.tar.gz: e1235a462a4f29c74a9ac912480513d04f06858ebea23a1a0b92438d7cf7f34c404d1237887590eefaae55fb9e6679ec95b46f9f5bd73cdf2c6beab76b64b12f
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ 0.4.0
2
+ - Added media query to emails for better display on mobile devices
3
+ - Added callbacks as a way for main app to be notified of new posts,
4
+ comments, or subscriptions. Configured in initializer
5
+ - Fixed bug where email field didn't hide after successful comment
6
+ - Added ability to administer subscriptions
7
+ - Added page titles for each Proclaim page
8
+ - Removed the use of calc from mailer layout
9
+
1
10
  v 0.3.1
2
11
  - Fixed bug causing floated images to display improperly in emails
3
12
  - Added link to emails to view post online
data/README.md CHANGED
@@ -14,7 +14,7 @@ Linkesch's [Image Insert plugin][2] tied to CarrierWave for image uploads.
14
14
  Proclaim doesn't include any users or authentication. It was made to be able to
15
15
  work with whatever setup you're using. All that it requires is that your
16
16
  application _has_ users and authentication ([Devise][3] is recommended). In
17
- Proclaim 0.1, authentication is also used as authorization. If a user is logged
17
+ Proclaim 0.4, authentication is also used as authorization. If a user is logged
18
18
  in, it can create/publish/edit/delete posts and edit/delete comments. If no user
19
19
  is logged in, it can only read posts and create comments.
20
20
 
@@ -25,11 +25,11 @@ scheme is given below.
25
25
 
26
26
  ### Get Proclaim
27
27
 
28
- Proclaim 0.2 works with Rails 4.2 and on, with Ruby 1.9.3 and on. Add it to your
28
+ Proclaim 0.4 works with Rails 4.2 and on, with Ruby 1.9.3 and on. Add it to your
29
29
  Gemfile with:
30
30
 
31
31
  ```ruby
32
- gem 'proclaim', "~> 0.3.1"
32
+ gem 'proclaim', "~> 0.4.0"
33
33
  ```
34
34
 
35
35
  Run `bundle install` to install it.
@@ -116,6 +116,7 @@ Proclaim.editor_whitelist_tags = %w(h1 h2 h3 h4 h5 h6
116
116
  Proclaim.editor_whitelist_attributes = %w(class id style href title src alt
117
117
  align draggable)
118
118
  Proclaim.mailer_sender = nil
119
+ Proclaim.secret_key = nil
119
120
  ```
120
121
 
121
122
  - **Proclaim.author_class**
@@ -132,13 +133,14 @@ Proclaim.mailer_sender = nil
132
133
 
133
134
  - **Proclaim.current_author_method**
134
135
 
135
- Method to obtain the currently-authenticated user. Should return nil if no
136
- user is currently authenticated.
136
+ Method to obtain the currently-authenticated user. This should be a method on
137
+ the `ApplicationController`, and it should return nil if no user is currently
138
+ authenticated.
137
139
 
138
140
  - **Proclaim.authentication_method**
139
141
 
140
- Method to verify that a user is authenticated, and if not, will redirect to
141
- some sort of authentication page.
142
+ `ApplicationController` method to verify that a user is authenticated, and if
143
+ not, to redirect to some sort of authentication page.
142
144
 
143
145
  - **Proclaim.excerpt_length**
144
146
 
@@ -164,10 +166,89 @@ Proclaim.mailer_sender = nil
164
166
  not specified (the default), the mailer's default params will be used, which
165
167
  means it should be set in your environment.
166
168
 
167
- Astute readers may note that the defaults corresponds to defaults from Devise (on
168
- the User class). If that's not your setup, all of these options can be changed
169
- in the initializer installed by `rails generate proclaim:install`.
169
+ - **Proclaim.secret_key**
170
170
 
171
+ The secret key to use for generating subscription tokens. Changing this will
172
+ invalidate any tokens already generated.
173
+
174
+ Astute readers may note that the defaults corresponds to defaults from Devise
175
+ (on the User class). If that's not your setup, all of these options can be
176
+ changed in the initializer installed by `rails generate proclaim:install`.
177
+
178
+
179
+ ## Handy Things
180
+
181
+ ### Page Titles
182
+
183
+ Each of Proclaim's included views stores its associated page title in the
184
+ content identifier `:proclaim_title`. In order to actually get that into one's
185
+ page title, then, one must simply throw something like this in one's layout
186
+ header:
187
+
188
+ ```html
189
+ <head>
190
+ ...
191
+ <title><%= content_for :proclaim_title %></title>
192
+ ...
193
+ </head>
194
+ ```
195
+
196
+ ### Callbacks
197
+
198
+ Proclaim can notify your main application when certain things happen. These are
199
+ all configured in the initializer installed by
200
+ `rails generate proclaim:install`.
201
+
202
+ #### When Posts Are Published
203
+
204
+ To register callbacks for when a post is published, use `after_post_published`
205
+ in the initializer, for example:
206
+
207
+ ```ruby
208
+ Proclaim.setup do |config|
209
+ # Can specify multiple callbacks. You can use a Proc:
210
+ config.after_post_published lambda { |p| puts "Post published: #{p.title}"}
211
+
212
+ # Or you can use a block:
213
+ config.after_post_published do |p|
214
+ puts "Post published: #{p.title}"
215
+ end
216
+ end
217
+ ```
218
+
219
+ #### When Comments Are Made
220
+
221
+ To register callbacks for when a comment is made, use `after_new_comment`
222
+ in the initializer, for example:
223
+
224
+ ```ruby
225
+ Proclaim.setup do |config|
226
+ # Can specify multiple callbacks. You can use a Proc:
227
+ config.after_new_comment lambda { |c| puts "Comment made by #{c.author}"}
228
+
229
+ # Or you can use a block:
230
+ config.after_new_comment do |c|
231
+ puts "Comment made by #{c.author}"
232
+ end
233
+ end
234
+ ```
235
+
236
+ #### When Subscriptions Are Created
237
+
238
+ To register callbacks for when a subscription is created, use
239
+ `after_new_subscription` in the initializer, for example:
240
+
241
+ ```ruby
242
+ Proclaim.setup do |config|
243
+ # Can specify multiple callbacks. You can use a Proc:
244
+ config.after_new_subscription lambda { |s| puts "New subsciber: #{s.name}"}
245
+
246
+ # Or you can use a block:
247
+ config.after_new_subscription do |s|
248
+ puts "New subsciber: #{s.name}"
249
+ end
250
+ end
251
+ ```
171
252
 
172
253
  ## Customizations
173
254
 
data/Rakefile CHANGED
@@ -40,7 +40,7 @@ namespace :test do
40
40
  end
41
41
 
42
42
  Rails::TestTask.new(:units) do |t|
43
- t.pattern = 'test/{models,helpers,unit}/**/*_test.rb'
43
+ t.pattern = 'test/{models,helpers,unit,policies}/**/*_test.rb'
44
44
  end
45
45
 
46
46
  Rails::TestTask.new(:functionals) do |t|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.4.0
@@ -179,6 +179,9 @@ class CommentsHandler
179
179
  form.each (index, element) =>
180
180
  thisForm = $(element)
181
181
 
182
+ # Hide the email field
183
+ thisForm.children(@subscribeEmailClass).hide()
184
+
182
185
  # Don't remove the main comment form-- just clear it
183
186
  if thisForm.is(@mainCommentFormClass)
184
187
  element.reset()
@@ -1,3 +1,36 @@
1
1
  // Place all the styles related to the Subscriptions controller here.
2
2
  // They will automatically be included in application.css.
3
3
  // You can use Sass (SCSS) here: http://sass-lang.com/
4
+
5
+ div.post_subscriptions
6
+ {
7
+ float: right;
8
+ width: 40%;
9
+
10
+ h2
11
+ {
12
+ margin-top: 0;
13
+ padding-top: 0;
14
+ }
15
+
16
+ table
17
+ {
18
+ width: 100%;
19
+ }
20
+ }
21
+
22
+ div.blog_subscriptions
23
+ {
24
+ width: 40%;
25
+
26
+ h2
27
+ {
28
+ margin-top: 0;
29
+ padding-top: 0;
30
+ }
31
+
32
+ table
33
+ {
34
+ width: 100%;
35
+ }
36
+ }
@@ -16,7 +16,9 @@ module Proclaim
16
16
  subscription = nil
17
17
  params = subscription_params
18
18
  if params and params[:subscribe]
19
- subscription = Subscription.new(email: params[:email], post: @comment.post)
19
+ subscription = Subscription.new(name: @comment.author,
20
+ email: params[:email],
21
+ post: @comment.post)
20
22
  end
21
23
 
22
24
  respond_to do |format|
@@ -3,7 +3,7 @@ require_dependency "proclaim/application_controller"
3
3
  module Proclaim
4
4
  class PostsController < ApplicationController
5
5
  before_action :authenticate_author, except: [:index, :show]
6
- after_action :verify_authorized, except: :index
6
+ after_action :verify_authorized
7
7
  after_action :verify_policy_scoped, only: :index
8
8
  before_action :set_post, only: [:show, :edit, :update, :destroy]
9
9
 
@@ -40,16 +40,20 @@ module Proclaim
40
40
  @post = Post.new(post_params)
41
41
  @post.author = current_author
42
42
 
43
- if params[:publish] == "true"
44
- @post.publish
45
- end
46
-
47
43
  authorize @post
48
44
 
49
- if @post.valid?
45
+ # Save here before potentially publishing, so we can save images
46
+ if @post.save
47
+
48
+ if params[:publish] == "true"
49
+ @post.publish
50
+ authorize @post # Re-authorize now that it's to be published
51
+ end
52
+
50
53
  # Save and rewrite each image in Carrierwave's cache
51
54
  @post.body = saved_and_rewrite_cached_images(@post.body)
52
55
 
56
+ # Save again, in case the body changed or it was published
53
57
  @post.save
54
58
 
55
59
  redirect_to @post, notice: 'Post was successfully created.'
@@ -2,24 +2,24 @@ require_dependency "proclaim/application_controller"
2
2
 
3
3
  module Proclaim
4
4
  class SubscriptionsController < ApplicationController
5
- after_action :verify_authorized, except: [:subscribed, :unsubscribed]
6
- before_action :set_subscription, only: [:unsubscribe, :destroy]
5
+ after_action :verify_authorized
6
+ after_action :verify_policy_scoped, only: :index
7
+ before_action :set_subscription, only: [:show, :edit, :update, :destroy]
8
+
9
+ def index
10
+ @subscriptions = policy_scope(Subscription).order(:post_id, :name)
11
+ authorize Subscription
12
+ end
7
13
 
8
14
  def new
9
15
  @subscription = Subscription.new
10
16
  authorize @subscription
11
17
  end
12
18
 
13
- def subscribed
14
- end
15
-
16
- def unsubscribe
19
+ def show
17
20
  authorize @subscription
18
21
  end
19
22
 
20
- def unsubscribed
21
- end
22
-
23
23
  def create
24
24
  @subscription = Subscription.new(subscription_params)
25
25
 
@@ -28,13 +28,19 @@ module Proclaim
28
28
  if antispam_params[:answer] == antispam_params[:solution]
29
29
  respond_to do |format|
30
30
  if @subscription.save
31
- format.html { redirect_to subscribed_path }
31
+ format.html {
32
+ redirect_to subscription_path(@subscription.token),
33
+ notice: "Thanks for subscribing! You should "\
34
+ "receive a confirmation email soon."
35
+ }
32
36
  else
33
37
  format.html { render :new }
34
38
  end
35
39
  end
36
40
  else
37
- @subscription.errors.add(:base, "Antispam question wasn't answered correctly")
41
+ @subscription.errors.add(:base,
42
+ "Antispam question wasn't answered "\
43
+ "correctly")
38
44
  respond_to do |format|
39
45
  format.html { render :new }
40
46
  end
@@ -43,9 +49,20 @@ module Proclaim
43
49
 
44
50
  def destroy
45
51
  authorize @subscription
46
-
47
52
  @subscription.destroy
48
- redirect_to unsubscribed_path, notice: "Successfully unsubscribed."
53
+
54
+ respond_to do |format|
55
+ format.html {
56
+ if current_author
57
+ redirect_to subscriptions_path,
58
+ notice: "Subscription was successfully destroyed."
59
+ else
60
+ redirect_to posts_path,
61
+ notice: "Successfully unsubscribed. Sorry to "\
62
+ "see you go!"
63
+ end
64
+ }
65
+ end
49
66
  end
50
67
 
51
68
  private
@@ -56,7 +73,7 @@ module Proclaim
56
73
 
57
74
  # Only allow a trusted parameter "white list" through.
58
75
  def subscription_params
59
- params.require(:subscription).permit(:email)
76
+ params.require(:subscription).permit(:name, :email)
60
77
  end
61
78
 
62
79
  def antispam_params
@@ -22,13 +22,8 @@ module Proclaim
22
22
  end.join.html_safe
23
23
  end
24
24
 
25
- # def timeago(time, options = {})
26
- # options[:class] ||= "timeago"
27
- # if time
28
- # content_tag(:time,
29
- # time.to_s,
30
- # options.merge(datetime: time.getutc.iso8601))
31
- # end
32
- # end
25
+ def proclaim_title(page_title)
26
+ content_for :proclaim_title, page_title.to_s
27
+ end
33
28
  end
34
29
  end
@@ -17,6 +17,7 @@ module Proclaim
17
17
  belongs_to :post, inverse_of: :comments
18
18
  after_initialize :maintainPost
19
19
  after_create :notifyPostSubscribers
20
+ after_create { Proclaim.notify_new_comment(self) }
20
21
 
21
22
  validates_presence_of :body, :author, :post
22
23
 
@@ -136,6 +136,8 @@ module Proclaim
136
136
  def notifyBlogSubscribersIfPublished
137
137
  # If we just published this post, notify the subscribers
138
138
  if published? and state_changed?
139
+ Proclaim.notify_post_published(self)
140
+
139
141
  Subscription.blog_subscriptions.each do | subscription |
140
142
  subscription.deliver_new_post_notification_email(self)
141
143
  end
@@ -15,13 +15,14 @@ module Proclaim
15
15
  belongs_to :post, inverse_of: :subscriptions
16
16
 
17
17
  after_create :deliver_welcome_email
18
-
19
- validates :email, uniqueness: { scope: :post_id, case_sensitive: false }, format: { with: /@/ }
18
+ after_create { Proclaim.notify_new_subscription(self) }
20
19
 
21
20
  # RFC-compliant email addresses are way nasty to match with regex, so why
22
21
  # try? We'll be sending them an email anyway-- if they don't get it, they
23
22
  # can re-subscribe. We'll just do an easy validation match here.
24
- #validates_format_of :email, :with => /@/
23
+ validates :email, uniqueness: { scope: :post_id, case_sensitive: false }, format: { with: /@/ }
24
+
25
+ validates_presence_of :name
25
26
 
26
27
  # Subscriptions aren't required to belong to a post, but if we're given
27
28
  # one it had better be valid
@@ -44,15 +45,15 @@ module Proclaim
44
45
  end
45
46
 
46
47
  def self.verifier
47
- ActiveSupport::MessageVerifier.new(Rails.application.secrets.secret_key_base)
48
+ ActiveSupport::MessageVerifier.new(Proclaim.secret_key)
48
49
  end
49
50
 
50
51
  def self.from_token(token)
51
52
  begin
52
53
  id = verifier.verify(token)
53
- Subscription.find_by_id(id)
54
+ Subscription.find(id)
54
55
  rescue ActiveSupport::MessageVerifier::InvalidSignature
55
- nil
56
+ raise ActiveRecord::RecordNotFound
56
57
  end
57
58
  end
58
59
 
@@ -21,7 +21,7 @@ module Proclaim
21
21
  if @user
22
22
  scope.all # Users can access all images
23
23
  else
24
- nil
24
+ scope.none
25
25
  end
26
26
  end
27
27
  end