hoodoo 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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