Files
Authentication/helper/access_log_test.go
T
2025-11-25 15:12:31 +08:00

302 lines
7.3 KiB
Go

package helper
import (
"authentication/models"
"encoding/json"
"testing"
"time"
)
func TestLogEvent(t *testing.T) {
// Note: This test requires database and Redis connections
// In a real test environment, you'd use mocks or test databases
// For now, we'll test the structure and basic validation
t.Skip("Integration test - requires database and Redis")
userID := "user123"
ipAddress := "192.168.1.1"
actType := 17
fieldUpdate := map[string]string{"field": "value"}
err := LogEvent("test-id", &userID, ipAddress, actType, fieldUpdate)
if err != nil {
t.Errorf("Expected no error, got: %v", err)
}
}
func TestLogEventNilUser(t *testing.T) {
t.Skip("Integration test - requires database and Redis")
ipAddress := "192.168.1.1"
actType := 17
err := LogEvent("test-id", nil, ipAddress, actType, nil)
if err != nil {
t.Errorf("Expected no error with nil user, got: %v", err)
}
}
func TestLogEventNilFieldUpdate(t *testing.T) {
t.Skip("Integration test - requires database and Redis")
userID := "user456"
ipAddress := "10.0.0.1"
actType := 5
err := LogEvent("test-id", &userID, ipAddress, actType, nil)
if err != nil {
t.Errorf("Expected no error with nil field update, got: %v", err)
}
}
func TestLogLoginEventV2(t *testing.T) {
t.Skip("Integration test - requires database and Redis")
err := LogLoginEventV2("user789", "172.16.0.1")
if err != nil {
t.Errorf("Expected no error, got: %v", err)
}
}
func TestLogLoginEventV2EmptyIP(t *testing.T) {
t.Skip("Integration test - requires database and Redis")
err := LogLoginEventV2("user999", "")
if err != nil {
t.Errorf("Expected no error with empty IP, got: %v", err)
}
}
func TestLogLoginEventParams(t *testing.T) {
t.Skip("Integration test - requires database and Redis")
fieldUpdated := new(json.RawMessage)
data := []byte(`{"key": "value"}`)
fieldUpdated = (*json.RawMessage)(&data)
params := models.LogEventParams{
UserID: stringPtr("user123"),
ActivityType: 17,
IPAddress: "192.168.1.100",
FieldUpdated: fieldUpdated,
ErrorMessage: ErrorFailedtoLogLoginEvent,
}
err := LogLoginEventParams(params, "192.168.1.100")
if err != nil {
t.Errorf("Expected no error, got: %v", err)
}
}
func TestLogLoginEventParamsActivityTypes(t *testing.T) {
t.Skip("Integration test - requires database and Redis")
activityTypes := []int{1, 5, 10, 17, 20}
for _, actType := range activityTypes {
params := models.LogEventParams{
ActivityType: actType,
IPAddress: "192.168.1.1",
FieldUpdated: new(json.RawMessage),
ErrorMessage: ErrorFailedtoLogLoginEvent,
}
err := LogLoginEventParams(params, "192.168.1.1")
if err != nil {
t.Errorf("Expected no error for activity type %d, got: %v", actType, err)
}
}
}
func TestLogEventJSONMarshalling(t *testing.T) {
// Test that field updates can be marshalled correctly
testCases := []struct {
name string
fieldUpdate interface{}
expectError bool
}{
{
name: "Simple map",
fieldUpdate: map[string]string{"field": "value"},
expectError: false,
},
{
name: "Complex object",
fieldUpdate: map[string]interface{}{"nested": map[string]string{"key": "value"}},
expectError: false,
},
{
name: "Array",
fieldUpdate: []string{"item1", "item2"},
expectError: false,
},
{
name: "Nil",
fieldUpdate: nil,
expectError: false,
},
{
name: "Unmarshalable (channel)",
fieldUpdate: make(chan int),
expectError: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
var fieldUpdated *json.RawMessage
if tc.fieldUpdate != nil {
data, err := json.Marshal(tc.fieldUpdate)
if tc.expectError {
if err == nil {
t.Error("Expected marshalling error")
}
return
}
if err != nil {
t.Errorf("Unexpected marshalling error: %v", err)
return
}
rawMsg := json.RawMessage(data)
fieldUpdated = &rawMsg
} else {
fieldUpdated = new(json.RawMessage)
}
if fieldUpdated == nil {
t.Error("Field updated should not be nil")
}
})
}
}
func TestLogEventParamsStructValidation(t *testing.T) {
// Test LogEventParams struct can be properly constructed
params := models.LogEventParams{
UserID: stringPtr("user123"),
ParticipantID: stringPtr("part456"),
ActivityType: 17,
IPAddress: "192.168.1.1",
FieldUpdated: new(json.RawMessage),
ErrorMessage: ErrorFailedtoLogLoginEvent,
}
if params.UserID == nil || *params.UserID != "user123" {
t.Error("UserID not set correctly")
}
if params.ParticipantID == nil || *params.ParticipantID != "part456" {
t.Error("ParticipantID not set correctly")
}
if params.ActivityType != 17 {
t.Errorf("Expected activity type 17, got %d", params.ActivityType)
}
if params.IPAddress != "192.168.1.1" {
t.Errorf("Expected IP 192.168.1.1, got %s", params.IPAddress)
}
if params.ErrorMessage != ErrorFailedtoLogLoginEvent {
t.Errorf("Expected error message '%s', got '%s'", ErrorFailedtoLogLoginEvent, params.ErrorMessage)
}
}
func TestUserAccessLogStructValidation(t *testing.T) {
location, _ := LoadAsiaManilaLocation()
now := timeNow().In(location)
fieldData := json.RawMessage(`{"key": "value"}`)
log := models.UserAccessLog{
UserID: stringPtr("user123"),
ParticipantID: stringPtr("part456"),
ActivityType: 17,
IPAddress: "192.168.1.1",
FieldUpdated: &fieldData,
Time: now,
}
if log.UserID == nil || *log.UserID != "user123" {
t.Error("UserID not set correctly")
}
if log.ActivityType != 17 {
t.Errorf("Expected activity type 17, got %d", log.ActivityType)
}
if log.IPAddress != "192.168.1.1" {
t.Errorf("Expected IP 192.168.1.1, got %s", log.IPAddress)
}
if log.FieldUpdated == nil {
t.Error("FieldUpdated should not be nil")
}
}
func TestLogEventIPAddressFormats(t *testing.T) {
// Test various IP address formats
ipAddresses := []string{
"192.168.1.1",
"10.0.0.1",
"172.16.0.1",
"2001:0db8:85a3:0000:0000:8a2e:0370:7334", // IPv6
"::1", // IPv6 loopback
"127.0.0.1", // localhost
}
for _, ip := range ipAddresses {
t.Run(ip, func(t *testing.T) {
// Just test that the IP format is accepted
params := models.LogEventParams{
ActivityType: 17,
IPAddress: ip,
FieldUpdated: new(json.RawMessage),
ErrorMessage: ErrorFailedtoLogLoginEvent,
}
if params.IPAddress != ip {
t.Errorf("Expected IP %s, got %s", ip, params.IPAddress)
}
})
}
}
func stringPtr(s string) *string {
return &s
}
func timeNow() time.Time {
return time.Now()
}
func TestLogLoginEventV2ActivityType(t *testing.T) {
// Verify that LogLoginEventV2 uses activity type 17
// This is verified by checking the function implementation
expectedActivityType := 17
// The function hardcodes activity type 17
// We can't directly test this without integration tests,
// but we can document the expected behavior
if expectedActivityType != 17 {
t.Errorf("LogLoginEventV2 should use activity type 17")
}
}
func TestErrorFailedtoLogLoginEventConstant(t *testing.T) {
if ErrorFailedtoLogLoginEvent == "" {
t.Error("ErrorFailedtoLogLoginEvent constant should not be empty")
}
expectedMsg := "Failed to log login event"
if ErrorFailedtoLogLoginEvent != expectedMsg {
t.Errorf("Expected error message '%s', got '%s'", expectedMsg, ErrorFailedtoLogLoginEvent)
}
}