require "spec_helper" module Uuids describe Base do describe ".included" do context "from non AR class" do before { class Test; end } after { begin; Uuids::Base.send :remove_constant, :Test; rescue; end } it "fails" do expect { Test.include Uuids::Base }.to raise_error end end context "from AR model" do it "doesn't fail" do expect { City.include Uuids::Base }.not_to raise_error end end end describe ".has_uuids" do # For running this specification, the City AR model prepared in the # `spec dummy/app/models/item.rb`. The model included Uuids::Base. before { City.send :has_uuids } subject { City.new } it "defines the #uuids attribute" do subject.uuids.new value: SecureRandom.uuid subject.save! expect(Uuids::Models::Uuid.first.try(:record)).to eq subject expect(subject.uuids.first).to eq Uuids::Models::Uuid.first end it "defines the #uuid method" do 2.times { subject.uuids.new value: SecureRandom.uuid } subject.save! expect(subject.uuid).to eq subject.uuids.map(&:value).sort.first end it "defines the #uuid= method" do value = "3ea8fd89-232f-4ed1-90b5-743da173cd7d" subject.uuid = value expect(subject.uuids.map(&:value)).to be_include(value) end it "defines the #uuids= method" do value = "3ea8fd89-232f-4ed1-90b5-743da173cd7d" subject.uuids = [value] expect(subject.uuids.map(&:value)).to be_include(value) end it "defines +by_uuid+ class scope" do subject.save! subject.uuids.create! values = subject.reload.uuids.map(&:value) expect(City.by_uuid(*values).to_a).to eq [subject] expect(City.by_uuid).to eq City.all end it "creates the first uuid by default" do expect(subject.uuid).not_to be_blank end it "requires the #uuids attribute" do subject.save! subject.uuids.each(&:delete) expect(subject.reload).not_to be_valid end it "forbids destruction if uuids present" do subject.save! expect { subject.destroy! }.to raise_error subject.uuids.each(&:delete) subject.reload expect { subject.destroy! }.not_to raise_error end end describe ".belongs_by_uuid_to" do context "when a model doesn't include Uuids::Base" do it "raises TypeError" do expect { City.send :belongs_by_uuid_to, :state, class: Record } .to raise_error { TypeError } end end context "when a class doesn't have column for uuids" do it "raises NotImplementedError" do expect { City.send :belongs_by_uuid_to, :country, class: State } .to raise_error { NotImplementedError } end end context "with valid arguments" do before { City.send :belongs_by_uuid_to, :state, class: State } subject { City.new } let!(:uuid) { "01234567-89ab-cdef-0123-456789abcdef" } let!(:state) { State.create uuid: uuid } it "defines the getter" do expect(subject).to respond_to :state expect(subject.method(:state).arity).to eq 0 end it "defines the setter" do expect(subject).to respond_to :state= expect(subject.method(:state=).arity).to eq 1 end it "sets the object" do expect { subject.state = state } .to change { subject.state }.to state end it "sets the object uuid" do expect { subject.state = state } .to change { subject.state_uuid }.to state.uuid end it "resets the object" do subject.state = state expect { subject.state = nil } .to change { subject.state }.to nil end it "resets the object uuid" do subject.state = state expect { subject.state = nil } .to change { subject.state_uuid }.to nil end it "sets the object by uuid" do expect { subject.state_uuid = state.uuid } .to change { subject.state }.to state end end end end end