fleakr 0.5.1 → 0.5.2

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.
@@ -44,10 +44,15 @@ user by his username:
44
44
  >> user = Fleakr.user('the decapitator')
45
45
  => #<Fleakr::Objects::User:0x692648 @username="the decapitator", @id="21775151@N06">
46
46
 
47
- Or by email:
47
+ By email:
48
48
 
49
49
  >> user = Fleakr.user('user@host.com')
50
50
  => #<Fleakr::Objects::User:0x11f484c @username="bckspcr", @id="84481630@N00">
51
+
52
+ Or even by URL:
53
+
54
+ >> user = Fleakr.user('http://www.flickr.com/photos/the_decapitator/')
55
+ => #<Fleakr::Objects::User:0x113440c @username="the decapitator", @id="21775151@N06">
51
56
 
52
57
  Once you have a user, you can find his associated sets:
53
58
 
@@ -201,6 +206,26 @@ All comments have additional information:
201
206
 
202
207
  See Fleakr::Objects::Comment for more information.
203
208
 
209
+ === Collections
210
+
211
+ An individual can have zero or more collections associated with his account. These collections,
212
+ in turn, can have either collections or sets associated with them. For example:
213
+
214
+ >> user = Fleakr.user('username')
215
+ >> user.collections.length
216
+ => 1
217
+ >> user.collections.first.title
218
+ => "The Year in Pictures"
219
+ >> user.collections.first.collections.length
220
+ => 2
221
+ >> user.collections.first.collections.first.sets.length
222
+ => 3
223
+ >> user.collections.first.collections.first.sets.first.title
224
+ => "A Trip to Yosemite"
225
+
226
+ Note that collections are limited to Flickr pro members. See Fleakr::Objects::Collection for more
227
+ information.
228
+
204
229
  === Saving Images
205
230
 
206
231
  If a photo interests you, save it down to a directory of your choosing:
@@ -327,29 +352,40 @@ just the requests you need to tune the log level:
327
352
  Even if something doesn't go wrong, this is a good way to get a sense for when you're making
328
353
  API requests.
329
354
 
355
+ == Contributing
356
+
357
+ If there is a feature that you would like to contribute, I gladly accept pull requests. There
358
+ are a few things that make my life easier when integrating your changes:
359
+
360
+ * Verify that all tests are passing (run `rake` from the project root)
361
+ * Keep your commits small, focused, and tested - this allows me to apply changes cleanly
362
+ * Leave the Rakefile and version information intact - if you really want to make changes,
363
+ please do so in a separate commit.
364
+
365
+ Once your changes are applied, I will add you to the list of contributors.
366
+
330
367
  == Contributors
331
368
 
332
369
  While Fleakr started as a labor of love for me, I'm glad that others have been interested
333
370
  in this project enough to contribute their ideas and code:
334
371
 
