/*
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
Copyright (C) ITsysCOM GmbH

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>
*/
package utils

import (
	"reflect"
	"testing"
	"time"
)

var (
	testRoutesPrfs = []*RouteProfile{
		{
			Tenant:    "cgrates.org",
			ID:        "RouteProfile1",
			FilterIDs: []string{"FLTR_RPP_1"},
			Sorting:   MetaWeight,
			Routes: []*Route{
				{
					ID:              "route1",
					Weights:         DynamicWeights{{Weight: 10}},
					RouteParameters: "param1",
				},
			},
			Weights:  DynamicWeights{{Weight: 10}},
			Blockers: DynamicBlockers{{Blocker: true}},
		},
		{
			Tenant:    "cgrates.org",
			ID:        "RouteProfile2",
			FilterIDs: []string{"FLTR_SUPP_2"},
			Sorting:   MetaWeight,
			Routes: []*Route{
				{
					ID:              "route2",
					Weights:         DynamicWeights{{Weight: 20}},
					RouteParameters: "param2",
				},
				{
					ID:              "route3",
					Weights:         DynamicWeights{{Weight: 10}},
					RouteParameters: "param3",
				},
				{
					ID:              "route1",
					Weights:         DynamicWeights{{Weight: 30}},
					RouteParameters: "param1",
				},
			},
			Weights: DynamicWeights{{Weight: 20}},
		},
		{
			Tenant:    "cgrates.org",
			ID:        "RouteProfilePrefix",
			FilterIDs: []string{"FLTR_SUPP_3"},
			Sorting:   MetaWeight,
			Routes: []*Route{
				{
					ID:              "route1",
					Weights:         DynamicWeights{{Weight: 10}},
					RouteParameters: "param1",
				},
			},
			Weights: DynamicWeights{{Weight: 10}},
		},
	}
	testRoutesArgs = []*CGREvent{
		{ //matching RouteProfile1
			Tenant: "cgrates.org",
			ID:     "CGREvent1",
			Event: map[string]any{
				"Route":         "RouteProfile1",
				AnswerTime:      time.Date(2014, 7, 14, 14, 30, 0, 0, time.UTC),
				"UsageInterval": "1s",
				"PddInterval":   "1s",
				Weight:          "20.0",
			},
			APIOpts: map[string]any{
				OptsRoutesProfilesCount: 1,
			},
		},
		{ //matching RouteProfile2
			Tenant: "cgrates.org",
			ID:     "CGREvent1",
			Event: map[string]any{
				"Route":         "RouteProfile2",
				AnswerTime:      time.Date(2014, 7, 14, 14, 30, 0, 0, time.UTC),
				"UsageInterval": "1s",
				"PddInterval":   "1s",
				Weight:          "20.0",
			},
			APIOpts: map[string]any{
				OptsRoutesProfilesCount: 1,
			},
		},
		{ //matching RouteProfilePrefix
			Tenant: "cgrates.org",
			ID:     "CGREvent1",
			Event: map[string]any{
				"Route": "RouteProfilePrefix",
			},
			APIOpts: map[string]any{
				OptsRoutesProfilesCount: 1,
			},
		},
		{ //matching
			Tenant: "cgrates.org",
			ID:     "CGR",
			Event: map[string]any{
				"UsageInterval": "1s",
				"PddInterval":   "1s",
			},
			APIOpts: map[string]any{
				OptsRoutesProfilesCount: 1,
			},
		},
	}
)

