1 /*! 2 * \brief Unit tests for \ref Apdu 3 * 4 * \copyright Copyright (c) 2017-2021 Governikus GmbH & Co. KG, Germany 5 */ 6 7 #include "ResponseApdu.h" 8 9 #include "LogHandler.h" 10 11 #include <QtCore> 12 #include <QtTest> 13 14 15 using namespace governikus; 16 17 18 class test_ResponceApdu 19 : public QObject 20 { 21 Q_OBJECT 22 23 private Q_SLOTS: initTestCase()24 void initTestCase() 25 { 26 Env::getSingleton<LogHandler>()->init(); 27 } 28 29 cleanup()30 void cleanup() 31 { 32 Env::getSingleton<LogHandler>()->resetBacklog(); 33 } 34 35 testRetryCounter_data()36 void testRetryCounter_data() 37 { 38 QTest::addColumn<QByteArray>("apdu"); 39 QTest::addColumn<int>("retryCounter"); 40 41 QTest::newRow("9000") << QByteArray::fromHex("9000") << 3; 42 QTest::newRow("63c2") << QByteArray::fromHex("63c2") << 2; 43 QTest::newRow("63c1") << QByteArray::fromHex("63c1") << 1; 44 QTest::newRow("63c0") << QByteArray::fromHex("63c0") << 0; 45 QTest::newRow("63c3") << QByteArray::fromHex("63c3") << -1; 46 QTest::newRow("6400") << QByteArray::fromHex("6400") << -1; 47 QTest::newRow("1234") << QByteArray::fromHex("1234") << -1; 48 QTest::newRow("12") << QByteArray::fromHex("12") << -1; 49 QTest::newRow("6283") << QByteArray::fromHex("6283") << 0; 50 QTest::newRow("empty") << QByteArray() << -1; 51 } 52 53 testRetryCounter()54 void testRetryCounter() 55 { 56 QFETCH(QByteArray, apdu); 57 QFETCH(int, retryCounter); 58 59 QCOMPARE(ResponseApdu(apdu).getRetryCounter(), retryCounter); 60 } 61 62 testReturnCode_data()63 void testReturnCode_data() 64 { 65 QTest::addColumn<StatusCode>("statusCode"); 66 QTest::addColumn<QByteArray>("bufferIn"); 67 QTest::addColumn<QByteArray>("bufferOut"); 68 69 QTest::newRow("empty") << StatusCode::EMPTY << QByteArray() << QByteArray::fromHex("0000"); 70 QTest::newRow("01") << StatusCode::INVALID << QByteArray::fromHex("01") << QByteArray::fromHex("0001"); 71 QTest::newRow("63c2") << StatusCode::PIN_RETRY_COUNT_2 << QByteArray::fromHex("63c2") << QByteArray::fromHex("63c2"); 72 QTest::newRow("6401") << StatusCode::INPUT_CANCELLED << QByteArray::fromHex("6401") << QByteArray::fromHex("6401"); 73 QTest::newRow("73c2") << StatusCode::INVALID << QByteArray::fromHex("73c2") << QByteArray::fromHex("0001"); 74 } 75 76 testReturnCode()77 void testReturnCode() 78 { 79 QFETCH(StatusCode, statusCode); 80 QFETCH(QByteArray, bufferIn); 81 QFETCH(QByteArray, bufferOut); 82 83 ResponseApdu apdu = ResponseApdu(statusCode); 84 QCOMPARE(apdu.getReturnCode(), statusCode); 85 QCOMPARE(apdu.getBuffer(), bufferOut); 86 87 apdu = ResponseApdu(bufferIn); 88 QCOMPARE(apdu.getReturnCode(), statusCode); 89 QCOMPARE(apdu.getBuffer(), bufferIn); 90 } 91 92 testCardReturnCode_data()93 void testCardReturnCode_data() 94 { 95 QTest::addColumn<CardReturnCode>("cardReturnCode"); 96 QTest::addColumn<StatusCode>("statCode"); 97 98 QTest::newRow("SUCCESS") << CardReturnCode::OK << StatusCode::SUCCESS; 99 QTest::newRow("INPUT_TIMEOUT") << CardReturnCode::INPUT_TIME_OUT << StatusCode::INPUT_TIMEOUT; 100 QTest::newRow("INPUT_CANCELLED") << CardReturnCode::CANCELLATION_BY_USER << StatusCode::INPUT_CANCELLED; 101 QTest::newRow("PASSWORDS_DIFFER") << CardReturnCode::NEW_PIN_MISMATCH << StatusCode::PASSWORDS_DIFFER; 102 QTest::newRow("PASSWORD_OUTOF_RANGE") << CardReturnCode::NEW_PIN_INVALID_LENGTH << StatusCode::PASSWORD_OUTOF_RANGE; 103 QTest::newRow("PIN_BLOCKED") << CardReturnCode::PIN_BLOCKED << StatusCode::PIN_BLOCKED; 104 QTest::newRow("default") << CardReturnCode::PROTOCOL_ERROR << StatusCode::NOT_YET_INITIALIZED; 105 } 106 107 testCardReturnCode()108 void testCardReturnCode() 109 { 110 QFETCH(CardReturnCode, cardReturnCode); 111 QFETCH(StatusCode, statCode); 112 113 ResponseApdu apdu = ResponseApdu(statCode); 114 QCOMPARE(apdu.getCardReturnCode(), cardReturnCode); 115 } 116 117 test_getSW2()118 void test_getSW2() 119 { 120 ResponseApdu apdu1 = ResponseApdu(QByteArray()); 121 ResponseApdu apdu2 = ResponseApdu(QByteArray("a")); 122 ResponseApdu apdu3 = ResponseApdu(QByteArray("date")); 123 QSignalSpy logSpy(Env::getSingleton<LogHandler>()->getEventHandler(), &LogEventHandler::fireLog); 124 125 QCOMPARE(apdu1.getSW2(), '\0'); 126 QCOMPARE(apdu2.getSW2(), 'a'); 127 QCOMPARE(apdu3.getSW2(), 'e'); 128 QCOMPARE(logSpy.count(), 1); 129 QVERIFY(logSpy.at(0).at(0).toString().contains("Buffer too short, returning 0")); 130 } 131 132 testGetSW1_data()133 void testGetSW1_data() 134 { 135 QTest::addColumn<SW1>("sw1"); 136 QTest::addColumn<QByteArray>("buffer"); 137 QTest::addColumn<QString>("warning"); 138 139 QTest::newRow("empty") << SW1::INVALID << QByteArray() << QString("Buffer too short, returning 0"); 140 QTest::newRow("0000") << SW1::INVALID << QByteArray::fromHex("0000") << QString(); 141 QTest::newRow("6100") << SW1::MORE_DATA_AVAILABLE << QByteArray::fromHex("6100") << QString(); 142 QTest::newRow("6900") << SW1::ERROR_COMMAND_NOT_ALLOWED << QByteArray::fromHex("6900") << QString(); 143 QTest::newRow("6c00") << SW1::WRONG_LE_FIELD << QByteArray::fromHex("6c00") << QString(); 144 QTest::newRow("invalid") << SW1::INVALID << QByteArray::fromHex("3300") << QString("Unknown SW1 value, returning INVALID, value: \"33\""); 145 } 146 147 testGetSW1()148 void testGetSW1() 149 { 150 QFETCH(SW1, sw1); 151 QFETCH(QByteArray, buffer); 152 QFETCH(QString, warning); 153 QSignalSpy logSpy(Env::getSingleton<LogHandler>()->getEventHandler(), &LogEventHandler::fireLog); 154 155 ResponseApdu apdu = ResponseApdu(buffer); 156 QCOMPARE(apdu.getSW1(), sw1); 157 if (!warning.isEmpty()) 158 { 159 QCOMPARE(logSpy.count(), 1); 160 QVERIFY(logSpy.takeFirst().at(0).toString().contains(warning)); 161 } 162 } 163 164 165 }; 166 167 168 QTEST_GUILESS_MAIN(test_ResponceApdu) 169 #include "test_ResponseApdu.moc" 170