const Folders = require('../models/folders'); const ObjectId = require('mongodb').ObjectId; const Quizzes = require('../models/quiz'); describe('Folders', () => { let folders; let db; let collection; let quizzes; beforeEach(() => { jest.clearAllMocks(); // Clear any previous mock calls // Mock the collection object collection = { findOne: jest.fn(), insertOne: jest.fn(), find: jest.fn().mockReturnValue({ toArray: jest.fn() }), // Mock the find method deleteOne: jest.fn(), deleteMany: jest.fn(), updateOne: jest.fn(), }; // Mock the database connection db = { connect: jest.fn(), getConnection: jest.fn().mockReturnThis(), // Add getConnection method collection: jest.fn().mockReturnValue(collection), }; quizzes = new Quizzes(db); folders = new Folders(db, quizzes); }); // create describe('create', () => { it('should create a new folder and return the new folder ID', async () => { const title = 'Test Folder'; // Mock the database response collection.findOne.mockResolvedValue(null); collection.insertOne.mockResolvedValue({ insertedId: new ObjectId() }); const result = await folders.create(title, '12345'); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('folders'); expect(collection.findOne).toHaveBeenCalledWith({ title, userId: '12345' }); expect(collection.insertOne).toHaveBeenCalledWith(expect.objectContaining({ title, userId: '12345' })); expect(result).toBeDefined(); }); // throw an error if userId is undefined it('should throw an error if userId is undefined', async () => { const title = 'Test Folder'; await expect(folders.create(title, undefined)).rejects.toThrow('Missing required parameter(s)'); expect(db.connect).not.toHaveBeenCalled(); }); it('should throw an error if the folder already exists', async () => { const title = 'Existing Folder'; const userId = '66fc70bea1b9e87655cf17c9'; // Mock the database response of a found folder collection.findOne.mockResolvedValue( // real result from mongosh { _id: ObjectId.createFromHexString('66fd33fd81758a882ce99aae'), userId: userId, title: title, created_at: new Date('2024-10-02T11:52:29.797Z') } ); await expect(folders.create(title, userId)).rejects.toThrow('Folder already exists'); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('folders'); expect(collection.findOne).toHaveBeenCalledWith({ title, userId: userId }); }); }); // getUserFolders describe('getUserFolders', () => { it('should return all folders for a user', async () => { const userId = '12345'; const userFolders = [ { title: 'Folder 1', userId }, { title: 'Folder 2', userId }, ]; // Mock the database response collection.find().toArray.mockResolvedValue(userFolders); const result = await folders.getUserFolders(userId); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('folders'); expect(collection.find).toHaveBeenCalledWith({ userId }); expect(result).toEqual(userFolders); }); }); // getOwner describe('getOwner', () => { it('should return the owner of a folder', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; const userId = '12345'; // Mock the database response collection.findOne.mockResolvedValue({ userId }); const result = await folders.getOwner(folderId); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('folders'); expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); expect(result).toBe(userId); }); }); // write a test for getContent describe('getContent', () => { it('should return the content of a folder', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; const content = [ { title: 'Quiz 1', content: [] }, { title: 'Quiz 2', content: [] }, ]; // Mock the database response collection.find().toArray.mockResolvedValue(content); const result = await folders.getContent(folderId); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('files'); expect(collection.find).toHaveBeenCalledWith({ folderId }); expect(result).toEqual(content); }); it('should return an empty array if the folder has no content', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; // Mock the database response collection.find().toArray.mockResolvedValue([]); const result = await folders.getContent(folderId); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('files'); expect(collection.find).toHaveBeenCalledWith({ folderId }); expect(result).toEqual([]); }); }); // delete describe('delete', () => { it('should delete a folder and return true', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; // Mock the database response collection.deleteOne.mockResolvedValue({ deletedCount: 1 }); // Mock the folders.quizModel.deleteQuizzesByFolderId() jest.spyOn(quizzes, 'deleteQuizzesByFolderId').mockResolvedValue(true); const result = await folders.delete(folderId); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('folders'); expect(collection.deleteOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); expect(result).toBe(true); }); it('should return false if the folder does not exist', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; // Mock the database response collection.deleteOne.mockResolvedValue({ deletedCount: 0 }); const result = await folders.delete(folderId); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('folders'); expect(collection.deleteOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); expect(result).toBe(false); }); }); // rename describe('rename', () => { it('should rename a folder and return true', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; const newTitle = 'New Folder Name'; const userId = '12345'; // Mock the database response collection.updateOne.mockResolvedValue({ modifiedCount: 1 }); const result = await folders.rename(folderId, userId, newTitle); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('folders'); // { _id: ObjectId.createFromHexString(folderId), userId: userId }, { $set: { title: newTitle } } expect(collection.updateOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId), userId: userId }, { $set: { title: newTitle } }); expect(result).toBe(true); }); it('should return false if the folder does not exist', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; const newTitle = 'New Folder Name'; const userId = '12345'; // Mock the database response collection.updateOne.mockResolvedValue({ modifiedCount: 0 }); const result = await folders.rename(folderId, userId, newTitle); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('folders'); expect(collection.updateOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId), userId: userId }, { $set: { title: newTitle } }); expect(result).toBe(false); }); it('should throw an error if the new title is already in use', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; const newTitle = 'Existing Folder'; const userId = '12345'; // Mock the database response collection.findOne.mockResolvedValue({ title: newTitle }); collection.updateOne.mockResolvedValue({ modifiedCount: 0 }); await expect(folders.rename(folderId, userId, newTitle)).rejects.toThrow(`Folder with name '${newTitle}' already exists.`); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('folders'); // expect(collection.updateOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }, { $set: { title: newTitle } }); expect(collection.findOne).toHaveBeenCalledWith({ userId: userId, title: newTitle }); }); }); // duplicate describe('duplicate', () => { it('should duplicate a folder and return the new folder ID', async () => { const userId = '12345'; const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; const sourceFolder = {title: 'SourceFolder', userId: userId, content: []}; const duplicatedFolder = {title: 'SourceFolder (1)', userId: userId, created_at: expect.any(Date), content: []}; // Mock the database responses for the folder and the new folder (first one is found, second one is null) // mock the findOne method jest.spyOn(collection, 'findOne') .mockResolvedValueOnce(sourceFolder) // source file exists .mockResolvedValueOnce(null); // new name is not found // Mock the folder create method const createSpy = jest.spyOn(folders, 'create').mockResolvedValue(new ObjectId()); // mock the folder.getContent method jest.spyOn(folders, 'getContent').mockResolvedValue([{ title: 'Quiz 1', content: [] }]); // Mock the quizzes.create method jest.spyOn(quizzes, 'create').mockResolvedValue(new ObjectId()); const result = await folders.duplicate(folderId, userId); expect(db.collection).toHaveBeenCalledWith('folders'); // expect folders.create method was called expect(createSpy).toHaveBeenCalledWith(duplicatedFolder.title, userId); // expect the getContent method was called expect(folders.getContent).toHaveBeenCalledWith(folderId); // expect the quizzes.create method was called expect(quizzes.create).toHaveBeenCalledWith('Quiz 1', [], expect.any(String), userId); expect(result).toBeDefined(); }); it('should throw an error if the folder does not exist', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; // Mock the database response for the source collection.findOne.mockResolvedValue(null); await expect(folders.duplicate(folderId, '54321')).rejects.toThrow(`Folder ${folderId} not found`); // expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('folders'); expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId), userId: '54321' }); }); }); describe('folderExists', () => { it('should return true if folder exists', async () => { const title = 'Test Folder'; const userId = '12345'; // Mock the database response collection.findOne.mockResolvedValue({ title, userId }); const result = await folders.folderExists(title, userId); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('folders'); expect(collection.findOne).toHaveBeenCalledWith({ title, userId }); expect(result).toBe(true); }); it('should return false if folder does not exist', async () => { const title = 'Nonexistent Folder'; const userId = '12345'; // Mock the database response collection.findOne.mockResolvedValue(null); const result = await folders.folderExists(title, userId); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('folders'); expect(collection.findOne).toHaveBeenCalledWith({ title, userId }); expect(result).toBe(false); }); }); describe('copy', () => { it('should copy a folder and return the new folder ID', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; const userId = '12345'; const newFolderId = new ObjectId(); // Mock some quizzes that are in folder.content const sourceFolder = { title: 'Test Folder', content: [ { title: 'Quiz 1', content: [] }, { title: 'Quiz 2', content: [] }, ], }; // Mock the response from getFolderWithContent jest.spyOn(folders, 'getFolderWithContent').mockResolvedValue(sourceFolder); jest.spyOn(folders, 'create').mockResolvedValue(newFolderId); // Mock the response from Quiz.createQuiz jest.spyOn(quizzes, 'create').mockImplementation(() => {}); const result = await folders.copy(folderId, userId); // expect(db.connect).toHaveBeenCalled(); // expect(db.collection).toHaveBeenCalledWith('folders'); // expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); // expect(collection.insertOne).toHaveBeenCalledWith(expect.objectContaining({ userId })); expect(result).toBe(newFolderId); }); it('should throw an error if the folder does not exist', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; const userId = '12345'; // Mock the response from getFolderWithContent jest.spyOn(folders, 'getFolderWithContent').mockImplementation(() => { throw new Error(`Folder ${folderId} not found`); }); await expect(folders.copy(folderId, userId)).rejects.toThrow(`Folder ${folderId} not found`); // expect(db.connect).toHaveBeenCalled(); // expect(db.collection).toHaveBeenCalledWith('folders'); // expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); }); }); // write a test for getFolderWithContent describe('getFolderWithContent', () => { it('should return a folder with content', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; const folder = { _id: new ObjectId(folderId), title: 'Test Folder', }; const content = { content : [ { title: 'Quiz 1', content: [] }, { title: 'Quiz 2', content: [] }, ]}; // Mock the response from getFolderById jest.spyOn(folders, 'getFolderById').mockResolvedValue(folder); // Mock the response from getContent jest.spyOn(folders, 'getContent').mockResolvedValue(content); const result = await folders.getFolderWithContent(folderId); // expect(db.connect).toHaveBeenCalled(); // expect(db.collection).toHaveBeenCalledWith('folders'); // expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); expect(result).toEqual({ ...folder, content: content }); }); it('should throw an error if the folder does not exist', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; // // Mock the database response // collection.findOne.mockResolvedValue(null); // Mock getFolderById to throw an error jest.spyOn(folders, 'getFolderById').mockImplementation(() => { throw new Error(`Folder ${folderId} not found`); }); await expect(folders.getFolderWithContent(folderId)).rejects.toThrow(`Folder ${folderId} not found`); // expect(db.connect).toHaveBeenCalled(); // expect(db.collection).toHaveBeenCalledWith('folders'); // expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); }); }); // write a test for getFolderById describe('getFolderById', () => { it('should return a folder by ID', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; const folder = { _id: new ObjectId(folderId), title: 'Test Folder', }; // Mock the database response collection.findOne.mockResolvedValue(folder); const result = await folders.getFolderById(folderId); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('folders'); expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); expect(result).toEqual(folder); }); it('should throw an error if the folder does not exist', async () => { const folderId = '60c72b2f9b1d8b3a4c8e4d3b'; // Mock the database response collection.findOne.mockResolvedValue(null); await expect(folders.getFolderById(folderId)).resolves.toThrow(`Folder ${folderId} not found`); expect(db.connect).toHaveBeenCalled(); expect(db.collection).toHaveBeenCalledWith('folders'); expect(collection.findOne).toHaveBeenCalledWith({ _id: new ObjectId(folderId) }); }); }); });