diff --git a/recordings/Friendship_3941134439/-request_4101572646/recording.har b/recordings/Friendship_3941134439/-request_4101572646/recording.har new file mode 100644 index 000000000..9ef701f9e --- /dev/null +++ b/recordings/Friendship_3941134439/-request_4101572646/recording.har @@ -0,0 +1,138 @@ +{ + "log": { + "_recordingName": "Friendship/.request", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "2.6.2" + }, + "entries": [ + { + "_id": "78cb055f5bef47633f61ab03fccc7d13", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 2, + "cookies": [], + "headers": [ + { + "name": "accept-encoding", + "value": "gzip, deflate" + }, + { + "name": "user-agent", + "value": "LeanCloud-JS-SDK/4.1.0 (Node.js; Node.js/v12.13.1)" + }, + { + "name": "x-lc-id", + "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "x-lc-sign", + "value": "4f23eeb4d02c43a30cee68244baeaa20,1577421062671" + }, + { + "name": "x-lc-hook-key", + "value": "2iCbUZDgEF0siKxmCn2kVQXV" + }, + { + "name": "x-lc-prod", + "value": "1" + }, + { + "name": "x-lc-session", + "value": "pijbhvhbq6noqi8sdaylrpby0" + }, + { + "name": "content-length", + "value": 2 + }, + { + "name": "host", + "value": "95tnuaos.lc-cn-e1-shared.com" + } + ], + "headersSize": 509, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json;charset=UTF-8", + "params": [], + "text": "{}" + }, + "queryString": [], + "url": "https://95tnuaos.lc-cn-e1-shared.com/1.1/users/self/friendship/5e05890eff02830008f3a54c/request" + }, + "response": { + "bodySize": 196, + "content": { + "mimeType": "application/json;charset=utf-8", + "size": 196, + "text": "[\"1f8b08000000000000030dca2b0e80301005c0bbaca6e46d3fb0ad43e251b8d26e058684d411ee0ea3e7a1eb38b5f4b552a2a00812a1adc18a0320cde5e095062ab7e6ae75e97fb3e068d81a3b6ff0c971628c13cb4eef07e21575874e000000\"]" + }, + "cookies": [], + "headers": [ + { + "name": "server", + "value": "openresty" + }, + { + "name": "date", + "value": "Fri, 27 Dec 2019 04:31:10 GMT" + }, + { + "name": "content-type", + "value": "application/json;charset=utf-8" + }, + { + "name": "transfer-encoding", + "value": "chunked" + }, + { + "name": "connection", + "value": "close" + }, + { + "name": "vary", + "value": "Accept-Encoding" + }, + { + "name": "cache-control", + "value": "no-cache,no-store" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-encoding", + "value": "gzip" + } + ], + "headersSize": 250, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2019-12-27T04:31:02.683Z", + "time": 107, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 107 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/recordings/Friendship_3941134439/-request_4101572646/shoud-return-void_1600384442/recording.har b/recordings/Friendship_3941134439/-request_4101572646/shoud-return-void_1600384442/recording.har new file mode 100644 index 000000000..c87e7b49f --- /dev/null +++ b/recordings/Friendship_3941134439/-request_4101572646/shoud-return-void_1600384442/recording.har @@ -0,0 +1,138 @@ +{ + "log": { + "_recordingName": "Friendship/.request/shoud return void", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "2.6.2" + }, + "entries": [ + { + "_id": "cb45bab1729dfdeac7f0009dbbbf77c2", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 191, + "cookies": [], + "headers": [ + { + "name": "accept-encoding", + "value": "gzip, deflate" + }, + { + "name": "x-lc-id", + "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "x-lc-sign", + "value": "95f4ba8b1e0a881d2b0b03770d9a513d,1590827736064" + }, + { + "name": "x-lc-hook-key", + "value": "2iCbUZDgEF0siKxmCn2kVQXV" + }, + { + "name": "x-lc-prod", + "value": "1" + }, + { + "name": "user-agent", + "value": "LeanCloud-JS-SDK/4.5.3 (Node.js/v12.16.3)" + }, + { + "name": "x-lc-session", + "value": "0ba67iauprltp56736hjfom50" + }, + { + "name": "content-length", + "value": 191 + }, + { + "name": "host", + "value": "95tnuaos.lc-cn-e1-shared.com" + } + ], + "headersSize": 472, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json;charset=UTF-8", + "params": [], + "text": "{\"user\":{\"__type\":\"Pointer\",\"className\":\"_User\",\"objectId\":\"5ed21ad9d5529d000945b0b6\"},\"friend\":{\"__type\":\"Pointer\",\"className\":\"_User\",\"objectId\":\"5ed21ad9d5529d000945b0b5\"},\"friendship\":{}}" + }, + "queryString": [], + "url": "https://95tnuaos.lc-cn-e1-shared.com/1.1/users/friendshipRequests" + }, + "response": { + "bodySize": 194, + "content": { + "mimeType": "application/json;charset=utf-8", + "size": 194, + "text": "[\"1f8b08000000000000030dca210e80300c05d0bb5433f2e9286c739378146e5b6b3024648e707778fa3d74d5d35adf941289294f458b8a70540071968a1a68a0765be9a6b9ff8dc17010e7b123242fc98711eb72d0fb0124ae102f4e000000\"]" + }, + "cookies": [], + "headers": [ + { + "name": "server", + "value": "openresty" + }, + { + "name": "date", + "value": "Sat, 30 May 2020 08:35:38 GMT" + }, + { + "name": "content-type", + "value": "application/json;charset=utf-8" + }, + { + "name": "transfer-encoding", + "value": "chunked" + }, + { + "name": "connection", + "value": "close" + }, + { + "name": "vary", + "value": "Accept-Encoding" + }, + { + "name": "cache-control", + "value": "no-cache,no-store" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-encoding", + "value": "gzip" + } + ], + "headersSize": 250, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2020-05-30T08:35:36.077Z", + "time": 121, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 121 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/recordings/Friendship_3941134439/query_4174280163/recording.har b/recordings/Friendship_3941134439/query_4174280163/recording.har new file mode 100644 index 000000000..0eec1c2a9 --- /dev/null +++ b/recordings/Friendship_3941134439/query_4174280163/recording.har @@ -0,0 +1,143 @@ +{ + "log": { + "_recordingName": "Friendship/query", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "2.6.2" + }, + "entries": [ + { + "_id": "2870398c13d90d70481a2e2b780ee8f3", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 2, + "cookies": [], + "headers": [ + { + "name": "accept-encoding", + "value": "gzip, deflate" + }, + { + "name": "user-agent", + "value": "LeanCloud-JS-SDK/4.1.0 (Node.js; Node.js/v12.13.1)" + }, + { + "name": "x-lc-id", + "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "x-lc-sign", + "value": "a1d6113b6912348bf4b87e193333e535,1577420537110" + }, + { + "name": "x-lc-hook-key", + "value": "2iCbUZDgEF0siKxmCn2kVQXV" + }, + { + "name": "x-lc-prod", + "value": "1" + }, + { + "name": "x-lc-session", + "value": "boa9t6l4ilt79bwox4ana6wif" + }, + { + "name": "content-length", + "value": 2 + }, + { + "name": "host", + "value": "95tnuaos.lc-cn-e1-shared.com" + } + ], + "headersSize": 518, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json;charset=UTF-8", + "params": [], + "text": "{}" + }, + "queryString": [ + { + "name": "new", + "value": "true" + } + ], + "url": "https://95tnuaos.lc-cn-e1-shared.com/1.1/users/self/friendship/5e058700ff02830008f3a4ce/request?new=true" + }, + "response": { + "bodySize": 354, + "content": { + "mimeType": "application/json;charset=utf-8", + "size": 354, + "text": "[\"1f8b0800000000000003adcf310bc2301086e1ff72732b97b4a1359ba38b08eae2526272814ada942645a4f4bf9b3aeae2e0faf0712f37c31468043943d3c4e74020e1e8db3e26cb403b15c24175ab3697f0367fbb938e7b9348108aba42b416795d20626d0b551a8425033bb6d49b5354710a20ad7281127ae7fc83e89f394d6b4e8fa422995d4c3b8e6c9b339ef3ea8ca5e45c72b1c14a5cd3b56930bfccbea3ece34706cb0bde8f27943a010000\"]" + }, + "cookies": [], + "headers": [ + { + "name": "server", + "value": "openresty" + }, + { + "name": "date", + "value": "Fri, 27 Dec 2019 04:22:25 GMT" + }, + { + "name": "content-type", + "value": "application/json;charset=utf-8" + }, + { + "name": "transfer-encoding", + "value": "chunked" + }, + { + "name": "connection", + "value": "close" + }, + { + "name": "vary", + "value": "Accept-Encoding" + }, + { + "name": "cache-control", + "value": "no-cache,no-store" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-encoding", + "value": "gzip" + } + ], + "headersSize": 250, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2019-12-27T04:22:17.121Z", + "time": 127, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 127 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/recordings/Friendship_3941134439/query_4174280163/should-get-result_299607447/recording.har b/recordings/Friendship_3941134439/query_4174280163/should-get-result_299607447/recording.har new file mode 100644 index 000000000..65c4fce0d --- /dev/null +++ b/recordings/Friendship_3941134439/query_4174280163/should-get-result_299607447/recording.har @@ -0,0 +1,138 @@ +{ + "log": { + "_recordingName": "Friendship/query/should get result", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "2.6.2" + }, + "entries": [ + { + "_id": "d72269118d35773ae41b5cfc25155555", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept-encoding", + "value": "gzip, deflate" + }, + { + "name": "x-lc-id", + "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "x-lc-sign", + "value": "9b2dc8437d8449336da3e796b314925e,1590827736382" + }, + { + "name": "x-lc-hook-key", + "value": "2iCbUZDgEF0siKxmCn2kVQXV" + }, + { + "name": "x-lc-prod", + "value": "1" + }, + { + "name": "user-agent", + "value": "LeanCloud-JS-SDK/4.5.3 (Node.js/v12.16.3)" + }, + { + "name": "x-lc-session", + "value": "0ba67iauprltp56736hjfom50" + }, + { + "name": "host", + "value": "95tnuaos.lc-cn-e1-shared.com" + } + ], + "headersSize": 596, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "where", + "value": "{\"friend\":{\"__type\":\"Pointer\",\"className\":\"_User\",\"objectId\":\"5ed21ad9d5529d000945b0b5\"}}" + } + ], + "url": "https://95tnuaos.lc-cn-e1-shared.com/1.1/classes/_FriendshipRequest?where=%7B%22friend%22%3A%7B%22__type%22%3A%22Pointer%22%2C%22className%22%3A%22_User%22%2C%22objectId%22%3A%225ed21ad9d5529d000945b0b5%22%7D%7D" + }, + "response": { + "bodySize": 360, + "content": { + "mimeType": "application/json;charset=utf-8", + "size": 360, + "text": "[\"1f8b0800000000000003ad8eb10e82301040ffe5663067b106ba39ba18075d348614ee341804d25e0743f8778ba32e0eae2f2f2f6f04c73eb4e2c19c47089e1d9811ca529e0383817ddf74125902756bbddfd9c74ccba37fb3beba732d5b8a4833a9a5a582b456052162b1d215566b9812b8ba863bfa6b57cf5d2f56421c8721e69bee36d71c5b61da48a40a15a6a8d30c0f989b4c9b2c5f28959fa21606fa45fbfeb01f1f054c97e9057529bb1444010000\"]" + }, + "cookies": [], + "headers": [ + { + "name": "server", + "value": "openresty" + }, + { + "name": "date", + "value": "Sat, 30 May 2020 08:35:38 GMT" + }, + { + "name": "content-type", + "value": "application/json;charset=utf-8" + }, + { + "name": "transfer-encoding", + "value": "chunked" + }, + { + "name": "connection", + "value": "close" + }, + { + "name": "vary", + "value": "Accept-Encoding" + }, + { + "name": "cache-control", + "value": "no-cache,no-store" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "last-modified", + "value": "Sat, 30 May 2020 08:35:38.229 GMT" + }, + { + "name": "content-encoding", + "value": "gzip" + } + ], + "headersSize": 300, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2020-05-30T08:35:36.387Z", + "time": 119, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 119 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/friendship.js b/src/friendship.js new file mode 100644 index 000000000..27b76bd77 --- /dev/null +++ b/src/friendship.js @@ -0,0 +1,84 @@ +const _ = require('underscore'); +const { request } = require('./request'); +const { getSessionToken } = require('./utils'); +const AV = require('./av'); + +/** + * @enum + */ +AV.FriendshipRequestStatus = { + PENDING: 'pending', + ACCEPTED: 'accepted', + DECLINED: 'declined', +}; + +AV.FriendshipRequest = AV.Object.extend( + '_FriendshipRequest', + { + accept() {}, + decline() {}, + }, + { + getFriendQuery(friendObjectId) { + return this.query + .include('user') + .equalTo( + 'friend', + AV.Object.createWithoutData(AV.User, friendObjectId) + ); + }, + } +); +AV.Object.register(AV.FriendshipRequest); + +const requireUserLogin = authOptions => { + const sessionToken = getSessionToken(authOptions); + return Promise.resolve( + sessionToken + ? undefined + : AV.User.currentAsync().then(user => { + if (!user) { + throw new Error('Please signin as an user.'); + } + }) + ); +}; + +AV.Friendship = AV.Object.extend( + '_Followee', + /** @lends AV.Friendship.prototype */ {}, + { + request(id, options = {}) { + return requireUserLogin(options).then(currentUser => { + if (!_.isString(id)) { + throw new TypeError( + 'The ID of the requested user must be a valid objectId' + ); + } + const friendshipReq = new AV.FriendshipRequest(); + const _makeRequest = (route, className, _id, method, payload) => + request({ + path: '/users/friendshipRequests', + method: 'POST', + data: { + // TODO: to be removed + user: currentUser._toPointer(), + friend: AV.Object.createWithoutData(AV.User, id)._toPointer(), + friendship: payload, + }, + }); + return friendshipReq + .save(options.attributes, _.extend({ _makeRequest }, options)) + .then(() => undefined); + }); + }, + + getQuery(friendObjectId) { + return this.query + .include('friend') + .equalTo('friendStatus', true) + .equalTo('user', AV.Object.createWithoutData(AV.User, friendObjectId)); + }, + } +); +// AV.Object.register(AV.Friendship); diff --git a/src/index.js b/src/index.js index f1398239a..c32323bac 100644 --- a/src/index.js +++ b/src/index.js @@ -37,6 +37,7 @@ require('./insight')(AV); AV.Conversation = require('./conversation'); require('./leaderboard'); +require('./friendship'); module.exports = AV; /** diff --git a/src/query.js b/src/query.js index bb2c7cc8d..5ffbe570d 100644 --- a/src/query.js +++ b/src/query.js @@ -1121,7 +1121,7 @@ module.exports = function(AV) { } ); - AV.FriendShipQuery = AV.Query._extend({ + AV.FollowshipQuery = AV.Query._extend({ _newObject: function() { const UserClass = AV.Object._getSubclass('_User'); return new UserClass(); diff --git a/src/status.js b/src/status.js index ebbc7357d..8df28dff1 100644 --- a/src/status.js +++ b/src/status.js @@ -6,7 +6,7 @@ module.exports = function(AV) { const getUser = (options = {}) => { const sessionToken = getSessionToken(options); if (sessionToken) { - return AV.User._fetchUserBySessionToken(getSessionToken(options)); + return AV.User._fetchUserBySessionToken(sessionToken); } return AV.User.currentAsync(); }; diff --git a/src/user.js b/src/user.js index 2bb7db19a..9aec40492 100644 --- a/src/user.js +++ b/src/user.js @@ -1459,14 +1459,14 @@ module.exports = function(AV) { /** *Create a follower query for special user to query the user's followers. * @param {String} userObjectId The user object id. - * @return {AV.FriendShipQuery} + * @return {AV.FollowshipQuery} * @since 0.3.0 */ followerQuery: function(userObjectId) { if (!userObjectId || !_.isString(userObjectId)) { throw new Error('Invalid user object id.'); } - var query = new AV.FriendShipQuery('_Follower'); + var query = new AV.FollowshipQuery('_Follower'); query._friendshipTag = 'follower'; query.equalTo( 'user', @@ -1478,14 +1478,14 @@ module.exports = function(AV) { /** *Create a followee query for special user to query the user's followees. * @param {String} userObjectId The user object id. - * @return {AV.FriendShipQuery} + * @return {AV.FollowshipQuery} * @since 0.3.0 */ followeeQuery: function(userObjectId) { if (!userObjectId || !_.isString(userObjectId)) { throw new Error('Invalid user object id.'); } - var query = new AV.FriendShipQuery('_Followee'); + var query = new AV.FollowshipQuery('_Followee'); query._friendshipTag = 'followee'; query.equalTo( 'user', diff --git a/test/friendship.js b/test/friendship.js new file mode 100644 index 000000000..657f398dd --- /dev/null +++ b/test/friendship.js @@ -0,0 +1,47 @@ +import { setupPolly } from './polly'; +import { forceDeleteUser } from './util'; + +describe('Friendship', () => { + setupPolly(); + + before(async function createTestUser() { + const targetUsername = 'friendship-target1'; + await forceDeleteUser(targetUsername); + const sourceUsername = 'friendship-source1'; + await forceDeleteUser(sourceUsername); + this.targetUser = await new AV.User.signUp(targetUsername, targetUsername); + this.currentUser = await AV.User.signUp(sourceUsername, sourceUsername); + }); + + describe('.request', () => { + it('shoud return void', async function() { + const result = await AV.Friendship.request(this.targetUser.id); + expect(result).to.equal(undefined); + }); + it('requires target user ID', function() { + AV.Friendship.request().should.be.rejected(); + }); + }); + + describe('query', () => { + before(function() { + return AV.Friendship.request(this.targetUser.id, { + attributes: { + group: 'closed', + }, + }); + }); + + it('should get result', async function() { + const requests = await AV.FriendshipRequest.getFriendQuery( + this.targetUser.id + ).find({ + user: this.targetUser, + }); + requests.should.be.length(1); + requests[0] + .get('status') + .should.be.eql(AV.FriendshipRequestStatus.PENDING); + }); + }); +}); diff --git a/test/index.js b/test/index.js index 148b3d52d..a2234c6db 100644 --- a/test/index.js +++ b/test/index.js @@ -17,6 +17,7 @@ require('./search.js'); require('./sms.js'); require('./status.js'); require('./user.js'); +require('./friendship.js'); if (process.env.REAL_BACKEND !== undefined) { require('./file.js');
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: