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.
@@ -1 +1,3 @@
1
- require 'fleakr/core_ext/hash'
1
+ require 'fleakr/core_ext/hash'
2
+ require 'fleakr/core_ext/false_class'
3
+ require 'fleakr/core_ext/true_class'
@@ -0,0 +1,7 @@
1
+ class FalseClass # :nodoc:
2
+
3
+ def to_i
4
+ 0
5
+ end
6
+
7
+ end
@@ -0,0 +1,7 @@
1
+ class TrueClass # :nodoc:
2
+
3
+ def to_i
4
+ 1
5
+ end
6
+
7
+ end
@@ -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(token)
24
- parameters = {:mini_token => token, :sign? => true}
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(token)
34
- parameters = {:auth_token => token, :sign? => true}
35
- response = Fleakr::Api::MethodRequest.with_response!('auth.checkToken', parameters)
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
@@ -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. This
63
- # call requires authentication.
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, :authenticate? => true)
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, :type => :update)
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
- response = Fleakr::Api::MethodRequest.with_response!('#{options[:call]}', :#{attribute} => value)
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
@@ -3,7 +3,7 @@ module Fleakr
3
3
 
4
4
  MAJOR = 0
5
5
  MINOR = 4
6
- TINY = 1
6
+ TINY = 2
7
7
 
8
8
  def self.to_s
9
9
  [MAJOR, MINOR, TINY].join('.')
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <rsp stat="ok">
3
+ <auth>
4
+ <token>abc-123</token>
5
+ <perms>delete</perms>
6
+ <user nsid="31066442@N69" fullname="Sir Froot Pants" username="frootpantz"></user>
7
+ </auth>
8
+ </rsp>
@@ -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 asked" do
80
- parameter_list = ParameterList.new(:sign? => true)
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(:sign? => true)
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