Skip to content
quarry Artifact [f88d3a1408]
Login

Artifact [f88d3a1408]

Artifact f88d3a1408a4b76a18b8a8bf1e2f87d0fe1a1207519b502fd9441ec15b135c0a:


package main

import (
	"net/http"
	"net/http/httptest"
	"net/url"
	"strings"
	"testing"

	"craftdesign.group/quarry/internal/oltp"
)

// fleetForm posts a fleet form as a person on their password.
func (g siteRig) fleetForm(user, path string, v url.Values) (int, string) {
	req := httptest.NewRequest(http.MethodPost, path, strings.NewReader(v.Encode()))
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.SetBasicAuth(user, doorPassword)
	w := httptest.NewRecorder()
	g.h.ServeHTTP(w, req)
	return w.Code, w.Body.String()
}

// A site admin holds no letters on other people's repositories (#318),
// so their settings pages are closed to them; the fleet row is where
// they stop serving or delete one. Every row offers stopping; only a
// store this node created offers deleting, behind the name typed back.
func TestTheFleetRowStopsAndDeletesForASiteAdmin(t *testing.T) {
	g := newSiteRig(t)
	code, body := g.doAs("dmestas", http.MethodGet, "/fleet", doorPassword, "", nil)
	if code != http.StatusOK {
		t.Fatalf("fleet: %d", code)
	}
	if n := strings.Count(body, `data-hook="fleet-row-menu"`); n < 4 {
		t.Errorf("FAIL: %d row menus, want one for every store", n)
	}
	if n := strings.Count(body, `data-hook="fleet-stop"`); n < 4 {
		t.Errorf("FAIL: %d stop-serving forms, want one for every store", n)
	}
	if !strings.Contains(body, `href="/fleet?delete=pub"`) {
		t.Error("FAIL: no delete link for pub, which this node created")
	}
	if strings.Contains(body, `href="/fleet?delete=secret"`) {
		t.Error("FAIL: a delete link for secret, which this node did not create")
	}

	if _, body := g.doAs("dmestas", http.MethodGet, "/fleet?delete=pub", doorPassword, "", nil); !strings.Contains(body, `data-hook="fleet-delete"`) {
		t.Error("FAIL: no confirmation for deleting pub")
	}
	if _, body := g.doAs("dmestas", http.MethodGet, "/fleet?delete=secret", doorPassword, "", nil); strings.Contains(body, `data-hook="fleet-delete"`) {
		t.Error("FAIL: a confirmation for deleting secret, which this node did not create")
	}

	if code, body := g.fleetForm("dmestas", "/fleet/repo/delete", url.Values{"repo": {"pub"}, "confirm": {"pub"}}); code != http.StatusSeeOther {
		t.Errorf("FAIL: the site admin's delete of alice's pub: %d %s", code, body)
	}
	if strings.Join(g.regs.deleted, ",") != "pub" {
		t.Errorf("FAIL: deleted %v, want pub", g.regs.deleted)
	}
}

// The fleet delete calls repo.delete in-process, so the op holds the
// line itself: an account with no letters on a store deletes nothing
// from the fleet, and a site token's session cannot destroy a private
// store it holds no grant on.
func TestTheFleetDeleteHoldsTheOpsLine(t *testing.T) {
	g := newSiteRig(t)
	if err := g.db.AddAccount("bob", doorPassword, false); err != nil {
		t.Fatal(err)
	}
	if code, _ := g.fleetForm("bob", "/fleet/repo/delete", url.Values{"repo": {"pub"}, "confirm": {"pub"}}); code == http.StatusSeeOther {
		t.Error("FAIL: bob, with no letters on pub, deleted it from the fleet")
	}
	_, siteTok := g.mint(t, oltp.ScopeAPI, oltp.ScopeWeb, oltp.ScopeSite)
	cookie := g.session(t, siteTok)
	if code, _ := g.form("/fleet/repo/delete", cookie, url.Values{"repo": {"secret"}, "confirm": {"secret"}}); code == http.StatusSeeOther {
		t.Error("FAIL: the site session deleted secret, private and ungranted")
	}
	if len(g.regs.deleted) != 0 {
		t.Errorf("FAIL: deleted %v", g.regs.deleted)
	}
}