sepastian-mongoid-paranoia-rails4 0.0.1.alpha

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