summaryrefslogtreecommitdiffstats
path: root/sw/qa/filter/html/html.cxx
blob: 4923cd6054683e4a966f9f5ff667a6e6a2ace1af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/* -*- 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 <swmodeltestbase.hxx>
#include <test/htmltesttools.hxx>

#include <vcl/gdimtf.hxx>

#include <docsh.hxx>
#include <fmtfsize.hxx>
#include <frameformats.hxx>
#include <unotxdoc.hxx>
#include <itabenum.hxx>
#include <wrtsh.hxx>
#include <cellatr.hxx>

namespace
{
/**
 * Covers sw/source/filter/html/ fixes.
 *
 * Note that these tests are meant to be simple: either load a file and assert some result or build
 * a document model with code, export and assert that result.
 *
 * Keep using the various sw_<format>import/export suites for multiple filter calls inside a single
 * test.
 */
class Test : public SwModelTestBase, public HtmlTestTools
{
public:
    Test()
        : SwModelTestBase("/sw/qa/filter/html/data/", "HTML (StarWriter)")
    {
    }
};

CPPUNIT_TEST_FIXTURE(Test, testEmptyParagraph)
{
    // Given a document with 2 paragraphs, the second is empty:
    setImportFilterOptions("xhtmlns=reqif-xhtml");
    setImportFilterName("HTML (StarWriter)");
    createSwDoc("empty-paragraph.xhtml");

    // Then make sure that the resulting document has a 2nd empty paragraph:
    getParagraph(1, "a");
    // Without the accompanying fix in place, this test would have failed with:
    // An uncaught exception of type com.sun.star.container.NoSuchElementException
    // i.e. the 2nd paragraph was lost.
    getParagraph(2);
}

CPPUNIT_TEST_FIXTURE(Test, testRelativeKeepAspect)
{
    // Given a document with an OLE object, width set to 100%, height is not set:
    setImportFilterOptions("xhtmlns=reqif-xhtml");
    setImportFilterName("HTML (StarWriter)");
    createSwDoc("relative-keep-aspect.xhtml");

    // Then make sure that the aspect ratio of the image is kept:
    auto pTextDocument = dynamic_cast<SwXTextDocument*>(mxComponent.get());
    SwDoc* pDoc = pTextDocument->GetDocShell()->GetDoc();
    const auto& rFormats = *pDoc->GetSpzFrameFormats();
    const auto pFormat = rFormats[0];
    const SwFormatFrameSize& rSize = pFormat->GetFrameSize();
    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 255
    // - Actual  : 0
    // i.e. the height had a fixed value, not "keep aspect".
    CPPUNIT_ASSERT_EQUAL(static_cast<int>(SwFormatFrameSize::SYNCED),
                         static_cast<int>(rSize.GetHeightPercent()));
}

CPPUNIT_TEST_FIXTURE(Test, testRelativeKeepAspectImage)
{
    // Given a document with an image, width set to 100%, height is not set:
    setImportFilterOptions("xhtmlns=reqif-xhtml");
    setImportFilterName("HTML (StarWriter)");
    createSwDoc("relative-keep-aspect-image.xhtml");

    // Then make sure that the aspect ratio of the image is kept:
    auto pTextDocument = dynamic_cast<SwXTextDocument*>(mxComponent.get());
    SwDoc* pDoc = pTextDocument->GetDocShell()->GetDoc();
    const auto& rFormats = *pDoc->GetSpzFrameFormats();
    const auto pFormat = rFormats[0];
    const SwFormatFrameSize& rSize = pFormat->GetFrameSize();
    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 255
    // - Actual  : 0
    // i.e. the height had a fixed value, not "keep aspect".
    CPPUNIT_ASSERT_EQUAL(static_cast<int>(SwFormatFrameSize::SYNCED),
                         static_cast<int>(rSize.GetHeightPercent()));
}

CPPUNIT_TEST_FIXTURE(Test, testSvmImageExport)
{
    // Given a document with an image, which has an SVM image data:
    createSwDoc();
    uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
    uno::Reference<beans::XPropertySet> xTextGraphic(
        xFactory->createInstance("com.sun.star.text.TextGraphicObject"), uno::UNO_QUERY);
    xTextGraphic->setPropertyValue("AnchorType",
                                   uno::Any(text::TextContentAnchorType_AS_CHARACTER));
    GDIMetaFile aMetafile;
    Graphic aGraphic(aMetafile);
    xTextGraphic->setPropertyValue("Graphic", uno::Any(aGraphic.GetXGraphic()));
    uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
    uno::Reference<text::XText> xBodyText = xTextDocument->getText();
    uno::Reference<text::XTextCursor> xCursor(xBodyText->createTextCursor());
    uno::Reference<text::XTextContent> xTextContent(xTextGraphic, uno::UNO_QUERY);
    xBodyText->insertTextContent(xCursor, xTextContent, false);

    // When exporting to reqif:
    setFilterOptions("xhtmlns=reqif-xhtml");
    save("HTML (StarWriter)");

    // Then make sure we only export PNG:
    xmlDocUniquePtr pXmlDoc = WrapReqifFromTempFile();
    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 1
    // - Actual  : 2
    // - XPath '//reqif-xhtml:object' number of nodes is incorrect
    // i.e. we wrote both GIF and PNG, not just PNG for SVM images.
    assertXPath(pXmlDoc, "//reqif-xhtml:object"_ostr, "type"_ostr, "image/png");
}

