╭ changed ──────╮ │src/test/ui.zig│ ╰───────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────╮ │43 try std.testing.expect(route != null); │ │44 } │ │45 │ │46 +// a ref name with a '/' is url-encoded in the route, so it survives the │ │47 +// '/'-delimited url round-trip as a single segment (kind + value) rather than │ │48 +// being mis-parsed as extra path. │ │49 +test "encoded ref name survives the commits url round-trip" { │ │50 + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); │ │51 + defer arena.deinit(); │ │52 + const RP = ui.RoutablePage; │ │53 + │ │54 + // the route layer holds the value already url-encoded ("feature%2Ffoo"). │ │55 + const route = RP.repoCommitsRoute("alice/ziglings", .branch, "feature%2Ffoo", 0).?; │ │56 + const url = try route.urlAlloc(&arena); │ │57 + try std.testing.expectEqualStrings("/repo/alice/ziglings/commits/branch/feature%2Ffoo", url);│ │58 + │ │59 + // parsing it back yields the same route, and the ref splits out intact. │ │60 + const parsed = RP.fromUrl(url, null); │ │61 + try std.testing.expect(parsed != null); │ │62 + const ref = RP.repoCommitsRef(parsed.?.repo_commits.name.slice()); │ │63 + try std.testing.expectEqual(RP.RefOrOid.branch, ref.ref_or_oid.?); │ │64 + try std.testing.expectEqualStrings("feature%2Ffoo", ref.value); │ │65 +} │ │66 + │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