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
@@ -50,5 +50,23 @@ module Proclaim
50
50
  config.generators do |g|
51
51
  g.fixture_replacement :factory_girl, :dir => 'test/factories'
52
52
  end
53
+
54
+ initializer :ensure_secret_key_presence do |app|
55
+ if app.respond_to?(:secrets)
56
+ Proclaim.secret_key ||= app.secrets.secret_key_base
57
+ elsif app.config.respond_to?(:secret_key_base)
58
+ Proclaim.secret_key ||= app.config.secret_key_base
59
+ end
60
+
61
+ if Proclaim.secret_key.nil?
62
+ raise <<-ERROR
63
+ Proclaim.secret_key was not set. Please add the following to your Proclaim initializer:
64
+
65
+ config.secret_key = '#{SecureRandom.hex(64)}'
66
+
67
+ Please ensure you restarted your application after installing Proclaim or setting the key.
68
+ ERROR
69
+ end
70
+ end
53
71
  end
54
72
  end
@@ -1,3 +1,3 @@
1
1
  module Proclaim
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -9,6 +9,60 @@ module Proclaim
9
9
  @controller.stubs(:authenticate_user).returns(false)
10
10
  end
11
11
 
12
+ test "should get index if logged in" do
13
+ user = FactoryGirl.create(:user)
14
+ sign_in user
15
+
16
+ subscription1 = FactoryGirl.create(:subscription)
17
+ subscription2 = FactoryGirl.create(:subscription)
18
+
19
+ get :index
20
+ assert_response :success
21
+ assert_not_nil assigns(:subscriptions)
22
+ assert_includes assigns(:subscriptions), subscription1
23
+ assert_includes assigns(:subscriptions), subscription2
24
+ end
25
+
26
+ test "should not get index if not logged in" do
27
+ get :index
28
+ assert_response :redirect
29
+ assert_match /not authorized/, flash[:error]
30
+ end
31
+
32
+ test "should get show if logged in" do
33
+ user = FactoryGirl.create(:user)
34
+ sign_in user
35
+
36
+ subscription = FactoryGirl.create(:subscription)
37
+
38
+ get :show, token: subscription.token
39
+ assert_response :success
40
+ assert_equal subscription, assigns(:subscription)
41
+ end
42
+
43
+ test "should get show if not logged in" do
44
+ subscription = FactoryGirl.create(:subscription)
45
+
46
+ get :show, token: subscription.token
47
+ assert_response :success
48
+ assert_equal subscription, assigns(:subscription)
49
+ end
50
+
51
+ test "should get new if logged in" do
52
+ user = FactoryGirl.create(:user)
53
+ sign_in user
54
+
55
+ get :new
56
+ assert_response :success
57
+ assert_not_nil assigns(:subscription)
58
+ end
59
+
60
+ test "should get new if not logged in" do
61
+ get :new
62
+ assert_response :success
63
+ assert_not_nil assigns(:subscription)
64
+ end
65
+
12
66
  test "should create subscription if logged in" do
13
67
  user = FactoryGirl.create(:user)
14
68
  sign_in user
@@ -18,6 +72,7 @@ module Proclaim
18
72
  assert_difference('Subscription.count') do
19
73
  post :create,
20
74
  subscription: {
75
+ name: newSubscription.name,
21
76
  email: newSubscription.email
22
77
  },
23
78
  antispam: {
@@ -26,7 +81,7 @@ module Proclaim
26
81
  }
27
82
  end
28
83
 
29
- assert_redirected_to :subscribed
84
+ assert_redirected_to subscription_path(assigns(:subscription).token)
30
85
  end
31
86
 
32
87
  test "should create subscription if not logged in" do
@@ -35,6 +90,7 @@ module Proclaim
35
90
  assert_difference('Subscription.count') do
36
91
  post :create,
37
92
  subscription: {
93
+ name: newSubscription.name,
38
94
  email: newSubscription.email
39
95
  },
40
96
  antispam: {
@@ -43,7 +99,7 @@ module Proclaim
43
99
  }
44
100
  end
45
101
 
46
- assert_redirected_to :subscribed
102
+ assert_redirected_to subscription_path(assigns(:subscription).token)
47
103
  end
48
104
 
49
105
  test "should not create subscription if spammy" do
@@ -52,6 +108,7 @@ module Proclaim
52
108
  assert_no_difference('Subscription.count') do
53
109
  post :create,
54
110
  subscription: {
111
+ name: newSubscription.name,
55
112
  email: newSubscription.email
56
113
  },
