fix(api): unit test

This commit is contained in:
Mohamed Marrouchi 2025-01-08 18:22:07 +01:00
parent 7be61150ac
commit 67831034ad
2 changed files with 25 additions and 9 deletions

View File

@ -6,6 +6,8 @@
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/ */
import fs from 'fs';
import { CACHE_MANAGER } from '@nestjs/cache-manager'; import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { BadRequestException } from '@nestjs/common/exceptions'; import { BadRequestException } from '@nestjs/common/exceptions';
import { NotFoundException } from '@nestjs/common/exceptions/not-found.exception'; import { NotFoundException } from '@nestjs/common/exceptions/not-found.exception';
@ -86,7 +88,10 @@ describe('AttachmentController', () => {
afterAll(closeInMongodConnection); afterAll(closeInMongodConnection);
afterEach(jest.clearAllMocks); afterEach(() => {
jest.clearAllMocks();
jest.restoreAllMocks();
});
describe('count', () => { describe('count', () => {
it('should count attachments', async () => { it('should count attachments', async () => {
@ -113,6 +118,8 @@ describe('AttachmentController', () => {
}); });
it('should upload attachment', async () => { it('should upload attachment', async () => {
jest.spyOn(fs.promises, 'writeFile').mockResolvedValue();
jest.spyOn(attachmentService, 'create'); jest.spyOn(attachmentService, 'create');
const result = await attachmentController.uploadFile( const result = await attachmentController.uploadFile(
{ {

View File

@ -6,8 +6,9 @@
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/ */
import fs, { createReadStream, promises as fsPromises } from 'fs'; import fs from 'fs';
import { join, resolve } from 'path'; import os from 'os';
import { join, normalize, resolve } from 'path';
import { Readable, Stream } from 'stream'; import { Readable, Stream } from 'stream';
import { import {
@ -95,7 +96,7 @@ export class AttachmentService extends BaseService<Attachment> {
join(config.parameters.avatarDir, `${foreign_id}.jpeg`), join(config.parameters.avatarDir, `${foreign_id}.jpeg`),
); );
if (fs.existsSync(path)) { if (fs.existsSync(path)) {
const picturetream = createReadStream(path); const picturetream = fs.createReadStream(path);
return new StreamableFile(picturetream); return new StreamableFile(picturetream);
} else { } else {
throw new NotFoundException('Profile picture not found'); throw new NotFoundException('Profile picture not found');
@ -181,7 +182,7 @@ export class AttachmentService extends BaseService<Attachment> {
const filePath = resolve(join(rootDir, sanitizeFilename(uniqueFilename))); const filePath = resolve(join(rootDir, sanitizeFilename(uniqueFilename)));
if (Buffer.isBuffer(file)) { if (Buffer.isBuffer(file)) {
await fsPromises.writeFile(filePath, file); await fs.promises.writeFile(filePath, file);
} else if (file instanceof Readable || file instanceof Stream) { } else if (file instanceof Readable || file instanceof Stream) {
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
const writeStream = fs.createWriteStream(filePath); const writeStream = fs.createWriteStream(filePath);
@ -193,11 +194,19 @@ export class AttachmentService extends BaseService<Attachment> {
} else { } else {
if (file.path) { if (file.path) {
// For example, if the file is an instance of `Express.Multer.File` (diskStorage case) // For example, if the file is an instance of `Express.Multer.File` (diskStorage case)
const srcFilePath = resolve(file.path); const srcFilePath = fs.realpathSync(resolve(file.path));
await fsPromises.copyFile(srcFilePath, filePath); // Get the system's temporary directory in a cross-platform way
await fsPromises.unlink(srcFilePath); const tempDir = os.tmpdir();
const normalizedTempDir = normalize(tempDir);
if (!srcFilePath.startsWith(normalizedTempDir)) {
throw new Error('Invalid file path');
}
await fs.promises.copyFile(srcFilePath, filePath);
await fs.promises.unlink(srcFilePath);
} else { } else {
await fsPromises.writeFile(filePath, file.buffer); await fs.promises.writeFile(filePath, file.buffer);
} }
} }