diff --git a/api/get_indexes.go b/api/get_indexes.go
index 28a7b5a14..c46831e3b 100644
--- a/api/get_indexes.go
+++ b/api/get_indexes.go
@@ -5,6 +5,7 @@ import (
"github.com/deluan/gosonic/repositories"
"github.com/deluan/gosonic/utils"
"github.com/karlkfi/inject"
+ "github.com/deluan/gosonic/api/responses"
)
type GetIndexesController struct {
@@ -17,7 +18,16 @@ func (c *GetIndexesController) Prepare() {
}
func (c *GetIndexesController) Get() {
- if c.repo == nil {
- c.CustomAbort(500, "INJECTION NOT WORKING")
+ indexes, err := c.repo.GetAll()
+ if err != nil {
+ beego.Error("Error retrieving Indexes:", err)
+ c.CustomAbort(200, string(responses.NewError(responses.ERROR_GENERIC, "Internal Error")))
}
+ res := &responses.ArtistIndex{}
+ res.Index = make([]responses.Index, len(indexes))
+ for i, idx := range indexes {
+ res.Index[i].Name = idx.Id
+ }
+
+ c.Ctx.Output.Body(responses.NewXML(res))
}
diff --git a/api/get_indexes_test.go b/api/get_indexes_test.go
index 11cb23888..7e0c01f92 100644
--- a/api/get_indexes_test.go
+++ b/api/get_indexes_test.go
@@ -3,18 +3,82 @@ package api_test
import (
"testing"
+ "github.com/deluan/gosonic/utils"
. "github.com/smartystreets/goconvey/convey"
"github.com/deluan/gosonic/tests"
+ "github.com/deluan/gosonic/models"
+ "github.com/deluan/gosonic/repositories"
+ "encoding/xml"
+ "encoding/json"
+ "fmt"
+ "errors"
+ "github.com/deluan/gosonic/api/responses"
)
func TestGetIndexes(t *testing.T) {
tests.Init(t, false)
-
- _, w := Get(AddParams("/rest/getIndexes.view"), "TestGetIndexes")
+ mockRepo := &mockArtistIndex{}
+ utils.DefineSingleton(new(repositories.ArtistIndex), func() repositories.ArtistIndex {
+ return mockRepo
+ })
Convey("Subject: GetIndexes Endpoint", t, func() {
- Convey("Status code should be 200", func() {
- So(w.Code, ShouldEqual, 200)
+ Convey("Return fail on DB error", func() {
+ mockRepo.err = true
+ _, w := Get(AddParams("/rest/getIndexes.view"), "TestGetIndexes")
+
+ v := responses.Subsonic{}
+ xml.Unmarshal(w.Body.Bytes(), &v)
+ So(v.Status, ShouldEqual, "fail")
+ })
+ Convey("When the index is empty", func() {
+ _, w := Get(AddParams("/rest/getIndexes.view"), "TestGetIndexes")
+
+ Convey("Status code should be 200", func() {
+ So(w.Code, ShouldEqual, 200)
+ })
+ Convey("It should return valid XML", func() {
+ v := new(string)
+ err := xml.Unmarshal(w.Body.Bytes(), &v)
+ So(err, ShouldBeNil)
+ })
+ Convey("Then it should return an empty collection", func() {
+ So(w.Body.String(), ShouldContainSubstring, "")
+ })
+ })
+ Convey("When the index is not empty", func() {
+ mockRepo.data = makeMockData(`[{"Id": "A","Artists": []}]`, 2)
+ _, w := Get(AddParams("/rest/getIndexes.view"), "TestGetIndexes")
+
+ Convey("Then it should return the the items in the response", func() {
+ So(w.Body.String(), ShouldContainSubstring, ``)
+ })
+ })
+ Reset(func() {
+ mockRepo.data = make([]models.ArtistIndex, 0)
+ mockRepo.err = false
})
})
}
+
+func makeMockData(j string, length int) []models.ArtistIndex {
+ data := make([]models.ArtistIndex, length)
+ err := json.Unmarshal([]byte(j), &data)
+ if err != nil {
+ fmt.Println("ERROR: ", err)
+ }
+ return data
+}
+
+type mockArtistIndex struct {
+ repositories.ArtistIndexImpl
+ data []models.ArtistIndex
+ err bool
+}
+
+func (m *mockArtistIndex) GetAll() ([]models.ArtistIndex, error) {
+ if m.err {
+ return nil, errors.New("Error!")
+ }
+ return m.data, nil
+}
\ No newline at end of file
diff --git a/api/responses/error.go b/api/responses/error.go
index 040238236..f048b1ec9 100644
--- a/api/responses/error.go
+++ b/api/responses/error.go
@@ -2,6 +2,7 @@ package responses
import (
"encoding/xml"
+ "fmt"
)
const (
@@ -37,13 +38,19 @@ type error struct {
Message string `xml:"message,attr"`
}
-func NewError(errorCode int) []byte {
+func NewError(errorCode int, message ...interface{}) []byte {
response := NewEmpty()
response.Status = "fail"
if errors[errorCode] == "" {
errorCode = ERROR_GENERIC
}
- xmlBody, _ := xml.Marshal(&error{Code: errorCode, Message: errors[errorCode]})
+ var msg string
+ if (len(message) == 0) {
+ msg = errors[errorCode]
+ } else {
+ msg = fmt.Sprintf(message[0].(string), message[1:len(message)]...)
+ }
+ xmlBody, _ := xml.Marshal(&error{Code: errorCode, Message: msg})
response.Body = xmlBody
xmlResponse, _ := xml.Marshal(response)
return []byte(xml.Header + string(xmlResponse))
diff --git a/api/responses/indexes.go b/api/responses/indexes.go
new file mode 100644
index 000000000..718cc9130
--- /dev/null
+++ b/api/responses/indexes.go
@@ -0,0 +1,14 @@
+package responses
+
+import "encoding/xml"
+
+type Index struct {
+ XMLName xml.Name `xml:"index"`
+ Name string `xml:"name,attr"`
+}
+
+type ArtistIndex struct {
+ XMLName xml.Name `xml:"indexes"`
+ Index []Index `xml:"indexes"`
+}
+
diff --git a/conf/inject_definitions.go b/conf/inject_definitions.go
index b3a3804ab..eff8e885d 100644
--- a/conf/inject_definitions.go
+++ b/conf/inject_definitions.go
@@ -1,15 +1,10 @@
package conf
import (
- "github.com/deluan/gosonic/repositories"
"github.com/deluan/gosonic/utils"
- "github.com/karlkfi/inject"
+ "github.com/deluan/gosonic/repositories"
)
-func define(ptr interface{}, constructor interface{}, argPtrs ...interface{}) {
- utils.Graph.Define(ptr, inject.NewProvider(constructor, argPtrs...))
-}
-
func init () {
- define(new(repositories.ArtistIndex), repositories.NewArtistIndexRepository)
+ utils.DefineSingleton(new(repositories.ArtistIndex), repositories.NewArtistIndexRepository)
}
diff --git a/repositories/index_repository.go b/repositories/index_repository.go
index 26e3fff01..ea378b479 100644
--- a/repositories/index_repository.go
+++ b/repositories/index_repository.go
@@ -11,30 +11,30 @@ type ArtistIndex interface {
GetAll() ([]models.ArtistIndex, error)
}
-type artistIndex struct {
+type ArtistIndexImpl struct {
BaseRepository
}
func NewArtistIndexRepository() ArtistIndex {
- r := &artistIndex{}
+ r := &ArtistIndexImpl{}
r.init("index", &models.ArtistIndex{})
return r
}
-func (r *artistIndex) Put(m *models.ArtistIndex) error {
+func (r *ArtistIndexImpl) Put(m *models.ArtistIndex) error {
if m.Id == "" {
return errors.New("Id is not set")
}
return r.saveOrUpdate(m.Id, m)
}
-func (r *artistIndex) Get(id string) (*models.ArtistIndex, error) {
+func (r *ArtistIndexImpl) Get(id string) (*models.ArtistIndex, error) {
var rec interface{}
rec, err := r.readEntity(id)
return rec.(*models.ArtistIndex), err
}
-func (r *artistIndex) GetAll() ([]models.ArtistIndex, error) {
+func (r *ArtistIndexImpl) GetAll() ([]models.ArtistIndex, error) {
var indices = make([]models.ArtistIndex, 0)
err := r.loadAll(&indices)
return indices, err
diff --git a/utils/graph.go b/utils/graph.go
index 0f1c08ae5..f37d6ee36 100644
--- a/utils/graph.go
+++ b/utils/graph.go
@@ -1,9 +1,27 @@
package utils
-import "github.com/karlkfi/inject"
+import (
+ "github.com/karlkfi/inject"
+ "reflect"
+)
var Graph inject.Graph
+var (
+ definitions map[reflect.Type]interface{}
+)
+
+func DefineSingleton(ptr interface{}, constructor interface{}, args ...interface{}) {
+ typ := reflect.TypeOf(ptr)
+ if definitions[typ] == nil {
+ Graph.Define(ptr, inject.NewProvider(constructor, args...))
+ } else {
+ Graph.Define(definitions[typ], inject.NewProvider(constructor, args...))
+ }
+ definitions[typ] = ptr
+}
+
func init() {
+ definitions = make(map[reflect.Type]interface{})
Graph = inject.NewGraph()
}