Move mock datastore to tests package

This commit is contained in:
Deluan
2020-10-27 11:01:40 -04:00
parent 313a088f86
commit d0bf37a8a9
19 changed files with 41 additions and 79 deletions
+2 -2
View File
@@ -11,7 +11,7 @@ import (
"github.com/deluan/navidrome/conf"
"github.com/deluan/navidrome/consts"
"github.com/deluan/navidrome/model"
"github.com/deluan/navidrome/persistence"
"github.com/deluan/navidrome/tests"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
@@ -22,7 +22,7 @@ var _ = Describe("serveIndex", func() {
fs := http.Dir("tests/fixtures")
BeforeEach(func() {
ds = &persistence.MockDataStore{MockedUser: mockUser}
ds = &tests.MockDataStore{MockedUser: mockUser}
conf.Server.UILoginBackgroundURL = ""
})
+4 -4
View File
@@ -6,7 +6,7 @@ import (
"github.com/deluan/navidrome/log"
"github.com/deluan/navidrome/model"
"github.com/deluan/navidrome/persistence"
"github.com/deluan/navidrome/tests"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
@@ -14,13 +14,13 @@ import (
var _ = Describe("AlbumListController", func() {
var controller *AlbumListController
var ds model.DataStore
var mockRepo *persistence.MockAlbum
var mockRepo *tests.MockAlbum
var w *httptest.ResponseRecorder
ctx := log.NewContext(context.TODO())
BeforeEach(func() {
ds = &persistence.MockDataStore{}
mockRepo = ds.Album(ctx).(*persistence.MockAlbum)
ds = &tests.MockDataStore{}
mockRepo = ds.Album(ctx).(*tests.MockAlbum)
controller = NewAlbumListController(ds, nil)
w = httptest.NewRecorder()
})
+2 -2
View File
@@ -27,7 +27,7 @@ type Router struct {
Playlists engine.Playlists
Streamer core.MediaStreamer
Archiver core.Archiver
Players engine.Players
Players core.Players
ExternalInfo core.ExternalInfo
DataStore model.DataStore
@@ -36,7 +36,7 @@ type Router struct {
func New(artwork core.Artwork,
playlists engine.Playlists, streamer core.MediaStreamer,
archiver core.Archiver, players engine.Players, externalInfo core.ExternalInfo, ds model.DataStore) *Router {
archiver core.Archiver, players core.Players, externalInfo core.ExternalInfo, ds model.DataStore) *Router {
r := &Router{Artwork: artwork, Playlists: playlists,
Streamer: streamer, Archiver: archiver, Players: players, ExternalInfo: externalInfo, DataStore: ds}
r.mux = r.routes()
@@ -1,17 +0,0 @@
package engine
import (
"testing"
"github.com/deluan/navidrome/log"
"github.com/deluan/navidrome/tests"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
func TestEngine(t *testing.T) {
tests.Init(t, false)
log.SetLevel(log.LevelCritical)
RegisterFailHandler(Fail)
RunSpecs(t, "Engine Suite")
}
@@ -1,22 +0,0 @@
package engine
import "github.com/deluan/navidrome/model"
type mockTranscodingRepository struct {
model.TranscodingRepository
}
func (m *mockTranscodingRepository) Get(id string) (*model.Transcoding, error) {
return &model.Transcoding{ID: id, TargetFormat: "mp3", DefaultBitRate: 160}, nil
}
func (m *mockTranscodingRepository) FindByFormat(format string) (*model.Transcoding, error) {
switch format {
case "mp3":
return &model.Transcoding{ID: "mp31", TargetFormat: "mp3", DefaultBitRate: 160}, nil
case "oga":
return &model.Transcoding{ID: "oga1", TargetFormat: "oga", DefaultBitRate: 128}, nil
default:
return nil, model.ErrNotFound
}
}
-68
View File
@@ -1,68 +0,0 @@
package engine
import (
"context"
"fmt"
"time"
"github.com/deluan/navidrome/log"
"github.com/deluan/navidrome/model"
"github.com/deluan/navidrome/model/request"
"github.com/google/uuid"
)
type Players interface {
Get(ctx context.Context, playerId string) (*model.Player, error)
Register(ctx context.Context, id, client, typ, ip string) (*model.Player, *model.Transcoding, error)
}
func NewPlayers(ds model.DataStore) Players {
return &players{ds}
}
type players struct {
ds model.DataStore
}
func (p *players) Register(ctx context.Context, id, client, typ, ip string) (*model.Player, *model.Transcoding, error) {
var plr *model.Player
var trc *model.Transcoding
var err error
userName, _ := request.UsernameFrom(ctx)
if id != "" {
plr, err = p.ds.Player(ctx).Get(id)
if err == nil && plr.Client != client {
id = ""
}
}
if err != nil || id == "" {
plr, err = p.ds.Player(ctx).FindByName(client, userName)
if err == nil {
log.Debug("Found player by name", "id", plr.ID, "client", client, "username", userName)
} else {
r, _ := uuid.NewRandom()
plr = &model.Player{
ID: r.String(),
Name: fmt.Sprintf("%s (%s)", client, userName),
UserName: userName,
Client: client,
}
log.Info("Registering new player", "id", plr.ID, "client", client, "username", userName)
}
}
plr.LastSeen = time.Now()
plr.Type = typ
plr.IPAddress = ip
err = p.ds.Player(ctx).Put(plr)
if err != nil {
return nil, nil, err
}
if plr.TranscodingId != "" {
trc, err = p.ds.Transcoding(ctx).Get(plr.TranscodingId)
}
return plr, trc, err
}
func (p *players) Get(ctx context.Context, playerId string) (*model.Player, error) {
return p.ds.Player(ctx).Get(playerId)
}
-140
View File
@@ -1,140 +0,0 @@
package engine
import (
"context"
"time"
"github.com/deluan/navidrome/log"
"github.com/deluan/navidrome/model"
"github.com/deluan/navidrome/model/request"
"github.com/deluan/navidrome/persistence"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("Players", func() {
var players Players
var repo *mockPlayerRepository
ctx := log.NewContext(context.TODO())
ctx = request.WithUser(ctx, model.User{ID: "userid", UserName: "johndoe"})
ctx = request.WithUsername(ctx, "johndoe")
var beforeRegister time.Time
BeforeEach(func() {
repo = &mockPlayerRepository{}
ds := &persistence.MockDataStore{MockedPlayer: repo, MockedTranscoding: &mockTranscodingRepository{}}
players = NewPlayers(ds)
beforeRegister = time.Now()
})
Describe("Register", func() {
It("creates a new player when no ID is specified", func() {
p, trc, err := players.Register(ctx, "", "client", "chrome", "1.2.3.4")
Expect(err).ToNot(HaveOccurred())
Expect(p.ID).ToNot(BeEmpty())
Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister))
Expect(p.Client).To(Equal("client"))
Expect(p.UserName).To(Equal("johndoe"))
Expect(p.Type).To(Equal("chrome"))
Expect(repo.lastSaved).To(Equal(p))
Expect(trc).To(BeNil())
})
It("creates a new player if it cannot find any matching player", func() {
p, trc, err := players.Register(ctx, "123", "client", "chrome", "1.2.3.4")
Expect(err).ToNot(HaveOccurred())
Expect(p.ID).ToNot(BeEmpty())
Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister))
Expect(repo.lastSaved).To(Equal(p))
Expect(trc).To(BeNil())
})
It("creates a new player if client does not match the one in DB", func() {
plr := &model.Player{ID: "123", Name: "A Player", Client: "client1111", LastSeen: time.Time{}}
repo.add(plr)
p, trc, err := players.Register(ctx, "123", "client2222", "chrome", "1.2.3.4")
Expect(err).ToNot(HaveOccurred())
Expect(p.ID).ToNot(BeEmpty())
Expect(p.ID).ToNot(Equal("123"))
Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister))
Expect(p.Client).To(Equal("client2222"))
Expect(trc).To(BeNil())
})
It("finds players by ID", func() {
plr := &model.Player{ID: "123", Name: "A Player", Client: "client", LastSeen: time.Time{}}
repo.add(plr)
p, trc, err := players.Register(ctx, "123", "client", "chrome", "1.2.3.4")
Expect(err).ToNot(HaveOccurred())
Expect(p.ID).To(Equal("123"))
Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister))
Expect(repo.lastSaved).To(Equal(p))
Expect(trc).To(BeNil())
})
It("finds player by client and user names when ID is not found", func() {
plr := &model.Player{ID: "123", Name: "A Player", Client: "client", UserName: "johndoe", LastSeen: time.Time{}}
repo.add(plr)
p, _, err := players.Register(ctx, "999", "client", "chrome", "1.2.3.4")
Expect(err).ToNot(HaveOccurred())
Expect(p.ID).To(Equal("123"))
Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister))
Expect(repo.lastSaved).To(Equal(p))
})
It("finds player by client and user names when not ID is provided", func() {
plr := &model.Player{ID: "123", Name: "A Player", Client: "client", UserName: "johndoe", LastSeen: time.Time{}}
repo.add(plr)
p, _, err := players.Register(ctx, "", "client", "chrome", "1.2.3.4")
Expect(err).ToNot(HaveOccurred())
Expect(p.ID).To(Equal("123"))
Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister))
Expect(repo.lastSaved).To(Equal(p))
})
It("finds player by ID and return its transcoding", func() {
plr := &model.Player{ID: "123", Name: "A Player", Client: "client", LastSeen: time.Time{}, TranscodingId: "1"}
repo.add(plr)
p, trc, err := players.Register(ctx, "123", "client", "chrome", "1.2.3.4")
Expect(err).ToNot(HaveOccurred())
Expect(p.ID).To(Equal("123"))
Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister))
Expect(repo.lastSaved).To(Equal(p))
Expect(trc.ID).To(Equal("1"))
})
})
})
type mockPlayerRepository struct {
model.PlayerRepository
lastSaved *model.Player
data map[string]model.Player
}
func (m *mockPlayerRepository) add(p *model.Player) {
if m.data == nil {
m.data = make(map[string]model.Player)
}
m.data[p.ID] = *p
}
func (m *mockPlayerRepository) Get(id string) (*model.Player, error) {
if p, ok := m.data[id]; ok {
return &p, nil
}
return nil, model.ErrNotFound
}
func (m *mockPlayerRepository) FindByName(client, userName string) (*model.Player, error) {
for _, p := range m.data {
if p.Client == client && p.UserName == userName {
return &p, nil
}
}
return nil, model.ErrNotFound
}
func (m *mockPlayerRepository) Put(p *model.Player) error {
m.lastSaved = p
return nil
}
+2 -1
View File
@@ -1,10 +1,11 @@
package engine
import (
"github.com/deluan/navidrome/core"
"github.com/google/wire"
)
var Set = wire.NewSet(
NewPlaylists,
NewPlayers,
core.NewPlayers,
)
+2 -2
View File
@@ -10,11 +10,11 @@ import (
"net/url"
"strings"
"github.com/deluan/navidrome/core"
"github.com/deluan/navidrome/core/auth"
"github.com/deluan/navidrome/log"
"github.com/deluan/navidrome/model"
"github.com/deluan/navidrome/model/request"
"github.com/deluan/navidrome/server/subsonic/engine"
"github.com/deluan/navidrome/server/subsonic/responses"
"github.com/deluan/navidrome/utils"
)
@@ -139,7 +139,7 @@ func validateUser(ctx context.Context, ds model.DataStore, username, pass, token
return user, nil
}
func getPlayer(players engine.Players) func(next http.Handler) http.Handler {
func getPlayer(players core.Players) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
+5 -5
View File
@@ -7,12 +7,12 @@ import (
"net/http/httptest"
"strings"
"github.com/deluan/navidrome/core"
"github.com/deluan/navidrome/core/auth"
"github.com/deluan/navidrome/log"
"github.com/deluan/navidrome/model"
"github.com/deluan/navidrome/model/request"
"github.com/deluan/navidrome/persistence"
"github.com/deluan/navidrome/server/subsonic/engine"
"github.com/deluan/navidrome/tests"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
@@ -117,7 +117,7 @@ var _ = Describe("Middlewares", func() {
Describe("Authenticate", func() {
var ds model.DataStore
BeforeEach(func() {
ds = &persistence.MockDataStore{}
ds = &tests.MockDataStore{}
})
It("passes authentication with correct credentials", func() {
@@ -222,7 +222,7 @@ var _ = Describe("Middlewares", func() {
Describe("validateUser", func() {
var ds model.DataStore
BeforeEach(func() {
ds = &persistence.MockDataStore{}
ds = &tests.MockDataStore{}
})
Context("Plaintext password", func() {
@@ -302,7 +302,7 @@ func (mh *mockHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
type mockPlayers struct {
engine.Players
core.Players
transcoding *model.Transcoding
}