A disabled record stays in Jarl with its ID, TTL and comment but is left out of the zone; the zone file lists it as a comment. Web UI toggle, jarl record disable|enable, record.disable|enable operations and API endpoints. Database schema 5. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
62 lines
2.8 KiB
Go
62 lines
2.8 KiB
Go
package server
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestDisableRecords(t *testing.T) {
|
|
e := newAPIEnv(t)
|
|
e.do("POST", "/zones", e.token, map[string]any{"name": "example.com", "records": []map[string]any{{"name": "ns1", "type": "A", "data": "192.0.2.1"}}}, 201)
|
|
www := e.do("POST", "/zones/example.com/records", e.token, map[string]any{"name": "www", "type": "A", "data": "192.0.2.10"}, 201)["object"].(map[string]any)
|
|
id := itoa(int64(www["id"].(float64)))
|
|
|
|
// By ID: the record comes back disabled.
|
|
if r := e.do("POST", "/records/"+id+"/disable", e.token, nil, 201)["object"].(map[string]any); r["disabled"] != true {
|
|
t.Errorf("disabled record = %v", r)
|
|
}
|
|
if _, status := e.req("POST", "/records/"+id+"/disable", e.token, nil); status != 409 {
|
|
t.Errorf("disabling twice = %d, want 409", status)
|
|
}
|
|
if z := e.do("GET", "/zones/example.com", e.token, nil, 200); z["disabled_count"] != 1.0 || z["record_count"] != 3.0 {
|
|
t.Errorf("zone counts = %v / %v", z["record_count"], z["disabled_count"])
|
|
}
|
|
off := e.list("/zones/example.com/records?disabled=1", e.token)
|
|
on := e.list("/zones/example.com/records?disabled=0", e.token)
|
|
if len(off) != 1 || off[0]["name"] != "www.example.com." || len(on) != 2 {
|
|
t.Errorf("filtered: %d disabled, %d enabled", len(off), len(on))
|
|
}
|
|
file := e.do("GET", "/zones/example.com/file", e.token, nil, 200)
|
|
if s, _ := file["_raw"].(string); !strings.Contains(s, "; disabled: www") {
|
|
t.Errorf("zone file = %v", file)
|
|
}
|
|
|
|
// Staged: listing with the changeset marks the record.
|
|
cs := itoa(int64(e.do("POST", "/changesets", e.token, map[string]any{"description": "back"}, 201)["id"].(float64)))
|
|
e.do("POST", "/records/"+id+"/enable?changeset="+cs, e.token, nil, 202)
|
|
for _, r := range e.list("/zones/example.com/records?changeset="+cs, e.token) {
|
|
if r["name"] == "www.example.com." && (r["pending"] != "enable" || r["disabled"] == true) {
|
|
t.Errorf("staged record = %v", r)
|
|
}
|
|
}
|
|
e.do("POST", "/changesets/"+cs+"/discard", e.token, nil, 204)
|
|
|
|
// By match.
|
|
e.do("POST", "/zones/example.com/records/enable?name=www&type=A", e.token, nil, 201)
|
|
if _, status := e.req("POST", "/zones/example.com/records/disable?name=nope&type=A", e.token, nil); status != 404 {
|
|
t.Errorf("no match = %d", status)
|
|
}
|
|
if _, status := e.req("POST", "/zones/example.com/records/disable?name=www", e.token, nil); status != 400 {
|
|
t.Errorf("no type = %d", status)
|
|
}
|
|
e.do("POST", "/zones/example.com/records/disable?name=www&type=A&data=192.0.2.10", e.token, nil, 201)
|
|
if r := e.do("GET", "/records/"+id, e.token, nil, 200); r["disabled"] != true {
|
|
t.Errorf("after match disable = %v", r)
|
|
}
|
|
// And in a batch.
|
|
e.do("POST", "/apply", e.token, map[string]any{"ops": []map[string]any{{"op": "record.enable", "id": www["id"]}}}, 201)
|
|
if r := e.do("GET", "/records/"+id, e.token, nil, 200); r["disabled"] == true {
|
|
t.Errorf("after batch enable = %v", r)
|
|
}
|
|
}
|