opds-web-client
Version:
262 lines (261 loc) • 14.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var chai_1 = require("chai");
var sinon_1 = require("sinon");
var React = require("react");
var PropTypes = require("prop-types");
var enzyme_1 = require("enzyme");
var dgx_svg_icons_1 = require("@nypl/dgx-svg-icons");
var react_redux_1 = require("react-redux");
var Book_1 = require("../Book");
var CatalogLink_1 = require("../CatalogLink");
var BookCover_1 = require("../BookCover");
var BorrowButton_1 = require("../BorrowButton");
var DownloadButton_1 = require("../DownloadButton");
var routing_1 = require("../../__mocks__/routing");
var ActionsContext_1 = require("../context/ActionsContext");
var store_1 = require("../../store");
var DataFetcher_1 = require("../../DataFetcher");
var OPDSDataAdapter_1 = require("../../OPDSDataAdapter");
var actions_1 = require("../../actions");
var book = {
id: "urn:librarysimplified.org/terms/id/3M%20ID/crrmnr9",
title: "The Mayan Secrets",
authors: ["Clive Cussler", "Thomas Perry"],
summary: "<strong>Sam and Remi Fargo race for treasure—and survival—in this lightning-paced new adventure from #1<i> New York Times</i> bestselling author Clive Cussler.</strong><br />Husband-and-wife team Sam and Remi Fargo are in Mexico when they come upon a remarkable discovery—the mummified remainsof a man clutching an ancient sealed pot. Within the pot is a Mayan book larger than any known before.<br />The book contains astonishing information about the Mayans, their cities, and about mankind itself. The secrets are so powerful that some people would do anything to possess them—as the Fargos are about to find out.",
imageUrl: "https://dlotdqc6pnwqb.cloudfront.net/3M/crrmnr9/cover.jpg",
openAccessLinks: [
{ url: "secrets.epub", type: "application/epub+zip" },
{ url: "secrets.mobi", type: "application/x-mobipocket-ebook" }
],
borrowUrl: "borrow url",
publisher: "Penguin Publishing Group",
published: "February 29, 2016",
categories: ["category 1", "category 2"],
series: {
name: "Fake Series"
},
language: "de",
raw: {
$: { "schema:additionalType": { value: "http://bib.schema.org/Audiobook" } }
}
};
describe("Book", function () {
var updateBook;
var epubReaderUrlTemplate;
beforeEach(function () {
updateBook = (0, sinon_1.stub)();
epubReaderUrlTemplate = (0, sinon_1.stub)().returns("test reader url");
});
it("shows the book cover", function () {
var wrapper = (0, enzyme_1.shallow)(React.createElement(Book_1.default, { book: book, updateBook: updateBook }));
var links = wrapper.find(CatalogLink_1.default);
var cover = links.at(0).children().at(0);
(0, chai_1.expect)(cover.type()).to.equal(BookCover_1.default);
(0, chai_1.expect)(cover.props().book).to.equal(book);
});
it("has language attribute matching the book's language", function () {
var wrapper = (0, enzyme_1.shallow)(React.createElement(Book_1.default, { book: book, updateBook: updateBook }));
var bookElement = wrapper.find(".book");
(0, chai_1.expect)(bookElement.props().lang).to.equal("de");
});
describe("compact info", function () {
it("shows book info", function () {
var _a;
var wrapper = (0, enzyme_1.shallow)(React.createElement(Book_1.default, { book: book, updateBook: updateBook }));
var links = wrapper.find(CatalogLink_1.default);
var bookInfo = links.at(0).children().at(1);
var title = bookInfo.find(".title");
var authors = bookInfo.find(".authors");
(0, chai_1.expect)(title.text()).to.equal(book.title);
(0, chai_1.expect)(authors.text()).to.equal("By ".concat((_a = book.authors) === null || _a === void 0 ? void 0 : _a.join(", ")));
});
it("shows contributors when there's no author", function () {
var bookCopy = Object.assign({}, book, {
authors: [],
contributors: ["contributor"]
});
var wrapper = (0, enzyme_1.shallow)(React.createElement(Book_1.default, { book: bookCopy, updateBook: updateBook }));
var links = wrapper.find(CatalogLink_1.default);
var bookInfo = links.at(0).children().at(1);
var authors = bookInfo.find(".authors");
(0, chai_1.expect)(authors.text()).to.equal("By ".concat(bookCopy.contributors[0]));
});
it("renders two icons and labels in the compact and expanded views", function () {
var wrapper = (0, enzyme_1.shallow)(React.createElement(Book_1.default, { book: book, updateBook: updateBook }));
var itemIcon = wrapper.find(".item-icon");
var svg = itemIcon.find(dgx_svg_icons_1.AudioHeadphoneIcon);
(0, chai_1.expect)(svg.length).to.equal(2);
(0, chai_1.expect)(itemIcon.first().render().text()).to.equal("Audio/Headphone Icon ");
});
});
describe("expanded info", function () {
var wrapper;
beforeEach(function () {
wrapper = (0, enzyme_1.shallow)(React.createElement(Book_1.default, { book: book, updateBook: updateBook, epubReaderUrlTemplate: epubReaderUrlTemplate }));
});
it("shows header with title and authors", function () {
var _a;
var bookInfo = wrapper.find(".expanded-info");
var title = bookInfo.find(".title");
var authors = bookInfo.find(".authors");
(0, chai_1.expect)(title.text()).to.equal(book.title);
(0, chai_1.expect)(authors.text()).to.equal("By ".concat((_a = book.authors) === null || _a === void 0 ? void 0 : _a.join(", ")));
});
it("shows contributors when there's no author", function () {
var bookCopy = Object.assign({}, book, {
authors: [],
contributors: ["contributor"]
});
wrapper = (0, enzyme_1.shallow)(React.createElement(Book_1.default, { book: bookCopy, updateBook: updateBook }));
var bookInfo = wrapper.find(".expanded-info");
var authors = bookInfo.find(".authors");
(0, chai_1.expect)(authors.text()).to.equal("By ".concat(bookCopy.contributors[0]));
});
it("shows series", function () {
var _a;
var bookInfo = wrapper.find(".expanded-info");
var series = bookInfo.find(".series");
(0, chai_1.expect)(series.text()).to.equal((_a = book.series) === null || _a === void 0 ? void 0 : _a.name);
});
it("shows publisher", function () {
var publisher = wrapper.find(".publisher");
(0, chai_1.expect)(publisher.text()).to.equal("Publisher: " + book.publisher);
});
it("doesn't show publisher when there isn't one", function () {
var bookCopy = Object.assign({}, book, {
publisher: null
});
wrapper = (0, enzyme_1.shallow)(React.createElement(Book_1.default, { book: bookCopy, updateBook: (0, sinon_1.stub)() }));
var publisher = wrapper.find(".publisher");
(0, chai_1.expect)(publisher.length).to.equal(0);
});
it("shows publish date", function () {
var published = wrapper.find(".published");
(0, chai_1.expect)(published.text()).to.equal("Published: " + book.published);
});
it("shows categories", function () {
var categories = wrapper.find(".categories");
(0, chai_1.expect)(categories.text()).to.equal("Categories: category 1, category 2");
});
it("doesn't show categories when there aren't any", function () {
var bookCopy = Object.assign({}, book, { categories: [] });
wrapper = (0, enzyme_1.shallow)(React.createElement(Book_1.default, { book: bookCopy, updateBook: (0, sinon_1.stub)() }));
var categories = wrapper.find(".categories");
(0, chai_1.expect)(categories.length).to.equal(0);
});
it("has english as the language for the fields", function () {
var fields = wrapper.find(".fields");
(0, chai_1.expect)(fields.props().lang).to.equal("en");
});
it("shows summary, in book's language, with html stripped out and more link", function () {
var context = (0, routing_1.mockRouterContext)();
var store = (0, store_1.default)();
var fetcher = new DataFetcher_1.default({ adapter: OPDSDataAdapter_1.adapter });
var actions = new actions_1.default(fetcher);
wrapper = (0, enzyme_1.mount)(React.createElement(react_redux_1.Provider, { store: store },
React.createElement(ActionsContext_1.ActionsProvider, { fetcher: fetcher, actions: actions },
React.createElement(Book_1.default, { book: book, updateBook: updateBook }))), {
context: context,
childContextTypes: {
router: PropTypes.object,
pathFor: PropTypes.func,
actions: PropTypes.any
}
});
var summary = wrapper.find(".summary");
(0, chai_1.expect)(summary.html()).to.contain("Sam and Remi");
(0, chai_1.expect)(summary.html()).not.to.contain("strong");
(0, chai_1.expect)(summary.props().lang).to.equal("de");
var moreLink = summary.find("a");
(0, chai_1.expect)(moreLink.length).to.equal(1);
(0, chai_1.expect)(moreLink.html()).to.contain("More");
});
it("shows download button for open access urls", function () {
var buttons = wrapper.find(DownloadButton_1.default);
(0, chai_1.expect)(buttons.length).to.equal(2);
var epubButton = buttons.at(0);
var mobiButton = buttons.at(1);
(0, chai_1.expect)(epubButton.props().link.url).to.equal("secrets.epub");
(0, chai_1.expect)(epubButton.props().link.type).to.equal("application/epub+zip");
(0, chai_1.expect)(epubButton.props().isPlainLink).to.equal(true);
(0, chai_1.expect)(mobiButton.props().link.url).to.equal("secrets.mobi");
(0, chai_1.expect)(mobiButton.props().link.type).to.equal("application/x-mobipocket-ebook");
(0, chai_1.expect)(mobiButton.props().isPlainLink).to.equal(true);
});
it("shows read button for open access epub urls", function () {
var buttons = wrapper.find(".read-button");
(0, chai_1.expect)(buttons.length).to.equal(1);
(0, chai_1.expect)(buttons.props().href).to.equal("test reader url");
});
it("shows borrow/hold button", function () {
var bookCopy = Object.assign({}, book, {
borrowUrl: "borrow url"
});
var updateBook = (0, sinon_1.stub)();
wrapper = (0, enzyme_1.shallow)(React.createElement(Book_1.default, { book: bookCopy, updateBook: updateBook }));
var button = wrapper.find(BorrowButton_1.default);
(0, chai_1.expect)(button.children().text()).to.equal("Borrow");
button.props().borrow();
(0, chai_1.expect)(updateBook.callCount).to.equal(1);
(0, chai_1.expect)(updateBook.args[0][0]).to.equal(bookCopy.borrowUrl);
wrapper.setProps({
book: Object.assign({}, bookCopy, {
copies: { total: 2, available: 0 }
})
});
button = wrapper.find(BorrowButton_1.default);
(0, chai_1.expect)(button.children().text()).to.equal("Reserve");
});
it("shows fulfill button if there's no download button", function () {
var link = {
url: "fulfillment url",
type: "application/vnd.adobe.adept+xml"
};
var bookCopy = Object.assign({}, book, {
openAccessLinks: [],
fulfillmentLinks: [link]
});
wrapper = (0, enzyme_1.shallow)(React.createElement(Book_1.default, { book: bookCopy, updateBook: (0, sinon_1.stub)(), isSignedIn: false }));
var button = wrapper.find(DownloadButton_1.default);
(0, chai_1.expect)(button.props().link.url).to.equal(link.url);
(0, chai_1.expect)(button.props().title).to.equal(bookCopy.title);
(0, chai_1.expect)(button.props().link.type).to.equal(link.type);
(0, chai_1.expect)(button.props().isPlainLink).to.equal(true);
});
it("shows 'borrowed'", function () {
var link = {
url: "fulfillment url",
type: "application/vnd.adobe.adept+xml"
};
var bookCopy = Object.assign({}, book, {
openAccessLinks: [],
fulfillmentLinks: [link]
});
wrapper = (0, enzyme_1.shallow)(React.createElement(Book_1.default, { book: bookCopy, updateBook: (0, sinon_1.stub)() }));
var button = wrapper.find(BorrowButton_1.default);
(0, chai_1.expect)(button.props().children).to.equal("Borrowed");
(0, chai_1.expect)(button.props().disabled).to.equal(true);
});
it("shows 'reserved'", function () {
var bookCopy = Object.assign({}, book, {
openAccessLinks: [],
availability: { status: "reserved" }
});
wrapper = (0, enzyme_1.shallow)(React.createElement(Book_1.default, { book: bookCopy, updateBook: (0, sinon_1.stub)() }));
var button = wrapper.find("button");
(0, chai_1.expect)(button.text()).to.equal("Reserved");
(0, chai_1.expect)(button.props().className).to.contain("disabled");
});
it("shows 'borrow' when a reserved book becomes available", function () {
var bookCopy = Object.assign({}, book, {
openAccessLinks: [],
availability: { status: "ready" }
});
wrapper = (0, enzyme_1.shallow)(React.createElement(Book_1.default, { book: bookCopy, updateBook: (0, sinon_1.stub)() }));
var button = wrapper.find(BorrowButton_1.default);
(0, chai_1.expect)(button.length).to.equal(1);
(0, chai_1.expect)(button.html()).to.contain("Borrow");
});
});
});