diff --git a/linkdrop/controllers/contacts.py b/linkdrop/controllers/contacts.py index 27a95ba..5ef2674 100644 --- a/linkdrop/controllers/contacts.py +++ b/linkdrop/controllers/contacts.py @@ -86,9 +86,7 @@ Name of the group to return. ], response={'type': 'object', 'doc': 'Portable Contacts Collection'}) def get(self, domain): - group = request.POST.get('group', None) - startIndex = int(request.POST.get('startindex', '0')) - maxResults = int(request.POST.get('maxresults', '25')) + page_data = request.POST.get('pageData', None) account_data = request.POST.get('account', None) acct = None @@ -103,10 +101,10 @@ Name of the group to return. } return {'result': None, 'error': error} + page_data = page_data and json.loads(page_data) or {} try: services = get_services() - result, error = services.getcontacts(domain, acct, startIndex, - maxResults, group) + result, error = services.getcontacts(domain, acct, page_data) except DomainNotRegisteredError: error = { 'message': "'domain' is invalid", diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-auth-successful/expected-f1-response.json b/linkdrop/tests/services/corpus/http-api.linkedin.com-auth-successful/expected-f1-response.json new file mode 100644 index 0000000..46dd0fa --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-auth-successful/expected-f1-response.json @@ -0,0 +1,3 @@ +{ + "status": 302 +} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-auth-successful/meta.json b/linkdrop/tests/services/corpus/http-api.linkedin.com-auth-successful/meta.json new file mode 100644 index 0000000..99dfdbb --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-auth-successful/meta.json @@ -0,0 +1,5 @@ +{ + "protocol": "http", + "reason": "automatic success save", + "uri": "https://api.linkedin.com/uas/oauth/requestToken" +} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-auth-successful/request-0 b/linkdrop/tests/services/corpus/http-api.linkedin.com-auth-successful/request-0 new file mode 100644 index 0000000..cc3c8ba --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-auth-successful/request-0 @@ -0,0 +1,5 @@ +GET /uas/oauth/requestToken +accept-encoding: gzip, deflate +authorization: OAuth realm="", oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_nonce="9999999", oauth_timestamp="1303186687", oauth_consumer_key="the_key", oauth_signature_method="HMAC-SHA1", oauth_version="1.0", oauth_signature="the_sig%3D", oauth_callback="http%3A%2F%2Flinkdrop.caraveo.com%3A5000%2Fapi%2Faccount%2Fverify%3Fprovider%3Dlinkedin.com" +user-agent: Python-httplib2/$Rev$ + diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-auth-successful/response-0 b/linkdrop/tests/services/corpus/http-api.linkedin.com-auth-successful/response-0 new file mode 100644 index 0000000..871e9ef --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-auth-successful/response-0 @@ -0,0 +1,10 @@ +HTTP/1.1 200 OK +status: 200 +content-location: https://api.linkedin.com/uas/oauth/requestToken +vary: Accept-Encoding +server: Apache-Coyote/1.1 +-content-encoding: gzip +date: Tue, 19 Apr 2011 04:19:01 GMT +content-type: text/plain + +oauth_token=the_token&oauth_token_secret=the_secret&oauth_callback_confirmed=true&xoauth_request_auth_url=https%3A%2F%2Fapi.linkedin.com%2Fuas%2Foauth%2Fauthorize&oauth_expires_in=599 diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-contacts-successful/expected-f1-data.json b/linkdrop/tests/services/corpus/http-api.linkedin.com-contacts-successful/expected-f1-data.json new file mode 100644 index 0000000..456a131 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-contacts-successful/expected-f1-data.json @@ -0,0 +1,24 @@ +{ + "error": null, + "result": { + "entry": [ + { + "accounts": [ + { + "domain": "linkedin.com", + "userid": "11111111", + "username": "" + } + ], + "displayName": "Jean Reilly", + "urls": [ + { + "primary": true, + "type": "profile", + "value": "http://www.linkedin.com/profile?viewProfile=&key=999999&authToken=xxxx&authType=name&trk=api*xxx*xxx*" + } + ] + } + ] + } +} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-contacts-successful/meta.json b/linkdrop/tests/services/corpus/http-api.linkedin.com-contacts-successful/meta.json new file mode 100644 index 0000000..42fe2a5 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-contacts-successful/meta.json @@ -0,0 +1,5 @@ +{ + "protocol": "http", + "reason": "automatic success save", + "uri": "http://api.linkedin.com/v1/people/~/connections?count=25" +} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-contacts-successful/request-0 b/linkdrop/tests/services/corpus/http-api.linkedin.com-contacts-successful/request-0 new file mode 100644 index 0000000..e52eb13 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-contacts-successful/request-0 @@ -0,0 +1,5 @@ +GET /v1/people/~/connections?count=25 +x-li-format: json +accept-encoding: gzip, deflate +user-agent: Python-httplib2/$Rev$ + diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-contacts-successful/response-0 b/linkdrop/tests/services/corpus/http-api.linkedin.com-contacts-successful/response-0 new file mode 100644 index 0000000..5c02c0a --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-contacts-successful/response-0 @@ -0,0 +1,35 @@ +HTTP/1.1 200 OK +status: 200 +content-location: http://api.linkedin.com/v1/people/~/connections?count=500&oauth_body_hash=K%2BiMpCQsduglOsYkdIUQZQMtaDM%3D&oauth_nonce999999&oauth_timestamp=1303186697&oauth_consumer_key=the_key&oauth_signature_method=HMAC-SHA1&oauth_version=1.0&oauth_token=the_token&oauth_signature=the_sig%3D +vary: x-li-format,Accept-Encoding +server: Apache-Coyote/1.1 +-content-encoding: gzip +date: Tue, 19 Apr 2011 04:19:09 GMT +x-li-format: json +content-type: application/json;charset=UTF-8 + +{ + "values": [{ + "headline": "Banking Professional", + "id": "11111111", + "lastName": "Reilly", + "location": { + "name": "Vancouver, Canada Area", + "country": {"code": "ca"} + }, + "siteStandardProfileRequest": {"url": "http://www.linkedin.com/profile?viewProfile=&key=999999&authToken=xxxx&authType=name&trk=api*xxx*xxx*"}, + "apiStandardProfileRequest": { + "headers": { + "values": [{ + "name": "x-li-auth-token", + "value": "name:TVgH" + }], + "_total": 1 + }, + "url": "http://api.linkedin.com/v1/people/11111111" + }, + "industry": "Banking", + "firstName": "Jean" + }], + "_total": 1 +} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/expected-f1-data.json b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/expected-f1-data.json new file mode 100644 index 0000000..f822209 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/expected-f1-data.json @@ -0,0 +1,13 @@ +{ + "error": null, + "result": { + "date": "Tue, 19 Apr 2011 05:24:44 GMT", + "from": null, + "location": "http://api.linkedin.com/v1/people/ppppppp/shares/sssssss", + "server": "Apache-Coyote/1.1", + "shorturl": null, + "status": "201", + "to": "anyone", + "vary": "Accept-Encoding" + } +} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/f1-request.json b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/f1-request.json new file mode 100644 index 0000000..cf5f9f3 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/f1-request.json @@ -0,0 +1,8 @@ +{"domain": "linkedin.com", + "shareType": "public", + "to": "anyone", + "message": "nerdy for anyone", + "link": "http://slashdot.org/", + "title": "Slashdot: News for nerds, stuff that matters", + "account": {"oauth_token": "foo", "oauth_token_secret": "bar", "username": "mylinkedinid"} +} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/meta.json b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/meta.json new file mode 100644 index 0000000..72649de --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/meta.json @@ -0,0 +1,5 @@ +{ + "protocol": "http", + "reason": "automatic success save", + "uri": "http://api.linkedin.com/v1/people/~/shares" +} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/request-0 b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/request-0 new file mode 100644 index 0000000..47cc5b4 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/request-0 @@ -0,0 +1,7 @@ +POST /v1/people/~/shares +x-li-format: json +content-type: application/json +authorization: OAuth realm="http://api.linkedin.com", oauth_body_hash="the_hash_value", oauth_nonce="111111", oauth_timestamp="1303190627", oauth_consumer_key="the_consumer_key", oauth_signature_method="HMAC-SHA1", oauth_version="1.0", oauth_token="the_token", oauth_signature="the_sig%3D" +user-agent: Python-httplib2/$Rev$ + +{"comment": "nerdy for anyone", "content": {"submitted-image-url": "", "description": "", "submitted-url": "http://slashdot.org/", "title": ""}, "visibility": {"code": "anyone"}} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/response-0 b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/response-0 new file mode 100644 index 0000000..86a4153 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-anyone-successful/response-0 @@ -0,0 +1,7 @@ +HTTP/1.1 201 Created +status: 201 +vary: Accept-Encoding +server: Apache-Coyote/1.1 +location: http://api.linkedin.com/v1/people/ppppppp/shares/sssssss +date: Tue, 19 Apr 2011 05:24:44 GMT + diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/expected-f1-data.json b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/expected-f1-data.json new file mode 100644 index 0000000..a4841d8 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/expected-f1-data.json @@ -0,0 +1,14 @@ +{ + "error": null, + "result": { + "content-length": "0", + "date": "Tue, 19 Apr 2011 07:11:40 GMT", + "from": null, + "location": "http://api.linkedin.com/v1/people/pppppppp/shares/ssssssss", + "server": "Apache-Coyote/1.1", + "shorturl": null, + "status": "201", + "to": "connections-only", + "vary": "Accept-Encoding" + } +} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/f1-request.json b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/f1-request.json new file mode 100644 index 0000000..67fefb1 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/f1-request.json @@ -0,0 +1,8 @@ +{"domain": "linkedin.com", + "shareType": "myConnections", + "to": "connections-only", + "message": "nerdy for my connections!", + "link": "http://slashdot.org/", + "title": "Slashdot: News for nerds, stuff that matters", + "account": {"oauth_token": "foo", "oauth_token_secret": "bar", "username": "mylinkedinid"} +} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/meta.json b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/meta.json new file mode 100644 index 0000000..72649de --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/meta.json @@ -0,0 +1,5 @@ +{ + "protocol": "http", + "reason": "automatic success save", + "uri": "http://api.linkedin.com/v1/people/~/shares" +} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/request-0 b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/request-0 new file mode 100644 index 0000000..751c2a0 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/request-0 @@ -0,0 +1,7 @@ +POST /v1/people/~/shares +x-li-format: json +content-type: application/json +authorization: OAuth realm="http://api.linkedin.com", oauth_body_hash="the_hash%3D", oauth_nonce="9999999", oauth_timestamp="1303197039", oauth_consumer_key="the_key", oauth_signature_method="HMAC-SHA1", oauth_version="1.0", oauth_token="the_token", oauth_signature="the_sig%3D" +user-agent: Python-httplib2/$Rev$ + +{"comment": "nerdy for my connections!", "content": {"submitted-image-url": "", "description": "", "submitted-url": "http://slashdot.org/", "title": ""}, "visibility": {"code": "connections-only"}} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/response-0 b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/response-0 new file mode 100644 index 0000000..61af951 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-connections-successful/response-0 @@ -0,0 +1,8 @@ +HTTP/1.1 201 Created +status: 201 +content-length: 0 +vary: Accept-Encoding +server: Apache-Coyote/1.1 +location: http://api.linkedin.com/v1/people/pppppppp/shares/ssssssss +date: Tue, 19 Apr 2011 07:11:40 GMT + diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/expected-f1-data.json b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/expected-f1-data.json new file mode 100644 index 0000000..ac835d4 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/expected-f1-data.json @@ -0,0 +1,13 @@ +{ + "error": null, + "result": { + "content-length": "0", + "date": "Tue, 19 Apr 2011 07:14:32 GMT", + "from": null, + "server": "Apache-Coyote/1.1", + "shorturl": null, + "status": "201", + "to": "ppppp", + "vary": "Accept-Encoding" + } +} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/f1-request.json b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/f1-request.json new file mode 100644 index 0000000..c8b0be3 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/f1-request.json @@ -0,0 +1,11 @@ +{"domain": "linkedin.com", + "shareType": "contact", + "to": "ppppp", + "message": "nerdy just for you!", + "link": "http://slashdot.org/", + "title": "Slashdot: News for nerds, stuff that matters", + "account": {"oauth_token": "foo", + "oauth_token_secret": "bar", + "username": "mylinkedinid", + "verifiedEmail": "me@somewhere.com"} +} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/meta.json b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/meta.json new file mode 100644 index 0000000..581011c --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/meta.json @@ -0,0 +1,5 @@ +{ + "protocol": "http", + "reason": "automatic success save", + "uri": "http://api.linkedin.com/v1/people/~/mailbox" +} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/request-0 b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/request-0 new file mode 100644 index 0000000..0cc1727 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/request-0 @@ -0,0 +1,7 @@ +POST /v1/people/~/mailbox +x-li-format: json +content-type: application/json +authorization: OAuth realm="http://api.linkedin.com", oauth_body_hash="the_hash%3D", oauth_nonce="999999", oauth_timestamp="1303197211", oauth_consumer_key="the_key", oauth_signature_method="HMAC-SHA1", oauth_version="1.0", oauth_token="the_token", oauth_signature="the_sig%3D" +user-agent: Python-httplib2/$Rev$ + +{"body": "nerdy just for you!\n\n*Slashdot: News for nerds, stuff that matters*\n\nhttp://slashdot.org/\n\n\n\n--\nshared via Mozilla F1 for Firefox -- http://f1.mozillamessaging.com/\n:: share links with the people that matter to you ::\n", "recipients": {"values": [{"person": {"_path": "/people/ppppp"}}]}, "subject": "A web link has been shared with you"} diff --git a/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/response-0 b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/response-0 new file mode 100644 index 0000000..a3c1258 --- /dev/null +++ b/linkdrop/tests/services/corpus/http-api.linkedin.com-send-private-successful/response-0 @@ -0,0 +1,7 @@ +HTTP/1.1 201 Created +date: Tue, 19 Apr 2011 07:14:32 GMT +status: 201 +content-length: 0 +vary: Accept-Encoding +server: Apache-Coyote/1.1 + diff --git a/linkdrop/tests/services/corpus/http-api.twitter.com-contacts-successful/request-0 b/linkdrop/tests/services/corpus/http-api.twitter.com-contacts-successful/request-0 index a89350f..4f90d28 100644 --- a/linkdrop/tests/services/corpus/http-api.twitter.com-contacts-successful/request-0 +++ b/linkdrop/tests/services/corpus/http-api.twitter.com-contacts-successful/request-0 @@ -1,4 +1,4 @@ -GET /1/statuses/followers.json?screen_name=mytwitterid +GET /1/statuses/followers.json?screen_name=mytwitterid&cursor=-1 accept-encoding: gzip, deflate user-agent: Python-httplib2/$Rev$ diff --git a/linkdrop/tests/services/corpus/http-api.twitter.com-contacts-successful/response-0 b/linkdrop/tests/services/corpus/http-api.twitter.com-contacts-successful/response-0 index 5caac76..e125ff6 100644 --- a/linkdrop/tests/services/corpus/http-api.twitter.com-contacts-successful/response-0 +++ b/linkdrop/tests/services/corpus/http-api.twitter.com-contacts-successful/response-0 @@ -20,7 +20,8 @@ x-ratelimit-limit: 350 content-type: application/json; charset=utf-8 x-ratelimit-reset: 1302676561 -[ +{ + "users": [ { "follow_request_sent":false, "profile_background_image_url":"http:\/\/a3.twimg.com\/a\/1302541726\/images\/themes\/theme1\/bg.png", @@ -99,4 +100,9 @@ x-ratelimit-reset: 1302676561 "utc_offset":36000, "profile_background_color":"C0DEED" } -] + ], + "next_cursor":0, + "previous_cursor":0, + "next_cursor_str":"0", + "previous_cursor_str":"0" +} diff --git a/linkdrop/tests/services/corpus/http-graph.facebook.com-contacts-list-no-groups/expected-f1-data.json b/linkdrop/tests/services/corpus/http-graph.facebook.com-contacts-list-no-groups/expected-f1-data.json index 6aeeff2..af415cb 100644 --- a/linkdrop/tests/services/corpus/http-graph.facebook.com-contacts-list-no-groups/expected-f1-data.json +++ b/linkdrop/tests/services/corpus/http-graph.facebook.com-contacts-list-no-groups/expected-f1-data.json @@ -3,7 +3,6 @@ "result": { "entry": [], "itemsPerPage": 0, - "startIndex": 0, - "totalResults": 0 + "startIndex": 0 } } diff --git a/linkdrop/tests/services/corpus/http-social.yahooapis.com-contacts-success/expected-f1-data.json b/linkdrop/tests/services/corpus/http-social.yahooapis.com-contacts-success/expected-f1-data.json index 83c055f..69be310 100644 --- a/linkdrop/tests/services/corpus/http-social.yahooapis.com-contacts-success/expected-f1-data.json +++ b/linkdrop/tests/services/corpus/http-social.yahooapis.com-contacts-success/expected-f1-data.json @@ -12,9 +12,6 @@ ], "nickname": "test" } - ], - "itemsPerPage": 1, - "startIndex": 0, - "totalResults": 1 + ] } } diff --git a/linkdrop/tests/services/test_playback.py b/linkdrop/tests/services/test_playback.py index 162b190..aa8dd2c 100644 --- a/linkdrop/tests/services/test_playback.py +++ b/linkdrop/tests/services/test_playback.py @@ -53,8 +53,16 @@ def assert_messages_equal(got, expected): got_items = dict(parse_qsl(gotpl)) expected_items = dict(parse_qsl(expectedpl)) assert_dicts_with_oauth_equal(got_items, expected_items) + elif got.get_content_type() == "application/json": + got_items = json.loads(gotpl) + expected_items = json.loads(expectedpl) + assert_dicts_equal(got_items, expected_items) + elif gotpl is None: + assert expectedpl is None else: - eq_(gotpl, expectedpl) + # rstrip the payloads as some of our corpus items have trailing + # newlines to stop git/hg/etc complaining... + eq_(gotpl.rstrip(), expectedpl.rstrip()) # Somewhat analogous to a protocap.ProtocolCapturingBase object - but @@ -97,7 +105,7 @@ class HttpReplayer(ProtocolReplayer): gotheadersstr = "\r\n".join( ["%s: %s" % (n, v.encode("ascii")) for n, v in headers.iteritems()]) - bodystr = gotheadersstr + "\r\n" + (body or '') + bodystr = gotheadersstr + "\r\n\r\n" + (body or '') gotob = email.message_from_string(bodystr) if headers: if 'content-type' in gotob: @@ -367,6 +375,28 @@ class GoogleReplayTestCase(ServiceReplayTestCase): raise AssertionError(req_type) +class LinkedinReplayTestCase(ServiceReplayTestCase): + def getDefaultRequest(self, req_type): + # No 'send' - all send tests have an f1-request.json file... + if req_type == "contacts": + account = {"oauth_token": "foo", "oauth_token_secret": "bar", + "profile": {"emails": [{'value': 'me@example.com'}], + "displayName": "Me", + }, + } + return {'username': 'me', + 'userid': '123', + 'keys': "1,2,3", + 'account': json.dumps(account), + 'domain': 'linkedin.com', + 'maxresults': 500, + } + if req_type == "auth": + return {'domain': 'linkedin.com', 'username': 'foo', + 'userid': 'bar'} + raise AssertionError(req_type) + + def setupReplayers(): from linkoauth.backends import facebook_ facebook_.HttpRequestor = HttpReplayer @@ -377,6 +407,8 @@ def setupReplayers(): google_.OAuth2Requestor = HttpReplayer from linkoauth.backends import twitter_ twitter_.OAuth2Requestor = HttpReplayer + from linkoauth.backends import linkedin_ + linkedin_.OAuth2Requestor = HttpReplayer import linkoauth.oauth linkoauth.oauth.HttpRequestor = HttpReplayer HttpReplayer.to_playback = [] @@ -396,6 +428,8 @@ def teardownReplayers(): google_.OAuth2Requestor = linkoauth.protocap.OAuth2Requestor from linkoauth.backends import twitter_ twitter_.OAuth2Requestor = linkoauth.protocap.OAuth2Requestor + from linkoauth.backends import linkedin_ + linkedin_.OAuth2Requestor = linkoauth.protocap.OAuth2Requestor from linkoauth import oauth oauth.HttpRequestor = linkoauth.protocap.HttpRequestor @@ -408,6 +442,7 @@ host_to_test = { 'social.yahooapis.com': YahooReplayTestCase, 'api.twitter.com': TwitterReplayTestCase, 'twitter.com': TwitterReplayTestCase, + 'api.linkedin.com': LinkedinReplayTestCase, } diff --git a/test.ini b/test.ini index 7e370e5..14c8853 100644 --- a/test.ini +++ b/test.ini @@ -70,6 +70,12 @@ oauth.yahoo.com.app_id = FILL_ME_IN # set to true if you have completed domain verification with Yahoo oauth.yahoo.com.verified = 0 +oauth.linkedin.com.consumer_key = A_BIT_OF_A_SECRET +oauth.linkedin.com.consumer_secret = TOP_SECRET +oauth.linkedin.com.request = https://api.linkedin.com/uas/oauth/requestToken +oauth.linkedin.com.access = https://api.linkedin.com/uas/oauth/accessToken +oauth.linkedin.com.authorize = https://api.linkedin.com/uas/oauth/authorize + sstatus.enabled = 0 sstatus.servers = 127.0.0.1:11211 sstatus.domains = google.com,twitter.com,facebook.com,linkedin.com diff --git a/web/dev/1/scripts/Contacts.js b/web/dev/1/scripts/Contacts.js index 136e893..c7ee059 100644 --- a/web/dev/1/scripts/Contacts.js +++ b/web/dev/1/scripts/Contacts.js @@ -129,36 +129,49 @@ function ($, object, fn, dispatch, rdapi, accounts) { })); }, - fetch: function () { + fetch: function (pageData) { var acct = this.svcAccount; accounts.getService(acct.domain, acct.userid, acct.username, fn.bind(this, function (svcData) { + + var data = { + username: acct.username, + userid: acct.userid, + account: JSON.stringify(svcData) + }; + if (pageData) { + data.pageData = JSON.stringify(pageData); + } rdapi('contacts/' + acct.domain, { type: 'POST', - data: { - username: acct.username, - userid: acct.userid, - startindex: 0, - maxresults: 500, - account: JSON.stringify(svcData) - }, + data: data, //Only wait for 10 seconds, then give up. timeout: 10000, success: fn.bind(this, function (json) { //Transform data to a form usable by the front end. if (json && !json.error) { var entries = json.result.entry; + var nextPageData = json.result.pageData; this.getFormattedContacts(entries, fn.bind(this, function (contacts) { - this.contacts = contacts; + if (!pageData) { + this.contacts = contacts; + } else { + this.contacts.push.apply(this.contacts, contacts); + } this.lastUpdated = (new Date()).getTime(); this.toStore({ list: this.contacts }); + if (nextPageData) { + setTimeout(fn.bind(this, function(nextPageData) { + this.fetch(nextPageData); + }), 1, nextPageData); + } }) ); }