57
114
  antispam: {
@@ -61,33 +118,31 @@ module Proclaim
61
118
  end
62
119
  end
63
120
 
64
- test "ensure token resolves to correct subscription" do
65
- subscription1 = FactoryGirl.create(:subscription)
66
- subscription2 = FactoryGirl.create(:subscription)
121
+ test "should delete subscription if logged in" do
122
+ user = FactoryGirl.create(:user)
123
+ sign_in user
67
124
 
68
- get :unsubscribe, token: subscription1.token
69
- assert_response :success
70
- assert_equal subscription1, assigns(:subscription)
125
+ subscription = FactoryGirl.create(:subscription)
71
126
 
72
- get :unsubscribe, token: subscription2.token
73
- assert_response :success
74
- assert_equal subscription2, assigns(:subscription)
127
+ assert_difference('Subscription.count', -1) do
128
+ delete :destroy, token: subscription.token
129
+ end
130
+
131
+ # If a user is logged in, deletion should take them back to the
132
+ # subscriptions index
133
+ assert_redirected_to subscriptions_path
75
134
  end
76
135
 
77
- test "ensure deletion with token actually deletes correct subscription" do
78
- subscription1 = FactoryGirl.create(:subscription)
79
- subscription2 = FactoryGirl.create(:subscription)
136
+ test "should delete subscription if not logged in" do
137
+ subscription = FactoryGirl.create(:subscription)
80
138
 
81
139
  assert_difference('Subscription.count', -1) do
82
- delete :destroy, token: subscription1.token
140
+ delete :destroy, token: subscription.token
83
141
  end
84
- assert_equal subscription2, Subscription.first
85
- assert_redirected_to :unsubscribed
86
142
 
87
- assert_difference('Subscription.count', -1) do
88
- delete :destroy, token: subscription2.token
89
- end
90
- assert_redirected_to :unsubscribed
143
+ # If no user is logged in, deletion should take them back to the
144
+ # posts index
145
+ assert_redirected_to posts_path
91
146
  end
92
147
  end
93
148
  end
@@ -11,7 +11,7 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20141222224905) do
14
+ ActiveRecord::Schema.define(version: 20150123115226) do
15
15
 
16
16
  create_table "proclaim_comment_hierarchies", id: false, force: :cascade do |t|
17
17
  t.integer "ancestor_id", null: false
@@ -58,8 +58,9 @@ ActiveRecord::Schema.define(version: 20141222224905) do
58
58
  create_table "proclaim_subscriptions", force: :cascade do |t|
59
59
  t.integer "post_id"
60
60
  t.string "email"
61
- t.datetime "created_at", null: false
62
- t.datetime "updated_at", null: false
61
+ t.datetime "created_at", null: false
62
+ t.datetime "updated_at", null: false
63
+ t.string "name", default: "", null: false
63
64
  end
64
65
 
65
66
  add_index "proclaim_subscriptions", ["post_id", "email"], name: "index_proclaim_subscriptions_on_post_id_and_email", unique: true
@@ -1,5 +1,6 @@
1
1
  FactoryGirl.define do
2
2
  factory :subscription, class: Proclaim::Subscription do
3
+ sequence(:name) {|n| "name#{n}"}
3
4
  sequence(:email) {|n| "email#{n}@example.com"}
4
5
 
5
6
  factory :post_subscription do
@@ -39,11 +39,18 @@ class PostSubscriptionTest < ActionDispatch::IntegrationTest
39
39
  fill_in 'Email', with: "example@example.com"
40
40
  end
41
41
 
42
+ # Verify that email field is shown
43
+ assert page.has_text?('Email')
44
+
42
45
  assert_difference('Proclaim::Subscription.count', 1, "A new subscription should have been added!") do
43
46
  @show_page.new_comment_submit_button.click
44
47
  wait_for_ajax
45
48
  end
46
49
 
50
+ # Now email field should be hidden
51
+ assert page.has_no_text?('Email'),
52
+ "Email field should be hidden again when form is successful"
53
+
47
54
  # Make sure a welcome email was sent
48
55
  assert_equal ["example@example.com"], ActionMailer::Base.deliveries.last.to
49
56
 
@@ -270,4 +277,26 @@ class PostSubscriptionTest < ActionDispatch::IntegrationTest
270
277
  # Make sure no email was sent
271
278
  assert_empty ActionMailer::Base.deliveries
272
279
  end
280
+
281
+ test "cancel button should remove email field" do
282
+ post = FactoryGirl.create(:published_post)
283
+
284
+ visit proclaim.post_path(post)
285
+
286
+ within('#new_comment') do
287
+ fill_in 'Author', with: "Comment Author"
288
+ fill_in 'Body', with: "Comment Body"
289
+ fill_in 'What is', with: @show_page.antispam_solution
290
+ check 'Notify me of other comments on this post'
291
+ end
292
+
293
+ # Verify email field is shown
294
+ assert page.has_text?('Email')
295
+
296
+ # Now click cancel
297
+ @show_page.new_comment_cancel_button.click
298
+
299
+ # Now email field should be hidden
300
+ assert page.has_no_text?('Email')
301
+ end
273
302
  end
