sitehub 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.rspec +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +114 -0
- data/LICENSE +28 -0
- data/README.md +198 -0
- data/Rakefile +11 -0
- data/lib/sitehub.rb +9 -0
- data/lib/sitehub/builder.rb +82 -0
- data/lib/sitehub/collection.rb +35 -0
- data/lib/sitehub/collection/route_collection.rb +28 -0
- data/lib/sitehub/collection/split_route_collection.rb +50 -0
- data/lib/sitehub/collection/split_route_collection/split.rb +18 -0
- data/lib/sitehub/constants.rb +23 -0
- data/lib/sitehub/constants/http_header_keys.rb +25 -0
- data/lib/sitehub/constants/rack_http_header_keys.rb +17 -0
- data/lib/sitehub/cookie.rb +54 -0
- data/lib/sitehub/cookie/attribute.rb +22 -0
- data/lib/sitehub/cookie/flag.rb +22 -0
- data/lib/sitehub/cookie_rewriting.rb +35 -0
- data/lib/sitehub/forward_proxies.rb +50 -0
- data/lib/sitehub/forward_proxy.rb +67 -0
- data/lib/sitehub/forward_proxy_builder.rb +99 -0
- data/lib/sitehub/http_headers.rb +60 -0
- data/lib/sitehub/logging.rb +5 -0
- data/lib/sitehub/logging/access_logger.rb +74 -0
- data/lib/sitehub/logging/error_logger.rb +36 -0
- data/lib/sitehub/logging/log_entry.rb +14 -0
- data/lib/sitehub/logging/log_stash.rb +10 -0
- data/lib/sitehub/logging/log_wrapper.rb +23 -0
- data/lib/sitehub/middleware.rb +21 -0
- data/lib/sitehub/path_directive.rb +32 -0
- data/lib/sitehub/path_directives.rb +21 -0
- data/lib/sitehub/request_mapping.rb +43 -0
- data/lib/sitehub/resolver.rb +11 -0
- data/lib/sitehub/reverse_proxy.rb +53 -0
- data/lib/sitehub/rules.rb +13 -0
- data/lib/sitehub/string_sanitiser.rb +7 -0
- data/lib/sitehub/transaction_id.rb +16 -0
- data/lib/sitehub/version.rb +3 -0
- data/mem_usage.txt +1584 -0
- data/sitehub.gemspec +43 -0
- data/spec/basket_spec.rb +30 -0
- data/spec/sitehub/builder_spec.rb +203 -0
- data/spec/sitehub/collection/route_collection_spec.rb +91 -0
- data/spec/sitehub/collection/split_route_collection_spec.rb +111 -0
- data/spec/sitehub/collection_spec.rb +40 -0
- data/spec/sitehub/cookie/attribute_spec.rb +37 -0
- data/spec/sitehub/cookie/flag_spec.rb +27 -0
- data/spec/sitehub/cookie_rewriting_spec.rb +67 -0
- data/spec/sitehub/cookie_spec.rb +61 -0
- data/spec/sitehub/error_handling_spec.rb +21 -0
- data/spec/sitehub/forward_proxies_spec.rb +99 -0
- data/spec/sitehub/forward_proxy_builder_spec.rb +295 -0
- data/spec/sitehub/forward_proxy_spec.rb +138 -0
- data/spec/sitehub/http_headers_spec.rb +71 -0
- data/spec/sitehub/integration_spec.rb +21 -0
- data/spec/sitehub/logging/access_logger_spec.rb +127 -0
- data/spec/sitehub/logging/error_logger_spec.rb +80 -0
- data/spec/sitehub/logging/log_entry_spec.rb +34 -0
- data/spec/sitehub/logging/log_stash_spec.rb +21 -0
- data/spec/sitehub/logging/log_wrapper_spec.rb +33 -0
- data/spec/sitehub/middleware_spec.rb +69 -0
- data/spec/sitehub/path_directive_spec.rb +50 -0
- data/spec/sitehub/path_directives_spec.rb +45 -0
- data/spec/sitehub/request_mapping_spec.rb +71 -0
- data/spec/sitehub/resolver_spec.rb +15 -0
- data/spec/sitehub/reverse_proxy_spec.rb +105 -0
- data/spec/sitehub/transaction_id_spec.rb +28 -0
- data/spec/sitehub_spec.rb +19 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/patch/rack/response.rb +25 -0
- data/spec/support/shared_contexts/async_context.rb +69 -0
- data/spec/support/shared_contexts/middleware_context.rb +51 -0
- data/spec/support/shared_contexts/rack_test_context.rb +12 -0
- data/spec/support/shared_contexts/sitehub_context.rb +25 -0
- data/spec/support/silent_warnings.rb +5 -0
- metadata +359 -0
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'sitehub/forward_proxy'
|
2
|
+
|
3
|
+
class SiteHub
|
4
|
+
describe ForwardProxy do
|
5
|
+
|
6
|
+
let(:current_version_url) { 'http://does.not.exist.com' }
|
7
|
+
let(:mapped_path) { '/path' }
|
8
|
+
|
9
|
+
subject do
|
10
|
+
described_class.new(id: :id, url: current_version_url, mapped_path: mapped_path,sitehub_cookie_name: :cookie_name)
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:app) do
|
14
|
+
subject
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'includes Resolver' do
|
18
|
+
expect(subject).to be_a(Resolver)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'includes Rules' do
|
22
|
+
expect(subject).to be_a(Rules)
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#call' do
|
26
|
+
before do
|
27
|
+
WebMock.enable!
|
28
|
+
stub_request(:get, current_version_url).to_return(:body => 'body')
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'recorded routes cookie' do
|
32
|
+
it 'drops a cookie using the name of the sitehub_cookie_name containing the id' do
|
33
|
+
get(mapped_path, {})
|
34
|
+
expect(last_response.cookies[:cookie_name.to_s]).to eq(value: :id.to_s, path: subject.mapped_path)
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'recorded_routes_cookie_path not set' do
|
38
|
+
it 'sets the path to be the request path' do
|
39
|
+
get(mapped_path, {})
|
40
|
+
expect(last_response.cookies[:cookie_name.to_s][:path]).to eq(mapped_path)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'recorded_routes_cookie_path set' do
|
45
|
+
|
46
|
+
let(:expected_path){'/expected_path'}
|
47
|
+
|
48
|
+
subject do
|
49
|
+
described_class.new(id: :id,
|
50
|
+
url: current_version_url,
|
51
|
+
mapped_path: mapped_path,
|
52
|
+
sitehub_cookie_path: expected_path,
|
53
|
+
sitehub_cookie_name: :cookie_name)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'is set as the path' do
|
57
|
+
get(mapped_path, {})
|
58
|
+
expect(last_response.cookies[:cookie_name.to_s][:path]).to eq(expected_path)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
it 'passes request mapping information in to the environment hash' do
|
66
|
+
get(mapped_path, {})
|
67
|
+
expect(last_request.env[REQUEST_MAPPING]).to eq(RequestMapping.new(source_url: "http://example.org#{mapped_path}", mapped_url: current_version_url, mapped_path: mapped_path))
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'downstream call' do
|
71
|
+
context 'it fails' do
|
72
|
+
before do
|
73
|
+
WebMock.disable!
|
74
|
+
end
|
75
|
+
it 'adds an error to be logged' do
|
76
|
+
env = {ERRORS.to_s => []}
|
77
|
+
get(mapped_path, {}, env)
|
78
|
+
expect(last_request.env[ERRORS]).to eq(["unable to resolve server address"])
|
79
|
+
end
|
80
|
+
|
81
|
+
describe 'parameters to callback' do
|
82
|
+
it 'calls the callback with an error response' do
|
83
|
+
expect(described_class::ERROR_RESPONSE).to receive(:dup).and_return(described_class::ERROR_RESPONSE)
|
84
|
+
env = {ERRORS.to_s => []}
|
85
|
+
get(mapped_path, {}, env)
|
86
|
+
|
87
|
+
expect(last_response.body).to eq(described_class::ERROR_RESPONSE.body.join)
|
88
|
+
expect(last_response.headers).to eq(described_class::ERROR_RESPONSE.headers)
|
89
|
+
expect(last_response.status).to eq(described_class::ERROR_RESPONSE.status)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'passes the request mapping' do
|
93
|
+
env = { ERRORS.to_s => []}
|
94
|
+
get(mapped_path, {}, env)
|
95
|
+
expect(last_request.env[REQUEST_MAPPING]).to eq(RequestMapping.new(source_url: "http://example.org#{mapped_path}", mapped_url: current_version_url, mapped_path: mapped_path))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
it 'translates the header names back in to the http compatible names' do
|
102
|
+
get(mapped_path, {})
|
103
|
+
expect(last_response.headers).to include('Content-Length')
|
104
|
+
expect(last_response.headers).to_not include('CONTENT_LENGTH')
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'adding http_x_forwarded_host header' do
|
108
|
+
context 'when not present in the original request' do
|
109
|
+
it 'appends original request url with port' do
|
110
|
+
get(mapped_path, {})
|
111
|
+
assert_requested :get, current_version_url, headers: {'X-FORWARDED-HOST' => 'example.org:80'}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'when present in the original request' do
|
116
|
+
it 'appends original request url without port' do
|
117
|
+
get(mapped_path, {}, 'HTTP_X_FORWARDED_HOST' => 'staging.com')
|
118
|
+
assert_requested :get, current_version_url, headers: {'X-FORWARDED-HOST' => 'staging.com,staging.com'}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'preserves the body when forwarding request' do
|
123
|
+
body = {"key" => "value"}
|
124
|
+
stub_request(:put, current_version_url).with(:body => body)
|
125
|
+
|
126
|
+
put(mapped_path, body)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'preserves the headers when forwarding request' do
|
130
|
+
get(mapped_path, '', 'HTTP_HEADER' => 'value')
|
131
|
+
assert_requested :get, current_version_url, headers: {'Header' => 'value'}
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'sitehub/http_headers'
|
2
|
+
class SiteHub
|
3
|
+
describe HttpHeaders do
|
4
|
+
|
5
|
+
subject do
|
6
|
+
Object.new.tap do |o|
|
7
|
+
o.extend(described_class)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:headers_underscored) do
|
12
|
+
{'CONNECTION' => 'close',
|
13
|
+
'KEEP_ALIVE' => 'something',
|
14
|
+
'PROXY_AUTHENTICATE' => 'something',
|
15
|
+
'PROXY_AUTHORIZATION' => 'something',
|
16
|
+
'TE' => 'something',
|
17
|
+
'TRAILERS' => 'something',
|
18
|
+
'TRANSFER_ENCODING' => 'something',
|
19
|
+
'CONTENT_ENCODING' => 'something',
|
20
|
+
'PROXY_CONNECTION' => 'something'}
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:headers_hyphonised) do
|
24
|
+
Hash.new.tap do |hash|
|
25
|
+
headers_underscored.each do |key, value|
|
26
|
+
hash[key.gsub('_', '-')] = value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#sanitise_headers' do
|
32
|
+
|
33
|
+
context 'port 80 present in url' do
|
34
|
+
it 'removes the port' do
|
35
|
+
headers_hyphonised['location'] = 'http://mysite.com:80/redirect_endpoint'
|
36
|
+
expect(subject.sanitise_headers(headers_hyphonised)['location']).to eq('http://mysite.com/redirect_endpoint')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'port 443 present in url' do
|
41
|
+
it 'removes the port' do
|
42
|
+
headers_hyphonised['location'] = 'http://mysite.com:443/redirect_endpoint'
|
43
|
+
expect(subject.sanitise_headers(headers_hyphonised)['location']).to eq('http://mysite.com/redirect_endpoint')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'treatment of headers according to RFC2616: 13.5.1 and RFC2616: 14.10' do
|
48
|
+
context 'prohibitted headers hyphonised' do
|
49
|
+
it 'filters them out' do
|
50
|
+
sanatised_headers = subject.sanitise_headers(headers_hyphonised)
|
51
|
+
expect(sanatised_headers.empty?).to eq(true)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'prohibitted headers underscored' do
|
56
|
+
it 'filters them out' do
|
57
|
+
sanatised_headers = subject.sanitise_headers(headers_underscored)
|
58
|
+
expect(sanatised_headers.empty?).to eq(true)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'filters out connections' do
|
63
|
+
headers = subject.sanitise_headers('connection' => 'a, b', 'a' => 'value_a', 'b' => 'value_b', 'c' => 'value_c')
|
64
|
+
expect(headers).to eq('c' => 'value_c')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
describe 'proxying calls' do
|
2
|
+
include_context :site_hub
|
3
|
+
include_context :async
|
4
|
+
|
5
|
+
describe 'supported HTTP verbs' do
|
6
|
+
|
7
|
+
before do
|
8
|
+
WebMock.enable!
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:app){async_middleware.new(rack_application)}
|
12
|
+
|
13
|
+
%i(get post put delete).each do |verb|
|
14
|
+
it "forwards the downstream" do
|
15
|
+
stub_request(verb, downstream_url).to_return(:body => 'hello')
|
16
|
+
send(verb, '/endpoint')
|
17
|
+
expect(app.last_response.body).to eq(['hello'])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'sitehub/logging/access_logger'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
class SiteHub
|
5
|
+
module Logging
|
6
|
+
describe AccessLogger do
|
7
|
+
|
8
|
+
let(:logger) do
|
9
|
+
StringIO.new
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:app) do
|
13
|
+
proc{[200, {}, []]}
|
14
|
+
end
|
15
|
+
|
16
|
+
subject do
|
17
|
+
described_class.new(app, logger)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#initialize' do
|
21
|
+
|
22
|
+
context 'logger supplied' do
|
23
|
+
it 'sets logger to that logger' do
|
24
|
+
expect(described_class.new(:app, :custom_logger).logger).to eq(LogWrapper.new(:custom_logger))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'logger not supplied' do
|
29
|
+
it 'sets the logger to go to STDERR' do
|
30
|
+
expect(::Logger).to receive(:new).with(STDOUT).and_return(:logging)
|
31
|
+
expect(described_class.new(:app).logger).to eq(LogWrapper.new(:logging))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
#describe '#before_call' do
|
37
|
+
# it 'saves the time' do
|
38
|
+
# now = Time.now
|
39
|
+
# allow(Time).to receive(:now).and_return(now)
|
40
|
+
# subject.before_call(:env)
|
41
|
+
# expect(subject.start_time).to eq(now)
|
42
|
+
# end
|
43
|
+
#end
|
44
|
+
|
45
|
+
describe '#call' do
|
46
|
+
let(:env) do
|
47
|
+
{
|
48
|
+
REQUEST_MAPPING => request_mapping,
|
49
|
+
described_class::QUERY_STRING => '',
|
50
|
+
described_class::PATH_INFO => 'path_info',
|
51
|
+
Constants::RackHttpHeaderKeys::TRANSACTION_ID => :transaction_id
|
52
|
+
}
|
53
|
+
|
54
|
+
end
|
55
|
+
let(:request_mapping) { RequestMapping.new(source_url: :source_url, mapped_url: :mapped_url.to_s, mapped_path: :mapped_path.to_s) }
|
56
|
+
before { subject.call(env) }
|
57
|
+
|
58
|
+
let(:args) { {request_mapping: request_mapping, downstream_response: Rack::Response.new} }
|
59
|
+
it 'logs the request / response details in the required format' do
|
60
|
+
expect(subject).to receive(:log_template).and_return(:template.to_s)
|
61
|
+
expect(logger).to receive(:write).with(:template.to_s)
|
62
|
+
|
63
|
+
subject.call(env)
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'query string' do
|
67
|
+
let(:query_string) { described_class::QUERY_STRING }
|
68
|
+
context 'present' do
|
69
|
+
it 'logs it' do
|
70
|
+
env[query_string] = 'query'
|
71
|
+
subject.call(env)
|
72
|
+
expect(logger.string).to include("?query")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'not present' do
|
77
|
+
it 'is not logged' do
|
78
|
+
subject.call(env)
|
79
|
+
expect(logger.string).to_not include("?")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'logs the transaction id' do
|
85
|
+
subject.call(env)
|
86
|
+
|
87
|
+
expect(logger.string).to include("transaction_id:#{:transaction_id}")
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'logs the response status' do
|
91
|
+
subject.call(env)
|
92
|
+
|
93
|
+
expect(logger.string).to include(args[:downstream_response].status.to_s)
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
it 'logs the downstream url that was proxied to' do
|
98
|
+
subject.call(env)
|
99
|
+
|
100
|
+
expect(logger.string).to include("#{env[described_class::PATH_INFO]} => #{:mapped_url}")
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
describe '#extract_content_length' do
|
105
|
+
context 'content length header not present' do
|
106
|
+
it 'returns -' do
|
107
|
+
expect(subject.extract_content_length({})).to eq('-')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'content length header not present' do
|
112
|
+
let(:content_length) { described_class::CONTENT_LENGTH }
|
113
|
+
context 'it is 0' do
|
114
|
+
it 'returns -' do
|
115
|
+
expect(subject.extract_content_length({content_length => 0})).to eq('-')
|
116
|
+
end
|
117
|
+
end
|
118
|
+
context 'it is set to a number other than 0'
|
119
|
+
it 'returns the number' do
|
120
|
+
expect(subject.extract_content_length({content_length => 5})).to eq(5)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'sitehub/logging/error_logger'
|
2
|
+
|
3
|
+
class SiteHub
|
4
|
+
module Logging
|
5
|
+
describe ErrorLogger do
|
6
|
+
|
7
|
+
let(:app){ proc{[200, {}, []]}}
|
8
|
+
subject { described_class.new(app) }
|
9
|
+
|
10
|
+
describe '#initialize' do
|
11
|
+
context 'logger supplied' do
|
12
|
+
it 'sets logger to that logger' do
|
13
|
+
expect(described_class.new(:app, :custom_logger).logger).to eq(LogWrapper.new(:custom_logger))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'logger not supplied' do
|
18
|
+
it 'sets the logger to go to STDERR' do
|
19
|
+
expect(::Logger).to receive(:new).with(STDERR).and_return(:logging)
|
20
|
+
expect(described_class.new(:app).logger).to eq(LogWrapper.new(:logging))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#before_call' do
|
26
|
+
it 'adds a collection hold errors' do
|
27
|
+
env = {}
|
28
|
+
subject.call(env)
|
29
|
+
expect(env[ERRORS]).to eq([])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#call' do
|
34
|
+
let(:output) { StringIO.new }
|
35
|
+
let(:logger) { Logger.new(output) }
|
36
|
+
let(:error_message) { 'error' }
|
37
|
+
let(:errors) do
|
38
|
+
Logging::LogStash.new.tap do |stash|
|
39
|
+
stash << error_message
|
40
|
+
end
|
41
|
+
end
|
42
|
+
subject { described_class.new(app, logger) }
|
43
|
+
|
44
|
+
context 'errors have occurred' do
|
45
|
+
it 'logs errors' do
|
46
|
+
log_message = subject.log_message(error: error_message, transaction_id: :transaction_id)
|
47
|
+
subject.call({ERRORS => errors, Constants::RackHttpHeaderKeys::TRANSACTION_ID => :transaction_id})
|
48
|
+
expect(output.string).to eq(log_message)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'no errors have occured' do
|
53
|
+
it 'does not log anything' do
|
54
|
+
expect(logger).to_not receive(:write)
|
55
|
+
subject.call({ERRORS => []})
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#log_message' do
|
61
|
+
let(:error) { 'error' }
|
62
|
+
it 'contains the time and date' do
|
63
|
+
now = Time.now
|
64
|
+
expect(Time).to receive(:now).and_return(now)
|
65
|
+
expected_time = now.strftime("%d/%b/%Y:%H:%M:%S %z")
|
66
|
+
expect(subject.log_message(error: error, transaction_id: :transaction_id)).to start_with("[#{expected_time}]")
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'logs statements made against blah' do
|
70
|
+
|
71
|
+
expect(subject.log_message(error: error, transaction_id: :transaction_id)).to match(/ERROR: .* - ?#{error}$/)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'contains the transation id of the request' do
|
75
|
+
expect(subject.log_message(error: error, transaction_id: :transaction_id)).to include("ERROR: #{:transaction_id}")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'sitehub/logging/log_entry'
|
2
|
+
class SiteHub
|
3
|
+
module Logging
|
4
|
+
describe LogEntry do
|
5
|
+
describe '#initialize' do
|
6
|
+
|
7
|
+
let(:time){Time.now}
|
8
|
+
subject do
|
9
|
+
described_class.new(:message, time)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'sets the message' do
|
13
|
+
expect(subject.message).to be(:message)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'sets the time' do
|
17
|
+
expect(subject.time).to be(time)
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'time not supplied' do
|
21
|
+
subject do
|
22
|
+
described_class.new(:message)
|
23
|
+
end
|
24
|
+
it 'defaults the time' do
|
25
|
+
expect(Time).to receive(:now).and_return(:current_time)
|
26
|
+
expect(subject.time).to be(:current_time)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|