reagent-fleakr 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. data/README.rdoc +115 -20
  2. data/Rakefile +1 -1
  3. data/lib/fleakr.rb +66 -7
  4. data/lib/fleakr/api.rb +7 -0
  5. data/lib/fleakr/api/file_parameter.rb +47 -0
  6. data/lib/fleakr/api/method_request.rb +57 -0
  7. data/lib/fleakr/api/parameter.rb +35 -0
  8. data/lib/fleakr/api/parameter_list.rb +96 -0
  9. data/lib/fleakr/api/response.rb +2 -2
  10. data/lib/fleakr/api/upload_request.rb +64 -0
  11. data/lib/fleakr/api/value_parameter.rb +36 -0
  12. data/lib/fleakr/core_ext.rb +1 -0
  13. data/lib/fleakr/core_ext/hash.rb +22 -0
  14. data/lib/fleakr/objects.rb +9 -0
  15. data/lib/fleakr/objects/authentication_token.rb +43 -0
  16. data/lib/fleakr/objects/contact.rb +5 -5
  17. data/lib/fleakr/objects/error.rb +2 -2
  18. data/lib/fleakr/objects/group.rb +2 -2
  19. data/lib/fleakr/objects/image.rb +7 -7
  20. data/lib/fleakr/objects/photo.rb +69 -5
  21. data/lib/fleakr/objects/search.rb +3 -6
  22. data/lib/fleakr/objects/set.rb +11 -5
  23. data/lib/fleakr/objects/user.rb +14 -26
  24. data/lib/fleakr/support.rb +2 -0
  25. data/lib/fleakr/support/attribute.rb +30 -12
  26. data/lib/fleakr/support/object.rb +20 -4
  27. data/lib/fleakr/version.rb +1 -1
  28. data/test/fixtures/auth.checkToken.xml +8 -0
  29. data/test/fixtures/auth.getFullToken.xml +8 -0
  30. data/test/fixtures/people.getInfo.xml +1 -1
  31. data/test/fixtures/photos.getInfo.xml +20 -0
  32. data/test/test_helper.rb +18 -3
  33. data/test/unit/fleakr/api/file_parameter_test.rb +63 -0
  34. data/test/unit/fleakr/api/method_request_test.rb +103 -0
  35. data/test/unit/fleakr/api/parameter_list_test.rb +161 -0
  36. data/test/unit/fleakr/api/parameter_test.rb +34 -0
  37. data/test/unit/fleakr/api/upload_request_test.rb +133 -0
  38. data/test/unit/fleakr/api/value_parameter_test.rb +41 -0
  39. data/test/unit/fleakr/core_ext/hash_test.rb +32 -0
  40. data/test/unit/fleakr/objects/authentication_token_test.rb +47 -0
  41. data/test/unit/fleakr/objects/image_test.rb +10 -5
  42. data/test/unit/fleakr/objects/photo_test.rb +96 -36
  43. data/test/unit/fleakr/objects/search_test.rb +1 -1
  44. data/test/unit/fleakr/objects/set_test.rb +12 -1
  45. data/test/unit/fleakr/objects/user_test.rb +2 -16
  46. data/test/unit/fleakr/support/attribute_test.rb +82 -24
  47. data/test/unit/fleakr/support/object_test.rb +26 -3
  48. data/test/unit/fleakr_test.rb +65 -6
  49. metadata +27 -4
  50. data/lib/fleakr/api/request.rb +0 -58
  51. data/test/unit/fleakr/api/request_test.rb +0 -93
@@ -45,6 +45,9 @@ module Fleakr::Objects
45
45
  @image = Image.new
46
46
  @image.stubs(:url).with().returns(@url)
47
47
  @image.stubs(:filename).with().returns(@image_filename)
48
+
49
+ @image_data = 'image_data'
50
+ Net::HTTP.expects(:get).with(URI.parse(@url)).returns(@image_data)
48
51
  end
49
52
 
50
53
  after do
@@ -52,20 +55,22 @@ module Fleakr::Objects
52
55
  end
53
56
 
54
57
  should "be able to save to a directory with the original filename" do
55
- Net::HTTP.expects(:get).with(URI.parse(@url)).returns('image_data')
56
-
57
58
  @image.save_to(@tmp_dir)
58
- File.read("#{@tmp_dir}/image.jpg").should == 'image_data'
59
+ File.read("#{@tmp_dir}/image.jpg").should == @image_data
59
60
  end
60
61
 
61
62
  should "be able to save to a specified file" do
62
- Net::HTTP.expects(:get).with(URI.parse(@url)).returns('image_data')
63
63
  existing_file = "#{@tmp_dir}/existing_file.jpg"
64
64
 
65
65
  FileUtils.touch(existing_file)
66
66
 
67
67
  @image.save_to(existing_file)
68
- File.read(existing_file).should == 'image_data'
68
+ File.read(existing_file).should == @image_data
69
+ end
70
+
71
+ should "be able to save the file using a specified prefix" do
72
+ @image.save_to(@tmp_dir, '001_')
73
+ File.read("#{@tmp_dir}/001_image.jpg").should == @image_data
69
74
  end
70
75
 
71
76
  end
@@ -5,16 +5,52 @@ module Fleakr::Objects
5
5
 
6
6
  should_have_many :images
7
7
 
8
+ should_autoload_when_accessing :posted, :taken, :updated, :comment_count, :with => :load_info
9
+ should_autoload_when_accessing :url, :description, :with => :load_info
10
+
8
11
  describe "The Photo class" do
9
12
 
10
13
  should_find_all :photos, :by => :user_id, :call => 'people.getPublicPhotos', :path => 'rsp/photos/photo'
11
14
  should_find_all :photos, :by => :photoset_id, :call => 'photosets.getPhotos', :path => 'rsp/photoset/photo'
12
15
  should_find_all :photos, :by => :group_id, :call => 'groups.pools.getPhotos', :path => 'rsp/photos/photo'
16
+
17
+ should_find_one :photo, :by => :id, :with => :photo_id, :call => 'photos.getInfo'
18
+
19
+
20
+ it "should be able to upload a photo and return the new photo information" do
21
+ filename = '/path/to/mugshot.jpg'
22
+ photo = stub()
23
+
24
+ response = stub do |s|
25
+ s.stubs(:body).with().returns(Hpricot.XML('<photoid>123</photoid>'))
26
+ end
27
+
28
+ Fleakr::Api::UploadRequest.expects(:with_response!).with(filename).returns(response)
29
+ Photo.expects(:find_by_id).with('123', :authenticate? => true).returns(photo)
30
+
31
+ Photo.upload(filename).should == photo
32
+ end
13
33
 
14
34
  end
15
35
 
16
36
  describe "An instance of the Photo class" do
17
- context "when populating from an XML document" do
37
+
38
+ it "should be able to replace the associated photo data" do
39
+ filename = '/path/to/file.jpg'
40
+ response = stub(:body => 'body')
41
+
42
+ params = {:type => :update, :photo_id => '1'}
43
+
44
+ Fleakr::Api::UploadRequest.expects(:with_response!).with(filename, params).returns(response)
45
+
46
+ photo = Photo.new
47
+ photo.stubs(:id).returns('1')
48
+ photo.expects(:populate_from).with('body')
49
+
50
+ photo.replace_with(filename).should == photo
51
+ end
52
+
53
+ context "when populating from the people_getPublicPhotos XML data" do
18
54
  before do
19
55
  @object = Photo.new(Hpricot.XML(read_fixture('people.getPublicPhotos')).at('rsp/photos/photo'))
20
56
  end
@@ -24,11 +60,69 @@ module Fleakr::Objects
24
60
  should_have_a_value_for :farm_id => '4'
25
61
  should_have_a_value_for :server_id => '3250'
26
62
  should_have_a_value_for :secret => 'cbc1804258'
