diff --git a/.gitignore b/.gitignore index 89f27ac..6b1c8a2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.sw* .bundle *.db +.env.rb diff --git a/README.md b/README.md index cd93b2e..7958b5a 100644 --- a/README.md +++ b/README.md @@ -5,18 +5,32 @@ Roda, Falcon, Sequel, and SQLite the point of this project is to quickly build something and work on continuous deployment while making small refinements to the functional pieces. +the only outside piece of software that this project relies on is sqlite3. + first you have to install the dependencies: `bundle install` + if you want the development group included run this first: -`bundle config set --local with 'development' +`bundle config set --local with 'development'` + + +then create a .env.rb file in the root directory that contains the following ENV attributes: + +``` +ENV["APP_SESSION_SECRET"] = {output of a random 64 byte secret} + +ENV["DB_NAME"] = {db file name} +``` + after the dependencies are installed, you have to create the db -`sequel -m db/migrations sqlite://db/url_shortener.db` +`sequel -m db/migrations sqlite://db/{DB_NAME}` + to start the application with Falcon: diff --git a/app.rb b/app.rb index 4b2b414..54554b6 100644 --- a/app.rb +++ b/app.rb @@ -4,11 +4,16 @@ require 'json' require 'sequel' class App < Roda - DB = Sequel.sqlite('db/url_shortener.db') - links = DB[:links] + plugin :sessions, secret: ENV.delete('APP_SESSION_SECRET') plugin :render, escape: true + plugin :flash + + DB = Sequel.sqlite("db/#{ENV['DB_NAME']}") + links = DB[:links] + route do |r| r.root do + @message = flash['message'] || "Enter a URL" view :home end @@ -19,11 +24,16 @@ class App < Roda r.post "create" do url = r.params['url'] - if url.empty? then r.redirect '/' end + if url.empty? + flash['message'] = "Please enter a valid URL"; + r.redirect '/' + end if nil == links.filter(:url => url).first code = SecureRandom.urlsafe_base64 4 links.insert(url: url, code: code) + @message = "Link created" end + @message ||= "Link exists" @new_link = 'http://' + request.env['HTTP_HOST'] + '/' + links.filter(:url => url).first[:code] view :create end diff --git a/config.ru b/config.ru index 90dc7d6..02b347a 100644 --- a/config.ru +++ b/config.ru @@ -1,3 +1,4 @@ +require './.env' require './app' run App.app diff --git a/features/homepage.feature b/features/homepage.feature index 9215df1..4a96c4a 100644 --- a/features/homepage.feature +++ b/features/homepage.feature @@ -7,6 +7,7 @@ Feature: Homepage Scenario: Homepage Loads with a form Given I visit the "/" page Then I should see text "URL Shortener" + And I should see the message "Enter a URL" And I should see a form field "url" And I should see a "Submit" button @@ -14,9 +15,21 @@ Feature: Homepage Given I visit the "/" page When I click the "Submit" button Then I should be on "/" page + And I should see the message "Please enter a valid URL" + @db-test Scenario: Submitting the form with a correct URL Given I visit the "/" page - When I type "http://google.com/" in the "url" field + When I type "http://google.com" in the "url" field And I click the "Submit" button Then I should be on "/create" page + And I should see the message "Link created" + + @db-test + Scenario: Submitting the form with an existing URL + Given I visit the "/" page + And A link already exists with the url "http://google.com" + When I type "http://google.com" in the "url" field + And I click the "Submit" button + Then I should be on "/create" page + And I should see the message "Link exists" diff --git a/features/step_definitions/steps.rb b/features/step_definitions/steps.rb index 78eb083..9bc830e 100644 --- a/features/step_definitions/steps.rb +++ b/features/step_definitions/steps.rb @@ -1,9 +1,18 @@ +# BEFORE +Before('@db-test') do + @links = Sequel.sqlite("db/#{ENV['DB_NAME']}")[:links] +end + # GIVEN Given('I visit the {string} page') do |string| visit string end +Given('A link already exists with the url {string}') do |string| + @links.insert(url: string, code: "aaaaaa") +end + # WHEN When('I click the {string} button') do |string| @@ -31,3 +40,13 @@ end Then('I should be on {string} page') do |string| page.should have_current_path string end + +Then('I should see the message {string}') do |message| + page.should have_selector '#message', text: message +end + +# AFTER + +After('@db-test') do + @links.delete +end diff --git a/features/support/env.rb b/features/support/env.rb index 6ee27f9..5307da0 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -1,11 +1,20 @@ +require_relative '../../.env' +ENV["DB_NAME"] = "test_#{ENV["DB_NAME"]}" require_relative '../../app' require 'rubygems' require 'roda' +require 'sequel' require 'capybara' require 'capybara/dsl' require 'rspec' +# DB initialization +Sequel.extension :migration +Sequel.sqlite("db/#{ENV['DB_NAME']}") do |db| + Sequel::Migrator.apply(db, "db/migrations") +end +# attach app to Capybara Capybara.app = App include Capybara::DSL diff --git a/views/layout.erb b/views/layout.erb index e1b8a4b..a15f97c 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -6,6 +6,7 @@