package state_test import ( "os" "path/filepath" "testing" "time" "ldpost/shared/state" ) func TestSaveAndLoadState(t *testing.T) { dir := t.TempDir() postPath := filepath.Join(dir, "Codigo", "test-slug") s := state.NewPostState("test-slug", "Codigo", "como", "Test tema", "Test trend") s.Status = state.StatusWaitingRedator s.SetEtapa("evaluator", state.EtapaDone) if err := state.SaveState(postPath, s); err != nil { t.Fatalf("SaveState: %v", err) } loaded, err := state.LoadState(postPath) if err != nil { t.Fatalf("LoadState: %v", err) } if loaded.Slug != "test-slug" { t.Errorf("slug: got %q, want %q", loaded.Slug, "test-slug") } if loaded.Status != state.StatusWaitingRedator { t.Errorf("status: got %q, want %q", loaded.Status, state.StatusWaitingRedator) } if loaded.Etapas.Evaluator != state.EtapaDone { t.Errorf("evaluator etapa: got %q, want %q", loaded.Etapas.Evaluator, state.EtapaDone) } } func TestAtomicWrite(t *testing.T) { dir := t.TempDir() postPath := filepath.Join(dir, "Cat", "slug-atomic") // Write initial state s1 := state.NewPostState("slug-atomic", "Cat", "como", "Tema 1", "Trend 1") if err := state.SaveState(postPath, s1); err != nil { t.Fatalf("first SaveState: %v", err) } // Verify original file exists stateFile := filepath.Join(postPath, "work", "state.json") before, err := os.ReadFile(stateFile) if err != nil { t.Fatalf("read state file: %v", err) } // Write second state s2 := state.NewPostState("slug-atomic", "Cat", "erro", "Tema 2", "Trend 2") if err := state.SaveState(postPath, s2); err != nil { t.Fatalf("second SaveState: %v", err) } after, err := os.ReadFile(stateFile) if err != nil { t.Fatalf("read state file after: %v", err) } // Files should differ (second write changed the content) if string(before) == string(after) { t.Error("estado não mudou após segundo SaveState") } // Verify no .tmp files left behind tmpFile := stateFile + ".tmp" if _, err := os.Stat(tmpFile); !os.IsNotExist(err) { t.Error("arquivo .tmp deixado para trás após SaveState") } } func TestSetEtapa(t *testing.T) { s := state.NewPostState("slug", "Cat", "como", "tema", "trend") agentes := []string{"evaluator", "redator", "editor", "art", "director", "publisher"} for _, ag := range agentes { before := s.UpdatedAt time.Sleep(time.Millisecond) // ensure time advances s.SetEtapa(ag, state.EtapaDone) if s.UpdatedAt.Equal(before) || s.UpdatedAt.Before(before) { t.Errorf("SetEtapa(%s): UpdatedAt não avançou", ag) } } if s.Etapas.Evaluator != state.EtapaDone { t.Errorf("evaluator etapa: got %q", s.Etapas.Evaluator) } if s.Etapas.Publisher != state.EtapaDone { t.Errorf("publisher etapa: got %q", s.Etapas.Publisher) } } func TestIsStatus(t *testing.T) { s := state.NewPostState("slug", "Cat", "como", "tema", "trend") s.Status = state.StatusWaitingEditor if !s.IsStatus(state.StatusWaitingEditor) { t.Error("IsStatus deveria retornar true") } if s.IsStatus(state.StatusPublished) { t.Error("IsStatus deveria retornar false") } }