proclaim 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|