Welcome to mirror list, hosted at ThFree Co, Russian Federation.

testremotediscovery.cpp « test - github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 05066a50494adc028064b0a4779bc2065b310173 (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
/*
 *    This software is in the public domain, furnished "as is", without technical
 *    support, and with no warranty, express or implied, as to its usefulness for
 *    any purpose.
 *
 */

#include <QtTest>
#include "syncenginetestutils.h"
#include <syncengine.h>
#include <localdiscoverytracker.h>

using namespace OCC;

struct FakeBrokenXmlPropfindReply : FakePropfindReply {
    FakeBrokenXmlPropfindReply(FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op,
                               const QNetworkRequest &request, QObject *parent)
        : FakePropfindReply(remoteRootFileInfo, op, request, parent) {
        QVERIFY(payload.size() > 50);
        // turncate the XML
        payload.chop(20);
    }
};

struct MissingPermissionsPropfindReply : FakePropfindReply {
    MissingPermissionsPropfindReply(FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op,
                               const QNetworkRequest &request, QObject *parent)
        : FakePropfindReply(remoteRootFileInfo, op, request, parent) {
        // If the propfind contains a single file without permissions, this is a server error
        const char toRemove[] = "<oc:permissions>RDNVCKW</oc:permissions>";
        auto pos = payload.indexOf(toRemove, payload.size()/2);
        QVERIFY(pos > 0);
        payload.remove(pos, sizeof(toRemove) - 1);
    }
};


enum ErrorKind : int {
    // Lower code are corresponding to HTML error code
    InvalidXML = 1000,
    MissingPermissions,
    Timeout,
};

Q_DECLARE_METATYPE(ErrorCategory)

class TestRemoteDiscovery : public QObject
{
    Q_OBJECT

private slots:

    void testRemoteDiscoveryError_data()
    {
        qRegisterMetaType<ErrorCategory>();
        QTest::addColumn<int>("errorKind");
        QTest::addColumn<QString>("expectedErrorString");

        QTest::newRow("404") << 404 << "File or directory not found: B";
        QTest::newRow("500") << 500 << "An error occurred while opening a folder B: Internal Server Fake Error";
        QTest::newRow("503") << 503 << "An error occurred while opening a folder B: Internal Server Fake Error";
        // 200 should be an error since propfind should return 207
        QTest::newRow("200") << 200 << "An error occurred while opening a folder B: Internal Server Fake Error";
        QTest::newRow("InvalidXML") << +InvalidXML << "An error occurred while opening a folder B: Unknown error";
        QTest::newRow("MissingPermissions") << +MissingPermissions << "A HTTP transmission error happened. B: The server file discovery reply is missing data.";
        QTest::newRow("Timeout") << +Timeout << "An error occurred while opening a folder B: Operation canceled";
    }


    // Check what happens when there is an error.
    void testRemoteDiscoveryError()
    {
        QFETCH(int, errorKind);
        QFETCH(QString, expectedErrorString);
        bool syncSucceeds = errorKind == 503; // 503 just ignore the temporarily unavailable directory

        FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() };

        // Do Some change as well
        fakeFolder.localModifier().insert("A/z1");
        fakeFolder.localModifier().insert("B/z1");
        fakeFolder.localModifier().insert("C/z1");
        fakeFolder.remoteModifier().insert("A/z2");
        fakeFolder.remoteModifier().insert("B/z2");
        fakeFolder.remoteModifier().insert("C/z2");

        auto oldLocalState = fakeFolder.currentLocalState();
        auto oldRemoteState = fakeFolder.currentRemoteState();

        fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *)
                -> QNetworkReply *{
            if (req.attribute(QNetworkRequest::CustomVerbAttribute) == "PROPFIND" && req.url().path().endsWith("/B")) {
                if (errorKind == InvalidXML) {
                    return new FakeBrokenXmlPropfindReply(fakeFolder.remoteModifier(), op, req, this);
                } else if (errorKind == MissingPermissions) {
                    return new MissingPermissionsPropfindReply(fakeFolder.remoteModifier(), op, req, this);
                } else if (errorKind == Timeout) {
                    return new FakeHangingReply(op, req, this);
                } else if (errorKind < 1000) {
                    return new FakeErrorReply(op, req, this, errorKind);
                }
            }
            return nullptr;
        });

        // So the test that test timeout finishes fast
        QScopedValueRollback<int> setHttpTimeout(AbstractNetworkJob::httpTimeout, errorKind == Timeout ? 1 : 10000);

        QSignalSpy errorSpy(&fakeFolder.syncEngine(), &SyncEngine::syncError);
        QCOMPARE(fakeFolder.syncOnce(), false);
        qDebug() << "errorSpy=" << errorSpy;

        // The folder B should not have been sync'ed (and in particular not removed)
        QCOMPARE(oldLocalState.children["B"], fakeFolder.currentLocalState().children["B"]);
        QCOMPARE(oldRemoteState.children["B"], fakeFolder.currentRemoteState().children["B"]);
        if (!syncSucceeds) {
            // Check we got the right error
            QCOMPARE(errorSpy.count(), 1);
            QVERIFY(errorSpy[0][0].toString().contains(expectedErrorString));
        } else {
            // The other folder should have been sync'ed as the sync just ignored the faulty dir
            QCOMPARE(fakeFolder.currentRemoteState().children["A"], fakeFolder.currentLocalState().children["A"]);
            QCOMPARE(fakeFolder.currentRemoteState().children["C"], fakeFolder.currentLocalState().children["C"]);
        }
    }
};

QTEST_GUILESS_MAIN(TestRemoteDiscovery)
#include "testremotediscovery.moc"