Skip to content
quarry Artifact [54f8b88637]
Login

Artifact [54f8b88637]

Artifact 54f8b88637e1e407eae4a417cb6eb1df67db60ee8e617dec0393f2b8fb232bc4:


package api

import (
	"context"
	"testing"
	"time"

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

// A moderator deleting someone else's chat message writes the same
// moderation log the forum and attachments write, and tells the author;
// an author deleting their own writes nothing and tells nobody.
func TestAModeratorChatDeleteIsLoggedAndTold(t *testing.T) {
	fc := &fakeChat{}
	fn := &fakeNotify{}
	ff := &recordingForum{}
	r := ops.NewRegistry()
	repos := testRepos(wikiIndex(t))
	mustRepo(t, repos, "test").Code = "c1"
	if err := RegisterAll(r, Deps{Version: "v", Repos: repos, Chat: fc, Notify: fn, Forum: ff}); err != nil {
		t.Fatal(err)
	}
	ctxAlice := ops.WithUser(context.Background(), "alice")
	post := func(text string) uint64 {
		out, err := r.Invoke(ctxAlice, "chat.post", chatPostIn{Repo: "test", Text: text})
		if err != nil {
			t.Fatal(err)
		}
		return out.(chatPostOut).Seq
	}
	own, other := post("mine to remove"), post("buy cheap watches")

	if _, err := r.Invoke(ctxAlice, "chat.delete", chatDeleteIn{Repo: "test", Seq: own}); err != nil {
		t.Fatal(err)
	}
	if len(ff.lines) != 0 {
		t.Fatalf("FAIL: an author's own delete wrote %d log lines, want 0", len(ff.lines))
	}

	ctxMod := ops.WithCaps(ops.WithUser(context.Background(), "mod"), allCaps{})
	if _, err := r.Invoke(ctxMod, "chat.delete", chatDeleteIn{Repo: "test", Seq: other, Reason: "spam"}); err != nil {
		t.Fatal(err)
	}
	if len(ff.lines) != 1 {
		t.Fatalf("FAIL: a moderator delete wrote %d log lines, want 1", len(ff.lines))
	}
	if l := ff.lines[0]; l[0] != "test" || l[1] != "mod" || l[2] != "chat-delete" || l[4] != "spam" || l[5] != "alice" {
		t.Fatalf("FAIL: log line = %q", l)
	}
	t.Log("ok: moderator delete logged with actor, reason and author")

	var told []NotifyEvent
	for i := 0; i < 50; i++ {
		if told = fn.snapshot(); len(told) > 0 {
			break
		}
		time.Sleep(20 * time.Millisecond)
	}
	var found bool
	for _, e := range told {
		if e.Workflow == "quarry-moderation" {
			found = e.To == "alice" && e.Payload["from"] == "mod"
		}
	}
	if !found {
		t.Fatalf("FAIL: no moderation notice to alice; events = %+v", told)
	}
	t.Log("ok: author told")
}