Skip to content
quarry Artifact [442441402c]
Login

Artifact [442441402c]

Artifact 442441402cbae878f3322a097933e703381d20eba4a1e869b544361a69158bf1:


package notify

import (
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"
)

// A forge that can send its own invites can tell the companion how, so a
// self-hoster does not have to POST a credential into notify by hand
// before any email works at all.
func TestEnsureEmailIntegrationCreatesOneWhenThereIsNone(t *testing.T) {
	var posted map[string]any
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch {
		case r.Method == "GET" && r.URL.Path == "/v1/integrations":
			w.Write([]byte(`[{"channel":"push","identifier":"webpush"}]`))
		case r.Method == "POST" && r.URL.Path == "/v1/integrations/email":
			json.NewDecoder(r.Body).Decode(&posted)
			w.WriteHeader(http.StatusCreated)
			w.Write([]byte(`{"id":"1"}`))
		default:
			t.Errorf("FAIL: unexpected %s %s", r.Method, r.URL.Path)
		}
	}))
	defer srv.Close()

	made, err := New(srv.URL, "k").EnsureEmailIntegration(context.Background(),
		EmailSender{Provider: "resend", Identifier: "quarry-mail",
			From: "quarry <[email protected]>", Key: "re_secret"})
	if err != nil || !made {
		t.Fatalf("FAIL: made=%v err=%v", made, err)
	}
	if posted["provider"] != "resend" || posted["from"] != "quarry <[email protected]>" {
		t.Errorf("FAIL: the sender was not carried across: %+v", posted)
	}
	if posted["apiKey"] != "re_secret" {
		t.Error("FAIL: the credential did not reach the companion")
	}
	if posted["primary"] != true {
		t.Error("FAIL: the only email integration is not the primary one")
	}
	t.Log("ok: a forge with a mailer gives the companion one too")
}

// An operator who configured their own provider meant it, and a forge
// restart must not replace their choice.
func TestEnsureEmailIntegrationLeavesAnExistingOneAlone(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "POST" {
			t.Error("FAIL: an existing email integration was overwritten")
		}
		w.Write([]byte(`[{"channel":"email","identifier":"their-smtp"}]`))
	}))
	defer srv.Close()

	made, err := New(srv.URL, "k").EnsureEmailIntegration(context.Background(),
		EmailSender{Provider: "resend", From: "quarry <[email protected]>", Key: "re_secret"})
	if err != nil || made {
		t.Fatalf("FAIL: made=%v err=%v", made, err)
	}
	t.Log("ok: an operator's own provider survives a restart")
}

// A forge with no mailer of its own asks for nothing: there is no
// credential to pass on, and inventing one is not this function's job.
func TestEnsureEmailIntegrationIsSilentWithoutACredential(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		t.Errorf("FAIL: asked the companion anything at all: %s %s", r.Method, r.URL.Path)
	}))
	defer srv.Close()
	c := New(srv.URL, "k")
	for _, s := range []EmailSender{
		{Provider: "resend", From: "quarry <[email protected]>"},
		{Provider: "resend", Key: "re_secret"},
	} {
		if made, err := c.EnsureEmailIntegration(context.Background(), s); made || err != nil {
			t.Errorf("FAIL: %+v gave made=%v err=%v", s, made, err)
		}
	}
	t.Log("ok: no credential, no integration, no noise")
}

// notify's subscriber upsert REPLACES the row, so an address has to ride
// along every time or the one already stored is blanked — and a
// subscriber with no address is one no email can reach.
func TestEnsureSubscriberCarriesTheAddress(t *testing.T) {
	var got map[string]string
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		json.NewDecoder(r.Body).Decode(&got)
		w.WriteHeader(http.StatusCreated)
		w.Write([]byte(`{}`))
	}))
	defer srv.Close()
	if err := New(srv.URL, "k").EnsureSubscriber(context.Background(), "dan", "[email protected]"); err != nil {
		t.Fatal(err)
	}
	if got["subscriberId"] != "dan" || got["email"] != "[email protected]" {
		t.Errorf("FAIL: sent %+v", got)
	}
	t.Log("ok: the address travels with the subscriber")
}