friendly_id 5.6.0 → 5.7.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.
data/test/slugged_test.rb DELETED
@@ -1,628 +0,0 @@
1
- require "helper"
2
-
3
- class Journalist < ActiveRecord::Base
4
- extend FriendlyId
5
- friendly_id :name, use: :slugged
6
- end
7
-
8
- class Article < ActiveRecord::Base
9
- extend FriendlyId
10
- friendly_id :name, use: :slugged
11
- end
12
-
13
- class Novelist < ActiveRecord::Base
14
- extend FriendlyId
15
- friendly_id :name, use: :slugged, sequence_separator: "_"
16
-
17
- def normalize_friendly_id(string)
18
- super.tr("-", "_")
19
- end
20
- end
21
-
22
- class SluggedTest < TestCaseClass
23
- include FriendlyId::Test
24
- include FriendlyId::Test::Shared::Core
25
- include FriendlyId::Test::Shared::Slugged
26
-
27
- def model_class
28
- Journalist
29
- end
30
-
31
- test "should allow validations on the slug" do
32
- model_class = Class.new(ActiveRecord::Base) do
33
- self.table_name = "articles"
34
- extend FriendlyId
35
- friendly_id :name, use: :slugged
36
- validates_length_of :slug, maximum: 1
37
- def self.name
38
- "Article"
39
- end
40
- end
41
- instance = model_class.new name: "hello"
42
- refute instance.valid?
43
- end
44
-
45
- test "should allow nil slugs" do
46
- transaction do
47
- m1 = model_class.create!
48
- model_class.create!
49
- assert_nil m1.slug
50
- end
51
- end
52
-
53
- test "should not break validates_uniqueness_of" do
54
- model_class = Class.new(ActiveRecord::Base) do
55
- self.table_name = "journalists"
56
- extend FriendlyId
57
- friendly_id :name, use: :slugged
58
- validates_uniqueness_of :slug_en
59
- def self.name
60
- "Journalist"
61
- end
62
- end
63
- transaction do
64
- instance = model_class.create! name: "hello", slug_en: "hello"
65
- instance2 = model_class.create name: "hello", slug_en: "hello"
66
- assert instance.valid?
67
- refute instance2.valid?
68
- end
69
- end
70
-
71
- test "should allow a record to reuse its own slug" do
72
- with_instance_of(model_class) do |record|
73
- old_id = record.friendly_id
74
- record.slug = nil
75
- record.save!
76
- assert_equal old_id, record.friendly_id
77
- end
78
- end
79
-
80
- test "should not update matching slug" do
81
- klass = Class.new model_class do
82
- def should_generate_new_friendly_id?
83
- name_changed?
84
- end
85
- end
86
- with_instance_of klass do |record|
87
- old_id = record.friendly_id
88
- record.name += " "
89
- record.save!
90
- assert_equal old_id, record.friendly_id
91
- end
92
- end
93
-
94
- test "should set slug on create if unrelated validations fail" do
95
- klass = Class.new model_class do
96
- validates_presence_of :active
97
- friendly_id :name, use: :slugged
98
-
99
- def self.name
100
- "Journalist"
101
- end
102
- end
103
-
104
- transaction do
105
- instance = klass.new name: "foo"
106
- refute instance.save
107
- refute instance.valid?
108
- assert_equal "foo", instance.slug
109
- end
110
- end
111
-
112
- test "should not set slug on create if slug validation fails" do
113
- klass = Class.new model_class do
114
- validates_presence_of :active
115
- validates_length_of :slug, minimum: 2
116
- friendly_id :name, use: :slugged
117
-
118
- def self.name
119
- "Journalist"
120
- end
121
- end
122
-
123
- transaction do
124
- instance = klass.new name: "x"
125
- refute instance.save
126
- refute instance.valid?
127
- assert_nil instance.slug
128
- end
129
- end
130
-
131
- test "should set slug on create if unrelated validations fail with custom slug_column" do
132
- klass = Class.new(ActiveRecord::Base) do
133
- self.table_name = "authors"
134
- extend FriendlyId
135
- validates_presence_of :active
136
- friendly_id :name, use: :slugged, slug_column: :subdomain
137
-
138
- def self.name
139
- "Author"
140
- end
141
- end
142
-
143
- transaction do
144
- instance = klass.new name: "foo"
145
- refute instance.save
146
- refute instance.valid?
147
- assert_equal "foo", instance.subdomain
148
- end
149
- end
150
-
151
- test "should not set slug on create if custom slug column validations fail" do
152
- klass = Class.new(ActiveRecord::Base) do
153
- self.table_name = "authors"
154
- extend FriendlyId
155
- validates_length_of :subdomain, minimum: 2
156
- friendly_id :name, use: :slugged, slug_column: :subdomain
157
-
158
- def self.name
159
- "Author"
160
- end
161
- end
162
-
163
- transaction do
164
- instance = klass.new name: "x"
165
- refute instance.save
166
- refute instance.valid?
167
- assert_nil instance.subdomain
168
- end
169
- end
170
-
171
- test "should keep new slug on save if unrelated validations fail" do
172
- klass = Class.new model_class do
173
- validates_presence_of :active
174
- friendly_id :name, use: :slugged
175
-
176
- def self.name
177
- "Journalist"
178
- end
179
- end
180
-
181
- transaction do
182
- instance = klass.new name: "foo", active: true
183
- assert instance.save
184
- assert instance.valid?
185
- instance.name = "foobar"
186
- instance.slug = nil
187
- instance.active = nil
188
- refute instance.save
189
- refute instance.valid?
190
- assert_equal "foobar", instance.slug
191
- end
192
- end
193
-
194
- test "should not update slug on save if slug validations fail" do
195
- klass = Class.new model_class do
196
- validates_length_of :slug, minimum: 2
197
- friendly_id :name, use: :slugged
198
-
199
- def self.name
200
- "Journalist"
201
- end
202
- end
203
-
204
- transaction do
205
- instance = klass.new name: "foo", active: true
206
- assert instance.save
207
- assert instance.valid?
208
- instance.name = "x"
209
- instance.slug = nil
210
- instance.active = nil
211
- refute instance.save
212
- assert_equal "foo", instance.slug
213
- end
214
- end
215
- end
216
-
217
- class SlugGeneratorTest < TestCaseClass
218
- include FriendlyId::Test
219
-
220
- def model_class
221
- Journalist
222
- end
223
-
224
- test "should quote column names" do
225
- model_class = Class.new(ActiveRecord::Base) do
226
- # This has been added in 635731bb to fix MySQL/Rubinius. It may still
227
- # be necessary, but causes an exception to be raised on Rails 4, so I'm
228
- # commenting it out. If it causes MySQL/Rubinius to fail again we'll
229
- # look for another solution.
230
- # self.abstract_class = true
231
- self.table_name = "journalists"
232
- extend FriendlyId
233
- friendly_id :name, use: :slugged, slug_column: "strange name"
234
- end
235
-
236
- begin
237
- with_instance_of(model_class) { |record| assert model_class.friendly.find(record.friendly_id) }
238
- rescue ActiveRecord::StatementInvalid
239
- flunk "column name was not quoted"
240
- end
241
- end
242
-
243
- test "should not resequence lower sequences on update" do
244
- transaction do
245
- m1 = model_class.create! name: "a b c d"
246
- assert_equal "a-b-c-d", m1.slug
247
- model_class.create! name: "a b c d"
248
- m1 = model_class.friendly.find(m1.id)
249
- m1.save!
250
- assert_equal "a-b-c-d", m1.slug
251
- end
252
- end
253
-
254
- test "should correctly sequence slugs that end with numbers" do
255
- transaction do
256
- record1 = model_class.create! name: "Peugeot 206"
257
- assert_equal "peugeot-206", record1.slug
258
- record2 = model_class.create! name: "Peugeot 206"
259
- assert_match(/\Apeugeot-206-([a-z0-9]+-){4}[a-z0-9]+\z/, record2.slug)
260
- end
261
- end
262
-
263
- test "should correctly sequence slugs with underscores" do
264
- transaction do
265
- Novelist.create! name: "wordsfail, buildings tumble"
266
- record2 = Novelist.create! name: "word fail"
267
- assert_equal "word_fail", record2.slug
268
- end
269
- end
270
-
271
- test "should correctly sequence numeric slugs" do
272
- transaction do
273
- n2 = 2.times.map { Article.create name: "123" }.last
274
- assert_match(/\A123-.*/, n2.friendly_id)
275
- end
276
- end
277
- end
278
-
279
- class SlugSeparatorTest < TestCaseClass
280
- include FriendlyId::Test
281
-
282
- class Journalist < ActiveRecord::Base
283
- extend FriendlyId
284
- friendly_id :name, use: :slugged, sequence_separator: ":"
285
- end
286
-
287
- def model_class
288
- Journalist
289
- end
290
-
291
- test "should sequence with configured sequence separator" do
292
- with_instance_of model_class do |record|
293
- record2 = model_class.create! name: record.name
294
- assert record2.friendly_id.match(/:.*\z/)
295
- end
296
- end
297
-
298
- test "should detect when a stored slug has been cleared" do
299
- with_instance_of model_class do |record|
300
- record.slug = nil
301
- assert record.should_generate_new_friendly_id?
302
- end
303
- end
304
-
305
- test "should correctly sequence slugs that uses single dashes as sequence separator" do
306
- model_class = Class.new(ActiveRecord::Base) do
307
- self.table_name = "journalists"
308
- extend FriendlyId
309
- friendly_id :name, use: :slugged, sequence_separator: "-"
310
- def self.name
311
- "Journalist"
312
- end
313
- end
314
- transaction do
315
- record1 = model_class.create! name: "Peugeot 206"
316
- assert_equal "peugeot-206", record1.slug
317
- record2 = model_class.create! name: "Peugeot 206"
318
- assert_match(/\Apeugeot-206-([a-z0-9]+-){4}[a-z0-9]+\z/, record2.slug)
319
- end
320
- end
321
-
322
- test "should sequence blank slugs without a separator" do
323
- with_instance_of model_class, name: "" do |record|
324
- assert_match(/\A([a-z0-9]+-){4}[a-z0-9]+\z/, record.slug)
325
- end
326
- end
327
- end
328
-
329
- class SlugLimitTest < TestCaseClass
330
- include FriendlyId::Test
331
-
332
- class Journalist < ActiveRecord::Base
333
- extend FriendlyId
334
- friendly_id :name, use: :slugged, slug_limit: 40
335
- end
336
-
337
- def model_class
338
- Journalist
339
- end
340
-
341
- test "should limit slug size" do
342
- transaction do
343
- m1 = model_class.create! name: "a" * 50
344
- assert_equal m1.slug, "a" * 40
345
- m2 = model_class.create! name: m1.name
346
- m2.save!
347
- # "aaa-<uid>"
348
- assert_match(/\Aa{3}-/, m2.slug)
349
- end
350
- end
351
- end
352
-
353
- class DefaultScopeTest < TestCaseClass
354
- include FriendlyId::Test
355
-
356
- class Journalist < ActiveRecord::Base
357
- extend FriendlyId
358
- friendly_id :name, use: :slugged
359
- default_scope -> { where(active: true).order("id ASC") }
360
- end
361
-
362
- test "friendly_id should correctly sequence a default_scoped ordered table" do
363
- transaction do
364
- 3.times { assert Journalist.create name: "a", active: true }
365
- end
366
- end
367
-
368
- test "friendly_id should correctly sequence a default_scoped scoped table" do
369
- transaction do
370
- assert Journalist.create name: "a", active: false
371
- assert Journalist.create name: "a", active: true
372
- end
373
- end
374
- end
375
-
376
- class UuidAsPrimaryKeyFindTest < TestCaseClass
377
- include FriendlyId::Test
378
-
379
- class MenuItem < ActiveRecord::Base
380
- extend FriendlyId
381
- friendly_id :name, use: :slugged
382
- before_create :init_primary_key
383
-
384
- def self.primary_key
385
- "uuid_key"
386
- end
387
-
388
- # Overwrite the method added by FriendlyId
389
- def self.primary_key_type
390
- :uuid
391
- end
392
-
393
- private
394
-
395
- def init_primary_key
396
- self.uuid_key = SecureRandom.uuid
397
- end
398
- end
399
-
400
- def model_class
401
- MenuItem
402
- end
403
-
404
- test "should have a uuid_key as a primary key" do
405
- assert_equal "uuid_key", model_class.primary_key
406
- assert_equal :uuid, model_class.primary_key_type
407
- end
408
-
409
- test "should be findable by the UUID primary key" do
410
- with_instance_of(model_class) do |record|
411
- assert model_class.friendly.find record.id
412
- end
413
- end
414
-
415
- test "should handle a string that simply contains a UUID correctly" do
416
- with_instance_of(model_class) do |record|
417
- assert_raises(ActiveRecord::RecordNotFound) do
418
- model_class.friendly.find "test-#{SecureRandom.uuid}"
419
- end
420
- end
421
- end
422
- end
423
-
424
- class UnderscoreAsSequenceSeparatorRegressionTest < TestCaseClass
425
- include FriendlyId::Test
426
-
427
- class Manual < ActiveRecord::Base
428
- extend FriendlyId
429
- friendly_id :name, use: :slugged, sequence_separator: "_"
430
- end
431
-
432
- test "should not create duplicate slugs" do
433
- 3.times do
434
- transaction do
435
- assert Manual.create! name: "foo"
436
- rescue
437
- flunk "Tried to insert duplicate slug"
438
- end
439
- end
440
- end
441
- end
442
-
443
- # https://github.com/norman/friendly_id/issues/148
444
- class FailedValidationAfterUpdateRegressionTest < TestCaseClass
445
- include FriendlyId::Test
446
-
447
- class Journalist < ActiveRecord::Base
448
- extend FriendlyId
449
- friendly_id :name, use: :slugged
450
- validates_presence_of :slug_de
451
- end
452
-
453
- test "to_param should return the unchanged value if the slug changes before validation fails" do
454
- transaction do
455
- journalist = Journalist.create! name: "Joseph Pulitzer", slug_de: "value"
456
- assert_equal "joseph-pulitzer", journalist.to_param
457
- assert journalist.valid?
458
- assert journalist.persisted?
459
- journalist.name = "Joe Pulitzer"
460
- journalist.slug_de = nil
461
- assert !journalist.valid?
462
- assert_equal "joseph-pulitzer", journalist.to_param
463
- end
464
- end
465
- end
466
-
467
- # https://github.com/norman/friendly_id/issues/947
468
- class GeneratingSlugWithValidationSkippedTest < TestCaseClass
469
- include FriendlyId::Test
470
-
471
- class Journalist < ActiveRecord::Base
472
- extend FriendlyId
473
- friendly_id :name, use: :slugged
474
- end
475
-
476
- test "should generate slug when skipping validation" do
477
- transaction do
478
- m1 = Journalist.new
479
- m1.name = "Bob Timesletter"
480
- m1.save(validate: false)
481
- assert_equal "bob-timesletter", m1.slug
482
- end
483
- end
484
-
485
- test "should generate slug when #valid? called" do
486
- transaction do
487
- m1 = Journalist.new
488
- m1.name = "Bob Timesletter"
489
- m1.valid?
490
- m1.save(validate: false)
491
- assert_equal "bob-timesletter", m1.slug
492
- end
493
- end
494
- end
495
-
496
- class ToParamTest < TestCaseClass
497
- include FriendlyId::Test
498
-
499
- class Journalist < ActiveRecord::Base
500
- extend FriendlyId
501
- validates_presence_of :active
502
- validates_length_of :slug, minimum: 2
503
- friendly_id :name, use: :slugged
504
-
505
- attr_accessor :to_param_in_callback
506
-
507
- after_save do
508
- self.to_param_in_callback = to_param
509
- end
510
- end
511
-
512
- test "to_param should return nil if record is unpersisted" do
513
- assert_nil Journalist.new.to_param
514
- end
515
-
516
- test "to_param should return original slug if record failed validation" do
517
- journalist = Journalist.new name: "Clark Kent", active: nil
518
- refute journalist.save
519
- assert_equal "clark-kent", journalist.to_param
520
- end
521
-
522
- test "to_param should clear slug attributes if slug attribute fails validation" do
523
- journalist = Journalist.new name: "x", active: true
524
- refute journalist.save
525
- assert_nil journalist.to_param
526
- end
527
-
528
- test "to_param should clear slug attribute if slug attribute fails validation and unrelated validation fails" do
529
- journalist = Journalist.new name: "x", active: nil
530
- refute journalist.save
531
- assert_nil journalist.to_param
532
- end
533
-
534
- test "to_param should use slugged attribute if record saved successfully" do
535
- transaction do
536
- journalist = Journalist.new name: "Clark Kent", active: true
537
- assert journalist.save
538
- assert_equal "clark-kent", journalist.to_param
539
- end
540
- end
541
-
542
- test "to_param should use new slug if existing record changes but fails to save" do
543
- transaction do
544
- journalist = Journalist.new name: "Clark Kent", active: true
545
- assert journalist.save
546
- journalist.name = "Superman"
547
- journalist.slug = nil
548
- journalist.active = nil
549
- refute journalist.save
550
- assert_equal "superman", journalist.to_param
551
- end
552
- end
553
-
554
- test "to_param should use original slug if new slug attribute is not valid" do
555
- transaction do
556
- journalist = Journalist.new name: "Clark Kent", active: true
557
- assert journalist.save
558
- journalist.name = "x"
559
- journalist.slug = nil
560
- journalist.active = nil
561
- refute journalist.save
562
- assert_equal "clark-kent", journalist.to_param
563
- end
564
- end
565
-
566
- test "to_param should use new slug if existing record changes successfully" do
567
- transaction do
568
- journalist = Journalist.new name: "Clark Kent", active: true
569
- assert journalist.save
570
- journalist.name = "Superman"
571
- journalist.slug = nil
572
- assert journalist.save
573
- assert_equal "superman", journalist.to_param
574
- end
575
- end
576
-
577
- test "to_param should use new slug within callbacks if new record is saved successfully" do
578
- transaction do
579
- journalist = Journalist.new name: "Clark Kent", active: true
580
- assert journalist.save
581
- assert_equal "clark-kent", journalist.to_param_in_callback, "value of to_param in callback should use the new slug value"
582
- end
583
- end
584
-
585
- test "to_param should use new slug within callbacks if existing record changes successfully" do
586
- transaction do
587
- journalist = Journalist.new name: "Clark Kent", active: true
588
- assert journalist.save
589
- assert journalist.valid?
590
- journalist.name = "Superman"
591
- journalist.slug = nil
592
- assert journalist.save, "save should be successful"
593
- assert_equal "superman", journalist.to_param_in_callback, "value of to_param in callback should use the new slug value"
594
- end
595
- end
596
- end
597
-
598
- class ConfigurableRoutesTest < TestCaseClass
599
- include FriendlyId::Test
600
-
601
- class Article < ActiveRecord::Base
602
- extend FriendlyId
603
-
604
- friendly_id :name, use: :slugged, routes: :friendly
605
- end
606
-
607
- class Novel < ActiveRecord::Base
608
- extend FriendlyId
609
-
610
- friendly_id :name, use: :slugged, routes: :default
611
- end
612
-
613
- test "to_param should return a friendly id when the routes option is set to :friendly" do
614
- transaction do
615
- article = Article.create! name: "Titanic Hits; Iceberg Sinks"
616
-
617
- assert_equal "titanic-hits-iceberg-sinks", article.to_param
618
- end
619
- end
620
-
621
- test "to_param should return the id when the routes option is set to anything but friendly" do
622
- transaction do
623
- novel = Novel.create! name: "Don Quixote"
624
-
625
- assert_equal novel.id.to_s, novel.to_param
626
- end
627
- end
628
- end