theoooo-fleakr 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/README.rdoc +350 -0
  2. data/Rakefile +41 -0
  3. data/lib/fleakr.rb +163 -0
  4. data/lib/fleakr/api.rb +8 -0
  5. data/lib/fleakr/api/file_parameter.rb +47 -0
  6. data/lib/fleakr/api/method_request.rb +66 -0
  7. data/lib/fleakr/api/option.rb +175 -0
  8. data/lib/fleakr/api/parameter.rb +35 -0
  9. data/lib/fleakr/api/parameter_list.rb +97 -0
  10. data/lib/fleakr/api/response.rb +35 -0
  11. data/lib/fleakr/api/upload_request.rb +75 -0
  12. data/lib/fleakr/api/value_parameter.rb +36 -0
  13. data/lib/fleakr/core_ext.rb +3 -0
  14. data/lib/fleakr/core_ext/false_class.rb +7 -0
  15. data/lib/fleakr/core_ext/hash.rb +22 -0
  16. data/lib/fleakr/core_ext/true_class.rb +7 -0
  17. data/lib/fleakr/objects.rb +12 -0
  18. data/lib/fleakr/objects/authentication_token.rb +60 -0
  19. data/lib/fleakr/objects/comment.rb +49 -0
  20. data/lib/fleakr/objects/contact.rb +31 -0
  21. data/lib/fleakr/objects/error.rb +22 -0
  22. data/lib/fleakr/objects/group.rb +36 -0
  23. data/lib/fleakr/objects/image.rb +50 -0
  24. data/lib/fleakr/objects/photo.rb +147 -0
  25. data/lib/fleakr/objects/photo_context.rb +49 -0
  26. data/lib/fleakr/objects/search.rb +30 -0
  27. data/lib/fleakr/objects/set.rb +50 -0
  28. data/lib/fleakr/objects/tag.rb +56 -0
  29. data/lib/fleakr/objects/user.rb +95 -0
  30. data/lib/fleakr/support.rb +2 -0
  31. data/lib/fleakr/support/attribute.rb +46 -0
  32. data/lib/fleakr/support/object.rb +110 -0
  33. data/lib/fleakr/version.rb +13 -0
  34. data/test/fixtures/auth.checkToken.xml +8 -0
  35. data/test/fixtures/auth.getFullToken.xml +8 -0
  36. data/test/fixtures/auth.getToken.xml +8 -0
  37. data/test/fixtures/contacts.getPublicList.xml +7 -0
  38. data/test/fixtures/groups.pools.getPhotos.xml +7 -0
  39. data/test/fixtures/people.findByEmail.xml +6 -0
  40. data/test/fixtures/people.findByUsername.xml +6 -0
  41. data/test/fixtures/people.getInfo.xml +18 -0
  42. data/test/fixtures/people.getPublicGroups.xml +7 -0
  43. data/test/fixtures/people.getPublicPhotos.xml +7 -0
  44. data/test/fixtures/photos.comments.getList.xml +7 -0
  45. data/test/fixtures/photos.getContext.xml +6 -0
  46. data/test/fixtures/photos.getInfo.xml +20 -0
  47. data/test/fixtures/photos.getSizes.xml +10 -0
  48. data/test/fixtures/photos.search.xml +7 -0
  49. data/test/fixtures/photosets.comments.getList.xml +7 -0
  50. data/test/fixtures/photosets.getList.xml +13 -0
  51. data/test/fixtures/photosets.getPhotos.xml +7 -0
  52. data/test/fixtures/tags.getListPhoto.xml +9 -0
  53. data/test/fixtures/tags.getListUser.xml +10 -0
  54. data/test/fixtures/tags.getRelated.xml +9 -0
  55. data/test/test_helper.rb +140 -0
  56. data/test/unit/fleakr/api/file_parameter_test.rb +63 -0
  57. data/test/unit/fleakr/api/method_request_test.rb +93 -0
  58. data/test/unit/fleakr/api/option_test.rb +179 -0
  59. data/test/unit/fleakr/api/parameter_list_test.rb +176 -0
  60. data/test/unit/fleakr/api/parameter_test.rb +34 -0
  61. data/test/unit/fleakr/api/response_test.rb +49 -0
  62. data/test/unit/fleakr/api/upload_request_test.rb +145 -0
  63. data/test/unit/fleakr/api/value_parameter_test.rb +41 -0
  64. data/test/unit/fleakr/core_ext/false_class_test.rb +13 -0
  65. data/test/unit/fleakr/core_ext/hash_test.rb +32 -0
  66. data/test/unit/fleakr/core_ext/true_class_test.rb +13 -0
  67. data/test/unit/fleakr/objects/authentication_token_test.rb +61 -0
  68. data/test/unit/fleakr/objects/comment_test.rb +66 -0
  69. data/test/unit/fleakr/objects/contact_test.rb +58 -0
  70. data/test/unit/fleakr/objects/error_test.rb +21 -0
  71. data/test/unit/fleakr/objects/group_test.rb +46 -0
  72. data/test/unit/fleakr/objects/image_test.rb +81 -0
  73. data/test/unit/fleakr/objects/photo_context_test.rb +80 -0
  74. data/test/unit/fleakr/objects/photo_test.rb +243 -0
  75. data/test/unit/fleakr/objects/search_test.rb +74 -0
  76. data/test/unit/fleakr/objects/set_test.rb +82 -0
  77. data/test/unit/fleakr/objects/tag_test.rb +98 -0
  78. data/test/unit/fleakr/objects/user_test.rb +91 -0
  79. data/test/unit/fleakr/support/attribute_test.rb +126 -0
  80. data/test/unit/fleakr/support/object_test.rb +129 -0
  81. data/test/unit/fleakr_test.rb +171 -0
  82. metadata +175 -0
@@ -0,0 +1,93 @@
1
+ require File.dirname(__FILE__) + '/../../../test_helper'
2
+
3
+ module Fleakr::Api
4
+ class MethodRequestTest < Test::Unit::TestCase
5
+
6
+ describe "An instance of MethodRequest" do
7
+
8
+ context "with API credentials" do
9
+
10
+ before do
11
+ @api_key = 'f00b4r'
12
+ Fleakr.stubs(:api_key).with().returns(@api_key)
13
+ Fleakr.stubs(:shared_secret).with().returns('sekrit')
14
+ end
15
+
16
+ it "should know the full query parameters" do
17
+ request = MethodRequest.new('flickr.people.findByUsername', :username => 'foobar')
18
+
19
+ request.parameters[:api_key].value.should == @api_key
20
+ request.parameters[:method].value.should == 'flickr.people.findByUsername'
21
+ request.parameters[:username].value.should == 'foobar'
22
+ end
23
+
24
+ it "should translate a shorthand API call" do
25
+ request = MethodRequest.new('people.findByUsername')
26
+ request.parameters[:method].value.should == 'flickr.people.findByUsername'
27
+ end
28
+
29
+ it "should know the endpoint with full parameters" do
30
+ query_parameters = 'foo=bar'
31
+
32
+ request = MethodRequest.new('people.getInfo')
33
+ request.parameters.stubs(:to_query).returns(query_parameters)
34
+
35
+ uri_mock = mock() {|m| m.expects(:query=).with(query_parameters)}
36
+ URI.expects(:parse).with("http://api.flickr.com/services/rest/").returns(uri_mock)
37
+
38
+ request.__send__(:endpoint_uri).should == uri_mock
39
+ end
40
+
41
+ it "should be able to make a request" do
42
+ endpoint_uri = stub()
43
+
44
+ request = MethodRequest.new('people.findByUsername')
45
+ request.stubs(:endpoint_uri).with().returns(endpoint_uri)
46
+
47
+ Net::HTTP.expects(:get).with(endpoint_uri).returns('<xml>')
48
+
49
+ request.send
50
+ end
51
+
52
+ it "should create a response from the request" do
53
+ response_xml = '<xml>'
54
+ response_stub = stub()
55
+
56
+ Net::HTTP.stubs(:get).returns(response_xml)
57
+ Response.expects(:new).with(response_xml).returns(response_stub)
58
+
59
+ request = MethodRequest.new('people.findByUsername')
60
+ request.stubs(:endpoint_uri)
61
+
62
+ request.send.should == response_stub
63
+ end
64
+
65
+ it "should be able to make a full request and response cycle" do
66
+ method = 'flickr.people.findByUsername'
67
+ params = {:username => 'foobar'}
68
+
69
+ response = stub(:error? => false)
70
+
71
+ MethodRequest.expects(:new).with(method, params).returns(stub(:send => response))
72
+
73
+ MethodRequest.with_response!(method, params).should == response
74
+ end
75
+
76
+ it "should raise an exception when the full request / response cycle has errors" do
77
+ method = 'flickr.people.findByUsername'
78
+ params = {:username => 'foobar'}
79
+
80
+ response = stub(:error? => true, :error => stub(:code => '1', :message => 'User not found'))
81
+
82
+ MethodRequest.expects(:new).with(method, params).returns(stub(:send => response))
83
+
84
+ lambda do
85
+ MethodRequest.with_response!('flickr.people.findByUsername', :username => 'foobar')
86
+ end.should raise_error(Fleakr::ApiError)
87
+ end
88
+
89
+ end
90
+ end
91
+
92
+ end
93
+ end
@@ -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
@@ -0,0 +1,176 @@
1
+ require File.dirname(__FILE__) + '/../../../test_helper'
2
+
3
+ module Fleakr::Api
4
+ class ParameterListTest < Test::Unit::TestCase
5
+
6
+ describe "An instance of the ParameterList class" do
7
+
8
+ before do
9
+ @api_key = 'key'
10
+ @secret = 'foobar'
11
+
12
+ Fleakr.stubs(:api_key).with().returns(@api_key)
13
+ @parameter_list = ParameterList.new
14
+ end
15
+
16
+ it "should contain the :api_key by default" do
17
+ @parameter_list[:api_key].name.should == 'api_key'
18
+ @parameter_list[:api_key].value.should == @api_key
19
+ @parameter_list[:api_key].include_in_signature?.should be(true)
20
+ end
21
+
22
+ it "should be able to create an initial list of parameters" do
23
+ parameter_list = ParameterList.new(:one => 'two')
24
+ parameter_list[:one].value.should == 'two'
25
+ end
26
+
27
+ it "should be able to add parameters to its list" do
28
+ parameter = ValueParameter.new('foo', 'bar')
29
+
30
+ @parameter_list << parameter
31
+ @parameter_list['foo'].should == parameter
32
+ end
33
+
34
+ it "should allow access to parameters by symbol" do
35
+ parameter = ValueParameter.new('foo', 'bar')
36
+ @parameter_list << parameter
37
+
38
+ @parameter_list[:foo].should == parameter
39
+ end
40
+
41
+ it "should overwrite existing values when a duplicate is added" do
42
+ length = @parameter_list.instance_variable_get(:@list).length
43
+ 2.times {@parameter_list << ValueParameter.new('foo', 'bar') }
44
+
45
+ @parameter_list.instance_variable_get(:@list).length.should == length + 1
46
+ end
47
+
48
+ it "should be able to calculate the signature of the parameters" do
49
+ Fleakr.stubs(:shared_secret).with().returns(@secret)
50
+
51
+ @parameter_list << ValueParameter.new('foo', 'bar')
52
+ @parameter_list.signature.should == Digest::MD5.hexdigest("#{@secret}api_key#{@api_key}foobar")
53
+ end
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
+
58
+ @parameter_list << ValueParameter.new('z', 'a')
59
+ @parameter_list << ValueParameter.new('a', 'z')
60
+
61
+ @parameter_list.signature.should == Digest::MD5.hexdigest("#{@secret}azapi_key#{@api_key}za")
62
+ end
63
+
64
+ it "should ignore the parameters that aren't included in the signature" do
65
+ Fleakr.stubs(:shared_secret).with().returns(@secret)
66
+
67
+ @parameter_list << ValueParameter.new('foo', 'bar')
68
+ @parameter_list << ValueParameter.new('yes', 'no', false)
69
+
70
+ @parameter_list.signature.should == Digest::MD5.hexdigest("#{@secret}api_key#{@api_key}foobar")
71
+ end
72
+
73
+ it "should be able to generate a boundary for post data" do
74
+ rand = '0.123'
75
+
76
+ @parameter_list.stubs(:rand).with().returns(stub(:to_s => rand))
77
+ @parameter_list.boundary.should == Digest::MD5.hexdigest(rand)
78
+ end
79
+
80
+ it "should know that it doesn't need to sign the request by default" do
81
+ @parameter_list.sign?.should be(false)
82
+ end
83
+
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)
87
+ end
88
+
89
+ it "should know that it doesn't need to authenticate the request by default" do
90
+ @parameter_list.authenticate?.should be(false)
91
+ end
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
+
108
+ it "should know to authenticate the request when asked" do
109
+ Fleakr.expects(:token).with().returns(stub(:value => 'toke'))
110
+
111
+ parameter_list = ParameterList.new(:authenticate? => true)
112
+ parameter_list.authenticate?.should be(true)
113
+ end
114
+
115
+ it "should contain the :auth_token parameter in the list if the request is to be authenticated" do
116
+ Fleakr.expects(:token).with().returns(stub(:value => 'toke'))
117
+
118
+ parameter_list = ParameterList.new(:authenticate? => true)
119
+ auth_param = parameter_list[:auth_token]
120
+
121
+ auth_param.name.should == 'auth_token'
122
+ auth_param.value.should == 'toke'
123
+ auth_param.include_in_signature?.should be(true)
124
+ end
125
+
126
+ it "should include the signature in the list of parameters if the request is to be signed" do
127
+ parameter_list = ParameterList.new
128
+
129
+ parameter_list.stubs(:sign?).with().returns(true)
130
+ parameter_list.stubs(:signature).with().returns('sig')
131
+
132
+ signature_param = parameter_list[:api_sig]
133
+
134
+ signature_param.name.should == 'api_sig'
135
+ signature_param.value.should == 'sig'
136
+ signature_param.include_in_signature?.should be(false)
137
+ end
138
+
139
+ context "with associated parameters" do
140
+
141
+ before do
142
+ @p1 = ValueParameter.new('a', 'b')
143
+ @p2 = ValueParameter.new('c', 'd')
144
+
145
+ @p1.stubs(:to_query).with().returns('q1')
146
+ @p1.stubs(:to_form).with().returns('f1')
147
+
148
+ @p2.stubs(:to_query).with().returns('q2')
149
+ @p2.stubs(:to_form).with().returns('f2')
150
+
151
+ @parameter_list.stubs(:list).with().returns('a' => @p1, 'c' => @p2)
152
+ end
153
+
154
+ it "should be able to generate a query representation of itself" do
155
+ @parameter_list.to_query.should == 'q1&q2'
156
+ end
157
+
158
+ it "should be able to represent a form representation of itself" do
159
+ @parameter_list.stubs(:boundary).returns('bound')
160
+
161
+ expected =
162
+ "--bound\r\n" +
163
+ "f1" +
164
+ "--bound\r\n" +
165
+ "f2" +
166
+ "--bound--"
167
+
168
+ @parameter_list.to_form.should == expected
169
+ end
170
+
171
+ end
172
+
173
+ end
174
+
175
+ end
176
+ end