333 lines
7.5 KiB
Go
333 lines
7.5 KiB
Go
package domain
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
func TestNewResult(t *testing.T) {
|
|
id := uuid.New()
|
|
competitionID := uuid.New()
|
|
userID := uuid.New()
|
|
submissionID := uuid.New()
|
|
now := time.Now()
|
|
rank := 1
|
|
|
|
result := NewResult(
|
|
id,
|
|
competitionID,
|
|
userID,
|
|
95.5,
|
|
&rank,
|
|
ResultStatusCompleted,
|
|
&submissionID,
|
|
map[string]interface{}{"notes": "test"},
|
|
now,
|
|
now,
|
|
)
|
|
|
|
if result.ID != id {
|
|
t.Errorf("Expected ID %v, got %v", id, result.ID)
|
|
}
|
|
if result.CompetitionID != competitionID {
|
|
t.Errorf("Expected CompetitionID %v, got %v", competitionID, result.CompetitionID)
|
|
}
|
|
if result.UserID != userID {
|
|
t.Errorf("Expected UserID %v, got %v", userID, result.UserID)
|
|
}
|
|
if result.Score != 95.5 {
|
|
t.Errorf("Expected Score 95.5, got %v", result.Score)
|
|
}
|
|
if result.Rank == nil || *result.Rank != 1 {
|
|
t.Errorf("Expected Rank 1, got %v", result.Rank)
|
|
}
|
|
if result.Status != ResultStatusCompleted {
|
|
t.Errorf("Expected Status %v, got %v", ResultStatusCompleted, result.Status)
|
|
}
|
|
if result.SubmissionID == nil || *result.SubmissionID != submissionID {
|
|
t.Errorf("Expected SubmissionID %v, got %v", submissionID, result.SubmissionID)
|
|
}
|
|
if len(result.Metadata) != 1 {
|
|
t.Errorf("Expected Metadata with 1 item, got %d", len(result.Metadata))
|
|
}
|
|
}
|
|
|
|
func TestResultStatusConstants(t *testing.T) {
|
|
tests := []struct {
|
|
status ResultStatus
|
|
expected string
|
|
}{
|
|
{ResultStatusUnspecified, "UNSPECIFIED"},
|
|
{ResultStatusPending, "PENDING"},
|
|
{ResultStatusProcessing, "PROCESSING"},
|
|
{ResultStatusCompleted, "COMPLETED"},
|
|
{ResultStatusFailed, "FAILED"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(string(tt.status), func(t *testing.T) {
|
|
if string(tt.status) != tt.expected {
|
|
t.Errorf("Expected %s, got %s", tt.expected, tt.status)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestResultWithNilValues(t *testing.T) {
|
|
id := uuid.New()
|
|
competitionID := uuid.New()
|
|
userID := uuid.New()
|
|
now := time.Now()
|
|
|
|
result := NewResult(
|
|
id,
|
|
competitionID,
|
|
userID,
|
|
0.0,
|
|
nil,
|
|
ResultStatusPending,
|
|
nil,
|
|
nil,
|
|
now,
|
|
now,
|
|
)
|
|
|
|
if result.Rank != nil {
|
|
t.Errorf("Expected Rank to be nil, got %v", result.Rank)
|
|
}
|
|
if result.SubmissionID != nil {
|
|
t.Errorf("Expected SubmissionID to be nil, got %v", result.SubmissionID)
|
|
}
|
|
if result.Metadata != nil {
|
|
t.Errorf("Expected Metadata to be nil, got %v", result.Metadata)
|
|
}
|
|
}
|
|
|
|
func TestResultMetadata(t *testing.T) {
|
|
id := uuid.New()
|
|
competitionID := uuid.New()
|
|
userID := uuid.New()
|
|
now := time.Now()
|
|
|
|
metadata := map[string]interface{}{
|
|
"attempt": 3,
|
|
"time_spent": 3600,
|
|
"notes": "First submission",
|
|
"tags": []string{"urgent", "review"},
|
|
}
|
|
|
|
result := NewResult(
|
|
id,
|
|
competitionID,
|
|
userID,
|
|
95.5,
|
|
nil,
|
|
ResultStatusCompleted,
|
|
nil,
|
|
metadata,
|
|
now,
|
|
now,
|
|
)
|
|
|
|
if len(result.Metadata) != 4 {
|
|
t.Errorf("Expected 4 metadata items, got %d", len(result.Metadata))
|
|
}
|
|
|
|
if result.Metadata["attempt"] != 3 {
|
|
t.Errorf("Expected attempt=3, got %v", result.Metadata["attempt"])
|
|
}
|
|
|
|
if result.Metadata["notes"] != "First submission" {
|
|
t.Errorf("Expected notes='First submission', got %v", result.Metadata["notes"])
|
|
}
|
|
}
|
|
|
|
func TestResultScoreRange(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
score float64
|
|
valid bool
|
|
}{
|
|
{"Zero score", 0.0, true},
|
|
{"Positive score", 95.5, true},
|
|
{"Max score", 100.0, true},
|
|
{"High score", 1000.0, true},
|
|
{"Negative score", -10.0, true}, // Negative might be valid in some contexts
|
|
{"Decimal precision", 95.123456, true},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := &Result{
|
|
ID: uuid.New(),
|
|
CompetitionID: uuid.New(),
|
|
UserID: uuid.New(),
|
|
Score: tt.score,
|
|
Status: ResultStatusCompleted,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
if result.Score != tt.score {
|
|
t.Errorf("Expected score %v, got %v", tt.score, result.Score)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestResultRankValidation(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
rank *int
|
|
}{
|
|
{"First place", intPtr(1)},
|
|
{"Middle rank", intPtr(50)},
|
|
{"Last place", intPtr(1000)},
|
|
{"No rank", nil},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := &Result{
|
|
ID: uuid.New(),
|
|
CompetitionID: uuid.New(),
|
|
UserID: uuid.New(),
|
|
Score: 95.5,
|
|
Rank: tt.rank,
|
|
Status: ResultStatusCompleted,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
if tt.rank != nil && result.Rank != nil && *result.Rank != *tt.rank {
|
|
t.Errorf("Expected rank %d, got %d", *tt.rank, *result.Rank)
|
|
}
|
|
|
|
if tt.rank == nil && result.Rank != nil {
|
|
t.Errorf("Expected rank to be nil, got %d", *result.Rank)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestResultStatusTransitions(t *testing.T) {
|
|
result := &Result{
|
|
ID: uuid.New(),
|
|
CompetitionID: uuid.New(),
|
|
UserID: uuid.New(),
|
|
Score: 0.0,
|
|
Status: ResultStatusPending,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
result.Status = ResultStatusProcessing
|
|
if result.Status != ResultStatusProcessing {
|
|
t.Errorf("Expected status %v, got %v", ResultStatusProcessing, result.Status)
|
|
}
|
|
|
|
result.Status = ResultStatusCompleted
|
|
result.Score = 95.5
|
|
if result.Status != ResultStatusCompleted {
|
|
t.Errorf("Expected status %v, got %v", ResultStatusCompleted, result.Status)
|
|
}
|
|
|
|
result.Status = ResultStatusFailed
|
|
if result.Status != ResultStatusFailed {
|
|
t.Errorf("Expected status %v, got %v", ResultStatusFailed, result.Status)
|
|
}
|
|
}
|
|
|
|
func TestResultTimestamps(t *testing.T) {
|
|
now := time.Now()
|
|
result := &Result{
|
|
ID: uuid.New(),
|
|
CompetitionID: uuid.New(),
|
|
UserID: uuid.New(),
|
|
Score: 95.5,
|
|
Status: ResultStatusCompleted,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
if !result.CreatedAt.Equal(now) {
|
|
t.Errorf("Expected CreatedAt %v, got %v", now, result.CreatedAt)
|
|
}
|
|
|
|
if !result.UpdatedAt.Equal(now) {
|
|
t.Errorf("Expected UpdatedAt %v, got %v", now, result.UpdatedAt)
|
|
}
|
|
|
|
if result.UpdatedAt.Before(result.CreatedAt) {
|
|
t.Errorf("UpdatedAt should not be before CreatedAt")
|
|
}
|
|
}
|
|
|
|
func TestResultWithSubmission(t *testing.T) {
|
|
submissionID := uuid.New()
|
|
result := &Result{
|
|
ID: uuid.New(),
|
|
CompetitionID: uuid.New(),
|
|
UserID: uuid.New(),
|
|
Score: 95.5,
|
|
Status: ResultStatusCompleted,
|
|
SubmissionID: &submissionID,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
if result.SubmissionID == nil {
|
|
t.Error("Expected SubmissionID to be set")
|
|
}
|
|
|
|
if *result.SubmissionID != submissionID {
|
|
t.Errorf("Expected SubmissionID %v, got %v", submissionID, *result.SubmissionID)
|
|
}
|
|
}
|
|
|
|
func TestResultComparison(t *testing.T) {
|
|
competitionID := uuid.New()
|
|
now := time.Now()
|
|
|
|
result1 := &Result{
|
|
ID: uuid.New(),
|
|
CompetitionID: competitionID,
|
|
UserID: uuid.New(),
|
|
Score: 100.0,
|
|
Rank: intPtr(1),
|
|
Status: ResultStatusCompleted,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
result2 := &Result{
|
|
ID: uuid.New(),
|
|
CompetitionID: competitionID,
|
|
UserID: uuid.New(),
|
|
Score: 95.0,
|
|
Rank: intPtr(2),
|
|
Status: ResultStatusCompleted,
|
|
CreatedAt: now.Add(1 * time.Second),
|
|
UpdatedAt: now.Add(1 * time.Second),
|
|
}
|
|
|
|
if result1.Score <= result2.Score {
|
|
t.Errorf("result1 should have higher score than result2")
|
|
}
|
|
|
|
if *result1.Rank >= *result2.Rank {
|
|
t.Errorf("result1 should have lower (better) rank than result2")
|
|
}
|
|
|
|
if result1.CreatedAt.After(result2.CreatedAt) {
|
|
t.Errorf("result1 should be created before result2")
|
|
}
|
|
}
|
|
|
|
// Helper function
|
|
func intPtr(i int) *int {
|
|
return &i
|
|
}
|