27
-
63
+ end
64
+
65
+ context "when populating from the photo upload XML data" do
66
+ before do
67
+ @object = Photo.new(Hpricot.XML('<photoid>123</photoid>'))
68
+ end
69
+
70
+ should_have_a_value_for :id => '123'
71
+ end
72
+
73
+ context "when populating from the photos_getInfo XML data" do
74
+ before do
75
+ @object = Photo.new(Hpricot.XML(read_fixture('photos.getInfo')))
76
+
77
+ end
78
+
79
+ should_have_a_value_for :id => '1'
80
+ should_have_a_value_for :title => 'Tree'
81
+ should_have_a_value_for :description => 'A Tree'
82
+ should_have_a_value_for :farm_id => '4'
83
+ should_have_a_value_for :server_id => '3085'
84
+ should_have_a_value_for :secret => 'secret'
85
+ should_have_a_value_for :posted => '1230274722'
86
+ should_have_a_value_for :taken => '2008-12-25 18:26:55'
87
+ should_have_a_value_for :updated => '1230276652'
88
+ should_have_a_value_for :comment_count => '0'
89
+ should_have_a_value_for :url => 'http://www.flickr.com/photos/yes/1'
90
+
28
91
  end
29
92
 
30
93
  context "in general" do
31
94
 
95
+ before do
96
+ @photo = Photo.new
97
+ @time = Time.parse('2009-08-01 00:00:00')
98
+ end
99
+
100
+ it "should be able to retrieve additional information about the current user" do
101
+ photo_id = '1'
102
+ photo = Photo.new
103
+ photo.expects(:id).with().returns(photo_id)
104
+ response = mock_request_cycle :for => 'photos.getInfo', :with => {:photo_id => photo_id}
105
+
106
+ photo.expects(:populate_from).with(response.body)
107
+
108
+ photo.load_info
109
+ end
110
+
111
+ it "should have a value for :posted_at" do
112
+ @photo.expects(:posted).with().returns("#{@time.to_i}")
113
+ @photo.posted_at.should == @time
114
+ end
115
+
116
+ it "should have a value for :taken_at" do
117
+ @photo.expects(:taken).with().returns(@time.strftime('%Y-%m-%d %H:%M:%S'))
118
+ @photo.taken_at.should == @time
119
+ end
120
+
121
+ it "should have a value for :updated_at" do
122
+ @photo.expects(:updated).with().returns("#{@time.to_i}")
123
+ @photo.updated_at.should == @time
124
+ end
125
+
32
126
  it "should have a collection of images by size" do
33
127
  photo = Photo.new
34
128
 
@@ -62,40 +156,6 @@ module Fleakr::Objects
62
156
  end
63
157
  end
64
158
 
65
- # context "in general" do
66
- #
67
- # before do
68
- # @photo = Photo.new
69
- #
70
- # @photo.stubs(:id).with().returns('1')
71
- # @photo.stubs(:farm_id).with().returns('2')
72
- # @photo.stubs(:server_id).with().returns('3')
73
- # @photo.stubs(:secret).with().returns('secret')
74
- # end
75
- #
76
- # it "should know the base URL to retrieve images" do
77
- # @photo.send(:base_url).should == "http://farm2.static.flickr.com/3/1_secret"
78
- # end
79
- #
80
- # end
81
-
82
- # context "with a base URL" do
83
- #
84
- # before do
85
- # @photo = Photo.new
86
- # @photo.stubs(:base_url).with().returns('url')
87
- # end
88
- #
89
- # [:square, :thumbnail, :small, :medium, :large].each do |size|
90
- # it "should have a :#{size} image" do
91
- # image = stub()
92
- # Image.expects(:new).with('url', size).returns(image)
93
- #
94
- # @photo.send(size).should == image
95
- # end
96
- # end
97
- #
98
- # end
99
159
  end
100
160
 
101
161
  end
@@ -56,7 +56,7 @@ module Fleakr::Objects
56
56
 
57
57
  should "memoize the search results" do
58
58
  response = stub(:body => Hpricot.XML(read_fixture('photos.search')))
59
- Fleakr::Api::Request.expects(:with_response!).with(kind_of(String), kind_of(Hash)).once.returns(response)
59
+ Fleakr::Api::MethodRequest.expects(:with_response!).with(kind_of(String), kind_of(Hash)).once.returns(response)
60
60
 
61
61
  (response.body/'rsp/photos/photo').each do |doc|
62
62
  Photo.expects(:new).with(doc).once
@@ -21,6 +21,7 @@ module Fleakr::Objects
21
21
  should_have_a_value_for :id => '72157609490909659'
22
22
  should_have_a_value_for :title => 'Second Set'
23
23
  should_have_a_value_for :description => 'This is the second set.'
24
+ should_have_a_value_for :count => '138'
24
25
 
25
26
  end
26
27
 
@@ -34,14 +35,24 @@ module Fleakr::Objects
34
35
  end
35
36
 
36
37
  after { FileUtils.rm_rf(@tmp_dir) }
38
+
39
+ it "should know the prefix string based on the number of photos in the set" do
40
+ set = Set.new
41
+ set.stubs(:count).with().returns('5')
42
+ set.file_prefix(0).should == '1_'
43
+
44
+ set.stubs(:count).with().returns('99')
45
+ set.file_prefix(0).should == '01_'
46
+ end
37
47
 
38
48
  it "should save all files of the specified size to the specified directory" do
39
49
  image = mock()
40
- image.expects(:save_to).with("#{@tmp_dir}/set")
50
+ image.expects(:save_to).with("#{@tmp_dir}/set", '1_')
41
51
 
42
52
  photo = stub(:small => image)
43
53
 
44
54
  @set.stubs(:photos).with().returns([photo])
55
+ @set.stubs(:file_prefix).with(0).returns('1_')
45
56
 
46
57
  FileUtils.expects(:mkdir).with("#{@tmp_dir}/set")
47
58
 
@@ -3,22 +3,11 @@ require File.dirname(__FILE__) + '/../../../test_helper'
3
3
  module Fleakr::Objects
4
4
  class UserTest < Test::Unit::TestCase
5
5
 
6
- def self.should_autoload_when_accessing(*attributes)
7
- options = attributes.extract_options!
8
- attributes.each do |accessor_name|
9
- it "should load the additional user information when accessing the :#{accessor_name} attribute" do
10
- user = User.new
11
- user.expects(options[:with]).with()
12
- user.send(accessor_name)
13
- end
14
- end
15
- end
16
-
17
6
  should_search_by :user_id
18
7
 
19
8
  should_have_many :photos, :groups, :sets, :contacts
20
9
 
21
- should_autoload_when_accessing :name, :photos_url, :profile_url, :photos_count, :with => :load_info
10
+ should_autoload_when_accessing :name, :photos_url, :profile_url, :photos_count, :location, :with => :load_info
22
11
  should_autoload_when_accessing :icon_server, :icon_farm, :pro, :admin, :icon_url, :with => :load_info
23
12
 
24
13
  describe "The User class" do
@@ -38,6 +27,7 @@ module Fleakr::Objects
38
27
  should_have_a_value_for :id => '31066442@N69'
39
28
  should_have_a_value_for :username => 'frootpantz'
40
29
  should_have_a_value_for :name => 'Sir Froot Pantz'
30
+ should_have_a_value_for :location => 'The Moon'
41
31
  should_have_a_value_for :photos_url => 'http://www.flickr.com/photos/frootpantz/'
42
32
  should_have_a_value_for :profile_url => 'http://www.flickr.com/people/frootpantz/'
43
33
  should_have_a_value_for :photos_count => '3907'
@@ -93,10 +83,6 @@ module Fleakr::Objects
93
83
  @user.admin?.should be(true)
94
84
  end
95
85
 
96
-
97
-
98
-
99
-
100
86
  end
101
87
  end
102
88
 
@@ -9,60 +9,118 @@ module Fleakr::Support
9
9
  attr.name.should == :foo
10
10
  end
11
11
 
12
- it "should infer the xpath information from the attribute name" do
13
- attr = Attribute.new('foo')
14
- attr.xpath.should == 'foo'
12
+ it "should have a default source" do
13
+ attr = Attribute.new(:foo)
14
+ attr.sources.should == ['foo']
15
15
  end
16
16
 
17
- it "should use a string value for the xpath from the inferred attribute name" do
18
- attr = Attribute.new(:foo)
19
- attr.xpath.should == 'foo'
17
+ it "should be able to assign multiple sources" do
18
+ attr = Attribute.new(:foo, ['foo1', 'foo2'])
19
+ attr.sources.should == ['foo1', 'foo2']
20
+ end
21
+
22
+ it "should pull the location from the source" do
23
+ attr = Attribute.new('foo')
24
+ attr.location('foo').should == 'foo'
20
25
  end
21
26
 
22
- it "should allow the setting of the xpath information" do
23
- attr = Attribute.new('foo', :xpath => 'bar')
24
- attr.xpath.should == 'bar'
27
+ it "should return the location when splitting" do
28
+ attr = Attribute.new('foo')
29
+ attr.split('foo').should == ['foo', nil]
25
30
  end
26
31
 
27
- it "should have a default attribute value of nil" do
32
+ it "should return the name for the location when splitting if the location isn't specified" do
28
33
  attr = Attribute.new('foo')
29
- attr.attribute.should be(nil)
34
+ attr.split('@bar').should == ['foo', 'bar']
35
+ end
36
+
37
+ it "should allow the setting of the location information" do
38
+ attr = Attribute.new('foo', 'bar')
39
+ attr.sources.should == ['bar']
30
40
  end
31
41
 
32
42
  it "should allow the setting of the attribute value" do
33
- attr = Attribute.new('foo', :attribute => 'bogon')
34
- attr.attribute.should == 'bogon'
43
+ attr = Attribute.new('foo')
44
+ attr.attribute('@bogon').should == 'bogon'
45
+ end
46
+
47
+ it "should use the location as the attribute" do
48
+ attr = Attribute.new('foo')
49
+ attr.attribute('foo').should == 'foo'
35
50
  end
36
51
 
37
- it "should not infer the xpath value when the attribute is set" do
38
- attr = Attribute.new(:foo, :attribute => 'bogon')
39
- attr.xpath.should be(nil)
52
+ it "should use the attribute for the attribute if specified" do
53
+ attr = Attribute.new(:id, '@nsid')
54
+ attr.attribute('@nsid').should == 'nsid'
55
+ end
56
+
57
+ it "should be able to retrieve the node from the path" do
58
+ document = Hpricot.XML('<name>Bassdrive</name>')
59
+ expected = document.at('name')
60
+
61
+ attr = Attribute.new(:name)
62
+ attr.node_for(document, 'name').should == expected
63
+ end
64
+
65
+ it "should be able to retrieve the node that contains the specified attribute" do
66
+ document = Hpricot.XML('<user id="1337" />')
67
+ expected = document.at('user')
68
+
69
+ attr = Attribute.new(:id)
70
+ attr.node_for(document, '@id').should == expected
71
+ end
72
+
73
+ it "should be able to retrieve the node for the specified attribute" do
74
+ document = Hpricot.XML('<user nsid="1337" />')
75
+ expected = document.at('user')
76
+
77
+ attr = Attribute.new(:id, '@nsid')
78
+ attr.node_for(document, '@nsid').should == expected
40
79
  end
41
80
 
42
81
  it "should be able to pull simple values from an XML document" do
43
82
  document = Hpricot.XML('<name>Bassdrive</name>')
44
- attr = Attribute.new('name')
83
+ attr = Attribute.new(:name)
45
84
  attr.value_from(document).should == 'Bassdrive'
46
85
  end
47
-
86
+
48
87
  it "should be able to pull an attribute value from the current XML node" do
49
- document = Hpricot.XML('<user id="1337" />').at('user')
50
- attr = Attribute.new(:id, :attribute => 'id')
88
+ document = Hpricot.XML('<user id="1337" />')
89
+ attr = Attribute.new(:id)
51
90
  attr.value_from(document).should == '1337'
52
91
  end
53
-
92
+
93
+ it "should be able to pull a specific attribute value from the current XML node" do
94
+ document = Hpricot.XML('<user nsid="1337" />')
95
+ attr = Attribute.new(:id, '@nsid')
96
+ attr.value_from(document).should == '1337'
97
+ end
98
+
54
99
  it "should be able to pull an attribute value for a node and attribute" do
55
100
  document = Hpricot.XML('<station><genre slug="dnb">Drum & Bass</genre></station>')
56
- attr = Attribute.new(:slug, :xpath => 'station/genre', :attribute => 'slug')
101
+ attr = Attribute.new(:slug, 'station/genre@slug')
57
102
  attr.value_from(document).should == 'dnb'
58
103
  end
59
-
104
+
105
+ it "should be able to pull a value from a nested XML node" do
106
+ document = Hpricot.XML('<rsp><user>blip</user></rsp>')
107
+ attr = Attribute.new(:user)
108
+ attr.value_from(document).should == 'blip'
109
+ end
110
+
60
111
  it "should return nil if it cannot find the specified node" do
61
112
  document = Hpricot.XML('<user id="1" />')
62
- attr = Attribute.new(:photoset, :attribute => 'id')
113
+ attr = Attribute.new(:photoset, '@nsid')
63
114
  attr.value_from(document).should be(nil)
64
115
  end
65
116
 
117
+ it "should be able to try a series of nodes to find a value" do
118
+ document = Hpricot.XML('<photoid>123</photoid>')
119
+
120
+ attr = Attribute.new(:id, ['photo@nsid', 'photoid'])
121
+ attr.value_from(document).should == '123'
122
+ end
123
+
66
124
  end
67
125
  end
68
126
  end
@@ -9,9 +9,11 @@ class FlickrObject
9
9
  include Fleakr::Support::Object
10
10
 
11
11
  flickr_attribute :name
12
- flickr_attribute :description, :xpath => 'desc'
13
- flickr_attribute :id, :attribute => 'nsid'
14
- flickr_attribute :photoset_id, :xpath => 'photoset', :attribute => 'id'
12
+ flickr_attribute :description, :from => 'desc'
13
+ flickr_attribute :id, :from => '@nsid'
14
+ flickr_attribute :photoset_id, :from => 'photoset@id'
15
+
16
+ find_one :by_id, :call => 'people.getInfo'
15
17
 
16
18
  end
17
19
 
@@ -28,6 +30,27 @@ module Fleakr
28
30
  FlickrObject.attributes.map {|a| a.name.to_s }.should == %w(name description id photoset_id)
29
31
  end
30
32
 
33
+ it "should be able to find by ID" do
34
+ id = 1
35
+ flickr_object = stub()
36
+
37
+ response = mock_request_cycle :for => 'people.getInfo', :with => {:id => id}
38
+ FlickrObject.expects(:new).with(response.body).returns(flickr_object)
39
+
40
+ FlickrObject.find_by_id(id).should == flickr_object
41
+ end
42
+
43
+ it "should be able to pass parameters to the :find_by_id method" do
44
+ id = 1
45
+ params = {:authenticate? => true}
46
+ flickr_object = stub()
47
+
48
+ response = mock_request_cycle :for => 'people.getInfo', :with => {:id => id, :authenticate? => true}
49
+ FlickrObject.expects(:new).with(response.body).returns(flickr_object)
50
+
51
+ FlickrObject.find_by_id(id, params).should == flickr_object
52
+ end
53
+
31
54
  end
32
55
 
33
56
  describe "An instance method provided by the Flickr::Object module" do