fleakr 0.4.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc CHANGED
@@ -119,7 +119,61 @@ Other sizes are available (:square, :thumbnail, :small, :medium, :large, :origin
119
119
  are accessed in the same way:
120
120
 
121
121
  >> photo.original.url
122
- => "http://farm4.static.flickr.com/3250/2924549350_1cf67c2d47_o.jpg"
122
+ => "http://farm4.static.flickr.com/3250/2924549350_1cf67c2d47_o.jpg"
123
+
124
+ === Tags
125
+
126
+ Tags are available for users and photos. Retrieving them is easy:
127
+
128
+ >> user = Fleakr.user('the decapitator')
129
+ >> user.tags
130
+ => [#<Fleakr::Objects::Tag:0x190d5fc @value="ad">,
131
+ #<Fleakr::Objects::Tag:0x1908a20 @value="ads">, ...
132
+ >> user.photos.first.tags
133
+ => [#<Fleakr::Objects::Tag:0x17b1b18 @machine_flag="0", @author_id="21775151@N06", ...
134
+
135
+ All tags have values, but for tags associated with photos there is some additional information:
136
+
137
+ >> tag = user.photos.first.tags.first
138
+ >> tag.id
139
+ => "21729829-3263659141-427098"
140
+ >> tag.raw
141
+ => "decapitator"
142
+ >> tag.value
143
+ => "decapitator"
144
+ >> tag.to_s
145
+ => "decapitator"
146
+ >> tag.machine?
147
+ => false
148
+ >> tag.author
149
+ => #<Fleakr::Objects::User:0x1a149f0 @username="the decapitator", ... >
150
+
151
+ See Fleakr::Objects::Tag for more information.
152
+
153
+ === Comments
154
+
155
+ Similar to tags, photosets and photos can each have comments:
156
+
157
+ >> user.sets.first.comments
158
+ => [#<Fleakr::Objects::Comment:0x19795cc ...
159
+ >> user.photos.first.comments
160
+ => [#<Fleakr::Objects::Comment:0x17bf0b0 @body="Dayum, that's some wishful thinking!" ...
161
+
162
+ All comments have additional information:
163
+
164
+ >> comment = user.photos.first.comments.first
165
+ >> comment.id
166
+ => "21729829-3263659141-72157613553885978"
167
+ >> comment.body
168
+ => "Dayum, that's some wishful thinking!"
169
+ >> comment.to_s
170
+ => "Dayum, that's some wishful thinking!"
171
+ >> comment.url
172
+ => "http://www.flickr.com/photos/the_decapitator/3263659141/#comment72157613553885978"
173
+ >> comment.author
174
+ => #<Fleakr::Objects::User:0x178e3d4 @username="jaspertandy", ... >
175
+
176
+ See Fleakr::Objects::Comment for more information.
123
177
 
124
178
  === Saving Images
125
179
 
@@ -0,0 +1,49 @@
1
+ module Fleakr
2
+ module Objects # :nodoc:
3
+
4
+ # = Comment
5
+ #
6
+ # This class represents a comment that can be associated with a single photo or an
7
+ # entire photoset.
8
+ #
9
+ # == Attributes
10
+ #
11
+ # [id] The unique identifier for this comment
12
+ # [url] The direct URL / permalink to reference this comment
13
+ # [body] The comment itself - also available with <tt>to_s</tt>
14
+ #
15
+ class Comment
16
+
17
+ include Fleakr::Support::Object
18
+
19
+ find_all :by_photo_id, :call => 'photos.comments.getList', :path => 'comments/comment'
20
+ find_all :by_set_id, :using => :photoset_id, :call => 'photosets.comments.getList', :path => 'comments/comment'
21
+
22
+ flickr_attribute :id
23
+ flickr_attribute :author_id, :from => '@author'
24
+ flickr_attribute :created, :from => '@datecreate'
25
+ flickr_attribute :url, :from => '@permalink'
26
+ flickr_attribute :body, :from => '.'
27
+
28
+ # The user who supplied the comment. See Fleakr::Objects::User for more information
29
+ #
30
+ def author
31
+ @author ||= User.find_by_id(author_id)
32
+ end
33
+
34
+ # When was this comment created?
35
+ #
36
+ def created_at
37
+ Time.at(created.to_i)
38
+ end
39
+
40
+ # The contents of the comment - also available as <tt>body</tt>
41
+ #
42
+ def to_s
43
+ body
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+ end
@@ -8,18 +8,28 @@ module Fleakr
8
8
  # [id] This group's ID
9
9
  # [name] The name of the group
10
10
  #
11
+ # == Associations
12
+ #
13
+ # [photos] The photos that are in this group
14
+ #
11
15
  class Group
12
16
 
13
17
  include Fleakr::Support::Object
14
18
 
15
19
  flickr_attribute :id, :from => '@nsid'
16
20
  flickr_attribute :name
21
+ flickr_attribute :adult_flag, :from => '@eighteenplus'
17
22
 
18
23
  find_all :by_user_id, :call => 'people.getPublicGroups', :path => 'groups/group'
19
24
 
20
25
  has_many :photos
21
26
 
22
27
  scoped_search
28
+
29
+ # Is this group adult-only? (e.g. only 18+ allowed to view)
30
+ def adult?
31
+ (adult_flag == '1')
32
+ end
23
33
 
24
34
  end
25
35
  end
@@ -24,9 +24,8 @@ module Fleakr
24
24
 
25
25
  include Fleakr::Support::Object
26
26
 
27
+ flickr_attribute :width, :height
27
28
  flickr_attribute :size, :from => '@label'
28
- flickr_attribute :width
29
- flickr_attribute :height
30
29
  flickr_attribute :url, :from => '@source'
31
30
  flickr_attribute :page, :from => '@url'
32
31
 
@@ -20,10 +20,14 @@ module Fleakr
20
20
  # [medium] The medium representation of this photo
21
21
  # [large] The large representation of this photo
22
22
  # [original] The original photo
23
+ # [previous] The previous photo based on the current context
24
+ # [next] The next photo based on the current context
23
25
  #
24
26
  # == Associations
25
27
  #
26
28
  # [images] The underlying images for this photo.
29
+ # [tags] The tags for this photo.
30
+ # [comments] The comments associated with this photo
27
31
  #
28
32
  class Photo
29
33
 
@@ -31,28 +35,24 @@ module Fleakr
31
35
  SIZES = [:square, :thumbnail, :small, :medium, :large, :original]
32
36
 
33
37
  include Fleakr::Support::Object
38
+ extend Forwardable
39
+
40
+ def_delegators :context, :next, :previous
34
41
 
35
42
  flickr_attribute :id, :from => ['@id', 'photoid']
36
- flickr_attribute :title
37
- flickr_attribute :description
43
+ flickr_attribute :title, :description, :secret, :posted, :taken, :url
38
44
  flickr_attribute :farm_id, :from => '@farm'
39
45
  flickr_attribute :server_id, :from => '@server'
40
- flickr_attribute :secret
41
- flickr_attribute :posted
42
- flickr_attribute :taken
46
+ flickr_attribute :owner_id, :from => ['@owner', 'owner@nsid']
43
47
  flickr_attribute :updated, :from => '@lastupdate'
44
48
  flickr_attribute :comment_count, :from => 'comments'
45
- flickr_attribute :url
46
49
 
47
50
  # TODO:
48
- # * owner (user)
49
51
  # * visibility
50
52
  # * editability
51
53
  # * usage
52
- # * notes
53
- # * tags
54
54
 
55
- find_all :by_photoset_id, :call => 'photosets.getPhotos', :path => 'photoset/photo'
55
+ find_all :by_set_id, :using => :photoset_id, :call => 'photosets.getPhotos', :path => 'photoset/photo'
56
56
  find_all :by_user_id, :call => 'people.getPublicPhotos', :path => 'photos/photo'
57
57
  find_all :by_group_id, :call => 'groups.pools.getPhotos', :path => 'photos/photo'
58
58
 
@@ -60,7 +60,7 @@ module Fleakr
60
60
 
61
61
  lazily_load :posted, :taken, :updated, :comment_count, :url, :description, :with => :load_info
62
62
 
63
- has_many :images
63
+ has_many :images, :tags, :comments
64
64
 
65
65
  # Upload the photo specified by <tt>filename</tt> to the user's Flickr account. When uploading,
66
66
  # there are several options available (none are required):
@@ -98,6 +98,19 @@ module Fleakr
98
98
  self.populate_from(response.body)
99
99
  end
100
100
 
101
+ def context # :nodoc:
102
+ @context ||= begin
103
+ response = Fleakr::Api::MethodRequest.with_response!('photos.getContext', :photo_id => self.id)
104
+ PhotoContext.new(response.body)
105
+ end
106
+ end
107
+
108
+ # The user who uploaded this photo. See Fleakr::Objects::User for additional information.
109
+ #
110
+ def owner
111
+ @owner ||= User.find_by_id(owner_id)
112
+ end
113
+
101
114
  # When was this photo posted?
102
115
  #
103
116
  def posted_at
@@ -0,0 +1,49 @@
1
+ module Fleakr
2
+ module Objects # :nodoc:
3
+
4
+ # = PhotoContext
5
+ #
6
+ # This class represents the context for a photo as retrieved from the API. It's not
7
+ # intended to be used directly, but is used in conjunction with Photo#previous and
8
+ # Photo#next
9
+ #
10
+ # == Attributes
11
+ #
12
+ # [count] The number of photos available
13
+
14
+ class PhotoContext
15
+
16
+ include Fleakr::Support::Object
17
+
18
+ flickr_attribute :count
19
+ flickr_attribute :next_id, :from => 'nextphoto@id'
20
+ flickr_attribute :previous_id, :from => 'prevphoto@id'
21
+
22
+ # Is there a previous photo available for the current photo?
23
+ #
24
+ def previous?
25
+ previous_id != '0'
26
+ end
27
+
28
+ # The previous photo if one is available
29
+ #
30
+ def previous
31
+ Photo.find_by_id(previous_id) if previous?
32
+ end
33
+
34
+ # Is there a next photo available for the current photo?
35
+ #
36
+ def next?
37
+ next_id != '0'
38
+ end
39
+
40
+ # The next photo if one is available
41
+ #
42
+ def next
43
+ Photo.find_by_id(next_id) if next?
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+ end
@@ -13,16 +13,15 @@ module Fleakr
13
13
  # == Associations
14
14
  #
15
15
  # [photos] The collection of photos for this set. See Fleakr::Objects::Photo
16
+ # [comments] All comments associated with this set. See Fleakr::Objects::Comment
16
17
  #
17
18
  class Set
18
19
 
19
20
  include Fleakr::Support::Object
20
21
 
21
- has_many :photos, :using => :photoset_id
22
+ has_many :photos, :comments
22
23
 
23
- flickr_attribute :id
24
- flickr_attribute :title
25
- flickr_attribute :description
24
+ flickr_attribute :id, :title, :description
26
25
  flickr_attribute :count, :from => '@photos'
27
26
 
28
27
  find_all :by_user_id, :call => 'photosets.getList', :path => 'photosets/photoset'
@@ -0,0 +1,56 @@
1
+ module Fleakr
2
+ module Objects # :nodoc:
3
+
4
+ # = Tag
5
+ #
6
+ # This class represents a tag that can be associated with a photo or an individual user.
7
+ #
8
+ # == Attributes
9
+ #
10
+ # [id] The unique identifier for this tag
11
+ # [raw] The raw, user-entered value for this tag
12
+ # [value] The formatted value for this tag. Also available through <tt>to_s</tt>
13
+ #
14
+ class Tag
15
+
16
+ include Fleakr::Support::Object
17
+
18
+ flickr_attribute :id, :raw
19
+ flickr_attribute :author_id, :from => '@author'
20
+ flickr_attribute :value, :from => '.' # pull this from the current node
21
+ flickr_attribute :machine_flag, :from => '@machine_tag'
22
+
23
+ find_all :by_photo_id, :call => 'tags.getListPhoto', :path => 'photo/tags/tag'
24
+ find_all :by_user_id, :call => 'tags.getListUser', :path => 'who/tags/tag'
25
+
26
+ # The first user who created this tag. See Fleakr::Objects::User for more information
27
+ #
28
+ def author
29
+ @author ||= User.find_by_id(author_id) unless author_id.nil?
30
+ end
31
+
32
+ # A list of related tags. Each of the objects in the collection is an instance of Tag
33
+ #
34
+ def related
35
+ @related ||= begin
36
+ response = Fleakr::Api::MethodRequest.with_response!('tags.getRelated', :tag => value)
37
+ (response.body/'rsp/tags/tag').map {|e| Tag.new(e) }
38
+ end
39
+ end
40
+
41
+ # Is this a machine tag?
42
+ #
43
+ def machine?
44
+ machine_flag != '0'
45
+ end
46
+
47
+ # The formatted value of the tag. Also available as <tt>value</tt>
48
+ #
49
+ def to_s
50
+ value
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+ end
@@ -28,6 +28,7 @@ module Fleakr
28
28
  # [groups] A list of this user's public groups. See Fleakr::Objects::Group.
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
+ # [tags] The tags associated with this user
31
32
  #
32
33
  # == Examples
33
34
  #
@@ -44,9 +45,8 @@ module Fleakr
44
45
  include Fleakr::Support::Object
45
46
 
46
47
  flickr_attribute :id, :from => 'user@nsid'
47
- flickr_attribute :username
48
+ flickr_attribute :username, :location
48
49
  flickr_attribute :name, :from => 'person/realname'
49
- flickr_attribute :location
50
50
  flickr_attribute :photos_url, :from => 'person/photosurl'
51
51
  flickr_attribute :profile_url, :from => 'person/profileurl'
52
52
  flickr_attribute :photos_count, :from => 'person/photos/count'
@@ -55,10 +55,11 @@ module Fleakr
55
55
  flickr_attribute :pro, :from => 'person@ispro'
56
56
  flickr_attribute :admin, :from => 'person@isadmin'
57
57
 
58
- has_many :sets, :groups, :photos, :contacts
58
+ has_many :sets, :groups, :photos, :contacts, :tags
59
59
 
60
60
  find_one :by_username, :call => 'people.findByUsername'
61
61
  find_one :by_email, :using => :find_email, :call => 'people.findByEmail'
62
+ find_one :by_id, :using => :user_id, :call => 'people.getInfo'
62
63
 
63
64
  lazily_load :name, :photos_url, :profile_url, :photos_count, :location, :with => :load_info
64
65
  lazily_load :icon_server, :icon_farm, :pro, :admin, :with => :load_info
@@ -3,7 +3,10 @@ require 'fleakr/objects/contact'
3
3
  require 'fleakr/objects/error'
4
4
  require 'fleakr/objects/group'
5
5
  require 'fleakr/objects/image'
6
+ require 'fleakr/objects/photo_context'
6
7
  require 'fleakr/objects/photo'
8
+ require 'fleakr/objects/comment'
9
+ require 'fleakr/objects/tag'
7
10
  require 'fleakr/objects/search'
8
11
  require 'fleakr/objects/set'
9
12
  require 'fleakr/objects/user'
@@ -8,18 +8,22 @@ module Fleakr
8
8
  @attributes ||= []
9
9
  end
10
10
 
11
- def flickr_attribute(name, options = {})
12
- self.attributes << Attribute.new(name, options[:from])
13
- class_eval "attr_accessor :#{name}"
11
+ def flickr_attribute(*names_and_options)
12
+ options = names_and_options.extract_options!
13
+
14
+ names_and_options.each do |name|
15
+ self.attributes << Attribute.new(name, options[:from])
16
+ class_eval "attr_accessor :#{name}"
17
+ end
14
18
  end
15
19
 
16
20
  def has_many(*attributes)
17
- options = attributes.extract_options!
18
21
  class_name = self.name
19
22
 
20
23
  attributes.each do |attribute|
21
- target = "Fleakr::Objects::#{attribute.to_s.classify}"
22
- finder_attribute = options[:using].nil? ? "#{class_name.demodulize.underscore}_id": options[:using]
24
+ target = "Fleakr::Objects::#{attribute.to_s.classify}"
25
+ finder_attribute = "#{class_name.demodulize.underscore}_id"
26
+
23
27
  class_eval <<-CODE
24
28
  def #{attribute}
25
29
  @#{attribute} ||= #{target}.send("find_all_by_#{finder_attribute}".to_sym, self.id)
@@ -3,7 +3,7 @@ module Fleakr
3
3
 
4
4
  MAJOR = 0
5
5
  MINOR = 4
6
- TINY = 2
6
+ TINY = 3
7
7
 
8
8
  def self.to_s
9
9
  [MAJOR, MINOR, TINY].join('.')
data/lib/fleakr.rb CHANGED
@@ -5,6 +5,7 @@ require 'uri'
5
5
  require 'cgi'
6
6
  require 'net/http'
7
7
  require 'hpricot'
8
+ require 'forwardable'
8
9
 
9
10
  # Require only what we need from ActiveSupport
10
11
  require 'active_support/core_ext/array'
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8" ?>
2
2
  <rsp stat="ok">
3
3
  <groups>
4
- <group nsid="13378274@N00" name="Group #1" admin="0" eighteenplus="0" />
5
- <group nsid="52242140489@N01" name="Group #2" admin="0" eighteenplus="0" />
4
+ <group nsid="13378274@N00" name="Group #1" admin="0" eighteenplus="1" />
5
+ <group nsid="52242140489@N01" name="Group #2" admin="1" eighteenplus="0" />
6
6
  </groups>
7
7
  </rsp>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <comments photo_id="1">
4
+ <comment id="1" author="10490170@N04" authorname="blip" datecreate="1239217523" permalink="http://www.flickr.com/photos/frootpantz/3422268412/#comment72157616515348062">comment one</comment>
5
+ <comment id="2" author="10490170@N02" authorname="bleep" datecreate="1239217222" permalink="http://www.flickr.com/photos/frootpantz/3422268413/#comment72157616515348063">comment two</comment>
6
+ </comments>
7
+ </rsp>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <count>5584</count>
4
+ <prevphoto id="12345" secret="abc234" server="3560" farm="4" title="Previous" url="/photos/frootpantz/12345/in/photostream/" thumb="http://farm4.static.flickr.com/3560/3369675369_d97d2b1345_s.jpg" media="photo" />
5
+ <nextphoto id="12343" secret="abc123" server="3562" farm="4" title="Next" url="/photos/frootpantz/12343/in/photostream/" thumb="http://farm4.static.flickr.com/3562/3370497926_ba89f4343a_s.jpg" media="photo" />
6
+ </rsp>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <comments photo_id="1">
4
+ <comment id="1" author="10490170@N04" authorname="blip" datecreate="1239217523" permalink="http://www.flickr.com/photos/frootpantz/3422268412/#comment72157616515348062">comment one</comment>
5
+ <comment id="2" author="10490170@N02" authorname="bleep" datecreate="1239217222" permalink="http://www.flickr.com/photos/frootpantz/3422268413/#comment72157616515348063">comment two</comment>
6
+ </comments>
7
+ </rsp>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <photo id="3411015045">
4
+ <tags>
5
+ <tag id="1" author="15498419@N05" authorname="stu72" raw="stu 72" machine_tag="0">stu72</tag>
6
+ <tag id="2" author="15498419@N05" authorname="stu72" raw="ellie" machine_tag="0">ellie</tag>
7
+ </tags>
8
+ </photo>
9
+ </rsp>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <who id="32719556@N00">
4
+ <tags>
5
+ <tag>08fo</tag>
6
+ <tag>101building</tag>
7
+ <tag>101cookbooks</tag>
8
+ </tags>
9
+ </who>
10
+ </rsp>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <tags source="family">
4
+ <tag>portrait</tag>
5
+ <tag>baby</tag>
6
+ <tag>child</tag>
7
+ </tags>
8
+ </rsp>
9
+
data/test/test_helper.rb CHANGED
@@ -92,13 +92,15 @@ class Test::Unit::TestCase
92
92
  end
93
93
 
94
94
  def self.should_find_all(thing, options)
95
- class_name = thing.to_s.singularize.camelcase
96
- klass = "Fleakr::Objects::#{class_name}".constantize
97
- object_type = class_name.downcase
95
+ class_name = thing.to_s.singularize.camelcase
96
+ klass = "Fleakr::Objects::#{class_name}".constantize
97
+ object_type = class_name.downcase
98
98
 
99
99
  it "should be able to find all #{thing} by #{options[:by]}" do
100
100
  condition_value = '1'
101
- response = mock_request_cycle :for => options[:call], :with => {options[:by] => condition_value}
101
+ finder_options = {(options[:using] || options[:by]) => condition_value}
102
+
103
+ response = mock_request_cycle :for => options[:call], :with => finder_options
102
104
 
103
105
  stubs = []
104
106
  elements = (response.body/options[:path]).map
@@ -0,0 +1,66 @@
1
+ require File.dirname(__FILE__) + '/../../../test_helper'
2
+
3
+ module Fleakr::Objects
4
+ class CommentTest < Test::Unit::TestCase
5
+
6
+ describe "The Comment class" do
7
+
8
+ should_find_all :comments, :by => :photo_id, :call => 'photos.comments.getList', :path => 'rsp/comments/comment'
9
+ should_find_all :comments, :by => :set_id, :using => :photoset_id, :call => 'photosets.comments.getList', :path => 'rsp/comments/comment'
10
+
11
+ end
12
+
13
+ describe "An instance of the Comment class" do
14
+
15
+ context "when populating from the photos_comments_getList XML data" do
16
+ before do
17
+ @object = Comment.new(Hpricot.XML(read_fixture('photos.comments.getList')).at('rsp/comments/comment'))
18
+ end
19
+
20
+ should_have_a_value_for :id => '1'
21
+ should_have_a_value_for :author_id => '10490170@N04'
22
+ should_have_a_value_for :created => '1239217523'
23
+ should_have_a_value_for :url => 'http://www.flickr.com/photos/frootpantz/3422268412/#comment72157616515348062'
24
+ should_have_a_value_for :body => 'comment one'
25
+
26
+ end
27
+
28
+ context "in general" do
29
+
30
+ before { @comment = Comment.new }
31
+
32
+ it "should have a value for :created_at" do
33
+ @comment.expects(:created).with().returns('1239217523')
34
+ Time.expects(:at).with(1239217523).returns('time')
35
+
36
+ @comment.created_at.should == 'time'
37
+ end
38
+
39
+ it "should use the body as the string representation" do
40
+ @comment.expects(:body).with().returns('bod')
41
+ @comment.to_s.should == 'bod'
42
+ end
43
+
44
+ it "should be able to find the author of the comment" do
45
+ author = stub()
46
+
47
+
48
+ @comment.stubs(:author_id).with().returns('1')
49
+ User.expects(:find_by_id).with('1').returns(author)
50
+
51
+ @comment.author.should == author
52
+ end
53
+
54
+ it "should memoize the owner information" do
55
+ @comment.stubs(:author_id).with().returns('1')
56
+
57
+ User.expects(:find_by_id).with('1').once.returns(stub())
58
+
59
+ 2.times { @comment.author }
60
+ end
61
+
62
+ end
63
+ end
64
+
65
+ end
66
+ end
@@ -23,9 +23,24 @@ module Fleakr::Objects
23
23
 
24
24
  should_have_a_value_for :id => '13378274@N00'
25
25
  should_have_a_value_for :name => 'Group #1'
26
+ should_have_a_value_for :adult_flag => '1'
26
27
 
27
28
  end
29
+
30
+ it "should know that the group is adult-only" do
31
+ group = Group.new
32
+ group.stubs(:adult_flag).with().returns('1')
33
+ group.adult?.should be(true)
34
+ end
35
+
36
+ it "should know that the group is not adult-only" do
37
+ group = Group.new
38
+ group.stubs(:adult_flag).with().returns('0')
39
+ group.adult?.should be(false)
40
+ end
41
+
28
42
  end
29
43
 
30
44
  end
31
- end
45
+ end
46
+
@@ -0,0 +1,80 @@
1
+ require File.dirname(__FILE__) + '/../../../test_helper'
2
+
3
+ module Fleakr::Objects
4
+ class PhotoContextTest < Test::Unit::TestCase
5
+
6
+ describe "An instance of the PhotoContext class" do
7
+
8
+ before { @context = PhotoContext.new }
9
+
10
+ context "when populating from the photos_getContext XML data" do
11
+ before do
12
+ @object = PhotoContext.new(Hpricot.XML(read_fixture('photos.getContext')))
13
+ end
14
+
15
+ should_have_a_value_for :count => '5584'
16
+ should_have_a_value_for :next_id => '12343'
17
+ should_have_a_value_for :previous_id => '12345'
18
+
19
+ end
20
+
21
+ it "should know that there is a previous photo" do
22
+ @context.expects(:previous_id).with().returns('1')
23
+ @context.previous?.should be(true)
24
+ end
25
+
26
+ it "should know that there isn't a previous photo" do
27
+ @context.expects(:previous_id).with().returns('0')
28
+ @context.previous?.should be(false)
29
+ end
30
+
31
+ it "should know that there is a next photo" do
32
+ @context.expects(:next_id).with().returns('1')
33
+ @context.next?.should be(true)
34
+ end
35
+
36
+ it "should know that there isn't a next photo" do
37
+ @context.expects(:next_id).with().returns('0')
38
+ @context.next?.should be(false)
39
+ end
40
+
41
+ it "should find the previous photo" do
42
+ photo = stub()
43
+
44
+ @context.expects(:previous_id).with().returns('1')
45
+ @context.expects(:previous?).with().returns(true)
46
+
47
+ Photo.expects(:find_by_id).with('1').returns(photo)
48
+
49
+ @context.previous.should == photo
50
+ end
51
+
52
+ it "should not try to find the previous photo if it doesn't exist" do
53
+ @context.expects(:previous?).with().returns(false)
54
+ Photo.expects(:find_by_id).never
55
+
56
+ @context.previous.should be(nil)
57
+ end
58
+
59
+ it "should find the next photo" do
60
+ photo = stub()
61
+ @context.expects(:next_id).with().returns('1')
62
+ @context.expects(:next?).with().returns(true)
63
+
64
+ Photo.expects(:find_by_id).with('1').returns(photo)
65
+
66
+ @context.next.should == photo
67
+ end
68
+
69
+ it "should not try to find the next photo if it doesn't exist" do
70
+ @context.expects(:next?).with().returns(false)
71
+ Photo.expects(:find_by_id).never
72
+
73
+ @context.next.should be(nil)
74
+ end
75
+
76
+
77
+ end
78
+
79
+ end
80
+ end
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/../../../test_helper'
3
3
  module Fleakr::Objects
4
4
  class PhotoTest < Test::Unit::TestCase
5
5
 
6
- should_have_many :images
6
+ should_have_many :images, :tags, :comments
7
7
 
8
8
  should_autoload_when_accessing :posted, :taken, :updated, :comment_count, :with => :load_info
9
9
  should_autoload_when_accessing :url, :description, :with => :load_info
@@ -11,7 +11,7 @@ module Fleakr::Objects
11
11
  describe "The Photo class" do
12
12
 
13
13
  should_find_all :photos, :by => :user_id, :call => 'people.getPublicPhotos', :path => 'rsp/photos/photo'
14
- should_find_all :photos, :by => :photoset_id, :call => 'photosets.getPhotos', :path => 'rsp/photoset/photo'
14
+ should_find_all :photos, :by => :set_id, :using => :photoset_id, :call => 'photosets.getPhotos', :path => 'rsp/photoset/photo'
15
15
  should_find_all :photos, :by => :group_id, :call => 'groups.pools.getPhotos', :path => 'rsp/photos/photo'
16
16
 
17
17
  should_find_one :photo, :by => :id, :with => :photo_id, :call => 'photos.getInfo'
@@ -74,6 +74,8 @@ module Fleakr::Objects
74
74
  should_have_a_value_for :farm_id => '4'
75
75
  should_have_a_value_for :server_id => '3250'
76
76
  should_have_a_value_for :secret => 'cbc1804258'
77
+ should_have_a_value_for :owner_id => '21775151@N06'
78
+
77
79
  end
78
80
 
79
81
  context "when populating from the photo upload XML data" do
@@ -95,6 +97,7 @@ module Fleakr::Objects
95
97
  should_have_a_value_for :description => 'A Tree'
96
98
  should_have_a_value_for :farm_id => '4'
97
99
  should_have_a_value_for :server_id => '3085'
100
+ should_have_a_value_for :owner_id => '31066442@N69'
98
101
  should_have_a_value_for :secret => 'secret'
99
102
  should_have_a_value_for :posted => '1230274722'
100
103
  should_have_a_value_for :taken => '2008-12-25 18:26:55'
@@ -166,10 +169,75 @@ module Fleakr::Objects
166
169
  end
167
170
  end
168
171
 
172
+ it "should be able to retrieve the context for this photo" do
173
+ id = '1'
174
+
175
+ context = stub()
176
+
177
+ photo = Photo.new
178
+ photo.stubs(:id).with().returns(id)
179
+
180
+ response = mock_request_cycle :for => 'photos.getContext', :with => {:photo_id => id}
181
+ PhotoContext.expects(:new).with(response.body).returns(context)
182
+
183
+ photo.context.should == context
184
+ end
185
+
186
+ it "should memoize the context data" do
187
+ id = '1'
188
+
189
+ context = stub()
190
+
191
+ photo = Photo.new
192
+ photo.stubs(:id).with().returns(id)
193
+
194
+ response = mock_request_cycle :for => 'photos.getContext', :with => {:photo_id => id}
195
+ PhotoContext.expects(:new).once.returns(context)
196
+
197
+ 2.times { photo.context }
198
+ end
199
+
200
+ it "should be able to retrieve the next photo" do
201
+ next_photo = stub()
202
+
203
+ photo = Photo.new
204
+ photo.expects(:context).with().returns(mock {|m| m.expects(:next).with().returns(next_photo)})
205
+
206
+ photo.next.should == next_photo
207
+ end
208
+
209
+ it "should be able to retrieve the previous photo" do
210
+ previous_photo = stub()
211
+
212
+ photo = Photo.new
213
+ photo.expects(:context).with().returns(mock {|m| m.expects(:previous).with().returns(previous_photo)})
214
+
215
+ photo.previous.should == previous_photo
216
+ end
217
+
218
+ it "should be able to find the owner of the photo" do
219
+ owner = stub()
220
+
221
+ photo = Photo.new
222
+ photo.stubs(:owner_id).with().returns('1')
223
+
224
+ User.expects(:find_by_id).with('1').returns(owner)
225
+
226
+ photo.owner.should == owner
227
+ end
228
+
229
+ it "should memoize the owner information" do
230
+ photo = Photo.new
231
+ photo.stubs(:owner_id).with().returns('1')
232
+
233
+ User.expects(:find_by_id).with('1').once.returns(stub())
234
+
235
+ 2.times { photo.owner }
236
+ end
169
237
 
170
238
  end
171
239
  end
172
240
 
173
241
  end
174
242
 
175
- end
243
+ end
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/../../../test_helper'
3
3
  module Fleakr::Objects
4
4
  class SetTest < Test::Unit::TestCase
5
5
 
6
- should_have_many :photos, :using => 'photoset_id'
6
+ should_have_many :photos, :comments
7
7
 
8
8
  describe "The Set class" do
9
9
 
@@ -0,0 +1,98 @@
1
+ require File.dirname(__FILE__) + '/../../../test_helper'
2
+
3
+ module Fleakr::Objects
4
+ class TagTest < Test::Unit::TestCase
5
+
6
+ describe "The Tag class" do
7
+
8
+ should_find_all :tags, :by => :photo_id, :call => 'tags.getListPhoto', :path => 'rsp/photo/tags/tag'
9
+ should_find_all :tags, :by => :user_id, :call => 'tags.getListUser', :path => 'rsp/who/tags/tag'
10
+ end
11
+
12
+ describe "An instance of the Tag class" do
13
+
14
+ before { @tag = Tag.new }
15
+
16
+ context "when populating from the tags_getListPhoto XML data" do
17
+ before do
18
+ @object = Tag.new(Hpricot.XML(read_fixture('tags.getListPhoto')).at('rsp/photo/tags/tag'))
19
+ end
20
+
21
+ should_have_a_value_for :id => '1'
22
+ should_have_a_value_for :author_id => '15498419@N05'
23
+ should_have_a_value_for :value => 'stu72'
24
+ should_have_a_value_for :raw => 'stu 72'
25
+ should_have_a_value_for :machine_flag => '0'
26
+
27
+ end
28
+
29
+ it "should have an author" do
30
+ user = stub()
31
+
32
+ @tag.expects(:author_id).at_least_once.with().returns('1')
33
+
34
+
35
+ User.expects(:find_by_id).with('1').returns(user)
36
+
37
+ @tag.author.should == user
38
+ end
39
+
40
+ it "should memoize the author data" do
41
+ @tag.expects(:author_id).at_least_once.with().returns('1')
42
+
43
+ User.expects(:find_by_id).with('1').once.returns(stub())
44
+
45
+ 2.times { @tag.author }
46
+ end
47
+
48
+ it "should return nil for author if author_id is not present" do
49
+ @tag.expects(:author_id).with().returns(nil)
50
+
51
+ @tag.author.should be(nil)
52
+ end
53
+
54
+ it "should have related tags" do
55
+ @tag.expects(:value).with().returns('foo')
56
+
57
+ response = mock_request_cycle :for => 'tags.getRelated', :with => {:tag => 'foo'}
58
+
59
+ stubs = []
60
+ elements = (response.body/'rsp/tags/tag').map
61
+
62
+ elements.each do |element|
63
+ stub = stub()
64
+ stubs << stub
65
+
66
+ Tag.expects(:new).with(element).returns(stub)
67
+ end
68
+
69
+ @tag.related.should == stubs
70
+ end
71
+
72
+ it "should memoize the data for related tags" do
73
+ @tag.expects(:value).with().returns('foo')
74
+
75
+ mock_request_cycle :for => 'tags.getRelated', :with => {:tag => 'foo'}
76
+
77
+ 2.times { @tag.related }
78
+ end
79
+
80
+ it "should be able to generate a string representation of itself" do
81
+ @tag.expects(:value).with().returns('foo')
82
+ @tag.to_s.should == 'foo'
83
+ end
84
+
85
+ it "should know that it is not a machine tag" do
86
+ @tag.expects(:machine_flag).with().returns('0')
87
+ @tag.machine?.should be(false)
88
+ end
89
+
90
+ it "should know that it is a machine tag" do
91
+ @tag.expects(:machine_flag).with().returns('1')
92
+ @tag.machine?.should be(true)
93
+ end
94
+
95
+ end
96
+
97
+ end
98
+ end
@@ -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
8
+ should_have_many :photos, :groups, :sets, :contacts, :tags
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
@@ -14,6 +14,7 @@ module Fleakr::Objects
14
14
 
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
+ should_find_one :user, :by => :id, :with => :user_id, :call => 'people.getInfo', :path => 'rsp/person'
17
18
 
18
19
  end
19
20
 
@@ -12,6 +12,7 @@ class FlickrObject
12
12
  flickr_attribute :description, :from => 'desc'
13
13
  flickr_attribute :id, :from => '@nsid'
14
14
  flickr_attribute :photoset_id, :from => 'photoset@id'
15
+ flickr_attribute :tag, :category
15
16
 
16
17
  find_one :by_id, :call => 'people.getInfo'
17
18
 
@@ -27,7 +28,7 @@ module Fleakr
27
28
  end
28
29
 
29
30
  it "should know the names of all its attributes" do
30
- FlickrObject.attributes.map {|a| a.name.to_s }.should == %w(name description id photoset_id)
31
+ FlickrObject.attributes.map {|a| a.name.to_s }.should == %w(name description id photoset_id tag category)
31
32
  end
32
33
 
33
34
  it "should be able to find by ID" do
@@ -56,7 +57,7 @@ module Fleakr
56
57
  describe "An instance method provided by the Flickr::Object module" do
57
58
 
58
59
  it "should have default reader methods" do
59
- [:name, :description, :id, :photoset_id].each do |method_name|
60
+ [:name, :description, :id, :photoset_id, :tag, :category].each do |method_name|
60
61
  FlickrObject.new.respond_to?(method_name).should == true
61
62
  end
62
63
  end
@@ -67,6 +68,8 @@ module Fleakr
67
68
  <name>Fleakr</name>
68
69
  <desc>Awesome</desc>
69
70
  <photoset id="1" />
71
+ <tag>Tag</tag>
72
+ <category>Category</category>
70
73
  XML
71
74
 
72
75
  @object = FlickrObject.new
@@ -91,6 +94,14 @@ module Fleakr
91
94
 
92
95
  @object.id.should == '1'
93
96
  end
97
+
98
+ it "should have the correct value for :tag" do
99
+ @object.tag.should == 'Tag'
100
+ end
101
+
102
+ it "should have the correct value for :category" do
103
+ @object.category.should == 'Category'
104
+ end
94
105
  end
95
106
 
96
107
  it "should populate its data from an XML document when initializing" do
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.4.2
4
+ version: 0.4.3
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-03-03 00:00:00 -05:00
12
+ date: 2009-04-11 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -71,13 +71,16 @@ files:
71
71
  - lib/fleakr/core_ext.rb
72
72
  - lib/fleakr/objects
73
73
  - lib/fleakr/objects/authentication_token.rb
74
+ - lib/fleakr/objects/comment.rb
74
75
  - lib/fleakr/objects/contact.rb
75
76
  - lib/fleakr/objects/error.rb
76
77
  - lib/fleakr/objects/group.rb
77
78
  - lib/fleakr/objects/image.rb
78
79
  - lib/fleakr/objects/photo.rb
80
+ - lib/fleakr/objects/photo_context.rb
79
81
  - lib/fleakr/objects/search.rb
80
82
  - lib/fleakr/objects/set.rb
83
+ - lib/fleakr/objects/tag.rb
81
84
  - lib/fleakr/objects/user.rb
82
85
  - lib/fleakr/objects.rb
83
86
  - lib/fleakr/support
@@ -97,11 +100,17 @@ files:
97
100
  - test/fixtures/people.getInfo.xml
98
101
  - test/fixtures/people.getPublicGroups.xml
99
102
  - test/fixtures/people.getPublicPhotos.xml
103
+ - test/fixtures/photos.comments.getList.xml
104
+ - test/fixtures/photos.getContext.xml
100
105
  - test/fixtures/photos.getInfo.xml
101
106
  - test/fixtures/photos.getSizes.xml
102
107
  - test/fixtures/photos.search.xml
108
+ - test/fixtures/photosets.comments.getList.xml
103
109
  - test/fixtures/photosets.getList.xml
104
110
  - test/fixtures/photosets.getPhotos.xml
111
+ - test/fixtures/tags.getListPhoto.xml
112
+ - test/fixtures/tags.getListUser.xml
113
+ - test/fixtures/tags.getRelated.xml
105
114
  - test/test_helper.rb
106
115
  - test/unit
107
116
  - test/unit/fleakr
@@ -120,13 +129,16 @@ files:
120
129
  - test/unit/fleakr/core_ext/true_class_test.rb
121
130
  - test/unit/fleakr/objects
122
131
  - test/unit/fleakr/objects/authentication_token_test.rb
132
+ - test/unit/fleakr/objects/comment_test.rb
123
133
  - test/unit/fleakr/objects/contact_test.rb
124
134
  - test/unit/fleakr/objects/error_test.rb
125
135
  - test/unit/fleakr/objects/group_test.rb
126
136
  - test/unit/fleakr/objects/image_test.rb
137
+ - test/unit/fleakr/objects/photo_context_test.rb
127
138
  - test/unit/fleakr/objects/photo_test.rb
128
139
  - test/unit/fleakr/objects/search_test.rb
129
140
  - test/unit/fleakr/objects/set_test.rb
141
+ - test/unit/fleakr/objects/tag_test.rb
130
142
  - test/unit/fleakr/objects/user_test.rb
131
143
  - test/unit/fleakr/support
132
144
  - test/unit/fleakr/support/attribute_test.rb