Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ function generateNewName(
// XML document into a full path to file in project directory
export function resolve(reference: MediaItemReference): string {
let dir = path.dirname(reference.filePath);
const originalRef = removeQueryParams(reference.assetReference);
const originalRef = removeQueryParams(reference.assetReference.trim());

// First prefer the path as-authored and normal package upward search.
// This preserves references to nested sibling webcontent folders.
Expand Down
2 changes: 2 additions & 0 deletions src/resources/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ export function standardContentManipulations($: any) {
$('testandconfigure').remove();
$('theme').remove();
$('popout').remove();
// One course used <sym> for right arrow, just replace with bold unicode char
$('sym[name="rarr"]').replaceWith('<em style="bold">→</em>');
$('sym').remove();
$('applet').remove();
$('director').remove();
Expand Down
7 changes: 7 additions & 0 deletions src/resources/formative.ts
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,13 @@ export function determineSubType(question: any): ItemTypes {
}

export function performRestructure($: any) {
$('assessment').each((_i: any, assessment: any) => {
const id = $(assessment).attr('id');
if (id !== undefined) {
$(assessment).attr('id', id.trim());
}
});

standardContentManipulations($);

DOM.rename($, 'question body', 'stem');
Expand Down
4 changes: 3 additions & 1 deletion src/resources/workbook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ export class WorkbookPage extends Resource {
`<cite id="${entryId}" bibref="${bibRef.id}">[citation]</cite>`
);
} else {
$(elem).remove();
// found course using empty cites to wrap text, so strip rather than remove to preserve
DOM.stripElement($, elem);
}
});
// Also include any uncited refs. Handles case we've seen of references
Expand Down Expand Up @@ -247,6 +248,7 @@ export class WorkbookPage extends Resource {
material: true,
anchor: true,
translation: true,
foreign: true,
dt: true,
dd: true,
}).then((r: any) => {
Expand Down
23 changes: 23 additions & 0 deletions test/content/x-oli-inline-assessment/trailing-assessment-id.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE assessment
PUBLIC "-//Carnegie Mellon University//DTD Inline Assessment 1.4//EN" "http://oli.web.cmu.edu/dtd/oli_inline_assessment_1_4.dtd">
<assessment id="assessment-with-whitespace ">
<title>Assessment title</title>
<question id="question-one">
<body>
<p>Question text</p>
</body>
<multiple_choice shuffle="false">
<choice value="correct">Correct</choice>
<choice value="incorrect">Incorrect</choice>
</multiple_choice>
<part>
<response match="correct" score="1">
<feedback>Correct</feedback>
</response>
<response match="incorrect" score="0">
<feedback>Incorrect</feedback>
</response>
</part>
</question>
</assessment>
10 changes: 10 additions & 0 deletions test/content/x-oli-workbook_page/foreign-whitespace.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE workbook_page PUBLIC "-//Carnegie Mellon University//DTD Workbook Page MathML 3.8//EN" "http://oli.web.cmu.edu/dtd/oli_workbook_page_mathml_3_8.dtd">
<workbook_page id="foreign-whitespace">
<head>
<title>Foreign whitespace</title>
</head>
<body>
<p><foreign xml:lang="fr">Il est grand. </foreign><foreign xml:lang="fr"> Il </foreign><foreign xml:lang="fr">est </foreign><foreign xml:lang="fr"> grand.</foreign></p>
</body>
</workbook_page>
10 changes: 10 additions & 0 deletions test/content/x-oli-workbook_page/invalid-cite.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE workbook_page PUBLIC "-//Carnegie Mellon University//DTD Workbook Page MathML 3.8//EN" "http://oli.web.cmu.edu/dtd/oli_workbook_page_mathml_3_8.dtd">
<workbook_page id="invalid-cite">
<head>
<title>Invalid cite</title>
</head>
<body>
<p>Before <cite id="credit">Map by <em>Babsy</em></cite> after<cite id="empty"/>.</p>
</body>
</workbook_page>
29 changes: 29 additions & 0 deletions test/foreign-whitespace-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { MediaSummary } from 'src/media';
import { ProjectSummary } from 'src/project';
import { WorkbookPage } from 'src/resources/workbook';

const mediaSummary: MediaSummary = {
mediaItems: {},
missing: [],
urlPrefix: '',
downloadRemote: false,
flattenedNames: {},
};

const projectSummary = new ProjectSummary('', '', '', mediaSummary);

describe('foreign text whitespace', () => {
test('should preserve whitespace at foreign element boundaries', async () => {
const results: any = await new WorkbookPage(
'./test/content/x-oli-workbook_page/foreign-whitespace.xml',
true
).convert(projectSummary);

const paragraph = results[0].content.model[0].children[0];
const foreignText = paragraph.children.map(
(foreign: any) => foreign.children[0].text
);

expect(foreignText).toEqual(['Il est grand. ', ' Il ', 'est ', ' grand.']);
});
});
64 changes: 64 additions & 0 deletions test/formative-test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { MediaSummary } from 'src/media';
import { ProjectSummary } from 'src/project';
import { Formative } from 'src/resources/formative';
import { updateDerivativeReferences } from 'src/convert';
import { Page } from 'src/resources/resource';

const mediaSummary: MediaSummary = {
mediaItems: {},
Expand Down Expand Up @@ -56,4 +58,66 @@ describe('conversion to Torus resources', () => {
expect(pt5CorrectResponse.score).toEqual(10);
});
});

test('should trim assessment ids before deriving activities', async () => {
const results = await new Formative(
'./test/content/x-oli-inline-assessment/trailing-assessment-id.xml',
true
).convert(projectSummary);

expect(results).toHaveLength(1);
expect(results[0]).toEqual(
expect.objectContaining({
id: 'assessment-with-whitespace-question-one',
legacyId: 'assessment-with-whitespace',
title: 'assessment-with-whitespace-question-one',
})
);

const page = {
type: 'Page',
id: 'referencing-page',
legacyPath: '',
legacyId: 'referencing-page',
title: 'Referencing page',
tags: [],
unresolvedReferences: ['assessment-with-whitespace'],
warnings: [],
content: {
model: [
{
type: 'activity_placeholder',
idref: 'assessment-with-whitespace',
},
],
},
isGraded: false,
isSurvey: false,
collabSpace: {
status: 'disabled',
threaded: true,
auto_accept: true,
show_full_history: true,
participation_min_posts: 0,
participation_min_replies: 0,
},
objectives: [],
} as Page;

const [updatedPage] = updateDerivativeReferences([
page,
...(results as any),
]);
expect((updatedPage as Page).content.model).toEqual([
expect.objectContaining({
type: 'group',
children: [
expect.objectContaining({
type: 'activity-reference',
activity_id: 'assessment-with-whitespace-question-one',
}),
],
}),
]);
});
});
31 changes: 31 additions & 0 deletions test/invalid-cite-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { MediaSummary } from 'src/media';
import { ProjectSummary } from 'src/project';
import { WorkbookPage } from 'src/resources/workbook';

