From 75ed45772b3435c5fbcaf8d8298a5e2cdd456012 Mon Sep 17 00:00:00 2001 From: aynakeya Date: Thu, 19 Feb 2026 12:12:25 +0800 Subject: [PATCH] add test --- internal/sysmediacontrol/smc_linux_test.go | 153 +++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 internal/sysmediacontrol/smc_linux_test.go diff --git a/internal/sysmediacontrol/smc_linux_test.go b/internal/sysmediacontrol/smc_linux_test.go new file mode 100644 index 0000000..0d8f7bb --- /dev/null +++ b/internal/sysmediacontrol/smc_linux_test.go @@ -0,0 +1,153 @@ +//go:build linux + +package sysmediacontrol + +import ( + "AynaLivePlayer/core/events" + "AynaLivePlayer/global" + "AynaLivePlayer/pkg/eventbus" + "errors" + "sync" + "testing" + + "github.com/godbus/dbus/v5" + "github.com/stretchr/testify/require" +) + +type publishRecord struct { + id string + data interface{} +} + +type mockBus struct { + mu sync.Mutex + published []publishRecord +} + +func (m *mockBus) Start() error { return nil } +func (m *mockBus) Wait() error { return nil } +func (m *mockBus) Stop() error { return nil } +func (m *mockBus) Subscribe(string, string, string, eventbus.HandlerFunc) error { + return nil +} +func (m *mockBus) SubscribeAny(string, string, eventbus.HandlerFunc) error { return nil } +func (m *mockBus) SubscribeOnce(string, string, string, eventbus.HandlerFunc) error { + return nil +} +func (m *mockBus) Unsubscribe(string, string) error { return nil } +func (m *mockBus) Publish(eventID string, data interface{}) error { + m.mu.Lock() + defer m.mu.Unlock() + m.published = append(m.published, publishRecord{id: eventID, data: data}) + return nil +} +func (m *mockBus) PublishToChannel(string, string, interface{}) error { return nil } +func (m *mockBus) PublishEvent(*eventbus.Event) error { return nil } +func (m *mockBus) Call(string, string, interface{}) (*eventbus.Event, error) { + return nil, errors.New("not implemented") +} +func (m *mockBus) Reply(*eventbus.Event, string, interface{}) error { return nil } + +func (m *mockBus) snapshot() []publishRecord { + m.mu.Lock() + defer m.mu.Unlock() + out := make([]publishRecord, len(m.published)) + copy(out, m.published) + return out +} + +func setupSMCTest(t *testing.T) *mockBus { + t.Helper() + oldBus := global.EventBus + oldSMC := linuxSMC + mb := &mockBus{} + global.EventBus = mb + linuxSMC = nil + t.Cleanup(func() { + global.EventBus = oldBus + linuxSMC = oldSMC + }) + return mb +} + +func TestMprisPlayerPublishesControlEvents(t *testing.T) { + mb := setupSMCTest(t) + p := &mprisPlayer{} + + require.Nil(t, p.Next()) + require.Nil(t, p.Previous()) + require.Nil(t, p.Pause()) + require.Nil(t, p.Play()) + require.Nil(t, p.PlayPause()) + require.Nil(t, p.Stop()) + require.Nil(t, p.Seek(3_000_000)) + + pubs := mb.snapshot() + require.Len(t, pubs, 7) + + require.Equal(t, events.PlayerPlayNextCmd, pubs[0].id) + _, ok := pubs[0].data.(events.PlayerPlayNextCmdEvent) + require.True(t, ok) + + require.Equal(t, events.PlayerSeekCmd, pubs[1].id) + prevSeek, ok := pubs[1].data.(events.PlayerSeekCmdEvent) + require.True(t, ok) + require.True(t, prevSeek.Absolute) + require.Equal(t, 0.0, prevSeek.Position) + + require.Equal(t, events.PlayerSetPauseCmd, pubs[2].id) + pauseEvt, ok := pubs[2].data.(events.PlayerSetPauseCmdEvent) + require.True(t, ok) + require.True(t, pauseEvt.Pause) + + require.Equal(t, events.PlayerSetPauseCmd, pubs[3].id) + playEvt, ok := pubs[3].data.(events.PlayerSetPauseCmdEvent) + require.True(t, ok) + require.False(t, playEvt.Pause) + + require.Equal(t, events.PlayerToggleCmd, pubs[4].id) + _, ok = pubs[4].data.(events.PlayerToggleCmdEvent) + require.True(t, ok) + + require.Equal(t, events.PlayerSetPauseCmd, pubs[5].id) + stopEvt, ok := pubs[5].data.(events.PlayerSetPauseCmdEvent) + require.True(t, ok) + require.True(t, stopEvt.Pause) + + require.Equal(t, events.PlayerSeekCmd, pubs[6].id) + seekEvt, ok := pubs[6].data.(events.PlayerSeekCmdEvent) + require.True(t, ok) + require.False(t, seekEvt.Absolute) + require.InDelta(t, 3.0, seekEvt.Position, 1e-6) +} + +func TestMprisPlayerSetPositionTrackGuard(t *testing.T) { + mb := setupSMCTest(t) + p := &mprisPlayer{} + + linuxSMC = &linuxMpris{ + trackPath: dbus.ObjectPath("/org/mpris/MediaPlayer2/track/1"), + } + + require.Nil(t, p.SetPosition(dbus.ObjectPath("/org/mpris/MediaPlayer2/track/2"), 5_000_000)) + require.Len(t, mb.snapshot(), 0) + + require.Nil(t, p.SetPosition(dbus.ObjectPath("/org/mpris/MediaPlayer2/track/1"), 5_000_000)) + pubs := mb.snapshot() + require.Len(t, pubs, 1) + require.Equal(t, events.PlayerSeekCmd, pubs[0].id) + seekEvt, ok := pubs[0].data.(events.PlayerSeekCmdEvent) + require.True(t, ok) + require.True(t, seekEvt.Absolute) + require.InDelta(t, 5.0, seekEvt.Position, 1e-6) + + linuxSMC.trackPath = noTrackPath + require.Nil(t, p.SetPosition(dbus.ObjectPath("/org/mpris/MediaPlayer2/track/whatever"), 2_000_000)) + pubs = mb.snapshot() + require.Len(t, pubs, 2) + lastEvt, ok := pubs[1].data.(events.PlayerSeekCmdEvent) + require.True(t, ok) + require.True(t, lastEvt.Absolute) + require.InDelta(t, 2.0, lastEvt.Position, 1e-6) +} +