[Libreoffice-commits] online.git: Branch 'private/Ashod/repairactions' - 3 commits - loolwsd/ChildSession.cpp loolwsd/ChildSession.hpp loolwsd/ClientSession.cpp loolwsd/protocol.txt loolwsd/test

Ashod Nakashian (via logerrit) logerrit at kemper.freedesktop.org
Sat Dec 7 01:50:27 UTC 2019


Rebased ref, commits from common ancestor:
commit abdefeec68a0790f5b8ac567fb2ec2edca29697e
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Sun Aug 28 12:26:01 2016 -0400
Commit:     Ashod Nakashian <ashod.nakashian at 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.nakashian at collabora.co.uk>
AuthorDate: Sun Aug 28 12:25:40 2016 -0400
Commit:     Ashod Nakashian <ashod.nakashian at 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.nakashian at collabora.co.uk>
AuthorDate: Sun Aug 28 12:21:50 2016 -0400
Commit:     Ashod Nakashian <ashod.nakashian at 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
 ===============


More information about the Libreoffice-commits mailing list