github.com/readium/readium-lcp-server@v0.0.0-20240101192032-6e95190e99f1/epub/writer_test.go (about) 1 // Copyright (c) 2016 Readium Foundation 2 // 3 // Redistribution and use in source and binary forms, with or without modification, 4 // are permitted provided that the following conditions are met: 5 // 6 // 1. Redistributions of source code must retain the above copyright notice, this 7 // list of conditions and the following disclaimer. 8 // 2. Redistributions in binary form must reproduce the above copyright notice, 9 // this list of conditions and the following disclaimer in the documentation and/or 10 // other materials provided with the distribution. 11 // 3. Neither the name of the organization nor the names of its contributors may be 12 // used to endorse or promote products derived from this software without specific 13 // prior written permission 14 // 15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 26 package epub 27 28 import ( 29 "archive/zip" 30 "bytes" 31 "fmt" 32 "io/ioutil" 33 "strings" 34 "testing" 35 ) 36 37 const containerSpec = `<?xml version="1.0" encoding="UTF-8"?><container xmlns="urn:oasis:names:tc:opendocument:xmlns:container" version="1.0"> 38 <rootfiles> 39 <rootfile full-path="EPUB/package.opf" media-type="application/oebps-package+xml"/> 40 </rootfiles> 41 </container>` 42 43 const basicOpf = ` 44 <?xml version="1.0" encoding="UTF-8"?> 45 <package xmlns="http://www.idpf.org/2007/opf" prefix="rendition: http://www.idpf.org/vocab/rendition/# cc: http://creativecommons.org/ns#" version="3.0" unique-identifier="bookid" xml:lang="fr" dir="ltr" id="package"> 46 <metadata xmlns:dc="http://purl.org/dc/elements/1.1/"> 47 <dc:identifier id="bookid">test-basic-epub</dc:identifier> 48 <dc:language>fr</dc:language> 49 </metadata> 50 <manifest> 51 <item id="page" href="page.xhtml" media-type="application/xhtml+xml"/> 52 </manifest> 53 <spine> 54 <itemref idref="page"/> 55 </spine> 56 </package>` 57 58 const basicPage = ` 59 <?xml version="1.0" encoding="UTF-8"?> 60 <!DOCTYPE html> 61 <html> 62 <body>Hello</body> 63 </htmL>` 64 65 func createBasicEpub() Epub { 66 var ep Epub 67 ep.Add(ContainerFile, strings.NewReader(containerSpec), uint64(len(containerSpec))) 68 69 ep.Add("EPUB/package.opf", strings.NewReader(basicOpf), uint64(len(basicOpf))) 70 71 ep.Add("EPUB/page.xhtml", strings.NewReader(basicPage), uint64(len(basicPage))) 72 73 return ep 74 } 75 76 func TestWriteBasicEpub(t *testing.T) { 77 ep := createBasicEpub() 78 79 // Mark the page as already-compressed 80 ep.Resource[len(ep.Resource)-1].Compressed = true 81 82 var buf bytes.Buffer 83 ep.Write(&buf) 84 85 r := bytes.NewReader(buf.Bytes()) 86 zr, err := zip.NewReader(r, int64(buf.Len())) 87 88 if err != nil { 89 t.Fatal("Could not read zip", err) 90 } 91 92 out, err := Read(zr) 93 if err != nil { 94 t.Fatal("Could not construct epub from zip", err) 95 } 96 97 if l := len(out.Resource); l != 3 { 98 t.Fatalf("Expected 3 resources, got %d", l) 99 } 100 101 for i, r := range ep.Resource { 102 if equiv := out.Resource[i]; r.Path != equiv.Path { 103 t.Errorf("Expected %s, got %s", r.Path, equiv.Path) 104 } 105 } 106 107 testContentsOfFileInZip(t, zr, zip.Store, "mimetype", ContentType_EPUB) 108 testContentsOfFileInZip(t, zr, zip.Deflate, ContainerFile, containerSpec) 109 testContentsOfFileInZip(t, zr, zip.Deflate, "EPUB/package.opf", basicOpf) 110 testContentsOfFileInZip(t, zr, zip.Deflate, "EPUB/page.xhtml", basicPage) 111 } 112 113 func testContentsOfFileInZip(t *testing.T, zr *zip.Reader, m uint16, path, expected string) { 114 for _, f := range zr.File { 115 fmt.Println(f.Name) 116 } 117 118 if f, err := findFileInZip(zr, path); err != nil { 119 t.Fatalf("Could not find %s in file", path) 120 } else { 121 if meth := f.FileHeader.Method; meth != m { 122 t.Errorf("Expected %s to have method %d, got %d", path, m, meth) 123 } 124 125 r, err := f.Open() 126 if err != nil { 127 t.Fatalf("Could not open %s", path) 128 } 129 defer r.Close() 130 131 if bb, err := ioutil.ReadAll(r); err != nil { 132 t.Fatalf("Could not read %s", path) 133 } else { 134 if string(bb) != expected { 135 t.Errorf("Expected %s to contain %s, got %s", path, expected, string(bb)) 136 } 137 } 138 } 139 }