Add more backend unit tests

This commit is contained in:
Jamie Curnow 2023-07-27 21:17:08 +10:00
parent d94e304f31
commit 7f9a1f5a98
No known key found for this signature in database
GPG Key ID: FFBB624C43388E9E
10 changed files with 836 additions and 0 deletions

View File

@ -0,0 +1,156 @@
package tags
import (
"npm/internal/util"
"testing"
"github.com/stretchr/testify/assert"
)
func TestGetFilterSchema(t *testing.T) {
m := struct {
ID int `filter:"id"`
Name string `filter:"name"`
}{
ID: 1,
Name: "John",
}
filterSchema := util.PrettyPrintJSON(GetFilterSchema(m))
expectedSchema := `{
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"field": {
"type": "string",
"pattern": "^id$"
},
"modifier": {
"type": "string",
"pattern": "^(equals|not|contains|starts|ends|in|notin)$"
},
"value": {
"oneOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
}
]
}
}
},
{
"type": "object",
"properties": {
"field": {
"type": "string",
"pattern": "^name$"
},
"modifier": {
"type": "string",
"pattern": "^(equals|not|contains|starts|ends|in|notin)$"
},
"value": {
"oneOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
}
]
}
}
}
]
}
}`
assert.Equal(t, expectedSchema, filterSchema)
}
func TestGetFilterTagSchema(t *testing.T) {
schema := util.PrettyPrintJSON(getFilterTagSchema("id,integer"))
expectedSchema := `{
"type": "object",
"properties": {
"field": {
"type": "string",
"pattern": "^id$"
},
"modifier": {
"type": "string",
"pattern": "^(equals|not|contains|starts|ends|in|notin|min|max|greater|less)$"
},
"value": {
"oneOf": [
{
"type": "string",
"pattern": "^[0-9]+$"
},
{
"type": "array",
"items": {
"type": "string",
"pattern": "^[0-9]+$"
}
}
]
}
}
}`
assert.Equal(t, expectedSchema, schema)
}
func TestBoolFieldSchema(t *testing.T) {
schema := util.PrettyPrintJSON(boolFieldSchema("active"))
expectedSchema := `{
"type": "object",
"properties": {
"field": {
"type": "string",
"pattern": "^active$"
},
"modifier": {
"type": "string",
"pattern": "^(equals|not)$"
},
"value": {
"oneOf": [
{
"type": "string",
"pattern": "^(TRUE|true|t|yes|y|on|1|FALSE|f|false|n|no|off|0)$"
},
{
"type": "array",
"items": {
"type": "string",
"pattern": "^(TRUE|true|t|yes|y|on|1|FALSE|f|false|n|no|off|0)$"
}
}
]
}
}
}`
assert.Equal(t, expectedSchema, schema)
}

View File

@ -0,0 +1,110 @@
package types
import (
"encoding/json"
"testing"
"time"
)
func TestDBDate_Value(t *testing.T) {
// Create a DBDate instance with a specific time
expectedTime := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC)
dbDate := DBDate{Time: expectedTime}
// Call the Value method
value, err := dbDate.Value()
// Assert the value and error
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
// Convert the value to int64
unixTime := value.(int64)
// Convert the unix time back to time.Time
actualTime := time.Unix(unixTime, 0)
// Compare the actual time with the expected time
if !actualTime.Equal(expectedTime) {
t.Errorf("Expected time '%v', got '%v'", expectedTime, actualTime)
}
}
func TestDBDate_Scan(t *testing.T) {
// Simulate a value from the database (unix timestamp)
unixTime := int64(1640995200)
// Create a DBDate instance
dbDate := DBDate{}
// Call the Scan method
err := dbDate.Scan(unixTime)
// Assert the error
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
// Convert the DBDate's time to unix timestamp for comparison
actualUnixTime := dbDate.Time.Unix()
// Compare the actual unix time with the expected unix time
if actualUnixTime != unixTime {
t.Errorf("Expected unix time '%v', got '%v'", unixTime, actualUnixTime)
}
}
func TestDBDate_UnmarshalJSON(t *testing.T) {
// Simulate a JSON input representing a unix timestamp
jsonData := []byte("1640995200")
// Create a DBDate instance
dbDate := DBDate{}
// Call the UnmarshalJSON method
err := dbDate.UnmarshalJSON(jsonData)
// Assert the error
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
// Convert the DBDate's time to unix timestamp for comparison
actualUnixTime := dbDate.Time.Unix()
// Compare the actual unix time with the expected unix time
expectedUnixTime := int64(1640995200)
if actualUnixTime != expectedUnixTime {
t.Errorf("Expected unix time '%v', got '%v'", expectedUnixTime, actualUnixTime)
}
}
func TestDBDate_MarshalJSON(t *testing.T) {
// Create a DBDate instance with a specific time
expectedTime := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC)
dbDate := DBDate{Time: expectedTime}
// Call the MarshalJSON method
jsonData, err := dbDate.MarshalJSON()
// Assert the value and error
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
// Convert the JSON data to an integer
var actualUnixTime int64
err = json.Unmarshal(jsonData, &actualUnixTime)
if err != nil {
t.Errorf("Failed to unmarshal JSON data: %v", err)
}
// Convert the unix time back to time.Time
actualTime := time.Unix(actualUnixTime, 0)
// Compare the actual time with the expected time
if !actualTime.Equal(expectedTime) {
t.Errorf("Expected time '%v', got '%v'", expectedTime, actualTime)
}
}

