dev vouch dev on at. thats about it atvouch.dev
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

merge and remove some tests

authored by

Luna and committed by tangled.org 45c3a093 1ab8eae9

+68 -180
+7 -13
appview/test/atvouch/tangled/comment_builder_test.exs
··· 85 85 assert result =~ "- no route from [@dave.test](https://bsky.app/profile/did:plc:dave)" 86 86 end 87 87 88 - test "falls back to DID when handle is nil" do 89 - routes = [{@alice_did, nil, {:direct, @author_did}}] 90 - result = CommentBuilder.build_comment(@author_did, nil, routes) 91 - 92 - refute result =~ "##" 93 - assert result =~ "- [#{@alice_did}](https://bsky.app/profile/#{@alice_did}) -> [#{@author_did}](https://bsky.app/profile/#{@author_did})" 94 - end 95 - 96 - test "falls back to DID when handle is empty string" do 97 - routes = [{@alice_did, "", {:direct, @author_did}}] 98 - result = CommentBuilder.build_comment(@author_did, "", routes) 88 + test "falls back to DID when handle is nil or empty string" do 89 + for maintainer_handle <- [nil, ""] do 90 + routes = [{@alice_did, maintainer_handle, {:direct, @author_did}}] 91 + result = CommentBuilder.build_comment(@author_did, maintainer_handle, routes) 99 92 100 - refute result =~ "##" 101 - assert result =~ "- [#{@alice_did}](https://bsky.app/profile/#{@alice_did}) -> [#{@author_did}](https://bsky.app/profile/#{@author_did})" 93 + refute result =~ "##" 94 + assert result =~ "- [#{@alice_did}](https://bsky.app/profile/#{@alice_did}) -> [#{@author_did}](https://bsky.app/profile/#{@author_did})" 95 + end 102 96 end 103 97 104 98 test "formats three-hop path" do
-24
appview/test/atvouch/tangled/scraper_test.exs
··· 48 48 """ 49 49 end 50 50 51 - test "parses pulls page HTML to extract PR list with timestamps" do 52 - html = 53 - wrap_page( 54 - pr_entry("alice.test", "3abc123", 3, "Fix broken tests", "2026-03-19T14:37:19+00:00") <> 55 - pr_entry("alice.test", "3abc123", 2, "Add new feature", "2026-03-10T16:25:26+00:00") <> 56 - pr_entry("alice.test", "3abc123", 1, "Initial setup", "2026-02-15T10:00:00+00:00") 57 - ) 58 - 59 - pulls = Scraper.parse_pulls_page(html) 60 - 61 - assert length(pulls) == 3 62 - {3, title3, ts3} = Enum.at(pulls, 0) 63 - assert title3 =~ "Fix broken tests" 64 - assert ts3 == "2026-03-19T14:37:19+00:00" 65 - 66 - {2, title2, ts2} = Enum.at(pulls, 1) 67 - assert title2 =~ "Add new feature" 68 - assert ts2 == "2026-03-10T16:25:26+00:00" 69 - 70 - {1, title1, ts1} = Enum.at(pulls, 2) 71 - assert title1 =~ "Initial setup" 72 - assert ts1 == "2026-02-15T10:00:00+00:00" 73 - end 74 - 75 51 test "handles empty pulls page" do 76 52 html = wrap_page("<p>No pull requests found.</p>") 77 53 pulls = Scraper.parse_pulls_page(html)
+2 -16
appview/test/atvouch/tangled/session_test.exs
··· 15 15 {:ok, tangled_port: servers.tangled_port} 16 16 end 17 17 18 - test "successful login returns cookies", %{tangled_port: tangled_port} do 19 - {:ok, pid} = 20 - Session.start_link( 21 - handle: "bot.test", 22 - password: "test-password", 23 - tangled_url: "http://127.0.0.1:#{tangled_port}", 24 - name: :"session_test_#{tangled_port}" 25 - ) 26 - 27 - result = Session.get_cookies(pid) 28 - assert {:ok, cookies} = result 29 - assert String.contains?(cookies, "appview-session-v2=") 30 - end 31 - 32 - test "cookies are cached on second call", %{tangled_port: tangled_port} do 18 + test "successful login returns cookies and caches them", %{tangled_port: tangled_port} do 33 19 {:ok, pid} = 34 20 Session.start_link( 35 21 handle: "bot.test", ··· 39 25 ) 40 26 41 27 {:ok, cookies1} = Session.get_cookies(pid) 28 + assert String.contains?(cookies1, "appview-session-v2=") 42 29 43 30 # Drain messages from first login 44 31 drain_messages() 45 32 46 33 {:ok, cookies2} = Session.get_cookies(pid) 47 - 48 34 assert cookies1 == cookies2 49 35 50 36 # Should NOT have received another login attempt
+2 -15
appview/test/atvouch/xrpc_get_routes_test.exs
··· 40 40 end 41 41 42 42 describe "GET /xrpc/dev.atvouch.graph.getRoutes" do 43 - test "returns 401 without authentication" do 44 - conn = 45 - conn(:get, "/xrpc/dev.atvouch.graph.getRoutes?target=did:plc:bob") 46 - |> Atvouch.Router.call(@opts) 47 - 48 - assert conn.status == 401 49 - end 50 - 51 - test "returns 401 with invalid token" do 52 - conn = 53 - conn(:get, "/xrpc/dev.atvouch.graph.getRoutes?target=did:plc:bob") 54 - |> put_req_header("authorization", "Bearer bad-token") 55 - |> Atvouch.Router.call(@opts) 56 - 57 - assert conn.status == 401 43 + test "requires authentication" do 44 + assert_requires_auth("/xrpc/dev.atvouch.graph.getRoutes?target=did:plc:bob", @opts) 58 45 end 59 46 60 47 test "returns 400 when target parameter is missing" do
+16 -112
appview/test/atvouch/xrpc_vouches_test.exs
··· 78 78 assert body["vouches"] == [] 79 79 end 80 80 81 - test "returns 401 without authentication" do 82 - conn = 83 - conn(:get, "/xrpc/dev.atvouch.graph.getCurrentUserVouches") 84 - |> Atvouch.Router.call(@opts) 85 - 86 - assert conn.status == 401 87 - end 88 - 89 - test "returns 401 with invalid token" do 90 - conn = 91 - conn(:get, "/xrpc/dev.atvouch.graph.getCurrentUserVouches") 92 - |> put_req_header("authorization", "Bearer bad-token") 93 - |> Atvouch.Router.call(@opts) 94 - 95 - assert conn.status == 401 81 + test "requires authentication" do 82 + assert_requires_auth("/xrpc/dev.atvouch.graph.getCurrentUserVouches", @opts) 96 83 end 97 84 98 85 test "returns pagination data and behaves with limit" do ··· 152 139 refute body["cursor"] 153 140 end 154 141 155 - test "returns 400 with invalid cursor" do 156 - conn = 157 - conn(:get, "/xrpc/dev.atvouch.graph.getCurrentUserVouches?cursor=notanumber") 158 - |> put_req_header("authorization", "Bearer valid-token:did:plc:alice") 159 - |> Atvouch.Router.call(@opts) 160 - 161 - assert conn.status == 400 162 - end 163 - 164 - test "returns 400 with limit over 1000" do 165 - conn = 166 - conn(:get, "/xrpc/dev.atvouch.graph.getCurrentUserVouches?limit=1001") 167 - |> put_req_header("authorization", "Bearer valid-token:did:plc:alice") 168 - |> Atvouch.Router.call(@opts) 169 - 170 - assert conn.status == 400 171 - end 172 - 173 - test "returns 400 with limit under 1" do 174 - conn = 175 - conn(:get, "/xrpc/dev.atvouch.graph.getCurrentUserVouches?limit=0") 176 - |> put_req_header("authorization", "Bearer valid-token:did:plc:alice") 177 - |> Atvouch.Router.call(@opts) 178 - 179 - assert conn.status == 400 142 + test "validates pagination parameters" do 143 + assert_validates_pagination_params( 144 + "/xrpc/dev.atvouch.graph.getCurrentUserVouches", @opts, 145 + auth_did: "did:plc:alice" 146 + ) 180 147 end 181 148 end 182 149 ··· 231 198 assert vouch["targetDid"] == "did:plc:carol" 232 199 end 233 200 234 - test "returns 401 without authentication" do 235 - conn = 236 - conn(:get, "/xrpc/dev.atvouch.graph.getRemoteVouches") 237 - |> Atvouch.Router.call(@opts) 238 - 239 - assert conn.status == 401 240 - end 241 - 242 - test "returns 401 with invalid token" do 243 - conn = 244 - conn(:get, "/xrpc/dev.atvouch.graph.getRemoteVouches") 245 - |> put_req_header("authorization", "Bearer bad-token") 246 - |> Atvouch.Router.call(@opts) 247 - 248 - assert conn.status == 401 201 + test "requires authentication" do 202 + assert_requires_auth("/xrpc/dev.atvouch.graph.getRemoteVouches", @opts) 249 203 end 250 204 251 205 test "returns total count" do ··· 335 289 refute body["cursor"] 336 290 end 337 291 338 - test "returns 400 with invalid cursor" do 339 - conn = 340 - conn(:get, "/xrpc/dev.atvouch.graph.getRemoteVouches?cursor=notanumber") 341 - |> put_req_header("authorization", "Bearer valid-token:did:plc:alice") 342 - |> Atvouch.Router.call(@opts) 343 - 344 - assert conn.status == 400 345 - end 346 - 347 - test "returns 400 with limit over 1000" do 348 - conn = 349 - conn(:get, "/xrpc/dev.atvouch.graph.getRemoteVouches?limit=1001") 350 - |> put_req_header("authorization", "Bearer valid-token:did:plc:alice") 351 - |> Atvouch.Router.call(@opts) 352 - 353 - assert conn.status == 400 354 - end 355 - 356 - test "returns 400 with limit under 1" do 357 - conn = 358 - conn(:get, "/xrpc/dev.atvouch.graph.getRemoteVouches?limit=0") 359 - |> put_req_header("authorization", "Bearer valid-token:did:plc:alice") 360 - |> Atvouch.Router.call(@opts) 361 - 362 - assert conn.status == 400 292 + test "validates pagination parameters" do 293 + assert_validates_pagination_params( 294 + "/xrpc/dev.atvouch.graph.getRemoteVouches", @opts, 295 + auth_did: "did:plc:alice" 296 + ) 363 297 end 364 298 end 365 299 ··· 382 316 "at://did:plc:alice/dev.atvouch.graph.vouch/did:plc:carol", 383 317 "at://did:plc:alice/dev.atvouch.graph.vouch/did:plc:bob" 384 318 ] 385 - end 386 - 387 - test "returns total count of vouches" do 388 - conn = 389 - conn(:get, "/xrpc/dev.atvouch.graph.getEntireGraph") 390 - |> Atvouch.Router.call(@opts) 391 - 392 - assert conn.status == 200 393 - body = Jason.decode!(conn.resp_body) 394 - assert body["total"] == 3 395 319 end 396 320 397 321 test "total count is consistent across paginated requests" do ··· 478 402 assert length(body["vouches"]) == 3 479 403 end 480 404 481 - test "returns 400 with invalid cursor" do 482 - conn = 483 - conn(:get, "/xrpc/dev.atvouch.graph.getEntireGraph?cursor=notanumber") 484 - |> Atvouch.Router.call(@opts) 485 - 486 - assert conn.status == 400 487 - end 488 - 489 - test "returns 400 with limit over 1000" do 490 - conn = 491 - conn(:get, "/xrpc/dev.atvouch.graph.getEntireGraph?limit=1001") 492 - |> Atvouch.Router.call(@opts) 493 - 494 - assert conn.status == 400 495 - end 496 - 497 - test "returns 400 with limit under 1" do 498 - conn = 499 - conn(:get, "/xrpc/dev.atvouch.graph.getEntireGraph?limit=0") 500 - |> Atvouch.Router.call(@opts) 501 - 502 - assert conn.status == 400 405 + test "validates pagination parameters" do 406 + assert_validates_pagination_params("/xrpc/dev.atvouch.graph.getEntireGraph", @opts) 503 407 end 504 408 end 505 409 end
+41
appview/test/support/test_helpers.ex
··· 219 219 } 220 220 end 221 221 222 + # --- Auth & Pagination Assertions --- 223 + 224 + def assert_requires_auth(path, router_opts) do 225 + import ExUnit.Assertions 226 + import Plug.Test 227 + import Plug.Conn 228 + 229 + conn_no_auth = conn(:get, path) |> Atvouch.Router.call(router_opts) 230 + assert conn_no_auth.status == 401, "expected 401 without auth for #{path}" 231 + 232 + conn_bad_token = 233 + conn(:get, path) 234 + |> put_req_header("authorization", "Bearer bad-token") 235 + |> Atvouch.Router.call(router_opts) 236 + 237 + assert conn_bad_token.status == 401, "expected 401 with invalid token for #{path}" 238 + end 239 + 240 + def assert_validates_pagination_params(path, router_opts, opts \\ []) do 241 + import ExUnit.Assertions 242 + import Plug.Test 243 + import Plug.Conn 244 + 245 + auth_did = Keyword.get(opts, :auth_did) 246 + sep = if String.contains?(path, "?"), do: "&", else: "?" 247 + 248 + make_conn = fn url -> 249 + c = conn(:get, url) 250 + if auth_did, do: put_req_header(c, "authorization", "Bearer valid-token:#{auth_did}"), else: c 251 + end 252 + 253 + conn1 = make_conn.("#{path}#{sep}cursor=notanumber") |> Atvouch.Router.call(router_opts) 254 + assert conn1.status == 400, "expected 400 for invalid cursor on #{path}" 255 + 256 + conn2 = make_conn.("#{path}#{sep}limit=1001") |> Atvouch.Router.call(router_opts) 257 + assert conn2.status == 400, "expected 400 for limit over 1000 on #{path}" 258 + 259 + conn3 = make_conn.("#{path}#{sep}limit=0") |> Atvouch.Router.call(router_opts) 260 + assert conn3.status == 400, "expected 400 for limit under 1 on #{path}" 261 + end 262 + 222 263 # --- Drain Messages --- 223 264 224 265 def drain_messages(timeout \\ 100) do