Compare commits

..

71 Commits

Author SHA1 Message Date
bucky 4490ed3e7c output something from the bundler audit to see in the reports 2023-10-22 16:22:18 -07:00
bucky 30c1192e27 Merge pull request 'audit' (#31) from audit into master
Reviewed-on: #31

closes bucky/url-shortener#30
2023-10-22 16:06:15 -07:00
bucky 6e30705810 rubocop autofixed quotes 2023-10-22 15:57:57 -07:00
bucky d7c9105995 added audit checks, this should help keep things secure 2023-10-22 15:51:16 -07:00
bucky a732eb2a61 added bundle-audit and ruby_audit gems 2023-10-22 15:48:40 -07:00
bucky c29d53a33b Merge pull request 'rubocop' (#29) from rubocop into master
Reviewed-on: #29

closes bucky/url-shortener#28
2023-10-22 15:11:23 -07:00
bucky 3fd8e8c630 wrap the string in single quotes 2023-10-22 15:00:59 -07:00
bucky 950c358ae5 another try 2023-10-22 14:55:06 -07:00
bucky f81199e31b maybe this will clean up a few things 2023-10-22 14:15:27 -07:00
bucky bf1fefd1bc still worknig on env file, and adding logic to not build if the tests fail 2023-10-22 14:05:51 -07:00
bucky c51a6782d9 another shot at cleaning up the .env.rb file 2023-10-22 13:50:58 -07:00
bucky 795447e029 attempting to clean up the .env.rb file 2023-10-22 13:43:12 -07:00
bucky 7caf25c4d0 don't kill it if linting breaks, mark it as unstable 2023-10-22 13:32:39 -07:00
bucky 3fa1de5e4e install bundled gems in /vendor, and use bundle exec to run them 2023-10-22 13:27:07 -07:00
bucky f86da2ed6f forgot to wrap the steps in a steps block 2023-10-22 13:19:30 -07:00
bucky 282a07c5fb added rubocop linting section with output for reports and clean up
rubocop config
2023-10-22 13:16:20 -07:00
bucky bf6ed14b5e custom parts for rubocop to run. don't worry about block length in many
parts. hide extension suggestions
2023-10-22 13:15:09 -07:00
bucky 7d35133e43 require capybara and rspec parts needed for tests to run instead of
including them. rubocop autofixed formatting
2023-10-22 13:14:23 -07:00
bucky c505012b00 rubocop added frozen string literal comment 2023-10-22 13:14:02 -07:00
bucky 4f54124519 rubocop autofixed formatting 2023-10-22 13:13:27 -07:00
bucky 18e8eac2ab rubocop autofixed formatting 2023-10-22 13:12:48 -07:00
bucky 5abf07d0c7 rubocop formatting fixes 2023-10-22 13:07:07 -07:00
bucky 48ffdf560b frozen string literal for rubocop 2023-10-22 13:06:12 -07:00
bucky e0392f2483 added rubocop 2023-10-22 13:05:43 -07:00
bucky 15a5017c86 set up to run with only the freebsd and ruby labeled agent(s) 2023-10-18 13:08:41 -07:00
bucky dd5caa4056 updated README, swapped Falcon for Puma for now, and ignored more files 2023-10-17 21:53:12 -07:00
bucky 360ddbe6d2 include the branch name in the zip, so it can be identified a little easier later 2023-10-17 21:45:14 -07:00
bucky b3b886f0b3 Merge pull request 'simplify-secret' (#27) from simplify-secret into master
Reviewed-on: #27
2023-10-17 21:43:19 -07:00
bucky 93aa007c14 removed secret.rb, it's no longer needed 2023-10-17 21:40:39 -07:00
bucky 4e32f4a60d use the escaped quotes for it to work correctly 2023-10-17 21:39:15 -07:00
bucky 2759880a53 remove env. 2023-10-17 21:37:45 -07:00
bucky 7bc1a852db swap quotes on the db name 2023-10-17 21:36:56 -07:00
bucky 00119f9723 use env.DB_NAME to access the environment variable 2023-10-17 21:32:30 -07:00
bucky ff2a0e867d swap the quotes because single quotes doesn't exec the ruby command 2023-10-17 21:30:53 -07:00
bucky 1fae85ff9d moved the init step into one shell command to load it all, and don't use
the secret.rb file
2023-10-17 21:26:23 -07:00
bucky 10fe82ab6a Merge pull request 'archive-deliverable' (#26) from archive-deliverable into master
Reviewed-on: #26
2023-10-17 18:12:37 -07:00
bucky 9812a92d59 remove ls 2023-10-17 18:09:17 -07:00
bucky e8b12c307a include ruby version 2023-10-17 18:06:36 -07:00
bucky ae00ac8672 forgot the .rb 2023-10-17 18:04:29 -07:00
bucky bf92201721 removed some unnecessary lines, and check what's in the current
directory
2023-10-17 18:02:40 -07:00
bucky 1f2e3d41dd syntax error extra - in there 2023-10-17 18:00:46 -07:00
bucky f31b6da49c include the .env file and remove the scret.rb file 2023-10-17 17:58:40 -07:00
bucky f32d153b69 simplified things? 2023-10-17 17:46:24 -07:00
bucky 15d9ade2cf remove EXPORT 2023-10-17 17:42:17 -07:00
bucky 4587c35806 just set it in the script 2023-10-17 17:40:23 -07:00
bucky 340614dadc echo outside catch error 2023-10-17 17:37:35 -07:00
bucky 8a0fef63b2 another try 2023-10-17 17:35:37 -07:00
bucky 8691d19e8d dump the zip file, let's see how it's working? 2023-10-17 17:32:50 -07:00
bucky 35d196bdc2 another shot accessing the new env var 2023-10-17 17:28:41 -07:00
bucky e2c3cb7035 access the ZIP_FILE variable properly? 2023-10-17 17:25:02 -07:00
bucky a69b3e4226 missed quote 2023-10-17 17:22:00 -07:00
bucky 36285b060b better try to set the environment 2023-10-17 17:19:31 -07:00
bucky a0a9e84b91 another try 2023-10-17 17:14:33 -07:00
bucky 01d9f9a21c another shot at setting the zip file name 2023-10-17 17:12:16 -07:00
bucky 621a777a46 update env vars
+ removed the app session secret. it's used where it is set
+ added zip file to make it easier to name the zip and reuse the name
2023-10-17 17:05:15 -07:00
bucky 6fbecd78a4 clean out unnecessary files a little easier 2023-10-17 10:39:17 -07:00
bucky 873b86a809 Merge pull request 'remove db files as well' (#25) from archive-deliverable into master
Reviewed-on: #25
2023-10-16 17:41:38 -07:00
bucky 47393a5ead remove db files as well 2023-10-16 17:30:11 -07:00
bucky 69c56ae31a Merge pull request 'archive-deliverable' (#24) from archive-deliverable into master
Reviewed-on: #24
2023-10-16 17:28:43 -07:00
bucky b2cdf60a32 Revert "simplify it a little"
This reverts commit 91f45965a0.
2023-10-16 17:23:50 -07:00
bucky 91f45965a0 simplify it a little 2023-10-16 17:18:06 -07:00
bucky 3097cb69aa clean the workspace when done 2023-10-16 17:04:23 -07:00
bucky eed17d61a3 use tmp as a staging place for building the tgz file 2023-10-16 16:35:56 -07:00
bucky 9e5a4069a4 wrapping all the commands in one script, hope it works? 2023-10-16 15:44:50 -07:00
bucky f8c20541d5 removed shopt, added that in jenkins user's .profile 2023-10-16 15:09:44 -07:00
bucky ee07312b86 another shot at getting local shell 2023-10-16 13:48:31 -07:00
bucky e4eabf8aa6 looking to see what shell is used 2023-10-16 12:06:11 -07:00
bucky 3ec0f0ff7b mkdir -p and wrapped the steps in a catch so the clean up happens 2023-10-16 12:01:10 -07:00
bucky 27b32fc8f4 another shot 2023-10-16 11:57:20 -07:00
bucky ceab408ec0 build deliverable, store it, and clean up afterwards 2023-10-16 10:54:52 -07:00
bucky b56b618a8c added stages to build a deliverable and then clean it up when done 2023-10-16 10:50:22 -07:00
13 changed files with 203 additions and 102 deletions
+2
View File
@@ -3,3 +3,5 @@
*.db
.env.rb
coverage
vendor
.ruby-version
+6
View File
@@ -0,0 +1,6 @@
AllCops:
NewCops: enable
SuggestExtensions: false
Metrics/BlockLength:
AllowedMethods: ['describe', 'context', 'route', 'r.on', 'r.post']
+17 -14
View File
@@ -1,32 +1,35 @@
# frozen_string_literal: true
source "https://rubygems.org"
source 'https://rubygems.org'
gem 'puma', '~> 6.4'
gem "roda", "~> 3.72"
gem 'rackup', '~> 2.1'
gem "sequel", "~> 5.72"
gem 'roda', '~> 3.72'
gem "tilt", "~> 2.2"
gem 'sequel', '~> 5.72'
gem "sqlite3", "~> 1.6"
gem 'tilt', '~> 2.2'
gem "erubi", "~> 1.12"
gem 'sqlite3', '~> 1.6'
gem 'erubi', '~> 1.12'
group :test do
gem 'cucumber', '~> 9.0'
gem "cucumber", "~> 9.0"
gem 'capybara', '~> 3.39'
gem "capybara", "~> 3.39"
gem 'rspec', '~> 3.12'
gem "rspec", "~> 3.12"
gem 'selenium-webdriver', '~> 4.13'
gem "selenium-webdriver", "~> 4.13"
gem 'simplecov'
gem "simplecov"
gem 'rubocop', require: false
gem 'ruby_audit', '~> 2.2'
end
gem "puma", "~> 6.4"
gem "rackup", "~> 2.1"
gem 'bundle-audit', '~> 0.1.0'
+36
View File
@@ -3,8 +3,15 @@ GEM
specs:
addressable (2.8.5)
public_suffix (>= 2.0.2, < 6.0)
ast (2.4.2)
base64 (0.1.1)
bigdecimal (3.1.4)
builder (3.2.4)
bundle-audit (0.1.0)
bundler-audit
bundler-audit (0.9.1)
bundler (>= 1.2.0, < 3)
thor (~> 1.0)
capybara (3.39.2)
addressable
matrix
@@ -42,6 +49,8 @@ GEM
docile (1.4.0)
erubi (1.12.0)
ffi (1.16.2)
json (2.6.3)
language_server-protocol (3.17.0.3)
matrix (0.4.2)
mini_mime (1.1.5)
mini_portile2 (2.8.4)
@@ -50,6 +59,10 @@ GEM
nokogiri (1.15.4)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
parallel (1.23.0)
parser (3.2.2.4)
ast (~> 2.4.1)
racc
public_suffix (5.0.3)
puma (6.4.0)
nio4r (~> 2.0)
@@ -60,6 +73,7 @@ GEM
rackup (2.1.0)
rack (>= 3)
webrick (~> 1.8)
rainbow (3.1.1)
regexp_parser (2.8.1)
rexml (3.2.6)
roda (3.72.0)
@@ -77,6 +91,23 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-support (3.12.1)
rubocop (1.57.1)
base64 (~> 0.1.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.2.2.4)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.28.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.29.0)
parser (>= 3.2.1.0)
ruby-progressbar (1.13.0)
ruby_audit (2.2.0)
bundler-audit (~> 0.9.0)
rubyzip (2.3.2)
selenium-webdriver (4.13.1)
rexml (~> 3.2, >= 3.2.5)
@@ -94,7 +125,9 @@ GEM
mini_portile2 (~> 2.8.0)
sys-uname (1.2.3)
ffi (~> 1.1)
thor (1.3.0)
tilt (2.3.0)
unicode-display_width (2.5.0)
webrick (1.8.1)
websocket (1.2.10)
xpath (3.2.0)
@@ -104,6 +137,7 @@ PLATFORMS
x86_64-freebsd-13
DEPENDENCIES
bundle-audit (~> 0.1.0)
capybara (~> 3.39)
cucumber (~> 9.0)
erubi (~> 1.12)
@@ -111,6 +145,8 @@ DEPENDENCIES
rackup (~> 2.1)
roda (~> 3.72)
rspec (~> 3.12)
rubocop
ruby_audit (~> 2.2)
selenium-webdriver (~> 4.13)
sequel (~> 5.72)
simplecov
Vendored
+57 -14
View File
@@ -1,49 +1,89 @@
pipeline {
agent any
agent { label 'ruby && freebsd' }
environment {
APP_SESSION_SECRET = ''
DB_NAME = 'url_shortener.db'
}
stages {
stage('Init') {
steps {
sh 'rbenv local 3.2.2'
script {
env.APP_SESSION_SECRET = sh(script: 'ruby secret.rb', returnStdout: true)
}
sh 'echo "ENV[\\\"APP_SESSION_SECRET\\\"] ||= $(ruby secret.rb)" > .env.rb'
sh 'echo "ENV[\\\"DB_NAME\\\"] ||= \\\"${DB_NAME}\\\"" >> .env.rb'
sh 'cat .env.rb'
sh ''' #!/usr/local/bin/bash
rbenv local 3.2.2
echo "# frozen_string_literal: true\n" > .env.rb
echo "ENV['APP_SESSION_SECRET'] ||= '$(ruby -rsecurerandom -e 'puts SecureRandom.base64(64)')'" >> .env.rb
echo "ENV['DB_NAME'] ||= '${DB_NAME}'" >> .env.rb
cat .env.rb
'''
}
}
stage('Build dependencies') {
steps {
sh 'bundle config set --local path "vendor"'
sh 'bundle install'
sh 'sequel -m db/migrations sqlite://db/${DB_NAME}'
}
}
stage('Audit Dependencies') {
steps {
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
sh 'bundle exec ruby-audit check'
sh 'bundle exec bundle-audit check >> audit.html'
}
}
}
stage('Code Linting') {
steps {
catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
sh 'bundle exec rubocop --format html --out rubocop.html'
}
}
}
stage('Run tests') {
steps {
catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
sh 'cucumber features --format html --out cucumber.html'
sh 'bundle exec cucumber features --format html --out cucumber.html'
}
catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
sh 'rspec spec --format html --out spec.html'
sh 'bundle exec rspec spec --format html --out spec.html'
}
}
}
stage('Report results') {
steps {
archive(includes: 'pkg/*.gem')
publishHTML (target: [
allowMissing: false,
alwaysLinkToLastBuild: false,
keepAll: true,
reportDir: '.',
reportFiles: 'cucumber.html, spec.html, coverage/index.html',
reportFiles: 'rubocop.html, audit.html, cucumber.html, spec.html, coverage/index.html',
reportName: 'Test Results',
reportTitles: 'Cucumber Results, RSpec Results, Test Coverage'])
reportTitles: 'Rubocop Results, Bundler Audit Results, Cucumber Results, RSpec Results, Test Coverage'])
}
}
stage('Build production deliverable') {
steps {
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
sh ''' #!/usr/local/bin/bash
ZIP_FILE="url-shortener_${BRANCH_NAME}_$(date "+%Y-%m-%d_%H-%M-%S").tgz"
CUR_DIR=$(pwd)
mkdir -p /tmp/url-shortener
cp -R * /tmp/url-shortener
cp .env.rb /tmp/url-shortener/
cp .ruby-version /tmp/url-shortener/
cd /tmp/url-shortener
rm -rf features spec coverage db/*.db .git* Jenkinsfile *.html .rubocop.yml
cd /tmp
tar -czvf $ZIP_FILE url-shortener/
mv /tmp/$ZIP_FILE $CUR_DIR/
'''
}
archiveArtifacts artifacts: '*.tgz'
}
}
stage('Clean up deliverable') {
steps {
sh 'rm -rf /tmp/url-shortener'
sh 'rm -rf *.tgz'
}
}
}
@@ -57,5 +97,8 @@ pipeline {
failure {
mattermostSend channel: 'git-messages', color: 'danger', message: "[${JOB_NAME}](${JOB_URL}) [#${BUILD_NUMBER}](${BUILD_URL}) ([Gitea](${GIT_URL}))", text: "Build Failed"
}
always {
cleanWs deleteDirs: true, patterns: [[pattern: '*', type: 'INCLUDE']]
}
}
}
+12 -8
View File
@@ -1,11 +1,11 @@
# simple url shortener
this project is a simple solution to build out a URL shortener using
Roda, Falcon, Sequel, and SQLite
Roda, Puma, Sequel, and SQLite on a FreeBSD Jail
the point of this project is to quickly build something and work on continuous deployment while making small refinements to the functional pieces.
the outside pieces of software that this project relies on are sqlite3 and pkgconf.
the outside pieces of software that this project relies on are rbenv, ruby-build, sqlite3, and pkgconf.
@@ -14,9 +14,9 @@ first you have to install the dependencies:
`bundle install`
if you want the development group included run this first:
if you want to skip the test dependencies:
`bundle config set --local with 'development'`
`bundle config set --local without 'test'`
then create a .env.rb file in the root directory that contains the following ENV attributes:
@@ -24,15 +24,19 @@ then create a .env.rb file in the root directory that contains the following ENV
```
ENV["APP_SESSION_SECRET"] = {output of a random 64 byte secret}
ENV["DB_NAME"] = {db file name}
ENV["DB_NAME"] = {DB_NAME}
```
after the dependencies are installed, you have to create the db
after the dependencies are installed, you have to create the db and schema
`sequel -m db/migrations sqlite://db/{DB_NAME}`
to start the application with Falcon:
to start the application with Puma:
`rackup -o {ip address} -p {port} -s falcon`
`rackup -o {ip address} -p {port}`
to run it as a daemon:
`rackup -o {ip address} -p {port} -D`
+34 -31
View File
@@ -1,9 +1,12 @@
# frozen_string_literal: true
require 'roda'
require 'securerandom'
require 'json'
require 'sequel'
require 'open-uri'
# URL Shortener App class
class App < Roda
plugin :sessions, secret: ENV.delete('APP_SESSION_SECRET')
plugin :render, escape: true
@@ -11,92 +14,92 @@ class App < Roda
plugin :json_parser
plugin :request_headers
DB = Sequel.sqlite("db/#{ENV['DB_NAME']}")
DB = Sequel.sqlite("db/#{ENV.fetch('DB_NAME', nil)}")
links = DB[:links]
route do |r|
r.root do
@message = flash['message'] || "Enter a URL"
@message = flash['message'] || 'Enter a URL'
view :home
end
r.get String do | url_code |
link = links.filter(:code => url_code)
r.get String do |url_code|
link = links.filter(code: url_code)
r.redirect link.first[:url] unless link.first.nil?
@message = "Link #{url_code} doesn't exist"
response.status = 404
view :home
end
r.post "create" do
r.post 'create' do
url = r.params['url']
if url.nil? or url.empty?
flash['message'] = "Please enter a valid URL";
if url.nil? || url.empty?
flash['message'] = 'Please enter a valid URL'
r.redirect '/'
end
begin
OpenURI.open_uri(url)
rescue URI::BadURIError
flash['message'] = "Invalid URL"
flash['message'] = 'Invalid URL'
r.redirect '/'
rescue OpenURI::HTTPError
flash['message'] = "URL not found"
flash['message'] = 'URL not found'
r.redirect '/'
rescue SocketError => e
flash['message'] = "URL does not resolve"
rescue SocketError
flash['message'] = 'URL does not resolve'
r.redirect '/'
end
if links.filter(:url => url).first.nil?
if links.filter(url:).first.nil?
code = SecureRandom.urlsafe_base64 4
links.insert(url: url, code: code)
@message = "Link created"
links.insert(url:, code:)
@message = 'Link created'
end
code = links.filter(:url => url).first[:code]
@message ||= "Link exists"
@new_link = 'http://' + request.env['HTTP_HOST'] + '/' + code
code = links.filter(url:).first[:code]
@message ||= 'Link exists'
@new_link = "http://#{request.env['HTTP_HOST']}/#{code}"
view :create
end
r.on "links" do
r.on 'links' do
r.post do
if 'application/json' != r.headers['CONTENT_TYPE']
if r.headers['CONTENT_TYPE'] != 'application/json'
response.status = 400
return {message: "not a valid json request"}.to_json
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
return { message: 'missing url parameter' }.to_json
end
if url.empty?
response.status = 400
return {message: "invalid url parameter"}.to_json
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
return { message: 'invalid url parameter' }.to_json
rescue OpenURI::HTTPError
response.status = 400
return {message: "url not found"}.to_json
rescue SocketError => e
return { message: 'url not found' }.to_json
rescue SocketError
response.status = 400
return {message: "url does not resolve"}.to_json
return { message: 'url does not resolve' }.to_json
end
if links.filter(:url => url).first.nil?
if links.filter(url:).first.nil?
code = SecureRandom.urlsafe_base64 4
links.insert(url: url, code: code)
links.insert(url:, 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
code = links.filter(url:).first[:code]
@new_link = "http://#{request.env['HTTP_HOST']}/#{code}"
return { url:, code:, link: @new_link }.to_json
end
end
end
+2
View File
@@ -1,3 +1,5 @@
# frozen_string_literal: true
require './.env'
require './app'
+2
View File
@@ -1,3 +1,5 @@
# frozen_string_literal: true
Sequel.migration do
change do
create_table :links do
+6 -8
View File
@@ -1,9 +1,10 @@
# frozen_string_literal: true
# BEFORE
Before('@db-test') do
@links = Sequel.sqlite("db/#{ENV['DB_NAME']}")[:links]
@links = Sequel.sqlite("db/#{ENV.fetch('DB_NAME', nil)}")[:links]
end
# GIVEN
Given('I visit the {string} page') do |string|
@@ -11,18 +12,17 @@ Given('I visit the {string} page') do |string|
end
Given('A link already exists with the url {string}') do |string|
@links.insert(url: string, code: "aaaaaa")
@links.insert(url: string, code: 'aaaaaa')
end
Given('A link already exists with the url {string} and code {string}') do |url, code|
@links.insert(url: url, code: code)
@links.insert(url:, code:)
end
# WHEN
When('I click the {string} button') do |string|
click_button {string}
click_button { string }
end
When('I type {string} in the {string} field') do |text, field|
@@ -33,7 +33,6 @@ When('I visit the {string} location') do |string|
visit string
end
# THEN
Then('I should see text {string}') do |string|
@@ -66,7 +65,6 @@ Then('The status code should be {int}') do |code|
page.status_code.should eq(code)
end
# AFTER
After('@db-test') do
+9 -7
View File
@@ -1,25 +1,27 @@
# frozen_string_literal: true
require 'simplecov'
SimpleCov.start
require_relative '../../.env'
ENV["DB_NAME"] = "test_#{ENV["DB_NAME"]}"
ENV['DB_NAME'] = "test_#{ENV.fetch('DB_NAME', nil)}"
require_relative '../../app'
require 'rubygems'
require 'roda'
require 'sequel'
require 'capybara'
require 'capybara/dsl'
require 'capybara/cucumber'
require 'rspec'
###
require 'rspec/expectations'
require 'rspec/matchers'
# DB initialization
Sequel.extension :migration
Sequel.sqlite("db/#{ENV['DB_NAME']}") do |db|
Sequel::Migrator.apply(db, "db/migrations")
Sequel.sqlite("db/#{ENV.fetch('DB_NAME', nil)}") do |db|
Sequel::Migrator.apply(db, 'db/migrations')
end
# attach app to Capybara
Capybara.app = App
include Capybara::DSL
include RSpec::Expectations
include RSpec::Matchers
-2
View File
@@ -1,2 +0,0 @@
require 'securerandom'
puts SecureRandom.base64(64).inspect()
+17 -15
View File
@@ -1,8 +1,10 @@
# frozen_string_literal: true
require 'simplecov'
SimpleCov.start
require_relative '../.env'
ENV["DB_NAME"] = "test_#{ENV["DB_NAME"]}"
ENV['DB_NAME'] = "test_#{ENV.fetch('DB_NAME', nil)}"
require_relative '../app'
require 'rubygems'
require 'roda'
@@ -12,27 +14,27 @@ require 'rack/test'
# DB initialization
Sequel.extension :migration
Sequel.sqlite("db/#{ENV['DB_NAME']}") do |db|
Sequel::Migrator.apply(db, "db/migrations")
Sequel.sqlite("db/#{ENV.fetch('DB_NAME', nil)}") do |db|
Sequel::Migrator.apply(db, 'db/migrations')
end
def app
App
end
describe "Submit API request to create new link" do
describe 'Submit API request to create new link' do
include Rack::Test::Methods
before :each do
@links = Sequel.sqlite("db/#{ENV['DB_NAME']}")[:links]
@links = Sequel.sqlite("db/#{ENV.fetch('DB_NAME', nil)}")[:links]
end
after :each do
@links.delete
end
it "should return link data in json format when a valid url is submitted" do
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")
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])
@@ -44,16 +46,15 @@ describe "Submit API request to create new link" do
data = {
url: ''
}
post('/links', data.to_json, "CONTENT_TYPE" => "application/json")
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")
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')
@@ -63,7 +64,7 @@ describe "Submit API request to create new link" do
data = {
url: 'not-an-url'
}
post('/links', data.to_json, "CONTENT_TYPE" => "application/json")
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')
@@ -73,7 +74,7 @@ describe "Submit API request to create new link" do
data = {
url: 'http://google.com/example'
}
post('/links', data.to_json, "CONTENT_TYPE" => "application/json")
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')
@@ -83,13 +84,14 @@ describe "Submit API request to create new link" do
data = {
url: 'http://bad.tld'
}
post('/links', data.to_json, "CONTENT_TYPE" => "application/json")
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
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'
}