mongoid_paranoia 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,751 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Paranoia do
4
+
5
+ describe ".scoped" do
6
+
7
+ it "returns a scoped criteria" do
8
+ expect(ParanoidPost.scoped.selector).to eq({ "deleted_at" => nil })
9
+ end
10
+ end
11
+
12
+ describe ".deleted" do
13
+
14
+ context "when called on a root document" do
15
+
16
+ let(:post) do
17
+ ParanoidPost.create(title: "testing")
18
+ end
19
+
20
+ before do
21
+ post.destroy
22
+ end
23
+
24
+ let(:deleted) do
25
+ ParanoidPost.deleted
26
+ end
27
+
28
+ it "returns the deleted documents" do
29
+ expect(deleted).to eq([ post ])
30
+ end
31
+ end
32
+
33
+ context "when called on an embedded document" do
34
+
35
+ let(:person) do
36
+ Person.create
37
+ end
38
+
39
+ let(:phone) do
40
+ person.paranoid_phones.create
41
+ end
42
+
43
+ before do
44
+ phone.destroy
45
+ person.reload
46
+ end
47
+
48
+ it "returns the deleted documents" do
49
+ expect(person.paranoid_phones.deleted.to_a).to eq([ phone ])
50
+ end
51
+
52
+ it "returns the correct count" do
53
+ expect(person.paranoid_phones.deleted.count).to eq(1)
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "#destroy!" do
59
+
60
+ context "when the document is a root" do
61
+
62
+ let(:post) do
63
+ ParanoidPost.create(title: "testing")
64
+ end
65
+
66
+ before do
67
+ post.destroy!
68
+ end
69
+
70
+ let(:raw) do
71
+ ParanoidPost.collection.find(_id: post.id).first
72
+ end
73
+
74
+ it "hard deletes the document" do
75
+ expect(raw).to be_nil
76
+ end
77
+
78
+ it "executes the before destroy callbacks" do
79
+ expect(post.before_destroy_called).to be_truthy
80
+ end
81
+
82
+ it "executes the after destroy callbacks" do
83
+ expect(post.after_destroy_called).to be_truthy
84
+ end
85
+ end
86
+
87
+ context "when the document is embedded" do
88
+
89
+ let(:person) do
90
+ Person.create
91
+ end
92
+
93
+ let(:phone) do
94
+ person.paranoid_phones.create(number: "911")
95
+ end
96
+
97
+ before do
98
+ phone.destroy!
99
+ end
100
+
101
+ let(:raw) do
102
+ Person.collection.find(_id: person.id).first
103
+ end
104
+
105
+ it "hard deletes the document" do
106
+ expect(raw["paranoid_phones"]).to be_empty
107
+ end
108
+
109
+ it "executes the before destroy callbacks" do
110
+ expect(phone.before_destroy_called).to be_truthy
111
+ end
112
+
113
+ it "executes the after destroy callbacks" do
114
+ expect(phone.after_destroy_called).to be_truthy
115
+ end
116
+ end
117
+
118
+ context "when the document has a dependent relation" do
119
+
120
+ let(:post) do
121
+ ParanoidPost.create(title: "test")
122
+ end
123
+
124
+ let!(:author) do
125
+ post.authors.create(name: "poe")
126
+ end
127
+
128
+ before do
129
+ post.destroy!
130
+ end
131
+
132
+ it "cascades the dependent option" do
133
+ expect {
134
+ author.reload
135
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
136
+ end
137
+ end
138
+ end
139
+
140
+ describe "#destroy" do
141
+
142
+ context "when the document is a root" do
143
+
144
+ let(:post) do
145
+ ParanoidPost.create(title: "testing")
146
+ end
147
+
148
+ before do
149
+ post.destroy
150
+ end
151
+
152
+ let(:raw) do
153
+ ParanoidPost.collection.find(_id: post.id).first
154
+ end
155
+
156
+ it "soft deletes the document" do
157
+ expect(raw["deleted_at"]).to be_within(1).of(Time.now)
158
+ end
159
+
160
+ it "is still marked as persisted" do
161
+ expect(post.persisted?).to eq(true)
162
+ end
163
+
164
+ it "does not return the document in a find" do
165
+ expect {
166
+ ParanoidPost.find(post.id)
167
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
168
+ end
169
+
170
+ it "executes the before destroy callbacks" do
171
+ expect(post.before_destroy_called).to be_truthy
172
+ end
173
+
174
+ it "executes the after destroy callbacks" do
175
+ expect(post.after_destroy_called).to be_truthy
176
+ end
177
+ end
178
+
179
+ context "when the document is embedded" do
180
+
181
+ let(:person) do
182
+ Person.create
183
+ end
184
+
185
+ let(:phone) do
186
+ person.paranoid_phones.create(number: "911")
187
+ end
188
+
189
+ before do
190
+ phone.destroy
191
+ end
192
+
193
+ let(:raw) do
194
+ Person.collection.find(_id: person.id).first
195
+ end
196
+
197
+ it "soft deletes the document" do
198
+ expect(raw["paranoid_phones"].first["deleted_at"]).to be_within(1).of(Time.now)
199
+ end
200
+
201
+ it "does not return the document in a find" do
202
+ expect {
203
+ person.paranoid_phones.find(phone.id)
204
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
205
+ end
206
+
207
+ it "does not include the document in the relation" do
208
+ expect(person.paranoid_phones.scoped).to be_empty
209
+ end
210
+
211
+ it "executes the before destroy callbacks" do
212
+ expect(phone.before_destroy_called).to be_truthy
213
+ end
214
+
215
+ it "executes the after destroy callbacks" do
216
+ expect(phone.after_destroy_called).to be_truthy
217
+ end
218
+ end
219
+
220
+ context "when the document has a dependent: :delete relation" do
221
+
222
+ let(:post) do
223
+ ParanoidPost.create(title: "test")
224
+ end
225
+
226
+ let!(:author) do
227
+ post.authors.create(name: "poe")
228
+ end
229
+
230
+ before do
231
+ post.destroy
232
+ end
233
+
234
+ it "cascades the dependent option" do
235
+ expect {
236
+ author.reload
237
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
238
+ end
239
+ end
240
+
241
+ context "when the document has a dependent: :restrict relation" do
242
+
243
+ let(:post) do
244
+ ParanoidPost.create(title: "test")
245
+ end
246
+
247
+ let!(:title) do
248
+ post.titles.create
249
+ end
250
+
251
+ before do
252
+ begin
253
+ post.destroy
254
+ rescue Mongoid::Errors::DeleteRestriction
255
+ end
256
+ end
257
+
258
+ it "does not destroy the document" do
259
+ expect(post).not_to be_destroyed
260
+ end
261
+ end
262
+ end
263
+
264
+ describe "#destroyed?" do
265
+
266
+ context "when the document is a root" do
267
+
268
+ let(:post) do
269
+ ParanoidPost.create(title: "testing")
270
+ end
271
+
272
+ context "when the document is hard deleted" do
273
+
274
+ before do
275
+ post.destroy!
276
+ end
277
+
278
+ it "returns true" do
279
+ expect(post).to be_destroyed
280
+ end
281
+ end
282
+
283
+ context "when the document is soft deleted" do
284
+
285
+ before do
286
+ post.destroy
287
+ end
288
+
289
+ it "returns true" do
290
+ expect(post).to be_destroyed
291
+ end
292
+
293
+ it "returns true for deleted scope document" do
294
+ expect(ParanoidPost.deleted.last).to be_destroyed
295
+ end
296
+ end
297
+ end
298
+
299
+ context "when the document is embedded" do
300
+
301
+ let(:person) do
302
+ Person.create
303
+ end
304
+
305
+ let(:phone) do
306
+ person.paranoid_phones.create(number: "911")
307
+ end
308
+
309
+ context "when the document is hard deleted" do
310
+
311
+ before do
312
+ phone.destroy!
313
+ end
314
+
315
+ it "returns true" do
316
+ expect(phone).to be_destroyed
317
+ end
318
+ end
319
+
320
+ context "when the document is soft deleted" do
321
+
322
+ before do
323
+ phone.destroy
324
+ end
325
+
326
+ it "returns true" do
327
+ expect(phone).to be_destroyed
328
+ end
329
+ end
330
+ end
331
+ end
332
+
333
+ describe "#deleted?" do
334
+
335
+ context "when the document is a root" do
336
+
337
+ let(:post) do
338
+ ParanoidPost.create(title: "testing")
339
+ end
340
+
341
+ context "when the document is hard deleted" do
342
+
343
+ before do
344
+ post.destroy!
345
+ end
346
+
347
+ it "returns true" do
348
+ expect(post).to be_deleted
349
+ end
350
+ end
351
+
352
+ context "when the document is soft deleted" do
353
+
354
+ before do
355
+ post.destroy
356
+ end
357
+
358
+ it "returns true" do
359
+ expect(post).to be_deleted
360
+ end
361
+ end
362
+ end
363
+
364
+ context "when the document is embedded" do
365
+
366
+ let(:person) do
367
+ Person.create
368
+ end
369
+
370
+ let(:phone) do
371
+ person.paranoid_phones.create(number: "911")
372
+ end
373
+
374
+ context "when the document is hard deleted" do
375
+
376
+ before do
377
+ phone.destroy!
378
+ end
379
+
380
+ it "returns true" do
381
+ expect(phone).to be_deleted
382
+ end
383
+ end
384
+
385
+ context "when the document is soft deleted" do
386
+
387
+ before do
388
+ phone.destroy
389
+ end
390
+
391
+ it "returns true" do
392
+ expect(phone).to be_deleted
393
+ end
394
+ end
395
+
396
+ context "when the document has non-dependent relation" do
397
+ let(:post) do
398
+ ParanoidPost.create(title: "test")
399
+ end
400
+
401
+ let!(:tag) do
402
+ post.tags.create(text: "tagie")
403
+ end
404
+
405
+ before do
406
+ post.delete
407
+ end
408
+
409
+ it "doesn't cascades the dependent option" do
410
+ expect(tag.reload).to eq(tag)
411
+ end
412
+
413
+ end
414
+ end
415
+ end
416
+
417
+ describe "#delete!" do
418
+
419
+ context "when the document is a root" do
420
+
421
+ let(:post) do
422
+ ParanoidPost.create(title: "testing")
423
+ end
424
+
425
+ before do
426
+ post.delete!
427
+ end
428
+
429
+ let(:raw) do
430
+ ParanoidPost.collection.find(_id: post.id).first
431
+ end
432
+
433
+ it "hard deletes the document" do
434
+ expect(raw).to be_nil
435
+ end
436
+ end
437
+
438
+ context "when the document is embedded" do
439
+
440
+ let(:person) do
441
+ Person.create
442
+ end
443
+
444
+ let(:phone) do
445
+ person.paranoid_phones.create(number: "911")
446
+ end
447
+
448
+ before do
449
+ phone.delete!
450
+ end
451
+
452
+ let(:raw) do
453
+ Person.collection.find(_id: person.id).first
454
+ end
455
+
456
+ it "hard deletes the document" do
457
+ expect(raw["paranoid_phones"]).to be_empty
458
+ end
459
+ end
460
+
461
+ context "when the document has a dependent relation" do
462
+
463
+ let(:post) do
464
+ ParanoidPost.create(title: "test")
465
+ end
466
+
467
+ let!(:author) do
468
+ post.authors.create(name: "poe")
469
+ end
470
+
471
+ before do
472
+ post.delete!
473
+ end
474
+
475
+ it "cascades the dependent option" do
476
+ expect {
477
+ author.reload
478
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
479
+ end
480
+ end
481
+ end
482
+
483
+ describe "#delete" do
484
+
485
+ context "when the document is a root" do
486
+
487
+ let(:post) do
488
+ ParanoidPost.create(title: "testing")
489
+ end
490
+
491
+ before do
492
+ post.delete
493
+ end
494
+
495
+ let(:raw) do
496
+ ParanoidPost.collection.find(_id: post.id).first
497
+ end
498
+
499
+ it "soft deletes the document" do
500
+ expect(raw["deleted_at"]).to be_within(1).of(Time.now)
501
+ end
502
+
503
+ it "does not return the document in a find" do
504
+ expect {
505
+ ParanoidPost.find(post.id)
506
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
507
+ end
508
+ end
509
+
510
+ context "when the document is embedded" do
511
+
512
+ let(:person) do
513
+ Person.create
514
+ end
515
+
516
+ let(:phone) do
517
+ person.paranoid_phones.create(number: "911")
518
+ end
519
+
520
+ before do
521
+ phone.delete
522
+ end
523
+
524
+ let(:raw) do
525
+ Person.collection.find(_id: person.id).first
526
+ end
527
+
528
+ it "soft deletes the document" do
529
+ expect(raw["paranoid_phones"].first["deleted_at"]).to be_within(1).of(Time.now)
530
+ end
531
+
532
+ it "does not return the document in a find" do
533
+ expect {
534
+ person.paranoid_phones.find(phone.id)
535
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
536
+ end
537
+
538
+ it "does not include the document in the relation" do
539
+ expect(person.paranoid_phones.scoped).to be_empty
540
+ end
541
+ end
542
+
543
+ context "when the document has a dependent relation" do
544
+
545
+ let(:post) do
546
+ ParanoidPost.create(title: "test")
547
+ end
548
+
549
+ let!(:author) do
550
+ post.authors.create(name: "poe")
551
+ end
552
+
553
+ before do
554
+ post.delete
555
+ end
556
+
557
+ it "cascades the dependent option" do
558
+ expect {
559
+ author.reload
560
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
561
+ end
562
+ end
563
+
564
+ context "when the document has a dependent: :restrict relation" do
565
+
566
+ let(:post) do
567
+ ParanoidPost.create(title: "test")
568
+ end
569
+
570
+ let!(:title) do
571
+ post.titles.create
572
+ end
573
+
574
+ before do
575
+ begin
576
+ post.delete
577
+ rescue Mongoid::Errors::DeleteRestriction
578
+ end
579
+ end
580
+
581
+ it "does not destroy the document" do
582
+ expect(post).not_to be_destroyed
583
+ end
584
+ end
585
+ end
586
+
587
+ describe "#remove" do
588
+
589
+ let(:post) do
590
+ ParanoidPost.new
591
+ end
592
+
593
+ let!(:time) do
594
+ Time.now
595
+ end
596
+
597
+ before do
598
+ post.remove
599
+ end
600
+
601
+ it "sets the deleted flag" do
602
+ expect(post).to be_destroyed
603
+ end
604
+ end
605
+
606
+ describe "#restore" do
607
+
608
+ context "when the document is a root" do
609
+
610
+ let(:post) do
611
+ ParanoidPost.create(title: "testing")
612
+ end
613
+
614
+ before do
615
+ post.delete
616
+ post.restore
617
+ end
618
+
619
+ it "removes the deleted at time" do
620
+ expect(post.deleted_at).to be_nil
621
+ end
622
+
623
+ it "persists the change" do
624
+ expect(post.reload.deleted_at).to be_nil
625
+ end
626
+
627
+ it "marks document again as persisted" do
628
+ expect(post.persisted?).to be_truthy
629
+ end
630
+
631
+ context "will run callback" do
632
+
633
+ it "before restore" do
634
+ expect(post.before_restore_called).to be_truthy
635
+ end
636
+
637
+ it "after restore" do
638
+ expect(post.after_restore_called).to be_truthy
639
+ end
640
+
641
+ it "around restore" do
642
+ expect(post.around_before_restore_called).to be_truthy
643
+ expect(post.around_after_restore_called).to be_truthy
644
+ end
645
+ end
646
+
647
+ end
648
+
649
+ context "when the document is embedded" do
650
+
651
+ let(:person) do
652
+ Person.create
653
+ end
654
+
655
+ let(:phone) do
656
+ person.paranoid_phones.create(number: "911")
657
+ end
658
+
659
+ before do
660
+ phone.delete
661
+ phone.restore
662
+ end
663
+
664
+ it "removes the deleted at time" do
665
+ expect(phone.deleted_at).to be_nil
666
+ end
667
+
668
+ it "persists the change" do
669
+ expect(person.reload.paranoid_phones.first.deleted_at).to be_nil
670
+ end
671
+ end
672
+ end
673
+
674
+ describe ".scoped" do
675
+
676
+ let(:scoped) do
677
+ ParanoidPost.scoped
678
+ end
679
+
680
+ it "returns a scoped criteria" do
681
+ expect(scoped.selector).to eq({ "deleted_at" => nil })
682
+ end
683
+ end
684
+
685
+ describe "#set" do
686
+
687
+ let!(:post) do
688
+ ParanoidPost.create
689
+ end
690
+
691
+ let(:time) do
692
+ 20.days.ago
693
+ end
694
+
695
+ let!(:set) do
696
+ post.set(:deleted_at => time)
697
+ end
698
+
699
+ it "persists the change" do
700
+ expect(post.reload.deleted_at).to be_within(1).of(time)
701
+ end
702
+ end
703
+
704
+ describe ".unscoped" do
705
+
706
+ let(:unscoped) do
707
+ ParanoidPost.unscoped
708
+ end
709
+
710
+ it "returns an unscoped criteria" do
711
+ expect(unscoped.selector).to eq({})
712
+ end
713
+ end
714
+
715
+ describe "#to_param" do
716
+
717
+ let(:post) do
718
+ ParanoidPost.new(title: "testing")
719
+ end
720
+
721
+ context "when the document is new" do
722
+
723
+ it "still returns nil" do
724
+ expect(post.to_param).to be_nil
725
+ end
726
+ end
727
+
728
+ context "when the document is not deleted" do
729
+
730
+ before do
731
+ post.save
732
+ end
733
+
734
+ it "returns the id as a string" do
735
+ expect(post.to_param).to eq(post.id.to_s)
736
+ end
737
+ end
738
+
739
+ context "when the document is deleted" do
740
+
741
+ before do
742
+ post.save
743
+ post.delete
744
+ end
745
+
746
+ it "returns the id as a string" do
747
+ expect(post.to_param).to eq(post.id.to_s)
748
+ end
749
+ end
750
+ end
751
+ end