Skip to content

Commit

Permalink
Merge pull request #772 from King-Mikaelson/feat/profile-pic
Browse files Browse the repository at this point in the history
fix:upload profile pic
  • Loading branch information
Homoakin619 authored Aug 13, 2024
2 parents a6376a9 + 7c1e894 commit 5f8904f
Show file tree
Hide file tree
Showing 12 changed files with 25 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/app.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('Health Check Test', () => {
it('should return healthy endpoint', async () => {
const result = { message: 'This is a healthy endpoint', status_code: 200 };

expect(await healthController.health()).toStrictEqual(result);
expect(await healthController.health()).toMatchObject(result);
});
});

Expand Down
2 changes: 1 addition & 1 deletion src/database/seeding/seeding.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { Role } from '../../modules/role/entities/role.entity';
import { User } from '../../modules/user/entities/user.entity';
import { CreateAdminDto } from './dto/admin.dto';
import { CreateAdminResponseDto } from './dto/create-admin-response.dto';
import { OrganisationUserRole } from 'src/modules/role/entities/organisation-user-role.entity';
import { OrganisationUserRole } from '../../modules/role/entities/organisation-user-role.entity';

@Injectable()
export class SeedingService {
Expand Down
2 changes: 1 addition & 1 deletion src/modules/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { GenericAuthResponseDto } from './dto/generic-reponse.dto';
import { UpdatePasswordDto } from './dto/updatePasswordDto';
import { LoginErrorResponseDto } from './dto/login-error-dto';
import { UpdateUserPasswordResponseDTO } from './dto/update-user-password.dto';
import { CustomHttpException } from 'src/helpers/custom-http-filter';
import { CustomHttpException } from '../../helpers/custom-http-filter';

@ApiTags('Authentication')
@Controller('auth')
Expand Down
2 changes: 1 addition & 1 deletion src/modules/auth/tests/auth.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { GoogleAuthService } from '../google-auth.service';
import { Profile } from '../../profile/entities/profile.entity';
import { CustomHttpException } from '../../../helpers/custom-http-filter';
import { OrganisationsService } from '../../../modules/organisations/organisations.service';
import { Organisation } from 'src/modules/organisations/entities/organisations.entity';
import { Organisation } from '../../../modules/organisations/entities/organisations.entity';

jest.mock('speakeasy');

Expand Down
2 changes: 1 addition & 1 deletion src/modules/blogs/blogs.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ export class BlogService {

private validateEmptyValues(query: any): void {
for (const key in query) {
if (query.hasOwnProperty(key) && query[key] !== undefined) {
if (Object.prototype.hasOwnProperty.call(query, key) && query[key] !== undefined) {
const value = query[key];
if (typeof value === 'string' && !value.trim()) {
throw new CustomHttpException(`${key.replace(/_/g, ' ')} value is empty`, HttpStatus.BAD_REQUEST);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ export class MarkAllNotificationAsReadResponse {
type: 'object',
properties: { notifications: { type: 'array', items: { type: 'string' }, example: [] } },
})
data: {};
data: object;
}
2 changes: 1 addition & 1 deletion src/modules/products/products.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { INVALID_ORG_ID, INVALID_PRODUCT_ID } from '../../helpers/SystemMessages
import { AddCommentDto } from '../comments/dto/add-comment.dto';
import { GetTotalProductsResponseDto } from './dto/get-total-products.dto';
import { SuperAdminGuard } from '../../guards/super-admin.guard';
import { skipAuth } from 'src/helpers/skipAuth';
import { skipAuth } from '../../helpers/skipAuth';

@ApiTags('Products')
@Controller('')
Expand Down
2 changes: 1 addition & 1 deletion src/modules/profile/dto/upload-profile-pic.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ export class UploadProfilePicDto {
})
@HasMimeType(['image/jpeg', 'image/png'])
@MaxFileSize(2 * 1024 * 1024)
file: Express.Multer.File;
avatar: Express.Multer.File;
}
10 changes: 5 additions & 5 deletions src/modules/profile/profile.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export class ProfileController {

@ApiOperation({ summary: 'Upload Profile Picture' })
@ApiResponse({
status: 200,
status: 201,
description: 'Profile picture uploaded successfully',
})
@Post('upload-image')
Expand All @@ -90,12 +90,12 @@ export class ProfileController {
)
file: Express.Multer.File
): Promise<{
status: number;
message: string;
status: string;
message: string
}> {
const userId = req.user.id;
const uploadProfilePicDto = new UploadProfilePicDto()
uploadProfilePicDto.file = file;
return await this.profileService.uploadProfilePicture(userId, uploadProfilePicDto, BASE_URL);
uploadProfilePicDto.avatar = file
return await this.profileService.uploadProfilePicture(userId, uploadProfilePicDto, BASE_URL)
}
}
12 changes: 6 additions & 6 deletions src/modules/profile/profile.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ export class ProfileService {
userId: string,
uploadProfilePicDto: UploadProfilePicDto,
baseUrl: string
): Promise<{ status: number; message: string; data: { profile_picture_url: string } }> {
if (!uploadProfilePicDto.file) {
): Promise<{ status: string; message: string; data: { profile_picture_url: string } }> {
if (!uploadProfilePicDto.avatar) {
throw new CustomHttpException(SYS_MSG.NO_FILE_FOUND, HttpStatus.BAD_REQUEST);
}

Expand Down Expand Up @@ -152,11 +152,11 @@ export class ProfileService {
}
}

const fileExtension = path.extname(uploadProfilePicDto.file.originalname);
const fileExtension = path.extname(uploadProfilePicDto.avatar.originalname);
const fileName = `${userId}${fileExtension}`;
const filePath = path.join(this.uploadsDir, fileName);

const fileStream = Readable.from(uploadProfilePicDto.file.buffer);
const fileStream = Readable.from(uploadProfilePicDto.avatar.buffer);
const writeStream = fs.createWriteStream(filePath);

return new Promise((resolve, reject) => {
Expand All @@ -165,14 +165,14 @@ export class ProfileService {
Logger.error(SYS_MSG.FILE_SAVE_ERROR, err.stack);
reject(new CustomHttpException(SYS_MSG.FILE_SAVE_ERROR, HttpStatus.INTERNAL_SERVER_ERROR));
} else {
await sharp(uploadProfilePicDto.file.buffer).resize({ width: 200, height: 200 }).toFile(filePath);
await sharp(uploadProfilePicDto.avatar.buffer).resize({ width: 200, height: 200 }).toFile(filePath);

profile.profile_pic_url = `${baseUrl}/uploads/${fileName}`;

await this.profileRepository.update(profile.id, profile);
const updatedProfile = await this.profileRepository.findOne({ where: { id: profile.id } });
resolve({
status: HttpStatus.OK,
status: "success",
message: SYS_MSG.PICTURE_UPDATED,
data: { profile_picture_url: updatedProfile.profile_pic_url },
});
Expand Down
12 changes: 5 additions & 7 deletions src/modules/profile/tests/profile.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,12 @@ describe('ProfileService', () => {
buffer: Buffer.from('test'),
originalname: 'test.jpg',
};
const mockUploadProfilePicDto = { file: mockFile as any };

const mockUploadProfilePicDto = { avatar: mockFile as any };

it('should throw an exception if no file is provided', async () => {
await expect(service.uploadProfilePicture(userId, { file: null }, baseUrl)).rejects.toThrow(CustomHttpException);
await expect(service.uploadProfilePicture(userId, { avatar: null }, baseUrl)).rejects.toThrow(
CustomHttpException
);
});

it('should throw an exception if user is not found', async () => {
Expand All @@ -216,7 +217,6 @@ describe('ProfileService', () => {
});

it('should delete previous profile picture if it exists', async () => {

jest.spyOn(userRepository, 'findOne').mockResolvedValue(mockUser);

jest.spyOn(userRepository, 'findOne').mockResolvedValue(mockUser);
Expand All @@ -238,7 +238,6 @@ describe('ProfileService', () => {
});

it('should handle non-existent previous profile picture', async () => {

const mockResult: UpdateResult = {
generatedMaps: [],
raw: [],
Expand All @@ -259,7 +258,6 @@ describe('ProfileService', () => {
});

it('should save new profile picture and update profile', async () => {

jest.spyOn(userRepository, 'findOne').mockResolvedValue(mockUser);

(sharp as jest.MockedFunction<typeof sharp>).mockReturnValue({
Expand All @@ -279,7 +277,7 @@ describe('ProfileService', () => {
const result = await service.uploadProfilePicture(userId, mockUploadProfilePicDto, baseUrl);

expect(result).toEqual({
status: HttpStatus.OK,
status: 'success',
message: PICTURE_UPDATED,
data: { profile_picture_url: `${baseUrl}/uploads/${userId}.jpg` },
});
Expand Down
2 changes: 1 addition & 1 deletion src/modules/role/role.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
AttachPermissionsDto,
UpdateOrganisationRoleDto,
} from './dto/update-organisation-role.dto';
import { SuperAdminGuard } from 'src/guards/super-admin.guard';
import { SuperAdminGuard } from '../../guards/super-admin.guard';

@ApiTags('organisation Settings')
@UseGuards(SuperAdminGuard)
Expand Down

0 comments on commit 5f8904f

Please sign in to comment.