frenetic 0.0.12 → 0.0.20.alpha.0
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.
- data/.gitignore +1 -0
- data/.irbrc +3 -0
- data/.ruby-version +1 -0
- data/.travis.yml +0 -1
- data/Gemfile +1 -3
- data/README.md +138 -125
- data/frenetic.gemspec +5 -6
- data/lib/frenetic.rb +31 -43
- data/lib/frenetic/concerns/collection_rest_methods.rb +13 -0
- data/lib/frenetic/concerns/configurable.rb +59 -0
- data/lib/frenetic/concerns/hal_linked.rb +59 -0
- data/lib/frenetic/concerns/member_rest_methods.rb +15 -0
- data/lib/frenetic/concerns/structured.rb +53 -0
- data/lib/frenetic/configuration.rb +40 -76
- data/lib/frenetic/middleware/hal_json.rb +23 -0
- data/lib/frenetic/resource.rb +77 -62
- data/lib/frenetic/resource_collection.rb +46 -0
- data/lib/frenetic/version.rb +2 -2
- data/spec/concerns/configurable_spec.rb +50 -0
- data/spec/concerns/hal_linked_spec.rb +116 -0
- data/spec/concerns/member_rest_methods_spec.rb +41 -0
- data/spec/concerns/structured_spec.rb +214 -0
- data/spec/configuration_spec.rb +99 -0
- data/spec/fixtures/test_api_requests.rb +88 -0
- data/spec/frenetic_spec.rb +137 -0
- data/spec/middleware/hal_json_spec.rb +83 -0
- data/spec/resource_collection_spec.rb +80 -0
- data/spec/resource_spec.rb +211 -0
- data/spec/spec_helper.rb +4 -13
- data/spec/support/rspec.rb +5 -0
- data/spec/support/webmock.rb +3 -0
- metadata +59 -57
- data/.rvmrc +0 -1
- data/lib/frenetic/hal_json.rb +0 -23
- data/lib/frenetic/hal_json/response_wrapper.rb +0 -43
- data/lib/recursive_open_struct.rb +0 -79
- data/spec/fixtures/vcr_cassettes/description_error_unauthorized.yml +0 -36
- data/spec/fixtures/vcr_cassettes/description_success.yml +0 -38
- data/spec/lib/frenetic/configuration_spec.rb +0 -189
- data/spec/lib/frenetic/hal_json/response_wrapper_spec.rb +0 -70
- data/spec/lib/frenetic/hal_json_spec.rb +0 -68
- data/spec/lib/frenetic/resource_spec.rb +0 -182
- data/spec/lib/frenetic_spec.rb +0 -129
@@ -1,68 +0,0 @@
|
|
1
|
-
describe Frenetic::HalJson do
|
2
|
-
let(:hal_json) { described_class.new }
|
3
|
-
|
4
|
-
let(:app_callbacks_stub) do
|
5
|
-
double('FaradayCallbackStubs').tap do |cb|
|
6
|
-
cb.stub(:on_complete).and_yield env
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
let(:app_stub) do
|
11
|
-
double('FaradayAppStub').tap do |app|
|
12
|
-
app.stub(:call).and_return app_callbacks_stub
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
before { hal_json.instance_variable_set '@app', app_stub }
|
17
|
-
|
18
|
-
subject { hal_json }
|
19
|
-
|
20
|
-
describe "#call" do
|
21
|
-
let(:env) { { status:200 } }
|
22
|
-
|
23
|
-
it "should execute the on_complete callback" do
|
24
|
-
hal_json.should_receive( :on_complete ).with env
|
25
|
-
|
26
|
-
hal_json.call env
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
describe "#on_complete" do
|
31
|
-
context "with a successful response" do
|
32
|
-
let(:env) do
|
33
|
-
{
|
34
|
-
status:200,
|
35
|
-
body: JSON.generate({
|
36
|
-
'_links' => {}
|
37
|
-
})
|
38
|
-
}
|
39
|
-
end
|
40
|
-
|
41
|
-
before { hal_json.on_complete(env) }
|
42
|
-
|
43
|
-
it "should parse the HAL+JSON response" do
|
44
|
-
env[:body].should be_a( Frenetic::HalJson::ResponseWrapper )
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe "#success?" do
|
50
|
-
subject { hal_json.success?( env ) }
|
51
|
-
|
52
|
-
context "with a 200 OK response" do
|
53
|
-
let(:env) { { status:200 } }
|
54
|
-
|
55
|
-
it { should be_true }
|
56
|
-
end
|
57
|
-
context "with a 201 Created response" do
|
58
|
-
let(:env) { { status:201 } }
|
59
|
-
|
60
|
-
it { should be_true }
|
61
|
-
end
|
62
|
-
context "with a 204 No Content" do
|
63
|
-
let(:env) { { status:204 } }
|
64
|
-
|
65
|
-
it { should be_false }
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
@@ -1,182 +0,0 @@
|
|
1
|
-
describe Frenetic::Resource do
|
2
|
-
|
3
|
-
let(:client) { Frenetic.new(url:'http://example.org') }
|
4
|
-
|
5
|
-
let(:resource) { MyResource.new }
|
6
|
-
|
7
|
-
let(:other_resource) { MyOtherResource.new }
|
8
|
-
|
9
|
-
let(:description_stub) do
|
10
|
-
Frenetic::HalJson::ResponseWrapper.new('resources' => {
|
11
|
-
'schema' => {
|
12
|
-
'my_resource' => { 'properties' => { 'foo' => 'string', 'baz' => 'integer' } },
|
13
|
-
'my_other_resource' => { 'properties' => { 'bar' => 'integer' } }
|
14
|
-
} } )
|
15
|
-
end
|
16
|
-
|
17
|
-
before do
|
18
|
-
client.stub(:description).and_return description_stub
|
19
|
-
|
20
|
-
described_class.stub(:api).and_return client
|
21
|
-
|
22
|
-
stub_const 'MyResource', Class.new(described_class)
|
23
|
-
stub_const 'MyOtherResource', Class.new(described_class)
|
24
|
-
end
|
25
|
-
|
26
|
-
subject { resource }
|
27
|
-
|
28
|
-
describe '#attributes' do
|
29
|
-
subject { resource.attributes }
|
30
|
-
|
31
|
-
it { should include 'foo' => nil }
|
32
|
-
it { should include 'baz' => nil }
|
33
|
-
end
|
34
|
-
|
35
|
-
describe '#to_hash' do
|
36
|
-
subject { resource.to_hash }
|
37
|
-
|
38
|
-
it { should == resource.attributes }
|
39
|
-
end
|
40
|
-
|
41
|
-
context "created from a Hash" do
|
42
|
-
let(:resource) { MyResource.new( foo: 'bar' ) }
|
43
|
-
|
44
|
-
it { should respond_to(:foo) }
|
45
|
-
it { should respond_to(:foo=) }
|
46
|
-
its(:links) { should be_a Hash }
|
47
|
-
its(:links) { should be_empty }
|
48
|
-
|
49
|
-
context 'other subclasses' do
|
50
|
-
subject { other_resource }
|
51
|
-
|
52
|
-
it { should_not respond_to(:foo) }
|
53
|
-
it { should_not respond_to(:foo=) }
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
context "created from a HAL-JSON response" do
|
58
|
-
let(:api_response) do
|
59
|
-
{
|
60
|
-
'_links' => {
|
61
|
-
'_self' => { '_href' => 'bar' }
|
62
|
-
},
|
63
|
-
'foo' => 1,
|
64
|
-
'bar' => 2
|
65
|
-
}
|
66
|
-
end
|
67
|
-
|
68
|
-
let(:wrapped_response) do
|
69
|
-
Frenetic::HalJson::ResponseWrapper.new(api_response)
|
70
|
-
end
|
71
|
-
|
72
|
-
let(:resource_a) { MyResource.new( wrapped_response ) }
|
73
|
-
|
74
|
-
let(:resource_b) { MyResource.new }
|
75
|
-
|
76
|
-
before do
|
77
|
-
resource_a && resource_b
|
78
|
-
end
|
79
|
-
|
80
|
-
context "initialized with data" do
|
81
|
-
subject { resource_a }
|
82
|
-
|
83
|
-
its(:foo) { should == 1 }
|
84
|
-
it { should_not respond_to(:bar) }
|
85
|
-
its(:links) { should_not be_empty }
|
86
|
-
end
|
87
|
-
|
88
|
-
context "intiailized in sequence without data" do
|
89
|
-
subject { resource_b }
|
90
|
-
|
91
|
-
it { should respond_to(:foo) }
|
92
|
-
it { should_not respond_to(:bar) }
|
93
|
-
its(:links) { should be_empty }
|
94
|
-
end
|
95
|
-
|
96
|
-
context "with embedded resources" do
|
97
|
-
let(:api_response) do
|
98
|
-
{
|
99
|
-
'_links' => {
|
100
|
-
'_self' => { '_href' => 'bar' }
|
101
|
-
},
|
102
|
-
'foo' => 1,
|
103
|
-
'_embedded' => embed
|
104
|
-
}
|
105
|
-
end
|
106
|
-
|
107
|
-
subject { resource_a }
|
108
|
-
|
109
|
-
context 'that have a Resource representation' do
|
110
|
-
subject { super().my_other_resource }
|
111
|
-
|
112
|
-
let(:embed) do
|
113
|
-
{ 'my_other_resource' => { 'bar' => 123 } }
|
114
|
-
end
|
115
|
-
|
116
|
-
its(:bar) { should == 123 }
|
117
|
-
end
|
118
|
-
|
119
|
-
context 'that do not have a Resource representation' do
|
120
|
-
subject { super().foo }
|
121
|
-
|
122
|
-
let(:embed) do
|
123
|
-
{ 'foo' => { 'bar' => 'baz' } }
|
124
|
-
end
|
125
|
-
|
126
|
-
it { should include 'bar' => 'baz' }
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
describe ".api_client" do
|
132
|
-
before do
|
133
|
-
described_class.unstub! :api
|
134
|
-
end
|
135
|
-
|
136
|
-
subject { MyResource }
|
137
|
-
|
138
|
-
context "with a block" do
|
139
|
-
before { subject.api_client { client } }
|
140
|
-
|
141
|
-
it "should reference the defined API client" do
|
142
|
-
subject.api.should eq client
|
143
|
-
|
144
|
-
MyOtherResource.should_not respond_to :api
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
context "with an argument" do
|
149
|
-
before { MyResource.api_client client }
|
150
|
-
|
151
|
-
it "should reference the defined API client" do
|
152
|
-
subject.api.should eq client
|
153
|
-
|
154
|
-
MyOtherResource.should_not respond_to :api
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
describe ".schema" do
|
160
|
-
subject { resource.class.schema }
|
161
|
-
|
162
|
-
context "with a defined API Client" do
|
163
|
-
before do
|
164
|
-
client.stub(:description).and_return description_stub
|
165
|
-
|
166
|
-
resource.class.api_client client
|
167
|
-
end
|
168
|
-
|
169
|
-
it "should return the schema for the specific resource" do
|
170
|
-
subject.should == description_stub.resources.schema.my_resource.properties
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
context "without a defined API Client" do
|
175
|
-
before { described_class.stub(:respond_to?).with(:api).and_return false }
|
176
|
-
|
177
|
-
it "should raise an error" do
|
178
|
-
expect { subject }.to raise_error(Frenetic::MissingAPIReference)
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
data/spec/lib/frenetic_spec.rb
DELETED
@@ -1,129 +0,0 @@
|
|
1
|
-
describe Frenetic do
|
2
|
-
let(:config) do
|
3
|
-
{
|
4
|
-
url: 'http://example.org:5447/api',
|
5
|
-
api_key: '1234567890',
|
6
|
-
version: 'v1',
|
7
|
-
response: {}
|
8
|
-
}
|
9
|
-
end
|
10
|
-
|
11
|
-
let(:client) { described_class.new(config) }
|
12
|
-
|
13
|
-
subject { client }
|
14
|
-
|
15
|
-
it { should respond_to(:description) }
|
16
|
-
it { should respond_to(:connection) }
|
17
|
-
it { should respond_to(:conn) }
|
18
|
-
it { should respond_to(:get) }
|
19
|
-
it { should respond_to(:put) }
|
20
|
-
it { should respond_to(:post) }
|
21
|
-
it { should respond_to(:delete) }
|
22
|
-
|
23
|
-
its(:connection) { should be_a(Faraday::Connection) }
|
24
|
-
|
25
|
-
it 'should accept a configuration block' do
|
26
|
-
described_class.new( config ) do |cfg|
|
27
|
-
cfg.should be_a described_class::Configuration
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
describe "#connection" do
|
32
|
-
let(:connection) { client.connection }
|
33
|
-
|
34
|
-
subject { client.connection }
|
35
|
-
|
36
|
-
it { should be_a Faraday::Connection }
|
37
|
-
|
38
|
-
it "should be created" do
|
39
|
-
Faraday.should_receive( :new ).with do |cfg|
|
40
|
-
cfg.has_key? :url
|
41
|
-
end
|
42
|
-
|
43
|
-
client
|
44
|
-
end
|
45
|
-
|
46
|
-
describe 'logger configuration' do
|
47
|
-
before { config[:response][:use_logger] = true }
|
48
|
-
|
49
|
-
subject { connection.builder.handlers.collect(&:name) }
|
50
|
-
|
51
|
-
it { should include 'Faraday::Response::Logger' }
|
52
|
-
end
|
53
|
-
|
54
|
-
describe 'middleware initialization' do
|
55
|
-
before { stub_const 'MyMiddleware', Class.new }
|
56
|
-
|
57
|
-
let(:client) do
|
58
|
-
described_class.new(config) do |cfg|
|
59
|
-
cfg.use MyMiddleware, foo:123
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
subject { connection.builder.handlers }
|
64
|
-
|
65
|
-
it 'should add the middleware to the connection' do
|
66
|
-
subject.should include MyMiddleware
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe 'Faraday adapter' do
|
71
|
-
subject { connection.builder.handlers }
|
72
|
-
|
73
|
-
context 'by default' do
|
74
|
-
it 'should be :patron' do
|
75
|
-
subject.should include Faraday::Adapter::NetHttp
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
context 'when explicitly set' do
|
80
|
-
before do
|
81
|
-
config.merge! adapter: :patron
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'should use the specified adapter' do
|
85
|
-
subject.should include Faraday::Adapter::Patron
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
describe "#description" do
|
92
|
-
context "for a conforming API" do
|
93
|
-
subject do
|
94
|
-
VCR.use_cassette('description_success') do
|
95
|
-
client.description
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
it { should be_a( Frenetic::HalJson::ResponseWrapper ) }
|
100
|
-
end
|
101
|
-
|
102
|
-
context "with an unauthorized request" do
|
103
|
-
let(:fetch!) do
|
104
|
-
VCR.use_cassette('description_error_unauthorized') do
|
105
|
-
client.description
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
it "should raise an error" do
|
110
|
-
expect{ fetch! }.to raise_error(Frenetic::InvalidAPIDescription)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
describe "#reload!" do
|
116
|
-
before do
|
117
|
-
VCR.use_cassette('description_success') do
|
118
|
-
client.description
|
119
|
-
end
|
120
|
-
|
121
|
-
client.reload!
|
122
|
-
end
|
123
|
-
|
124
|
-
it "should not have any non-Nil instance variables" do
|
125
|
-
client.instance_variables.none? { |s| client.instance_variable_get(s).nil? }.should be_false
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
end
|