func TestRouteProfileSet(t *testing.T) {
	rp := RouteProfile{}
	exp := RouteProfile{
		Tenant:    "cgrates.org",
		ID:        "ID",
		FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"},
		Weights:   DynamicWeights{{}},
		Blockers: DynamicBlockers{
			{Blocker: false},
		},
		Sorting:           MetaQOS,
		SortingParameters: []string{"param"},
		Routes: []*Route{{
			ID:             "RT1",
			FilterIDs:      []string{"fltr1"},
			AccountIDs:     []string{"acc1"},
			RateProfileIDs: []string{"rp1"},
			ResourceIDs:    []string{"res1"},
			StatIDs:        []string{"stat1"},
			Weights:        DynamicWeights{{}},
			Blockers: DynamicBlockers{
				{
					Blocker: true,
				},
			},
			RouteParameters: "params",
		}},
	}
	if err := rp.Set([]string{}, "", false); err != ErrWrongPath {
		t.Error(err)
	}
	if err := rp.Set([]string{"", ""}, "", false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{"NotAField"}, "", false); err != ErrWrongPath {
		t.Error(err)
	}
	if err := rp.Set([]string{"NotAField", "1"}, ":", false); err != ErrWrongPath {
		t.Error(err)
	}

	if err := rp.Set([]string{Tenant}, "cgrates.org", false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{ID}, "ID", false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{FilterIDs}, "fltr1;*string:~*req.Account:1001", false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{Weights}, ";0", false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{Blockers}, ";false", false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{Sorting}, MetaQOS, false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{SortingParameters}, "param", false); err != nil {
		t.Error(err)
	}

	if err := rp.Set([]string{Routes, ID}, "RT1", false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{Routes, FilterIDs}, "fltr1", false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{Routes, AccountIDs}, "acc1", false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{Routes, RateProfileIDs}, "rp1", false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{Routes, ResourceIDs}, "res1", false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{Routes, StatIDs}, "stat1", false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{Routes, Weights}, ";0", false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{Routes, Blockers}, ";true", false); err != nil {
		t.Error(err)
	}
	if err := rp.Set([]string{Routes, RouteParameters}, "params", false); err != nil {
		t.Error(err)
	}

	if err := rp.Set([]string{SortingParameters, "wrong"}, "param", false); err != ErrWrongPath {
		t.Error(err)
	}
	if err := rp.Set([]string{Routes, "wrong"}, "param", false); err != ErrWrongPath {
		t.Error(err)
	}

	if !reflect.DeepEqual(exp, rp) {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(rp))
	}
}

