Rebased ref, commits from common ancestor: commit abdefeec68a0790f5b8ac567fb2ec2edca29697e Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sun Aug 28 12:26:01 2016 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Sun Aug 28 12:45:12 2016 -0400
loolwsd: getrepairactions unittests added Change-Id: I8df51d30e127cdfe0311a4e730de5d40bdd657ce diff --git a/loolwsd/test/httpwstest.cpp b/loolwsd/test/httpwstest.cpp index 423e69825..56756af01 100644 --- a/loolwsd/test/httpwstest.cpp +++ b/loolwsd/test/httpwstest.cpp @@ -88,6 +88,8 @@ class HTTPWSTest : public CPPUNIT_NS::TestFixture CPPUNIT_TEST(testFontList); CPPUNIT_TEST(testStateUnoCommand); CPPUNIT_TEST(testColumnRowResize); + CPPUNIT_TEST(testEmptyRepairActions); + CPPUNIT_TEST(testRepairActions); CPPUNIT_TEST_SUITE_END(); @@ -124,6 +126,8 @@ class HTTPWSTest : public CPPUNIT_NS::TestFixture void testFontList(); void testStateUnoCommand(); void testColumnRowResize(); + void testEmptyRepairActions(); + void testRepairActions(); void loadDoc(const std::string& documentURL); @@ -2030,6 +2034,76 @@ void HTTPWSTest::testColumnRowResize() } } +void HTTPWSTest::testEmptyRepairActions() +{ + try + { + const auto testname = "repairactions "; + auto socket = loadDocAndGetSocket("hello.odt", _uri, testname); + + // Check if the document contains the pasted text. + sendTextFrame(socket, "getrepairactions"); + const std::string prefix = "repairactions:"; + const auto response = getResponseMessage(socket, prefix, testname); + const std::string repairActions(response.data(), response.size()); + CPPUNIT_ASSERT_EQUAL(std::string("repairactions: [{ \"undo\": {\n \"actions\": \"\"\n}\n}, { \"redo\": {\n \"actions\": \"\"\n}\n}]"), repairActions); + + const auto jsonString = repairActions.substr(prefix.size()); + + Poco::JSON::Parser parser; + const auto result = parser.parse(jsonString); + const auto& json = result.extract<Poco::JSON::Array::Ptr>(); + auto redo = json->getObject(0); + auto redoActions = redo->getArray("actions"); + CPPUNIT_ASSERT(!redoActions); + } + catch (const Poco::Exception& exc) + { + CPPUNIT_FAIL(exc.displayText()); + } +} + +void HTTPWSTest::testRepairActions() +{ + try + { + const auto testname = "repairactions "; + auto socket = loadDocAndGetSocket("hello.odt", _uri, testname); + + sendTextFrame(socket, "uno .uno:SelectAll"); + sendTextFrame(socket, "uno .uno:Delete"); + + // Check if the document contains the pasted text. + sendTextFrame(socket, "getrepairactions"); + const std::string prefix = "repairactions:"; + const auto response = getResponseMessage(socket, prefix, testname); + const std::string repairActions(response.data(), response.size()); + + const auto jsonString = repairActions.substr(prefix.size()); + + Poco::JSON::Parser parser; + const auto result = parser.parse(jsonString); + const auto& json = result.extract<Poco::JSON::Array::Ptr>(); + + auto undo = json->getObject(0)->get("undo"); + auto subUndo = undo.extract<Poco::JSON::Object::Ptr>(); + auto undoActionsVar = subUndo->get("actions"); + auto undoActions = undoActionsVar.extract<Poco::JSON::Array::Ptr>(); + CPPUNIT_ASSERT_MESSAGE("Expected one undo action in the actions array.", !!undoActions); + CPPUNIT_ASSERT_EQUAL(std::size_t(1), undoActions->size()); + CPPUNIT_ASSERT_EQUAL(std::string("Delete 'Hello world'"), undoActions->getObject(0)->get("comment").toString()); + + auto redo = json->getObject(1)->get("redo"); + auto subRedo = redo.extract<Poco::JSON::Object::Ptr>(); + auto redoActionsVar = subRedo->get("actions"); + CPPUNIT_ASSERT_EQUAL(std::string(), redoActionsVar.toString()); + } + catch (const Poco::Exception& exc) + { + CPPUNIT_FAIL(exc.displayText()); + } +} + CPPUNIT_TEST_SUITE_REGISTRATION(HTTPWSTest); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit f18aebb04e7a0a90e518759c9e48e1251160e376 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sun Aug 28 12:25:40 2016 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Sun Aug 28 12:45:12 2016 -0400 loolwsd: unittest cleanups Change-Id: Ic383915012ac1c254960d976cc89d3f7c1a2cb02 diff --git a/loolwsd/test/helpers.hpp b/loolwsd/test/helpers.hpp index fd7abef80..d24d5e08b 100644 --- a/loolwsd/test/helpers.hpp +++ b/loolwsd/test/helpers.hpp @@ -82,9 +82,9 @@ std::vector<char> readDataFromFile(std::unique_ptr<std::fstream>& file) } inline -void getDocumentPathAndURL(const char* document, std::string& documentPath, std::string& documentURL) +void getDocumentPathAndURL(const std::string& docFilename, std::string& documentPath, std::string& documentURL) { - documentPath = Util::getTempFilePath(TDOC, document); + documentPath = Util::getTempFilePath(TDOC, docFilename); documentURL = "lool/ws/file://" + Poco::Path(documentPath).makeAbsolute().toString(); std::cerr << "Test file: " << documentPath << std::endl; @@ -256,7 +256,7 @@ std::vector<char> getResponseMessage(Poco::Net::WebSocket& ws, const std::string int bytes = ws.receiveFrame(response.data(), response.size(), flags); response.resize(bytes >= 0 ? bytes : 0); auto message = LOOLProtocol::getAbbreviatedMessage(response); - std::cerr << name << "Got " << bytes << " bytes: " << message << std::endl; + std::cerr << name << "Got " << bytes << " bytes: " << std::string(response.data(), response.size()) << std::endl; if (bytes > 0 && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE) { if (message.find(prefix) == 0) @@ -389,6 +389,24 @@ std::shared_ptr<Poco::Net::WebSocket> loadDocAndGetSocket(const Poco::URI& uri, } inline +std::shared_ptr<Poco::Net::WebSocket> loadDocAndGetSocket(const std::string& docFilename, const Poco::URI& uri, const std::string& name = "", bool isView = false) +{ + try + { + std::string documentPath, documentURL; + getDocumentPathAndURL(docFilename, documentPath, documentURL); + return loadDocAndGetSocket(uri, documentURL, name, isView); + } + catch (const Poco::Exception& exc) + { + CPPUNIT_FAIL(exc.displayText()); + } + + // Really couldn't reach here, but the compiler doesn't know any better. + return nullptr; +} + +inline void SocketProcessor(const std::string& name, const std::shared_ptr<Poco::Net::WebSocket>& socket, std::function<bool(const std::string& msg)> handler, diff --git a/loolwsd/test/httpwstest.cpp b/loolwsd/test/httpwstest.cpp index 97e391af1..423e69825 100644 --- a/loolwsd/test/httpwstest.cpp +++ b/loolwsd/test/httpwstest.cpp @@ -1438,11 +1438,9 @@ void HTTPWSTest::testLimitCursor( std::function<void(const std::shared_ptr<Poco: void HTTPWSTest::testInsertAnnotationWriter() { - std::string documentPath, documentURL; - getDocumentPathAndURL("hello.odt", documentPath, documentURL); - Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - - auto socket = loadDocAndGetSocket(_uri, documentURL); + const auto testname = "insertAnnotationWriter "; + const std::string docFilename = "hello.odt"; + auto socket = loadDocAndGetSocket(docFilename, _uri, testname); // Insert comment. sendTextFrame(socket, "uno .uno:InsertAnnotation"); @@ -1490,7 +1488,7 @@ void HTTPWSTest::testInsertAnnotationWriter() // Close and reopen the same document and test again. socket->shutdown(); std::cerr << "Reloading " << std::endl; - socket = loadDocAndGetSocket(_uri, documentURL); + socket = loadDocAndGetSocket(docFilename, _uri, testname); // Confirm that the text is in the comment and not doc body. // Click in the body. @@ -1520,11 +1518,9 @@ void HTTPWSTest::testInsertAnnotationWriter() void HTTPWSTest::testEditAnnotationWriter() { - std::string documentPath, documentURL; - getDocumentPathAndURL("with_comment.odt", documentPath, documentURL); - Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - - auto socket = loadDocAndGetSocket(_uri, documentURL); + const auto testname = "editAnnotationWriter "; + const std::string docFilename = "with_comment.odt"; + auto socket = loadDocAndGetSocket(docFilename, _uri, testname); // Click in the body. sendTextFrame(socket, "mouse type=buttondown x=1600 y=1600 count=1 buttons=1 modifier=0"); @@ -1532,7 +1528,7 @@ void HTTPWSTest::testEditAnnotationWriter() // Read body text. sendTextFrame(socket, "uno .uno:SelectAll"); sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8"); - auto res = getResponseLine(socket, "textselectioncontent:", "insertAnnotationWriter "); + auto res = getResponseLine(socket, "textselectioncontent:", testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: Hello world"), res); // Confirm that the comment is intact. @@ -1540,20 +1536,20 @@ void HTTPWSTest::testEditAnnotationWriter() sendTextFrame(socket, "mouse type=buttonup x=13855 y=1893 count=1 buttons=1 modifier=0"); sendTextFrame(socket, "uno .uno:SelectAll"); sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8"); - res = getResponseLine(socket, "textselectioncontent:", "insertAnnotationWriter "); + res = getResponseLine(socket, "textselectioncontent:", testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: blah blah xyz"), res); // Can we still edit the coment? sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\nand now for something completely different"); sendTextFrame(socket, "uno .uno:SelectAll"); sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8"); - res = getResponseLine(socket, "textselectioncontent:", "insertAnnotationWriter "); + res = getResponseLine(socket, "textselectioncontent:", testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: and now for something completely different"), res); // Close and reopen the same document and test again. socket->shutdown(); std::cerr << "Reloading " << std::endl; - socket = loadDocAndGetSocket(_uri, documentURL); + socket = loadDocAndGetSocket(docFilename, _uri, testname); // Confirm that the text is in the comment and not doc body. // Click in the body. @@ -1562,7 +1558,7 @@ void HTTPWSTest::testEditAnnotationWriter() // Read body text. sendTextFrame(socket, "uno .uno:SelectAll"); sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8"); - res = getResponseLine(socket, "textselectioncontent:", "insertAnnotationWriter "); + res = getResponseLine(socket, "textselectioncontent:", testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: Hello world"), res); // Confirm that the comment is still intact. @@ -1570,24 +1566,21 @@ void HTTPWSTest::testEditAnnotationWriter() sendTextFrame(socket, "mouse type=buttonup x=13855 y=1893 count=1 buttons=1 modifier=0"); sendTextFrame(socket, "uno .uno:SelectAll"); sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8"); - res = getResponseLine(socket, "textselectioncontent:", "insertAnnotationWriter "); + res = getResponseLine(socket, "textselectioncontent:", testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: and now for something completely different"), res); // Can we still edit the coment? sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\nnew text different"); sendTextFrame(socket, "uno .uno:SelectAll"); sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8"); - res = getResponseLine(socket, "textselectioncontent:", "insertAnnotationWriter "); + res = getResponseLine(socket, "textselectioncontent:", testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: new text different"), res); } void HTTPWSTest::testInsertAnnotationCalc() { - std::string documentPath, documentURL; - getDocumentPathAndURL("setclientpart.ods", documentPath, documentURL); - Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - - auto socket = loadDocAndGetSocket(_uri, documentURL); + const auto testname = "insertAnnotationCalc "; + auto socket = loadDocAndGetSocket("setclientpart.ods", _uri, testname); // Insert comment. sendTextFrame(socket, "uno .uno:InsertAnnotation"); @@ -1598,17 +1591,14 @@ void HTTPWSTest::testInsertAnnotationCalc() // Read it back. sendTextFrame(socket, "uno .uno:SelectAll"); sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8"); - auto res = getResponseLine(socket, "textselectioncontent:", "insertAnnotationCalc "); + auto res = getResponseLine(socket, "textselectioncontent:", testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: aaa bbb ccc"), res); } void HTTPWSTest::testCalcEditRendering() { - std::string documentPath, documentURL; - getDocumentPathAndURL("calc_render.xls", documentPath, documentURL); - Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - - auto socket = loadDocAndGetSocket(_uri, documentURL); + const auto testname = "calcEditRendering "; + auto socket = loadDocAndGetSocket("calc_render.xls", _uri, testname); const std::string x = "5000"; const std::string y = "5"; @@ -1617,12 +1607,12 @@ void HTTPWSTest::testCalcEditRendering() sendTextFrame(socket, "key type=input char=98 key=0"); sendTextFrame(socket, "key type=input char=99 key=0"); - assertResponseLine(socket, "cellformula: abc", "calcEditRendering "); + assertResponseLine(socket, "cellformula: abc", testname); const auto req = "tilecombine part=0 width=512 height=512 tileposx=3840 tileposy=0 tilewidth=7680 tileheight=7680"; sendTextFrame(socket, req); - const auto tile = getResponseMessage(socket, "tile:", "calcEditRendering "); + const auto tile = getResponseMessage(socket, "tile:", testname); std::cout << "size: " << tile.size() << std::endl; // Return early for now when on LO >= 5.2. commit 8f701840b57c263dc8cf18a78295faaf4ac56f13 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sun Aug 28 12:21:50 2016 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Sun Aug 28 12:45:12 2016 -0400 loolwsd: getrepairactions command added A new command and response, getrepairactions and repairactions: respectively, have been added to combine the undo and redo repair actions for the UI to promp the user. Change-Id: I0a72df6dfdd6b0075545b06a2aa5ea2df44faa72 diff --git a/loolwsd/ChildSession.cpp b/loolwsd/ChildSession.cpp index b9a2f4924..57216b988 100644 --- a/loolwsd/ChildSession.cpp +++ b/loolwsd/ChildSession.cpp @@ -203,7 +203,8 @@ bool ChildSession::_handleInput(const char *buffer, int length) tokens[0] == "saveas" || tokens[0] == "useractive" || tokens[0] == "userinactive" || - tokens[0] == "editlock:"); + tokens[0] == "editlock:" || + tokens[0] == "getrepairactions"); if (tokens[0] == "clientzoom") { @@ -280,6 +281,10 @@ bool ChildSession::_handleInput(const char *buffer, int length) Log::trace("Echoing back [" + firstLine + "]."); return sendTextFrame(firstLine); } + else if (tokens[0] == "getrepairactions") + { + return getRepairActions(buffer, length, tokens); + } else { assert(false && "Unknown command token."); @@ -441,6 +446,29 @@ bool ChildSession::getCommandValues(const char* /*buffer*/, int /*length*/, Stri return success; } +bool ChildSession::getRepairActions(const char* /*buffer*/, int /*length*/, StringTokenizer& /*tokens*/) +{ + std::unique_lock<std::recursive_mutex> lock(Mutex); + + if (_multiView) + _loKitDocument->setView(_viewId); + + std::ostringstream oss; + + char* ptrValues = _loKitDocument->getCommandValues(".uno:Undo"); + oss << "[{ \"undo\": " << ptrValues << "}, "; + std::free(ptrValues); + + ptrValues = _loKitDocument->getCommandValues(".uno:Redo"); + + oss << "{ \"redo\": " << ptrValues << "}]"; + std::free(ptrValues); + + Log::trace(oss.str()); + + return sendTextFrame("repairactions: " + oss.str()); +} + bool ChildSession::getPartPageRectangles(const char* /*buffer*/, int /*length*/) { std::unique_lock<std::recursive_mutex> lock(Mutex); diff --git a/loolwsd/ChildSession.hpp b/loolwsd/ChildSession.hpp index 7bd51220a..746be9ac6 100644 --- a/loolwsd/ChildSession.hpp +++ b/loolwsd/ChildSession.hpp @@ -77,6 +77,7 @@ private: bool sendFontRendering(const char *buffer, int length, Poco::StringTokenizer& tokens); bool getCommandValues(const char *buffer, int length, Poco::StringTokenizer& tokens); + bool getRepairActions(const char *buffer, int length, Poco::StringTokenizer& tokens); bool clientZoom(const char *buffer, int length, Poco::StringTokenizer& tokens); bool clientVisibleArea(const char *buffer, int length, Poco::StringTokenizer& tokens); diff --git a/loolwsd/ClientSession.cpp b/loolwsd/ClientSession.cpp index c0607a95c..d225268a9 100644 --- a/loolwsd/ClientSession.cpp +++ b/loolwsd/ClientSession.cpp @@ -117,6 +117,7 @@ bool ClientSession::_handleInput(const char *buffer, int length) tokens[0] != "downloadas" && tokens[0] != "getchildid" && tokens[0] != "gettextselection" && + tokens[0] != "getrepairactions" && tokens[0] != "paste" && tokens[0] != "insertfile" && tokens[0] != "key" && diff --git a/loolwsd/protocol.txt b/loolwsd/protocol.txt index 396a35971..3c0dad688 100644 --- a/loolwsd/protocol.txt +++ b/loolwsd/protocol.txt @@ -165,6 +165,15 @@ userinactive See 'useractive'. +getrepairactions + + Requests both Undo and Redo repair results. + They are both merged into a single json with two nodes, "redo" and "undo". + The value of each is the actions array. + + See 'repairactions' response. + + server -> client ================ @@ -350,6 +359,28 @@ redlinetablechanged: Signals that the redlines table has been modified. Redlines are used for tracking changes. +repairactions: + + The response to getrepairactions request. + Returns the actions arrays of both Undo and Redo repair. + This is a json with two entries, "undo" and "redo", each + with its respective actions array. + Example: + repairactions: [{ "undo": { + "actions": [ + { + "index": "0", + "comment": "Delete 'Hello world'", + "viewId": "0", + "dateTime": "2016-08-28T11:57:57,967527310" + } + ] + } + }, { "redo": { + "actions": "" + } + }] + child -> parent =============== _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits