Merge remote-tracking branch 'origin/feature/own-learning-objects' into feature/own-learning-objects

# Conflicts:
#	backend/src/services/learning-objects/database-learning-object-provider.ts
#	backend/tests/services/learning-objects/database-learning-object-provider.test.ts
#	backend/tests/test-utils/expectations.ts
This commit is contained in:
Gerald Schmittinger 2025-03-11 04:45:09 +01:00
commit 9f28e4ed17
84 changed files with 874 additions and 1048 deletions

View file

@ -23,7 +23,7 @@ async function initExampleData(): Promise<{learningObject: LearningObject, learn
const EXPECTED_TITLE_FROM_DWENGO_LEARNING_OBJECT = "Notebook opslaan";
describe("DatabaseLearningObjectProvider", () => {
describe('DatabaseLearningObjectProvider', () => {
let exampleLearningObject: LearningObject;
let exampleLearningPath: LearningPath;
@ -33,32 +33,32 @@ describe("DatabaseLearningObjectProvider", () => {
exampleLearningObject = exampleData.learningObject;
exampleLearningPath = exampleData.learningPath;
});
describe("getLearningObjectById", () => {
it("should return the learning object when it is queried by its id", async () => {
describe('getLearningObjectById', () => {
it('should return the learning object when it is queried by its id', async () => {
const result: FilteredLearningObject | null = await databaseLearningObjectProvider.getLearningObjectById(exampleLearningObject);
expect(result).toBeTruthy();
expectToBeCorrectFilteredLearningObject(result!, exampleLearningObject);
});
it("should return the learning object when it is queried by only hruid and language (but not version)", async () => {
it('should return the learning object when it is queried by only hruid and language (but not version)', async () => {
const result: FilteredLearningObject | null = await databaseLearningObjectProvider.getLearningObjectById({
hruid: exampleLearningObject.hruid,
language: exampleLearningObject.language
language: exampleLearningObject.language,
});
expect(result).toBeTruthy();
expectToBeCorrectFilteredLearningObject(result!, exampleLearningObject);
});
it("should return null when queried with an id that does not exist", async () => {
it('should return null when queried with an id that does not exist', async () => {
const result: FilteredLearningObject | null = await databaseLearningObjectProvider.getLearningObjectById({
hruid: "non_existing_hruid",
language: Language.Dutch
hruid: 'non_existing_hruid',
language: Language.Dutch,
});
expect(result).toBeNull();
});
});
describe("getLearningObjectHTML", () => {
it("should return the correct rendering of the learning object", async () => {
describe('getLearningObjectHTML', () => {
it('should return the correct rendering of the learning object', async () => {
const result = await databaseLearningObjectProvider.getLearningObjectHTML(exampleLearningObject);
expect(result).toEqual(example.getHTMLRendering());
});

View file

@ -1,30 +1,30 @@
import {beforeAll, describe, expect, it} from "vitest";
import {setupTestApp} from "../../setup-tests";
import {LearningObject} from "../../../src/entities/content/learning-object.entity";
import {getLearningObjectRepository} from "../../../src/data/repositories";
import learningObjectExample from "../../test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example";
import learningObjectService from "../../../src/services/learning-objects/learning-object-service";
import {LearningObjectIdentifier} from "../../../src/interfaces/learning-content";
import {Language} from "../../../src/entities/content/language";
import {EnvVars, getEnvVar} from "../../../src/util/envvars";
import { beforeAll, describe, expect, it } from 'vitest';
import { setupTestApp } from '../../setup-tests';
import { LearningObject } from '../../../src/entities/content/learning-object.entity';
import { getLearningObjectRepository } from '../../../src/data/repositories';
import learningObjectExample from '../../test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example';
import learningObjectService from '../../../src/services/learning-objects/learning-object-service';
import { LearningObjectIdentifier } from '../../../src/interfaces/learning-content';
import { Language } from '../../../src/entities/content/language';
import { EnvVars, getEnvVar } from '../../../src/util/envvars';
const TEST_LEARNING_OBJECT_TITLE = "Test title";
const EXPECTED_DWENGO_LEARNING_OBJECT_TITLE = "Werken met notebooks";
const TEST_LEARNING_OBJECT_TITLE = 'Test title';
const EXPECTED_DWENGO_LEARNING_OBJECT_TITLE = 'Werken met notebooks';
const DWENGO_TEST_LEARNING_OBJECT_ID: LearningObjectIdentifier = {
hruid: "pn_werkingnotebooks",
hruid: 'pn_werkingnotebooks',
language: Language.Dutch,
version: 3
version: 3,
};
async function initExampleData(): Promise<LearningObject> {
const learningObjectRepo = getLearningObjectRepository();
let learningObject = learningObjectExample.createLearningObject();
learningObject.title = TEST_LEARNING_OBJECT_TITLE
const learningObject = learningObjectExample.createLearningObject();
learningObject.title = TEST_LEARNING_OBJECT_TITLE;
await learningObjectRepo.save(learningObject);
return learningObject;
}
describe("LearningObjectService", () => {
describe('LearningObjectService', () => {
let exampleLearningObject: LearningObject;
beforeAll(async () => {
@ -32,47 +32,50 @@ describe("LearningObjectService", () => {
exampleLearningObject = await initExampleData();
});
describe("getLearningObjectById", () => {
it("returns the learning object from the Dwengo API if it does not have the user content prefix", async () => {
describe('getLearningObjectById', () => {
it('returns the learning object from the Dwengo API if it does not have the user content prefix', async () => {
const result = await learningObjectService.getLearningObjectById(DWENGO_TEST_LEARNING_OBJECT_ID);
expect(result).not.toBeNull();
expect(result?.title).toBe(EXPECTED_DWENGO_LEARNING_OBJECT_TITLE);
});
it("returns the learning object from the database if it does have the user content prefix", async () => {
it('returns the learning object from the database if it does have the user content prefix', async () => {
const result = await learningObjectService.getLearningObjectById(exampleLearningObject);
expect(result).not.toBeNull();
expect(result?.title).toBe(exampleLearningObject.title);
});
it("returns null if the hruid does not have the user content prefix and does not exist in the Dwengo repo", async () => {
it('returns null if the hruid does not have the user content prefix and does not exist in the Dwengo repo', async () => {
const result = await learningObjectService.getLearningObjectById({
hruid: "non-existing",
language: Language.Dutch
hruid: 'non-existing',
language: Language.Dutch,
});
expect(result).toBeNull();
});
});
describe("getLearningObjectHTML", () => {
it("returns the expected HTML when queried with the identifier of a learning object saved in the database", async () => {
describe('getLearningObjectHTML', () => {
it('returns the expected HTML when queried with the identifier of a learning object saved in the database', async () => {
const result = await learningObjectService.getLearningObjectHTML(exampleLearningObject);
expect(result).not.toBeNull();
expect(result).toEqual(learningObjectExample.getHTMLRendering());
});
it("returns the same HTML as the Dwengo API when queried with the identifier of a learning object that does " +
"not start with the user content prefix", async () => {
const result = await learningObjectService.getLearningObjectHTML(DWENGO_TEST_LEARNING_OBJECT_ID);
expect(result).not.toBeNull();
it(
'returns the same HTML as the Dwengo API when queried with the identifier of a learning object that does ' +
'not start with the user content prefix',
async () => {
const result = await learningObjectService.getLearningObjectHTML(DWENGO_TEST_LEARNING_OBJECT_ID);
expect(result).not.toBeNull();
const htmlFromDwengoApi = await fetch(
getEnvVar(EnvVars.LearningContentRepoApiBaseUrl)
+ `/learningObject/getRaw?hruid=${DWENGO_TEST_LEARNING_OBJECT_ID.hruid}&language=${DWENGO_TEST_LEARNING_OBJECT_ID.language}&version=${DWENGO_TEST_LEARNING_OBJECT_ID.version}`
).then(it => it.text());
expect(result).toEqual(htmlFromDwengoApi);
});
it("returns null when queried with a non-existing identifier", async () => {
const htmlFromDwengoApi = await fetch(
getEnvVar(EnvVars.LearningContentRepoApiBaseUrl) +
`/learningObject/getRaw?hruid=${DWENGO_TEST_LEARNING_OBJECT_ID.hruid}&language=${DWENGO_TEST_LEARNING_OBJECT_ID.language}&version=${DWENGO_TEST_LEARNING_OBJECT_ID.version}`
).then((it) => it.text());
expect(result).toEqual(htmlFromDwengoApi);
}
);
it('returns null when queried with a non-existing identifier', async () => {
const result = await learningObjectService.getLearningObjectHTML({
hruid: "non_existing_hruid",
language: Language.Dutch
hruid: 'non_existing_hruid',
language: Language.Dutch,
});
expect(result).toBeNull();
});

View file

@ -1,23 +1,23 @@
import {describe, expect, it} from "vitest";
import mdExample from "../../../test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example";
import multipleChoiceExample from "../../../test-assets/learning-objects/test-multiple-choice/test-multiple-choice-example";
import essayExample from "../../../test-assets/learning-objects/test-essay/test-essay-example";
import processingService from "../../../../src/services/learning-objects/processing/processing-service";
import { describe, expect, it } from 'vitest';
import mdExample from '../../../test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example';
import multipleChoiceExample from '../../../test-assets/learning-objects/test-multiple-choice/test-multiple-choice-example';
import essayExample from '../../../test-assets/learning-objects/test-essay/test-essay-example';
import processingService from '../../../../src/services/learning-objects/processing/processing-service';
describe("ProcessingService", () => {
it("renders a markdown learning object correctly", async () => {
describe('ProcessingService', () => {
it('renders a markdown learning object correctly', async () => {
const markdownLearningObject = mdExample.createLearningObject();
const result = await processingService.render(markdownLearningObject);
expect(result).toEqual(mdExample.getHTMLRendering());
});
it("renders a multiple choice question correctly", async () => {
it('renders a multiple choice question correctly', async () => {
const multipleChoiceLearningObject = multipleChoiceExample.createLearningObject();
const result = await processingService.render(multipleChoiceLearningObject);
expect(result).toEqual(multipleChoiceExample.getHTMLRendering());
});
it("renders an essay question correctly", async () => {
it('renders an essay question correctly', async () => {
const essayLearningObject = essayExample.createLearningObject();
const result = await processingService.render(essayLearningObject);
expect(result).toEqual(essayExample.getHTMLRendering());