diff --git a/internal/storage/memory/memory.go b/internal/storage/memory/memory.go index 4274cbd..af5dff7 100644 --- a/internal/storage/memory/memory.go +++ b/internal/storage/memory/memory.go @@ -2,6 +2,7 @@ package memory import ( + "fmt" "sync" "github.com/OCAP2/extension/v5/internal/config" @@ -104,6 +105,10 @@ func (b *Backend) EndMission() error { b.mu.Lock() defer b.mu.Unlock() + if b.mission == nil { + return fmt.Errorf("no mission to end: mission was never started") + } + return b.exportJSON() } @@ -313,10 +318,15 @@ func (b *Backend) GetExportedFilePath() string { } // GetExportMetadata returns metadata about the last export. +// Returns empty metadata if no mission was started. func (b *Backend) GetExportMetadata() storage.UploadMetadata { b.mu.RLock() defer b.mu.RUnlock() + if b.mission == nil || b.world == nil { + return storage.UploadMetadata{} + } + var endFrame uint for _, record := range b.soldiers { for _, state := range record.States { diff --git a/internal/storage/memory/memory_test.go b/internal/storage/memory/memory_test.go index a4dfa3c..5da75e1 100644 --- a/internal/storage/memory/memory_test.go +++ b/internal/storage/memory/memory_test.go @@ -934,3 +934,36 @@ func TestStartMissionResetsExportPath(t *testing.T) { t.Errorf("expected empty path after StartMission, got %s", path) } } + +func TestEndMissionWithoutStartMission(t *testing.T) { + b := New(config.MemoryConfig{}) + + // EndMission without StartMission should return an error, not panic + err := b.EndMission() + if err == nil { + t.Error("expected error when ending mission that was never started") + } + if !strings.Contains(err.Error(), "no mission to end") { + t.Errorf("expected error message to contain 'no mission to end', got: %s", err.Error()) + } +} + +func TestGetExportMetadataWithoutStartMission(t *testing.T) { + b := New(config.MemoryConfig{}) + + // GetExportMetadata without StartMission should return empty metadata, not panic + meta := b.GetExportMetadata() + + if meta.WorldName != "" { + t.Errorf("expected empty WorldName, got %s", meta.WorldName) + } + if meta.MissionName != "" { + t.Errorf("expected empty MissionName, got %s", meta.MissionName) + } + if meta.Tag != "" { + t.Errorf("expected empty Tag, got %s", meta.Tag) + } + if meta.MissionDuration != 0 { + t.Errorf("expected MissionDuration=0, got %f", meta.MissionDuration) + } +}