jbgutierrez-delicious_api 1.0.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.
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe DeliciousApi do
4
+
5
+ end
6
+
7
+ # EOF
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ include DeliciousApi
4
+
5
+ describe Base do
6
+ it "should raise an exception when no wrapper has been assigned" do
7
+ lambda { Base.wrapper }.should raise_error(WrapperNotInitialized)
8
+ end
9
+ end
@@ -0,0 +1,177 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ include DeliciousApi
4
+
5
+ describe Bookmark do
6
+
7
+ configure_wrapper
8
+
9
+ freeze_time # Freezing time for better testing
10
+
11
+ describe "an instance of the Bookmark class" do
12
+
13
+ def build_bookmark(opt={})
14
+ options = { :description => 'Yahoo!', :extended => 'My favorite site ever',
15
+ :hash => '2f9704c729e7ed3b41647b7d0ad649fe', :meta => '77e1ec24a43bae61fb67586649683d30',
16
+ :others => '433', :tags => 'yahoo web search', :time => Time.now.iso8601 }
17
+ Bookmark.new 'http://www.yahoo.com/', options.merge(opt)
18
+ end
19
+
20
+ before(:each) do
21
+ @bookmark = build_bookmark
22
+ end
23
+
24
+ it "should have a href attribute" do
25
+ @bookmark.href.should == 'http://www.yahoo.com/'
26
+ end
27
+
28
+ it "should have a description attribute" do
29
+ @bookmark.description.should == 'Yahoo!'
30
+ end
31
+
32
+ it "should have an extended description attribute" do
33
+ @bookmark.extended.should == 'My favorite site ever'
34
+ end
35
+
36
+ it "should have a hash attribute" do
37
+ @bookmark.hash.should == '2f9704c729e7ed3b41647b7d0ad649fe'
38
+ end
39
+
40
+ it "should have a meta attribute" do
41
+ @bookmark.meta.should == '77e1ec24a43bae61fb67586649683d30'
42
+ end
43
+
44
+ it "should have an others attribute" do
45
+ @bookmark.others.should == '433'
46
+ end
47
+
48
+ it "should have an array of tags" do
49
+ @bookmark.tags.should == %w[yahoo web search]
50
+ end
51
+
52
+ it "should have a time attribute" do
53
+ @bookmark.time.iso8601.should == Time.now.iso8601
54
+ end
55
+
56
+ it "should be 'shared' by default" do
57
+ @bookmark.shared.should == true
58
+ end
59
+
60
+ it "should allow to specify an array of tags or an actual Time instance as a parameter" do
61
+ @bookmark = build_bookmark :tags => %w[array of tags],
62
+ :time => Time.now
63
+ @bookmark.tags.should == %w[array of tags]
64
+ @bookmark.time.should == Time.now
65
+ end
66
+
67
+ describe "having a save method" do
68
+
69
+ it "should do it succesfully" do
70
+ @bookmark.wrapper.should_receive(:add_bookmark).
71
+ with('http://www.yahoo.com/', 'Yahoo!',
72
+ {:shared => 'yes', :tags => 'yahoo web search', :dt => Time.now.iso8601,
73
+ :extended => 'My favorite site ever', :replace => 'no' }).
74
+ and_return(true)
75
+ @bookmark.save
76
+ end
77
+
78
+ it "should force replacement through a bang method" do
79
+ @bookmark.wrapper.should_receive(:add_bookmark).
80
+ with('http://www.yahoo.com/', 'Yahoo!',
81
+ {:shared => 'yes', :tags => 'yahoo web search', :dt => Time.now.iso8601,
82
+ :extended => 'My favorite site ever', :replace => 'yes' }).
83
+ and_return(true)
84
+ @bookmark.save!
85
+ end
86
+
87
+ it "should raise an exception when href is nil" do
88
+ @bookmark.href = nil
89
+ lambda { @bookmark.save }.should raise_error(MissingAttributeError)
90
+ end
91
+
92
+ it "should raise an exception when description is nil" do
93
+ @bookmark.description = nil
94
+ lambda { @bookmark.save }.should raise_error(MissingAttributeError)
95
+ end
96
+
97
+ it "should raise OperationFailed" do
98
+ @bookmark.wrapper.should_receive(:add_bookmark).and_return(false)
99
+ lambda { @bookmark.save! }.should raise_error(OperationFailed)
100
+ end
101
+
102
+ end
103
+
104
+ describe "having a fetch suggested tags method" do
105
+
106
+ it "should do it succesfully" do
107
+ @bookmark.wrapper.should_receive(:get_suggested_tags_for_url).with('http://www.yahoo.com/')
108
+ @bookmark.suggested_tags
109
+ end
110
+
111
+ it "should raise an exception on missing attributes" do
112
+ @bookmark.href = nil
113
+ lambda { @bookmark.suggested_tags }.should raise_error(MissingAttributeError)
114
+ end
115
+
116
+ end
117
+
118
+ describe "having a destroy method" do
119
+
120
+ it "should do it succesfully" do
121
+ @bookmark.wrapper.should_receive(:delete_bookmark).with('http://www.yahoo.com/').and_return(true)
122
+ @bookmark.destroy
123
+ end
124
+
125
+ it "should raise an exception on missing attributes" do
126
+ @bookmark.href = nil
127
+ lambda { @bookmark.destroy }.should raise_error(MissingAttributeError)
128
+ end
129
+
130
+ it "should raise OperationFailed" do
131
+ @bookmark.wrapper.should_receive(:delete_bookmark).and_return(false)
132
+ @bookmark.destroy
133
+ end
134
+ end
135
+
136
+ end
137
+
138
+ describe "Bookmark class" do
139
+
140
+ it "should find a Bookmark by its url" do
141
+ Base.wrapper.should_receive(:get_bookmark_by_url).with('http://www.yahoo.com/')
142
+ Bookmark.find 'http://www.yahoo.com/'
143
+ end
144
+
145
+ it "should find one or more bookmarks on a single day matching filtered (by tags or hashes) the results" do
146
+ Base.wrapper.should_receive(:get_bookmarks_by_date).
147
+ with( Time.now.iso8601, {:tag => 'yahoo web search', :hashes => 'hash1 hash2 hash3', :meta => 'yes' })
148
+ Bookmark.find_by_date Time.now, :tags => %w[yahoo web search], :hashes => %w[hash1 hash2 hash3]
149
+ end
150
+
151
+ describe "fetching recent bookmarks" do
152
+ it "should allow to limit and filter (by tag) the results" do
153
+ Base.wrapper.should_receive(:get_recent_bookmarks).with(:tag => 'yahoo', :limit => 10)
154
+ Bookmark.find_recent :tag => 'yahoo', :limit => 10
155
+ end
156
+ it "should default limit size to 10" do
157
+ Base.wrapper.should_receive(:get_recent_bookmarks).with(:tag => 'yahoo', :limit => 10)
158
+ Bookmark.find_recent :tag => 'yahoo'
159
+ end
160
+ end
161
+
162
+ describe "fetching all the bookmarks" do
163
+ it "should allow to limit and filter (by tag) the results" do
164
+ Base.wrapper.should_receive(:get_all_bookmarks).with(:tag => 'yahoo', :limit => 10)
165
+ Bookmark.find_all :tag => 'yahoo', :limit => 10
166
+ end
167
+ it "should allow to filter the results by a date range" do
168
+ start_time = Time.now - 2
169
+ end_time = Time.now
170
+ Base.wrapper.should_receive(:get_all_bookmarks).with(:fromdt => start_time.iso8601, :todt => end_time.iso8601)
171
+ Bookmark.find_all :start_time => start_time, :end_time => end_time
172
+ end
173
+ end
174
+
175
+ end
176
+
177
+ end
@@ -0,0 +1,76 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ include DeliciousApi
4
+
5
+ describe Bundle do
6
+
7
+ configure_wrapper
8
+
9
+ describe "an instance of the Bundle class" do
10
+
11
+ before(:each) do
12
+ @bundle = Bundle.new 'languages', %w[galician spanish english french]
13
+ end
14
+
15
+ it "should have a name" do
16
+ @bundle.name.should == 'languages'
17
+ end
18
+
19
+ it "should have an array of tags" do
20
+ @bundle.tags.size.should == 4
21
+ @bundle.tags.first.should == 'galician'
22
+ @bundle.tags.last.should == 'french'
23
+ end
24
+
25
+ describe "having a save method" do
26
+
27
+ it "should do it succesfully" do
28
+ @bundle.wrapper.should_receive(:set_bundle).with(@bundle.name, @bundle.tags.join(' ')).and_return(true)
29
+ @bundle.save
30
+ end
31
+
32
+ it "should raise an exception on missing attributes" do
33
+ @bundle.name = nil
34
+ @bundle.tags = nil
35
+ lambda { @bundle.save }.should raise_error(MissingAttributeError)
36
+ end
37
+
38
+ it "should raise OperationFailed" do
39
+ @bundle.wrapper.should_receive(:set_bundle).and_return(false)
40
+ lambda { @bundle.save }.should raise_error(OperationFailed)
41
+ end
42
+
43
+ end
44
+
45
+ describe "having a remove method" do
46
+
47
+ it "should do it succesfully" do
48
+ @bundle.wrapper.should_receive(:delete_bundle).with(@bundle.name).and_return(true)
49
+ @bundle.delete
50
+ end
51
+
52
+ it "should raise an exception on missing attributes" do
53
+ @bundle.name = nil
54
+ lambda { @bundle.delete }.should raise_error(MissingAttributeError)
55
+ end
56
+
57
+ it "should raise OperationFailed" do
58
+ @bundle.wrapper.should_receive(:delete_bundle).and_return(false)
59
+ lambda { @bundle.delete }.should raise_error(OperationFailed)
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+
66
+ describe "Bundle class" do
67
+
68
+ it "should fetch tag bundles" do
69
+ LIMIT = 10
70
+ Base.wrapper.should_receive(:get_all_bundles).with(LIMIT)
71
+ Bundle.all(LIMIT)
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,78 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ include DeliciousApi
4
+
5
+ describe Tag do
6
+
7
+ configure_wrapper
8
+
9
+ describe "an instance of the Tag class" do
10
+
11
+ before(:each) do
12
+ @tag = Tag.new 'name', 'count' => '5'
13
+ end
14
+
15
+ it "should have a name" do
16
+ @tag.name.should == 'name'
17
+ end
18
+
19
+ it "should have a count" do
20
+ @tag.count.should == '5'
21
+ end
22
+
23
+ describe "having a remove method" do
24
+
25
+ it "should do it succesfully" do
26
+ @tag.wrapper.should_receive(:delete_tag).with(@tag.name).and_return(true)
27
+ @tag.delete
28
+ end
29
+
30
+ it "should raise an exception on missing attributes" do
31
+ @tag.name = nil
32
+ lambda { @tag.delete }.should raise_error(MissingAttributeError)
33
+ end
34
+
35
+ it "should raise OperationFailed" do
36
+ @tag.wrapper.should_receive(:delete_tag).and_return(false)
37
+ lambda { @tag.delete }.should raise_error(OperationFailed)
38
+ end
39
+
40
+ end
41
+
42
+ describe "having a save method" do
43
+
44
+ it "should do it succesfully" do
45
+ @tag.wrapper.should_receive(:rename_tag).with(@tag.name, 'new_name').and_return(true)
46
+ @tag.name = 'new_name'
47
+ @tag.save
48
+ end
49
+
50
+ it "should description" do
51
+ @tag.name = nil
52
+ lambda { @tag.save }.should raise_error(MissingAttributeError)
53
+ end
54
+
55
+ it "should raise OperationFailed" do
56
+ @tag.wrapper.should_receive(:rename_tag).and_return(false)
57
+ @tag.name = 'new_name'
58
+ lambda { @tag.save }.should raise_error(OperationFailed)
59
+ end
60
+
61
+ it "should do nothing when the name hasn't been change" do
62
+ @tag.wrapper.should_not_receive(:rename_tag)
63
+ @tag.save
64
+ end
65
+
66
+ end
67
+ end
68
+
69
+ describe "Bundle class" do
70
+
71
+ it "should fetch all tags" do
72
+ Base.wrapper.should_receive(:get_all_tags)
73
+ Tag.all
74
+ end
75
+
76
+ end
77
+
78
+ end
@@ -0,0 +1,431 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ include DeliciousApi
4
+
5
+ USER = 'user'
6
+ PASSWORD = 'password'
7
+ USER_AGENT = 'user agent'
8
+
9
+ def request_should_be_sent_to(url)
10
+ headers = { 'User-Agent' => USER_AGENT }
11
+ Net::HTTP::Get.should_receive(:new).with(url,headers).at_most(2).and_return(@request)
12
+ end
13
+
14
+ def stub_body_response_with(xml)
15
+ @response.stub!(:body).and_return(xml)
16
+ end
17
+
18
+ describe Wrapper do
19
+
20
+ describe "Initialization" do
21
+
22
+ it "should raise error when no credentials have been specified" do
23
+ lambda { Wrapper.new(nil, nil) }.should raise_error(ArgumentError)
24
+ lambda { Wrapper.new(USER, nil) }.should raise_error(ArgumentError)
25
+ lambda { Wrapper.new(nil, PASSWORD) }.should raise_error(ArgumentError)
26
+ end
27
+
28
+ it "should set user and password and a default User-Agent" do
29
+ wrapper = Wrapper.new(USER, PASSWORD)
30
+ wrapper.user.should eql(USER)
31
+ wrapper.password.should eql(PASSWORD)
32
+ end
33
+
34
+ it "should allow an optional User-Agent" do
35
+ wrapper = Wrapper.new(USER, PASSWORD, :user_agent => USER_AGENT)
36
+ wrapper.user_agent.should equal(USER_AGENT)
37
+ end
38
+
39
+ it "should allow an alternative time gap" do
40
+ waiting_time_gap = 2
41
+ wrapper = Wrapper.new(USER, PASSWORD, :waiting_time_gap => waiting_time_gap)
42
+ wrapper.waiting_time_gap.should equal(waiting_time_gap)
43
+ end
44
+
45
+ end
46
+
47
+ describe "Requests" do
48
+
49
+ before do
50
+ options = { :user_agent => USER_AGENT, :waiting_time_gap => 0 }
51
+
52
+ @wrapper = Wrapper.new(USER, PASSWORD, options )
53
+ @request = Net::HTTP::Get.new('/')
54
+ @response = Net::HTTPSuccess.new('httpv', '200', 'msg')
55
+ @http_client = Net::HTTP.new('api.del.icio.us')
56
+
57
+ Net::HTTP.stub!(:new).and_return(@http_client)
58
+ @http_client.stub!(:start).and_yield(@http_client) # behaviour overriden so that it doesn't open a TCP connection
59
+ @http_client.stub!(:request).with(@request).and_return(@response)
60
+ end
61
+
62
+ describe "Generic request" do
63
+
64
+ def send_fake_request
65
+ request_should_be_sent_to "/"
66
+ stub_body_response_with "response"
67
+ @wrapper.send :process_request, "/" # not quite sure if sending a message to a a private method is a good practice
68
+ end
69
+
70
+ it "should use SSL" do
71
+ Net::HTTP.should_receive(:new).with('api.del.icio.us', 443)
72
+ @http_client.should_receive(:use_ssl=).with(true)
73
+ send_fake_request
74
+ end
75
+
76
+ it "should set user and password" do
77
+ @request.should_receive(:basic_auth).with(USER, PASSWORD).once
78
+ send_fake_request
79
+ end
80
+
81
+ it "should set User-Agent to something identifiable"
82
+
83
+ it "should wait AT LEAST ONE SECOND between queries" do
84
+ @wrapper = Wrapper.new(USER, PASSWORD, :user_agent => USER_AGENT )
85
+ measurement = Benchmark.measure{ send_fake_request; send_fake_request; }
86
+ measurement.real.should take_more_than(1.second)
87
+ measurement.real.should_not take_more_than(1.05.second)
88
+ end
89
+
90
+ it "should handle 401 errors" do
91
+ response_401 = Net::HTTPUnauthorized.new nil, nil, nil
92
+ @http_client.stub!(:request).with(@request).and_return(response_401)
93
+ lambda { send_fake_request }.should raise_error(HTTPError)
94
+ end
95
+
96
+ it "should handle 503 errors" do
97
+ response_503 = Net::HTTPServiceUnavailable.new nil, nil, nil
98
+ @http_client.stub!(:request).with(@request).and_return(response_503)
99
+ lambda { send_fake_request }.should raise_error(HTTPError)
100
+ end
101
+
102
+ end
103
+
104
+ describe "Tags requests" do
105
+
106
+ it "should fetch all tags" do
107
+ #mocking
108
+ request_should_be_sent_to '/v1/tags/get'
109
+ stub_body_response_with <<-EOS
110
+ <tags>
111
+ <tag count="1" tag="activedesktop" />
112
+ <tag count="1" tag="business" />
113
+ <tag count="3" tag="radio" />
114
+ <tag count="5" tag="xml" />
115
+ <tag count="1" tag="xp" />
116
+ <tag count="1" tag="xpi" />
117
+ </tags>
118
+ EOS
119
+ # actual method call
120
+ tags = @wrapper.get_all_tags
121
+
122
+ # return value expectations
123
+ tags.size.should == 6
124
+ tag = tags.first
125
+ tag.should be_a_kind_of(Tag)
126
+
127
+ tag.name.should == "activedesktop"
128
+ tag.count.should == "1"
129
+ end
130
+
131
+ it "should rename a tag on all posts" do
132
+ # mocking
133
+ request_should_be_sent_to '/v1/tags/rename?new=new_name&old=original_name'
134
+ stub_body_response_with '<result code="done" />'
135
+
136
+ # actual method call
137
+ result = @wrapper.rename_tag 'original_name', 'new_name'
138
+
139
+ # return value expectations
140
+ result.should == true
141
+
142
+ end
143
+
144
+ it "should delete a tag from all posts" do
145
+ # mocking
146
+ request_should_be_sent_to '/v1/tags/delete?tag=tag_to_delete'
147
+ stub_body_response_with '<result code="done" />'
148
+
149
+ # actual method call
150
+ result = @wrapper.delete_tag 'tag_to_delete'
151
+
152
+ # return value expectations
153
+ result.should == true
154
+ end
155
+
156
+ it "should fetch popular, recommended and network tags for a specific url" do
157
+ #mocking
158
+ request_should_be_sent_to '/v1/posts/suggest?url=http%3A%2F%2Fyahoo.com%2F'
159
+ stub_body_response_with <<-EOS
160
+ <?xml version="1.0" encoding="UTF-8"?>
161
+ <suggest>
162
+ <popular>yahoo!</popular>
163
+ <popular>yahoo</popular>
164
+ <popular>web</popular>
165
+ <popular>tools</popular>
166
+ <popular>searchengines</popular>
167
+ <recommended>yahoo!</recommended>
168
+ <recommended>yahoo</recommended>
169
+ <recommended>web</recommended>
170
+ <recommended>tools</recommended>
171
+ <recommended>search</recommended>
172
+ <recommended>reference</recommended>
173
+ <recommended>portal</recommended>
174
+ <recommended>news</recommended>
175
+ <recommended>music</recommended>
176
+ <recommended>internet</recommended>
177
+ <recommended>home</recommended>
178
+ <recommended>games</recommended>
179
+ <recommended>entertainment</recommended>
180
+ <recommended>email</recommended>
181
+ <network>for:Bernard</network>
182
+ <network>for:britta</network>
183
+ <network>for:deusx</network>
184
+ <network>for:joshua</network>
185
+ <network>for:stlhood</network>
186
+ <network>for:theteam</network>
187
+ </suggest>
188
+ EOS
189
+ # actual method call
190
+ suggestions = @wrapper.get_suggested_tags_for_url('http://yahoo.com/')
191
+
192
+ # return value expectations
193
+ suggestions[:popular].size.should == 5
194
+ suggestions[:recommended].size.should == 14
195
+ suggestions[:network].size.should == 6
196
+
197
+ first_popular = suggestions[:popular].first
198
+ first_popular.should be_a_kind_of(Tag)
199
+ first_popular.name.should == 'yahoo!'
200
+
201
+ first_recommended = suggestions[:recommended].first
202
+ first_recommended.should be_a_kind_of(Tag)
203
+ first_recommended.name.should == 'yahoo!'
204
+
205
+ first_network = suggestions[:network].first
206
+ first_network.should be_a_kind_of(Tag)
207
+ first_network.name.should == 'for:Bernard'
208
+ end
209
+
210
+ end
211
+
212
+ describe "Bookmark requests" do
213
+
214
+ it "should add a new bookmark" do
215
+ request_should_be_sent_to '/v1/posts/add?description=foo&url=bar'
216
+ stub_body_response_with '<result code="done" />'
217
+ result = @wrapper.add_bookmark 'bar', 'foo'
218
+ result.should == true
219
+ end
220
+
221
+ describe "should delete an existing bookmark" do
222
+ it do
223
+ request_should_be_sent_to '/v1/posts/delete?url=foo'
224
+ stub_body_response_with '<result code="done" />'
225
+ result = @wrapper.delete_bookmark 'foo'
226
+ result.should == true
227
+ end
228
+
229
+ it "(item not found)" do
230
+ request_should_be_sent_to '/v1/posts/delete?url=foo'
231
+ stub_body_response_with '<result code="item not found" />'
232
+ result = @wrapper.delete_bookmark 'foo'
233
+ result.should == true
234
+ end
235
+ end
236
+
237
+ it "should get bookmark for a single date" do
238
+ # mocking
239
+ request_should_be_sent_to '/v1/posts/get?meta=yes&tag=webdev'
240
+ stub_body_response_with <<-EOS
241
+ <?xml version="1.0" encoding="UTF-8"?>
242
+ <posts dt="2005-11-28" tag="webdev" user="user">
243
+ <post href="http://www.howtocreate.co.uk/tutorials/texterise.php?dom=1"
244
+ description="JavaScript DOM reference"
245
+ extended="dom reference"
246
+ hash="c0238dc0c44f07daedd9a1fd9bbdeebd"
247
+ meta="92959a96fd69146c5fe7cbde6e5720f2"
248
+ others="55" tag="dom javascript webdev" time="2005-11-28T05:26:09Z" />
249
+ </posts>
250
+ EOS
251
+
252
+ # actual method
253
+ bookmarks = @wrapper.get_bookmarks_by_date(nil, { :tag => 'webdev', :meta => 'yes'})
254
+
255
+ # return value expectations
256
+ bookmarks.size.should == 1
257
+ bookmark = bookmarks.first
258
+ bookmark.should be_a_kind_of(Bookmark)
259
+ bookmark.href.should == "http://www.howtocreate.co.uk/tutorials/texterise.php?dom=1"
260
+ bookmark.description.should == "JavaScript DOM reference"
261
+ bookmark.extended.should == "dom reference"
262
+ bookmark.hash.should == "c0238dc0c44f07daedd9a1fd9bbdeebd"
263
+ bookmark.meta.should == "92959a96fd69146c5fe7cbde6e5720f2"
264
+ bookmark.others.should == "55"
265
+ bookmark.tags.should == %w[dom javascript webdev]
266
+ bookmark.time.should == Time.iso8601('2005-11-28T05:26:09Z')
267
+ end
268
+
269
+ it "should get fetch a specific bookmark" do
270
+ # mocking
271
+ request_should_be_sent_to '/v1/posts/get?url=http%3A%2F%2Fwww.yahoo.com%2F'
272
+ stub_body_response_with <<-EOS
273
+ <?xml version="1.0" encoding="UTF-8"?>
274
+ <posts user="user" dt="2007-12-11" tag="">
275
+ <post href="http://www.yahoo.com/"
276
+ hash="2f9704c729e7ed3b41647b7d0ad649fe"
277
+ description="Yahoo!"
278
+ extended="My favorite site ever"
279
+ tag="yahoo web search" time="2007-12-11T00:00:07Z" others="433" />
280
+ </posts>
281
+ EOS
282
+
283
+ # actual method
284
+ bookmark = @wrapper.get_bookmark_by_url('http://www.yahoo.com/')
285
+
286
+ # return value expectations
287
+ bookmark.should be_a_kind_of(Bookmark)
288
+ bookmark.href.should == "http://www.yahoo.com/"
289
+ bookmark.description.should == "Yahoo!"
290
+ bookmark.extended.should == "My favorite site ever"
291
+ bookmark.hash.should == "2f9704c729e7ed3b41647b7d0ad649fe"
292
+ bookmark.others.should == "433"
293
+ bookmark.tags.should == %w[yahoo web search]
294
+ bookmark.time.should == Time.iso8601('2007-12-11T00:00:07Z')
295
+ end
296
+
297
+ it "should fetch recent bookmarks" do
298
+ # mocking
299
+ request_should_be_sent_to '/v1/posts/recent?count=2'
300
+ stub_body_response_with <<-EOS
301
+ <?xml version="1.0" encoding="UTF-8"?>
302
+ <posts user="jbgutierrez" tag="">
303
+ <post href="http://foo/" hash="82860ec95b0c5ca86212bfca3b352ed0" description="Foo Site" tag="Foo" time="2008-01-01T00:00:00Z" extended=""/>
304
+ <post href="http://bar/" hash="fbaf0c0208a3f1664d5e520fd4e8000a" description="Bar Site" tag="Bar" time="2009-01-01T00:00:00Z" extended=""/>
305
+ </posts>
306
+ EOS
307
+
308
+ # actual method
309
+ bookmarks = @wrapper.get_recent_bookmarks(:count => 2)
310
+
311
+ # return value expectations
312
+ bookmarks.size.should == 2
313
+ bookmark = bookmarks.first
314
+ bookmark.should be_a_kind_of(Bookmark)
315
+
316
+ bookmark.href.should == "http://foo/"
317
+ bookmark.hash.should == "82860ec95b0c5ca86212bfca3b352ed0"
318
+ bookmark.description.should == "Foo Site"
319
+ bookmark.tags.should == %w[Foo]
320
+ bookmark.time.should == Time.iso8601('2008-01-01T00:00:00Z')
321
+ end
322
+
323
+ it "should fetch all bookmarks by date or index range" do
324
+ # mocking
325
+ request_should_be_sent_to "/v1/posts/all?results=2"
326
+ stub_body_response_with <<-EOS
327
+ <?xml version="1.0" encoding="UTF-8"?>
328
+ <posts user="jbgutierrez" tag="">
329
+ <post href="http://foo/" hash="82860ec95b0c5ca86212bfca3b352ed0" description="Foo Site" tag="Foo" time="2008-01-01T00:00:00Z" extended=""/>
330
+ <post href="http://bar/" hash="fbaf0c0208a3f1664d5e520fd4e8000a" description="Bar Site" tag="Bar" time="2009-01-01T00:00:00Z" extended=""/>
331
+ </posts>
332
+ EOS
333
+
334
+ # actual method
335
+ bookmarks = @wrapper.get_all_bookmarks(:results => 2)
336
+
337
+ # return value expectations
338
+ bookmarks.size.should == 2
339
+ bookmark = bookmarks.first
340
+ bookmark.should be_a_kind_of(Bookmark)
341
+
342
+ bookmark.href.should == "http://foo/"
343
+ bookmark.hash.should == "82860ec95b0c5ca86212bfca3b352ed0"
344
+ bookmark.description.should == "Foo Site"
345
+ bookmark.tags.should == %w[Foo]
346
+ bookmark.time.should == Time.iso8601('2008-01-01T00:00:00Z')
347
+ end
348
+
349
+ end
350
+
351
+ describe "Tag Bundles requests" do
352
+
353
+ it "should fetch user bundles" do
354
+ # mocking
355
+ request_should_be_sent_to "/v1/tags/bundles/all?"
356
+ stub_body_response_with <<-EOS
357
+ <bundles>
358
+ <bundle name="languages" tags="galician spanish english french" />
359
+ <bundle name="music" tags="ipod mp3 music" />
360
+ </bundles>
361
+ EOS
362
+
363
+ # actual method
364
+ bundles = @wrapper.get_all_bundles
365
+
366
+ # return value expectations
367
+ bundles.size.should == 2
368
+ bundle = bundles.first
369
+ bundle.should be_a_kind_of(Bundle)
370
+
371
+ bundle.name.should == "languages"
372
+ bundle.tags.should == %w[galician spanish english french]
373
+ end
374
+
375
+ it "should fetch a specific tag bundle" do
376
+ # mocking
377
+ request_should_be_sent_to "/v1/tags/bundles/all?bundle=music"
378
+ stub_body_response_with <<-EOS
379
+ <bundles>
380
+ <bundle name="music" tags="ipod mp3 music" />
381
+ </bundles>
382
+ EOS
383
+
384
+ # actual method
385
+ bundle = @wrapper.get_bundle_by_name 'music'
386
+
387
+ # return value expectations
388
+ bundle.should be_a_kind_of(Bundle)
389
+ bundle.name.should == "music"
390
+ bundle.tags.should == %w[ipod mp3 music]
391
+ end
392
+
393
+ it "should assign a set of tags to a bundle" do
394
+ # mocking
395
+ request_should_be_sent_to "/v1/tags/bundles/set?bundle=music&tags=ipod+mp3+music"
396
+ stub_body_response_with "<result>ok</result>"
397
+
398
+ # actual method
399
+ result = @wrapper.set_bundle 'music', 'ipod mp3 music'
400
+
401
+ # return value expectations
402
+ result.should == true
403
+ end
404
+
405
+ it "should delete a tag bundle" do
406
+ # mocking
407
+ request_should_be_sent_to '/v1/tags/bundles/delete?bundle=foo'
408
+ stub_body_response_with '<result code="done" />'
409
+
410
+ # actual method call
411
+ result = @wrapper.delete_bundle 'foo'
412
+
413
+ # return value expectations
414
+ result.should == true
415
+ end
416
+
417
+ end
418
+
419
+ describe "Other requests" do
420
+
421
+ it "should fetch a change detection manifest of all items"
422
+
423
+ it "should list dates on which bookmarks were posted"
424
+
425
+ it "should check to see when a user last posted an item."
426
+
427
+ end
428
+
429
+ end
430
+
431
+ end