# frozen_string_literal: true
require 'soaspec'
require 'sinatra'
require 'sinatra/basic_auth'
require 'docdsl'
require 'nokogiri'
require 'erb'
require 'json'
require 'faker'
require 'soaspec/test_server/get_bank'
require 'soaspec/test_server/test_attribute'
require 'soaspec/test_server/puppy_service'
require 'soaspec/test_server/invoices'
require 'soaspec/test_server/test_namespace'
require 'soaspec/test_server/id_manager'
module Soaspec
# Used to run virtual web service on localhost. This makes tests more reliable and faster
# First argument overrides the default port
class VirtualServer < Sinatra::Application
set :bind, '0.0.0.0'
set :port, (ENV['port'] || 4999).to_i
register Sinatra::DocDsl
page do
title 'Soaspec Virtual Services'
header 'Perform efficient API testing with Ruby'
introduction 'This has some simple virtual services aimed at helping you with testing your Ruby API code.'
end
documentation 'Nothing under /. Go look at /docs' do
response 'redirects to the documentation page'
status 302
end
get '/' do
redirect '/docs'
end
doc_endpoint '/docs'
documentation 'Simulate server error' do
status 500
end
get '/server_error' do
[500, {}, 'Internal Server Error']
end
documentation 'Used to verify extract from text response' do
response 'Plain text with a pattern to match in it'
end
get '/text_response' do
'This is some text. In here it says ID=12345 to indicate value to obtain'
end
documentation 'Used to demonstrate a multi layered path' do
response 'Simple xml'
end
get '/this/is/a/long/path' do
'Text from drilling down to a long path'
end
documentation 'Used to demonstrate response that could be baselined' do
response 'JSON varying according to request params'
end
get '/baseline' do
JSON.pretty_generate(success: true, params: 'Empty')
end
get '/baseline/:sub1/:sub2' do
JSON.generate(success: true, params: params)
end
documentation 'Used to test attributes' do
response 'A simple Note XML with a date attribute'
end
get '/test_attribute' do
Soaspec::TestServer::TestAttribute.note
end
documentation 'Used to test namespaces' do
response 'XML with 2 namespaces and same elements inside it'
end
get '/namespace' do
Soaspec::TestServer::TestNamespace.food
end
documentation 'Used for showing a simple difference in value depending on the id used' do
param :num, 'Number of tester'
param :id, 'Test parameter'
response 'JSON with success or true or false and the id sent
Idea is for tester to find the id that causes a failure (the fake "defect")
'
end
get '/packages/:num/:id' do |num, id|
JSON.generate(success: Soaspec::TestServer::IdManager.result_for(num, id), id: id)
end
documentation 'Sets status as developed'
post '/packages/developed' do
Soaspec::TestServer::IdManager.developed = request.body.include?('true')
Soaspec::TestServer::IdManager.developed.to_s
end
documentation 'Sends back params received'
get '/echoer' do
params.to_s
end
# Used for simple testing of posing
documentation 'Simply sends the response body back'
post '/echoer' do
request.body
end
documentation "Simulate retrieving an ouath token Passed to '/invoices'"
post '/as/token.oauth2' do
Soaspec::TestServer::Invoices.user_used = request.env['rack.request.form_hash']['username']
[200, Soaspec::TestServer::Invoices.oauth_headers, JSON.generate(Soaspec::TestServer::Invoices.oauth_body)]
end
documentation 'Replies with HTTP authorization and user set in /as/token.oauth2'
get '/invoice/:id' do |id|
JSON.generate(customer_id: id, oauth: request.env['HTTP_AUTHORIZATION'], user: Soaspec::TestServer::Invoices.user_used)
end
documentation 'This is returned when a query for the WSDL is made' do
response 'WSDL containing SCHEMA information'
end
get '/BLZService' do
[200, { 'Content-Type' => 'text/xml' }, Soaspec::TestServer::GetBank.test_wsdl]
end
authorize do |username, password|
username == 'admin' && password == 'secret'
end
protect do
documentation "Get path used to test basic auth. User is 'admin' & password is 'secret'" do
response 'Secret text'
end
get '/basic_secrets' do
'Secret data'
end
documentation 'This is the basic service being hit by SOAP actions'
post '/BLZService' do
Soaspec::TestServer::GetBank.response_for request
end
end
documentation 'Used for testing storage of data' do
payload 'Puppy JSON',
Name: 'Test', Failure_Type__c: 'Fail'
end
post '/test/puppy' do
request_hash = JSON.parse(request.body.string)
id = Soaspec::TestServer::PuppyService.new_id
Soaspec::TestServer::PuppyService.data[id][:Name] = request_hash['Name']
Soaspec::TestServer::PuppyService.data[id][:Failure_Type__c] = request_hash['Failure_Type__c'] if request_hash['Failure_Type__c']
response_hash = { result: { Status: 'success', Data: Soaspec::TestServer::PuppyService.data[id] } }
JSON.generate response_hash
end
documentation 'Used for testing retrieving storage of data'
get '/test/puppy/:id' do |id|
result = Soaspec::TestServer::PuppyService.data[id.to_i]
JSON.generate result
end
documentation 'Used for testing updating data'
patch '/test/puppy/:id' do |id|
request_hash = JSON.parse(request.body.string)
Soaspec::TestServer::PuppyService.data[id.to_i][:Name] = request_hash['Name']
response_hash = { result: { Status: 'updated', With: request_hash['Name'] } }
JSON.generate response_hash
end
documentation 'Used for testing the handling of JSON path' do
response 'JSON with multiple elements of the same name at different nested levels'
end
get '/test/multiple_json' do
<<-BOOKS
{"store":
{"bicycle":
{"price":19.95, "color":"red"},
"book":[
{"price":8.95, "category":"reference", "title":"Sayings of the Century", "author":"Nigel Rees"},
{"price":12.99, "category":"fiction", "title":"Sword of Honour", "author":"Evelyn Waugh"},
{"price":8.99, "category":"fiction", "isbn":"0-553-21311-3", "title":"Moby Dick", "author":"Herman Melville","color":"blue"},
{"price":22.99, "category":"fiction", "isbn":"0-395-19395-8", "title":"The Lord of the Rings", "author":"Tolkien"}
]
}
}
BOOKS
end
documentation 'HTML doc that is not valid HTML'
get '/html_doc' do
<<~HTML
Heading
HTML
end
end
end