axel 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +21 -0
  3. data/.octopolo.yml +2 -0
  4. data/.rspec +2 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +23 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +271 -0
  11. data/Rakefile +13 -0
  12. data/app/models/axel/api_proxy.rb +86 -0
  13. data/app/models/axel/associations/base.rb +64 -0
  14. data/app/models/axel/associations/belongs_to.rb +43 -0
  15. data/app/models/axel/associations/has_many.rb +29 -0
  16. data/app/models/axel/associations/has_one.rb +30 -0
  17. data/app/models/axel/payload.rb +4 -0
  18. data/app/models/axel/payload/base.rb +107 -0
  19. data/app/models/axel/payload/errors.rb +62 -0
  20. data/app/models/axel/payload/metadata.rb +57 -0
  21. data/app/models/axel/querier.rb +166 -0
  22. data/app/models/axel/router.rb +119 -0
  23. data/app/models/axel/service_resource.rb +4 -0
  24. data/app/models/axel/service_resource/associations.rb +80 -0
  25. data/app/models/axel/service_resource/attributes.rb +23 -0
  26. data/app/models/axel/service_resource/automatic_resource.rb +23 -0
  27. data/app/models/axel/service_resource/base.rb +47 -0
  28. data/app/models/axel/service_resource/builder.rb +40 -0
  29. data/app/models/axel/service_resource/inspects.rb +17 -0
  30. data/app/models/axel/service_resource/payload_parser.rb +46 -0
  31. data/app/models/axel/service_resource/queries.rb +25 -0
  32. data/app/models/axel/service_resource/requesters.rb +49 -0
  33. data/app/models/axel/service_resource/routes.rb +19 -0
  34. data/app/models/axel/service_resource/typhoid_extensions.rb +134 -0
  35. data/app/views/axel/base/empty.json.erb +0 -0
  36. data/app/views/axel/base/empty.xml.builder +0 -0
  37. data/app/views/layouts/axel.json.jbuilder +7 -0
  38. data/app/views/layouts/axel.xml.builder +12 -0
  39. data/axel.gemspec +42 -0
  40. data/lib/axel.rb +56 -0
  41. data/lib/axel/application_extensions.rb +13 -0
  42. data/lib/axel/application_helper.rb +27 -0
  43. data/lib/axel/base_controller.rb +6 -0
  44. data/lib/axel/cascadable_attribute.rb +33 -0
  45. data/lib/axel/configurations/resource.rb +29 -0
  46. data/lib/axel/configurations/service.rb +28 -0
  47. data/lib/axel/configurator.rb +54 -0
  48. data/lib/axel/configurators/services.rb +29 -0
  49. data/lib/axel/controller_base.rb +27 -0
  50. data/lib/axel/controller_helpers.rb +209 -0
  51. data/lib/axel/controller_parameters.rb +32 -0
  52. data/lib/axel/engine.rb +14 -0
  53. data/lib/axel/inspector.rb +91 -0
  54. data/lib/axel/payload/remote_error.rb +14 -0
  55. data/lib/axel/request_options.rb +26 -0
  56. data/lib/axel/uri.rb +47 -0
  57. data/lib/axel/version.rb +3 -0
  58. data/lib/generators/axel/install_generator.rb +16 -0
  59. data/lib/generators/templates/README.md +22 -0
  60. data/lib/generators/templates/axel.rb +81 -0
  61. data/script/rails +5 -0
  62. data/spec/controllers/pages_controller_spec.rb +217 -0
  63. data/spec/dummy/README.rdoc +261 -0
  64. data/spec/dummy/Rakefile +7 -0
  65. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  66. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  67. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  68. data/spec/dummy/app/controllers/pages_controller.rb +6 -0
  69. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  70. data/spec/dummy/app/mailers/.gitkeep +0 -0
  71. data/spec/dummy/app/models/.gitkeep +0 -0
  72. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  73. data/spec/dummy/config.ru +4 -0
  74. data/spec/dummy/config/application.rb +62 -0
  75. data/spec/dummy/config/boot.rb +10 -0
  76. data/spec/dummy/config/database.yml +25 -0
  77. data/spec/dummy/config/environment.rb +5 -0
  78. data/spec/dummy/config/environments/development.rb +37 -0
  79. data/spec/dummy/config/environments/production.rb +67 -0
  80. data/spec/dummy/config/environments/test.rb +37 -0
  81. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  82. data/spec/dummy/config/initializers/inflections.rb +15 -0
  83. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  84. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  85. data/spec/dummy/config/initializers/session_store.rb +8 -0
  86. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  87. data/spec/dummy/config/locales/en.yml +5 -0
  88. data/spec/dummy/config/routes.rb +3 -0
  89. data/spec/dummy/db/development.sqlite3 +0 -0
  90. data/spec/dummy/db/test.sqlite3 +0 -0
  91. data/spec/dummy/lib/assets/.gitkeep +0 -0
  92. data/spec/dummy/log/.gitignore +1 -0
  93. data/spec/dummy/log/.gitkeep +0 -0
  94. data/spec/dummy/public/404.html +26 -0
  95. data/spec/dummy/public/422.html +26 -0
  96. data/spec/dummy/public/500.html +25 -0
  97. data/spec/dummy/public/favicon.ico +0 -0
  98. data/spec/dummy/script/rails +6 -0
  99. data/spec/envelope_integration_check.rb +96 -0
  100. data/spec/helpers/axel/application_helper_spec.rb +31 -0
  101. data/spec/lib/axel/associations/base_spec.rb +28 -0
  102. data/spec/lib/axel/associations/belongs_to_spec.rb +62 -0
  103. data/spec/lib/axel/associations/has_many_spec.rb +23 -0
  104. data/spec/lib/axel/associations/has_one_spec.rb +23 -0
  105. data/spec/lib/axel/configurations/resource_spec.rb +15 -0
  106. data/spec/lib/axel/configurations/service_spec.rb +31 -0
  107. data/spec/lib/axel/configurator_spec.rb +26 -0
  108. data/spec/lib/axel/configurators/services_spec.rb +37 -0
  109. data/spec/lib/axel/controller_base_spec.rb +16 -0
  110. data/spec/lib/axel/controller_parameters_spec.rb +31 -0
  111. data/spec/lib/axel/inspector_spec.rb +45 -0
  112. data/spec/lib/axel/request_options_spec.rb +50 -0
  113. data/spec/lib/axel/uri_spec.rb +42 -0
  114. data/spec/lib/axel_spec.rb +64 -0
  115. data/spec/models/axel/api_proxy_spec.rb +66 -0
  116. data/spec/models/axel/payload/errors_spec.rb +165 -0
  117. data/spec/models/axel/payload/metadata_spec.rb +141 -0
  118. data/spec/models/axel/querier_spec.rb +158 -0
  119. data/spec/models/axel/router_spec.rb +115 -0
  120. data/spec/models/axel/service_resource/base_spec.rb +244 -0
  121. data/spec/models/axel/service_resource/builder_spec.rb +64 -0
  122. data/spec/models/axel/service_resource/payload_parser_spec.rb +60 -0
  123. data/spec/spec_helper.rb +39 -0
  124. data/spec/support/address.rb +5 -0
  125. data/spec/support/persona.rb +15 -0
  126. data/spec/support/user.rb +6 -0
  127. data/spec/views/axel/base/empty_spec.rb +34 -0
  128. metadata +508 -0
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+ module Axel
3
+ module Payload
4
+ describe Metadata do
5
+ describe "class" do
6
+ subject { Metadata }
7
+ its(:root_node) { should == :metadata }
8
+ end
9
+
10
+ context "instance" do
11
+ before do
12
+ subject[:name] = "jon"
13
+ end
14
+
15
+ it "isn't paged" do
16
+ subject.paged?.should be_falsey
17
+ end
18
+
19
+ it "has 1 page" do
20
+ subject.total_pages.should == 1
21
+ end
22
+
23
+ describe "drops" do
24
+ context "with a drop" do
25
+ it "changes the boolean and drops the message" do
26
+ subject.drop?.should be_falsey
27
+ subject.drop!
28
+ subject.drop?.should be_truthy
29
+ subject.display.should == {}
30
+ end
31
+ end
32
+
33
+ context "without a drop" do
34
+ its(:display) { should == { "name" => "jon" } }
35
+ end
36
+ end
37
+
38
+ context "dup" do
39
+ specify { subject.attributes.should_not be(subject.dup.attributes) }
40
+ end
41
+
42
+ context "clone" do
43
+ specify { subject.attributes.should_not be(subject.clone.attributes) }
44
+ end
45
+
46
+ context "merge" do
47
+ let(:age_metadata) { Metadata.new age: 10 }
48
+ let(:name_metadata) { Metadata.new name: "tom" }
49
+
50
+ it "merges a different key" do
51
+ merged = subject.merge(age_metadata)
52
+ subject.should_not == merged
53
+ subject.attributes.should_not == merged.attributes
54
+ subject.attributes.should == { name: "jon" }.with_indifferent_access
55
+ end
56
+
57
+ it "merges a similar key" do
58
+ merged = subject.merge(name_metadata)
59
+ subject.attributes.should_not == merged.attributes
60
+ subject.attributes.should == { name: "jon" }.with_indifferent_access
61
+ end
62
+ end
63
+
64
+ context "paged" do
65
+ before do
66
+ subject[:pagination] = { total_pages: 2 }
67
+ end
68
+
69
+ it "isn't paged" do
70
+ subject.paged?.should be_truthy
71
+ end
72
+
73
+ it "has 1 page" do
74
+ subject.total_pages.should == 2
75
+ end
76
+ end
77
+
78
+ context "decode" do
79
+ let(:xml) do
80
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?><current_user><id type=\"integer\">1</id></current_user>"
81
+ end
82
+
83
+ let(:json) do
84
+ "{\"current_user\":{\"id\":1}}"
85
+ end
86
+
87
+ let(:ruby_hash) do
88
+ { current_user: { id: 1 } }
89
+ end
90
+
91
+ it "set the hash for json" do
92
+ subject[:json] = json
93
+ subject[:json].should == { "current_user" => { "id" => 1 } }
94
+ end
95
+
96
+ it "set the hash for xml" do
97
+ subject[:xml] = xml
98
+ subject[:xml].should == { "current_user" => { "id" => 1 } }
99
+ end
100
+
101
+ it "set the hash for a ruby hash" do
102
+ subject[:ruby_hash] = ruby_hash
103
+ subject[:ruby_hash].should == { current_user: { id: 1 } }.with_indifferent_access
104
+ end
105
+ end
106
+
107
+ context "merge!" do
108
+ let(:age_metadata) { Metadata.new age: 10 }
109
+ let(:name_metadata) { Metadata.new name: "tom" }
110
+
111
+ it "merges a different key" do
112
+ subject.merge! age_metadata
113
+ subject.attributes.should == { age: 10, name: "jon" }.with_indifferent_access
114
+ end
115
+
116
+ it "merges a similar key" do
117
+ subject.merge! name_metadata
118
+ subject.attributes.should == { name: "tom" }.with_indifferent_access
119
+ end
120
+ end
121
+
122
+ context "setting objects" do
123
+ it "set the object value" do
124
+ subject[:name].should == "jon"
125
+ subject["name"].should == "jon"
126
+ end
127
+ end
128
+
129
+ context "display" do
130
+ its(:display) { should == { name: "jon" }.with_indifferent_access }
131
+ its(:display?) { should == true }
132
+ end
133
+
134
+ context "formatting" do
135
+ its(:to_json) { should == { name: "jon" }.to_json }
136
+ its(:to_xml) { should == { name: "jon" }.to_xml(skip_instruct: true, root: :metadata) }
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,158 @@
1
+ require 'spec_helper'
2
+ SomeClass = Class.new do
3
+ def self.routes
4
+ {}
5
+ end
6
+
7
+ def self.retrieve_default_request_options(options)
8
+ Axel::RequestOptions.new({}, options).compiled
9
+ end
10
+ end
11
+
12
+ module Axel
13
+ describe Querier do
14
+ subject { Querier.new klass }
15
+ let(:klass) { SomeClass.tap { |c| c.stub request_uri: "http://localhost" } }
16
+
17
+ its(:klass) { should == klass }
18
+
19
+ before do
20
+ SomeClass.stub :request do
21
+ [SomeClass.new]
22
+ end
23
+ end
24
+
25
+ describe "paged" do
26
+ describe "paged, but not asked for" do
27
+ let(:returned) { [double(paged?: true)] }
28
+ it "should be requested once" do
29
+ klass.should_receive(:request).once.and_return(returned)
30
+ subject.to_a.should == returned
31
+ end
32
+ end
33
+
34
+ describe "paged requested" do
35
+ describe "nil element" do
36
+ it "returns empty array" do
37
+ klass.should_receive(:request).once.and_return([])
38
+ subject.paged.to_a.should == []
39
+ end
40
+ end
41
+
42
+ describe "single element" do
43
+ let(:returned) { [double(paged?: false)] }
44
+
45
+ it "returns singular array" do
46
+ klass.should_receive(:request).once.and_return(returned)
47
+ subject.paged.to_a.should == returned
48
+ end
49
+ end
50
+
51
+ describe "multiple pages" do
52
+ let(:returned) { [double(paged?: true, total_pages: 3)] }
53
+
54
+ it "returns singular array" do
55
+ klass.should_receive(:request).exactly(3).times.and_return(returned)
56
+ subject.paged.to_a.should == returned + returned + returned
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ describe "accidentally build an array" do
63
+ before do
64
+ subject.stub build_into_response_container: []
65
+ end
66
+
67
+ it "successfully builds from a list" do
68
+ subject.send :run_requests # should not error, want full trace if it DOES error
69
+ end
70
+ end
71
+
72
+ describe "to_a" do
73
+ it "calls run_requests" do
74
+ subject.should_receive(:run_requests).once.and_return []
75
+ subject.to_a
76
+ end
77
+ end
78
+
79
+ describe "path" do
80
+ subject { Querier.new(klass).at_path("some_resource", "1") }
81
+ before do
82
+ subject.class.any_instance.stub manual_uri: "http://localhost"
83
+ end
84
+
85
+ it "has a built request_uri" do
86
+ subject.send(:request_uri).should == "http://localhost/some_resource/1"
87
+ end
88
+
89
+ it "has appended the request_uri" do
90
+ subject.at_path("another_resource")
91
+ .send(:request_uri).should == "http://localhost/some_resource/1/another_resource"
92
+ end
93
+ end
94
+
95
+ describe "where" do
96
+ subject { Querier.new(klass).where(id: 1) }
97
+ it "sets parameters" do
98
+ subject.send(:retrieve_request_options).should == {"headers"=>{"Content-Type"=>"application/json"}, "params"=>{"id"=>1}}
99
+ end
100
+
101
+ it "has appended the request_uri" do
102
+ subject.where(name: "jon").send(:retrieve_request_options).should == {"headers"=>{"Content-Type"=>"application/json"}, "params"=>{"id"=>1, "name"=>"jon"}}
103
+ end
104
+ end
105
+
106
+ describe "uri" do
107
+ subject { Querier.new(klass).uri("http://user-service.dev") }
108
+
109
+ it "has a built request_uri" do
110
+ subject.send(:manual_uri).should == "http://user-service.dev"
111
+ subject.send(:request_uri).should == "http://user-service.dev"
112
+ end
113
+
114
+ it "has appended the request_uri" do
115
+ subject.uri("http://other-url").send(:manual_uri).should == "http://other-url"
116
+ subject.uri("http://other-url").send(:request_uri).should == "http://other-url"
117
+ end
118
+ end
119
+
120
+ describe "none" do
121
+ it "forces empty" do
122
+ subject.none == []
123
+ end
124
+ end
125
+
126
+ describe "reload" do
127
+ before do
128
+ subject.send :loaded=, true
129
+ subject.send :records=, [1,2,3]
130
+ end
131
+
132
+ it "resets variables and tries to force a reload of data" do
133
+ subject.loaded?.should be_truthy
134
+ subject.send(:records).should == [1,2,3]
135
+ subject.reload
136
+ subject.loaded?.should be_falsey
137
+ subject.send(:records).should == []
138
+ end
139
+ end
140
+
141
+ describe "enumerations" do
142
+ it { should respond_to :each }
143
+ it { should respond_to :first }
144
+ it { should respond_to :last }
145
+
146
+ its(:each) { should be_an Enumerator }
147
+ end
148
+
149
+ describe "loaded?" do
150
+ its(:loaded?) { should == false }
151
+ describe 'with ran requests' do
152
+ it "becomes loaded when to_a ran" do
153
+ expect { subject.to_a }.to change { subject.loaded? }.from(false).to(true)
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+ module Axel
3
+ SomeClass = Class.new ServiceResource::Base
4
+ SomeOtherClass = Class.new ServiceResource::Base
5
+
6
+ describe Router do
7
+ subject { Router.new(klass, path, method_name, options) }
8
+ let(:path) { "users/:id/personas/:persona_id" }
9
+ let(:klass) { SomeClass }
10
+ let(:method_name) { :user_persona }
11
+ let(:options) { {} }
12
+
13
+ its(:parameters) { should == ["id", "persona_id"] }
14
+ its(:arity) { should == 2 }
15
+
16
+ before do
17
+ klass.stub request_uri: "http://localhost", site: "http://localhost"
18
+ end
19
+
20
+ describe "with custom class filler" do
21
+ describe "given class constant" do
22
+ let(:options) { { class: SomeOtherClass } }
23
+ let(:querier_stub) { double }
24
+ it "calls via some other class" do
25
+ SomeOtherClass.should_receive(:querier).and_return querier_stub
26
+ querier_stub.should_receive(:without_default_path).and_return querier_stub
27
+ querier_stub.should_receive(:at_path).and_return querier_stub
28
+ querier_stub.should_receive(:request_options).and_return querier_stub
29
+ subject.route 1
30
+ end
31
+ end
32
+
33
+ describe "given class name" do
34
+ let(:options) { { class_name: "axel/some_other_class" } }
35
+ let(:querier_stub) { double }
36
+ it "calls via some other class" do
37
+ SomeOtherClass.should_receive(:querier).and_return querier_stub
38
+ querier_stub.should_receive(:without_default_path).and_return querier_stub
39
+ querier_stub.should_receive(:at_path).and_return querier_stub
40
+ querier_stub.should_receive(:request_options).and_return querier_stub
41
+ subject.route 1
42
+ end
43
+ end
44
+ end
45
+
46
+ context "no arity" do
47
+ let(:path) { "users" }
48
+ let(:route_with_options) { subject.route(params: { some_param: 1 }) }
49
+ its(:arity) { should == 0 }
50
+ it "can route with regular params and request options" do
51
+ route_with_options.send(:extra_paths).should == ["users"]
52
+ route_with_options.send(:retrieve_request_options).should == {
53
+ "headers" => { "Content-Type"=>"application/json" },
54
+ "params" => { "some_param"=>1 }
55
+ }
56
+ end
57
+ end
58
+
59
+ context "route" do
60
+ let(:regular_routed) { subject.route(1,2) }
61
+ let(:hash_routed) { subject.route(id: 1, persona_id: 2) }
62
+ let(:regular_routed_with_request_options) { subject.route(1, 2, params: { some_param: 1 }) }
63
+ let(:hash_routed_with_request_options) { subject.route({ id: 1, persona_id: 2 }, { params: { some_param: 1 } }) }
64
+ it "can route with regular params" do
65
+ regular_routed.send(:extra_paths).should == ["users/1/personas/2"]
66
+ regular_routed.send(:retrieve_request_options).should == {
67
+ "headers" => { "Content-Type"=>"application/json" }
68
+ }
69
+ end
70
+
71
+ it "can route with hash params" do
72
+ hash_routed.send(:extra_paths).should == ["users/1/personas/2"]
73
+ hash_routed.send(:retrieve_request_options).should == {
74
+ "headers" => { "Content-Type"=>"application/json" }
75
+ }
76
+ end
77
+
78
+ it "can route with regular params and request options" do
79
+ regular_routed_with_request_options.send(:extra_paths).should == ["users/1/personas/2"]
80
+ regular_routed_with_request_options.send(:retrieve_request_options).should == {
81
+ "headers" => { "Content-Type"=>"application/json" },
82
+ "params" => { "some_param"=>1 }
83
+ }
84
+ end
85
+
86
+ it "can route with hash params and request options" do
87
+ hash_routed_with_request_options.send(:extra_paths).should == ["users/1/personas/2"]
88
+ hash_routed_with_request_options.send(:retrieve_request_options).should == {
89
+ "headers" => { "Content-Type"=>"application/json" },
90
+ "params" => { "some_param"=>1 }
91
+ }
92
+ end
93
+
94
+ context "with arity of 1" do
95
+ let(:path) { "users/:id/personas" }
96
+ let(:hash_routed) { subject.route({ id: 1}) }
97
+ let(:hash_routed_with_request_options) { subject.route({ id: 1}, { params: { some_param: 1 } }) }
98
+ it "can route with hash params" do
99
+ hash_routed.send(:extra_paths).should == ["users/1/personas"]
100
+ hash_routed.send(:retrieve_request_options).should == {
101
+ "headers" => { "Content-Type"=>"application/json" }
102
+ }
103
+ end
104
+
105
+ it "can route with hash params and request options" do
106
+ hash_routed_with_request_options.send(:extra_paths).should == ["users/1/personas"]
107
+ hash_routed_with_request_options.send(:retrieve_request_options).should == {
108
+ "headers" => { "Content-Type"=>"application/json" },
109
+ "params" => { "some_param"=>1 }
110
+ }
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,244 @@
1
+ require 'spec_helper'
2
+ require 'json'
3
+ FakeResource = Class.new Axel::ServiceResource::Base
4
+ module Axel
5
+ module ServiceResource
6
+ describe Base do
7
+ context "class" do
8
+ subject { Base }
9
+
10
+ context "#load_values" do
11
+ let(:old_attributes) { { key_1: 'value_1', key_2: 'value_2' }.with_indifferent_access }
12
+ let(:response_body) { '{"result":{"key_1":"value_1_mod"}}' }
13
+ let(:new_attributes) { ::JSON.parse(response_body)['result'] }
14
+ let(:object) { FakeResource.new(old_attributes) }
15
+ let(:response) { double(body: response_body, success?: true, code: 200) }
16
+
17
+ it 'merges attributes' do
18
+ subject.load_values(object, response)
19
+ object.attributes.should eq(old_attributes.merge(new_attributes))
20
+ end
21
+ end
22
+
23
+ context "routes" do
24
+ its(:routes) { should be_a HashWithIndifferentAccess }
25
+ context "defining route" do
26
+ after { subject.instance_variable_set("@_routes", nil) }
27
+ it "sets up a route" do
28
+ subject.should_not respond_to :user_with_id
29
+ subject.route "user/:id", :user_with_id
30
+ subject.should respond_to :user_with_id
31
+ end
32
+ end
33
+ end
34
+
35
+ context "site" do
36
+ context "without setting site" do
37
+ before { subject.stub(resource: double(base_url: "http://some-url")) }
38
+
39
+ its(:site) { should == "http://some-url" }
40
+ end
41
+
42
+ context "manual set site" do
43
+ before { subject.site("http://some-other-url") }
44
+ after { subject.instance_variable_set("@site", nil) }
45
+ it "set the site" do
46
+ subject.site.should == "http://some-other-url"
47
+ end
48
+ end
49
+ end
50
+
51
+ context "path" do
52
+ context "without setting path" do
53
+ context "without resource" do
54
+ its(:path) { should == "bases" }
55
+ end
56
+
57
+ context "with resource" do
58
+ before { subject.stub(resource: double(path: "resources")) }
59
+
60
+ its(:path) { should == "resources" }
61
+ end
62
+ end
63
+
64
+ context "manual set path" do
65
+ context "with resource" do
66
+ before { subject.stub(resource: double(path: "resources")) }
67
+
68
+ it "sets resource path" do
69
+ subject.resource.should_receive(:path=).once
70
+ subject.path "some_path"
71
+ end
72
+ end
73
+ end
74
+
75
+ context "without resource" do
76
+ before { subject.stub resource: nil }
77
+ after { subject.instance_variable_set("@path", nil) }
78
+ it "sets instance variable" do
79
+ subject.path "some_other_path"
80
+ subject.instance_variable_get("@path").should == "some_other_path"
81
+ end
82
+ end
83
+ end
84
+
85
+ context "querier" do
86
+ its(:querier) { should be_a Axel::Querier }
87
+ it "has a querier where self is the klass" do
88
+ subject.querier.klass.should == Base
89
+ end
90
+ end
91
+
92
+ context "resource_name" do
93
+ # testing order messes with the name
94
+ before { subject.instance_variable_set("@_resource_name", nil) }
95
+ after { subject.instance_variable_set("@_resource_name", nil) }
96
+ it "sets the resource name and makes accessible" do
97
+ subject.resource_name.should == "bases"
98
+ subject.resource_name "users"
99
+ subject.resource_name.should == "users"
100
+ end
101
+ end
102
+
103
+ context "resource" do
104
+ # testing order messes with the name
105
+ before { subject.instance_variable_set("@_resource_name", nil) }
106
+ after { subject.instance_variable_set("@_resource_name", nil) }
107
+ # for the should_receive
108
+ before { Axel.stub(resources: double) }
109
+ it "tries based on the class name" do
110
+ Axel.resources.should_receive(:[]).with "bases"
111
+ subject.resource
112
+ end
113
+
114
+ it "with a resource name set it tries that name" do
115
+ subject.resource_name "users"
116
+ Axel.resources.should_receive(:[]).with "users"
117
+ subject.resource
118
+ subject.send(:instance_variable_set, "@_resource_name", nil)
119
+ end
120
+ end
121
+
122
+ describe "uri_join" do
123
+ it "builds a id path" do
124
+ subject.uri_join("http://localhost", 1).should == "http://localhost/1"
125
+ end
126
+
127
+ it "builds a id path with extra" do
128
+ subject.uri_join("http://localhost", "1/", "/personas/").should == "http://localhost/1/personas"
129
+ end
130
+
131
+ it "just one" do
132
+ subject.uri_join("http://localhost").should == "http://localhost"
133
+ end
134
+ end
135
+
136
+ context "#request" do
137
+ let(:request_builder) { double }
138
+
139
+ before do
140
+ subject.should_receive(:build_request).with("http://localhost", { 'headers' => { 'Content-Type' => 'application/json'} }).and_return request_builder
141
+ request_builder.should_receive(:run).once
142
+ end
143
+
144
+ it "builds and runs synchronous request with typhoid" do
145
+ subject.request "http://localhost"
146
+ end
147
+ end
148
+
149
+ context "#inherited" do
150
+ subject { FakeResource }
151
+ context "it setup accessors" do
152
+ context "instance" do
153
+ subject { FakeResource.new }
154
+ it { should respond_to :id }
155
+ it { should respond_to :id= }
156
+ it { should respond_to :uri }
157
+ it { should respond_to :uri= }
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ context "instance" do
164
+ subject { Base.new params }
165
+ let(:params) { {} }
166
+
167
+ context "resource_exception" do
168
+ context "remote errors" do
169
+ let(:remote_errors) { Payload::Errors.new status: 404, messages: ["Fail!"] }
170
+ before do
171
+ subject.stub remote_errors: remote_errors
172
+ end
173
+
174
+ it "sets error resource exception" do
175
+ subject.resource_exception.to_s.should == "Failed. HTTP Status: 404, Messages: Fail!"
176
+ end
177
+ end
178
+ end
179
+
180
+ context "new instance" do
181
+ context "without envelope response" do
182
+ let(:params) { { id: 1 } }
183
+
184
+ its(:envelope?) { should be_falsey }
185
+
186
+ its(:metadata) { should be_a Payload::Metadata }
187
+ it "sets no metadata" do
188
+ subject.metadata.attributes.should == {}
189
+ end
190
+
191
+ its(:remote_errors) { should be_a Payload::Errors }
192
+ it "sets error" do
193
+ subject.remote_errors.status_code.should == 200
194
+ subject.remote_errors.messages.should == []
195
+ end
196
+
197
+ its(:result) { should == { id: 1 }.with_indifferent_access }
198
+ it "converts attributes to result" do
199
+ subject.result.should == subject.attributes
200
+ end
201
+ end
202
+
203
+ context "with envelope response" do
204
+ let(:params) { { metadata: { current_user: { id: 1 } }, result: { id: 1 } } }
205
+
206
+ its(:envelope?) { should be_truthy }
207
+
208
+ its(:metadata) { should be_a Payload::Metadata }
209
+ it "sets metadata" do
210
+ subject.metadata[:current_user].should == { id: 1 }.with_indifferent_access
211
+ end
212
+
213
+ its(:remote_errors) { should be_a Payload::Errors }
214
+ it "sets error" do
215
+ subject.remote_errors.status_code.should == 200
216
+ subject.remote_errors.messages.should == []
217
+ end
218
+
219
+ its(:result) { should == { id: 1 }.with_indifferent_access }
220
+ it "converts attributes to result" do
221
+ subject.result.should == subject.attributes
222
+ end
223
+ end
224
+ end
225
+
226
+ context "request_uri" do
227
+ context "uri set by incoming object" do
228
+ let(:params) { { metadata: { current_user: { id: 1 } }, result: { id: 1, uri: "http://localhost/users" } } }
229
+
230
+ its(:request_uri) { should == "http://localhost/users" }
231
+ end
232
+
233
+ context "uri computed" do
234
+ before do
235
+ Base.stub site: "http://localhost", path: "users"
236
+ end
237
+
238
+ its(:request_uri) { should == "http://localhost/users" }
239
+ end
240
+ end
241
+ end
242
+ end
243
+ end
244
+ end