573 - New plugin - schema mapper
This commit is contained in:
240
pkg/plugin/implementation/reqmapper/reqmapper_test.go
Normal file
240
pkg/plugin/implementation/reqmapper/reqmapper_test.go
Normal file
@@ -0,0 +1,240 @@
|
||||
package reqmapper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func resetEngineState(t *testing.T) {
|
||||
t.Helper()
|
||||
engineInstance = nil
|
||||
engineOnce = sync.Once{}
|
||||
}
|
||||
|
||||
func testMappingsFile(t *testing.T) string {
|
||||
t.Helper()
|
||||
path := filepath.Join("testdata", "mappings.yaml")
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
t.Fatalf("test mappings file missing: %v", err)
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
func initTestEngine(t *testing.T) *MappingEngine {
|
||||
t.Helper()
|
||||
resetEngineState(t)
|
||||
engine, err := initMappingEngine(&Config{
|
||||
Role: "bap",
|
||||
MappingsFile: testMappingsFile(t),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to init mapping engine: %v", err)
|
||||
}
|
||||
return engine
|
||||
}
|
||||
|
||||
func TestNewReqMapper_InvalidConfig(t *testing.T) {
|
||||
t.Run("nil config", func(t *testing.T) {
|
||||
if _, err := NewReqMapper(nil); err == nil {
|
||||
t.Fatalf("expected error for nil config")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("invalid role", func(t *testing.T) {
|
||||
if _, err := NewReqMapper(&Config{Role: "invalid"}); err == nil {
|
||||
t.Fatalf("expected error for invalid role")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestNewReqMapper_MiddlewareTransformsRequest(t *testing.T) {
|
||||
resetEngineState(t)
|
||||
mw, err := NewReqMapper(&Config{
|
||||
Role: "bap",
|
||||
MappingsFile: testMappingsFile(t),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("NewReqMapper returned error: %v", err)
|
||||
}
|
||||
|
||||
startLocation := map[string]interface{}{
|
||||
"gps": "12.9716,77.5946",
|
||||
"city": "Bengaluru",
|
||||
}
|
||||
endLocation := map[string]interface{}{
|
||||
"gps": "13.0827,80.2707",
|
||||
"city": "Chennai",
|
||||
}
|
||||
|
||||
requestPayload := map[string]interface{}{
|
||||
"context": map[string]interface{}{
|
||||
"domain": "retail",
|
||||
"action": "search",
|
||||
"version": "1.1.0",
|
||||
"bap_id": "bap.example",
|
||||
"bap_uri": "https://bap.example/api",
|
||||
"transaction_id": "txn-1",
|
||||
"message_id": "msg-1",
|
||||
"timestamp": "2023-01-01T10:00:00Z",
|
||||
},
|
||||
"message": map[string]interface{}{
|
||||
"intent": map[string]interface{}{
|
||||
"item": map[string]interface{}{
|
||||
"id": "item-1",
|
||||
},
|
||||
"provider": map[string]interface{}{
|
||||
"id": "provider-1",
|
||||
},
|
||||
"fulfillment": map[string]interface{}{
|
||||
"start": map[string]interface{}{
|
||||
"location": startLocation,
|
||||
},
|
||||
"end": map[string]interface{}{
|
||||
"location": endLocation,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
body, err := json.Marshal(requestPayload)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to marshal request payload: %v", err)
|
||||
}
|
||||
|
||||
var captured map[string]interface{}
|
||||
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
data, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read request in handler: %v", err)
|
||||
}
|
||||
if err := json.Unmarshal(data, &captured); err != nil {
|
||||
t.Fatalf("failed to unmarshal transformed payload: %v", err)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/", bytes.NewReader(body))
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
mw(next).ServeHTTP(rec, req)
|
||||
|
||||
if captured == nil {
|
||||
t.Fatalf("middleware did not forward request to next handler")
|
||||
}
|
||||
|
||||
message, ok := captured["message"].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("expected message field in transformed payload")
|
||||
}
|
||||
|
||||
filters, ok := message["filters"].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("expected filters in transformed payload")
|
||||
}
|
||||
|
||||
if pickup := filters["pickup"]; !reflect.DeepEqual(pickup, startLocation) {
|
||||
t.Fatalf("pickup location mismatch\ngot: %#v\nwant: %#v", pickup, startLocation)
|
||||
}
|
||||
if drop := filters["drop"]; !reflect.DeepEqual(drop, endLocation) {
|
||||
t.Fatalf("drop location mismatch\ngot: %#v\nwant: %#v", drop, endLocation)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMappingEngine_TransformFallbackForUnknownAction(t *testing.T) {
|
||||
engine := initTestEngine(t)
|
||||
req := map[string]interface{}{
|
||||
"context": map[string]interface{}{
|
||||
"action": "unknown_action",
|
||||
},
|
||||
"message": map[string]interface{}{},
|
||||
}
|
||||
|
||||
expected, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to marshal expected payload: %v", err)
|
||||
}
|
||||
|
||||
result, err := engine.Transform(context.Background(), "unknown_action", req, "bap")
|
||||
if err != nil {
|
||||
t.Fatalf("Transform returned error: %v", err)
|
||||
}
|
||||
if !bytes.Equal(result, expected) {
|
||||
t.Fatalf("expected Transform to return original payload")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMappingEngine_TransformFallbackForUnknownRole(t *testing.T) {
|
||||
engine := initTestEngine(t)
|
||||
req := map[string]interface{}{
|
||||
"context": map[string]interface{}{
|
||||
"action": "search",
|
||||
},
|
||||
"message": map[string]interface{}{},
|
||||
}
|
||||
|
||||
expected, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to marshal expected payload: %v", err)
|
||||
}
|
||||
|
||||
result, err := engine.Transform(context.Background(), "search", req, "unknown-role")
|
||||
if err != nil {
|
||||
t.Fatalf("Transform returned error: %v", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(result, expected) {
|
||||
t.Fatalf("expected Transform to return original payload when role is unknown")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMappingEngine_ReloadMappings(t *testing.T) {
|
||||
engine := initTestEngine(t)
|
||||
|
||||
engine.mutex.RLock()
|
||||
originalBAP := len(engine.bapMaps)
|
||||
originalBPP := len(engine.bppMaps)
|
||||
engine.mutex.RUnlock()
|
||||
|
||||
if originalBAP == 0 || originalBPP == 0 {
|
||||
t.Fatalf("expected test mappings to be loaded")
|
||||
}
|
||||
|
||||
engine.mutex.Lock()
|
||||
for action := range engine.bapMaps {
|
||||
delete(engine.bapMaps, action)
|
||||
break
|
||||
}
|
||||
engine.mutex.Unlock()
|
||||
|
||||
engine.mutex.RLock()
|
||||
if len(engine.bapMaps) == originalBAP {
|
||||
engine.mutex.RUnlock()
|
||||
t.Fatalf("expected BAP map to be altered before reload")
|
||||
}
|
||||
engine.mutex.RUnlock()
|
||||
|
||||
if err := engine.ReloadMappings(); err != nil {
|
||||
t.Fatalf("ReloadMappings returned error: %v", err)
|
||||
}
|
||||
|
||||
engine.mutex.RLock()
|
||||
defer engine.mutex.RUnlock()
|
||||
|
||||
if len(engine.bapMaps) != originalBAP {
|
||||
t.Fatalf("expected BAP mappings to be reloaded, got %d want %d", len(engine.bapMaps), originalBAP)
|
||||
}
|
||||
if len(engine.bppMaps) != originalBPP {
|
||||
t.Fatalf("expected BPP mappings to be reloaded, got %d want %d", len(engine.bppMaps), originalBPP)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user