The charger's own card list gets a door, and says where it differs

0104 was already implemented and already in the action catalogue; nothing
routed to it, so the only way to see the device's list was as a side
effect of writing a card. It has an endpoint now, and the panel a button.

The two lists are compared where they meet: a card the charger holds and
the account has forgotten still opens it, and a card only the account
holds will not, and neither shows anywhere else. The comparison is drawn
only when they disagree, and the device's reading is dropped on a refresh
rather than measured against an account list from a later moment.

The new test asks all four card routes without a token: a capability the
plugin implements and the catalogue advertises is still unusable if
nothing routes to it, and no other test here would notice.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tajniak81andClaude Opus 5 committed 2026-09-03 14:35:27 +02:00
1 parent 7176867eb3
commit 3064bff8ad
8 files changed
+165 -2

No files matched your search

@@ -3,10 +3,12 @@ package api
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
"drivervault/apiserver/internal/config"
"drivervault/apiserver/internal/pb"
)
@@ -217,3 +219,25 @@ func TestOCPPEndpoint(t *testing.T) {
t.Errorf("tls endpoint = %q", got)
}
}
// The four card routes are reachable at all. A capability the plugin implements
// and the action catalogue advertises is still unusable if nothing routes to it,
// and that is not a failure any other test here would notice: the plugin's own
// tests pass, and the panel simply has no button. Each route is asked for
// without a token, so what is being checked is that the request reached the
// authentication middleware rather than a 404.
func TestAnkerCardRoutesAreRegistered(t *testing.T) {
h := New(config.Config{}, nil).Handler()
for _, tc := range []struct{ method, path string }{
{"POST", "/api/integrations/anker-solix/chargers/SN1/rfid-cards"},
{"POST", "/api/integrations/anker-solix/chargers/SN1/rfid-cards/scan"},
{"GET", "/api/integrations/anker-solix/chargers/SN1/rfid-cards/charger"},
{"DELETE", "/api/integrations/anker-solix/chargers/SN1/rfid-cards/AABBCCDD"},
} {
rr := httptest.NewRecorder()
h.ServeHTTP(rr, httptest.NewRequest(tc.method, tc.path, nil))
if rr.Code == http.StatusNotFound {
t.Errorf("%s %s is not routed", tc.method, tc.path)
}
}
}