func TestRouteProfileAsInterface(t *testing.T) {
	rp := RouteProfile{
		Tenant:            "cgrates.org",
		ID:                "ID",
		FilterIDs:         []string{"fltr1", "*string:~*req.Account:1001"},
		Weights:           DynamicWeights{{}},
		Blockers:          DynamicBlockers{{Blocker: false}},
		Sorting:           MetaQOS,
		SortingParameters: []string{"param"},
		Routes: []*Route{{
			ID:             "RT1",
			FilterIDs:      []string{"fltr1"},
			AccountIDs:     []string{"acc1"},
			RateProfileIDs: []string{"rp1"},
			ResourceIDs:    []string{"res1"},
			StatIDs:        []string{"stat1"},
			Weights:        DynamicWeights{{}},
			Blockers: DynamicBlockers{
				{
					Blocker: true,
				},
			},
			RouteParameters: "params",
		}},
	}
	if _, err := rp.FieldAsInterface(nil); err != ErrNotFound {
		t.Fatal(err)
	}
	if _, err := rp.FieldAsInterface([]string{"field"}); err != ErrNotFound {
		t.Fatal(err)
	}
	if _, err := rp.FieldAsInterface([]string{"field", ""}); err != ErrNotFound {
		t.Fatal(err)
	}
	if val, err := rp.FieldAsInterface([]string{Tenant}); err != nil {
		t.Fatal(err)
	} else if exp := "cgrates.org"; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{ID}); err != nil {
		t.Fatal(err)
	} else if exp := ID; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Weights}); err != nil {
		t.Fatal(err)
	} else if exp := ";0"; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Blockers}); err != nil {
		t.Fatal(err)
	} else if exp := ";false"; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{FilterIDs}); err != nil {
		t.Fatal(err)
	} else if exp := rp.FilterIDs; !reflect.DeepEqual(exp, val) {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{FilterIDs + "[0]"}); err != nil {
		t.Fatal(err)
	} else if exp := rp.FilterIDs[0]; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{SortingParameters}); err != nil {
		t.Fatal(err)
	} else if exp := rp.SortingParameters; !reflect.DeepEqual(exp, val) {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{SortingParameters + "[0]"}); err != nil {
		t.Fatal(err)
	} else if exp := rp.SortingParameters[0]; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Sorting}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Sorting; !reflect.DeepEqual(exp, val) {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Routes; !reflect.DeepEqual(exp, val) {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]"}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Routes[0]; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if _, err := rp.FieldAsInterface([]string{Routes + "[4]", ""}); err != ErrNotFound {
		t.Fatal(err)
	}
	if _, err := rp.FieldAsInterface([]string{Routes + "[0]", ""}); err != ErrNotFound {
		t.Fatal(err)
	}
	if _, err := rp.FieldAsInterface([]string{Routes + "[0]", "", ""}); err != ErrNotFound {
		t.Fatal(err)
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]", ID}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Routes[0].ID; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]", Weights}); err != nil {
		t.Fatal(err)
	} else if exp := ";0"; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]", Blockers}); err != nil {
		t.Fatal(err)
	} else if exp := ";true"; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]", RouteParameters}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Routes[0].RouteParameters; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]", FilterIDs}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Routes[0].FilterIDs; !reflect.DeepEqual(exp, val) {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]", FilterIDs + "[0]"}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Routes[0].FilterIDs[0]; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]", AccountIDs}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Routes[0].AccountIDs; !reflect.DeepEqual(exp, val) {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]", AccountIDs + "[0]"}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Routes[0].AccountIDs[0]; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]", RateProfileIDs}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Routes[0].RateProfileIDs; !reflect.DeepEqual(exp, val) {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]", RateProfileIDs + "[0]"}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Routes[0].RateProfileIDs[0]; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]", ResourceIDs}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Routes[0].ResourceIDs; !reflect.DeepEqual(exp, val) {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]", ResourceIDs + "[0]"}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Routes[0].ResourceIDs[0]; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]", StatIDs}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Routes[0].StatIDs; !reflect.DeepEqual(exp, val) {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, err := rp.FieldAsInterface([]string{Routes + "[0]", StatIDs + "[0]"}); err != nil {
		t.Fatal(err)
	} else if exp := rp.Routes[0].StatIDs[0]; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}

	if _, err := rp.FieldAsString([]string{""}); err != ErrNotFound {
		t.Fatal(err)
	}
	if val, err := rp.FieldAsString([]string{ID}); err != nil {
		t.Fatal(err)
	} else if exp := "ID"; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, exp := rp.String(), ToJSON(rp); exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}

	if _, err := rp.Routes[0].FieldAsString([]string{""}); err != ErrNotFound {
		t.Fatal(err)
	}
	if val, err := rp.Routes[0].FieldAsString([]string{ID}); err != nil {
		t.Fatal(err)
	} else if exp := "RT1"; exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
	if val, exp := rp.Routes[0].String(), ToJSON(rp.Routes[0]); exp != val {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val))
	}
}

