Skip to content
quarry Artifact [7e05bdb8d4]
Login

Artifact [7e05bdb8d4]

Artifact 7e05bdb8d44fc3f9cd385a79c98ca1faa74122414d71dccc5945d9e31b867100:


package notify

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

// An endpoint already carrying the forge's URL and signing is left
// alone; nothing is created or rotated across restarts.
func TestEnsureReplyEndpointKeepsASignedOne(t *testing.T) {
	posts := 0
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.Method + " " + r.URL.Path {
		case "GET /v1/webhooks/endpoints":
			w.Write([]byte(`{"data":[{"id":"ep_7","url":"https://forge/api/v1/notify/events","active":true,"signed":true}]}`))
		default:
			posts++
			w.WriteHeader(http.StatusCreated)
		}
	}))
	t.Cleanup(srv.Close)
	ep, err := New(srv.URL, "k").EnsureReplyEndpoint(context.Background(), "https://forge/api/v1/notify/events")
	if err != nil || posts != 0 || ep.ID != "ep_7" || ep.Secret != "" {
		t.Fatalf("FAIL: posts=%d ep=%+v err=%v", posts, ep, err)
	}
	t.Log("ok: the signed endpoint is reused and no secret is shown")
}

// An endpoint that exists unsigned is given a secret, and that secret
// comes back for the forge to keep.
func TestEnsureReplyEndpointSignsAnUnsignedOne(t *testing.T) {
	var hit []string
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		hit = append(hit, r.Method+" "+r.URL.Path)
		switch r.Method + " " + r.URL.Path {
		case "GET /v1/webhooks/endpoints":
			w.Write([]byte(`{"data":[{"id":"ep_7","url":"https://forge/api/v1/notify/events","active":true,"signed":false}]}`))
		case "POST /v1/webhooks/endpoints/ep_7/secret":
			w.Write([]byte(`{"id":"ep_7","signed":true,"secret":"whsec_new"}`))
		default:
			w.WriteHeader(http.StatusNotFound)
		}
	}))
	t.Cleanup(srv.Close)
	ep, err := New(srv.URL, "k").EnsureReplyEndpoint(context.Background(), "https://forge/api/v1/notify/events")
	if err != nil || ep.ID != "ep_7" || ep.Secret != "whsec_new" || !ep.Signed {
		t.Fatalf("FAIL: ep=%+v err=%v hits=%v", ep, err, hit)
	}
	t.Log("ok: the unsigned endpoint is rotated onto a secret")
}

// A forge that has none registers one, active, and keeps the secret
// notify shows once.
func TestEnsureReplyEndpointCreatesAndKeepsTheSecret(t *testing.T) {
	var got map[string]any
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.Method + " " + r.URL.Path {
		case "GET /v1/webhooks/endpoints":
			w.Write([]byte(`{"data":[]}`))
		case "POST /v1/webhooks/endpoints":
			b, _ := io.ReadAll(r.Body)
			json.Unmarshal(b, &got)
			w.WriteHeader(http.StatusCreated)
			w.Write([]byte(`{"id":"ep_1","url":"https://forge/api/v1/notify/events","active":true,"signed":true,"secret":"whsec_1"}`))
		}
	}))
	t.Cleanup(srv.Close)
	ep, err := New(srv.URL, "k").EnsureReplyEndpoint(context.Background(), "https://forge/api/v1/notify/events")
	if err != nil || ep.ID != "ep_1" || ep.Secret != "whsec_1" {
		t.Fatalf("FAIL: ep=%+v err=%v", ep, err)
	}
	if got["url"] != "https://forge/api/v1/notify/events" || got["active"] != true {
		t.Fatalf("FAIL: create request was %+v", got)
	}
	t.Log("ok: the endpoint is created active and its secret kept")
}

// A disabled client registers nothing and says so quietly.
func TestEnsureReplyEndpointNilClient(t *testing.T) {
	var c *Client
	if ep, err := c.EnsureReplyEndpoint(context.Background(), "https://forge/x"); err != nil || ep.ID != "" {
		t.Fatalf("FAIL: %+v %v", ep, err)
	}
	t.Log("ok: no notify, no endpoint")
}