From 33089e6fbdf0713199b343e88dfd15ccfc201c0e Mon Sep 17 00:00:00 2001 From: Adam Townsend Date: Thu, 12 Oct 2023 16:25:22 -0700 Subject: [PATCH 01/13] build HTML output with cucumber and rspec files in root dir --- Jenkinsfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index f14f88f..091d725 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -26,10 +26,10 @@ pipeline { stage('Run tests') { steps { catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { - sh 'cucumber features --format html --out coverage/cucumber.html' + sh 'cucumber features --format html --out cucumber.html' } catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { - sh 'rspec spec --format html --out coverage/spec.html' + sh 'rspec spec --format html --out spec.html' } } } @@ -40,8 +40,8 @@ pipeline { allowMissing: false, alwaysLinkToLastBuild: false, keepAll: true, - reportDir: 'coverage', - reportFiles: 'cucumber.html, spec.html, index.html', + reportDir: '.', + reportFiles: 'cucumber.html, spec.html, coverage/index.html', reportName: 'Test Results', reportTitles: 'Cucumber Results, RSpec Results, Test Coverage']) } -- 2.41.0 From 11206854adb3c81b8765f930028ffcda891d6466 Mon Sep 17 00:00:00 2001 From: Adam Townsend Date: Thu, 12 Oct 2023 18:20:35 -0700 Subject: [PATCH 02/13] added test for an invalid url --- spec/create_spec.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/spec/create_spec.rb b/spec/create_spec.rb index c814803..0ce9011 100644 --- a/spec/create_spec.rb +++ b/spec/create_spec.rb @@ -45,8 +45,8 @@ describe "Submit API request to create new link" do 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 = { } @@ -54,7 +54,15 @@ describe "Submit API request to create new link" do expect(last_response.status).to eq(400) response_json = JSON.parse(last_response.body) expect(response_json['message']).to eq('missing url parameter') + end + it "should return with a 400 status and 'invalid url parameter' message when an invalid url is submitted" do + data = { + url: 'not-an-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 end - -- 2.41.0 From 1ae6c0247212a18a6353606906f34ac574fc2825 Mon Sep 17 00:00:00 2001 From: Adam Townsend Date: Thu, 12 Oct 2023 18:20:56 -0700 Subject: [PATCH 03/13] rescue BadURIError for invalid URL format --- app.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app.rb b/app.rb index b8501a6..6bd5136 100644 --- a/app.rb +++ b/app.rb @@ -2,6 +2,7 @@ require 'roda' require 'securerandom' require 'json' require 'sequel' +require 'open-uri' class App < Roda plugin :sessions, secret: ENV.delete('APP_SESSION_SECRET') @@ -60,6 +61,14 @@ class App < Roda return {message: "invalid url parameter"}.to_json end + begin + OpenURI.open_uri(url) + rescue URI::BadURIError + 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) -- 2.41.0 From d78e361c295b0bfb570bd625e23c6114bc8a2ddf Mon Sep 17 00:00:00 2001 From: Adam Townsend Date: Thu, 12 Oct 2023 18:25:38 -0700 Subject: [PATCH 04/13] added test for validating a url is accessible --- spec/create_spec.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spec/create_spec.rb b/spec/create_spec.rb index 0ce9011..6b7ecc9 100644 --- a/spec/create_spec.rb +++ b/spec/create_spec.rb @@ -65,4 +65,14 @@ describe "Submit API request to create new link" do 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 'url not found' message when an invalid url is submitted" do + data = { + url: 'http://google.com/example' + } + 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('url not found') + end end -- 2.41.0 From 7eaa8eacf872adecd313363b7c7557e8e7c73e0c Mon Sep 17 00:00:00 2001 From: Adam Townsend Date: Thu, 12 Oct 2023 18:26:13 -0700 Subject: [PATCH 05/13] added rescue for OpenURI HTTPErrors --- app.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app.rb b/app.rb index 6bd5136..d1ab2c6 100644 --- a/app.rb +++ b/app.rb @@ -66,6 +66,9 @@ class App < Roda rescue URI::BadURIError response.status = 400 return {message: "invalid url parameter"}.to_json + rescue OpenURI::HTTPError + response.status = 400 + return {message: "url not found"}.to_json end -- 2.41.0 From bbb710a5e185b80aeaf006366bc8a4bac5d58a59 Mon Sep 17 00:00:00 2001 From: Adam Townsend Date: Thu, 12 Oct 2023 19:02:38 -0700 Subject: [PATCH 06/13] added test for bad TLD, better named 404 url test --- spec/create_spec.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/spec/create_spec.rb b/spec/create_spec.rb index 6b7ecc9..16611cf 100644 --- a/spec/create_spec.rb +++ b/spec/create_spec.rb @@ -66,7 +66,7 @@ describe "Submit API request to create new link" do expect(response_json['message']).to eq('invalid url parameter') end - it "should return with a 400 status and 'url not found' message when an invalid url is submitted" do + it "should return with a 400 status and 'url not found' message when a 404 url is submitted" do data = { url: 'http://google.com/example' } @@ -75,4 +75,14 @@ describe "Submit API request to create new link" do response_json = JSON.parse(last_response.body) expect(response_json['message']).to eq('url not found') end + + it "should return with a 400 status and 'url not found' message when a URL with no DNS is submitted" do + data = { + url: 'http://bad.tld' + } + 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('url does not resolve') + end end -- 2.41.0 From c81a7a616001dda7050a45c7458a0c7a66c905c1 Mon Sep 17 00:00:00 2001 From: Adam Townsend Date: Thu, 12 Oct 2023 19:03:03 -0700 Subject: [PATCH 07/13] added rescue for urls that don't resolve --- app.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app.rb b/app.rb index d1ab2c6..dc43868 100644 --- a/app.rb +++ b/app.rb @@ -69,9 +69,11 @@ class App < Roda rescue OpenURI::HTTPError response.status = 400 return {message: "url not found"}.to_json + rescue SocketError => e + response.status = 400 + return {message: "url does not resolve"}.to_json end - if links.filter(:url => url).first.nil? code = SecureRandom.urlsafe_base64 4 links.insert(url: url, code: code) -- 2.41.0 From dfb6b23e703bd27d1216a85911a2da82840a782a Mon Sep 17 00:00:00 2001 From: Adam Townsend Date: Thu, 12 Oct 2023 23:12:14 -0700 Subject: [PATCH 08/13] run simplecov for rspec tests --- spec/create_spec.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/create_spec.rb b/spec/create_spec.rb index 16611cf..0c2afd3 100644 --- a/spec/create_spec.rb +++ b/spec/create_spec.rb @@ -1,3 +1,6 @@ +require 'simplecov' +SimpleCov.start + require_relative '../.env' ENV["DB_NAME"] = "test_#{ENV["DB_NAME"]}" require_relative '../app' -- 2.41.0 From 213265a5d00c9b48f005b0bca9fee232421c58af Mon Sep 17 00:00:00 2001 From: Adam Townsend Date: Thu, 12 Oct 2023 23:30:47 -0700 Subject: [PATCH 09/13] added test for submitting with the wrong content type header --- spec/create_spec.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spec/create_spec.rb b/spec/create_spec.rb index 0c2afd3..4ef0610 100644 --- a/spec/create_spec.rb +++ b/spec/create_spec.rb @@ -88,4 +88,14 @@ describe "Submit API request to create new link" do response_json = JSON.parse(last_response.body) expect(response_json['message']).to eq('url does not resolve') end + + it "should return with a 400 status and 'not a valid json request' message when a request is made with the wrong content type header" do + data = { + url: 'http://google.com' + } + post('/links', data.to_json) + expect(last_response.status).to eq(400) + response_json = JSON.parse(last_response.body) + expect(response_json['message']).to eq('not a valid json request') + end end -- 2.41.0 From ae2360a48074df6501ae2312c83d1fe67c87f6ea Mon Sep 17 00:00:00 2001 From: Adam Townsend Date: Thu, 12 Oct 2023 23:31:15 -0700 Subject: [PATCH 10/13] include the proper status code --- app.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app.rb b/app.rb index dc43868..aa82f35 100644 --- a/app.rb +++ b/app.rb @@ -47,7 +47,8 @@ class App < Roda r.on "links" do r.post do if 'application/json' != r.headers['CONTENT_TYPE'] - return {message: "Not a valid JSON request"}.to_json + response.status = 400 + return {message: "not a valid json request"}.to_json end url = r.params['url'] -- 2.41.0 From b08693e86672c67d5b7926f376d1724825c983ad Mon Sep 17 00:00:00 2001 From: Adam Townsend Date: Thu, 12 Oct 2023 23:41:38 -0700 Subject: [PATCH 11/13] remove the puts, don't print out the test result --- features/step_definitions/steps.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/step_definitions/steps.rb b/features/step_definitions/steps.rb index d1581a3..04262a8 100644 --- a/features/step_definitions/steps.rb +++ b/features/step_definitions/steps.rb @@ -63,7 +63,7 @@ Then('I should be redirected to {string}') do |string| end Then('The status code should be {int}') do |code| - puts page.status_code.should eq(code) + page.status_code.should eq(code) end -- 2.41.0 From 72f3e03edd2635cd2607b35298fa36f6f3b44050 Mon Sep 17 00:00:00 2001 From: Adam Townsend Date: Thu, 12 Oct 2023 23:42:04 -0700 Subject: [PATCH 12/13] added tests for invalid URL entries + URL that returns a 404 + URL where the domain does not resolve with DNS + URL that is not properly formatted --- features/submit.feature | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/features/submit.feature b/features/submit.feature index 422e082..7bbbf69 100644 --- a/features/submit.feature +++ b/features/submit.feature @@ -26,3 +26,27 @@ Feature: Submit And I click the "Submit" button Then I should be on "/create" page And I should see the message "Link exists" + + @db-test + Scenario: Submitting the form with a URL that is 404 + Given I visit the "/" page + When I type "http://google.com/example" in the "url" field + And I click the "Submit" button + Then I should be on "/" page + And I should see the message "URL not found" + + @db-test + Scenario: Submitting the form with a URL that does not resolve + Given I visit the "/" page + When I type "http://bad.tld" in the "url" field + And I click the "Submit" button + Then I should be on "/" page + And I should see the message "URL does not resolve" + + @db-test + Scenario: Submitting the form with an invalid URL + Given I visit the "/" page + When I type "not-an-url" in the "url" field + And I click the "Submit" button + Then I should be on "/" page + And I should see the message "Invalid URL" -- 2.41.0 From 144731062ba0332ef8908d27939b41b82497cac3 Mon Sep 17 00:00:00 2001 From: Adam Townsend Date: Thu, 12 Oct 2023 23:42:52 -0700 Subject: [PATCH 13/13] added URL validation to webpage part --- app.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app.rb b/app.rb index aa82f35..b9ef9e5 100644 --- a/app.rb +++ b/app.rb @@ -34,6 +34,20 @@ class App < Roda flash['message'] = "Please enter a valid URL"; r.redirect '/' end + + begin + OpenURI.open_uri(url) + rescue URI::BadURIError + flash['message'] = "Invalid URL" + r.redirect '/' + rescue OpenURI::HTTPError + flash['message'] = "URL not found" + r.redirect '/' + rescue SocketError => e + flash['message'] = "URL does not resolve" + r.redirect '/' + end + if links.filter(:url => url).first.nil? code = SecureRandom.urlsafe_base64 4 links.insert(url: url, code: code) -- 2.41.0