M12b: category contract v2 on the server (schema 2, fourteen defaults, finer import mapping)
- migrations/0002_categories_v2.sql, byte-identical to contracts/schema/migrations/0002_categories_v2.sql (SPEC §14.1.1), with an identity test; SCHEMA_VERSION = 2 (E-1 reports it, the importer's check follows). - Seed test on a fresh database (the fourteen rows of AC-7.2, server_version 11 to 14) and an upgrade test of a v1 database in use (0001 applied through the migrator, then users, a custom, a renamed and an archived default, an account, a recurring template, expenses): every earlier row unchanged, the four rows above the old sequence, foreign_key_check empty, schema_version 2, a pull from the old cursor returns exactly the four rows. - DefaultCategoryKey with the fourteen keys (wire enum and contracts/openapi.yaml); icons 33 and colours 14 (§9.7) in validation. - The two category examples M12a held back (E-26 response-default, sync/pull-page-categories-v2) and its contracts-check patch for them and the enum. - Importer: splitwise_categories.csv per the §10.8 v0.8 table (D-053), DEFAULT_KEYS of fourteen, synthetic fixtures for the finer mapping (Insurance/Försäkringar to insurance among them), a schema-1 refusal test. - Test harnesses seed users at server_version 15/16 (after the fourteen seeds); pull counts 10 -> 14. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
This commit is contained in:
@@ -171,7 +171,7 @@ impl TestApp {
|
||||
/// Only the admin (Jacob) with one device: the household is incomplete.
|
||||
pub async fn admin_only() -> Self {
|
||||
let app = Self::empty().await;
|
||||
app.insert_user(ADMIN_ID, "admin", "Jacob", 11).await;
|
||||
app.insert_user(ADMIN_ID, "admin", "Jacob", 15).await;
|
||||
app.insert_device(
|
||||
ADMIN_DEVICE_ID,
|
||||
ADMIN_ID,
|
||||
@@ -186,7 +186,7 @@ impl TestApp {
|
||||
/// Admin Jacob and member Anna, one device each, plus a revoked old device of the admin.
|
||||
pub async fn household() -> Self {
|
||||
let app = Self::admin_only().await;
|
||||
app.insert_user(MEMBER_ID, "member", "Anna", 12).await;
|
||||
app.insert_user(MEMBER_ID, "member", "Anna", 16).await;
|
||||
app.insert_device(
|
||||
MEMBER_DEVICE_ID,
|
||||
MEMBER_ID,
|
||||
|
||||
@@ -186,7 +186,7 @@ async fn e3_invalid_request_and_validation_failed() {
|
||||
async fn e3_household_full_when_two_users_exist() {
|
||||
let app = TestApp::admin_only().await;
|
||||
let code = new_invite(&app, InviteKind::Partner, None).await;
|
||||
app.insert_user(MEMBER_ID, "member", "Anna", 12).await;
|
||||
app.insert_user(MEMBER_ID, "member", "Anna", 16).await;
|
||||
let reply = accept(&app, accept_body(&code, Some("Bertil"))).await;
|
||||
assert_error(&reply, 409, "household_full");
|
||||
}
|
||||
|
||||
@@ -19,11 +19,16 @@ async fn e7_returns_user_device_household_and_public_url() {
|
||||
.insert("x-kvitt-app-version", "41".parse().unwrap());
|
||||
let reply = app.send(request).await;
|
||||
assert_eq!(reply.status, 200);
|
||||
// `server_version` is volatile here: the example's users have 11 and 12 (schema 1, after ten seeded
|
||||
// categories); since migration 0002 seeds fourteen, the harness's users have 15 and 16 (SPEC §14.1.1).
|
||||
assert_like_example(
|
||||
&reply.json,
|
||||
"E-7-me/response.json",
|
||||
&["created_at", "updated_at", "last_seen_at"],
|
||||
&["created_at", "updated_at", "last_seen_at", "server_version"],
|
||||
);
|
||||
assert_eq!(reply.json["user"]["server_version"], 15);
|
||||
assert_eq!(reply.json["household"][0]["server_version"], 15);
|
||||
assert_eq!(reply.json["household"][1]["server_version"], 16);
|
||||
assert_eq!(reply.json["device"]["id"], ADMIN_DEVICE_ID);
|
||||
assert_eq!(reply.json["device"]["is_current"], true);
|
||||
let member = app.call(Method::GET, "/me", &member_token(), None).await;
|
||||
|
||||
Reference in New Issue
Block a user