Use COMReference to handle COM pointers in CreateShortcut
[LibreOffice.git] / sw / qa / core / tox / tox.cxx
blob338a9654d801efcc0f837148fd3eae5739337d29
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(u"com.sun.star.text.TextField.Bibliography"_ustr), uno::UNO_QUERY);
38 uno::Sequence<beans::PropertyValue> aFields = {
39 comphelper::makePropertyValue(u"BibiliographicType"_ustr, text::BibliographyDataType::WWW),
40 comphelper::makePropertyValue(u"Identifier"_ustr, u"ARJ00"_ustr),
41 comphelper::makePropertyValue(u"Author"_ustr, u"Ar, J"_ustr),
42 comphelper::makePropertyValue(u"Title"_ustr, u"mytitle"_ustr),
43 comphelper::makePropertyValue(u"Year"_ustr, u"2020"_ustr),
44 comphelper::makePropertyValue(u"URL"_ustr, u"http://www.example.com/test.pdf"_ustr),
46 xField->setPropertyValue(u"Fields"_ustr, 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(u"com.sun.star.text.Bibliography"_ustr), 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), u"HyperLinkURL"_ustr);
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(u"http://www.example.com/test.pdf"_ustr, 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(u"com.sun.star.text.TextField.Bibliography"_ustr), uno::UNO_QUERY);
80 uno::Sequence<beans::PropertyValue> aFields = {
81 comphelper::makePropertyValue(u"BibiliographicType"_ustr, text::BibliographyDataType::WWW),
82 comphelper::makePropertyValue(u"Identifier"_ustr, u"AT"_ustr),
83 comphelper::makePropertyValue(u"Author"_ustr, u"Author"_ustr),
84 comphelper::makePropertyValue(u"Title"_ustr, u"Title"_ustr),
85 comphelper::makePropertyValue(u"URL"_ustr, u"http://www.example.com/test.pdf#page=1"_ustr),
87 xField->setPropertyValue(u"Fields"_ustr, 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(u"com.sun.star.text.Bibliography"_ustr), 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), u"HyperLinkURL"_ustr);
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(u"http://www.example.com/test.pdf"_ustr, 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(u"com.sun.star.text.TextField.Bibliography"_ustr), uno::UNO_QUERY);
126 uno::Sequence<beans::PropertyValue> aFields = {
127 comphelper::makePropertyValue(u"BibiliographicType"_ustr, text::BibliographyDataType::WWW),
128 comphelper::makePropertyValue(u"Identifier"_ustr, u"AT"_ustr),
129 comphelper::makePropertyValue(u"Author"_ustr, u"Author"_ustr),
130 comphelper::makePropertyValue(u"Title"_ustr, u"Title"_ustr),
131 comphelper::makePropertyValue(u"URL"_ustr, u"http://www.example.com/test.pdf#page=1"_ustr),
133 xField->setPropertyValue(u"Fields"_ustr, 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(u"FilterName"_ustr, u"writer8"_ustr),
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(u"com.sun.star.text.TextField.Bibliography"_ustr), uno::UNO_QUERY);
175 uno::Sequence<beans::PropertyValue> aFields = {
176 comphelper::makePropertyValue(u"BibiliographicType"_ustr, text::BibliographyDataType::WWW),
177 comphelper::makePropertyValue(u"Identifier"_ustr, u"AT"_ustr),
178 comphelper::makePropertyValue(u"Author"_ustr, u"Author"_ustr),
179 comphelper::makePropertyValue(u"Title"_ustr, u"Title"_ustr),
180 comphelper::makePropertyValue(u"URL"_ustr, u"test.pdf#page=1"_ustr),
182 xField->setPropertyValue(u"Fields"_ustr, 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(u"com.sun.star.text.TextField.Bibliography"_ustr),
221 uno::UNO_QUERY);
222 uno::Sequence<beans::PropertyValue> aFields = {
223 comphelper::makePropertyValue(u"BibiliographicType"_ustr,
224 text::BibliographyDataType::WWW),
225 comphelper::makePropertyValue(u"Identifier"_ustr, u"AT"_ustr),
226 comphelper::makePropertyValue(u"Author"_ustr, u"Author"_ustr),
227 comphelper::makePropertyValue(u"Title"_ustr, u"Title"_ustr),
228 comphelper::makePropertyValue(u"URL"_ustr, OUString(rURL)),
230 xField->setPropertyValue(u"Fields"_ustr, uno::Any(aFields));
231 uno::Reference<text::XTextContent> xContent(xField, uno::UNO_QUERY);
232 xText->insertTextContent(xCursor, xContent, /*bAbsorb=*/false);
234 // Create a bibliography table.
235 uno::Reference<text::XTextContent> xTable(
236 xFactory->createInstance(u"com.sun.star.text.Bibliography"_ustr), uno::UNO_QUERY);
237 xCursor->gotoEnd(/*bExpand=*/false);
238 xText->insertControlCharacter(xCursor, text::ControlCharacter::APPEND_PARAGRAPH,
239 /*bAbsorb=*/false);
240 xText->insertTextContent(xCursor, xTable, /*bAbsorb=*/false);
242 // When updating that table:
243 uno::Reference<text::XDocumentIndex> xTableIndex(xTable, uno::UNO_QUERY);
244 xTableIndex->update();
246 // Then the first two fields should be merged to a single source, but not the third.
247 CPPUNIT_ASSERT_EQUAL(u"AT: Author, Title, , http://www.example.com/test.pdf"_ustr,
248 getParagraph(3)->getString());
249 // Without the accompanying fix in place, this test would have failed with:
250 // - Expected: AT: Author, Title, , http://www.example.com/test2.pdf
251 // - Actual : AT: Author, Title, , http://www.example.com/test.pdf
252 // i.e. test.pdf was mentioned twice, without deduplication.
253 CPPUNIT_ASSERT_EQUAL(u"AT: Author, Title, , http://www.example.com/test2.pdf"_ustr,
254 getParagraph(4)->getString());
258 CPPUNIT_PLUGIN_IMPLEMENT();
260 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */