proclaim 0.4.0 → 0.5.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG +4 -0
- data/README.md +2 -2
- data/VERSION +1 -1
- data/app/controllers/proclaim/posts_controller.rb +8 -1
- data/app/helpers/proclaim/posts_helper.rb +7 -0
- data/app/models/proclaim/post.rb +35 -2
- data/app/views/proclaim/posts/_form.html.erb +20 -4
- data/config/initializers/friendly_id.rb +88 -0
- data/db/migrate/20150213015321_create_friendly_id_slugs.rb +16 -0
- data/db/migrate/20150213015850_add_slug_to_posts.rb +20 -0
- data/lib/proclaim/engine.rb +1 -0
- data/lib/proclaim/version.rb +1 -1
- data/proclaim.gemspec +1 -0
- data/test/controllers/proclaim/posts_controller_test.rb +71 -13
- data/test/dummy/db/schema.rb +16 -1
- data/test/integration/without_javascript/post_test.rb +31 -1
- data/test/models/proclaim/post_test.rb +59 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3097ffe58a4ddda60a5dea886f2ee9397bb39acb
|
4
|
+
data.tar.gz: f80505cac5a11b356e077aa93191d31928fba9d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c61057de07fd97a72401a70f8bfd034066d4417e654b9864ae43943140fb190c18bb11400c806e7615484457f4f8ba14739ccd4ca6756bf89f6a5d7c0a04d43
|
7
|
+
data.tar.gz: d6700afa0c73bf5e8c4fe07e1d08c6726f56f849fdeebf24565a499b741941913d9c014833e028aeecb52b4ede9a80fda3c9fa4c641b2dd4cd1ae38d4612f2ef
|
data/CHANGELOG
CHANGED
data/README.md
CHANGED
@@ -25,11 +25,11 @@ scheme is given below.
|
|
25
25
|
|
26
26
|
### Get Proclaim
|
27
27
|
|
28
|
-
Proclaim 0.
|
28
|
+
Proclaim 0.5 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.
|
32
|
+
gem 'proclaim', "~> 0.5.0"
|
33
33
|
```
|
34
34
|
|
35
35
|
Run `bundle install` to install it.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
@@ -17,6 +17,13 @@ module Proclaim
|
|
17
17
|
def show
|
18
18
|
begin
|
19
19
|
authorize @post
|
20
|
+
|
21
|
+
# If an old id or a numeric id was used to find the record, then
|
22
|
+
# the request path will not match the post_path, and we should do
|
23
|
+
# a 301 redirect that uses the current friendly id.
|
24
|
+
if request.path != post_path(@post)
|
25
|
+
return redirect_to @post, status: :moved_permanently
|
26
|
+
end
|
20
27
|
rescue Pundit::NotAuthorizedError
|
21
28
|
# Don't leak that this resource actually exists. Turn the
|
22
29
|
# "permission denied" into a "not found"
|
@@ -97,7 +104,7 @@ module Proclaim
|
|
97
104
|
|
98
105
|
# Use callbacks to share common setup or constraints between actions.
|
99
106
|
def set_post
|
100
|
-
@post = Post.find(params[:id])
|
107
|
+
@post = Post.friendly.find(params[:id])
|
101
108
|
end
|
102
109
|
|
103
110
|
# Only allow a trusted parameter "white list" through.
|
data/app/models/proclaim/post.rb
CHANGED
@@ -20,8 +20,10 @@ module Proclaim
|
|
20
20
|
has_many :images, inverse_of: :post, dependent: :destroy
|
21
21
|
accepts_nested_attributes_for :images, allow_destroy: true
|
22
22
|
|
23
|
-
|
23
|
+
extend FriendlyId
|
24
|
+
friendly_id :slug_candidates, use: :history
|
24
25
|
|
26
|
+
include AASM
|
25
27
|
aasm column: :state, no_direct_assignment: true do
|
26
28
|
state :draft, initial: true
|
27
29
|
state :published
|
@@ -41,9 +43,21 @@ module Proclaim
|
|
41
43
|
validates_presence_of :title, :body, :author
|
42
44
|
validate :verifyBodyHtml
|
43
45
|
|
46
|
+
after_validation :move_friendly_id_error_to_title
|
47
|
+
|
44
48
|
before_save :sanitizeBody
|
45
49
|
after_save :notifyBlogSubscribersIfPublished
|
46
50
|
|
51
|
+
# Only save the slug history if the post is published
|
52
|
+
def create_slug
|
53
|
+
# No real reason to keep a slug history unless it's been published
|
54
|
+
unless published?
|
55
|
+
slugs.destroy_all
|
56
|
+
end
|
57
|
+
|
58
|
+
super
|
59
|
+
end
|
60
|
+
|
47
61
|
attr_writer :excerpt_length
|
48
62
|
def excerpt_length
|
49
63
|
@excerpt_length || Proclaim.excerpt_length
|
@@ -71,6 +85,23 @@ module Proclaim
|
|
71
85
|
|
72
86
|
private
|
73
87
|
|
88
|
+
def should_generate_new_friendly_id?
|
89
|
+
title_changed?
|
90
|
+
end
|
91
|
+
|
92
|
+
def move_friendly_id_error_to_title
|
93
|
+
errors.add :title, *errors.delete(:friendly_id) if errors[:friendly_id].present?
|
94
|
+
end
|
95
|
+
|
96
|
+
# Try building a slug based on the following fields in
|
97
|
+
# increasing order of specificity.
|
98
|
+
def slug_candidates
|
99
|
+
[
|
100
|
+
:title,
|
101
|
+
[:title, :id]
|
102
|
+
]
|
103
|
+
end
|
104
|
+
|
74
105
|
def verifyBodyHtml
|
75
106
|
if not errors.messages.include?(:body) and
|
76
107
|
body_plaintext.strip.empty? and
|
@@ -107,7 +138,9 @@ module Proclaim
|
|
107
138
|
|
108
139
|
def first_block_element_text(nokogiri_node)
|
109
140
|
if nokogiri_node.text?
|
110
|
-
|
141
|
+
text = block_element_text(nokogiri_node.parent).strip
|
142
|
+
|
143
|
+
return text unless text.empty?
|
111
144
|
end
|
112
145
|
|
113
146
|
nokogiri_node.children.each do |child|
|
@@ -33,11 +33,27 @@
|
|
33
33
|
<% end %>
|
34
34
|
|
35
35
|
<div class = "post">
|
36
|
-
|
36
|
+
<%=
|
37
|
+
fake_form_field @post, :title do
|
38
|
+
content_tag :h1, @post.title, class: "post_title editable",
|
39
|
+
data: {
|
40
|
+
placeholder: "Post Title",
|
41
|
+
disable_return: "true",
|
42
|
+
disable_toolbar: "true",
|
43
|
+
}
|
44
|
+
end
|
45
|
+
%>
|
37
46
|
|
38
|
-
|
39
|
-
|
40
|
-
|
47
|
+
<%=
|
48
|
+
fake_form_field @post, :body do
|
49
|
+
content_tag :div, @post.body.html_safe, class: "post_body editable",
|
50
|
+
data: {
|
51
|
+
placeholder: "Post Body",
|
52
|
+
image_upload_path: cache_image_path,
|
53
|
+
image_delete_path: discard_image_path,
|
54
|
+
}
|
55
|
+
end
|
56
|
+
%>
|
41
57
|
|
42
58
|
<div class = "post_information" style = "margin-bottom: 30px;">
|
43
59
|
<% if @post.published? %>
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# FriendlyId Global Configuration
|
2
|
+
#
|
3
|
+
# Use this to set up shared configuration options for your entire application.
|
4
|
+
# Any of the configuration options shown here can also be applied to single
|
5
|
+
# models by passing arguments to the `friendly_id` class method or defining
|
6
|
+
# methods in your model.
|
7
|
+
#
|
8
|
+
# To learn more, check out the guide:
|
9
|
+
#
|
10
|
+
# http://norman.github.io/friendly_id/file.Guide.html
|
11
|
+
|
12
|
+
FriendlyId.defaults do |config|
|
13
|
+
# ## Reserved Words
|
14
|
+
#
|
15
|
+
# Some words could conflict with Rails's routes when used as slugs, or are
|
16
|
+
# undesirable to allow as slugs. Edit this list as needed for your app.
|
17
|
+
config.use :reserved
|
18
|
+
|
19
|
+
config.reserved_words = %w(new edit index session login logout users admin
|
20
|
+
stylesheets assets javascripts images)
|
21
|
+
|
22
|
+
# ## Friendly Finders
|
23
|
+
#
|
24
|
+
# Uncomment this to use friendly finders in all models. By default, if
|
25
|
+
# you wish to find a record by its friendly id, you must do:
|
26
|
+
#
|
27
|
+
# MyModel.friendly.find('foo')
|
28
|
+
#
|
29
|
+
# If you uncomment this, you can do:
|
30
|
+
#
|
31
|
+
# MyModel.find('foo')
|
32
|
+
#
|
33
|
+
# This is significantly more convenient but may not be appropriate for
|
34
|
+
# all applications, so you must explicity opt-in to this behavior. You can
|
35
|
+
# always also configure it on a per-model basis if you prefer.
|
36
|
+
#
|
37
|
+
# Something else to consider is that using the :finders addon boosts
|
38
|
+
# performance because it will avoid Rails-internal code that makes runtime
|
39
|
+
# calls to `Module.extend`.
|
40
|
+
#
|
41
|
+
# config.use :finders
|
42
|
+
#
|
43
|
+
# ## Slugs
|
44
|
+
#
|
45
|
+
# Most applications will use the :slugged module everywhere. If you wish
|
46
|
+
# to do so, uncomment the following line.
|
47
|
+
#
|
48
|
+
# config.use :slugged
|
49
|
+
#
|
50
|
+
# By default, FriendlyId's :slugged addon expects the slug column to be named
|
51
|
+
# 'slug', but you can change it if you wish.
|
52
|
+
#
|
53
|
+
# config.slug_column = 'slug'
|
54
|
+
#
|
55
|
+
# When FriendlyId can not generate a unique ID from your base method, it appends
|
56
|
+
# a UUID, separated by a single dash. You can configure the character used as the
|
57
|
+
# separator. If you're upgrading from FriendlyId 4, you may wish to replace this
|
58
|
+
# with two dashes.
|
59
|
+
#
|
60
|
+
# config.sequence_separator = '-'
|
61
|
+
#
|
62
|
+
# ## Tips and Tricks
|
63
|
+
#
|
64
|
+
# ### Controlling when slugs are generated
|
65
|
+
#
|
66
|
+
# As of FriendlyId 5.0, new slugs are generated only when the slug field is
|
67
|
+
# nil, but if you're using a column as your base method can change this
|
68
|
+
# behavior by overriding the `should_generate_new_friendly_id` method that
|
69
|
+
# FriendlyId adds to your model. The change below makes FriendlyId 5.0 behave
|
70
|
+
# more like 4.0.
|
71
|
+
#
|
72
|
+
# config.use Module.new {
|
73
|
+
# def should_generate_new_friendly_id?
|
74
|
+
# slug.blank? || <your_column_name_here>_changed?
|
75
|
+
# end
|
76
|
+
# }
|
77
|
+
#
|
78
|
+
# FriendlyId uses Rails's `parameterize` method to generate slugs, but for
|
79
|
+
# languages that don't use the Roman alphabet, that's not usually sufficient.
|
80
|
+
# Here we use the Babosa library to transliterate Russian Cyrillic slugs to
|
81
|
+
# ASCII. If you use this, don't forget to add "babosa" to your Gemfile.
|
82
|
+
#
|
83
|
+
# config.use Module.new {
|
84
|
+
# def normalize_friendly_id(text)
|
85
|
+
# text.to_slug.normalize! :transliterations => [:russian, :latin]
|
86
|
+
# end
|
87
|
+
# }
|
88
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateFriendlyIdSlugs < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :friendly_id_slugs do |t|
|
4
|
+
t.string :slug, :null => false
|
5
|
+
t.integer :sluggable_id, :null => false
|
6
|
+
t.string :sluggable_type, :limit => 50
|
7
|
+
t.string :scope
|
8
|
+
t.datetime :created_at
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index :friendly_id_slugs, :sluggable_id
|
12
|
+
add_index :friendly_id_slugs, [:slug, :sluggable_type]
|
13
|
+
add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope], :unique => true
|
14
|
+
add_index :friendly_id_slugs, :sluggable_type
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class AddSlugToPosts < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
change_table :proclaim_posts do |t|
|
4
|
+
t.string :slug, null: false
|
5
|
+
end
|
6
|
+
|
7
|
+
# This ensures that even if two clients try to create the same
|
8
|
+
# post slug at exactly the same time, the database won't accept
|
9
|
+
# one of them (Rails would have)
|
10
|
+
add_index :proclaim_posts, :slug, unique: true
|
11
|
+
|
12
|
+
reversible do |direction|
|
13
|
+
direction.up do
|
14
|
+
print "Generating slugs for existing posts... "
|
15
|
+
Proclaim::Post.find_each(&:save)
|
16
|
+
puts "done."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/proclaim/engine.rb
CHANGED
data/lib/proclaim/version.rb
CHANGED
data/proclaim.gemspec
CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
|
|
27
27
|
s.add_dependency "sass-rails", "~> 5.0"
|
28
28
|
s.add_dependency "jquery-rails", "~> 4.0"
|
29
29
|
s.add_dependency "htmlentities", "~> 4.3"
|
30
|
+
s.add_dependency "friendly_id", "~> 5.1"
|
30
31
|
s.add_dependency "nokogiri", "~> 1.6"
|
31
32
|
s.add_dependency "premailer", "~> 1.8"
|
32
33
|
s.add_dependency "closure_tree", "~> 5.2"
|
@@ -173,34 +173,32 @@ module Proclaim
|
|
173
173
|
assert_match /not authorized/, flash[:error]
|
174
174
|
end
|
175
175
|
|
176
|
-
test "should show post if logged in" do
|
176
|
+
test "should show draft post if logged in" do
|
177
177
|
user = FactoryGirl.create(:user)
|
178
178
|
sign_in user
|
179
179
|
|
180
|
-
# Should show
|
181
|
-
newPost = FactoryGirl.create(:published_post)
|
182
|
-
|
183
|
-
get :show, id: newPost
|
184
|
-
assert_response :success
|
185
|
-
assert_equal assigns(:post), newPost
|
186
|
-
|
187
|
-
# Should also show unpublished post
|
180
|
+
# Should show draft post
|
188
181
|
newPost = FactoryGirl.create(:post)
|
189
182
|
|
190
183
|
get :show, id: newPost
|
191
184
|
assert_response :success
|
192
|
-
assert_equal assigns(:post)
|
185
|
+
assert_equal newPost, assigns(:post)
|
193
186
|
end
|
194
187
|
|
195
|
-
test "should show post if
|
188
|
+
test "should show published post if logged in" do
|
189
|
+
user = FactoryGirl.create(:user)
|
190
|
+
sign_in user
|
191
|
+
|
196
192
|
# Should show published post
|
197
193
|
newPost = FactoryGirl.create(:published_post)
|
198
194
|
|
199
195
|
get :show, id: newPost
|
200
196
|
assert_response :success
|
201
|
-
assert_equal assigns(:post)
|
197
|
+
assert_equal newPost, assigns(:post)
|
198
|
+
end
|
202
199
|
|
203
|
-
|
200
|
+
test "should not show draft post if not logged in" do
|
201
|
+
# Should not show draft post
|
204
202
|
newPost = FactoryGirl.create(:post)
|
205
203
|
|
206
204
|
# Controller should hide the "permission denied" in a "not-found"
|
@@ -209,6 +207,66 @@ module Proclaim
|
|
209
207
|
end
|
210
208
|
end
|
211
209
|
|
210
|
+
test "should show published post if not logged in" do
|
211
|
+
# Should show published post
|
212
|
+
newPost = FactoryGirl.create(:published_post)
|
213
|
+
|
214
|
+
get :show, id: newPost
|
215
|
+
assert_response :success
|
216
|
+
assert_equal newPost, assigns(:post)
|
217
|
+
end
|
218
|
+
|
219
|
+
test "should show post via id" do
|
220
|
+
post = FactoryGirl.create(:published_post, title: "New Post")
|
221
|
+
|
222
|
+
# Test with ID
|
223
|
+
get :show, id: post.id
|
224
|
+
assert_response :redirect,
|
225
|
+
"Visiting a post by ID should redirect to slug"
|
226
|
+
assert_equal post, assigns(:post)
|
227
|
+
end
|
228
|
+
|
229
|
+
test "should show post via slug" do
|
230
|
+
post = FactoryGirl.create(:published_post, title: "New Post")
|
231
|
+
|
232
|
+
# Test with slug
|
233
|
+
get :show, id: post.friendly_id
|
234
|
+
assert_response :success
|
235
|
+
assert_equal post, assigns(:post)
|
236
|
+
end
|
237
|
+
|
238
|
+
test "should not show draft post via old slugs" do
|
239
|
+
user = FactoryGirl.create(:user)
|
240
|
+
sign_in user
|
241
|
+
|
242
|
+
post = FactoryGirl.create(:post, title: "New Post")
|
243
|
+
old_slug = post.friendly_id
|
244
|
+
|
245
|
+
# Now change slug
|
246
|
+
post.title = "New Post Modified"
|
247
|
+
post.save
|
248
|
+
|
249
|
+
# Verify that old slug doesn't work
|
250
|
+
assert_raises ActiveRecord::RecordNotFound,
|
251
|
+
"Draft posts should not maintain slug history" do
|
252
|
+
get :show, id: old_slug
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
test "should show published post via old slugs" do
|
257
|
+
post = FactoryGirl.create(:published_post, title: "New Post")
|
258
|
+
old_slug = post.friendly_id
|
259
|
+
|
260
|
+
# Now change slug
|
261
|
+
post.title = "New Post Modified"
|
262
|
+
post.save
|
263
|
+
|
264
|
+
# Verify that old slug still works
|
265
|
+
get :show, id: old_slug
|
266
|
+
assert_response :redirect, "This should redirect to the current slug"
|
267
|
+
assert_equal assigns(:post), post
|
268
|
+
end
|
269
|
+
|
212
270
|
test "should get edit if logged in" do
|
213
271
|
user = FactoryGirl.create(:user)
|
214
272
|
sign_in user
|
data/test/dummy/db/schema.rb
CHANGED
@@ -11,7 +11,20 @@
|
|
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: 20150213015850) do
|
15
|
+
|
16
|
+
create_table "friendly_id_slugs", force: :cascade do |t|
|
17
|
+
t.string "slug", null: false
|
18
|
+
t.integer "sluggable_id", null: false
|
19
|
+
t.string "sluggable_type", limit: 50
|
20
|
+
t.string "scope"
|
21
|
+
t.datetime "created_at"
|
22
|
+
end
|
23
|
+
|
24
|
+
add_index "friendly_id_slugs", ["slug", "sluggable_type", "scope"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope", unique: true
|
25
|
+
add_index "friendly_id_slugs", ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type"
|
26
|
+
add_index "friendly_id_slugs", ["sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_id"
|
27
|
+
add_index "friendly_id_slugs", ["sluggable_type"], name: "index_friendly_id_slugs_on_sluggable_type"
|
15
28
|
|
16
29
|
create_table "proclaim_comment_hierarchies", id: false, force: :cascade do |t|
|
17
30
|
t.integer "ancestor_id", null: false
|
@@ -50,9 +63,11 @@ ActiveRecord::Schema.define(version: 20150123115226) do
|
|
50
63
|
t.datetime "published_at"
|
51
64
|
t.datetime "created_at", null: false
|
52
65
|
t.datetime "updated_at", null: false
|
66
|
+
t.string "slug"
|
53
67
|
end
|
54
68
|
|
55
69
|
add_index "proclaim_posts", ["author_id"], name: "index_proclaim_posts_on_author_id"
|
70
|
+
add_index "proclaim_posts", ["slug"], name: "index_proclaim_posts_on_slug", unique: true
|
56
71
|
add_index "proclaim_posts", ["state"], name: "index_proclaim_posts_on_state"
|
57
72
|
|
58
73
|
create_table "proclaim_subscriptions", force: :cascade do |t|
|
@@ -145,7 +145,7 @@ class PostTest < ActionDispatch::IntegrationTest
|
|
145
145
|
"Post 3 draft should be shown before post 1 draft!"
|
146
146
|
end
|
147
147
|
|
148
|
-
test "show should
|
148
|
+
test "show should include author name" do
|
149
149
|
post = FactoryGirl.create(:published_post)
|
150
150
|
|
151
151
|
visit proclaim.post_path(post)
|
@@ -153,6 +153,36 @@ class PostTest < ActionDispatch::IntegrationTest
|
|
153
153
|
assert page.has_text? post.author.send(Proclaim.author_name_method)
|
154
154
|
end
|
155
155
|
|
156
|
+
test "show should work via id" do
|
157
|
+
post = FactoryGirl.create(:published_post)
|
158
|
+
|
159
|
+
visit proclaim.post_path(post.id)
|
160
|
+
assert page.has_text? post.title
|
161
|
+
assert_equal proclaim.post_path(post.friendly_id), current_path,
|
162
|
+
"Post show via ID should redirect to more friendly URL"
|
163
|
+
end
|
164
|
+
|
165
|
+
test "show should work via slug" do
|
166
|
+
post = FactoryGirl.create(:published_post)
|
167
|
+
|
168
|
+
visit proclaim.post_path(post.friendly_id)
|
169
|
+
assert page.has_text? post.title
|
170
|
+
end
|
171
|
+
|
172
|
+
test "show should work via old slugs for published posts" do
|
173
|
+
post = FactoryGirl.create(:published_post, title: "New Post")
|
174
|
+
old_slug = post.friendly_id
|
175
|
+
|
176
|
+
# Change slug
|
177
|
+
post.title = "New Post Modified"
|
178
|
+
post.save
|
179
|
+
|
180
|
+
visit proclaim.post_path(old_slug)
|
181
|
+
assert page.has_text? post.title
|
182
|
+
assert_equal proclaim.post_path(post.friendly_id), current_path,
|
183
|
+
"Post show via ID should redirect to more friendly URL"
|
184
|
+
end
|
185
|
+
|
156
186
|
test "image should have relative source path" do
|
157
187
|
user = FactoryGirl.create(:user)
|
158
188
|
sign_in user
|
@@ -122,6 +122,10 @@ module Proclaim
|
|
122
122
|
post = FactoryGirl.build(:post,
|
123
123
|
body: "This is outside.<p>This is inside.</p>")
|
124
124
|
assert_equal "This is outside.", post.excerpt
|
125
|
+
|
126
|
+
post = FactoryGirl.build(:post,
|
127
|
+
body: "<p>\r\n</p><p>foo</p>")
|
128
|
+
assert_equal "foo", post.excerpt
|
125
129
|
end
|
126
130
|
|
127
131
|
test "verify body sanitization" do
|
@@ -130,5 +134,60 @@ module Proclaim
|
|
130
134
|
|
131
135
|
assert_equal "foo alert('bar');", post.body
|
132
136
|
end
|
137
|
+
|
138
|
+
test "verify slug presence" do
|
139
|
+
post = FactoryGirl.build(:post, title: "New Post")
|
140
|
+
assert_nil post.slug
|
141
|
+
|
142
|
+
post.save
|
143
|
+
assert_equal "new-post", post.slug
|
144
|
+
|
145
|
+
assert_equal post, Post.friendly.find(post.slug)
|
146
|
+
assert_equal post, Post.friendly.find(post.id),
|
147
|
+
"Should also be able to use regular-old ID"
|
148
|
+
end
|
149
|
+
|
150
|
+
test "verify slug uniqueness" do
|
151
|
+
post = FactoryGirl.create(:post, title: "New Post")
|
152
|
+
assert_equal "new-post", post.slug
|
153
|
+
|
154
|
+
post = FactoryGirl.build(:post, title: "New Post") # Same title
|
155
|
+
post.valid?
|
156
|
+
|
157
|
+
assert post.save, "Title should not be required to be unique"
|
158
|
+
assert_not_equal "new-post", post.slug, "Slugs should be unique"
|
159
|
+
end
|
160
|
+
|
161
|
+
test "verify unpublished post slug changes but does not keep history" do
|
162
|
+
post = FactoryGirl.create(:post, title: "New Post")
|
163
|
+
assert_equal "new-post", post.slug
|
164
|
+
assert_equal post, Post.friendly.find(post.slug)
|
165
|
+
|
166
|
+
post.title = "New Post Modified"
|
167
|
+
post.save
|
168
|
+
assert_equal "new-post-modified", post.slug,
|
169
|
+
"The slug should change if the post title changes"
|
170
|
+
assert_equal post, Post.friendly.find(post.slug)
|
171
|
+
|
172
|
+
# Assert that we cannot use the old slug
|
173
|
+
refute Post.friendly.exists_by_friendly_id?("new-post"),
|
174
|
+
"Should not be able to use old slug on an unpublished post"
|
175
|
+
end
|
176
|
+
|
177
|
+
test "verify published post slug changes and keeps history" do
|
178
|
+
post = FactoryGirl.create(:published_post, title: "New Post")
|
179
|
+
assert_equal "new-post", post.slug
|
180
|
+
assert_equal post, Post.friendly.find(post.slug)
|
181
|
+
|
182
|
+
post.title = "New Post Modified"
|
183
|
+
post.save
|
184
|
+
assert_equal "new-post-modified", post.slug,
|
185
|
+
"The slug should change if the post title changes"
|
186
|
+
assert_equal post, Post.friendly.find(post.slug)
|
187
|
+
|
188
|
+
# Also assert that we can use the old slug (i.e. published links
|
189
|
+
# can't be broken)
|
190
|
+
assert_equal post, Post.friendly.find("new-post")
|
191
|
+
end
|
133
192
|
end
|
134
193
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: proclaim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyle Fazzari
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '4.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: friendly_id
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '5.1'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '5.1'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: nokogiri
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -395,6 +409,7 @@ files:
|
|
395
409
|
- app/views/proclaim/subscriptions/index.html.erb
|
396
410
|
- app/views/proclaim/subscriptions/new.html.erb
|
397
411
|
- app/views/proclaim/subscriptions/show.html.erb
|
412
|
+
- config/initializers/friendly_id.rb
|
398
413
|
- config/routes.rb
|
399
414
|
- db/migrate/20141108222616_create_proclaim_posts.rb
|
400
415
|
- db/migrate/20141114235359_create_proclaim_comments.rb
|
@@ -402,6 +417,8 @@ files:
|
|
402
417
|
- db/migrate/20141210234057_create_proclaim_subscriptions.rb
|
403
418
|
- db/migrate/20141222224905_create_proclaim_images.rb
|
404
419
|
- db/migrate/20150123115226_add_name_to_subscriptions.rb
|
420
|
+
- db/migrate/20150213015321_create_friendly_id_slugs.rb
|
421
|
+
- db/migrate/20150213015850_add_slug_to_posts.rb
|
405
422
|
- lib/generators/proclaim/install_generator.rb
|
406
423
|
- lib/generators/proclaim/templates/README
|
407
424
|
- lib/generators/proclaim/templates/initialize_proclaim.rb
|