package discord import ( "context" "encoding/json" "net/http" "net/http/httptest" "testing" "time" "mixmaker/backend/internal/domain" ) func TestAnnounceEventCreated(t *testing.T) { var received messagePayload server := httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) { if request.Method != http.MethodPost || request.URL.Path != "/channels/channel-123/messages" { t.Errorf("unexpected request: %s %s", request.Method, request.URL.Path) } if authorization := request.Header.Get("Authorization"); authorization != "Bot secret-token" { t.Errorf("unexpected Authorization header: %q", authorization) } if err := json.NewDecoder(request.Body).Decode(&received); err != nil { t.Errorf("decode payload: %v", err) } response.WriteHeader(http.StatusCreated) })) defer server.Close() announcer, err := New(Config{ BotToken: "secret-token", ChannelID: "channel-123", PublicURL: "https://mix.example.com", Locale: "ru", APIBaseURL: server.URL, HTTPClient: server.Client(), }) if err != nil { t.Fatal(err) } start := time.Date(2026, time.July, 20, 18, 0, 0, 0, time.UTC) event := domain.Event{ ID: "event-456", Name: "Воскресный микс", Description: "Собираемся на Bo3", StartsAt: start, RegistrationDeadline: start.Add(-2 * time.Hour), } if err := announcer.AnnounceEventCreated(context.Background(), event); err != nil { t.Fatal(err) } if received.Content != "@everyone" { t.Fatalf("unexpected content: %q", received.Content) } if len(received.AllowedMentions.Parse) != 1 || received.AllowedMentions.Parse[0] != "everyone" { t.Fatalf("unexpected allowed mentions: %+v", received.AllowedMentions) } if len(received.Embeds) != 1 { t.Fatalf("expected one embed, got %d", len(received.Embeds)) } eventURL := "https://mix.example.com/events/event-456" if received.Embeds[0].Title != "Новый микс: Воскресный микс" || received.Embeds[0].Description != event.Description || received.Embeds[0].URL != eventURL || len(received.Embeds[0].Fields) != 2 { t.Fatalf("unexpected embed: %+v", received.Embeds[0]) } if len(received.Components) != 1 || len(received.Components[0].Components) != 1 { t.Fatalf("unexpected components: %+v", received.Components) } linkButton := received.Components[0].Components[0] if linkButton.Style != 5 || linkButton.Label != "Зарегистрироваться" || linkButton.URL != eventURL { t.Fatalf("unexpected registration button: %+v", linkButton) } } func TestAnnounceEventCreatedReturnsDiscordError(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, _ *http.Request) { http.Error(response, `{"message":"Missing Permissions"}`, http.StatusForbidden) })) defer server.Close() announcer, err := New(Config{ BotToken: "secret-token", ChannelID: "channel-123", PublicURL: "https://mix.example.com", APIBaseURL: server.URL, HTTPClient: server.Client(), }) if err != nil { t.Fatal(err) } if err := announcer.AnnounceEventCreated(context.Background(), domain.Event{ID: "event-456"}); err == nil { t.Fatal("expected Discord error") } }