Skip to content

Commit d3c864f

Browse files
test(provider): add test cases for Cognito OAuth (#102)
added test cases for Cognito OAuth gh-97
1 parent 32821de commit d3c864f

File tree

4 files changed

+258
-0
lines changed

4 files changed

+258
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {Provider} from '@loopback/context';
2+
import {Request} from '@loopback/rest';
3+
import {Cognito, IAuthUser, VerifyFunction} from '../../../types';
4+
5+
/**
6+
* A provider for default implementation of VerifyFunction.CognitoAuthFn
7+
*
8+
* It will just throw an error saying Not Implemented
9+
*/
10+
export class BearerTokenVerifyProvider
11+
implements Provider<VerifyFunction.CognitoAuthFn>
12+
{
13+
constructor() {}
14+
15+
value(): VerifyFunction.CognitoAuthFn {
16+
return async (
17+
accessToken: string,
18+
refreshToken: string,
19+
profile: Cognito.Profile,
20+
cb: Cognito.VerifyCallback,
21+
req?: Request,
22+
) => {
23+
const userToPass: IAuthUser = {
24+
id: 1,
25+
username: 'xyz',
26+
password: 'pass',
27+
};
28+
29+
return userToPass;
30+
};
31+
}
32+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import {Client, createClientForHandler} from '@loopback/testlab';
2+
import {RestServer, Request} from '@loopback/rest';
3+
import {Application, Provider} from '@loopback/core';
4+
import {get} from '@loopback/openapi-v3';
5+
import {authenticate} from '../../../../decorators';
6+
import {STRATEGY} from '../../../../strategy-name.enum';
7+
import {getApp} from '../helpers/helpers';
8+
import {MyAuthenticationSequence} from '../../../fixtures/sequences/authentication.sequence';
9+
import {Strategies} from '../../../../strategies/keys';
10+
import {VerifyFunction} from '../../../../strategies';
11+
import {userWithoutReqObj} from '../../../fixtures/data/bearer-data';
12+
import {Cognito} from '../../../../types';
13+
14+
describe('getting cognito oauth2 strategy with options', () => {
15+
let app: Application;
16+
let server: RestServer;
17+
beforeEach(givenAServer);
18+
beforeEach(givenAuthenticatedSequence);
19+
beforeEach(getAuthVerifier);
20+
21+
it('should return 302 when client id is passed and passReqToCallback is set true', async () => {
22+
class TestController {
23+
@get('/test')
24+
@authenticate(STRATEGY.COGNITO_OAUTH2, {
25+
clientID: 'string',
26+
clientSecret: 'string',
27+
passReqToCallback: true,
28+
})
29+
test() {
30+
return 'test successful';
31+
}
32+
}
33+
34+
app.controller(TestController);
35+
36+
await whenIMakeRequestTo(server).get('/test').expect(302);
37+
});
38+
39+
function whenIMakeRequestTo(restServer: RestServer): Client {
40+
return createClientForHandler(restServer.requestHandler);
41+
}
42+
43+
async function givenAServer() {
44+
app = getApp();
45+
server = await app.getServer(RestServer);
46+
}
47+
48+
function getAuthVerifier() {
49+
app
50+
.bind(Strategies.Passport.COGNITO_OAUTH2_VERIFIER)
51+
.toProvider(CognitoAuthVerifyProvider);
52+
}
53+
54+
function givenAuthenticatedSequence() {
55+
// bind user defined sequence
56+
server.sequence(MyAuthenticationSequence);
57+
}
58+
});
59+
60+
class CognitoAuthVerifyProvider
61+
implements Provider<VerifyFunction.CognitoAuthFn>
62+
{
63+
constructor() {}
64+
65+
value(): VerifyFunction.CognitoAuthFn {
66+
return async (
67+
accessToken: string,
68+
refreshToken: string,
69+
profile: Cognito.Profile,
70+
cd: Cognito.VerifyCallback,
71+
req?: Request,
72+
) => {
73+
return userWithoutReqObj;
74+
};
75+
}
76+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import {Client, createClientForHandler} from '@loopback/testlab';
2+
import {RestServer, Request} from '@loopback/rest';
3+
import {Application, Provider} from '@loopback/core';
4+
import {get} from '@loopback/openapi-v3';
5+
import {authenticate} from '../../../../decorators';
6+
import {STRATEGY} from '../../../../strategy-name.enum';
7+
import {getApp} from '../helpers/helpers';
8+
import {Strategies} from '../../../../strategies/keys';
9+
import {VerifyFunction} from '../../../../strategies';
10+
import {userWithoutReqObj} from '../../../fixtures/data/bearer-data';
11+
import {Cognito} from '../../../../types';
12+
import {MyAuthenticationMiddlewareSequence} from '../../../fixtures/sequences/authentication-middleware.sequence';
13+
14+
describe('getting cognito oauth2 strategy with options using Middleware Sequence', () => {
15+
let app: Application;
16+
let server: RestServer;
17+
beforeEach(givenAServer);
18+
beforeEach(givenAuthenticatedSequence);
19+
beforeEach(getAuthVerifier);
20+
21+
it('should return 302 when client id is passed and passReqToCallback is set true', async () => {
22+
class TestController {
23+
@get('/test')
24+
@authenticate(STRATEGY.COGNITO_OAUTH2, {
25+
clientID: 'string',
26+
clientSecret: 'string',
27+
passReqToCallback: true,
28+
})
29+
test() {
30+
return 'test successful';
31+
}
32+
}
33+
34+
app.controller(TestController);
35+
36+
await whenIMakeRequestTo(server).get('/test').expect(302);
37+
});
38+
39+
function whenIMakeRequestTo(restServer: RestServer): Client {
40+
return createClientForHandler(restServer.requestHandler);
41+
}
42+
43+
async function givenAServer() {
44+
app = getApp();
45+
server = await app.getServer(RestServer);
46+
}
47+
48+
function getAuthVerifier() {
49+
app
50+
.bind(Strategies.Passport.COGNITO_OAUTH2_VERIFIER)
51+
.toProvider(CognitoAuthVerifyProvider);
52+
}
53+
54+
function givenAuthenticatedSequence() {
55+
// bind user defined sequence
56+
server.sequence(MyAuthenticationMiddlewareSequence);
57+
}
58+
});
59+
60+
class CognitoAuthVerifyProvider
61+
implements Provider<VerifyFunction.CognitoAuthFn>
62+
{
63+
constructor() {}
64+
65+
value(): VerifyFunction.CognitoAuthFn {
66+
return async (
67+
accessToken: string,
68+
refreshToken: string,
69+
profile: Cognito.Profile,
70+
cd: Cognito.VerifyCallback,
71+
req?: Request,
72+
) => {
73+
return userWithoutReqObj;
74+
};
75+
}
76+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import {Cognito, IAuthUser} from '../../../types';
2+
import {expect} from '@loopback/testlab';
3+
import {
4+
CognitoStrategyFactoryProvider,
5+
CognitoAuthStrategyFactory,
6+
} from '../../../strategies/passport/passport-cognito-oauth2';
7+
8+
describe('getting cognito-auth strategy with options', () => {
9+
it('should return strategy by passing options and passReqToCallback as true', async () => {
10+
const strategyVerifier: CognitoAuthStrategyFactory = await getStrategy();
11+
12+
const options: Cognito.StrategyOptions = {
13+
callbackURL: 'string',
14+
clientDomain: 'string',
15+
clientID: 'string',
16+
clientSecret: 'string',
17+
region: 'string',
18+
passReqToCallback: true,
19+
};
20+
21+
const cognitoAuthStrategyVerifier = strategyVerifier(options);
22+
23+
expect(cognitoAuthStrategyVerifier).to.have.property('name');
24+
expect(cognitoAuthStrategyVerifier)
25+
.to.have.property('authenticate')
26+
.which.is.a.Function();
27+
});
28+
29+
it('should return strategy by passing options and passReqToCallback as false', async () => {
30+
const strategyVerifier: CognitoAuthStrategyFactory = await getStrategy();
31+
32+
const options: Cognito.StrategyOptions = {
33+
callbackURL: 'string',
34+
clientDomain: 'string',
35+
clientID: 'string',
36+
clientSecret: 'string',
37+
region: 'string',
38+
passReqToCallback: false,
39+
};
40+
41+
const cognitoAuthStrategyVerifier = strategyVerifier(options);
42+
43+
expect(cognitoAuthStrategyVerifier).to.have.property('name');
44+
expect(cognitoAuthStrategyVerifier)
45+
.to.have.property('authenticate')
46+
.which.is.a.Function();
47+
});
48+
});
49+
50+
async function getStrategy() {
51+
const provider = new CognitoStrategyFactoryProvider(verifierBearer);
52+
53+
//this fuction will return a function which will then accept options.
54+
return provider.value();
55+
}
56+
57+
//returning a user
58+
function verifierBearer(
59+
accessToken: string,
60+
refreshToken: string,
61+
profile: Cognito.Profile,
62+
): Promise<IAuthUser | null> {
63+
const userToPass: IAuthUser = {
64+
id: 1,
65+
username: 'xyz',
66+
password: 'pass',
67+
};
68+
69+
return new Promise(function (resolve, reject) {
70+
if (userToPass) {
71+
resolve(userToPass);
72+
}
73+
});
74+
}

0 commit comments

Comments
 (0)