Compare commits

...

14 Commits

Author SHA1 Message Date
bucky 5fae0c4fa9 Merge pull request 'rspec-coverage' (#22) from rspec-coverage into master
Reviewed-on: #22
2023-10-12 23:49:48 -07:00
Adam Townsend 144731062b added URL validation to webpage part 2023-10-12 23:42:52 -07:00
Adam Townsend 72f3e03edd 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
2023-10-12 23:42:04 -07:00
Adam Townsend b08693e866 remove the puts, don't print out the test result 2023-10-12 23:41:38 -07:00
Adam Townsend ae2360a480 include the proper status code 2023-10-12 23:31:15 -07:00
Adam Townsend 213265a5d0 added test for submitting with the wrong content type header 2023-10-12 23:30:47 -07:00
Adam Townsend dfb6b23e70 run simplecov for rspec tests 2023-10-12 23:12:14 -07:00
Adam Townsend c81a7a6160 added rescue for urls that don't resolve 2023-10-12 19:03:03 -07:00
Adam Townsend bbb710a5e1 added test for bad TLD, better named 404 url test 2023-10-12 19:02:38 -07:00
Adam Townsend 7eaa8eacf8 added rescue for OpenURI HTTPErrors 2023-10-12 18:26:13 -07:00
Adam Townsend d78e361c29 added test for validating a url is accessible 2023-10-12 18:25:38 -07:00
Adam Townsend 1ae6c02472 rescue BadURIError for invalid URL format 2023-10-12 18:20:56 -07:00
Adam Townsend 11206854ad added test for an invalid url 2023-10-12 18:20:35 -07:00
Adam Townsend 33089e6fbd build HTML output with cucumber and rspec files in root dir 2023-10-12 16:25:22 -07:00
5 changed files with 102 additions and 8 deletions

8
Jenkinsfile vendored
View File

@ -26,10 +26,10 @@ pipeline {
stage('Run tests') { stage('Run tests') {
steps { steps {
catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { 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') { 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, allowMissing: false,
alwaysLinkToLastBuild: false, alwaysLinkToLastBuild: false,
keepAll: true, keepAll: true,
reportDir: 'coverage', reportDir: '.',
reportFiles: 'cucumber.html, spec.html, index.html', reportFiles: 'cucumber.html, spec.html, coverage/index.html',
reportName: 'Test Results', reportName: 'Test Results',
reportTitles: 'Cucumber Results, RSpec Results, Test Coverage']) reportTitles: 'Cucumber Results, RSpec Results, Test Coverage'])
} }

31
app.rb
View File

@ -2,6 +2,7 @@ require 'roda'
require 'securerandom' require 'securerandom'
require 'json' require 'json'
require 'sequel' require 'sequel'
require 'open-uri'
class App < Roda class App < Roda
plugin :sessions, secret: ENV.delete('APP_SESSION_SECRET') plugin :sessions, secret: ENV.delete('APP_SESSION_SECRET')
@ -33,6 +34,20 @@ class App < Roda
flash['message'] = "Please enter a valid URL"; flash['message'] = "Please enter a valid URL";
r.redirect '/' r.redirect '/'
end 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? if links.filter(:url => url).first.nil?
code = SecureRandom.urlsafe_base64 4 code = SecureRandom.urlsafe_base64 4
links.insert(url: url, code: code) links.insert(url: url, code: code)
@ -46,7 +61,8 @@ class App < Roda
r.on "links" do r.on "links" do
r.post do r.post do
if 'application/json' != r.headers['CONTENT_TYPE'] 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 end
url = r.params['url'] url = r.params['url']
@ -60,6 +76,19 @@ class App < Roda
return {message: "invalid url parameter"}.to_json return {message: "invalid url parameter"}.to_json
end end
begin
OpenURI.open_uri(url)
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
rescue SocketError => e
response.status = 400
return {message: "url does not resolve"}.to_json
end
if links.filter(:url => url).first.nil? if links.filter(:url => url).first.nil?
code = SecureRandom.urlsafe_base64 4 code = SecureRandom.urlsafe_base64 4
links.insert(url: url, code: code) links.insert(url: url, code: code)

View File

@ -63,7 +63,7 @@ Then('I should be redirected to {string}') do |string|
end end
Then('The status code should be {int}') do |code| Then('The status code should be {int}') do |code|
puts page.status_code.should eq(code) page.status_code.should eq(code)
end end

View File

@ -26,3 +26,27 @@ Feature: Submit
And I click the "Submit" button And I click the "Submit" button
Then I should be on "/create" page Then I should be on "/create" page
And I should see the message "Link exists" 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"

View File

@ -1,3 +1,6 @@
require 'simplecov'
SimpleCov.start
require_relative '../.env' require_relative '../.env'
ENV["DB_NAME"] = "test_#{ENV["DB_NAME"]}" ENV["DB_NAME"] = "test_#{ENV["DB_NAME"]}"
require_relative '../app' require_relative '../app'
@ -45,8 +48,8 @@ describe "Submit API request to create new link" do
expect(last_response.status).to eq(400) expect(last_response.status).to eq(400)
response_json = JSON.parse(last_response.body) response_json = JSON.parse(last_response.body)
expect(response_json['message']).to eq('invalid url parameter') expect(response_json['message']).to eq('invalid url parameter')
end end
it "should return with a 400 status and 'missing url parameter' message when an empty url is submitted" do it "should return with a 400 status and 'missing url parameter' message when an empty url is submitted" do
data = { data = {
} }
@ -54,7 +57,45 @@ describe "Submit API request to create new link" do
expect(last_response.status).to eq(400) expect(last_response.status).to eq(400)
response_json = JSON.parse(last_response.body) response_json = JSON.parse(last_response.body)
expect(response_json['message']).to eq('missing url parameter') 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
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'
}
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
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
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
end end