party_resource 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,19 +0,0 @@
1
- class OtherClass < TestBaseClass
2
- def self.make_boolean(data)
3
- data =~ /OK/
4
- end
5
- end
6
-
7
-
8
- class OtherPartyClass
9
- include PartyResource
10
- party_connector :other_connector
11
-
12
- connect :test, :get => '/url', :as => :raw
13
-
14
- property :thing
15
-
16
- def initialize(args)
17
- populate_properties(args)
18
- end
19
- end
@@ -1,17 +0,0 @@
1
- class TestBaseClass
2
- attr :args
3
-
4
- def initialize(args={})
5
- @args = args
6
- end
7
-
8
- def method_missing(name, *params)
9
- return args[name] if params.empty? && args.has_key?(name)
10
- super
11
- end
12
-
13
- def ==(other)
14
- self.class == other.class && args == other.args
15
- end
16
- end
17
-
@@ -1,44 +0,0 @@
1
- PartyResource::Connector.add(:other_connector, {:base_uri => 'http://otherserver/'})
2
- PartyResource::Connector.add(:my_connector, {:base_uri => 'http://myserver/path', :username => 'fred', :password => 'pass', :default => true})
3
-
4
- class TestClass < TestBaseClass
5
- include PartyResource
6
-
7
- connect :find, :get => '/find/:id.ext', :with => :id, :on => :class
8
-
9
- connect :update, :put => '/update/:var.ext', :on => :instance, :as => OtherClass
10
-
11
- connect :save, :post => '/save/file', :with => :data, :as => :raw
12
-
13
- connect :destroy, :delete => '/delete', :as => [OtherClass, :make_boolean]
14
-
15
- connect :foo, :get => '/foo', :with => :value, :as => lambda {|data| "New #{data} Improved" }
16
-
17
- connect :fetch_json, :get => '/big_data', :as => [:self, :from_json], :rescue => {'ResourceNotFound' => nil}
18
-
19
- connect :include, :get => '/include', :on => :instance, :as => OtherClass, :including => {:thing => :value2}
20
-
21
- property :value, :from => :input_name
22
-
23
- property :value2, :value3
24
-
25
- property :nested_value, :from => [:block, :var]
26
-
27
- property :other, :as => OtherClass
28
-
29
- property :processed, :as => lambda { |data| "Processed: #{data}" }, :to => :output_name
30
-
31
- property :child, :as => OtherPartyClass
32
-
33
- def self.from_json(args)
34
- obj = self.new
35
- obj.send(:populate_properties, args)
36
- obj
37
- end
38
-
39
- end
40
-
41
- class InheritedTestClass < TestClass
42
- property :child_property
43
- end
44
-
@@ -1,213 +0,0 @@
1
- require File.expand_path(File.join(__FILE__, '..', '..', 'spec_helper'))
2
- require 'fixtures/test_base_class'
3
- require 'fixtures/other_class'
4
- require 'fixtures/test_class'
5
-
6
- describe TestClass do
7
-
8
- let(:object) {TestClass.new(:foo)}
9
-
10
- after do
11
- PartyResource.logger = nil
12
- end
13
-
14
- describe 'class level call' do
15
- it 'raises an argument error when called with the wrong number of arguments' do
16
- lambda { TestClass.find }.should raise_error(ArgumentError)
17
- end
18
-
19
- it 'finds an object' do
20
- stub_request(:get, "http://fred:pass@myserver/path/find/99.ext").to_return(:body => 'some data')
21
- TestClass.find(99).should == TestClass.new('some data')
22
- end
23
-
24
- it 'finds an object with extra options' do
25
- stub_request(:get, "http://fred:pass@myserver/path/find/99.ext?extra=options").to_return(:body => 'some data')
26
- TestClass.find(99, :extra => 'options').should == TestClass.new('some data')
27
- end
28
-
29
- it 'uses other connectors' do
30
- stub_request(:get, 'http://otherserver/url').to_return(:body => 'from the otherserver')
31
- OtherPartyClass.test.should == 'from the otherserver'
32
- end
33
- end
34
-
35
- describe 'instance level call' do
36
- it 'gets the result' do
37
- stub_request(:put, "http://fred:pass@myserver/path/update/99.ext").to_return(:body => 'updated data')
38
- TestClass.new(:var => 99).update
39
- end
40
- end
41
-
42
- describe 'building connected objects' do
43
- it 'build the requested response object' do
44
- stub_request(:put, "http://fred:pass@myserver/path/update/99.ext").to_return(:body => 'updated data')
45
- TestClass.new(:var => 99).update.should == OtherClass.new('updated data')
46
- end
47
-
48
- it 'passes the raw result back when requested' do
49
- stub_request(:post, "http://fred:pass@myserver/path/save/file").with(:body => "data=somedata").to_return(:body => 'saved data')
50
- TestClass.save('somedata').should == 'saved data'
51
- end
52
-
53
- it 'builds the result using the specified method' do
54
- stub_request(:delete, "http://fred:pass@myserver/path/delete").to_return(:body => 'deleted OK')
55
- TestClass.destroy.should be_true
56
- end
57
-
58
- it 'builds the result using the specified proc' do
59
- stub_request(:get, "http://fred:pass@myserver/path/foo?value=908").to_return(:body => 'foo data')
60
- TestClass.foo(908).should == 'New foo data Improved'
61
- end
62
-
63
- it 'builds each value in an array individually' do
64
- stub_request(:get, "http://fred:pass@myserver/path/foo?value=908").to_return(:headers => {'Content-Type' => 'text/json'}, :body => '[foo,data]')
65
- TestClass.foo(908).should == ['New foo Improved', 'New data Improved']
66
- end
67
-
68
- it 'passes "included" variables to the new object' do
69
- v2 = mock(:v2)
70
- stub_request(:get, "http://fred:pass@myserver/path/include").to_return(:headers => {'Content-Type' => 'text/json'}, :body => '{}')
71
- test = TestClass.from_json(:value2 => v2)
72
- test.include.should == OtherClass.new(:thing => v2)
73
- end
74
-
75
- context 'error cases' do
76
- it 'raises ResourceNotFound' do
77
- stub_request(:delete, "http://fred:pass@myserver/path/delete").to_return(:status => 404)
78
- lambda { TestClass.destroy }.should raise_error(PartyResource::Exceptions::ResourceNotFound)
79
- end
80
-
81
- it 'raises ResourceInvalid' do
82
- stub_request(:delete, "http://fred:pass@myserver/path/delete").to_return(:status => 422)
83
- lambda { TestClass.destroy }.should raise_error(PartyResource::Exceptions::ResourceInvalid)
84
- end
85
-
86
- it 'raises ClientError' do
87
- stub_request(:delete, "http://fred:pass@myserver/path/delete").to_return(:status => 405)
88
- lambda { TestClass.destroy }.should raise_error(PartyResource::Exceptions::ClientError)
89
- end
90
-
91
- it 'raises ServerError' do
92
- stub_request(:delete, "http://fred:pass@myserver/path/delete").to_return(:status => 501)
93
- lambda { TestClass.destroy }.should raise_error(PartyResource::Exceptions::ServerError)
94
- end
95
-
96
- it 'rescues exceptions' do
97
- stub_request(:get, "http://fred:pass@myserver/path/big_data").to_return(:status => 404)
98
- TestClass.fetch_json.should be_nil
99
- end
100
-
101
- end
102
- end
103
-
104
- describe 'populating properties' do
105
- it 'populates result values' do
106
- stub_request(:get, "http://fred:pass@myserver/path/big_data").to_return(:headers => {'Content-Type' => 'text/json'}, :body => '{value2:"value2", value4:"ignored"}')
107
- result = TestClass.fetch_json
108
- result.value2.should == 'value2'
109
- result.value3.should == nil
110
- result.should_not be_respond_to(:value4)
111
- end
112
-
113
- it 'populates renamed values' do
114
- stub_request(:get, "http://fred:pass@myserver/path/big_data").to_return(:headers => {'Content-Type' => 'text/json'}, :body => '{input_name:"value"}')
115
- result = TestClass.fetch_json
116
- result.value.should == 'value'
117
- end
118
-
119
- it 'populates nested values' do
120
- stub_request(:get, "http://fred:pass@myserver/path/big_data").to_return(:headers => {'Content-Type' => 'text/json'}, :body => '{block:{var:"value"}}')
121
- result = TestClass.fetch_json
122
- result.nested_value.should == 'value'
123
- end
124
-
125
- it 'falls back to populating based on the property name if from is not found' do
126
- stub_request(:get, "http://fred:pass@myserver/path/big_data").to_return(:headers => {'Content-Type' => 'text/json'}, :body => '{value:"value"}')
127
- result = TestClass.fetch_json
128
- result.value.should == 'value'
129
- end
130
-
131
- it 'populates a property as another class' do
132
- stub_request(:get, "http://fred:pass@myserver/path/big_data").to_return(:headers => {'Content-Type' => 'text/json'}, :body => '{other: "value"}')
133
- result = TestClass.fetch_json
134
- result.other.should == OtherClass.new('value')
135
- end
136
-
137
- it 'populates a property with a proc' do
138
- stub_request(:get, "http://fred:pass@myserver/path/big_data").to_return(:headers => {'Content-Type' => 'text/json'}, :body => '{processed: "value"}')
139
- result = TestClass.fetch_json
140
- result.processed.should == "Processed: value"
141
- end
142
-
143
- it 'does not build null data' do
144
- stub_request(:get, "http://fred:pass@myserver/path/big_data").to_return(:headers => {'Content-Type' => 'text/json'}, :body => '{processed: null}')
145
- result = TestClass.fetch_json
146
- result.processed.should == nil
147
- end
148
-
149
- it 'builds each value when populating an array' do
150
- stub_request(:get, "http://fred:pass@myserver/path/big_data").to_return(:headers => {'Content-Type' => 'text/json'}, :body => '{processed: [1,2,3,4]}')
151
- result = TestClass.fetch_json
152
- result.processed.should == ['Processed: 1','Processed: 2','Processed: 3','Processed: 4']
153
- end
154
-
155
- context 'and inherited class' do
156
- it 'self refers to the child class' do
157
- stub_request(:get, "http://fred:pass@myserver/path/big_data").to_return(:headers => {'Content-Type' => 'text/json'}, :body => '{value2:"value2", child_property:"child"}')
158
- result = InheritedTestClass.fetch_json
159
- result.should be_a(InheritedTestClass)
160
- end
161
-
162
- it 'all local and inherited properties are available' do
163
- stub_request(:get, "http://fred:pass@myserver/path/big_data").to_return(:headers => {'Content-Type' => 'text/json'}, :body => '{value2:"value2", child_property:"child"}')
164
- result = InheritedTestClass.fetch_json
165
- result.child_property.should == 'child'
166
- result.value2.should == 'value2'
167
- end
168
- end
169
- end
170
-
171
- describe '#to_property_hash' do
172
- it 'converts an object to external hash representation' do
173
- obj = TestClass.from_json(:value => 'v1', :value2 => 'v2', :nested_value => 'nv', :processed => 'Milk', :child => {:thing => 'Happiness'})
174
- obj.to_properties_hash.should == {:input_name => 'v1', :value2 => 'v2', :block => {:var => 'nv'}, :output_name => 'Processed: Milk', :child => {:thing => 'Happiness'}}
175
- end
176
- end
177
-
178
- describe 'logging' do
179
- context 'with no logger' do
180
- it 'does not fail' do
181
- stub_request(:get, "http://fred:pass@myserver/path/find/99.ext").to_return(:body => 'some data')
182
- TestClass.find(99)
183
- end
184
- end
185
-
186
- context 'with a logger object' do
187
- before do
188
- @logger = mock(:logger)
189
- PartyResource.logger = @logger
190
- end
191
-
192
- it 'logs all api calls to debug' do
193
- stub_request(:get, "http://fred:pass@myserver/path/find/99.ext").to_return(:body => 'some data')
194
- @logger.should_receive(:debug).with('** PartyResource GET call to /find/99.ext with {:basic_auth=>{:username=>"fred", :password=>"pass"}, :base_uri=>"http://myserver/path"}')
195
- TestClass.find(99)
196
- end
197
- end
198
-
199
- context 'with a logger lambda' do
200
- before do
201
- @logger = mock(:logger)
202
- PartyResource.logger = lambda {|message| @logger.log(message) }
203
- end
204
-
205
- it 'logs all api calls to debug' do
206
- stub_request(:get, "http://fred:pass@myserver/path/find/99.ext").to_return(:body => 'some data')
207
- @logger.should_receive(:log).with('** PartyResource GET call to /find/99.ext with {:basic_auth=>{:username=>"fred", :password=>"pass"}, :base_uri=>"http://myserver/path"}')
208
- TestClass.find(99)
209
- end
210
- end
211
-
212
- end
213
- end
@@ -1,20 +0,0 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__))
2
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
-
4
- require 'party_resource'
5
- require 'spec'
6
- require 'spec/autorun'
7
- require 'webmock/rspec'
8
-
9
- include WebMock
10
-
11
- module LetMock
12
- def let_mock(name, options = {})
13
- let(name) { mock(name, options) }
14
- end
15
- end
16
-
17
- Spec::Runner.configure do |config|
18
- config.extend(LetMock)
19
- end
20
-
@@ -1,83 +0,0 @@
1
- require File.expand_path(File.join(__FILE__, '..', '..', '..', 'spec_helper'))
2
-
3
- describe PartyResource::Connector::Base do
4
- describe "creation" do
5
- subject { PartyResource::Connector::Base.new(:test, options) }
6
-
7
- let_mock(:username)
8
- let_mock(:password)
9
- let_mock(:normalized_uri)
10
- let_mock(:original_uri)
11
-
12
- before do
13
- HTTParty.stub(:normalize_base_uri => normalized_uri)
14
- end
15
-
16
- context "with a base_uri" do
17
- let(:options) { { :base_uri => original_uri } }
18
-
19
- it 'normalizes the base_uri' do
20
- HTTParty.should_receive(:normalize_base_uri).with(original_uri)
21
- subject.options.should == {:base_uri => normalized_uri }
22
- end
23
- end
24
-
25
- context 'with username' do
26
- let(:options) { { :username => username } }
27
-
28
- it 'stores the username' do
29
- subject.options.should == {:basic_auth => {:username => username, :password => nil} }
30
- end
31
- end
32
-
33
- context 'with password' do
34
- let(:options) { { :password => password } }
35
-
36
- it 'stores the password' do
37
- subject.options.should == {:basic_auth => {:password => password, :username => nil} }
38
- end
39
- end
40
-
41
- context 'with all options' do
42
- let(:options) { { :base_uri => original_uri, :username => username, :password => password } }
43
-
44
- it 'stores the options' do
45
- subject.options.should == {:base_uri => normalized_uri,
46
- :basic_auth => {:password => password, :username => username } }
47
- end
48
- end
49
- end
50
-
51
- describe '#fetch' do
52
- let(:options) { {:base_uri => 'http://myserver.test/path'} }
53
- let_mock(:data, :empty? => false)
54
- let_mock(:path)
55
- let_mock(:return_data, :code => 200)
56
- let(:request) { mock(:request, :path => path, :verb => verb, :http_data => data) }
57
-
58
- subject { PartyResource::Connector::Base.new(:test, options) }
59
-
60
- [:put, :post, :delete, :get].each do |http_verb|
61
- context "for #{http_verb} requests" do
62
- let(:verb) { http_verb }
63
- it "fetches the request using HTTParty" do
64
- HTTParty.should_receive(verb).with(path, data).and_return(return_data)
65
- subject.fetch(request).should == return_data
66
- end
67
-
68
- end
69
- end
70
-
71
- context 'error cases' do
72
- let(:request) { mock(:request, :path => mock(:path), :verb => :get, :http_data => mock(:data)) }
73
-
74
- it 'raises an exception' do
75
- return_data = mock(:data, :code => 404)
76
- HTTParty.should_receive(:get).and_return(return_data)
77
- lambda{ subject.fetch(request) }.should raise_error(PartyResource::Exceptions::ConnectionError)
78
- end
79
- end
80
-
81
- end
82
-
83
- end
@@ -1,67 +0,0 @@
1
- require File.expand_path(File.join(__FILE__, '..', '..', 'spec_helper'))
2
-
3
- describe PartyResource::Connector do
4
- describe '#lookup' do
5
-
6
- let(:test_connector) { mock(:connector) }
7
- let(:default_connector) { mock(:connector) }
8
- let(:connectors) { { :test => test_connector, :other => default_connector } }
9
-
10
- before do
11
- PartyResource::Connector.send(:repository).stub(:connectors => connectors)
12
- end
13
-
14
- it "returns the named connectors" do
15
- PartyResource::Connector.lookup(:test).should == test_connector
16
- end
17
-
18
- it "returns the default connector for nil name" do
19
- PartyResource::Connector.send(:repository).stub(:default => :other)
20
-
21
- PartyResource::Connector.lookup(nil).should == default_connector
22
- end
23
-
24
- it 'raises a NoConnector error it the connector could not be found' do
25
- lambda { PartyResource::Connector.lookup(:missing_name) }.should raise_error(PartyResource::Exceptions::NoConnector)
26
- end
27
- end
28
-
29
- describe '#new' do
30
- let_mock(:name)
31
- let_mock(:options)
32
- let_mock(:connector)
33
-
34
- before do
35
- @repository = PartyResource::Connector::Repository.new
36
- PartyResource::Connector.stub(:repository => @repository)
37
- PartyResource::Connector::Base.stub(:new => connector)
38
- options.stub(:[]).with(:default).and_return(false)
39
- end
40
-
41
- it 'creates a new connector' do
42
- PartyResource::Connector::Base.should_receive(:new).with(name, options).and_return(connector)
43
- PartyResource::Connector.add(name, options)
44
- PartyResource::Connector.lookup(name).should == connector
45
- end
46
-
47
- it 'sets the default if it is currently unset' do
48
- name2 = mock(:name2)
49
- PartyResource::Connector.add(name, options)
50
- PartyResource::Connector.send(:repository).default.should == name
51
-
52
- PartyResource::Connector.add(name2, options)
53
- PartyResource::Connector.send(:repository).default.should == name
54
- end
55
-
56
- it 'sets the default if the default option is set' do
57
- name2 = mock(:name2)
58
- PartyResource::Connector.add(name, options)
59
- PartyResource::Connector.repository.default.should == name
60
-
61
- options.stub(:[]).with(:default).and_return(true)
62
- PartyResource::Connector.add(name2, options)
63
- PartyResource::Connector.repository.default.should == name2
64
- end
65
- end
66
- end
67
-