Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Serve changes at /r/<repo>/changes

8fb7aabf534adf208cd795724b1e3d287dc62f5a · Keenan Nemetz · 3d ago · parent b492b557

Serve changes at /r/<repo>/changes

The metadata tree and the interface say changes; the browser was the last
place spelling the route requests. Rename every method on that subtree and
the URLs the server builds: redirects, activity and search results, the
number alias, code links, templates, and the CLI's page links.

The old route is gone rather than aliased. Nothing has been publicly
released, so there is no bookmark or client to keep working, and a redirect
would leave two spellings of the same page in the code.

Refs #204 (01M6S6685JFG8S64ZFF452217W).

server/auth_test.go +19−19

@@ -248,7 +248,7 @@ func TestWebApprovalNamesTheSessionAccount(t *testing.T) {
248 248 }
249 249
250 250 sess, cookie := f.browserSession(t, f.ownerID)
251 resp, body := f.browserPost(t, "/r/"+f.repo+"/requests/"+req.ID+"/approve", cookie,
251 resp, body := f.browserPost(t, "/r/"+f.repo+"/changes/"+req.ID+"/approve", cookie,
252 252 url.Values{"csrf": {sess.CSRF}, "base": {"main"}, "head": {head}})
253 253 if resp.StatusCode != http.StatusSeeOther {
254 254 t.Fatalf("approve: status=%d body=%s", resp.StatusCode, body)
@@ -282,7 +282,7 @@ func TestWebApprovalRefusesAStaleTarget(t *testing.T) {
282 282 }
283 283
284 284 sess, cookie := f.browserSession(t, f.ownerID)
285 resp, body := f.browserPost(t, "/r/"+f.repo+"/requests/"+req.ID+"/approve", cookie,
285 resp, body := f.browserPost(t, "/r/"+f.repo+"/changes/"+req.ID+"/approve", cookie,
286 286 url.Values{"csrf": {sess.CSRF}, "base": {"main"}, "head": {stale}})
287 287 if resp.StatusCode != http.StatusBadRequest {
288 288 t.Fatalf("stale approval: status=%d body=%s", resp.StatusCode, body)
@@ -296,7 +296,7 @@ func TestWebApprovalRefusesAStaleTarget(t *testing.T) {
296 296 if _, err := metadata.SetRequestBase(m.Git(), req.ID, "other", f.ownerID); err != nil {
297 297 t.Fatal(err)
298 298 }
299 resp, body = f.browserPost(t, "/r/"+f.repo+"/requests/"+req.ID+"/approve", cookie,
299 resp, body = f.browserPost(t, "/r/"+f.repo+"/changes/"+req.ID+"/approve", cookie,
300 300 url.Values{"csrf": {sess.CSRF}, "base": {"main"}, "head": {head}})
301 301 if resp.StatusCode != http.StatusBadRequest {
302 302 t.Fatalf("stale base approval: status=%d body=%s", resp.StatusCode, body)
@@ -401,12 +401,12 @@ func TestContributorNamespaceAndRequestUseTheAccountName(t *testing.T) {
401 401 t.Fatalf("contributor issue: status=%d body=%s", resp.StatusCode, body)
402 402 }
403 403
404 resp, body = f.browserGet(t, "/r/"+f.repo+"/requests/new", cookie)
404 resp, body = f.browserGet(t, "/r/"+f.repo+"/changes/new", cookie)
405 405 if resp.StatusCode != http.StatusOK || !strings.Contains(body, headRef) || !strings.Contains(body, "Open change") {
406 406 t.Fatalf("request form: status=%d body=%s", resp.StatusCode, body)
407 407 }
408 408
409 resp, body = f.browserPost(t, "/r/"+f.repo+"/requests", cookie, url.Values{
409 resp, body = f.browserPost(t, "/r/"+f.repo+"/changes", cookie, url.Values{
410 410 "csrf": {sess.CSRF}, "title": {"Contributor patch"}, "body": {"please review"},
411 411 "base": {"main"}, "head": {headRef},
412 412 })
@@ -427,7 +427,7 @@ func TestContributorNamespaceAndRequestUseTheAccountName(t *testing.T) {
427 427
428 428 // The handler refuses a head outside the contributor namespace even if the
429 429 // form is edited by hand.
430 resp, _ = f.browserPost(t, "/r/"+f.repo+"/requests", cookie, url.Values{
430 resp, _ = f.browserPost(t, "/r/"+f.repo+"/changes", cookie, url.Values{
431 431 "csrf": {sess.CSRF}, "title": {"Wrong branch"}, "base": {"main"}, "head": {"main"},
432 432 })
433 433 if resp.StatusCode != http.StatusForbidden {
@@ -471,7 +471,7 @@ func TestContributorRepointsRequestTarget(t *testing.T) {
471 471 }
472 472
473 473 sess, cookie := f.browserSession(t, contrib.Name)
474 resp, body := f.browserPost(t, "/r/"+f.repo+"/requests", cookie, url.Values{
474 resp, body := f.browserPost(t, "/r/"+f.repo+"/changes", cookie, url.Values{
475 475 "csrf": {sess.CSRF}, "title": {"Contributor patch"}, "base": {"main"}, "head": {headRef},
476 476 })
477 477 if resp.StatusCode != http.StatusSeeOther {
@@ -508,11 +508,11 @@ func TestContributorRepointsRequestTarget(t *testing.T) {
508 508 }
509 509
510 510 // The control is offered, with the contributor's own branch as a choice.
511 resp, body = f.browserGet(t, "/r/"+f.repo+"/requests/"+id, cookie)
511 resp, body = f.browserGet(t, "/r/"+f.repo+"/changes/"+id, cookie)
512 512 if resp.StatusCode != http.StatusOK {
513 513 t.Fatalf("request page: status=%d body=%s", resp.StatusCode, body)
514 514 }
515 if !strings.Contains(body, `action="/r/`+f.repo+`/requests/`+id+`/target"`) || !strings.Contains(body, headRef) {
515 if !strings.Contains(body, `action="/r/`+f.repo+`/changes/`+id+`/target"`) || !strings.Contains(body, headRef) {
516 516 t.Fatalf("the request page does not offer the target control:\n%s", body)
517 517 }
518 518 // The Review header carries the head commit under review.
@@ -520,7 +520,7 @@ func TestContributorRepointsRequestTarget(t *testing.T) {
520 520 t.Fatalf("the Review header does not show the head commit:\n%s", body)
521 521 }
522 522
523 resp, body = f.browserPost(t, "/r/"+f.repo+"/requests/"+id+"/target", cookie, url.Values{
523 resp, body = f.browserPost(t, "/r/"+f.repo+"/changes/"+id+"/target", cookie, url.Values{
524 524 "csrf": {sess.CSRF}, "base": {"main"}, "head": {headRef},
525 525 })
526 526 if resp.StatusCode != http.StatusSeeOther {
@@ -536,7 +536,7 @@ func TestContributorRepointsRequestTarget(t *testing.T) {
536 536
537 537 // The namespace rule is the one the create form applies: a contributor cannot
538 538 // point their request at a branch they could not have pushed.
539 resp, _ = f.browserPost(t, "/r/"+f.repo+"/requests/"+id+"/target", cookie, url.Values{
539 resp, _ = f.browserPost(t, "/r/"+f.repo+"/changes/"+id+"/target", cookie, url.Values{
540 540 "csrf": {sess.CSRF}, "base": {"main"}, "head": {"main"},
541 541 })
542 542 if resp.StatusCode != http.StatusForbidden {
@@ -549,7 +549,7 @@ func TestContributorRepointsRequestTarget(t *testing.T) {
549 549 // A maintainer may move any open request, including a contributor's.
550 550 ownerSess, ownerCookie := f.browserSession(t, f.ownerID)
551 551 mainTip, _ := m.Git().RevParse("refs/heads/main")
552 resp, body = f.browserPost(t, "/r/"+f.repo+"/requests/"+id+"/target", ownerCookie, url.Values{
552 resp, body = f.browserPost(t, "/r/"+f.repo+"/changes/"+id+"/target", ownerCookie, url.Values{
553 553 "csrf": {ownerSess.CSRF}, "base": {"main"}, "head": {"main"},
554 554 })
555 555 if resp.StatusCode != http.StatusSeeOther {
@@ -565,11 +565,11 @@ func TestContributorRepointsRequestTarget(t *testing.T) {
565 565 if _, errs, err := f.git(base, "push", f.sshURL(f.repo), "main:refs/heads/parent"); err != nil {
566 566 t.Fatalf("parent push: %v\n%s", err, errs)
567 567 }
568 resp, body = f.browserGet(t, "/r/"+f.repo+"/requests/"+id, cookie)
569 if resp.StatusCode != http.StatusOK || !strings.Contains(body, `action="/r/`+f.repo+`/requests/`+id+`/target"`) {
568 resp, body = f.browserGet(t, "/r/"+f.repo+"/changes/"+id, cookie)
569 if resp.StatusCode != http.StatusOK || !strings.Contains(body, `action="/r/`+f.repo+`/changes/`+id+`/target"`) {
570 570 t.Fatalf("the request page does not offer the target control:\n%s", body)
571 571 }
572 resp, body = f.browserPost(t, "/r/"+f.repo+"/requests/"+id+"/target", cookie, url.Values{
572 resp, body = f.browserPost(t, "/r/"+f.repo+"/changes/"+id+"/target", cookie, url.Values{
573 573 "csrf": {sess.CSRF}, "base": {"parent"}, "head": {"main"},
574 574 })
575 575 if resp.StatusCode != http.StatusSeeOther {
@@ -580,13 +580,13 @@ func TestContributorRepointsRequestTarget(t *testing.T) {
580 580 }
581 581
582 582 // Closed requests are settled: the head and base are history, not settings.
583 resp, body = f.browserPost(t, "/r/"+f.repo+"/requests/"+id+"/state", cookie, url.Values{
583 resp, body = f.browserPost(t, "/r/"+f.repo+"/changes/"+id+"/state", cookie, url.Values{
584 584 "csrf": {sess.CSRF}, "state": {"closed"},
585 585 })
586 586 if resp.StatusCode != http.StatusSeeOther {
587 587 t.Fatalf("close: status=%d body=%s", resp.StatusCode, body)
588 588 }
589 resp, _ = f.browserPost(t, "/r/"+f.repo+"/requests/"+id+"/target", cookie, url.Values{
589 resp, _ = f.browserPost(t, "/r/"+f.repo+"/changes/"+id+"/target", cookie, url.Values{
590 590 "csrf": {sess.CSRF}, "base": {"main"}, "head": {headRef},
591 591 })
592 592 if resp.StatusCode != http.StatusForbidden {
@@ -652,7 +652,7 @@ jobs:
652 652 }
653 653
654 654 contribSess, contribCookie := f.browserSession(t, contrib.Name)
655 resp, body := f.browserPost(t, "/r/"+f.repo+"/requests", contribCookie, url.Values{
655 resp, body := f.browserPost(t, "/r/"+f.repo+"/changes", contribCookie, url.Values{
656 656 "csrf": {contribSess.CSRF}, "title": {"CI gate"}, "body": {"please review"},
657 657 "base": {"main"}, "head": {ref},
658 658 })
@@ -664,7 +664,7 @@ jobs:
664 664 t.Fatalf("requests = %v, err = %v", list, err)
665 665 }
666 666 requestID := list[0].ID
667 requestURL := "/r/" + f.repo + "/requests/" + requestID
667 requestURL := "/r/" + f.repo + "/changes/" + requestID
668 668
669 669 // The Runs tab is history only; the approval belongs with the code under review.
670 670 resp, body = f.browserGet(t, "/r/"+f.repo+"/runs", contribCookie)