# -*- coding: utf-8 -*- require 'spec_helper' describe Shortener::ShortenedUrl, type: :model do it { should belong_to :owner } it { should validate_presence_of :url } describe '#generate!' do context 'shortened url record for requested url does not exist' do let(:expected_url) { Faker::Internet.url } shared_examples_for "shortened url" do let(:short_url) { Shortener::ShortenedUrl.generate!(long_url, owner: owner) } it 'creates a shortened url record for the url' do expect{short_url}.to change{Shortener::ShortenedUrl.count}.by(1) expect(short_url.url).to eq expected_url expect(short_url.unique_key.length).to eq 5 expect(short_url.owner).to eq owner end end context 'userless url' do let(:owner) { nil } context 'shortened url' do it_should_behave_like "shortened url" do let(:long_url) { expected_url } end end context 'shortened url with relative path' do it_should_behave_like "shortened url" do let(:long_url) { Faker::Internet.slug } let(:expected_url) { "/#{long_url}" } end end context "shortened url with i18n path" do it_should_behave_like "shortened url" do let(:long_url) { "#{Faker::Internet.url}/%E6%97%A5%E6%9C%AC%E8%AA%9E" } let(:expected_url) { long_url } end end end context "shortened url with user" do it_should_behave_like "shortened url" do let(:owner) { User.create } let(:long_url) { expected_url } end end end context "existing shortened URL" do let(:url) { Faker::Internet.url } let!(:existing_shortened_url) { Shortener::ShortenedUrl.generate!(url) } context 'different url from existing' do it "generates a new shortened url record for a different url" do expect(Shortener::ShortenedUrl.generate!(Faker::Internet.url)).not_to eq existing_shortened_url end end context "duplicate unique key" do before do expect_any_instance_of(Shortener::ShortenedUrl).to receive(:generate_unique_key). and_return(existing_shortened_url.unique_key, 'ABCDEF') Shortener::ShortenedUrl.where(unique_key: 'ABCDEF').delete_all end it 'should try until it finds a non-dup key' do short_url = Shortener::ShortenedUrl.generate!(Faker::Internet.url) expect(short_url).not_to be_nil expect(short_url.unique_key).to eq "ABCDEF" end end end context "existing shortened URL with relative path" do let(:path) { Faker::Internet.slug } let!(:existing_shortened_url) { Shortener::ShortenedUrl.generate!(path) } context 'same relative path' do it 'finds the shortened url from slashless oath' do expect(Shortener::ShortenedUrl.generate!(path)).to eq existing_shortened_url end it "should look up exsiting URL" do expect(Shortener::ShortenedUrl.generate!("/#{path}")).to eq existing_shortened_url end end end end describe '#generate' do context 'cannot generate a unique key' do before do expect(Shortener::ShortenedUrl).to receive(:generate!).and_raise(ActiveRecord::RecordNotUnique.new(nil)) end it 'returns nil' do expect(Shortener::ShortenedUrl.generate(Faker::Internet.url)).to eq nil end end end end