mogli 0.0.29 → 0.0.30

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,98 @@
1
+ require "spec_helper"
2
+ describe Mogli::FetchingArray do
3
+
4
+ let :fetching_array do
5
+ array = Mogli::FetchingArray.new
6
+ array << Mogli::User.new(:id=>4)
7
+ array << Mogli::User.new(:id=>5)
8
+ array.next_url = "https://next"
9
+ array.previous_url = "https://previous"
10
+ array.client = client
11
+ array.classes = [Mogli::User]
12
+ array
13
+ end
14
+
15
+ let :client do
16
+ Mogli::Client.new
17
+ end
18
+
19
+ it "has a next_url" do
20
+ fetching_array.next_url.should == "https://next"
21
+ end
22
+
23
+ it "has a previous url" do
24
+ fetching_array.previous_url.should == "https://previous"
25
+ end
26
+
27
+ it "has a client" do
28
+ fetching_array.client.should == client
29
+ end
30
+
31
+ it "has the classes that it fetches for" do
32
+ fetching_array.classes = ["User"]
33
+ fetching_array.classes.should == ["User"]
34
+ end
35
+
36
+
37
+ describe "fetching" do
38
+ before(:each) do
39
+ Mogli::Client.stub!(:get).and_return("data"=>[:id=>3],"paging"=>{"previous"=>"https://new_previous","next"=>"https://new_next"})
40
+ end
41
+
42
+ describe "fetch next" do
43
+
44
+ it "returns an empty array if there is no next_url" do
45
+ Mogli::FetchingArray.new.fetch_next.should == []
46
+ end
47
+
48
+ it "adds the contents to this container" do
49
+ fetching_array.fetch_next
50
+ fetching_array.should == [Mogli::User.new(:id=>4),Mogli::User.new(:id=>5),Mogli::User.new(:id=>3)]
51
+ end
52
+
53
+ it "updates the next url with the newly fetched next url" do
54
+ fetching_array.fetch_next
55
+ fetching_array.next_url.should == "https://new_next"
56
+
57
+ end
58
+
59
+ it "should not change the previous url" do
60
+ fetching_array.fetch_next
61
+ fetching_array.previous_url.should == "https://previous"
62
+ end
63
+
64
+ it "returns the new records" do
65
+ fetching_array.fetch_next.should == [Mogli::User.new(:id=>3)]
66
+ end
67
+
68
+ end
69
+
70
+ describe "fetch previous" do
71
+
72
+ it "returns an empty array if there is no previous url" do
73
+ Mogli::FetchingArray.new.fetch_previous.should == []
74
+
75
+ end
76
+
77
+ it "adds the contents to this container" do
78
+ fetching_array.fetch_previous
79
+ fetching_array.should == [Mogli::User.new(:id=>3),Mogli::User.new(:id=>4),Mogli::User.new(:id=>5)]
80
+ end
81
+
82
+ it "updates the previous url with the newly fetched previous url" do
83
+ fetching_array.fetch_previous
84
+ fetching_array.previous_url.should == "https://new_previous"
85
+ end
86
+
87
+ it "should not change the next url" do
88
+ fetching_array.fetch_previous
89
+ fetching_array.next_url.should == "https://next"
90
+ end
91
+
92
+ it "returns the new records" do
93
+ fetching_array.fetch_previous.should == [Mogli::User.new(:id=>3)]
94
+ end
95
+
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,245 @@
1
+ require "spec_helper"
2
+ class TestModel < Mogli::Model
3
+ set_search_type :test_model
4
+ define_properties :id, :other_property, :actions
5
+ creation_properties :other_property, :actions
6
+ has_association :comments, "Comment"
7
+
8
+ hash_populating_accessor :from, "User"
9
+ hash_populating_accessor :activities, "Activity"
10
+ hash_populating_accessor :actions, "Action"
11
+ end
12
+
13
+
14
+ describe Mogli::Model do
15
+
16
+ let :model do
17
+ model = TestModel.new(:id=>1)
18
+ model.client = mock_client
19
+ model
20
+ end
21
+
22
+ let :mock_client do
23
+ Mogli::Client.new
24
+ end
25
+
26
+
27
+ it "allows setting the client" do
28
+ user = Mogli::Model.new
29
+ user.client = "client"
30
+ user.client.should == "client"
31
+ end
32
+
33
+ it "has a define properties method" do
34
+ model.respond_to?(:id).should be_true
35
+ model.respond_to?(:other_property).should be_true
36
+ end
37
+
38
+ it "warns when you try to set invalid properties" do
39
+ lambda do
40
+ TestModel.new(:invalid_property=>1,:id=>2)
41
+ end.should_not raise_error
42
+ end
43
+
44
+ it "has a comments attribute which fetches when called" do
45
+ mock_client.should_receive(:get_and_map).with("1/comments","Comment", {}).and_return("comments")
46
+ model.comments.should == "comments"
47
+ end
48
+
49
+ it "populates associations if available" do
50
+ model = TestModel.new("id"=>1, "comments"=>{"data"=>[{"id"=>1,"message"=>"first"},{"id"=>2,"message"=>"second"}]})
51
+ mock_client.should_receive(:get_and_map).never
52
+ model.comments.size.should == 2
53
+ model.comments.first.id.should == 1
54
+ model.comments.last.message.should == "second"
55
+ end
56
+
57
+ it "only fetches activities once" do
58
+ mock_client.should_receive(:get_and_map).once.with("1/comments","Comment", {}).and_return([])
59
+ model.comments
60
+ model.comments
61
+ end
62
+
63
+ describe "creation" do
64
+
65
+ it "has a create method on associations" do
66
+ mock_client.stub!(:post)
67
+ model.comments_create(Mogli::Activity.new)
68
+ end
69
+
70
+ it "posts the params to the client" do
71
+ mock_client.should_receive(:post).with("1/comments","Comment",:message=>"my message")
72
+ model.comments_create(Mogli::Comment.new(:message=>"my message"))
73
+ end
74
+
75
+ end
76
+
77
+ it "populates from as the user from a hash" do
78
+ model.from = {"id" => "12451752", "name" => "Mike Mangino"}
79
+ model.from.should be_an_instance_of(Mogli::User)
80
+ model.from.id.should == "12451752"
81
+ model.from.name.should == "Mike Mangino"
82
+ end
83
+
84
+ it "populates activities from a hash array" do
85
+ model.activities = {"data"=>[{"id"=>1,"name"=>"Coding"},{"id"=>2}]}
86
+ model.activities.size.should == 2
87
+ model.activities.each {|c| c.should be_an_instance_of(Mogli::Activity)}
88
+ model.activities.first.id.should == 1
89
+ model.activities.first.client.should == mock_client
90
+ end
91
+
92
+ it "allows deleting the post" do
93
+ mock_client.should_receive(:delete).with(1)
94
+ model.destroy
95
+ end
96
+
97
+ it "freezes deleted objects" do
98
+ mock_client.should_receive(:delete).with(1)
99
+ model.destroy
100
+ model.should be_frozen
101
+ end
102
+
103
+ it "emits warnings when properties that don't exist are written to" do
104
+ model.should_receive(:warn_about_invalid_property).with("doesnt_exist")
105
+ model.doesnt_exist=1
106
+ end
107
+
108
+ describe "Posting" do
109
+ it "knows which properties are posted" do
110
+ TestModel.new(:id=>1,:other_property=>2).post_params.keys.map(&:to_s).sort.should == TestModel.creation_keys.map(&:to_s).sort
111
+ end
112
+
113
+ it "includes regular hash properties for posting" do
114
+ TestModel.new(:id=>1,:other_property=>2).post_params[:other_property].should == 2
115
+ end
116
+
117
+ it "includes associated properties for posting" do
118
+ actions_data = {:name => 'Action Name', :link => 'http://example.com'}
119
+ new_model = TestModel.new(:id=>1,:other_property=>2,:actions => [actions_data])
120
+ new_model.post_params[:actions].should == "[{\"name\":\"Action Name\",\"link\":\"http://example.com\"}]"
121
+ end
122
+
123
+ it "includes associated properties for posting even if Array doesn't have to_json method" do
124
+ actions_data = {:name => 'Action Name', :link => 'http://example.com'}
125
+ actions_data_array = [actions_data]
126
+ actions_data_array.stub!(:respond_to?).with(:to_json).and_return(false)
127
+ actions_data_array.stub!(:respond_to?).with(:code).and_return(false)
128
+ actions_data_array.stub!(:respond_to?).with(:parsed_response).and_return(false)
129
+
130
+ new_model = TestModel.new(:id=>1,:other_property=>2,:actions => actions_data_array)
131
+ new_model.post_params[:actions].should == "[{\"name\":\"Action Name\",\"link\":\"http://example.com\"}]"
132
+ end
133
+
134
+ it "will allow updating status with no object" do
135
+ mock_client.should_receive(:post).once.with("1/comments",nil,{}).and_return([])
136
+ model.comments_create
137
+ end
138
+ end
139
+
140
+ describe "Fetching" do
141
+
142
+ it "fetches data for a model with an id " do
143
+ Mogli::Client.should_receive(:get).with("https://graph.facebook.com/1", :query=>{}).and_return({:id=>1,:other_property=>2})
144
+ model.fetch
145
+ model.other_property.should == 2
146
+ end
147
+ it "fetches data and returns itself" do
148
+ Mogli::Client.stub!(:get).and_return({:id=>1,:other_property=>2})
149
+ model.fetch.should == model
150
+ end
151
+
152
+ it "raises an exception when there is no id" do
153
+ lambda do
154
+ TestModel.new.fetch
155
+ end.should raise_error(ArgumentError)
156
+ end
157
+ end
158
+
159
+ describe "Finding" do
160
+
161
+ it "finds many models when id is an Array" do
162
+ Mogli::Client.should_receive(:get).with(
163
+ "https://graph.facebook.com/", :query =>{ :ids => '1,2'}
164
+ ).and_return({
165
+ "1" => { :id => 1 }, "2" => { :id => 2 , :other_property => "Bob"}
166
+ })
167
+ users = TestModel.find([1,2])
168
+ users.should have(2).elements
169
+ users.each {|user| user.should be_instance_of(TestModel)}
170
+ users[1].other_property.should == "Bob"
171
+ end
172
+
173
+ it "raises an exeption if id doesn't exist" do
174
+ Mogli::Client.should_receive(:get).with(
175
+ "https://graph.facebook.com/123456", :query => {}
176
+ ).and_return({
177
+ "error"=> {"type"=>"QueryParseException", "message"=>"Some of the aliases you requested do not exist: 123456"}
178
+ })
179
+ lambda do
180
+ TestModel.find(123456)
181
+ end.should raise_error(Mogli::Client::QueryParseException, "Some of the aliases you requested do not exist: 123456")
182
+
183
+ end
184
+
185
+ it "raises an exception if one from many ids doesn't exist" do
186
+ Mogli::Client.should_receive(:get).with(
187
+ "https://graph.facebook.com/", :query =>{ :ids => '1,123456'}
188
+ ).and_return({
189
+ "error"=> {"type"=>"QueryParseException", "message"=>"Some of the aliases you requested do not exist: 123456"}
190
+ })
191
+ lambda do
192
+ TestModel.find([1,123456])
193
+ end.should raise_error(Mogli::Client::QueryParseException, "Some of the aliases you requested do not exist: 123456")
194
+
195
+ end
196
+
197
+ end
198
+
199
+ describe "Searching" do
200
+
201
+
202
+ it "search for graph resources if specific class defined search type" do
203
+ client = Mogli::Client.new('123');
204
+ Mogli::Client.should_receive(:get).with(
205
+ "https://graph.facebook.com/search", :query => {:q=> "s", :type => 'test_model', :access_token => "123"}
206
+ ).and_return({
207
+ 'data' => [{'id' => 1, 'other_property' => "Test"}]
208
+ })
209
+ results = TestModel.search('s',client)
210
+ results.class.should == Mogli::FetchingArray
211
+ results.first.id.should == 1
212
+ end
213
+
214
+ it "search in all resource types when searching in Mogli::Model" do
215
+ client = Mogli::Client.new('123');
216
+ Mogli::Client.should_receive(:get).with(
217
+ "https://graph.facebook.com/search", :query => {:q=> "s", :access_token => "123"}
218
+ ).and_return({
219
+ 'data' => [{'id' => 1, 'message' => "status!", 'type' => "status"},
220
+ {'id' => 2, 'email' => "bob@example.org", 'type' => "user"}
221
+ ]})
222
+ results = Mogli::Model.search('s',client)
223
+ results.map(&:class).sort_by(&:to_s).should == [Mogli::Status, Mogli::User]
224
+ end
225
+
226
+ it "raises access token error if client is not defined" do
227
+ Mogli::Client.should_receive(:get).with(
228
+ "https://graph.facebook.com/search", :query => {:q=> "s", :type => 'user'}
229
+ ).and_return({
230
+ "error"=> {"type"=>"OAuthUnauthorizedClientException", "message"=>"An access token is required to request this resource."}
231
+ })
232
+ lambda {
233
+ Mogli::User.search('s')
234
+ }.should raise_error(Mogli::Client::OAuthUnauthorizedClientException, "An access token is required to request this resource.")
235
+ end
236
+
237
+ it "raises error if class doesn't define search type" do
238
+ lambda {
239
+ Mogli::Album.search("Joe")
240
+ }.should raise_error(NoMethodError, "Can't search for Mogli::Album")
241
+ end
242
+
243
+ end
244
+
245
+ end
data/spec/page_spec.rb ADDED
@@ -0,0 +1,19 @@
1
+ require "spec_helper"
2
+ describe Mogli::Page do
3
+ it "has an access_token" do
4
+ Mogli::Page.new.access_token.should be_nil
5
+ end
6
+
7
+ it "gets raises an error if the accesstoken is nil" do
8
+ lambda do
9
+ Mogli::Page.new.client_for_page
10
+ end.should raise_error(Mogli::Page::MissingAccessToken)
11
+ end
12
+
13
+ it "gets a client if access token has been populated" do
14
+ page = Mogli::Page.new
15
+ page.access_token="my token"
16
+ client = page.client_for_page
17
+ client.access_token.should == "my token"
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+ describe Mogli::Profile do
3
+ it "has an image_url" do
4
+ profile = Mogli::Profile.new
5
+ profile.id="1"
6
+ profile.image_url.should == "https://graph.facebook.com/1/picture"
7
+ end
8
+
9
+ it "has image_url methods for small/large/square" do
10
+ profile = Mogli::Profile.new
11
+ profile.id="1"
12
+ profile.square_image_url.should == "https://graph.facebook.com/1/picture?type=square"
13
+ profile.large_image_url.should == "https://graph.facebook.com/1/picture?type=large"
14
+ profile.small_image_url.should == "https://graph.facebook.com/1/picture?type=small"
15
+ end
16
+ end
@@ -0,0 +1,2 @@
1
+ require "rubygems"
2
+ require (Pathname(__FILE__).dirname + '../init')
@@ -0,0 +1,25 @@
1
+ require "spec_helper"
2
+ describe Mogli::User do
3
+
4
+ let(:app_id) { '12345' }
5
+ let(:access_token) { '678910' }
6
+
7
+ describe "#create" do
8
+ it "POSTs to the test user creation url" do
9
+ Mogli::Client.should_receive(:post).with("https://graph.facebook.com/#{app_id}/accounts/test-users",
10
+ :body => {:access_token => access_token, :installed => false, :name => 'The Sock Hammer'}).
11
+ and_return({:id=>1, :login_url => 'http://example.com/hamsocks' })
12
+ user = Mogli::TestUser.create({:installed => false, :name => 'The Sock Hammer'}, Mogli::AppClient.new(access_token, app_id))
13
+ user.login_url.should == 'http://example.com/hamsocks'
14
+ end
15
+ end
16
+
17
+ describe "#all" do
18
+ it "GETs the test user url" do
19
+ Mogli::Client.should_receive(:get).with("https://graph.facebook.com/#{app_id}/accounts/test-users",
20
+ :query => {:access_token => access_token}).and_return([{:id=>1, :login_url => 'http://example.com/hamsocks'}])
21
+ users = Mogli::TestUser.all(Mogli::AppClient.new(access_token, app_id))
22
+ users.first.login_url.should == 'http://example.com/hamsocks'
23
+ end
24
+ end
25
+ end
data/spec/user_spec.rb ADDED
@@ -0,0 +1,107 @@
1
+ require "spec_helper"
2
+ describe Mogli::User do
3
+
4
+ let :user_1 do
5
+ user_1 = Mogli::User.new(:id=>1)
6
+ user_1.client = mock_client
7
+ user_1
8
+ end
9
+
10
+ let :mock_client do
11
+ mock("client")
12
+ end
13
+
14
+
15
+ it "won't recognize pages" do
16
+ Mogli::User.recognize?("id"=>1,"name"=>"bob","category"=>"fdhsjkfsd")
17
+ end
18
+
19
+ it "will recognize itself" do
20
+ Mogli::User.recognize?("id"=>1,"name"=>"bob")
21
+ end
22
+
23
+
24
+ describe "Finding" do
25
+
26
+ it "finds optional fields for a user" do
27
+ Mogli::Client.should_receive(:get).with("https://graph.facebook.com/1",
28
+ :query=>{:fields => "birthday,gender"}).and_return({:id=>1, :birthday=>'09/15', :gender => 'male'})
29
+ user = Mogli::User.find(1, nil, :birthday, :gender)
30
+ user.birthday.should == '09/15'
31
+ user.gender.should == 'male'
32
+ end
33
+
34
+ it "finds a user's friends with optional fields" do
35
+ mock_client.should_receive(:get_and_map).with(
36
+ "1/friends", "User", {:fields => [:birthday, :gender]}).and_return(
37
+ [Mogli::User.new(:id=>2, :birthday=>'09/15', :gender => 'male')])
38
+ friends = user_1.friends(:birthday, :gender)
39
+ friends.size.should == 1
40
+ end
41
+ end
42
+
43
+ describe "checking extended permissions" do
44
+ before :each do
45
+ # construct a response that will avoid errors: we're just testing query
46
+ @dummy_response = 'dummy response'
47
+ @dummy_response.stub!(:parsed_response).and_return [{}]
48
+
49
+ # this HTTParty parsed response is taken directly from an actual fql response
50
+ @valid_response = 'valid response'
51
+ @valid_response.stub!(:parsed_response).and_return [{"publish_stream"=>1, "create_event"=>0, "rsvp_event"=>0, "sms"=>0, "offline_access"=>1, "publish_checkins"=>0, "user_about_me"=>0, "user_activities"=>0, "user_birthday"=>0, "user_education_history"=>0, "user_events"=>0, "user_groups"=>0, "user_hometown"=>0, "user_interests"=>0, "user_likes"=>0, "user_location"=>0, "user_notes"=>0, "user_online_presence"=>0, "user_photo_video_tags"=>0, "user_photos"=>0, "user_relationships"=>0, "user_relationship_details"=>0, "user_religion_politics"=>0, "user_status"=>0, "user_videos"=>0, "user_website"=>0, "user_work_history"=>0, "email"=>1, "read_friendlists"=>0, "read_insights"=>0, "read_mailbox"=>0, "read_requests"=>0, "read_stream"=>0, "xmpp_login"=>0, "ads_management"=>0, "user_checkins"=>0, "manage_pages"=>0}]
52
+
53
+ @request_regexp = /^SELECT ([\w,]*) FROM permissions WHERE uid = \d*$/
54
+ end
55
+
56
+ it "sends FQL with correct syntax when querying permissions" do
57
+ user_1.client.should_receive(:fql_query).with(@request_regexp).and_return @dummy_response
58
+ user_1.send :fetch_permissions
59
+ end
60
+
61
+ it "includes all known permissions in FQL query" do
62
+ user_1.client.should_receive(:fql_query) do |query|
63
+ @request_regexp =~ query
64
+ permissions_list = $1
65
+
66
+ Mogli::User::ALL_EXTENDED_PERMISSIONS.each do |perm|
67
+ permissions_list.should match /,?#{perm.to_s},?/
68
+ end
69
+
70
+ @dummy_response # stubbed return val
71
+ end
72
+
73
+ user_1.send :fetch_permissions
74
+ end
75
+
76
+ it "only submits permissions-checking FQL once when checking a permission" do
77
+ user_1.client.should_receive(:fql_query).once.and_return @dummy_response
78
+ user_1.has_permission? :publish_stream
79
+ user_1.has_permission? :offline_access
80
+ end
81
+
82
+ it "correctly converts FQL response into the permissions hash" do
83
+ user_1.client.should_receive(:fql_query).and_return @valid_response
84
+ user_1.send :fetch_permissions
85
+ Mogli::User::ALL_EXTENDED_PERMISSIONS.each do |perm|
86
+ user_1.extended_permissions.should be_include perm
87
+ end
88
+ end
89
+
90
+ it "correctly reports that user has permission they have granted" do
91
+ user_1.client.should_receive(:fql_query).and_return @valid_response
92
+ user_1.should be_has_permission(:offline_access)
93
+ end
94
+
95
+ it "correctly reports that user does not have permission they have not granted" do
96
+ user_1.client.should_receive(:fql_query).and_return @valid_response
97
+ user_1.should_not be_has_permission(:manage_pages)
98
+ end
99
+
100
+ it "should raise exception on unrecognized permission" do
101
+ lambda {
102
+ user_1.has_permission? :not_a_permission
103
+ }.should raise_error(Mogli::User::UnrecognizedExtendedPermissionException)
104
+ end
105
+ end
106
+
107
+ end