302 lines
7.3 KiB
Go
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)
|
|
}
|
|
}
|