style: fix linting issues met ESLint
This commit is contained in:
parent
a30c4d0d32
commit
aa1a85e64e
24 changed files with 76 additions and 90 deletions
|
@ -23,9 +23,7 @@ export async function getLearningPaths(
|
||||||
? hruids.map(String)
|
? hruids.map(String)
|
||||||
: [String(hruids)];
|
: [String(hruids)];
|
||||||
} else if (themeKey) {
|
} else if (themeKey) {
|
||||||
const theme = themes.find((t) => {
|
const theme = themes.find((t) => t.title === themeKey);
|
||||||
return t.title === themeKey;
|
|
||||||
});
|
|
||||||
if (theme) {
|
if (theme) {
|
||||||
hruidList = theme.hruids;
|
hruidList = theme.hruids;
|
||||||
} else {
|
} else {
|
||||||
|
@ -39,9 +37,7 @@ export async function getLearningPaths(
|
||||||
res.json(searchResults);
|
res.json(searchResults);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
hruidList = themes.flatMap((theme) => {
|
hruidList = themes.flatMap((theme) => theme.hruids);
|
||||||
return theme.hruids;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const learningPaths = await learningPathService.fetchLearningPaths(
|
const learningPaths = await learningPathService.fetchLearningPaths(
|
||||||
|
|
|
@ -12,9 +12,9 @@ const attachmentService = {
|
||||||
language: learningObjectId.language,
|
language: learningObjectId.language,
|
||||||
version: learningObjectId.version,
|
version: learningObjectId.version,
|
||||||
}, attachmentName);
|
}, attachmentName);
|
||||||
} else {
|
}
|
||||||
return attachmentRepo.findByMostRecentVersionOfLearningObjectAndName(learningObjectId.hruid, learningObjectId.language, attachmentName);
|
return attachmentRepo.findByMostRecentVersionOfLearningObjectAndName(learningObjectId.hruid, learningObjectId.language, attachmentName);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,23 +68,15 @@ async function fetchLearningObjects(
|
||||||
const nodes: LearningObjectNode[] = learningPathResponse.data[0].nodes;
|
const nodes: LearningObjectNode[] = learningPathResponse.data[0].nodes;
|
||||||
|
|
||||||
if (!full) {
|
if (!full) {
|
||||||
return nodes.map((node) => {
|
return nodes.map((node) => node.learningobject_hruid);
|
||||||
return node.learningobject_hruid;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return await Promise.all(
|
return await Promise.all(
|
||||||
nodes.map(async (node) => {
|
nodes.map(async (node) => dwengoApiLearningObjectProvider.getLearningObjectById({
|
||||||
return dwengoApiLearningObjectProvider.getLearningObjectById({
|
|
||||||
hruid: node.learningobject_hruid,
|
hruid: node.learningobject_hruid,
|
||||||
language: learningPathId.language
|
language: learningPathId.language
|
||||||
});
|
}))
|
||||||
})
|
).then((objects) => objects.filter((obj): obj is FilteredLearningObject => obj !== null));
|
||||||
).then((objects) => {
|
|
||||||
return objects.filter((obj): obj is FilteredLearningObject => {
|
|
||||||
return obj !== null;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Error fetching learning objects:', error);
|
console.error('❌ Error fetching learning objects:', error);
|
||||||
return [];
|
return [];
|
||||||
|
@ -98,7 +90,7 @@ const dwengoApiLearningObjectProvider: LearningObjectProvider = {
|
||||||
async getLearningObjectById(
|
async getLearningObjectById(
|
||||||
id: LearningObjectIdentifier
|
id: LearningObjectIdentifier
|
||||||
): Promise<FilteredLearningObject | null> {
|
): Promise<FilteredLearningObject | null> {
|
||||||
let metadataUrl = `${DWENGO_API_BASE}/learningObject/getMetadata`;
|
const metadataUrl = `${DWENGO_API_BASE}/learningObject/getMetadata`;
|
||||||
const metadata = await fetchWithLogging<LearningObjectMetadata>(
|
const metadata = await fetchWithLogging<LearningObjectMetadata>(
|
||||||
metadataUrl,
|
metadataUrl,
|
||||||
`Metadata for Learning Object HRUID "${id.hruid}" (language ${id.language})`,
|
`Metadata for Learning Object HRUID "${id.hruid}" (language ${id.language})`,
|
||||||
|
|
|
@ -11,9 +11,9 @@ import databaseLearningObjectProvider from "./database-learning-object-provider"
|
||||||
function getProvider(id: LearningObjectIdentifier): LearningObjectProvider {
|
function getProvider(id: LearningObjectIdentifier): LearningObjectProvider {
|
||||||
if (id.hruid.startsWith(getEnvVar(EnvVars.UserContentPrefix))) {
|
if (id.hruid.startsWith(getEnvVar(EnvVars.UserContentPrefix))) {
|
||||||
return databaseLearningObjectProvider;
|
return databaseLearningObjectProvider;
|
||||||
} else {
|
}
|
||||||
return dwengoApiLearningObjectProvider;
|
return dwengoApiLearningObjectProvider;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,7 +22,7 @@ class ExternProcessor extends StringProcessor {
|
||||||
|
|
||||||
// If a seperate youtube-processor would be added, this code would need to move to that processor
|
// If a seperate youtube-processor would be added, this code would need to move to that processor
|
||||||
// Converts youtube urls to youtube-embed urls
|
// Converts youtube urls to youtube-embed urls
|
||||||
let match = /(.*youtube.com\/)watch\?v=(.*)/.exec(externURL)
|
const match = /(.*youtube.com\/)watch\?v=(.*)/.exec(externURL)
|
||||||
if (match) {
|
if (match) {
|
||||||
externURL = match[1] + "embed/" + match[2];
|
externURL = match[1] + "embed/" + match[2];
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,9 +38,9 @@ class GiftProcessor extends StringProcessor {
|
||||||
|
|
||||||
let html = "<div class='learning-object-gift'>\n";
|
let html = "<div class='learning-object-gift'>\n";
|
||||||
let i = 1;
|
let i = 1;
|
||||||
for (let question of quizQuestions) {
|
for (const question of quizQuestions) {
|
||||||
html += ` <div class='gift-question' id='gift-q${i}'>\n`;
|
html += ` <div class='gift-question' id='gift-q${i}'>\n`;
|
||||||
html += " " + this.renderQuestion(question, i).replaceAll(/\n(.+)/g, "\n $1"); // replace for indentation.
|
html += " " + this.renderQuestion(question, i).replaceAll(/\n(.+)/g, "\n $1"); // Replace for indentation.
|
||||||
html += ` </div>\n`;
|
html += ` </div>\n`;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ export class MultipleChoiceQuestionRenderer extends GIFTQuestionRenderer<Multipl
|
||||||
renderedHtml += `<p class='gift-stem' id='gift-q${questionNumber}-stem'>${question.stem.text}</p>\n`;
|
renderedHtml += `<p class='gift-stem' id='gift-q${questionNumber}-stem'>${question.stem.text}</p>\n`;
|
||||||
}
|
}
|
||||||
let i = 0;
|
let i = 0;
|
||||||
for (let choice of question.choices) {
|
for (const choice of question.choices) {
|
||||||
renderedHtml += `<div class="gift-choice-div">\n`;
|
renderedHtml += `<div class="gift-choice-div">\n`;
|
||||||
renderedHtml += ` <input type='radio' id='gift-q${questionNumber}-choice-${i}' name='gift-q${questionNumber}-choices' value="${i}"/>\n`;
|
renderedHtml += ` <input type='radio' id='gift-q${questionNumber}-choice-${i}' name='gift-q${questionNumber}-choices' value="${i}"/>\n`;
|
||||||
renderedHtml += ` <label for='gift-q${questionNumber}-choice-${i}'>${choice.text}</label>\n`;
|
renderedHtml += ` <label for='gift-q${questionNumber}-choice-${i}'>${choice.text}</label>\n`;
|
||||||
|
|
|
@ -11,7 +11,7 @@ class BlockImageProcessor extends InlineImageProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
override renderFn(imageUrl: string){
|
override renderFn(imageUrl: string){
|
||||||
let inlineHtml = super.render(imageUrl);
|
const inlineHtml = super.render(imageUrl);
|
||||||
return DOMPurify.sanitize(`<div>${inlineHtml}</div>`);
|
return DOMPurify.sanitize(`<div>${inlineHtml}</div>`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,53 +56,53 @@ function extractLearningObjectIdFromHref(href: string): LearningObjectIdentifier
|
||||||
},
|
},
|
||||||
|
|
||||||
// When the syntax for a link is used => [text](href "title")
|
// When the syntax for a link is used => [text](href "title")
|
||||||
// render a custom link when the prefix for a learning object is used.
|
// Render a custom link when the prefix for a learning object is used.
|
||||||
link(link: Link): string {
|
link(link: Link): string {
|
||||||
const href = link.href;
|
const href = link.href;
|
||||||
const title = link.title || "";
|
const title = link.title || "";
|
||||||
const text = marked.parseInline(link.text); // There could for example be an image in the link.
|
const text = marked.parseInline(link.text); // There could for example be an image in the link.
|
||||||
|
|
||||||
if (href.startsWith(prefixes.learningObject)) {
|
if (href.startsWith(prefixes.learningObject)) {
|
||||||
// link to learning-object
|
// Link to learning-object
|
||||||
const learningObjectId = extractLearningObjectIdFromHref(href);
|
const learningObjectId = extractLearningObjectIdFromHref(href);
|
||||||
return `<a href="${getUrlStringForLearningObjectHTML(learningObjectId)}" target="_blank" title="${title}">${text}</a>`;
|
return `<a href="${getUrlStringForLearningObjectHTML(learningObjectId)}" target="_blank" title="${title}">${text}</a>`;
|
||||||
} else {
|
}
|
||||||
// any other link
|
// Any other link
|
||||||
if (!isValidHttpUrl(href)) {
|
if (!isValidHttpUrl(href)) {
|
||||||
throw new ProcessingError("Link is not a valid HTTP URL!");
|
throw new ProcessingError("Link is not a valid HTTP URL!");
|
||||||
}
|
}
|
||||||
//<a href="https://kiks.ilabt.imec.be/hub/tmplogin?id=0101" title="Notebooks Werking"><img src="Knop.png" alt="" title="Knop"></a>
|
//<a href="https://kiks.ilabt.imec.be/hub/tmplogin?id=0101" title="Notebooks Werking"><img src="Knop.png" alt="" title="Knop"></a>
|
||||||
return `<a href="${href}" target="_blank" title="${title}">${text}</a>`;
|
return `<a href="${href}" target="_blank" title="${title}">${text}</a>`;
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// When the syntax for an image is used => 
|
// When the syntax for an image is used => 
|
||||||
// render a learning object, pdf, audio or video if a prefix is used.
|
// Render a learning object, pdf, audio or video if a prefix is used.
|
||||||
image(img: Image): string {
|
image(img: Image): string {
|
||||||
const href = img.href;
|
const href = img.href;
|
||||||
if (href.startsWith(prefixes.learningObject)) {
|
if (href.startsWith(prefixes.learningObject)) {
|
||||||
// embedded learning-object
|
// Embedded learning-object
|
||||||
const learningObjectId = extractLearningObjectIdFromHref(href);
|
const learningObjectId = extractLearningObjectIdFromHref(href);
|
||||||
return `
|
return `
|
||||||
<learning-object hruid="${learningObjectId.hruid}" language="${learningObjectId.language}" version="${learningObjectId.version}"/>
|
<learning-object hruid="${learningObjectId.hruid}" language="${learningObjectId.language}" version="${learningObjectId.version}"/>
|
||||||
`; // Placeholder for the learning object since we cannot fetch its HTML here (this has to be a sync function!)
|
`; // Placeholder for the learning object since we cannot fetch its HTML here (this has to be a sync function!)
|
||||||
} else if (href.startsWith(prefixes.pdf)) {
|
} else if (href.startsWith(prefixes.pdf)) {
|
||||||
// embedded pdf
|
// Embedded pdf
|
||||||
let proc = new PdfProcessor();
|
const proc = new PdfProcessor();
|
||||||
return proc.render(href.split(/\/(.+)/, 2)[1]);
|
return proc.render(href.split(/\/(.+)/, 2)[1]);
|
||||||
} else if (href.startsWith(prefixes.audio)) {
|
} else if (href.startsWith(prefixes.audio)) {
|
||||||
// embedded audio
|
// Embedded audio
|
||||||
let proc = new AudioProcessor();
|
const proc = new AudioProcessor();
|
||||||
return proc.render(href.split(/\/(.+)/, 2)[1]);
|
return proc.render(href.split(/\/(.+)/, 2)[1]);
|
||||||
} else if (href.startsWith(prefixes.extern) || href.startsWith(prefixes.video) || href.startsWith(prefixes.notebook)) {
|
} else if (href.startsWith(prefixes.extern) || href.startsWith(prefixes.video) || href.startsWith(prefixes.notebook)) {
|
||||||
// embedded youtube video or notebook (or other extern content)
|
// Embedded youtube video or notebook (or other extern content)
|
||||||
let proc = new ExternProcessor();
|
const proc = new ExternProcessor();
|
||||||
return proc.render(href.split(/\/(.+)/, 2)[1]);
|
return proc.render(href.split(/\/(.+)/, 2)[1]);
|
||||||
} else {
|
}
|
||||||
// embedded image
|
// Embedded image
|
||||||
let proc = new InlineImageProcessor();
|
const proc = new InlineImageProcessor();
|
||||||
return proc.render(href)
|
return proc.render(href)
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ class MarkdownProcessor extends StringProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
replaceLinks(html: string) {
|
replaceLinks(html: string) {
|
||||||
let proc = new InlineImageProcessor();
|
const proc = new InlineImageProcessor();
|
||||||
html = html.replace(/<img.*?src="(.*?)".*?(alt="(.*?)")?.*?(title="(.*?)")?.*?>/g, (
|
html = html.replace(/<img.*?src="(.*?)".*?(alt="(.*?)")?.*?(title="(.*?)")?.*?>/g, (
|
||||||
match: string,
|
match: string,
|
||||||
src: string,
|
src: string,
|
||||||
|
@ -35,9 +35,7 @@ class MarkdownProcessor extends StringProcessor {
|
||||||
altText: string,
|
altText: string,
|
||||||
title: string,
|
title: string,
|
||||||
titleText: string
|
titleText: string
|
||||||
) => {
|
) => proc.render(src));
|
||||||
return proc.render(src);
|
|
||||||
});
|
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ class ProcessingService {
|
||||||
learningObject: LearningObject,
|
learningObject: LearningObject,
|
||||||
fetchEmbeddedLearningObjects?: (loId: LearningObjectIdentifier) => Promise<LearningObject | null>
|
fetchEmbeddedLearningObjects?: (loId: LearningObjectIdentifier) => Promise<LearningObject | null>
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
let html = this.processors.get(learningObject.contentType)!.renderLearningObject(learningObject);
|
const html = this.processors.get(learningObject.contentType)!.renderLearningObject(learningObject);
|
||||||
if (fetchEmbeddedLearningObjects) {
|
if (fetchEmbeddedLearningObjects) {
|
||||||
// Replace all embedded learning objects.
|
// Replace all embedded learning objects.
|
||||||
return replaceAsync(
|
return replaceAsync(
|
||||||
|
|
|
@ -22,7 +22,7 @@ import {LearningPathTransition} from "../../entities/content/learning-path-trans
|
||||||
*/
|
*/
|
||||||
async function getLearningObjectsForNodes(nodes: LearningPathNode[]): Promise<Map<LearningPathNode, FilteredLearningObject>> {
|
async function getLearningObjectsForNodes(nodes: LearningPathNode[]): Promise<Map<LearningPathNode, FilteredLearningObject>> {
|
||||||
// Fetching the corresponding learning object for each of the nodes and creating a map that maps each node to
|
// Fetching the corresponding learning object for each of the nodes and creating a map that maps each node to
|
||||||
// its corresponding learning object.
|
// Its corresponding learning object.
|
||||||
const nullableNodesToLearningObjects = new Map<LearningPathNode, FilteredLearningObject | null>(
|
const nullableNodesToLearningObjects = new Map<LearningPathNode, FilteredLearningObject | null>(
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
nodes.map(node =>
|
nodes.map(node =>
|
||||||
|
@ -58,7 +58,7 @@ async function convertLearningPath(learningPath: LearningPathEntity, order: numb
|
||||||
const image = learningPath.image ? learningPath.image.toString("base64") : undefined;
|
const image = learningPath.image ? learningPath.image.toString("base64") : undefined;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_id: `${learningPath.hruid}/${learningPath.language}`, // for backwards compatibility with the original Dwengo API.
|
_id: `${learningPath.hruid}/${learningPath.language}`, // For backwards compatibility with the original Dwengo API.
|
||||||
__order: order,
|
__order: order,
|
||||||
hruid: learningPath.hruid,
|
hruid: learningPath.hruid,
|
||||||
language: learningPath.language,
|
language: learningPath.language,
|
||||||
|
|
|
@ -43,7 +43,7 @@ function transitionPossible(transition: LearningPathTransition, submitted: objec
|
||||||
*/
|
*/
|
||||||
const learningPathPersonalizingService = {
|
const learningPathPersonalizingService = {
|
||||||
async calculatePersonalizedTrajectory(nodes: LearningPathNode[], pathFor: {student?: Student, group?: Group}): Promise<LearningPathNode[]> {
|
async calculatePersonalizedTrajectory(nodes: LearningPathNode[], pathFor: {student?: Student, group?: Group}): Promise<LearningPathNode[]> {
|
||||||
let trajectory: LearningPathNode[] = [];
|
const trajectory: LearningPathNode[] = [];
|
||||||
|
|
||||||
// Always start with the start node.
|
// Always start with the start node.
|
||||||
let currentNode = nodes.filter(it => it.startNode)[0];
|
let currentNode = nodes.filter(it => it.startNode)[0];
|
||||||
|
@ -51,17 +51,17 @@ const learningPathPersonalizingService = {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// At every node, calculate all the possible next transitions.
|
// At every node, calculate all the possible next transitions.
|
||||||
let lastSubmission = await getLastRelevantSubmission(currentNode, pathFor);
|
const lastSubmission = await getLastRelevantSubmission(currentNode, pathFor);
|
||||||
let submitted = lastSubmission === null ? null : JSON.parse(lastSubmission.content);
|
const submitted = lastSubmission === null ? null : JSON.parse(lastSubmission.content);
|
||||||
let possibleTransitions = currentNode.transitions
|
const possibleTransitions = currentNode.transitions
|
||||||
.filter(it => transitionPossible(it, submitted));
|
.filter(it => transitionPossible(it, submitted));
|
||||||
|
|
||||||
if (possibleTransitions.length === 0) { // If there are none, the trajectory has ended.
|
if (possibleTransitions.length === 0) { // If there are none, the trajectory has ended.
|
||||||
return trajectory;
|
return trajectory;
|
||||||
} else { // Otherwise, take the first possible transition.
|
} // Otherwise, take the first possible transition.
|
||||||
currentNode = possibleTransitions[0].node;
|
currentNode = possibleTransitions[0].node;
|
||||||
trajectory.push(currentNode);
|
trajectory.push(currentNode);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,5 +19,5 @@ export async function replaceAsync(str: string, regex: RegExp, replacementFn: (m
|
||||||
const replacements: string[] = (await Promise.all(promises));
|
const replacements: string[] = (await Promise.all(promises));
|
||||||
|
|
||||||
// Second run through matches: Replace them by their previously computed replacements.
|
// Second run through matches: Replace them by their previously computed replacements.
|
||||||
return str.replace(regex, () => replacements.pop()!!);
|
return str.replace(regex, () => replacements.pop()!);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,10 @@ import {LearningObjectIdentifier} from "../../../src/entities/content/learning-o
|
||||||
const NEWER_TEST_SUFFIX = "nEweR";
|
const NEWER_TEST_SUFFIX = "nEweR";
|
||||||
|
|
||||||
function createTestLearningObjects(learningObjectRepo: LearningObjectRepository): {older: LearningObject, newer: LearningObject} {
|
function createTestLearningObjects(learningObjectRepo: LearningObjectRepository): {older: LearningObject, newer: LearningObject} {
|
||||||
let olderExample = example.createLearningObject();
|
const olderExample = example.createLearningObject();
|
||||||
learningObjectRepo.save(olderExample);
|
learningObjectRepo.save(olderExample);
|
||||||
|
|
||||||
let newerExample = example.createLearningObject();
|
const newerExample = example.createLearningObject();
|
||||||
newerExample.title = "Newer example";
|
newerExample.title = "Newer example";
|
||||||
newerExample.version = 100;
|
newerExample.version = 100;
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ describe("AttachmentRepository", () => {
|
||||||
.values(example.createAttachment)
|
.values(example.createAttachment)
|
||||||
.map(fn => fn(exampleLearningObjects.older));
|
.map(fn => fn(exampleLearningObjects.older));
|
||||||
|
|
||||||
for (let attachment of attachmentsOlderLearningObject) {
|
for (const attachment of attachmentsOlderLearningObject) {
|
||||||
attachmentRepo.save(attachment);
|
attachmentRepo.save(attachment);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,8 +12,8 @@ import {FilteredLearningObject} from "../../../src/interfaces/learning-content";
|
||||||
import {Language} from "../../../src/entities/content/language";
|
import {Language} from "../../../src/entities/content/language";
|
||||||
|
|
||||||
async function initExampleData(): Promise<LearningObject> {
|
async function initExampleData(): Promise<LearningObject> {
|
||||||
let learningObjectRepo = getLearningObjectRepository();
|
const learningObjectRepo = getLearningObjectRepository();
|
||||||
let exampleLearningObject = createExampleLearningObjectWithAttachments(example);
|
const exampleLearningObject = createExampleLearningObjectWithAttachments(example);
|
||||||
await learningObjectRepo.insert(exampleLearningObject);
|
await learningObjectRepo.insert(exampleLearningObject);
|
||||||
return exampleLearningObject;
|
return exampleLearningObject;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ const DWENGO_TEST_LEARNING_OBJECT_ID: LearningObjectIdentifier = {
|
||||||
|
|
||||||
async function initExampleData(): Promise<LearningObject> {
|
async function initExampleData(): Promise<LearningObject> {
|
||||||
const learningObjectRepo = getLearningObjectRepository();
|
const learningObjectRepo = getLearningObjectRepository();
|
||||||
let learningObject = learningObjectExample.createLearningObject();
|
const learningObject = learningObjectExample.createLearningObject();
|
||||||
learningObject.title = TEST_LEARNING_OBJECT_TITLE
|
learningObject.title = TEST_LEARNING_OBJECT_TITLE
|
||||||
await learningObjectRepo.save(learningObject);
|
await learningObjectRepo.save(learningObject);
|
||||||
return learningObject;
|
return learningObject;
|
||||||
|
|
|
@ -14,8 +14,8 @@ import {Language} from "../../../src/entities/content/language";
|
||||||
async function initExampleData(): Promise<{ learningObject: LearningObject, learningPath: LearningPath }> {
|
async function initExampleData(): Promise<{ learningObject: LearningObject, learningPath: LearningPath }> {
|
||||||
const learningObjectRepo = getLearningObjectRepository();
|
const learningObjectRepo = getLearningObjectRepository();
|
||||||
const learningPathRepo = getLearningPathRepository();
|
const learningPathRepo = getLearningPathRepository();
|
||||||
let learningObject = learningObjectExample.createLearningObject();
|
const learningObject = learningObjectExample.createLearningObject();
|
||||||
let learningPath = learningPathExample.createLearningPath();
|
const learningPath = learningPathExample.createLearningPath();
|
||||||
await learningObjectRepo.save(learningObject);
|
await learningObjectRepo.save(learningObject);
|
||||||
await learningPathRepo.save(learningPath);
|
await learningPathRepo.save(learningPath);
|
||||||
return { learningObject, learningPath };
|
return { learningObject, learningPath };
|
||||||
|
@ -55,7 +55,7 @@ describe("DatabaseLearningPathProvider", () => {
|
||||||
it("returns a non-successful response if a non-existing learning path is queried", async () => {
|
it("returns a non-successful response if a non-existing learning path is queried", async () => {
|
||||||
const result = await databaseLearningPathProvider.fetchLearningPaths(
|
const result = await databaseLearningPathProvider.fetchLearningPaths(
|
||||||
[example.learningPath.hruid],
|
[example.learningPath.hruid],
|
||||||
Language.Abkhazian, // wrong language
|
Language.Abkhazian, // Wrong language
|
||||||
"the source"
|
"the source"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ import learningPathService from "../../../src/services/learning-paths/learning-p
|
||||||
async function initExampleData(): Promise<{ learningObject: LearningObject, learningPath: LearningPath }> {
|
async function initExampleData(): Promise<{ learningObject: LearningObject, learningPath: LearningPath }> {
|
||||||
const learningObjectRepo = getLearningObjectRepository();
|
const learningObjectRepo = getLearningObjectRepository();
|
||||||
const learningPathRepo = getLearningPathRepository();
|
const learningPathRepo = getLearningPathRepository();
|
||||||
let learningObject = learningObjectExample.createLearningObject();
|
const learningObject = learningObjectExample.createLearningObject();
|
||||||
let learningPath = learningPathExample.createLearningPath();
|
const learningPath = learningPathExample.createLearningPath();
|
||||||
await learningObjectRepo.save(learningObject);
|
await learningObjectRepo.save(learningObject);
|
||||||
await learningPathRepo.save(learningPath);
|
await learningPathRepo.save(learningPath);
|
||||||
return { learningObject, learningPath };
|
return { learningObject, learningPath };
|
||||||
|
@ -76,7 +76,7 @@ describe("LearningPathService", () => {
|
||||||
).length
|
).length
|
||||||
).toBe(1);
|
).toBe(1);
|
||||||
|
|
||||||
// but should not only find that one.
|
// But should not only find that one.
|
||||||
expect(result.length).not.toBeLessThan(2);
|
expect(result.length).not.toBeLessThan(2);
|
||||||
});
|
});
|
||||||
it("should still return results from the Dwengo API even though there are no matches in the database", async () => {
|
it("should still return results from the Dwengo API even though there are no matches in the database", async () => {
|
||||||
|
@ -88,7 +88,7 @@ describe("LearningPathService", () => {
|
||||||
// Should find something...
|
// Should find something...
|
||||||
expect(result.length).not.toBe(0);
|
expect(result.length).not.toBe(0);
|
||||||
|
|
||||||
// but not the example learning path.
|
// But not the example learning path.
|
||||||
expect(
|
expect(
|
||||||
result.filter(it =>
|
result.filter(it =>
|
||||||
it.hruid === example.learningPath.hruid && it.title === example.learningPath.title
|
it.hruid === example.learningPath.hruid && it.title === example.learningPath.title
|
||||||
|
|
|
@ -2,8 +2,8 @@ import {LearningObjectExample} from "./learning-object-example";
|
||||||
import {LearningObject} from "../../../src/entities/content/learning-object.entity";
|
import {LearningObject} from "../../../src/entities/content/learning-object.entity";
|
||||||
|
|
||||||
export function createExampleLearningObjectWithAttachments(example: LearningObjectExample): LearningObject {
|
export function createExampleLearningObjectWithAttachments(example: LearningObjectExample): LearningObject {
|
||||||
let learningObject = example.createLearningObject();
|
const learningObject = example.createLearningObject();
|
||||||
for (let creationFn of Object.values(example.createAttachment)) {
|
for (const creationFn of Object.values(example.createAttachment)) {
|
||||||
learningObject.attachments.push(creationFn(learningObject));
|
learningObject.attachments.push(creationFn(learningObject));
|
||||||
}
|
}
|
||||||
return learningObject;
|
return learningObject;
|
||||||
|
|
|
@ -10,7 +10,7 @@ const ASSETS_PREFIX = "learning-objects/pn-werkingnotebooks/";
|
||||||
|
|
||||||
const example: LearningObjectExample = {
|
const example: LearningObjectExample = {
|
||||||
createLearningObject: ()=> {
|
createLearningObject: ()=> {
|
||||||
let learningObject = new LearningObject();
|
const learningObject = new LearningObject();
|
||||||
learningObject.hruid = `${getEnvVar(EnvVars.UserContentPrefix)}pn_werkingnotebooks`;
|
learningObject.hruid = `${getEnvVar(EnvVars.UserContentPrefix)}pn_werkingnotebooks`;
|
||||||
learningObject.version = 3;
|
learningObject.version = 3;
|
||||||
learningObject.language = Language.Dutch;
|
learningObject.language = Language.Dutch;
|
||||||
|
@ -18,11 +18,11 @@ const example: LearningObjectExample = {
|
||||||
learningObject.description = "Leren werken met notebooks";
|
learningObject.description = "Leren werken met notebooks";
|
||||||
learningObject.keywords = ["Python", "KIKS", "Wiskunde", "STEM", "AI"]
|
learningObject.keywords = ["Python", "KIKS", "Wiskunde", "STEM", "AI"]
|
||||||
|
|
||||||
let educationalGoal1 = new EducationalGoal();
|
const educationalGoal1 = new EducationalGoal();
|
||||||
educationalGoal1.source = "Source";
|
educationalGoal1.source = "Source";
|
||||||
educationalGoal1.id = "id";
|
educationalGoal1.id = "id";
|
||||||
|
|
||||||
let educationalGoal2 = new EducationalGoal();
|
const educationalGoal2 = new EducationalGoal();
|
||||||
educationalGoal2.source = "Source2";
|
educationalGoal2.source = "Source2";
|
||||||
educationalGoal2.id = "id2";
|
educationalGoal2.id = "id2";
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ const example: LearningObjectExample = {
|
||||||
learningObject.license = "dwengo";
|
learningObject.license = "dwengo";
|
||||||
learningObject.estimatedTime = 10;
|
learningObject.estimatedTime = 10;
|
||||||
|
|
||||||
let returnValue = new ReturnValue();
|
const returnValue = new ReturnValue();
|
||||||
returnValue.callbackUrl = "callback_url_example";
|
returnValue.callbackUrl = "callback_url_example";
|
||||||
returnValue.callbackSchema = '{"att": "test", "att2": "test2"}';
|
returnValue.callbackSchema = '{"att": "test", "att2": "test2"}';
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ const example: LearningObjectExample = {
|
||||||
},
|
},
|
||||||
createAttachment: {
|
createAttachment: {
|
||||||
dwengoLogo: (learningObject) => {
|
dwengoLogo: (learningObject) => {
|
||||||
let att = new Attachment();
|
const att = new Attachment();
|
||||||
att.learningObject = learningObject;
|
att.learningObject = learningObject;
|
||||||
att.name = "dwengo.png";
|
att.name = "dwengo.png";
|
||||||
att.mimeType = "image/png";
|
att.mimeType = "image/png";
|
||||||
|
@ -59,7 +59,7 @@ const example: LearningObjectExample = {
|
||||||
return att;
|
return att;
|
||||||
},
|
},
|
||||||
knop: (learningObject) => {
|
knop: (learningObject) => {
|
||||||
let att = new Attachment();
|
const att = new Attachment();
|
||||||
att.learningObject = learningObject;
|
att.learningObject = learningObject;
|
||||||
att.name = "Knop.png";
|
att.name = "Knop.png";
|
||||||
att.mimeType = "image/png";
|
att.mimeType = "image/png";
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {LearningPathNode} from "../../../src/entities/content/learning-path-node
|
||||||
import {LearningPath} from "../../../src/entities/content/learning-path.entity";
|
import {LearningPath} from "../../../src/entities/content/learning-path.entity";
|
||||||
|
|
||||||
export function createLearningPathTransition(node: LearningPathNode, transitionNumber: number, condition: string | null, to: LearningPathNode) {
|
export function createLearningPathTransition(node: LearningPathNode, transitionNumber: number, condition: string | null, to: LearningPathNode) {
|
||||||
let trans = new LearningPathTransition();
|
const trans = new LearningPathTransition();
|
||||||
trans.node = node;
|
trans.node = node;
|
||||||
trans.transitionNumber = transitionNumber;
|
trans.transitionNumber = transitionNumber;
|
||||||
trans.condition = condition || "true";
|
trans.condition = condition || "true";
|
||||||
|
@ -20,7 +20,7 @@ export function createLearningPathNode(
|
||||||
language: Language,
|
language: Language,
|
||||||
startNode: boolean
|
startNode: boolean
|
||||||
) {
|
) {
|
||||||
let node = new LearningPathNode();
|
const node = new LearningPathNode();
|
||||||
node.learningPath = learningPath;
|
node.learningPath = learningPath;
|
||||||
node.nodeNumber = nodeNumber;
|
node.nodeNumber = nodeNumber;
|
||||||
node.learningObjectHruid = learningObjectHruid;
|
node.learningObjectHruid = learningObjectHruid;
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {createLearningPathNode, createLearningPathTransition} from "./learning-p
|
||||||
import {LearningPathNode} from "../../../src/entities/content/learning-path-node.entity";
|
import {LearningPathNode} from "../../../src/entities/content/learning-path-node.entity";
|
||||||
|
|
||||||
function createNodes(learningPath: LearningPath): LearningPathNode[] {
|
function createNodes(learningPath: LearningPath): LearningPathNode[] {
|
||||||
let nodes = [
|
const nodes = [
|
||||||
createLearningPathNode(learningPath, 0, "u_pn_werkingnotebooks", 3, Language.Dutch, true),
|
createLearningPathNode(learningPath, 0, "u_pn_werkingnotebooks", 3, Language.Dutch, true),
|
||||||
createLearningPathNode(learningPath, 1, "pn_werkingnotebooks2", 3, Language.Dutch, false),
|
createLearningPathNode(learningPath, 1, "pn_werkingnotebooks2", 3, Language.Dutch, false),
|
||||||
createLearningPathNode(learningPath, 2, "pn_werkingnotebooks3", 3, Language.Dutch, false),
|
createLearningPathNode(learningPath, 2, "pn_werkingnotebooks3", 3, Language.Dutch, false),
|
||||||
|
|
|
@ -22,7 +22,7 @@ export function expectToBeCorrectEntity<T extends object>(
|
||||||
if (!expected.name) {
|
if (!expected.name) {
|
||||||
expected.name = "expected";
|
expected.name = "expected";
|
||||||
}
|
}
|
||||||
for (let property in expected.entity) {
|
for (const property in expected.entity) {
|
||||||
if (
|
if (
|
||||||
property !in IGNORE_PROPERTIES
|
property !in IGNORE_PROPERTIES
|
||||||
&& expected.entity[property] !== undefined // If we don't expect a certain value for a property, we assume it can be filled in by the database however it wants.
|
&& expected.entity[property] !== undefined // If we don't expect a certain value for a property, we assume it can be filled in by the database however it wants.
|
||||||
|
@ -34,10 +34,10 @@ export function expectToBeCorrectEntity<T extends object>(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (typeof expected.entity[property] === "boolean") { // Sometimes, booleans get represented by numbers 0 and 1 in the objects actual from the database.
|
if (typeof expected.entity[property] === "boolean") { // Sometimes, booleans get represented by numbers 0 and 1 in the objects actual from the database.
|
||||||
if (!!expected.entity[property] !== !!actual.entity[property]) {
|
if (Boolean(expected.entity[property]) !== Boolean(actual.entity[property])) {
|
||||||
throw new AssertionError({
|
throw new AssertionError({
|
||||||
message: `${property} was ${expected.entity[property]} in ${expected.name},
|
message: `${property} was ${expected.entity[property]} in ${expected.name},
|
||||||
but ${actual.entity[property]} (${!!expected.entity[property]}) in ${actual.name}`
|
but ${actual.entity[property]} (${Boolean(expected.entity[property])}) in ${actual.name}`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (typeof expected.entity[property] !== typeof actual.entity[property]) {
|
} else if (typeof expected.entity[property] !== typeof actual.entity[property]) {
|
||||||
|
@ -78,7 +78,7 @@ export function expectToBeCorrectFilteredLearningObject(filtered: FilteredLearni
|
||||||
expect(filtered.key).toEqual(original.hruid);
|
expect(filtered.key).toEqual(original.hruid);
|
||||||
expect(filtered.targetAges).toEqual(original.targetAges);
|
expect(filtered.targetAges).toEqual(original.targetAges);
|
||||||
expect(filtered.title).toEqual(original.title);
|
expect(filtered.title).toEqual(original.title);
|
||||||
expect(!!filtered.teacherExclusive).toEqual(original.teacherExclusive) // !!: Workaround: MikroORM with SQLite returns 0 and 1 instead of booleans.
|
expect(Boolean(filtered.teacherExclusive)).toEqual(original.teacherExclusive) // !!: Workaround: MikroORM with SQLite returns 0 and 1 instead of booleans.
|
||||||
expect(filtered.skosConcepts).toEqual(original.skosConcepts);
|
expect(filtered.skosConcepts).toEqual(original.skosConcepts);
|
||||||
expect(filtered.estimatedTime).toEqual(original.estimatedTime);
|
expect(filtered.estimatedTime).toEqual(original.estimatedTime);
|
||||||
expect(filtered.educationalGoals).toEqual(original.educationalGoals);
|
expect(filtered.educationalGoals).toEqual(original.educationalGoals);
|
||||||
|
@ -123,21 +123,21 @@ export function expectToBeCorrectLearningPath(
|
||||||
expect(learningPath.num_nodes).toEqual(expectedEntity.nodes.length);
|
expect(learningPath.num_nodes).toEqual(expectedEntity.nodes.length);
|
||||||
expect(learningPath.image || null).toEqual(expectedEntity.image);
|
expect(learningPath.image || null).toEqual(expectedEntity.image);
|
||||||
|
|
||||||
let expectedLearningPathNodes = new Map(
|
const expectedLearningPathNodes = new Map(
|
||||||
expectedEntity.nodes.map(node => [
|
expectedEntity.nodes.map(node => [
|
||||||
{learningObjectHruid: node.learningObjectHruid, language: node.language, version: node.version},
|
{learningObjectHruid: node.learningObjectHruid, language: node.language, version: node.version},
|
||||||
{startNode: node.startNode, transitions: node.transitions}
|
{startNode: node.startNode, transitions: node.transitions}
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
for (let node of learningPath.nodes) {
|
for (const node of learningPath.nodes) {
|
||||||
const nodeKey = {
|
const nodeKey = {
|
||||||
learningObjectHruid: node.learningobject_hruid,
|
learningObjectHruid: node.learningobject_hruid,
|
||||||
language: node.language,
|
language: node.language,
|
||||||
version: node.version
|
version: node.version
|
||||||
};
|
};
|
||||||
expect(expectedLearningPathNodes.keys()).toContainEqual(nodeKey);
|
expect(expectedLearningPathNodes.keys()).toContainEqual(nodeKey);
|
||||||
let expectedNode = [...expectedLearningPathNodes.entries()]
|
const expectedNode = [...expectedLearningPathNodes.entries()]
|
||||||
.filter(([key, _]) =>
|
.filter(([key, _]) =>
|
||||||
key.learningObjectHruid === nodeKey.learningObjectHruid
|
key.learningObjectHruid === nodeKey.learningObjectHruid
|
||||||
&& key.language === node.language
|
&& key.language === node.language
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue