Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / qa / core / tox / tox.cxx
blob89fc71a7eb3369d43b8ad7b60c0750a63dfb01fe
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <swmodeltestbase.hxx>
12 #include <com/sun/star/frame/XStorable.hpp>
13 #include <com/sun/star/text/BibliographyDataType.hpp>
14 #include <com/sun/star/text/ControlCharacter.hpp>
15 #include <com/sun/star/text/XDocumentIndex.hpp>
16 #include <com/sun/star/text/XTextDocument.hpp>
18 #include <comphelper/propertyvalue.hxx>
20 #include <IDocumentFieldsAccess.hxx>
21 #include <authfld.hxx>
22 #include <fmtfld.hxx>
24 namespace
26 /// Covers sw/source/core/tox/ fixes.
27 class Test : public SwModelTestBase
31 CPPUNIT_TEST_FIXTURE(Test, testAuthorityLinkClick)
33 // Create a document with a bibliography reference (of type WWW) in it.
34 createSwDoc();
35 uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
36 uno::Reference<beans::XPropertySet> xField(
37 xFactory->createInstance("com.sun.star.text.TextField.Bibliography"), uno::UNO_QUERY);
38 uno::Sequence<beans::PropertyValue> aFields = {
39 comphelper::makePropertyValue("BibiliographicType", text::BibliographyDataType::WWW),
40 comphelper::makePropertyValue("Identifier", OUString("ARJ00")),
41 comphelper::makePropertyValue("Author", OUString("Ar, J")),
42 comphelper::makePropertyValue("Title", OUString("mytitle")),
43 comphelper::makePropertyValue("Year", OUString("2020")),
44 comphelper::makePropertyValue("URL", OUString("http://www.example.com/test.pdf")),
46 xField->setPropertyValue("Fields", uno::Any(aFields));
47 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
48 uno::Reference<text::XText> xText = xTextDocument->getText();
49 uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
50 uno::Reference<text::XTextContent> xContent(xField, uno::UNO_QUERY);
51 xText->insertTextContent(xCursor, xContent, /*bAbsorb=*/false);
52 // Create a bibliography table.
53 uno::Reference<text::XTextContent> xTable(
54 xFactory->createInstance("com.sun.star.text.Bibliography"), uno::UNO_QUERY);
55 xCursor->gotoEnd(/*bExpand=*/false);
56 xText->insertControlCharacter(xCursor, text::ControlCharacter::APPEND_PARAGRAPH,
57 /*bAbsorb=*/false);
58 xText->insertTextContent(xCursor, xTable, /*bAbsorb=*/false);
60 // Update it.
61 uno::Reference<text::XDocumentIndex> xTableIndex(xTable, uno::UNO_QUERY);
62 xTableIndex->update();
64 // Paragraph index: Reference, table header, table row.
65 // Portion index: ID, etc; then the URL.
66 auto aActual = getProperty<OUString>(getRun(getParagraph(3), 2), "HyperLinkURL");
67 // Without the accompanying fix in place, this test would have failed with:
68 // An uncaught exception of type com.sun.star.container.NoSuchElementException
69 // i.e. the URL was not clickable and the table row was a single text portion.
70 CPPUNIT_ASSERT_EQUAL(OUString("http://www.example.com/test.pdf"), aActual);
73 CPPUNIT_TEST_FIXTURE(Test, testAuthorityTableEntryURL)
75 // Given a document with a bibliography reference (of type WWW) in it:
76 createSwDoc();
77 uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
78 uno::Reference<beans::XPropertySet> xField(
79 xFactory->createInstance("com.sun.star.text.TextField.Bibliography"), uno::UNO_QUERY);
80 uno::Sequence<beans::PropertyValue> aFields = {
81 comphelper::makePropertyValue("BibiliographicType", text::BibliographyDataType::WWW),
82 comphelper::makePropertyValue("Identifier", OUString("AT")),
83 comphelper::makePropertyValue("Author", OUString("Author")),
84 comphelper::makePropertyValue("Title", OUString("Title")),
85 comphelper::makePropertyValue("URL", OUString("http://www.example.com/test.pdf#page=1")),
87 xField->setPropertyValue("Fields", uno::Any(aFields));
88 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
89 uno::Reference<text::XText> xText = xTextDocument->getText();
90 uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
91 uno::Reference<text::XTextContent> xContent(xField, uno::UNO_QUERY);
92 xText->insertTextContent(xCursor, xContent, /*bAbsorb=*/false);
93 // Create a bibliography table.
94 uno::Reference<text::XTextContent> xTable(
95 xFactory->createInstance("com.sun.star.text.Bibliography"), uno::UNO_QUERY);
96 xCursor->gotoEnd(/*bExpand=*/false);
97 xText->insertControlCharacter(xCursor, text::ControlCharacter::APPEND_PARAGRAPH,
98 /*bAbsorb=*/false);
99 xText->insertTextContent(xCursor, xTable, /*bAbsorb=*/false);
101 // When updating that table:
102 uno::Reference<text::XDocumentIndex> xTableIndex(xTable, uno::UNO_QUERY);
103 xTableIndex->update();
105 // Then the page number from the source's URL should be stripped:
106 // Paragraph index: Reference, table header, table row.
107 // Portion index: ID, etc; then the URL.
108 auto aActual = getProperty<OUString>(getRun(getParagraph(3), 2), "HyperLinkURL");
109 // Without the accompanying fix in place, this test would have failed with:
110 // - Expected: http://www.example.com/test.pdf
111 // - Actual : http://www.example.com/test.pdf#page=1
112 // i.e. the page number was still part of the bibliography table.
113 CPPUNIT_ASSERT_EQUAL(OUString("http://www.example.com/test.pdf"), aActual);
116 CPPUNIT_TEST_FIXTURE(Test, testAuthorityTableEntryClick)
118 // Given an empty document:
119 createSwDoc();
120 SwDoc* pDoc = getSwDoc();
122 // When inserting a biblio entry field with an URL:
123 uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
124 uno::Reference<beans::XPropertySet> xField(
125 xFactory->createInstance("com.sun.star.text.TextField.Bibliography"), uno::UNO_QUERY);
126 uno::Sequence<beans::PropertyValue> aFields = {
127 comphelper::makePropertyValue("BibiliographicType", text::BibliographyDataType::WWW),
128 comphelper::makePropertyValue("Identifier", OUString("AT")),
129 comphelper::makePropertyValue("Author", OUString("Author")),
130 comphelper::makePropertyValue("Title", OUString("Title")),
131 comphelper::makePropertyValue("URL", OUString("http://www.example.com/test.pdf#page=1")),
133 xField->setPropertyValue("Fields", uno::Any(aFields));
134 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
135 uno::Reference<text::XText> xText = xTextDocument->getText();
136 uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
137 uno::Reference<text::XTextContent> xContent(xField, uno::UNO_QUERY);
138 xText->insertTextContent(xCursor, xContent, /*bAbsorb=*/false);
140 // Then make sure that the field is clickable, since the page part will not be part of the
141 // bibliography table:
142 const SwFieldTypes* pTypes = pDoc->getIDocumentFieldsAccess().GetFieldTypes();
143 auto it = std::find_if(pTypes->begin(), pTypes->end(),
144 [](const std::unique_ptr<SwFieldType>& pType) {
145 return pType->Which() == SwFieldIds::TableOfAuthorities;
147 CPPUNIT_ASSERT(it != pTypes->end());
148 const SwFieldType* pType = it->get();
149 std::vector<SwFormatField*> aFormatFields;
150 pType->GatherFields(aFormatFields);
151 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aFormatFields.size());
152 SwField* pField = aFormatFields[0]->GetField();
153 // Without the accompanying fix in place, this test would have failed, as the field was not
154 // clickable.
155 CPPUNIT_ASSERT(pField->IsClickable());
156 // This is needed, so the mouse has the correct RefHand pointer style.
157 CPPUNIT_ASSERT(pField->HasClickHdl());
160 CPPUNIT_TEST_FIXTURE(Test, testAuthorityTableEntryRelClick)
162 // Given an empty document with a file:// base URL:
163 createSwDoc();
164 SwDoc* pDoc = getSwDoc();
165 uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
166 uno::Sequence<beans::PropertyValue> aArgs = {
167 comphelper::makePropertyValue("FilterName", OUString("writer8")),
169 xStorable->storeAsURL(maTempFile.GetURL(), aArgs);
171 // When inserting a biblio entry field with a relative URL:
172 uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
173 uno::Reference<beans::XPropertySet> xField(
174 xFactory->createInstance("com.sun.star.text.TextField.Bibliography"), uno::UNO_QUERY);
175 uno::Sequence<beans::PropertyValue> aFields = {
176 comphelper::makePropertyValue("BibiliographicType", text::BibliographyDataType::WWW),
177 comphelper::makePropertyValue("Identifier", OUString("AT")),
178 comphelper::makePropertyValue("Author", OUString("Author")),
179 comphelper::makePropertyValue("Title", OUString("Title")),
180 comphelper::makePropertyValue("URL", OUString("test.pdf#page=1")),
182 xField->setPropertyValue("Fields", uno::Any(aFields));
183 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
184 uno::Reference<text::XText> xText = xTextDocument->getText();
185 uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
186 uno::Reference<text::XTextContent> xContent(xField, uno::UNO_QUERY);
187 xText->insertTextContent(xCursor, xContent, /*bAbsorb=*/false);
189 // Then make sure that the field is clickable:
190 const SwFieldTypes* pTypes = pDoc->getIDocumentFieldsAccess().GetFieldTypes();
191 auto it = std::find_if(pTypes->begin(), pTypes->end(),
192 [](const std::unique_ptr<SwFieldType>& pType) {
193 return pType->Which() == SwFieldIds::TableOfAuthorities;
195 CPPUNIT_ASSERT(it != pTypes->end());
196 const SwFieldType* pType = it->get();
197 std::vector<SwFormatField*> aFormatFields;
198 pType->GatherFields(aFormatFields);
199 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aFormatFields.size());
200 auto pField = static_cast<SwAuthorityField*>(aFormatFields[0]->GetField());
201 CPPUNIT_ASSERT(pField->GetAbsoluteURL().startsWith("file://"));
204 CPPUNIT_TEST_FIXTURE(Test, testAuthorityTableURLDeduplication)
206 // Given a document with 3 bibliography references (of type WWW) in it:
207 static const std::initializer_list<std::u16string_view> aURLs = {
208 u"http://www.example.com/test.pdf#page=1",
209 u"http://www.example.com/test.pdf#page=2",
210 u"http://www.example.com/test2.pdf",
212 createSwDoc();
213 uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
214 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
215 uno::Reference<text::XText> xText = xTextDocument->getText();
216 uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
217 for (const auto& rURL : aURLs)
219 uno::Reference<beans::XPropertySet> xField(
220 xFactory->createInstance("com.sun.star.text.TextField.Bibliography"), uno::UNO_QUERY);
221 uno::Sequence<beans::PropertyValue> aFields = {
222 comphelper::makePropertyValue("BibiliographicType", text::BibliographyDataType::WWW),
223 comphelper::makePropertyValue("Identifier", OUString("AT")),
224 comphelper::makePropertyValue("Author", OUString("Author")),
225 comphelper::makePropertyValue("Title", OUString("Title")),
226 comphelper::makePropertyValue("URL", OUString(rURL)),
228 xField->setPropertyValue("Fields", uno::Any(aFields));
229 uno::Reference<text::XTextContent> xContent(xField, uno::UNO_QUERY);
230 xText->insertTextContent(xCursor, xContent, /*bAbsorb=*/false);
232 // Create a bibliography table.
233 uno::Reference<text::XTextContent> xTable(
234 xFactory->createInstance("com.sun.star.text.Bibliography"), uno::UNO_QUERY);
235 xCursor->gotoEnd(/*bExpand=*/false);
236 xText->insertControlCharacter(xCursor, text::ControlCharacter::APPEND_PARAGRAPH,
237 /*bAbsorb=*/false);
238 xText->insertTextContent(xCursor, xTable, /*bAbsorb=*/false);
240 // When updating that table:
241 uno::Reference<text::XDocumentIndex> xTableIndex(xTable, uno::UNO_QUERY);
242 xTableIndex->update();
244 // Then the first two fields should be merged to a single source, but not the third.
245 CPPUNIT_ASSERT_EQUAL(OUString("AT: Author, Title, , http://www.example.com/test.pdf"),
246 getParagraph(3)->getString());
247 // Without the accompanying fix in place, this test would have failed with:
248 // - Expected: AT: Author, Title, , http://www.example.com/test2.pdf
249 // - Actual : AT: Author, Title, , http://www.example.com/test.pdf
250 // i.e. test.pdf was mentioned twice, without deduplication.
251 CPPUNIT_ASSERT_EQUAL(OUString("AT: Author, Title, , http://www.example.com/test2.pdf"),
252 getParagraph(4)->getString());
256 CPPUNIT_PLUGIN_IMPLEMENT();
258 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */