hoodoo 1.0.2
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/bin/hoodoo +5 -0
- data/lib/hoodoo.rb +27 -0
- data/lib/hoodoo/active.rb +32 -0
- data/lib/hoodoo/active/active_model/uuid_validator.rb +45 -0
- data/lib/hoodoo/active/active_record/base.rb +81 -0
- data/lib/hoodoo/active/active_record/creator.rb +134 -0
- data/lib/hoodoo/active/active_record/dated.rb +343 -0
- data/lib/hoodoo/active/active_record/error_mapping.rb +351 -0
- data/lib/hoodoo/active/active_record/finder.rb +606 -0
- data/lib/hoodoo/active/active_record/search_helper.rb +189 -0
- data/lib/hoodoo/active/active_record/secure.rb +431 -0
- data/lib/hoodoo/active/active_record/support.rb +106 -0
- data/lib/hoodoo/active/active_record/translated.rb +87 -0
- data/lib/hoodoo/active/active_record/uuid.rb +80 -0
- data/lib/hoodoo/active/active_record/writer.rb +321 -0
- data/lib/hoodoo/client.rb +23 -0
- data/lib/hoodoo/client/augmented_array.rb +29 -0
- data/lib/hoodoo/client/augmented_base.rb +168 -0
- data/lib/hoodoo/client/augmented_hash.rb +23 -0
- data/lib/hoodoo/client/client.rb +354 -0
- data/lib/hoodoo/client/endpoint/endpoint.rb +427 -0
- data/lib/hoodoo/client/endpoint/endpoints/amqp.rb +180 -0
- data/lib/hoodoo/client/endpoint/endpoints/auto_session.rb +194 -0
- data/lib/hoodoo/client/endpoint/endpoints/http.rb +203 -0
- data/lib/hoodoo/client/endpoint/endpoints/http_based.rb +367 -0
- data/lib/hoodoo/client/endpoint/endpoints/not_found.rb +59 -0
- data/lib/hoodoo/client/headers.rb +269 -0
- data/lib/hoodoo/communicators.rb +23 -0
- data/lib/hoodoo/communicators/fast.rb +44 -0
- data/lib/hoodoo/communicators/pool.rb +601 -0
- data/lib/hoodoo/communicators/slow.rb +84 -0
- data/lib/hoodoo/data.rb +51 -0
- data/lib/hoodoo/data/resources/caller.rb +39 -0
- data/lib/hoodoo/data/resources/errors.rb +28 -0
- data/lib/hoodoo/data/resources/log.rb +31 -0
- data/lib/hoodoo/data/resources/session.rb +26 -0
- data/lib/hoodoo/data/types/error_primitive.rb +27 -0
- data/lib/hoodoo/data/types/permissions.rb +40 -0
- data/lib/hoodoo/data/types/permissions_defaults.rb +32 -0
- data/lib/hoodoo/data/types/permissions_full.rb +28 -0
- data/lib/hoodoo/data/types/permissions_resources.rb +31 -0
- data/lib/hoodoo/discovery.rb +20 -0
- data/lib/hoodoo/errors.rb +19 -0
- data/lib/hoodoo/errors/error_descriptions.rb +229 -0
- data/lib/hoodoo/errors/errors.rb +322 -0
- data/lib/hoodoo/generator.rb +139 -0
- data/lib/hoodoo/logger.rb +23 -0
- data/lib/hoodoo/logger/fast_writer.rb +27 -0
- data/lib/hoodoo/logger/flattener_mixin.rb +36 -0
- data/lib/hoodoo/logger/logger.rb +387 -0
- data/lib/hoodoo/logger/slow_writer.rb +49 -0
- data/lib/hoodoo/logger/writer_mixin.rb +52 -0
- data/lib/hoodoo/logger/writers/file_writer.rb +45 -0
- data/lib/hoodoo/logger/writers/log_entries_dot_com_writer.rb +64 -0
- data/lib/hoodoo/logger/writers/stream_writer.rb +43 -0
- data/lib/hoodoo/middleware.rb +33 -0
- data/lib/hoodoo/presenters.rb +45 -0
- data/lib/hoodoo/presenters/base.rb +281 -0
- data/lib/hoodoo/presenters/base_dsl.rb +519 -0
- data/lib/hoodoo/presenters/common_resource_fields.rb +31 -0
- data/lib/hoodoo/presenters/embedding.rb +232 -0
- data/lib/hoodoo/presenters/types/array.rb +118 -0
- data/lib/hoodoo/presenters/types/boolean.rb +26 -0
- data/lib/hoodoo/presenters/types/date.rb +26 -0
- data/lib/hoodoo/presenters/types/date_time.rb +26 -0
- data/lib/hoodoo/presenters/types/decimal.rb +47 -0
- data/lib/hoodoo/presenters/types/enum.rb +55 -0
- data/lib/hoodoo/presenters/types/field.rb +158 -0
- data/lib/hoodoo/presenters/types/float.rb +26 -0
- data/lib/hoodoo/presenters/types/hash.rb +361 -0
- data/lib/hoodoo/presenters/types/integer.rb +26 -0
- data/lib/hoodoo/presenters/types/object.rb +117 -0
- data/lib/hoodoo/presenters/types/string.rb +53 -0
- data/lib/hoodoo/presenters/types/tags.rb +24 -0
- data/lib/hoodoo/presenters/types/text.rb +26 -0
- data/lib/hoodoo/presenters/types/uuid.rb +54 -0
- data/lib/hoodoo/services.rb +34 -0
- data/lib/hoodoo/services/discovery/discoverers/by_consul.rb +66 -0
- data/lib/hoodoo/services/discovery/discoverers/by_convention.rb +173 -0
- data/lib/hoodoo/services/discovery/discoverers/by_drb/by_drb.rb +195 -0
- data/lib/hoodoo/services/discovery/discoverers/by_drb/drb_server.rb +166 -0
- data/lib/hoodoo/services/discovery/discoverers/by_drb/drb_server_start.rb +37 -0
- data/lib/hoodoo/services/discovery/discovery.rb +186 -0
- data/lib/hoodoo/services/discovery/results/for_amqp.rb +58 -0
- data/lib/hoodoo/services/discovery/results/for_http.rb +85 -0
- data/lib/hoodoo/services/discovery/results/for_local.rb +85 -0
- data/lib/hoodoo/services/discovery/results/for_remote.rb +57 -0
- data/lib/hoodoo/services/middleware/amqp_log_message.rb +186 -0
- data/lib/hoodoo/services/middleware/amqp_log_writer.rb +119 -0
- data/lib/hoodoo/services/middleware/endpoints/inter_resource_local.rb +130 -0
- data/lib/hoodoo/services/middleware/endpoints/inter_resource_remote.rb +202 -0
- data/lib/hoodoo/services/middleware/exception_reporting/base_reporter.rb +105 -0
- data/lib/hoodoo/services/middleware/exception_reporting/exception_reporting.rb +115 -0
- data/lib/hoodoo/services/middleware/exception_reporting/reporters/airbrake_reporter.rb +64 -0
- data/lib/hoodoo/services/middleware/exception_reporting/reporters/raygun_reporter.rb +63 -0
- data/lib/hoodoo/services/middleware/interaction.rb +127 -0
- data/lib/hoodoo/services/middleware/middleware.rb +2705 -0
- data/lib/hoodoo/services/middleware/rack_monkey_patch.rb +73 -0
- data/lib/hoodoo/services/services/context.rb +153 -0
- data/lib/hoodoo/services/services/implementation.rb +132 -0
- data/lib/hoodoo/services/services/interface.rb +934 -0
- data/lib/hoodoo/services/services/permissions.rb +250 -0
- data/lib/hoodoo/services/services/request.rb +189 -0
- data/lib/hoodoo/services/services/response.rb +316 -0
- data/lib/hoodoo/services/services/service.rb +141 -0
- data/lib/hoodoo/services/services/session.rb +729 -0
- data/lib/hoodoo/utilities.rb +12 -0
- data/lib/hoodoo/utilities/string_inquirer.rb +54 -0
- data/lib/hoodoo/utilities/utilities.rb +380 -0
- data/lib/hoodoo/utilities/uuid.rb +44 -0
- data/lib/hoodoo/version.rb +17 -0
- data/spec/active/active_record/base_spec.rb +57 -0
- data/spec/active/active_record/creator_spec.rb +88 -0
- data/spec/active/active_record/dated_spec.rb +248 -0
- data/spec/active/active_record/error_mapping_spec.rb +360 -0
- data/spec/active/active_record/finder_spec.rb +744 -0
- data/spec/active/active_record/search_helper_spec.rb +384 -0
- data/spec/active/active_record/secure_spec.rb +435 -0
- data/spec/active/active_record/support_spec.rb +225 -0
- data/spec/active/active_record/translated_spec.rb +19 -0
- data/spec/active/active_record/uuid_spec.rb +72 -0
- data/spec/active/active_record/writer_spec.rb +272 -0
- data/spec/alchemy/alchemy-amq.rb +33 -0
- data/spec/client/augmented_array_spec.rb +15 -0
- data/spec/client/augmented_base_spec.rb +50 -0
- data/spec/client/augmented_hash_spec.rb +15 -0
- data/spec/client/client_spec.rb +955 -0
- data/spec/client/endpoint/endpoint_spec.rb +70 -0
- data/spec/client/endpoint/endpoints/amqp_spec.rb +16 -0
- data/spec/client/endpoint/endpoints/auto_session_spec.rb +9 -0
- data/spec/client/endpoint/endpoints/http_based_spec.rb +9 -0
- data/spec/client/endpoint/endpoints/http_spec.rb +103 -0
- data/spec/client/endpoint/endpoints/not_found_spec.rb +35 -0
- data/spec/client/headers_spec.rb +172 -0
- data/spec/communicators/fast_spec.rb +9 -0
- data/spec/communicators/pool_spec.rb +339 -0
- data/spec/communicators/slow_spec.rb +15 -0
- data/spec/data/resources/caller_spec.rb +156 -0
- data/spec/data/resources/errors_spec.rb +22 -0
- data/spec/data/resources/log_spec.rb +20 -0
- data/spec/data/resources/session_spec.rb +15 -0
- data/spec/data/types/error_primitive_spec.rb +15 -0
- data/spec/data/types/permissions_defaults_spec.rb +25 -0
- data/spec/data/types/permissions_full_spec.rb +44 -0
- data/spec/data/types/permissions_resources_spec.rb +34 -0
- data/spec/data/types/permissions_spec.rb +37 -0
- data/spec/errors/error_descriptions_spec.rb +98 -0
- data/spec/errors/errors_spec.rb +346 -0
- data/spec/integration/service_actions_spec.rb +112 -0
- data/spec/logger/fast_writer_spec.rb +18 -0
- data/spec/logger/logger_spec.rb +259 -0
- data/spec/logger/slow_writer_spec.rb +144 -0
- data/spec/logger/writers/file_writer_spec.rb +37 -0
- data/spec/logger/writers/log_entries_dot_com_writer_spec.rb +29 -0
- data/spec/logger/writers/stream_writer_spec.rb +38 -0
- data/spec/presenters/base_dsl_spec.rb +111 -0
- data/spec/presenters/base_spec.rb +871 -0
- data/spec/presenters/common_resource_fields_spec.rb +30 -0
- data/spec/presenters/embedding_spec.rb +87 -0
- data/spec/presenters/types/array_spec.rb +249 -0
- data/spec/presenters/types/boolean_spec.rb +51 -0
- data/spec/presenters/types/date_spec.rb +57 -0
- data/spec/presenters/types/date_time_spec.rb +59 -0
- data/spec/presenters/types/decimal_spec.rb +58 -0
- data/spec/presenters/types/enum_spec.rb +71 -0
- data/spec/presenters/types/field_spec.rb +77 -0
- data/spec/presenters/types/float_spec.rb +50 -0
- data/spec/presenters/types/hash_spec.rb +1069 -0
- data/spec/presenters/types/integer_spec.rb +50 -0
- data/spec/presenters/types/object_spec.rb +177 -0
- data/spec/presenters/types/string_spec.rb +65 -0
- data/spec/presenters/types/tags_spec.rb +56 -0
- data/spec/presenters/types/text_spec.rb +50 -0
- data/spec/presenters/types/uuid_spec.rb +46 -0
- data/spec/presenters/walk_spec.rb +198 -0
- data/spec/services/discovery/discoverers/by_consul_spec.rb +29 -0
- data/spec/services/discovery/discoverers/by_convention_spec.rb +67 -0
- data/spec/services/discovery/discoverers/by_drb/by_drb_spec.rb +80 -0
- data/spec/services/discovery/discoverers/by_drb/drb_server_spec.rb +205 -0
- data/spec/services/discovery/discovery_spec.rb +73 -0
- data/spec/services/discovery/results/for_amqp_spec.rb +17 -0
- data/spec/services/discovery/results/for_http_spec.rb +37 -0
- data/spec/services/discovery/results/for_local_spec.rb +21 -0
- data/spec/services/discovery/results/for_remote_spec.rb +15 -0
- data/spec/services/middleware/amqp_log_message_spec.rb +60 -0
- data/spec/services/middleware/amqp_log_writer_spec.rb +95 -0
- data/spec/services/middleware/endpoints/inter_resource_local_spec.rb +9 -0
- data/spec/services/middleware/endpoints/inter_resource_remote_spec.rb +9 -0
- data/spec/services/middleware/exception_reporting/base_reporter_spec.rb +16 -0
- data/spec/services/middleware/exception_reporting/exception_reporting_spec.rb +92 -0
- data/spec/services/middleware/exception_reporting/reporters/airbrake_reporter_spec.rb +24 -0
- data/spec/services/middleware/exception_reporting/reporters/raygun_reporter_spec.rb +23 -0
- data/spec/services/middleware/middleware_cors_spec.rb +93 -0
- data/spec/services/middleware/middleware_create_update_spec.rb +489 -0
- data/spec/services/middleware/middleware_dated_at_spec.rb +186 -0
- data/spec/services/middleware/middleware_exotic_communication_spec.rb +560 -0
- data/spec/services/middleware/middleware_logging_spec.rb +356 -0
- data/spec/services/middleware/middleware_multi_local_spec.rb +1094 -0
- data/spec/services/middleware/middleware_multi_remote_spec.rb +1440 -0
- data/spec/services/middleware/middleware_permissions_spec.rb +1014 -0
- data/spec/services/middleware/middleware_public_spec.rb +238 -0
- data/spec/services/middleware/middleware_spec.rb +1569 -0
- data/spec/services/middleware/string_inquirer_spec.rb +30 -0
- data/spec/services/services/application_spec.rb +74 -0
- data/spec/services/services/context_spec.rb +48 -0
- data/spec/services/services/implementation_spec.rb +45 -0
- data/spec/services/services/interface_spec.rb +262 -0
- data/spec/services/services/permissions_spec.rb +249 -0
- data/spec/services/services/request_spec.rb +95 -0
- data/spec/services/services/response_spec.rb +250 -0
- data/spec/services/services/session_spec.rb +432 -0
- data/spec/spec_helper.rb +298 -0
- data/spec/utilities/utilities_spec.rb +537 -0
- data/spec/utilities/uuid_spec.rb +20 -0
- metadata +615 -0
@@ -0,0 +1,346 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hoodoo::Errors do
|
4
|
+
before do
|
5
|
+
@desc = Hoodoo::ErrorDescriptions.new( :test_domain ) do
|
6
|
+
error 'http_345_no_references', status: 345, 'message' => '345 message'
|
7
|
+
error 'http_456_has_reference', status: 456, 'message' => '456 message', 'reference' => [ :ref1 ]
|
8
|
+
error 'http_567_has_references', status: 567, 'message' => '567 message', 'reference' => [ :ref2, :ref3, :ref4 ]
|
9
|
+
end
|
10
|
+
|
11
|
+
@errors = Hoodoo::Errors.new(@desc)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#initialize' do
|
15
|
+
it 'should have correct descriptions' do
|
16
|
+
|
17
|
+
# Read the ivars to compare objects. The "@descriptions" variable in an
|
18
|
+
# ErrorDescriptions instance gives its descriptions hash. The same-named
|
19
|
+
# variable in the Errors instance gives the ErrorDescriptions instances,
|
20
|
+
# so the chained "instance_variable_get" call in the second and third
|
21
|
+
# test is correct.
|
22
|
+
|
23
|
+
expect(Hoodoo::Errors::DEFAULT_ERROR_DESCRIPTIONS.instance_variable_get('@descriptions')).to eq(Hoodoo::ErrorDescriptions.new().instance_variable_get('@descriptions'))
|
24
|
+
expect(Hoodoo::Errors.new().instance_variable_get('@descriptions').instance_variable_get('@descriptions')).to eq(Hoodoo::ErrorDescriptions.new().instance_variable_get('@descriptions'))
|
25
|
+
expect(@errors.instance_variable_get('@descriptions').instance_variable_get('@descriptions')).to eq(@desc.instance_variable_get('@descriptions'))
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should have a UUID, empty errors and a 200 code' do
|
29
|
+
expect(@errors.uuid.size).to eq(32)
|
30
|
+
expect(@errors.errors).to be_empty
|
31
|
+
expect(@errors.http_status_code).to eq(200)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should inspect elegantly' do
|
35
|
+
@errors.add_error('platform.malformed')
|
36
|
+
expect(@errors.inspect).to eq( '[{"code"=>"platform.malformed", "message"=>"Malformed request"}]' )
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#add_error, #has_errors?' do
|
41
|
+
it 'should let me add a generic error and tell me it was added' do
|
42
|
+
expect(@errors.has_errors?).to eq(false)
|
43
|
+
@errors.add_error('platform.malformed')
|
44
|
+
expect(@errors.has_errors?).to eq(true)
|
45
|
+
expect(@errors.errors).to_not be_empty
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should complain about unknown error codes' do
|
49
|
+
expect {
|
50
|
+
@errors.add_error('imaginary')
|
51
|
+
}.to raise_error(Hoodoo::Errors::UnknownCode, "In \#add_error: Unknown error code 'imaginary'")
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should let me add simple custom errors' do
|
55
|
+
expect {
|
56
|
+
@errors.add_error('test_domain.http_345_no_references')
|
57
|
+
@errors.add_error('test_domain.http_345_no_references', 'message' => 'foo 1')
|
58
|
+
@errors.add_error('test_domain.http_345_no_references', 'message' => 'foo 2', 'reference' => { :bar => 'baz', :baz => 'foo' })
|
59
|
+
}.to_not raise_error
|
60
|
+
|
61
|
+
expect(@errors.errors[-3]).to eq({'code' => 'test_domain.http_345_no_references', 'message' => '345 message'})
|
62
|
+
expect(@errors.errors[-2]).to eq({'code' => 'test_domain.http_345_no_references', 'message' => 'foo 1'})
|
63
|
+
expect(@errors.errors[-1]).to eq({'code' => 'test_domain.http_345_no_references', 'message' => 'foo 2', 'reference' => 'baz,foo'})
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should complain about missing fields' do
|
67
|
+
expect {
|
68
|
+
@errors.add_error('test_domain.http_456_has_reference')
|
69
|
+
}.to raise_error(Hoodoo::Errors::MissingReferenceData, "In \#add_error: Reference hash missing required keys: 'ref1'")
|
70
|
+
|
71
|
+
expect {
|
72
|
+
@errors.add_error('test_domain.http_567_has_references')
|
73
|
+
}.to raise_error(Hoodoo::Errors::MissingReferenceData, "In \#add_error: Reference hash missing required keys: 'ref2, ref3, ref4'")
|
74
|
+
|
75
|
+
expect {
|
76
|
+
@errors.add_error('test_domain.http_567_has_references', 'reference' => {:ref3 => "hello"})
|
77
|
+
}.to raise_error(Hoodoo::Errors::MissingReferenceData, "In \#add_error: Reference hash missing required keys: 'ref2, ref4'")
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should let me specify mandatory reference data' do
|
81
|
+
expect {
|
82
|
+
@errors.add_error('test_domain.http_456_has_reference', 'reference' => {:ref1 => 'ref1-data'})
|
83
|
+
}.to_not raise_error
|
84
|
+
|
85
|
+
expect(@errors.errors[-1]).to eq({'code' => 'test_domain.http_456_has_reference', 'message' => '456 message', 'reference' => 'ref1-data'})
|
86
|
+
|
87
|
+
expect {
|
88
|
+
@errors.add_error('test_domain.http_456_has_reference', 'message' => 'ref1-test', 'reference' => {:ref1 => 'ref1-data'})
|
89
|
+
}.to_not raise_error
|
90
|
+
|
91
|
+
expect(@errors.errors[-1]).to eq({'code' => 'test_domain.http_456_has_reference', 'message' => 'ref1-test', 'reference' => 'ref1-data'})
|
92
|
+
|
93
|
+
expect {
|
94
|
+
@errors.add_error('test_domain.http_567_has_references', 'reference' => {:ref2 => 'ref2-data', :ref3 => 'ref3-data', :ref4 => 'ref4-data'})
|
95
|
+
}.to_not raise_error
|
96
|
+
|
97
|
+
expect(@errors.errors[-1]).to eq({'code' => 'test_domain.http_567_has_references', 'message' => '567 message', 'reference' => 'ref2-data,ref3-data,ref4-data'})
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should let me specify additional reference data and list it after mandatory data' do
|
101
|
+
expect {
|
102
|
+
@errors.add_error('test_domain.http_567_has_references', 'reference' => {:add2 => 'add2-data', :ref2 => 'ref2-data', :add1 => 'add1-data', :ref3 => 'ref3-data', :ref4 => 'ref4-data'})
|
103
|
+
}.to_not raise_error
|
104
|
+
|
105
|
+
expect(@errors.errors[-1]).to eq({'code' => 'test_domain.http_567_has_references', 'message' => '567 message', 'reference' => 'ref2-data,ref3-data,ref4-data,add2-data,add1-data'})
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '#clear_errors' do
|
110
|
+
it 'should correctly clear errors' do
|
111
|
+
@errors.clear_errors
|
112
|
+
expect(@errors.has_errors?).to eq(false)
|
113
|
+
expect(@errors.errors).to be_empty
|
114
|
+
|
115
|
+
@errors.add_error('platform.malformed')
|
116
|
+
expect(@errors.has_errors?).to eq(true)
|
117
|
+
expect(@errors.errors).to_not be_empty
|
118
|
+
|
119
|
+
@errors.clear_errors
|
120
|
+
expect(@errors.has_errors?).to eq(false)
|
121
|
+
expect(@errors.errors).to be_empty
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '#add_precompiled_error' do
|
126
|
+
it 'should let me add precompiled errors' do
|
127
|
+
expect {
|
128
|
+
@errors.add_precompiled_error('test_domain.http_345_no_references 1', 'message 1', 'baz, foo 1')
|
129
|
+
@errors.add_precompiled_error('test_domain.http_345_no_references 2', 'message 2', 'baz, foo 2')
|
130
|
+
@errors.add_precompiled_error('test_domain.http_345_no_references 3', 'message 3', 'baz, foo 3')
|
131
|
+
}.to_not raise_error
|
132
|
+
|
133
|
+
expect(@errors.errors[0]).to eq({'code' => 'test_domain.http_345_no_references 1', 'message' => 'message 1', 'reference' => 'baz, foo 1'})
|
134
|
+
expect(@errors.errors[1]).to eq({'code' => 'test_domain.http_345_no_references 2', 'message' => 'message 2', 'reference' => 'baz, foo 2'})
|
135
|
+
expect(@errors.errors[2]).to eq({'code' => 'test_domain.http_345_no_references 3', 'message' => 'message 3', 'reference' => 'baz, foo 3'})
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe '#render' do
|
140
|
+
it 'complains about invalid Interaction IDs' do
|
141
|
+
expect {
|
142
|
+
@errors.render( nil )
|
143
|
+
}.to raise_error( RuntimeError, "Hoodoo::Errors\#render must be given a valid Interaction ID (got 'nil')" )
|
144
|
+
|
145
|
+
expect {
|
146
|
+
@errors.render( 12345 )
|
147
|
+
}.to raise_error( RuntimeError, "Hoodoo::Errors\#render must be given a valid Interaction ID (got '12345')" )
|
148
|
+
|
149
|
+
expect {
|
150
|
+
@errors.render( 'hello' )
|
151
|
+
}.to raise_error( RuntimeError, "Hoodoo::Errors\#render must be given a valid Interaction ID (got '\"hello\"')" )
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'renders' do
|
155
|
+
@errors.clear_errors
|
156
|
+
@errors.add_error('platform.malformed')
|
157
|
+
|
158
|
+
data = @errors.render(Hoodoo::UUID.generate())
|
159
|
+
expect(data['errors']).to be_a(Array)
|
160
|
+
expect(data['errors'].count).to eq(1)
|
161
|
+
expect(data['errors'][0]['code']).to eq('platform.malformed')
|
162
|
+
expect(data['errors'][0]['message']).to be_a(String)
|
163
|
+
expect(data['errors'][0]['message'].size).to_not eq(0)
|
164
|
+
expect(data['errors'][0]['reference']).to be_nil
|
165
|
+
expect(data['id']).to be_a(String)
|
166
|
+
expect(data['id'].size).to eq(32)
|
167
|
+
expect(data['kind']).to eq('Errors')
|
168
|
+
expect(data['created_at']).to be_a(String)
|
169
|
+
expect {
|
170
|
+
raise "Broken or missing created_at" if Date.parse(data['created_at']).nil?
|
171
|
+
}.to_not raise_error
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe '#add_precompiled_error' do
|
176
|
+
it 'should not complain about random data' do
|
177
|
+
@errors.clear_errors
|
178
|
+
@errors.add_precompiled_error( 'code', 'message', 'reference' )
|
179
|
+
expect(@errors.errors).to eq([
|
180
|
+
{
|
181
|
+
'code' => 'code',
|
182
|
+
'message' => 'message',
|
183
|
+
'reference' => 'reference'
|
184
|
+
}
|
185
|
+
])
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'should not store empty references' do
|
189
|
+
@errors.clear_errors
|
190
|
+
@errors.add_precompiled_error( 'code', 'message', '' )
|
191
|
+
expect(@errors.errors).to eq([
|
192
|
+
{
|
193
|
+
'code' => 'code',
|
194
|
+
'message' => 'message'
|
195
|
+
}
|
196
|
+
])
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'should not store nil references' do
|
200
|
+
@errors.clear_errors
|
201
|
+
@errors.add_precompiled_error( 'code', 'message', nil )
|
202
|
+
expect(@errors.errors).to eq([
|
203
|
+
{
|
204
|
+
'code' => 'code',
|
205
|
+
'message' => 'message'
|
206
|
+
}
|
207
|
+
])
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
describe '#merge' do
|
212
|
+
it 'should merge when neither have errors' do
|
213
|
+
@errors.clear_errors
|
214
|
+
source = Hoodoo::Errors.new
|
215
|
+
expect(@errors.merge!(source)).to eq(false)
|
216
|
+
expect(@errors.errors).to eq([])
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'should merge when only the source has errors' do
|
220
|
+
@errors.clear_errors
|
221
|
+
source = Hoodoo::Errors.new
|
222
|
+
source.add_error('platform.method_not_allowed', 'message' => 'Method not allowed 1', 'reference' => { :data => '1' })
|
223
|
+
source.add_error('platform.malformed', 'message' => 'Malformed request 1', 'reference' => { :data => '1' })
|
224
|
+
expect(@errors.merge!(source)).to eq(true)
|
225
|
+
|
226
|
+
expect(@errors.errors).to eq([
|
227
|
+
{
|
228
|
+
'code' => 'platform.method_not_allowed',
|
229
|
+
'message' => 'Method not allowed 1',
|
230
|
+
'reference' => '1'
|
231
|
+
},
|
232
|
+
{
|
233
|
+
'code' => 'platform.malformed',
|
234
|
+
'message' => 'Malformed request 1',
|
235
|
+
'reference' => '1'
|
236
|
+
}
|
237
|
+
])
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'should merge when only the destination has errors' do
|
241
|
+
@errors.clear_errors
|
242
|
+
source = Hoodoo::Errors.new
|
243
|
+
@errors.add_error('platform.method_not_allowed', 'message' => 'Method not allowed 2', 'reference' => { :data => '2' })
|
244
|
+
@errors.add_error('platform.malformed', 'message' => 'Malformed request 2', 'reference' => { :data => '2' })
|
245
|
+
@errors.merge!( source )
|
246
|
+
|
247
|
+
expect(@errors.errors).to eq([
|
248
|
+
{
|
249
|
+
'code' => 'platform.method_not_allowed',
|
250
|
+
'message' => 'Method not allowed 2',
|
251
|
+
'reference' => '2'
|
252
|
+
},
|
253
|
+
{
|
254
|
+
'code' => 'platform.malformed',
|
255
|
+
'message' => 'Malformed request 2',
|
256
|
+
'reference' => '2'
|
257
|
+
}
|
258
|
+
])
|
259
|
+
end
|
260
|
+
|
261
|
+
it 'should merge when both have errors' do
|
262
|
+
@errors.clear_errors
|
263
|
+
source = Hoodoo::Errors.new
|
264
|
+
source.add_error('platform.method_not_allowed', 'message' => 'Method not allowed 1', 'reference' => { :data => '1' })
|
265
|
+
source.add_error('platform.malformed', 'message' => 'Malformed request 1', 'reference' => { :data => '1' })
|
266
|
+
@errors.add_error('platform.method_not_allowed', 'message' => 'Method not allowed 2', 'reference' => { :data => '2' })
|
267
|
+
@errors.add_error('platform.malformed', 'message' => 'Malformed request 2', 'reference' => { :data => '2' })
|
268
|
+
@errors.merge!( source )
|
269
|
+
|
270
|
+
expect(@errors.errors).to eq([
|
271
|
+
{
|
272
|
+
'code' => 'platform.method_not_allowed',
|
273
|
+
'message' => 'Method not allowed 2',
|
274
|
+
'reference' => '2'
|
275
|
+
},
|
276
|
+
{
|
277
|
+
'code' => 'platform.malformed',
|
278
|
+
'message' => 'Malformed request 2',
|
279
|
+
'reference' => '2'
|
280
|
+
},
|
281
|
+
{
|
282
|
+
'code' => 'platform.method_not_allowed',
|
283
|
+
'message' => 'Method not allowed 1',
|
284
|
+
'reference' => '1'
|
285
|
+
},
|
286
|
+
{
|
287
|
+
'code' => 'platform.malformed',
|
288
|
+
'message' => 'Malformed request 1',
|
289
|
+
'reference' => '1'
|
290
|
+
}
|
291
|
+
])
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'should acquire the source status code when it has none itself' do
|
295
|
+
@errors.clear_errors
|
296
|
+
expect(@errors.http_status_code).to eq(200) # Default; collection is empty
|
297
|
+
|
298
|
+
source = Hoodoo::Errors.new
|
299
|
+
source.add_error('platform.method_not_allowed')
|
300
|
+
expect(source.http_status_code).to eq(405)
|
301
|
+
|
302
|
+
@errors.merge!(source)
|
303
|
+
expect(@errors.http_status_code).to eq(405) # Acquires the 405 from the merged collection
|
304
|
+
end
|
305
|
+
|
306
|
+
it 'should keep its original status code when it has one' do
|
307
|
+
@errors.clear_errors
|
308
|
+
@errors.add_error( 'platform.not_found', 'reference' => { :entity_name => 'something' } )
|
309
|
+
source = Hoodoo::Errors.new
|
310
|
+
source.add_error('platform.method_not_allowed')
|
311
|
+
expect(@errors.http_status_code).to eq(404) # Non-default; collection has an error recorded
|
312
|
+
expect(source.http_status_code).to eq(405)
|
313
|
+
@errors.merge!(source)
|
314
|
+
expect(@errors.http_status_code).to eq(404) # Keeps the 404 from its original collection
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
describe 'comma escaping' do
|
319
|
+
it 'should escape commas' do
|
320
|
+
str = @errors.send(:escape_commas, "This, that, one \\ another")
|
321
|
+
expect(str).to eq("This\\, that\\, one \\\\ another")
|
322
|
+
end
|
323
|
+
|
324
|
+
it 'should unescape commas' do
|
325
|
+
str = @errors.send(:escape_commas, "This, that, one \\ another")
|
326
|
+
str = @errors.send(:unescape_commas, str)
|
327
|
+
expect(str).to eq("This, that, one \\ another")
|
328
|
+
end
|
329
|
+
|
330
|
+
it 'should unpack an escaped comma separated list' do
|
331
|
+
ary = [ 'this, that', 'one \\ another' ]
|
332
|
+
str = @errors.send(:escape_commas, ary[0])
|
333
|
+
str << ',' << @errors.send(:escape_commas, ary[1])
|
334
|
+
expect(@errors.unjoin_and_unescape_commas(str)).to eq(ary)
|
335
|
+
end
|
336
|
+
|
337
|
+
it 'should escape reference data, which should be recoverable' do
|
338
|
+
@errors.clear_errors
|
339
|
+
@errors.add_error('test_domain.http_567_has_references', 'reference' => {:ref2 => 'ref \\ 2 data', :ref3 => 'ref, 3, data', :ref4 => 'ref4-data'})
|
340
|
+
|
341
|
+
rendered = @errors.render(Hoodoo::UUID.generate())
|
342
|
+
ary = @errors.unjoin_and_unescape_commas(rendered['errors'][0]['reference'])
|
343
|
+
expect(ary).to eq(['ref \\ 2 data', 'ref, 3, data', 'ref4-data'])
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# This is a sort-of-integration test that ad hoc tests different elements of
|
2
|
+
# the stack already exercised elsewhere, especially in the middleware tests
|
3
|
+
# from service_middleware_spec.rb. It's just a different "angle" on everthing
|
4
|
+
# for a belt and braces approach.
|
5
|
+
|
6
|
+
require 'spec_helper'
|
7
|
+
|
8
|
+
class RSpecTestServiceAImplementation < Hoodoo::Services::Implementation
|
9
|
+
def list( context )
|
10
|
+
raise self.class.name + ' list'
|
11
|
+
end
|
12
|
+
|
13
|
+
def show( context )
|
14
|
+
raise self.class.name + ' show'
|
15
|
+
end
|
16
|
+
|
17
|
+
def create( context )
|
18
|
+
raise self.class.name + ' create'
|
19
|
+
end
|
20
|
+
|
21
|
+
def update( context )
|
22
|
+
raise self.class.name + ' update'
|
23
|
+
end
|
24
|
+
|
25
|
+
def delete( context )
|
26
|
+
raise self.class.name + ' delete'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class RSpecTestServiceAInterface < Hoodoo::Services::Interface
|
31
|
+
interface :RSpecTestService do
|
32
|
+
endpoint :rspec_test_service_a, RSpecTestServiceAImplementation
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class RSpecTestServiceA < Hoodoo::Services::Service
|
37
|
+
comprised_of RSpecTestServiceAInterface
|
38
|
+
end
|
39
|
+
|
40
|
+
describe RSpecTestServiceA do
|
41
|
+
describe 'when badly configured' do
|
42
|
+
context 'with no middleware' do
|
43
|
+
def app
|
44
|
+
Rack::Builder.new do
|
45
|
+
# The deliberate mistake - no 'use ...' telling Rack about
|
46
|
+
# the service middleware...
|
47
|
+
run RSpecTestServiceA.new
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should complain about being called directly' do
|
52
|
+
expect {
|
53
|
+
get '/v1/rspec_test_service_a'
|
54
|
+
}.to raise_error(RuntimeError)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe 'when well configured' do
|
60
|
+
def app
|
61
|
+
Rack::Builder.new do
|
62
|
+
use Hoodoo::Services::Middleware
|
63
|
+
run RSpecTestServiceA.new
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# This batch of tests doesn't worry about middleware-level rejection of
|
68
|
+
# bad requests and so-on as the middleware specs catch that. It just wants
|
69
|
+
# to make sure that a top-end get/post/patch/delete gets routed down to
|
70
|
+
# the correct action method in the correct implementation.
|
71
|
+
|
72
|
+
it 'should list items' do
|
73
|
+
get '/v1/rspec_test_service_a', nil, { 'CONTENT_TYPE' => 'application/json; charset=utf-8' }
|
74
|
+
expect(last_response.status).to eq(500)
|
75
|
+
result = JSON.parse(last_response.body)
|
76
|
+
expect(result['errors'][0]['code']).to eq('platform.fault')
|
77
|
+
expect(result['errors'][0]['message']).to eq('RSpecTestServiceAImplementation list')
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should show an item' do
|
81
|
+
get '/v1/rspec_test_service_a/foo', nil, { 'CONTENT_TYPE' => 'application/json; charset=utf-8' }
|
82
|
+
expect(last_response.status).to eq(500)
|
83
|
+
result = JSON.parse(last_response.body)
|
84
|
+
expect(result['errors'][0]['code']).to eq('platform.fault')
|
85
|
+
expect(result['errors'][0]['message']).to eq('RSpecTestServiceAImplementation show')
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should create an item' do
|
89
|
+
post '/v1/rspec_test_service_a/', "{}", { 'CONTENT_TYPE' => 'application/json; charset=utf-8' }
|
90
|
+
expect(last_response.status).to eq(500)
|
91
|
+
result = JSON.parse(last_response.body)
|
92
|
+
expect(result['errors'][0]['code']).to eq('platform.fault')
|
93
|
+
expect(result['errors'][0]['message']).to eq('RSpecTestServiceAImplementation create')
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should update an item' do
|
97
|
+
patch '/v1/rspec_test_service_a/foo', "{}", { 'CONTENT_TYPE' => 'application/json; charset=utf-8' }
|
98
|
+
expect(last_response.status).to eq(500)
|
99
|
+
result = JSON.parse(last_response.body)
|
100
|
+
expect(result['errors'][0]['code']).to eq('platform.fault')
|
101
|
+
expect(result['errors'][0]['message']).to eq('RSpecTestServiceAImplementation update')
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should delete an item' do
|
105
|
+
delete '/v1/rspec_test_service_a/foo', nil, { 'CONTENT_TYPE' => 'application/json; charset=utf-8' }
|
106
|
+
expect(last_response.status).to eq(500)
|
107
|
+
result = JSON.parse(last_response.body)
|
108
|
+
expect(result['errors'][0]['code']).to eq('platform.fault')
|
109
|
+
expect(result['errors'][0]['message']).to eq('RSpecTestServiceAImplementation delete')
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|