test(backend): Testen voor DatabaseLearningObjectProvider.getLearningObjectHTML toegevoegd.

Hierbij optredende problemen ook opgelost.
This commit is contained in:
Gerald Schmittinger 2025-03-09 19:29:20 +01:00
parent a3b995393b
commit 91e3b5ad91
15 changed files with 103 additions and 60 deletions

View file

@ -1,12 +1,13 @@
/**
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/audio/audio_processor.js
*/
import Processor from "../processor.js";
import DOMPurify from 'isomorphic-dompurify';
import {type} from "node:os";
import {DwengoContentType} from "../content-type";
import {StringProcessor} from "../string-processor";
class AudioProcessor extends Processor<string> {
class AudioProcessor extends StringProcessor {
constructor() {
super(DwengoContentType.AUDIO_MPEG);

View file

@ -2,13 +2,13 @@
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/extern/extern_processor.js
*/
import Processor from "../processor.js";
import DOMPurify from 'isomorphic-dompurify';
import {ProcessingError} from "../processing-error";
import {isValidHttpUrl} from "../../../../util/links";
import {DwengoContentType} from "../content-type";
import {StringProcessor} from "../string-processor";
class ExternProcessor extends Processor<string> {
class ExternProcessor extends StringProcessor {
constructor() {
super(DwengoContentType.EXTERN);
}

View file

@ -2,7 +2,6 @@
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/gift/gift_processor.js
*/
import Processor from "../processor.js";
import DOMPurify from 'isomorphic-dompurify';
import {GIFTQuestion, parse} from "gift-pegjs"
import {DwengoContentType} from "../content-type";
@ -15,8 +14,9 @@ import {MatchingQuestionRenderer} from "./question-renderers/matching-question-r
import {NumericalQuestionRenderer} from "./question-renderers/numerical-question-renderer";
import {ShortQuestionRenderer} from "./question-renderers/short-question-renderer";
import {TrueFalseQuestionRenderer} from "./question-renderers/true-false-question-renderer";
import {StringProcessor} from "../string-processor";
class GiftProcessor extends Processor<string> {
class GiftProcessor extends StringProcessor {
private renderers: RendererMap = {
Category: new CategoryQuestionRenderer(),

View file

@ -2,13 +2,13 @@
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/image/inline_image_processor.js
*/
import Processor from "../processor.js";
import DOMPurify from 'isomorphic-dompurify';
import {DwengoContentType} from "../content-type.js";
import {ProcessingError} from "../processing-error.js";
import {isValidHttpUrl} from "../../../../util/links";
import {StringProcessor} from "../string-processor";
class InlineImageProcessor extends Processor<string> {
class InlineImageProcessor extends StringProcessor {
constructor(contentType: DwengoContentType = DwengoContentType.IMAGE_INLINE) {
super(contentType);
}

View file

@ -42,45 +42,43 @@ function extractLearningObjectIdFromHref(href: string): LearningObjectIdentifier
* - embeddings of other learning objects.
*/
const dwengoMarkedRenderer: RendererObject = {
heading(heading: Heading) {
heading(heading: Heading): string {
const text = heading.text;
const level = heading.depth;
const escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');
return `
<h${level}>
<a name="${escapedText}" class="anchor" href="#${escapedText}">
<span class="header-link"></span>
</a>
${text}
</h${level}>`;
return `<h${level}>\n` +
` <a name="${escapedText}" class="anchor" href="#${escapedText}">\n` +
` <span class="header-link"></span>\n` +
` </a>\n` +
` ${text}\n` +
`</h${level}>\n`
},
// When the syntax for a link is used => [text](href "title")
// render a custom link when the prefix for a learning object is used.
link(link: Link) {
link(link: Link): string {
const href = link.href;
const title = link.title || "";
const text = link.text;
const text = marked.parseInline(link.text); // There could for example be an image in the link.
if (href.startsWith(prefixes.learningObject)) {
// link to learning-object
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
if (!isValidHttpUrl(href)) {
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>
return `<a href="${href}" target="_blank" title="${title}">${text}</a>`;
}
},
// When the syntax for an image is used => ![text](href "title")
// render a learning object, pdf, audio or video if a prefix is used.
image(img: Image) {
image(img: Image): string {
const href = img.href;
if (href.startsWith(prefixes.learningObject)) {
// embedded learning-object

View file

@ -2,14 +2,14 @@
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/markdown/markdown_processor.js
*/
import {marked} from 'marked'
import Processor from '../processor.js';
import {marked} from 'marked';
import InlineImageProcessor from '../image/inline-image-processor.js';
import {DwengoContentType} from "../content-type";
import {ProcessingError} from "../processing-error";
import dwengoMarkedRenderer from "./dwengo-marked-renderer";
import {StringProcessor} from "../string-processor";
import {ProcessingError} from "../processing-error";
class MarkdownProcessor extends Processor<string> {
class MarkdownProcessor extends StringProcessor {
constructor() {
super(DwengoContentType.TEXT_MARKDOWN);
}
@ -17,9 +17,9 @@ class MarkdownProcessor extends Processor<string> {
override renderFn(mdText: string) {
let html = "";
try {
mdText = this.replaceLinks(mdText); // Replace html image links with path based on metadata
marked.use({renderer: dwengoMarkedRenderer});
html = marked(mdText, {async: false});
html = this.replaceLinks(html); // Replace html image links path
} catch (e: any) {
throw new ProcessingError(e.message);
}

View file

@ -2,13 +2,13 @@
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/pdf/pdf_processor.js
*/
import Processor from "../processor.js";
import DOMPurify from 'isomorphic-dompurify';
import {DwengoContentType} from "../content-type.js";
import {isValidHttpUrl} from "../../../../util/links.js";
import {ProcessingError} from "../processing-error.js";
import {StringProcessor} from "../string-processor";
class PdfProcessor extends Processor<string> {
class PdfProcessor extends StringProcessor {
constructor() {
super(DwengoContentType.APPLICATION_PDF);
}

View file

@ -48,7 +48,6 @@ abstract class Processor<T> {
/**
* Function which actually executes the rendering of a learning object.
* By default, this just means rendering the content in the content property of the learning object.
*
* When implementing this function, we may assume that we are responsible for the content type of the learning
* object.
@ -56,9 +55,7 @@ abstract class Processor<T> {
* @param toRender Learning object to render
* @protected
*/
protected renderLearningObjectFn(toRender: LearningObject): string {
return this.render(toRender.content as T);
}
protected abstract renderLearningObjectFn(toRender: LearningObject): string;
}
export default Processor;

View file

@ -0,0 +1,19 @@
import Processor from "./processor";
import {LearningObject} from "../../../entities/content/learning-object.entity";
export abstract class StringProcessor extends Processor<string> {
/**
* Function which actually executes the rendering of a learning object.
* By default, this just means rendering the content in the content property of the learning object (interpreted
* as string)
*
* When implementing this function, we may assume that we are responsible for the content type of the learning
* object.
*
* @param toRender Learning object to render
* @protected
*/
protected renderLearningObjectFn(toRender: LearningObject): string {
return this.render(toRender.content.toString("ascii"));
}
}

View file

@ -2,11 +2,11 @@
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/text/text_processor.js
*/
import DOMPurify from 'isomorphic-dompurify'
import Processor from "../processor.js"
import DOMPurify from 'isomorphic-dompurify';
import {DwengoContentType} from "../content-type.js";
import {StringProcessor} from "../string-processor";
class TextProcessor extends Processor<string> {
class TextProcessor extends StringProcessor {
constructor() {
super(DwengoContentType.TEXT_PLAIN);
}

View file

@ -2,7 +2,7 @@ import {LearningObjectIdentifier} from "../interfaces/learning-content";
export function isValidHttpUrl(url: string): boolean {
try {
const parsedUrl = new URL(url);
const parsedUrl = new URL(url, "http://test.be");
return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:";
} catch (e) {
return false;