@nestjs/common#UnsupportedMediaTypeException TypeScript Examples

The following examples show how to use @nestjs/common#UnsupportedMediaTypeException. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: profile.controller.ts    From codeclannigeria-backend with MIT License 6 votes vote down vote up
@Post('upload_profile_photo')
  @UseInterceptors(FileInterceptor('file'))
  @ApiConsumes('multipart/form-data')
  @ApiBody({
    description: 'Upload avatar photo',
    type: AvatarUploadDto
  })
  @UseGuards(JwtAuthGuard)
  @ApiBearerAuth()
  @ApiResponse({ type: UserDto, status: HttpStatus.OK })
  @HttpCode(HttpStatus.OK)
  async uploadFile(
    @UploadedFile() file: BufferedFile,
    @Req() req: Request
  ): Promise<UserDto> {
    if (!file) throw new BadRequestException('File image cannot be empty');

    if (file.mimetype.split('/')[0] !== 'image')
      throw new UnsupportedMediaTypeException('File is not an image');

    if (file.size / 1024 > 200)
      throw new BadRequestException('File cannot be larger than 200KB');

    const id = req.user['userId'];
    await this.profileService.uploadAvatar(file, id);
    const user = await this.userService.findByIdAsync(id);

    return plainToClass(UserDto, user, {
      enableImplicitConversion: true,
      excludeExtraneousValues: true
    });
  }
Example #2
Source File: tracks.controller.ts    From codeclannigeria-backend with MIT License 6 votes vote down vote up
@Post('create_with_thumbnail')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.MENTOR)
  @ApiResponse({ type: TrackDto, status: HttpStatus.CREATED })
  @ApiResponse({ status: HttpStatus.FORBIDDEN, type: ApiException })
  @UseInterceptors(FileInterceptor('thumbnail'))
  @ApiConsumes('multipart/form-data')
  @ApiBearerAuth()
  async createTrack(
    @Body() input: CreateWithThumbnailTrackDto,
    @UploadedFile() thumbnail: BufferedFile,
    @Req() req: Request
  ): Promise<TrackDto> {
    if (!thumbnail)
      throw new BadRequestException('Thumbnail image cannot be empty');
    if (thumbnail.mimetype.split('/')[0] !== 'image')
      throw new UnsupportedMediaTypeException('File is not an image');
    if (thumbnail.size / ONE_KB > 200)
      throw new BadRequestException('File cannot be larger than 200KB');
    const exist = await this.trackService.findOneAsync({
      title: input.title.toUpperCase()
    });
    if (exist)
      throw new ConflictException(
        `Track with the title "${exist.title}" already exists`
      );

    const userId = req.user['userId'];
    const thumbnailUrl = await uploadFileToCloud(thumbnail, 'avatars', userId);
    const dto = input as any;
    dto.thumbnailUrl = thumbnailUrl;
    delete dto.thumbnail;
    return await super.create(dto);
  }