const mediaSummary: MediaSummary = {
mediaItems: {},
missing: [],
urlPrefix: '',
downloadRemote: false,
flattenedNames: {},
};

const projectSummary = new ProjectSummary('', '', '', mediaSummary);

describe('invalid citations', () => {
test('should strip cite wrappers while preserving their content', async () => {
const results: any = await new WorkbookPage(
'./test/content/x-oli-workbook_page/invalid-cite.xml',
true
).convert(projectSummary);

const paragraph = results[0].content.model[0].children[0];

expect(paragraph.children).toEqual([
{ text: 'Before Map by ' },
{ text: 'Babsy', strong: true },
{ text: ' after.' },
]);
expect(JSON.stringify(paragraph)).not.toContain('"type":"cite"');
});
});
20 changes: 20 additions & 0 deletions test/resources/common-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,24 @@ describe('cdata and codeblocks', () => {
expect(video.type).toBe('video');
expect(video.src[0].contenttype).toBe('video/webm');
});

test('should convert legacy right-arrow symbols to bold Unicode', async () => {
const content =
'<root><p>before <sym name="rarr"/> after <sym name="unknown"/></p></root>';

const $ = cheerio.load(content, {
normalizeWhitespace: true,
xmlMode: true,
});

standardContentManipulations($);

expect($('em').attr('style')).toBe('bold');
expect($('em').text()).toBe('→');
expect($('sym')).toHaveLength(0);

const result: any = await toJSON($.xml(), projectSummary);
const paragraph = result.children[0].children[0];
expect(paragraph.children).toContainEqual({ text: '→', strong: true });
});
});
20 changes: 20 additions & 0 deletions test/resources/media-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,26 @@ describe('Media conversions', () => {
);
});

it('Should trim whitespace around media references', () => {
expect(
flatten(
{
filePath: fixturePath(
'test',
'content',
'subdir',
'deeper',
'fake.xml'
),
assetReference: ' ../../webcontent/abby.jpg ',
},
testSummary()
)
).toEqual(
'unit-test://media/62/62dd67c254e1d067d385a32c3f51bf4d/abby.jpg'
);
});

it('Should prefer nested sibling webcontent folders when present', () => {
expect(
flatten(
Expand Down
Loading