Introduced engine.Scrobbler

Also refactored mocks into their original packages, to avoid cyclic references. Is there a better way to have mocks in GoLang tests?
This commit is contained in:
Deluan
2016-03-16 17:48:44 -04:00
parent 4aa02e68e5
commit b660a70688
16 changed files with 158 additions and 47 deletions
+2 -2
View File
@@ -7,15 +7,15 @@ import (
"image"
"github.com/deluan/gosonic/engine"
"github.com/deluan/gosonic/persistence"
. "github.com/deluan/gosonic/tests"
"github.com/deluan/gosonic/tests/mocks"
. "github.com/smartystreets/goconvey/convey"
)
func TestCover(t *testing.T) {
Init(t, false)
mockMediaFileRepo := mocks.CreateMockMediaFileRepo()
mockMediaFileRepo := persistence.CreateMockMediaFileRepo()
cover := engine.NewCover(mockMediaFileRepo)
out := new(bytes.Buffer)
+44
View File
@@ -0,0 +1,44 @@
package engine
import (
"errors"
)
func CreateMockPropertyRepo() *MockProperty {
return &MockProperty{data: make(map[string]string)}
}
type MockProperty struct {
PropertyRepository
data map[string]string
err bool
}
func (m *MockProperty) SetError(err bool) {
m.err = err
}
func (m *MockProperty) Put(id string, value string) error {
if m.err {
return errors.New("Error!")
}
m.data[id] = value
return nil
}
func (m *MockProperty) Get(id string) (string, error) {
if m.err {
return "", errors.New("Error!")
}
return m.data[id], nil
}
func (m *MockProperty) DefaultGet(id string, defaultValue string) (string, error) {
v, err := m.Get(id)
if v == "" {
v = defaultValue
}
return v, err
}
+41
View File
@@ -0,0 +1,41 @@
package engine
import (
"errors"
"fmt"
"time"
"github.com/deluan/gosonic/domain"
"github.com/deluan/gosonic/itunesbridge"
)
type Scrobbler interface {
Register(id string, playDate time.Time, submit bool) (*domain.MediaFile, error)
}
func NewScrobbler(itunes itunesbridge.ItunesControl, mr domain.MediaFileRepository) Scrobbler {
return scrobbler{itunes, mr}
}
type scrobbler struct {
itunes itunesbridge.ItunesControl
mfRepo domain.MediaFileRepository
}
func (s scrobbler) Register(id string, playDate time.Time, submit bool) (*domain.MediaFile, error) {
mf, err := s.mfRepo.Get(id)
if err != nil {
return nil, err
}
if mf == nil {
return nil, errors.New(fmt.Sprintf(`Id "%s" not found`, id))
}
if submit {
if err := s.itunes.MarkAsPlayed(id, playDate); err != nil {
return nil, err
}
}
return mf, nil
}
+74
View File
@@ -0,0 +1,74 @@
package engine_test
import (
"testing"
"time"
"github.com/deluan/gosonic/engine"
"github.com/deluan/gosonic/itunesbridge"
"github.com/deluan/gosonic/persistence"
. "github.com/deluan/gosonic/tests"
. "github.com/smartystreets/goconvey/convey"
"github.com/syndtr/goleveldb/leveldb/errors"
)
func TestScrobbler(t *testing.T) {
Init(t, false)
mfRepo := persistence.CreateMockMediaFileRepo()
itCtrl := &mockItunesControl{}
scrobbler := engine.NewScrobbler(itCtrl, mfRepo)
Convey("Given a DB with one song", t, func() {
mfRepo.SetData(`[{"Id":"2","Title":"Hands Of Time"}]`, 1)
Convey("When I scrobble an existing song", func() {
now := time.Now()
mf, err := scrobbler.Register("2", now, true)
Convey("Then I get the scrobbled song back", func() {
So(err, ShouldBeNil)
So(mf.Title, ShouldEqual, "Hands Of Time")
})
Convey("And iTunes is notified", func() {
So(itCtrl.played, ShouldContainKey, "2")
So(itCtrl.played["2"].Equal(now), ShouldBeTrue)
})
})
Convey("When the ID is not in the DB", func() {
_, err := scrobbler.Register("3", time.Now(), true)
Convey("Then I receive an error", func() {
So(err, ShouldNotBeNil)
})
Convey("And iTunes is not notified", func() {
So(itCtrl.played, ShouldNotContainKey, "3")
})
})
})
}
type mockItunesControl struct {
itunesbridge.ItunesControl
played map[string]time.Time
error bool
}
func (m *mockItunesControl) MarkAsPlayed(id string, playDate time.Time) error {
if m.error {
return errors.New("ID not found")
}
if m.played == nil {
m.played = make(map[string]time.Time)
}
m.played[id] = playDate
return nil
}