Files
Kareer/autotests/jobsdatabasetest.cpp
T
austinandClaude Fable 5 170129feec
Lint / REUSE compliance (push) Failing after 3s
Build and Test / Build and run tests (push) Failing after 1s
Lint / clang-format (push) Failing after 5s
Fix the Lint CI workflow (broken since v0.1.2)
clang-format job: the flatpak CI image has no ECM on the host, so the
configure step that generated .clang-format could never run. Commit the
ECM-generated .clang-format instead (it is MIT, LICENSES/MIT.txt added),
drop the container, pin clang-format 22.1.8 from PyPI to match the
version the tree is formatted with, and reformat the sources to match.

REUSE job: add the missing CC0-1.0 license text, a copyright line for
the metainfo, REUSE.toml coverage for README/CONTRIBUTING/.gitignore,
and REUSE-Ignore markers around CONTRIBUTING.md's SPDX example so the
parser stops reading prose as a license declaration. reuse lint now
passes locally (54/54 files).

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019FXfh48mASRsE1WEhy9jcM
2026-08-31 19:23:01 -05:00

151 lines
4.4 KiB
C++

/*
SPDX-FileCopyrightText: 2026 ToServeTheKing <[email protected]>
SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "jobsdatabase.h"
#include "job.h"
#include <QTemporaryDir>
#include <QtTest>
namespace
{
QString dbPathIn(const QTemporaryDir &dir)
{
return dir.path() + QStringLiteral("/test.sqlite");
}
}
class JobsDatabaseTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void addAndRetrieve()
{
QTemporaryDir dir;
QVERIFY(dir.isValid());
JobsDatabase db(dbPathIn(dir));
QVERIFY(db.isOpen());
Job job;
job.company = QStringLiteral("Acme Corp");
job.title = QStringLiteral("Software Engineer");
job.dateApplied = QDate(2026, 6, 1);
job.salaryMin = 120000;
job.salaryMax = 150000;
QVERIFY(db.addJob(job));
QVERIFY(job.id > 0);
QCOMPARE(job.stage, QStringLiteral("Applied"));
QVERIFY(job.createdAt.isValid());
const auto fetched = db.jobById(job.id);
QVERIFY(fetched.has_value());
QCOMPARE(fetched->company, QStringLiteral("Acme Corp"));
QCOMPARE(fetched->salaryMin, 120000);
QCOMPARE(fetched->salaryMax, 150000);
QCOMPARE(fetched->stage, QStringLiteral("Applied"));
const auto transitions = db.stageTransitions();
QCOMPARE(transitions.size(), 1);
QVERIFY(transitions.first().fromStage.isEmpty());
QCOMPARE(transitions.first().toStage, QStringLiteral("Applied"));
}
void rejectsUnknownStage()
{
QTemporaryDir dir;
JobsDatabase db(dbPathIn(dir));
Job job;
job.company = QStringLiteral("Acme");
job.title = QStringLiteral("Engineer");
job.stage = QStringLiteral("Bogus");
QVERIFY(!db.addJob(job));
QVERIFY(!db.lastError().isEmpty());
}
void updateJobDoesNotTouchStage()
{
QTemporaryDir dir;
JobsDatabase db(dbPathIn(dir));
Job job;
job.company = QStringLiteral("A");
job.title = QStringLiteral("B");
QVERIFY(db.addJob(job));
Job edited = *db.jobById(job.id);
edited.company = QStringLiteral("Updated Co");
edited.stage = QStringLiteral("Rejected"); // updateJob must ignore this
QVERIFY(db.updateJob(edited));
const auto fetched = db.jobById(job.id);
QCOMPARE(fetched->company, QStringLiteral("Updated Co"));
QCOMPARE(fetched->stage, QStringLiteral("Applied"));
}
void stageTransitionsRecordHistory()
{
QTemporaryDir dir;
JobsDatabase db(dbPathIn(dir));
Job job;
job.company = QStringLiteral("A");
job.title = QStringLiteral("B");
QVERIFY(db.addJob(job));
QVERIFY(db.setStage(job.id, QStringLiteral("Screening")));
QVERIFY(db.setStage(job.id, QStringLiteral("Screening"))); // no-op: same stage
QVERIFY(db.setStage(job.id, QStringLiteral("Rejected")));
const auto transitions = db.stageTransitions();
// Start->Applied, Applied->Screening, Screening->Rejected (the no-op adds nothing)
QCOMPARE(transitions.size(), 3);
QCOMPARE(transitions.at(1).fromStage, QStringLiteral("Applied"));
QCOMPARE(transitions.at(1).toStage, QStringLiteral("Screening"));
QCOMPARE(transitions.at(2).fromStage, QStringLiteral("Screening"));
QCOMPARE(transitions.at(2).toStage, QStringLiteral("Rejected"));
const auto fetched = db.jobById(job.id);
QCOMPARE(fetched->stage, QStringLiteral("Rejected"));
}
void setStageRejectsUnknownStage()
{
QTemporaryDir dir;
JobsDatabase db(dbPathIn(dir));
Job job;
job.company = QStringLiteral("A");
job.title = QStringLiteral("B");
QVERIFY(db.addJob(job));
QVERIFY(!db.setStage(job.id, QStringLiteral("Bogus")));
QCOMPARE(db.jobById(job.id)->stage, QStringLiteral("Applied"));
}
void deleteCascadesHistory()
{
QTemporaryDir dir;
JobsDatabase db(dbPathIn(dir));
Job job;
job.company = QStringLiteral("A");
job.title = QStringLiteral("B");
QVERIFY(db.addJob(job));
QVERIFY(db.setStage(job.id, QStringLiteral("Screening")));
QVERIFY(db.deleteJob(job.id));
QVERIFY(!db.jobById(job.id).has_value());
QVERIFY(db.stageTransitions().isEmpty());
}
};
QTEST_GUILESS_MAIN(JobsDatabaseTest)
#include "jobsdatabasetest.moc"