/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { testEnvironment, cleanDB, contributionDateFormatter } from '@test/helpers' import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' import { peterLustig } from '@/seeds/users/peter-lustig' import { User } from '@entity/User' import { Contribution } from '@entity/Contribution' import { userFactory } from '@/seeds/factory/user' import { login, createContribution, adminCreateContribution } from '@/seeds/graphql/mutations' import { getUserCreation } from './creations' let mutate: any, con: any let testEnv: any beforeAll(async () => { testEnv = await testEnvironment() mutate = testEnv.mutate con = testEnv.con await cleanDB() }) afterAll(async () => { await cleanDB() await con.close() }) const setZeroHours = (date: Date): Date => { return new Date(date.getFullYear(), date.getMonth(), date.getDate()) } describe('util/creation', () => { let user: User let admin: User const now = new Date() beforeAll(async () => { user = await userFactory(testEnv, bibiBloxberg) admin = await userFactory(testEnv, peterLustig) }) describe('getUserCreations', () => { beforeAll(async () => { await mutate({ mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, }) await mutate({ mutation: adminCreateContribution, variables: { email: 'bibi@bloxberg.de', amount: 250.0, memo: 'Admin contribution for this month', creationDate: contributionDateFormatter(now), }, }) await mutate({ mutation: adminCreateContribution, variables: { email: 'bibi@bloxberg.de', amount: 160.0, memo: 'Admin contribution for the last month', creationDate: contributionDateFormatter( new Date(now.getFullYear(), now.getMonth() - 1, now.getDate()), ), }, }) await mutate({ mutation: adminCreateContribution, variables: { email: 'bibi@bloxberg.de', amount: 450.0, memo: 'Admin contribution for two months ago', creationDate: contributionDateFormatter( new Date(now.getFullYear(), now.getMonth() - 2, now.getDate()), ), }, }) await mutate({ mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) await mutate({ mutation: createContribution, variables: { amount: 400.0, memo: 'Contribution for this month', creationDate: contributionDateFormatter(now), }, }) await mutate({ mutation: createContribution, variables: { amount: 500.0, memo: 'Contribution for the last month', creationDate: contributionDateFormatter( new Date(now.getFullYear(), now.getMonth() - 1, now.getDate()), ), }, }) }) it('has the correct data setup', async () => { await expect(Contribution.find()).resolves.toEqual([ expect.objectContaining({ userId: user.id, contributionDate: setZeroHours(now), amount: expect.decimalEqual(250), memo: 'Admin contribution for this month', moderatorId: admin.id, contributionType: 'ADMIN', contributionStatus: 'PENDING', }), expect.objectContaining({ userId: user.id, contributionDate: setZeroHours( new Date(now.getFullYear(), now.getMonth() - 1, now.getDate()), ), amount: expect.decimalEqual(160), memo: 'Admin contribution for the last month', moderatorId: admin.id, contributionType: 'ADMIN', contributionStatus: 'PENDING', }), expect.objectContaining({ userId: user.id, contributionDate: setZeroHours( new Date(now.getFullYear(), now.getMonth() - 2, now.getDate()), ), amount: expect.decimalEqual(450), memo: 'Admin contribution for two months ago', moderatorId: admin.id, contributionType: 'ADMIN', contributionStatus: 'PENDING', }), expect.objectContaining({ userId: user.id, contributionDate: setZeroHours(now), amount: expect.decimalEqual(400), memo: 'Contribution for this month', moderatorId: null, contributionType: 'USER', contributionStatus: 'PENDING', }), expect.objectContaining({ userId: user.id, contributionDate: setZeroHours( new Date(now.getFullYear(), now.getMonth() - 1, now.getDate()), ), amount: expect.decimalEqual(500), memo: 'Contribution for the last month', moderatorId: null, contributionType: 'USER', contributionStatus: 'PENDING', }), ]) }) describe('call getUserCreation now', () => { it('returns the expected open contributions', async () => { await expect(getUserCreation(user.id, 0)).resolves.toEqual([ expect.decimalEqual(550), expect.decimalEqual(340), expect.decimalEqual(350), ]) }) describe('run forward in time one hour before next month', () => { const targetDate = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 0, 0) beforeAll(() => { const halfMsToRun = (targetDate.getTime() - now.getTime()) / 2 jest.useFakeTimers() setTimeout(jest.fn(), halfMsToRun) jest.runAllTimers() setTimeout(jest.fn(), halfMsToRun) jest.runAllTimers() }) afterAll(() => { jest.useRealTimers() }) it('has the clock set correctly', () => { expect(new Date().toISOString()).toContain( `${targetDate.getFullYear()}-${targetDate.getMonth() + 1}-${targetDate.getDate()}T23:`, ) }) describe('call getUserCreation with UTC', () => { it('returns the expected open contributions', async () => { await expect(getUserCreation(user.id, 0)).resolves.toEqual([ expect.decimalEqual(550), expect.decimalEqual(340), expect.decimalEqual(350), ]) }) }) describe('call getUserCreation with JST (GMT+0900)', () => { it('returns the expected open contributions', async () => { await expect(getUserCreation(user.id, -540, true)).resolves.toEqual([ expect.decimalEqual(340), expect.decimalEqual(350), expect.decimalEqual(1000), ]) }) }) describe('call getUserCreation with PST (GMT-0800)', () => { it('returns the expected open contributions', async () => { await expect(getUserCreation(user.id, 480, true)).resolves.toEqual([ expect.decimalEqual(550), expect.decimalEqual(340), expect.decimalEqual(350), ]) }) }) describe('run two hours forward to be in the next month in UTC', () => { const nextMonthTargetDate = new Date() nextMonthTargetDate.setTime(targetDate.getTime() + 2 * 60 * 60 * 1000) beforeAll(() => { setTimeout(jest.fn(), 2 * 60 * 60 * 1000) jest.runAllTimers() }) it('has the clock set correctly', () => { const targetMonth = nextMonthTargetDate.getMonth() + 1 const targetMonthString = (targetMonth < 10 ? '0' : '') + String(targetMonth) expect(new Date().toISOString()).toContain( `${nextMonthTargetDate.getFullYear()}-${targetMonthString}-01T01:`, ) }) describe('call getUserCreation with UTC', () => { it('returns the expected open contributions', async () => { await expect(getUserCreation(user.id, 0, true)).resolves.toEqual([ expect.decimalEqual(340), expect.decimalEqual(350), expect.decimalEqual(1000), ]) }) }) describe('call getUserCreation with JST (GMT+0900)', () => { it('returns the expected open contributions', async () => { await expect(getUserCreation(user.id, -540, true)).resolves.toEqual([ expect.decimalEqual(340), expect.decimalEqual(350), expect.decimalEqual(1000), ]) }) }) describe('call getUserCreation with PST (GMT-0800)', () => { it('returns the expected open contributions', async () => { await expect(getUserCreation(user.id, 450, true)).resolves.toEqual([ expect.decimalEqual(550), expect.decimalEqual(340), expect.decimalEqual(350), ]) }) }) }) }) }) }) })