Skip to content

Commit 79caaee

Browse files
committed
add impersonateQuery integration tests for every auth mode
1 parent 991819d commit 79caaee

File tree

2 files changed

+211
-56
lines changed

2 files changed

+211
-56
lines changed

src/data-connect/data-connect-api-client-internal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ export class DataConnectApiClient {
220220
return resp;
221221
})
222222
.catch((err) => {
223-
console.log(err)
223+
// console.log(err)
224224
throw this.toFirebaseError(err);
225225
});
226226
}

test/integration/data-connect.spec.ts

Lines changed: 210 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -168,18 +168,38 @@ describe('getDataConnect()', () => {
168168
})
169169
}`;
170170

171+
const optsUnauthorizedClaims: GraphqlOptions<undefined> = {
172+
impersonate: {
173+
unauthenticated: true
174+
}
175+
};
176+
177+
const optsAuthorizedFredAnonClaims: GraphqlOptions<undefined> = {
178+
impersonate: {
179+
authClaims: {
180+
sub: fredUser.id,
181+
firebase: {
182+
identities: { who: 'me' },
183+
sign_in_provider: 'anonymous'
184+
}
185+
}
186+
}
187+
};
188+
171189
const optsAuthorizedFredClaims: GraphqlOptions<undefined> = {
172190
impersonate: {
173191
authClaims: {
174192
sub: fredUser.id,
175-
email_verified: true
176193
}
177194
}
178195
};
179196

180-
const optsUnauthorizedClaims: GraphqlOptions<undefined> = {
197+
const optsAuthorizedFredVerifiedClaims: GraphqlOptions<undefined> = {
181198
impersonate: {
182-
unauthenticated: true
199+
authClaims: {
200+
sub: fredUser.id,
201+
email_verified: true
202+
}
183203
}
184204
};
185205

@@ -192,40 +212,6 @@ describe('getDataConnect()', () => {
192212
}
193213
};
194214

195-
// const optsAuthorizedClaims: GraphqlOptions<undefined> = {
196-
// impersonate: {
197-
// authClaims: {
198-
// sub: fredUser.id,
199-
// email_verified: true,
200-
// firebase: {
201-
// identities: { who: 'me' },
202-
// sign_in_provider: 'google.com'
203-
// }
204-
// }
205-
// }
206-
// };
207-
208-
// const optsAnonymousClaims: GraphqlOptions<undefined> = {
209-
// impersonate: {
210-
// authClaims: {
211-
// sub: fredUser.id,
212-
// email_verified: true,
213-
// firebase: {
214-
// identities: { who: 'me' },
215-
// sign_in_provider: 'anonymous'
216-
// }
217-
// }
218-
// }
219-
// };
220-
221-
// const optsUnverifiedClaims: GraphqlOptions<undefined> = {
222-
// impersonate: {
223-
// authClaims: {
224-
// sub: 'non-exisiting-id',
225-
// email_verified: false
226-
// }
227-
// }
228-
// };
229215
describe('executeGraphql* API', () => {
230216
describe('executeGraphql()', () => {
231217
it('executeGraphql() successfully executes a GraphQL mutation', async () => {
@@ -364,7 +350,6 @@ describe('getDataConnect()', () => {
364350

365351
it('executeGraphql() should return null for an impersonated mutation with non-existing authenticated claims',
366352
async () => {
367-
console.log('test')
368353
const resp = await getDataConnect(connectorConfig).executeGraphql<UserUpdateResponse, undefined>(
369354
updateFredrickUserImpersonation, { ...optsNonExistingClaims });
370355
// Should mutate no data
@@ -430,7 +415,7 @@ describe('getDataConnect()', () => {
430415
describe('with unauthenticated impersonation', () => {
431416
it('should successfully execute a query with @auth(level: PUBLIC)', async () => {
432417
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
433-
{ ...optsUnauthorizedClaims, operationName: 'listUsers' }
418+
{ ...optsUnauthorizedClaims, operationName: 'ListUsersPublic' }
434419
);
435420
expect(resp.data.users).to.be.not.empty;
436421
expect(resp.data.users.length).to.be.greaterThan(1);
@@ -439,6 +424,24 @@ describe('getDataConnect()', () => {
439424
});
440425
});
441426

427+
it('should fail to successfully execute a query with @auth(level: USER_ANON)', () => {
428+
return getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
429+
{ ...optsUnauthorizedClaims, operationName: 'ListUsersUserAnon' }
430+
).should.eventually.be.rejected.and.has.property('code', 'data-connect/unauthenticated');
431+
});
432+
433+
it('should fail to successfully execute a query with @auth(level: USER)', async () => {
434+
return getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
435+
{ ...optsUnauthorizedClaims, operationName: 'ListUsersUser' }
436+
).should.eventually.be.rejected.and.has.property('code', 'data-connect/unauthenticated');
437+
});
438+
439+
it('should fail to successfully execute a query with @auth(level: USER_EMAIL_VERIFIED)', () => {
440+
return getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
441+
{ ...optsUnauthorizedClaims, operationName: 'ListUsersUserEmailVerified' }
442+
).should.eventually.be.rejected.and.has.property('code', 'data-connect/unauthenticated');
443+
});
444+
442445
it('should successfully execute a query with @auth(level: NO_ACCESS)', async () => {
443446
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListEmailsResponse, undefined>(
444447
{ ...optsUnauthorizedClaims, operationName: 'ListEmails' }
@@ -447,37 +450,189 @@ describe('getDataConnect()', () => {
447450
expect(resp.data.emails.length).to.equal(1);
448451
expect(resp.data.emails[0]).to.equal(fredEmail);
449452
});
453+
});
454+
455+
describe('with authenticated anonymous impersonation', () => {
456+
it('should successfully execute a query with @auth(level: PUBLIC)', async () => {
457+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
458+
{ ...optsAuthorizedFredAnonClaims, operationName: 'ListUsersPublic' }
459+
);
460+
expect(resp.data.users).to.not.be.empty;
461+
expect(resp.data.users.length).to.be.greaterThan(1);
462+
resp.data.users.forEach(user => {
463+
expect(expectedUserIds).to.include(user.id);
464+
});
465+
});
466+
467+
it('should successfully execute a query with @auth(level: USER_ANON)', async () => {
468+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
469+
{ ...optsAuthorizedFredAnonClaims, operationName: 'ListUsersUserAnon' }
470+
);
471+
expect(resp.data.users).to.not.be.empty;
472+
expect(resp.data.users.length).to.be.greaterThan(1);
473+
resp.data.users.forEach(user => {
474+
expect(expectedUserIds).to.include(user.id);
475+
});
476+
});
450477

451478
it('should fail to successfully execute a query with @auth(level: USER)', async () => {
452479
return getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
453-
{ ...optsUnauthorizedClaims, operationName: 'ListUsersImpersonation' }
480+
{ ...optsAuthorizedFredAnonClaims, operationName: 'ListUsersUser' }
454481
).should.eventually.be.rejected.and.has.property('code', 'data-connect/unauthenticated');
455482
});
456483

457-
it('should fail to successfully execute a query with @auth(level: USER_ANON)', () => {});
484+
it('should fail to successfully execute a query with @auth(level: USER_EMAIL_VERIFIED)', async () => {
485+
return getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
486+
{ ...optsAuthorizedFredAnonClaims, operationName: 'ListUsersUserEmailVerified' }
487+
).should.eventually.be.rejected.and.has.property('code', 'data-connect/unauthenticated');
488+
});
458489

459-
it('should fail to successfully execute a query with @auth(level: USER_EMAIL_VERIFIED)', () => {});
490+
it('should successfully execute a query with @auth(level: NO_ACCESS)', async () => {
491+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
492+
{ ...optsAuthorizedFredAnonClaims, operationName: 'ListUsersNoAccess' }
493+
);
494+
expect(resp.data.users).to.not.be.empty;
495+
expect(resp.data.users.length).to.be.greaterThan(1);
496+
resp.data.users.forEach(user => {
497+
expect(expectedUserIds).to.include(user.id);
498+
});
499+
});
500+
501+
it("should grab the impersonated user's data", async () => {
502+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
503+
{ ...optsAuthorizedFredAnonClaims, operationName: 'ListUsersImpersonationAnon' }
504+
);
505+
expect(resp.data.users).to.not.be.empty;
506+
expect(resp.data.users.length).to.equal(1);
507+
expect(resp.data.users[0].id).to.equal(fredUser.id);
508+
});
460509
});
461-
describe('with authenticated impersonation', () => {
462-
it('should successfully execute a query with @auth(level: PUBLIC)', () => {});
463510

464-
it('should successfully execute a query with @auth(level: NO_ACCESS)', () => {});
511+
describe('with authenticated user impersonation', () => {
512+
it('should successfully execute a query with @auth(level: PUBLIC)', async () => {
513+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
514+
{ ...optsAuthorizedFredClaims, operationName: 'ListUsersPublic' }
515+
);
516+
expect(resp.data.users).to.not.be.empty;
517+
expect(resp.data.users.length).to.be.greaterThan(1);
518+
resp.data.users.forEach(user => {
519+
expect(expectedUserIds).to.include(user.id);
520+
});
521+
});
465522

466-
it(`should successfully execute a query with @auth(level: USER)
467-
if the impersonated user is not anonymous`, () => {});
523+
it('should successfully execute a query with @auth(level: USER_ANON)', async () => {
524+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
525+
{ ...optsAuthorizedFredClaims, operationName: 'ListUsersUserAnon' }
526+
);
527+
expect(resp.data.users).to.not.be.empty;
528+
expect(resp.data.users.length).to.be.greaterThan(1);
529+
resp.data.users.forEach(user => {
530+
expect(expectedUserIds).to.include(user.id);
531+
});
532+
});
468533

469-
it(`should fail to successfully execute a query with @auth(level: USER)
470-
if the impersonated user is anonymous`, () => {});
534+
it('should successfully execute a query with @auth(level: USER)', async () => {
535+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
536+
{ ...optsAuthorizedFredClaims, operationName: 'ListUsersUser' }
537+
);
538+
expect(resp.data.users).to.not.be.empty;
539+
expect(resp.data.users.length).to.be.greaterThan(1);
540+
resp.data.users.forEach(user => {
541+
expect(expectedUserIds).to.include(user.id);
542+
});
543+
});
471544

472-
it('should successfully execute a query with @auth(level: USER_ANON)', () => {});
545+
it('should fail to successfully execute a query with @auth(level: USER_EMAIL_VERIFIED)', async () => {
546+
return getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
547+
{ ...optsAuthorizedFredClaims, operationName: 'ListUsersUserEmailVerified' }
548+
).should.eventually.be.rejected.and.has.property('code', 'data-connect/unauthenticated');
549+
});
473550

474-
it(`should successfully execute a query with @auth(level: USER_EMAIL_VERIFIED)
475-
if the impersonated user has their email verified`, () => {});
551+
it('should successfully execute a query with @auth(level: NO_ACCESS)', async () => {
552+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
553+
{ ...optsAuthorizedFredClaims, operationName: 'ListUsersNoAccess' }
554+
);
555+
expect(resp.data.users).to.not.be.empty;
556+
expect(resp.data.users.length).to.be.greaterThan(1);
557+
resp.data.users.forEach(user => {
558+
expect(expectedUserIds).to.include(user.id);
559+
});
560+
});
476561

477-
it(`should fail to successfully execute a query with @auth(level: USER_EMAIL_VERIFIED)
478-
if the impersonated user does not have email verified`, () => {});
562+
it("should grab the impersonated user's data", async () => {
563+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
564+
{ ...optsAuthorizedFredClaims, operationName: 'ListUsersImpersonationAnon' }
565+
);
566+
expect(resp.data.users).to.not.be.empty;
567+
expect(resp.data.users.length).to.equal(1);
568+
expect(resp.data.users[0].id).to.equal(fredUser.id);
569+
});
570+
});
479571

480-
it("should grab the impersonated user's data", () => {});
572+
describe('with authenticated email verified user impersonation', () => {
573+
it('should successfully execute a query with @auth(level: PUBLIC)', async () => {
574+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
575+
{ ...optsAuthorizedFredVerifiedClaims, operationName: 'ListUsersPublic' }
576+
);
577+
expect(resp.data.users).to.not.be.empty;
578+
expect(resp.data.users.length).to.be.greaterThan(1);
579+
resp.data.users.forEach(user => {
580+
expect(expectedUserIds).to.include(user.id);
581+
});
582+
});
583+
584+
it('should successfully execute a query with @auth(level: USER_ANON)', async () => {
585+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
586+
{ ...optsAuthorizedFredVerifiedClaims, operationName: 'ListUsersUserAnon' }
587+
);
588+
expect(resp.data.users).to.not.be.empty;
589+
expect(resp.data.users.length).to.be.greaterThan(1);
590+
resp.data.users.forEach(user => {
591+
expect(expectedUserIds).to.include(user.id);
592+
});
593+
});
594+
595+
it('should successfully execute a query with @auth(level: USER)', async () => {
596+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
597+
{ ...optsAuthorizedFredVerifiedClaims, operationName: 'ListUsersUser' }
598+
);
599+
expect(resp.data.users).to.not.be.empty;
600+
expect(resp.data.users.length).to.be.greaterThan(1);
601+
resp.data.users.forEach(user => {
602+
expect(expectedUserIds).to.include(user.id);
603+
});
604+
});
605+
606+
it('should successfully execute a query with @auth(level: USER_EMAIL_VERIFIED)', async () => {
607+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
608+
{ ...optsAuthorizedFredVerifiedClaims, operationName: 'ListUsersUserEmailVerified' }
609+
);
610+
expect(resp.data.users).to.not.be.empty;
611+
expect(resp.data.users.length).to.be.greaterThan(1);
612+
resp.data.users.forEach(user => {
613+
expect(expectedUserIds).to.include(user.id);
614+
});
615+
});
616+
617+
it('should successfully execute a query with @auth(level: NO_ACCESS)', async () => {
618+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
619+
{ ...optsAuthorizedFredVerifiedClaims, operationName: 'ListUsersNoAccess' }
620+
);
621+
expect(resp.data.users).to.not.be.empty;
622+
expect(resp.data.users.length).to.be.greaterThan(1);
623+
resp.data.users.forEach(user => {
624+
expect(expectedUserIds).to.include(user.id);
625+
});
626+
});
627+
628+
it("should grab the impersonated user's data", async () => {
629+
const resp = await getDataConnect(connectorConfig).impersonateQuery<ListUsersResponse, undefined>(
630+
{ ...optsAuthorizedFredVerifiedClaims, operationName: 'ListUsersImpersonationAnon' }
631+
);
632+
expect(resp.data.users).to.not.be.empty;
633+
expect(resp.data.users.length).to.equal(1);
634+
expect(resp.data.users[0].id).to.equal(fredUser.id);
635+
});
481636
});
482637
});
483638

0 commit comments

Comments
 (0)