@@ -15,6 +15,7 @@ class BlogSubscriptionTest < ActionDispatch::IntegrationTest
15
15
  visit proclaim.new_subscription_path
16
16
 
17
17
  within('#new_subscription') do
18
+ fill_in 'Name', with: "example"
18
19
  fill_in 'Email', with: "example@example.com"
19
20
  fill_in 'What is', with: antispam_solution
20
21
  end
@@ -24,13 +25,17 @@ class BlogSubscriptionTest < ActionDispatch::IntegrationTest
24
25
  find('#new_subscription input[type=submit]').click
25
26
  end
26
27
 
27
- assert page.has_text?("Welcome"), "Should be shown the welcome page!"
28
+ assert page.has_text?("example"),
29
+ "Should be shown subscription name"
30
+ assert page.has_no_text?("example@example.com"),
31
+ "Should not be shown email address, in case link is compromised"
28
32
  end
29
33
 
30
34
  test "should be able to create new blog subscription while not logged in" do
31
35
  visit proclaim.new_subscription_path
32
36
 
33
37
  within('#new_subscription') do
38
+ fill_in 'Name', with: "example"
34
39
  fill_in 'Email', with: "example@example.com"
35
40
  fill_in 'What is', with: antispam_solution
36
41
  end
@@ -40,7 +45,10 @@ class BlogSubscriptionTest < ActionDispatch::IntegrationTest
40
45
  find('#new_subscription input[type=submit]').click
41
46
  end
42
47
 
43
- assert page.has_text?("Welcome"), "Should be shown the welcome page!"
48
+ assert page.has_text?("example"),
49
+ "Should be shown subscription name"
50
+ assert page.has_no_text?("example@example.com"),
51
+ "Should not be shown email address, in case link is compromised"
44
52
  end
45
53
 
46
54
  test "should not be able to create new blog subscription if spammy" do
@@ -50,6 +58,7 @@ class BlogSubscriptionTest < ActionDispatch::IntegrationTest
50
58
  visit proclaim.new_subscription_path
51
59
 
52
60
  within('#new_subscription') do
61
+ fill_in 'Name', with: "example"
53
62
  fill_in 'Email', with: "example@example.com"
54
63
  fill_in 'What is', with: "wrong answer"
55
64
  end
@@ -63,10 +72,28 @@ class BlogSubscriptionTest < ActionDispatch::IntegrationTest
63
72
  "Should be shown errors since the antispam questions failed!"
64
73
  end
65
74
 
75
+ test "catch missing name" do
76
+ visit proclaim.new_subscription_path
77
+
78
+ within('#new_subscription') do
79
+ # Don't fill in name
80
+ fill_in 'Email', with: "example@example.com"
81
+ fill_in 'What is', with: antispam_solution
82
+ end
83
+
84
+ assert_no_difference('Proclaim::Subscription.count',
85
+ "Should have caught missing name!") do
86
+ find('#new_subscription input[type=submit]').click
87
+ end
88
+
89
+ assert page.has_css?('div#error_explanation')
90
+ end
91
+
66
92
  test "catch bad email address" do
67
93
  visit proclaim.new_subscription_path
68
94
 
69
95
  within('#new_subscription') do
96
+ fill_in 'Name', with: "example"
70
97
  fill_in 'Email', with: "bad_email_address"
71
98
  fill_in 'What is', with: antispam_solution
72
99
  end
@@ -0,0 +1,37 @@
1
+ require 'test_helper'
2
+
3
+ class ManageSubscriptionTest < ActionDispatch::IntegrationTest
4
+ setup do
5
+ ApplicationController.any_instance.stubs(:current_user).returns(nil)
6
+ ApplicationController.any_instance.stubs(:authenticate_user).returns(false)
7
+
8
+ ActionMailer::Base.deliveries.clear
9
+ end
10
+
11
+ test "should be able to see subscribers index if logged in" do
12
+ user = FactoryGirl.create(:user)
13
+ sign_in user
14
+
15
+ blog_subscription = FactoryGirl.create(:subscription)
16
+ post_subscription = FactoryGirl.create(:published_post_subscription)
17
+
18
+ visit proclaim.subscriptions_path
19
+
20
+ # Verify that the blog subscription is shown
21
+ assert page.has_text?(blog_subscription.name),
22
+ "Blog subscription name should be on the index"
23
+ assert page.has_text?(blog_subscription.email),
24
+ "Blog subscription email should be on the index"
25
+
26
+ # Verify that the title of the post to which the post subscription belongs
27
+ # is shown as well
28
+ assert page.has_text?(post_subscription.post.title),
29
+ "Post subscription's post's title should be on the index"
30
+
31
+ # Finally, verify that the post subscription is shown
32
+ assert page.has_text?(post_subscription.name),
33
+ "Post subscription name should be on the index"
34
+ assert page.has_text?(post_subscription.email),
35
+ "Post subscription email should be on the index"
36
+ end
37
+ end
@@ -9,24 +9,24 @@ class UnsubscribeTest < ActionDispatch::IntegrationTest
9
9
  test "should be able to unsubscribe from blog" do
