╭ changed ────────────────╮ │src/test/event/notify.zig│ ╰─────────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │26 return try evt.Notify.readMode(evt.UserDB, evt.user_repo_opts.hash, moment, arena, repo_id, thread_id); │ │27 } │ │28 │ │29 -fn readSubscribers(io: std.Io, allocator: std.mem.Allocator, arena: *std.heap.ArenaAllocator, users_dir: []const u8, owner_id: *const [evt.event_id_size]u8, notif_id: *const [evt.event_id_size]u8) ![]const [evt.event_id_size]u8 {│ │29 +fn readNotified(io: std.Io, allocator: std.mem.Allocator, arena: *std.heap.ArenaAllocator, users_dir: []const u8, owner_id: *const [evt.event_id_size]u8, notif_id: *const [evt.event_id_size]u8) ![]const [evt.event_id_size]u8 { │ │30 var user_repo = (try evt.openUserRepo(io, allocator, users_dir, owner_id)) orelse return error.TestUnexpectedResult; │ │31 defer user_repo.deinit(io, allocator); │ │32 - return try notify.readSubscribers(try user_repo.core.latestMoment(), arena, notif_id); │ │32 + return try notify.readNotified(try user_repo.core.latestMoment(), arena, notif_id); │ │33 +} │ │34 + │ │35 +fn initUserRepo(io: std.Io, allocator: std.mem.Allocator, users_dir: []const u8, user_id: *const [evt.event_id_size]u8) !void { │ │36 + const path = try evt.userRepoPath(allocator, users_dir, user_id); │ │37 + defer allocator.free(path); │ │38 + var user_repo = try evt.initUserRepo(io, allocator, path); │ │39 + defer user_repo.deinit(io, allocator); │ │40 } │ │41 │ │42 test "notifs" { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │56 var prng = std.Random.DefaultPrng.init(std.testing.random_seed); │ │57 const owner_id = evt.EventWithId.randomId(prng.random()); │ │58 const recipient_id = evt.EventWithId.randomId(prng.random()); │ │52 - for ([_]*const [evt.event_id_size]u8{ &owner_id, &recipient_id }) |user_id| { │ │53 - const path = try evt.userRepoPath(allocator, users_dir, user_id); │ │54 - defer allocator.free(path); │ │55 - var user_repo = try evt.initUserRepo(io, allocator, path); │ │56 - defer user_repo.deinit(io, allocator); │ │57 - } │ │59 + for ([_]*const [evt.event_id_size]u8{ &owner_id, &recipient_id }) |user_id| try initUserRepo(io, allocator, users_dir, user_id);│ │60 const location = try evt.createRepo(io, allocator, users_dir, &owner_id, author, "repo", "", .private, repo_opts.hash); │ │61 │ │62 // │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │126 │ │127 // subscribing replaces the mute record and indexes the subscriber in the owner's repo │ │128 const id_b = notify.idOf(&location.repo_id, &thread_b); │ │127 - try std.testing.expectEqual(.mute, try readMode(io, allocator, &arena, users_dir, &recipient_id, &location.repo_id, &thread_b)); │ │129 + try std.testing.expectEqual(.muted, try readMode(io, allocator, &arena, users_dir, &recipient_id, &location.repo_id, &thread_b)); │ │130 try notify.subscribe(io, allocator, users_dir, &recipient_id, location, &thread_b, author); │ │129 - try std.testing.expectEqual(.subscribe, try readMode(io, allocator, &arena, users_dir, &recipient_id, &location.repo_id, &thread_b)); │ │131 + try std.testing.expectEqual(.subscribed, try readMode(io, allocator, &arena, users_dir, &recipient_id, &location.repo_id, &thread_b));│ │132 try notify.deliver(io, allocator, users_dir, &recipient_id, &.{notif_b}); │ │133 try std.testing.expectEqual(1, (try readRecent(io, allocator, &arena, users_dir, &recipient_id)).len); │ │134 { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │133 - const subscribers = try readSubscribers(io, allocator, &arena, users_dir, &owner_id, &id_b);│ │134 - try std.testing.expectEqual(1, subscribers.len); │ │135 - try std.testing.expectEqualSlices(u8, &recipient_id, &subscribers[0]); │ │135 + const notified = try readNotified(io, allocator, &arena, users_dir, &owner_id, &id_b); │ │136 + try std.testing.expectEqual(1, notified.len); │ │137 + try std.testing.expectEqualSlices(u8, &recipient_id, &notified[0]); │ │138 } │ │139 │ │140 // muting drops the subscriber from the index │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │141 try notify.mute(io, allocator, users_dir, &recipient_id, location, &thread_b, author); │ │140 - try std.testing.expectEqual(0, (try readSubscribers(io, allocator, &arena, users_dir, &owner_id, &id_b)).len); │ │142 + try std.testing.expectEqual(0, (try readNotified(io, allocator, &arena, users_dir, &owner_id, &id_b)).len); │ │143 + │ │144 + // a full subscribed tier refuses one more │ │145 + for (0..notify.max_subscribed) |_| { │ │146 + const user_id = evt.EventWithId.randomId(prng.random()); │ │147 + try initUserRepo(io, allocator, users_dir, &user_id); │ │148 + try notify.subscribe(io, allocator, users_dir, &user_id, location, &thread_a, author); │ │149 + } │ │150 + try notify.subscribe(io, allocator, users_dir, &recipient_id, location, &thread_a, author); │ │151 + try std.testing.expectEqual(null, try readMode(io, allocator, &arena, users_dir, &recipient_id, &location.repo_id, &thread_a));│ │152 │ │153 // past the cap, the oldest go. times tie within a second, so which one goes isn't checked. │ │154 { │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