Skip to content

Commit cbf03b9

Browse files
authored
Merge pull request #1855 from rocket-admin/backend_tests
feat(tests): add end-to-end tests for GET /saas/company/my/email/:email endpoint
2 parents 40cccd5 + 059f160 commit cbf03b9

1 file changed

Lines changed: 140 additions & 0 deletions

File tree

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import { faker } from '@faker-js/faker';
2+
import { INestApplication, ValidationPipe } from '@nestjs/common';
3+
import { Test } from '@nestjs/testing';
4+
import test from 'ava';
5+
import { ValidationError } from 'class-validator';
6+
import cookieParser from 'cookie-parser';
7+
import jwt from 'jsonwebtoken';
8+
import request from 'supertest';
9+
import { DataSource } from 'typeorm';
10+
import { ApplicationModule } from '../../../src/app.module.js';
11+
import { BaseType } from '../../../src/common/data-injection.tokens.js';
12+
import { CompanyInfoEntity } from '../../../src/entities/company-info/company-info.entity.js';
13+
import { WinstonLogger } from '../../../src/entities/logging/winston-logger.js';
14+
import { UserRoleEnum } from '../../../src/entities/user/enums/user-role.enum.js';
15+
import { UserEntity } from '../../../src/entities/user/user.entity.js';
16+
import { AllExceptionsFilter } from '../../../src/exceptions/all-exceptions.filter.js';
17+
import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js';
18+
import { Messages } from '../../../src/exceptions/text/messages.js';
19+
import { Cacher } from '../../../src/helpers/cache/cacher.js';
20+
import { appConfig } from '../../../src/shared/config/app-config.js';
21+
import { DatabaseModule } from '../../../src/shared/database/database.module.js';
22+
import { DatabaseService } from '../../../src/shared/database/database.service.js';
23+
import { TestUtils } from '../../utils/test.utils.js';
24+
25+
// Tests for the SaaS bridge GET /saas/company/my/email/:email (SaaSAuthMiddleware / microservice JWT).
26+
// It duplicates the open-source GET /company/my/email/:email lookup so rocketadmin-saas can expose the
27+
// same "which companies is this email in" list (used by the multi-company login picker). The
28+
// open-source endpoint is unchanged.
29+
30+
let app: INestApplication;
31+
let currentTest: string;
32+
let _testUtils: TestUtils;
33+
34+
// A microservice JWT identical in shape to the one rocketadmin-saas signs (payload { request_id }).
35+
function microserviceAuthHeader(): string {
36+
const token = jwt.sign({ request_id: faker.string.uuid() }, appConfig.auth.microserviceJwtSecret);
37+
return `Bearer ${token}`;
38+
}
39+
40+
async function createCoreUserWithCompany(): Promise<{ email: string; companyId: string; companyName: string }> {
41+
const dataSource = app.get<DataSource>(BaseType.DATA_SOURCE);
42+
const userRepository = dataSource.getRepository(UserEntity);
43+
const companyRepository = dataSource.getRepository(CompanyInfoEntity);
44+
45+
const email = `${faker.lorem.word()}_${faker.string.alphanumeric(6)}_${faker.internet.email()}`.toLowerCase();
46+
const companyName = faker.company.name();
47+
48+
const company = await companyRepository.save(
49+
companyRepository.create({ id: faker.string.uuid(), name: companyName }),
50+
);
51+
await userRepository.save(
52+
userRepository.create({
53+
email,
54+
password: `#r@dY^e&7R4b5Ib@31iE4xbn`,
55+
isActive: true,
56+
company,
57+
role: UserRoleEnum.ADMIN,
58+
}),
59+
);
60+
61+
return { email, companyId: company.id, companyName };
62+
}
63+
64+
test.before(async () => {
65+
const moduleFixture = await Test.createTestingModule({
66+
imports: [ApplicationModule, DatabaseModule],
67+
providers: [DatabaseService, TestUtils],
68+
}).compile();
69+
app = moduleFixture.createNestApplication();
70+
_testUtils = moduleFixture.get<TestUtils>(TestUtils);
71+
72+
app.use(cookieParser());
73+
app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger)));
74+
app.useGlobalPipes(
75+
new ValidationPipe({
76+
exceptionFactory(validationErrors: ValidationError[] = []) {
77+
return new ValidationException(validationErrors);
78+
},
79+
}),
80+
);
81+
await app.init();
82+
app.getHttpServer().listen(0);
83+
});
84+
85+
test.after(async () => {
86+
try {
87+
await Cacher.clearAllCache();
88+
await app.close();
89+
} catch (e) {
90+
console.error('After tests error ' + e);
91+
}
92+
});
93+
94+
currentTest = 'GET /saas/company/my/email/:email';
95+
96+
test.serial(`${currentTest} returns the companies a registered email belongs to`, async (t) => {
97+
const { email, companyId, companyName } = await createCoreUserWithCompany();
98+
99+
const result = await request(app.getHttpServer())
100+
.get(`/saas/company/my/email/${encodeURIComponent(email)}`)
101+
.set('Authorization', microserviceAuthHeader())
102+
.set('Accept', 'application/json');
103+
104+
t.is(result.status, 200);
105+
const ro = JSON.parse(result.text);
106+
t.true(Array.isArray(ro));
107+
const found = ro.find((c: { id: string; name?: string }) => c.id === companyId);
108+
t.truthy(found);
109+
t.is(found.name, companyName);
110+
});
111+
112+
test.serial(`${currentTest} rejects an email with no registered companies`, async (t) => {
113+
const result = await request(app.getHttpServer())
114+
.get(`/saas/company/my/email/${encodeURIComponent(`nobody_${faker.string.alphanumeric(8)}@example.com`)}`)
115+
.set('Authorization', microserviceAuthHeader())
116+
.set('Accept', 'application/json');
117+
118+
t.is(result.status, 400);
119+
const ro = JSON.parse(result.text);
120+
t.is(ro.message, Messages.COMPANIES_USER_EMAIL_NOT_FOUND);
121+
});
122+
123+
test.serial(`${currentTest} rejects a malformed email`, async (t) => {
124+
const result = await request(app.getHttpServer())
125+
.get(`/saas/company/my/email/not-an-email`)
126+
.set('Authorization', microserviceAuthHeader())
127+
.set('Accept', 'application/json');
128+
129+
t.is(result.status, 400);
130+
});
131+
132+
test.serial(`${currentTest} rejects a request without a microservice JWT`, async (t) => {
133+
const { email } = await createCoreUserWithCompany();
134+
135+
const result = await request(app.getHttpServer())
136+
.get(`/saas/company/my/email/${encodeURIComponent(email)}`)
137+
.set('Accept', 'application/json');
138+
139+
t.is(result.status, 401);
140+
});

0 commit comments

Comments
 (0)