test(backend): Testen voor DatabaseLearningObjectProvider.getLearningObjectHTML toegevoegd.
Hierbij optredende problemen ook opgelost.
This commit is contained in:
		
							parent
							
								
									a3b995393b
								
							
						
					
					
						commit
						91e3b5ad91
					
				
					 15 changed files with 103 additions and 60 deletions
				
			
		|  | @ -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); | ||||
|  |  | |||
|  | @ -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); | ||||
|     } | ||||
|  |  | |||
|  | @ -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(), | ||||
|  |  | |||
|  | @ -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); | ||||
|     } | ||||
|  |  | |||
|  | @ -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 => 
 | ||||
|     // 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
 | ||||
|  |  | |||
|  | @ -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); | ||||
|         } | ||||
|  |  | |||
|  | @ -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); | ||||
|     } | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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")); | ||||
|     } | ||||
| } | ||||
|  | @ -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); | ||||
|     } | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
		Reference in a new issue
	
	 Gerald Schmittinger
						Gerald Schmittinger