diff --git a/Jenkinsfile b/Jenkinsfile index 6363195..f14f88f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -25,7 +25,12 @@ pipeline { } stage('Run tests') { steps { - sh 'cucumber features --format html --out coverage/cucumber.html' + catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { + sh 'cucumber features --format html --out coverage/cucumber.html' + } + catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { + sh 'rspec spec --format html --out coverage/spec.html' + } } } stage('Report results') { @@ -36,9 +41,9 @@ pipeline { alwaysLinkToLastBuild: false, keepAll: true, reportDir: 'coverage', - reportFiles: 'cucumber.html, index.html', + reportFiles: 'cucumber.html, spec.html, index.html', reportName: 'Test Results', - reportTitles: 'Cucumber Results, Test Coverage']) + reportTitles: 'Cucumber Results, RSpec Results, Test Coverage']) } } } diff --git a/app.rb b/app.rb index 2e49f5e..b8501a6 100644 --- a/app.rb +++ b/app.rb @@ -7,6 +7,8 @@ class App < Roda plugin :sessions, secret: ENV.delete('APP_SESSION_SECRET') plugin :render, escape: true plugin :flash + plugin :json_parser + plugin :request_headers DB = Sequel.sqlite("db/#{ENV['DB_NAME']}") links = DB[:links] @@ -27,7 +29,7 @@ class App < Roda r.post "create" do url = r.params['url'] - if url.empty? + if url.nil? or url.empty? flash['message'] = "Please enter a valid URL"; r.redirect '/' end @@ -36,9 +38,37 @@ class App < Roda links.insert(url: url, code: code) @message = "Link created" end + code = links.filter(:url => url).first[:code] @message ||= "Link exists" - @new_link = 'http://' + request.env['HTTP_HOST'] + '/' + links.filter(:url => url).first[:code] + @new_link = 'http://' + request.env['HTTP_HOST'] + '/' + code view :create end + r.on "links" do + r.post do + if 'application/json' != r.headers['CONTENT_TYPE'] + return {message: "Not a valid JSON request"}.to_json + end + + url = r.params['url'] + if url.nil? + response.status = 400 + return {message: "missing url parameter"}.to_json + end + + if url.empty? + response.status = 400 + return {message: "invalid url parameter"}.to_json + end + + if links.filter(:url => url).first.nil? + code = SecureRandom.urlsafe_base64 4 + links.insert(url: url, code: code) + end + + code = links.filter(:url => url).first[:code] + @new_link = 'http://' + request.env['HTTP_HOST'] + '/' + code + return {url: url, code: code, link: @new_link}.to_json + end + end end end diff --git a/features/homepage.feature b/features/homepage.feature index 4a96c4a..55bc3b4 100644 --- a/features/homepage.feature +++ b/features/homepage.feature @@ -10,26 +10,3 @@ Feature: Homepage And I should see the message "Enter a URL" And I should see a form field "url" And I should see a "Submit" button - - Scenario: Submitting the form without entering a URL - 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 - 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/submit.feature b/features/submit.feature new file mode 100644 index 0000000..422e082 --- /dev/null +++ b/features/submit.feature @@ -0,0 +1,28 @@ +# features/submit.feature + +Feature: Submit + + Submitting URL's on the homepage + + Scenario: Submitting the form without entering a URL + 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 + 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/spec/create_spec.rb b/spec/create_spec.rb new file mode 100644 index 0000000..c814803 --- /dev/null +++ b/spec/create_spec.rb @@ -0,0 +1,60 @@ +require_relative '../.env' +ENV["DB_NAME"] = "test_#{ENV["DB_NAME"]}" +require_relative '../app' +require 'rubygems' +require 'roda' +require 'sequel' +require 'rspec' +require 'rack/test' + +# DB initialization +Sequel.extension :migration +Sequel.sqlite("db/#{ENV['DB_NAME']}") do |db| + Sequel::Migrator.apply(db, "db/migrations") +end + +def app + App +end + +describe "Submit API request to create new link" do + include Rack::Test::Methods + before :each do + @links = Sequel.sqlite("db/#{ENV['DB_NAME']}")[:links] + end + after :each do + @links.delete + end + it "should return link data in json format when a valid url is submitted" do + data = { + url: 'http://google.com' + } + post('/links', data.to_json, "CONTENT_TYPE" => "application/json") + expect(last_response).to be_ok + response_json = JSON.parse(last_response.body) + expect(response_json['url']).to eq(data[:url]) + expect(response_json['code']).not_to eq(nil) + expect(response_json['link']).to include(response_json['code']) + end + + it "should return with a 400 status and 'invalid url parameter' message when an empty url is submitted" do + data = { + url: '' + } + post('/links', data.to_json, "CONTENT_TYPE" => "application/json") + expect(last_response.status).to eq(400) + response_json = JSON.parse(last_response.body) + expect(response_json['message']).to eq('invalid url parameter') + + end + it "should return with a 400 status and 'missing url parameter' message when an empty url is submitted" do + data = { + } + post('/links', data.to_json, "CONTENT_TYPE" => "application/json") + expect(last_response.status).to eq(400) + response_json = JSON.parse(last_response.body) + expect(response_json['message']).to eq('missing url parameter') + + end +end +