CPPUNIT_TEST_FIXTURE(Test, testTableCellFloatValueType)
{
    // Given a document with a single table cell, its cell value is set to double:
    createSwDoc();
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
    SwInsertTableOptions aTableOptions(SwInsertTableFlags::DefaultBorder, 0);
    pWrtShell->InsertTable(aTableOptions, 1, 1);
    pWrtShell->MoveTable(GotoPrevTable, fnTableStart);
    SwTableNode* pTableNode = pWrtShell->GetCursor()->GetPointNode().FindTableNode();
    SwTable& rTable = pTableNode->GetTable();
    auto pBox = const_cast<SwTableBox*>(rTable.GetTableBox("A1"));
    SwFrameFormat* pBoxFormat = pBox->ClaimFrameFormat();
    SwAttrSet aSet(pBoxFormat->GetAttrSet());
    SwTableBoxValue aBoxValue(42.0);
    aSet.Put(aBoxValue);
    pBoxFormat->GetDoc()->SetAttr(aSet, *pBoxFormat);

    // When exporting to XHTML:
    setFilterOptions("xhtmlns=reqif-xhtml");
    save("HTML (StarWriter)");

    // Then make sure that the sdval attribute is omitted, which is not in the XHTML spec:
    xmlDocUniquePtr pXmlDoc = WrapReqifFromTempFile();
    // Without the accompanying fix in place, this test would have failed with:
    // - XPath '//reqif-xhtml:td' unexpected 'sdval' attribute
    // i.e. sdval was written in XHTML mode.
    assertXPathNoAttribute(pXmlDoc, "//reqif-xhtml:td"_ostr, "sdval"_ostr);
    assertXPathNoAttribute(pXmlDoc, "//reqif-xhtml:td"_ostr, "sdnum"_ostr);
}

CPPUNIT_TEST_FIXTURE(Test, testTableRowSpanInAllCells)
{
    // Given a document with a 2x2 table, A1:A2 and B1:B2 is merged:
    createSwDoc();
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
    SwInsertTableOptions aTableOptions(SwInsertTableFlags::DefaultBorder, 0);
    pWrtShell->InsertTable(aTableOptions, /*nRows=*/2, /*nCols=*/2);
    pWrtShell->MoveTable(GotoPrevTable, fnTableStart);
    SwTableNode* pTableNode = pWrtShell->GetCursor()->GetPointNode().FindTableNode();
    SwTable& rTable = pTableNode->GetTable();
    auto pBox = const_cast<SwTableBox*>(rTable.GetTableBox("A1"));
    pBox->setRowSpan(2);
    pBox = const_cast<SwTableBox*>(rTable.GetTableBox("B1"));
    pBox->setRowSpan(2);
    pBox = const_cast<SwTableBox*>(rTable.GetTableBox("A2"));
    pBox->setRowSpan(-1);
    pBox = const_cast<SwTableBox*>(rTable.GetTableBox("B2"));
    pBox->setRowSpan(-1);

    // When exporting to HTML:
    save("HTML (StarWriter)");

    // Then make sure that the output is simplified to valid HTML, by omitting the rowspan attribute
    // & the empty <tr> element:
    htmlDocUniquePtr pHtmlDoc = parseHtml(maTempFile);
    // Without the accompanying fix in place, this test would have failed with:
    // - XPath '//tr[1]/td[1]' unexpected 'rowspan' attribute
    // i.e. a combination of rowspan + empty <tr> was emitted.
    assertXPathNoAttribute(pHtmlDoc, "//tr[1]/td[1]"_ostr, "rowspan"_ostr);
    assertXPath(pHtmlDoc, "//tr"_ostr, 1);
}

CPPUNIT_TEST_FIXTURE(Test, testCenteredTableCSSExport)
{
    // Given a document with a centered table:
    createSwDoc();
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
    SwInsertTableOptions aTableOptions(SwInsertTableFlags::NONE, 0);
    pWrtShell->InsertTable(aTableOptions, 1, 1);
    pWrtShell->MoveTable(GotoPrevTable, fnTableStart);
    SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END - 1> aSet(pWrtShell->GetAttrPool());
    SwFormatHoriOrient aHoriOrientItem(/*nX=*/0, text::HoriOrientation::CENTER);
    aSet.Put(aHoriOrientItem);
    pWrtShell->SetTableAttr(aSet);

    // When exporting to XHTML:
    setFilterOptions("xhtmlns=reqif-xhtml");
    save("HTML (StarWriter)");

    // Then make sure that CSS is used to horizontally position the table:
    xmlDocUniquePtr pXmlDoc = WrapReqifFromTempFile();
    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 0
    // - Actual  : 1
    // i.e <center> was used to position the table, not CSS.
    assertXPath(pXmlDoc, "//reqif-xhtml:center"_ostr, 0);
    assertXPath(pXmlDoc, "//reqif-xhtml:table"_ostr, "style"_ostr,
                "margin-left: auto; margin-right: auto");
}

CPPUNIT_TEST_FIXTURE(Test, testCenteredTableCSSImport)
{
    // Given an XHTML file with a centered (with inline CSS) table, when importing that document:
    setImportFilterOptions("xhtmlns=reqif-xhtml");
    setImportFilterName("HTML (StarWriter)");
    createSwDoc("centered-table.xhtml");

    // Then make sure that the table is centered:
    SwDoc* pDoc = getSwDoc();
    const sw::TableFrameFormats& rTableFormats = *pDoc->GetTableFrameFormats();
    const SwFrameFormat* pTableFormat = rTableFormats[0];
    sal_Int16 eHoriOrient = pTableFormat->GetHoriOrient().GetHoriOrient();
    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 2 (CENTER)
    // - Actual  : 3 (LEFT)
    // i.e. the table alignment was lost on import.
    CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER, eHoriOrient);
}
}

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */