Compare commits

..

15 Commits

Author SHA1 Message Date
bucky 5631ae386f include rackup 2023-10-13 21:28:47 -07:00
bucky c31c556df5 removed falcon and it's dependencies, because it wasn't working right.
use puma for now
2023-10-13 21:27:25 -07:00
bucky 5fae0c4fa9 Merge pull request 'rspec-coverage' (#22) from rspec-coverage into master
Reviewed-on: #22
2023-10-12 23:49:48 -07:00
bucky 144731062b added URL validation to webpage part 2023-10-12 23:42:52 -07:00
bucky 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
bucky b08693e866 remove the puts, don't print out the test result 2023-10-12 23:41:38 -07:00
bucky ae2360a480 include the proper status code 2023-10-12 23:31:15 -07:00
bucky 213265a5d0 added test for submitting with the wrong content type header 2023-10-12 23:30:47 -07:00
bucky dfb6b23e70 run simplecov for rspec tests 2023-10-12 23:12:14 -07:00
bucky c81a7a6160 added rescue for urls that don't resolve 2023-10-12 19:03:03 -07:00
bucky bbb710a5e1 added test for bad TLD, better named 404 url test 2023-10-12 19:02:38 -07:00
bucky 7eaa8eacf8 added rescue for OpenURI HTTPErrors 2023-10-12 18:26:13 -07:00
bucky d78e361c29 added test for validating a url is accessible 2023-10-12 18:25:38 -07:00
bucky 1ae6c02472 rescue BadURIError for invalid URL format 2023-10-12 18:20:56 -07:00
bucky 11206854ad added test for an invalid url 2023-10-12 18:20:35 -07:00
6 changed files with 111 additions and 69 deletions
+4 -1
View File
@@ -2,7 +2,6 @@
source "https://rubygems.org" source "https://rubygems.org"
gem "falcon", "~> 0.42.3"
gem "roda", "~> 3.72" gem "roda", "~> 3.72"
@@ -27,3 +26,7 @@ group :test do
gem "simplecov" gem "simplecov"
end end
gem "puma", "~> 6.4"
gem "rackup", "~> 2.1"
+9 -64
View File
@@ -3,30 +3,7 @@ GEM
specs: specs:
addressable (2.8.5) addressable (2.8.5)
public_suffix (>= 2.0.2, < 6.0) public_suffix (>= 2.0.2, < 6.0)
async (2.6.4)
console (~> 1.10)
fiber-annotation
io-event (~> 1.1)
timers (~> 4.1)
async-container (0.16.12)
async
async-io
async-http (0.60.2)
async (>= 1.25)
async-io (>= 1.28)
async-pool (>= 0.2)
protocol-http (~> 0.24.0)
protocol-http1 (~> 0.15.0)
protocol-http2 (~> 0.15.0)
traces (>= 0.10.0)
async-http-cache (0.4.3)
async-http (~> 0.56)
async-io (1.36.0)
async
async-pool (0.4.0)
async (>= 1.25)
bigdecimal (3.1.4) bigdecimal (3.1.4)
build-environment (1.13.0)
builder (3.2.4) builder (3.2.4)
capybara (3.39.2) capybara (3.39.2)
addressable addressable
@@ -37,9 +14,6 @@ GEM
rack-test (>= 0.6.3) rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0) regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2) xpath (~> 3.2)
console (1.23.2)
fiber-annotation
fiber-local
cucumber (9.0.2) cucumber (9.0.2)
builder (~> 3.2, >= 3.2.4) builder (~> 3.2, >= 3.2.4)
cucumber-ci-environment (~> 9.2, >= 9.2.0) cucumber-ci-environment (~> 9.2, >= 9.2.0)
@@ -67,51 +41,25 @@ GEM
diff-lcs (1.5.0) diff-lcs (1.5.0)
docile (1.4.0) docile (1.4.0)
erubi (1.12.0) erubi (1.12.0)
falcon (0.42.3)
async
async-container (~> 0.16.0)
async-http (~> 0.57)
async-http-cache (~> 0.4.0)
async-io (~> 1.22)
build-environment (~> 1.13)
bundler
localhost (~> 1.1)
openssl (~> 3.0)
process-metrics (~> 0.2.0)
protocol-rack (~> 0.1)
samovar (~> 2.1)
ffi (1.16.2) ffi (1.16.2)
fiber-annotation (0.2.0)
fiber-local (1.0.0)
io-event (1.3.2)
localhost (1.1.10)
mapping (1.1.1)
matrix (0.4.2) matrix (0.4.2)
mini_mime (1.1.5) mini_mime (1.1.5)
mini_portile2 (2.8.4) mini_portile2 (2.8.4)
multi_test (1.1.0) multi_test (1.1.0)
nio4r (2.5.9)
nokogiri (1.15.4) nokogiri (1.15.4)
mini_portile2 (~> 2.8.2) mini_portile2 (~> 2.8.2)
racc (~> 1.4) racc (~> 1.4)
openssl (3.2.0)
process-metrics (0.2.1)
console (~> 1.8)
samovar (~> 2.1)
protocol-hpack (1.4.2)
protocol-http (0.24.7)
protocol-http1 (0.15.1)
protocol-http (~> 0.22)
protocol-http2 (0.15.1)
protocol-hpack (~> 1.4)
protocol-http (~> 0.18)
protocol-rack (0.2.6)
protocol-http (~> 0.23)
rack (>= 1.0)
public_suffix (5.0.3) public_suffix (5.0.3)
puma (6.4.0)
nio4r (~> 2.0)
racc (1.7.1) racc (1.7.1)
rack (3.0.8) rack (3.0.8)
rack-test (2.1.0) rack-test (2.1.0)
rack (>= 1.3) rack (>= 1.3)
rackup (2.1.0)
rack (>= 3)
webrick (~> 1.8)
regexp_parser (2.8.1) regexp_parser (2.8.1)
rexml (3.2.6) rexml (3.2.6)
roda (3.72.0) roda (3.72.0)
@@ -130,9 +78,6 @@ GEM
rspec-support (~> 3.12.0) rspec-support (~> 3.12.0)
rspec-support (3.12.1) rspec-support (3.12.1)
rubyzip (2.3.2) rubyzip (2.3.2)
samovar (2.2.0)
console (~> 1.0)
mapping (~> 1.0)
selenium-webdriver (4.13.1) selenium-webdriver (4.13.1)
rexml (~> 3.2, >= 3.2.5) rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0) rubyzip (>= 1.2.2, < 3.0)
@@ -150,8 +95,7 @@ GEM
sys-uname (1.2.3) sys-uname (1.2.3)
ffi (~> 1.1) ffi (~> 1.1)
tilt (2.3.0) tilt (2.3.0)
timers (4.3.5) webrick (1.8.1)
traces (0.11.1)
websocket (1.2.10) websocket (1.2.10)
xpath (3.2.0) xpath (3.2.0)
nokogiri (~> 1.8) nokogiri (~> 1.8)
@@ -163,7 +107,8 @@ DEPENDENCIES
capybara (~> 3.39) capybara (~> 3.39)
cucumber (~> 9.0) cucumber (~> 9.0)
erubi (~> 1.12) erubi (~> 1.12)
falcon (~> 0.42.3) puma (~> 6.4)
rackup (~> 2.1)
roda (~> 3.72) roda (~> 3.72)
rspec (~> 3.12) rspec (~> 3.12)
selenium-webdriver (~> 4.13) selenium-webdriver (~> 4.13)
+30 -1
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)
+1 -1
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
+24
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"
+44 -3
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
end 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