-- https://www.gutenberg.org/ebooks.opds/ local navigation_sample = [[ http://www.gutenberg.org/ebooks.opds/ 2021-04-02T13:27:36Z Project Gutenberg Free ebooks since 1971. Project Gutenberg https://www.gutenberg.org webmaster@gutenberg.org https://www.gutenberg.org/gutenberg/favicon.ico 25 1 2021-04-02T13:27:36Z https://www.gutenberg.org/ebooks/search.opds/?sort_order=downloads Popular Our most popular books. 2021-04-02T13:27:36Z https://www.gutenberg.org/ebooks/search.opds/?sort_order=release_date Latest Our latest releases. 2021-04-02T13:27:36Z https://www.gutenberg.org/ebooks/search.opds/?sort_order=random Random Random books. ]] -- https://www.gutenberg.org/ebooks/42474.opds local acquisition_sample = [[ http://www.gutenberg.org/ebooks/42474.opds 2021-04-02T13:29:52Z 1000 Mythological Characters Briefly Described by Edward Sylvester Ellis Free ebooks since 1971. Project Gutenberg https://www.gutenberg.org webmaster@gutenberg.org https://www.gutenberg.org/gutenberg/favicon.ico 25 1 2021-04-02T13:29:52Z 1000 Mythological Characters Briefly Described

This edition had all images removed.

LoC No.: 00001011

Title: 1000 Mythological Characters Briefly Described
Adapted to Private Schools, High Schools and Academies

Alternate Title: One Thousand Mythological Characters Briefly Described
Adapted to Private Schools, High Schools and Academies

Author: Ellis, Edward Sylvester, 1840-1916

Ebook No.: 42474

Published: 7 apr. 2013

Downloads: 401

Language: English

Subject: Mythology -- Dictionaries

LoCC: Philosophy, Psychology, Religion: Religion: General, Miscellaneous and Atheism

Category: Text

Rights: Public domain in the USA.

urn:gutenberg:42474:2 2013-04-07T00:00:00+00:00 Public domain in the USA. Ellis, Edward Sylvester en urn:lccn:00001011 1
2021-04-02T13:29:52Z 1000 Mythological Characters Briefly Described

This edition has images.

LoC No.: 00001011

Title: 1000 Mythological Characters Briefly Described
Adapted to Private Schools, High Schools and Academies

Alternate Title: One Thousand Mythological Characters Briefly Described
Adapted to Private Schools, High Schools and Academies

Author: Ellis, Edward Sylvester, 1840-1916

Ebook No.: 42474

Published: 7 apr. 2013

Downloads: 401

Language: Engels

Subject: Mythology -- Dictionaries

LoCC: Philosophy, Psychology, Religion: Religion: General, Miscellaneous and Atheism

Category: Text

Rights: Public domain in the USA.

