fleakr 0.4.1 → 0.4.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.
- data/README.rdoc +32 -5
- data/Rakefile +1 -1
- data/lib/fleakr.rb +34 -6
- data/lib/fleakr/api.rb +1 -0
- data/lib/fleakr/api/method_request.rb +9 -4
- data/lib/fleakr/api/option.rb +175 -0
- data/lib/fleakr/api/parameter_list.rb +7 -6
- data/lib/fleakr/api/upload_request.rb +17 -11
- data/lib/fleakr/core_ext.rb +3 -1
- data/lib/fleakr/core_ext/false_class.rb +7 -0
- data/lib/fleakr/core_ext/true_class.rb +7 -0
- data/lib/fleakr/objects/authentication_token.rb +25 -8
- data/lib/fleakr/objects/photo.rb +21 -6
- data/lib/fleakr/support/object.rb +4 -2
- data/lib/fleakr/version.rb +1 -1
- data/test/fixtures/auth.getToken.xml +8 -0
- data/test/unit/fleakr/api/method_request_test.rb +0 -10
- data/test/unit/fleakr/api/option_test.rb +179 -0
- data/test/unit/fleakr/api/parameter_list_test.rb +33 -18
- data/test/unit/fleakr/api/upload_request_test.rb +21 -9
- data/test/unit/fleakr/core_ext/false_class_test.rb +13 -0
- data/test/unit/fleakr/core_ext/true_class_test.rb +13 -0
- data/test/unit/fleakr/objects/authentication_token_test.rb +16 -2
- data/test/unit/fleakr/objects/photo_test.rb +22 -8
- data/test/unit/fleakr_test.rb +72 -4
- metadata +10 -3
data/lib/fleakr/core_ext.rb
CHANGED
@@ -17,22 +17,39 @@ module Fleakr
|
|
17
17
|
|
18
18
|
flickr_attribute :value, :from => 'auth/token'
|
19
19
|
flickr_attribute :permissions, :from => 'auth/perms'
|
20
|
+
flickr_attribute :user_id, :from => 'auth/user@nsid'
|
21
|
+
flickr_attribute :user_name, :from => 'auth/user@username'
|
22
|
+
flickr_attribute :full_name, :from => 'auth/user@fullname'
|
20
23
|
|
21
24
|
# Retrieve a full authentication token from the supplied mini-token (e.g. 123-456-789)
|
22
25
|
#
|
23
|
-
def self.from_mini_token(
|
24
|
-
|
25
|
-
response = Fleakr::Api::MethodRequest.with_response!('auth.getFullToken', parameters)
|
26
|
-
|
27
|
-
self.new(response.body)
|
26
|
+
def self.from_mini_token(mini_token)
|
27
|
+
from :mini_token, mini_token
|
28
28
|
end
|
29
29
|
|
30
30
|
# Retrieve a full authentication token from the supplied auth_token string
|
31
31
|
# (e.g. 45-76598454353455)
|
32
32
|
#
|
33
|
-
def self.from_auth_token(
|
34
|
-
|
35
|
-
|
33
|
+
def self.from_auth_token(auth_token)
|
34
|
+
from :auth_token, auth_token
|
35
|
+
end
|
36
|
+
|
37
|
+
# Retrieve a full authentication token from the supplied frob
|
38
|
+
def self.from_frob(frob)
|
39
|
+
from :frob, frob
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.from(thing, value) # :nodoc:
|
43
|
+
api_methods = {
|
44
|
+
:mini_token => 'getFullToken',
|
45
|
+
:auth_token => 'checkToken',
|
46
|
+
:frob => 'getToken'
|
47
|
+
}
|
48
|
+
|
49
|
+
method = "auth.#{api_methods[thing]}"
|
50
|
+
|
51
|
+
parameters = {thing => value, :authenticate? => false}
|
52
|
+
response = Fleakr::Api::MethodRequest.with_response!(method, parameters)
|
36
53
|
|
37
54
|
self.new(response.body)
|
38
55
|
end
|
data/lib/fleakr/objects/photo.rb
CHANGED
@@ -3,6 +3,9 @@ module Fleakr
|
|
3
3
|
|
4
4
|
# = Photo
|
5
5
|
#
|
6
|
+
# Handles both the retrieval of Photo objects from various associations (e.g. User / Set) as
|
7
|
+
# well as the ability to upload images to the Flickr site.
|
8
|
+
#
|
6
9
|
# == Attributes
|
7
10
|
#
|
8
11
|
# [id] The ID for this photo
|
@@ -59,20 +62,32 @@ module Fleakr
|
|
59
62
|
|
60
63
|
has_many :images
|
61
64
|
|
62
|
-
# Upload the photo specified by <tt>filename</tt> to the user's Flickr account.
|
63
|
-
#
|
65
|
+
# Upload the photo specified by <tt>filename</tt> to the user's Flickr account. When uploading,
|
66
|
+
# there are several options available (none are required):
|
67
|
+
#
|
68
|
+
# [:title] The title for this photo. Any string is allowed.
|
69
|
+
# [:description] The description for this photo. Any string is allowed.
|
70
|
+
# [:tags] A collection of tags for this photo. This can be a string or array of strings.
|
71
|
+
# [:viewable_by] Who can view this photo? Acceptable values are one of <tt>:everyone</tt>,
|
72
|
+
# <tt>:friends</tt> or <tt>:family</tt>. This can also take an array of values
|
73
|
+
# (e.g. <tt>[:friends, :family]</tt>) to make it viewable by friends and family.
|
74
|
+
# [:level] The safety level of this photo. Acceptable values are one of <tt>:safe</tt>,
|
75
|
+
# <tt>:moderate</tt>, or <tt>:restricted</tt>.
|
76
|
+
# [:type] The type of image this is. Acceptable values are one of <tt>:photo</tt>,
|
77
|
+
# <tt>:screenshot</tt>, or <tt>:other</tt>.
|
78
|
+
# [:hide?] Should this photo be hidden from public searches? Takes a boolean.
|
64
79
|
#
|
65
|
-
def self.upload(filename)
|
66
|
-
response = Fleakr::Api::UploadRequest.with_response!(filename)
|
80
|
+
def self.upload(filename, options = {})
|
81
|
+
response = Fleakr::Api::UploadRequest.with_response!(filename, :create, options)
|
67
82
|
photo = Photo.new(response.body)
|
68
|
-
Photo.find_by_id(photo.id
|
83
|
+
Photo.find_by_id(photo.id)
|
69
84
|
end
|
70
85
|
|
71
86
|
# Replace the current photo's image with the one specified by filename. This
|
72
87
|
# call requires authentication.
|
73
88
|
#
|
74
89
|
def replace_with(filename)
|
75
|
-
response = Fleakr::Api::UploadRequest.with_response!(filename, :photo_id => self.id
|
90
|
+
response = Fleakr::Api::UploadRequest.with_response!(filename, :update, :photo_id => self.id)
|
76
91
|
self.populate_from(response.body)
|
77
92
|
self
|
78
93
|
end
|
@@ -33,8 +33,10 @@ module Fleakr
|
|
33
33
|
target_class = options[:class_name].nil? ? self.name : "Fleakr::Objects::#{options[:class_name]}"
|
34
34
|
|
35
35
|
class_eval <<-CODE
|
36
|
-
def self.find_all_#{condition}(value)
|
37
|
-
|
36
|
+
def self.find_all_#{condition}(value, options = {})
|
37
|
+
options.merge!(:#{attribute} => value)
|
38
|
+
|
39
|
+
response = Fleakr::Api::MethodRequest.with_response!('#{options[:call]}', options)
|
38
40
|
(response.body/'rsp/#{options[:path]}').map {|e| #{target_class}.new(e) }
|
39
41
|
end
|
40
42
|
CODE
|
data/lib/fleakr/version.rb
CHANGED
@@ -26,16 +26,6 @@ module Fleakr::Api
|
|
26
26
|
request.parameters[:method].value.should == 'flickr.people.findByUsername'
|
27
27
|
end
|
28
28
|
|
29
|
-
it "should know that it needs to sign the request" do
|
30
|
-
ParameterList.expects(:new).with(:sign? => true).returns(stub(:<< => nil))
|
31
|
-
request = MethodRequest.new('people.findByUsername', :sign? => true)
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should know that it needs to authenticate the request" do
|
35
|
-
ParameterList.expects(:new).with(:authenticate? => true).returns(stub(:<< => nil))
|
36
|
-
request = MethodRequest.new('activity.userPhotos', :authenticate? => true)
|
37
|
-
end
|
38
|
-
|
39
29
|
it "should know the endpoint with full parameters" do
|
40
30
|
query_parameters = 'foo=bar'
|
41
31
|
|
@@ -0,0 +1,179 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
+
|
3
|
+
module Fleakr::Api
|
4
|
+
|
5
|
+
class OptionTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def self.should_know_the_class_for(type, options)
|
8
|
+
it "should know the class for the :#{type} type" do
|
9
|
+
Option.class_for(type).should == options[:is]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "The Option class" do
|
14
|
+
should_know_the_class_for :title, :is => Fleakr::Api::SimpleOption
|
15
|
+
should_know_the_class_for :description, :is => Fleakr::Api::SimpleOption
|
16
|
+
should_know_the_class_for :tags, :is => Fleakr::Api::TagOption
|
17
|
+
should_know_the_class_for :viewable_by, :is => Fleakr::Api::ViewOption
|
18
|
+
should_know_the_class_for :level, :is => Fleakr::Api::LevelOption
|
19
|
+
should_know_the_class_for :type, :is => Fleakr::Api::TypeOption
|
20
|
+
should_know_the_class_for :hide?, :is => Fleakr::Api::HiddenOption
|
21
|
+
|
22
|
+
it "should be able to create an option for a type" do
|
23
|
+
option = stub()
|
24
|
+
|
25
|
+
Option.expects(:class_for).with(:title).returns(Fleakr::Api::SimpleOption)
|
26
|
+
Fleakr::Api::SimpleOption.expects(:new).with(:title, 'blip').returns(option)
|
27
|
+
|
28
|
+
Option.for(:title, 'blip').should == option
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
class SimpleOptionTest < Test::Unit::TestCase
|
35
|
+
|
36
|
+
describe "An instance of the SimpleOption class" do
|
37
|
+
it "should have a type" do
|
38
|
+
so = SimpleOption.new(:title, 'blip')
|
39
|
+
so.type.should == :title
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should have a value" do
|
43
|
+
so = SimpleOption.new(:title, 'blip')
|
44
|
+
so.value.should == 'blip'
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should be able to generate a hash representation of itself" do
|
48
|
+
so = SimpleOption.new(:title, 'blip')
|
49
|
+
so.to_hash.should == {:title => 'blip'}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
class TagOptionTest < Test::Unit::TestCase
|
56
|
+
|
57
|
+
describe "An instance of the TagOption class" do
|
58
|
+
|
59
|
+
it "should normalize the input value to an array" do
|
60
|
+
to = TagOption.new(:tags, 'blip')
|
61
|
+
to.value.should == ['blip']
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should be able to generate a hash representation of itself with tags joined on spaces" do
|
65
|
+
to = TagOption.new(:tags, %w(bop bip))
|
66
|
+
to.to_hash.should == {:tags => '"bop" "bip"'}
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should quote tag values with spaces" do
|
70
|
+
to = TagOption.new(:tags, ['tag', 'one with spaces'])
|
71
|
+
to.to_hash.should == {:tags => '"tag" "one with spaces"'}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
class ViewOptionTest < Test::Unit::TestCase
|
78
|
+
|
79
|
+
describe "An instance of the ViewOption class" do
|
80
|
+
it "should be able to generate a hash representation for viewing by :everyone" do
|
81
|
+
vo = ViewOption.new(:viewable_by, :everyone)
|
82
|
+
vo.to_hash.should == {:is_public => 1, :is_family => 0, :is_friend => 0}
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should be able to generate a hash representation for viewing by :family" do
|
86
|
+
vo = ViewOption.new(:viewable_by, :family)
|
87
|
+
vo.to_hash.should == {:is_public => 0, :is_family => 1, :is_friend => 0}
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should be able to generate a hash representation for viewing by :friends" do
|
91
|
+
vo = ViewOption.new(:viewable_by, :friends)
|
92
|
+
vo.to_hash.should == {:is_public => 0, :is_family => 0, :is_friend => 1}
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should know the visibility is public if value is set to :everyone" do
|
96
|
+
vo = ViewOption.new(:viewable_by, :everyone)
|
97
|
+
vo.public?.should be(true)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should know the visibility is not public if :everyone is not the only value" do
|
101
|
+
vo = ViewOption.new(:viewable_by, [:everyone, :family])
|
102
|
+
vo.public?.should be(false)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should know that its visible to friends and family if specified as such" do
|
106
|
+
vo = ViewOption.new(:viewable_by, [:friends, :family])
|
107
|
+
vo.friends?.should be(true)
|
108
|
+
vo.family?.should be(true)
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
class LevelOptionTest < Test::Unit::TestCase
|
116
|
+
|
117
|
+
describe "An instance of the LevelOption class" do
|
118
|
+
|
119
|
+
it "should be able to generate a hash representation for the :safe level" do
|
120
|
+
lo = LevelOption.new(:level, :safe)
|
121
|
+
lo.to_hash.should == {:safety_level => 1}
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should be able to generate a hash representation for the :moderate level" do
|
125
|
+
lo = LevelOption.new(:level, :moderate)
|
126
|
+
lo.to_hash.should == {:safety_level => 2}
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should be able to generate a hash representation for the :restricted level" do
|
130
|
+
lo = LevelOption.new(:level, :restricted)
|
131
|
+
lo.to_hash.should == {:safety_level => 3}
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
class TypeOptionTest < Test::Unit::TestCase
|
139
|
+
|
140
|
+
describe "An instance of the TypeOption class" do
|
141
|
+
|
142
|
+
it "should be able to generate a hash representation for the :photo type" do
|
143
|
+
to = TypeOption.new(:type, :photo)
|
144
|
+
to.to_hash.should == {:content_type => 1}
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should be able to generate a hash representation for the :screenshot type" do
|
148
|
+
to = TypeOption.new(:type, :screenshot)
|
149
|
+
to.to_hash.should == {:content_type => 2}
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should be able to generate a hash representation for the :other type" do
|
153
|
+
to = TypeOption.new(:type, :other)
|
154
|
+
to.to_hash.should == {:content_type => 3}
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
class HiddenOptionTest < Test::Unit::TestCase
|
162
|
+
|
163
|
+
describe "An instance of the HiddenOption class" do
|
164
|
+
|
165
|
+
it "should be able to generate a hash representation when set to true" do
|
166
|
+
ho = HiddenOption.new(:hide?, true)
|
167
|
+
ho.to_hash.should == {:hidden => 2}
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should be able to generate a hash representation when set to false" do
|
171
|
+
ho = HiddenOption.new(:hide?, false)
|
172
|
+
ho.to_hash.should == {:hidden => 1}
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
@@ -9,7 +9,6 @@ module Fleakr::Api
|
|
9
9
|
@api_key = 'key'
|
10
10
|
@secret = 'foobar'
|
11
11
|
|
12
|
-
Fleakr.stubs(:shared_secret).with().returns(@secret)
|
13
12
|
Fleakr.stubs(:api_key).with().returns(@api_key)
|
14
13
|
@parameter_list = ParameterList.new
|
15
14
|
end
|
@@ -24,7 +23,7 @@ module Fleakr::Api
|
|
24
23
|
parameter_list = ParameterList.new(:one => 'two')
|
25
24
|
parameter_list[:one].value.should == 'two'
|
26
25
|
end
|
27
|
-
|
26
|
+
|
28
27
|
it "should be able to add parameters to its list" do
|
29
28
|
parameter = ValueParameter.new('foo', 'bar')
|
30
29
|
|
@@ -47,11 +46,15 @@ module Fleakr::Api
|
|
47
46
|
end
|
48
47
|
|
49
48
|
it "should be able to calculate the signature of the parameters" do
|
49
|
+
Fleakr.stubs(:shared_secret).with().returns(@secret)
|
50
|
+
|
50
51
|
@parameter_list << ValueParameter.new('foo', 'bar')
|
51
52
|
@parameter_list.signature.should == Digest::MD5.hexdigest("#{@secret}api_key#{@api_key}foobar")
|
52
53
|
end
|
53
54
|
|
54
55
|
it "should use the correct order when signing a list of multiple parameters" do
|
56
|
+
Fleakr.stubs(:shared_secret).with().returns(@secret)
|
57
|
+
|
55
58
|
@parameter_list << ValueParameter.new('z', 'a')
|
56
59
|
@parameter_list << ValueParameter.new('a', 'z')
|
57
60
|
|
@@ -59,6 +62,8 @@ module Fleakr::Api
|
|
59
62
|
end
|
60
63
|
|
61
64
|
it "should ignore the parameters that aren't included in the signature" do
|
65
|
+
Fleakr.stubs(:shared_secret).with().returns(@secret)
|
66
|
+
|
62
67
|
@parameter_list << ValueParameter.new('foo', 'bar')
|
63
68
|
@parameter_list << ValueParameter.new('yes', 'no', false)
|
64
69
|
|
@@ -76,15 +81,30 @@ module Fleakr::Api
|
|
76
81
|
@parameter_list.sign?.should be(false)
|
77
82
|
end
|
78
83
|
|
79
|
-
it "should know that it needs to sign the request when
|
80
|
-
|
81
|
-
parameter_list.sign?.should be(true)
|
84
|
+
it "should know that it needs to sign the request when a shared secret is available" do
|
85
|
+
Fleakr.expects(:shared_secret).with().returns(@secret)
|
86
|
+
@parameter_list.sign?.should be(true)
|
82
87
|
end
|
83
88
|
|
84
89
|
it "should know that it doesn't need to authenticate the request by default" do
|
85
90
|
@parameter_list.authenticate?.should be(false)
|
86
91
|
end
|
87
92
|
|
93
|
+
it "should know to authenticate the request when a token is available" do
|
94
|
+
Fleakr.stubs(:token).with().returns(stub(:value => 'toke'))
|
95
|
+
parameter_list = ParameterList.new
|
96
|
+
|
97
|
+
parameter_list.authenticate?.should be(true)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should not authenticate the request if it's been specifically told not to" do
|
101
|
+
Fleakr.expects(:token).with().never
|
102
|
+
|
103
|
+
parameter_list = ParameterList.new(:authenticate? => false)
|
104
|
+
parameter_list.authenticate?.should be(false)
|
105
|
+
end
|
106
|
+
|
107
|
+
|
88
108
|
it "should know to authenticate the request when asked" do
|
89
109
|
Fleakr.expects(:token).with().returns(stub(:value => 'toke'))
|
90
110
|
|
@@ -103,15 +123,10 @@ module Fleakr::Api
|
|
103
123
|
auth_param.include_in_signature?.should be(true)
|
104
124
|
end
|
105
125
|
|
106
|
-
it "should know that it needs to sign the request when it is to be authenticated" do
|
107
|
-
Fleakr.expects(:token).with().returns(stub(:value => 'toke'))
|
108
|
-
|
109
|
-
parameter_list = ParameterList.new(:authenticate? => true)
|
110
|
-
parameter_list.sign?.should be(true)
|
111
|
-
end
|
112
|
-
|
113
126
|
it "should include the signature in the list of parameters if the request is to be signed" do
|
114
|
-
parameter_list = ParameterList.new
|
127
|
+
parameter_list = ParameterList.new
|
128
|
+
|
129
|
+
parameter_list.stubs(:sign?).with().returns(true)
|
115
130
|
parameter_list.stubs(:signature).with().returns('sig')
|
116
131
|
|
117
132
|
signature_param = parameter_list[:api_sig]
|
@@ -122,24 +137,24 @@ module Fleakr::Api
|
|
122
137
|
end
|
123
138
|
|
124
139
|
context "with associated parameters" do
|
125
|
-
|
140
|
+
|
126
141
|
before do
|
127
142
|
@p1 = ValueParameter.new('a', 'b')
|
128
143
|
@p2 = ValueParameter.new('c', 'd')
|
129
|
-
|
144
|
+
|
130
145
|
@p1.stubs(:to_query).with().returns('q1')
|
131
146
|
@p1.stubs(:to_form).with().returns('f1')
|
132
147
|
|
133
148
|
@p2.stubs(:to_query).with().returns('q2')
|
134
149
|
@p2.stubs(:to_form).with().returns('f2')
|
135
|
-
|
150
|
+
|
136
151
|
@parameter_list.stubs(:list).with().returns('a' => @p1, 'c' => @p2)
|
137
152
|
end
|
138
|
-
|
153
|
+
|
139
154
|
it "should be able to generate a query representation of itself" do
|
140
155
|
@parameter_list.to_query.should == 'q1&q2'
|
141
156
|
end
|
142
|
-
|
157
|
+
|
143
158
|
it "should be able to represent a form representation of itself" do
|
144
159
|
@parameter_list.stubs(:boundary).returns('bound')
|
145
160
|
|