proclaim 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +9 -0
- data/README.md +91 -10
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/app/assets/javascripts/proclaim/comments_handler.js.coffee +3 -0
- data/app/assets/stylesheets/proclaim/subscriptions.css.scss +33 -0
- data/app/controllers/proclaim/comments_controller.rb +3 -1
- data/app/controllers/proclaim/posts_controller.rb +10 -6
- data/app/controllers/proclaim/subscriptions_controller.rb +31 -14
- data/app/helpers/proclaim/application_helper.rb +3 -8
- data/app/models/proclaim/comment.rb +1 -0
- data/app/models/proclaim/post.rb +2 -0
- data/app/models/proclaim/subscription.rb +7 -6
- data/app/policies/proclaim/image_policy.rb +1 -1
- data/app/policies/proclaim/subscription_policy.rb +10 -6
- data/app/views/layouts/proclaim/subscription_mailer.html.erb +34 -4
- data/app/views/proclaim/posts/edit.html.erb +3 -1
- data/app/views/proclaim/posts/index.html.erb +2 -0
- data/app/views/proclaim/posts/new.html.erb +3 -1
- data/app/views/proclaim/posts/show.html.erb +3 -1
- data/app/views/proclaim/subscription_mailer/welcome_email.html.erb +9 -7
- data/app/views/proclaim/subscriptions/_form.html.erb +7 -2
- data/app/views/proclaim/subscriptions/index.html.erb +89 -0
- data/app/views/proclaim/subscriptions/new.html.erb +3 -1
- data/app/views/proclaim/subscriptions/show.html.erb +26 -0
- data/config/routes.rb +2 -6
- data/db/migrate/20150123115226_add_name_to_subscriptions.rb +7 -0
- data/lib/generators/proclaim/templates/initialize_proclaim.rb +19 -0
- data/lib/proclaim.rb +93 -0
- data/lib/proclaim/engine.rb +18 -0
- data/lib/proclaim/version.rb +1 -1
- data/test/controllers/proclaim/subscriptions_controller_test.rb +76 -21
- data/test/dummy/db/schema.rb +4 -3
- data/test/factories/proclaim/subscription.rb +1 -0
- data/test/integration/with_javascript/post_subscription_test.rb +29 -0
- data/test/integration/without_javascript/blog_subscription_test.rb +29 -2
- data/test/integration/without_javascript/manage_subscriptions_test.rb +37 -0
- data/test/integration/without_javascript/unsubscribe_test.rb +6 -6
- data/test/mailers/proclaim/subscription_mailer_test.rb +10 -6
- data/test/models/proclaim/subscription_test.rb +5 -0
- data/test/policies/proclaim/image_policy_test.rb +83 -0
- data/test/policies/proclaim/post_policy_test.rb +11 -0
- data/test/policies/proclaim/subscription_policy_test.rb +27 -15
- data/test/unit/proclaim/new_comment_callback_test.rb +62 -0
- data/test/unit/proclaim/new_subscription_callback_test.rb +62 -0
- data/test/unit/proclaim/post_published_callback_test.rb +74 -0
- metadata +15 -5
- data/app/views/proclaim/subscriptions/subscribed.html.erb +0 -7
- data/app/views/proclaim/subscriptions/unsubscribe.html.erb +0 -7
- data/app/views/proclaim/subscriptions/unsubscribed.html.erb +0 -3
data/lib/proclaim/engine.rb
CHANGED
@@ -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
|
data/lib/proclaim/version.rb
CHANGED
@@ -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 :
|
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 :
|
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 "
|
65
|
-
|
66
|
-
|
121
|
+
test "should delete subscription if logged in" do
|
122
|
+
user = FactoryGirl.create(:user)
|
123
|
+
sign_in user
|
67
124
|
|
68
|
-
|
69
|
-
assert_response :success
|
70
|
-
assert_equal subscription1, assigns(:subscription)
|
125
|
+
subscription = FactoryGirl.create(:subscription)
|
71
126
|
|
72
|
-
|
73
|
-
|
74
|
-
|
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 "
|
78
|
-
|
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:
|
140
|
+
delete :destroy, token: subscription.token
|
83
141
|
end
|
84
|
-
assert_equal subscription2, Subscription.first
|
85
|
-
assert_redirected_to :unsubscribed
|
86
142
|
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
data/test/dummy/db/schema.rb
CHANGED
@@ -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:
|
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",
|
62
|
-
t.datetime "updated_at",
|
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
|
@@ -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?("
|
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?("
|
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.
|
12
|
+
visit proclaim.subscription_path(subscription.token)
|
13
13
|
|
14
14
|
assert_difference('Proclaim::Subscription.count', -1) do
|
15
|
-
|
15
|
+
click_button "Unsubscribe"
|
16
16
|
end
|
17
17
|
|
18
|
-
assert_equal proclaim.
|
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.
|
24
|
+
visit proclaim.subscription_path(subscription.token)
|
25
25
|
|
26
26
|
assert_difference('Proclaim::Subscription.count', -1) do
|
27
|
-
|
27
|
+
click_button "Unsubscribe"
|
28
28
|
end
|
29
29
|
|
30
|
-
assert_equal proclaim.
|
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.
|
27
|
-
assert_match proclaim.
|
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.
|
42
|
-
assert_match proclaim.
|
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.
|
57
|
-
assert_match proclaim.
|
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,
|