Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(data): extract and report link info from the Package Document #130

Merged
merged 1 commit into from
Dec 20, 2017
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
7 changes: 4 additions & 3 deletions packages/ace-report/src/report-builders.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ function withAssertions(obj, assertions) {
return obj;
}

function withTestSubject(obj, url, title = '', identifier = '', metadata = null) {
function withTestSubject(obj, url, title = '', identifier = '', metadata = null, links = null) {
const testSubject = { url };
if (title.length > 0) testSubject['dct:title'] = title;
if (identifier.length > 0) testSubject['dct:identifier'] = identifier;
if (metadata !== undefined && metadata != null) testSubject.metadata = metadata;
if (links !== undefined && links != null) testSubject.links = links;
obj['earl:testSubject'] = testSubject;
return obj;
}
Expand Down Expand Up @@ -149,8 +150,8 @@ class ReportBuilder {
});
return this;
}
withTestSubject(url, title, identifier, metadata) {
withTestSubject(this._json, url, title, identifier, metadata);
withTestSubject(url, title, identifier, metadata, links) {
withTestSubject(this._json, url, title, identifier, metadata, links);
return this;
}
}
Expand Down
73 changes: 70 additions & 3 deletions packages/ace-report/src/report-builders.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ describe('report builder', () => {
});
});
});
describe('adding assertions', () => {

describe('withAssertions', () => {
let assertions;
test('adding null assertion is ignored', () => {
expect(report.withAssertions(null)).toBeDefined();
Expand Down Expand Up @@ -119,7 +120,8 @@ describe('report builder', () => {
expect(assertions[1]).toEqual({ foo: 'foo' });
});
});
describe('adding data', () => {

describe('withData', () => {
let data;
beforeEach(() => {
data = report.build().data;
Expand Down Expand Up @@ -152,7 +154,8 @@ describe('report builder', () => {
expect(data).toEqual({ foo: ['foo', 'bar'] });
});
});
describe('adding properties', () => {

describe('withProperties', () => {
let properties;
beforeEach(() => {
properties = report.build().properties;
Expand Down Expand Up @@ -189,4 +192,68 @@ describe('report builder', () => {
expect(properties).toEqual({ foo: true });
});
});

describe('withTestSubject', () => {
test('with URL', () => {
expect(report.withTestSubject('https://example.com')).toBeDefined();
const testSubject = report.build()['earl:testSubject'];
expect(testSubject).toBeDefined();
expect(testSubject).toEqual({
url: 'https://example.com'
})
});
test('with title', () => {
expect(report.withTestSubject('https://example.com', 'title')).toBeDefined();
const testSubject = report.build()['earl:testSubject'];
expect(testSubject).toBeDefined();
expect(testSubject).toEqual({
url: 'https://example.com',
'dct:title': 'title',
})
});
test('with identifier', () => {
expect(report.withTestSubject('https://example.com', '', 'uid')).toBeDefined();
const testSubject = report.build()['earl:testSubject'];
expect(testSubject).toBeDefined();
expect(testSubject).toEqual({
url: 'https://example.com',
'dct:identifier': 'uid',
})
});
test('with metadata null', () => {
expect(report.withTestSubject('https://example.com', '', '', null)).toBeDefined();
const testSubject = report.build()['earl:testSubject'];
expect(testSubject).toBeDefined();
expect(testSubject).toEqual({
url: 'https://example.com',
})
});
test('with metadata', () => {
expect(report.withTestSubject('https://example.com', '', '', { foo: 'bar' })).toBeDefined();
const testSubject = report.build()['earl:testSubject'];
expect(testSubject).toBeDefined();
expect(testSubject).toEqual({
url: 'https://example.com',
metadata: { foo: 'bar' }
})
});

test('with link null', () => {
expect(report.withTestSubject('https://example.com', '', '', null, null)).toBeDefined();
const testSubject = report.build()['earl:testSubject'];
expect(testSubject).toBeDefined();
expect(testSubject).toEqual({
url: 'https://example.com',
})
});
test('with links', () => {
expect(report.withTestSubject('https://example.com', '', '', null, { foo: 'bar' })).toBeDefined();
const testSubject = report.build()['earl:testSubject'];
expect(testSubject).toBeDefined();
expect(testSubject).toEqual({
url: 'https://example.com',
links: { foo: 'bar' }
})
});
});
});
8 changes: 2 additions & 6 deletions packages/ace-report/src/report.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ function aggregateHTMLOutlines(outlines) {
module.exports = class Report {
constructor(epub) {
this._builder = new builders.ReportBuilder()
.withTestSubject(epub.path, '', '', epub.metadata)
.withA11yMeta(a11yMetaChecker.analyze(epub.metadata));
.withTestSubject(epub.path, '', '', epub.metadata, epub.links)
.withA11yMeta(a11yMetaChecker.analyze(epub.metadata))
}

get json() {
Expand All @@ -56,10 +56,6 @@ module.exports = class Report {
addData(data) {
this._builder.withData(data);
}
addOutline(outline) {
this._builder.withHOutline(outline);
return this;
}
addHeadings(headings) {
this._builder.withHeadingsOutline(headingsToOutline(headings));
return this;
Expand Down
19 changes: 19 additions & 0 deletions packages/epub-utils/src/epub-parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,24 @@ function parseMetadata(doc, select) {
return result;
}


function addLink(rel, href, link) {
if (!link[rel]) {
link[rel] = href;
} else if (!(link[rel] instanceof Array)) {
link[rel] = [link[rel], href];
} else {
link[rel].push(href);
}
}
function parseLinks(doc, select) {
const result = {};
select('//opf:link[not(@refines)]', doc).forEach((link) => {
addLink(link.getAttribute('rel'), link.getAttribute('href'), result);
});
return result;
}

// override the default of XHTML
EpubParser.prototype.setContentDocMediaType = function(mediaType) {
this.contentDocMediaType = mediaType;
Expand Down Expand Up @@ -114,6 +132,7 @@ EpubParser.prototype.parseData = function(packageDocPath, epubDir) {
{ opf: 'http://www.idpf.org/2007/opf',
dc: 'http://purl.org/dc/elements/1.1/'});
this.metadata = parseMetadata(doc, select);
this.links = parseLinks(doc, select);

const spineItemIdrefs = select('//opf:itemref/@idref', doc);
spineItemIdrefs.forEach((idref) => {
Expand Down
9 changes: 9 additions & 0 deletions tests/__tests__/report_json.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@ describe('check data', () => {
});
});

test('extract links', async () => {
const report = await ace(path.join(__dirname, '../data/feat-links'));
expect(report['earl:testSubject']).toMatchObject({
links: {
"a11y:certifierReport": "http://www.example.com/report.html"
},
});
});

test('extract videos', async () => {
const report = await ace(path.join(__dirname, '../data/feat-video'));
expect(report.data).toMatchObject({
Expand Down
9 changes: 9 additions & 0 deletions tests/data/feat-links/EPUB/content_001.xhtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en">
<head>
<title>Minimal EPUB</title>
</head>
<body>
<h1>Loomings</h1>
<p>Call me Ishmael.</p>
</body>
</html>
12 changes: 12 additions & 0 deletions tests/data/feat-links/EPUB/nav.xhtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en">
<head>
<title>Minimal Nav</title>
</head>
<body>
<nav epub:type="toc">
<ol>
<li><a href="content_001.xhtml">content 001</a></li>
</ol>
</nav>
</body>
</html>
25 changes: 25 additions & 0 deletions tests/data/feat-links/EPUB/package.opf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="en" unique-identifier="uid"
prefix="a11y: http://www.idpf.org/epub/vocab/package/a11y/#">
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title id="title">Minimal EPUB 3.0</dc:title>
<dc:language>en</dc:language>
<dc:identifier id="uid">NOID</dc:identifier>
<meta property="dcterms:modified">2017-01-01T00:00:01Z</meta>
<meta property="schema:accessibilityFeature">structuralNavigation</meta>
<meta property="schema:accessibilitySummary">everything OK!</meta>
<meta property="schema:accessibilityHazard">noFlashingHazard</meta>
<meta property="schema:accessibilityHazard">noSoundHazard</meta>
<meta property="schema:accessibilityHazard">noMotionSimulationHazard</meta>
<meta property="schema:accessMode">textual</meta>
<meta property="schema:accessModeSufficient">textual</meta>
<link rel="a11y:certifierReport" href="http://www.example.com/report.html"/>
</metadata>
<manifest>
<item id="nav" href="nav.xhtml" media-type="application/xhtml+xml" properties="nav"/>
<item id="content_001" href="content_001.xhtml" media-type="application/xhtml+xml"/>
</manifest>
<spine>
<itemref idref="content_001" />
</spine>
</package>
6 changes: 6 additions & 0 deletions tests/data/feat-links/META-INF/container.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
<rootfiles>
<rootfile full-path="EPUB/package.opf" media-type="application/oebps-package+xml"/>
</rootfiles>
</container>
1 change: 1 addition & 0 deletions tests/data/feat-links/mimetype
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
application/epub+zip