Example #3
Source File: profile.controller.spec.ts    From codeclannigeria-backend with MIT License 5 votes vote down vote up
describe('Profile Controller', () => {
  let controller: ProfileController;
  const req: any = { user: { userId: "userId" } };
  const profileService: any = { uploadAvatar: () => Promise.resolve() }
  const userService: any = {
    findByIdAsync: () => 'user',
    findById: () => ({ tracks: [], id: 'id' })
  }
  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      imports: [ProfileModule, DbTest]
    })
      .overrideProvider(UsersService)
      .useValue(userService)
      .overrideProvider(ProfileService)
      .useValue(profileService)
      .compile();

    controller = module.get<ProfileController>(ProfileController);
  });

  it('should be defined', () => {
    expect(controller).toBeDefined();
  });

  it('should get current logged in user', async () => {

    const result = await controller.getProfile(req);
    expect(result.id).toBe('id')
  });

  it('should update current user', async () => {
    const input: UpdateProfileDto = {
      firstName: 'firstName',
      lastName: 'lastName',
      country: "Nigeria",
      city: "Abuja",
      gender: Gender.FEMALE,
      dob: new Date(2000, 1, 1)
    }
    userService.updateAsync = () => Promise.resolve();
    return controller.updateProfile(input, req);
  });

  describe('Avatar Upload', () => {
    const file: BufferedFile = {
      fieldname: 'avatar',
      mimetype: 'video/mp4',
      buffer: 'string',
      encoding: 'encoding',
      size: 1024 * 201,
      originalname: 'avatar'
    }
    it(`should throw ${UnsupportedMediaTypeException.name} exception for non-image file`, async () => {
      await expect(controller.uploadFile(file, req)).rejects.toThrowError(UnsupportedMediaTypeException);
    });
    it(`should throw ${BadRequestException.name} exception if image is larger than 200KB`, async () => {
      file.mimetype = "image/jpg"
      await expect(controller.uploadFile(file, req)).rejects.toThrowError(BadRequestException);
    });
    it('should upload file', async () => {
      file.size = 1024 * 200;
      const result = await controller.uploadFile(file, req);
      expect(result).toBe('user')
    });
  });
});
Example #4
Source File: profile.e2e-spec.ts    From codeclannigeria-backend with MIT License 4 votes vote down vote up
describe('ProfileController (e2e)', () => {
  let app: INestApplication;
  let route: request.SuperTest<request.Test>;
  let currentUser: JwtPayload;
  let mongo: typeof mongoose;
  let UserModel: ReturnModelType<typeof User>;

  const validEmail = '[email protected]';
  const validPass = 'pass@45Pdd';

  const jwtGuard = {
    canActivate: (context: ExecutionContext): boolean => {
      const req = context.switchToHttp().getRequest();
      req.user = currentUser;
      return true;
    }
  };

  beforeAll(async () => {
    const module: TestingModule = await Test.createTestingModule({
      imports: [ProfileModule, DbTest],
      providers: [JwtStrategy]
    })
      .overrideGuard(JwtAuthGuard)
      .useValue(jwtGuard)
      .compile();

    app = module.createNestApplication();
    app.useGlobalPipes(
      new ValidationPipe({
        whitelist: true,
        forbidUnknownValues: true,
        forbidNonWhitelisted: true,
        transform: true,
        transformOptions: {
          enableImplicitConversion: true
        }
      })
    );

    await app.init();

    const { uri } = await inMemoryDb.runningInstance;
    mongoose.Promise = Promise;
    mongo = await mongoose.connect(uri, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      useCreateIndex: true,
      useFindAndModify: false
    });
    UserModel = getModelForClass(User, { existingMongoose: mongo });
    const user = await UserModel.create({
      email: validEmail,
      firstName: 'firstName',
      lastName: 'lastName',
      password: validPass
    });

    currentUser = {
      email: user.email,
      userId: user.id,
      role: user.role
    };
    route = request(app.getHttpServer());
  });

  it('should get current user', async () => {
    const { body } = await route.get('/profile').expect(200);
    expect(currentUser.userId).toBe(body.id);
  });

  it('should update current user detail', async () => {
    await UserModel.updateOne({ _id: currentUser.userId }, {
      createdBy: currentUser.userId
    } as any);
    const input: UpdateProfileDto = {
      firstName: 'NewFirstName',
      lastName: 'NewLastName',
      phoneNumber: '+2348074455596',
      technologies: ['.NET', 'NodeJs'],
      description: 'description',
      city: 'Lagos',
      dob: new Date(2000, 1, 1),
      country: 'Nigeria',
      gender: Gender.FEMALE
    };
    await route.put('/profile').send(input).expect(200);

    const user = await UserModel.findById(currentUser.userId);
    expect(user.phoneNumber).toBe(input.phoneNumber);
    expect(user.firstName).toBe(input.firstName);
  });

  describe('Mentees/Mentors', () => {
    const MentorMenteeModel = getModelForClass(MentorMentee, {
      existingMongoose: mongo
    });
    let track: Track;
    const TrackModel = getModelForClass(Track, { existingMongoose: mongo });
    it('should get user mentees', async () => {
      track = await TrackModel.create({
        title: 'title',
        description: 'description'
      });
      const mentee = await UserModel.create({
        email: '[email protected]',
        firstName: 'Mentee',
        lastName: 'Mentee',
        password: validPass,
        tracks: [track]
      });
      currentUser.role = UserRole.MENTOR;
      await MentorMenteeModel.create({
        mentor: currentUser.userId,
        mentee: mentee.id,
        track: track.id
      });
      const { body } = await route.get('/profile/mentees').expect(200);
      expect(body.items.length).toBeGreaterThan(0);
      expect(body.items[0].id).toContain(mentee.id);
      expect(body.items[0].firstName).toContain(mentee.firstName);
    });

    it('should get user mentors', async () => {
      const mentor = await UserModel.create({
        email: '[email protected]',
        firstName: 'Mentor',
        lastName: 'Mentor',
        password: validPass
      });
      currentUser.role = UserRole.MENTEE;
      await MentorMenteeModel.create({
        mentee: currentUser.userId,
        mentor: mentor.id,
        track: track.id
      });
      const { body } = await route.get('/profile/mentors').expect(200);
      expect(body.items.length).toBeGreaterThan(0);
      expect(body.items[0].id).toContain(mentor.id);
      expect(body.items[0].firstName).toContain(mentor.firstName);
    });
  });

  describe('File Upload', () => {
    it(`should return ${UnsupportedMediaTypeException.name} for non-image files`, async () => {
      return route
        .post('/profile/upload_profile_photo')
        .set('Content-Type', 'multipart/form-data')
        .attach('file', './docs/coverage.html')
        .expect(HttpStatus.UNSUPPORTED_MEDIA_TYPE);
    });
    it('should upload avatar', async () => {
      const mockPhotoUrl = 'https://www.securePhtotUrl.com';
      jest.spyOn(uploader, 'uploadFileToCloud').mockResolvedValue(mockPhotoUrl);

      const { body } = await route
        .post('/profile/upload_profile_photo')
        .set('Content-Type', 'multipart/form-data')
        .attach('file', './docs/images/compodoc-vectorise.png')
        .expect(HttpStatus.OK);

      expect(body.photoUrl).toBe(mockPhotoUrl);
    });
  });
  afterAll(async () => {
    const { collections } = mongoose.connection;

    Object.keys(collections).forEach(async (k) =>
      collections[`${k}`].deleteMany({})
    );

    // await mongo.disconnect();
    // await inMemoryDb.stop();
    await app.close();
  });
});