1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
10 #include <sal/types.h>
18 #include <cppunit/TestAssert.h>
19 #include <cppunit/extensions/HelperMacros.h>
20 #include <cppunit/plugin/TestPlugIn.h>
22 #include <com/sun/star/beans/PropertyState.hpp>
23 #include <com/sun/star/beans/PropertyValue.hpp>
24 #include <com/sun/star/document/DocumentProperties.hpp>
25 #include <com/sun/star/packages/zip/ZipFileAccess.hpp>
26 #include <com/sun/star/frame/Desktop.hpp>
27 #include <com/sun/star/frame/XStorable.hpp>
29 #include <test/bootstrapfixture.hxx>
30 #include <test/xmltesttools.hxx>
31 #include <unotest/macros_test.hxx>
33 #include <unotools/ucbstreamhelper.hxx>
34 #include <comphelper/propertysequence.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <sfx2/app.hxx>
37 #include <osl/file.hxx>
40 using namespace ::com::sun::star
;
46 : public test::BootstrapFixture
47 , public unotest::MacrosTest
51 virtual void setUp() override
;
53 virtual void registerNamespaces(xmlXPathContextPtr
& pXmlXpathCtx
) override
56 xmlXPathRegisterNs(pXmlXpathCtx
, BAD_CAST("office"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:office:1.0"));
57 xmlXPathRegisterNs(pXmlXpathCtx
, BAD_CAST("meta"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:meta:1.0"));
58 xmlXPathRegisterNs(pXmlXpathCtx
, BAD_CAST("dc"), BAD_CAST("http://purl.org/dc/elements/1.1/"));
59 // used in testCustomMetadata
60 xmlXPathRegisterNs(pXmlXpathCtx
, BAD_CAST("foo"), BAD_CAST("http://foo.net"));
61 xmlXPathRegisterNs(pXmlXpathCtx
, BAD_CAST("baz"), BAD_CAST("http://baz.net"));
65 void MiscTest::setUp()
67 m_xContext
= comphelper::getProcessComponentContext();
68 mxDesktop
.set(frame::Desktop::create(m_xContext
));
69 SfxApplication::GetOrCreate();
72 CPPUNIT_TEST_FIXTURE(MiscTest
, testODFCustomMetadata
)
74 uno::Reference
<document::XDocumentProperties
> const xProps(
75 ::com::sun::star::document::DocumentProperties::create(m_xContext
));
77 OUString
const url(m_directories
.getURLFromSrc("/sfx2/qa/complex/sfx2/testdocuments/CUSTOM.odt"));
78 xProps
->loadFromMedium(url
, uno::Sequence
<beans::PropertyValue
>());
79 CPPUNIT_ASSERT_EQUAL(OUString(""), xProps
->getAuthor());
80 uno::Sequence
<beans::PropertyValue
> mimeArgs({
81 beans::PropertyValue("MediaType", -1, uno::Any(OUString("application/vnd.oasis.opendocument.text")), beans::PropertyState_DIRECT_VALUE
)
83 utl::TempFile aTempFile
;
84 xProps
->storeToMedium(aTempFile
.GetURL(), mimeArgs
);
86 // check that custom metadata is preserved
87 uno::Reference
<packages::zip::XZipFileAccess2
> const xZip(
88 packages::zip::ZipFileAccess::createWithURL(m_xContext
, aTempFile
.GetURL()));
89 uno::Reference
<io::XInputStream
> const xInputStream(xZip
->getByName("meta.xml"), uno::UNO_QUERY
);
90 std::unique_ptr
<SvStream
> const pStream(utl::UcbStreamHelper::CreateStream(xInputStream
, true));
91 xmlDocUniquePtr pXmlDoc
= parseXmlStream(pStream
.get());
92 assertXPathContent(pXmlDoc
, "/office:document-meta/office:meta/bork", "bork");
93 assertXPath(pXmlDoc
, "/office:document-meta/office:meta/foo:bar", 1);
94 assertXPath(pXmlDoc
, "/office:document-meta/office:meta/foo:bar/baz:foo", 1);
95 assertXPath(pXmlDoc
, "/office:document-meta/office:meta/foo:bar/baz:foo[@baz:bar='foo']");
96 assertXPathContent(pXmlDoc
, "/office:document-meta/office:meta/foo:bar/foo:baz", "bar");
98 aTempFile
.EnableKillingFile();
101 CPPUNIT_TEST_FIXTURE(MiscTest
, testNoThumbnail
)
104 const OUString
aURL(m_directories
.getURLFromSrc("/sfx2/qa/cppunit/misc/hello.odt"));
105 uno::Reference
<lang::XComponent
> xComponent
106 = loadFromDesktop(aURL
, "com.sun.star.text.TextDocument");
107 CPPUNIT_ASSERT(xComponent
.is());
109 // Save it with the NoThumbnail option and assert that it has no thumbnail.
111 mode_t nMask
= umask(022);
113 uno::Reference
<frame::XStorable
> xStorable(xComponent
, uno::UNO_QUERY
);
114 CPPUNIT_ASSERT(xStorable
.is());
115 utl::TempFile aTempFile
;
116 aTempFile
.EnableKillingFile();
117 uno::Sequence
<beans::PropertyValue
> aProperties(
118 comphelper::InitPropertySequence({ { "NoThumbnail", uno::makeAny(true) } }));
119 osl::File::remove(aTempFile
.GetURL());
120 xStorable
->storeToURL(aTempFile
.GetURL(), aProperties
);
121 uno::Reference
<packages::zip::XZipFileAccess2
> xZipFile
122 = packages::zip::ZipFileAccess::createWithURL(m_xContext
, aTempFile
.GetURL());
123 CPPUNIT_ASSERT(!xZipFile
->hasByName("Thumbnails/thumbnail.png"));
126 // Check permissions of the URL after store.
127 osl::DirectoryItem aItem
;
128 CPPUNIT_ASSERT_EQUAL(osl::DirectoryItem::E_None
,
129 osl::DirectoryItem::get(aTempFile
.GetURL(), aItem
));
131 osl::FileStatus
aStatus(osl_FileStatus_Mask_Attributes
);
132 CPPUNIT_ASSERT_EQUAL(osl::DirectoryItem::E_None
, aItem
.getFileStatus(aStatus
));
134 // The following checks used to fail in the past, osl_File_Attribute_GrpRead was not set even if
135 // umask requested so:
136 CPPUNIT_ASSERT(aStatus
.getAttributes() & osl_File_Attribute_GrpRead
);
137 CPPUNIT_ASSERT(aStatus
.getAttributes() & osl_File_Attribute_OthRead
);
139 // Now "save as" again to trigger the "overwrite" case.
140 xStorable
->storeToURL(aTempFile
.GetURL(), {});
141 CPPUNIT_ASSERT_EQUAL(osl::DirectoryItem::E_None
, aItem
.getFileStatus(aStatus
));
142 // The following check used to fail in the past, result had temp file
144 CPPUNIT_ASSERT(aStatus
.getAttributes() & osl_File_Attribute_GrpRead
);
149 xComponent
->dispose();
152 CPPUNIT_TEST_FIXTURE(MiscTest
, testHardLinks
)
155 OUString aSourceDir
= m_directories
.getURLFromSrc("/sfx2/qa/cppunit/misc/");
156 OUString aTargetDir
= m_directories
.getURLFromWorkdir("/CppunitTest/sfx2_misc.test.user/");
157 const OUString
aURL(aTargetDir
+ "hello.odt");
158 osl::File::copy(aSourceDir
+ "hello.odt", aURL
);
159 OUString aTargetPath
;
160 osl::FileBase::getSystemPathFromFileURL(aURL
, aTargetPath
);
161 OString aOld
= aTargetPath
.toUtf8();
163 OString aNew
= aTargetPath
.toUtf8();
164 int nRet
= link(aOld
.getStr(), aNew
.getStr());
165 CPPUNIT_ASSERT_EQUAL(0, nRet
);
167 uno::Reference
<lang::XComponent
> xComponent
= loadFromDesktop(aURL
, "com.sun.star.text.TextDocument");
168 CPPUNIT_ASSERT(xComponent
.is());
170 uno::Reference
<frame::XStorable
> xStorable(xComponent
, uno::UNO_QUERY
);
174 // coverity[fs_check_call] - this is legitimate in the context of this test
175 nRet
= stat(aOld
.getStr(), &buf
);
176 CPPUNIT_ASSERT_EQUAL(0, nRet
);
177 // This failed: hard link count was 1, the hard link broke on store.
178 CPPUNIT_ASSERT(buf
.st_nlink
> 1);
180 // Test that symlinks are preserved as well.
181 nRet
= remove(aNew
.getStr());
182 CPPUNIT_ASSERT_EQUAL(0, nRet
);
183 nRet
= symlink(aOld
.getStr(), aNew
.getStr());
184 CPPUNIT_ASSERT_EQUAL(0, nRet
);
185 xStorable
->storeToURL(aURL
+ ".2", {});
186 nRet
= lstat(aNew
.getStr(), &buf
);
187 CPPUNIT_ASSERT_EQUAL(0, nRet
);
188 // This failed, the hello.odt.2 symlink was replaced with a real file.
189 CPPUNIT_ASSERT(bool(S_ISLNK(buf
.st_mode
)));
191 xComponent
->dispose();
197 CPPUNIT_PLUGIN_IMPLEMENT();
199 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */