Files
Datarush/internal/results/domain/result_test.go
T
2025-12-17 10:25:18 +03:00

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
}