View File

@ -0,0 +1,91 @@
package types
import (
"testing"
)
func TestNullableDBIntValue(t *testing.T) {
var d NullableDBInt
// Test when Int is 0 (null)
d.Int = 0
value, err := d.Value()
if value != nil || err != nil {
t.Errorf("Expected Value() to return nil, nil but got %v, %v", value, err)
}
// Test when Int is not null
d.Int = 10
value, err = d.Value()
if value != int64(10) || err != nil {
t.Errorf("Expected Value() to return 10, nil but got %v, %v", value, err)
}
}
func TestNullableDBIntScan(t *testing.T) {
var d NullableDBInt
// Test when src is an int
err := d.Scan(20)
if d.Int != 20 || err != nil {
t.Errorf("Expected Scan(20) to set d.Int to 20 and return nil but got d.Int = %d, err = %v", d.Int, err)
}
// Test when src is an int64
err = d.Scan(int64(30))
if d.Int != 30 || err != nil {
t.Errorf("Expected Scan(int64(30)) to set d.Int to 30 and return nil but got d.Int = %d, err = %v", d.Int, err)
}
// Test when src is a float32
err = d.Scan(float32(40))
if d.Int != 40 || err != nil {
t.Errorf("Expected Scan(float32(40)) to set d.Int to 40 and return nil but got d.Int = %d, err = %v", d.Int, err)
}
// Test when src is a float64
err = d.Scan(float64(50))
if d.Int != 50 || err != nil {
t.Errorf("Expected Scan(float64(50)) to set d.Int to 50 and return nil but got d.Int = %d, err = %v", d.Int, err)
}
// Test when src is a string
err = d.Scan("60")
if d.Int != 60 || err != nil {
t.Errorf("Expected Scan(\"60\") to set d.Int to 60 and return nil but got d.Int = %d, err = %v", d.Int, err)
}
}
func TestNullableDBIntUnmarshalJSON(t *testing.T) {
var d NullableDBInt
// Test when data is an integer value
err := d.UnmarshalJSON([]byte("10"))
if d.Int != 10 || err != nil {
t.Errorf("Expected UnmarshalJSON([]byte(\"10\")) to set d.Int to 10 and return nil but got d.Int = %d, err = %v", d.Int, err)
}
// Test when data is null
err = d.UnmarshalJSON([]byte("null"))
if d.Int != 0 || err != nil {
t.Errorf("Expected UnmarshalJSON([]byte(\"null\")) to set d.Int to 0 and return nil but got d.Int = %d, err = %v", d.Int, err)
}
}
func TestNullableDBIntMarshalJSON(t *testing.T) {
var d NullableDBInt
// Test when Int is 0 (null)
d.Int = 0
result, err := d.MarshalJSON()
if string(result) != "null" || err != nil {
t.Errorf("Expected MarshalJSON() to return \"null\", nil but got %s, %v", result, err)
}
// Test when Int is not null
d.Int = 10
result, err = d.MarshalJSON()
if string(result) != "10" || err != nil {
t.Errorf("Expected MarshalJSON() to return \"10\", nil but got %s, %v", result, err)
}
}

