╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ───────────────╮ │src/test/event/admin.zig│ ╰────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │302 } │ │303 │ │304 // update repo0 at a later timestamp -> keeps its original place │ │299 - try evt.consume(.server, .admin, .xit, repo_opts, io, allocator, &repo, evt.events_ref, &[_]evt.EventWithId{ │ │305 + try evt.consume(.server, .user, .xit, repo_opts, io, allocator, &repo, evt.events_ref, &[_]evt.EventWithId{ │ │306 .{ .id = std.fmt.bytesToHex(repo_ids[0], .lower), .author = author, .timestamp = 300, .event = .{ .repo = .{ .user_id = &user_id, .name = "repo0", .description = "updated" } } },│ │307 }); │ │308 { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │353 .password_hash = "", │ │354 } }, │ │355 }, │ │356 + }); │ │357 + const user_repo_path = try evt.userRepoPath(allocator, repos_dir, &user_id); │ │358 + defer allocator.free(user_repo_path); │ │359 + var user_repo = try evt.initUserRepo(io, allocator, user_repo_path); │ │360 + defer user_repo.deinit(io, allocator); │ │361 + try evt.consume(.server, .user, .xit, evt.user_repo_opts, io, allocator, &user_repo, evt.events_ref, &.{│ │362 .{ │ │363 .id = std.fmt.bytesToHex(repo_id, .lower), │ │364 .timestamp = 1, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────╮ │383 try target.add(io, allocator, &.{"README"}); │ │384 _ = try target.commit(io, allocator, .{ .message = "initial" }); │ │385 │ │374 - const draft_path = try fork.create(fork_repo_opts, io, allocator, repos_dir, &admin, .{ │ │386 + const draft_path = try fork.create(fork_repo_opts, io, allocator, repos_dir, &user_repo, .{│ │387 .target_branch = "master", │ │388 .id = fork_id_hex, │ │389 .user_id = user_id, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────╮ │390 .repo_id = repo_id, │ │391 + .repo_user_id = user_id, │ │392 .title = "add a feature", │ │393 .description = "a draft patch",│ │394 .labels = "enhancement", │ ╰────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │399 │ │400 var arena = std.heap.ArenaAllocator.init(allocator); │ │401 defer arena.deinit(); │ │389 - var moment = try evt.currentMoment(evt.admin_repo_opts, &admin); │ │390 - var record = (try evt.Fork.readById(evt.AdminDB, evt.admin_repo_opts.hash, moment, &arena, &fork_id)) orelse return error.NotFound;│ │391 - try std.testing.expectEqualSlices(u8, &user_id, record.event.user_id); │ │402 + var moment = try evt.currentMoment(evt.user_repo_opts, &user_repo); │ │403 + var record = (try evt.Fork.readById(evt.UserDB, evt.user_repo_opts.hash, moment, &arena, &fork_id)) orelse return error.NotFound; │ │404 try std.testing.expectEqualSlices(u8, &repo_id, record.event.repo_id); │ │405 + try std.testing.expectEqualSlices(u8, &user_id, record.event.repo_user_id); │ │406 try std.testing.expectEqual(.draft, record.event.stage); │ │394 - try std.testing.expectEqual(1, try indexedForkCount(moment, evt.Fork.user_id_to_fork_id_set_key, &user_id)); │ │395 - const draft_key = evt.Fork.draftKey(&repo_id, &user_id); │ │396 - try std.testing.expectEqual(1, try indexedForkCount(moment, evt.Fork.repo_user_to_draft_id_set_key, &draft_key)); │ │407 + try std.testing.expectEqual(1, try activeForkCount(moment)); │ │408 + try std.testing.expectEqual(1, try draftForkCount(moment, &repo_id)); │ │409 │ │410 var draft_repo = try rp.Repo(.xit, fork_repo_opts).open(io, allocator, .{ .path = draft_path }); │ │411 defer draft_repo.deinit(io, allocator); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │414 try std.testing.expectEqualStrings("add a feature", draft.event.title); │ │415 try std.testing.expectEqual(null, draft.event.revision); │ │416 │ │405 - var wrong_user_id = user_id; │ │406 - wrong_user_id[0] ^= 1; │ │407 - try std.testing.expectError(error.InvalidPatchDraft, fork.remove(io, allocator, repos_dir, &admin, &fork_id_hex, &wrong_user_id, author));│ │408 - try std.Io.Dir.accessAbsolute(io, draft_path, .{}); │ │409 - │ │410 - try fork.remove(io, allocator, repos_dir, &admin, &fork_id_hex, &user_id, author); │ │417 + try fork.remove(io, allocator, repos_dir, &user_repo, &fork_id_hex, author); │ │418 try std.testing.expectError(error.FileNotFound, std.Io.Dir.accessAbsolute(io, draft_path, .{})); │ │419 _ = arena.reset(.retain_capacity); │ │413 - moment = try evt.currentMoment(evt.admin_repo_opts, &admin); │ │414 - record = (try evt.Fork.readById(evt.AdminDB, evt.admin_repo_opts.hash, moment, &arena, &fork_id)) orelse return error.NotFound; │ │420 + moment = try evt.currentMoment(evt.user_repo_opts, &user_repo); │ │421 + record = (try evt.Fork.readById(evt.UserDB, evt.user_repo_opts.hash, moment, &arena, &fork_id)) orelse return error.NotFound; │ │422 try std.testing.expect(record.removed); │ │416 - try std.testing.expectEqual(0, try indexedForkCount(moment, evt.Fork.user_id_to_fork_id_set_key, &user_id)); │ │417 - try std.testing.expectEqual(0, try indexedForkCount(moment, evt.Fork.repo_user_to_draft_id_set_key, &draft_key)); │ │423 + try std.testing.expectEqual(0, try activeForkCount(moment)); │ │424 + try std.testing.expectEqual(0, try draftForkCount(moment, &repo_id)); │ │425 │ │419 - try fork.remove(io, allocator, repos_dir, &admin, &fork_id_hex, &user_id, author); │ │426 + try fork.remove(io, allocator, repos_dir, &user_repo, &fork_id_hex, author); │ │427 } │ │428 │ │422 -fn indexedForkCount( │ │423 - moment: evt.AdminDB.HashMap(.read_only), │ │424 - index_key: []const u8, │ │425 - parent_id: []const u8, │ │426 -) !u64 { │ │427 - const index_cursor = try moment.getCursor(hash.hashInt(evt.admin_repo_opts.hash, index_key)) orelse return 0; │ │428 - const index = try evt.AdminDB.HashMap(.read_only).init(index_cursor); │ │429 - const ids_cursor = try index.getCursor(hash.hashInt(evt.admin_repo_opts.hash, parent_id)) orelse return 0; │ │430 - const ids = try evt.AdminDB.SortedSet(.read_only).init(ids_cursor); │ │429 +fn draftForkCount(moment: evt.UserDB.HashMap(.read_only), repo_id: []const u8) !u64 { │ │430 + const index_cursor = try moment.getCursor(hash.hashInt(evt.user_repo_opts.hash, evt.Fork.repo_to_draft_id_set_key)) orelse return 0; │ │431 + const index = try evt.UserDB.HashMap(.read_only).init(index_cursor); │ │432 + const ids_cursor = try index.getCursor(hash.hashInt(evt.user_repo_opts.hash, repo_id)) orelse return 0; │ │433 + const ids = try evt.UserDB.SortedSet(.read_only).init(ids_cursor); │ │434 + return try ids.count(); │ │435 +} │ │436 + │ │437 +fn activeForkCount(moment: evt.UserDB.HashMap(.read_only)) !u64 { │ │438 + const ids_cursor = try moment.getCursor(hash.hashInt(evt.user_repo_opts.hash, evt.Fork.active_id_set_key)) orelse return 0; │ │439 + const ids = try evt.UserDB.SortedSet(.read_only).init(ids_cursor); │ │440 return try ids.count(); │ │441 } │ │442 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ───────────────╮ │src/test/event/patch.zig│ ╰────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │842 .password_hash = "", │ │843 } }, │ │844 }, │ │845 + }); │ │846 + const user_repo_path = try evt.userRepoPath(allocator, repos_dir, &user_id); │ │847 + defer allocator.free(user_repo_path); │ │848 + var user_repo = try evt.initUserRepo(io, allocator, user_repo_path); │ │849 + defer user_repo.deinit(io, allocator); │ │850 + try evt.consume(.server, .user, .xit, evt.user_repo_opts, io, allocator, &user_repo, evt.events_ref, &.{│ │851 .{ │ │852 .id = repo_id_hex, │ │853 .timestamp = 1, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────╮ │882 │ │883 const patch_id = evt.EventWithId.randomId(prng.random()); │ │884 const patch_id_hex = std.fmt.bytesToHex(patch_id, .lower); │ │879 - const draft_path = try fork.create(repo_opts, io, allocator, repos_dir, &admin, .{ │ │885 + const draft_path = try fork.create(repo_opts, io, allocator, repos_dir, &user_repo, .{│ │886 .target_branch = "master", │ │887 .id = patch_id_hex, │ │888 .user_id = user_id, │ ╰───────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────╮ │889 .repo_id = repo_id, │ │890 + .repo_user_id = user_id, │ │891 .title = "add the answer", │ │892 .labels = "enhancement", │ │893 .description = "adds a reusable answer constant",│ ╰──────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ │968 │ │969 const unpushed_id = evt.EventWithId.randomId(prng.random()); │ │970 const unpushed_id_hex = std.fmt.bytesToHex(unpushed_id, .lower); │ │964 - const unpushed_path = try fork.create(repo_opts, io, allocator, repos_dir, &admin, .{ │ │971 + const unpushed_path = try fork.create(repo_opts, io, allocator, repos_dir, &user_repo, .{│ │972 .id = unpushed_id_hex, │ │973 .user_id = user_id, │ │974 .repo_id = repo_id, │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