Skip to content
Browse files

Allow shortening of URLs

  • Loading branch information...
1 parent 714257b commit 42a70d7e04f10bbeaf92f0335e703861c961a974 @ariejan committed Jun 7, 2012
Showing with 62 additions and 2 deletions.
  1. +1 −0 Gemfile
  2. +2 −0 Gemfile.lock
  3. +5 −1 app/controllers/api/v1/urls_controller.rb
  4. +4 −0 app/models/url.rb
  5. +1 −0 config/database.yml
  6. +21 −1 spec/api/v1/shorten_url_spec.rb
  7. +28 −0 spec/models/url_spec.rb
View
1 Gemfile
@@ -17,4 +17,5 @@ group :development, :test do
gem 'guard-rspec'
gem 'factory_girl_rails'
gem 'json_spec'
+ gem 'shoulda-matchers'
end
View
2 Gemfile.lock
@@ -122,6 +122,7 @@ GEM
multi_json (~> 1.0)
rubyzip
settingslogic (2.0.8)
+ shoulda-matchers (1.0.0)
sprockets (2.1.3)
hike (~> 1.2)
rack (~> 1.0)
@@ -150,3 +151,4 @@ DEPENDENCIES
rake
rspec-rails
settingslogic
+ shoulda-matchers
View
6 app/controllers/api/v1/urls_controller.rb
@@ -3,7 +3,11 @@ module V1
class UrlsController < BaseController
# /api/v1/shorten
def shorten
- @url = Url.create(url: params[:long_url])
+ @url = Url.find_or_initialize_by_url(url: params[:long_url])
+
+ if !@url.save
+ render nothing: true, status: :not_acceptable
+ end
end
# /api/v1/expand
View
4 app/models/url.rb
@@ -1,6 +1,10 @@
+require 'uri'
+
class Url < ActiveRecord::Base
attr_accessible :url
+ validates :url, format: { with: URI.regexp(['http', 'https']) }
+
after_create :set_fingerprint
private
View
1 config/database.yml
@@ -14,6 +14,7 @@ test:
pool: 5
username: ariejan
password:
+ min_messages: warning
production:
adapter: postgresql
View
22 spec/api/v1/shorten_url_spec.rb
@@ -3,7 +3,7 @@
describe '/api/v1/shorten', type: :api do
let(:api_url) { '/api/v1/shorten' }
- context 'a valid longUrl' do
+ context 'a valid long_url' do
let(:long_url) { 'http://example.com' }
before do
@@ -23,4 +23,24 @@
last_response.body.should be_json_eql expected_json
end
end
+
+ context 'a duplicate URL' do
+ let(:long_url) { 'http://example.com' }
+
+ let!(:reference_url) { create :url, url: long_url }
+
+ it 'returns the same fingerprint' do
+ post api_url, long_url: long_url
+ JSON.parse(last_response.body)["fingerprint"].should == reference_url.fingerprint
+ end
+ end
+
+ context 'using an invalid long_url' do
+ let(:long_url) { 'ftp://surfnet.nl' }
+
+ it 'returns status 406' do
+ post api_url, long_url: long_url
+ last_response.status.should == 406
+ end
+ end
end
View
28 spec/models/url_spec.rb
@@ -1,6 +1,34 @@
require 'spec_helper'
describe Url do
+ context 'validations' do
+ context 'valid' do
+ urls = [
+ "http://example.com",
+ "https://example.org",
+ "http://example.com/path",
+ "http://example.com/sub/path/index.html",
+ "http://example.com/?a=123&b=456",
+ "http://example.com/sub/path/index with spaces.html"
+ ]
+
+ urls.each do |url|
+ it { should allow_value(url).for(:url) }
+ end
+ end
+
+ context 'invalid' do
+ urls = [
+ "ftp://example.com",
+ "gopher://example.org"
+ ]
+
+ urls.each do |url|
+ it { should_not allow_value(url).for(:url) }
+ end
+ end
+ end
+
context 'fingerprint' do
it 'sets the ID to fingerprint after_create' do
url = Url.create(url: 'http://example.com')

0 comments on commit 42a70d7

Please sign in to comment.
Something went wrong with that request. Please try again.