mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-08 15:05:22 +02:00
remove plaid from queue test
This commit is contained in:
parent
024f289ee9
commit
3a9e68c5eb
2 changed files with 66 additions and 111 deletions
|
@ -2,25 +2,19 @@
|
|||
// Keep these imports above the rest to avoid errors
|
||||
// =====================================================
|
||||
import type { SharedType } from '@maybe-finance/shared'
|
||||
import type { AccountsGetResponse, TransactionsGetResponse } from 'plaid'
|
||||
import { TellerGenerator } from 'tools/generators'
|
||||
import type { AccountConnection, User } from '@prisma/client'
|
||||
import { TestUtil } from '@maybe-finance/shared'
|
||||
import { PlaidTestData } from '../../../../../tools/test-data'
|
||||
import { Prisma } from '@prisma/client'
|
||||
import prisma from '../lib/prisma'
|
||||
import { default as _plaid } from '../lib/plaid'
|
||||
import nock from 'nock'
|
||||
import { DateTime } from 'luxon'
|
||||
import { default as _teller } from '../lib/teller'
|
||||
import { resetUser } from './helpers/user.test-helper'
|
||||
|
||||
// Import the workers process
|
||||
import '../../main'
|
||||
import { queueService, securityPricingService } from '../lib/di'
|
||||
|
||||
jest.mock('plaid')
|
||||
import { queueService } from '../lib/di'
|
||||
|
||||
// For TypeScript support
|
||||
const plaid = jest.mocked(_plaid)
|
||||
jest.mock('../lib/teller')
|
||||
const teller = jest.mocked(_teller)
|
||||
|
||||
let user: User | null
|
||||
let connection: AccountConnection
|
||||
|
@ -30,25 +24,6 @@ if (process.env.IS_VSCODE_DEBUG === 'true') {
|
|||
jest.setTimeout(100000)
|
||||
}
|
||||
|
||||
beforeAll(() => {
|
||||
nock.disableNetConnect()
|
||||
|
||||
nock('https://api.polygon.io')
|
||||
.get((uri) => uri.includes('v2/aggs/ticker/AAPL/range/1/day'))
|
||||
.reply(200, PlaidTestData.AAPL)
|
||||
.persist()
|
||||
|
||||
nock('https://api.polygon.io')
|
||||
.get((uri) => uri.includes('v2/aggs/ticker/WMT/range/1/day'))
|
||||
.reply(200, PlaidTestData.WMT)
|
||||
.persist()
|
||||
|
||||
nock('https://api.polygon.io')
|
||||
.get((uri) => uri.includes('v2/aggs/ticker/VOO/range/1/day'))
|
||||
.reply(200, PlaidTestData.VOO)
|
||||
.persist()
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
|
||||
|
@ -57,10 +32,10 @@ beforeEach(async () => {
|
|||
connection = await prisma.accountConnection.create({
|
||||
data: {
|
||||
name: 'Chase Test',
|
||||
type: 'plaid' as SharedType.AccountConnectionType,
|
||||
plaidItemId: 'test-plaid-item-workers',
|
||||
plaidInstitutionId: 'ins_3',
|
||||
plaidAccessToken:
|
||||
type: 'teller' as SharedType.AccountConnectionType,
|
||||
tellerEnrollmentId: 'test-teller-item-workers',
|
||||
tellerInstitutionId: 'chase_test',
|
||||
tellerAccessToken:
|
||||
'U2FsdGVkX1+WMq9lfTS9Zkbgrn41+XT1hvSK5ain/udRPujzjVCAx/lyPG7EumVZA+nVKXPauGwI+d7GZgtqTA9R3iCZNusU6LFPnmFOCE4=', // need correct encoding here
|
||||
userId: user.id,
|
||||
syncStatus: 'PENDING',
|
||||
|
@ -84,7 +59,7 @@ describe('Message queue tests', () => {
|
|||
it('Should handle sync errors', async () => {
|
||||
const syncQueue = queueService.getQueue('sync-account-connection')
|
||||
|
||||
plaid.accountsGet.mockRejectedValueOnce('forced error for Jest tests')
|
||||
teller.getAccounts.mockRejectedValueOnce(new Error('forced error for Jest tests'))
|
||||
|
||||
await syncQueue.add('sync-connection', { accountConnectionId: connection.id })
|
||||
|
||||
|
@ -92,7 +67,7 @@ describe('Message queue tests', () => {
|
|||
where: { id: connection.id },
|
||||
})
|
||||
|
||||
expect(plaid.accountsGet).toHaveBeenCalledTimes(1)
|
||||
expect(teller.getAccounts).toHaveBeenCalledTimes(1)
|
||||
expect(updatedConnection?.status).toEqual('ERROR')
|
||||
})
|
||||
|
||||
|
@ -117,28 +92,23 @@ describe('Message queue tests', () => {
|
|||
const syncQueue = queueService.getQueue('sync-account-connection')
|
||||
|
||||
// Mock will return a basic banking checking account
|
||||
plaid.accountsGet.mockResolvedValueOnce(
|
||||
TestUtil.axiosSuccess<AccountsGetResponse>({
|
||||
accounts: [PlaidTestData.checkingAccount],
|
||||
item: PlaidTestData.item,
|
||||
request_id: 'bkVE1BHWMAZ9Rnr',
|
||||
}) as any
|
||||
)
|
||||
const mockAccounts = TellerGenerator.generateAccountsWithBalances({
|
||||
count: 1,
|
||||
institutionId: 'chase_test',
|
||||
enrollmentId: 'test-teller-item-workers',
|
||||
institutionName: 'Chase Test',
|
||||
accountType: 'depository',
|
||||
accountSubType: 'checking',
|
||||
})
|
||||
teller.getAccounts.mockResolvedValueOnce(mockAccounts)
|
||||
|
||||
plaid.transactionsGet.mockResolvedValueOnce(
|
||||
TestUtil.axiosSuccess<TransactionsGetResponse>({
|
||||
accounts: [PlaidTestData.checkingAccount],
|
||||
transactions: PlaidTestData.checkingTransactions,
|
||||
item: PlaidTestData.item,
|
||||
total_transactions: PlaidTestData.checkingTransactions.length,
|
||||
request_id: '45QSn',
|
||||
}) as any
|
||||
)
|
||||
const mockTransactions = TellerGenerator.generateTransactions(10, mockAccounts[0].id)
|
||||
teller.getTransactions.mockResolvedValueOnce(mockTransactions)
|
||||
|
||||
await syncQueue.add('sync-connection', { accountConnectionId: connection.id })
|
||||
|
||||
expect(plaid.accountsGet).toHaveBeenCalledTimes(1)
|
||||
expect(plaid.transactionsGet).toHaveBeenCalledTimes(1)
|
||||
expect(teller.getAccounts).toHaveBeenCalledTimes(1)
|
||||
expect(teller.getTransactions).toHaveBeenCalledTimes(1)
|
||||
|
||||
const item = await prisma.accountConnection.findUniqueOrThrow({
|
||||
where: { id: connection.id },
|
||||
|
@ -146,7 +116,7 @@ describe('Message queue tests', () => {
|
|||
accounts: {
|
||||
include: {
|
||||
balances: {
|
||||
where: PlaidTestData.testDates.prismaWhereFilter,
|
||||
where: TellerGenerator.testDates.prismaWhereFilter,
|
||||
orderBy: { date: 'asc' },
|
||||
},
|
||||
transactions: true,
|
||||
|
@ -161,62 +131,15 @@ describe('Message queue tests', () => {
|
|||
expect(item.accounts).toHaveLength(1)
|
||||
|
||||
const [account] = item.accounts
|
||||
|
||||
expect(account.transactions).toHaveLength(PlaidTestData.checkingTransactions.length)
|
||||
expect(account.balances.map((b) => b.balance)).toEqual(
|
||||
[
|
||||
3630,
|
||||
5125,
|
||||
5125,
|
||||
5125,
|
||||
5125,
|
||||
5125,
|
||||
5125,
|
||||
5125,
|
||||
5125,
|
||||
5125,
|
||||
5115,
|
||||
5115,
|
||||
5115,
|
||||
5089.45,
|
||||
5089.45,
|
||||
PlaidTestData.checkingAccount.balances.current!,
|
||||
].map((v) => new Prisma.Decimal(v))
|
||||
const transactionBalance = mockTransactions.reduce(
|
||||
(acc, t) => acc + t.amount,
|
||||
mockAccounts[0].balance.available
|
||||
)
|
||||
|
||||
expect(account.transactions).toHaveLength(10)
|
||||
expect(account.balances.map((b) => b.balance)).toEqual(transactionBalance)
|
||||
expect(account.holdings).toHaveLength(0)
|
||||
expect(account.valuations).toHaveLength(0)
|
||||
expect(account.investmentTransactions).toHaveLength(0)
|
||||
})
|
||||
|
||||
it('Should sync valid security prices', async () => {
|
||||
const security = await prisma.security.create({
|
||||
data: {
|
||||
name: 'Walmart Inc.',
|
||||
symbol: 'WMT',
|
||||
cusip: '93114210310',
|
||||
pricingLastSyncedAt: new Date(),
|
||||
},
|
||||
})
|
||||
|
||||
await securityPricingService.sync(security)
|
||||
|
||||
const prices = await prisma.securityPricing.findMany({
|
||||
where: { securityId: security.id },
|
||||
orderBy: { date: 'asc' },
|
||||
})
|
||||
|
||||
expect(prices).toHaveLength(PlaidTestData.WMT.results.length)
|
||||
|
||||
expect(
|
||||
prices.map((p) => ({
|
||||
date: DateTime.fromJSDate(p.date, { zone: 'utc' }).toISODate(),
|
||||
price: p.priceClose.toNumber(),
|
||||
}))
|
||||
).toEqual(
|
||||
PlaidTestData.WMT.results.map((p) => ({
|
||||
date: DateTime.fromMillis(p.t, { zone: 'utc' }).toISODate(),
|
||||
price: p.c,
|
||||
}))
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { faker } from '@faker-js/faker'
|
||||
import type { TellerTypes } from '../../libs/teller-api/src'
|
||||
import type { Prisma } from '@prisma/client'
|
||||
import { DateTime } from 'luxon'
|
||||
|
||||
function generateSubType(
|
||||
type: TellerTypes.AccountTypes
|
||||
|
@ -23,6 +25,8 @@ type GenerateAccountsParams = {
|
|||
enrollmentId: string
|
||||
institutionName: string
|
||||
institutionId: string
|
||||
accountType?: TellerTypes.AccountTypes
|
||||
accountSubType?: TellerTypes.DepositorySubtypes | TellerTypes.CreditSubtype
|
||||
}
|
||||
|
||||
export function generateAccounts({
|
||||
|
@ -30,12 +34,15 @@ export function generateAccounts({
|
|||
enrollmentId,
|
||||
institutionName,
|
||||
institutionId,
|
||||
accountType,
|
||||
accountSubType,
|
||||
}: GenerateAccountsParams) {
|
||||
const accounts: TellerTypes.Account[] = []
|
||||
for (let i = 0; i < count; i++) {
|
||||
const accountId = faker.string.uuid()
|
||||
const lastFour = faker.finance.creditCardNumber().slice(-4)
|
||||
const type: TellerTypes.AccountTypes = faker.helpers.arrayElement(['depository', 'credit'])
|
||||
const type: TellerTypes.AccountTypes =
|
||||
accountType ?? faker.helpers.arrayElement(['depository', 'credit'])
|
||||
let subType: TellerTypes.DepositorySubtypes | TellerTypes.CreditSubtype
|
||||
subType = generateSubType(type)
|
||||
|
||||
|
@ -99,6 +106,8 @@ type GenerateAccountsWithBalancesParams = {
|
|||
enrollmentId: string
|
||||
institutionName: string
|
||||
institutionId: string
|
||||
accountType?: TellerTypes.AccountTypes
|
||||
accountSubType?: TellerTypes.DepositorySubtypes | TellerTypes.CreditSubtype
|
||||
}
|
||||
|
||||
export function generateAccountsWithBalances({
|
||||
|
@ -106,7 +115,9 @@ export function generateAccountsWithBalances({
|
|||
enrollmentId,
|
||||
institutionName,
|
||||
institutionId,
|
||||
}: GenerateAccountsWithBalancesParams): TellerTypes.AccountWithBalances[] {
|
||||
accountType,
|
||||
accountSubType,
|
||||
}: GenerateAccountsWithBalancesParams): TellerTypes.GetAccountsResponse {
|
||||
const accountsWithBalances: TellerTypes.AccountWithBalances[] = []
|
||||
for (let i = 0; i < count; i++) {
|
||||
const account = generateAccounts({
|
||||
|
@ -114,6 +125,8 @@ export function generateAccountsWithBalances({
|
|||
enrollmentId,
|
||||
institutionName,
|
||||
institutionId,
|
||||
accountType,
|
||||
accountSubType,
|
||||
})[0]
|
||||
const balance = generateBalance(account.id)
|
||||
accountsWithBalances.push({
|
||||
|
@ -170,7 +183,10 @@ export function generateTransactions(count: number, accountId: string): TellerTy
|
|||
running_balance: null,
|
||||
description: faker.word.words({ count: { min: 3, max: 10 } }),
|
||||
id: transactionId,
|
||||
date: faker.date.recent({ days: 30 }).toISOString().split('T')[0], // recent date in 'YYYY-MM-DD' format
|
||||
date: faker.date
|
||||
.between({ from: lowerBound.toJSDate(), to: now.toJSDate() })
|
||||
.toISOString()
|
||||
.split('T')[0], // recent date in 'YYYY-MM-DD' format
|
||||
account_id: accountId,
|
||||
links: {
|
||||
account: `https://api.teller.io/accounts/${accountId}`,
|
||||
|
@ -246,3 +262,19 @@ export function generateConnection(): GenerateConnectionsResponse {
|
|||
transactions,
|
||||
}
|
||||
}
|
||||
|
||||
const now = DateTime.fromISO('2022-01-03', { zone: 'utc' })
|
||||
|
||||
const lowerBound = DateTime.fromISO('2021-12-01', { zone: 'utc' })
|
||||
|
||||
export const testDates = {
|
||||
now,
|
||||
lowerBound,
|
||||
totalDays: now.diff(lowerBound, 'days').days,
|
||||
prismaWhereFilter: {
|
||||
date: {
|
||||
gte: lowerBound.toJSDate(),
|
||||
lte: now.toJSDate(),
|
||||
},
|
||||
} as Prisma.AccountBalanceWhereInput,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue