Created
August 22, 2023 11:21
-
-
Save danilaplee/2a67f80d25683e892fd4dda8508c74c5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Feature: Data Source Join and Mapping | |
Scenario: Joining and mapping data from third-party API and local DB query in execute() | |
GIVEN two different data sources, one from a third-party API (call3partyAPI) and one from a local DB query (dbQuery) | |
AND the call3partyAPI() returns static "curriculum" data | |
AND the dbQuery() returns user learning progress data from our DB | |
WHEN the execute() function is called | |
THEN it should return an array of [{lessonName, readableStatus}] | |
AND the readableStatus for each lesson is defined as follows: | |
1: pending | |
2: submitted | |
3: passed | |
4: failed | |
definition of response: | |
[ | |
{ | |
userId: number | |
userName: string | |
lessons: { | |
lessonName: string | |
readableStatus: string | |
curriculumId: number | |
lessonId: number | |
}[] | |
} | |
] | |
*/ | |
const StatusMap = { | |
1: "pending", | |
2: "submitted", | |
3: "passed", | |
4: "failed" | |
} | |
async function call3partyAPI() { //not enought data cases for unit testing | |
return { | |
status: 200, // could be 400 or 500 sometimes | |
data: [ // data property may or may not exist | |
{ | |
curriculum: { | |
id: 1, | |
title: 'Technology and Sustainability', | |
lessons: [ | |
{ | |
id: 28, | |
name: 'Multiple Choice', | |
}, | |
{ | |
id: 76, | |
name: 'True or False Questions', | |
}, | |
] | |
} | |
}, | |
{ | |
curriculum: { | |
id: 2, | |
title: 'Technology and Sustainability', | |
lessons: [ | |
{ | |
id: 120, | |
name: 'Chaos', | |
}, | |
{ | |
id: 160, | |
name: 'Order', | |
}, | |
] | |
} | |
}, | |
] | |
}; | |
}; | |
// Assume only one user will ever get returned | |
async function dbQuery() { //not enought data cases for unit testing | |
return [ | |
{ | |
user: { id: 1, name: 'Tom' }, | |
progress: { | |
lessons: [ | |
{ | |
lesson_id: 28, | |
status: 2, | |
}, | |
{ | |
lesson_id: 76, | |
status: 1 | |
} | |
] | |
}, | |
}, | |
{ | |
user: { id: 2, name: 'Dan' }, | |
progress: { | |
lessons: [ | |
{ | |
lesson_id: 76, | |
status: 1 | |
}, | |
{ | |
lesson_id: 120, | |
status: 1 | |
} | |
] | |
} | |
} | |
] | |
} | |
async function execute() { | |
const [client_response, students] = await Promise.all([call3partyAPI(), dbQuery()]) | |
const curriculums = client_response.data | |
const curriculumIds = [] | |
const curriculumsMap = curriculums.reduce((a, curriculum)=>{ | |
const curriculumId = curriculum.curriculum.id; | |
curriculumIds.push(curriculumId) | |
const lessons = curriculum.curriculum.lessons | |
a[curriculumId] = { | |
lessons:lessons.reduce((aggr, lesson)=>{ | |
aggr[lesson.id] = lesson.name | |
return aggr | |
}, {}), | |
set: new Set(lessons.map(lesson=>lesson.id)) | |
} | |
return a | |
}, {}) | |
// console.info("curriculumsMap", curriculumsMap) | |
const Response = []; | |
if (client_response) { | |
students.map(student => { | |
const studentResult = { | |
userId: student.user.id, | |
userName: student.user.name, | |
lessons: [] | |
} | |
const studentLessonIds = [] | |
const studentLessonMap = student.progress.lessons.reduce((a,i)=>{ | |
studentLessonIds.push(i.lesson_id) | |
a[i.lesson_id] = i.status | |
return a | |
}, {}) | |
// console.info("studentLessonMap", studentLessonMap) | |
curriculumIds.map((curriculumId) => { | |
const intersection = studentLessonIds.filter((x) => curriculumsMap[parseInt(curriculumId)].set.has(x)); | |
// console.info("intersection", intersection, studentLessonIds, curriculumIds) | |
intersection.map(lessonId => { | |
studentResult.lessons.push({ | |
lessonName: curriculumsMap[curriculumId].lessons[lessonId], | |
readableStatus: StatusMap[studentLessonMap[lessonId]], | |
curriculumId, | |
lessonId | |
}); | |
}) | |
}) | |
Response.push(studentResult) | |
}) | |
} | |
return Response; | |
} | |
execute().then((res) => console.log(JSON.stringify(res, 0, 2))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment