facebook-stub 0.0.1.4 → 0.0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/Rakefile +23 -0
- data/facebook-stub.gemspec +12 -4
- data/lib/facebook-stub.js +5 -0
- data/lib/facebook-stub.rb +1 -54
- data/lib/facebook_stub.rb +55 -0
- data/{src/libs → lib/facebook_stub}/base64_encode.js +0 -0
- data/{src/libs → lib/facebook_stub}/cookie.js +0 -0
- data/{src/facebook.js → lib/facebook_stub/core.js} +100 -62
- data/lib/facebook_stub/rails/action_view_helper.rb +10 -0
- data/{src/libs → lib/facebook_stub}/sha256.js +0 -0
- data/{src/libs → lib/facebook_stub}/utf8_encode.js +0 -0
- data/lib/facebook_stub/version.rb +3 -0
- data/spec/acceptance/facebook-stub_spec.rb +301 -0
- data/spec/spec_helper.rb +41 -0
- data/test/config.ru +3 -0
- data/test/server.rb +20 -0
- data/test/views/test.haml +20 -0
- metadata +173 -62
- data/builder/concat +0 -8
- data/facebook-stub.js +0 -707
- data/lib/facebook-stub/rails/action_view_helper.rb +0 -20
- data/lib/facebook-stub/version.rb +0 -5
- data/test/test.html +0 -19
data/.gitignore
CHANGED
data/.rspec
ADDED
data/Rakefile
CHANGED
@@ -1 +1,24 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
ROOT = Pathname.new(File.expand_path('..',__FILE__))
|
6
|
+
LIB = ROOT + 'lib'
|
7
|
+
PKG = ROOT + 'pkg'
|
8
|
+
|
9
|
+
task :build do
|
10
|
+
require 'sprockets'
|
11
|
+
environment = Sprockets::Environment.new
|
12
|
+
environment.append_path LIB.to_s
|
13
|
+
source = environment['facebook-stub.js'].source
|
14
|
+
PKG.join('facebook-stub.js').open('w'){|f| f.write source }
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "run rspec"
|
18
|
+
RSpec::Core::RakeTask.new do |t|
|
19
|
+
t.pattern = ROOT.join("spec/**/*_spec.rb").to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
task :test => [:build, :spec]
|
23
|
+
|
24
|
+
task :default => :test
|
data/facebook-stub.gemspec
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
$:.push File.expand_path("../lib", __FILE__)
|
3
|
-
require "
|
3
|
+
require "facebook_stub/version"
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = "facebook-stub"
|
7
|
-
s.version =
|
7
|
+
s.version = FacebookStub::VERSION
|
8
8
|
s.authors = ["Change.org"]
|
9
9
|
s.email = ["techops@change.org"]
|
10
10
|
s.homepage = ""
|
@@ -15,11 +15,19 @@ Gem::Specification.new do |s|
|
|
15
15
|
|
16
16
|
s.files = `git ls-files`.split("\n")
|
17
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
-
s.executables = `git ls-files --
|
18
|
+
s.executables = `git ls-files -- pkg/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
21
|
# specify any dependencies here; for example:
|
22
22
|
# s.add_development_dependency "rspec"
|
23
23
|
# s.add_runtime_dependency "rest-client"
|
24
|
-
s.add_development_dependency
|
24
|
+
s.add_development_dependency 'debugger'
|
25
|
+
s.add_development_dependency 'sprockets'
|
26
|
+
s.add_development_dependency 'rake'
|
27
|
+
s.add_development_dependency 'sinatra'
|
28
|
+
s.add_development_dependency 'shotgun'
|
29
|
+
s.add_development_dependency 'haml'
|
30
|
+
s.add_development_dependency 'rspec'
|
31
|
+
s.add_development_dependency 'capybara'
|
32
|
+
|
25
33
|
end
|
data/lib/facebook-stub.rb
CHANGED
@@ -1,54 +1 @@
|
|
1
|
-
require
|
2
|
-
require 'facebook-stub/rails/action_view_helper'
|
3
|
-
|
4
|
-
module Facebook
|
5
|
-
module Stub
|
6
|
-
BASE_INFO = {
|
7
|
-
"name" => "Gandalf the Grey",
|
8
|
-
"location" => {
|
9
|
-
"name" => "San Francisco, California",
|
10
|
-
"city" => "San Francisco",
|
11
|
-
"zip" => "94107",
|
12
|
-
"country" => "United States",
|
13
|
-
"id" => 114952118516947,
|
14
|
-
"state" => "California"
|
15
|
-
},
|
16
|
-
"timezone" => -8,
|
17
|
-
"gender" => "male",
|
18
|
-
"id" => "234567898765432",
|
19
|
-
"birthday" => "07/21/1954",
|
20
|
-
"updated_time" => "2011-02-10T00:40:26+0000",
|
21
|
-
"verified" => true,
|
22
|
-
"locale" => "en_US",
|
23
|
-
"religion" => "Wikipedia",
|
24
|
-
"bio" => "The greatest thing you'll ever learn is just to love and be loved in return.\r\n\r\nIf hearing the name Sharon Salinger causes you physical pain and emotional trauma then we are friends.\r\n\r\nMy life has a great cast but I can't figure out the plot.",
|
25
|
-
"hometown" => { "name" => nil, "id" => "" },
|
26
|
-
"link" => "http://www.facebook.com/gandalf.the.grey",
|
27
|
-
"political" => "Fellowship",
|
28
|
-
"email" => "gandalf@change.org",
|
29
|
-
"first_name" => "Gandalf",
|
30
|
-
"middle_name" => "the",
|
31
|
-
"last_name" => "Grey"
|
32
|
-
}
|
33
|
-
|
34
|
-
def Stub::reset!
|
35
|
-
# Marshal to force a deep copy
|
36
|
-
@info = Marshal.load(Marshal.dump(BASE_INFO))
|
37
|
-
end
|
38
|
-
|
39
|
-
def Stub::info
|
40
|
-
@info
|
41
|
-
end
|
42
|
-
|
43
|
-
def Stub::invalid!
|
44
|
-
@info = {}
|
45
|
-
end
|
46
|
-
|
47
|
-
Stub::reset!
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
|
52
|
-
if defined?(ActionView::Base)
|
53
|
-
ActionView::Base.send(:include, Facebook::Stub::Rails::ActionViewHelper)
|
54
|
-
end
|
1
|
+
require 'facebook_stub'
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "facebook_stub/version"
|
2
|
+
require 'facebook_stub/rails/action_view_helper'
|
3
|
+
|
4
|
+
module FacebookStub
|
5
|
+
|
6
|
+
extend self
|
7
|
+
|
8
|
+
BASE_INFO = {
|
9
|
+
"name" => "Gandalf the Grey",
|
10
|
+
"location" => {
|
11
|
+
"name" => "San Francisco, California",
|
12
|
+
"city" => "San Francisco",
|
13
|
+
"zip" => "94107",
|
14
|
+
"country" => "United States",
|
15
|
+
"id" => 114952118516947,
|
16
|
+
"state" => "California"
|
17
|
+
},
|
18
|
+
"timezone" => -8,
|
19
|
+
"gender" => "male",
|
20
|
+
"id" => "234567898765432",
|
21
|
+
"birthday" => "07/21/1954",
|
22
|
+
"updated_time" => "2011-02-10T00:40:26+0000",
|
23
|
+
"verified" => true,
|
24
|
+
"locale" => "en_US",
|
25
|
+
"religion" => "Wikipedia",
|
26
|
+
"bio" => "The greatest thing you'll ever learn is just to love and be loved in return.\r\n\r\nIf hearing the name Sharon Salinger causes you physical pain and emotional trauma then we are friends.\r\n\r\nMy life has a great cast but I can't figure out the plot.",
|
27
|
+
"hometown" => { "name" => nil, "id" => "" },
|
28
|
+
"link" => "http://www.facebook.com/gandalf.the.grey",
|
29
|
+
"political" => "Fellowship",
|
30
|
+
"email" => "gandalf@change.org",
|
31
|
+
"first_name" => "Gandalf",
|
32
|
+
"middle_name" => "the",
|
33
|
+
"last_name" => "Grey"
|
34
|
+
}
|
35
|
+
|
36
|
+
def reset!
|
37
|
+
# Marshal to force a deep copy
|
38
|
+
@info = Marshal.load(Marshal.dump(BASE_INFO))
|
39
|
+
end
|
40
|
+
|
41
|
+
def info
|
42
|
+
@info
|
43
|
+
end
|
44
|
+
|
45
|
+
def invalid!
|
46
|
+
@info = {}
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
FacebookStub.reset!
|
52
|
+
|
53
|
+
if defined?(ActionView::Base)
|
54
|
+
ActionView::Base.send(:include, FacebookStub::Rails::ActionViewHelper)
|
55
|
+
end
|
File without changes
|
File without changes
|
@@ -1,6 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
(function(window, undefined) {
|
2
|
+
|
3
|
+
// var permissions = {
|
4
|
+
// "data": [
|
5
|
+
// {
|
6
|
+
// "installed": 1,
|
7
|
+
// "status_update": 1,
|
8
|
+
// "photo_upload": 1,
|
9
|
+
// "video_upload": 1,
|
10
|
+
// "email": 1,
|
11
|
+
// "create_note": 1,
|
12
|
+
// "share_item": 1,
|
13
|
+
// "publish_stream": 1,
|
14
|
+
// "publish_actions": 1
|
15
|
+
// }
|
16
|
+
// ]
|
17
|
+
// }
|
4
18
|
|
5
19
|
// two globals for creating the cookie
|
6
20
|
// FB Functions
|
@@ -9,11 +23,12 @@
|
|
9
23
|
state('appId', data.appId);
|
10
24
|
}
|
11
25
|
|
12
|
-
function missingPermissions(
|
26
|
+
function missingPermissions(permissions){
|
13
27
|
var missing = [];
|
14
|
-
var perms =
|
15
|
-
|
16
|
-
|
28
|
+
var perms = getPermissions();
|
29
|
+
var desired = permissions && permissions.split(',') || [];
|
30
|
+
for (var i=0; i<desired.length; i++){
|
31
|
+
if (!perms || !perms[desired[i]]) {
|
17
32
|
missing.push(desired[i]);
|
18
33
|
}
|
19
34
|
}
|
@@ -24,13 +39,12 @@
|
|
24
39
|
function login(callback, options) {
|
25
40
|
if (calledBeforeInit('login')) return;
|
26
41
|
if (FBWorld.state('loggedIn')) {
|
27
|
-
console.log('FB.login() called when user is already connected.');
|
28
42
|
if (FBWorld.state('connected')) {
|
29
|
-
var missing = missingPermissions(options.scope
|
30
|
-
if (missing.length === 0){
|
31
|
-
callback(getStatus(
|
43
|
+
var missing = missingPermissions(options.scope);
|
44
|
+
if (!missing || missing.length === 0){
|
45
|
+
callback(getStatus());
|
32
46
|
}else{
|
33
|
-
options.
|
47
|
+
options.missing_permissions = missing;
|
34
48
|
promptToAddPermissions(options, callback);
|
35
49
|
}
|
36
50
|
}else{
|
@@ -67,8 +81,8 @@
|
|
67
81
|
if (!FBWorld.state('connected')) {
|
68
82
|
promptToConnect(options, callback);
|
69
83
|
} else {
|
70
|
-
|
71
|
-
callback(getStatus(
|
84
|
+
setPermissions(options.scope);
|
85
|
+
callback(getStatus());
|
72
86
|
}
|
73
87
|
|
74
88
|
} else {
|
@@ -112,12 +126,12 @@
|
|
112
126
|
|
113
127
|
if (approved){
|
114
128
|
FBWorld.connected();
|
115
|
-
|
129
|
+
setPermissions(options.scope);
|
116
130
|
} else {
|
117
131
|
FBWorld.notConnected();
|
118
132
|
}
|
119
133
|
|
120
|
-
callback(getStatus(
|
134
|
+
callback(getStatus());
|
121
135
|
}
|
122
136
|
|
123
137
|
function acceptPromptToConnect() {
|
@@ -132,19 +146,15 @@
|
|
132
146
|
resolvePromptToConnect(false);
|
133
147
|
}
|
134
148
|
|
149
|
+
// add permissions to app
|
135
150
|
|
136
|
-
|
137
|
-
function promptToAddPermissions(options, callback){
|
151
|
+
// simulate prompt to add permissions
|
152
|
+
function promptToAddPermissions(options, callback) {
|
138
153
|
FBWorld.beingPromptedToAddPermissions = true;
|
139
154
|
FBWorld.beingPromptedToAddPermissionsOptions = options;
|
140
155
|
FBWorld.beingPromptedToAddPermissionsCallback = callback;
|
141
156
|
}
|
142
157
|
|
143
|
-
function beingPromptedToAddThesePermissions(permissions){
|
144
|
-
// sort and stringify permissions arrays to make them easier to compare. maybe not fast, but succinct
|
145
|
-
return FBWorld.beingPromptedToAddPermissions && FBWorld.beingPromptedToAddPermissionsOptions.missing_perms.sort().toString() == permissions.split(',').sort().toString();
|
146
|
-
}
|
147
|
-
|
148
158
|
function resolvePromptToAddPermissions(approved, permissions) {
|
149
159
|
if (!FBWorld.beingPromptedToAddPermissions) throw "you are not being prompted to add permissions";
|
150
160
|
var
|
@@ -157,27 +167,46 @@
|
|
157
167
|
FBWorld.beingPromptedToAddPermissionsCallback = undefined;
|
158
168
|
|
159
169
|
if (approved){
|
160
|
-
|
170
|
+
if (permissions){
|
171
|
+
var existing_permissions = getPermissions();
|
172
|
+
if (existing_permissions){
|
173
|
+
var new_permissions = permissions.split(',');
|
174
|
+
for (var i=0; i<new_permissions.length; i++){
|
175
|
+
existing_permissions[new_permissions[i]] = 1;
|
176
|
+
}
|
177
|
+
setPermissions(Object.keys(existing_permissions).join(','));
|
178
|
+
}
|
179
|
+
else{
|
180
|
+
setPermissions(permissions);
|
181
|
+
}
|
182
|
+
}else{
|
183
|
+
setPermissions(options.scope);
|
184
|
+
}
|
161
185
|
}
|
162
|
-
callback(getStatus('standard'));
|
163
|
-
}
|
164
186
|
|
165
|
-
|
166
|
-
var perms = getStatus("standard").perms;
|
167
|
-
var separator = perms.length ? ',' : '';
|
168
|
-
resolvePromptToAddPermissions(true, perms + separator + add);
|
187
|
+
callback(getStatus());
|
169
188
|
}
|
170
189
|
|
171
|
-
function
|
172
|
-
resolvePromptToAddPermissions(
|
190
|
+
function acceptPromptToAddPermissions(permissions) {
|
191
|
+
resolvePromptToAddPermissions(true, permissions);
|
173
192
|
}
|
174
193
|
|
175
|
-
function
|
194
|
+
function skipPromptToAddPermissions() {
|
176
195
|
resolvePromptToAddPermissions(false);
|
177
196
|
}
|
178
197
|
|
198
|
+
function beingPromptedToAddThesePermissions(permissions){
|
199
|
+
if (FBWorld.beingPromptedToAddPermissionsOptions && FBWorld.beingPromptedToAddPermissionsOptions.missing_permissions) {
|
200
|
+
var missingOptions = FBWorld.beingPromptedToAddPermissionsOptions.missing_permissions;
|
201
|
+
return missingOptions.sort().toString() == permissions.split(',').sort().toString();
|
202
|
+
} else {
|
203
|
+
return false;
|
204
|
+
}
|
205
|
+
}
|
179
206
|
|
180
|
-
|
207
|
+
function hasPermissions(permissions) {
|
208
|
+
return missingPermissions(permissions).length === 0;
|
209
|
+
}
|
181
210
|
|
182
211
|
function logout(callback) {
|
183
212
|
if (calledBeforeInit('logout')) return;
|
@@ -186,13 +215,13 @@
|
|
186
215
|
callback(getStatus());
|
187
216
|
}
|
188
217
|
|
189
|
-
function getLoginStatus(callback,
|
218
|
+
function getLoginStatus(callback, force) {
|
190
219
|
if (calledBeforeInit('getLoginStatus')) return;
|
191
|
-
callback(getStatus(
|
220
|
+
callback(getStatus());
|
192
221
|
}
|
193
222
|
|
194
223
|
function getUserID() {
|
195
|
-
if (calledBeforeInit('getUserID')) return;
|
224
|
+
if (calledBeforeInit('getUserID')) return undefined;
|
196
225
|
return uid();
|
197
226
|
}
|
198
227
|
|
@@ -210,8 +239,8 @@
|
|
210
239
|
} else if (location == '/me/permissions') {
|
211
240
|
var theState = FBWorld.state();
|
212
241
|
var perms;
|
213
|
-
if (theState && theState.perms) {
|
214
|
-
perms = {data:[theState.perms.
|
242
|
+
if (theState && theState.perms && theState.perms.data) {
|
243
|
+
perms = {data:[theState.perms.data]};
|
215
244
|
}
|
216
245
|
callback( perms );
|
217
246
|
}
|
@@ -244,8 +273,8 @@
|
|
244
273
|
return FBWorld.state('uid', newUid);
|
245
274
|
}
|
246
275
|
|
247
|
-
function
|
248
|
-
return FBWorld.state('perms', '
|
276
|
+
function setPermissions(newPermissions) {
|
277
|
+
return FBWorld.state('perms', 'data', convertPermsToData(newPermissions));
|
249
278
|
}
|
250
279
|
|
251
280
|
function setSecret(newSecret) {
|
@@ -299,14 +328,14 @@
|
|
299
328
|
function resolveSharePrompt(way) {
|
300
329
|
response = {};
|
301
330
|
if (way === 'share') response.post_id = Math.floor(Math.random() * 100000);
|
302
|
-
if (way === 'cancel');
|
331
|
+
//if (way === 'cancel');
|
303
332
|
|
304
333
|
if (typeof FBWorld.beingPromptedToShareCallback === 'function')
|
305
334
|
FBWorld.beingPromptedToShareCallback(response);
|
306
335
|
FBWorld.beingPromptedToShare = false;
|
307
336
|
FBWorld.beingPromptedToShareOptions = undefined;
|
308
337
|
FBWorld.beingPromptedToShareCallback = undefined;
|
309
|
-
}
|
338
|
+
}
|
310
339
|
|
311
340
|
function confirmSharePrompt(){
|
312
341
|
resolveSharePrompt('share');
|
@@ -347,7 +376,8 @@
|
|
347
376
|
uid : uid,
|
348
377
|
connected : connected,
|
349
378
|
notConnected : notConnected,
|
350
|
-
|
379
|
+
setPermissions : setPermissions,
|
380
|
+
getPermissions : getPermissions,
|
351
381
|
|
352
382
|
initialized : false,
|
353
383
|
|
@@ -369,14 +399,14 @@
|
|
369
399
|
denyPromptToConnect : denyPromptToConnect,
|
370
400
|
cancelPromptToConnect : cancelPromptToConnect,
|
371
401
|
|
372
|
-
//
|
402
|
+
// permissions
|
373
403
|
beingPromptedToAddPermissions : false,
|
374
|
-
beingPromptedToAddThesePermissions : beingPromptedToAddThesePermissions,
|
375
404
|
beingPromptedToAddPermissionsOptions : undefined,
|
376
405
|
beingPromptedToAddPermissionsCallback : undefined,
|
406
|
+
beingPromptedToAddThesePermissions : beingPromptedToAddThesePermissions,
|
407
|
+
hasPermissions : hasPermissions,
|
377
408
|
acceptPromptToAddPermissions : acceptPromptToAddPermissions,
|
378
|
-
|
379
|
-
cancelPromptToAddPermissions : cancelPromptToAddPermissions,
|
409
|
+
skipPromptToAddPermissions : skipPromptToAddPermissions,
|
380
410
|
|
381
411
|
//sharing
|
382
412
|
beingPromptedToShare : false,
|
@@ -393,12 +423,9 @@
|
|
393
423
|
|
394
424
|
|
395
425
|
|
396
|
-
|
397
|
-
|
398
|
-
|
399
426
|
// PRIVATE FUNCTIONS
|
400
427
|
|
401
|
-
function getStatus(
|
428
|
+
function getStatus() {
|
402
429
|
var theState = FBWorld.state();
|
403
430
|
|
404
431
|
// Connected
|
@@ -408,16 +435,12 @@
|
|
408
435
|
authResponse: createConnectedCookie()
|
409
436
|
};
|
410
437
|
|
411
|
-
if(typeof(permissions) != 'undefined') {
|
412
|
-
status.perms = permissions == 'extended' ? JSON.stringify(theState.perms) : theState.perms.standard;
|
413
|
-
}
|
414
438
|
return status;
|
415
439
|
}
|
416
440
|
|
417
441
|
// not connected
|
418
442
|
if (theState.loggedIn && !theState.connected) {
|
419
443
|
return {
|
420
|
-
perms: null,
|
421
444
|
authResponse: null,
|
422
445
|
status: 'notConnected'
|
423
446
|
};
|
@@ -426,20 +449,33 @@
|
|
426
449
|
// not logged in
|
427
450
|
if (!theState.loggedIn) {
|
428
451
|
return {
|
429
|
-
perms: null,
|
430
452
|
authResponse: null,
|
431
453
|
status: 'unknown'
|
432
454
|
};
|
433
455
|
}
|
434
456
|
|
435
|
-
}
|
457
|
+
}
|
436
458
|
|
437
|
-
function
|
459
|
+
function getPermissions() {
|
460
|
+
var theState = FBWorld.state();
|
461
|
+
return theState.perms && theState.perms.data || undefined;
|
462
|
+
}
|
463
|
+
|
464
|
+
function calledBeforeInit(function_name) {
|
438
465
|
if (FBWorld.initialized) return false;
|
439
|
-
console.log("FB."+
|
466
|
+
console.log("FB."+function_name+" called before FB.init");
|
440
467
|
return true;
|
441
468
|
}
|
442
469
|
|
470
|
+
function convertPermsToData(perms) {
|
471
|
+
var data = {};
|
472
|
+
perms = perms && perms.split(',') || [];
|
473
|
+
for (var i=0; i<perms.length; i++){
|
474
|
+
data[perms[i]] = 1;
|
475
|
+
}
|
476
|
+
return data;
|
477
|
+
}
|
478
|
+
|
443
479
|
var cookieOptions = { path: '/', domain: window.location.hostname.replace(/^www/, '')};
|
444
480
|
|
445
481
|
// cookie looks like this: (with the quotes): "access_token=theToken&base_domain=local-change.org&expires=0&secret=theSecret&session_key=theSessionKeysig=theSig-Hashed&uid=theUID"
|
@@ -451,11 +487,13 @@
|
|
451
487
|
issued_at: Math.floor(new Date().getTime() / 1000)
|
452
488
|
};
|
453
489
|
|
454
|
-
if (uid()
|
490
|
+
if (uid() !== null) {
|
455
491
|
theState.uid = uid();
|
456
492
|
}
|
457
493
|
|
458
|
-
|
494
|
+
var secret = state('secret');
|
495
|
+
if (!secret) throw "secret is not set. Use FBWorld.setSecret('secret')";
|
496
|
+
FBWorld.Helpers.makeMeACookie('fbsr_'+state('appId'), cookieToString(theState, secret), cookieOptions);
|
459
497
|
return theState;
|
460
498
|
}
|
461
499
|
|