/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include #include #include class HtmlExportTest : public SwModelTestBase, public HtmlTestTools { private: FieldUnit m_eUnit; public: HtmlExportTest() : SwModelTestBase("/sw/qa/extras/htmlexport/data/", "HTML (StarWriter)"), m_eUnit(FUNIT_NONE) {} private: bool mustCalcLayoutOf(const char* filename) override { return OString(filename) != "fdo62336.docx"; } bool mustTestImportOf(const char* filename) const override { return OString(filename) != "fdo62336.docx"; } void preTest(const char* filename) override { if (getTestName().indexOf("SkipImage") != -1) setFilterOptions("SkipImages"); else setFilterOptions(""); if (OString(filename) == "charborder.odt") { // FIXME if padding-top gets exported as inches, not cms, we get rounding errors. SwGlobals::ensure(); // make sure that SW_MOD() is not 0 SwMasterUsrPref* pPref = const_cast(SW_MOD()->GetUsrPref(false)); m_eUnit = pPref->GetMetric(); pPref->SetMetric(FUNIT_CM); } } void postTest(const char* filename) override { if (OString(filename) == "charborder.odt") { SwMasterUsrPref* pPref = const_cast(SW_MOD()->GetUsrPref(false)); pPref->SetMetric(m_eUnit); } } }; #define DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, HtmlExportTest) DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testFdo81276, "fdo81276.html") { uno::Reference xPageStyles(getStyles("PageStyles")); uno::Reference xStyle(xPageStyles->getByName("HTML"), uno::UNO_QUERY); // some rounding going on here? CPPUNIT_ASSERT(abs(sal_Int32(29700) - getProperty(xStyle, "Width")) < 10); CPPUNIT_ASSERT(abs(sal_Int32(21006) - getProperty(xStyle, "Height")) < 10); CPPUNIT_ASSERT(abs(sal_Int32(500) - getProperty(xStyle, "LeftMargin")) < 10); CPPUNIT_ASSERT(abs(sal_Int32(500) - getProperty(xStyle, "RightMargin")) < 10); CPPUNIT_ASSERT(abs(sal_Int32(2000) - getProperty(xStyle, "TopMargin")) < 10); CPPUNIT_ASSERT(abs(sal_Int32(500) - getProperty(xStyle, "BottomMargin")) < 10); } DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testFdo62336, "fdo62336.docx") { // The problem was essentially a crash during table export as docx/rtf/html // If either of no-calc-layout or no-test-import is enabled, the crash does not occur } DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testFdo86857, "fdo86857.html") { // problem was that background color on page style was not exported uno::Reference xPageStyles(getStyles("PageStyles")); uno::Reference xStyle(xPageStyles->getByName("HTML"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(0xff0000), getProperty(xStyle, "BackColor")); // check that table background color works, which still uses RES_BACKGROUND uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount()); uno::Reference xTable(xTables->getByIndex(0), uno::UNO_QUERY); uno::Reference xCell(xTable->getCellByName("A1"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(0x66ffff), getProperty(xCell, "BackColor")); } DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testCharacterBorder, "charborder.odt") { uno::Reference xRun(getRun(getParagraph(1),1), uno::UNO_QUERY); // Different Border { CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0x6666FF,12,12,12,3,37), getProperty(xRun,"CharTopBorder")); CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0xFF9900,0,99,0,2,99), getProperty(xRun,"CharLeftBorder")); CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0xFF0000,0,169,0,1,169), getProperty(xRun,"CharBottomBorder")); CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0x0000FF,0,169,0,0,169), getProperty(xRun,"CharRightBorder")); } // Different Padding { CPPUNIT_ASSERT_EQUAL(sal_Int32(450), getProperty(xRun,"CharTopBorderDistance")); CPPUNIT_ASSERT_EQUAL(sal_Int32(550), getProperty(xRun,"CharLeftBorderDistance")); CPPUNIT_ASSERT_EQUAL(sal_Int32(150), getProperty(xRun,"CharBottomBorderDistance")); CPPUNIT_ASSERT_EQUAL(sal_Int32(250), getProperty(xRun,"CharRightBorderDistance")); } // No shadow } #define DECLARE_HTMLEXPORT_TEST(TestName, filename) DECLARE_SW_EXPORT_TEST(TestName, filename, HtmlExportTest) DECLARE_HTMLEXPORT_TEST(testExportOfImages, "textAndImage.docx") { htmlDocPtr pDoc = parseHtml(maTempFile); CPPUNIT_ASSERT(pDoc); assertXPath(pDoc, "/html/body", 1); assertXPath(pDoc, "/html/body/p/img", 1); } DECLARE_HTMLEXPORT_TEST(testExportOfImagesWithSkipImageEnabled, "textAndImage.docx") { htmlDocPtr pDoc = parseHtml(maTempFile); CPPUNIT_ASSERT(pDoc); assertXPath(pDoc, "/html/body", 1); assertXPath(pDoc, "/html/body/p/img", 0); } DECLARE_HTMLEXPORT_TEST(testSkipImageEmbedded, "skipimage-embedded.doc") { // Embedded spreadsheet was exported as image, so content was lost. Make // sure it's exported as HTML instead. htmlDocPtr pDoc = parseHtml(maTempFile); CPPUNIT_ASSERT(pDoc); // This was 0. assertXPath(pDoc, "//table", 1); // This was 2, the HTML header was in the document two times. assertXPath(pDoc, "//meta[@name='generator']", 1); // This was 0, was directly under

, which caused errors in the parser. assertXPath(pDoc, "//span/table", 1); } DECLARE_HTMLEXPORT_TEST(testSkipImageEmbeddedDocument, "skipimage-embedded-document.docx") { // Similar to testSkipImageEmbedded, but with an embedded Writer object, // not a Calc one, and this time OOXML, not WW8. htmlDocPtr pDoc = parseHtml(maTempFile); CPPUNIT_ASSERT(pDoc); // This was 2, the HTML header was in the document two times. assertXPath(pDoc, "//meta[@name='generator']", 1); // Text of embedded document was missing. assertXPathContent(pDoc, "/html/body/p/span/p/span", "Inner."); } DECLARE_HTMLEXPORT_TEST(testExportImageProperties, "HTMLImage.odt") { htmlDocPtr pDoc = parseHtml(maTempFile); CPPUNIT_ASSERT(pDoc); assertXPath(pDoc, "/html/body", 1); assertXPath(pDoc, "/html/body/p/map/area", "shape", "poly"); assertXPath(pDoc, "/html/body/p/map/area", "href", "http://www.microsoft.com/"); assertXPath(pDoc, "/html/body/p/map/area", "target", "_self"); assertXPath(pDoc, "/html/body/p/map/area", "alt", "microsoft"); assertXPath(pDoc, "/html/body/p/a", 1); assertXPath(pDoc, "/html/body/p/a", "href", "http://www.google.com/"); assertXPath(pDoc, "/html/body/p/a/font", 1); assertXPath(pDoc, "/html/body/p/a/font", "color", "#ff0000"); assertXPath(pDoc, "/html/body/p/a/font/img", 1); assertXPath(pDoc, "/html/body/p/a/font/img", "name", "Text"); assertXPath(pDoc, "/html/body/p/a/font/img", "alt", "Four colors"); assertXPath(pDoc, "/html/body/p/a/font/img", "align", "middle"); // Probably the DPI in OSX is different and Twip -> Pixel conversion produces // different results - so disable OSX for now. // // It would make sense to switch to use CSS and use "real world" units instead // i.e. (style="margin: 0cm 1.5cm; width: 1cm; height: 1cm") #if 0 // disabled as it depends that the system DPI is set to 96 assertXPath(pDoc, "/html/body/p/a/font/img", "hspace", "38"); assertXPath(pDoc, "/html/body/p/a/font/img", "vspace", "19"); assertXPath(pDoc, "/html/body/p/a/font/img", "width", "222"); assertXPath(pDoc, "/html/body/p/a/font/img", "height", "222"); assertXPath(pDoc, "/html/body/p/a/font/img", "border", "3"); #endif assertXPath(pDoc, "/html/body/p/a/font/img", "usemap", "#map1"); } DECLARE_HTMLEXPORT_TEST(testExportCheckboxRadioButtonState, "checkbox-radiobutton.doc") { htmlDocPtr pDoc = parseHtml(maTempFile); CPPUNIT_ASSERT(pDoc); assertXPath(pDoc, "/html/body", 1); assertXPath(pDoc, "/html/body/p[1]/input", "type", "checkbox"); assertXPath(pDoc, "/html/body/p[1]/input", "checked", "checked"); assertXPath(pDoc, "/html/body/p[2]/input", "type", "checkbox"); assertXPathNoAttribute(pDoc, "/html/body/p[2]/input", "checked"); assertXPath(pDoc, "/html/body/form/p[1]/input", "type", "checkbox"); assertXPath(pDoc, "/html/body/form/p[1]/input", "checked", "checked"); assertXPath(pDoc, "/html/body/form/p[2]/input", "type", "checkbox"); assertXPathNoAttribute(pDoc, "/html/body/form/p[2]/input", "checked"); assertXPath(pDoc, "/html/body/form/p[3]/input", "type", "radio"); assertXPath(pDoc, "/html/body/form/p[3]/input", "checked", "checked"); assertXPath(pDoc, "/html/body/form/p[4]/input", "type", "radio"); assertXPathNoAttribute(pDoc, "/html/body/form/p[4]/input", "checked"); } DECLARE_HTMLEXPORT_TEST(testExportUrlEncoding, "tdf76291.odt") { htmlDocPtr pDoc = parseHtml(maTempFile); CPPUNIT_ASSERT(pDoc); // Test URI encoded hyperlink with Chinese characters assertXPath(pDoc, "/html/body/p/a", "href", "http://www.youtube.com/results?search_query=%E7%B2%B5%E8%AA%9Emv&sm=12"); } DECLARE_HTMLEXPORT_TEST(testExportInternalUrl, "tdf90905.odt") { htmlDocPtr pDoc = parseHtml(maTempFile); CPPUNIT_ASSERT(pDoc); // Internal url should be valid assertXPath(pDoc, "/html/body/p[1]/a", "href", "#0.0.1.Text|outline"); assertXPath(pDoc, "/html/body/p[2]/a", "href", "#bookmark"); } DECLARE_HTMLEXPORT_TEST(testExportImageBulletList, "tdf66822.odt") { htmlDocPtr pDoc = parseHtml(maTempFile); CPPUNIT_ASSERT(pDoc); // Encoded base64 SVG bullet should match and render on browser assertXPath(pDoc, "/html/body/ul", 1); assertXPath(pDoc, "/html/body/ul", "style", "list-style-image: url(data:image/svg+xml;base64,cnNpb249IjEuMCIgZW5jb2Rpbmc9InV0Zi04Ij8+DQo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTIuMC4xLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCA1MTQ0OCkgIC0tPg0KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIiBbDQoJPCFFTlRJVFkgbnNfc3ZnICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+DQoJPCFFTlRJVFkgbnNfeGxpbmsgImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KXT4NCjxzdmcgIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSImbnNfc3ZnOyIgeG1sbnM6eGxpbms9IiZuc194bGluazsiIHdpZHRoPSIxNC4wMDgiIGhlaWdodD0iMTQuMDEiDQoJIHZpZXdCb3g9IjAgMCAxNC4wMDggMTQuMDEiIG92ZXJmbG93PSJ2aXNpYmxlIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxNC4wMDggMTQuMDEiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPGc+DQoJPHJhZGlhbEdyYWRpZW50IGlkPSJYTUxJRF80XyIgY3g9IjcuMDA0NCIgY3k9IjcuMDA0OSIgcj0iNy4wMDQ0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+DQoJCTxzdG9wICBvZmZzZXQ9IjAiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNURCMzUiLz4NCgkJPHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzAwQTAwMCIvPg0KCTwvcmFkaWFsR3JhZGllbnQ+DQoJPGNpcmNsZSBmaWxsPSJ1cmwoI1hNTElEXzRfKSIgY3g9IjcuMDA0IiBjeT0iNy4wMDUiIHI9IjcuMDA0Ii8+DQoJPGRlZnM+DQoJCTxmaWx0ZXIgaWQ9IkFkb2JlX09wYWNpdHlNYXNrRmlsdGVyIiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIHg9IjMuNDgxIiB5PSIwLjY5MyIgd2lkdGg9IjYuOTg4IiBoZWlnaHQ9IjMuODkzIj4NCgkJCTxmZUNvbG9yTWF0cml4ICB0eXBlPSJtYXRyaXgiIHZhbHVlcz0iMSAwIDAgMCAwICAwIDEgMCAwIDAgIDAgMCAxIDAgMCAgMCAwIDAgMSAwIi8+DQoJCTwvZmlsdGVyPg0KCTwvZGVmcz4NCgk8bWFzayBtYXNrVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4PSIzLjQ4MSIgeT0iMC42OTMiIHdpZHRoPSI2Ljk4OCIgaGVpZ2h0PSIzLjg5MyIgaWQ9IlhNTElEXzVfIj4NCgkJPGcgZmlsdGVyPSJ1cmwoI0Fkb2JlX09wYWNpdHlNYXNrRmlsdGVyKSI+DQoJCQk8bGluZWFyR3JhZGllbnQgaWQ9IlhNTElEXzZfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjcuMTIyMSIgeTE9IjAuMTAzIiB4Mj0iNy4xMjIxIiB5Mj0iNS4yMzQ0Ij4NCgkJCQk8c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojRkZGRkZGIi8+DQoJCQkJPHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzAwMDAwMCIvPg0KCQkJPC9saW5lYXJHcmFkaWVudD4NCgkJCTxyZWN0IHg9IjMuMTk5IiB5PSIwLjMzOSIgb3BhY2l0eT0iMC43IiBmaWxsPSJ1cmwoI1hNTElEXzZfKSIgd2lkdGg9IjcuODQ2IiBoZWlnaHQ9IjQuNjAxIi8+DQoJCTwvZz4NCgk8L21hc2s+DQoJPGVsbGlwc2UgbWFzaz0idXJsKCNYTUxJRF81XykiIGZpbGw9IiNGRkZGRkYiIGN4PSI2Ljk3NSIgY3k9IjIuNjQiIHJ4PSIzLjQ5NCIgcnk9IjEuOTQ2Ii8+DQo8L2c+DQo8L3N2Zz4NPC9zdmc+Cg==);"); } DECLARE_HTMLEXPORT_TEST(testTdf83890, "tdf83890.odt") { htmlDocPtr pDoc = parseHtml(maTempFile); CPPUNIT_ASSERT(pDoc); assertXPath(pDoc, "/html/body/ol[2]/ol", "start", "2"); } CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */