lib/slugworth_shared_examples.rb
shared_examples_for :has_slug_functionality do
describe "#slug" do
context "when no slug is set" do
specify "slug is generated with slug attribute" do
obj = described_class.new(described_class.slug_attribute => "Generated slug")
obj.valid?
expect(obj.slug).to eq("generated-slug")
end
specify "slug is not generated with no slug attribute" do
obj = described_class.new
obj.valid?
expect(obj.slug).to be_nil
end
end
context "when the slug is set" do
specify "slug is set to passed value" do
obj = described_class.new(slug: "passed-slug")
obj.valid?
expect(obj.slug).to eq("passed-slug")
end
end
context "when slug is already taken" do
before do
existing = described_class.new(slug: "taken-slug")
existing.save(validate: false)
end
specify "object is not valid" do
obj = described_class.new(slug: "taken-slug")
obj.valid?
expect(obj.errors[:slug]).to_not be_empty
end
end
end
describe "#to_param" do
specify "parameter uses slug" do
obj = described_class.new(slug: "passed-slug")
expect(obj.to_param).to eq("passed-slug")
end
end
describe ".find_by_slug" do
context "when record is available to be found" do
before do
record = described_class.new(slug: "named-slug")
record.save(validate: false)
end
specify "record is returned" do
record = described_class.find_by_slug("named-slug")
expect(record).to be_present
end
end
context "when record is not found" do
specify "nil is returned" do
expect(described_class.find_by_slug("named-slug")).to eq(nil)
end
specify "error is raised" do
expect { described_class.find_by_slug!("named-slug") }.to raise_error(ActiveRecord::RecordNotFound)
end
end
end
end
shared_examples_for :has_updatable_slug_functionality do
describe "#slug :updatable" do
let!(:existing) { described_class.create(described_class.slug_attribute => "Name") }
context "when attribute is changed" do
specify "updates the slug" do
existing[described_class.slug_attribute] = "New Name"
expect(existing).to be_valid
expect(existing.slug).to eq("new-name")
end
end
context "when attribute is not changed" do
specify "does not update the slug" do
expect(existing).to be_valid
expect(existing.slug).to eq("name")
end
end
end
end
shared_examples_for :has_incremental_slug_functionality do
describe "#slug :incremental" do
context "when slug is already taken" do
before do
existing = described_class.new(slug: "taken-slug")
existing.save(validate: false)
end
specify "increments the slug" do
obj = described_class.new(described_class.slug_attribute => "Taken Slug")
expect(obj).to be_valid
expect(obj.slug).to eq("taken-slug-1")
end
end
context "when incremented slug is already taken" do
before do
existing = described_class.new(slug: "taken-slug")
existing.save(validate: false)
existing = described_class.new(slug: "taken-slug-1")
existing.save(validate: false)
end
specify "increments the slug" do
obj = described_class.new(described_class.slug_attribute => "Taken Slug")
expect(obj).to be_valid
expect(obj.slug).to eq("taken-slug-2")
end
end
context "when existing slug is reset" do
let!(:existing) { described_class.create(described_class.slug_attribute => "New Name") }
specify "does not increment the slug" do
existing.slug = nil
expect(existing).to be_valid
expect(existing.slug).to eq("new-name")
end
end
end
end
shared_examples_for :has_scoped_slug_functionality do
describe "#slug :scope" do
context "when slug is already taken on same scope" do
before do
existing = described_class.new(:slug => "taken-slug", described_class.slug_scope => 1)
existing.save(validate: false)
end
specify "object is not valid" do
obj = described_class.new(:slug => "taken-slug", described_class.slug_scope => 1)
expect(obj).to_not be_valid
expect(obj.errors[:slug]).to_not be_empty
end
end
context "when slug is already taken on another scope" do
before do
existing = described_class.new(:slug => "taken-slug", described_class.slug_scope => 1)
existing.save(validate: false)
end
specify "object is valid" do
obj = described_class.new(:slug => "taken-slug", described_class.slug_scope => 2)
expect(obj).to be_valid
end
end
end
end
shared_examples_for :has_incremental_scoped_slug_functionality do
describe "#slug :incremental" do
context "when slug is already taken" do
before do
existing = described_class.new(:slug => "taken-slug", described_class.slug_scope => 1)
existing.save(validate: false)
end
specify "increments the slug" do
obj = described_class.new(described_class.slug_attribute => "Taken Slug", described_class.slug_scope => 1)
expect(obj).to be_valid
expect(obj.slug).to eq("taken-slug-1")
end
end
context "when incremented slug is already taken" do
before do
existing = described_class.new(:slug => "taken-slug", described_class.slug_scope => 1)
existing.save(validate: false)
existing = described_class.new(:slug => "taken-slug-1", described_class.slug_scope => 1)
existing.save(validate: false)
end
specify "increments the slug" do
obj = described_class.new(described_class.slug_attribute => "Taken Slug", described_class.slug_scope => 1)
expect(obj).to be_valid
expect(obj.slug).to eq("taken-slug-2")
end
end
context "when slug is already taken in another scope" do
before do
existing = described_class.new(:slug => "taken-slug", described_class.slug_scope => 1)
existing.save(validate: false)
end
specify "does not increment the slug" do
obj = described_class.new(described_class.slug_attribute => "Taken Slug", described_class.slug_scope => 2)
expect(obj).to be_valid
expect(obj.slug).to eq("taken-slug")
end
end
end
end