@@ -28,6 +28,12 @@ private Q_SLOTS:
2828 void parseGpgColonOutputWithGrpRecord ();
2929 void parseGpgColonOutputUnknownRecordTypes ();
3030 void parseGpgColonOutputAllPublicRecordTypes ();
31+ void multipleUidRecordsOnlyFirstNameUsed ();
32+ void pubRecordDoesNotSetHaveSecret ();
33+ void secRecordSetsHaveSecretOnlyWhenSecretTrue ();
34+ void createdDateParsedFromEpoch ();
35+ void expiryDateParsedFromEpoch ();
36+ void fprWithEmptyKeyIdIsNoop ();
3137};
3238
3339void tst_gpgkeystate::parseMultiKeyPublic () {
@@ -384,5 +390,82 @@ void tst_gpgkeystate::parseGpgColonOutputAllPublicRecordTypes() {
384390 QVERIFY2 (!result.first ().name .isEmpty (), " UID name should be populated" );
385391}
386392
393+ void tst_gpgkeystate::multipleUidRecordsOnlyFirstNameUsed () {
394+ const QString input = QStringLiteral (
395+ " pub:u:4096:1:KEYID001:1774947438:::u::::\n "
396+ " uid:u::::1774947438::H1::First Name <first@test.org>::::\n "
397+ " uid:u::::1774947438::H2::Second Name <second@test.org>::::\n " );
398+ QList<UserInfo> result = parseGpgColonOutput (input, false );
399+ QVERIFY2 (result.size () == 1 , " one key expected" );
400+ QVERIFY2 (result.first ().name == QStringLiteral (" First Name <first@test.org>" ),
401+ " only the first uid record should set the name" );
402+ }
403+
404+ void tst_gpgkeystate::pubRecordDoesNotSetHaveSecret () {
405+ const QString input =
406+ QStringLiteral (" pub:u:4096:1:PUBKEY001:1774947438:::u::::\n "
407+ " uid:u::::1774947438::H::Alice <alice@test.org>::::\n " );
408+ QList<UserInfo> result = parseGpgColonOutput (input, true );
409+ QVERIFY2 (result.size () == 1 , " one key expected" );
410+ QVERIFY2 (!result.first ().have_secret ,
411+ " pub record must not set have_secret even when secret=true" );
412+ }
413+
414+ void tst_gpgkeystate::secRecordSetsHaveSecretOnlyWhenSecretTrue () {
415+ const QString secLine =
416+ QStringLiteral (" sec:u:4096:1:SECKEY001:1774947438:::u::::\n "
417+ " uid:u::::1774947438::H::Bob <bob@test.org>::::\n " );
418+
419+ QList<UserInfo> withSecret = parseGpgColonOutput (secLine, true );
420+ QVERIFY2 (withSecret.size () == 1 , " one key expected with secret=true" );
421+ QVERIFY2 (withSecret.first ().have_secret ,
422+ " sec record must set have_secret when secret=true" );
423+
424+ QList<UserInfo> withoutSecret = parseGpgColonOutput (secLine, false );
425+ QVERIFY2 (withoutSecret.size () == 1 , " one key expected with secret=false" );
426+ QVERIFY2 (!withoutSecret.first ().have_secret ,
427+ " sec record must not set have_secret when secret=false" );
428+ }
429+
430+ void tst_gpgkeystate::createdDateParsedFromEpoch () {
431+ const qint64 epoch = 1700000000 ;
432+ const QString input = QString (" pub:u:4096:1:DATEKEY01:%1:::u::::\n "
433+ " uid:u::::%1::H::Date Test <dt@test.org>::::\n " )
434+ .arg (epoch);
435+ QList<UserInfo> result = parseGpgColonOutput (input, false );
436+ QVERIFY2 (result.size () == 1 , " one key expected" );
437+ QVERIFY2 (result.first ().created .isValid (),
438+ " created date must be valid when epoch is present" );
439+ QVERIFY2 (result.first ().created .toSecsSinceEpoch () == epoch,
440+ " created date must round-trip through epoch seconds" );
441+ }
442+
443+ void tst_gpgkeystate::expiryDateParsedFromEpoch () {
444+ const qint64 created = 1700000000 ;
445+ const qint64 expiry = 1800000000 ;
446+ const QString input =
447+ QString (" pub:u:4096:1:EXPKEY001:%1:%2:u::::\n "
448+ " uid:u::::%1::H::Expiry Test <et@test.org>::::\n " )
449+ .arg (created)
450+ .arg (expiry);
451+ QList<UserInfo> result = parseGpgColonOutput (input, false );
452+ QVERIFY2 (result.size () == 1 , " one key expected" );
453+ QVERIFY2 (result.first ().expiry .isValid (),
454+ " expiry date must be valid when epoch is present" );
455+ QVERIFY2 (result.first ().expiry .toSecsSinceEpoch () == expiry,
456+ " expiry date must round-trip through epoch seconds" );
457+ }
458+
459+ void tst_gpgkeystate::fprWithEmptyKeyIdIsNoop () {
460+ UserInfo user;
461+ QStringList props;
462+ for (int i = 0 ; i < 10 ; ++i)
463+ props.append (QString ());
464+ props[9 ] = QStringLiteral (" SOMEFINGERPRINT" );
465+ handleFprRecord (props, user);
466+ QVERIFY2 (user.key_id .isEmpty (),
467+ " fpr record must not update key_id when key_id is empty" );
468+ }
469+
387470QTEST_MAIN (tst_gpgkeystate)
388471#include " tst_gpgkeystate.moc"
0 commit comments