reagent-fleakr 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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