Compare commits

...

53 Commits

Author SHA1 Message Date
bucky 1822004460 use the hostname of the artifacts repository
Gitea Bucky/url-shortener/pipeline/head There was a failure building this commit
2023-12-19 07:58:59 -08:00
bucky b9345f9cb5 removed extra line
Gitea Bucky/url-shortener/pipeline/head This commit looks good
2023-12-18 20:19:55 -08:00
bucky 166c68570d v1.0.1
Gitea Bucky/url-shortener/pipeline/head There was a failure building this commit
2023-12-18 20:16:52 -08:00
bucky 28fc8b3b86 updated Gemfile with falcon instead of puma
Gitea Bucky/url-shortener/pipeline/head There was a failure building this commit
2023-12-18 20:15:33 -08:00
bucky 2c7a18c374 create the directory before syncingit
Gitea Bucky/url-shortener/pipeline/head This commit looks good
2023-12-18 18:38:18 -08:00
bucky 0a3f6c5fab try with ssh-agent
Gitea Bucky/url-shortener/pipeline/head There was a failure building this commit
2023-12-18 18:11:28 -08:00
bucky ca29051dc2 try to rsync with the user/key pair
Gitea Bucky/url-shortener/pipeline/head There was a failure building this commit
2023-12-18 17:50:42 -08:00
bucky 0b51b52b84 echo the file to see what's in there/how to handle it
Gitea Bucky/url-shortener/pipeline/head This commit looks good
2023-12-18 17:45:55 -08:00
bucky 4659942800 use user/key pair
Gitea Bucky/url-shortener/pipeline/head This commit looks good
2023-12-18 17:33:09 -08:00
bucky 6d0f594bba set file in the stage it is used in
Gitea Bucky/url-shortener/pipeline/head There was a failure building this commit
2023-12-18 17:15:30 -08:00
bucky 4ca73cc3ca use artifacts key
Gitea Bucky/url-shortener/pipeline/head There was a failure building this commit
2023-12-18 16:59:52 -08:00
bucky 1f96facbf2 use the ZIP FILE variable not ZIP_FILE text
Gitea Bucky/url-shortener/pipeline/head There was a failure building this commit
2023-12-18 15:57:02 -08:00
bucky e362cef9ba added SHA256 and sync both the sig and the zip
Gitea Bucky/url-shortener/pipeline/head There was a failure building this commit
2023-12-18 15:51:41 -08:00
bucky 25d94bbfc2 attempt to use rsync to sync data to artifact repo jail
Gitea Bucky/url-shortener/pipeline/head There was a failure building this commit
2023-12-18 13:09:52 -08:00
bucky 40e3703650 get the actual version, not the line
Gitea Bucky/url-shortener/pipeline/head This commit looks good
2023-10-24 18:11:12 -07:00
bucky 21eeb9db72 use version instead of date
Gitea Bucky/url-shortener/pipeline/head There was a failure building this commit
2023-10-24 18:01:15 -07:00
bucky 2cbe5f85b0 moved bundle-audit inside test group, added version file 2023-10-24 17:53:56 -07:00
bucky b62d45d0d8 Merge pull request 'prod-artifact-when-good' (#34) from prod-artifact-when-good into master
Gitea Bucky/url-shortener/pipeline/head This commit looks good
Reviewed-on: #34
2023-10-23 15:54:27 -07:00
bucky 0dc792b0bf added try catch wrappers around other parts. if they fail, don't build
Gitea Bucky/url-shortener/pipeline/head This commit looks good
the deliverable
2023-10-23 15:48:42 -07:00
bucky 5f4209dbe8 testing skipping building the artifact at the end (and cleanup of it)
Gitea Bucky/url-shortener/pipeline/head This commit looks good
2023-10-23 15:10:16 -07:00
bucky fbba67a9bd install, not clean, since it changed the bundle location
Gitea Bucky/url-shortener/pipeline/head This commit looks good
2023-10-23 15:05:20 -07:00
bucky 5cd296cb70 when is outside the steps
Gitea Bucky/url-shortener/pipeline/head There was a failure building this commit
2023-10-23 15:03:45 -07:00
bucky 7c0f6eb603 limit building deployment artifact
Gitea Bucky/url-shortener/pipeline/head There was a failure building this commit
+ added buildArtifact variable and set it to true
+ in auditing stage, if there's an error, set buildArtifact to false
+ in build artifact stage, if buildArtifact is true, build  it
2023-10-23 14:58:02 -07:00
bucky de3dcc48ab removed the when, and removed unnecessary rm command
Gitea Bucky/url-shortener/pipeline/head There was a failure building this commit
2023-10-23 12:31:29 -07:00
bucky 958091e000 see if we can access the buildResult status to use it 2023-10-23 11:32:02 -07:00
bucky 35583e404e move the local path in the build prod artifact stage to make the tests
quicker
2023-10-23 07:43:30 -07:00
bucky 0e9342fab6 only build the production environment when the previous steps all executed successfully 2023-10-23 07:41:52 -07:00
bucky ca4182d798 Merge pull request 'added bundle config to only use prod gems and bundle clean to remove unnecessary gems from the current poject' (#33) from build-deployment-artifact into master
Reviewed-on: #33

closes bucky/url-shortener#32
2023-10-23 07:31:15 -07:00
bucky 7d04c46728 added bundle config to only use prod gems and bundle clean to remove unnecessary gems from the current poject 2023-10-23 07:18:31 -07:00
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
11 changed files with 290 additions and 92 deletions
+6
View File
@@ -0,0 +1,6 @@
AllCops:
NewCops: enable
SuggestExtensions: false
Metrics/BlockLength:
AllowedMethods: ['describe', 'context', 'route', 'r.on', 'r.post']
+18 -15
View File
@@ -1,32 +1,35 @@
# frozen_string_literal: true
source "https://rubygems.org"
source 'https://rubygems.org'
gem 'rackup', '~> 2.1'
gem "roda", "~> 3.72"
gem 'falcon', '~> 0.42.3'
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'
gem 'bundle-audit', '~> 0.1.0'
end
gem "puma", "~> 6.4"
gem "rackup", "~> 2.1"
+100 -4
View File
@@ -3,8 +3,38 @@ GEM
specs:
addressable (2.8.5)
public_suffix (>= 2.0.2, < 6.0)
ast (2.4.2)
async (2.6.5)
console (~> 1.10)
fiber-annotation
io-event (~> 1.1)
timers (~> 4.1)
async-container (0.16.12)
async
async-io
async-http (0.61.0)
async (>= 1.25)
async-io (>= 1.28)
async-pool (>= 0.2)
protocol-http (~> 0.25.0)
protocol-http1 (~> 0.16.0)
protocol-http2 (~> 0.15.0)
traces (>= 0.10.0)
async-http-cache (0.4.3)
async-http (~> 0.56)
async-io (1.37.0)
async
async-pool (0.4.0)
async (>= 1.25)
base64 (0.1.1)
bigdecimal (3.1.4)
build-environment (1.13.0)
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
@@ -14,6 +44,9 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
console (1.23.2)
fiber-annotation
fiber-local
cucumber (9.0.2)
builder (~> 3.2, >= 3.2.4)
cucumber-ci-environment (~> 9.2, >= 9.2.0)
@@ -41,18 +74,53 @@ GEM
diff-lcs (1.5.0)
docile (1.4.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)
fiber-annotation (0.2.0)
fiber-local (1.0.0)
io-event (1.3.3)
json (2.6.3)
language_server-protocol (3.17.0.3)
localhost (1.1.10)
mapping (1.1.1)
matrix (0.4.2)
mini_mime (1.1.5)
mini_portile2 (2.8.4)
multi_test (1.1.0)
nio4r (2.5.9)
nokogiri (1.15.4)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
openssl (3.2.0)
parallel (1.23.0)
parser (3.2.2.4)
ast (~> 2.4.1)
racc
process-metrics (0.2.1)
console (~> 1.8)
samovar (~> 2.1)
protocol-hpack (1.4.2)
protocol-http (0.25.0)
protocol-http1 (0.16.0)
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)
puma (6.4.0)
nio4r (~> 2.0)
racc (1.7.1)
rack (3.0.8)
rack-test (2.1.0)
@@ -60,6 +128,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,7 +146,27 @@ 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)
samovar (2.2.0)
console (~> 1.0)
mapping (~> 1.0)
selenium-webdriver (4.13.1)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
@@ -94,7 +183,11 @@ GEM
mini_portile2 (~> 2.8.0)
sys-uname (1.2.3)
ffi (~> 1.1)
thor (1.3.0)
tilt (2.3.0)
timers (4.3.5)
traces (0.11.1)
unicode-display_width (2.5.0)
webrick (1.8.1)
websocket (1.2.10)
xpath (3.2.0)
@@ -104,13 +197,16 @@ PLATFORMS
x86_64-freebsd-13
DEPENDENCIES
bundle-audit (~> 0.1.0)
capybara (~> 3.39)
cucumber (~> 9.0)
erubi (~> 1.12)
puma (~> 6.4)
falcon (~> 0.42.3)
rackup (~> 2.1)
roda (~> 3.72)
rspec (~> 3.12)
rubocop
ruby_audit (~> 2.2)
selenium-webdriver (~> 4.13)
sequel (~> 5.72)
simplecov
Vendored
+92 -9
View File
@@ -1,3 +1,5 @@
def buildArtifact = true
pipeline {
agent { label 'ruby && freebsd' }
@@ -9,8 +11,10 @@ pipeline {
steps {
sh ''' #!/usr/local/bin/bash
rbenv local 3.2.2
echo "ENV[\\\"APP_SESSION_SECRET\\\"] ||= $(ruby -rsecurerandom -e 'puts SecureRandom.base64(64).inspect()')" > .env.rb
echo "ENV[\\\"DB_NAME\\\"] ||= \\\"${DB_NAME}\\\"" >> .env.rb
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
'''
}
}
@@ -20,13 +24,60 @@ pipeline {
sh 'sequel -m db/migrations sqlite://db/${DB_NAME}'
}
}
stage('Audit Dependencies') {
steps {
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
script {
try {
sh 'bundle exec ruby-audit check'
sh 'bundle exec bundle-audit check >> audit.html'
} catch (e) {
script {
buildArtifact = false
}
}
}
}
}
}
stage('Code Linting') {
steps {
catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
script {
try {
sh 'bundle exec rubocop --format html --out rubocop.html'
} catch (e) {
script {
buildArtifact = false
}
}
}
}
}
}
stage('Run tests') {
steps {
catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
sh 'cucumber features --format html --out cucumber.html'
script {
try {
sh 'bundle exec cucumber features --format html --out cucumber.html'
} catch (e) {
script {
buildArtifact = false
}
}
}
}
catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
sh 'rspec spec --format html --out spec.html'
script {
try {
sh 'bundle exec rspec spec --format html --out spec.html'
} catch (e) {
script {
buildArtifact = false
}
}
}
}
}
}
@@ -37,23 +88,31 @@ pipeline {
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') {
when {
expression {
buildArtifact
}
}
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"
ZIP_FILE="url-shortener_${BRANCH_NAME}_$(cat VERSION | cut -d"'" -f2).tgz"
CUR_DIR=$(pwd)
bundle config set --local without 'test'
bundle config set --local path "vendor"
bundle install
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
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/
@@ -62,10 +121,34 @@ pipeline {
archiveArtifacts artifacts: '*.tgz'
}
}
stage('Generate SHA256 Hash and Upload to Artifact Repository') {
environment {
ARTIFACTS_KEY = credentials('artifactor-key')
}
steps {
sshagent(['artifactor-key']) {
sh ''' #!/usr/local/bin/bash
UUID=$(uuidgen -r)
VERSION=$(cat VERSION | cut -d"'" -f2)
BRANCH=${BRANCH_NAME}
ZIP_FILE="url-shortener_${BRANCH_NAME}_$(cat VERSION | cut -d"'" -f2).tgz"
sha256 $ZIP_FILE >> SHA256.sig
ssh artifactor@artifacts mkdir -p projects/url-shortener/$BRANCH/$VERSION/$UUID
rsync SHA256.sig artifactor@artifacts:projects/url-shortener/$BRANCH/$VERSION/$UUID/
rsync $ZIP_FILE artifactor@artifacts:projects/url-shortener/$BRANCH/$VERSION/$UUID/
'''
}
}
}
stage('Clean up deliverable') {
when {
expression {
buildArtifact
}
}
steps {
sh 'rm -rf /tmp/url-shortener'
sh 'rm -rf *.tgz'
sh 'rm SHA256.sig'
}
}
}
+1
View File
@@ -0,0 +1 @@
VERSION = '1.0.1'
+36 -33
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
view :create
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?
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
+18 -16
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,48 +14,47 @@ 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])
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")
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'
}