Skip to content

Commit f7c8682

Browse files
committed
placeOfEvent test
1 parent 33574cb commit f7c8682

File tree

3 files changed

+63
-44
lines changed

3 files changed

+63
-44
lines changed

packages/events/src/service/indexing/indexing.test.ts

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@ import {
1717
AddressType,
1818
createPrng,
1919
EventConfig,
20+
EventState,
2021
field,
2122
FieldConditional,
2223
FieldType,
2324
generateActionDeclarationInput,
25+
generateUuid,
2426
LocationType,
2527
QueryType,
26-
TENNIS_CLUB_MEMBERSHIP
28+
TENNIS_CLUB_MEMBERSHIP,
29+
TestUserRole
2730
} from '@opencrvs/commons/events'
28-
import { getUUID } from '@opencrvs/commons'
2931
import {
3032
createTestClient,
3133
setupTestCase,
@@ -829,7 +831,9 @@ test('builds Address field query', async () => {
829831

830832
test('placeOfEvent resolves from conditional address fields and returns leaf-level locations in search results', async () => {
831833
// Setup: Generate location IDs upfront
832-
const parentLocationId = getUUID()
834+
const prng = createPrng(942)
835+
const childOfficeId = generateUuid(prng)
836+
const parentLocationId = generateUuid(prng)
833837

834838
// Setup: Configure event with conditional address fields
835839
const createAddressField = (
@@ -873,11 +877,10 @@ test('placeOfEvent resolves from conditional address fields and returns leaf-lev
873877
if (i !== 0) {
874878
return page
875879
}
876-
877880
return {
878881
...page,
879882
fields: [
880-
...page.fields,
883+
...page.fields.filter((x) => x.type !== FieldType.ADDRESS),
881884
{
882885
id: 'addressType',
883886
type: FieldType.TEXT,
@@ -886,69 +889,72 @@ test('placeOfEvent resolves from conditional address fields and returns leaf-lev
886889
defaultMessage: 'Address Type',
887890
description: ''
888891
},
889-
defaultValue: 'homeAddress'
892+
defaultValue: 'home.address'
890893
},
891-
createAddressField('homeAddress', [
894+
createAddressField('home.address', [
892895
{
893896
type: 'SHOW',
894-
conditional: field('addressType').isEqualTo('homeAddress')
897+
conditional: field('addressType').isEqualTo('home.address')
895898
}
896899
]),
897-
createAddressField('officeAddress', [
900+
createAddressField('office.address', [
898901
{
899902
type: 'SHOW',
900-
conditional: field('addressType').isEqualTo('officeAddress')
903+
conditional: field('addressType').isEqualTo('office.address')
901904
}
902905
])
903906
]
904907
}
905908
})
906909
},
907-
placeOfEvent: [field('homeAddress'), field('officeAddress')]
910+
placeOfEvent: [field('home.address'), field('office.address')]
908911
}
909-
910-
const { user, generator, seed } = await setupTestCase(
911-
100,
912-
modifiedEventConfig
913-
)
914-
915912
mswServer.use(
916913
http.get(`${env.COUNTRY_CONFIG_URL}/events`, () => {
917914
return HttpResponse.json([modifiedEventConfig])
918915
})
919916
)
920917

918+
// Setup: seed, user, client, esClient
919+
const { generator, seed } = await setupTestCase(942, modifiedEventConfig)
920+
921+
const user = seed.user({
922+
role: TestUserRole.enum.LOCAL_REGISTRAR,
923+
name: [{ use: 'en', family: 'Doe', given: ['John'] }],
924+
primaryOfficeId: childOfficeId,
925+
fullHonorificName: undefined
926+
})
927+
921928
const client = createTestClient(user, [
922929
...TEST_USER_DEFAULT_SCOPES,
923930
`search[event=${TENNIS_CLUB_MEMBERSHIP},access=all]`
924931
])
925932
const esClient = getOrCreateClient()
926933

927934
// Setup: Create location hierarchy (grandparent -> parent -> child office)
928-
const locationRng = createPrng(842)
929935
const grandParentLocation = {
930-
...generator.locations.set(1, locationRng)[0],
936+
...generator.locations.set(1, prng)[0],
931937
locationType: LocationType.enum.ADMIN_STRUCTURE,
932938
name: 'Grand Parent location'
933939
}
934940
const parentLocation = {
935-
...generator.locations.set(1, locationRng)[0],
941+
...generator.locations.set(1, prng)[0],
936942
id: parentLocationId,
937943
parentId: grandParentLocation.id,
938944
locationType: LocationType.enum.ADMIN_STRUCTURE,
939945
name: 'Parent location'
940946
}
941947
const childOffice = {
942-
...generator.locations.set(1, locationRng)[0],
948+
...generator.locations.set(1, prng)[0],
943949
id: user.primaryOfficeId,
944-
parentId: parentLocation.id,
950+
parentId: parentLocationId,
945951
name: 'Child location',
946952
locationType: LocationType.enum.CRVS_OFFICE
947953
}
948954

949955
await seed.locations([grandParentLocation, parentLocation, childOffice])
950956

951-
// Test Part 1: Declare event with homeAddress, verify ES contains full hierarchy
957+
// Test Part 1: Declare event with home.address, verify ES contains full hierarchy
952958
const createdEvent = await client.event.create(
953959
generator.event.create({ type: TENNIS_CLUB_MEMBERSHIP })
954960
)
@@ -959,12 +965,12 @@ test('placeOfEvent resolves from conditional address fields and returns leaf-lev
959965
ActionType.DECLARE,
960966
createPrng(100)
961967
),
962-
addressType: 'homeAddress',
963-
homeAddress: {
968+
addressType: 'home.address',
969+
'home.address': {
964970
country: 'FAR',
965971
streetLevelDetails: { town: 'Gazipur' },
966972
addressType: AddressType.DOMESTIC,
967-
administrativeArea: parentLocation.id
973+
administrativeArea: parentLocationId
968974
}
969975
}
970976

@@ -1014,12 +1020,13 @@ test('placeOfEvent resolves from conditional address fields and returns leaf-lev
10141020
}
10151021
},
10161022
declaration: {
1017-
applicant____address: {
1018-
administrativeArea: [
1019-
grandParentLocation.id,
1020-
parentLocation.id,
1021-
childOffice.id
1022-
]
1023+
home____address: {
1024+
addressType: 'DOMESTIC',
1025+
country: 'FAR',
1026+
streetLevelDetails: {
1027+
town: 'Gazipur'
1028+
},
1029+
administrativeArea: [grandParentLocation.id, parentLocation.id]
10231030
}
10241031
}
10251032
})
@@ -1037,18 +1044,22 @@ test('placeOfEvent resolves from conditional address fields and returns leaf-lev
10371044
childOffice.id
10381045
)
10391046

1040-
// Test Part 2: Register event with officeAddress, verify placeOfEvent updates correctly
1041-
1042-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
1043-
const { homeAddress, ...declarationWithoutHomeAddress } =
1047+
// Test Part 2: Register event with office.address, verify placeOfEvent updates correctly
1048+
const declarationWithoutHomeAddress = Object.keys(
10441049
declarationWithHomeAddress
1050+
).reduce((obj, key) => {
1051+
if (key !== 'home.address') {
1052+
obj[key] = (declarationWithHomeAddress as EventState)[key]
1053+
}
1054+
return obj
1055+
}, {} as EventState)
10451056

10461057
await client.event.actions.register.request(
10471058
generator.event.actions.register(createdEvent.id, {
10481059
declaration: {
10491060
...declarationWithoutHomeAddress,
1050-
addressType: 'officeAddress',
1051-
officeAddress: {
1061+
addressType: 'office.address',
1062+
'office.address': {
10521063
country: 'FAR',
10531064
streetLevelDetails: { town: 'Dhaka' },
10541065
addressType: AddressType.DOMESTIC,

packages/events/src/service/indexing/indexing.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,12 +343,17 @@ export async function indexEventsInBulk(
343343
) {
344344
const esClient = getOrCreateClient()
345345

346+
const locationHierarchyCache = new Map<string, string[]>()
346347
const indexedDocs = await Promise.all(
347348
batch.map(async (doc) => {
348349
const config = getEventConfigById(configs, doc.type)
349350
const eventIndex = eventToEventIndex(doc, config)
350351
const eventIndexWithLocationHierarchy =
351-
await getEventIndexWithLocationHierarchy(config, eventIndex)
352+
await getEventIndexWithLocationHierarchy(
353+
config,
354+
eventIndex,
355+
locationHierarchyCache
356+
)
352357
return [
353358
{ index: { _index: getEventIndexName(doc.type), _id: doc.id } },
354359
eventIndexWithLocationHierarchy

packages/events/src/service/indexing/utils.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,25 +185,28 @@ export function getEventIndexWithoutLocationHierarchy(
185185
*
186186
* @param eventConfig Event configuration containing field definitions
187187
* @param event Event index with leaf-level location UUIDs
188+
* @param locationHierarchyCache Optional in-memory cache for location hierarchies, to avoid redundant lookups
188189
* @returns Event index with full location hierarchies (arrays of UUIDs from top to leaf)
189190
*/
190-
const locationHierarchyCache = new Map<string, string[]>()
191191
export async function getEventIndexWithLocationHierarchy(
192192
eventConfig: EventConfig,
193-
event: EventIndex
193+
event: EventIndex,
194+
locationHierarchyCache?: Map<string, string[]>
194195
) {
195196
const buildFullLocationHierarchy = async (
196197
locationId: UUID
197198
): Promise<string[]> => {
198199
if (!locationId) {
199200
return []
200201
}
201-
if (locationHierarchyCache.has(locationId)) {
202+
if (locationHierarchyCache && locationHierarchyCache.has(locationId)) {
202203
return locationHierarchyCache.get(locationId) || [locationId]
203204
}
204205
const hierarchyRows = await getLocationHierarchyRaw(locationId)
205-
locationHierarchyCache.set(locationId, hierarchyRows)
206-
return locationHierarchyCache.get(locationId) || [locationId]
206+
if (locationHierarchyCache) {
207+
locationHierarchyCache.set(locationId, hierarchyRows)
208+
}
209+
return hierarchyRows
207210
}
208211
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
209212
const tempEvent = { ...event, declaration: { ...event.declaration } } as any

0 commit comments

Comments
 (0)