diff --git a/utils/json_codec_test.go b/utils/json_codec_test.go new file mode 100644 index 000000000..791a68b1e --- /dev/null +++ b/utils/json_codec_test.go @@ -0,0 +1,202 @@ +/* +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 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package utils + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/rpc" + "testing" +) + +func TestNewCustomJSONServerCodec(t *testing.T) { + + reader, writer := io.Pipe() + + codec := NewCustomJSONServerCodec(struct { + io.Reader + io.Writer + io.Closer + }{Reader: reader, Writer: writer, Closer: writer}) + + c := codec.(*jsonServerCodec) + + if c.dec == nil { + t.Error("Decoder is nil") + } + if c.enc == nil { + t.Error("Encoder is nil") + } + if c.c == nil { + t.Error("Connection is nil") + } + if c.pending == nil { + t.Error("Pending map is nil") + } + + writer.Close() +} + +func TestJSONCodecReset(t *testing.T) { + + r := serverRequest{ + Method: "test", + Params: &json.RawMessage{}, + Id: &json.RawMessage{}, + isApier: false, + } + + r.reset() + + if r.Method != "" { + t.Error("Method didn't clear") + } + if r.Params != nil { + t.Error("Params didn't clear") + } + if r.Id != nil { + t.Error("Id didn't clear") + } +} + +type bufferClose struct { + *bytes.Buffer +} + +func (b *bufferClose) Close() error { + return nil +} + +func TestJSONCodecReadRequestHeader2(t *testing.T) { + tests := []struct { + name string + write []byte + exp error + }{ + { + name: "ValidRequest", + write: []byte(`{ + "method": "APIerSv1.RemTP", + "params": [{ + "TPid": "test" + }], + "id": 0 + }`), + exp: nil, + }, + { + name: "InvalidRequest", + write: []byte("test"), + exp: fmt.Errorf("invalid character 'e' in literal true (expecting 'r')"), + }, + { + name: "ValidApierRequest", + write: []byte(`{ + "method": "ApierV.Method", + "params": [{ + "TPid": "test" + }], + "id": 0 + }`), + exp: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + conn := &bufferClose{ + Buffer: &bytes.Buffer{}, + } + s := NewCustomJSONServerCodec(conn) + + rr := rpc.Request{ + ServiceMethod: "Service.Method", + Seq: 1, + } + + conn.Write(tt.write) + + err := s.ReadRequestHeader(&rr) + if err != nil { + if err.Error() != tt.exp.Error() { + t.Errorf("Received an error: %v", err) + } + } + }) + } +} + +func TestJSONReadRequestBody(t *testing.T) { + tests := []struct{ + name string + arg any + exp error + params bool + }{ + { + name: "nil argument", + arg: nil, + exp: nil, + params: false, + }, + { + name: "check error missing param", + arg: "test", + exp: errMissingParams, + params: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + conn := &bufferClose{ + Buffer: &bytes.Buffer{}, + } + s := NewCustomJSONServerCodec(conn) + sj := s.(*jsonServerCodec) + + if tt.params { + sj.req.Params = nil + } + + err := s.ReadRequestBody(tt.arg) + + if err != nil { + if err.Error() != tt.exp.Error() { + t.Errorf("recived %s, expected %s", err, tt.exp) + } + } + }) + } +} + +func TestJSONCodecClose(t *testing.T) { + conn := &bufferClose{ + Buffer: &bytes.Buffer{}, + } + s := NewCustomJSONServerCodec(conn) + + err := s.Close() + + if err != nil { + t.Errorf("unexpected error: %s", err) + } +} diff --git a/utils/value_formula_test.go b/utils/value_formula_test.go index 2fee56cef..246bfe065 100644 --- a/utils/value_formula_test.go +++ b/utils/value_formula_test.go @@ -19,6 +19,7 @@ package utils import ( "encoding/json" + "errors" "reflect" "testing" "time" @@ -76,3 +77,134 @@ func TestValueFormulaParseBalanceFilterValue(t *testing.T) { t.Errorf("Expecting: %+v, received: %+v", eVF, vf) } } + +func TestValueFormulaString(t *testing.T) { + vf := ValueFormula{ + Method: "test", + Params: map[string]any{"test": "val1"}, + Static: 1.2, + } + + rcv := vf.String() + exp := `{"Method":"test","Params":{"test":"val1"},"Static":1.2}` + + if rcv != exp { + t.Errorf("recived %s, expected %s", rcv, exp) + } +} + +func TestValueFormulaParseBalanceFilterValue2(t *testing.T) { + vf := ValueFormula{ + Method: "test", + Params: map[string]any{"test": "val1"}, + Static: 1.2, + } + + type args struct { + tor string + val string + } + + type exp struct { + val *ValueFormula + err error + } + tests := []struct { + name string + args args + exp exp + }{ + { + name: "json unmarshal error case", + args: args{tor: "*voice", val: "test"}, + exp: exp{val: nil, err: errors.New("Invalid value: " + "test")}, + }, + { + name: "json unmarshal case", + args: args{tor: "*voice", val: `{"Method":"test","Params":{"test":"val1"},"Static":1.2}`}, + exp: exp{val: &vf, err: nil}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + rcv, err := ParseBalanceFilterValue(tt.args.tor, tt.args.val) + + if err != nil { + if err.Error() != tt.exp.err.Error() { + t.Fatalf("recived %s, expected %s", err, tt.exp.err) + } + } + + if !reflect.DeepEqual(rcv, tt.exp.val) { + t.Errorf("recived %s, expected %s", rcv, tt.exp.val) + } + }) + } +} + +func TestValueFormulaIncremetalFormula(t *testing.T) { + now := time.Now() + + tests := []struct { + name string + arg map[string]any + exp float64 + }{ + { + name: "keys not found", + arg: map[string]any{}, + exp: 0.0, + }, + { + name: "units is not a float64", + arg: map[string]any{"Units": "test", "Interval": "test", "Increment": "test"}, + exp: 0.0, + }, + { + name: "type []byte", + arg: map[string]any{"Units": 1.2, "Interval": []byte{1, 2}, "Increment": []byte{1, 2}}, + exp: 0.0, + }, + { + name: "default interval", + arg: map[string]any{"Units": 1.2, "Interval": 1, "Increment": 1}, + exp: 0.0, + }, + { + name: "default increment", + arg: map[string]any{"Units": 1.2, "Interval": []byte{1, 2}, "Increment": 1}, + exp: 0.0, + }, + { + name: "hour day", + arg: map[string]any{"Units": 1.5, "Interval": "day", "Increment": "hour"}, + exp: 1.5 / 24, + }, + { + name: "hour month", + arg: map[string]any{"Units": 1.5, "Interval": "month", "Increment": "hour"}, + exp: 1.5 / (DaysInMonth(now.Year(), now.Month()) * 24), + }, + { + name: "hour year", + arg: map[string]any{"Units": 1.5, "Interval": "year", "Increment": "hour"}, + exp: 1.5 / (DaysInYear(now.Year()) * 24), + }, + { + name: "minute hour", + arg: map[string]any{"Units": 1.5, "Interval": "hour", "Increment": "minute"}, + exp: 1.5 / 60, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + rcv := incrementalFormula(tt.arg) + + if rcv != tt.exp { + t.Errorf("recived %v, expected %v", rcv, tt.exp) + } + }) + } +}