mirror of
https://github.com/jc21/nginx-proxy-manager.git
synced 2024-08-30 18:22:48 +00:00
Add more backend unit tests
This commit is contained in:
parent
d94e304f31
commit
7f9a1f5a98
156
backend/internal/tags/filters_test.go
Normal file
156
backend/internal/tags/filters_test.go
Normal 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)
|
||||||
|
}
|
110
backend/internal/types/db_date_test.go
Normal file
110
backend/internal/types/db_date_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
91
backend/internal/types/db_nullable_int_test.go
Normal file
91
backend/internal/types/db_nullable_int_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
146
backend/internal/types/db_nullable_uint_test.go
Normal file
146
backend/internal/types/db_nullable_uint_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
133
backend/internal/types/jsonb_test.go
Normal file
133
backend/internal/types/jsonb_test.go
Normal 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
|
||||||
|
}
|
107
backend/internal/types/nullable_db_date_test.go
Normal file
107
backend/internal/types/nullable_db_date_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
33
backend/internal/util/interfaces_test.go
Normal file
33
backend/internal/util/interfaces_test.go
Normal 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)
|
||||||
|
}
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
25
backend/internal/util/time_test.go
Normal file
25
backend/internal/util/time_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user