Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
package eprel
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestNormalizeAndExtractID(t *testing.T) {
|
||||
if got := NormalizeID(" 246834 "); got != "246834" {
|
||||
t.Fatalf("string=%q", got)
|
||||
}
|
||||
if got := NormalizeID(float64(246834)); got != "246834" {
|
||||
t.Fatalf("float=%q", got)
|
||||
}
|
||||
if got := NormalizeID(map[string]any{"#text": "99"}); got != "99" {
|
||||
t.Fatalf("xml text=%q", got)
|
||||
}
|
||||
if IsValidID("") || IsValidID(nil) {
|
||||
t.Fatal("empty should be invalid")
|
||||
}
|
||||
mapped := map[string]any{"title": "Fridge"}
|
||||
raw := map[string]any{"EPRELID": "12345"}
|
||||
if got := ExtractID(mapped, raw); got != "12345" {
|
||||
t.Fatalf("extract=%q", got)
|
||||
}
|
||||
mapped2 := map[string]any{"eprel_id": "777"}
|
||||
if got := ExtractID(mapped2); got != "777" {
|
||||
t.Fatalf("mapped key=%q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientFetch_httptest(t *testing.T) {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/api/product/246834/fiches", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Query().Get("noRedirect") != "true" {
|
||||
t.Errorf("missing noRedirect")
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(map[string]string{
|
||||
"address": "/fiches/demo/Fiche_246834_EN.pdf",
|
||||
})
|
||||
})
|
||||
mux.HandleFunc("/api/product/246834", func(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.Contains(r.URL.Path, "fiches") || strings.Contains(r.URL.Path, "labels") {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(map[string]string{
|
||||
"energyClass": "A_plus",
|
||||
"energyClassRange": "A-G",
|
||||
})
|
||||
})
|
||||
srv := httptest.NewServer(mux)
|
||||
defer srv.Close()
|
||||
|
||||
client := NewClient(Options{
|
||||
Enabled: true,
|
||||
BaseURL: srv.URL + "/api",
|
||||
Timeout: 2 * time.Second,
|
||||
HTTPClient: srv.Client(),
|
||||
})
|
||||
data, err := client.Fetch(context.Background(), "246834")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if data == nil {
|
||||
t.Fatal("expected data")
|
||||
}
|
||||
if !strings.Contains(data.Label, "/product/246834/labels") {
|
||||
t.Fatalf("label=%q", data.Label)
|
||||
}
|
||||
if !strings.HasSuffix(data.PDF, "/fiches/demo/Fiche_246834_EN.pdf") {
|
||||
t.Fatalf("pdf=%q", data.PDF)
|
||||
}
|
||||
if data.EnergyClass != "A-plus" {
|
||||
t.Fatalf("class=%q", data.EnergyClass)
|
||||
}
|
||||
if data.EnergyScale != "A-G" {
|
||||
t.Fatalf("scale=%q", data.EnergyScale)
|
||||
}
|
||||
|
||||
attrs := MergeInto(nil, data)
|
||||
if attrs[AttrID] != "246834" || attrs[AttrEnergyClass] != "A-plus" {
|
||||
t.Fatalf("attrs=%v", attrs)
|
||||
}
|
||||
if FieldValue(data, "eprel_pdf_url") == "" {
|
||||
t.Fatal("FieldValue pdf empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientDisabledAndInvalid(t *testing.T) {
|
||||
c := NewClient(Options{Enabled: false})
|
||||
if c.Enabled() {
|
||||
t.Fatal("should be disabled")
|
||||
}
|
||||
data, err := c.Fetch(context.Background(), "1")
|
||||
if err != nil || data != nil {
|
||||
t.Fatalf("disabled fetch: %v %#v", err, data)
|
||||
}
|
||||
enabled := NewClient(Options{Enabled: true, BaseURL: "http://127.0.0.1:1", Timeout: time.Millisecond})
|
||||
if _, err := enabled.Fetch(context.Background(), "../etc/passwd"); err == nil {
|
||||
t.Fatal("expected invalid id error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientPartialFicheFailure(t *testing.T) {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/api/product/1/fiches", func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "gone", http.StatusNotFound)
|
||||
})
|
||||
mux.HandleFunc("/api/product/1", func(w http.ResponseWriter, r *http.Request) {
|
||||
_ = json.NewEncoder(w).Encode(map[string]string{"energyClass": "B"})
|
||||
})
|
||||
srv := httptest.NewServer(mux)
|
||||
defer srv.Close()
|
||||
|
||||
client := NewClient(Options{Enabled: true, BaseURL: srv.URL + "/api", Timeout: time.Second, HTTPClient: srv.Client()})
|
||||
data, err := client.Fetch(context.Background(), "1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if data.PDF != "" {
|
||||
t.Fatalf("expected empty pdf, got %q", data.PDF)
|
||||
}
|
||||
if data.EnergyClass != "B" {
|
||||
t.Fatalf("class=%q", data.EnergyClass)
|
||||
}
|
||||
if data.Label == "" {
|
||||
t.Fatal("label should still be set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAPIKeyNotInErrorBodies(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("X-API-KEY") != "super-secret-key" {
|
||||
t.Errorf("missing api key header")
|
||||
}
|
||||
http.Error(w, "unauthorized secret=super-secret-key", http.StatusUnauthorized)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
client := NewClient(Options{
|
||||
Enabled: true,
|
||||
BaseURL: srv.URL,
|
||||
APIKey: "super-secret-key",
|
||||
Timeout: time.Second,
|
||||
})
|
||||
// Fiche failure is soft; product info soft-fails too — Fetch still returns label-only data.
|
||||
data, err := client.Fetch(context.Background(), "9")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if data == nil || data.Label == "" {
|
||||
t.Fatal("expected label-only result")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user