372
+ * {Mark Dickson}[http://github.com/ideaoforder]
335
373
  * {John Guenin}[http://github.com/johng]
336
374
  * {Thomas Olausson}[http://github.com/latompa]
375
+ * {Robert Sköld}[http://github.com/slaskis]
337
376
 
338
377
  Thanks!
339
378
 
340
379
  == Roadmap / TODO
341
380
 
342
- === 0.4.x
343
-
344
- * Implement remaining bits of person and photo-related API calls (read-only)
345
-
346
381
  === 0.5.x
347
382
 
348
- * Implement asynchronous file upload / replacement w/ ticket checking
383
+ * Implement remaining bits of person and photo-related API calls (read-only)
349
384
  * Provide a better searching interface with ruby-like option syntax
350
385
 
351
386
  === Future
352
387
 
388
+ * Implement asynchronous file upload / replacement w/ ticket checking
353
389
  * Implement save-able search results (e.g. Fleakr.search('ponies').save_to('/path', :medium))
354
390
  * Implement deeper associations for core elements (e.g. tags / etc..)
355
391
  * Implement write methods for photos & photosets
data/Rakefile CHANGED
@@ -49,7 +49,7 @@ rescue LoadError
49
49
  end
50
50
 
51
51
  desc 'Generate the gemspec to serve this Gem from Github'
52
- task :github do
52
+ task :gemspec do
53
53
  file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
54
54
  File.open(file, 'w') {|f| f << spec.to_ruby }
55
55
  puts "Created gemspec: #{file}"
@@ -88,18 +88,22 @@ module Fleakr
88
88
  mattr_accessor :api_key, :shared_secret, :mini_token, :auth_token, :frob
89
89
 
90
90
  # Find a user based on some unique user data. This method will try to find
91
- # the user based on username and will fall back to email if that fails. Example:
91
+ # the user based on several methods, starting with username and falling back to email and URL
92
+ # sequentially if these methods fail. Example:
92
93
  #
93
94
  # Fleakr.api_key = 'ABC123'
94
- # Fleakr.user('the decapitator') # => #<Fleakr::Objects::User:0x692648 @username="the decapitator", @id="21775151@N06">
95
- # Fleakr.user('user@host.com') # => #<Fleakr::Objects::User:0x11f484c @username="bckspcr", @id="84481630@N00">
95
+ # Fleakr.user('the decapitator')
96
+ # Fleakr.user('user@host.com')
97
+ # Fleakr.user('http://www.flickr.com/photos/the_decapitator/')
96
98
  #
97
99
  def self.user(user_data)
98
- begin
99
- Objects::User.find_by_username(user_data)
100
- rescue ApiError
101
- Objects::User.find_by_email(user_data)
100
+ user = nil
101
+ [:username, :email, :url].each do |attribute|
102
+ if user.nil?
103
+ user = Objects::User.send("find_by_#{attribute}", user_data) rescue nil
104
+ end
102
105
  end
106
+ user
103
107
  end
104
108
 
105
109
  # Search all photos on the Flickr site. By default, this searches based on text, but you can pass
@@ -1,4 +1,5 @@
1
1
  require 'fleakr/objects/authentication_token'
2
+ require 'fleakr/objects/collection'
2
3
  require 'fleakr/objects/contact'
3
4
  require 'fleakr/objects/error'
4
5
  require 'fleakr/objects/group'
@@ -0,0 +1,57 @@
1
+ module Fleakr
2
+ module Objects # :nodoc:
3
+
4
+ # = Collection
5
+ #
6
+ # == Attributes
7
+ #
8
+ # [id] The ID for this collection
9
+ # [title] The title of this collection
10
+ # [description] The description of this collection
11
+ # [small_icon_url] The URL for the small icon that represents this collection
12
+ # [large_icon_url] The URL for the large icon that represents this collection
13
+ #
14
+ class Collection
15
+
16
+ include Fleakr::Support::Object
17
+
18
+ flickr_attribute :id, :title, :description
19
+ flickr_attribute :created, :from => '@datecreate'
20
+ flickr_attribute :small_icon_url, :from => '@iconsmall'
21
+ flickr_attribute :large_icon_url, :from => '@iconlarge'
22
+
23
+ find_one :by_id, :call => 'collections.getInfo', :path => 'collection'
24
+ find_all :by_user_id, :call => 'collections.getTree', :path => 'collections/collection'
25
+
26
+ # When was this collection created?
27
+ #
28
+ def created_at
29
+ Time.at(created.to_i)
30
+ end
31
+
32
+ # The sets associated with this collection
33
+ #
34
+ def sets
35
+ sibling_nodes_for('set').map {|n| Set.new(n) }
36
+ end
37
+
38
+ # The collections associated with this collection
39
+ #
40
+ def collections
41
+ sibling_nodes_for('collection').map {|n| Collection.new(n) }
42
+ end
43
+
44
+ private
45
+ def sibling_nodes_for(node) # :nodoc:
46
+ nodes = []
47
+ selector = "/collection/#{node}"
48
+
49
+ document = Hpricot.XML(self.document.to_s)
50
+ document.search(selector) {|e| nodes << e }
51
+
52
+ nodes
53
+ end
54
+
55
+ end
56
+ end
57
+ end
@@ -2,9 +2,21 @@ module Fleakr
2
2
  module Objects # :nodoc:
3
3
  class Search
4
4
 
5
+ # attr_reader :search_options
6
+
5
7
  # Create a new search
6
- def initialize(search_options)
7
- @search_options = search_options
8
+ def initialize(*parameters)
9
+ @parameters = Hash.new
10
+ parameters.each {|param| add_parameter(param) }
11
+ end
12
+
13
+ def add_parameter(parameter)
14
+ value = parameter.is_a?(String) ? {:text => parameter} : parameter
15
+ @parameters.merge!(value)
16
+ end
17
+
18
+ def tags
19
+ Array(@parameters[:tags])
8
20
  end
9
21
 
10
22
  # Retrieve search results from the API
@@ -17,12 +29,12 @@ module Fleakr
17
29
 
18
30
  private
19
31
  def tag_list
20
- Array(@search_options[:tags]).join(',')
32
+ tags.join(',')
21
33
  end
22
34
 
23
35
  def parameters
24
- @search_options.merge!(:tags => tag_list) if tag_list.length > 0
25
- @search_options
36
+ @parameters.merge!(:tags => tag_list) if tags.any?
37
+ @parameters
26
38
  end
27
39
 
28
40
  end
@@ -22,6 +22,7 @@ module Fleakr
22
22
  has_many :photos, :comments
23
23
 
24
24
  flickr_attribute :id, :title, :description
25
+ flickr_attribute :primary_photo_id, :from => '@primary'
25
26
  flickr_attribute :count, :from => '@photos'
26
27
 
27
28
  find_all :by_user_id, :call => 'photosets.getList', :path => 'photosets/photoset'
@@ -45,6 +46,10 @@ module Fleakr
45
46
  sprintf("%0#{self.count.length}d_", (index + 1))
46
47
  end
47
48
 
49
+ def primary_photo
50
+ @primary_photo ||= Photo.find_by_id(primary_photo_id)
51
+ end
52
+
48
53
  end
49
54
  end
50
55
  end
@@ -29,6 +29,7 @@ module Fleakr
29
29
  # [photos] A list of this user's public photos (newest first). See Fleakr::Objects::Photo.
30
30
  # [contacts] A list of this user's contacts - these are simply User objects
31
31
  # [tags] The tags associated with this user
32
+ # [collections] The top-level collections that this user has created. See Fleakr::Objects::Collection.
32
33
  #
33
34
  # == Examples
34
35
  #
@@ -44,7 +45,7 @@ module Fleakr
44
45
 
45
46
  include Fleakr::Support::Object
46
47
 
47
- flickr_attribute :id, :from => 'user@nsid'
48
+ flickr_attribute :id, :from => ['user@id', 'user@nsid']
48
49
  flickr_attribute :username, :location
49
50
  flickr_attribute :name, :from => 'person/realname'
50
51
  flickr_attribute :photos_url, :from => 'person/photosurl'
@@ -55,11 +56,12 @@ module Fleakr
55
56
  flickr_attribute :pro, :from => 'person@ispro'
56
57
  flickr_attribute :admin, :from => 'person@isadmin'
57
58
 
58
- has_many :sets, :groups, :photos, :contacts, :tags
59
+ has_many :sets, :groups, :photos, :contacts, :tags, :collections
59
60
 
60
61
  find_one :by_username, :call => 'people.findByUsername'
61
62
  find_one :by_email, :using => :find_email, :call => 'people.findByEmail'
62
63
  find_one :by_id, :using => :user_id, :call => 'people.getInfo'
64
+ find_one :by_url, :call => 'urls.lookupUser'
63
65
 
64
66
  lazily_load :name, :photos_url, :profile_url, :photos_count, :location, :with => :load_info
65
67
  lazily_load :icon_server, :icon_farm, :pro, :admin, :with => :load_info
@@ -63,8 +63,9 @@ module Fleakr
63
63
  key = "#{self.name.demodulize.underscore.downcase}_id".to_sym
64
64
 
65
65
  class_eval <<-CODE
66
- def search(search_text)
67
- Fleakr::Objects::Search.new(:text => search_text, :#{key} => self.id).results
66
+ def search(*parameters)
67
+ parameters << {:#{key} => self.id}
68
+ Fleakr::Objects::Search.new(*parameters).results
68
69
  end
69
70
  CODE
70
71
  end
@@ -87,11 +88,14 @@ module Fleakr
87
88
 
88
89
  module InstanceMethods
89
90
 
91
+ attr_reader :document
92
+
90
93
  def initialize(document = nil)
91
94
  self.populate_from(document) unless document.nil?
92
95
  end
93
96
 
94
97
  def populate_from(document)
98
+ @document = document
95
99
  self.class.attributes.each do |attribute|
96
100
  value = attribute.value_from(document)
97
101
  self.send("#{attribute.name}=".to_sym, value) unless value.nil?
@@ -3,7 +3,7 @@ module Fleakr
3
3
 
4
4
  MAJOR = 0
5
5
  MINOR = 5
6
- TINY = 1
6
+ TINY = 2
7
7
 
8
8
  def self.to_s
9
9
  [MAJOR, MINOR, TINY].join('.')
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <collection id="34762917-72157619347181335" child_count="5" datecreate="1244460707" iconlarge="http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_l.jpg" iconsmall="http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_s.jpg" server="3603" secret="30d89a2682">
4
+ <title>Work</title>
5
+ <description>Sample Collection</description>
6
+ <iconphotos>
7
+ <photo id="3509228143" owner="34808239@N06" secret="2ed3119372" server="3637" farm="4" title="" ispublic="1" isfriend="0" isfamily="0" />
8
+ <photo id="3509261341" owner="34808239@N06" secret="43a07ee13c" server="3638" farm="4" title="Saab 9X Air" ispublic="1" isfriend="0" isfamily="0" />
9
+ <photo id="3488255219" owner="34808239@N06" secret="b94e2c39c1" server="3624" farm="4" title="" ispublic="1" isfriend="0" isfamily="0" />
10
+ <photo id="3488219705" owner="34808239@N06" secret="d26642a09b" server="3560" farm="4" title="stellaUK_1" ispublic="1" isfriend="0" isfamily="0" />
11
+ <photo id="3489034148" owner="34808239@N06" secret="89d6f94800" server="3577" farm="4" title="abba_kalles_3" ispublic="1" isfriend="0" isfamily="0" />
12
+ <photo id="3488220307" owner="34808239@N06" secret="a96a8acbb0" server="3578" farm="4" title="abba_kalles_1" ispublic="1" isfriend="0" isfamily="0" />
13
+ <photo id="3489034014" owner="34808239@N06" secret="d392cca5d6" server="3124" farm="4" title="abba_kalles_2" ispublic="1" isfriend="0" isfamily="0" />
14
+ <photo id="3489033670" owner="34808239@N06" secret="4f08e7368c" server="3547" farm="4" title="stellaUK_3" ispublic="1" isfriend="0" isfamily="0" />
15
+ <photo id="3488219913" owner="34808239@N06" secret="6bcdeb4bf6" server="3310" farm="4" title="stellaUK_2" ispublic="1" isfriend="0" isfamily="0" />
16
+ <photo id="3509261445" owner="34808239@N06" secret="595cc58f50" server="3313" farm="4" title="Saab 9X Air" ispublic="1" isfriend="0" isfamily="0" />
17
+ <photo id="3488255345" owner="34808239@N06" secret="de5f1b9133" server="3644" farm="4" title="" ispublic="1" isfriend="0" isfamily="0" />
18
+ <photo id="3509228095" owner="34808239@N06" secret="3b0a661db7" server="3392" farm="4" title="" ispublic="1" isfriend="0" isfamily="0" />
19
+ </iconphotos>
20
+ </collection>
21
+ </rsp>
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <collections>
4
+ <collection id="123-456" title="Top-Level Collection 1" description="Description 1" iconlarge="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_l.jpg" iconsmall="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_s.jpg">
5
+ <collection id="123-457" title="Second-Level Collection 1" description="Description 2" iconlarge="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_l.jpg" iconsmall="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_s.jpg">
6
+ <collection id="123-789" title="Third-Level Collection 1" description="Description 3" iconlarge="http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_l.jpg" iconsmall="http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_s.jpg">
7
+ <set id="1234" title="Set 1" description="" />
8
+ <set id="1235" title="Set 2" description="" />
9
+ </collection>
10
+ <collection id="123-101" title="Third-Level Collection 2" description="Description 4" iconlarge="http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_l.jpg" iconsmall="http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_s.jpg">
11
+ <set id="1236" title="Set 3" description="" />
12
+ <set id="1237" title="Set 4" description="" />
13
+ </collection>
14
+ </collection>
15
+ </collection>
16
+ <collection id="123-102" title="Top-Level Collection 2" description="Description 5" iconlarge="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_l.jpg" iconsmall="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_s.jpg">
17
+ <set id="1238" title="Set 5" description="" />
18
+ <set id="1239" title="Set 6" description="" />
19
+ </collection>
20
+ </collections>
21
+ </rsp>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <user id="123456">
4
+ <username>frootpantz</username>
5
+ </user>
6
+ </rsp>
@@ -39,7 +39,7 @@ class Test::Unit::TestCase
39
39
  instance = klass.new
40
40
  instance.stubs(:id).with().returns('1')
41
41
 
42
- Fleakr::Objects::Search.expects(:new).with(:text => 'foo', key => '1').returns(search)
42
+ Fleakr::Objects::Search.expects(:new).with('foo', key => '1').returns(search)
43
43
 
44
44
  instance.search('foo').should == photos
45
45
  end
@@ -0,0 +1,99 @@
1
+ require File.dirname(__FILE__) + '/../../../test_helper'
2
+
3
+ module Fleakr::Objects
4
+ class CollectionTest < Test::Unit::TestCase
5
+
6
+ context "The Collection class" do
7
+
8
+ should_find_one :collections, :by => :id, :call => 'collections.getInfo', :path => 'rsp/collection'
9
+ should_find_all :collections, :by => :user_id, :call => 'collections.getTree', :path => 'rsp/collections/collection'
10
+
11
+ end
12
+
13
+ context "An instance of the Collection class" do
14
+
15
+ context "when populating from a call to collections.getInfo" do
16
+ setup do
17
+ document = Hpricot.XML(read_fixture('collections.getInfo')).at('rsp/collection')
18
+ @object = Collection.new(document)
19
+ end
20
+
21
+ should_have_a_value_for :id => '34762917-72157619347181335'
22
+ should_have_a_value_for :title => 'Work'
23
+ should_have_a_value_for :description => 'Sample Collection'
24
+ should_have_a_value_for :large_icon_url => 'http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_l.jpg'
25
+ should_have_a_value_for :small_icon_url => 'http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_s.jpg'
26
+ should_have_a_value_for :created => '1244460707'
27
+
28
+ end
29
+
30
+ context "when populating from a call to collections.getTree" do
31
+ setup do
32
+ document = Hpricot.XML(read_fixture('collections.getTree')).at('rsp/collections/collection')
33
+ @object = Collection.new(document)
34
+ end
35
+
36
+ should_have_a_value_for :id => '123-456'
37
+ should_have_a_value_for :title => 'Top-Level Collection 1'
38
+ should_have_a_value_for :description => 'Description 1'
39
+ should_have_a_value_for :large_icon_url => 'http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_l.jpg'
40
+ should_have_a_value_for :small_icon_url => 'http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_s.jpg'
41
+
42
+ end
43
+
44
+ context "that contains collections" do
45
+ setup do
46
+ document = Hpricot.XML(read_fixture('collections.getTree')).at('rsp/collections/collection')
47
+ @collection = Collection.new(document)
48
+ end
49
+
50
+ should "have a set of collections" do
51
+ collection_titles = @collection.collections.map {|c| c.title }
52
+ collection_titles.should == ['Second-Level Collection 1']
53
+ end
54
+
55
+ should "not have any associated sets" do
56
+ @collection.sets.should == []
57
+ end
58
+ end
59
+
60
+ context "that contains sets" do
61
+ setup do
62
+ xml = <<-XML
63
+ <collection id="123-102" title="Top-Level Collection 2" description="Description 5" iconlarge="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_l.jpg" iconsmall="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_s.jpg">
64
+ <set id="1238" title="Set 5" description="" />
65
+ <set id="1239" title="Set 6" description="" />
66
+ </collection>
67
+ XML
68
+
69
+ document = Hpricot.XML(xml).at('collection')
70
+ @collection = Collection.new(document)
71
+ end
72
+
73
+ should "not have any associated collections" do
74
+ @collection.collections.should == []
75
+ end
76
+
77
+ should "have associated sets" do
78
+ set_titles = @collection.sets.map {|s| s.title }
79
+ set_titles.should == ['Set 5', 'Set 6']
80
+ end
81
+
82
+ end
83
+
84
+ context "in general" do
85
+ setup do
86
+ @collection = Collection.new
87
+ @time = Time.parse('2008-08-01 00:00:00')
88
+ end
89
+
90
+ should "have a value for :created_at" do
91
+ @collection.expects(:created).with().returns("#{@time.to_i}")
92
+ @collection.created_at.to_s.should == @time.to_s
93
+ end
94
+
95
+ end
96
+ end
97
+
98
+ end
99
+ end
@@ -5,6 +5,16 @@ module Fleakr::Objects
5
5
 
6
6
  context "An instance of the Search class" do
7
7
 
8
+ should "have a list of tags" do
9
+ search = Search.new(:tags => %w(a b c))
10
+ search.tags.should == %w(a b c)
11
+ end
12
+
13
+ should "have convert tags into an array" do
14
+ search = Search.new(:tags => 'a')
15
+ search.tags.should == ['a']
16
+ end
17
+
8
18
  should "be able to generate a list of tags from a single-valued parameter" do
9
19
  search = Search.new(:tags => 'foo')
10
20
  search.send(:tag_list).should == 'foo'
@@ -35,6 +45,16 @@ module Fleakr::Objects
35
45
  search.send(:parameters).should == {:text => 'foo'}
36
46
  end
37
47
 
48
+ should "convert a single string parameter into a text search" do
49
+ search = Search.new('term')
50
+ search.send(:parameters).should == {:text => 'term'}
51
+ end
52
+
53
+ should "be able to handle a combination of text and options" do
54
+ search = Search.new('term', :tags => %w(a b))
55
+ search.send(:parameters).should == {:text => 'term', :tags => 'a,b'}
56
+ end
57
+
38
58
  should "be able to search photos based on text" do
39
59
  response = mock_request_cycle :for => 'photos.search', :with => {:text => 'foo'}
40
60
  search = Search.new(:text => 'foo')
@@ -18,13 +18,38 @@ module Fleakr::Objects
18
18
  @object = Set.new(Hpricot.XML(read_fixture('photosets.getList')).at('rsp/photosets/photoset'))
19
19
  end
20
20
 
21
- should_have_a_value_for :id => '72157609490909659'
22
- should_have_a_value_for :title => 'Second Set'
23
- should_have_a_value_for :description => 'This is the second set.'
24
- should_have_a_value_for :count => '138'
21
+ should_have_a_value_for :id => '72157609490909659'
22
+ should_have_a_value_for :title => 'Second Set'
23
+ should_have_a_value_for :description => 'This is the second set.'
24
+ should_have_a_value_for :count => '138'
25
+ should_have_a_value_for :primary_photo_id => '3044180117'
25
26
 
26
27
  end
27
28
 
29
+ should "know the primary photo in the set" do
30
+ id = '1'
31
+ photo = stub()
32
+
33
+ Photo.expects(:find_by_id).with(id).returns(photo)
34
+
35
+ set = Set.new
36
+ set.stubs(:primary_photo_id).with().returns(id)
37
+
38
+ set.primary_photo.should == photo
39
+ end
40
+
41
+ should "memoize the primary photo" do
42
+ id = '1'
43
+ photo = stub()
44
+
45
+ Photo.expects(:find_by_id).with(id).once.returns(photo)
46
+
47
+ set = Set.new
48
+ set.stubs(:primary_photo_id).with().returns(id)
49
+
50
+ 2.times { set.primary_photo }
51
+ end
52
+
28
53
  context "when saving the set" do
29
54
  setup do
30
55
  @tmp_dir = create_temp_directory
@@ -5,7 +5,7 @@ module Fleakr::Objects
5
5
 
6
6
  should_search_by :user_id
7
7
 
8
- should_have_many :photos, :groups, :sets, :contacts, :tags
8
+ should_have_many :photos, :groups, :sets, :contacts, :tags, :collections
9
9
 
10
10
  should_autoload_when_accessing :name, :photos_url, :profile_url, :photos_count, :location, :with => :load_info
11
11
  should_autoload_when_accessing :icon_server, :icon_farm, :pro, :admin, :icon_url, :with => :load_info
@@ -15,6 +15,7 @@ module Fleakr::Objects
15
15
  should_find_one :user, :by => :username, :call => 'people.findByUsername', :path => 'rsp/user'
16
16
  should_find_one :user, :by => :email, :with => :find_email, :call => 'people.findByEmail', :path => 'rsp/user'
17
17
  should_find_one :user, :by => :id, :with => :user_id, :call => 'people.getInfo', :path => 'rsp/person'
18
+ should_find_one :user, :by => :url, :call => 'urls.lookupUser', :path => 'rsp/user'
18
19
 
19
20
  end
20
21
 
@@ -38,6 +39,17 @@ module Fleakr::Objects
38
39
  should_have_a_value_for :admin => '0'
39
40
 
40
41
  end
42
+
43
+ context "when populating an object from the urls.lookupUser API call" do
44
+ setup do
45
+ document = Hpricot.XML(read_fixture('urls.lookupUser'))
46
+ @object = User.new(document)
47
+ end
48
+
49
+ should_have_a_value_for :id => '123456'
50
+ should_have_a_value_for :username => 'frootpantz'
51
+
52
+ end
41
53
 
42
54
  context "in general" do
43
55
 
@@ -72,8 +72,10 @@ module Fleakr
72
72
  <category>Category</category>
73
73
  XML
74
74
 
75
+ @document = Hpricot.XML(xml)
76
+
75
77
  @object = FlickrObject.new
76
- @object.populate_from(Hpricot.XML(xml))
78
+ @object.populate_from(@document)
77
79
  end
78
80
 
79
81
  should "have the correct value for :name" do
@@ -102,6 +104,10 @@ module Fleakr
102
104
  should "have the correct value for :category" do
103
105
  @object.category.should == 'Category'
104
106
  end
107
+
108
+ should "maintain a reference to the original document" do
109
+ @object.document.should == @document
110
+ end
105
111
  end
106
112
 
107
113
  should "populate its data from an XML document when initializing" do
@@ -29,6 +29,27 @@ class FleakrTest < Test::Unit::TestCase
29
29
  Fleakr.user(email).should == user
30
30
  end
31
31
 
32
+ should "fall back to finding a user by URL if username and email both fail" do
33
+ user = stub()
34
+ url = 'http://flickr.com/photos/user'
35
+
36
+ Fleakr::Objects::User.stubs(:find_by_username).with(url).raises(Fleakr::ApiError)
37
+ Fleakr::Objects::User.stubs(:find_by_email).with(url).raises(Fleakr::ApiError)
38
+ Fleakr::Objects::User.expects(:find_by_url).with(url).returns(user)
39
+
40
+ Fleakr.user(url).should == user
41
+ end
42
+
43
+ should "not return nil if a user cannot be found" do
44
+ data = 'data'
45
+
46
+ Fleakr::Objects::User.stubs(:find_by_username).with(data).raises(Fleakr::ApiError)
47
+ Fleakr::Objects::User.stubs(:find_by_email).with(data).raises(Fleakr::ApiError)
48
+ Fleakr::Objects::User.stubs(:find_by_url).with(data).raises(Fleakr::ApiError)
49
+
50
+ Fleakr.user(data).should be_nil
51
+ end
52
+
32
53
  should "find all contacts for the authenticated user" do
33
54
  Fleakr::Objects::Contact.expects(:find_all).with({}).returns('contacts')
34
55
  Fleakr.contacts.should == 'contacts'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fleakr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick Reagan
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-21 00:00:00 -04:00
12
+ date: 2009-10-18 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -67,6 +67,7 @@ files:
67
67
  - lib/fleakr/core_ext/true_class.rb
68
68
  - lib/fleakr/core_ext.rb
69
69
  - lib/fleakr/objects/authentication_token.rb
70
+ - lib/fleakr/objects/collection.rb
70
71
  - lib/fleakr/objects/comment.rb
71
72
  - lib/fleakr/objects/contact.rb
72
73
  - lib/fleakr/objects/error.rb
@@ -87,6 +88,8 @@ files:
87
88
  - test/fixtures/auth.checkToken.xml
88
89
  - test/fixtures/auth.getFullToken.xml
89
90
  - test/fixtures/auth.getToken.xml
91
+ - test/fixtures/collections.getInfo.xml
92
+ - test/fixtures/collections.getTree.xml
90
93
  - test/fixtures/contacts.getList.xml
91
94
  - test/fixtures/contacts.getPublicList.xml
92
95
  - test/fixtures/groups.pools.getPhotos.xml
@@ -106,6 +109,7 @@ files:
106
109
  - test/fixtures/tags.getListPhoto.xml
107
110
  - test/fixtures/tags.getListUser.xml
108
111
  - test/fixtures/tags.getRelated.xml
112
+ - test/fixtures/urls.lookupUser.xml
109
113
  - test/test_helper.rb
110
114
  - test/unit/fleakr/api/file_parameter_test.rb
111
115
  - test/unit/fleakr/api/method_request_test.rb
@@ -119,6 +123,7 @@ files:
119
123
  - test/unit/fleakr/core_ext/hash_test.rb
120
124
  - test/unit/fleakr/core_ext/true_class_test.rb
121
125
  - test/unit/fleakr/objects/authentication_token_test.rb
126
+ - test/unit/fleakr/objects/collection_test.rb
122
127
  - test/unit/fleakr/objects/comment_test.rb
123
128
  - test/unit/fleakr/objects/contact_test.rb
124
129
  - test/unit/fleakr/objects/error_test.rb