Skip to content

Commit bb5fe25

Browse files
authored
Implementation of user-affiliation loaders and tests (canada-ca#1113)
* Implementation of loaders and tests * Update and amend tests and loader functionality * Fix queries
1 parent 7d8adfd commit bb5fe25

14 files changed

Lines changed: 3134 additions & 1298 deletions

api-js/package-lock.json

Lines changed: 42 additions & 730 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
1+
const dotenv = require('dotenv-safe')
2+
dotenv.config()
3+
const { DB_PASS: rootPass, DB_URL: url } = process.env
4+
5+
const { ArangoTools, dbNameFromFile } = require('arango-tools')
6+
const { makeMigrations } = require('../../migrations')
7+
const { affiliationLoaderByKey } = require('../loaders')
8+
const { setupI18n } = require('@lingui/core')
9+
10+
const englishMessages = require('../locale/en/messages')
11+
const frenchMessages = require('../locale/fr/messages')
12+
13+
describe('given a affiliationLoaderByKey dataloader', () => {
14+
let query,
15+
drop,
16+
truncate,
17+
migrate,
18+
collections,
19+
orgOne,
20+
orgTwo,
21+
affOne,
22+
user,
23+
i18n
24+
25+
let consoleOutput = []
26+
const mockedError = (output) => consoleOutput.push(output)
27+
beforeAll(async () => {
28+
console.error = mockedError
29+
})
30+
31+
beforeEach(async () => {
32+
;({ migrate } = await ArangoTools({ rootPass, url }))
33+
;({ query, drop, truncate, collections } = await migrate(
34+
makeMigrations({ databaseName: dbNameFromFile(__filename), rootPass }),
35+
))
36+
await truncate()
37+
user = await collections.users.save({
38+
userName: 'test.account@istio.actually.exists',
39+
displayName: 'Test Account',
40+
preferredLang: 'french',
41+
tfaValidated: false,
42+
emailValidated: false,
43+
})
44+
orgOne = await collections.organizations.save({
45+
orgDetails: {
46+
en: {
47+
slug: 'treasury-board-secretariat',
48+
acronym: 'TBS',
49+
name: 'Treasury Board of Canada Secretariat',
50+
zone: 'FED',
51+
sector: 'TBS',
52+
country: 'Canada',
53+
province: 'Ontario',
54+
city: 'Ottawa',
55+
},
56+
fr: {
57+
slug: 'secretariat-conseil-tresor',
58+
acronym: 'SCT',
59+
name: 'Secrétariat du Conseil Trésor du Canada',
60+
zone: 'FED',
61+
sector: 'TBS',
62+
country: 'Canada',
63+
province: 'Ontario',
64+
city: 'Ottawa',
65+
},
66+
},
67+
})
68+
orgTwo = await collections.organizations.save({
69+
orgDetails: {
70+
en: {
71+
slug: 'not-treasury-board-secretariat',
72+
acronym: 'NTBS',
73+
name: 'Not Treasury Board of Canada Secretariat',
74+
zone: 'NFED',
75+
sector: 'NTBS',
76+
country: 'Canada',
77+
province: 'Ontario',
78+
city: 'Ottawa',
79+
},
80+
fr: {
81+
slug: 'ne-pas-secretariat-conseil-tresor',
82+
acronym: 'NPSCT',
83+
name: 'Ne Pas Secrétariat du Conseil Trésor du Canada',
84+
zone: 'NPFED',
85+
sector: 'NPTBS',
86+
country: 'Canada',
87+
province: 'Ontario',
88+
city: 'Ottawa',
89+
},
90+
},
91+
})
92+
affOne = await collections.affiliations.save({
93+
_from: orgOne._id,
94+
_to: user._id,
95+
permission: 'user',
96+
})
97+
await collections.affiliations.save({
98+
_from: orgTwo._id,
99+
_to: user._id,
100+
permission: 'user',
101+
})
102+
consoleOutput = []
103+
})
104+
105+
afterEach(async () => {
106+
await drop()
107+
})
108+
109+
describe('language is set to english', () => {
110+
beforeAll(() => {
111+
i18n = setupI18n({
112+
language: 'en',
113+
locales: ['en', 'fr'],
114+
missing: 'Traduction manquante',
115+
catalogs: {
116+
en: englishMessages,
117+
fr: frenchMessages,
118+
},
119+
})
120+
})
121+
describe('given a single id', () => {
122+
it('returns a single user affiliation', async () => {
123+
// Get affiliation From db
124+
const expectedCursor = await query`
125+
FOR affiliation IN affiliations
126+
FILTER affiliation._id == ${affOne._id}
127+
LET orgKey = PARSE_IDENTIFIER(affiliation._from).key
128+
LET userKey = PARSE_IDENTIFIER(affiliation._to).key
129+
RETURN MERGE(affiliation, { orgKey: orgKey, userKey: userKey })
130+
`
131+
const expectedAffiliation = await expectedCursor.next()
132+
133+
const loader = affiliationLoaderByKey(query, i18n)
134+
const affiliation = await loader.load(expectedAffiliation._key)
135+
136+
expect(affiliation).toEqual(expectedAffiliation)
137+
})
138+
})
139+
describe('provided a list of ids', () => {
140+
it('returns a list of user affiliations', async () => {
141+
const affiliationIds = []
142+
const expectedAffiliations = []
143+
const expectedCursor = await query`
144+
FOR affiliation IN affiliations
145+
LET orgKey = PARSE_IDENTIFIER(affiliation._from).key
146+
LET userKey = PARSE_IDENTIFIER(affiliation._to).key
147+
RETURN MERGE(affiliation, { orgKey: orgKey, userKey: userKey })
148+
`
149+
150+
while (expectedCursor.hasNext()) {
151+
const tempAff = await expectedCursor.next()
152+
affiliationIds.push(tempAff._key)
153+
expectedAffiliations.push(tempAff)
154+
}
155+
156+
const loader = affiliationLoaderByKey(query, i18n)
157+
const affiliations = await loader.loadMany(affiliationIds)
158+
expect(affiliations).toEqual(expectedAffiliations)
159+
})
160+
})
161+
describe('database error is raised', () => {
162+
it('throws an error', async () => {
163+
const expectedCursor = await query`
164+
FOR affiliation IN affiliations
165+
FILTER affiliation._id == ${affOne._id}
166+
LET orgKey = PARSE_IDENTIFIER(affiliation._from).key
167+
LET userKey = PARSE_IDENTIFIER(affiliation._to).key
168+
RETURN MERGE(affiliation, { orgKey: orgKey, userKey: userKey })
169+
`
170+
const expectedAffiliation = await expectedCursor.next()
171+
172+
query = jest
173+
.fn()
174+
.mockRejectedValue(new Error('Database error occurred.'))
175+
const loader = affiliationLoaderByKey(query, i18n)
176+
177+
try {
178+
await loader.load(expectedAffiliation._key)
179+
} catch (err) {
180+
expect(err).toEqual(
181+
new Error('Unable to find user affiliation(s). Please try again.'),
182+
)
183+
}
184+
185+
expect(consoleOutput).toEqual([
186+
`Database error occurred when running affiliationLoaderByKey: Error: Database error occurred.`,
187+
])
188+
})
189+
})
190+
describe('cursor error is raised', () => {
191+
it('throws an error', async () => {
192+
const expectedCursor = await query`
193+
FOR affiliation IN affiliations
194+
FILTER affiliation._id == ${affOne._id}
195+
LET orgKey = PARSE_IDENTIFIER(affiliation._from).key
196+
LET userKey = PARSE_IDENTIFIER(affiliation._to).key
197+
RETURN MERGE(affiliation, { orgKey: orgKey, userKey: userKey })
198+
`
199+
const expectedAffiliation = await expectedCursor.next()
200+
201+
const cursor = {
202+
each() {
203+
throw new Error('Cursor error occurred.')
204+
},
205+
}
206+
query = jest.fn().mockReturnValue(cursor)
207+
const loader = affiliationLoaderByKey(query, i18n)
208+
209+
try {
210+
await loader.load(expectedAffiliation._key)
211+
} catch (err) {
212+
expect(err).toEqual(
213+
new Error('Unable to find user affiliation(s). Please try again.'),
214+
)
215+
}
216+
217+
expect(consoleOutput).toEqual([
218+
`Cursor error occurred during affiliationLoaderByKey: Error: Cursor error occurred.`,
219+
])
220+
})
221+
})
222+
})
223+
describe('language is set to french', () => {
224+
beforeAll(() => {
225+
i18n = setupI18n({
226+
language: 'fr',
227+
locales: ['en', 'fr'],
228+
missing: 'Traduction manquante',
229+
catalogs: {
230+
en: englishMessages,
231+
fr: frenchMessages,
232+
},
233+
})
234+
})
235+
describe('given a single id', () => {
236+
it('returns a single user affiliation', async () => {
237+
// Get affiliation From db
238+
const expectedCursor = await query`
239+
FOR affiliation IN affiliations
240+
FILTER affiliation._id == ${affOne._id}
241+
LET orgKey = PARSE_IDENTIFIER(affiliation._from).key
242+
LET userKey = PARSE_IDENTIFIER(affiliation._to).key
243+
RETURN MERGE(affiliation, { orgKey: orgKey, userKey: userKey })
244+
`
245+
const expectedAffiliation = await expectedCursor.next()
246+
247+
const loader = affiliationLoaderByKey(query, i18n)
248+
const affiliation = await loader.load(expectedAffiliation._key)
249+
250+
expect(affiliation).toEqual(expectedAffiliation)
251+
})
252+
})
253+
describe('provided a list of ids', () => {
254+
it('returns a list of user affiliations', async () => {
255+
const affiliationIds = []
256+
const expectedAffiliations = []
257+
const expectedCursor = await query`
258+
FOR affiliation IN affiliations
259+
LET orgKey = PARSE_IDENTIFIER(affiliation._from).key
260+
LET userKey = PARSE_IDENTIFIER(affiliation._to).key
261+
RETURN MERGE(affiliation, { orgKey: orgKey, userKey: userKey })
262+
`
263+
264+
while (expectedCursor.hasNext()) {
265+
const tempAff = await expectedCursor.next()
266+
affiliationIds.push(tempAff._key)
267+
expectedAffiliations.push(tempAff)
268+
}
269+
270+
const loader = affiliationLoaderByKey(query, i18n)
271+
const affiliations = await loader.loadMany(affiliationIds)
272+
expect(affiliations).toEqual(expectedAffiliations)
273+
})
274+
})
275+
describe('database error is raised', () => {
276+
it('throws an error', async () => {
277+
const expectedCursor = await query`
278+
FOR affiliation IN affiliations
279+
FILTER affiliation._id == ${affOne._id}
280+
LET orgKey = PARSE_IDENTIFIER(affiliation._from).key
281+
LET userKey = PARSE_IDENTIFIER(affiliation._to).key
282+
RETURN MERGE(affiliation, { orgKey: orgKey, userKey: userKey })
283+
`
284+
const expectedAffiliation = await expectedCursor.next()
285+
286+
query = jest
287+
.fn()
288+
.mockRejectedValue(new Error('Database error occurred.'))
289+
const loader = affiliationLoaderByKey(query, i18n)
290+
291+
try {
292+
await loader.load(expectedAffiliation._key)
293+
} catch (err) {
294+
expect(err).toEqual(new Error('todo'))
295+
}
296+
297+
expect(consoleOutput).toEqual([
298+
`Database error occurred when running affiliationLoaderByKey: Error: Database error occurred.`,
299+
])
300+
})
301+
})
302+
describe('cursor error is raised', () => {
303+
it('throws an error', async () => {
304+
const expectedCursor = await query`
305+
FOR affiliation IN affiliations
306+
FILTER affiliation._id == ${affOne._id}
307+
LET orgKey = PARSE_IDENTIFIER(affiliation._from).key
308+
LET userKey = PARSE_IDENTIFIER(affiliation._to).key
309+
RETURN MERGE(affiliation, { orgKey: orgKey, userKey: userKey })
310+
`
311+
const expectedAffiliation = await expectedCursor.next()
312+
313+
const cursor = {
314+
each() {
315+
throw new Error('Cursor error occurred.')
316+
},
317+
}
318+
query = jest.fn().mockReturnValue(cursor)
319+
const loader = affiliationLoaderByKey(query, i18n)
320+
321+
try {
322+
await loader.load(expectedAffiliation._key)
323+
} catch (err) {
324+
expect(err).toEqual(new Error('todo'))
325+
}
326+
327+
expect(consoleOutput).toEqual([
328+
`Cursor error occurred during affiliationLoaderByKey: Error: Cursor error occurred.`,
329+
])
330+
})
331+
})
332+
})
333+
})

0 commit comments

Comments
 (0)