mogli 0.0.29 → 0.0.30

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.
@@ -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