╭ changed ────────╮ │src/test/undo.zig│ ╰─────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────╮ │137 try std.testing.expectEqual(null, session.next_page); │ │138 } │ │139 │ │140 -test "local git has no undo and local xit can undo and refresh" {│ │140 +test "local mode has no undo" { │ │141 inline for ([_]xit.repo.RepoKind{ .git, .xit }) |kind| { │ │142 var temp = std.testing.tmpDir(.{}); │ │143 defer temp.cleanup(); │ ╰──────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │147 { │ │148 var repo = try xit.repo.Repo(kind, .{}).init(io, allocator, .{ .path = path }); │ │149 defer repo.deinit(io, allocator); │ │150 - try repo.addConfig(io, allocator, .{ .name = "undo.value", .value = "first" }); │ │150 } │ │151 var session = ui.Session{ .arena = &arena, .page_arena = &arena, .io = io, .local = .{ .path = path, .repo_kind = kind }, .data = .{ .host_kind = .local } };│ │153 - const files = ui.RoutablePage.repoFilesRoute("", null, "", "", 0).?; │ │154 - const data = try ui.Repo.init(&arena, &session, files); │ │155 - try std.testing.expectEqual(kind == .xit, data.undo != null); │ │156 - if (kind == .git) { │ │157 - try std.testing.expectError(error.NotFound, ui.Repo.init(&arena, &session, ui.RoutablePage.repoUndoRoute("", null).?)); │ │158 - try std.testing.expectError(error.NotFound, Undo.execute(io, allocator, session.local.?, 1)); │ │159 - } else { │ │160 - Undo.handleRequest(allocator, &session, ui.RoutablePage.repoUndoRoute("", 999).?.repo_undo); │ │161 - try std.testing.expectEqualStrings("InvalidHistoryIndex", session.data.undo_failure.?); │ │162 - try std.testing.expectEqual(null, session.next_page); │ │163 - Undo.handleRequest(allocator, &session, ui.RoutablePage.repoUndoRoute("", 1).?.repo_undo); │ │164 - try std.testing.expectEqual(null, session.data.undo_failure); │ │165 - const refreshed = try ui.Repo.init(&arena, &session, session.next_page.?); │ │166 - try std.testing.expectEqualStrings("undo", refreshed.undo.?.items[0].action); │ │167 - } │ │152 + const data = try ui.Repo.init(&arena, &session, ui.RoutablePage.repoFilesRoute("", null, "", "", 0).?); │ │153 + try std.testing.expect(data.undo == null); │ │154 + try std.testing.expectError(error.NotFound, ui.Repo.init(&arena, &session, ui.RoutablePage.repoUndoRoute("", null).?)); │ │155 } │ │156 } │ │157 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │174 defer temp.cleanup(); │ │175 var arena = std.heap.ArenaAllocator.init(allocator); │ │176 defer arena.deinit(); │ │190 - const path = try temp.dir.realPathFileAlloc(io, ".", arena.allocator()); │ │177 + const aa = arena.allocator(); │ │178 + │ │179 + // a server with one user who owns the repo │ │180 + const base = try temp.dir.realPathFileAlloc(io, ".", aa); │ │181 + const admin_path = try std.Io.Dir.path.join(aa, &.{ base, "admin" }); │ │182 + const users_dir = try std.Io.Dir.path.join(aa, &.{ base, "users" }); │ │183 + var admin = try xit.repo.Repo(.xit, evt.admin_repo_opts).init(io, allocator, .{ .path = admin_path }); │ │184 + defer admin.deinit(io, allocator); │ │185 + const owner: [evt.event_id_size]u8 = @splat(1); │ │186 + const repo_id: [evt.event_id_size]u8 = @splat(4); │ │187 + const author: evt.CommitAuthor = .{ .name = "test", .email = "test@example.test" }; │ │188 + try evt.consume(.{ .server = .{ .users_dir = users_dir } }, .admin, .xit, evt.admin_repo_opts, io, allocator, &admin, evt.events_ref, &.{ │ │189 + .{ .id = std.fmt.bytesToHex(owner, .lower), .author = author, .event = .{ .user = .{ .name = "alice", .email = "alice@example.test", .password_hash = "unused" } } }, │ │190 + }); │ │191 + var user_repo = try evt.initUserRepo(io, allocator, try evt.userRepoPath(aa, users_dir, &owner)); │ │192 + defer user_repo.deinit(io, allocator); │ │193 + try evt.consume(.{ .server = .{ .users_dir = users_dir } }, .user, .xit, evt.user_repo_opts, io, allocator, &user_repo, evt.events_ref, &.{ │ │194 + .{ .id = std.fmt.bytesToHex(repo_id, .lower), .author = author, .event = .{ .repo = .{ .user_id = std.fmt.bytesToHex(owner, .lower), .name = "demo", .description = "", .read_access = .public } } },│ │195 + }); │ │196 + const path = try evt.repoPath(aa, users_dir, &owner, &repo_id); │ │197 const Repo = xit.repo.Repo(.xit, .{}); │ │198 var repo = try Repo.init(io, allocator, .{ .path = path }); │ │199 defer repo.deinit(io, allocator); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │208 const history = try Repo.DB.ArrayList(.read_write).init(repo.core.db.rootCursor()); │ │209 try history.appendContext(.{ .slot = try history.getSlot(-1) }, Corrupt{}); │ │210 │ │205 - var session = ui.Session{ .arena = &arena, .page_arena = &arena, .io = io, .local = .{ .path = path, .repo_kind = .xit }, .data = .{ .host_kind = .local } };│ │211 + var session = try ui.Session.init(&arena, &admin, .{ .user_id = &owner }); │ │212 + session.io = io; │ │213 + session.users_dir = users_dir; │ │214 // tabs switch in-page, so every tab carries the undo data and its failure │ │207 - const files = try ui.Repo.init(&arena, &session, ui.RoutablePage.repoFilesRoute("", null, "", "", 0).?); │ │215 + const files = try ui.Repo.init(&arena, &session, ui.RoutablePage.repoFilesRoute("alice:demo", null, "", "", 0).?); │ │216 try std.testing.expectEqual(0, files.undo.?.items.len); │ │217 try std.testing.expectEqualStrings("InvalidUndoRecord", files.undo.?.failure.?); │ │210 - const undo = try ui.Repo.init(&arena, &session, ui.RoutablePage.repoUndoRoute("", null).?); │ │218 + const undo = try ui.Repo.init(&arena, &session, ui.RoutablePage.repoUndoRoute("alice:demo", null).?); │ │219 try std.testing.expectEqualStrings("InvalidUndoRecord", undo.undo.?.failure.?); │ │220 │ │221 var root = ui.Widget{ .repo_undo = try Undo.View.init(allocator, &undo.undo.?, &session) }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