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,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hoodoo::Logger::LogEntriesDotComWriter do
|
4
|
+
|
5
|
+
let( :example_token ) do
|
6
|
+
# https://logentries.com/doc/input-token/
|
7
|
+
'2bfbea1e-10c3-4419-bdad-7e6435882e1f'
|
8
|
+
end
|
9
|
+
|
10
|
+
before( :each ) do
|
11
|
+
@instance = described_class.new( example_token() )
|
12
|
+
@logger = @instance.class.class_variable_get( '@@logger' )
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'creates an appropriate logger instance' do
|
16
|
+
example = Le.new( example_token(), :ssl => true )
|
17
|
+
expect( @logger.class ).to eq( example.class )
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'calls the logger instance by log level method' do
|
21
|
+
expect( @logger ).to receive( :info ).once
|
22
|
+
@instance.report( :info, :b, :c, :d )
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'converts unrecognised debug levels to "unknown"' do
|
26
|
+
expect( @logger ).to receive( :unknown ).once
|
27
|
+
@instance.report( :a, :b, :c, :d )
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
describe Hoodoo::Logger::StreamWriter do
|
5
|
+
before :all do
|
6
|
+
temp_name = Dir::Tmpname.make_tmpname( 'hoodoo_rspec_', nil )
|
7
|
+
@temp_path = File.join( Dir::Tmpname.tmpdir, temp_name )
|
8
|
+
@stream = File.open( @temp_path, 'ab' )
|
9
|
+
end
|
10
|
+
|
11
|
+
after :all do
|
12
|
+
begin
|
13
|
+
@stream.close
|
14
|
+
rescue
|
15
|
+
end
|
16
|
+
|
17
|
+
begin
|
18
|
+
File.unlink( @temp_path )
|
19
|
+
rescue
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'writes to streams' do
|
24
|
+
|
25
|
+
instance = described_class.new( @stream )
|
26
|
+
|
27
|
+
time = Time.parse("2014-01-01 00:00:00 UTC")
|
28
|
+
expect( Time ).to receive( :now ).at_least( 1 ).times.and_return( time )
|
29
|
+
|
30
|
+
instance.report( :a, :b, :c, :d )
|
31
|
+
expect( File.exist?( @temp_path ) ).to be( true )
|
32
|
+
@stream.close
|
33
|
+
|
34
|
+
logged = File.read( @temp_path )
|
35
|
+
expect( logged ).to eq( "A [2014-01-01T00:00:00.000000Z] b - c: :d\n")
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Hoodoo::Presenters::BaseDSL do
|
4
|
+
|
5
|
+
# There are few tests needed beyond the base presenter tests at
|
6
|
+
# present.
|
7
|
+
|
8
|
+
describe '#type' do
|
9
|
+
class Hoodoo::Data::Types::TestType < Hoodoo::Presenters::Base
|
10
|
+
schema do
|
11
|
+
text :name
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class ArbitraryTestType < Hoodoo::Presenters::Base
|
16
|
+
schema do
|
17
|
+
float :floaty
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should raise an error for unrecognised types' do
|
22
|
+
expect {
|
23
|
+
class BaseDSLTest < Hoodoo::Presenters::Base
|
24
|
+
schema do
|
25
|
+
object :obj do
|
26
|
+
type :DoesNotExist
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
}.to raise_error(RuntimeError, "Hoodoo::Presenters::Base#type: Unrecognised type name 'DoesNotExist'")
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should not raise an error for existing types' do
|
34
|
+
expect {
|
35
|
+
class BaseDSLTest < Hoodoo::Presenters::Base
|
36
|
+
schema do
|
37
|
+
type :TestType
|
38
|
+
end
|
39
|
+
end
|
40
|
+
}.not_to raise_error
|
41
|
+
|
42
|
+
expect {
|
43
|
+
class BaseDSLTest < Hoodoo::Presenters::Base
|
44
|
+
schema do
|
45
|
+
type Hoodoo::Data::Types::TestType
|
46
|
+
end
|
47
|
+
end
|
48
|
+
}.not_to raise_error
|
49
|
+
|
50
|
+
expect {
|
51
|
+
class BaseDSLTest < Hoodoo::Presenters::Base
|
52
|
+
schema do
|
53
|
+
type ArbitraryTestType
|
54
|
+
end
|
55
|
+
end
|
56
|
+
}.not_to raise_error
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#resource' do
|
61
|
+
class Hoodoo::Data::Resources::TestResource < Hoodoo::Presenters::Base
|
62
|
+
schema do
|
63
|
+
internationalised
|
64
|
+
|
65
|
+
text :name
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class ArbitraryTestResource < Hoodoo::Presenters::Base
|
70
|
+
schema do
|
71
|
+
float :floaty
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should raise an error for unrecognised resources' do
|
76
|
+
expect {
|
77
|
+
class BaseDSLTest < Hoodoo::Presenters::Base
|
78
|
+
schema do
|
79
|
+
resource :DoesNotExist
|
80
|
+
end
|
81
|
+
end
|
82
|
+
}.to raise_error(RuntimeError, "Hoodoo::Presenters::Base#resource: Unrecognised resource name 'DoesNotExist'")
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should not raise an error for existing resources' do
|
86
|
+
expect {
|
87
|
+
class BaseDSLTest < Hoodoo::Presenters::Base
|
88
|
+
schema do
|
89
|
+
resource :TestResource
|
90
|
+
end
|
91
|
+
end
|
92
|
+
}.not_to raise_error
|
93
|
+
|
94
|
+
expect {
|
95
|
+
class BaseDSLTest < Hoodoo::Presenters::Base
|
96
|
+
schema do
|
97
|
+
resource Hoodoo::Data::Resources::TestResource
|
98
|
+
end
|
99
|
+
end
|
100
|
+
}.not_to raise_error
|
101
|
+
|
102
|
+
expect {
|
103
|
+
class BaseDSLTest < Hoodoo::Presenters::Base
|
104
|
+
schema do
|
105
|
+
resource ArbitraryTestResource
|
106
|
+
end
|
107
|
+
end
|
108
|
+
}.not_to raise_error
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,871 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe '#schema' do
|
4
|
+
|
5
|
+
before do
|
6
|
+
|
7
|
+
class TestPresenter < Hoodoo::Presenters::Base
|
8
|
+
|
9
|
+
schema do
|
10
|
+
integer :one, :required => true
|
11
|
+
boolean :two, :required => true
|
12
|
+
string :three, :length => 15, :required => false, :default => 'default_three'
|
13
|
+
datetime :four
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
class TestPresenter2 < Hoodoo::Presenters::Base
|
19
|
+
|
20
|
+
schema do
|
21
|
+
object :four, :required => true do
|
22
|
+
decimal :five, :precision => 20
|
23
|
+
float :six
|
24
|
+
date :seven, :required => true
|
25
|
+
array :eight
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
class TestPresenter3 < Hoodoo::Presenters::Base
|
32
|
+
|
33
|
+
schema do
|
34
|
+
integer :one, :required => true
|
35
|
+
object :four, :required => true do
|
36
|
+
decimal :five, :precision => 20
|
37
|
+
float :six
|
38
|
+
date :seven, :required => true
|
39
|
+
array :eight
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
class TestPresenter4 < Hoodoo::Presenters::Base
|
46
|
+
|
47
|
+
schema do
|
48
|
+
array :an_array, :required => true do
|
49
|
+
integer :an_integer
|
50
|
+
datetime :a_datetime
|
51
|
+
end
|
52
|
+
enum :an_enum, :from => [ :one, 'two', 3 ]
|
53
|
+
text :some_text
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# Just in case someone's deliberately excluding other source files to
|
60
|
+
# check on code coverage...
|
61
|
+
#
|
62
|
+
module Hoodoo
|
63
|
+
module Data
|
64
|
+
module Types
|
65
|
+
end
|
66
|
+
module Resources
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# This exercises basic type definition using the Presenters DSL's #text
|
72
|
+
# and #internationalised methods.
|
73
|
+
#
|
74
|
+
class Hoodoo::Data::Types::Hello < Hoodoo::Presenters::Base
|
75
|
+
schema do
|
76
|
+
internationalised
|
77
|
+
text :name, :required => true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# This exercises basic resource definition with extended DSL methods #tags,
|
82
|
+
# #uuid and #type, with the #object and #array parts checking methods from
|
83
|
+
# both the extended and Presenters base DSL. The type reference is deeply
|
84
|
+
# nested to make sure that internationalisation in the Hello type "taints"
|
85
|
+
# the referencing type all the way up to the top level schema.
|
86
|
+
|
87
|
+
class Hoodoo::Data::Resources::World < Hoodoo::Presenters::Base
|
88
|
+
schema do
|
89
|
+
uuid :errors_id, :resource => :Errors
|
90
|
+
tags :test_tags
|
91
|
+
|
92
|
+
object :test_object, :required => true do
|
93
|
+
object :nested_object do
|
94
|
+
type :Hello
|
95
|
+
string :obj_suffix, :length => 1
|
96
|
+
end
|
97
|
+
|
98
|
+
array :test_array do
|
99
|
+
type :Hello
|
100
|
+
string :ary_suffix, :length => 2
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Check the 'resource' reference part of the DSL works too
|
107
|
+
|
108
|
+
class Hoodoo::Data::Resources::HelloWorld < Hoodoo::Presenters::Base
|
109
|
+
schema do
|
110
|
+
type :Hello
|
111
|
+
resource :World
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
class NastyNesting < Hoodoo::Presenters::Base
|
116
|
+
schema do
|
117
|
+
array :outer_array, :required => true do
|
118
|
+
text :one, :required => true
|
119
|
+
text :two, :required => true
|
120
|
+
array :middle_array, :required => true do
|
121
|
+
text :three, :required => true
|
122
|
+
text :four, :required => true
|
123
|
+
array :inner_array, :required => true do
|
124
|
+
text :five, :required => true
|
125
|
+
text :six, :required => true
|
126
|
+
object :inner_object, :required => true do
|
127
|
+
text :seven, :required => true
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# For testing resource validation for internationalised (or not) resources.
|
136
|
+
|
137
|
+
class Internationalised < Hoodoo::Presenters::Base
|
138
|
+
schema do
|
139
|
+
internationalised
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class NotInternationalised < Hoodoo::Presenters::Base
|
144
|
+
schema do
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# For testing hashes with type references
|
149
|
+
|
150
|
+
class Internationalised2 < Hoodoo::Presenters::Base
|
151
|
+
schema do
|
152
|
+
internationalised
|
153
|
+
text :hello
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
class HashGainsInternationalisation < Hoodoo::Presenters::Base
|
158
|
+
schema do
|
159
|
+
hash :inter do
|
160
|
+
keys do
|
161
|
+
type :Internationalised2
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
class HashGainsInternationalisation2 < Hoodoo::Presenters::Base
|
168
|
+
schema do
|
169
|
+
hash :inter do
|
170
|
+
key :one do
|
171
|
+
text :foo
|
172
|
+
end
|
173
|
+
key :two do
|
174
|
+
type :Internationalised2
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe '#validate' do
|
182
|
+
it 'should have a simple schema defined properly' do
|
183
|
+
schema = TestPresenter.get_schema
|
184
|
+
|
185
|
+
expect(schema.properties.count).to eq(4)
|
186
|
+
expect(schema.properties['one']).to be_a(Hoodoo::Presenters::Integer)
|
187
|
+
expect(schema.properties['one'].required).to eq(true)
|
188
|
+
expect(schema.properties['two']).to be_a(Hoodoo::Presenters::Boolean)
|
189
|
+
expect(schema.properties['two'].required).to eq(true)
|
190
|
+
expect(schema.properties['three']).to be_a(Hoodoo::Presenters::String)
|
191
|
+
expect(schema.properties['three'].required).to eq(false)
|
192
|
+
expect(schema.properties['three'].length).to eq(15)
|
193
|
+
expect(schema.properties['four']).to be_a(Hoodoo::Presenters::DateTime)
|
194
|
+
expect(schema.properties['four'].required).to eq(false)
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'should have a nested schema defined properly' do
|
198
|
+
schema = TestPresenter2.get_schema
|
199
|
+
|
200
|
+
expect(schema.properties.length).to eq(1)
|
201
|
+
expect(schema.properties['four']).to be_a(Hoodoo::Presenters::Object)
|
202
|
+
expect(schema.properties['four'].properties.length).to eq(4)
|
203
|
+
expect(schema.properties['four'].properties['five']).to be_a(Hoodoo::Presenters::Decimal)
|
204
|
+
expect(schema.properties['four'].properties['five'].precision).to eq(20)
|
205
|
+
expect(schema.properties['four'].properties['six']).to be_a(Hoodoo::Presenters::Float)
|
206
|
+
expect(schema.properties['four'].properties['seven']).to be_a(Hoodoo::Presenters::Date)
|
207
|
+
expect(schema.properties['four'].properties['seven'].required).to eq(true)
|
208
|
+
expect(schema.properties['four'].properties['eight']).to be_a(Hoodoo::Presenters::Array)
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'should have a nested schema for arrays' do
|
212
|
+
schema = TestPresenter4.get_schema
|
213
|
+
expect(schema.properties.length).to eq(3)
|
214
|
+
expect(schema.properties['an_array']).to be_a(Hoodoo::Presenters::Array)
|
215
|
+
expect(schema.properties['an_array'].required).to eq(true)
|
216
|
+
expect(schema.properties['an_array'].properties.length).to eq(2)
|
217
|
+
expect(schema.properties['an_array'].properties['an_integer']).to be_a(Hoodoo::Presenters::Integer)
|
218
|
+
expect(schema.properties['an_array'].properties['an_integer'].required).to eq(false)
|
219
|
+
expect(schema.properties['an_array'].properties['a_datetime']).to be_a(Hoodoo::Presenters::DateTime)
|
220
|
+
expect(schema.properties['an_array'].properties['a_datetime'].required).to eq(false)
|
221
|
+
expect(schema.properties['an_enum']).to be_a(Hoodoo::Presenters::Enum)
|
222
|
+
expect(schema.properties['an_enum'].required).to eq(false)
|
223
|
+
expect(schema.properties['an_enum'].from).to eq(['one', 'two', '3'])
|
224
|
+
expect(schema.properties['some_text']).to be_a(Hoodoo::Presenters::Text)
|
225
|
+
expect(schema.properties['some_text'].required).to eq(false)
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'should return no errors with a simple schema and valid data' do
|
229
|
+
data = {
|
230
|
+
'one' => 1,
|
231
|
+
'two' => true,
|
232
|
+
'three' => 'hello',
|
233
|
+
}
|
234
|
+
|
235
|
+
expect(TestPresenter.validate(data).errors).to eq([])
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'should return correct errors with a simple schema and invalid data' do
|
239
|
+
data = {
|
240
|
+
'one' => 'test',
|
241
|
+
'three' => 9323423,
|
242
|
+
}
|
243
|
+
|
244
|
+
errors = TestPresenter.validate(data)
|
245
|
+
expect(errors.errors).to eq([
|
246
|
+
{'code'=>"generic.invalid_integer", 'message'=>"Field `one` is an invalid integer", 'reference'=>"one"},
|
247
|
+
{'code'=>"generic.required_field_missing", 'message'=>"Field `two` is required", 'reference'=>"two"},
|
248
|
+
{'code'=>"generic.invalid_string", 'message'=>"Field `three` is an invalid string", 'reference'=>"three"},
|
249
|
+
])
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'should have nested complex schema defined properly' do
|
253
|
+
|
254
|
+
schema = Hoodoo::Data::Types::Hello.get_schema
|
255
|
+
|
256
|
+
expect(Hoodoo::Data::Types::Hello.is_internationalised?()).to eq(true)
|
257
|
+
expect(schema.is_internationalised?()).to eq(true)
|
258
|
+
expect(schema.properties.count).to eq(1)
|
259
|
+
expect(schema.properties['name']).to be_a(Hoodoo::Presenters::Text)
|
260
|
+
expect(schema.properties['name'].required).to eq(true)
|
261
|
+
|
262
|
+
schema = Hoodoo::Data::Resources::World.get_schema
|
263
|
+
|
264
|
+
expect(Hoodoo::Data::Resources::World.is_internationalised?()).to eq(true)
|
265
|
+
expect(schema.is_internationalised?()).to eq(true)
|
266
|
+
expect(schema.properties.count).to eq(3)
|
267
|
+
expect(schema.properties['errors_id']).to be_a(Hoodoo::Presenters::UUID)
|
268
|
+
expect(schema.properties['errors_id'].required).to eq(false)
|
269
|
+
expect(schema.properties['errors_id'].resource).to eq(:Errors)
|
270
|
+
expect(schema.properties['test_tags']).to be_a(Hoodoo::Presenters::Tags)
|
271
|
+
expect(schema.properties['test_tags'].required).to eq(false)
|
272
|
+
expect(schema.properties['test_object']).to be_a(Hoodoo::Presenters::Object)
|
273
|
+
expect(schema.properties['test_object'].required).to eq(true)
|
274
|
+
expect(schema.properties['test_object'].properties['nested_object']).to be_a(Hoodoo::Presenters::Object)
|
275
|
+
expect(schema.properties['test_object'].properties['nested_object'].required).to eq(false)
|
276
|
+
expect(schema.properties['test_object'].properties['nested_object'].properties['name']).to be_a(Hoodoo::Presenters::Text)
|
277
|
+
expect(schema.properties['test_object'].properties['nested_object'].properties['obj_suffix']).to be_a(Hoodoo::Presenters::String)
|
278
|
+
expect(schema.properties['test_object'].properties['nested_object'].properties['obj_suffix'].length).to eq(1)
|
279
|
+
expect(schema.properties['test_object'].properties['test_array']).to be_a(Hoodoo::Presenters::Array)
|
280
|
+
expect(schema.properties['test_object'].properties['test_array'].required).to eq(false)
|
281
|
+
expect(schema.properties['test_object'].properties['test_array'].properties['name']).to be_a(Hoodoo::Presenters::Text)
|
282
|
+
expect(schema.properties['test_object'].properties['test_array'].properties['ary_suffix']).to be_a(Hoodoo::Presenters::String)
|
283
|
+
expect(schema.properties['test_object'].properties['test_array'].properties['ary_suffix'].length).to eq(2)
|
284
|
+
|
285
|
+
schema = Hoodoo::Data::Resources::HelloWorld.get_schema
|
286
|
+
|
287
|
+
expect(Hoodoo::Data::Resources::World.is_internationalised?()).to eq(true)
|
288
|
+
expect(schema.is_internationalised?()).to eq(true)
|
289
|
+
expect(schema.properties.count).to eq(4)
|
290
|
+
expect(schema.properties['name']).to be_a(Hoodoo::Presenters::Text)
|
291
|
+
expect(schema.properties['name'].required).to eq(true)
|
292
|
+
expect(schema.properties['errors_id']).to be_a(Hoodoo::Presenters::UUID)
|
293
|
+
expect(schema.properties['errors_id'].required).to eq(false)
|
294
|
+
expect(schema.properties['errors_id'].resource).to eq(:Errors)
|
295
|
+
expect(schema.properties['test_tags']).to be_a(Hoodoo::Presenters::Tags)
|
296
|
+
expect(schema.properties['test_tags'].required).to eq(false)
|
297
|
+
expect(schema.properties['test_object']).to be_a(Hoodoo::Presenters::Object)
|
298
|
+
expect(schema.properties['test_object'].required).to eq(true)
|
299
|
+
expect(schema.properties['test_object'].properties['nested_object']).to be_a(Hoodoo::Presenters::Object)
|
300
|
+
expect(schema.properties['test_object'].properties['nested_object'].required).to eq(false)
|
301
|
+
expect(schema.properties['test_object'].properties['nested_object'].properties['name']).to be_a(Hoodoo::Presenters::Text)
|
302
|
+
expect(schema.properties['test_object'].properties['nested_object'].properties['obj_suffix']).to be_a(Hoodoo::Presenters::String)
|
303
|
+
expect(schema.properties['test_object'].properties['nested_object'].properties['obj_suffix'].length).to eq(1)
|
304
|
+
expect(schema.properties['test_object'].properties['test_array']).to be_a(Hoodoo::Presenters::Array)
|
305
|
+
expect(schema.properties['test_object'].properties['test_array'].required).to eq(false)
|
306
|
+
expect(schema.properties['test_object'].properties['test_array'].properties['name']).to be_a(Hoodoo::Presenters::Text)
|
307
|
+
expect(schema.properties['test_object'].properties['test_array'].properties['ary_suffix']).to be_a(Hoodoo::Presenters::String)
|
308
|
+
expect(schema.properties['test_object'].properties['test_array'].properties['ary_suffix'].length).to eq(2)
|
309
|
+
end
|
310
|
+
|
311
|
+
it 'should return no errors with valid data for type only' do
|
312
|
+
data = {
|
313
|
+
:errors_id => Hoodoo::UUID.generate,
|
314
|
+
:test_tags => 'foo,bar,baz',
|
315
|
+
:test_object => {
|
316
|
+
:nested_object => {
|
317
|
+
:name => 'Some name',
|
318
|
+
:obj_suffix => '!'
|
319
|
+
},
|
320
|
+
:test_array => [
|
321
|
+
{ :name => 'Some name 0', :ary_suffix => '00' },
|
322
|
+
{ :name => 'Some name 1' }
|
323
|
+
]
|
324
|
+
}
|
325
|
+
}
|
326
|
+
|
327
|
+
data = Hoodoo::Utilities.stringify(data)
|
328
|
+
expect(Hoodoo::Data::Resources::World.validate(data, false).errors).to eq([])
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'should return no errors with valid data for resource' do
|
332
|
+
data = {
|
333
|
+
:errors_id => Hoodoo::UUID.generate,
|
334
|
+
:test_tags => 'foo,bar,baz',
|
335
|
+
:test_object => {
|
336
|
+
:nested_object => {
|
337
|
+
:name => 'Some name',
|
338
|
+
:obj_suffix => '!'
|
339
|
+
},
|
340
|
+
:test_array => [
|
341
|
+
{ :name => 'Some name 0', :ary_suffix => '00' },
|
342
|
+
{ :name => 'Some name 1' }
|
343
|
+
]
|
344
|
+
}
|
345
|
+
}
|
346
|
+
|
347
|
+
data = Hoodoo::Utilities.stringify(data)
|
348
|
+
rendered = Hoodoo::Data::Resources::World.render(
|
349
|
+
data,
|
350
|
+
Hoodoo::UUID.generate,
|
351
|
+
Time.now
|
352
|
+
)
|
353
|
+
|
354
|
+
expect(Hoodoo::Data::Resources::World.validate(rendered, true).errors).to eq([])
|
355
|
+
end
|
356
|
+
|
357
|
+
it 'should return correct errors invalid data' do
|
358
|
+
data = {
|
359
|
+
:errors_id => Hoodoo::UUID.generate,
|
360
|
+
:test_tags => 'foo,bar,baz',
|
361
|
+
:test_object => {
|
362
|
+
:nested_object => {
|
363
|
+
:name => 'Some name',
|
364
|
+
:obj_suffix => '!!!'
|
365
|
+
},
|
366
|
+
:test_array => [
|
367
|
+
{ :name => 'Some name 0', :ary_suffix => '00' },
|
368
|
+
{ :name => 'Some name 1' },
|
369
|
+
{ :ary_suffix => 22 }
|
370
|
+
]
|
371
|
+
}
|
372
|
+
}
|
373
|
+
|
374
|
+
data = Hoodoo::Utilities.stringify(data)
|
375
|
+
expect(Hoodoo::Data::Resources::World.validate(data, false).errors).to eq([
|
376
|
+
{
|
377
|
+
'code' => 'generic.invalid_string',
|
378
|
+
'message' => 'Field `test_object.nested_object.obj_suffix` is longer than maximum length `1`',
|
379
|
+
'reference' => "test_object.nested_object.obj_suffix"
|
380
|
+
},
|
381
|
+
{
|
382
|
+
'code' => 'generic.required_field_missing',
|
383
|
+
'message' => 'Field `test_object.test_array[2].name` is required',
|
384
|
+
'reference' => "test_object.test_array[2].name"
|
385
|
+
},
|
386
|
+
{
|
387
|
+
'code' => 'generic.invalid_string',
|
388
|
+
'message' => 'Field `test_object.test_array[2].ary_suffix` is an invalid string',
|
389
|
+
'reference' => "test_object.test_array[2].ary_suffix"
|
390
|
+
}
|
391
|
+
])
|
392
|
+
end
|
393
|
+
|
394
|
+
it 'should return correct paths in errors for deeply nested cases' do
|
395
|
+
|
396
|
+
# The array must be present, but that doesn't tell us anything about
|
397
|
+
# the contents yet so we only have one error.
|
398
|
+
|
399
|
+
data = {}
|
400
|
+
expect(NastyNesting.validate(data, false).errors).to eq([
|
401
|
+
{
|
402
|
+
'code' => 'generic.required_field_missing',
|
403
|
+
'message' => 'Field `outer_array` is required',
|
404
|
+
'reference' => "outer_array"
|
405
|
+
}
|
406
|
+
])
|
407
|
+
|
408
|
+
# The outer array is present but empty. That's allowed. If we had
|
409
|
+
# added entries, then their requirements would apply.
|
410
|
+
|
411
|
+
data = {
|
412
|
+
:outer_array => []
|
413
|
+
}
|
414
|
+
data = Hoodoo::Utilities.stringify(data)
|
415
|
+
expect(NastyNesting.validate(data, false).errors).to eq([])
|
416
|
+
|
417
|
+
# The outer array is present and has two entries that omit required
|
418
|
+
# fields, so we expect errors for all of them.
|
419
|
+
|
420
|
+
data = {
|
421
|
+
:outer_array => [{}, {}]
|
422
|
+
}
|
423
|
+
data = Hoodoo::Utilities.stringify(data)
|
424
|
+
expect(NastyNesting.validate(data, false).errors).to eq([
|
425
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].one` is required', 'reference' => "outer_array[0].one"},
|
426
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].two` is required', 'reference' => "outer_array[0].two"},
|
427
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array` is required', 'reference' => "outer_array[0].middle_array"},
|
428
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[1].one` is required', 'reference' => "outer_array[1].one"},
|
429
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[1].two` is required', 'reference' => "outer_array[1].two"},
|
430
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[1].middle_array` is required', 'reference' => "outer_array[1].middle_array"}
|
431
|
+
])
|
432
|
+
|
433
|
+
# ...and follow that pattern for nested items...
|
434
|
+
|
435
|
+
data = {
|
436
|
+
:outer_array => [
|
437
|
+
{
|
438
|
+
:one => 'here',
|
439
|
+
:two => 'here',
|
440
|
+
:middle_array => []
|
441
|
+
}
|
442
|
+
]
|
443
|
+
}
|
444
|
+
data = Hoodoo::Utilities.stringify(data)
|
445
|
+
expect(NastyNesting.validate(data, false).errors).to eq([])
|
446
|
+
|
447
|
+
data = {
|
448
|
+
:outer_array => [
|
449
|
+
{
|
450
|
+
:one => 'here',
|
451
|
+
:two => 'here',
|
452
|
+
:middle_array => [{},{}]
|
453
|
+
}
|
454
|
+
]
|
455
|
+
}
|
456
|
+
data = Hoodoo::Utilities.stringify(data)
|
457
|
+
expect(NastyNesting.validate(data, false).errors).to eq([
|
458
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array[0].three` is required', 'reference' => "outer_array[0].middle_array[0].three"},
|
459
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array[0].four` is required', 'reference' => "outer_array[0].middle_array[0].four"},
|
460
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array[0].inner_array` is required', 'reference' => "outer_array[0].middle_array[0].inner_array"},
|
461
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array[1].three` is required', 'reference' => "outer_array[0].middle_array[1].three"},
|
462
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array[1].four` is required', 'reference' => "outer_array[0].middle_array[1].four"},
|
463
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array[1].inner_array` is required', 'reference' => "outer_array[0].middle_array[1].inner_array"}
|
464
|
+
])
|
465
|
+
|
466
|
+
data = {
|
467
|
+
:outer_array => [
|
468
|
+
{
|
469
|
+
:one => 'here',
|
470
|
+
:two => 'here',
|
471
|
+
:middle_array => [
|
472
|
+
{
|
473
|
+
:three => 'here',
|
474
|
+
:four => 'here',
|
475
|
+
:inner_array => []
|
476
|
+
}
|
477
|
+
]
|
478
|
+
}
|
479
|
+
]
|
480
|
+
}
|
481
|
+
data = Hoodoo::Utilities.stringify(data)
|
482
|
+
expect(NastyNesting.validate(data, false).errors).to eq([])
|
483
|
+
|
484
|
+
data = {
|
485
|
+
:outer_array => [
|
486
|
+
{
|
487
|
+
:one => 'here',
|
488
|
+
:two => 'here',
|
489
|
+
:middle_array => [
|
490
|
+
{
|
491
|
+
:three => 'here',
|
492
|
+
:four => 'here',
|
493
|
+
:inner_array => [{},{}]
|
494
|
+
}
|
495
|
+
]
|
496
|
+
}
|
497
|
+
]
|
498
|
+
}
|
499
|
+
data = Hoodoo::Utilities.stringify(data)
|
500
|
+
expect(NastyNesting.validate(data, false).errors).to eq([
|
501
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array[0].inner_array[0].five` is required', 'reference' => "outer_array[0].middle_array[0].inner_array[0].five"},
|
502
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array[0].inner_array[0].six` is required', 'reference' => "outer_array[0].middle_array[0].inner_array[0].six"},
|
503
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array[0].inner_array[0].inner_object` is required', 'reference' => "outer_array[0].middle_array[0].inner_array[0].inner_object"},
|
504
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array[0].inner_array[0].inner_object.seven` is required', 'reference' => "outer_array[0].middle_array[0].inner_array[0].inner_object.seven"},
|
505
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array[0].inner_array[1].five` is required', 'reference' => "outer_array[0].middle_array[0].inner_array[1].five"},
|
506
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array[0].inner_array[1].six` is required', 'reference' => "outer_array[0].middle_array[0].inner_array[1].six"},
|
507
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array[0].inner_array[1].inner_object` is required', 'reference' => "outer_array[0].middle_array[0].inner_array[1].inner_object"},
|
508
|
+
{'code' => 'generic.required_field_missing', 'message' => 'Field `outer_array[0].middle_array[0].inner_array[1].inner_object.seven` is required', 'reference' => "outer_array[0].middle_array[0].inner_array[1].inner_object.seven"}
|
509
|
+
])
|
510
|
+
|
511
|
+
data = {
|
512
|
+
:outer_array => [
|
513
|
+
{
|
514
|
+
:one => 'here',
|
515
|
+
:two => 'here',
|
516
|
+
:middle_array => [
|
517
|
+
{
|
518
|
+
:three => 'here',
|
519
|
+
:four => 'here',
|
520
|
+
:inner_array => [
|
521
|
+
{
|
522
|
+
:five => 'here',
|
523
|
+
:six => 'here',
|
524
|
+
:inner_object => {
|
525
|
+
:seven => 'here'
|
526
|
+
}
|
527
|
+
}
|
528
|
+
]
|
529
|
+
}
|
530
|
+
]
|
531
|
+
}
|
532
|
+
]
|
533
|
+
}
|
534
|
+
data = Hoodoo::Utilities.stringify(data)
|
535
|
+
expect(NastyNesting.validate(data, false).errors).to eq([])
|
536
|
+
end
|
537
|
+
|
538
|
+
it 'should validate resource fields for language correctly' do
|
539
|
+
expect(Internationalised.validate({}, true).errors.count).to eq(4)
|
540
|
+
expect(NotInternationalised.validate({}, true).errors.count).to eq(3)
|
541
|
+
|
542
|
+
# Check schema redefinition for the required language field is working
|
543
|
+
# OK by repeating the above two expectations.
|
544
|
+
#
|
545
|
+
expect(Internationalised.validate({}, true).errors.count).to eq(4)
|
546
|
+
expect(NotInternationalised.validate({}, true).errors.count).to eq(3)
|
547
|
+
end
|
548
|
+
|
549
|
+
it 'should validate an internationalised hash (1)' do
|
550
|
+
result = HashGainsInternationalisation.validate({}, true)
|
551
|
+
expect(result.errors.count).to eq(4) # I.e. missing ID, created_at, kind *and language*.
|
552
|
+
end
|
553
|
+
|
554
|
+
it 'should validate an internationalised hash (2)' do
|
555
|
+
result = HashGainsInternationalisation2.validate({}, true)
|
556
|
+
expect(result.errors.count).to eq(4) # I.e. missing ID, created_at, kind *and language*.
|
557
|
+
end
|
558
|
+
|
559
|
+
it 'should validate contents correctly (1)' do
|
560
|
+
data = { 'inter' => { 'a' => { 'hello' => 'hellotext' }, 'b' => { 'hello' => 'morehellotext' } } }
|
561
|
+
result = HashGainsInternationalisation.validate( data, false ) # false => Type fields only, ignore common fields
|
562
|
+
expect(result.errors.count).to eq(0)
|
563
|
+
end
|
564
|
+
|
565
|
+
it 'should validate contents correctly (2)' do
|
566
|
+
data = { 'inter' => { 'one' => { 'foo' => 'bar' }, 'two' => { 'hello' => 'twohellotext' } } }
|
567
|
+
result = HashGainsInternationalisation2.validate( data, false ) # true => Type fields only, ignore common fields
|
568
|
+
expect(result.errors.count).to eq(0)
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
572
|
+
describe '#render' do
|
573
|
+
it 'should ignore non-schema fields' do
|
574
|
+
data = {
|
575
|
+
'one' => 1,
|
576
|
+
'three' => 'hello',
|
577
|
+
'ignore' => 'me'
|
578
|
+
}
|
579
|
+
|
580
|
+
expect(TestPresenter.render(data)).to eq({
|
581
|
+
'one'=>1,
|
582
|
+
'three'=>'hello'
|
583
|
+
})
|
584
|
+
end
|
585
|
+
|
586
|
+
it 'should omit fields when not supplied, without defaults' do
|
587
|
+
data = {
|
588
|
+
'one' => 1,
|
589
|
+
'three' => 'hello'
|
590
|
+
}
|
591
|
+
|
592
|
+
expect(TestPresenter.render(data)).to eq({
|
593
|
+
'one'=>1,
|
594
|
+
'three'=>'hello'
|
595
|
+
})
|
596
|
+
end
|
597
|
+
|
598
|
+
it 'should include default values where available for fields when not supplied' do
|
599
|
+
data = {
|
600
|
+
'one' => 1,
|
601
|
+
'two' => 'hello',
|
602
|
+
}
|
603
|
+
|
604
|
+
expect(TestPresenter.render(data)).to eq({
|
605
|
+
'one'=>1,
|
606
|
+
'two'=>'hello',
|
607
|
+
'three'=>'default_three',
|
608
|
+
})
|
609
|
+
end
|
610
|
+
|
611
|
+
it 'should include fields with explicit nil values and not override with defaults' do
|
612
|
+
data = {
|
613
|
+
'one' => 1,
|
614
|
+
'two' => nil,
|
615
|
+
'three' => nil
|
616
|
+
}
|
617
|
+
|
618
|
+
expect(TestPresenter.render(data)).to eq({
|
619
|
+
'one'=>1,
|
620
|
+
'two'=>nil,
|
621
|
+
'three'=>nil
|
622
|
+
})
|
623
|
+
end
|
624
|
+
|
625
|
+
it 'should render correctly as a type without a UUID' do
|
626
|
+
data = Hoodoo::Utilities.stringify({
|
627
|
+
:errors_id => Hoodoo::UUID.generate,
|
628
|
+
:test_tags => 'foo,bar,baz',
|
629
|
+
:test_object => {
|
630
|
+
:nested_object => {
|
631
|
+
:name => 'Some name',
|
632
|
+
:obj_suffix => '!'
|
633
|
+
},
|
634
|
+
:test_array => [
|
635
|
+
{ :name => 'Some name 0', :ary_suffix => '00' },
|
636
|
+
{ :name => 'Some name 1' }
|
637
|
+
]
|
638
|
+
}
|
639
|
+
})
|
640
|
+
|
641
|
+
expect(Hoodoo::Data::Resources::World.render(data)).to eq({
|
642
|
+
'errors_id' => data['errors_id'],
|
643
|
+
'test_tags' => 'foo,bar,baz',
|
644
|
+
'test_object' => {
|
645
|
+
'nested_object' => {
|
646
|
+
'name' => 'Some name',
|
647
|
+
'obj_suffix' => '!'
|
648
|
+
},
|
649
|
+
'test_array' => [
|
650
|
+
{ 'name' => 'Some name 0', 'ary_suffix' => '00' },
|
651
|
+
{ 'name' => 'Some name 1' }
|
652
|
+
]
|
653
|
+
}
|
654
|
+
})
|
655
|
+
end
|
656
|
+
|
657
|
+
it 'should render correctly as a resource with a UUID' do
|
658
|
+
data = Hoodoo::Utilities.stringify({
|
659
|
+
:errors_id => Hoodoo::UUID.generate,
|
660
|
+
:test_tags => 'foo,bar,baz',
|
661
|
+
:test_object => {
|
662
|
+
:nested_object => {
|
663
|
+
:name => 'Some name',
|
664
|
+
:obj_suffix => '!'
|
665
|
+
},
|
666
|
+
:test_array => [
|
667
|
+
{ :name => 'Some name 0', :ary_suffix => '00' },
|
668
|
+
{ :name => 'Some name 1' }
|
669
|
+
]
|
670
|
+
}
|
671
|
+
})
|
672
|
+
|
673
|
+
uuid = Hoodoo::UUID.generate
|
674
|
+
time = Time.now
|
675
|
+
|
676
|
+
expect(Hoodoo::Data::Resources::World.render(
|
677
|
+
data,
|
678
|
+
uuid,
|
679
|
+
time,
|
680
|
+
'en-gb'
|
681
|
+
)).to eq({
|
682
|
+
'id' => uuid,
|
683
|
+
'kind' => 'World',
|
684
|
+
'created_at' => time.utc.iso8601,
|
685
|
+
'language' => 'en-gb',
|
686
|
+
'errors_id' => data['errors_id'],
|
687
|
+
'test_tags' => 'foo,bar,baz',
|
688
|
+
'test_object' => {
|
689
|
+
'nested_object' => {
|
690
|
+
'name' => 'Some name',
|
691
|
+
'obj_suffix' => '!'
|
692
|
+
},
|
693
|
+
'test_array' => [
|
694
|
+
{ 'name' => 'Some name 0', 'ary_suffix' => '00' },
|
695
|
+
{ 'name' => 'Some name 1' }
|
696
|
+
]
|
697
|
+
}
|
698
|
+
})
|
699
|
+
end
|
700
|
+
|
701
|
+
it 'should complain about resources with no creation date' do
|
702
|
+
data = {
|
703
|
+
:errors_id => Hoodoo::UUID.generate,
|
704
|
+
:test_tags => 'foo,bar,baz',
|
705
|
+
:test_object => {
|
706
|
+
:nested_object => {
|
707
|
+
:name => 'Some name',
|
708
|
+
:obj_suffix => '!'
|
709
|
+
},
|
710
|
+
:test_array => [
|
711
|
+
{ :name => 'Some name 0', :ary_suffix => '00' },
|
712
|
+
{ :name => 'Some name 1' }
|
713
|
+
]
|
714
|
+
}
|
715
|
+
}
|
716
|
+
|
717
|
+
data = Hoodoo::Utilities.stringify(data)
|
718
|
+
uuid = Hoodoo::UUID.generate
|
719
|
+
|
720
|
+
expect {
|
721
|
+
Hoodoo::Data::Resources::World.render(
|
722
|
+
data,
|
723
|
+
uuid,
|
724
|
+
nil,
|
725
|
+
'en-gb'
|
726
|
+
)
|
727
|
+
}.to raise_error(RuntimeError, "Can't render a Resource with a nil 'created_at'")
|
728
|
+
end
|
729
|
+
|
730
|
+
it 'should render hash contents correctly (1)' do
|
731
|
+
data = { 'inter' => { 'a' => { 'hello' => 'hellotext' }, 'b' => { 'hello' => 'morehellotext' } } }
|
732
|
+
result = HashGainsInternationalisation.render( data )
|
733
|
+
expect(result).to eq(data)
|
734
|
+
end
|
735
|
+
|
736
|
+
it 'should render hash contents correctly (2)' do
|
737
|
+
data = { 'inter' => { 'one' => { 'foo' => 'bar' }, 'two' => { 'hello' => 'twohellotext' } } }
|
738
|
+
result = HashGainsInternationalisation2.render( data )
|
739
|
+
expect(result).to eq(data)
|
740
|
+
end
|
741
|
+
|
742
|
+
it 'should render hash contents correctly (3)' do
|
743
|
+
data = { 'inter' => { 'one' => { 'foo' => 'bar' }, 'two' => { 'hello' => 'twohellotext' } } }
|
744
|
+
result = HashGainsInternationalisation.render( data ) # Note not the '2' variant of the class
|
745
|
+
expect(result).to eq({ 'inter' => { 'one' => {}, 'two' => { 'hello' => 'twohellotext' } } })
|
746
|
+
end
|
747
|
+
end
|
748
|
+
|
749
|
+
# Note that #render_in is tested in secure_spec.rb since a lot of the
|
750
|
+
# other complex setup therein would otherwise need copying here.
|
751
|
+
|
752
|
+
describe '#render_in' do
|
753
|
+
class RSpecTestContextForRenderInBasicImplementation < Hoodoo::Services::Implementation
|
754
|
+
end
|
755
|
+
|
756
|
+
class RSpecTestContextForRenderInBasicInterface < Hoodoo::Services::Interface
|
757
|
+
interface :RSpecTestResource do
|
758
|
+
endpoint :rspec_test_service_stub, RSpecTestContextForRenderInBasicImplementation
|
759
|
+
end
|
760
|
+
end
|
761
|
+
|
762
|
+
class RSpecTestContextForRenderInBasic < Hoodoo::Services::Service
|
763
|
+
comprised_of RSpecTestContextForRenderInBasicInterface
|
764
|
+
end
|
765
|
+
|
766
|
+
class TestPresenter5 < Hoodoo::Presenters::Base
|
767
|
+
schema do
|
768
|
+
string :three, :length => 15, :required => false, :default => 'default_three'
|
769
|
+
internationalised
|
770
|
+
end
|
771
|
+
end
|
772
|
+
|
773
|
+
before :each do
|
774
|
+
ses = Hoodoo::Services::Session.new
|
775
|
+
req = Hoodoo::Services::Request.new
|
776
|
+
res = Hoodoo::Services::Response.new( Hoodoo::UUID.generate() )
|
777
|
+
mid = Hoodoo::Services::Middleware.new( RSpecTestContextForRenderInBasic.new )
|
778
|
+
int = Hoodoo::Services::Middleware::Interaction.new( {}, mid )
|
779
|
+
|
780
|
+
req.locale = 'de'
|
781
|
+
|
782
|
+
@con = Hoodoo::Services::Context.new( ses, req, res, int )
|
783
|
+
end
|
784
|
+
|
785
|
+
it 'renders without options' do
|
786
|
+
data = {}
|
787
|
+
expect(TestPresenter5.render_in(@con, data)).to eq({
|
788
|
+
'three' => 'default_three'
|
789
|
+
})
|
790
|
+
end
|
791
|
+
|
792
|
+
it 'renders with minimal options' do
|
793
|
+
data = {}
|
794
|
+
t = Time.now.utc
|
795
|
+
u = Hoodoo::UUID.generate
|
796
|
+
options = { :uuid => u, :created_at => t }
|
797
|
+
expect(TestPresenter5.render_in(@con, data, options)).to eq({
|
798
|
+
'id' => u,
|
799
|
+
'kind' => 'TestPresenter5',
|
800
|
+
'created_at' => t.iso8601,
|
801
|
+
'language' => 'de',
|
802
|
+
'three' => 'default_three'
|
803
|
+
})
|
804
|
+
end
|
805
|
+
|
806
|
+
it 'overrides language' do
|
807
|
+
data = {}
|
808
|
+
t = Time.now.utc
|
809
|
+
u = Hoodoo::UUID.generate
|
810
|
+
options = { :uuid => u, :created_at => t, :language => 'fr' }
|
811
|
+
expect(TestPresenter5.render_in(@con, data, options)).to eq({
|
812
|
+
'id' => u,
|
813
|
+
'kind' => 'TestPresenter5',
|
814
|
+
'created_at' => t.iso8601,
|
815
|
+
'language' => 'fr',
|
816
|
+
'three' => 'default_three'
|
817
|
+
})
|
818
|
+
end
|
819
|
+
|
820
|
+
it 'embeds things' do
|
821
|
+
data = {}
|
822
|
+
t = Time.now.utc
|
823
|
+
u = Hoodoo::UUID.generate
|
824
|
+
e = Hoodoo::Presenters::Embedding::Embeds.new
|
825
|
+
voucher = {'description' => 'foo'}
|
826
|
+
balances = [ {'NZD' => '23', 'X-FBPTS' => '1'} ]
|
827
|
+
e.add_one( 'voucher', voucher )
|
828
|
+
e.add_many( 'balances', balances )
|
829
|
+
options = { :uuid => u, :created_at => t, :embeds => e }
|
830
|
+
expect(TestPresenter5.render_in(@con, data, options)).to eq({
|
831
|
+
'id' => u,
|
832
|
+
'kind' => 'TestPresenter5',
|
833
|
+
'created_at' => t.iso8601,
|
834
|
+
'language' => 'de',
|
835
|
+
'three' => 'default_three',
|
836
|
+
'_embed' => {
|
837
|
+
'voucher' => voucher,
|
838
|
+
'balances' => balances
|
839
|
+
}
|
840
|
+
})
|
841
|
+
end
|
842
|
+
|
843
|
+
it 'references things' do
|
844
|
+
data = {}
|
845
|
+
t = Time.now.utc
|
846
|
+
u = Hoodoo::UUID.generate
|
847
|
+
r = Hoodoo::Presenters::Embedding::References.new
|
848
|
+
voucher = Hoodoo::UUID.generate
|
849
|
+
balances = [ Hoodoo::UUID.generate, Hoodoo::UUID.generate ]
|
850
|
+
r.add_one( 'voucher', voucher )
|
851
|
+
r.add_many( 'balances', balances )
|
852
|
+
options = { :uuid => u, :created_at => t, :references => r }
|
853
|
+
expect(TestPresenter5.render_in(@con, data, options)).to eq({
|
854
|
+
'id' => u,
|
855
|
+
'kind' => 'TestPresenter5',
|
856
|
+
'created_at' => t.iso8601,
|
857
|
+
'language' => 'de',
|
858
|
+
'three' => 'default_three',
|
859
|
+
'_reference' => {
|
860
|
+
'voucher' => voucher,
|
861
|
+
'balances' => balances
|
862
|
+
}
|
863
|
+
})
|
864
|
+
end
|
865
|
+
|
866
|
+
# The "secured_with" option is tested in "secure_spec.rb" as lots of
|
867
|
+
# tricky related setup is done there that would only end up being
|
868
|
+
# coped in here otherwise.
|
869
|
+
|
870
|
+
end
|
871
|
+
end
|