10
10
  subscription = FactoryGirl.create(:subscription)
11
11
 
12
- visit proclaim.unsubscribe_path(subscription.token)
12
+ visit proclaim.subscription_path(subscription.token)
13
13
 
14
14
  assert_difference('Proclaim::Subscription.count', -1) do
15
- click_link "unsubscribe"
15
+ click_button "Unsubscribe"
16
16
  end
17
17
 
18
- assert_equal proclaim.unsubscribed_path, current_path
18
+ assert_equal proclaim.posts_path, current_path
19
19
  end
20
20
 
21
21
  test "should be able to unsubscribe from post" do
22
22
  subscription = FactoryGirl.create(:published_post_subscription)
23
23
 
24
- visit proclaim.unsubscribe_path(subscription.token)
24
+ visit proclaim.subscription_path(subscription.token)
25
25
 
26
26
  assert_difference('Proclaim::Subscription.count', -1) do
27
- click_link "unsubscribe"
27
+ click_button "Unsubscribe"
28
28
  end
29
29
 
30
- assert_equal proclaim.unsubscribed_path, current_path
30
+ assert_equal proclaim.posts_path, current_path
31
31
  end
32
32
  end
@@ -22,9 +22,13 @@ module Proclaim
22
22
  assert_equal ["from@example.com"], mail.from
23
23
  assert_equal 2, mail.body.parts.length # Ensure multipart: text and HTML
24
24
 
25
+ # Verify the email includes a greeting
26
+ assert_match "Hello, #{subscription.name}", get_text_part(mail)
27
+ assert_match "Hello, #{subscription.name}", get_html_part(mail)
28
+
25
29
  # Verify the email includes an unsubscription URL
26
- assert_match proclaim.unsubscribe_url(subscription.token), get_text_part(mail)
27
- assert_match proclaim.unsubscribe_url(subscription.token), get_html_part(mail)
30
+ assert_match proclaim.subscription_url(subscription.token), get_text_part(mail)
31
+ assert_match proclaim.subscription_url(subscription.token), get_html_part(mail)
28
32
  end
29
33
 
30
34
  test "new comment notification email" do
@@ -38,8 +42,8 @@ module Proclaim
38
42
  assert_equal 2, mail.body.parts.length # Ensure multipart: text and HTML
39
43
 
40
44
  # Verify the email includes an unsubscription URL
41
- assert_match proclaim.unsubscribe_url(subscription.token), get_text_part(mail)
42
- assert_match proclaim.unsubscribe_url(subscription.token), get_html_part(mail)
45
+ assert_match proclaim.subscription_url(subscription.token), get_text_part(mail)
46
+ assert_match proclaim.subscription_url(subscription.token), get_html_part(mail)
43
47
  end
44
48
 
45
49
  test "new post notification email" do
@@ -53,8 +57,8 @@ module Proclaim
53
57
  assert_equal 2, mail.body.parts.length # Ensure multipart: text and HTML
54
58
 
55
59
  # Verify the email includes an unsubscription URL
56
- assert_match proclaim.unsubscribe_url(subscription.token), get_text_part(mail)
57
- assert_match proclaim.unsubscribe_url(subscription.token), get_html_part(mail)
60
+ assert_match proclaim.subscription_url(subscription.token), get_text_part(mail)
61
+ assert_match proclaim.subscription_url(subscription.token), get_html_part(mail)
58
62
  end
59
63
 
60
64
  test "images in new post notification email should have absolute URLs" do
@@ -27,6 +27,11 @@ module Proclaim
27
27
  "Post subscriptions should have unique emails!"
28
28
  end
29
29
 
30
+ test "should require a name" do
31
+ subscription = FactoryGirl.build(:subscription, name: nil)
32
+ refute subscription.save, "Subscription should require a name!"
33
+ end
34
+
30
35
  test "should not save without valid email address" do
31
36
  subscription = FactoryGirl.build(:subscription, email: nil)
32
37
  refute subscription.save,