From 0220aa03a30db688c8537937637962142c171e0a Mon Sep 17 00:00:00 2001 From: Ray Lee Date: Fri, 18 Nov 2022 09:51:37 -0500 Subject: [PATCH] Add prop to control rendering of book circulation links. (#18) --- packages/web-opds-client/CHANGELOG.md | 5 + .../web-opds-client/src/components/Book.tsx | 5 +- .../src/components/Collection.tsx | 2 + .../src/components/__tests__/Book-test.tsx | 223 +++++++++++------- .../components/__tests__/Collection-test.tsx | 9 + 5 files changed, 159 insertions(+), 85 deletions(-) diff --git a/packages/web-opds-client/CHANGELOG.md b/packages/web-opds-client/CHANGELOG.md index 538add21..c652e6f8 100644 --- a/packages/web-opds-client/CHANGELOG.md +++ b/packages/web-opds-client/CHANGELOG.md @@ -1,5 +1,10 @@ ## Changelog +### v1.0.0 + +- In the Book component, the circulation links (e.g. Borrow, Download) are no longer rendered by default. There is now a showCirculationLinks prop that must be set to true to render the circulation links. +- The Collection component now has a showCirculationLinks prop that controls the rendering of circulation links on the Books in the Collection. + ### v0.6.4 - Initial Palace release. diff --git a/packages/web-opds-client/src/components/Book.tsx b/packages/web-opds-client/src/components/Book.tsx index c24db229..11ce8250 100644 --- a/packages/web-opds-client/src/components/Book.tsx +++ b/packages/web-opds-client/src/components/Book.tsx @@ -19,6 +19,7 @@ export interface BookProps { updateBook: (url: string | undefined) => Promise; isSignedIn?: boolean; epubReaderUrlTemplate?: (epubUrl: string) => string; + showCirculationLinks?: boolean; } /** Displays a single book for use in a lane, list, or grid view. */ @@ -89,7 +90,9 @@ export default class Book

extends React.Component { )} -

