Skip to content

Commit 15c7871

Browse files
committed
test: add tests
1 parent 05d5785 commit 15c7871

3 files changed

Lines changed: 333 additions & 1 deletion

File tree

docker-compose.test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ services:
1313
- 3000:3000
1414
command: ['yarn', 'test:e2e', '--runInBand']
1515
environment:
16-
- DATABASE_URL=mongodb://root:example@db:5432/dev
16+
- DATABASE_URL=mongodb://db:27017/test
1717
- NODE_ENV=testing
1818
- SECRET=secret
1919
db:

src/modules/restaurants/restaurants.service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ export class RestaurantsService {
121121
$limit: input.limit,
122122
})
123123

124+
console.log(JSON.stringify(pipeline))
124125

125126
const data = await this.collection.aggregate(pipeline).toArray().then((e: any[]) => e.map(this.mapDocumentFromGeoJson).map(mapOID))
126127
return data;

test/app.e2e-spec.ts

Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
import { Test, TestingModule } from '@nestjs/testing';
2+
import * as request from 'supertest';
3+
import { INestApplication, ValidationPipe } from '@nestjs/common';
4+
import * as argon2 from 'argon2';
5+
import { AppModule } from '../src/app.module';
6+
7+
describe('AppController (e2e)', () => {
8+
let app: INestApplication;
9+
let db: any;
10+
let usersData: any[];
11+
let restaurantsData: any[];
12+
let foodsData: any[];
13+
let reviewsData: any[];
14+
15+
beforeAll(async () => {
16+
17+
const moduleFixture: TestingModule = await Test.createTestingModule({
18+
imports: [AppModule],
19+
}).compile();
20+
21+
app = moduleFixture.createNestApplication();
22+
app.useGlobalPipes(new ValidationPipe());
23+
await app.init();
24+
25+
// Connect to the database
26+
db = app.get('DATABASE_CONNECTION');
27+
});
28+
29+
beforeEach(async () => {
30+
// Clean the database and insert initial data
31+
await db.collection('users').deleteMany({});
32+
await db.collection('restaurants').deleteMany({});
33+
await db.collection('foods').deleteMany({});
34+
await db.collection('reviews').deleteMany({});
35+
36+
const password = await argon2.hash('password');
37+
const users = [
38+
{
39+
email: 'user1@example.com',
40+
name: 'User 1',
41+
password,
42+
role: 0, // normal user
43+
},
44+
{
45+
email: 'user2@example.com',
46+
name: 'User 2',
47+
password,
48+
role: 0, // normal user
49+
},
50+
{
51+
email: 'user3@example.com',
52+
name: 'User 3',
53+
password,
54+
role: 1, // admin
55+
},
56+
{
57+
email: 'user4@example.com',
58+
name: 'User 4',
59+
password,
60+
role: 1, // admin
61+
},
62+
{
63+
email: 'user5@example.com',
64+
name: 'User 5',
65+
password,
66+
role: 2, // superadmin
67+
},
68+
];
69+
await db.collection('users').insertMany(users);
70+
usersData = await db.collection('users').find().toArray();
71+
72+
const restaurants = [
73+
{
74+
name: 'Restaurant A',
75+
location: {
76+
type: 'Point',
77+
coordinates: [51.5074, -0.1278],
78+
},
79+
address: '1 London Bridge St, London SE1 9BG',
80+
rating: 4,
81+
cuisine: 'British',
82+
creatorId: usersData[2]._id.toString(), // admin
83+
},
84+
{
85+
name: 'Restaurant B',
86+
location: {
87+
type: 'Point',
88+
coordinates: [48.8566, 2.3522],
89+
},
90+
address: '5 Rue de la Paix, 75002 Paris, France',
91+
rating: 3,
92+
cuisine: 'French',
93+
creatorId: usersData[3]._id.toString(), // admin
94+
},
95+
];
96+
await db.collection('restaurants').insertMany(restaurants);
97+
restaurantsData = await db.collection('restaurants').find().toArray();
98+
99+
const foods = [
100+
{
101+
name: 'Food 1',
102+
description: 'Description for Food 1',
103+
price: 15,
104+
restaurantId: restaurantsData[0]._id.toString(),
105+
creatorId: usersData[2]._id.toString(), // admin
106+
},
107+
{
108+
name: 'Food 2',
109+
description: 'Description for Food 2',
110+
price: 20,
111+
restaurantId: restaurantsData[0]._id.toString(),
112+
creatorId: usersData[3]._id.toString(), // admin
113+
},
114+
{
115+
name: 'Food 3',
116+
description: 'Description for Food 3',
117+
price: 25,
118+
restaurantId: restaurantsData[1]._id.toString(),
119+
creatorId: usersData[0]._id.toString(), // normal user
120+
},
121+
{
122+
name: 'Food 4',
123+
description: 'Description for Food 4',
124+
price: 30,
125+
restaurantId: restaurantsData[1]._id.toString(),
126+
creatorId: usersData[1]._id.toString(), // normal user
127+
},
128+
];
129+
await db.collection('foods').insertMany(foods);
130+
foodsData = await db.collection('foods').find().toArray();
131+
132+
const reviews = [
133+
{
134+
restaurantId: restaurantsData[0]._id.toString(),
135+
comment: 'Comment from User 1',
136+
rating: 3,
137+
userId: usersData[0]._id.toString(),
138+
},
139+
{
140+
restaurantId: restaurantsData[0]._id.toString(),
141+
comment: 'Comment from User 2',
142+
rating: 4,
143+
userId: usersData[1]._id.toString(),
144+
},
145+
{
146+
restaurantId: restaurantsData[1]._id.toString(),
147+
comment: 'Comment from User 3',
148+
rating: 5,
149+
userId: usersData[2]._id.toString(),
150+
},
151+
{
152+
restaurantId: restaurantsData[1]._id.toString(),
153+
comment: 'Comment from User 1',
154+
rating: 2,
155+
userId: usersData[0]._id.toString(),
156+
},
157+
];
158+
await db.collection('reviews').insertMany(reviews);
159+
reviewsData = await db.collection('reviews').find().toArray();
160+
});
161+
describe('login', () => {
162+
163+
async function login(email: string, password: string): Promise<request.Response> {
164+
const mutation = `
165+
mutation Login($input: LoginUserInput!) {
166+
login(input: $input) {
167+
user { id name }
168+
token
169+
}
170+
}
171+
`;
172+
const variables = { input: { email, password } };
173+
return request(app.getHttpServer())
174+
.post('/graphql')
175+
.send({ query: mutation, variables });
176+
}
177+
178+
let user;
179+
beforeEach(() => { user = usersData[0] });
180+
181+
it('should return an error if the user does not exist', async () => {
182+
const response = await login('nonexistinguser@example.com', 'password');
183+
expect(response.status).toBe(200);
184+
expect(response.body.errors[0].extensions.code).toBe('BAD_REQUEST');
185+
});
186+
187+
it('should return an error if the password is incorrect', async () => {
188+
const response = await login(user.email, 'wrongpassword');
189+
expect(response.status).toBe(200);
190+
expect(response.body.errors[0].extensions.code).toBe('BAD_REQUEST');
191+
});
192+
193+
it('should return the user and token if the credentials are correct', async () => {
194+
const response = await login(user.email, "password");
195+
expect(response.status).toBe(200);
196+
expect(response.body.data.login.user.id).toBe(user._id.toString());
197+
expect(response.body.data.login.user.name).toBe(user.name);
198+
expect(response.body.data.login.token).toBeTruthy();
199+
});
200+
});
201+
describe('User', () => {
202+
let user;
203+
beforeEach(() => { user = usersData[0] });
204+
205+
describe('Query.user', () => {
206+
async function getUser(token: string): Promise<request.Response> {
207+
const query = `
208+
query {
209+
user {
210+
id
211+
name
212+
}
213+
}
214+
`;
215+
return request(app.getHttpServer())
216+
.post('/graphql')
217+
.send({ query })
218+
.set('Authorization', `Bearer ${token}`);
219+
}
220+
221+
it('should return an error if the token is invalid', async () => {
222+
const response = await getUser('invalid_token');
223+
expect(response.status).toBe(200);
224+
expect(response.body.errors[0].extensions.code).toBe('FORBIDDEN');
225+
});
226+
227+
it('should return the user if the token is valid', async () => {
228+
const token = await request(app.getHttpServer())
229+
.post('/graphql')
230+
.send({
231+
query: `
232+
mutation Login($input: LoginUserInput!) {
233+
login(input: $input) {
234+
token
235+
}
236+
}
237+
`,
238+
variables: { input: { email: user.email, password: 'password' } },
239+
})
240+
.then(res => res.body.data.login.token);
241+
242+
const response = await getUser(token);
243+
expect(response.status).toBe(200);
244+
expect(response.body.data.user.id).toBe(user._id.toString());
245+
expect(response.body.data.user.name).toBe(user.name);
246+
});
247+
});
248+
249+
});
250+
251+
describe('Registration', () => {
252+
it('should create a new user', async () => {
253+
// Define the mutation payload
254+
const registerMutation = `
255+
mutation Register($input: RegisterUserInput!) {
256+
register(input: $input) {
257+
user {
258+
id
259+
name
260+
}
261+
token
262+
}
263+
}
264+
`;
265+
const variables = {
266+
input: {
267+
email: 'newuser@example.com',
268+
name: 'New User',
269+
password: 'Test123!',
270+
},
271+
};
272+
273+
// Send the mutation request and check the response
274+
const response = await request(app.getHttpServer())
275+
.post('/graphql')
276+
.send({ query: registerMutation, variables });
277+
278+
console.log(response.body);
279+
// Assert the response
280+
expect(response.status).toBe(200);
281+
expect(response.body.errors).toBeFalsy();
282+
expect(response.body.data.register.user.name).toBe('New User');
283+
expect(response.body.data.register.token).toBeTruthy();
284+
285+
// Check that the user was created in the database
286+
const newUser = await db.collection('users').findOne({
287+
email: 'newuser@example.com',
288+
});
289+
expect(newUser).toBeTruthy();
290+
expect(newUser.name).toBe('New User');
291+
});
292+
293+
it('should return an error if the email is already in use', async () => {
294+
// Define the mutation payload
295+
const registerMutation = `
296+
mutation Register($input: RegisterUserInput!) {
297+
register(input: $input) {
298+
user {
299+
id
300+
name
301+
}
302+
token
303+
}
304+
}
305+
`;
306+
const variables = {
307+
input: {
308+
email: usersData[0].email,
309+
name: 'New User',
310+
password:'Test123!',
311+
},
312+
};
313+
314+
// Send the mutation request and check the response
315+
const response = await request(app.getHttpServer())
316+
.post('/graphql')
317+
.send({ query: registerMutation, variables });
318+
319+
// Assert the response
320+
expect(response.status).toBe(200);
321+
expect(response.body.errors[0].extensions.code).toBe('BAD_REQUEST');
322+
323+
// Check that the user was not created in the database
324+
const newUser = await db.collection('users').findOne({
325+
email: 'newuser@example.com',
326+
});
327+
expect(newUser).toBeFalsy();
328+
});
329+
});
330+
});
331+

0 commit comments

Comments
 (0)