Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions source/.rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--color
--require spec_helper
2 changes: 1 addition & 1 deletion source/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ gem 'spring', group: :development
# Use debugger
# gem 'debugger', group: [:development, :test]
gem 'rspec-rails', group: [:development, :test]

gem 'pry'
109 changes: 60 additions & 49 deletions source/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -28,33 +28,40 @@ GEM
thread_safe (~> 0.1)
tzinfo (~> 1.1)
arel (5.0.1.20140414130214)
builder (3.2.2)
builder (3.2.3)
coderay (1.1.2)
coffee-rails (4.0.1)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.0)
coffee-script (2.3.0)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.8.0)
diff-lcs (1.2.5)
coffee-script-source (1.12.2)
concurrent-ruby (1.0.5)
diff-lcs (1.3)
erubis (2.7.0)
execjs (2.2.1)
execjs (2.7.0)
hike (1.2.3)
i18n (0.6.11)
jbuilder (2.2.2)
activesupport (>= 3.0.0, < 5)
multi_json (~> 1.2)
jquery-rails (3.1.2)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
jbuilder (2.6.4)
activesupport (>= 3.0.0)
multi_json (>= 1.2)
jquery-rails (3.1.5)
railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0)
json (1.8.1)
mail (2.6.1)
mime-types (>= 1.16, < 3)
mime-types (2.4.1)
minitest (5.4.2)
multi_json (1.10.1)
rack (1.5.2)
rack-test (0.6.2)
json (1.8.6)
mail (2.7.0)
mini_mime (>= 0.1.1)
method_source (0.9.0)
mini_mime (1.0.0)
minitest (5.11.3)
multi_json (1.13.1)
pry (0.11.3)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
rack (1.5.5)
rack-test (0.6.3)
rack (>= 1.0)
rails (4.1.6)
actionmailer (= 4.1.6)
Expand All @@ -71,55 +78,55 @@ GEM
activesupport (= 4.1.6)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rake (10.3.2)
rdoc (4.1.2)
json (~> 1.4)
rspec-core (3.1.6)
rspec-support (~> 3.1.0)
rspec-expectations (3.1.2)
rake (12.3.1)
rdoc (4.3.0)
rspec-core (3.7.1)
rspec-support (~> 3.7.0)
rspec-expectations (3.7.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.1.0)
rspec-mocks (3.1.3)
rspec-support (~> 3.1.0)
rspec-rails (3.1.0)
rspec-support (~> 3.7.0)
rspec-mocks (3.7.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.7.0)
rspec-rails (3.7.2)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 3.1.0)
rspec-expectations (~> 3.1.0)
rspec-mocks (~> 3.1.0)
rspec-support (~> 3.1.0)
rspec-support (3.1.2)
rspec-core (~> 3.7.0)
rspec-expectations (~> 3.7.0)
rspec-mocks (~> 3.7.0)
rspec-support (~> 3.7.0)
rspec-support (3.7.1)
sass (3.2.19)
sass-rails (4.0.3)
sass-rails (4.0.5)
railties (>= 4.0.0, < 5.0)
sass (~> 3.2.0)
sprockets (~> 2.8, <= 2.11.0)
sass (~> 3.2.2)
sprockets (~> 2.8, < 3.0)
sprockets-rails (~> 2.0)
sdoc (0.4.1)
sdoc (0.4.2)
json (~> 1.7, >= 1.7.7)
rdoc (~> 4.0)
spring (1.1.3)
sprockets (2.11.0)
spring (1.7.2)
sprockets (2.12.4)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sprockets-rails (2.2.0)
sprockets-rails (2.3.3)
actionpack (>= 3.0)
activesupport (>= 3.0)
sprockets (>= 2.8, < 4.0)
sqlite3 (1.3.9)
thor (0.19.1)
thread_safe (0.3.4)
sqlite3 (1.3.13)
thor (0.20.0)
thread_safe (0.3.6)
tilt (1.4.1)
turbolinks (2.4.0)
coffee-rails
tzinfo (1.2.2)
turbolinks (5.1.1)
turbolinks-source (~> 5.1)
turbolinks-source (5.1.0)
tzinfo (1.2.5)
thread_safe (~> 0.1)
uglifier (2.5.3)
execjs (>= 0.3.0)
json (>= 1.8.0)
uglifier (4.1.10)
execjs (>= 0.3.0, < 3)

PLATFORMS
ruby
Expand All @@ -128,6 +135,7 @@ DEPENDENCIES
coffee-rails (~> 4.0.0)
jbuilder (~> 2.0)
jquery-rails
pry
rails (= 4.1.6)
rspec-rails
sass-rails (~> 4.0.3)
Expand All @@ -136,3 +144,6 @@ DEPENDENCIES
sqlite3
turbolinks
uglifier (>= 1.3.0)

