ruby-picasa 0.2.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/.autotest +7 -0
- data/History.txt +11 -0
- data/Manifest.txt +15 -0
- data/README.txt +74 -0
- data/Rakefile +23 -0
- data/lib/ruby_picasa.rb +279 -0
- data/lib/ruby_picasa/types.rb +165 -0
- data/spec/ruby_picasa/types_spec.rb +221 -0
- data/spec/ruby_picasa_spec.rb +319 -0
- data/spec/sample/album.atom +141 -0
- data/spec/sample/recent.atom +111 -0
- data/spec/sample/search.atom +99 -0
- data/spec/sample/user.atom +107 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +13 -0
- metadata +91 -0
@@ -0,0 +1,221 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../spec_helper')
|
2
|
+
|
3
|
+
include RubyPicasa
|
4
|
+
|
5
|
+
describe 'a RubyPicasa document', :shared => true do
|
6
|
+
it 'should have an id' do
|
7
|
+
@object.id.should_not be_nil
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should have an author' do
|
11
|
+
unless @no_author
|
12
|
+
@object.author.should_not be_nil
|
13
|
+
@object.author.name.should == 'Liz'
|
14
|
+
@object.author.uri.should == 'http://picasaweb.google.com/liz'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should get links by name' do
|
19
|
+
@object.link('abc').should be_nil
|
20
|
+
@object.link('self').href.should_not be_nil
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should do nothing for previous and next' do
|
24
|
+
@object.previous.should be_nil if @object.link('previous').nil?
|
25
|
+
@object.next.should be_nil if @object.link('next').nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should load' do
|
29
|
+
@object.session.expects(:get_url).with(@object.id, {})
|
30
|
+
@object.load
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should have links' do
|
34
|
+
@object.links.should_not be_empty
|
35
|
+
@object.links.each do |l|
|
36
|
+
l.should be_an_instance_of(Objectify::Atom::Link)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe 'session' do
|
41
|
+
it 'should return @session' do
|
42
|
+
@object.session = :sess
|
43
|
+
@object.session.should == :sess
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should get the parent session' do
|
47
|
+
@object.session = nil
|
48
|
+
@parent.expects(:session).returns(:parent_sess)
|
49
|
+
@object.session.should == :parent_sess
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should be nil if no parent' do
|
53
|
+
@object.session = nil
|
54
|
+
@object.expects(:parent).returns nil
|
55
|
+
@object.session.should be_nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
describe User do
|
62
|
+
it_should_behave_like 'a RubyPicasa document'
|
63
|
+
|
64
|
+
before :all do
|
65
|
+
@xml = open_file('user.atom').read
|
66
|
+
end
|
67
|
+
|
68
|
+
before do
|
69
|
+
@parent = mock('parent')
|
70
|
+
@object = @user = User.new(@xml, @parent)
|
71
|
+
@user.session = mock('session')
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should have albums' do
|
75
|
+
@user.albums.length.should == 1
|
76
|
+
@user.albums.first.should be_an_instance_of(Album)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe RecentPhotos do
|
81
|
+
it_should_behave_like 'a RubyPicasa document'
|
82
|
+
|
83
|
+
before :all do
|
84
|
+
@xml = open_file('recent.atom').read
|
85
|
+
end
|
86
|
+
|
87
|
+
before do
|
88
|
+
@parent = mock('parent')
|
89
|
+
@object = @album = RecentPhotos.new(@xml, @parent)
|
90
|
+
@album.session = mock('session')
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should have 1 photo' do
|
94
|
+
@album.photos.length.should == 1
|
95
|
+
@album.photos.first.should be_an_instance_of(Photo)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should request next' do
|
99
|
+
@album.session.expects(:get_url).with('http://picasaweb.google.com/data/feed/api/user/liz?start-index=2&max-results=1&kind=photo').returns(:result)
|
100
|
+
@album.next.should == :result
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should not request previous on first page' do
|
104
|
+
@album.session.expects(:get_url).never
|
105
|
+
@album.previous.should be_nil
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe Album do
|
110
|
+
it_should_behave_like 'a RubyPicasa document'
|
111
|
+
|
112
|
+
before :all do
|
113
|
+
@xml = open_file('album.atom').read
|
114
|
+
end
|
115
|
+
|
116
|
+
before do
|
117
|
+
@parent = mock('parent')
|
118
|
+
@object = @album = Album.new(@xml, @parent)
|
119
|
+
@album.session = mock('session')
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should have 1 entry' do
|
123
|
+
@album.entries.length.should == 1
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should get links by name' do
|
127
|
+
@album.link('abc').should be_nil
|
128
|
+
@album.link('alternate').href.should == 'http://picasaweb.google.com/liz/Lolcats'
|
129
|
+
end
|
130
|
+
|
131
|
+
describe 'photos' do
|
132
|
+
it 'should use entries if available' do
|
133
|
+
@album.expects(:session).never
|
134
|
+
@album.photos.should == @album.entries
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should request photos if needed' do
|
138
|
+
@album.entries = []
|
139
|
+
new_album = mock('album', :entries => [:photo])
|
140
|
+
@album.session.expects(:album).with(@album.id, {}).returns(new_album)
|
141
|
+
@album.photos.should == [:photo]
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'should be public' do
|
146
|
+
@album.public?.should be_true
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should not be private' do
|
150
|
+
@album.private?.should be_false
|
151
|
+
end
|
152
|
+
|
153
|
+
describe 'first Photo' do
|
154
|
+
before do
|
155
|
+
@photo = @album.entries.first
|
156
|
+
@photo.should be_an_instance_of(Photo)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should have a parent' do
|
160
|
+
@photo.parent.should == @album
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should not have an author' do
|
164
|
+
@photo.author.should be_nil
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should have a content' do
|
168
|
+
@photo.content.should be_an_instance_of(PhotoUrl)
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should have 3 thumbnails' do
|
172
|
+
@photo.thumbnails.length.should == 3
|
173
|
+
@photo.thumbnails.each do |t|
|
174
|
+
t.should be_an_instance_of(ThumbnailUrl)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'should have a default url' do
|
179
|
+
@photo.url.should == 'http://lh5.ggpht.com/liz/SKXR5BoXabI/AAAAAAAAAzs/tJQefyM4mFw/invisible_bike.jpg'
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should have thumbnail urls' do
|
183
|
+
@photo.url('s72').should == 'http://lh5.ggpht.com/liz/SKXR5BoXabI/AAAAAAAAAzs/tJQefyM4mFw/s72/invisible_bike.jpg'
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'should have thumbnail info' do
|
187
|
+
@photo.thumbnail('s72').width.should == 72
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
describe Search do
|
193
|
+
it_should_behave_like 'a RubyPicasa document'
|
194
|
+
|
195
|
+
before :all do
|
196
|
+
@xml = open_file('search.atom').read
|
197
|
+
end
|
198
|
+
|
199
|
+
before do
|
200
|
+
@no_author = true
|
201
|
+
@parent = mock('parent')
|
202
|
+
@object = @search = Search.new(@xml, @parent)
|
203
|
+
@search.session = mock('session')
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'should have 1 entry' do
|
207
|
+
@search.entries.length.should == 1
|
208
|
+
@search.entries.first.should be_an_instance_of(Photo)
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'should request next' do
|
212
|
+
@search.session.expects(:get_url).with('http://picasaweb.google.com/data/feed/api/all?q=puppy&start-index=3&max-results=1').returns(:result)
|
213
|
+
@search.next.should == :result
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'should request previous' do
|
217
|
+
@search.session.expects(:get_url).with('http://picasaweb.google.com/data/feed/api/all?q=puppy&start-index=1&max-results=1').returns(:result)
|
218
|
+
@search.previous.should == :result
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
@@ -0,0 +1,319 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
class Picasa
|
4
|
+
class << self
|
5
|
+
public :parse_url
|
6
|
+
end
|
7
|
+
public :auth_header, :with_cache, :class_from_xml, :xml_data
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'Picasa class methods' do
|
11
|
+
it 'should generate an authorization_url' do
|
12
|
+
return_url = 'http://example.com/example?example=ex'
|
13
|
+
url = Picasa.authorization_url(return_url)
|
14
|
+
url.should include(CGI.escape(return_url))
|
15
|
+
url.should match(/session=1/)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'token_from_request' do
|
19
|
+
it 'should pluck the token from the request' do
|
20
|
+
request = mock('request', :params => { 'token' => 'abc' })
|
21
|
+
Picasa.token_from_request(request).should == 'abc'
|
22
|
+
end
|
23
|
+
it 'should raise if no token is present' do
|
24
|
+
request = mock('request', :params => { })
|
25
|
+
lambda do
|
26
|
+
Picasa.token_from_request(request)
|
27
|
+
end.should raise_error(RubyPicasa::PicasaTokenError)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should authorize a request' do
|
32
|
+
Picasa.expects(:token_from_request).with(:request).returns('abc')
|
33
|
+
picasa = mock('picasa')
|
34
|
+
Picasa.expects(:new).with('abc').returns(picasa)
|
35
|
+
picasa.expects(:authorize_token!).with()
|
36
|
+
Picasa.authorize_request(:request).should == picasa
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should recognize absolute urls' do
|
40
|
+
Picasa.is_url?('http://something.com').should be_true
|
41
|
+
Picasa.is_url?('https://something.com').should be_true
|
42
|
+
Picasa.is_url?('12323412341').should_not be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should recognize relative urls?' do
|
46
|
+
pending 'not currently needed'
|
47
|
+
Picasa.is_url?('something.com/else').should be_true
|
48
|
+
Picasa.is_url?('/else').should be_true
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'path' do
|
52
|
+
it 'should use parse_url and add options' do
|
53
|
+
Picasa.expects(:parse_url).with({}).returns(['url', {'a' => 'b'}])
|
54
|
+
Picasa.path({}).should ==
|
55
|
+
"url?a=b"
|
56
|
+
end
|
57
|
+
it 'should build the url from user_id and album_id and add options' do
|
58
|
+
hash = { :user_id => '123', :album_id => '321' }
|
59
|
+
Picasa.expects(:parse_url).with(hash).returns([nil, {}])
|
60
|
+
Picasa.path(hash).should ==
|
61
|
+
"/data/feed/api/user/123/albumid/321?kind=photo"
|
62
|
+
end
|
63
|
+
it 'should build the url from special user_id all' do
|
64
|
+
hash = { :user_id => 'all' }
|
65
|
+
Picasa.expects(:parse_url).with(hash).returns([nil, {}])
|
66
|
+
Picasa.path(hash).should ==
|
67
|
+
"/data/feed/api/all"
|
68
|
+
end
|
69
|
+
[ :max_results, :start_index, :tag, :q, :kind,
|
70
|
+
:access, :thumbsize, :imgmax, :bbox, :l].each do |arg|
|
71
|
+
it "should add #{ arg } to options" do
|
72
|
+
Picasa.path(:url => 'url', arg => '!value').should ==
|
73
|
+
"url?#{ arg.to_s.dasherize }=%21value"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
it 'should ignore unknown options' do
|
77
|
+
Picasa.path(:url => 'place', :eggs => 'over_easy').should == 'place'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe 'parse_url' do
|
82
|
+
it 'should prefer url' do
|
83
|
+
hash = { :url => 'url', :user_id => 'user_id', :album_id => 'album_id' }
|
84
|
+
Picasa.parse_url(hash).should == ['url', {}]
|
85
|
+
end
|
86
|
+
it 'should next prefer user_id' do
|
87
|
+
Picasa.stubs(:is_url?).returns true
|
88
|
+
hash = { :user_id => 'user_id', :album_id => 'album_id' }
|
89
|
+
Picasa.parse_url(hash).should == ['user_id', {}]
|
90
|
+
end
|
91
|
+
it 'should use album_id' do
|
92
|
+
Picasa.stubs(:is_url?).returns true
|
93
|
+
hash = { :album_id => 'album_id' }
|
94
|
+
Picasa.parse_url(hash).should == ['album_id', {}]
|
95
|
+
end
|
96
|
+
it 'should split up the params' do
|
97
|
+
hash = { :url => 'url?specs=fun%21' }
|
98
|
+
Picasa.parse_url(hash).should == ['url', { 'specs' => 'fun!' }]
|
99
|
+
end
|
100
|
+
it 'should not use non-url user_id or album_id' do
|
101
|
+
hash = { :user_id => 'user_id', :album_id => 'album_id' }
|
102
|
+
Picasa.parse_url(hash).should == [nil, {}]
|
103
|
+
end
|
104
|
+
it 'should handle with no relevant options' do
|
105
|
+
hash = { :saoetu => 'aeu' }
|
106
|
+
Picasa.parse_url(hash).should == [nil, {}]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe Picasa do
|
112
|
+
def body(text)
|
113
|
+
#open_file('user_feed.atom').read
|
114
|
+
@response.stubs(:body).returns(text)
|
115
|
+
end
|
116
|
+
|
117
|
+
before do
|
118
|
+
@response = mock('response')
|
119
|
+
@response.stubs(:code).returns '200'
|
120
|
+
@http = mock('http')
|
121
|
+
@http.stubs(:get).returns @response
|
122
|
+
Net::HTTP.stubs(:new).returns(@http)
|
123
|
+
@p = Picasa.new 'token'
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should initialize' do
|
127
|
+
@p.token.should == 'token'
|
128
|
+
end
|
129
|
+
|
130
|
+
describe 'authorize_token!' do
|
131
|
+
before do
|
132
|
+
@p.expects(:auth_header).returns('Authorization' => 'etc')
|
133
|
+
@http.expects(:use_ssl=).with true
|
134
|
+
@http.expects(:get).with('/accounts/accounts/AuthSubSessionToken',
|
135
|
+
'Authorization' => 'etc').returns(@response)
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should set the new token' do
|
139
|
+
body 'Token=hello'
|
140
|
+
@p.authorize_token!
|
141
|
+
@p.token.should == 'hello'
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should raise if the token is not found' do
|
145
|
+
body 'nothing to see here'
|
146
|
+
lambda do
|
147
|
+
@p.authorize_token!
|
148
|
+
end.should raise_error(RubyPicasa::PicasaTokenError)
|
149
|
+
@p.token.should == 'token'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should get the user' do
|
154
|
+
@p.expects(:get).with(:user_id => 'default')
|
155
|
+
@p.user
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'should get an album' do
|
159
|
+
@p.expects(:get).with(:album_id => 'album')
|
160
|
+
@p.album('album')
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should get a url' do
|
164
|
+
@p.expects(:get).with(:url => 'the url')
|
165
|
+
@p.get_url('the url')
|
166
|
+
end
|
167
|
+
|
168
|
+
describe 'search' do
|
169
|
+
it 'should prefer given options' do
|
170
|
+
@p.expects(:get).with(:q => 'q', :max_results => 20, :user_id => 'me', :kind => 'comments')
|
171
|
+
@p.search('q', :max_results => 20, :user_id => 'me', :kind => 'comments', :q => 'wrong')
|
172
|
+
end
|
173
|
+
it 'should have good defaults' do
|
174
|
+
@p.expects(:get).with(:q => 'q', :max_results => 10, :user_id => 'all', :kind => 'photo')
|
175
|
+
@p.search('q')
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'should get recent photos' do
|
180
|
+
@p.expects(:get).with(:user_id => 'default', :recent_photos => true, :max_results => 10)
|
181
|
+
@p.recent_photos :max_results => 10
|
182
|
+
end
|
183
|
+
|
184
|
+
describe 'album_by_title' do
|
185
|
+
before do
|
186
|
+
@a1 = mock('a1')
|
187
|
+
@a2 = mock('a2')
|
188
|
+
@a1.stubs(:title).returns('a1')
|
189
|
+
@a2.stubs(:title).returns('a2')
|
190
|
+
albums = [ @a1, @a2 ]
|
191
|
+
user = mock('user', :albums => albums)
|
192
|
+
@p.expects(:user).returns(user)
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should match the title string' do
|
196
|
+
@a2.expects(:load).with({}).returns :result
|
197
|
+
@p.album_by_title('a2').should == :result
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'should match a regex' do
|
201
|
+
@a1.expects(:load).with({}).returns :result
|
202
|
+
@p.album_by_title(/a\d/).should == :result
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'should return nil' do
|
206
|
+
@p.album_by_title('zzz').should be_nil
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
describe 'xml' do
|
211
|
+
it 'should return the body with a 200 status' do
|
212
|
+
body 'xml goes here'
|
213
|
+
@p.xml.should == 'xml goes here'
|
214
|
+
end
|
215
|
+
it 'should return nil with a non-200 status' do
|
216
|
+
body 'xml goes here'
|
217
|
+
@response.expects(:code).returns '404'
|
218
|
+
@p.xml.should be_nil
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
describe 'get' do
|
223
|
+
it 'should call class_from_xml if with_cache yields' do
|
224
|
+
@p.expects(:with_cache).with({}).yields(:xml).returns(:result)
|
225
|
+
@p.expects(:class_from_xml).with(:xml)
|
226
|
+
@p.get.should == :result
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'should do nothing if with_cache does not yield' do
|
230
|
+
@p.expects(:with_cache).with({}) # doesn't yield
|
231
|
+
@p.expects(:class_from_xml).never
|
232
|
+
@p.get.should be_nil
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
describe 'auth_header' do
|
237
|
+
it 'should build an AuthSub header' do
|
238
|
+
@p.auth_header.should == { "Authorization" => %{AuthSub token="token"} }
|
239
|
+
end
|
240
|
+
|
241
|
+
it 'should do nothing' do
|
242
|
+
p = Picasa.new nil
|
243
|
+
p.auth_header.should == { }
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
describe 'with_cache' do
|
248
|
+
it 'yields fresh xml' do
|
249
|
+
body 'fresh xml'
|
250
|
+
yielded = false
|
251
|
+
@p.with_cache(:url => 'place') do |xml|
|
252
|
+
yielded = true
|
253
|
+
xml.should == 'fresh xml'
|
254
|
+
end
|
255
|
+
yielded.should be_true
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'yields cached xml' do
|
259
|
+
@p.instance_variable_get('@request_cache')['place'] = 'some xml'
|
260
|
+
yielded = false
|
261
|
+
@p.with_cache(:url => 'place') do |xml|
|
262
|
+
yielded = true
|
263
|
+
xml.should == 'some xml'
|
264
|
+
end
|
265
|
+
yielded.should be_true
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
describe 'xml_data' do
|
270
|
+
it 'should extract categories from the xml' do
|
271
|
+
xml, feed_schema, entry_schema = @p.xml_data(open_file('album.atom'))
|
272
|
+
xml.should be_an_instance_of(Nokogiri::XML::Element)
|
273
|
+
feed_schema.should == 'http://schemas.google.com/photos/2007#album'
|
274
|
+
entry_schema.should == 'http://schemas.google.com/photos/2007#photo'
|
275
|
+
end
|
276
|
+
|
277
|
+
it 'should handle nil' do
|
278
|
+
xml, feed_schema, entry_schema = @p.xml_data(nil)
|
279
|
+
xml.should be_nil
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'should handle bad xml' do
|
283
|
+
xml, feed_schema, entry_schema = @p.xml_data('<entry>something went wrong')
|
284
|
+
xml.should_not be_nil
|
285
|
+
feed_schema.should be_nil
|
286
|
+
entry_schema.should be_nil
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
describe 'class_from_xml' do
|
291
|
+
before do
|
292
|
+
@user = 'http://schemas.google.com/photos/2007#user'
|
293
|
+
@album = 'http://schemas.google.com/photos/2007#album'
|
294
|
+
@photo = 'http://schemas.google.com/photos/2007#photo'
|
295
|
+
end
|
296
|
+
|
297
|
+
describe 'valid feed category types' do
|
298
|
+
def to_create(klass, feed, entry)
|
299
|
+
@object = mock('object', :session= => nil)
|
300
|
+
@p.expects(:xml_data).with(:xml).returns([:xml, feed, entry])
|
301
|
+
klass.expects(:new).with(:xml, @p).returns(@object)
|
302
|
+
@p.class_from_xml(:xml)
|
303
|
+
end
|
304
|
+
it('user album') { to_create RubyPicasa::User, @user, @album }
|
305
|
+
it('user photo') { to_create RubyPicasa::RecentPhotos, @user, @photo }
|
306
|
+
it('album nil') { to_create RubyPicasa::Album, @album, nil }
|
307
|
+
it('album photo') { to_create RubyPicasa::Album, @album, @photo }
|
308
|
+
it('photo nil') { to_create RubyPicasa::Photo, @photo, nil }
|
309
|
+
it('photo photo') { to_create RubyPicasa::Search, @photo, @photo }
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'should raise an error for invalid feed category types' do
|
313
|
+
@p.expects(:xml_data).with(:xml).returns([:xml, @album, @user])
|
314
|
+
lambda do
|
315
|
+
@p.class_from_xml(:xml)
|
316
|
+
end.should raise_error(RubyPicasa::PicasaError)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|