File: qr-input.cpp

package info (click to toggle)
keysmith 25.08.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,276 kB
  • sloc: cpp: 11,649; xml: 352; sh: 121; makefile: 3
file content (117 lines) | stat: -rw-r--r-- 4,819 bytes parent folder | download | duplicates (2)
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
/*
 * SPDX-License-Identifier: GPL-3.0-or-later
 * SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com>
 */
#include "model/input.h"
#include "model/qr.h"

#include <QTest>

class QrInputTest : public QObject // clazy:exclude=ctor-missing-parent-argument
{
    Q_OBJECT
private Q_SLOTS:
    void testValidUri(void);
    void testValidUri_data(void);
    void testInvalidUri(void);
    void testInvalidUri_data(void);
};

static void define_valid_test_case(const char *testCase,
                                   const QString &uri,
                                   const QString &name,
                                   const QString &issuer,
                                   const QString &secret,
                                   const QString &counter,
                                   uint tokenLength,
                                   uint timeStep,
                                   model::AccountInput::TokenType type,
                                   model::AccountInput::TOTPAlgorithm algorithm)
{
    QTest::newRow(testCase) << uri << name << issuer << secret << counter << tokenLength << timeStep << type << algorithm;
}

static void define_invalid_test_case(const char *testCase, const QString &uri)
{
    QTest::newRow(testCase) << uri;
}

void QrInputTest::testValidUri(void)
{
    QFETCH(QString, uri);

    model::AccountInput target;

    auto result = model::QrParameters::parse(uri);
    QVERIFY2(result, "should be able to parse valid URIs");

    result->populate(&target);

    QTEST(target.name(), "name");
    QTEST(target.issuer(), "issuer");
    QTEST(target.secret(), "secret");
    QTEST(target.counter(), "counter");
    QTEST(target.tokenLength(), "tokenLength");
    QTEST(target.timeStep(), "timeStep");
    QTEST(target.type(), "type");
    QTEST(target.algorithm(), "algorithm");
}

void QrInputTest::testValidUri_data(void)
{
    QTest::addColumn<QString>("uri");
    QTest::addColumn<QString>("name");
    QTest::addColumn<QString>("issuer");
    QTest::addColumn<QString>("secret");
    QTest::addColumn<QString>("counter");
    QTest::addColumn<uint>("tokenLength");
    QTest::addColumn<uint>("timeStep");
    QTest::addColumn<model::AccountInput::TokenType>("type");
    QTest::addColumn<model::AccountInput::TOTPAlgorithm>("algorithm");

    define_valid_test_case("hotp (all fields set)",
                           QStringLiteral("otpauth://hotp/issuer:valid?secret=VALUE&digits=8&period=60&issuer=issuer&counter=42&algorithm=sha512"),
                           QStringLiteral("valid"),
                           QStringLiteral("issuer"),
                           QStringLiteral("VALUE==="),
                           QStringLiteral("42"),
                           8U,
                           60U,
                           model::AccountInput::TokenType::Hotp,
                           model::AccountInput::TOTPAlgorithm::Sha512);
}

void QrInputTest::testInvalidUri(void)
{
    QFETCH(QString, uri);
    QVERIFY2(!model::QrParameters::parse(uri), "should reject invalid URIs");
}

void QrInputTest::testInvalidUri_data(void)
{
    QTest::addColumn<QString>("uri");

    define_invalid_test_case("token length not a number", QStringLiteral("otpauth://totp/invalid?secret=VALUE&digits=nan"));
    define_invalid_test_case("token length too small", QStringLiteral("otpauth://totp/invalid?secret=VALUE&digits=2"));
    define_invalid_test_case("token length too large", QStringLiteral("otpauth://totp/invalid?secret=VALUE&digits=22"));

    define_invalid_test_case("time step not a number", QStringLiteral("otpauth://totp/invalid?secret=VALUE&period=nan"));
    define_invalid_test_case("time step too small", QStringLiteral("otpauth://totp/invalid?secret=VALUE&period=0"));
    define_invalid_test_case("time step too large", QStringLiteral("otpauth://totp/invalid?secret=VALUE&period=999999999999"));

    define_invalid_test_case("invalid base32 secret", QStringLiteral("otpauth://totp/invalid?secret=19"));
    define_invalid_test_case("empty secret", QStringLiteral("otpauth://totp/invalid?secret="));

    define_invalid_test_case("counter not a number", QStringLiteral("otpauth://hotp/invalid?secret=VALUE&counter=nan"));

    define_invalid_test_case("invalid algorithm ", QStringLiteral("otpauth://totp/invalid?secret=VALUE&algorithm=foo"));

    define_invalid_test_case("name contains non-printable characters", QStringLiteral("otpauth://totp/inv%00alid?secret=VALUE"));

    define_invalid_test_case("issuer contains non-printable characters", QStringLiteral("otpauth://totp/iss%00:invalid?secret=VALUE"));
    define_invalid_test_case("issuer parameter contains non-printable characters", QStringLiteral("otpauth://totp/invalid?secret=VALUE&issuer=iss%03"));
}

QTEST_APPLESS_MAIN(QrInputTest)

#include "qr-input.moc"