Skip to content

Commit 08bba4f

Browse files
committed
Proper testing of the caching
1 parent e357059 commit 08bba4f

File tree

2 files changed

+42
-22
lines changed

2 files changed

+42
-22
lines changed

spec/ParseLiveQueryServer.spec.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,14 @@ describe('ParseLiveQueryServer', function() {
6161
jasmine.mockLibrary('../lib/LiveQuery/ParsePubSub', 'ParsePubSub', mockParsePubSub);
6262
spyOn(auth, 'getAuthForSessionToken').and.callFake(({ sessionToken, cacheController }) => {
6363
if (typeof sessionToken === 'undefined') {
64-
return Promise.reject(/*new auth.Auth({ user: undefined })*/);
64+
return Promise.reject();
6565
}
6666
if (sessionToken === null) {
6767
return Promise.reject();
6868
}
69+
if (sessionToken === 'pleaseThrow') {
70+
return Promise.reject();
71+
}
6972
return Promise.resolve(new auth.Auth({ cacheController, user: { id: testUserId }}));
7073
});
7174
done();
@@ -1388,7 +1391,27 @@ describe('ParseLiveQueryServer', function() {
13881391
expect(isMatched).toBe(false);
13891392
done();
13901393
});
1394+
});
13911395

1396+
it('should properly pull auth from cache', () => {
1397+
const parseLiveQueryServer = new ParseLiveQueryServer({});
1398+
const promise = parseLiveQueryServer.getAuthForSessionToken('sessionToken');
1399+
const secondPromise = parseLiveQueryServer.getAuthForSessionToken('sessionToken');
1400+
// should be in the cache
1401+
expect(parseLiveQueryServer.authCache.get('sessionToken')).toBe(promise);
1402+
// should be the same promise returned
1403+
expect(promise).toBe(secondPromise);
1404+
// the auth should be called only once
1405+
expect(auth.getAuthForSessionToken.calls.count()).toBe(1);
1406+
});
1407+
1408+
it('should delete from cache throwing auth calls', async () => {
1409+
const parseLiveQueryServer = new ParseLiveQueryServer({});
1410+
const promise = parseLiveQueryServer.getAuthForSessionToken('pleaseThrow');
1411+
expect(parseLiveQueryServer.authCache.get('pleaseThrow')).toBe(promise);
1412+
// after the promise finishes, it should have removed it from the cache
1413+
expect(await promise).toEqual({});
1414+
expect(parseLiveQueryServer.authCache.get('pleaseThrow')).toBe(undefined);
13921415
});
13931416

13941417
afterEach(function(){

src/LiveQuery/ParseLiveQueryServer.js

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -351,19 +351,17 @@ class ParseLiveQueryServer {
351351
if (fromCache) {
352352
return fromCache;
353353
}
354-
try {
355-
const authPromise = getAuthForSessionToken({ cacheController: this.cacheController, sessionToken: sessionToken })
356-
.then((auth) => {
357-
return { auth, userId: auth && auth.user && auth.user.id };
358-
}, () => {
359-
// If you can't continue, let's just wrap it up and delete it.
360-
// Next time, one will try again
361-
this.authCache.del(sessionToken);
362-
});
363-
this.authCache.set(sessionToken, authPromise);
364-
return authPromise;
365-
} catch(e) { /* ignore errors */ }
366-
return Promise.resolve({});
354+
const authPromise = getAuthForSessionToken({ cacheController: this.cacheController, sessionToken: sessionToken })
355+
.then((auth) => {
356+
return { auth, userId: auth && auth.user && auth.user.id };
357+
}, () => {
358+
// If you can't continue, let's just wrap it up and delete it.
359+
// Next time, one will try again
360+
this.authCache.del(sessionToken);
361+
return {};
362+
});
363+
this.authCache.set(sessionToken, authPromise);
364+
return authPromise;
367365
}
368366

369367
async _matchesCLP(classLevelPermissions: ?any, object: any, client: any, requestId: number, op: string): any {
@@ -379,10 +377,10 @@ class ParseLiveQueryServer {
379377
}
380378
try {
381379
await SchemaController.validatePermission(classLevelPermissions, object.className, aclGroup, op);
382-
return Promise.resolve(true);
380+
return true;
383381
} catch(e) {
384382
logger.verbose(`Failed matching CLP for ${object.id} ${userId} ${e}`);
385-
return Promise.resolve(false);
383+
return false;
386384
}
387385
// TODO: handle roles permissions
388386
// Object.keys(classLevelPermissions).forEach((key) => {
@@ -403,22 +401,22 @@ class ParseLiveQueryServer {
403401
&& typeof query.objectId === 'string' ? 'get' : 'find';
404402
}
405403

406-
async _matchesACL(acl: any, client: any, requestId: number): any {
404+
async _matchesACL(acl: any, client: any, requestId: number): Promise<boolean> {
407405
// Return true directly if ACL isn't present, ACL is public read, or client has master key
408406
if (!acl || acl.getPublicReadAccess() || client.hasMasterKey) {
409-
return Promise.resolve(true);
407+
return true;
410408
}
411409
// Check subscription sessionToken matches ACL first
412410
const subscriptionInfo = client.getSubscriptionInfo(requestId);
413411
if (typeof subscriptionInfo === 'undefined') {
414-
return Promise.resolve(false);
412+
return false;
415413
}
416414

417415
// TODO: get auth there and de-duplicate code below to work with the same Auth obj.
418416
const { auth, userId } = await this.getAuthForSessionToken(subscriptionInfo.sessionToken);
419417
const isSubscriptionSessionTokenMatched = acl.getReadAccess(userId);
420418
if (isSubscriptionSessionTokenMatched) {
421-
return Promise.resolve(true);
419+
return true;
422420
}
423421

424422
// Check if the user has any roles that match the ACL
@@ -453,8 +451,7 @@ class ParseLiveQueryServer {
453451
} else {
454452
return isRoleMatched;
455453
}
456-
}).catch((error) => {
457-
error;
454+
}).catch(() => {
458455
return false;
459456
});
460457
}

0 commit comments

Comments
 (0)