1package tester
2
3import (
4	"encoding/json"
5	"net/http"
6	"net/http/httptest"
7
8	"github.com/go-acme/lego/v3/acme"
9)
10
11// SetupFakeAPI Minimal stub ACME server for validation.
12func SetupFakeAPI() (*http.ServeMux, string, func()) {
13	mux := http.NewServeMux()
14	ts := httptest.NewServer(mux)
15
16	mux.HandleFunc("/dir", func(w http.ResponseWriter, r *http.Request) {
17		if r.Method != http.MethodGet {
18			http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
19			return
20		}
21
22		err := WriteJSONResponse(w, acme.Directory{
23			NewNonceURL:   ts.URL + "/nonce",
24			NewAccountURL: ts.URL + "/account",
25			NewOrderURL:   ts.URL + "/newOrder",
26			RevokeCertURL: ts.URL + "/revokeCert",
27			KeyChangeURL:  ts.URL + "/keyChange",
28		})
29
30		mux.HandleFunc("/nonce", func(w http.ResponseWriter, r *http.Request) {
31			if r.Method != http.MethodHead {
32				http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
33				return
34			}
35
36			w.Header().Add("Replay-Nonce", "12345")
37			w.Header().Add("Retry-After", "0")
38		})
39
40		if err != nil {
41			http.Error(w, err.Error(), http.StatusInternalServerError)
42			return
43		}
44	})
45
46	return mux, ts.URL, ts.Close
47}
48
49// WriteJSONResponse marshals the body as JSON and writes it to the response.
50func WriteJSONResponse(w http.ResponseWriter, body interface{}) error {
51	bs, err := json.Marshal(body)
52	if err != nil {
53		return err
54	}
55
56	w.Header().Set("Content-Type", "application/json")
57	if _, err := w.Write(bs); err != nil {
58		return err
59	}
60
61	return nil
62}
63