package app import ( "context" "os" "path/filepath" "strings" "testing" ) // TestNew проверяет, что composition root собирается без ошибок. // Использует :memory: (? или file-based с t.TempDir). func TestNew(t *testing.T) { tmp := t.TempDir() dbPath := filepath.Join(tmp, "test.db") // Настраиваем минимальные env для обязательных полей t.Setenv("TG_TOKEN", "test:token") t.Setenv("TG_CHAT_ID", "12345") t.Setenv("RATATOSKR_DB", dbPath) // Загружаем без config-файла (дефолты + env) a, err := New("") if err != nil { t.Fatalf("New() err = %v", err) } if a.Store == nil { t.Fatal("Store не создан") } if a.Router == nil { t.Fatal("Router не создан") } if a.CoreCtx == nil { t.Fatal("Core не создан") } if a.Worker == nil { t.Fatal("Worker не создан") } if a.tg == nil { t.Fatal("Telegram-канал не создан") } t.Logf("app OK: db=%s", a.Config.Paths.DB) } // TestNew_MissingToken проверяет ошибку при пустом токене. func TestNew_MissingToken(t *testing.T) { tmp := t.TempDir() dbPath := filepath.Join(tmp, "test.db") t.Setenv("TG_TOKEN", "") t.Setenv("TG_CHAT_ID", "12345") t.Setenv("RATATOSKR_DB", dbPath) _, err := New("") if err == nil { t.Fatal("expected error for missing token") } t.Logf("got expected error: %v", err) } // TestNew_BadDB проверяет ошибку при пути к БД, который нельзя создать. func TestNew_BadDB(t *testing.T) { tmp := t.TempDir() dbPath := filepath.Join(tmp, "nonexistent", "test.db") // родителя нет t.Setenv("TG_TOKEN", "test:token") t.Setenv("TG_CHAT_ID", "12345") t.Setenv("RATATOSKR_DB", dbPath) _, err := New("") if err == nil { t.Fatal("expected error for invalid db path") } if !strings.Contains(err.Error(), "db open error") { t.Errorf("expected 'db open error' in message, got %v", err) } } // TestNew_CtxCancel проверяет, что Run завершается на отмене контекста. func TestNew_RunCtxCancel(t *testing.T) { tmp := t.TempDir() dbPath := filepath.Join(tmp, "test-runcancel.db") t.Setenv("TG_TOKEN", "test:token") t.Setenv("TG_CHAT_ID", "12345") t.Setenv("RATATOSKR_DB", dbPath) a, err := New("") if err != nil { t.Fatalf("New() err = %v", err) } ctx, cancel := context.WithCancel(context.Background()) cancel() // сразу отменяем err = a.Run(ctx) if err != nil { t.Fatalf("Run() expected nil, got %v", err) } t.Log("Run OK on cancelled context") } // TestMain — дёргает fatalf, нормально что os.Exit не тестируется. // Просто тест, что main.go компилируется. func TestMain(t *testing.T) { // main() не вызываем — он бы os.Exit _, err := os.Stat("../../cmd/ratatoskr/main.go") if err != nil { t.Fatalf("main.go not found: %v", err) } t.Log("main.go exists") }