func TestRouteProfileMerge(t *testing.T) {
	dp := &RouteProfile{}
	exp := &RouteProfile{
		Tenant:            "cgrates.org",
		ID:                "ID",
		FilterIDs:         []string{"fltr1", "*string:~*req.Account:1001"},
		Weights:           DynamicWeights{{}},
		Sorting:           MetaQOS,
		SortingParameters: []string{"param"},
		Routes: []*Route{{
			ID:             "RT1",
			FilterIDs:      []string{"fltr1"},
			AccountIDs:     []string{"acc1"},
			RateProfileIDs: []string{"rp1"},
			ResourceIDs:    []string{"res1"},
			StatIDs:        []string{"stat1"},
			Weights:        DynamicWeights{{}},
			Blockers: DynamicBlockers{
				{
					Blocker: true,
				},
			},
			RouteParameters: "params",
		}},
	}
	if dp.Merge(&RouteProfile{
		Tenant:            "cgrates.org",
		ID:                "ID",
		FilterIDs:         []string{"fltr1", "*string:~*req.Account:1001"},
		Weights:           DynamicWeights{{}},
		Sorting:           MetaQOS,
		SortingParameters: []string{"param"},
		Routes: []*Route{{
			ID:             "RT1",
			FilterIDs:      []string{"fltr1"},
			AccountIDs:     []string{"acc1"},
			RateProfileIDs: []string{"rp1"},
			ResourceIDs:    []string{"res1"},
			StatIDs:        []string{"stat1"},
			Weights:        DynamicWeights{{}},
			Blockers: DynamicBlockers{
				{
					Blocker: true,
				},
			},
			RouteParameters: "params",
		}},
	}); !reflect.DeepEqual(exp, dp) {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(dp))
	}
}

func TestRouteMerge(t *testing.T) {

	route := &Route{}

	routeV2 := &Route{
		ID:              "RouteId",
		RouteParameters: "RouteParam",
		Weights:         DynamicWeights{{Weight: 10}},
		Blockers:        DynamicBlockers{{Blocker: false}},
		FilterIDs:       []string{"FltrId"},
		AccountIDs:      []string{"AccId"},
		RateProfileIDs:  []string{"RateProfileId"},
		ResourceIDs:     []string{"ResourceId"},
		StatIDs:         []string{"StatId"},
	}
	exp := routeV2

	route.Merge(routeV2)
	if !reflect.DeepEqual(route, exp) {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(route))
	}
}

func TestRouteProfileCompileCacheParametersErrParse(t *testing.T) {
	rp := &RouteProfile{
		Tenant:            "cgrates.org",
		ID:                "ID",
		FilterIDs:         []string{"fltr1", "*string:~*req.Account:1001"},
		Weights:           DynamicWeights{{}},
		Sorting:           MetaLoad,
		SortingParameters: []string{"sort:param"},
		Routes: []*Route{{
			ID:             "RT1",
			FilterIDs:      []string{"fltr1"},
			AccountIDs:     []string{"acc1"},
			RateProfileIDs: []string{"rp1"},
			ResourceIDs:    []string{"res1"},
			StatIDs:        []string{"stat1"},
			Weights:        DynamicWeights{{}},
			Blockers: DynamicBlockers{
				{
					Blocker: true,
				},
			},
			RouteParameters: "params",
		}},
	}

	expErr := `strconv.Atoi: parsing "param": invalid syntax`
	if err := rp.compileCacheParameters(); err.Error() != expErr || err == nil {
		t.Errorf("Expected error <%v>, Received error <%v>", expErr, err)
	}
}

func TestRouteProfileCompileCacheParametersConfigRatio(t *testing.T) {
	rp := &RouteProfile{
		Tenant:            "cgrates.org",
		ID:                "ID",
		FilterIDs:         []string{"fltr1", "*string:~*req.Account:1001"},
		Weights:           DynamicWeights{{}},
		Sorting:           MetaLoad,
		SortingParameters: []string{"param:1"},
		Routes: []*Route{{
			ID:             "RT1",
			FilterIDs:      []string{"fltr1"},
			AccountIDs:     []string{"acc1"},
			RateProfileIDs: []string{"rp1"},
			ResourceIDs:    []string{"res1"},
			StatIDs:        []string{"stat1"},
			Weights:        DynamicWeights{{}},
			Blockers: DynamicBlockers{
				{
					Blocker: true,
				},
			},
			RouteParameters: "params",
		}},
	}

	expErr := `strconv.Atoi: parsing "param": invalid syntax`
	if err := rp.compileCacheParameters(); err != nil {
		t.Errorf("Expected error <%v>, Received error <%v>", expErr, err)
	}
}

