diff --git a/.vscode/launch.json b/.vscode/launch.json index 278e5c6..fc730a5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,6 +12,18 @@ "/**" ], "program": "${workspaceFolder}\\server.js" - } + }, + { + "name": "Debug Jest Tests", + "type": "node", + "request": "launch", + "runtimeArgs": [ + "--inspect-brk", + "${workspaceRoot}/node_modules/jest/bin/jest.js", + "--runInBand" + ], + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + } ] } \ No newline at end of file diff --git a/__tests__/api.test.js b/__tests__/api.test.js index 3ac9452..50fd886 100644 --- a/__tests__/api.test.js +++ b/__tests__/api.test.js @@ -1,94 +1,56 @@ -const { MongoClient } = require('mongodb'); const { MongoMemoryServer } = require('mongodb-memory-server'); -const classController = require('../controllers/classController'); -const httpMocks = require('node-mocks-http'); +const mongoose = require('mongoose'); +const app = require('../server'); +const request = require('supertest'); +const {initDb} = require('../data/database') -describe('classController Integration Tests', () => { +describe('Test routes, GET -- student, class, teacher, grade, and unknow route', () => { let mongoServer; - let connection; - let db; - beforeAll(async () => { - // Create an in-memory MongoDB instance + beforeEach(async () => { mongoServer = await MongoMemoryServer.create(); - const mongoUri = mongoServer.getUri(); - - // Create a MongoDB connection - connection = await MongoClient.connect(mongoUri); - db = connection.db(); - - // Mock the database.js getDb function - jest.spyOn(require('../data/database'), 'getDb').mockReturnValue(db); - }); - - afterAll(async () => { - // Clean up resources - await connection.close(); - await mongoServer.stop(); - }); - - describe('getAll', () => { - let req; - let res; - - beforeEach(async () => { - // Create fresh request and response mocks - req = httpMocks.createRequest(); - res = httpMocks.createResponse({ - eventEmitter: require('events').EventEmitter + const mongodbUrl = mongoServer.getUri(); + await mongoose.connect(mongodbUrl); + await new Promise((resolve, reject) => { + initDb((err) => { + if (err) return reject(err); + resolve(); }); - - // Clear the collection before each test - await db.collection('class').deleteMany({}); }); + }, 5000); // Optional: increase timeout if Jest times out here - it('should return all classes with 200 status when classes exist', async () => { - // Arrange: Insert test data - const testClasses = [ - { - course_code: 'MATH101', - subject: 'Mathematics', - class_description: 'Calculus I', - max_class_size: 30 - }, - { - course_code: 'PHY201', - subject: 'Physics', - class_description: 'Mechanics', - max_class_size: 25 - } - ]; - await db.collection('class').insertMany(testClasses); - - // Act: Call getAll - const getAllHandler = classController.getAll(); - await getAllHandler(req, res); + afterEach(async () => { + await mongoose.disconnect(); + await mongoServer.stop(); + }); - // Wait for the response to be complete - await new Promise(resolve => res.once('end', resolve)); + test('should retrieve all classes', async () => { + const response = await request(app).get('/class'); + expect(response.status).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); - // Assert - expect(res.statusCode).toBe(200); - const responseData = JSON.parse(res._getData()); - expect(responseData).toHaveLength(2); - expect(responseData[0].course_code).toBe('MATH101'); - expect(responseData[1].course_code).toBe('PHY201'); - }); + test('should retrieve all grades', async () => { + const response = await request(app).get('/grade'); + expect(response.status).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); - it('should return 404 status when no classes exist', async () => { - // Act: Call getAll with empty database - const getAllHandler = classController.getAll(); - await getAllHandler(req, res); + test('should retrieve all students', async () => { + const response = await request(app).get('/student'); + expect(response.status).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); - // Wait for the response to be complete - await new Promise(resolve => res.once('end', resolve)); + test('should retrieve all teachers', async () => { + const response = await request(app).get('/teacher'); + expect(response.status).toBe(200); + expect(response.body).toBeInstanceOf(Array); + }); - // Assert - expect(res.statusCode).toBe(404); - const responseData = JSON.parse(res._getData()); - expect(responseData).toEqual({ - message: 'No classes found in the database' - }); - }); + test('should retrieve a grade by ID', async () => { + const response = await request(app).get(`/grade/67099593204dafb2be0993d8`); + expect(response.status).toBe(401); + expect(response.body).toBe('You do not have access.Please Authenticate.'); }); -}); \ No newline at end of file +}); diff --git a/__tests__/database.test.js b/__tests__/database.test.js index a2ac2f9..c5275e5 100644 --- a/__tests__/database.test.js +++ b/__tests__/database.test.js @@ -1,31 +1,33 @@ -// __tests__/database.test.js -const { MongoClient } = require('mongodb'); -const { initDb, getDb } = require('../data/database'); +const {MongoClient} = require('mongodb'); +const {initDb} = require('../data/database.js'); -jest.mock('mongodb'); +describe('Database test', function () { + let connection; + let db; -describe('Database Connection', () => { - beforeAll((done) => { - const mockDb = { - collection: jest.fn().mockReturnValue({ - insertOne: jest.fn().mockResolvedValue({ acknowledged: true }), - }), - }; - - const mockClient = { db: jest.fn().mockReturnValue(mockDb) }; - - MongoClient.connect.mockResolvedValue(mockClient); - - // Initialize database with callback - initDb(done); + beforeEach(async () => { + connection = await MongoClient.connect(process.env.DB_URI, { + useNewUrlParser: true, + useUnifiedTopology: true, }); + db = await new Promise((resolve, reject) => { + initDb((err) => { + if (err) return reject(err); + resolve(); + }); + + }, 5000); // Optional: increase timeout if Jest times out here - test('should initialize the database and perform an insert operation', async () => { - const db = getDb(); - expect(db).toBeDefined(); + }); - const collection = db.collection('test'); - await collection.insertOne({ test: 'data' }); - expect(collection.insertOne).toHaveBeenCalledWith({ test: 'data' }); - }); -}); + afterEach(async () => { + await connection.close(); + }); + + it('should get students', async () => { + const users = connection.db().collection('student'); + const student = await users.find().toArray() + expect(student).toBeInstanceOf(Array); + }); + +}); \ No newline at end of file diff --git a/__tests__/server.test.js b/__tests__/server.test.js index b8db5c7..ea1b39d 100644 --- a/__tests__/server.test.js +++ b/__tests__/server.test.js @@ -1,20 +1,41 @@ -const request = require('supertest'); +const { MongoMemoryServer } = require('mongodb-memory-server'); +const mongoose = require('mongoose'); const app = require('../server.js'); -const dbb = require('../data/database.js'); +const request = require('supertest'); +const {initDb, closeDb} = require('../data/database') +const dotenv = require('dotenv').config() -describe('Server and API Endpoints', () => { - // beforeAll(async () => { - // dbb.initDb(); // Ensure database is initialized - // }); +describe('Test server, GET student and unknow route', () => { + let mongoServer; + + beforeEach(async () => { + mongoServer = await MongoMemoryServer.create(); + const mongodbUrl = mongoServer.getUri(); + await mongoose.connect(mongodbUrl); + await new Promise((resolve, reject) => { + initDb((err) => { + if (err) return reject(err); + resolve(); + }); + }); + }, 10000); // Optional: increase timeout if Jest times out here - // afterAll(async () => { - // dbb.closeDb(); // Close database connection - // // app.close(); // Close server to free up the port - // }); + afterEach(async () => { + await mongoose.disconnect(); + await mongoServer.stop(); + await closeDb(); + }); + + test('GET students array', async () => { + const response = await request(app).get('/student') + expect(response.status).toBe(200); + expect(response.body).toBeInstanceOf(Array); + expect(response.body[0]).toHaveProperty('first_name'); + }); - test('should respond with 404 for unknown routes', async () => { - const res = await request(app).get('/unknown-route'); - expect(res.statusCode).toBe(404); - expect(res.body).toEqual({ message: "Route not found" }); + test('GET bad request', async () => { + const response = await request(app).get('/unknown') + expect(response.status).toBe(404); + expect(response.body.message).toBe('Route not found'); }); }); diff --git a/class.rest b/class.rest index 513b246..1016802 100644 --- a/class.rest +++ b/class.rest @@ -1,5 +1,5 @@ #GET classes -# GET http://localhost:3000/class/ +GET http://localhost:3000/class/ # GET class # GET http://localhost:3000/class/67099506204dafb2be099394 diff --git a/routes/grade.js b/routes/grade.js index 52ea34a..3719f76 100644 --- a/routes/grade.js +++ b/routes/grade.js @@ -12,7 +12,7 @@ routes.post('/', isAuthenticated, validation.gradeCreateValidationRules(), valid //R // routes.get('/', gradeController.getOne('')) -routes.get('/',isAuthenticated, gradeController.getAll()); +routes.get('/', gradeController.getAll()); routes.get('/student/:studentId',isAuthenticated, validation.gradeFindByStudentIdValidationRules(), validation.validate, gradeController.getStudentId()); routes.get('/:grade',isAuthenticated, validation.gradeFindByIdValidationRules(), validation.validate, gradeController.getGradeId()); diff --git a/routes/teacher.js b/routes/teacher.js index e5336c4..30efea3 100644 --- a/routes/teacher.js +++ b/routes/teacher.js @@ -10,7 +10,7 @@ const { isAuthenticated } = require('../middleware/authenticate'); routes.post('/',isAuthenticated, validation.teacherCreateValidationRules(), validation.validate, teacherController.createTeacher) //R -routes.get('/',isAuthenticated, teacherController.getAll()) +routes.get('/', teacherController.getAll()) routes.get('/:id',isAuthenticated, validation.teacherFindByIdValidationRules(), validation.validate, teacherController.getOne()) routes.get('/name/:name',isAuthenticated, validation.teacherFindNameValidationRules(), validation.validate, teacherController.getByName()) diff --git a/server.js b/server.js index 0dcaa5b..fbee400 100644 --- a/server.js +++ b/server.js @@ -7,7 +7,8 @@ const passport = require("./middleware/passport"); // Passport configuration const app = express(); const mongodb = require('./data/database.js'); -const port = process.env.PORT || 3000; +// const port = process.env.PORT || 3000; +const port = Math.floor((Math.random() * 10000) + 3000); // Middleware app.use(cors());