Skip to content

Commit a82e78b

Browse files
committed
Final tweaks and tests for H5P upload.
1 parent 36bbe24 commit a82e78b

File tree

2 files changed

+84
-16
lines changed

2 files changed

+84
-16
lines changed

contentcuration/contentcuration/frontend/shared/vuex/file/__tests__/module.spec.js

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,17 +149,17 @@ describe('file store', () => {
149149
it('getH5PMetadata should check for h5p.json file', () => {
150150
const zip = new JSZip();
151151
return zip.generateAsync({ type: 'blob' }).then(async function(h5pBlob) {
152-
await expect(Promise.resolve(getH5PMetadata(h5pBlob))).resolves.toThrowError(
152+
await expect(getH5PMetadata(h5pBlob)).rejects.toThrow(
153153
'h5p.json not found in the H5P file.'
154154
);
155155
});
156156
});
157-
it('getH5PMetadata should exract metadata from h5p.json', async () => {
157+
it('getH5PMetadata should extract metadata from h5p.json', async () => {
158158
const manifestFile = get_metadata_file({ title: 'Test file' });
159159
const zip = new JSZip();
160160
zip.file('h5p.json', manifestFile);
161161
await zip.generateAsync({ type: 'blob' }).then(async function(h5pBlob) {
162-
await expect(Promise.resolve(getH5PMetadata(h5pBlob))).resolves.toEqual({
162+
await expect(getH5PMetadata(h5pBlob)).resolves.toEqual({
163163
title: 'Test file',
164164
});
165165
});
@@ -169,7 +169,55 @@ describe('file store', () => {
169169
const zip = new JSZip();
170170
zip.file('h5p.json', manifestFile);
171171
await zip.generateAsync({ type: 'blob' }).then(async function(h5pBlob) {
172-
await expect(Promise.resolve(getH5PMetadata(h5pBlob))).resolves.toEqual({
172+
await expect(getH5PMetadata(h5pBlob)).resolves.toEqual({
173+
title: 'Test file',
174+
});
175+
});
176+
});
177+
it.each([
178+
['CC BY', 1],
179+
['CC BY-SA', 2],
180+
['CC BY-ND', 3],
181+
['CC BY-NC', 4],
182+
['CC BY-NC-SA', 5],
183+
['CC BY-NC-ND', 6],
184+
['CC0 1.0', 8],
185+
])('getH5PMetadata should parse CC license %s', async (licenseName, licenseId) => {
186+
const manifestFile = get_metadata_file({ title: 'Test file', license: licenseName });
187+
const zip = new JSZip();
188+
zip.file('h5p.json', manifestFile);
189+
await zip.generateAsync({ type: 'blob' }).then(async function(h5pBlob) {
190+
await expect(getH5PMetadata(h5pBlob)).resolves.toEqual({
191+
title: 'Test file',
192+
license: licenseId,
193+
});
194+
});
195+
});
196+
it.each([
197+
[{ role: 'Author', name: 'Testing' }, 'author'],
198+
[{ role: 'Editor', name: 'Testing' }, 'aggregator'],
199+
[{ role: 'Licensee', name: 'Testing' }, 'copyright_holder'],
200+
[{ role: 'Originator', name: 'Testing' }, 'provider'],
201+
])('getH5PMetadata should parse CC license %s', async (authorObj, field) => {
202+
const manifestFile = get_metadata_file({ title: 'Test file', authors: [authorObj] });
203+
const zip = new JSZip();
204+
zip.file('h5p.json', manifestFile);
205+
await zip.generateAsync({ type: 'blob' }).then(async function(h5pBlob) {
206+
await expect(getH5PMetadata(h5pBlob)).resolves.toEqual({
207+
title: 'Test file',
208+
[field]: authorObj.name,
209+
});
210+
});
211+
});
212+
it('getH5PMetadata should not extract Firstname Surname author', async () => {
213+
const manifestFile = get_metadata_file({
214+
title: 'Test file',
215+
authors: [{ name: 'Firstname Surname', role: 'Author' }],
216+
});
217+
const zip = new JSZip();
218+
zip.file('h5p.json', manifestFile);
219+
await zip.generateAsync({ type: 'blob' }).then(async function(h5pBlob) {
220+
await expect(getH5PMetadata(h5pBlob)).resolves.toEqual({
173221
title: 'Test file',
174222
});
175223
});
@@ -178,17 +226,13 @@ describe('file store', () => {
178226
const manifestFile = get_metadata_file({
179227
title: 'Test file',
180228
language: 'en',
181-
authors: 'author1',
182-
license: 'license1',
183229
});
184230
const zip = new JSZip();
185231
zip.file('h5p.json', manifestFile);
186232
await zip.generateAsync({ type: 'blob' }).then(async function(h5pBlob) {
187-
await expect(Promise.resolve(getH5PMetadata(h5pBlob))).resolves.toEqual({
233+
await expect(getH5PMetadata(h5pBlob)).resolves.toEqual({
188234
title: 'Test file',
189235
language: 'en',
190-
author: 'author1',
191-
license: 'license1',
192236
});
193237
});
194238
});

contentcuration/contentcuration/frontend/shared/vuex/file/utils.js

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import SparkMD5 from 'spark-md5';
22
import JSZip from 'jszip';
33
import { FormatPresetsList, FormatPresetsNames } from 'shared/leUtils/FormatPresets';
4+
import { LicensesList } from 'shared/leUtils/Licenses';
5+
import LanguagesMap from 'shared/leUtils/Languages';
46

57
const BLOB_SLICE = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
68
const CHUNK_SIZE = 2097152;
@@ -64,6 +66,13 @@ export function storageUrl(checksum, file_format) {
6466
return `/content/storage/${checksum[0]}/${checksum[1]}/${checksum}.${file_format}`;
6567
}
6668

69+
const AuthorFieldMappings = {
70+
Author: 'author',
71+
Editor: 'aggregator',
72+
Licensee: 'copyright_holder',
73+
Originator: 'provider',
74+
};
75+
6776
export async function getH5PMetadata(fileInput) {
6877
const zip = new JSZip();
6978
const metadata = {};
@@ -82,19 +91,34 @@ export async function getH5PMetadata(fileInput) {
8291
if (Object.prototype.hasOwnProperty.call(data, 'title')) {
8392
metadata.title = data['title'];
8493
}
85-
if (Object.prototype.hasOwnProperty.call(data, 'language') && data['language'] !== 'und') {
94+
if (
95+
Object.prototype.hasOwnProperty.call(data, 'language') &&
96+
LanguagesMap.has(data['language']) &&
97+
data['language'] !== 'und'
98+
) {
8699
metadata.language = data['language'];
87100
}
88101
if (Object.prototype.hasOwnProperty.call(data, 'authors')) {
89-
metadata.author = data['authors'];
102+
for (const author of data['authors']) {
103+
// Ignore obvious placedholders created by online H5P editor tools
104+
if (author.role && author.name !== 'Firstname Surname') {
105+
if (AuthorFieldMappings[author.role]) {
106+
metadata[AuthorFieldMappings[author.role]] = author.name;
107+
}
108+
}
109+
}
90110
}
91111
if (Object.prototype.hasOwnProperty.call(data, 'license')) {
92-
metadata.license = data['license'];
112+
const license = LicensesList.find(license => license.license_name === data['license']);
113+
if (license) {
114+
metadata.license = license.id;
115+
} else if (data['license'] == 'CC0 1.0') {
116+
// Special case for CC0 1.0
117+
// this is the hard coded license id for CC0 1.0
118+
metadata.license = 8;
119+
}
93120
}
94121
return metadata;
95-
})
96-
.catch(function(error) {
97-
return error;
98122
});
99123
}
100124

@@ -130,7 +154,7 @@ export function extractMetadata(file, preset = null) {
130154
return new Promise(resolve => {
131155
if (isH5P) {
132156
getH5PMetadata(file).then(data => {
133-
if (data.constructor !== Error) Object.assign(metadata, ...data);
157+
Object.assign(metadata, data);
134158
});
135159
resolve(metadata);
136160
} else {

0 commit comments

Comments
 (0)