dgiunta-flickr 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/History.txt +54 -0
  2. data/LICENSE +20 -0
  3. data/README.txt +74 -0
  4. data/TODO +6 -0
  5. data/lib/flickr.rb +732 -0
  6. data/test/test_flickr.rb +1104 -0
  7. metadata +66 -0
@@ -0,0 +1,1104 @@
1
+ #require 'rubygems'
2
+ require 'flickr'
3
+ require 'test/unit'
4
+ #require 'mocha'
5
+
6
+ class TestFlickr < Test::Unit::TestCase
7
+
8
+ def test_get_list_of_photos_from_specified_photoset
9
+ flickr = Flickr.new('5a3f78d9a0f34169777dbb3ff266ba06')
10
+ testPhotoset = flickr.photoset('72157611041801782')
11
+
12
+ assert_not_nil testPhotoset.getPhotos
13
+ end
14
+
15
+ # Flickr client tests
16
+ #
17
+ # instantiation tests
18
+ def test_should_instantiate_new_flickr_client
19
+ Flickr.any_instance.stubs(:login)
20
+ flickr = Flickr.new('some_api_key', 'email@test.com', 'some_password', 'some_shared_secret')
21
+
22
+ assert_equal 'some_api_key', flickr.api_key
23
+ assert_equal 'some_shared_secret', flickr.instance_variable_get(:@shared_secret)
24
+ end
25
+
26
+ def test_should_try_to_login_using_old_api_if_email_and_password_passed
27
+ Flickr.any_instance.expects(:login).with('email@test.com', 'some_password') # checks email and password have been set
28
+ flickr = Flickr.new('some_api_key', 'email@test.com', 'some_password', 'some_shared_secret')
29
+ end
30
+
31
+ def test_should_instantiate_new_flickr_client_on_new_api
32
+ flickr = Flickr.new('api_key' => 'some_api_key', 'email' => 'email@test.com', 'password' => 'some_password', 'shared_secret' => 'some_shared_secret', 'foo' => 'bar')
33
+
34
+ assert_equal 'some_api_key', flickr.api_key
35
+ assert_equal 'some_shared_secret', flickr.instance_variable_get(:@shared_secret)
36
+ assert_nil flickr.instance_variable_get(:@foo) # should ignore other params
37
+ end
38
+
39
+ def test_should_not_try_to_login_using_old_api_when_instantiate_new_flickr_client_on_new_api
40
+ Flickr.any_instance.expects(:login).never # doesn't bother trying to login with new api -- it'll fail in any case
41
+ flickr = Flickr.new('api_key' => 'some_api_key', 'email' => 'email@test.com', 'password' => 'some_password', 'shared_secret' => 'some_shared_secret', 'foo' => 'bar')
42
+ end
43
+
44
+ # signature_from method tests
45
+ def test_should_return_signature_from_given_params
46
+ assert_equal Digest::MD5.hexdigest('shared_secret_codea_param1234xb_param5678yc_param97531t'),
47
+ authenticated_flickr_client.send(:signature_from, {:b_param => '5678y', 'c_param' => '97531t', :a_param => '1234x', :d_param => nil})
48
+ end
49
+
50
+ def test_should_return_nil_for_signature_when_no_shared_secret
51
+ assert_nil flickr_client.send(:signature_from, {:b_param => '5678y', :c_param => '97531t', :a_param => '1234x'})
52
+ end
53
+
54
+ # request_url method tests
55
+ def test_should_get_signature_for_params_when_building_url
56
+ f = authenticated_flickr_client
57
+ f.expects(:signature_from).with( 'method' => 'flickr.someMethod',
58
+ 'api_key' => 'some_api_key',
59
+ 'foo' => 'value which/needs&escaping',
60
+ 'auth_token' => 'some_auth_token').returns("foo123bar456")
61
+
62
+ url = f.send(:request_url, 'someMethod', 'foo' => 'value which/needs&escaping')
63
+ end
64
+
65
+ def test_should_build_url_from_params_with_signature
66
+ f = authenticated_flickr_client
67
+ f.stubs(:signature_from).returns("foo123bar456")
68
+
69
+ url = f.send(:request_url, 'someMethod', 'foo' => 'value which/needs&escaping')
70
+ [ "#{Flickr::HOST_URL}#{Flickr::API_PATH}",
71
+ 'api_key=some_api_key',
72
+ 'method=flickr.someMethod',
73
+ 'foo=value+which%2Fneeds%26escaping',
74
+ 'auth_token=some_auth_token',
75
+ 'api_sig=foo123bar456'].each do |kv_pair|
76
+ assert_match Regexp.new(Regexp.escape(kv_pair)), url
77
+ end
78
+ end
79
+
80
+ def test_should_build_url_from_params_when_signature_returns_nil
81
+ flickr = flickr_client
82
+ flickr.stubs(:signature_from)
83
+ assert_equal "#{Flickr::HOST_URL}#{Flickr::API_PATH}/?api_key=some_api_key&method=flickr.someMethod", flickr.send(:request_url, 'someMethod')
84
+ assert_equal "#{Flickr::HOST_URL}#{Flickr::API_PATH}/?api_key=some_api_key&method=flickr.someMethod&foo=bar", flickr.send(:request_url, 'someMethod', 'foo' => 'bar', 'foobar' => nil)
85
+ assert_equal "#{Flickr::HOST_URL}#{Flickr::API_PATH}/?api_key=some_api_key&method=flickr.someMethod&foo=101", flickr.send(:request_url, 'someMethod', 'foo' => 101)
86
+ assert_equal "#{Flickr::HOST_URL}#{Flickr::API_PATH}/?api_key=some_api_key&method=flickr.someMethod&foo=value+which%2Fneeds%26escaping", flickr.send(:request_url, 'someMethod', 'foo' => 'value which/needs&escaping')
87
+ end
88
+
89
+ # method_missing tests
90
+ def test_should_generate_flickr_method_from_unkown_method_on_flickr_client
91
+ f = flickr_client
92
+ f.expects(:request).with('some.unknown.methodForFlickr', {})
93
+ f.some_unknown_methodForFlickr
94
+ end
95
+
96
+ # request method tests
97
+ def test_should_make_successful_request
98
+ f = flickr_client
99
+ f.expects(:http_get).with('some.url').returns(successful_xml_response)
100
+ f.expects(:request_url).with('some_method', 'foo' => 'bar').returns("some.url")
101
+
102
+ f.send(:request, 'some_method', 'foo' => 'bar') # request is protected
103
+ end
104
+
105
+ def test_should_raise_exception_on_unsuccessful_request
106
+ f = flickr_client
107
+ f.expects(:http_get).returns(unsuccessful_xml_response)
108
+
109
+ assert_raise(RuntimeError) { f.send(:request, 'some_method', 'foo' => 'bar') }
110
+ end
111
+
112
+ def test_should_parse_returned_xml_in_successful_request
113
+ f = flickr_client
114
+ f.stubs(:http_get).returns(successful_xml_response)
115
+ expected_response = { "contacts" => { "perpage" => "1000",
116
+ "contact" => [{ "nsid"=>"12037949629@N01",
117
+ "username"=>"Eric",
118
+ "ignored"=>"1",
119
+ "family"=>"0",
120
+ "friend"=>"1",
121
+ "realname"=>"Eric Costello",
122
+ "iconserver"=>"1"},
123
+ { "nsid"=>"12037949631@N01",
124
+ "username"=>"neb",
125
+ "ignored"=>"0",
126
+ "family"=>"0",
127
+ "friend"=>"0",
128
+ "realname"=>"Ben Cerveny",
129
+ "iconserver"=>"1"}],
130
+ "total" => "2",
131
+ "pages"=> "1",
132
+ "page"=>"1" },
133
+ "stat"=>"ok" }
134
+
135
+ assert_equal expected_response, f.send(:request, 'some_method', 'foo' => 'bar')
136
+ end
137
+
138
+ # photos_request tests
139
+ def test_should_pass_photos_request_params_to_request
140
+ f = flickr_client
141
+ f.expects(:request).with('flickr.method', :one => 1, :two => "2").returns(dummy_photos_response)
142
+ f.photos_request( 'flickr.method', :one => 1, :two => "2")
143
+ end
144
+
145
+ def test_should_instantiate_recent_photos_with_id_and_all_params_returned_by_flickr
146
+ f = flickr_client
147
+ f.expects(:request).returns(dummy_photos_response)
148
+ Flickr::Photo.expects(:new).with("foo123",
149
+ "some_api_key", { "key1" => "value1",
150
+ "key2" => "value2"})
151
+ Flickr::Photo.expects(:new).with("bar456",
152
+ "some_api_key", { "key3" => "value3"})
153
+ photos = f.photos_request('some_method')
154
+ end
155
+
156
+ def test_should_parse_photos_response_into_flickr_photo_collection
157
+ f = flickr_client
158
+ f.expects(:request).returns(dummy_photos_response)
159
+ assert_kind_of Flickr::PhotoCollection, f.photos_request('some_method')
160
+ end
161
+
162
+ def test_should_store_pagination_info_in_photo_collection
163
+ f = flickr_client
164
+ f.expects(:request).returns(dummy_photos_response)
165
+ photos = f.photos_request('some_method')
166
+
167
+ assert_equal "3", photos.page
168
+ assert_equal "5", photos.pages
169
+ assert_equal "10", photos.perpage
170
+ assert_equal "42", photos.total
171
+ end
172
+
173
+ def test_should_return_collection_of_photos
174
+ f = flickr_client
175
+ f.expects(:request).returns(dummy_photos_response)
176
+ photos = f.photos_request('some_method')
177
+ assert_equal 2, photos.size
178
+ assert_kind_of Flickr::Photo, photos.first
179
+ assert_equal "foo123", photos.first.id
180
+ end
181
+
182
+ def test_should_work_with_single_result
183
+ f = flickr_client
184
+ f.expects(:request).returns(dummy_single_photo_response)
185
+ photos = f.photos_request('some_method')
186
+ assert_equal 1, photos.size
187
+ assert_kind_of Flickr::Photo, photos.first
188
+ assert_equal "foo123", photos.first.id
189
+ end
190
+
191
+ def test_should_work_with_empty_result
192
+ f = flickr_client
193
+ f.expects(:request).returns(dummy_zero_photo_response)
194
+ photos = f.photos_request('some_method')
195
+ assert_equal [], photos
196
+ end
197
+
198
+ def test_should_generate_login_url
199
+ f = flickr_client
200
+ f.expects(:signature_from).with('api_key' => 'some_api_key', 'perms' => 'write').returns('validsignature')
201
+ assert_equal 'http://flickr.com/services/auth/?api_key=some_api_key&perms=write&api_sig=validsignature', f.login_url('write')
202
+ end
203
+
204
+ def test_should_get_token_from_frob
205
+ f = flickr_client
206
+ f.expects(:request).with('auth.getToken',:frob => 'some_frob').returns({'auth' => {'token' => 'some_auth_token', 'user' => {}}})
207
+
208
+ auth_token = f.get_token_from('some_frob')
209
+ assert_equal 'some_auth_token', auth_token
210
+ end
211
+
212
+ def test_should_store_auth_token_in_client
213
+ f = flickr_client
214
+ f.expects(:request).returns({'auth' => {'token' => 'some_auth_token','user' => {}}})
215
+ f.get_token_from('some_frob')
216
+ assert_equal 'some_auth_token', f.auth_token
217
+ end
218
+
219
+ def test_should_store_authenticated_user_details_in_client
220
+ f = flickr_client
221
+ f.expects(:request).returns({ 'auth' => { 'token' => 'some_auth_token',
222
+ 'user' => { 'nsid' => 'foo123',
223
+ 'username' => 'some_user', 'fullname' => 'Some User'}}})
224
+ f.get_token_from('some_frob')
225
+ assert_kind_of Flickr::User, user = f.user
226
+ assert_equal 'foo123', user.id
227
+ assert_equal 'some_user', user.username
228
+ assert_equal 'Some User', user.name
229
+ assert_equal f, user.client
230
+ end
231
+
232
+ # photos method tests
233
+ def test_should_get_recent_photos_if_no_params_for_photos
234
+ f = flickr_client
235
+ f.expects(:photos_search)
236
+ f.photos
237
+ end
238
+
239
+ # photos_search method tests
240
+ def test_should_search_photos
241
+ f = authenticated_flickr_client
242
+ f.expects(:request).with('photos.search', anything).returns(dummy_photos_response)
243
+ photos = f.photos_search
244
+ assert_kind_of Flickr::Photo, photos.first
245
+ end
246
+
247
+ # users method tests
248
+ def test_should_find_user_from_email
249
+ f = flickr_client
250
+ f.expects(:request).with('people.findByEmail', anything).returns(dummy_user_response)
251
+ assert_kind_of Flickr::User, user = f.users("email@test.com")
252
+ assert_equal "12037949632@N01", user.id
253
+ assert_equal "Stewart", user.username
254
+ end
255
+
256
+ def test_should_find_user_from_username_if_fails_to_get_from_email
257
+ f = flickr_client
258
+ f.expects(:request).with('people.findByEmail', anything).raises
259
+ f.expects(:request).with('people.findByUsername', anything).returns(dummy_user_response)
260
+ assert_kind_of Flickr::User, f.users("email@test.com")
261
+ end
262
+
263
+ def test_should_pass_on_flickr_client_when_finding_user
264
+ f = flickr_client
265
+ f.stubs(:request).returns(dummy_user_response)
266
+ user = f.users("email@test.com")
267
+ assert_equal f, user.client
268
+ end
269
+
270
+ # groups method tests
271
+ def test_should_search_for_given_group
272
+ f = flickr_client
273
+ f.expects(:request).with("groups.search", {"text" => "foo"}).returns(dummy_groups_response)
274
+ f.groups("foo")
275
+ end
276
+
277
+ def test_should_search_for_given_group_with_additional_params
278
+ f = flickr_client
279
+ f.expects(:request).with("groups.search", {"text" => "foo", "per_page" => "1"}).returns(dummy_groups_response)
280
+ f.groups("foo", "per_page" => "1")
281
+ end
282
+
283
+ def test_should_instantiate_groups_from_search_response
284
+ f = flickr_client
285
+ f.stubs(:request).returns(dummy_groups_response)
286
+ assert_kind_of Array, groups = f.groups("foo")
287
+ assert_kind_of Flickr::Group, group = groups.first
288
+ assert_equal "group1", group.id
289
+ assert_equal "Group One", group.name
290
+ assert_equal "0", group.eighteenplus
291
+ assert_equal f, group.client
292
+ end
293
+
294
+ def test_should_instantiate_groups_from_search_response_with_single_group_returned
295
+ f = flickr_client
296
+ f.stubs(:request).returns(dummy_single_group_response)
297
+ assert_kind_of Array, groups = f.groups("foo")
298
+ assert_equal 1, groups.size
299
+ assert_equal "group1", groups.first.id
300
+ end
301
+
302
+ # ##### DIRECT MODE
303
+ #
304
+ # def test_test_echo
305
+ # assert_equal @f.test_echo['stat'], 'ok'
306
+ # end
307
+ # def test_test_login
308
+ # assert_equal @f.test_login['stat'], 'ok'
309
+ # end
310
+ #
311
+ #
312
+ # ##### BASICS
313
+ #
314
+ # def test_login
315
+ # assert_equal @username, @f.user.getInfo.username
316
+ # end
317
+ #
318
+ # def test_find_by_url
319
+ # assert_equal @group_id, @f.find_by_url(@group_url).getInfo.id # find group by URL
320
+ # assert_equal @user_id, @f.find_by_url(@user_url).getInfo.id # find user by URL
321
+ # end
322
+ #
323
+ # def test_licenses
324
+ # assert_kind_of Array, @f.licenses # find all licenses
325
+ # end
326
+ #
327
+
328
+ #
329
+ # Flickr#photos tests
330
+ #
331
+
332
+
333
+ # ##### Flickr::User tests
334
+ #
335
+ def test_should_instantiate_user
336
+ user = new_user
337
+ assert_equal 'foo123', user.id
338
+ assert_equal 'some_user', user.username
339
+ assert_equal 'bar', user.instance_variable_get(:@foo) # should collect all other params up and store as instance variables
340
+ end
341
+
342
+ def test_should_instantiate_new_user_with_old_api
343
+ Flickr.any_instance.stubs(:login) # stub logging in
344
+ user = Flickr::User.new('foo123',
345
+ 'some_user',
346
+ 'email@test.com', # email irrelevant since Flickr API no longer supports authentication in this way
347
+ 'password', # password irrelevant since Flickr API no longer supports authentication in this way
348
+ 'bar456')
349
+ assert_equal 'foo123', user.id
350
+ assert_equal 'some_user', user.username
351
+ assert_equal 'email@test.com', user.instance_variable_get(:@email)
352
+ assert_equal 'password', user.instance_variable_get(:@password)
353
+ assert_equal 'bar456', user.client.api_key
354
+ end
355
+
356
+ def test_should_instantiate_new_client_when_instantiating_user_if_no_client_passed_in_params
357
+ f = flickr_client
358
+ Flickr.expects(:new).returns(f)
359
+ user = new_user( 'api_key' => 'an_api_key' )
360
+ assert_equal f, user.client
361
+ end
362
+
363
+ def test_should_not_instantiate_new_client_when_instantiating_user_if_client_passed_in_params
364
+ f = flickr_client
365
+ Flickr.expects(:new).never
366
+ user = new_user( 'client' => f )
367
+ assert_equal f, user.client
368
+ end
369
+
370
+ def test_should_not_instantiate_client_if_no_api_key_passed
371
+ Flickr.expects(:new).never
372
+ user = new_user
373
+ assert_nil user.client
374
+ end
375
+
376
+ def test_should_build_url_for_users_profile_page_using_user_id
377
+ Flickr.any_instance.expects(:http_get).never
378
+ assert_equal "http://www.flickr.com/people/foo123/", new_user.url
379
+ end
380
+
381
+ def test_should_build_url_for_users_photos_page_using_user_id
382
+ Flickr.any_instance.expects(:http_get).never
383
+ assert_equal "http://www.flickr.com/photos/foo123/", new_user.photos_url
384
+ end
385
+
386
+ def test_should_get_pretty_url_for_users_profile_page
387
+ f = flickr_client
388
+ f.expects(:urls_getUserProfile).returns({"user" => {"nsid" => "bar456", "url" => "http://www.flickr.com/people/killer_bob/"}})
389
+
390
+ assert_equal "http://www.flickr.com/people/killer_bob/", new_user( 'client' => f ).pretty_url
391
+ end
392
+
393
+ def test_should_cache_pretty_url_for_users_profile_page
394
+ f = flickr_client
395
+ user = new_user( 'client' => f )
396
+ f.expects(:urls_getUserProfile).returns({"user" => {"nsid" => "bar456", "url" => "http://www.flickr.com/people/killer_bob/"}}) # expects only one call
397
+
398
+ user.pretty_url
399
+ user.pretty_url
400
+ end
401
+
402
+ def test_should_get_users_public_groups
403
+ f = flickr_client
404
+ f.expects(:request).with("people.getPublicGroups", anything).returns(dummy_groups_response)
405
+ new_user( 'client' => f ).groups
406
+ end
407
+
408
+ def test_should_instantiate_users_public_groups
409
+ f = flickr_client
410
+ f.stubs(:request).returns(dummy_groups_response)
411
+ user = new_user( 'client' => f )
412
+
413
+ groups = user.groups
414
+ assert_equal 2, groups.size
415
+ assert_kind_of Flickr::Group, group = groups.first
416
+ assert_equal "group1", group.id
417
+ assert_equal "Group One", group.name
418
+ assert_equal "0", group.eighteenplus
419
+ assert_equal f, group.client
420
+ end
421
+
422
+ def test_should_instantiate_users_public_groups_when_only_one_returned
423
+ f = flickr_client
424
+ f.stubs(:request).returns(dummy_single_group_response)
425
+ user = new_user( 'client' => f )
426
+ groups = user.groups
427
+ assert_equal 1, groups.size
428
+ end
429
+
430
+ def test_should_get_users_tags
431
+ f = flickr_client
432
+ user = new_user( 'client' => f )
433
+ f.expects(:tags_getListUser).with('user_id'=>user.id).returns({"who"=>{"tags"=>{"tag"=>["offf08", "ruby", "rubyonrails", "timoteo", "wbs", "webreakstuff"]}, "id"=>"9259187@N05"}, "stat"=>"ok"})
434
+ tags = user.tags
435
+ assert_kind_of Array, tags
436
+ assert_equal tags, ["offf08", "ruby", "rubyonrails", "timoteo", "wbs", "webreakstuff"]
437
+ end
438
+
439
+ def test_should_get_users_popular_tags
440
+ f = flickr_client
441
+ user = new_user( 'client' => f )
442
+ f.expects(:tags_getListUserPopular).with('user_id' => user.id).with(anything).returns({"who"=>{"tags"=>{"tag"=>[{"content"=>"design", "count"=>"94"}, {"content"=>"offf08", "count"=>"94"}, {"content"=>"ruby", "count"=>"3"}, {"content"=>"rubyonrails", "count"=>"3"}, {"content"=>"wbs", "count"=>"3"}, {"content"=>"webreakstuff", "count"=>"97"}]}, "id"=>"9259187@N05"}, "stat"=>"ok"})
443
+ pop_tags = user.popular_tags
444
+ assert_kind_of Array, pop_tags
445
+ assert_equal pop_tags, [{"tag"=>"design", "count"=>"94"}, {"tag"=>"offf08", "count"=>"94"}, {"tag"=>"ruby", "count"=>"3"}, {"tag"=>"rubyonrails", "count"=>"3"}, {"tag"=>"wbs", "count"=>"3"}, {"tag"=>"webreakstuff", "count"=>"97"}]
446
+ end
447
+
448
+ # def test_getInfo
449
+ # @u.getInfo
450
+ # assert_equal @username, @u.username
451
+ # end
452
+ #
453
+ # def test_groups
454
+ # assert_kind_of Flickr::Group, @u.groups.first # public groups
455
+ # end
456
+ #
457
+ #
458
+ # def test_contacts
459
+ # assert_kind_of Flickr::User, @u.contacts.first # public contacts
460
+ # end
461
+ #
462
+ # def test_favorites
463
+ # assert_kind_of Flickr::Photo, @u.favorites.first # public favorites
464
+ # end
465
+ #
466
+ # def test_photosets
467
+ # assert_kind_of Flickr::Photoset, @u.photosets.first # public photosets
468
+ # end
469
+ #
470
+ # def test_contactsPhotos
471
+ # assert_kind_of Flickr::Photo, @u.contactsPhotos.first # contacts' favorites
472
+ # end
473
+
474
+ # User#photos tests
475
+
476
+ def test_should_get_users_public_photos
477
+ client = mock
478
+ client.expects(:photos_request).with('people.getPublicPhotos', {'user_id' => 'some_id'}).returns([new_photo, new_photo])
479
+ Flickr.expects(:new).at_least_once.returns(client)
480
+
481
+ user = Flickr::User.new("some_id", "some_user", nil, nil, "some_api_key")
482
+
483
+ photos = user.photos
484
+ assert_equal 2, photos.size
485
+ assert_kind_of Flickr::Photo, photos.first
486
+ end
487
+
488
+ def test_should_instantiate_favorite_photos_with_id_and_all_params_returned_by_query
489
+ client = mock
490
+ client.expects(:photos_request).with('favorites.getPublicList', {'user_id' => 'some_id'})
491
+ Flickr.expects(:new).at_least_once.returns(client)
492
+ user = Flickr::User.new("some_id", "some_user", nil, nil, "some_api_key")
493
+ user.favorites
494
+ end
495
+
496
+ def test_should_instantiate_contacts_photos_with_id_and_all_params_returned_by_query
497
+ client = mock
498
+ client.expects(:photos_request).with('photos.getContactsPublicPhotos', {'user_id' => 'some_id'})
499
+ Flickr.expects(:new).at_least_once.returns(client)
500
+ user = Flickr::User.new('some_id', "some_user", nil, nil, "some_api_key")
501
+ user.contactsPhotos
502
+ end
503
+
504
+ # ##### Flickr::Photo tests
505
+
506
+ def test_should_initialize_photo_from_id
507
+ photo = Flickr::Photo.new("foo123")
508
+ assert_equal "foo123", photo.id
509
+ end
510
+
511
+ def test_should_save_extra_params_as_instance_variables
512
+ photo = Flickr::Photo.new('foo123', 'some_api_key', { 'key1' => 'value1', 'key2' => 'value2'})
513
+ assert_equal 'value1', photo.instance_variable_get(:@key1)
514
+ assert_equal 'value2', photo.instance_variable_get(:@key2)
515
+ end
516
+
517
+ def test_should_be_able_to_access_instance_variables_through_hash_like_interface
518
+ photo = Flickr::Photo.new
519
+ photo.instance_variable_set(:@key1, 'value1')
520
+ assert_equal 'value1', photo['key1']
521
+ assert_equal 'value1', photo[:key1]
522
+ assert_nil photo[:key2]
523
+ assert_nil photo['key2']
524
+ end
525
+
526
+ def test_should_get_and_store_other_info_for_photo
527
+ Flickr.any_instance.stubs(:http_get).returns(photo_info_xml_response)
528
+ photo = Flickr::Photo.new('foo123', 'some_api_key')
529
+
530
+ assert_equal "1964 120 amazon estate", photo.title # calling #title method triggers getting of info
531
+ assert_equal "1964 120 amazon estate", photo.instance_variable_get(:@title)
532
+ assert_equal "3142", photo.instance_variable_get(:@server)
533
+ assert_equal "ae75bd3111", photo.instance_variable_get(:@secret)
534
+ assert_equal "4", photo.instance_variable_get(:@farm)
535
+ assert_equal "1204145093", photo.instance_variable_get(:@dateuploaded)
536
+ assert_equal "photo", photo.instance_variable_get(:@media)
537
+ assert_equal "0", photo.instance_variable_get(:@isfavorite)
538
+ assert_equal "0", photo.instance_variable_get(:@license)
539
+ assert_equal "0", photo.instance_variable_get(:@rotation)
540
+ assert_equal "1964 Volvo 120 amazon estate spotted in derbyshire.", photo.instance_variable_get(:@description)
541
+ assert_equal( { "w" => "50",
542
+ "x" => "10",
543
+ "y" => "10",
544
+ "authorname" => "Bees",
545
+ "author" => "12037949754@N01",
546
+ "id" => "313",
547
+ "content" => "foo",
548
+ "h" => "50" }, photo.instance_variable_get(:@notes))
549
+ assert_equal "http://www.flickr.com/photos/rootes_arrow/2296968304/", photo.instance_variable_get(:@url)
550
+ assert_equal [ { "id" => "9377979-2296968304-2228", "author" => "9383319@N05", "raw" => "volvo", "machine_tag" => "0", "content" => "volvo" },
551
+ { "id" => "9377979-2296968304-2229", "author" => "9383319@N06", "raw" => "amazon", "machine_tag" => "0", "content" => "amazon"
552
+ } ], photo.instance_variable_get(:@tags)
553
+ assert_equal "1", photo.instance_variable_get(:@comments)
554
+ assert_kind_of Flickr::User, owner = photo.instance_variable_get(:@owner)
555
+ assert_equal "Rootes_arrow_1725", owner.username
556
+ end
557
+
558
+ def test_should_get_and_other_info_for_photo_when_some_attributes_missing
559
+ Flickr.any_instance.stubs(:http_get).returns(sparse_photo_info_xml_response)
560
+ photo = Flickr::Photo.new('foo123', 'some_api_key')
561
+
562
+ assert_equal "1964 120 amazon estate", photo.title # calling #title method triggers getting of info
563
+ assert_equal "1964 120 amazon estate", photo.instance_variable_get(:@title)
564
+ assert_equal( {}, photo.instance_variable_get(:@description))
565
+ assert_nil photo.instance_variable_get(:@notes)
566
+ assert_nil photo.instance_variable_get(:@tags)
567
+ assert_equal "1", photo.instance_variable_get(:@comments)
568
+ end
569
+
570
+ def test_should_not_get_info_more_than_once
571
+ Flickr.any_instance.expects(:http_get).returns(photo_info_xml_response) # expects only one call
572
+ photo = Flickr::Photo.new('foo123', 'some_api_key')
573
+
574
+ photo.description # calling #description method triggers getting of info
575
+ photo.instance_variable_set(:@description, nil) # set description to nil
576
+ photo.description # call #description method again
577
+ end
578
+
579
+ #
580
+ # owner tests
581
+ def test_should_return_owner_when_flickr_user
582
+ user = Flickr::User.new
583
+ photo = new_photo("owner" => user)
584
+
585
+ assert_equal user, photo.owner
586
+ end
587
+
588
+ def test_should_get_info_on_owner_if_not_known
589
+ photo = new_photo("owner" => nil)
590
+ # stubbing private methods causes problems so we mock client method, which is what Photo#getInfo users to make API call
591
+ Flickr.any_instance.expects(:photos_getInfo).returns('photo' => { 'owner'=>{'nsid'=>'abc123', 'username'=>'SomeUserName', 'realname'=>"", 'location'=>''},
592
+ 'notes' => {}, 'tags' => {}, 'urls' => {'url' => {'content' => 'http://prettyurl'}}})
593
+
594
+ owner = photo.owner
595
+ assert_kind_of Flickr::User, owner
596
+ assert_equal 'abc123', owner.id
597
+ assert_equal 'SomeUserName', owner.username
598
+ end
599
+
600
+ def test_should_instantiate_flickr_user_from_owner_id_if_we_have_it
601
+ photo = Flickr::Photo.new
602
+ photo.instance_variable_set(:@owner, "some_user_id")
603
+ Flickr.any_instance.expects(:photos_getInfo).never
604
+
605
+ user = photo.owner
606
+ assert_kind_of Flickr::User, user
607
+ assert_equal "some_user_id", user.id
608
+ end
609
+
610
+ def test_should_cache_owner_when_instantiated
611
+ user = Flickr::User.new
612
+ photo = Flickr::Photo.new
613
+ photo.instance_variable_set(:@owner, "some_user_id")
614
+ Flickr::User.expects(:new).returns(user)
615
+
616
+ photo.owner
617
+ photo.owner # call twice but mock expects only one call
618
+ end
619
+
620
+ #
621
+ # image_source_uri_from_self tests
622
+ def test_should_build_image_source_uri_from_self
623
+ assert_equal "http://farm1.static.flickr.com/2/1418878_1e92283336.jpg",
624
+ new_photo.send(:image_source_uri_from_self) # no size specified
625
+ end
626
+
627
+ def test_should_build_image_source_uri_from_self_for_given_size
628
+ assert_equal "http://farm1.static.flickr.com/2/1418878_1e92283336_m.jpg",
629
+ new_photo.send(:image_source_uri_from_self, "Small") # size specified
630
+ end
631
+
632
+ def test_should_build_image_source_uri_from_self_for_default_size_when_explicitly_asked_for
633
+ assert_equal "http://farm1.static.flickr.com/2/1418878_1e92283336.jpg",
634
+ new_photo.send(:image_source_uri_from_self, "Medium") # medium size specified -- the default
635
+ end
636
+
637
+ def test_should_build_image_source_uri_from_self_for_default_size_when_unknown_size_asked_for
638
+ assert_equal "http://farm1.static.flickr.com/2/1418878_1e92283336.jpg",
639
+ new_photo.send(:image_source_uri_from_self, "Dummy") # bad size specified
640
+ end
641
+
642
+ def test_should_return_nil_for_image_source_uri_if_no_attributes
643
+ assert_nil Flickr::Photo.new.send(:image_source_uri_from_self)
644
+ end
645
+
646
+ def test_should_return_nil_for_image_source_uri_if_missing_required_attributes
647
+ assert_nil Flickr::Photo.new("1418878", nil, "farm" => "1").send(:image_source_uri_from_self)
648
+ end
649
+
650
+ def test_image_source_uri_from_self_should_normalize_size
651
+ photo = new_photo
652
+ assert_equal photo.send(:image_source_uri_from_self, 'Large'),
653
+ photo.send(:image_source_uri_from_self, :large)
654
+ end
655
+
656
+ def test_uri_for_photo_from_self_should_normalize_size
657
+ photo = new_photo
658
+ assert_equal photo.send(:uri_for_photo_from_self, 'Large'),
659
+ photo.send(:uri_for_photo_from_self, :large)
660
+ end
661
+
662
+ def test_should_get_source_uri_by_building_from_self_if_possible
663
+ photo = Flickr::Photo.new
664
+ photo.expects(:image_source_uri_from_self).with('Medium').returns(true) # return any non-false-evaluating value so that sizes method isn't called
665
+ photo.source
666
+ end
667
+
668
+ def test_should_get_source_uri_by_building_from_self_if_possible_requesting_source_for_given_size
669
+ photo = Flickr::Photo.new
670
+ photo.expects(:image_source_uri_from_self).with('Large').returns(true) # return any non-false-evaluating value so that sizes method isn't called
671
+ photo.source('Large')
672
+ end
673
+
674
+ def test_should_get_source_uri_by_calling_sizes_method_if_no_luck_building_uri
675
+ photo = Flickr::Photo.new
676
+ photo.stubs(:image_source_uri_from_self) # ...and hence returns nil
677
+ photo.expects(:sizes).with('Medium').returns({})
678
+ photo.source
679
+ end
680
+
681
+ def test_should_build_uri_for_photo_from_self
682
+ assert_equal "http://www.flickr.com/photos/abc123/1418878", new_photo.send(:uri_for_photo_from_self)
683
+ end
684
+
685
+ def test_should_build_uri_for_photo_from_self_when_owner_is_a_string
686
+ assert_equal "http://www.flickr.com/photos/789user321/1418878", new_photo('owner' => "789user321").send(:uri_for_photo_from_self)
687
+ end
688
+
689
+ def test_should_build_uri_for_photo_from_self_for_given_size
690
+ assert_equal "http://www.flickr.com/photos/abc123/1418878/sizes/s/", new_photo.send(:uri_for_photo_from_self, "Small")
691
+ end
692
+
693
+ def test_should_build_uri_for_photo_from_self_with_unknown_size
694
+ assert_equal "http://www.flickr.com/photos/abc123/1418878", new_photo.send(:uri_for_photo_from_self, "Dummy")
695
+ end
696
+
697
+ def test_should_return_nil_for_uri_for_photo_when_no_user_id
698
+ assert_nil Flickr::Photo.new("1418878", nil).send(:uri_for_photo_from_self)
699
+ end
700
+
701
+ def test_should_return_nil_for_uri_for_photo_when_no_photo_id
702
+ assert_nil Flickr::Photo.new.send(:uri_for_photo_from_self)
703
+ end
704
+
705
+ def test_should_get_uri_for_photo_flickr_page
706
+ photo = new_photo
707
+ assert_equal "http://www.flickr.com/photos/abc123/1418878", photo.url
708
+ end
709
+
710
+ def test_should_return_main_page_for_photo_flickr_page_when_medium_size_requested_as_per_previous_version
711
+ assert_equal "http://www.flickr.com/photos/abc123/1418878", new_photo.url('Medium')
712
+ end
713
+
714
+ def test_should_call_size_url_if_url_given_a_size
715
+ photo = new_photo
716
+ photo.expects(:size_url).with('Large')
717
+ photo.url('Large')
718
+ end
719
+
720
+ def test_should_get_flickr_page_uri_by_building_from_self_if_possible_requesting_source_for_given_size
721
+ photo = new_photo
722
+ photo.expects(:uri_for_photo_from_self).with('Large').returns(true) # return any non-false-evaluating value so that sizes method isn't called
723
+ photo.size_url('Large')
724
+ end
725
+
726
+ def test_should_get_flickr_page_uri_by_calling_sizes_method_if_no_luck_building_uri
727
+ photo = new_photo
728
+ photo.stubs(:uri_for_photo_from_self) # ...and hence returns nil
729
+ photo.expects(:sizes).with('Large').returns({})
730
+ photo.size_url('Large')
731
+ end
732
+
733
+ def test_should_allow_size_to_be_lowercase_or_symbol
734
+ photo = new_photo
735
+ assert_equal photo.normalize_size('Small'), 'Small'
736
+ assert_equal photo.normalize_size('small'), 'Small'
737
+ assert_equal photo.normalize_size(:small), 'Small'
738
+ assert_equal photo.normalize_size(:Small), 'Small'
739
+ assert_equal photo.normalize_size('smAlL'), 'Small'
740
+
741
+ assert_equal photo.normalize_size(""), ""
742
+ assert_nil photo.normalize_size(nil)
743
+ end
744
+
745
+ def test_size_url_should_normalize_size
746
+ photo = new_photo
747
+ assert_equal photo.size_url('Large'), photo.size_url(:large)
748
+ end
749
+
750
+ def test_url_should_normalize_size
751
+ photo = new_photo
752
+ assert_equal photo.url('Medium'), photo.url(:medium)
753
+ assert_equal photo.url('Small'), photo.url('small')
754
+ end
755
+
756
+ def test_source_should_normalize_size
757
+ photo = new_photo
758
+ assert_equal photo.source('Large'), photo.source(:large)
759
+ end
760
+
761
+ def test_sizes_should_normalize_size
762
+ sizes = {'sizes' => {'size' => [{'label' => 'Small'}, {'label' => 'Large'}]}}
763
+ photo = new_photo
764
+ photo.client.expects(:photos_getSizes).at_least_once.returns(sizes)
765
+ assert_equal photo.sizes('Large'), photo.sizes(:large)
766
+ end
767
+
768
+ # Photo#context tests
769
+ def test_should_call_photos_getContext_to_get_context_photos
770
+ Flickr.any_instance.expects(:photos_getContext).returns({'prevphoto' => {}, 'nextphoto' => {}})
771
+ new_photo.context
772
+ end
773
+
774
+ def test_should_instantiate_context_photos_with_id_and_all_params_returned_by_query
775
+ photo = new_photo
776
+ Flickr.any_instance.expects(:photos_getContext).returns({ 'prevphoto' => {'id' => '123', 'key_1' => 'value_1' },
777
+ 'nextphoto' => {'id' => '456', 'key_2' => 'value_2'}})
778
+ Flickr::Photo.expects(:new).with("123", "foo123", { "key_1" => "value_1"})
779
+ Flickr::Photo.expects(:new).with("456", "foo123", { "key_2" => "value_2"})
780
+
781
+ photo.context
782
+ end
783
+
784
+ def test_should_not_instantiate_context_photos_with_id_of_0
785
+ photo = new_photo
786
+ Flickr.any_instance.expects(:photos_getContext).returns({ 'prevphoto' => {'id' => '123', 'key_1' => 'value_1' },
787
+ 'nextphoto' => {'id' => '0', 'key_2' => 'value_2'}})
788
+ Flickr::Photo.expects(:new).with("123", anything, anything)
789
+ Flickr::Photo.expects(:new).with("0", anything, anything).never
790
+
791
+ photo.context
792
+ end
793
+
794
+ # ##### Flickr::Group tests
795
+ #
796
+ def test_should_instantiate_group_from_id
797
+ group = Flickr::Group.new("group1")
798
+ assert_equal "group1", group.id
799
+ end
800
+
801
+ # tests old api for instantiating groups
802
+ def test_should_instantiate_group_from_id_and_api_key
803
+ f = flickr_client
804
+ Flickr.expects(:new).with("some_api_key").returns(f)
805
+ group = Flickr::Group.new("group1", "some_api_key")
806
+ assert_equal f, group.client
807
+ end
808
+
809
+ # new api for instantiating groups
810
+ def test_should_instantiate_group_from_params_hash
811
+ group = Flickr::Group.new("id" => "group1", "name" => "Group One", "eighteenplus" => "1", "foo" => "bar")
812
+ assert_equal "group1", group.id
813
+ assert_equal "Group One", group.name
814
+ assert_equal "1", group.eighteenplus
815
+ assert_equal "bar", group.instance_variable_get(:@foo)
816
+ end
817
+
818
+ def test_should_use_flickr_client_passed_in_params_hash_when_instantiating_group
819
+ f = flickr_client
820
+ Flickr.expects(:new).never
821
+ group = Flickr::Group.new("id" => "group1", "name" => "Group One", "client" => f)
822
+ assert_equal f, group.client
823
+ end
824
+
825
+ def test_should_provide_id_name_eighteenplus_description_members_online_privacy_reader_methods_for_group
826
+ g = Flickr::Group.new
827
+ %w(id name eighteenplus description members online privacy).each do |m|
828
+ g.instance_variable_set("@#{m}", "foo_#{m}")
829
+ assert_equal "foo_#{m}", g.send(m)
830
+ end
831
+ end
832
+
833
+ # def test_should_initialize_photo_from_id
834
+ # photo = Flickr::Photo.new("foo123")
835
+ # assert_equal "foo123", photo.id
836
+ # end
837
+ #
838
+ # def test_should_save_extra_params_as_instance_variables
839
+ # photo = Flickr::Photo.new('foo123', 'some_api_key', { 'key1' => 'value1', 'key2' => 'value2'})
840
+ # assert_equal 'value1', photo.instance_variable_get(:@key1)
841
+ # assert_equal 'value2', photo.instance_variable_get(:@key2)
842
+ # end
843
+ #
844
+ # def test_should_be_able_to_access_instance_variables_through_hash_like_interface
845
+ # photo = Flickr::Photo.new
846
+ # photo.instance_variable_set(:@key1, 'value1')
847
+ # assert_equal 'value1', photo['key1']
848
+ # assert_equal 'value1', photo[:key1]
849
+ # assert_nil photo[:key2]
850
+ # assert_nil photo['key2']
851
+ # end
852
+
853
+ # ##### PHOTOSETS
854
+ #
855
+ # #def setup
856
+ # # super
857
+ # # @photoset = @f.photosets_create('title'=>@title, 'primary_photo_id'=>@photo_id)
858
+ # # @photoset_id = @photoset['photoset']['id']
859
+ # #end
860
+ # #def teardown
861
+ # # @f.photosets_delete('photoset_id'=>@photoset_id)
862
+ # #end
863
+ #
864
+ # def test_photosets_editMeta
865
+ # assert_equal @f.photosets_editMeta('photoset_id'=>@photoset_id, 'title'=>@title)['stat'], 'ok'
866
+ # end
867
+ #
868
+ # def test_photosets_editPhotos
869
+ # assert_equal @f.photosets_editPhotos('photoset_id'=>@photoset_id, 'primary_photo_id'=>@photo_id, 'photo_ids'=>@photo_id)['stat'], 'ok'
870
+ # end
871
+ #
872
+ # def test_photosets_getContext
873
+ # assert_equal @f.photosets_getContext('photoset_id'=>@photoset_id, 'photo_id'=>@photo_id)['stat'], 'ok'
874
+ # end
875
+ #
876
+ # def test_photosets_getContext
877
+ # assert_equal @f.photosets_getContext('photoset_id'=>@photoset_id, 'photo_id'=>@photo_id)['stat'], 'ok'
878
+ # end
879
+ #
880
+ # def test_photosets_getInfo
881
+ # assert_equal @f.photosets_getInfo('photoset_id'=>@photoset_id)['stat'], 'ok'
882
+ # end
883
+ #
884
+ # def test_photosets_getList
885
+ # assert_equal @f.photosets_getList['stat'], 'ok'
886
+ # end
887
+ #
888
+ # def test_photosets_getPhotos
889
+ # assert_equal @f.photosets_getPhotos('photoset_id'=>@photoset_id)['stat'], 'ok'
890
+ # end
891
+ #
892
+ # def test_photosets_orderSets
893
+ # assert_equal @f.photosets_orderSets('photoset_ids'=>@photoset_id)['stat'], 'ok'
894
+ # end
895
+
896
+ def test_related_tags
897
+ f = flickr_client
898
+ tags_response = {
899
+ "tags" => {
900
+ "tag" => [ "zoo", "animal" ],
901
+ "source" => "monkey",
902
+ },
903
+ "stat" => "ok",
904
+ }
905
+ f.expects(:tags_getRelated).with('tag' => 'monkey').returns(tags_response)
906
+ assert_equal f.related_tags('monkey'), %w(zoo animal)
907
+ end
908
+
909
+ # ##### Flickr::PhotoCollection tests
910
+ #
911
+ def test_should_subclass_array_as_photo_collection
912
+ assert_equal Array, Flickr::PhotoCollection.superclass
913
+ end
914
+
915
+ def test_should_make_page_a_reader_method
916
+ assert_equal "3", dummy_photo_collection.page
917
+ end
918
+
919
+ def test_should_make_pages_a_reader_method
920
+ assert_equal "5", dummy_photo_collection.pages
921
+ end
922
+
923
+ def test_should_make_perpage_a_reader_method
924
+ assert_equal "10", dummy_photo_collection.perpage
925
+ end
926
+
927
+ def test_should_make_total_a_reader_method
928
+ assert_equal "42", dummy_photo_collection.total
929
+ end
930
+
931
+ def test_should_instantiate_photo_collection_from_photos_hash
932
+ pc = Flickr::PhotoCollection.new(dummy_photos_response)
933
+ assert_kind_of Flickr::PhotoCollection, pc
934
+ assert_equal 2, pc.size
935
+ assert_kind_of Flickr::Photo, pc.first
936
+ assert_equal "foo123", pc.first["id"]
937
+ end
938
+
939
+ def test_should_instantiate_photo_collection_using_given_api_key
940
+ photo = Flickr::PhotoCollection.new(dummy_photos_response, "some_api_key").first
941
+ assert_equal "some_api_key", photo.instance_variable_get(:@api_key)
942
+ end
943
+
944
+ private
945
+ def flickr_client
946
+ Flickr.new("some_api_key")
947
+ end
948
+
949
+ def authenticated_flickr_client
950
+ f = Flickr.new('api_key' => 'some_api_key', 'shared_secret' => 'shared_secret_code')
951
+ f.instance_variable_set(:@auth_token, 'some_auth_token')
952
+ f
953
+ end
954
+
955
+ def new_user(options={})
956
+ Flickr::User.new({ 'id' => 'foo123',
957
+ 'username' => 'some_user',
958
+ 'name' => 'Some User',
959
+ 'foo' => 'bar',
960
+ 'auth_token' => 'foobar789'}.merge(options))
961
+
962
+ end
963
+ def new_photo(options={})
964
+ Flickr::Photo.new("1418878",
965
+ "foo123",
966
+ { "farm" => "1",
967
+ "server" => "2",
968
+ "secret" => "1e92283336",
969
+ "owner" => Flickr::User.new("abc123", "some_user", nil, nil, "some_api_key") }.merge(options))
970
+ end
971
+
972
+ def dummy_photo_collection
973
+ Flickr::PhotoCollection.new(dummy_photos_response)
974
+ end
975
+
976
+ def dummy_photos_response
977
+ { "photos" =>
978
+ { "photo" =>
979
+ [{ "id" => "foo123",
980
+ "key1" => "value1",
981
+ "key2" => "value2" },
982
+ { "id" => "bar456",
983
+ "key3" => "value3"}],
984
+ "page"=>"3",
985
+ "pages"=>"5",
986
+ "perpage"=>"10",
987
+ "total"=>"42" } }
988
+ end
989
+
990
+ def dummy_single_photo_response
991
+ { "photos" =>
992
+ { "photo" =>
993
+ { "id" => "foo123",
994
+ "key1" => "value1",
995
+ "key2" => "value2" } } }
996
+ end
997
+
998
+ def dummy_zero_photo_response
999
+ { "photos" => { "total" => 0 } }
1000
+ end
1001
+
1002
+ def dummy_user_response
1003
+ { "user" =>
1004
+ { "nsid" => "12037949632@N01",
1005
+ "username" => "Stewart" }
1006
+ }
1007
+ end
1008
+
1009
+ def dummy_groups_response
1010
+ { "groups" =>
1011
+ { "group" =>
1012
+ [{ "nsid" => "group1",
1013
+ "name" => "Group One",
1014
+ "eighteenplus" => "0" },
1015
+ { "nsid" => "group2",
1016
+ "name" => "Group Two",
1017
+ "eighteenplus" => "1"}] } }
1018
+ end
1019
+
1020
+ def dummy_single_group_response
1021
+ { "groups" =>
1022
+ { "group" =>
1023
+ { "nsid" => "group1",
1024
+ "name" => "Group One",
1025
+ "eighteenplus" => "0" } } }
1026
+ end
1027
+
1028
+ def successful_xml_response
1029
+ <<-EOF
1030
+ <?xml version="1.0" encoding="utf-8" ?>
1031
+ <rsp stat="ok">
1032
+ <contacts page="1" pages="1" perpage="1000" total="2">
1033
+ <contact nsid="12037949629@N01" username="Eric" iconserver="1"
1034
+ realname="Eric Costello"
1035
+ friend="1" family="0" ignored="1" />
1036
+ <contact nsid="12037949631@N01" username="neb" iconserver="1"
1037
+ realname="Ben Cerveny"
1038
+ friend="0" family="0" ignored="0" />
1039
+ </contacts>
1040
+ </rsp>
1041
+ EOF
1042
+ end
1043
+
1044
+ def unsuccessful_xml_response
1045
+ <<-EOF
1046
+ <?xml version="1.0" encoding="utf-8" ?>
1047
+ <rsp stat="fail">
1048
+ <err code="[error-code]" msg="[error-message]" />
1049
+ </rsp>
1050
+ EOF
1051
+ end
1052
+
1053
+ def photo_info_xml_response
1054
+ <<-EOF
1055
+ <?xml version="1.0" encoding="utf-8" ?>
1056
+ <rsp stat="ok">
1057
+ <photo id="22527834" secret="ae75bd3111" server="3142" farm="4" dateuploaded="1204145093" isfavorite="0" license="0" rotation="0" media="photo">
1058
+ <owner nsid="9383319@N05" username="Rootes_arrow_1725" realname="John" location="U.K" />
1059
+ <title>1964 120 amazon estate</title>
1060
+ <description>1964 Volvo 120 amazon estate spotted in derbyshire.</description>
1061
+ <visibility ispublic="1" isfriend="0" isfamily="0" />
1062
+ <dates posted="1204145093" taken="2007-06-10 13:18:27" takengranularity="0" lastupdate="1204166772" />
1063
+ <editability cancomment="0" canaddmeta="0" />
1064
+ <usage candownload="0" canblog="0" canprint="0" />
1065
+ <comments>1</comments>
1066
+ <notes>
1067
+ <note id="313" author="12037949754@N01" authorname="Bees" x="10" y="10" w="50" h="50">foo</note>
1068
+ </notes>
1069
+ <tags>
1070
+ <tag id="9377979-2296968304-2228" author="9383319@N05" raw="volvo" machine_tag="0">volvo</tag>
1071
+ <tag id="9377979-2296968304-2229" author="9383319@N06" raw="amazon" machine_tag="0">amazon</tag>
1072
+ </tags>
1073
+ <urls>
1074
+ <url type="photopage">http://www.flickr.com/photos/rootes_arrow/2296968304/</url>
1075
+ </urls>
1076
+ </photo>
1077
+ </rsp>
1078
+ EOF
1079
+ end
1080
+
1081
+ def sparse_photo_info_xml_response
1082
+ <<-EOF
1083
+ <?xml version="1.0" encoding="utf-8" ?>
1084
+ <rsp stat="ok">
1085
+ <photo id="22527834" secret="ae75bd3111" server="3142" farm="4" dateuploaded="1204145093" isfavorite="0" license="0" rotation="0" media="photo">
1086
+ <owner nsid="9383319@N05" username="Rootes_arrow_1725" realname="John" location="U.K" />
1087
+ <title>1964 120 amazon estate</title>
1088
+ <description/>
1089
+ <visibility ispublic="1" isfriend="0" isfamily="0" />
1090
+ <dates posted="1204145093" taken="2007-06-10 13:18:27" takengranularity="0" lastupdate="1204166772" />
1091
+ <editability cancomment="0" canaddmeta="0" />
1092
+ <usage candownload="0" canblog="0" canprint="0" />
1093
+ <comments>1</comments>
1094
+ <notes/>
1095
+ <tags/>
1096
+ <urls>
1097
+ <url type="photopage">http://www.flickr.com/photos/rootes_arrow/2296968304/</url>
1098
+ </urls>
1099
+ </photo>
1100
+ </rsp>
1101
+ EOF
1102
+ end
1103
+
1104
+ end