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.
- 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
|