-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/testing approaches #61
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are that fields like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bassiounix iirc this is the type of the result of |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,29 @@ | ||
import { ContextIdFactory } from "@nestjs/core"; | ||
import { Test, TestingModule } from "@nestjs/testing"; | ||
import { AppModule } from "./app.module"; | ||
import { TestManager } from "../test/TestManager"; | ||
import { AppResolver } from "./app.resolver"; | ||
import { AppService } from "./app.service"; | ||
import { DrizzleModule } from "./drizzle/drizzle.module"; | ||
|
||
describe("AppService", () => { | ||
describe("[GraphQL] [IntegrationTesting] AppResolver", () => { | ||
let testManager = new TestManager(); | ||
let appResolver: AppResolver; | ||
|
||
beforeEach(async () => { | ||
// TODO: create proper test module / class. | ||
const app: TestingModule = await Test.createTestingModule({ | ||
imports: [AppModule], | ||
}).compile(); | ||
beforeAll(async () => { | ||
await testManager.beforeAll(); | ||
|
||
// TODO: are there a better handling for this? @xUser5000 | ||
const contextId = ContextIdFactory.create(); | ||
jest.spyOn(ContextIdFactory, "getByRequest").mockImplementation( | ||
() => contextId, | ||
); | ||
|
||
appResolver = await app.resolve(AppResolver, contextId); | ||
appResolver = await testManager.app.resolve(AppResolver, contextId); | ||
}); | ||
|
||
describe("root", () => { | ||
it('should return "Hello World!"', () => { | ||
expect(appResolver.hello()).toBe("Hello World!"); | ||
}); | ||
afterAll(async () => { | ||
await testManager.afterAll(); | ||
}); | ||
|
||
it('should return "Hello World!"', async () => { | ||
const result = appResolver.hello(); | ||
expect(result).toBe("Hello World!"); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { ContextIdFactory } from "@nestjs/core"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unused imports!!! |
||
import { Test, TestingModule } from "@nestjs/testing"; | ||
import { TestManager } from "../test/TestManager"; | ||
import { AppResolver } from "./app.resolver"; | ||
import { AppService } from "./app.service"; | ||
import { DrizzleService } from "./drizzle/drizzle.service"; | ||
|
||
describe("[GraphQL] [UnitTesting] AppService", () => { | ||
let appService: AppService; | ||
let drizzleService: DrizzleService; | ||
|
||
// Note: we *shouldn't* (?) need TestManager for unit tests. | ||
beforeAll(async () => { | ||
const app: TestingModule = await Test.createTestingModule({ | ||
// Mocking can happen here (if appService has dependencies), | ||
// or add specific mocks to each test case. | ||
providers: [ | ||
AppService, | ||
{ | ||
provide: DrizzleService, | ||
useValue: { | ||
db: { | ||
query: { | ||
users: { | ||
findMany: jest.fn().mockReturnValue([]), | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
], | ||
}).compile(); | ||
|
||
drizzleService = app.get<DrizzleService>(DrizzleService); | ||
appService = app.get<AppService>(AppService); | ||
}); | ||
|
||
afterAll(async () => {}); | ||
|
||
it('should return "Hello World!"', async () => { | ||
const spy = jest.spyOn(drizzleService.db.query.users, "findMany"); | ||
|
||
const result = await appService.testDb(); | ||
expect(spy).toHaveBeenCalled(); | ||
expect(result).toStrictEqual([]); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,63 @@ | ||||||||||||||
import { INestApplication, ValidationPipe } from "@nestjs/common"; | ||||||||||||||
import { ConfigService } from "@nestjs/config"; | ||||||||||||||
import { Test } from "@nestjs/testing"; | ||||||||||||||
import RedisStore from "connect-redis"; | ||||||||||||||
import * as session from "express-session"; | ||||||||||||||
import * as passport from "passport"; | ||||||||||||||
import { createClient } from "redis"; | ||||||||||||||
import { AppModule } from "../src/app.module"; | ||||||||||||||
|
||||||||||||||
export class TestManager { | ||||||||||||||
// biome-ignore lint/suspicious/noExplicitAny: it is any. | ||||||||||||||
public httpServer: any; | ||||||||||||||
public app: INestApplication; | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||
|
||||||||||||||
// TODO: Find a way to abstract this logic, found in main.ts too. | ||||||||||||||
async beforeAll(): Promise<void> { | ||||||||||||||
const moduleRef = await Test.createTestingModule({ | ||||||||||||||
imports: [AppModule], | ||||||||||||||
}).compile(); | ||||||||||||||
this.app = moduleRef.createNestApplication(); | ||||||||||||||
|
||||||||||||||
const configService = this.app.get(ConfigService); | ||||||||||||||
|
||||||||||||||
this.app.useGlobalPipes( | ||||||||||||||
new ValidationPipe({ | ||||||||||||||
transform: true, | ||||||||||||||
whitelist: true, | ||||||||||||||
}), | ||||||||||||||
); | ||||||||||||||
|
||||||||||||||
const redisClient = await createClient({ | ||||||||||||||
url: String(configService.getOrThrow("REDIS_URL")), | ||||||||||||||
}).connect(); | ||||||||||||||
|
||||||||||||||
this.app.use( | ||||||||||||||
session({ | ||||||||||||||
secret: configService.getOrThrow<string>("SESSION_SECRET"), | ||||||||||||||
resave: false, | ||||||||||||||
saveUninitialized: false, | ||||||||||||||
cookie: { | ||||||||||||||
maxAge: configService.getOrThrow<number>("COOKIE_MAX_AGE"), | ||||||||||||||
httpOnly: true, | ||||||||||||||
}, | ||||||||||||||
store: new RedisStore({ | ||||||||||||||
client: redisClient, | ||||||||||||||
}), | ||||||||||||||
}), | ||||||||||||||
Comment on lines
+36
to
+47
Check warning Code scanning / CodeQL Clear text transmission of sensitive cookie Medium test
Sensitive cookie sent without enforcing SSL encryption.
Copilot Autofix AI 19 days ago To fix the problem, we need to ensure that the session cookie is only transmitted over HTTPS by setting the
Suggested changeset
1
apps/api/test/TestManager.ts
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||
); | ||||||||||||||
|
||||||||||||||
this.app.use(passport.initialize()); | ||||||||||||||
this.app.use(passport.session()); | ||||||||||||||
this.app.enableCors(); | ||||||||||||||
|
||||||||||||||
this.httpServer = this.app.getHttpServer(); | ||||||||||||||
await this.app.init(); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
async afterAll() { | ||||||||||||||
await this.app.close(); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
// Helper functions can be added here if needed e.g. generateUser(). | ||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import "tsconfig-paths/register"; | ||
|
||
import { createClient } from "redis"; | ||
import { TestManager } from "./TestManager"; | ||
|
||
export default async (): Promise<void> => { | ||
console.log("# Started Jest globalSetup."); | ||
const testManager = new TestManager(); | ||
|
||
await testManager.beforeAll(); | ||
|
||
await testManager.app.init(); | ||
|
||
// TODO: Apply Database migrations/seeders. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where are the db stuff? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm... I can't recall why I didn't add them, I can work on them this weekend, but I prefer that we merge this anway. |
||
|
||
await testManager.app.close(); | ||
|
||
// Delete records in redis. | ||
const client = createClient(); | ||
await client.connect(); | ||
await client.flushAll(); | ||
console.log("# Finished Jest globalSetup."); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import "tsconfig-paths/register"; | ||
|
||
import { createClient } from "redis"; | ||
import { TestManager } from "./TestManager"; | ||
|
||
export default async (): Promise<void> => { | ||
console.log("# Started Jest globalTeardown."); | ||
const testManager = new TestManager(); | ||
|
||
await testManager.beforeAll(); | ||
|
||
await testManager.app.init(); | ||
|
||
// TODO: Apply Database migrations/seeders. | ||
|
||
await testManager.app.close(); | ||
|
||
// Delete records in redis. | ||
const client = createClient(); | ||
await client.connect(); | ||
await client.flushAll(); | ||
console.log("# Finished Jest globalTeardown."); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
appears when trying to run
jest
.Also
test:e2e
shows a similar message:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bassiounix
The intention of this branch is not to test. The intention is to show developer working on Disworse HOW to test. With examples on Unit, E2E, and ((kind of)) integration tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also on the Jest error, I never managed to fix it, I usually silence it with
--forceExit
.