{this.circulationLinks()}
+ {this.props.showCirculationLinks && ( +
{this.circulationLinks()}
+ )}
diff --git a/packages/web-opds-client/src/components/Collection.tsx b/packages/web-opds-client/src/components/Collection.tsx index a4417f2d..504231f7 100644 --- a/packages/web-opds-client/src/components/Collection.tsx +++ b/packages/web-opds-client/src/components/Collection.tsx @@ -12,6 +12,7 @@ export interface CollectionProps extends React.HTMLProps { isFetchingCollection?: boolean; isFetchingBook?: boolean; isFetchingPage?: boolean; + showCirculationLinks?: boolean; error?: FetchErrorData; fetchPage?: (url: string) => Promise; updateBook: (url: string) => Promise; @@ -111,6 +112,7 @@ export default class Collection extends React.Component { updateBook={this.props.updateBook} isSignedIn={this.props.isSignedIn} epubReaderUrlTemplate={this.props.epubReaderUrlTemplate} + showCirculationLinks={this.props.showCirculationLinks} /> ))} diff --git a/packages/web-opds-client/src/components/__tests__/Book-test.tsx b/packages/web-opds-client/src/components/__tests__/Book-test.tsx index a2320422..18eb7271 100644 --- a/packages/web-opds-client/src/components/__tests__/Book-test.tsx +++ b/packages/web-opds-client/src/components/__tests__/Book-test.tsx @@ -128,6 +128,7 @@ describe("Book", () => { book={book} updateBook={updateBook} epubReaderUrlTemplate={epubReaderUrlTemplate} + showCirculationLinks={true} /> ); }); @@ -227,104 +228,158 @@ describe("Book", () => { expect(moreLink.html()).to.contain("More"); }); - it("shows download button for open access urls", () => { - let buttons = wrapper.find(DownloadButton); - expect(buttons.length).to.equal(2); - let epubButton = buttons.at(0); - let mobiButton = buttons.at(1); - - expect(epubButton.props().link.url).to.equal("secrets.epub"); - expect(epubButton.props().link.type).to.equal("application/epub+zip"); - expect(epubButton.props().isPlainLink).to.equal(true); - - expect(mobiButton.props().link.url).to.equal("secrets.mobi"); - expect(mobiButton.props().link.type).to.equal( - "application/x-mobipocket-ebook" - ); - expect(mobiButton.props().isPlainLink).to.equal(true); - }); + context("when showCirculationLinks is true", () => { + it("shows download button for open access urls", () => { + let buttons = wrapper.find(DownloadButton); + expect(buttons.length).to.equal(2); + let epubButton = buttons.at(0); + let mobiButton = buttons.at(1); + + expect(epubButton.props().link.url).to.equal("secrets.epub"); + expect(epubButton.props().link.type).to.equal("application/epub+zip"); + expect(epubButton.props().isPlainLink).to.equal(true); + + expect(mobiButton.props().link.url).to.equal("secrets.mobi"); + expect(mobiButton.props().link.type).to.equal( + "application/x-mobipocket-ebook" + ); + expect(mobiButton.props().isPlainLink).to.equal(true); + }); - it("shows read button for open access epub urls", () => { - let buttons = wrapper.find(".read-button"); - expect(buttons.length).to.equal(1); - expect(buttons.props().href).to.equal("test reader url"); - }); + it("shows read button for open access epub urls", () => { + let buttons = wrapper.find(".read-button"); + expect(buttons.length).to.equal(1); + expect(buttons.props().href).to.equal("test reader url"); + }); - it("shows borrow/hold button", () => { - let bookCopy = Object.assign({}, book, { - borrowUrl: "borrow url" + it("shows borrow/hold button", () => { + let bookCopy = Object.assign({}, book, { + borrowUrl: "borrow url" + }); + let updateBook = stub(); + wrapper = shallow( + + ); + + let button = wrapper.find(BorrowButton); + expect(button.children().text()).to.equal("Borrow"); + button.props().borrow(); + expect(updateBook.callCount).to.equal(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); + expect(button.children().text()).to.equal("Reserve"); }); - let updateBook = stub(); - wrapper = shallow(); - let button = wrapper.find(BorrowButton); - expect(button.children().text()).to.equal("Borrow"); - button.props().borrow(); - expect(updateBook.callCount).to.equal(1); - expect(updateBook.args[0][0]).to.equal(bookCopy.borrowUrl); - wrapper.setProps({ - book: Object.assign({}, bookCopy, { - copies: { total: 2, available: 0 } - }) + it("shows fulfill button if there's no download button", () => { + let link = { + url: "fulfillment url", + type: "application/vnd.adobe.adept+xml" + }; + let bookCopy = Object.assign({}, book, { + openAccessLinks: [], + fulfillmentLinks: [link] + }); + wrapper = shallow( + + ); + let button = wrapper.find(DownloadButton); + expect(button.props().link.url).to.equal(link.url); + expect(button.props().title).to.equal(bookCopy.title); + expect(button.props().link.type).to.equal(link.type); + expect(button.props().isPlainLink).to.equal(true); }); - button = wrapper.find(BorrowButton); - expect(button.children().text()).to.equal("Reserve"); - }); - it("shows fulfill button if there's no download button", () => { - let link = { - url: "fulfillment url", - type: "application/vnd.adobe.adept+xml" - }; - let bookCopy = Object.assign({}, book, { - openAccessLinks: [], - fulfillmentLinks: [link] + it("shows 'borrowed'", () => { + let link = { + url: "fulfillment url", + type: "application/vnd.adobe.adept+xml" + }; + let bookCopy = Object.assign({}, book, { + openAccessLinks: [], + fulfillmentLinks: [link] + }); + wrapper = shallow( + + ); + let button = wrapper.find(BorrowButton); + expect(button.props().children).to.equal("Borrowed"); + expect(button.props().disabled).to.equal(true); }); - wrapper = shallow( - - ); - let button = wrapper.find(DownloadButton); - expect(button.props().link.url).to.equal(link.url); - expect(button.props().title).to.equal(bookCopy.title); - expect(button.props().link.type).to.equal(link.type); - expect(button.props().isPlainLink).to.equal(true); - }); - it("shows 'borrowed'", () => { - let link = { - url: "fulfillment url", - type: "application/vnd.adobe.adept+xml" - }; - let bookCopy = Object.assign({}, book, { - openAccessLinks: [], - fulfillmentLinks: [link] + it("shows 'reserved'", () => { + let bookCopy = Object.assign({}, book, { + openAccessLinks: [], + availability: { status: "reserved" } + }); + wrapper = shallow( + + ); + let button = wrapper.find("button"); + expect(button.text()).to.equal("Reserved"); + expect(button.props().className).to.contain("disabled"); }); - wrapper = shallow(); - let button = wrapper.find(BorrowButton); - expect(button.props().children).to.equal("Borrowed"); - expect(button.props().disabled).to.equal(true); - }); - it("shows 'reserved'", () => { - let bookCopy = Object.assign({}, book, { - openAccessLinks: [], - availability: { status: "reserved" } + it("shows 'borrow' when a reserved book becomes available", () => { + let bookCopy = Object.assign({}, book, { + openAccessLinks: [], + availability: { status: "ready" } + }); + wrapper = shallow( + + ); + let button = wrapper.find(BorrowButton); + expect(button.length).to.equal(1); + expect(button.html()).to.contain("Borrow"); }); - wrapper = shallow(); - let button = wrapper.find("button"); - expect(button.text()).to.equal("Reserved"); - expect(button.props().className).to.contain("disabled"); }); - it("shows 'borrow' when a reserved book becomes available", () => { - let bookCopy = Object.assign({}, book, { - openAccessLinks: [], - availability: { status: "ready" } + context("when showCirculationLinks is false", () => { + it("does not show borrow/hold button", () => { + const bookCopy = { + ...book, + borrowUrl: "borrow url" + }; + + const updateBook = stub(); + + wrapper = shallow( + + ); + + const button = wrapper.find(BorrowButton); + + expect(button.length).to.equal(0); }); - wrapper = shallow(); - let button = wrapper.find(BorrowButton); - expect(button.length).to.equal(1); - expect(button.html()).to.contain("Borrow"); }); }); }); diff --git a/packages/web-opds-client/src/components/__tests__/Collection-test.tsx b/packages/web-opds-client/src/components/__tests__/Collection-test.tsx index d0ba4df6..7b83d6bb 100644 --- a/packages/web-opds-client/src/components/__tests__/Collection-test.tsx +++ b/packages/web-opds-client/src/components/__tests__/Collection-test.tsx @@ -103,6 +103,7 @@ describe("Collection", () => { fulfillBook={fulfillBook} indirectFulfillBook={indirectFulfillBook} setPreference={setPreference} + showCirculationLinks={false} />, { context, @@ -131,6 +132,14 @@ describe("Collection", () => { expect(uniqueCollectionUrls).to.deep.equal([collectionData.url]); }); + it("passes showCirculationLinks prop to books", () => { + const books = wrapper.find(Book); + + books.forEach(book => + expect(book.props().showCirculationLinks).to.equal(false) + ); + }); + it("shows grid or list view", () => { let context = mockRouterContext(); wrapper = mount(