[CrashReporting] Real send path with consent gating (DSN still placeholder)

require_user_consent + give/revoke around the Ask dialog, message event
with in-memory crash-log.txt bytes attachment, before_send scrubs
message/logentry/breadcrumbs/data of cockatrice:// secrets. Failure box
offers Save (shows path) / Discard (revokes + rejects) / Cancel (back
to dialog); reject() override so X/Escape cannot bypass revocation;
silent AlwaysSend path falls back to a local file. Empty DSN keeps the
previous mock behavior byte-identical.

Tests: 528/528 ctest green, format clean, code + UI gates PASS.
This commit is contained in:
Lukas Brübach 2026-10-14 09:25:05 +02:00 • committed by GitHub
parent 0d3750f2be
commit 038e56aab6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 331 additions and 34 deletions

View file

@ -1,5 +1,6 @@
#include "client/crash/crash_reporter.h"
#include <QDir>
#include <QString>
#include <gtest/gtest.h>
#include <libcockatrice/settings/personal_settings.h>
@ -39,7 +40,7 @@ TEST(CrashReporterTest, RedactCockatriceUrlsLeavesOtherTextAlone)
TEST(CrashReporterTest, InitSkippedWithoutDsn)
{
CrashReporter reporter;
reporter.init(QString(), QStringLiteral("3.1.2"), QStringLiteral("/tmp/cockatrice-crash-test"),
reporter.init(QString(), QStringLiteral("3.1.2"), QDir::tempPath() + QStringLiteral("/cockatrice-crash-test"),
PersonalSettings::CrashReportingMode::Ask);
ASSERT_FALSE(reporter.isReady());
reporter.shutdown();
@ -50,7 +51,8 @@ TEST(CrashReporterTest, InitSkippedWhenNeverSend)
{
CrashReporter reporter;
reporter.init(QStringLiteral("https://key@sentry.io/1"), QStringLiteral("3.1.2"),
QStringLiteral("/tmp/cockatrice-crash-test"), PersonalSettings::CrashReportingMode::NeverSend);
QDir::tempPath() + QStringLiteral("/cockatrice-crash-test"),
PersonalSettings::CrashReportingMode::NeverSend);
ASSERT_FALSE(reporter.isReady());
reporter.shutdown();
}
@ -78,6 +80,21 @@ TEST(CrashReporterTest, ShutdownWithoutInitIsSafe)
ASSERT_FALSE(reporter.isReady());
}
TEST(CrashReporterTest, ConsentAndSendWithoutDsnAreSafeNoOps)
{
CrashReporter reporter;
reporter.init(QString(), QStringLiteral("3.1.2"), QDir::tempPath() + QStringLiteral("/cockatrice-crash-test"),
PersonalSettings::CrashReportingMode::Ask);
ASSERT_FALSE(reporter.isReady());
reporter.giveConsent();
reporter.revokeConsent();
ASSERT_FALSE(reporter.isReady());
ASSERT_FALSE(reporter.sendReport(QStringLiteral("preview")));
ASSERT_FALSE(reporter.sendReport(QString()));
reporter.shutdown();
ASSERT_FALSE(reporter.isReady());
}
} // namespace
int main(int argc, char **argv)