spec/mongoid/paranoia_spec.rb in mongoid_paranoia-0.1.2 vs spec/mongoid/paranoia_spec.rb in mongoid_paranoia-0.2.0

- old
+ new

@@ -1,751 +1,887 @@ -require "spec_helper" - -describe Mongoid::Paranoia do - - describe ".scoped" do - - it "returns a scoped criteria" do - expect(ParanoidPost.scoped.selector).to eq({ "deleted_at" => nil }) - end - end - - describe ".deleted" do - - context "when called on a root document" do - - let(:post) do - ParanoidPost.create(title: "testing") - end - - before do - post.destroy - end - - let(:deleted) do - ParanoidPost.deleted - end - - it "returns the deleted documents" do - expect(deleted).to eq([ post ]) - end - end - - context "when called on an embedded document" do - - let(:person) do - Person.create - end - - let(:phone) do - person.paranoid_phones.create - end - - before do - phone.destroy - person.reload - end - - it "returns the deleted documents" do - expect(person.paranoid_phones.deleted.to_a).to eq([ phone ]) - end - - it "returns the correct count" do - expect(person.paranoid_phones.deleted.count).to eq(1) - end - end - end - - describe "#destroy!" do - - context "when the document is a root" do - - let(:post) do - ParanoidPost.create(title: "testing") - end - - before do - post.destroy! - end - - let(:raw) do - ParanoidPost.collection.find(_id: post.id).first - end - - it "hard deletes the document" do - expect(raw).to be_nil - end - - it "executes the before destroy callbacks" do - expect(post.before_destroy_called).to be_truthy - end - - it "executes the after destroy callbacks" do - expect(post.after_destroy_called).to be_truthy - end - end - - context "when the document is embedded" do - - let(:person) do - Person.create - end - - let(:phone) do - person.paranoid_phones.create(number: "911") - end - - before do - phone.destroy! - end - - let(:raw) do - Person.collection.find(_id: person.id).first - end - - it "hard deletes the document" do - expect(raw["paranoid_phones"]).to be_empty - end - - it "executes the before destroy callbacks" do - expect(phone.before_destroy_called).to be_truthy - end - - it "executes the after destroy callbacks" do - expect(phone.after_destroy_called).to be_truthy - end - end - - context "when the document has a dependent relation" do - - let(:post) do - ParanoidPost.create(title: "test") - end - - let!(:author) do - post.authors.create(name: "poe") - end - - before do - post.destroy! - end - - it "cascades the dependent option" do - expect { - author.reload - }.to raise_error(Mongoid::Errors::DocumentNotFound) - end - end - end - - describe "#destroy" do - - context "when the document is a root" do - - let(:post) do - ParanoidPost.create(title: "testing") - end - - before do - post.destroy - end - - let(:raw) do - ParanoidPost.collection.find(_id: post.id).first - end - - it "soft deletes the document" do - expect(raw["deleted_at"]).to be_within(1).of(Time.now) - end - - it "is still marked as persisted" do - expect(post.persisted?).to eq(true) - end - - it "does not return the document in a find" do - expect { - ParanoidPost.find(post.id) - }.to raise_error(Mongoid::Errors::DocumentNotFound) - end - - it "executes the before destroy callbacks" do - expect(post.before_destroy_called).to be_truthy - end - - it "executes the after destroy callbacks" do - expect(post.after_destroy_called).to be_truthy - end - end - - context "when the document is embedded" do - - let(:person) do - Person.create - end - - let(:phone) do - person.paranoid_phones.create(number: "911") - end - - before do - phone.destroy - end - - let(:raw) do - Person.collection.find(_id: person.id).first - end - - it "soft deletes the document" do - expect(raw["paranoid_phones"].first["deleted_at"]).to be_within(1).of(Time.now) - end - - it "does not return the document in a find" do - expect { - person.paranoid_phones.find(phone.id) - }.to raise_error(Mongoid::Errors::DocumentNotFound) - end - - it "does not include the document in the relation" do - expect(person.paranoid_phones.scoped).to be_empty - end - - it "executes the before destroy callbacks" do - expect(phone.before_destroy_called).to be_truthy - end - - it "executes the after destroy callbacks" do - expect(phone.after_destroy_called).to be_truthy - end - end - - context "when the document has a dependent: :delete relation" do - - let(:post) do - ParanoidPost.create(title: "test") - end - - let!(:author) do - post.authors.create(name: "poe") - end - - before do - post.destroy - end - - it "cascades the dependent option" do - expect { - author.reload - }.to raise_error(Mongoid::Errors::DocumentNotFound) - end - end - - context "when the document has a dependent: :restrict relation" do - - let(:post) do - ParanoidPost.create(title: "test") - end - - let!(:title) do - post.titles.create - end - - before do - begin - post.destroy - rescue Mongoid::Errors::DeleteRestriction - end - end - - it "does not destroy the document" do - expect(post).not_to be_destroyed - end - end - end - - describe "#destroyed?" do - - context "when the document is a root" do - - let(:post) do - ParanoidPost.create(title: "testing") - end - - context "when the document is hard deleted" do - - before do - post.destroy! - end - - it "returns true" do - expect(post).to be_destroyed - end - end - - context "when the document is soft deleted" do - - before do - post.destroy - end - - it "returns true" do - expect(post).to be_destroyed - end - - it "returns true for deleted scope document" do - expect(ParanoidPost.deleted.last).to be_destroyed - end - end - end - - context "when the document is embedded" do - - let(:person) do - Person.create - end - - let(:phone) do - person.paranoid_phones.create(number: "911") - end - - context "when the document is hard deleted" do - - before do - phone.destroy! - end - - it "returns true" do - expect(phone).to be_destroyed - end - end - - context "when the document is soft deleted" do - - before do - phone.destroy - end - - it "returns true" do - expect(phone).to be_destroyed - end - end - end - end - - describe "#deleted?" do - - context "when the document is a root" do - - let(:post) do - ParanoidPost.create(title: "testing") - end - - context "when the document is hard deleted" do - - before do - post.destroy! - end - - it "returns true" do - expect(post).to be_deleted - end - end - - context "when the document is soft deleted" do - - before do - post.destroy - end - - it "returns true" do - expect(post).to be_deleted - end - end - end - - context "when the document is embedded" do - - let(:person) do - Person.create - end - - let(:phone) do - person.paranoid_phones.create(number: "911") - end - - context "when the document is hard deleted" do - - before do - phone.destroy! - end - - it "returns true" do - expect(phone).to be_deleted - end - end - - context "when the document is soft deleted" do - - before do - phone.destroy - end - - it "returns true" do - expect(phone).to be_deleted - end - end - - context "when the document has non-dependent relation" do - let(:post) do - ParanoidPost.create(title: "test") - end - - let!(:tag) do - post.tags.create(text: "tagie") - end - - before do - post.delete - end - - it "doesn't cascades the dependent option" do - expect(tag.reload).to eq(tag) - end - - end - end - end - - describe "#delete!" do - - context "when the document is a root" do - - let(:post) do - ParanoidPost.create(title: "testing") - end - - before do - post.delete! - end - - let(:raw) do - ParanoidPost.collection.find(_id: post.id).first - end - - it "hard deletes the document" do - expect(raw).to be_nil - end - end - - context "when the document is embedded" do - - let(:person) do - Person.create - end - - let(:phone) do - person.paranoid_phones.create(number: "911") - end - - before do - phone.delete! - end - - let(:raw) do - Person.collection.find(_id: person.id).first - end - - it "hard deletes the document" do - expect(raw["paranoid_phones"]).to be_empty - end - end - - context "when the document has a dependent relation" do - - let(:post) do - ParanoidPost.create(title: "test") - end - - let!(:author) do - post.authors.create(name: "poe") - end - - before do - post.delete! - end - - it "cascades the dependent option" do - expect { - author.reload - }.to raise_error(Mongoid::Errors::DocumentNotFound) - end - end - end - - describe "#delete" do - - context "when the document is a root" do - - let(:post) do - ParanoidPost.create(title: "testing") - end - - before do - post.delete - end - - let(:raw) do - ParanoidPost.collection.find(_id: post.id).first - end - - it "soft deletes the document" do - expect(raw["deleted_at"]).to be_within(1).of(Time.now) - end - - it "does not return the document in a find" do - expect { - ParanoidPost.find(post.id) - }.to raise_error(Mongoid::Errors::DocumentNotFound) - end - end - - context "when the document is embedded" do - - let(:person) do - Person.create - end - - let(:phone) do - person.paranoid_phones.create(number: "911") - end - - before do - phone.delete - end - - let(:raw) do - Person.collection.find(_id: person.id).first - end - - it "soft deletes the document" do - expect(raw["paranoid_phones"].first["deleted_at"]).to be_within(1).of(Time.now) - end - - it "does not return the document in a find" do - expect { - person.paranoid_phones.find(phone.id) - }.to raise_error(Mongoid::Errors::DocumentNotFound) - end - - it "does not include the document in the relation" do - expect(person.paranoid_phones.scoped).to be_empty - end - end - - context "when the document has a dependent relation" do - - let(:post) do - ParanoidPost.create(title: "test") - end - - let!(:author) do - post.authors.create(name: "poe") - end - - before do - post.delete - end - - it "cascades the dependent option" do - expect { - author.reload - }.to raise_error(Mongoid::Errors::DocumentNotFound) - end - end - - context "when the document has a dependent: :restrict relation" do - - let(:post) do - ParanoidPost.create(title: "test") - end - - let!(:title) do - post.titles.create - end - - before do - begin - post.delete - rescue Mongoid::Errors::DeleteRestriction - end - end - - it "does not destroy the document" do - expect(post).not_to be_destroyed - end - end - end - - describe "#remove" do - - let(:post) do - ParanoidPost.new - end - - let!(:time) do - Time.now - end - - before do - post.remove - end - - it "sets the deleted flag" do - expect(post).to be_destroyed - end - end - - describe "#restore" do - - context "when the document is a root" do - - let(:post) do - ParanoidPost.create(title: "testing") - end - - before do - post.delete - post.restore - end - - it "removes the deleted at time" do - expect(post.deleted_at).to be_nil - end - - it "persists the change" do - expect(post.reload.deleted_at).to be_nil - end - - it "marks document again as persisted" do - expect(post.persisted?).to be_truthy - end - - context "will run callback" do - - it "before restore" do - expect(post.before_restore_called).to be_truthy - end - - it "after restore" do - expect(post.after_restore_called).to be_truthy - end - - it "around restore" do - expect(post.around_before_restore_called).to be_truthy - expect(post.around_after_restore_called).to be_truthy - end - end - - end - - context "when the document is embedded" do - - let(:person) do - Person.create - end - - let(:phone) do - person.paranoid_phones.create(number: "911") - end - - before do - phone.delete - phone.restore - end - - it "removes the deleted at time" do - expect(phone.deleted_at).to be_nil - end - - it "persists the change" do - expect(person.reload.paranoid_phones.first.deleted_at).to be_nil - end - end - end - - describe ".scoped" do - - let(:scoped) do - ParanoidPost.scoped - end - - it "returns a scoped criteria" do - expect(scoped.selector).to eq({ "deleted_at" => nil }) - end - end - - describe "#set" do - - let!(:post) do - ParanoidPost.create - end - - let(:time) do - 20.days.ago - end - - let!(:set) do - post.set(:deleted_at => time) - end - - it "persists the change" do - expect(post.reload.deleted_at).to be_within(1).of(time) - end - end - - describe ".unscoped" do - - let(:unscoped) do - ParanoidPost.unscoped - end - - it "returns an unscoped criteria" do - expect(unscoped.selector).to eq({}) - end - end - - describe "#to_param" do - - let(:post) do - ParanoidPost.new(title: "testing") - end - - context "when the document is new" do - - it "still returns nil" do - expect(post.to_param).to be_nil - end - end - - context "when the document is not deleted" do - - before do - post.save - end - - it "returns the id as a string" do - expect(post.to_param).to eq(post.id.to_s) - end - end - - context "when the document is deleted" do - - before do - post.save - post.delete - end - - it "returns the id as a string" do - expect(post.to_param).to eq(post.id.to_s) - end - end - end -end +require "spec_helper" + +describe Mongoid::Paranoia do + context 'configuring the paranoid_field setting' do + before do + Mongoid::Paranoia.configure do |c| + c.paranoid_field = :myFieldName + end + end + + describe '.configure' do + before do + class ParanoidConfigured + include Mongoid::Document + include Mongoid::Paranoia + end + end + + it 'allows custom setting of the paranoid_field' do + paranoid_configured = ParanoidConfigured.new + expect(paranoid_configured.attribute_names).to include('myFieldName') + end + + after(:each) do + Mongoid::Paranoia.reset + end + end + + describe '.reset' do + before do + Mongoid::Paranoia.reset + + # the configuration gets set at include time + # so you need to reset before defining a new class + class ParanoidConfiguredReset + include Mongoid::Document + include Mongoid::Paranoia + end + end + + it 'restores the paranoid_field to the default setting' do + paranoid_configured = ParanoidConfiguredReset.new + expect(paranoid_configured.attribute_names).to include('deleted_at') + end + end + end + + describe ".scoped" do + + it "returns a scoped criteria" do + expect(ParanoidPost.scoped.selector).to eq({ "deleted_at" => nil }) + end + end + + describe ".deleted" do + + context "when called on a root document" do + + let(:post) do + ParanoidPost.create(title: "testing") + end + + before do + post.destroy + end + + let(:deleted) do + ParanoidPost.deleted + end + + it "returns the deleted documents" do + expect(deleted).to eq([ post ]) + end + end + + context "when called on an embedded document" do + + let(:person) do + Person.create + end + + let(:phone) do + person.paranoid_phones.create + end + + before do + phone.destroy + person.reload + end + + it "returns the deleted documents" do + expect(person.paranoid_phones.deleted.to_a).to eq([ phone ]) + end + + it "returns the correct count" do + expect(person.paranoid_phones.deleted.count).to eq(1) + end + end + end + + describe "#destroy!" do + + context "when the document is a root" do + + let(:post) do + ParanoidPost.create(title: "testing") + end + + before do + post.destroy! + end + + let(:raw) do + ParanoidPost.collection.find(_id: post.id).first + end + + it "hard deletes the document" do + expect(raw).to be_nil + end + + it "executes the before destroy callbacks" do + expect(post.before_destroy_called).to be_truthy + end + + it "executes the after destroy callbacks" do + expect(post.after_destroy_called).to be_truthy + end + + it "executes the before remove callbacks" do + expect(post.before_remove_called).to be_truthy + end + + it "executes the after remove callbacks" do + expect(post.after_remove_called).to be_truthy + end + end + + context "when the document is embedded" do + + let(:person) do + Person.create + end + + let(:phone) do + person.paranoid_phones.create(number: "911") + end + + before do + phone.destroy! + end + + let(:raw) do + Person.collection.find(_id: person.id).first + end + + it "hard deletes the document" do + expect(raw["paranoid_phones"]).to be_empty + end + + it "executes the before destroy callbacks" do + expect(phone.before_destroy_called).to be_truthy + end + + it "executes the after destroy callbacks" do + expect(phone.after_destroy_called).to be_truthy + end + end + + context "when the document has a dependent relation" do + + let(:post) do + ParanoidPost.create(title: "test") + end + + let!(:author) do + post.authors.create(name: "poe") + end + + before do + post.destroy! + end + + it "cascades the dependent option" do + expect { + author.reload + }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + end + end + + describe "#destroy" do + + context "when the document is a root" do + + let(:post) do + ParanoidPost.create(title: "testing") + end + + before do + post.destroy + end + + let(:raw) do + ParanoidPost.collection.find(_id: post.id).first + end + + it "soft deletes the document" do + expect(raw["deleted_at"]).to be_within(1).of(Time.now) + end + + it "is still marked as persisted" do + expect(post.persisted?).to eq(true) + end + + it "does not return the document in a find" do + expect { + ParanoidPost.find(post.id) + }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + + it "executes the before destroy callbacks" do + expect(post.before_destroy_called).to be_truthy + end + + it "executes the after destroy callbacks" do + expect(post.after_destroy_called).to be_truthy + end + + it "does not execute the before remove callbacks" do + expect(post.before_remove_called).to be_falsey + end + + it "does not execute the after remove callbacks" do + expect(post.after_remove_called).to be_falsey + end + end + + context "when the document is embedded" do + + let(:person) do + Person.create + end + + let(:phone) do + person.paranoid_phones.create(number: "911") + end + + before do + phone.destroy + end + + let(:raw) do + Person.collection.find(_id: person.id).first + end + + it "soft deletes the document" do + expect(raw["paranoid_phones"].first["deleted_at"]).to be_within(1).of(Time.now) + end + + it "does not return the document in a find" do + expect { + person.paranoid_phones.find(phone.id) + }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + + it "does not include the document in the relation" do + expect(person.paranoid_phones.scoped).to be_empty + end + + it "executes the before destroy callbacks" do + expect(phone.before_destroy_called).to be_truthy + end + + it "executes the after destroy callbacks" do + expect(phone.after_destroy_called).to be_truthy + end + end + + context "when the document has a dependent: :delete relation" do + + let(:post) do + ParanoidPost.create(title: "test") + end + + let!(:author) do + post.authors.create(name: "poe") + end + + before do + post.destroy + end + + it "cascades the dependent option" do + expect { + author.reload + }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + end + + context "when the document has a dependent: :restrict relation" do + + let(:post) do + ParanoidPost.create(title: "test") + end + + let!(:title) do + post.titles.create + end + + before do + begin + post.destroy + rescue Mongoid::Errors::DeleteRestriction + end + end + + it "does not destroy the document" do + expect(post).not_to be_destroyed + end + end + end + + describe "#destroyed?" do + + context "when the document is a root" do + + let(:post) do + ParanoidPost.create(title: "testing") + end + + context "when the document is hard deleted" do + + before do + post.destroy! + end + + it "returns true" do + expect(post).to be_destroyed + end + end + + context "when the document is soft deleted" do + + before do + post.destroy + end + + it "returns true" do + expect(post).to be_destroyed + end + + it "returns true for deleted scope document" do + expect(ParanoidPost.deleted.last).to be_destroyed + end + end + end + + context "when the document is embedded" do + + let(:person) do + Person.create + end + + let(:phone) do + person.paranoid_phones.create(number: "911") + end + + context "when the document is hard deleted" do + + before do + phone.destroy! + end + + it "returns true" do + expect(phone).to be_destroyed + end + end + + context "when the document is soft deleted" do + + before do + phone.destroy + end + + it "returns true" do + expect(phone).to be_destroyed + end + end + end + end + + describe "#deleted?" do + + context "when the document is a root" do + + let(:post) do + ParanoidPost.create(title: "testing") + end + + context "when the document is hard deleted" do + + before do + post.destroy! + end + + it "returns true" do + expect(post).to be_deleted + end + end + + context "when the document is soft deleted" do + + before do + post.destroy + end + + it "returns true" do + expect(post).to be_deleted + end + end + end + + context "when the document is embedded" do + + let(:person) do + Person.create + end + + let(:phone) do + person.paranoid_phones.create(number: "911") + end + + context "when the document is hard deleted" do + + before do + phone.destroy! + end + + it "returns true" do + expect(phone).to be_deleted + end + end + + context "when the document is soft deleted" do + + before do + phone.destroy + end + + it "returns true" do + expect(phone).to be_deleted + end + end + + context "when the document has non-dependent relation" do + let(:post) do + ParanoidPost.create(title: "test") + end + + let!(:tag) do + post.tags.create(text: "tagie") + end + + before do + post.delete + end + + it "doesn't cascades the dependent option" do + expect(tag.reload).to eq(tag) + end + + end + end + end + + describe "#delete!" do + + context "when the document is a root" do + + let(:post) do + ParanoidPost.create(title: "testing") + end + + before do + post.delete! + end + + let(:raw) do + ParanoidPost.collection.find(_id: post.id).first + end + + it "hard deletes the document" do + expect(raw).to be_nil + end + end + + context "when the document is embedded" do + + let(:person) do + Person.create + end + + let(:phone) do + person.paranoid_phones.create(number: "911") + end + + before do + phone.delete! + end + + let(:raw) do + Person.collection.find(_id: person.id).first + end + + it "hard deletes the document" do + expect(raw["paranoid_phones"]).to be_empty + end + end + + context "when the document has a dependent relation" do + + let(:post) do + ParanoidPost.create(title: "test") + end + + let!(:author) do + post.authors.create(name: "poe") + end + + before do + post.delete! + end + + it "cascades the dependent option" do + expect { + author.reload + }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + end + end + + describe "#delete" do + + context "when the document is a root" do + + let(:post) do + ParanoidPost.create(title: "testing") + end + + before do + post.delete + end + + let(:raw) do + ParanoidPost.collection.find(_id: post.id).first + end + + it "soft deletes the document" do + expect(raw["deleted_at"]).to be_within(1).of(Time.now) + end + + it "does not return the document in a find" do + expect { + ParanoidPost.find(post.id) + }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + end + + context "when the document is embedded" do + + let(:person) do + Person.create + end + + let(:phone) do + person.paranoid_phones.create(number: "911") + end + + before do + phone.delete + end + + let(:raw) do + Person.collection.find(_id: person.id).first + end + + it "soft deletes the document" do + expect(raw["paranoid_phones"].first["deleted_at"]).to be_within(1).of(Time.now) + end + + it "does not return the document in a find" do + expect { + person.paranoid_phones.find(phone.id) + }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + + it "does not include the document in the relation" do + expect(person.paranoid_phones.scoped).to be_empty + end + end + + context "when the document has a dependent relation" do + + let(:post) do + ParanoidPost.create(title: "test") + end + + let!(:author) do + post.authors.create(name: "poe") + end + + before do + post.delete + end + + it "cascades the dependent option" do + expect { + author.reload + }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + end + + context "when the document has a dependent: :restrict relation" do + + let(:post) do + ParanoidPost.create(title: "test") + end + + let!(:title) do + post.titles.create + end + + before do + begin + post.delete + rescue Mongoid::Errors::DeleteRestriction + end + end + + it "does not destroy the document" do + expect(post).not_to be_destroyed + end + end + end + + describe "#remove" do + + let(:post) do + ParanoidPost.new + end + + let!(:time) do + Time.now + end + + before do + post.remove + end + + it "sets the deleted flag" do + expect(post).to be_destroyed + end + end + + describe "#restore" do + + context "when the document is a root" do + + let(:post) do + ParanoidPost.create(title: "testing") + end + + before do + post.delete + post.restore + end + + it "removes the deleted at time" do + expect(post.deleted_at).to be_nil + end + + it "persists the change" do + expect(post.reload.deleted_at).to be_nil + end + + it "marks document again as persisted" do + expect(post.persisted?).to be_truthy + end + + context "will run callback" do + + it "before restore" do + expect(post.before_restore_called).to be_truthy + end + + it "after restore" do + expect(post.after_restore_called).to be_truthy + end + + it "around restore" do + expect(post.around_before_restore_called).to be_truthy + expect(post.around_after_restore_called).to be_truthy + end + end + end + + context "when the document is embedded" do + + let(:person) do + Person.create + end + + let(:phone) do + person.paranoid_phones.create(number: "911") + end + + before do + phone.delete + phone.restore + end + + it "removes the deleted at time" do + expect(phone.deleted_at).to be_nil + end + + it "persists the change" do + expect(person.reload.paranoid_phones.first.deleted_at).to be_nil + end + end + end + + describe "#restore_relations" do + + subject { ParaBase.create } + + let!(:para_has_one) { subject.para_has_one = ParaHasOne.create } + let!(:para_has_many) { 2.times.map { subject.para_has_many.create } } + let!(:para_habtm) { 3.times.map { subject.para_habtm.create } } + let!(:para_belongs_to) { subject.para_belongs_to = ParaBelongsTo.create } + let!(:para_embeds_one) { subject.para_embeds_one = ParaEmbedsOne.new } + let!(:para_embeds_many) { 2.times.map { subject.para_embeds_many.build } } + + let!(:norm_has_one) { subject.norm_has_one = NormHasOne.create } + let!(:norm_has_many) { 2.times.map { subject.norm_has_many.create } } + let!(:norm_habtm) { 3.times.map { subject.norm_habtm.create } } + let!(:norm_belongs_to) { subject.norm_belongs_to = NormBelongsTo.create } + let!(:norm_embeds_one) { subject.norm_embeds_one = NormEmbedsOne.new } + let!(:norm_embeds_many) { 2.times.map { subject.norm_embeds_many.build } } + + let(:prepare) do + subject.destroy + subject.restore + end + + context "restores paranoid associations" do + before { prepare } + + it { expect{ subject.restore_relations}.to change{ ParaHasOne.count }.by(1) } + it { expect{ subject.restore_relations}.to change{ ParaHasMany.count }.by(2) } + it { expect{ subject.restore_relations}.to change{ ParaHabtm.count }.by(3) } + it { expect{ subject.restore_relations}.to change{ ParaBelongsTo.count }.by(1) } + end + + context "does not affect embedded paranoid documents" do + before { prepare } + + it { expect{ subject.restore_relations}.to_not change{ subject.para_embeds_one } } + it { expect{ subject.restore_relations}.to_not change{ subject.para_embeds_many.count } } + end + + context "does not affect non-paranoid documents" do + before { prepare } + + it { expect{ subject.restore_relations}.to_not change{ NormHasOne.count } } + it { expect{ subject.restore_relations}.to_not change{ NormHasMany.count } } + it { expect{ subject.restore_relations}.to_not change{ NormHabtm.count } } + it { expect{ subject.restore_relations}.to_not change{ NormBelongsTo.count } } + it { expect{ subject.restore_relations}.to_not change{ subject.norm_embeds_one } } + it { expect{ subject.restore_relations}.to_not change{ subject.norm_embeds_many.count } } + end + + context "recursion" do + + let!(:para_habtm_norm_has_one) { subject.para_habtm.first.norm_has_one = NormHasOne.create } # not restored + let!(:para_habtm_para_has_one) { subject.para_habtm.first.para_has_one = ParaHasOne.create } # restored + let!(:para_habtm_norm_has_many) { 2.times.map { subject.para_habtm.first.norm_has_many = NormHasMany.create } } # not restored + let!(:para_habtm_para_has_many) { 3.times.map { subject.para_habtm.second.para_has_many = ParaHasMany.create } } # restored + + # Untestable due to infinite recursion condition in #destroy + # let!(:para_habtm_norm_habtm) { 3.times.map { subject.para_habtm.second.norm_habtm.create } } # not restored + # let!(:para_habtm_recursive) { 2.times.map { subject.para_habtm.first.recursive.create } } # restored + + before do + subject.destroy + subject.restore + end + + it { expect{ subject.restore_relations}.to change { ParaHasOne.count }.by(2) } + it { expect{ subject.restore_relations}.to change { ParaHasMany.count }.by(3) } + + # Untestable due to infinite recursion condition in #destroy + # it { expect{ ParaHabtm.unscoped.each(&:restore)}.to change { ParaHabtm.count }.by(5) } + + it { expect{ subject.restore_relations}.to_not change { NormHasOne.count } } + it { expect{ subject.restore_relations}.to_not change { NormHasMany.count } } + it { expect{ subject.restore_relations}.to_not change { NormHabtm.count } } + end + end + + describe ".scoped" do + + let(:scoped) do + ParanoidPost.scoped + end + + it "returns a scoped criteria" do + expect(scoped.selector).to eq({ "deleted_at" => nil }) + end + end + + describe "#set" do + + let!(:post) do + ParanoidPost.create + end + + let(:time) do + 20.days.ago + end + + let!(:set) do + post.set(:deleted_at => time) + end + + it "persists the change" do + expect(post.reload.deleted_at).to be_within(1).of(time) + end + end + + describe ".unscoped" do + + let(:unscoped) do + ParanoidPost.unscoped + end + + it "returns an unscoped criteria" do + expect(unscoped.selector).to eq({}) + end + end + + describe "#to_param" do + + let(:post) do + ParanoidPost.new(title: "testing") + end + + context "when the document is new" do + + it "still returns nil" do + expect(post.to_param).to be_nil + end + end + + context "when the document is not deleted" do + + before do + post.save + end + + it "returns the id as a string" do + expect(post.to_param).to eq(post.id.to_s) + end + end + + context "when the document is deleted" do + + before do + post.save + post.delete + end + + it "returns the id as a string" do + expect(post.to_param).to eq(post.id.to_s) + end + end + end +end