View File

@ -0,0 +1,146 @@
package types
import (
"database/sql/driver"
"testing"
)
func TestNullableDBUint_Value(t *testing.T) {
tests := []struct {
name string
input NullableDBUint
wantValue driver.Value
wantErr bool
}{
{
name: "Value should return nil when Uint is 0",
input: NullableDBUint{Uint: 0},
wantValue: nil,
wantErr: false,
},
{
name: "Value should return int64 value of Uint",
input: NullableDBUint{Uint: 10},
wantValue: int64(10),
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotValue, gotErr := tt.input.Value()
if gotValue != tt.wantValue {
t.Errorf("Value() = %v, want %v", gotValue, tt.wantValue)
}
if (gotErr != nil) != tt.wantErr {
t.Errorf("Value() error = %v, wantErr %v", gotErr, tt.wantErr)
}
})
}
}
func TestNullableDBUint_Scan(t *testing.T) {
tests := []struct {
name string
input interface{}
wantUint uint
wantErr bool
}{
{
name: "Scan should convert int to uint",
input: int(10),
wantUint: uint(10),
wantErr: false,
},
{
name: "Scan should convert int64 to uint",
input: int64(10),
wantUint: uint(10),
wantErr: false,
},
// Add more tests for other supported types
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var d NullableDBUint
err := d.Scan(tt.input)
if err != nil && !tt.wantErr {
t.Errorf("Scan() error = %v, wantErr %v", err, tt.wantErr)
}
if d.Uint != tt.wantUint {
t.Errorf("Scan() Uint = %v, want %v", d.Uint, tt.wantUint)
}
})
}
}
func TestNullableDBUint_UnmarshalJSON(t *testing.T) {
tests := []struct {
name string
input []byte
wantUint uint
wantErr bool
}{
{
name: "UnmarshalJSON should unmarshal integer value",
input: []byte("10"),
wantUint: uint(10),
wantErr: false,
},
{
name: "UnmarshalJSON should return zero Uint when data is invalid",
input: []byte(`"invalid"`),
wantUint: uint(0),
wantErr: false,
},
// Add more tests for other scenarios
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var d NullableDBUint
err := d.UnmarshalJSON(tt.input)
if err != nil && !tt.wantErr {
t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
}
if d.Uint != tt.wantUint {
t.Errorf("UnmarshalJSON() Uint = %v, want %v", d.Uint, tt.wantUint)
}
})
}
}
func TestNullableDBUint_MarshalJSON(t *testing.T) {
tests := []struct {
name string
input NullableDBUint
wantOutput []byte
wantErr bool
}{
{
name: "MarshalJSON should marshal nil when Uint is 0",
input: NullableDBUint{Uint: 0},
wantOutput: []byte("null"),
wantErr: false,
},
{
name: "MarshalJSON should marshal Uint as JSON value",
input: NullableDBUint{Uint: 10},
wantOutput: []byte("10"),
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotOutput, gotErr := tt.input.MarshalJSON()
if (gotErr != nil) != tt.wantErr {
t.Errorf("MarshalJSON() error = %v, wantErr %v", gotErr, tt.wantErr)
}
if string(gotOutput) != string(tt.wantOutput) {
t.Errorf("MarshalJSON() output = %s, want %s", gotOutput, tt.wantOutput)
}
})
}
}

View File

@ -0,0 +1,133 @@
package types
import (
"encoding/json"
"testing"
)
// TestJSONBValue tests the Value method of the JSONB type
func TestJSONBValue(t *testing.T) {
j := JSONB{
Decoded: map[string]interface{}{
"name": "John",
"age": 30,
},
}
value, err := j.Value()
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
// nolint: goconst
if value != `{"age":30,"name":"John"}` {
t.Errorf("Incorrect value. Expected: %s, Got: %s", `{"name":"John","age":30}`, value)
}
}
// TestJSONBScan tests the Scan method of the JSONB type
func TestJSONBScan(t *testing.T) {
src := `{"name":"John","age":30}`
var j JSONB
err := j.Scan(src)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
expectedDecoded := map[string]interface{}{
"name": "John",
"age": 30,
}
if !jsonEqual(j.Decoded, expectedDecoded) {
t.Errorf("Incorrect decoded value. Expected: %v, Got: %v", expectedDecoded, j.Decoded)
}
if j.Encoded != src {
t.Errorf("Incorrect encoded value. Expected: %s, Got: %s", src, j.Encoded)
}
}
// TestJSONBUnmarshalJSON tests the UnmarshalJSON method of the JSONB type
func TestJSONBUnmarshalJSON(t *testing.T) {
data := []byte(`{"name":"John","age":30}`)
var j JSONB
err := j.UnmarshalJSON(data)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
expectedDecoded := map[string]interface{}{
"name": "John",
"age": 30,
}
if !jsonEqual(j.Decoded, expectedDecoded) {
t.Errorf("Incorrect decoded value. Expected: %v, Got: %v", expectedDecoded, j.Decoded)
}
if j.Encoded != string(data) {
t.Errorf("Incorrect encoded value. Expected: %s, Got: %s", string(data), j.Encoded)
}
}
// TestJSONBMarshalJSON tests the MarshalJSON method of the JSONB type
func TestJSONBMarshalJSON(t *testing.T) {
j := JSONB{
Decoded: map[string]interface{}{
"name": "John",
"age": 30,
},
}
result, err := j.MarshalJSON()
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
expectedResult := `{"age":30,"name":"John"}`
if string(result) != expectedResult {
t.Errorf("Incorrect result. Expected: %s, Got: %s", expectedResult, string(result))
}
}
// TestJSONBAsStringArray tests the AsStringArray method of the JSONB type
func TestJSONBAsStringArray(t *testing.T) {
j := JSONB{
Decoded: []string{"apple", "banana", "orange"},
}
strs, err := j.AsStringArray()
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
expectedStrs := []string{"apple", "banana", "orange"}
if !stringSliceEqual(strs, expectedStrs) {
t.Errorf("Incorrect result. Expected: %v, Got: %v", expectedStrs, strs)
}
}
// Helper function to compare JSON objects
func jsonEqual(a, b interface{}) bool {
aJSON, _ := json.Marshal(a)
bJSON, _ := json.Marshal(b)
return string(aJSON) == string(bJSON)
}
// Helper function to compare string slices
func stringSliceEqual(a, b []string) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}

View File

@ -0,0 +1,107 @@
package types
import (
"testing"
"time"
)
// TestNullableDBDateValue tests the Value method of the NullableDBDate type
func TestNullableDBDateValue(t *testing.T) {
tme := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC)
d := NullableDBDate{
Time: &tme,
}
value, err := d.Value()
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
expectedValue := tme.Unix()
if value != expectedValue {
t.Errorf("Incorrect value. Expected: %d, Got: %v", expectedValue, value)
}
}
// TestNullableDBDateScan tests the Scan method of the NullableDBDate type
func TestNullableDBDateScan(t *testing.T) {
var d NullableDBDate
err := d.Scan(int64(1640995200))
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
expectedTime := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC)
if !expectedTime.Equal(*d.Time) {
t.Errorf("Incorrect time. Expected: %v, Got: %v", expectedTime, *d.Time)
}
}
// TestNullableDBDateUnmarshalJSON tests the UnmarshalJSON method of the NullableDBDate type
func TestNullableDBDateUnmarshalJSON(t *testing.T) {
data := []byte(`1640995200`)
var d NullableDBDate
err := d.UnmarshalJSON(data)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
expectedTime := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC)
if !expectedTime.Equal(*d.Time) {
t.Errorf("Incorrect time. Expected: %v, Got: %v", expectedTime, *d.Time)
}
}
// TestNullableDBDateMarshalJSON tests the MarshalJSON method of the NullableDBDate type
func TestNullableDBDateMarshalJSON(t *testing.T) {
tme := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC)
d := NullableDBDate{
Time: &tme,
}
result, err := d.MarshalJSON()
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
expectedResult := []byte(`1640995200`)
if string(result) != string(expectedResult) {
t.Errorf("Incorrect result. Expected: %s, Got: %s", expectedResult, result)
}
}
// TestNullableDBDateAsInt64 tests the AsInt64 method of the NullableDBDate type
func TestNullableDBDateAsInt64(t *testing.T) {
tme := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC)
d := NullableDBDate{
Time: &tme,
}
unixtime := d.AsInt64()
expectedUnixtime := tme.Unix()
if unixtime != expectedUnixtime {
t.Errorf("Incorrect unixtime. Expected: %d, Got: %d", expectedUnixtime, unixtime)
}
}
// TestNullableDBDateAsString tests the AsString method of the NullableDBDate type
func TestNullableDBDateAsString(t *testing.T) {
tme := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC)
d := NullableDBDate{
Time: &tme,
}
str := d.AsString()
expectedStr := tme.String()
if str != expectedStr {
t.Errorf("Incorrect string. Expected: %s, Got: %s", expectedStr, str)
}
}