BUNDLED WITH
1.16.1
25 changes: 25 additions & 0 deletions source/app/controllers/urls_controller.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,27 @@
class UrlsController < ApplicationController
def index
@urls = Url.all
end

def create
url = Url.new(url_params)
url.click_count = 0
if !url.save
flash[:error] = 'Invalid URL'
end
redirect_to urls_path
end

def show
url = Url.find(params[:id])
url.click_count += 1
url.save
redirect_to url.long_url
end

private

def url_params
params.require(:url).permit(:long_url)
end
end
3 changes: 3 additions & 0 deletions source/app/models/url.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Url < ActiveRecord::Base
validates :long_url, presence: true, format: { with: /http(|s):\/\/.+/ }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could nitpick this format regexp, but I'm not sure if it is needed. Is the URI::regexp matching sufficient?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right - this is leftover from before I implemented the URI matching.

end
14 changes: 14 additions & 0 deletions source/app/views/urls/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<p>Shorten URL:</p>

<%= flash[:error] if !nil? %>

<%= form_for :url do |f| %>
<%= f.label :long_url %>
<%= f.text_field :long_url %>
<% end %>

<ul>
<% @urls.each do |url| %>
<li><%= "0.0.0.0:3000/urls/#{url.id} ====> #{url.long_url} (clicked #{url.click_count} times)" %></li>
Copy link
Member

@mikegee mikegee May 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your routes file has a :urls resource with a :show action, so it should generate route helper methods for you. The name of it is kinda unfortunate in this case:

I think url_url(url) should output something like "0.0.0.0:3000/urls/#{url.id}" here. (and will remain correct in non-development environments)

<% end %>
</ul>
2 changes: 2 additions & 0 deletions source/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,6 @@
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end

resources :urls, only: [:index, :create, :show]
end
9 changes: 9 additions & 0 deletions source/db/migrate/20180514142357_create_urls.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class CreateUrls < ActiveRecord::Migration
def change
create_table :urls do |t|
t.string :long_url

t.timestamps
end
end
end
5 changes: 5 additions & 0 deletions source/db/migrate/20180514175827_add_click_counter_to_urls.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddClickCounterToUrls < ActiveRecord::Migration
def change
add_column :urls, :click_count, :integer
end
end
23 changes: 23 additions & 0 deletions source/db/schema.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# encoding: UTF-8
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20180514175827) do

create_table "urls", force: true do |t|
t.string "long_url"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "click_count"
end

end
73 changes: 73 additions & 0 deletions source/spec/controllers/url_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
require 'rails_helper'

describe UrlsController do
let(:url) { Url.create(long_url: 'https://www.google.com/', click_count: 0) }

describe 'GET index' do
it 'responds with a 200 OK' do
get :index
expect(response.status).to eq 200
end

it 'assigns @urls' do
get :index
expect(assigns[:urls]).to eq [url]
end

it 'renders the index template' do
get :index
expect(response).to render_template('index')
end
end

describe 'POST create' do
context 'with valid params' do
it 'creates a url entry' do
expect do
post :create, url: { long_url: 'https://www.google.com/' }
end.to change { Url.count }.by 1
end

it 'redirects to the index page' do
post :create, url: { long_url: 'https://www.google.com/' }
expect(response).to redirect_to urls_path
end

it 'sets the click counter to 0' do
post :create, url: { long_url: 'https://www.google.com/' }
expect(Url.first.click_count).to eq 0
end
end

context 'with invalid params' do
it 'does not create a url entry' do
expect do
post :create, url: { long_url: 'invalid URL' }
end.to_not change { Url.count }
end

it 'redirects to the index page' do
post :create, url: { long_url: 'invalid URL' }
expect(response).to redirect_to urls_path
end

it 'displays an error message' do
post :create, url: { long_url: 'invalid URL' }
expect(flash[:error]).to eq 'Invalid URL'
end
end
end

describe 'GET show' do
it 'redirects to the long url' do
get :show, { id: url.id }
expect(response).to redirect_to 'https://www.google.com/'
end

it 'increases the click_counter' do
expect do
get :show, { id: url.id }
end.to change { url.reload.click_count }.by 1
end
end
end
23 changes: 23 additions & 0 deletions source/spec/models/url_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require 'rails_helper'

RSpec.describe Url, :type => :model do
let(:url) { Url.new(long_url: 'https://www.google.com/') }

describe 'long_url' do
it 'is not an empty string' do
url.long_url = ''
expect(url).to_not be_valid
end

it 'has a prefix http:// or https://' do
url.long_url = 'www.google.com'
expect(url).to_not be_valid

url.long_url = 'http://www.google.com'
expect(url).to be_valid

url.long_url = 'https://www.google.com'
expect(url).to be_valid
end
end
end
Loading