Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
14 kB
0
Indexable
Never
// UserRepo test 

import client from "../../../../../lambdas/shared/client";
import { User } from "../../../../../lambdas/shared/models";
import { UserRepository } from "../../../../../lambdas/shared/repositories/legacy";
import {
  AiStatus,
  CkaStatus,
  CRSStatus,
  VerificationSource,
} from "../../../../../lambdas/shared/types";

jest.mock("../../../../../lambdas/shared/client", () => ({
  query: jest.fn(() => ({
    records: [],
  })),
  beginTransaction: jest.fn(() => ({
    transactionId: "mockTransactionId",
  })),
  commitTransaction: jest.fn(),
  rollbackTransaction: jest.fn(),
}));

describe("UserRepository tests", () => {
  let userRepository: UserRepository;
  const mockResult = { records: [{ value: "bars" }] };
  const mockQuery = jest.fn().mockResolvedValue(mockResult);
  const queryExecutor = {
    query: mockQuery,
  };

  beforeAll(() => {
    userRepository = new UserRepository({ client });
  });

  beforeEach(() => {
    jest.clearAllMocks();
  });

  it("should call findById", async () => {
    await userRepository.findById("mockId");
    expect(client.query).toHaveBeenCalledWith({
      sql: `SELECT * FROM (SELECT DISTINCT ON (u.id) * FROM users u LEFT JOIN kyc_veriff_sessions k ON u.id = k.user_id WHERE id = :userId ORDER BY u.id, k.initiated_on DESC) as us`,
      parameters: [{ name: "userId", value: "mockId" }],
    });
  });

  it("should call findAllByFilters without any filters", async () => {
    await userRepository.findAllByFilters(
      {},
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      queryExecutor as any,
      false
    );

    expect(mockQuery).toHaveBeenCalledWith(
      "SELECT * FROM (SELECT DISTINCT ON (u.id) * FROM users u LEFT JOIN kyc_veriff_sessions k ON u.id = k.user_id ORDER BY u.id, k.initiated_on DESC) as us",
      []
    );
  });

  it("should call findAllByFilters with pagination", async () => {
    await userRepository.findAllByFilters(
      { page: "1", pageSize: "50" },
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      queryExecutor as any,
      false
    );

    expect(mockQuery).toHaveBeenCalledWith(
      "SELECT *, COUNT(*) OVER() as total_count FROM (SELECT DISTINCT ON (u.id) * FROM users u LEFT JOIN kyc_veriff_sessions k ON u.id = k.user_id ORDER BY u.id, k.initiated_on DESC) as us ORDER BY created_at DESC LIMIT $1 OFFSET $2",
      ["50", 0]
    );
  });

  it("should call findAllByFilters with name", async () => {
    await userRepository.findAllByFilters(
      {
        page: "1",
        pageSize: "50",
        name: "las",
      },
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      queryExecutor as any,
      false
    );

    expect(mockQuery).toHaveBeenCalledWith(
      "SELECT *, COUNT(*) OVER() as total_count FROM (SELECT DISTINCT ON (u.id) * FROM users u LEFT JOIN kyc_veriff_sessions k ON u.id = k.user_id WHERE full_name ILIKE $1 ORDER BY u.id, k.initiated_on DESC) as us ORDER BY created_at DESC LIMIT $2 OFFSET $3",
      ["%las%", "50", 0]
    );
  });

  it("should call findAllByFilters with id", async () => {
    await userRepository.findAllByFilters(
      {
        page: "1",
        pageSize: "50",
        id: "12",
      },
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      queryExecutor as any,
      false
    );

    expect(mockQuery).toHaveBeenCalledWith(
      "SELECT *, LEVENSHTEIN(id_number, $1) as id_variance, COUNT(*) OVER() as total_count FROM (SELECT DISTINCT ON (u.id) * FROM users u LEFT JOIN kyc_veriff_sessions k ON u.id = k.user_id WHERE LEVENSHTEIN(id_number, $1) < 5 ORDER BY u.id, k.initiated_on DESC) as us ORDER BY LEVENSHTEIN(id_number, $1) ASC, created_at DESC LIMIT $2 OFFSET $3",
      ["12", "50", 0]
    );
  });

  it("should call findAllByFilters with mobile", async () => {
    await userRepository.findAllByFilters(
      {
        page: "1",
        pageSize: "50",
        mobile: "077",
      },
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      queryExecutor as any,
      false
    );
    expect(mockQuery).toHaveBeenCalledWith(
      "SELECT *, LEVENSHTEIN(mobile, $1) as mobile_variance, COUNT(*) OVER() as total_count FROM (SELECT DISTINCT ON (u.id) * FROM users u LEFT JOIN kyc_veriff_sessions k ON u.id = k.user_id WHERE LEVENSHTEIN(mobile, $1) < 5 ORDER BY u.id, k.initiated_on DESC) as us ORDER BY LEVENSHTEIN(mobile, $1) ASC, created_at DESC LIMIT $2 OFFSET $3",
      ["077", "50", 0]
    );
  });

  it("should call findAllByFilters with status", async () => {
    await userRepository.findAllByFilters(
      {
        page: "1",
        pageSize: "50",
        verification_status: "POSITIVE",
      },
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      queryExecutor as any,
      false
    );
    expect(mockQuery).toHaveBeenCalledWith(
      "SELECT *, COUNT(*) OVER() as total_count FROM (SELECT DISTINCT ON (u.id) * FROM users u LEFT JOIN kyc_veriff_sessions k ON u.id = k.user_id ORDER BY u.id, k.initiated_on DESC) as us WHERE us.verification_outcome = $3 ORDER BY created_at DESC LIMIT $1 OFFSET $2",
      ["50", 0, "POSITIVE"]
    );
  });

  it("should call findAllByFilters with multiple statuses", async () => {
    await userRepository.findAllByFilters(
      {
        page: "1",
        pageSize: "50",
        verification_status: "POSITIVE",
        sanctions_status: "REJECT",
      },
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      queryExecutor as any,
      false
    );

    expect(mockQuery).toHaveBeenCalledWith(
      "SELECT *, COUNT(*) OVER() as total_count FROM (SELECT DISTINCT ON (u.id) * FROM users u LEFT JOIN kyc_veriff_sessions k ON u.id = k.user_id ORDER BY u.id, k.initiated_on DESC) as us WHERE us.verification_outcome = $3 AND us.sanctions_outcome = $4 ORDER BY created_at DESC LIMIT $1 OFFSET $2",
      ["50", 0, "POSITIVE", "REJECT"]
    );
  });

  it("should call findAllByFilters with name and status", async () => {
    await userRepository.findAllByFilters(
      {
        page: "1",
        pageSize: "50",
        name: "las",
        verification_status: "POSITIVE",
      },

      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      queryExecutor as any,
      false
    );

    expect(mockQuery).toHaveBeenCalledWith(
      "SELECT *, COUNT(*) OVER() as total_count FROM (SELECT DISTINCT ON (u.id) * FROM users u LEFT JOIN kyc_veriff_sessions k ON u.id = k.user_id WHERE full_name ILIKE $1 ORDER BY u.id, k.initiated_on DESC) as us WHERE us.verification_outcome = $4 ORDER BY created_at DESC LIMIT $2 OFFSET $3",
      ["%las%", "50", 0, "POSITIVE"]
    );
  });

  it("should call findAllByFilters with name and mobile", async () => {
    await userRepository.findAllByFilters(
      {
        page: "1",
        pageSize: "50",
        name: "las",
        mobile: "077638",
      },
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      queryExecutor as any,
      false
    );

    expect(mockQuery).toHaveBeenCalledWith(
      "SELECT *, LEVENSHTEIN(mobile, $2) as mobile_variance, COUNT(*) OVER() as total_count FROM (SELECT DISTINCT ON (u.id) * FROM users u LEFT JOIN kyc_veriff_sessions k ON u.id = k.user_id WHERE full_name ILIKE $1 AND LEVENSHTEIN(mobile, $2) < 5 ORDER BY u.id, k.initiated_on DESC) as us ORDER BY LEVENSHTEIN(mobile, $2) ASC, created_at DESC LIMIT $3 OFFSET $4",
      ["%las%", "077638", "50", 0]
    );
  });

  it("should call findAllByFilters with name, mobile and status", async () => {
    await userRepository.findAllByFilters(
      {
        page: "1",
        pageSize: "50",
        name: "las",
        mobile: "077638",
        verification_status: "POSITIVE",
      },
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      queryExecutor as any,
      false
    );

    expect(mockQuery).toHaveBeenCalledWith(
      "SELECT *, LEVENSHTEIN(mobile, $2) as mobile_variance, COUNT(*) OVER() as total_count FROM (SELECT DISTINCT ON (u.id) * FROM users u LEFT JOIN kyc_veriff_sessions k ON u.id = k.user_id WHERE full_name ILIKE $1 AND LEVENSHTEIN(mobile, $2) < 5 ORDER BY u.id, k.initiated_on DESC) as us WHERE us.verification_outcome = $5 ORDER BY LEVENSHTEIN(mobile, $2) ASC, created_at DESC LIMIT $3 OFFSET $4",
      ["%las%", "077638", "50", 0, "POSITIVE"]
    );
  });

  it("can filter by one allowed proof of address filter", async () => {
    await userRepository.findAllByFilters(
      {
        name: "foo",
        proof_of_address_status: "EXEMPT",
      },
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      queryExecutor as any,
      false
    );

    expect(mockQuery).toHaveBeenCalledWith(
      "SELECT * FROM (SELECT DISTINCT ON (u.id) * FROM users u LEFT JOIN kyc_veriff_sessions k ON u.id = k.user_id WHERE full_name ILIKE $1 ORDER BY u.id, k.initiated_on DESC) as us WHERE us.proof_of_address_outcome = $2",
      ["%foo%", "EXEMPT"]
    );
  });

  it("it can filter by one allowed sanctions filter", async () => {
    await userRepository.findAllByFilters(
      { sanctions_status: "ACCEPT" },
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      queryExecutor as any,
      false
    );

    expect(mockQuery).toHaveBeenCalledWith(
      "SELECT * FROM (SELECT DISTINCT ON (u.id) * FROM users u LEFT JOIN kyc_veriff_sessions k ON u.id = k.user_id ORDER BY u.id, k.initiated_on DESC) as us WHERE us.sanctions_outcome = $1",
      ["ACCEPT"]
    );
  });

  it("should call updateUser", async () => {
    const user = new User({
      id: "123",
      isAdminUserSession: true,
    });

    user.date_of_birth = "2000-01-01";
    user.preferred_name = "Chocolate Tester";

    await userRepository.updateUser(user);
    expect(client.query).toBeCalledWith({
      sql: "UPDATE users SET preferred_name = :preferred_name, date_of_birth = :date_of_birth, updated_at = DEFAULT WHERE id = :userId RETURNING *",
      parameters: [
        { name: "preferred_name", value: "Chocolate Tester" },
        { name: "date_of_birth", value: "2000-01-01", cast: "date" },
        { name: "userId", value: "123" },
      ],
    });
  });

  it("should call updateUser with all the proper column mapping", async () => {
    const user = new User({
      id: "123",
      isAdminUserSession: true,
    });

    user.full_name = "John Doe";
    user.preferred_name = "John";
    user.sex = "MALE";
    user.mobile_country_code = "94";
    user.mobile = "778212132";
    user.phone_number_verified = false;
    user.id_number = "93212312";
    user.date_of_birth = "1990-10-05";
    user.nationality = "Singaporean";
    user.email = "john@gmail.com";
    user.addr_line_1 = "No 4";
    user.addr_line_2 = "Downing street";
    user.addr_line_3 = "Yemen";
    user.addr_country = "Singapore";
    user.addr_postal = "231";
    user.created_at = "2022-08-01";
    user.updated_at = "2022-08-02";
    user.cka_status = CkaStatus.NotTaken;
    user.ai_status = AiStatus.NonAi;
    user.crs_status = CRSStatus.unDeclared;
    user.verification_source = VerificationSource.Singpass;

    await userRepository.updateUser(user);
    expect(client.query).toBeCalledWith({
      sql: "UPDATE users SET full_name = :full_name, preferred_name = :preferred_name, sex = :sex, mobile_country_code = :mobile_country_code, mobile = :mobile, phone_number_verified = :phone_number_verified, id_number = :id_number, date_of_birth = :date_of_birth, nationality = :nationality, email = :email, addr_line_1 = :addr_line_1, addr_line_2 = :addr_line_2, addr_line_3 = :addr_line_3, addr_country = :addr_country, addr_postal = :addr_postal, created_at = :created_at, cka_status = :cka_status, ai_status = :ai_status, crs_status = :crs_status, verification_source = :verification_source, updated_at = DEFAULT WHERE id = :userId RETURNING *",
      parameters: [
        { name: "full_name", value: "John Doe" },
        { name: "preferred_name", value: "John" },
        { name: "sex", value: "MALE", cast: "gender" },
        { name: "mobile_country_code", value: "94" },
        { name: "mobile", value: "778212132" },
        { name: "phone_number_verified", value: false },
        { name: "id_number", value: "93212312" },
        { name: "date_of_birth", value: "1990-10-05", cast: "date" },
        { name: "nationality", value: "Singaporean" },
        { name: "email", value: "john@gmail.com" },
        { name: "addr_line_1", value: "No 4" },
        { name: "addr_line_2", value: "Downing street" },
        { name: "addr_line_3", value: "Yemen" },
        { name: "addr_country", value: "Singapore" },
        { name: "addr_postal", value: "231" },
        { name: "created_at", value: "2022-08-01", cast: "timestamp" },
        { name: "cka_status", value: "NOT_TAKEN", cast: "ckaStatus" },
        { name: "ai_status", value: "NON_AI", cast: "aiStatus" },
        { name: "crs_status", value: "UNDECLARED", cast: "CRSStatus" },
        {
          name: "verification_source",
          value: "SINGPASS",
          cast: "verificationSource",
        },
        { name: "userId", value: "123" },
      ],
    });
  });

  it("should call deleteAllByIds", async () => {
    const mockedDelete = jest.fn();
    const mockedGet = jest.fn();
    class MockIdentityProvider {
      providerId: string;
      adminDeleteUser(id: string) {
        return Promise.resolve(mockedDelete(id));
      }
      adminGetUser(id: string) {
        return Promise.resolve(mockedGet(id));
      }
      getUser(accessToken: string) {
        return Promise.resolve(mockedGet(accessToken));
      }
    }
    const userRepository = new UserRepository({
      primaryIdProvider: new MockIdentityProvider(),
      stepUpIdProvider: new MockIdentityProvider(),
      client,
    });
    await userRepository.deleteAllByIds(["mockId1", "mockId2"]);
    expect(client.query).toHaveBeenCalledWith({
      sql: `DELETE FROM users WHERE id IN (:id0, :id1)`,
      parameters: [
        { name: "id0", value: "mockId1" },
        { name: "id1", value: "mockId2" },
      ],
    });
    expect(mockedDelete).toHaveBeenNthCalledWith(1, "mockId1");
    expect(mockedDelete).toHaveBeenNthCalledWith(2, "mockId2");
    expect(mockedDelete).toHaveBeenNthCalledWith(3, "mockId1");
    expect(mockedDelete).toHaveBeenNthCalledWith(4, "mockId2");
  });
});