axel 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +21 -0
- data/.octopolo.yml +2 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +23 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +271 -0
- data/Rakefile +13 -0
- data/app/models/axel/api_proxy.rb +86 -0
- data/app/models/axel/associations/base.rb +64 -0
- data/app/models/axel/associations/belongs_to.rb +43 -0
- data/app/models/axel/associations/has_many.rb +29 -0
- data/app/models/axel/associations/has_one.rb +30 -0
- data/app/models/axel/payload.rb +4 -0
- data/app/models/axel/payload/base.rb +107 -0
- data/app/models/axel/payload/errors.rb +62 -0
- data/app/models/axel/payload/metadata.rb +57 -0
- data/app/models/axel/querier.rb +166 -0
- data/app/models/axel/router.rb +119 -0
- data/app/models/axel/service_resource.rb +4 -0
- data/app/models/axel/service_resource/associations.rb +80 -0
- data/app/models/axel/service_resource/attributes.rb +23 -0
- data/app/models/axel/service_resource/automatic_resource.rb +23 -0
- data/app/models/axel/service_resource/base.rb +47 -0
- data/app/models/axel/service_resource/builder.rb +40 -0
- data/app/models/axel/service_resource/inspects.rb +17 -0
- data/app/models/axel/service_resource/payload_parser.rb +46 -0
- data/app/models/axel/service_resource/queries.rb +25 -0
- data/app/models/axel/service_resource/requesters.rb +49 -0
- data/app/models/axel/service_resource/routes.rb +19 -0
- data/app/models/axel/service_resource/typhoid_extensions.rb +134 -0
- data/app/views/axel/base/empty.json.erb +0 -0
- data/app/views/axel/base/empty.xml.builder +0 -0
- data/app/views/layouts/axel.json.jbuilder +7 -0
- data/app/views/layouts/axel.xml.builder +12 -0
- data/axel.gemspec +42 -0
- data/lib/axel.rb +56 -0
- data/lib/axel/application_extensions.rb +13 -0
- data/lib/axel/application_helper.rb +27 -0
- data/lib/axel/base_controller.rb +6 -0
- data/lib/axel/cascadable_attribute.rb +33 -0
- data/lib/axel/configurations/resource.rb +29 -0
- data/lib/axel/configurations/service.rb +28 -0
- data/lib/axel/configurator.rb +54 -0
- data/lib/axel/configurators/services.rb +29 -0
- data/lib/axel/controller_base.rb +27 -0
- data/lib/axel/controller_helpers.rb +209 -0
- data/lib/axel/controller_parameters.rb +32 -0
- data/lib/axel/engine.rb +14 -0
- data/lib/axel/inspector.rb +91 -0
- data/lib/axel/payload/remote_error.rb +14 -0
- data/lib/axel/request_options.rb +26 -0
- data/lib/axel/uri.rb +47 -0
- data/lib/axel/version.rb +3 -0
- data/lib/generators/axel/install_generator.rb +16 -0
- data/lib/generators/templates/README.md +22 -0
- data/lib/generators/templates/axel.rb +81 -0
- data/script/rails +5 -0
- data/spec/controllers/pages_controller_spec.rb +217 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/pages_controller.rb +6 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +62 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/log/.gitignore +1 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/envelope_integration_check.rb +96 -0
- data/spec/helpers/axel/application_helper_spec.rb +31 -0
- data/spec/lib/axel/associations/base_spec.rb +28 -0
- data/spec/lib/axel/associations/belongs_to_spec.rb +62 -0
- data/spec/lib/axel/associations/has_many_spec.rb +23 -0
- data/spec/lib/axel/associations/has_one_spec.rb +23 -0
- data/spec/lib/axel/configurations/resource_spec.rb +15 -0
- data/spec/lib/axel/configurations/service_spec.rb +31 -0
- data/spec/lib/axel/configurator_spec.rb +26 -0
- data/spec/lib/axel/configurators/services_spec.rb +37 -0
- data/spec/lib/axel/controller_base_spec.rb +16 -0
- data/spec/lib/axel/controller_parameters_spec.rb +31 -0
- data/spec/lib/axel/inspector_spec.rb +45 -0
- data/spec/lib/axel/request_options_spec.rb +50 -0
- data/spec/lib/axel/uri_spec.rb +42 -0
- data/spec/lib/axel_spec.rb +64 -0
- data/spec/models/axel/api_proxy_spec.rb +66 -0
- data/spec/models/axel/payload/errors_spec.rb +165 -0
- data/spec/models/axel/payload/metadata_spec.rb +141 -0
- data/spec/models/axel/querier_spec.rb +158 -0
- data/spec/models/axel/router_spec.rb +115 -0
- data/spec/models/axel/service_resource/base_spec.rb +244 -0
- data/spec/models/axel/service_resource/builder_spec.rb +64 -0
- data/spec/models/axel/service_resource/payload_parser_spec.rb +60 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/support/address.rb +5 -0
- data/spec/support/persona.rb +15 -0
- data/spec/support/user.rb +6 -0
- data/spec/views/axel/base/empty_spec.rb +34 -0
- 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
|