summaryrefslogtreecommitdiffstats
path: root/test/UnitWOPIAsyncUpload_Close.cpp
blob: 3edee2a86c71b8643587caf92213914e79d16e27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <config.h>

#include "HttpRequest.hpp"
#include "Util.hpp"
#include "lokassert.hpp"

#include <WopiTestServer.hpp>
#include <Log.hpp>
#include <Unit.hpp>
#include <UnitHTTP.hpp>
#include <helpers.hpp>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Util/LayeredConfiguration.h>

/// Test Async uploading with simulated failing.
/// We modify the document, save, and attempt to upload,
/// which fails. We close the document and verify
/// that the document is uploaded upon closing.
// Modify, Save, Upload fails, close -> Upload.
class UnitWOPIAsyncUpload_Close : public WopiTestServer
{
    enum class Phase
    {
        Load,
        WaitLoadStatus,
        Modify,
        WaitModifiedStatus,
        WaitFirstPutFile,
        Close,
        WaitSecondPutFile,
        Polling
    } _phase;

public:
    UnitWOPIAsyncUpload_Close()
        : WopiTestServer("UnitWOPIAsyncUpload_Close")
        , _phase(Phase::Load)
    {
    }

    std::unique_ptr<http::Response>
    assertPutFileRequest(const Poco::Net::HTTPRequest& request) override
    {
        // We save twice. First right after loading, unmodified.
        if (_phase == Phase::WaitFirstPutFile)
        {
            LOG_TST("assertPutFileRequest: First PutFile, which will fail");

            LOG_TST("WaitFirstPutFile => Close");
            _phase = Phase::Close;

            LOK_ASSERT_EQUAL(std::string("true"), request.get("X-COOL-WOPI-IsModifiedByUser"));

            // We requested the save.
            LOK_ASSERT_EQUAL(std::string("false"), request.get("X-COOL-WOPI-IsAutosave"));

            // Fail with error.
            return Util::make_unique<http::Response>(http::StatusLine(404));
        }

        // This during closing the document.
        LOG_TST("assertPutFileRequest: Second PutFile, which will succeed");
        LOK_ASSERT_MESSAGE("Expected to be in Phase::WaitSecondPutFile",
                           _phase == Phase::WaitSecondPutFile);

        // the document is modified
        LOK_ASSERT_EQUAL(std::string("true"), request.get("X-COOL-WOPI-IsModifiedByUser"));

        // Triggered while closing.
        LOK_ASSERT_EQUAL(std::string("false"), request.get("X-COOL-WOPI-IsAutosave"));

        passTest("Document uploaded on closing as expected.");

        return nullptr;
    }

    /// The document is loaded.
    bool onDocumentLoaded(const std::string& message) override
    {
        LOG_TST("onDocumentLoaded: [" << message << ']');
        LOK_ASSERT_MESSAGE("Expected to be in Phase::WaitLoadStatus",
                           _phase == Phase::WaitLoadStatus);

        LOG_TST("onDocumentModified: Switching to Phase::Modify");
        _phase = Phase::Modify;

        SocketPoll::wakeupWorld();
        return true;
    }

    /// The document is modified. Save it.
    bool onDocumentModified(const std::string& message) override
    {
        LOG_TST("onDocumentModified: Doc (WaitModifiedStatus): [" << message << ']');
        LOK_ASSERT_MESSAGE("Expected to be in Phase::WaitModified",
                           _phase == Phase::WaitModifiedStatus);
        {
            LOG_TST("onDocumentModified: Switching to Phase::WaitFirstPutFile");
            _phase = Phase::WaitFirstPutFile;

            WSD_CMD("save dontTerminateEdit=0 dontSaveIfUnmodified=0 "
                    "extendedData=CustomFlag%3DCustom%20Value%3BAnotherFlag%3DAnotherValue");

            SocketPoll::wakeupWorld();
        }

        return true;
    }

    void invokeWSDTest() override
    {
        switch (_phase)
        {
            case Phase::Load:
            {
                LOG_TST("Load => WaitLoadStatus");
                _phase = Phase::WaitLoadStatus;

                LOG_TST("Load: initWebsocket.");
                initWebsocket("/wopi/files/0?access_token=anything");

                WSD_CMD("load url=" + getWopiSrc());
                break;
            }
            case Phase::WaitLoadStatus:
                break;
            case Phase::Modify:
            {
                LOG_TST("Modify => WaitModified");
                _phase = Phase::WaitModifiedStatus;

                WSD_CMD("key type=input char=97 key=0");
                WSD_CMD("key type=up char=0 key=512");
                break;
            }
            case Phase::WaitModifiedStatus:
                break;
            case Phase::WaitFirstPutFile:
                break;
            case Phase::Close:
            {
                LOG_TST("Close => WaitSecondPutFile");
                _phase = Phase::WaitSecondPutFile;

                WSD_CMD("closedocument");
                break;
            }
            case Phase::WaitSecondPutFile:
                break;
            case Phase::Polling:
            {
                // just wait for the results
                break;
            }
        }
    }
};

UnitBase* unit_create_wsd(void) { return new UnitWOPIAsyncUpload_Close(); }

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */