All files / app/models/user user-repository.ts

94.29% Statements 33/35
86.67% Branches 13/15
100% Functions 4/4
94.29% Lines 33/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 1351x 1x   1x 1x 1x 1x 1x 1x 1x 1x         1x                           7x 1x     6x 1x     5x 5x                                                                   11x 11x   11x 2x 2x     9x                               1x 1x         1x         1x                       2x 2x         2x 1x     1x       1x  
import config from '@app/config';
import {User} from './.';
import {RepositoryQueryOptions} from 'typings';
import sequelize from 'sequelize';
import debug from 'debug';
import {ProfilePictureNotFoundError, UserNotFoundError} from '@errors';
import {ProfilePic} from '@app/models';
import {containsTransaction, isTransaction} from '@util/is-transaction';
const log = debug('group-car:user:repository');
const error = debug('group-car:user:repository:error');
const Op = sequelize.Op;
 
/**
 * Repository for the {@link User} model.
 */
export const UserRepository = {
  /**
   * Finds a limited amount of users whose username
   * start with the specified string.
   * @param startsWith  - The string with which the usernames should start
   * @param limit       - The limit of how many users should be returns. Has
   *          a default and a max value.
   * @param options - Options
   */
  async findLimitedWithFilter(
      startsWith: string,
      limit: number = config.user.maxLimitQuery,
      options?: Partial<RepositoryQueryOptions>,
  ): Promise<User[]> {
    if (typeof startsWith !== 'string') {
      throw new TypeError('startsWith parameter has to be a string');
    }
 
    if (typeof limit !== 'number') {
      throw new TypeError('limit parameter has to be a number');
    }
 
    log('Find users with: starts with %s, limited to: %d', startsWith, limit);
    return User.findAll({
      where: {
        [Op.and]: [
          {
            // Only get not deleted users.
            deletedAt: {
              [Op.is]: null,
            },
            // Filter for specified startsWith parameter
            username: {
              [Op.startsWith]: startsWith,
            },
          },
        ],
      },
      order: [['username', 'ASC']],
      attributes: User.simpleAttributes,
      limit,
      ...containsTransaction(options),
    });
  },
 
  /**
   * Find a user by their id
   * @param id - The user id
   * @param options - Additional query options
   *
   * @throws {@link UserNotFoundError}
   * If no user with the id exists
   */
  async findById(
      id: number,
      options?: Partial<RepositoryQueryOptions>,
  ): Promise<User> {
    log('Find user %d', id);
    const user = await User.findByPk(id, containsTransaction(options));
 
    if (user === null) {
      error('User with id "%d" doesn\'t exist', id);
      throw new UserNotFoundError(id);
    }
 
    return user;
  },
 
  /**
   * Search for user by their username.
   *
   * @param username -  The username to look for
   * @param options -  Additional query options
   *
   * @throws {@link UserNotFoundError}
   * if no username exists with that username
   */
  async findByUsername(
      username: string,
      options?: Partial<RepositoryQueryOptions>,
  ): Promise<User> {
    log('Find user "%s"', username);
    const user = await User.findOne(
        {where: {username},
          ...containsTransaction(options)},
    );
 
    Iif (user === null) {
      error('User with username "%s" doesn\'t exist', username);
      throw new UserNotFoundError(username);
    }
 
    return user;
  },
 
  /**
   * Gets the profile picture of the user with the given id.
   * @param userId - The ID of the user
   * @param options - Additional options (only transaction is used)
   */
  async findProfilePictureById(
      userId: number,
      options?: Partial<RepositoryQueryOptions>,
  ): Promise<ProfilePic> {
    log('Find profile picture of user %d', userId);
    const pb = await ProfilePic.findByPk(
        userId,
        {transaction: isTransaction(options?.transaction)},
    );
 
    if (pb === null) {
      throw new ProfilePictureNotFoundError(userId);
    }
 
    return pb;
  },
};
 
export default UserRepository;