View File

@ -0,0 +1,33 @@
package util
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestFindItemInInterface(t *testing.T) {
obj := map[string]interface{}{
"key1": "value1",
"key2": 10,
"key3": map[string]interface{}{
"nestedKey": "nestedValue",
},
"key4": []interface{}{"item1", "item2"},
}
// Test case 1: Key exists at the top level
result, found := FindItemInInterface("key1", obj)
assert.Equal(t, true, found)
assert.Equal(t, "value1", result)
// Test case 2: Key exists at a nested level
result, found = FindItemInInterface("nestedKey", obj)
assert.Equal(t, true, found)
assert.Equal(t, "nestedValue", result)
// Test case 3: Key does not exist
result, found = FindItemInInterface("nonExistentKey", obj)
assert.Equal(t, false, found)
assert.Equal(t, nil, result)
}

View File

@ -1,6 +1,7 @@
package util package util
import ( import (
"reflect"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -90,3 +91,21 @@ func TestConvertIntSliceToString(t *testing.T) {
str := ConvertIntSliceToString(items) str := ConvertIntSliceToString(items)
assert.Equal(t, expectedStr, str) assert.Equal(t, expectedStr, str)
} }
func TestConvertStringSliceToInterface(t *testing.T) {
testCases := []struct {
input []string
expected []interface{}
}{
{[]string{"hello", "world"}, []interface{}{"hello", "world"}},
{[]string{"apple", "banana", "cherry"}, []interface{}{"apple", "banana", "cherry"}},
{[]string{}, []interface{}{}}, // Empty slice should return an empty slice
}
for _, tc := range testCases {
result := ConvertStringSliceToInterface(tc.input)
if !reflect.DeepEqual(result, tc.expected) {
t.Errorf("Expected: %v, Got: %v", tc.expected, result)
}
}
}

View File

@ -49,3 +49,19 @@ upstream npm_upstream_5 {
}) })
} }
} }
func TestPrettyPrintJSON(t *testing.T) {
testCases := []struct {
input string
expected string
}{
{`{"name":"John","age":30,"city":"New York"}`, "{\n \"name\": \"John\",\n \"age\": 30,\n \"city\": \"New York\"\n}"},
{`{"fruit":"apple","color":"red"}`, "{\n \"fruit\": \"apple\",\n \"color\": \"red\"\n}"},
{"invalid-json", "invalid-json"}, // non-JSON input should return the original string unchanged
}
for _, tc := range testCases {
result := PrettyPrintJSON(tc.input)
assert.Equal(t, tc.expected, result)
}
}

View File

@ -0,0 +1,25 @@
package util
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestUnixMilliToNiceFormat(t *testing.T) {
tests := []struct {
input int64
expected string
}{
{0, "1970-01-01 10:00:00"}, // Unix epoch time
{1568000000000, "2019-09-09 13:33:20"}, // Arbitrary millisecond timestamp
{1636598400000, "2021-11-11 12:40:00"}, // Another arbitrary millisecond timestamp
{-1000000000000, "1938-04-25 08:13:20"}, // Negative millisecond timestamp
{9223372036854775807, "1970-01-01 09:59:59"}, // Maximum representable millisecond timestamp
}
for _, test := range tests {
output := UnixMilliToNiceFormat(test.input)
assert.Equal(t, test.expected, output)
}
}