Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/app/models/SettingsModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ class SettingsModel : public QObject {

Q_PROPERTY(bool loggingEnabled READ loggingEnabled WRITE setLoggingEnabled NOTIFY loggingEnabledChanged)
Q_PROPERTY(QString logFilePath READ logFilePath NOTIFY loggingEnabledChanged)
/// True only in debug builds. Gates developer-only affordances in QML —
/// notably the Test Exception button, which deliberately crashes the app
/// and must never be reachable in a shipped build.
Q_PROPERTY(bool debugBuild READ debugBuild CONSTANT)

public:
explicit SettingsModel(QObject *parent = nullptr);
Expand All @@ -20,6 +24,16 @@ class SettingsModel : public QObject {
void setLoggingEnabled(bool enabled);
QString logFilePath() const;

/// Qt defines QT_NO_DEBUG for release configurations; packaging builds all
/// use CMAKE_BUILD_TYPE=Release, so this is false in every shipped package.
bool debugBuild() const {
#ifdef QT_NO_DEBUG
return false;
#else
return true;
#endif
}

Q_INVOKABLE void saveThemeDark(bool dark);
Q_INVOKABLE void openBugReport();
Q_INVOKABLE void testCrash() {
Expand Down
5 changes: 3 additions & 2 deletions src/app/qml/AppSettingsView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,10 @@ Item {
}
}

// Test crash button
// Test crash button — debug builds only. This deliberately throws, so
// it must never be reachable in a shipped package (see issue #146).
Rectangle {
visible: SettingsModel.loggingEnabled
visible: SettingsModel.debugBuild && SettingsModel.loggingEnabled
width: 180; height: 40
radius: 4; color: "transparent"
border.color: "#ff4444"; border.width: 1
Expand Down
24 changes: 24 additions & 0 deletions tests/test_settings_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,28 @@ TEST_F(SettingsModelTest, LogFilePathReturnsNonEmpty) {
SUCCEED();
}


// --- debug-build gating for the test-crash affordance ----------------------
//
// The "Test Exception" button deliberately crashes the app. It was gated only
// on loggingEnabled, which is on by default, so it shipped to end users and
// produced real crash reports (issue #146). It must be a debug-build-only
// affordance.

TEST_F(SettingsModelTest, DebugBuildPropertyIsExposedToQml) {
SettingsModel m;
const QVariant v = m.property("debugBuild");
ASSERT_TRUE(v.isValid()) << "debugBuild must be a Q_PROPERTY so QML can gate on it";
EXPECT_EQ(v.metaType().id(), QMetaType::Bool);
}

TEST_F(SettingsModelTest, DebugBuildReflectsBuildConfiguration) {
SettingsModel m;
#ifdef QT_NO_DEBUG
EXPECT_FALSE(m.debugBuild()) << "release builds must not expose the crash affordance";
#else
EXPECT_TRUE(m.debugBuild()) << "debug builds keep the crash affordance available";
#endif
}

} // namespace logitune::test
Loading