using SameBeat.Domain.Encje; using SameBeat.Domain.Enumy; using SameBeat.Domain.Wyjatki; using Xunit; namespace SameBeat.Tests.Unit; /// /// Testy "zegara" muzyki (ETAP 4) na encji Wydarzenie -- OdtworzOd/Wstrzymaj/Wznow/Zatrzymaj i /// walidacja glosnosci. Testy przeliczania pozycji przy pause uzywaja krotkiego Thread.Sleep i /// tolerancji czasowej -- to prawdziwy zegar (DateTime.UtcNow), nie fejk, wiec sprawdzamy przedzial, /// nie dokladna wartosc co do milisekundy. /// public class WydarzenieMuzykaTests { [Fact] public void Utworz_MaDomyslnyStanMuzyki() { var wydarzenie = Wydarzenie.Utworz("Test"); Assert.Null(wydarzenie.UtworId); Assert.Null(wydarzenie.CzasStartuUtc); Assert.Equal(0, wydarzenie.PozycjaStartowaMs); Assert.Equal(StanOdtwarzania.Zatrzymana, wydarzenie.StanOdtwarzania); Assert.Equal(0.9f, wydarzenie.GlosnoscMaster); } [Fact] public void OdtworzOd_UstawiaUtworPozycjeICzasStartu() { var wydarzenie = Wydarzenie.Utworz("Test"); var utworId = Guid.NewGuid(); var przed = DateTime.UtcNow; wydarzenie.OdtworzOd(utworId, 5000); Assert.Equal(utworId, wydarzenie.UtworId); Assert.Equal(5000, wydarzenie.PozycjaStartowaMs); Assert.Equal(StanOdtwarzania.Odtwarzana, wydarzenie.StanOdtwarzania); Assert.NotNull(wydarzenie.CzasStartuUtc); Assert.True(wydarzenie.CzasStartuUtc >= przed); } [Fact] public void OdtworzOd_PustyUtworId_Rzuca() { var wydarzenie = Wydarzenie.Utworz("Test"); Assert.Throws(() => wydarzenie.OdtworzOd(Guid.Empty, 0)); } [Fact] public void OdtworzOd_UjemnaPozycja_Rzuca() { var wydarzenie = Wydarzenie.Utworz("Test"); Assert.Throws(() => wydarzenie.OdtworzOd(Guid.NewGuid(), -1)); } [Fact] public void Wstrzymaj_PrzeliczaPozycjeNaPodstawieUplynietegoCzasu() { var wydarzenie = Wydarzenie.Utworz("Test"); wydarzenie.OdtworzOd(Guid.NewGuid(), 1000); Thread.Sleep(200); // symulujemy uplyw czasu -- prawdziwy zegar, nie fejk wydarzenie.Wstrzymaj(); Assert.Equal(StanOdtwarzania.Wstrzymana, wydarzenie.StanOdtwarzania); Assert.Null(wydarzenie.CzasStartuUtc); // Zegar sie zgadza: pozycja startowa (1000ms) + realnie uplyniety czas (>=200ms), z hojnym // gornym marginesem na wolne CI. Assert.InRange(wydarzenie.PozycjaStartowaMs, 1100, 5000); } [Fact] public void Wstrzymaj_GdyJuzWstrzymana_JestIdempotentneINieRuszaPozycji() { var wydarzenie = Wydarzenie.Utworz("Test"); wydarzenie.OdtworzOd(Guid.NewGuid(), 1000); Thread.Sleep(50); wydarzenie.Wstrzymaj(); var pozycjaPoPierwszymWstrzymaniu = wydarzenie.PozycjaStartowaMs; wydarzenie.Wstrzymaj(); Assert.Equal(pozycjaPoPierwszymWstrzymaniu, wydarzenie.PozycjaStartowaMs); Assert.Equal(StanOdtwarzania.Wstrzymana, wydarzenie.StanOdtwarzania); } [Fact] public void Wznow_KontynuujeOdZapisanejPozycji_ZegarSieZgadza() { var wydarzenie = Wydarzenie.Utworz("Test"); wydarzenie.OdtworzOd(Guid.NewGuid(), 1000); Thread.Sleep(100); wydarzenie.Wstrzymaj(); var pozycjaWstrzymania = wydarzenie.PozycjaStartowaMs; var przedWznowieniem = DateTime.UtcNow; wydarzenie.Wznow(); Assert.Equal(StanOdtwarzania.Odtwarzana, wydarzenie.StanOdtwarzania); // Wznowienie NIE rusza zapisanej pozycji startowej -- tylko przesuwa CzasStartuUtc na teraz, // zeby (pozycjaStartowaMs + uplyw od CzasStartuUtc) po stronie klienta dalo dokladnie tam, // gdzie muzyka zostala wstrzymana. Assert.Equal(pozycjaWstrzymania, wydarzenie.PozycjaStartowaMs); Assert.NotNull(wydarzenie.CzasStartuUtc); Assert.True(wydarzenie.CzasStartuUtc >= przedWznowieniem); } [Fact] public void Zatrzymaj_CzysciUtworICzasIZerujePozycje() { var wydarzenie = Wydarzenie.Utworz("Test"); wydarzenie.OdtworzOd(Guid.NewGuid(), 1000); wydarzenie.Zatrzymaj(); Assert.Null(wydarzenie.UtworId); Assert.Null(wydarzenie.CzasStartuUtc); Assert.Equal(0, wydarzenie.PozycjaStartowaMs); Assert.Equal(StanOdtwarzania.Zatrzymana, wydarzenie.StanOdtwarzania); } [Theory] [InlineData(0.0f)] [InlineData(1.0f)] [InlineData(0.5f)] public void UstawGlosnosc_WZakresie_Ustawia(float wartosc) { var wydarzenie = Wydarzenie.Utworz("Test"); wydarzenie.UstawGlosnosc(wartosc); Assert.Equal(wartosc, wydarzenie.GlosnoscMaster); } [Theory] [InlineData(-0.01f)] [InlineData(1.01f)] [InlineData(-5f)] public void UstawGlosnosc_PozaZakresem_Rzuca(float wartosc) { var wydarzenie = Wydarzenie.Utworz("Test"); Assert.Throws(() => wydarzenie.UstawGlosnosc(wartosc)); } }