mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2026-10-01 19:20:31 +00:00
99 lines
3.6 KiB
Go
99 lines
3.6 KiB
Go
package resolvespec
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func TestBuildHeadersFilters(t *testing.T) {
|
|
got := BuildHeaders(&FuncSpecOptions{Filters: []FilterOption{
|
|
{Column: "status", Operator: "eq", Value: "active"},
|
|
{Column: "age", Operator: "gte", Value: 18},
|
|
{Column: "name", Operator: "contains", Value: "x", LogicOperator: "OR"},
|
|
{Column: "deleted", Operator: "is_null"},
|
|
{Column: "id", Operator: "in", Value: []int{1, 2}},
|
|
{Column: "p", Operator: "between_inclusive", Value: []any{1, 5}},
|
|
}})
|
|
want := map[string]string{
|
|
"X-FieldFilter-status": "active",
|
|
"X-SearchOp-greaterthanorequal-age": "18",
|
|
"X-SearchOr-contains-name": "x",
|
|
"X-SearchOp-empty-deleted": "",
|
|
"X-SearchOp-in-id": "1,2",
|
|
"X-SearchOp-betweeninclusive-p": "1,5",
|
|
}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("%v", got)
|
|
}
|
|
}
|
|
|
|
func TestBuildHeadersMisc(t *testing.T) {
|
|
got := BuildHeaders(&FuncSpecOptions{
|
|
SearchFilters: map[string]string{"name": "bob"}, CustomSQLWhere: "a = 1", CustomSQLOr: "b = 2",
|
|
Sort: []SortOption{{"name", "asc"}, {"created_at", "DESC"}},
|
|
Limit: Int(5), Offset: Int(10), Distinct: Bool(true), SkipCount: Bool(true), SkipCache: Bool(false),
|
|
ResponseFormat: "syncfusion",
|
|
})
|
|
want := map[string]string{
|
|
"X-SearchFilter-name": "bob", "X-Custom-SQL-W": "a = 1", "X-Custom-SQL-Or": "b = 2",
|
|
"X-Sort": "name ASC,created_at DESC", "X-Limit": "5", "X-Offset": "10", "X-Distinct": "true",
|
|
"X-SkipCount": "true", "X-SkipCache": "false", "X-Syncfusion": "true",
|
|
}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("%v", got)
|
|
}
|
|
}
|
|
|
|
func TestEncodeUnsafe(t *testing.T) {
|
|
h := BuildHeaders(&FuncSpecOptions{Filters: []FilterOption{{Column: "n", Operator: "eq", Value: "héllo"}, {Column: "m", Operator: "eq", Value: " pad"}}})
|
|
for _, k := range []string{"X-FieldFilter-n", "X-FieldFilter-m"} {
|
|
if len(h[k]) < 4 || h[k][:4] != "ZIP_" {
|
|
t.Fatalf("%s=%q", k, h[k])
|
|
}
|
|
}
|
|
if DecodeHeaderValue(h["X-FieldFilter-n"]) != "héllo" || DecodeHeaderValue(h["X-FieldFilter-m"]) != " pad" {
|
|
t.Fatal("roundtrip")
|
|
}
|
|
}
|
|
|
|
func TestBuildQuery(t *testing.T) {
|
|
q := BuildQuery(Params{"a": true, "b": []string{"x", "y"}, "c": nil, "d": 3})
|
|
if q.Get("a") != "true" || !reflect.DeepEqual(q["b"], []string{"x", "y"}) || q.Has("c") || q.Get("d") != "3" {
|
|
t.Fatalf("%v", q)
|
|
}
|
|
}
|
|
|
|
func TestQueryListMetadata(t *testing.T) {
|
|
srv, s := server(t, 206, `[{"id":1},{"id":2}]`, map[string]string{"Content-Range": "items 10-12/50"})
|
|
c := NewFuncSpecClient(srv.URL, WithToken("tok"))
|
|
resp, err := c.QueryList(context.Background(), "/api/users", Params{"org": 1}, &FuncSpecOptions{Limit: Int(2)})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if s.method != "GET" || s.path != "/api/users?org=1" || s.header.Get("X-Limit") != "2" {
|
|
t.Fatalf("%s %v", s.path, s.header)
|
|
}
|
|
m := resp.Metadata
|
|
if m.Total != 50 || m.Count != 2 || m.Offset != 10 || m.Limit != 2 || m.Filtered != 50 {
|
|
t.Fatalf("%+v", m)
|
|
}
|
|
var rows []map[string]any
|
|
if err := resp.Decode(&rows); err != nil || len(rows) != 2 {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestQuerySingleNoMetadataAndError(t *testing.T) {
|
|
srv, _ := server(t, 200, `{"id":1}`, nil)
|
|
resp, err := NewFuncSpecClient(srv.URL).Query(context.Background(), "api/u", nil, nil)
|
|
if err != nil || resp.Metadata != nil {
|
|
t.Fatalf("%v %v", resp, err)
|
|
}
|
|
srv2, _ := server(t, 400, `{"success":false,"error":{"code":"hook_error","message":"Hook execution failed","detail":"authentication required"}}`, nil)
|
|
_, err = NewFuncSpecClient(srv2.URL).Query(context.Background(), "api/u", nil, nil)
|
|
if e := err.(*Error); e.Code != "hook_error" || e.Detail != "authentication required" {
|
|
t.Fatalf("%#v", e)
|
|
}
|
|
}
|