urn:gutenberg:42474:3 2013-04-07T00:00:00+00:00 Public domain in the USA. Ellis, Edward Sylvester en urn:lccn:00001011 1
]] -- https://www.gutenberg.org/catalog/osd-books.xml local opensearch_sample = [[ Project Gutenberg Gutenberg Search the Project Gutenberg ebook catalog. free ebooks books public domain Marcello Perathoner webmaster@gutenberg.org Search Data Copyright 1971-2012, Project Gutenberg, All Rights Reserved. open en-us UTF-8 UTF-8 ]] local popular_new_sample = [[ https://catalog.feedbooks.com/catalog/public_domain.atom Public Domain Books 2014-11-30T17:54:01Z https://catalog.feedbooks.com/favicon.ico Feedbooks http://www.feedbooks.com help@demarque.com Most popular 2024-07-19T16:19:38Z https://catalog.feedbooks.com/publicdomain/browse/top.atom?lang=en Based on last week's downloads Recently added 2024-07-19T16:19:38Z https://catalog.feedbooks.com/publicdomain/browse/recent.atom?lang=en Find the latest books available Fiction 2024-07-19T16:19:38Z https://catalog.feedbooks.com/publicdomain/category/FBFIC000000/sub.atom Browse books by category Nonfiction 2024-07-19T16:19:38Z https://catalog.feedbooks.com/publicdomain/category/FBNFC000000/sub.atom Browse books by category ]] local facet_sample = [[ tag:root:authors:Санд Книги по авторам 2014-11-30T17:27:27+01:00 /favicon.ico 2014-11-30T17:27:27+01:00 tag:author:75357 Санд Жаклин 6 книг ]] local pdf_query_sample = [[ tag:root:pdfquery PDF Query Test 2025-09-11T00:00:00Z Sample PDF With Query urn:pdf:with:query 2025-09-11T00:00:00Z A PDF that already has .pdf before a query parameter. ]] describe("OPDS module", function() local socketutil local OPDSParser, OPDSBrowser local orig_path, orig_lbt, orig_ltt, orig_fbt, orig_ftt setup(function() orig_path = package.path package.path = "plugins/opds.koplugin/?.lua;" .. package.path require("commonrequire") socketutil = require("socketutil") OPDSParser = require("opdsparser") OPDSBrowser = require("opdsbrowser") -- Make the timeouts more lenient to avoid spurious test failures orig_lbt = socketutil.LARGE_BLOCK_TIMEOUT socketutil.LARGE_BLOCK_TIMEOUT = socketutil.DEFAULT_BLOCK_TIMEOUT orig_ltt = socketutil.LARGE_TOTAL_TIMEOUT socketutil.LARGE_TOTAL_TIMEOUT = socketutil.DEFAULT_TOTAL_TIMEOUT orig_fbt = socketutil.FILE_BLOCK_TIMEOUT socketutil.FILE_BLOCK_TIMEOUT = socketutil.DEFAULT_BLOCK_TIMEOUT orig_ftt = socketutil.FILE_TOTAL_TIMEOUT socketutil.FILE_TOTAL_TIMEOUT = socketutil.DEFAULT_TOTAL_TIMEOUT end) teardown(function() package.path = orig_path socketutil.LARGE_BLOCK_TIMEOUT = orig_lbt socketutil.LARGE_TOTAL_TIMEOUT = orig_ltt socketutil.FILE_BLOCK_TIMEOUT = orig_fbt socketutil.FILE_TOTAL_TIMEOUT = orig_ftt end) describe("OPDS parser module", function() it("should parse OPDS navigation catalog", function() local catalog = OPDSParser:parse(navigation_sample) local feed = catalog.feed assert.truthy(feed) assert.are.same(feed.title, "Project Gutenberg") local entries = feed.entry assert.truthy(entries) assert.are.same(#entries, 3) local entry = entries[3] assert.are.same(entry.title, "Random") assert.are.same(entry.id, "https://www.gutenberg.org/ebooks/search.opds/?sort_order=random") assert.are.same( "/ebooks/search.opds/?sort_order=random", entry.link[1].href) end) it("should parse OPDS acquisition catalog", function() local catalog = OPDSParser:parse(acquisition_sample) local feed = catalog.feed assert.truthy(feed) local entries = feed.entry assert.truthy(entries) assert.are.same(#entries, 2) local entry = entries[2] assert.are.same(entry.title, "1000 Mythological Characters Briefly Described") assert.are.same(entry.link[1].href, "https://www.gutenberg.org/ebooks/42474.epub.images") assert.are.same(entry.link[1].title, "EPUB (with images)") end) end) describe("OPDS browser module", function() before_each(function() local Cache = require("cache") stub(Cache, "check", function() return nil end) end) after_each(function() local Cache = require("cache") if Cache.check.revert then Cache.check:revert() end end) describe("URL generation", function() it("should generate search url and catalog items #internet", function() local fetch_feed_stub = stub(OPDSBrowser, "getSearchTemplate", function(self, osd_url) local search_descriptor = OPDSParser:parse(opensearch_sample) if search_descriptor and search_descriptor.OpenSearchDescription and search_descriptor.OpenSearchDescription.Url then for _, candidate in ipairs(search_descriptor.OpenSearchDescription.Url) do if candidate.type and candidate.template and candidate.type:find(self.search_template_type) then return candidate.template:gsub("{searchTerms}", "%%s") end end end return nil end) local main_catalog = OPDSParser:parse(navigation_sample) local item_table = OPDSBrowser:genItemTableFromCatalog(main_catalog, "https://www.gutenberg.org/ebooks.opds/?format=opds") assert.truthy(OPDSBrowser.search_url) assert.are.same("http://m.gutenberg.org/ebooks/search.opds/?query=%s", OPDSBrowser.search_url) assert.truthy(item_table) assert.are.same(3, #item_table) assert.are.same("Popular", item_table[1].title) assert.are.same("Latest", item_table[2].title) assert.are.same("Random", item_table[3].title) fetch_feed_stub:revert() end) it("should generate URL on rel=subsection #internet", function() local catalog = OPDSParser:parse(navigation_sample) local item_table = OPDSBrowser:genItemTableFromCatalog(catalog, "https://www.gutenberg.org/ebooks.opds/?format=opds") assert.truthy(item_table) assert.are.same(item_table[1].title, "Popular") assert.are.same(item_table[1].url, "https://www.gutenberg.org/ebooks/search.opds/?sort_order=downloads") end) it("should generate URL on rel=popular and rel=new #internet", function() local catalog = OPDSParser:parse(popular_new_sample) local item_table = OPDSBrowser:genItemTableFromCatalog(catalog, "http://www.feedbooks.com/publicdomain/catalog.atom") assert.truthy(item_table) assert.are.same(item_table[1].title, "Most popular") assert.are.same(item_table[1].url, "https://catalog.feedbooks.com/publicdomain/browse/top.atom?lang=en") assert.are.same(item_table[2].title, "Recently added") assert.are.same(item_table[2].url, "https://catalog.feedbooks.com/publicdomain/browse/recent.atom?lang=en") end) it("should use the main URL for faceted links as long as faceted links aren't properly supported #internet", function() local catalog = OPDSParser:parse(facet_sample) local item_table = OPDSBrowser:genItemTableFromCatalog(catalog, "http://flibusta.is/opds") assert.truthy(item_table) assert.are.same(item_table[1].url, "http://flibusta.is/opds/author/75357") end) end) it("should not fill item table incorrectly with thumbnail or image URL #internet", function() local catalog = OPDSParser:parse(facet_sample) local item_table = OPDSBrowser:genItemTableFromCatalog(catalog, "http://flibusta.is/opds") assert.truthy(item_table) assert.are_not.same(item_table[1].image, "http://flibusta.is/opds/author/75357") end) it("should not append .pdf after query parameters or duplicate acquisition entries #14300 #internet", function() local catalog = OPDSParser:parse(pdf_query_sample) local item_table = OPDSBrowser:genItemTableFromCatalog(catalog, "http://example.org/opds") assert.truthy(item_table) assert.are.same(1, #item_table) local acquisitions = item_table[1].acquisitions assert.truthy(acquisitions) -- Only one acquisition entry should be present (generic provider entry). assert.are.same(1, #acquisitions) local href = acquisitions[1].href assert.truthy(href) -- It must contain the original query parameter unchanged. assert(href:match("file%.pdf%?opds$")) -- And must NOT have an extra .pdf appended after the query string. assert(not href:match("opds%.pdf$")) end) end) end)