Skip to content

Commit c86ccce

Browse files
authored
Fix/uth 171 reference state (#243)
* UTH-171: Verifies update logic for application profiles and housing references --------- Co-authored-by: Sven Johansson <sven.johansson@iteam.se>
1 parent 598381b commit c86ccce

File tree

5 files changed

+344
-67
lines changed

5 files changed

+344
-67
lines changed

jest.config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ module.exports = {
44
testEnvironment: 'node',
55
modulePathIgnorePatterns: ['<rootDir>/build/'],
66
transformIgnorePatterns: ['node_modules/(?!(onecore-types)/)'],
7-
extensionsToTreatAsEsm: ['.d.ts, .ts'],
7+
extensionsToTreatAsEsm: ['.d.ts', '.ts'],
88
setupFiles: ['<rootDir>/.jest/common.ts'],
9+
setupFilesAfterEnv: ['<rootDir>/src/common/test/matchers.ts'],
910
maxWorkers: 1,
1011
globalSetup: '<rootDir>/.jest/migrate.ts',
1112
globalTeardown: '<rootDir>/.jest/teardown.ts',

src/common/test/matchers.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { expect } from '@jest/globals'
2+
3+
expect.extend({
4+
toBeSameDayAs(received, expected) {
5+
const pass =
6+
received.getFullYear() === expected.getFullYear() &&
7+
received.getMonth() === expected.getMonth() &&
8+
received.getDate() === expected.getDate()
9+
return {
10+
pass,
11+
message: () => `expected ${received} to be same day as ${expected}`,
12+
}
13+
},
14+
toBeNearDate(actual: Date, expected: Date) {
15+
return {
16+
pass: Math.abs(actual.getTime() - expected.getTime()) < 100,
17+
message: () =>
18+
`expected ${actual} and ${expected} to be less than 100ms apart`,
19+
}
20+
},
21+
})
22+
23+
declare global {
24+
// eslint-disable-next-line @typescript-eslint/no-namespace
25+
namespace jest {
26+
interface Matchers<R> {
27+
toBeSameDayAs(expected: Date): R
28+
toBeNearDate(expected: Date): R
29+
}
30+
}
31+
}

src/services/lease-service/create-or-update-application-profile.ts

Lines changed: 78 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -12,86 +12,101 @@ type Params = z.infer<
1212

1313
type ApplicationProfile = z.infer<typeof schemas.v1.ApplicationProfileSchema>
1414

15-
export async function createOrUpdateApplicationProfile(
15+
async function create(
1616
db: Knex,
1717
contactCode: string,
1818
params: Params
19-
): Promise<
20-
AdapterResult<['created' | 'updated', ApplicationProfile], 'unknown'>
21-
> {
22-
const existingProfile = await applicationProfileAdapter.getByContactCode(
19+
): Promise<AdapterResult<['created', ApplicationProfile], 'unknown'>> {
20+
const now = new Date()
21+
22+
// A new profile is created with expiresAt set to 6 months from now
23+
if (params.housingReference.reviewStatus !== 'PENDING') {
24+
params.expiresAt = addMonths(now, 6)
25+
if (!params.housingReference.expiresAt) {
26+
params.housingReference.expiresAt = addMonths(now, 6)
27+
}
28+
}
29+
params.lastUpdatedAt = now
30+
31+
const profile = await applicationProfileAdapter.create(
2332
db,
24-
contactCode
33+
contactCode,
34+
params
2535
)
2636

37+
if (!profile.ok) {
38+
return { ok: false, err: 'unknown' }
39+
}
40+
41+
return { ok: true, data: ['created', profile.data] }
42+
}
43+
44+
async function update(
45+
db: Knex,
46+
contactCode: string,
47+
existingProfile: ApplicationProfile,
48+
params: Params
49+
): Promise<AdapterResult<['updated', ApplicationProfile], 'unknown'>> {
50+
// If the profile already exists, we need to check if the housing reference
51+
// or the application profile has been updated and update the expiresAts
52+
// accordingly
2753
const now = new Date()
2854

29-
if (!existingProfile.ok) {
30-
// A new profile is created with expiresAt set to 6 months from now
31-
if (params.housingReference.reviewStatus !== 'PENDING') {
32-
params.expiresAt = addMonths(now, 6)
33-
if (!params.housingReference.expiresAt) {
34-
params.housingReference.expiresAt = addMonths(now, 6)
35-
}
36-
}
37-
params.lastUpdatedAt = now
38-
// If the profile already exists, we need to check if the housing reference
39-
} else {
40-
// or the application profile has been updated and update the expiresAts
41-
// accordingly
42-
const hasUpdatedReviewStatus =
43-
existingProfile.data.housingReference.reviewStatus !==
44-
params.housingReference.reviewStatus
45-
46-
const hasUpdatedApplicationProfile =
47-
params.housingType !== existingProfile.data.housingType ||
48-
params.housingTypeDescription !==
49-
existingProfile.data.housingTypeDescription ||
50-
params.landlord !== existingProfile.data.landlord
51-
52-
const hasUpdatedNumberOfTenants =
53-
params.numAdults !== existingProfile.data.numAdults ||
54-
params.numChildren !== existingProfile.data.numChildren
55-
56-
if (hasUpdatedApplicationProfile) {
57-
params.lastUpdatedAt = now
58-
}
55+
const hasUpdatedReviewStatus =
56+
existingProfile.housingReference.reviewStatus !==
57+
params.housingReference.reviewStatus
5958

60-
if (hasUpdatedApplicationProfile || hasUpdatedNumberOfTenants) {
61-
params.expiresAt = addMonths(now, 6)
62-
}
59+
const hasUpdatedApplicationProfile =
60+
params.housingType !== existingProfile.housingType ||
61+
params.housingTypeDescription !== existingProfile.housingTypeDescription ||
62+
params.landlord !== existingProfile.landlord
6363

64-
// If housingReference.expiresAt is not set and the housingReference
65-
// has been updated, we set it to 6 months from now
66-
if (!params.housingReference.expiresAt) {
67-
if (hasUpdatedReviewStatus) {
68-
params.housingReference.expiresAt = addMonths(now, 6)
69-
}
70-
}
64+
const hasUpdatedNumberOfTenants =
65+
params.numAdults !== existingProfile.numAdults ||
66+
params.numChildren !== existingProfile.numChildren
67+
68+
if (hasUpdatedApplicationProfile) {
69+
params.lastUpdatedAt = now
70+
}
7171

72+
if (hasUpdatedApplicationProfile || hasUpdatedNumberOfTenants) {
73+
params.expiresAt = addMonths(now, 6)
74+
}
75+
76+
// If housingReference.expiresAt is not set and the housingReference
77+
// has been updated, we set it to 6 months from now
78+
if (!params.housingReference.expiresAt) {
7279
if (hasUpdatedReviewStatus) {
73-
params.housingReference.reviewedAt = now
80+
params.housingReference.expiresAt = addMonths(now, 6)
7481
}
7582
}
7683

84+
if (hasUpdatedReviewStatus) {
85+
params.housingReference.reviewedAt = now
86+
}
87+
7788
const update = await applicationProfileAdapter.update(db, contactCode, params)
7889

79-
if (!update.ok) {
80-
if (update.err !== 'no-update') {
81-
return { ok: false, err: 'unknown' }
82-
}
83-
const profile = await applicationProfileAdapter.create(
84-
db,
85-
contactCode,
86-
params
87-
)
88-
89-
if (!profile.ok) {
90-
return { ok: false, err: 'unknown' }
91-
}
90+
return update.ok
91+
? { ok: true, data: ['updated', update.data] }
92+
: { ok: false, err: 'unknown' }
93+
}
9294

93-
return { ok: true, data: ['created', profile.data] }
94-
}
95+
export async function createOrUpdateApplicationProfile(
96+
db: Knex,
97+
contactCode: string,
98+
params: Params
99+
): Promise<
100+
AdapterResult<['created' | 'updated', ApplicationProfile], 'unknown'>
101+
> {
102+
const existingProfile = await applicationProfileAdapter.getByContactCode(
103+
db,
104+
contactCode
105+
)
95106

96-
return { ok: true, data: ['updated', update.data] }
107+
if (!existingProfile.ok) {
108+
return create(db, contactCode, params)
109+
} else {
110+
return update(db, contactCode, existingProfile.data, params)
111+
}
97112
}

0 commit comments

Comments
 (0)