-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #156 from juicyllama/feature/support-relations-in-…
…get-profile Feature/support relations in get profile
- Loading branch information
Showing
17 changed files
with
408 additions
and
373 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
import 'dotenv/config' | ||
import { Logger } from '../../src/helpers/Logger' | ||
import axios from 'axios' | ||
import axios, { AxiosRequestConfig } from 'axios' | ||
|
||
// Data | ||
const Customers = require('./json/Customer.json') | ||
|
@@ -13,6 +13,15 @@ const DOMAIN = 'AIRTABLE' | |
const [apiKey, baseId] = AIRTABLE.split('://')[1].split('@') | ||
const logger = new Logger() | ||
|
||
const user = { | ||
userId: 1, | ||
email: '[email protected]', | ||
password: '$2a$10$jm6bM7acpRa18Vdy8FSqIu4yzWAdSgZgRtRrx8zknIeZhSqPJjJU.', | ||
role: 'ADMIN', | ||
firstName: 'Jon', | ||
lastName: 'Doe', | ||
} | ||
|
||
const buildUsers = async () => { | ||
const table = 'User' | ||
|
||
|
@@ -48,19 +57,53 @@ const buildUsers = async () => { | |
}, | ||
} | ||
|
||
const recordsRequest = { | ||
method: 'POST', | ||
url: `${ENDPOINT}/${baseId}/${table}`, | ||
data: { | ||
records: [ | ||
{ | ||
fields: user, | ||
}, | ||
], | ||
}, | ||
headers: { | ||
Authorization: `Bearer ${apiKey}`, | ||
}, | ||
} | ||
|
||
return await build(table, tableRequest, recordsRequest) | ||
} | ||
|
||
const buildUserApiKey = async userTable => { | ||
const table = 'UserApiKey' | ||
|
||
const tableRequest = { | ||
method: 'POST', | ||
url: `${ENDPOINT}/meta/bases/${baseId}/tables`, | ||
data: { | ||
name: table, | ||
fields: [ | ||
{ name: 'id', type: 'number', options: { precision: 0 } }, | ||
{ name: 'userId', type: 'multipleRecordLinks', options: { linkedTableId: userTable.id } }, | ||
{ name: 'apiKey', type: 'singleLineText' }, | ||
], | ||
}, | ||
headers: { | ||
Authorization: `Bearer ${apiKey}`, | ||
}, | ||
} | ||
|
||
const recordsRequest = { | ||
method: 'POST', | ||
url: `${ENDPOINT}/${baseId}/${table}`, | ||
data: { | ||
records: [ | ||
{ | ||
fields: { | ||
userId: 1, | ||
email: '[email protected]', | ||
password: '$2a$10$jm6bM7acpRa18Vdy8FSqIu4yzWAdSgZgRtRrx8zknIeZhSqPJjJU.', | ||
role: 'ADMIN', | ||
firstName: 'Jon', | ||
lastName: 'Doe', | ||
id: 1, | ||
userId: [userTable.records[0].id], | ||
apiKey: 'Ex@mp1eS$Cu7eAp!K3y', | ||
}, | ||
}, | ||
], | ||
|
@@ -724,11 +767,7 @@ const buildSalesOrders = async (shipperTable, customerTable, employeeTable) => { | |
return await build(table, tableRequest, recordsRequest) | ||
} | ||
|
||
const build = async ( | ||
table: string, | ||
tableRequest: axios.AxiosRequestConfig<any>, | ||
recordsRequest: axios.AxiosRequestConfig<any>, | ||
) => { | ||
const build = async (table: string, tableRequest: AxiosRequestConfig<any>, recordsRequest: AxiosRequestConfig<any>) => { | ||
let tableResponse | ||
|
||
try { | ||
|
@@ -814,7 +853,8 @@ const build = async ( | |
const seed = async () => { | ||
logger.log('Seeding Airtable database', DOMAIN) | ||
|
||
await buildUsers() | ||
const userTable = await buildUsers() | ||
const userApiKeyTable = await buildUserApiKey(userTable) | ||
const customerTable = await buildCustomers() | ||
const employeeTable = await buildEmployees() | ||
const shipperTable = await buildShippers() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
version: '3.8' | ||
name: llana | ||
|
||
networks: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
import { INestApplication } from '@nestjs/common' | ||
import { Test } from '@nestjs/testing' | ||
import { JwtModule } from '@nestjs/jwt' | ||
import { ConfigModule, ConfigService, ConfigFactory } from '@nestjs/config' | ||
import * as request from 'supertest' | ||
|
||
import { AppModule } from './app.module' | ||
import { TIMEOUT } from './testing/testing.const' | ||
import { Logger } from './helpers/Logger' | ||
|
||
// Import configs | ||
import auth from './config/auth.config' | ||
import database from './config/database.config' | ||
import hosts from './config/hosts.config' | ||
import jwt from './config/jwt.config' | ||
import roles from './config/roles.config' | ||
import { envValidationSchema } from './config/env.validation' | ||
|
||
// Type the config imports | ||
const configs: ConfigFactory[] = [auth, database, hosts, jwt, roles] | ||
|
||
describe('App > Controller > Auth', () => { | ||
let app: INestApplication | ||
|
||
let access_token: string | ||
let logger = new Logger() | ||
|
||
beforeAll(async () => { | ||
const moduleRef = await Test.createTestingModule({ | ||
imports: [ | ||
ConfigModule.forRoot({ | ||
load: configs, | ||
validationSchema: envValidationSchema, | ||
isGlobal: true, | ||
}), | ||
JwtModule.registerAsync({ | ||
imports: [ConfigModule], | ||
useFactory: async (configService: ConfigService) => ({ | ||
secret: configService.get('jwt.secret'), | ||
signOptions: configService.get('jwt.signOptions'), | ||
}), | ||
inject: [ConfigService], | ||
}), | ||
AppModule, | ||
], | ||
}).compile() | ||
app = moduleRef.createNestApplication() | ||
await app.init() | ||
}, TIMEOUT) | ||
|
||
beforeEach(() => { | ||
logger.debug('===========================================') | ||
logger.log('🧪 ' + expect.getState().currentTestName) | ||
logger.debug('===========================================') | ||
}) | ||
|
||
describe('Failed Login', () => { | ||
it('Missing username', async function () { | ||
const result = await request(app.getHttpServer()) | ||
.post(`/auth/login`) | ||
.send({ | ||
password: 'test', | ||
}) | ||
.expect(400) | ||
expect(result.body).toBeDefined() | ||
expect(result.body.statusCode).toEqual(400) | ||
expect(result.body.message).toEqual('Username is required') | ||
expect(result.body.error).toEqual('Bad Request') | ||
}) | ||
|
||
it('Missing password', async () => { | ||
const result = await request(app.getHttpServer()) | ||
.post(`/auth/login`) | ||
.send({ | ||
username: '[email protected]', | ||
}) | ||
.expect(400) | ||
expect(result.body).toBeDefined() | ||
expect(result.body.statusCode).toEqual(400) | ||
expect(result.body.message).toEqual('Password is required') | ||
expect(result.body.error).toEqual('Bad Request') | ||
}) | ||
|
||
it('Wrong username', async () => { | ||
const result = await request(app.getHttpServer()) | ||
.post(`/auth/login`) | ||
.send({ | ||
username: '[email protected]', | ||
password: 'test', | ||
}) | ||
.expect(401) | ||
expect(result.body).toBeDefined() | ||
expect(result.body.statusCode).toEqual(401) | ||
expect(result.body.message).toEqual('Unauthorized') | ||
}) | ||
|
||
it('Wrong password', async () => { | ||
const result = await request(app.getHttpServer()) | ||
.post(`/auth/login`) | ||
.send({ | ||
username: '[email protected]', | ||
password: 'wrong', | ||
}) | ||
.expect(401) | ||
expect(result.body).toBeDefined() | ||
expect(result.body.statusCode).toEqual(401) | ||
expect(result.body.message).toEqual('Unauthorized') | ||
}) | ||
}) | ||
|
||
describe('Successful Login', () => { | ||
it('Correct username & password', async () => { | ||
const result = await request(app.getHttpServer()) | ||
.post(`/auth/login`) | ||
.send({ | ||
username: '[email protected]', | ||
password: 'test', | ||
}) | ||
.expect(200) | ||
expect(result.body).toBeDefined() | ||
expect(result.body.access_token).toBeDefined() | ||
access_token = result.body.access_token | ||
}) | ||
}) | ||
|
||
describe('Access Token Works', () => { | ||
it('Get Profile', async () => { | ||
const result = await request(app.getHttpServer()) | ||
.get(`/auth/profile`) | ||
.set('Authorization', `Bearer ${access_token}`) | ||
.expect(200) | ||
expect(result.body).toBeDefined() | ||
expect(result.body.email).toBeDefined() | ||
}) | ||
|
||
it('Get Profile With Relations', async () => { | ||
const result = await request(app.getHttpServer()) | ||
.get(`/auth/profile?relations=UserApiKey`) | ||
.set('Authorization', `Bearer ${access_token}`) | ||
.expect(200) | ||
expect(result.body).toBeDefined() | ||
expect(result.body.email).toBeDefined() | ||
expect(result.body.UserApiKey).toBeDefined() | ||
expect(result.body.UserApiKey.length).toBeGreaterThan(0) | ||
expect(result.body.UserApiKey[0].apiKey).toBeDefined() | ||
}) | ||
}) | ||
|
||
afterAll(async () => { | ||
await app.close() | ||
}, TIMEOUT) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.