func TestRouteProfileCompileCacheParametersDefaultRatio(t *testing.T) {
	rp := &RouteProfile{
		Tenant:            "cgrates.org",
		ID:                "ID",
		FilterIDs:         []string{"fltr1", "*string:~*req.Account:1001"},
		Weights:           DynamicWeights{{}},
		Sorting:           MetaLoad,
		SortingParameters: []string{"*default:1"},
		Routes: []*Route{{
			ID:             "RT1",
			FilterIDs:      []string{"fltr1"},
			AccountIDs:     []string{"acc1"},
			RateProfileIDs: []string{"rp1"},
			ResourceIDs:    []string{"res1"},
			StatIDs:        []string{"stat1"},
			Weights:        DynamicWeights{{}},
			Blockers: DynamicBlockers{
				{
					Blocker: true,
				},
			},
			RouteParameters: "params",
		}},
	}

	expErr := `strconv.Atoi: parsing "param": invalid syntax`
	if err := rp.compileCacheParameters(); err != nil {
		t.Errorf("Expected error <%v>, Received error <%v>", expErr, err)
	}
}

func TestRouteProfileCompileCacheParametersRouteRatio(t *testing.T) {
	rp := &RouteProfile{
		Tenant:            "cgrates.org",
		ID:                "ID",
		FilterIDs:         []string{"fltr1", "*string:~*req.Account:1001"},
		Weights:           DynamicWeights{{}},
		Sorting:           MetaLoad,
		SortingParameters: []string{"RT1:1"},
		Routes: []*Route{{
			ID:             "RT1",
			FilterIDs:      []string{"fltr1"},
			AccountIDs:     []string{"acc1"},
			RateProfileIDs: []string{"rp1"},
			ResourceIDs:    []string{"res1"},
			StatIDs:        []string{"stat1"},
			Weights:        DynamicWeights{{}},
			Blockers: DynamicBlockers{
				{
					Blocker: true,
				},
			},
			RouteParameters: "params",
		}},
	}

	expErr := `strconv.Atoi: parsing "param": invalid syntax`
	if err := rp.compileCacheParameters(); err != nil {
		t.Errorf("Expected error <%v>, Received error <%v>", expErr, err)
	}
}

func TestRouteProfileMergeWithRPRoutes(t *testing.T) {
	dp := &RouteProfile{
		Routes: []*Route{
			{
				ID: "RT1",
			},
		},
	}
	exp := &RouteProfile{
		Tenant:            "cgrates.org",
		ID:                "ID",
		FilterIDs:         []string{"fltr1", "*string:~*req.Account:1001"},
		Weights:           DynamicWeights{{}},
		Sorting:           MetaQOS,
		SortingParameters: []string{"param"},
		Routes: []*Route{{
			ID:             "RT1",
			FilterIDs:      []string{"fltr1"},
			AccountIDs:     []string{"acc1"},
			RateProfileIDs: []string{"rp1"},
			ResourceIDs:    []string{"res1"},
			StatIDs:        []string{"stat1"},
			Weights:        DynamicWeights{{}},
			Blockers: DynamicBlockers{
				{
					Blocker: true,
				},
			},
			RouteParameters: "params",
		}},
	}
	if dp.Merge(&RouteProfile{
		Tenant:            "cgrates.org",
		ID:                "ID",
		FilterIDs:         []string{"fltr1", "*string:~*req.Account:1001"},
		Weights:           DynamicWeights{{}},
		Sorting:           MetaQOS,
		SortingParameters: []string{"param"},
		Routes: []*Route{{
			ID:             "RT1",
			FilterIDs:      []string{"fltr1"},
			AccountIDs:     []string{"acc1"},
			RateProfileIDs: []string{"rp1"},
			ResourceIDs:    []string{"res1"},
			StatIDs:        []string{"stat1"},
			Weights:        DynamicWeights{{}},
			Blockers: DynamicBlockers{
				{
					Blocker: true,
				},
			},
			RouteParameters: "params",
		}},
	}); !reflect.DeepEqual(exp, dp) {
		t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(dp))
	}
}
