Created
August 22, 2023 11:21
-
-
Save danilaplee/2a67f80d25683e892fd4dda8508c74c5 to your computer and use it in GitHub Desktop.
Revisions
-
danilaplee created this gist
Aug 22, 2023 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,172 @@ /* 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)))