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.
Files changed (216) hide show
  1. checksums.yaml +7 -0
  2. data/bin/hoodoo +5 -0
  3. data/lib/hoodoo.rb +27 -0
  4. data/lib/hoodoo/active.rb +32 -0
  5. data/lib/hoodoo/active/active_model/uuid_validator.rb +45 -0
  6. data/lib/hoodoo/active/active_record/base.rb +81 -0
  7. data/lib/hoodoo/active/active_record/creator.rb +134 -0
  8. data/lib/hoodoo/active/active_record/dated.rb +343 -0
  9. data/lib/hoodoo/active/active_record/error_mapping.rb +351 -0
  10. data/lib/hoodoo/active/active_record/finder.rb +606 -0
  11. data/lib/hoodoo/active/active_record/search_helper.rb +189 -0
  12. data/lib/hoodoo/active/active_record/secure.rb +431 -0
  13. data/lib/hoodoo/active/active_record/support.rb +106 -0
  14. data/lib/hoodoo/active/active_record/translated.rb +87 -0
  15. data/lib/hoodoo/active/active_record/uuid.rb +80 -0
  16. data/lib/hoodoo/active/active_record/writer.rb +321 -0
  17. data/lib/hoodoo/client.rb +23 -0
  18. data/lib/hoodoo/client/augmented_array.rb +29 -0
  19. data/lib/hoodoo/client/augmented_base.rb +168 -0
  20. data/lib/hoodoo/client/augmented_hash.rb +23 -0
  21. data/lib/hoodoo/client/client.rb +354 -0
  22. data/lib/hoodoo/client/endpoint/endpoint.rb +427 -0
  23. data/lib/hoodoo/client/endpoint/endpoints/amqp.rb +180 -0
  24. data/lib/hoodoo/client/endpoint/endpoints/auto_session.rb +194 -0
  25. data/lib/hoodoo/client/endpoint/endpoints/http.rb +203 -0
  26. data/lib/hoodoo/client/endpoint/endpoints/http_based.rb +367 -0
  27. data/lib/hoodoo/client/endpoint/endpoints/not_found.rb +59 -0
  28. data/lib/hoodoo/client/headers.rb +269 -0
  29. data/lib/hoodoo/communicators.rb +23 -0
  30. data/lib/hoodoo/communicators/fast.rb +44 -0
  31. data/lib/hoodoo/communicators/pool.rb +601 -0
  32. data/lib/hoodoo/communicators/slow.rb +84 -0
  33. data/lib/hoodoo/data.rb +51 -0
  34. data/lib/hoodoo/data/resources/caller.rb +39 -0
  35. data/lib/hoodoo/data/resources/errors.rb +28 -0
  36. data/lib/hoodoo/data/resources/log.rb +31 -0
  37. data/lib/hoodoo/data/resources/session.rb +26 -0
  38. data/lib/hoodoo/data/types/error_primitive.rb +27 -0
  39. data/lib/hoodoo/data/types/permissions.rb +40 -0
  40. data/lib/hoodoo/data/types/permissions_defaults.rb +32 -0
  41. data/lib/hoodoo/data/types/permissions_full.rb +28 -0
  42. data/lib/hoodoo/data/types/permissions_resources.rb +31 -0
  43. data/lib/hoodoo/discovery.rb +20 -0
  44. data/lib/hoodoo/errors.rb +19 -0
  45. data/lib/hoodoo/errors/error_descriptions.rb +229 -0
  46. data/lib/hoodoo/errors/errors.rb +322 -0
  47. data/lib/hoodoo/generator.rb +139 -0
  48. data/lib/hoodoo/logger.rb +23 -0
  49. data/lib/hoodoo/logger/fast_writer.rb +27 -0
  50. data/lib/hoodoo/logger/flattener_mixin.rb +36 -0
  51. data/lib/hoodoo/logger/logger.rb +387 -0
  52. data/lib/hoodoo/logger/slow_writer.rb +49 -0
  53. data/lib/hoodoo/logger/writer_mixin.rb +52 -0
  54. data/lib/hoodoo/logger/writers/file_writer.rb +45 -0
  55. data/lib/hoodoo/logger/writers/log_entries_dot_com_writer.rb +64 -0
  56. data/lib/hoodoo/logger/writers/stream_writer.rb +43 -0
  57. data/lib/hoodoo/middleware.rb +33 -0
  58. data/lib/hoodoo/presenters.rb +45 -0
  59. data/lib/hoodoo/presenters/base.rb +281 -0
  60. data/lib/hoodoo/presenters/base_dsl.rb +519 -0
  61. data/lib/hoodoo/presenters/common_resource_fields.rb +31 -0
  62. data/lib/hoodoo/presenters/embedding.rb +232 -0
  63. data/lib/hoodoo/presenters/types/array.rb +118 -0
  64. data/lib/hoodoo/presenters/types/boolean.rb +26 -0
  65. data/lib/hoodoo/presenters/types/date.rb +26 -0
  66. data/lib/hoodoo/presenters/types/date_time.rb +26 -0
  67. data/lib/hoodoo/presenters/types/decimal.rb +47 -0
  68. data/lib/hoodoo/presenters/types/enum.rb +55 -0
  69. data/lib/hoodoo/presenters/types/field.rb +158 -0
  70. data/lib/hoodoo/presenters/types/float.rb +26 -0
  71. data/lib/hoodoo/presenters/types/hash.rb +361 -0
  72. data/lib/hoodoo/presenters/types/integer.rb +26 -0
  73. data/lib/hoodoo/presenters/types/object.rb +117 -0
  74. data/lib/hoodoo/presenters/types/string.rb +53 -0
  75. data/lib/hoodoo/presenters/types/tags.rb +24 -0
  76. data/lib/hoodoo/presenters/types/text.rb +26 -0
  77. data/lib/hoodoo/presenters/types/uuid.rb +54 -0
  78. data/lib/hoodoo/services.rb +34 -0
  79. data/lib/hoodoo/services/discovery/discoverers/by_consul.rb +66 -0
  80. data/lib/hoodoo/services/discovery/discoverers/by_convention.rb +173 -0
  81. data/lib/hoodoo/services/discovery/discoverers/by_drb/by_drb.rb +195 -0
  82. data/lib/hoodoo/services/discovery/discoverers/by_drb/drb_server.rb +166 -0
  83. data/lib/hoodoo/services/discovery/discoverers/by_drb/drb_server_start.rb +37 -0
  84. data/lib/hoodoo/services/discovery/discovery.rb +186 -0
  85. data/lib/hoodoo/services/discovery/results/for_amqp.rb +58 -0
  86. data/lib/hoodoo/services/discovery/results/for_http.rb +85 -0
  87. data/lib/hoodoo/services/discovery/results/for_local.rb +85 -0
  88. data/lib/hoodoo/services/discovery/results/for_remote.rb +57 -0
  89. data/lib/hoodoo/services/middleware/amqp_log_message.rb +186 -0
  90. data/lib/hoodoo/services/middleware/amqp_log_writer.rb +119 -0
  91. data/lib/hoodoo/services/middleware/endpoints/inter_resource_local.rb +130 -0
  92. data/lib/hoodoo/services/middleware/endpoints/inter_resource_remote.rb +202 -0
  93. data/lib/hoodoo/services/middleware/exception_reporting/base_reporter.rb +105 -0
  94. data/lib/hoodoo/services/middleware/exception_reporting/exception_reporting.rb +115 -0
  95. data/lib/hoodoo/services/middleware/exception_reporting/reporters/airbrake_reporter.rb +64 -0
  96. data/lib/hoodoo/services/middleware/exception_reporting/reporters/raygun_reporter.rb +63 -0
  97. data/lib/hoodoo/services/middleware/interaction.rb +127 -0
  98. data/lib/hoodoo/services/middleware/middleware.rb +2705 -0
  99. data/lib/hoodoo/services/middleware/rack_monkey_patch.rb +73 -0
  100. data/lib/hoodoo/services/services/context.rb +153 -0
  101. data/lib/hoodoo/services/services/implementation.rb +132 -0
  102. data/lib/hoodoo/services/services/interface.rb +934 -0
  103. data/lib/hoodoo/services/services/permissions.rb +250 -0
  104. data/lib/hoodoo/services/services/request.rb +189 -0
  105. data/lib/hoodoo/services/services/response.rb +316 -0
  106. data/lib/hoodoo/services/services/service.rb +141 -0
  107. data/lib/hoodoo/services/services/session.rb +729 -0
  108. data/lib/hoodoo/utilities.rb +12 -0
  109. data/lib/hoodoo/utilities/string_inquirer.rb +54 -0
  110. data/lib/hoodoo/utilities/utilities.rb +380 -0
  111. data/lib/hoodoo/utilities/uuid.rb +44 -0
  112. data/lib/hoodoo/version.rb +17 -0
  113. data/spec/active/active_record/base_spec.rb +57 -0
  114. data/spec/active/active_record/creator_spec.rb +88 -0
  115. data/spec/active/active_record/dated_spec.rb +248 -0
  116. data/spec/active/active_record/error_mapping_spec.rb +360 -0
  117. data/spec/active/active_record/finder_spec.rb +744 -0
  118. data/spec/active/active_record/search_helper_spec.rb +384 -0
  119. data/spec/active/active_record/secure_spec.rb +435 -0
  120. data/spec/active/active_record/support_spec.rb +225 -0
  121. data/spec/active/active_record/translated_spec.rb +19 -0
  122. data/spec/active/active_record/uuid_spec.rb +72 -0
  123. data/spec/active/active_record/writer_spec.rb +272 -0
  124. data/spec/alchemy/alchemy-amq.rb +33 -0
  125. data/spec/client/augmented_array_spec.rb +15 -0
  126. data/spec/client/augmented_base_spec.rb +50 -0
  127. data/spec/client/augmented_hash_spec.rb +15 -0
  128. data/spec/client/client_spec.rb +955 -0
  129. data/spec/client/endpoint/endpoint_spec.rb +70 -0
  130. data/spec/client/endpoint/endpoints/amqp_spec.rb +16 -0
  131. data/spec/client/endpoint/endpoints/auto_session_spec.rb +9 -0
  132. data/spec/client/endpoint/endpoints/http_based_spec.rb +9 -0
  133. data/spec/client/endpoint/endpoints/http_spec.rb +103 -0
  134. data/spec/client/endpoint/endpoints/not_found_spec.rb +35 -0
  135. data/spec/client/headers_spec.rb +172 -0
  136. data/spec/communicators/fast_spec.rb +9 -0
  137. data/spec/communicators/pool_spec.rb +339 -0
  138. data/spec/communicators/slow_spec.rb +15 -0
  139. data/spec/data/resources/caller_spec.rb +156 -0
  140. data/spec/data/resources/errors_spec.rb +22 -0
  141. data/spec/data/resources/log_spec.rb +20 -0
  142. data/spec/data/resources/session_spec.rb +15 -0
  143. data/spec/data/types/error_primitive_spec.rb +15 -0
  144. data/spec/data/types/permissions_defaults_spec.rb +25 -0
  145. data/spec/data/types/permissions_full_spec.rb +44 -0
  146. data/spec/data/types/permissions_resources_spec.rb +34 -0
  147. data/spec/data/types/permissions_spec.rb +37 -0
  148. data/spec/errors/error_descriptions_spec.rb +98 -0
  149. data/spec/errors/errors_spec.rb +346 -0
  150. data/spec/integration/service_actions_spec.rb +112 -0
  151. data/spec/logger/fast_writer_spec.rb +18 -0
  152. data/spec/logger/logger_spec.rb +259 -0
  153. data/spec/logger/slow_writer_spec.rb +144 -0
  154. data/spec/logger/writers/file_writer_spec.rb +37 -0
  155. data/spec/logger/writers/log_entries_dot_com_writer_spec.rb +29 -0
  156. data/spec/logger/writers/stream_writer_spec.rb +38 -0
  157. data/spec/presenters/base_dsl_spec.rb +111 -0
  158. data/spec/presenters/base_spec.rb +871 -0
  159. data/spec/presenters/common_resource_fields_spec.rb +30 -0
  160. data/spec/presenters/embedding_spec.rb +87 -0
  161. data/spec/presenters/types/array_spec.rb +249 -0
  162. data/spec/presenters/types/boolean_spec.rb +51 -0
  163. data/spec/presenters/types/date_spec.rb +57 -0
  164. data/spec/presenters/types/date_time_spec.rb +59 -0
  165. data/spec/presenters/types/decimal_spec.rb +58 -0
  166. data/spec/presenters/types/enum_spec.rb +71 -0
  167. data/spec/presenters/types/field_spec.rb +77 -0
  168. data/spec/presenters/types/float_spec.rb +50 -0
  169. data/spec/presenters/types/hash_spec.rb +1069 -0
  170. data/spec/presenters/types/integer_spec.rb +50 -0
  171. data/spec/presenters/types/object_spec.rb +177 -0
  172. data/spec/presenters/types/string_spec.rb +65 -0
  173. data/spec/presenters/types/tags_spec.rb +56 -0
  174. data/spec/presenters/types/text_spec.rb +50 -0
  175. data/spec/presenters/types/uuid_spec.rb +46 -0
  176. data/spec/presenters/walk_spec.rb +198 -0
  177. data/spec/services/discovery/discoverers/by_consul_spec.rb +29 -0
  178. data/spec/services/discovery/discoverers/by_convention_spec.rb +67 -0
  179. data/spec/services/discovery/discoverers/by_drb/by_drb_spec.rb +80 -0
  180. data/spec/services/discovery/discoverers/by_drb/drb_server_spec.rb +205 -0
  181. data/spec/services/discovery/discovery_spec.rb +73 -0
  182. data/spec/services/discovery/results/for_amqp_spec.rb +17 -0
  183. data/spec/services/discovery/results/for_http_spec.rb +37 -0
  184. data/spec/services/discovery/results/for_local_spec.rb +21 -0
  185. data/spec/services/discovery/results/for_remote_spec.rb +15 -0
  186. data/spec/services/middleware/amqp_log_message_spec.rb +60 -0
  187. data/spec/services/middleware/amqp_log_writer_spec.rb +95 -0
  188. data/spec/services/middleware/endpoints/inter_resource_local_spec.rb +9 -0
  189. data/spec/services/middleware/endpoints/inter_resource_remote_spec.rb +9 -0
  190. data/spec/services/middleware/exception_reporting/base_reporter_spec.rb +16 -0
  191. data/spec/services/middleware/exception_reporting/exception_reporting_spec.rb +92 -0
  192. data/spec/services/middleware/exception_reporting/reporters/airbrake_reporter_spec.rb +24 -0
  193. data/spec/services/middleware/exception_reporting/reporters/raygun_reporter_spec.rb +23 -0
  194. data/spec/services/middleware/middleware_cors_spec.rb +93 -0
  195. data/spec/services/middleware/middleware_create_update_spec.rb +489 -0
  196. data/spec/services/middleware/middleware_dated_at_spec.rb +186 -0
  197. data/spec/services/middleware/middleware_exotic_communication_spec.rb +560 -0
  198. data/spec/services/middleware/middleware_logging_spec.rb +356 -0
  199. data/spec/services/middleware/middleware_multi_local_spec.rb +1094 -0
  200. data/spec/services/middleware/middleware_multi_remote_spec.rb +1440 -0
  201. data/spec/services/middleware/middleware_permissions_spec.rb +1014 -0
  202. data/spec/services/middleware/middleware_public_spec.rb +238 -0
  203. data/spec/services/middleware/middleware_spec.rb +1569 -0
  204. data/spec/services/middleware/string_inquirer_spec.rb +30 -0
  205. data/spec/services/services/application_spec.rb +74 -0
  206. data/spec/services/services/context_spec.rb +48 -0
  207. data/spec/services/services/implementation_spec.rb +45 -0
  208. data/spec/services/services/interface_spec.rb +262 -0
  209. data/spec/services/services/permissions_spec.rb +249 -0
  210. data/spec/services/services/request_spec.rb +95 -0
  211. data/spec/services/services/response_spec.rb +250 -0
  212. data/spec/services/services/session_spec.rb +432 -0
  213. data/spec/spec_helper.rb +298 -0
  214. data/spec/utilities/utilities_spec.rb +537 -0
  215. data/spec/utilities/uuid_spec.rb +20 -0
  216. metadata +615 -0
@@ -0,0 +1,30 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe Hoodoo::StringInquirer do
4
+ it 'should define implicit methods ending in "?"' do
5
+ greeting = Hoodoo::StringInquirer.new( 'hello' )
6
+ expect(greeting.hello?()).to eq(true)
7
+ expect(greeting.hi?()).to eq(false)
8
+ end
9
+
10
+ it 'should not define implicit methods that do not end in "?"' do
11
+ greeting = Hoodoo::StringInquirer.new( 'hello' )
12
+ expect {
13
+ greeting.hello()
14
+ }.to raise_error(NoMethodError)
15
+ end
16
+
17
+ # The above tests don't cause proper coverage according to RCov, so force
18
+ # the issue...
19
+ #
20
+ context 'poke private API for code coverage' do
21
+ it 'should sigh quietly to itself' do
22
+ greeting = Hoodoo::StringInquirer.new( 'hello' )
23
+ expect(greeting.send(:respond_to_missing?, :hello?, false)).to eq(true)
24
+ expect(greeting.send(:method_missing, :hello?)).to eq(true)
25
+ expect {
26
+ greeting.send(:method_missing, :hello)
27
+ }.to raise_error(NoMethodError)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ class RSpecTestImplementationA < Hoodoo::Services::Implementation
4
+ end
5
+
6
+ class RSpecTestImplementationB < Hoodoo::Services::Implementation
7
+ end
8
+
9
+ class RSpecTestInterfaceA < Hoodoo::Services::Interface
10
+ interface :RSpecTestResource do
11
+ endpoint :rspec_test_application_a, RSpecTestImplementationA
12
+ end
13
+ end
14
+
15
+ class RSpecTestInterfaceB < Hoodoo::Services::Interface
16
+ interface :RSpecTestResource do
17
+ endpoint :rspec_test_application_b, RSpecTestImplementationA
18
+ end
19
+ end
20
+
21
+ class RSpecTestService < Hoodoo::Services::Service
22
+ end
23
+
24
+ class RSpecTestService2 < Hoodoo::Services::Service
25
+ end
26
+
27
+ describe Hoodoo::Services::Service do
28
+ it 'should complain about incorrect interface classes' do
29
+ expect {
30
+ RSpecTestService.comprised_of( Hash )
31
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Implementation::comprised_of expects Hoodoo::Services::Interface subclasses only - got 'Hash'")
32
+
33
+ expect {
34
+ RSpecTestService.comprised_of( Hoodoo::Services::Interface )
35
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Implementation::comprised_of expects Hoodoo::Services::Interface subclasses only - got 'Hoodoo::Services::Interface'")
36
+ end
37
+
38
+ it 'should complain if called directly' do
39
+ expect {
40
+ RSpecTestService.new.call( nil )
41
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Implementation subclasses should only be called through the middleware - add 'use Hoodoo::Services::Middleware' to (e.g.) config.ru")
42
+ end
43
+
44
+ it 'should correctly report its component classes' do
45
+ RSpecTestService.comprised_of( RSpecTestInterfaceA,
46
+ RSpecTestInterfaceB )
47
+
48
+ expect(RSpecTestService.component_interfaces).to eq([
49
+ RSpecTestInterfaceA,
50
+ RSpecTestInterfaceB
51
+ ])
52
+
53
+ expect(RSpecTestService.new.component_interfaces).to eq([
54
+ RSpecTestInterfaceA,
55
+ RSpecTestInterfaceB
56
+ ])
57
+ end
58
+
59
+ it 'allows multiple calls to declare component classes and removes duplicates' do
60
+ RSpecTestService2.comprised_of( RSpecTestInterfaceB )
61
+ RSpecTestService2.comprised_of( RSpecTestInterfaceA )
62
+ RSpecTestService2.comprised_of( RSpecTestInterfaceB )
63
+
64
+ expect(RSpecTestService2.component_interfaces).to eq([
65
+ RSpecTestInterfaceB,
66
+ RSpecTestInterfaceA
67
+ ])
68
+
69
+ expect(RSpecTestService2.new.component_interfaces).to eq([
70
+ RSpecTestInterfaceB,
71
+ RSpecTestInterfaceA
72
+ ])
73
+ end
74
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ class RSpecTestContextImplementation < Hoodoo::Services::Implementation
4
+ end
5
+
6
+ class RSpecTestContextInterface < Hoodoo::Services::Interface
7
+ interface :RSpecTestResource do
8
+ endpoint :rspec_test_service_stub, RSpecTestContextImplementation
9
+ end
10
+ end
11
+
12
+ class RSpecTestContext < Hoodoo::Services::Service
13
+ comprised_of RSpecTestContextInterface
14
+ end
15
+
16
+ describe Hoodoo::Services::Context do
17
+
18
+ it 'should initialise correctly' do
19
+ ses = Hoodoo::Services::Session.new
20
+ req = Hoodoo::Services::Request.new
21
+ res = Hoodoo::Services::Response.new( Hoodoo::UUID.generate() )
22
+ mid = Hoodoo::Services::Middleware.new( RSpecTestContext.new )
23
+ int = Hoodoo::Services::Middleware::Interaction.new( {}, mid )
24
+
25
+ con = Hoodoo::Services::Context.new( ses, req, res, int )
26
+
27
+ expect(con.session).to eq(ses)
28
+ expect(con.request).to eq(req)
29
+ expect(con.response).to eq(res)
30
+ expect(con.owning_interaction).to eq(int)
31
+ end
32
+
33
+ it 'should report endpoints' do
34
+ ses = Hoodoo::Services::Session.new
35
+ req = Hoodoo::Services::Request.new
36
+ res = Hoodoo::Services::Response.new( Hoodoo::UUID.generate() )
37
+ mid = Hoodoo::Services::Middleware.new( RSpecTestContext.new )
38
+ int = Hoodoo::Services::Middleware::Interaction.new( {}, mid )
39
+
40
+ con = Hoodoo::Services::Context.new( ses, req, res, int )
41
+
42
+ expect(con.resource(:RSpecTestResource)).to be_a( Hoodoo::Services::Middleware::InterResourceLocal )
43
+ expect(con.resource(:RSpecTestResource).instance_variable_get( '@discovery_result' ) ).to be_a( Hoodoo::Services::Discovery::ForLocal )
44
+ expect(con.resource(:RSpecTestResource).instance_variable_get( '@discovery_result' ) .interface_class).to eq( RSpecTestContextInterface )
45
+ expect(con.resource(:AnotherResource)).to be_a( Hoodoo::Services::Middleware::InterResourceRemote )
46
+ expect(con.resource(:AnotherResource).instance_variable_get( '@discovery_result' ) ).to be_a( Hoodoo::Services::Discovery::ForRemote )
47
+ end
48
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ class RSpecTestImplementationImplementation < Hoodoo::Services::Implementation
4
+ end
5
+
6
+ class RSpecTestImplementationInterface < Hoodoo::Services::Interface
7
+ interface :RSpecTestResource do
8
+ endpoint :rspec_test_service_stub, RSpecTestImplementationImplementation
9
+ end
10
+ end
11
+
12
+ class RSpecTestImplementation < Hoodoo::Services::Service
13
+ comprised_of RSpecTestImplementationInterface
14
+ end
15
+
16
+ describe Hoodoo::Services::Implementation do
17
+ it 'should raise base class exceptions' do
18
+ mid = Hoodoo::Services::Middleware.new( RSpecTestImplementation.new )
19
+ int = Hoodoo::Services::Middleware::Interaction.new( {}, mid )
20
+ con = int.context
21
+ imp = Hoodoo::Services::Implementation.new
22
+
23
+ expect {
24
+ imp.list( con )
25
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Implementation subclasses must implement 'list'")
26
+
27
+ expect {
28
+ imp.show( con )
29
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Implementation subclasses must implement 'show'")
30
+
31
+ expect {
32
+ imp.create( con )
33
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Implementation subclasses must implement 'create'")
34
+
35
+ expect {
36
+ imp.update( con )
37
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Implementation subclasses must implement 'update'")
38
+
39
+ expect {
40
+ imp.delete( con )
41
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Implementation subclasses must implement 'delete'")
42
+
43
+ expect( imp.verify( con, :show ) ).to eq( Hoodoo::Services::Permissions::DENY )
44
+ end
45
+ end
@@ -0,0 +1,262 @@
1
+ require 'spec_helper'
2
+
3
+ class RSpecTestInterfaceImplementationA < Hoodoo::Services::Implementation
4
+ end
5
+
6
+ class RSpecTestInterfaceImplementationB < Hoodoo::Services::Implementation
7
+ end
8
+
9
+ class RSpecTestInterfaceInterfaceA < Hoodoo::Services::Interface
10
+ interface 'RSpecTestInterfaceAResource' do
11
+ version 42
12
+ endpoint :rspec_test_interface_a, RSpecTestInterfaceImplementationA
13
+ actions :show, :create, :delete
14
+ embeds :embed_one, :embed_two, :embed_three
15
+
16
+ to_list do
17
+ limit 25
18
+ sort :sort_one => [ :left, :right ], default( :sort_two ) => [ :up, :down ]
19
+ search :search_one, :search_two, :search_three
20
+ filter :filter_one, :filter_two, :filter_three
21
+ end
22
+
23
+ to_create do
24
+ text :foo
25
+ enum :bar, :from => [ 'baz', :boo ]
26
+ end
27
+
28
+ to_update do
29
+ text :hello
30
+ uuid :world, :resource => :Earth
31
+ end
32
+
33
+ errors_for 'transaction' do
34
+ error 'duplicate_transaction', status: 409, message: 'Duplicate transaction', :required => [ :client_uid ]
35
+ end
36
+ end
37
+ end
38
+
39
+ class RSpecTestInterfaceInterfaceB < Hoodoo::Services::Interface
40
+ interface :RSpecTestInterfaceBResource do
41
+ endpoint :rspec_test_interface_b, RSpecTestInterfaceImplementationB
42
+
43
+ to_create do
44
+ text :one
45
+ text :two, :required => true
46
+ end
47
+
48
+ update_same_as_create
49
+ end
50
+ end
51
+
52
+ class RSpecTestInterfaceInterfaceDefault < Hoodoo::Services::Interface
53
+ interface :RSpecTestInterfaceDefaultResource do
54
+ endpoint :rspec_test_interface_default, RSpecTestInterfaceImplementationA # (sic.)
55
+ end
56
+ end
57
+
58
+ describe Hoodoo::Services::Interface do
59
+
60
+ context 'DSL test classes' do
61
+
62
+ it 'acquires defaults' do
63
+ expect(RSpecTestInterfaceInterfaceDefault.version).to eq(1)
64
+ expect(RSpecTestInterfaceInterfaceDefault.endpoint).to eq(:rspec_test_interface_default)
65
+ expect(RSpecTestInterfaceInterfaceDefault.resource).to be_a(Symbol)
66
+ expect(RSpecTestInterfaceInterfaceDefault.resource).to eq(:RSpecTestInterfaceDefaultResource)
67
+ expect(RSpecTestInterfaceInterfaceDefault.implementation).to eq(RSpecTestInterfaceImplementationA)
68
+ expect(RSpecTestInterfaceInterfaceDefault.actions).to eq(Set.new([:list, :show, :create, :update, :delete]))
69
+ expect(RSpecTestInterfaceInterfaceDefault.public_actions).to be_empty
70
+ expect(RSpecTestInterfaceInterfaceDefault.embeds).to be_empty
71
+ expect(RSpecTestInterfaceInterfaceDefault.to_list.limit).to eq(50)
72
+ expect(RSpecTestInterfaceInterfaceDefault.to_list.sort).to eq({'created_at' => Set.new(['desc', 'asc'])})
73
+ expect(RSpecTestInterfaceInterfaceDefault.to_list.default_sort_key).to eq('created_at')
74
+ expect(RSpecTestInterfaceInterfaceDefault.to_list.default_sort_direction).to eq('desc')
75
+ expect(RSpecTestInterfaceInterfaceDefault.to_list.search).to be_empty
76
+ expect(RSpecTestInterfaceInterfaceDefault.to_list.filter).to be_empty
77
+ expect(RSpecTestInterfaceInterfaceDefault.to_create).to be_nil
78
+ expect(RSpecTestInterfaceInterfaceDefault.to_update).to be_nil
79
+ end
80
+
81
+ # This is checking most of the DSL in non-error call cases
82
+ #
83
+ it 'should be correctly configured (A)' do
84
+ expect(RSpecTestInterfaceInterfaceA.version).to eq(42)
85
+ expect(RSpecTestInterfaceInterfaceA.endpoint).to eq(:rspec_test_interface_a)
86
+ expect(RSpecTestInterfaceInterfaceA.resource).to be_a(Symbol)
87
+ expect(RSpecTestInterfaceInterfaceA.resource).to eq(:RSpecTestInterfaceAResource)
88
+ expect(RSpecTestInterfaceInterfaceA.implementation).to eq(RSpecTestInterfaceImplementationA)
89
+ expect(RSpecTestInterfaceInterfaceA.actions).to eq(Set.new([:show, :create, :delete]))
90
+ expect(RSpecTestInterfaceInterfaceA.embeds).to eq(['embed_one', 'embed_two', 'embed_three'])
91
+ expect(RSpecTestInterfaceInterfaceA.to_list.limit).to eq(25)
92
+ expect(RSpecTestInterfaceInterfaceA.to_list.sort).to eq({'created_at'=>Set.new(['desc', 'asc']), 'sort_one' => Set.new(['left', 'right']), 'sort_two' => Set.new(['up', 'down'])})
93
+ expect(RSpecTestInterfaceInterfaceA.to_list.default_sort_key).to eq('sort_two')
94
+ expect(RSpecTestInterfaceInterfaceA.to_list.default_sort_direction).to eq('up')
95
+ expect(RSpecTestInterfaceInterfaceA.to_list.search).to eq(['search_one', 'search_two', 'search_three'])
96
+ expect(RSpecTestInterfaceInterfaceA.to_list.filter).to eq(['filter_one', 'filter_two', 'filter_three'])
97
+ expect(RSpecTestInterfaceInterfaceA.to_create).to_not be_nil
98
+ expect(RSpecTestInterfaceInterfaceA.to_create.get_schema().properties['foo']).to be_a(Hoodoo::Presenters::Text)
99
+ expect(RSpecTestInterfaceInterfaceA.to_create.get_schema().properties['bar']).to be_a(Hoodoo::Presenters::Enum)
100
+ expect(RSpecTestInterfaceInterfaceA.to_create.get_schema().properties['bar'].from).to eq(["baz", "boo"])
101
+ expect(RSpecTestInterfaceInterfaceA.to_update.get_schema().properties['hello']).to be_a(Hoodoo::Presenters::Text)
102
+ expect(RSpecTestInterfaceInterfaceA.to_update.get_schema().properties['world']).to be_a(Hoodoo::Presenters::UUID)
103
+ expect(RSpecTestInterfaceInterfaceA.to_update.get_schema().properties['world'].resource).to eq(:Earth)
104
+ expect(RSpecTestInterfaceInterfaceA.errors_for.describe('transaction.duplicate_transaction')).to eq({'status' => 409, 'message' => 'Duplicate transaction', 'required' => [ :client_uid ]})
105
+ end
106
+
107
+ it 'should be correctly configured (B)' do
108
+
109
+ # Check that to_create has 'required' fields present.
110
+ #
111
+ expect(RSpecTestInterfaceInterfaceB.to_create).to_not be_nil
112
+ expect(RSpecTestInterfaceInterfaceB.to_create.get_schema().properties['two'].required).to be(true)
113
+
114
+ # Test #update_same_as_create.
115
+ #
116
+ expect(RSpecTestInterfaceInterfaceB.to_update).to_not be_nil
117
+ expect(RSpecTestInterfaceInterfaceB.to_update.get_schema().properties['one']).to be_a(Hoodoo::Presenters::Text)
118
+ expect(RSpecTestInterfaceInterfaceB.to_update.get_schema().properties['two']).to be_a(Hoodoo::Presenters::Text)
119
+
120
+ # Tests both to_update / update_same_as_create not having 'required'
121
+ # fields enforced.
122
+ #
123
+ expect(RSpecTestInterfaceInterfaceB.to_update.get_schema().properties['two'].required).to be(false)
124
+ end
125
+ end
126
+
127
+ context 'DSL errors' do
128
+ it 'should complain about interface redefinition' do
129
+ expect {
130
+ RSpecTestInterfaceInterfaceB.interface :FooB do
131
+ end
132
+ }.to raise_error(RuntimeError, 'Hoodoo::Services::Interface subclass unexpectedly ran ::interface more than once')
133
+ end
134
+
135
+ it 'should complain about no endpoint' do
136
+ class RSpecTestInterfaceInterfaceC < Hoodoo::Services::Interface
137
+ end
138
+
139
+ expect {
140
+ RSpecTestInterfaceInterfaceC.interface :FooC do
141
+ end
142
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Interface subclasses must always call the 'endpoint' DSL method in their interface descriptions")
143
+ end
144
+
145
+ it 'should complain about incorrect implementation classes' do
146
+ class RSpecTestInterfaceInterfaceD < Hoodoo::Services::Interface
147
+ end
148
+
149
+ expect {
150
+ RSpecTestInterfaceInterfaceD.interface :FooD do
151
+ endpoint :an_endpoint, Hoodoo::Services::Implementation # Not a *subclass*, so just as invalid as some other unrelated Class
152
+ end
153
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Interface#endpoint must provide Hoodoo::Services::Implementation subclasses, but 'Hoodoo::Services::Implementation' was given instead")
154
+ end
155
+
156
+ context 'in #action' do
157
+ it 'should complain about incorrect actions' do
158
+ class RSpecTestInterfaceImplementationE < Hoodoo::Services::Implementation
159
+ end
160
+ class RSpecTestInterfaceInterfaceE < Hoodoo::Services::Interface
161
+ end
162
+
163
+ expect {
164
+ RSpecTestInterfaceInterfaceE.interface :FooE do
165
+ endpoint :an_endpoint, RSpecTestInterfaceImplementationE
166
+ actions :create, :made_this_up, :delete, :made_this_up_too
167
+ end
168
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Interface#actions does not recognise one or more actions: 'made_this_up, made_this_up_too'")
169
+ end
170
+ end
171
+
172
+ context 'in #public_action' do
173
+ it 'should complain about incorrect actions' do
174
+ class RSpecTestInterfaceImplementationF < Hoodoo::Services::Implementation
175
+ end
176
+ class RSpecTestInterfaceInterfaceF < Hoodoo::Services::Interface
177
+ end
178
+
179
+ expect {
180
+ RSpecTestInterfaceInterfaceF.interface :FooF do
181
+ endpoint :an_endpoint, RSpecTestInterfaceImplementationF
182
+ public_actions :create, :made_this_up, :delete, :made_this_up_too
183
+ end
184
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Interface#public_actions does not recognise one or more actions: 'made_this_up, made_this_up_too'")
185
+ end
186
+ end
187
+
188
+ context 'in #public_action' do
189
+ it 'should complain about incorrect actions' do
190
+ class RSpecTestInterfaceImplementationG < Hoodoo::Services::Implementation
191
+ end
192
+ class RSpecTestInterfaceInterfaceG < Hoodoo::Services::Interface
193
+ end
194
+
195
+ expect {
196
+ RSpecTestInterfaceInterfaceG.interface :FooG do
197
+ endpoint :an_endpoint, RSpecTestInterfaceImplementationG
198
+ secure_log_for :create => :both, :made_this_up => :request, :delete => :response, :made_this_up_too => :both
199
+ end
200
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Interface#secure_log_for does not recognise one or more actions: 'made_this_up, made_this_up_too'")
201
+ end
202
+ end
203
+
204
+ # This is exercised in non-failure cases by
205
+ # middleware_permissions_spec.rb.
206
+ #
207
+ context 'in #additional_permissions_for' do
208
+ it 'should complain about a missing block' do
209
+ class RSpecTestInterfaceImplementationH < Hoodoo::Services::Implementation
210
+ end
211
+ class RSpecTestInterfaceInterfaceH < Hoodoo::Services::Interface
212
+ end
213
+
214
+ expect {
215
+ RSpecTestInterfaceInterfaceH.interface :FooH do
216
+ endpoint :an_endpoint, RSpecTestInterfaceImplementationH
217
+ additional_permissions_for( :show )
218
+ end
219
+ }.to raise_error(RuntimeError, 'Hoodoo::Services::Interface#additional_permissions_for must be passed a block')
220
+ end
221
+ end
222
+
223
+ # This is really an internal sanity test for code coverage purposes...
224
+ #
225
+ it 'should complain about incorrect instantiation' do
226
+ expect {
227
+ Hoodoo::Services::Interface::ToListDSL.new( Array.new ) do
228
+ end
229
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Interface::ToListDSL\#initialize requires a Hoodoo::Services::Interface::ToList instance - got 'Array'")
230
+ end
231
+
232
+ context 'in #limit' do
233
+ it 'should complain about incorrect types' do
234
+ expect {
235
+ Hoodoo::Services::Interface::ToListDSL.new( Hoodoo::Services::Interface::ToList.new ) do
236
+ limit "hello"
237
+ end
238
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Interface::ToListDSL\#limit requires an Integer - got 'String'")
239
+ end
240
+ end
241
+
242
+ context 'in #sort' do
243
+ it 'should complain about incorrect types' do
244
+ expect {
245
+ Hoodoo::Services::Interface::ToListDSL.new( Hoodoo::Services::Interface::ToList.new ) do
246
+ sort "hello"
247
+ end
248
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Interface::ToListDSL\#sort requires a Hash - got 'String'")
249
+ end
250
+ end
251
+
252
+ context 'in #default' do
253
+ it 'should complain about incorrect types' do
254
+ expect {
255
+ Hoodoo::Services::Interface::ToListDSL.new( Hoodoo::Services::Interface::ToList.new ) do
256
+ default 42
257
+ end
258
+ }.to raise_error(RuntimeError, "Hoodoo::Services::Interface::ToListDSL\#default requires a String or Symbol - got 'Fixnum'")
259
+ end
260
+ end
261
+ end
262
+ end