data/SendChecks.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "SendChecks.h" | ||
| 2 | |||
| 3 | #include "IdentityChoice.h" | ||
| 4 | |||
| 5 | #include <QRegularExpression> | ||
| 6 | |||
| 7 | namespace SendChecks { | ||
| 8 | |||
| 9 | 65 | QStringList defaultAttachmentWords() { | |
| 10 | 65 | return {QStringLiteral("attached"), QStringLiteral("attachment"), QStringLiteral("attachments"), | |
| 11 | 65 | QStringLiteral("enclosed"), QStringLiteral("see the file"), QStringLiteral("anbei"), | |
| 12 | 65 | QStringLiteral("Anhang"), QStringLiteral("angehängt"), QStringLiteral("im Anhang"), | |
| 13 |
2/4✓ Branch 37 → 38 taken 715 times.
✓ Branch 37 → 39 taken 65 times.
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 55 not taken.
|
845 | QStringLiteral("beigefügt"), QStringLiteral("Anlage")}; |
| 14 | 780 | } | |
| 15 | |||
| 16 | 53 | QString attachmentMention(const QString &text, const QStringList &words) { | |
| 17 |
2/2✓ Branch 55 → 4 taken 521 times.
✓ Branch 55 → 56 taken 43 times.
|
564 | for (const QString &word : words) { |
| 18 |
1/1✓ Branch 5 → 6 taken 521 times.
|
521 | const QString trimmed = word.trimmed(); |
| 19 |
3/6✓ Branch 7 → 8 taken 521 times.
✗ Branch 7 → 10 not taken.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 521 times.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 521 times.
|
521 | if (trimmed.isEmpty() || trimmed.size() > 100) continue; |
| 20 | // Whole words: no letter directly before or after the phrase. | ||
| 21 |
2/2✓ Branch 18 → 19 taken 521 times.
✓ Branch 22 → 23 taken 521 times.
|
1563 | const QRegularExpression pattern(QStringLiteral("(?<![\\p{L}\\p{N}])") + QRegularExpression::escape(trimmed) + |
| 22 |
1/1✓ Branch 23 → 24 taken 521 times.
|
1563 | QStringLiteral("(?![\\p{L}\\p{N}])"), |
| 23 |
1/1✓ Branch 24 → 25 taken 521 times.
|
1042 | QRegularExpression::CaseInsensitiveOption | QRegularExpression::UseUnicodePropertiesOption); |
| 24 |
1/1✓ Branch 33 → 34 taken 521 times.
|
521 | const auto match = pattern.match(text); |
| 25 |
4/4✓ Branch 34 → 35 taken 521 times.
✓ Branch 35 → 36 taken 10 times.
✓ Branch 35 → 38 taken 511 times.
✓ Branch 36 → 37 taken 10 times.
|
521 | if (match.hasMatch()) return match.captured(); |
| 26 | 541 | } | |
| 27 | 43 | return {}; | |
| 28 | } | ||
| 29 | |||
| 30 | namespace { | ||
| 31 | 80 | QString domainOf(const QString &address) { | |
| 32 | 80 | const qsizetype at = address.lastIndexOf(QLatin1Char('@')); | |
| 33 |
4/8✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 80 times.
✓ Branch 7 → 8 taken 80 times.
✓ Branch 8 → 9 taken 80 times.
✓ Branch 10 → 11 taken 80 times.
✗ Branch 10 → 12 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 16 not taken.
|
160 | return at < 0 ? QString() : address.mid(at + 1).toLower(); |
| 34 | } | ||
| 35 | } // namespace | ||
| 36 | |||
| 37 | 59 | QList<Finding> check(const Input &input) { | |
| 38 | 59 | QList<Finding> findings; | |
| 39 |
9/10✓ Branch 3 → 4 taken 9 times.
✓ Branch 3 → 11 taken 50 times.
✓ Branch 5 → 6 taken 9 times.
✗ Branch 5 → 11 not taken.
✓ Branch 7 → 8 taken 8 times.
✓ Branch 7 → 11 taken 1 time.
✓ Branch 9 → 10 taken 3 times.
✓ Branch 9 → 11 taken 5 times.
✓ Branch 12 → 13 taken 3 times.
✓ Branch 12 → 16 taken 56 times.
|
59 | if (input.to.isEmpty() && input.cc.isEmpty() && input.bcc.isEmpty() && input.invalidRecipients.isEmpty()) |
| 40 |
1/1✓ Branch 13 → 14 taken 3 times.
|
3 | findings.append({Kind::NoRecipient, {}, {}, 0, true}); |
| 41 |
2/2✓ Branch 24 → 18 taken 16 times.
✓ Branch 24 → 25 taken 59 times.
|
75 | for (const QString &address : input.invalidRecipients) |
| 42 | 16 | findings.append({Kind::InvalidRecipient, address, {}, 0, true}); | |
| 43 |
4/4✓ Branch 25 → 26 taken 59 times.
✓ Branch 28 → 29 taken 8 times.
✓ Branch 28 → 32 taken 51 times.
✓ Branch 29 → 30 taken 8 times.
|
59 | if (input.subject.trimmed().isEmpty()) findings.append({Kind::EmptySubject, {}, {}, 0, false}); |
| 44 |
2/2✓ Branch 32 → 33 taken 45 times.
✓ Branch 32 → 47 taken 14 times.
|
59 | if (input.attachmentCount == 0) { |
| 45 | const QString word = attachmentMention( | ||
| 46 |
4/4✓ Branch 34 → 35 taken 14 times.
✓ Branch 34 → 36 taken 31 times.
✓ Branch 35 → 37 taken 14 times.
✓ Branch 37 → 38 taken 45 times.
|
45 | input.newText, input.attachmentWords.isEmpty() ? defaultAttachmentWords() : input.attachmentWords); |
| 47 |
2/2✓ Branch 40 → 41 taken 4 times.
✓ Branch 40 → 45 taken 41 times.
|
49 | if (!word.isEmpty()) findings.append({Kind::ForgottenAttachment, word, {}, 0, false}); |
| 48 | 45 | } | |
| 49 |
2/2✓ Branch 55 → 49 taken 1 time.
✓ Branch 55 → 56 taken 59 times.
|
60 | for (const QString &file : input.filesOverLimit) findings.append({Kind::FileTooLarge, file, {}, 0, true}); |
| 50 |
5/6✓ Branch 57 → 58 taken 55 times.
✓ Branch 57 → 60 taken 4 times.
✓ Branch 58 → 59 taken 55 times.
✗ Branch 58 → 60 not taken.
✓ Branch 61 → 62 taken 55 times.
✓ Branch 61 → 81 taken 4 times.
|
59 | if (input.bcc.isEmpty() && !input.invitation) { |
| 51 | 55 | int external = 0; | |
| 52 |
2/2✓ Branch 76 → 64 taken 110 times.
✓ Branch 76 → 77 taken 55 times.
|
165 | for (const QStringList *field : {&input.to, &input.cc}) |
| 53 |
2/2✓ Branch 74 → 66 taken 80 times.
✓ Branch 74 → 75 taken 110 times.
|
190 | for (const QString &address : *field) |
| 54 |
3/3✓ Branch 67 → 68 taken 80 times.
✓ Branch 70 → 71 taken 35 times.
✓ Branch 70 → 72 taken 45 times.
|
80 | if (!input.ownDomains.contains(domainOf(address))) ++external; |
| 55 |
2/2✓ Branch 77 → 78 taken 1 time.
✓ Branch 77 → 81 taken 54 times.
|
55 | if (external >= input.manyRecipientsThreshold) |
| 56 |
1/1✓ Branch 78 → 79 taken 1 time.
|
1 | findings.append({Kind::ManyWithoutBcc, {}, {}, external, false}); |
| 57 | } | ||
| 58 |
5/6✓ Branch 82 → 83 taken 4 times.
✓ Branch 82 → 86 taken 55 times.
✓ Branch 84 → 85 taken 4 times.
✗ Branch 84 → 86 not taken.
✓ Branch 87 → 88 taken 4 times.
✓ Branch 87 → 102 taken 55 times.
|
59 | if (!input.originalSentTo.isEmpty() && !input.identityAddress.isEmpty()) { |
| 59 |
2/2✓ Branch 88 → 89 taken 4 times.
✓ Branch 89 → 90 taken 4 times.
|
4 | const QString original = IdentityChoice::withoutPlusTag(input.originalSentTo.toLower()); |
| 60 |
3/3✓ Branch 91 → 92 taken 4 times.
✓ Branch 94 → 95 taken 1 time.
✓ Branch 94 → 100 taken 3 times.
|
4 | if (original != input.identityAddress.toLower()) |
| 61 | 1 | findings.append({Kind::IdentityDiffers, input.originalSentTo, input.identityAddress, 0, false}); | |
| 62 | 4 | } | |
| 63 |
2/2✓ Branch 110 → 104 taken 1 time.
✓ Branch 110 → 111 taken 59 times.
|
60 | for (const QString &placeholder : input.placeholders) |
| 64 | 1 | findings.append({Kind::Placeholder, placeholder, {}, 0, false}); | |
| 65 |
5/6✓ Branch 111 → 112 taken 1 time.
✓ Branch 111 → 115 taken 58 times.
✓ Branch 113 → 114 taken 1 time.
✗ Branch 113 → 115 not taken.
✓ Branch 116 → 117 taken 1 time.
✓ Branch 116 → 121 taken 58 times.
|
60 | if (input.invitation && !input.bcc.isEmpty()) findings.append({Kind::InvitationBcc, {}, {}, int(input.bcc.size()), true}); |
| 66 |
3/4✓ Branch 121 → 122 taken 1 time.
✓ Branch 121 → 126 taken 58 times.
✓ Branch 122 → 123 taken 1 time.
✗ Branch 122 → 126 not taken.
|
59 | if (input.serverScheduledInvitation && input.invitationLosesContent) |
| 67 |
1/1✓ Branch 123 → 124 taken 1 time.
|
1 | findings.append({Kind::ServerInvitationLoses, {}, {}, 0, false}); |
| 68 |
3/3✓ Branch 126 → 127 taken 1 time.
✓ Branch 126 → 130 taken 58 times.
✓ Branch 127 → 128 taken 1 time.
|
59 | if (input.replyWithoutQuote) findings.append({Kind::QuoteUnavailable, {}, {}, 0, false}); |
| 69 | 59 | return findings; | |
| 70 | 24 | } | |
| 71 | |||
| 72 | } // namespace SendChecks | ||
| 73 |