tdf#156866 use mSize instead of mPixelSize for inverted surface
[LibreOffice.git] / framework / qa / cppunit / dispatchtest.cxx
blob9549ef150904423997514b8e07d9e6447f0c2fd2
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 <cppuhelper/implbase.hxx>
11 #include <test/unoapi_test.hxx>
13 #include <com/sun/star/frame/XDispatchProviderInterceptor.hpp>
14 #include <com/sun/star/frame/XInterceptorInfo.hpp>
15 #include <com/sun/star/util/URLTransformer.hpp>
17 #include <rtl/ref.hxx>
18 #include <mutex>
20 using namespace ::com::sun::star;
22 namespace
24 /// Sample interception implementation that asserts getInterceptedURLs() and queryDispatch() is in sync.
25 class MyInterceptor
26 : public cppu::WeakImplHelper<frame::XDispatchProviderInterceptor, frame::XInterceptorInfo>
28 std::mutex maMutex;
29 uno::Reference<frame::XDispatchProvider> m_xMaster;
30 uno::Reference<frame::XDispatchProvider> m_xSlave;
31 uno::Sequence<OUString> m_aDisabledCommands;
32 int m_nExpected;
33 int m_nUnexpected;
35 public:
36 MyInterceptor();
38 /// Number of queryDispatch() calls that operate on a command advertised by getInterceptedURLs().
39 int getExpected();
40 /// Number of queryDispatch() calls that operate on a command not advertised by getInterceptedURLs().
41 int getUnexpected();
43 // frame::XInterceptorInfo
44 virtual uno::Sequence<OUString> SAL_CALL getInterceptedURLs() override;
46 // frame::XDispatchProviderInterceptor
47 virtual void SAL_CALL setMasterDispatchProvider(
48 const uno::Reference<frame::XDispatchProvider>& xNewSupplier) override;
49 virtual uno::Reference<frame::XDispatchProvider> SAL_CALL getMasterDispatchProvider() override;
50 virtual void SAL_CALL
51 setSlaveDispatchProvider(const uno::Reference<frame::XDispatchProvider>& xNewSupplier) override;
52 virtual uno::Reference<frame::XDispatchProvider> SAL_CALL getSlaveDispatchProvider() override;
54 // frame::XDispatchProvider
55 virtual uno::Sequence<uno::Reference<frame::XDispatch>> SAL_CALL
56 queryDispatches(const uno::Sequence<frame::DispatchDescriptor>& rRequests) override;
57 virtual uno::Reference<frame::XDispatch>
58 SAL_CALL queryDispatch(const util::URL& rURL, const OUString& rTargetFrameName,
59 sal_Int32 SearchFlags) override;
62 MyInterceptor::MyInterceptor()
63 : m_aDisabledCommands{ ".uno:Bold" }
64 , m_nExpected(0)
65 , m_nUnexpected(0)
69 int MyInterceptor::getExpected()
71 std::unique_lock aGuard(maMutex);
72 int nRet = m_nExpected;
73 m_nExpected = 0;
74 return nRet;
77 int MyInterceptor::getUnexpected()
79 std::unique_lock aGuard(maMutex);
80 int nRet = m_nUnexpected;
81 m_nUnexpected = 0;
82 return nRet;
85 uno::Sequence<OUString> MyInterceptor::getInterceptedURLs() { return m_aDisabledCommands; }
87 void MyInterceptor::setMasterDispatchProvider(
88 const uno::Reference<frame::XDispatchProvider>& xNewSupplier)
90 std::unique_lock aGuard(maMutex);
91 m_xMaster = xNewSupplier;
94 uno::Reference<frame::XDispatchProvider> MyInterceptor::getMasterDispatchProvider()
96 std::unique_lock aGuard(maMutex);
97 return m_xMaster;
100 void MyInterceptor::setSlaveDispatchProvider(
101 const uno::Reference<frame::XDispatchProvider>& xNewSupplier)
103 std::unique_lock aGuard(maMutex);
104 m_xSlave = xNewSupplier;
107 uno::Reference<frame::XDispatchProvider> MyInterceptor::getSlaveDispatchProvider()
109 std::unique_lock aGuard(maMutex);
110 return m_xSlave;
113 uno::Sequence<uno::Reference<frame::XDispatch>>
114 MyInterceptor::queryDispatches(const uno::Sequence<frame::DispatchDescriptor>& rRequests)
116 uno::Sequence<uno::Reference<frame::XDispatch>> aResult(rRequests.getLength());
117 auto aResultRange = asNonConstRange(aResult);
119 for (sal_Int32 i = 0; i < rRequests.getLength(); ++i)
121 aResultRange[i] = queryDispatch(rRequests[i].FeatureURL, rRequests[i].FrameName,
122 rRequests[i].SearchFlags);
125 return aResult;
128 uno::Reference<frame::XDispatch> MyInterceptor::queryDispatch(const util::URL& rURL,
129 const OUString& /*rTargetFrameName*/,
130 sal_Int32 /*SearchFlags*/)
132 std::unique_lock aGuard(maMutex);
133 if (std::find(std::cbegin(m_aDisabledCommands), std::cend(m_aDisabledCommands), rURL.Complete)
134 != std::cend(m_aDisabledCommands))
135 ++m_nExpected;
136 else
137 ++m_nUnexpected;
139 return uno::Reference<frame::XDispatch>();
142 /// Tests how InterceptionHelper invokes a registered interceptor.
143 class DispatchTest : public UnoApiTest
145 public:
146 DispatchTest()
147 : UnoApiTest("/framework/qa/cppunit/data/")
152 CPPUNIT_TEST_FIXTURE(DispatchTest, testInterception)
154 mxComponent = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument");
155 uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
156 CPPUNIT_ASSERT(xModel.is());
158 uno::Reference<frame::XDispatchProviderInterception> xRegistration(
159 xModel->getCurrentController()->getFrame(), uno::UNO_QUERY);
160 CPPUNIT_ASSERT(xRegistration.is());
162 rtl::Reference<MyInterceptor> pInterceptor(new MyInterceptor());
163 xRegistration->registerDispatchProviderInterceptor(pInterceptor);
165 dispatchCommand(mxComponent, ".uno:Bold", {});
166 CPPUNIT_ASSERT_EQUAL(1, pInterceptor->getExpected());
167 CPPUNIT_ASSERT_EQUAL(0, pInterceptor->getUnexpected());
168 dispatchCommand(mxComponent, ".uno:Italic", {});
169 CPPUNIT_ASSERT_EQUAL(1, pInterceptor->getExpected());
170 // This was 1: MyInterceptor::queryDispatch() was called for .uno:Italic.
171 CPPUNIT_ASSERT_EQUAL(0, pInterceptor->getUnexpected());
174 CPPUNIT_TEST_FIXTURE(DispatchTest, testSfxOfficeDispatchDispose)
176 // this test doesn't work with a new document because of aURL.Main check in SfxBaseController::dispatch()
177 loadFromURL(u"empty.fodp");
178 uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
179 CPPUNIT_ASSERT(xModel.is());
180 uno::Reference<frame::XController> xController(xModel->getCurrentController());
181 CPPUNIT_ASSERT(xController.is());
182 uno::Reference<frame::XDispatchProvider> xFrame(xController->getFrame(), uno::UNO_QUERY);
183 CPPUNIT_ASSERT(xFrame.is());
185 uno::Reference<util::XURLTransformer> xParser(util::URLTransformer::create(mxComponentContext));
186 util::URL url;
187 url.Complete = xModel->getURL() + "#dummy";
188 xParser->parseStrict(url);
190 uno::Reference<frame::XDispatch> xDisp(xFrame->queryDispatch(url, "", 0));
191 CPPUNIT_ASSERT(xDisp.is());
193 mxComponent->dispose();
195 util::URL urlSlot;
196 urlSlot.Complete = "slot:5598";
197 xParser->parseStrict(urlSlot);
198 // crashed with UAF
199 xDisp->dispatch(urlSlot, {});
203 CPPUNIT_PLUGIN_IMPLEMENT();
205 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */