mwilliams-fleakr 0.5.1

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 (82) hide show
  1. data/README.rdoc +350 -0
  2. data/Rakefile +41 -0
  3. data/lib/fleakr/api/file_parameter.rb +47 -0
  4. data/lib/fleakr/api/method_request.rb +66 -0
  5. data/lib/fleakr/api/option.rb +175 -0
  6. data/lib/fleakr/api/parameter.rb +35 -0
  7. data/lib/fleakr/api/parameter_list.rb +97 -0
  8. data/lib/fleakr/api/response.rb +35 -0
  9. data/lib/fleakr/api/upload_request.rb +75 -0
  10. data/lib/fleakr/api/value_parameter.rb +36 -0
  11. data/lib/fleakr/api.rb +8 -0
  12. data/lib/fleakr/core_ext/false_class.rb +7 -0
  13. data/lib/fleakr/core_ext/hash.rb +22 -0
  14. data/lib/fleakr/core_ext/true_class.rb +7 -0
  15. data/lib/fleakr/core_ext.rb +3 -0
  16. data/lib/fleakr/objects/authentication_token.rb +60 -0
  17. data/lib/fleakr/objects/comment.rb +49 -0
  18. data/lib/fleakr/objects/contact.rb +31 -0
  19. data/lib/fleakr/objects/error.rb +22 -0
  20. data/lib/fleakr/objects/group.rb +36 -0
  21. data/lib/fleakr/objects/image.rb +50 -0
  22. data/lib/fleakr/objects/photo.rb +147 -0
  23. data/lib/fleakr/objects/photo_context.rb +49 -0
  24. data/lib/fleakr/objects/search.rb +30 -0
  25. data/lib/fleakr/objects/set.rb +50 -0
  26. data/lib/fleakr/objects/tag.rb +56 -0
  27. data/lib/fleakr/objects/user.rb +95 -0
  28. data/lib/fleakr/objects.rb +12 -0
  29. data/lib/fleakr/support/attribute.rb +46 -0
  30. data/lib/fleakr/support/object.rb +110 -0
  31. data/lib/fleakr/support.rb +2 -0
  32. data/lib/fleakr/version.rb +13 -0
  33. data/lib/fleakr.rb +164 -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 +141 -0
  56. data/test/unit/fleakr/api/file_parameter_test.rb +63 -0
  57. data/test/unit/fleakr/api/method_request_test.rb +94 -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 +149 -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 +61 -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 +246 -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
data/lib/fleakr.rb ADDED
@@ -0,0 +1,164 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+ require 'rubygems'
3
+
4
+ require 'uri'
5
+ require 'cgi'
6
+ require 'net/http'
7
+ require 'nokogiri'
8
+ require 'forwardable'
9
+
10
+ # Require only what we need from ActiveSupport
11
+ require 'active_support/core_ext/array'
12
+ require 'active_support/core_ext/module'
13
+ require 'active_support/core_ext/blank'
14
+ require 'active_support/core_ext/time'
15
+ require 'active_support/inflector'
16
+ require 'active_support/core_ext/string'
17
+
18
+ require 'digest/md5'
19
+ require 'fileutils'
20
+ require 'loggable'
21
+
22
+ require 'fleakr/api'
23
+ require 'fleakr/core_ext'
24
+ require 'fleakr/support'
25
+ require 'fleakr/objects'
26
+
27
+ # = Fleakr: A small, yet powerful, gem to interface with Flickr photostreams
28
+ #
29
+ # == Quick Start
30
+ #
31
+ # Getting started is easy, just make sure you have a valid API key from Flickr and you can
32
+ # then start making any non-authenticated request to pull back data for yours and others'
33
+ # photostreams, sets, contacts, groups, etc...
34
+ #
35
+ # For now, all activity originates from a single user which you can find by username or
36
+ # email address.
37
+ #
38
+ # Example:
39
+ #
40
+ # require 'rubygems'
41
+ # require 'fleakr'
42
+ #
43
+ # # Our API key is ABC123 (http://www.flickr.com/services/api/keys/apply/)
44
+ # Fleakr.api_key = 'ABC123'
45
+ # user = Fleakr.user('bees')
46
+ # user = Fleakr.user('user@host.com')
47
+ # # Grab a list of sets
48
+ # user.sets
49
+ # # Grab a list of the user's public groups
50
+ # user.groups
51
+ #
52
+ # To see what other associations and attributes are available, see the Fleakr::Objects::User class
53
+ #
54
+ # == Authentication
55
+ #
56
+ # If you want to do something more than just retrieve public photos (like upload your own),
57
+ # you'll need to generate an authentication token to use across requests and sessions.
58
+ #
59
+ # Assuming you've already applied for a key, go back and make sure you have the right settings
60
+ # to get your auth token. Click on the 'Edit key details' link and ensure that:
61
+ #
62
+ # 1. Your application description and notes are up-to-date
63
+ # 1. The value for 'Authentication Type' is set to 'Mobile Application'
64
+ # 1. The value for 'Mobile Permissions' is set to either 'write' or 'delete'
65
+ #
66
+ # Once this is set, you'll see your Authentication URL on the key details page (it will look
67
+ # something like http://www.flickr.com/auth-534525246245). Paste this URL into your browser and
68
+ # confirm access to get your mini-token. Now you're ready to make authenticated requests:
69
+ #
70
+ # require 'rubygems'
71
+ # require 'fleakr'
72
+ #
73
+ # Fleakr.api_key = 'ABC123'
74
+ # Fleakr.shared_secret = 'sekrit' # Available with your key details on the Flickr site
75
+ # Fleakr.mini_token = '362-133-214'
76
+ #
77
+ # Fleakr.upload('/path/to/my/photo.jpg')
78
+ # Fleakr.token.value # => "34132412341235-12341234ef34"
79
+ #
80
+ # Once you use the mini-token once, it is no longer available. To use the generated auth_token
81
+ # for future requests, just set Fleakr.auth_token to the generated value.
82
+ #
83
+ module Fleakr
84
+
85
+ # Generic catch-all exception for any API errors
86
+ class ApiError < StandardError; end
87
+
88
+ mattr_accessor :api_key, :shared_secret, :mini_token, :auth_token, :frob
89
+
90
+ # Find a user based on some unique user data. This method will try to find
91
+ # the user based on username and will fall back to email if that fails. Example:
92
+ #
93
+ # Fleakr.api_key = 'ABC123'
94
+ # Fleakr.user('the decapitator') # => #<Fleakr::Objects::User:0x692648 @username="the decapitator", @id="21775151@N06">
95
+ # Fleakr.user('user@host.com') # => #<Fleakr::Objects::User:0x11f484c @username="bckspcr", @id="84481630@N00">
96
+ #
97
+ def self.user(user_data)
98
+ begin
99
+ Objects::User.find_by_username(user_data)
100
+ rescue ApiError
101
+ Objects::User.find_by_email(user_data)
102
+ end
103
+ end
104
+
105
+ # Search all photos on the Flickr site. By default, this searches based on text, but you can pass
106
+ # different search parameters (passed as hash keys):
107
+ #
108
+ # [tags] The list of tags to search on (either as an array or comma-separated)
109
+ # [user_id] Scope the search to this user
110
+ # [group_id] Scope the search to this group
111
+ #
112
+ # If you're interested in User- and Group-scoped searches, you may want to use User#search and Group#search
113
+ # instead.
114
+ #
115
+ def self.search(params)
116
+ params = {:text => params} unless params.is_a?(Hash)
117
+ Objects::Search.new(params).results
118
+ end
119
+
120
+ # Upload one or more files to your Flickr account (requires authentication). Simply provide
121
+ # a filename or a pattern to upload one or more files:
122
+ #
123
+ # Fleakr.upload('/path/to/my/mug.jpg')
124
+ # Fleakr.upload('/User/Pictures/Party/*.jpg')
125
+ #
126
+ # Additionally, options can be supplied as part of the upload that will apply to all files
127
+ # that are matched by the pattern passed to <tt>glob</tt>. For a full list, see
128
+ # Fleakr::Objects::Photo.
129
+ #
130
+ def self.upload(glob, options = {})
131
+ Dir[glob].map {|file| Fleakr::Objects::Photo.upload(file, options) }
132
+ end
133
+
134
+ # Get the authentication token needed for authenticated requests. Will either use
135
+ # a valid auth_token (if available) or a mini-token to generate the auth_token.
136
+ #
137
+ def self.token
138
+ @token ||= begin
139
+ if Fleakr.auth_token
140
+ Fleakr::Objects::AuthenticationToken.from_auth_token(Fleakr.auth_token)
141
+ elsif Fleakr.frob
142
+ Fleakr::Objects::AuthenticationToken.from_frob(Fleakr.frob)
143
+ elsif Fleakr.mini_token
144
+ Fleakr::Objects::AuthenticationToken.from_mini_token(Fleakr.mini_token)
145
+ end
146
+ end
147
+ end
148
+
149
+ # Reset the cached token whenever setting a new value for the mini_token, auth_token, or frob
150
+ #
151
+ [:mini_token, :auth_token, :frob].each do |attribute|
152
+ class_eval <<-ACCESSOR
153
+ def self.#{attribute}=(#{attribute})
154
+ reset_token
155
+ @@#{attribute} = #{attribute}
156
+ end
157
+ ACCESSOR
158
+ end
159
+
160
+ def self.reset_token # :nodoc: #
161
+ @token = nil
162
+ end
163
+
164
+ end
@@ -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>
@@ -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>
@@ -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>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <contacts page="1" pages="1" per_page="1000" perpage="1000" total="17">
4
+ <contact nsid="9302864@N42" username="blinky" iconserver="2263" iconfarm="3" ignored="0" />
5
+ <contact nsid="63204625@N20" username="inky" iconserver="53" iconfarm="1" ignored="0" />
6
+ </contacts>
7
+ </rsp>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <photos page="1" pages="796" perpage="100" total="79509">
4
+ <photo id="3101830908" owner="64008250@N00" secret="e85e249e72" server="3042" farm="4" title="Canal Gate" ispublic="1" isfriend="0" isfamily="0" ownername="oakraidr" dateadded="1229049777" />
5
+ <photo id="3100780049" owner="98821864@N00" secret="f46fbe211b" server="3274" farm="4" title="2alarm" ispublic="1" isfriend="0" isfamily="0" ownername="LooknFeel" dateadded="1229042651" />
6
+ </photos>
7
+ </rsp>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <user id="31066442@N69" nsid="31066442@N69">
4
+ <username>frootpantz</username>
5
+ </user>
6
+ </rsp>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <user id="31066442@N69" nsid="31066442@N69">
4
+ <username>frootpantz</username>
5
+ </user>
6
+ </rsp>
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <person id="31066442@N69" nsid="31066442@N69" isadmin="0" ispro="1" iconserver="30" iconfarm="1">
4
+ <username>frootpantz</username>
5
+ <realname>Sir Froot Pantz</realname>
6
+ <mbox_sha1sum>e52ed1e5b91c763694995460e9796fc2adc02019</mbox_sha1sum>
7
+ <location>The Moon</location>
8
+ <photosurl>http://www.flickr.com/photos/frootpantz/</photosurl>
9
+ <profileurl>http://www.flickr.com/people/frootpantz/</profileurl>
10
+ <mobileurl>http://m.flickr.com/photostream.gne?id=34225</mobileurl>
11
+ <photos>
12
+ <firstdatetaken>2006-10-11 08:19:57</firstdatetaken>
13
+ <firstdate>1160612247</firstdate>
14
+ <count>3907</count>
15
+ <views>9002</views>
16
+ </photos>
17
+ </person>
18
+ </rsp>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <groups>
4
+ <group nsid="13378274@N00" name="Group #1" admin="0" eighteenplus="1" />
5
+ <group nsid="52242140489@N01" name="Group #2" admin="1" eighteenplus="0" />
6
+ </groups>
7
+ </rsp>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <photos page="1" pages="1" perpage="100" total="76">
4
+ <photo id="2924549350" owner="21775151@N06" secret="cbc1804258" server="3250" farm="4" title="Photo #1" ispublic="1" isfriend="0" isfamily="0" />
5
+ <photo id="2923697303" owner="21775151@N06" secret="649aa95f29" server="3208" farm="4" title="Photo #2" ispublic="1" isfriend="0" isfamily="0" />
6
+ </photos>
7
+ </rsp>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <comments photo_id="1">
4
+ <comment id="1" author="10490170@N04" authorname="blip" datecreate="1239217523" permalink="http://www.flickr.com/photos/frootpantz/3422268412/#comment72157616515348062">comment one</comment>
5
+ <comment id="2" author="10490170@N02" authorname="bleep" datecreate="1239217222" permalink="http://www.flickr.com/photos/frootpantz/3422268413/#comment72157616515348063">comment two</comment>
6
+ </comments>
7
+ </rsp>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <count>5584</count>
4
+ <prevphoto id="12345" secret="abc234" server="3560" farm="4" title="Previous" url="/photos/frootpantz/12345/in/photostream/" thumb="http://farm4.static.flickr.com/3560/3369675369_d97d2b1345_s.jpg" media="photo" />
5
+ <nextphoto id="12343" secret="abc123" server="3562" farm="4" title="Next" url="/photos/frootpantz/12343/in/photostream/" thumb="http://farm4.static.flickr.com/3562/3370497926_ba89f4343a_s.jpg" media="photo" />
6
+ </rsp>
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <photo id="1" secret="secret" server="3085" farm="4" dateuploaded="1230274722" isfavorite="0" license="0" rotation="0" originalsecret="sekrit" originalformat="jpg" media="photo">
4
+ <owner nsid="31066442@N69" username="frootpantz" realname="" location="" />
5
+ <title>Tree</title>
6
+ <description>A Tree</description>
7
+ <visibility ispublic="1" isfriend="0" isfamily="0" />
8
+ <dates posted="1230274722" taken="2008-12-25 18:26:55" takengranularity="0" lastupdate="1230276652" />
9
+
10
+ <editability cancomment="0" canaddmeta="0" />
11
+ <usage candownload="1" canblog="0" canprint="0" />
12
+ <comments>0</comments>
13
+ <notes />
14
+ <tags />
15
+ <urls>
16
+ <url type="photopage">http://www.flickr.com/photos/yes/1</url>
17
+ </urls>
18
+
19
+ </photo>
20
+ </rsp>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <sizes canblog="0" canprint="0" candownload="1">
4
+ <size label="Square" width="75" height="75" source="http://farm4.static.flickr.com/3093/2409912100_71e14ed08a_s.jpg" url="http://www.flickr.com/photos/the_decapitator/2409912100/sizes/sq/" media="photo" />
5
+ <size label="Thumbnail" width="100" height="67" source="http://farm4.static.flickr.com/3093/2409912100_71e14ed08a_t.jpg" url="http://www.flickr.com/photos/the_decapitator/2409912100/sizes/t/" media="photo" />
6
+ <size label="Small" width="240" height="160" source="http://farm4.static.flickr.com/3093/2409912100_71e14ed08a_m.jpg" url="http://www.flickr.com/photos/the_decapitator/2409912100/sizes/s/" media="photo" />
7
+ <size label="Medium" width="500" height="334" source="http://farm4.static.flickr.com/3093/2409912100_71e14ed08a.jpg" url="http://www.flickr.com/photos/the_decapitator/2409912100/sizes/m/" media="photo" />
8
+ <size label="Original" width="700" height="467" source="http://farm4.static.flickr.com/3093/2409912100_3305c4a108_o.jpg" url="http://www.flickr.com/photos/the_decapitator/2409912100/sizes/o/" media="photo" />
9
+ </sizes>
10
+ </rsp>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <photos page="1" pages="385" perpage="100" total="38424">
4
+ <photo id="3076020861" owner="31987693@N05" secret="b956549c07" server="3278" farm="4" title="Mona and Lisa" ispublic="1" isfriend="0" isfamily="0" />
5
+ <photo id="3075386827" owner="9377349@N05" secret="4e40291b2d" server="3151" farm="4" title="IMG_0055 1.JPG" ispublic="1" isfriend="0" isfamily="0" />
6
+ </photos>
7
+ </rsp>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <comments photo_id="1">
4
+ <comment id="1" author="10490170@N04" authorname="blip" datecreate="1239217523" permalink="http://www.flickr.com/photos/frootpantz/3422268412/#comment72157616515348062">comment one</comment>
5
+ <comment id="2" author="10490170@N02" authorname="bleep" datecreate="1239217222" permalink="http://www.flickr.com/photos/frootpantz/3422268413/#comment72157616515348063">comment two</comment>
6
+ </comments>
7
+ </rsp>
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <rsp stat="ok">
3
+ <photosets>
4
+ <photoset videos="0" primary="3044180117" farm="4" photos="138" id="72157609490909659" server="3012" secret="01cd1a741d">
5
+ <title>Second Set</title>
6
+ <description>This is the second set.</description>
7
+ </photoset>
8
+ <photoset videos="0" primary="2988511085" farm="4" photos="139" id="72157608538140671" server="3241" secret="a7b90926ba">
9
+ <title>First Set</title>
10
+ <description>This is the first set.</description>
11
+ </photoset>
12
+ </photosets>
13
+ </rsp>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <photoset id="72157609490909659" primary="3044180117" owner="31066442@N69" ownername="frootpantz" page="1" per_page="500" perpage="500" pages="1" total="138">
4
+ <photo id="3044163577" secret="fa27e5a824" server="3153" farm="4" title="Photo #1" isprimary="0" />
5
+ <photo id="3045001128" secret="a8c0e51b39" server="3204" farm="4" title="Photo #2" isprimary="0" />
6
+ </photoset>
7
+ </rsp>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <photo id="3411015045">
4
+ <tags>
5
+ <tag id="1" author="15498419@N05" authorname="stu72" raw="stu 72" machine_tag="0">stu72</tag>
6
+ <tag id="2" author="15498419@N05" authorname="stu72" raw="ellie" machine_tag="0">ellie</tag>
7
+ </tags>
8
+ </photo>
9
+ </rsp>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <who id="32719556@N00">
4
+ <tags>
5
+ <tag>08fo</tag>
6
+ <tag>101building</tag>
7
+ <tag>101cookbooks</tag>
8
+ </tags>
9
+ </who>
10
+ </rsp>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <tags source="family">
4
+ <tag>portrait</tag>
5
+ <tag>baby</tag>
6
+ <tag>child</tag>
7
+ </tags>
8
+ </rsp>
9
+
@@ -0,0 +1,141 @@
1
+ $:.reject! { |e| e.include? 'TextMate' }
2
+
3
+ require 'rubygems'
4
+ require 'test/unit'
5
+ require 'shoulda'
6
+ require 'matchy'
7
+ require 'mocha'
8
+
9
+ require File.dirname(__FILE__) + '/../lib/fleakr'
10
+
11
+ class Test::Unit::TestCase
12
+
13
+ def self.should_autoload_when_accessing(*attributes)
14
+ options = attributes.extract_options!
15
+ attributes.each do |accessor_name|
16
+ should "load the additional user information when accessing the :#{accessor_name} attribute" do
17
+ klass = self.class.name.sub(/Test$/, '').constantize
18
+
19
+ object = klass.new
20
+ object.expects(options[:with]).with()
21
+ object.send(accessor_name)
22
+ end
23
+ end
24
+ end
25
+
26
+ def self.should_have_a_value_for(attribute_test)
27
+ should "have a value for :#{attribute_test.keys.first}" do
28
+ @object.send(attribute_test.keys.first).should == attribute_test.values.first
29
+ end
30
+ end
31
+
32
+ def self.should_search_by(key)
33
+ should "be able to perform a scoped search by :#{key}" do
34
+ photos = [stub()]
35
+ search = stub(:results => photos)
36
+
37
+ klass = self.class.name.sub(/Test$/, '').constantize
38
+
39
+ instance = klass.new
40
+ instance.stubs(:id).with().returns('1')
41
+
42
+ Fleakr::Objects::Search.expects(:new).with(:text => 'foo', key => '1').returns(search)
43
+
44
+ instance.search('foo').should == photos
45
+ end
46
+ end
47
+
48
+ def self.should_have_many(*attributes)
49
+ class_name = self.name.demodulize.sub(/Test$/, '')
50
+ this_klass = "Fleakr::Objects::#{class_name}".constantize
51
+
52
+ options = attributes.extract_options!
53
+ finder_attribute = options[:using].nil? ? "#{class_name.downcase}_id" : options[:using]
54
+
55
+ attributes.each do |attribute|
56
+ target_klass = "Fleakr::Objects::#{attribute.to_s.singularize.classify}".constantize
57
+ should "be able to retrieve the #{class_name.downcase}'s #{attribute}" do
58
+ results = [stub()]
59
+ object = this_klass.new
60
+ object.stubs(:id).with().returns('1')
61
+
62
+ target_klass.expects("find_all_by_#{finder_attribute}".to_sym).with('1').returns(results)
63
+ object.send(attribute).should == results
64
+ end
65
+
66
+ should "memoize the results for the #{class_name.downcase}'s #{attribute}" do
67
+ object = this_klass.new
68
+
69
+ target_klass.expects("find_all_by_#{finder_attribute}".to_sym).once.returns([])
70
+ 2.times { object.send(attribute) }
71
+ end
72
+
73
+ end
74
+ end
75
+
76
+ def self.should_find_one(thing, options)
77
+ class_name = thing.to_s.singularize.camelcase
78
+ klass = "Fleakr::Objects::#{class_name}".constantize
79
+ object_type = class_name.downcase
80
+
81
+ condition_value = '1'
82
+
83
+ options[:with] = options[:by] if options[:with].nil?
84
+ params = {options[:with] => condition_value}
85
+
86
+ should "be able to find a #{thing} by #{options[:by]}" do
87
+ stub = stub()
88
+ response = mock_request_cycle :for => options[:call], :with => params
89
+
90
+ klass.expects(:new).with(response.body).returns(stub)
91
+ klass.send("find_by_#{options[:by]}".to_sym, condition_value).should == stub
92
+ end
93
+ end
94
+
95
+ def self.should_find_all(thing, options)
96
+ class_name = thing.to_s.singularize.camelcase
97
+ klass = "Fleakr::Objects::#{class_name}".constantize
98
+ object_type = class_name.downcase
99
+
100
+ should "be able to find all #{thing} by #{options[:by]}" do
101
+ condition_value = '1'
102
+ finder_options = {(options[:using] || options[:by]) => condition_value}
103
+
104
+ response = mock_request_cycle :for => options[:call], :with => finder_options
105
+
106
+ stubs = []
107
+ elements = (response.body/options[:path]).map
108
+
109
+
110
+ elements.each do |element|
111
+ stub = stub()
112
+ stubs << stub
113
+
114
+ klass.expects(:new).with(element).returns(stub)
115
+ end
116
+
117
+ klass.send("find_all_by_#{options[:by]}".to_sym, condition_value).should == stubs
118
+ end
119
+
120
+ end
121
+
122
+ def read_fixture(method_call)
123
+ fixture_path = File.dirname(__FILE__) + '/fixtures'
124
+ File.read("#{fixture_path}/#{method_call}.xml")
125
+ end
126
+
127
+ def mock_request_cycle(options)
128
+ response = stub(:body => Hpricot.XML(read_fixture(options[:for])))
129
+ Fleakr::Api::MethodRequest.expects(:with_response!).with(options[:for], options[:with]).returns(response)
130
+
131
+ response
132
+ end
133
+
134
+ def create_temp_directory
135
+ tmp_dir = File.dirname(__FILE__) + '/tmp'
136
+ FileUtils.mkdir(tmp_dir)
137
+
138
+ tmp_dir
139
+ end
140
+
141
+ end
@@ -0,0 +1,63 @@
1
+ require File.dirname(__FILE__) + '/../../../test_helper'
2
+
3
+ module Fleakr::Api
4
+ class FileParameterTest < Test::Unit::TestCase
5
+
6
+ context "An instance of the FileParameter class" do
7
+
8
+ setup do
9
+ @temp_dir = File.expand_path(create_temp_directory)
10
+ @filename = "#{@temp_dir}/image.jpg"
11
+ end
12
+
13
+ teardown do
14
+ FileUtils.rm_rf(@temp_dir)
15
+ end
16
+
17
+ should "know not to include itself in the parameter signature" do
18
+ parameter = FileParameter.new('photo', @filename)
19
+ parameter.include_in_signature?.should be(false)
20
+ end
21
+
22
+ {'jpg' => 'image/jpeg', 'png' => 'image/png', 'gif' => 'image/gif'}.each do |ext, mime_type|
23
+ should "know the correct MIME type for an extension of #{ext}" do
24
+ parameter = FileParameter.new('photo', "#{@temp_dir}/image.#{ext}")
25
+ parameter.mime_type.should == mime_type
26
+ end
27
+ end
28
+
29
+ should "retrieve the contents of the file when accessing the value" do
30
+ File.expects(:read).with(@filename).returns('bopbip')
31
+
32
+ parameter = FileParameter.new('photo', @filename)
33
+ parameter.value.should == 'bopbip'
34
+ end
35
+
36
+ should "cache the file contents after retrieving them" do
37
+ File.expects(:read).with(@filename).once.returns('bopbip')
38
+
39
+ parameter = FileParameter.new('photo', @filename)
40
+ 2.times { parameter.value }
41
+ end
42
+
43
+ should "know how to generate a form representation of itself" do
44
+ filename = 'image.jpg'
45
+ mime_type = 'image/jpeg'
46
+
47
+ parameter = FileParameter.new('photo', filename)
48
+ parameter.stubs(:mime_type).with().returns(mime_type)
49
+ parameter.stubs(:value).with().returns('data')
50
+
51
+ expected =
52
+ "Content-Disposition: form-data; name=\"photo\"; filename=\"#{filename}\"\r\n" +
53
+ "Content-Type: image/jpeg\r\n" +
54
+ "\r\n" +
55
+ "data\r\n"
56
+
57
+ parameter.to_form.should == expected
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+ end