Skip to content

Commit

Permalink
EW-799 Common Cartridge Export of Column Board Link Elements (#4932)
Browse files Browse the repository at this point in the history
* Adding link elements from the column board to the common cartridge export
* Tested for Common Cartridge 1.1.0
  • Loading branch information
psachmann authored Apr 18, 2024
1 parent 1ba1713 commit 05f055d
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ import {
import { ConfigService } from '@nestjs/config';
import { Test, TestingModule } from '@nestjs/testing';
import { ComponentProperties, ComponentType } from '@shared/domain/entity';
import { courseFactory, lessonFactory, setupEntities, taskFactory, userFactory } from '@shared/testing';
import { RichTextElement, RichTextElementProps } from '@shared/domain/domainobject';
import { InputFormat } from '@shared/domain/types';
import {
courseFactory,
lessonFactory,
linkElementFactory,
richTextElementFactory,
setupEntities,
taskFactory,
userFactory,
} from '@shared/testing';
import { LearnroomConfig } from '../learnroom.config';
import { CommonCartridgeMapper } from './common-cartridge.mapper';

Expand Down Expand Up @@ -403,16 +409,7 @@ describe('CommonCartridgeMapper', () => {
describe('mapRichTextElementToResource', () => {
describe('when mapping rich text element', () => {
const setup = () => {
const richTextElementProps: RichTextElementProps = {
text: faker.lorem.paragraph(),
inputFormat: InputFormat.RICH_TEXT_CK5,
id: faker.string.uuid(),
createdAt: faker.date.recent(),
updatedAt: faker.date.recent(),
};
const richTextElement = new RichTextElement(richTextElementProps);

configServiceMock.getOrThrow.mockReturnValue(faker.internet.url());
const richTextElement = richTextElementFactory.build();

return { richTextElement };
};
Expand All @@ -425,11 +422,37 @@ describe('CommonCartridgeMapper', () => {
expect(resourceProps).toStrictEqual<CommonCartridgeResourceProps>({
type: CommonCartridgeResourceType.WEB_CONTENT,
identifier: expect.any(String),
title: richTextElement.text.slice(0, 50).concat('...'),
title: richTextElement.text
.slice(0, 50)
.replace(/<[^>]*>?/gm, '')
.concat('...'),
html: `<p>${richTextElement.text}</p>`,
intendedUse: CommonCartridgeIntendedUseType.UNSPECIFIED,
});
});
});
});

describe('mapLinkElementToResource', () => {
describe('when mapping link element', () => {
const setup = () => {
const linkElement = linkElementFactory.build();

return { linkElement };
};

it('should map to web link', () => {
const { linkElement } = setup();

const resourceProps = sut.mapLinkElementToResource(linkElement);

expect(resourceProps).toStrictEqual<CommonCartridgeResourceProps>({
type: CommonCartridgeResourceType.WEB_LINK,
identifier: createIdentifier(linkElement.id),
title: linkElement.title,
url: linkElement.url,
});
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
} from '@modules/common-cartridge';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { LinkElement, RichTextElement } from '@shared/domain/domainobject';
import { ComponentProperties, ComponentType, Course, LessonEntity, Task } from '@shared/domain/entity';
import { RichTextElement } from '@shared/domain/domainobject';
import { LearnroomConfig } from '../learnroom.config';

@Injectable()
Expand Down Expand Up @@ -129,6 +129,15 @@ export class CommonCartridgeMapper {
};
}

public mapLinkElementToResource(element: LinkElement): CommonCartridgeResourceProps {
return {
type: CommonCartridgeResourceType.WEB_LINK,
identifier: createIdentifier(element.id),
title: element.title,
url: element.url,
};
}

private getTextTitle(text: string): string {
const title = text
.slice(0, 50)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import { ConfigService } from '@nestjs/config';
import { Test, TestingModule } from '@nestjs/testing';
import { ComponentType } from '@shared/domain/entity';
import {
cardFactory,
columnBoardFactory,
columnFactory,
cardFactory,
courseFactory,
lessonFactory,
linkElementFactory,
richTextElementFactory,
setupEntities,
taskFactory,
richTextElementFactory,
} from '@shared/testing';
import { ColumnBoardService } from '@src/modules/board';
import AdmZip from 'adm-zip';
Expand Down Expand Up @@ -73,7 +74,8 @@ describe('CommonCartridgeExportService', () => {
const [lesson] = lessons;
const taskFromLesson = taskFactory.buildWithId({ course, lesson });
const textCardElement = richTextElementFactory.build();
const card = cardFactory.build({ children: [textCardElement] });
const linkElement = linkElementFactory.build();
const card = cardFactory.build({ children: [textCardElement, linkElement] });
const column = columnFactory.build({ children: [card] });
const columnBoard = columnBoardFactory.build({ children: [column] });

Expand All @@ -94,7 +96,7 @@ describe('CommonCartridgeExportService', () => {
);
const archive = new AdmZip(buffer);

return { archive, course, lessons, tasks, taskFromLesson, columnBoard, column, card, textCardElement };
return { archive, course, lessons, tasks, taskFromLesson, columnBoard, column, card, textCardElement, linkElement };
};

beforeAll(async () => {
Expand Down Expand Up @@ -199,6 +201,20 @@ describe('CommonCartridgeExportService', () => {

expect(manifest).toContain(createXmlString('title', card.title));
});

it('should add content element of cards', async () => {
const { archive, textCardElement } = await setup();
const manifest = getFileContent(archive, 'imsmanifest.xml');

expect(manifest).toContain(`<resource identifier="i${textCardElement.id}"`);
});

it('should add link element of card', async () => {
const { archive, linkElement } = await setup();
const manifest = getFileContent(archive, 'imsmanifest.xml');

expect(manifest).toContain(`<resource identifier="i${linkElement.id}"`);
});
});

describe('when using version 1.3', () => {
Expand Down Expand Up @@ -269,6 +285,13 @@ describe('CommonCartridgeExportService', () => {

expect(manifest).toContain(`<resource identifier="i${textCardElement.id}"`);
});

it('should add link element of card', async () => {
const { archive, linkElement } = await setup();
const manifest = getFileContent(archive, 'imsmanifest.xml');

expect(manifest).toContain(`<resource identifier="i${linkElement.id}"`);
});
});

describe('When topics array is empty', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@ import {
import { LessonService } from '@modules/lesson';
import { TaskService } from '@modules/task';
import { Injectable } from '@nestjs/common';
import { BoardExternalReferenceType, Column, Card, RichTextElement } from '@shared/domain/domainobject';
import {
AnyBoardDo,
BoardExternalReferenceType,
Card,
Column,
isCard,
isColumn,
isLinkElement,
isRichTextElement,
} from '@shared/domain/domainobject';
import { ComponentProperties } from '@shared/domain/entity';
import { EntityId } from '@shared/domain/types';
import { ColumnBoardService } from '@src/modules/board';
Expand Down Expand Up @@ -110,7 +119,7 @@ export class CommonCartridgeExportService {
});

columnBoard.children
.filter((child) => child instanceof Column)
.filter((child) => isColumn(child))
.forEach((column) => this.addColumnToOrganization(column as Column, organization));
}
}
Expand All @@ -123,7 +132,7 @@ export class CommonCartridgeExportService {
});

column.children
.filter((child) => child instanceof Card)
.filter((child) => isCard(child))
.forEach((card) => this.addCardToOrganization(card as Card, columnOrganization));
}

Expand All @@ -134,11 +143,24 @@ export class CommonCartridgeExportService {
identifier: createIdentifier(id),
});

card.children
.filter((child) => child instanceof RichTextElement)
.forEach((child) =>
cardOrganization.addResource(this.commonCartridgeMapper.mapRichTextElementToResource(child as RichTextElement))
);
card.children.forEach((child) => this.addCardElementToOrganization(child, cardOrganization));
}

private addCardElementToOrganization(
element: AnyBoardDo,
organizationBuilder: CommonCartridgeOrganizationBuilder
): void {
if (isRichTextElement(element)) {
const resource = this.commonCartridgeMapper.mapRichTextElementToResource(element);

organizationBuilder.addResource(resource);
}

if (isLinkElement(element)) {
const resource = this.commonCartridgeMapper.mapLinkElementToResource(element);

organizationBuilder.addResource(resource);
}
}

private addComponentToOrganization(
Expand Down

0 comments on commit 05f055d

Please sign in to comment.