Rebooting
This commit is contained in:
parent
41ee2857ee
commit
6030310caa
149 changed files with 1489 additions and 9755 deletions
101
api/auth.go
101
api/auth.go
|
@ -1,101 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
const (
|
||||
tokenName = "AccessToken"
|
||||
)
|
||||
|
||||
var (
|
||||
verifyKey, signKey []byte
|
||||
errWhileSigningToken = errors.New("error while signing token")
|
||||
errPleaseLogIn = errors.New("please log in")
|
||||
errWhileParsingCookie = errors.New("error while parsing cookie")
|
||||
errTokenExpired = errors.New("token expired")
|
||||
errGenericError = errors.New("generic error")
|
||||
errAccessDenied = errors.New("insufficient privileges")
|
||||
)
|
||||
|
||||
func SetupCerts() error {
|
||||
signkey := os.Getenv("PRIVATE_KEY")
|
||||
if signkey == "" {
|
||||
return errors.New("please set PRIVATE_KEY")
|
||||
}
|
||||
signKey = []byte(signkey)
|
||||
|
||||
verifykey := os.Getenv("PUBLIC_KEY")
|
||||
if verifykey == "" {
|
||||
return errors.New("please set PUBLIC_KEY")
|
||||
}
|
||||
verifyKey = []byte(verifykey)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type authHandler func(http.ResponseWriter, *http.Request) error
|
||||
|
||||
// Only accessible with a valid token
|
||||
func (h authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Even though writeJSON sets the content type, we need to set it here because
|
||||
// calls to WriteHeader write out the entire header.
|
||||
w.Header().Set("content-type", "application/json; charset=utf-8")
|
||||
|
||||
authHeader := r.Header.Get("Authorization")
|
||||
if authHeader == "" {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
writeJSON(w, Error{errPleaseLogIn})
|
||||
return
|
||||
}
|
||||
s := strings.Split(authHeader, " ")
|
||||
|
||||
// Validate the token
|
||||
token, err := jwt.Parse(s[1], func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte(verifyKey), nil
|
||||
})
|
||||
|
||||
// Branch out into the possible error from signing
|
||||
switch err.(type) {
|
||||
case nil: // No error
|
||||
if !token.Valid { // But may still be invalid
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
writeJSON(w, Error{errPleaseLogIn})
|
||||
return
|
||||
}
|
||||
case *jwt.ValidationError: // Something was wrong during the validation
|
||||
vErr := err.(*jwt.ValidationError)
|
||||
switch vErr.Errors {
|
||||
case jwt.ValidationErrorExpired:
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
writeJSON(w, Error{errTokenExpired})
|
||||
return
|
||||
default:
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
writeJSON(w, Error{errGenericError})
|
||||
return
|
||||
}
|
||||
default: // Something else went wrong
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
writeJSON(w, Error{errGenericError})
|
||||
return
|
||||
}
|
||||
genus := mux.Vars(r)["genus"]
|
||||
// We don't care about this if we aren't accessing one of the subrouter routes.
|
||||
if genus != "" && genus != token.Claims["genus"] {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
writeJSON(w, Error{errAccessDenied})
|
||||
return
|
||||
}
|
||||
hErr := h(w, r)
|
||||
if hErr != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
writeJSON(w, Error{hErr})
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func serveCharacteristicType(w http.ResponseWriter, r *http.Request) error {
|
||||
id, err := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
characteristic_type, err := store.CharacteristicTypes.Get(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeJSON(w, characteristic_type)
|
||||
}
|
||||
|
||||
func serveCreateCharacteristicType(w http.ResponseWriter, r *http.Request) error {
|
||||
var characteristic_type models.CharacteristicType
|
||||
err := json.NewDecoder(r.Body).Decode(&characteristic_type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
created, err := store.CharacteristicTypes.Create(&characteristic_type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if created {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
||||
return writeJSON(w, characteristic_type)
|
||||
}
|
||||
|
||||
func serveCharacteristicTypeList(w http.ResponseWriter, r *http.Request) error {
|
||||
var opt models.CharacteristicTypeListOptions
|
||||
if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
characteristic_types, err := store.CharacteristicTypes.List(&opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if characteristic_types == nil {
|
||||
characteristic_types = []*models.CharacteristicType{}
|
||||
}
|
||||
|
||||
return writeJSON(w, characteristic_types)
|
||||
}
|
||||
|
||||
func serveUpdateCharacteristicType(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
var characteristic_type models.CharacteristicType
|
||||
err := json.NewDecoder(r.Body).Decode(&characteristic_type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updated, err := store.CharacteristicTypes.Update(id, &characteristic_type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if updated {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, characteristic_type)
|
||||
}
|
||||
|
||||
func serveDeleteCharacteristicType(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
|
||||
deleted, err := store.CharacteristicTypes.Delete(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if deleted {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, &models.CharacteristicType{})
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func newCharacteristicType() *models.CharacteristicType {
|
||||
characteristic_type := models.NewCharacteristicType()
|
||||
return characteristic_type
|
||||
}
|
||||
|
||||
func TestCharacteristicType_Get(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newCharacteristicType()
|
||||
|
||||
calledGet := false
|
||||
|
||||
store.CharacteristicTypes.(*models.MockCharacteristicTypesService).Get_ = func(id int64) (*models.CharacteristicType, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for characteristic_type %d but got %d", want.Id, id)
|
||||
}
|
||||
calledGet = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
got, err := apiClient.CharacteristicTypes.Get(want.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledGet {
|
||||
t.Error("!calledGet")
|
||||
}
|
||||
if !normalizeDeepEqual(want, got) {
|
||||
t.Errorf("got %+v but wanted %+v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCharacteristicType_Create(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newCharacteristicType()
|
||||
|
||||
calledPost := false
|
||||
store.CharacteristicTypes.(*models.MockCharacteristicTypesService).Create_ = func(characteristic_type *models.CharacteristicType) (bool, error) {
|
||||
if !normalizeDeepEqual(want, characteristic_type) {
|
||||
t.Errorf("wanted request for characteristic_type %d but got %d", want, characteristic_type)
|
||||
}
|
||||
calledPost = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.CharacteristicTypes.Create(want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPost {
|
||||
t.Error("!calledPost")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCharacteristicType_List(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := []*models.CharacteristicType{newCharacteristicType()}
|
||||
wantOpt := &models.CharacteristicTypeListOptions{ListOptions: models.ListOptions{Page: 1, PerPage: 10}}
|
||||
|
||||
calledList := false
|
||||
store.CharacteristicTypes.(*models.MockCharacteristicTypesService).List_ = func(opt *models.CharacteristicTypeListOptions) ([]*models.CharacteristicType, error) {
|
||||
if !normalizeDeepEqual(wantOpt, opt) {
|
||||
t.Errorf("wanted options %d but got %d", wantOpt, opt)
|
||||
}
|
||||
calledList = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
characteristic_types, err := apiClient.CharacteristicTypes.List(wantOpt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledList {
|
||||
t.Error("!calledList")
|
||||
}
|
||||
|
||||
if !normalizeDeepEqual(&want, &characteristic_types) {
|
||||
t.Errorf("got characteristic_types %+v but wanted characteristic_types %+v", characteristic_types, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCharacteristicType_Update(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newCharacteristicType()
|
||||
|
||||
calledPut := false
|
||||
store.CharacteristicTypes.(*models.MockCharacteristicTypesService).Update_ = func(id int64, characteristic_type *models.CharacteristicType) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for characteristic_type %d but got %d", want.Id, id)
|
||||
}
|
||||
if !normalizeDeepEqual(want, characteristic_type) {
|
||||
t.Errorf("wanted request for characteristic_type %d but got %d", want, characteristic_type)
|
||||
}
|
||||
calledPut = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.CharacteristicTypes.Update(want.Id, want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPut {
|
||||
t.Error("!calledPut")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCharacteristicType_Delete(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newCharacteristicType()
|
||||
|
||||
calledDelete := false
|
||||
store.CharacteristicTypes.(*models.MockCharacteristicTypesService).Delete_ = func(id int64) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for characteristic_type %d but got %d", want.Id, id)
|
||||
}
|
||||
calledDelete = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.CharacteristicTypes.Delete(want.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledDelete {
|
||||
t.Error("!calledDelete")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func serveCharacteristic(w http.ResponseWriter, r *http.Request) error {
|
||||
id, err := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
characteristic, err := store.Characteristics.Get(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeJSON(w, models.CharacteristicJSON{Characteristic: characteristic})
|
||||
}
|
||||
|
||||
func serveCreateCharacteristic(w http.ResponseWriter, r *http.Request) error {
|
||||
var characteristic models.CharacteristicJSON
|
||||
err := json.NewDecoder(r.Body).Decode(&characteristic)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
created, err := store.Characteristics.Create(characteristic.Characteristic)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if created {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
||||
return writeJSON(w, characteristic)
|
||||
}
|
||||
|
||||
func serveCharacteristicList(w http.ResponseWriter, r *http.Request) error {
|
||||
var opt models.CharacteristicListOptions
|
||||
if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
characteristics, err := store.Characteristics.List(&opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if characteristics == nil {
|
||||
characteristics = []*models.Characteristic{}
|
||||
}
|
||||
|
||||
return writeJSON(w, models.CharacteristicsJSON{Characteristics: characteristics})
|
||||
}
|
||||
|
||||
func serveUpdateCharacteristic(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
var characteristic models.CharacteristicJSON
|
||||
err := json.NewDecoder(r.Body).Decode(&characteristic)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updated, err := store.Characteristics.Update(id, characteristic.Characteristic)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if updated {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, characteristic)
|
||||
}
|
||||
|
||||
func serveDeleteCharacteristic(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
|
||||
deleted, err := store.Characteristics.Delete(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if deleted {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, nil)
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func newCharacteristic() *models.Characteristic {
|
||||
characteristic := models.NewCharacteristic()
|
||||
return characteristic
|
||||
}
|
||||
|
||||
func TestCharacteristic_Get(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newCharacteristic()
|
||||
|
||||
calledGet := false
|
||||
|
||||
store.Characteristics.(*models.MockCharacteristicsService).Get_ = func(id int64) (*models.Characteristic, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for characteristic %d but got %d", want.Id, id)
|
||||
}
|
||||
calledGet = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
got, err := apiClient.Characteristics.Get(want.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledGet {
|
||||
t.Error("!calledGet")
|
||||
}
|
||||
if !normalizeDeepEqual(want, got) {
|
||||
t.Errorf("got %+v but wanted %+v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCharacteristic_Create(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newCharacteristic()
|
||||
|
||||
calledPost := false
|
||||
store.Characteristics.(*models.MockCharacteristicsService).Create_ = func(characteristic *models.Characteristic) (bool, error) {
|
||||
if !normalizeDeepEqual(want, characteristic) {
|
||||
t.Errorf("wanted request for characteristic %d but got %d", want, characteristic)
|
||||
}
|
||||
calledPost = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Characteristics.Create(want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPost {
|
||||
t.Error("!calledPost")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCharacteristic_List(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := []*models.Characteristic{newCharacteristic()}
|
||||
wantOpt := &models.CharacteristicListOptions{ListOptions: models.ListOptions{Page: 1, PerPage: 10}}
|
||||
|
||||
calledList := false
|
||||
store.Characteristics.(*models.MockCharacteristicsService).List_ = func(opt *models.CharacteristicListOptions) ([]*models.Characteristic, error) {
|
||||
if !normalizeDeepEqual(wantOpt, opt) {
|
||||
t.Errorf("wanted options %d but got %d", wantOpt, opt)
|
||||
}
|
||||
calledList = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
characteristics, err := apiClient.Characteristics.List(wantOpt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledList {
|
||||
t.Error("!calledList")
|
||||
}
|
||||
|
||||
if !normalizeDeepEqual(&want, &characteristics) {
|
||||
t.Errorf("got characteristics %+v but wanted characteristics %+v", characteristics, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCharacteristic_Update(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newCharacteristic()
|
||||
|
||||
calledPut := false
|
||||
store.Characteristics.(*models.MockCharacteristicsService).Update_ = func(id int64, characteristic *models.Characteristic) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for characteristic %d but got %d", want.Id, id)
|
||||
}
|
||||
if !normalizeDeepEqual(want, characteristic) {
|
||||
t.Errorf("wanted request for characteristic %d but got %d", want, characteristic)
|
||||
}
|
||||
calledPut = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Characteristics.Update(want.Id, want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPut {
|
||||
t.Error("!calledPut")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCharacteristic_Delete(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newCharacteristic()
|
||||
|
||||
calledDelete := false
|
||||
store.Characteristics.(*models.MockCharacteristicsService).Delete_ = func(id int64) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for characteristic %d but got %d", want.Id, id)
|
||||
}
|
||||
calledDelete = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Characteristics.Delete(want.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledDelete {
|
||||
t.Error("!calledDelete")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"net/http"
|
||||
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func serveGenus(w http.ResponseWriter, r *http.Request) error {
|
||||
id, err := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
genus, err := store.Genera.Get(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeJSON(w, models.GenusJSON{Genus: genus})
|
||||
}
|
||||
|
||||
func serveCreateGenus(w http.ResponseWriter, r *http.Request) error {
|
||||
var genus models.GenusJSON
|
||||
err := json.NewDecoder(r.Body).Decode(&genus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
created, err := store.Genera.Create(genus.Genus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if created {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
||||
return writeJSON(w, genus)
|
||||
}
|
||||
|
||||
func serveGenera(w http.ResponseWriter, r *http.Request) error {
|
||||
var opt models.GenusListOptions
|
||||
if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
genera, err := store.Genera.List(&opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if genera == nil {
|
||||
genera = []*models.Genus{}
|
||||
}
|
||||
|
||||
return writeJSON(w, models.GeneraJSON{Genera: genera})
|
||||
}
|
||||
|
||||
func serveUpdateGenus(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
var genus models.GenusJSON
|
||||
err := json.NewDecoder(r.Body).Decode(&genus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updated, err := store.Genera.Update(id, genus.Genus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if updated {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, genus)
|
||||
}
|
||||
|
||||
func serveDeleteGenus(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
|
||||
deleted, err := store.Genera.Delete(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if deleted {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, nil)
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func newGenus() *models.Genus {
|
||||
genus := models.NewGenus()
|
||||
genus.Id = 1
|
||||
return genus
|
||||
}
|
||||
|
||||
func TestGenus_Get(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newGenus()
|
||||
|
||||
calledGet := false
|
||||
store.Genera.(*models.MockGeneraService).Get_ = func(id int64) (*models.Genus, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for genus %d but got %d", want.Id, id)
|
||||
}
|
||||
calledGet = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
got, err := apiClient.Genera.Get(want.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledGet {
|
||||
t.Error("!calledGet")
|
||||
}
|
||||
if !normalizeDeepEqual(want, got) {
|
||||
t.Errorf("got genus %+v but wanted genus %+v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenus_Create(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newGenus()
|
||||
|
||||
calledPost := false
|
||||
store.Genera.(*models.MockGeneraService).Create_ = func(genus *models.Genus) (bool, error) {
|
||||
if !normalizeDeepEqual(want, genus) {
|
||||
t.Errorf("wanted request for genus %d but got %d", want, genus)
|
||||
}
|
||||
calledPost = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Genera.Create(want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPost {
|
||||
t.Error("!calledPost")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenus_List(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := []*models.Genus{newGenus()}
|
||||
wantOpt := &models.GenusListOptions{ListOptions: models.ListOptions{Page: 1, PerPage: 10}}
|
||||
|
||||
calledList := false
|
||||
store.Genera.(*models.MockGeneraService).List_ = func(opt *models.GenusListOptions) ([]*models.Genus, error) {
|
||||
if !normalizeDeepEqual(wantOpt, opt) {
|
||||
t.Errorf("wanted options %d but got %d", wantOpt, opt)
|
||||
}
|
||||
calledList = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
genera, err := apiClient.Genera.List(wantOpt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledList {
|
||||
t.Error("!calledList")
|
||||
}
|
||||
if !normalizeDeepEqual(&want, &genera) {
|
||||
t.Errorf("got genera %+v but wanted genera %+v", genera, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenus_Update(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newGenus()
|
||||
|
||||
calledPut := false
|
||||
store.Genera.(*models.MockGeneraService).Update_ = func(id int64, genus *models.Genus) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for genus %d but got %d", want.Id, id)
|
||||
}
|
||||
if !normalizeDeepEqual(want, genus) {
|
||||
t.Errorf("wanted request for genus %d but got %d", want, genus)
|
||||
}
|
||||
calledPut = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Genera.Update(1, want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPut {
|
||||
t.Error("!calledPut")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenus_Delete(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newGenus()
|
||||
|
||||
calledDelete := false
|
||||
store.Genera.(*models.MockGeneraService).Delete_ = func(id int64) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for genus %d but got %d", want.Id, id)
|
||||
}
|
||||
calledDelete = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Genera.Delete(1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledDelete {
|
||||
t.Error("!calledDelete")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gorilla/schema"
|
||||
"github.com/thermokarst/bactdb/datastore"
|
||||
"github.com/thermokarst/bactdb/router"
|
||||
)
|
||||
|
||||
var (
|
||||
store = datastore.NewDatastore(nil)
|
||||
schemaDecoder = schema.NewDecoder()
|
||||
)
|
||||
|
||||
func Handler() *mux.Router {
|
||||
m := router.API()
|
||||
|
||||
m.Get(router.User).Handler(authHandler(serveUser))
|
||||
m.Get(router.CreateUser).Handler(authHandler(serveCreateUser))
|
||||
m.Get(router.Users).Handler(authHandler(serveUsers))
|
||||
m.Get(router.GetToken).Handler(handler(serveAuthenticateUser))
|
||||
|
||||
m.Get(router.Genus).Handler(authHandler(serveGenus))
|
||||
m.Get(router.CreateGenus).Handler(authHandler(serveCreateGenus))
|
||||
m.Get(router.Genera).Handler(authHandler(serveGenera))
|
||||
m.Get(router.UpdateGenus).Handler(authHandler(serveUpdateGenus))
|
||||
m.Get(router.DeleteGenus).Handler(authHandler(serveDeleteGenus))
|
||||
|
||||
m.Get(router.Species).Handler(authHandler(serveSpecies))
|
||||
m.Get(router.CreateSpecies).Handler(authHandler(serveCreateSpecies))
|
||||
m.Get(router.SpeciesList).Handler(authHandler(serveSpeciesList))
|
||||
m.Get(router.UpdateSpecies).Handler(authHandler(serveUpdateSpecies))
|
||||
m.Get(router.DeleteSpecies).Handler(authHandler(serveDeleteSpecies))
|
||||
|
||||
m.Get(router.Strain).Handler(authHandler(serveStrain))
|
||||
m.Get(router.CreateStrain).Handler(authHandler(serveCreateStrain))
|
||||
m.Get(router.Strains).Handler(authHandler(serveStrainList))
|
||||
m.Get(router.UpdateStrain).Handler(authHandler(serveUpdateStrain))
|
||||
m.Get(router.DeleteStrain).Handler(authHandler(serveDeleteStrain))
|
||||
|
||||
m.Get(router.CharacteristicType).Handler(authHandler(serveCharacteristicType))
|
||||
m.Get(router.CreateCharacteristicType).Handler(authHandler(serveCreateCharacteristicType))
|
||||
m.Get(router.CharacteristicTypes).Handler(authHandler(serveCharacteristicTypeList))
|
||||
m.Get(router.UpdateCharacteristicType).Handler(authHandler(serveUpdateCharacteristicType))
|
||||
m.Get(router.DeleteCharacteristicType).Handler(authHandler(serveDeleteCharacteristicType))
|
||||
|
||||
m.Get(router.Characteristic).Handler(authHandler(serveCharacteristic))
|
||||
m.Get(router.CreateCharacteristic).Handler(authHandler(serveCreateCharacteristic))
|
||||
m.Get(router.Characteristics).Handler(authHandler(serveCharacteristicList))
|
||||
m.Get(router.UpdateCharacteristic).Handler(authHandler(serveUpdateCharacteristic))
|
||||
m.Get(router.DeleteCharacteristic).Handler(authHandler(serveDeleteCharacteristic))
|
||||
|
||||
m.Get(router.TextMeasurementType).Handler(authHandler(serveTextMeasurementType))
|
||||
m.Get(router.CreateTextMeasurementType).Handler(authHandler(serveCreateTextMeasurementType))
|
||||
m.Get(router.TextMeasurementTypes).Handler(authHandler(serveTextMeasurementTypeList))
|
||||
m.Get(router.UpdateTextMeasurementType).Handler(authHandler(serveUpdateTextMeasurementType))
|
||||
m.Get(router.DeleteTextMeasurementType).Handler(authHandler(serveDeleteTextMeasurementType))
|
||||
|
||||
m.Get(router.UnitType).Handler(authHandler(serveUnitType))
|
||||
m.Get(router.CreateUnitType).Handler(authHandler(serveCreateUnitType))
|
||||
m.Get(router.UnitTypes).Handler(authHandler(serveUnitTypeList))
|
||||
m.Get(router.UpdateUnitType).Handler(authHandler(serveUpdateUnitType))
|
||||
m.Get(router.DeleteUnitType).Handler(authHandler(serveDeleteUnitType))
|
||||
|
||||
m.Get(router.Measurement).Handler(authHandler(serveMeasurement))
|
||||
m.Get(router.CreateMeasurement).Handler(authHandler(serveCreateMeasurement))
|
||||
m.Get(router.Measurements).Handler(authHandler(serveMeasurementList))
|
||||
m.Get(router.UpdateMeasurement).Handler(authHandler(serveUpdateMeasurement))
|
||||
m.Get(router.DeleteMeasurement).Handler(authHandler(serveDeleteMeasurement))
|
||||
|
||||
m.Get(router.SubrouterListSpecies).Handler(authHandler(serveSubrouterSpeciesList))
|
||||
m.Get(router.SubrouterListStrains).Handler(authHandler(serveSubrouterStrainsList))
|
||||
m.Get(router.SubrouterListMeasurements).Handler(authHandler(serveSubrouterMeasurementsList))
|
||||
|
||||
m.Get(router.Health).Handler(handler(healthHandler))
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
type handler func(http.ResponseWriter, *http.Request) error
|
||||
|
||||
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
err := h(w, r)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
writeJSON(w, Error{err})
|
||||
}
|
||||
}
|
||||
|
||||
func healthHandler(w http.ResponseWriter, r *http.Request) error {
|
||||
return writeJSON(w, Message{"great success"})
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// writeJSON writes a JSON Content-Type header and a JSON-encoded object to
|
||||
// the http.ResponseWriter.
|
||||
func writeJSON(w http.ResponseWriter, v interface{}) error {
|
||||
data, err := json.MarshalIndent(v, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.Header().Set("content-type", "application/json; charset=utf-8")
|
||||
_, err = w.Write(data)
|
||||
return err
|
||||
}
|
||||
|
||||
// Message is for returning simple message payloads to the user
|
||||
type Message struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// Error is for returning simple error payloads to the user, as well as logging
|
||||
type Error struct {
|
||||
Error error
|
||||
}
|
||||
|
||||
func (e Error) MarshalJSON() ([]byte, error) {
|
||||
log.Println(e.Error)
|
||||
return json.Marshal(struct {
|
||||
Error string `json:"error"`
|
||||
}{e.Error.Error()})
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Helper function that normalizes structs for comparison with reflect.DeepEqual
|
||||
func normalize(v interface{}) {
|
||||
j, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Could not normalize object %+v due to JSON marshalling error: %s", v, err))
|
||||
}
|
||||
err = json.Unmarshal(j, v)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Could not normalize object %+v due to JSON un-marshalling error: %s", v, err))
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeDeepEqual(u, v interface{}) bool {
|
||||
normalize(u)
|
||||
normalize(v)
|
||||
return reflect.DeepEqual(u, v)
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func serveMeasurement(w http.ResponseWriter, r *http.Request) error {
|
||||
id, err := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
measurement, err := store.Measurements.Get(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeJSON(w, models.MeasurementJSON{Measurement: measurement})
|
||||
}
|
||||
|
||||
func serveCreateMeasurement(w http.ResponseWriter, r *http.Request) error {
|
||||
var measurement models.MeasurementJSON
|
||||
err := json.NewDecoder(r.Body).Decode(&measurement)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
created, err := store.Measurements.Create(measurement.Measurement)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if created {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
||||
return writeJSON(w, measurement)
|
||||
}
|
||||
|
||||
func serveMeasurementList(w http.ResponseWriter, r *http.Request) error {
|
||||
var opt models.MeasurementListOptions
|
||||
if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
measurements, err := store.Measurements.List(&opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if measurements == nil {
|
||||
measurements = []*models.Measurement{}
|
||||
}
|
||||
|
||||
return writeJSON(w, models.MeasurementsJSON{Measurements: measurements})
|
||||
}
|
||||
|
||||
func serveUpdateMeasurement(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
var measurement models.MeasurementJSON
|
||||
err := json.NewDecoder(r.Body).Decode(&measurement)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updated, err := store.Measurements.Update(id, measurement.Measurement)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if updated {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, measurement)
|
||||
}
|
||||
|
||||
func serveDeleteMeasurement(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
|
||||
deleted, err := store.Measurements.Delete(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if deleted {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, nil)
|
||||
}
|
||||
|
||||
func serveSubrouterMeasurementsList(w http.ResponseWriter, r *http.Request) error {
|
||||
var opt models.MeasurementListOptions
|
||||
if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opt.Genus = mux.Vars(r)["genus"]
|
||||
|
||||
measurements, err := store.Measurements.List(&opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if measurements == nil {
|
||||
measurements = []*models.Measurement{}
|
||||
}
|
||||
|
||||
return writeJSON(w, models.MeasurementsJSON{Measurements: measurements})
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"testing"
|
||||
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func newMeasurement() *models.Measurement {
|
||||
measurement := models.NewMeasurement()
|
||||
measurement.Id = 1
|
||||
measurement.StrainId = 2
|
||||
measurement.CharacteristicId = 3
|
||||
measurement.TextMeasurementTypeId = models.NullInt64{sql.NullInt64{Int64: 4, Valid: false}}
|
||||
measurement.UnitTypeId = models.NullInt64{sql.NullInt64{Int64: 5, Valid: true}}
|
||||
measurement.Notes = models.NullString{sql.NullString{String: "a note", Valid: true}}
|
||||
return measurement
|
||||
}
|
||||
|
||||
func TestMeasurement_Get(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newMeasurement()
|
||||
|
||||
calledGet := false
|
||||
|
||||
store.Measurements.(*models.MockMeasurementsService).Get_ = func(id int64) (*models.Measurement, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for measurement %d but got %d", want.Id, id)
|
||||
}
|
||||
calledGet = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
got, err := apiClient.Measurements.Get(want.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledGet {
|
||||
t.Error("!calledGet")
|
||||
}
|
||||
if !normalizeDeepEqual(want, got) {
|
||||
t.Errorf("got %+v but wanted %+v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMeasurement_Create(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newMeasurement()
|
||||
|
||||
calledPost := false
|
||||
store.Measurements.(*models.MockMeasurementsService).Create_ = func(measurement *models.Measurement) (bool, error) {
|
||||
if !normalizeDeepEqual(want, measurement) {
|
||||
t.Errorf("wanted request for measurement %d but got %d", want, measurement)
|
||||
}
|
||||
calledPost = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Measurements.Create(want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPost {
|
||||
t.Error("!calledPost")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMeasurement_List(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := []*models.Measurement{newMeasurement()}
|
||||
wantOpt := &models.MeasurementListOptions{ListOptions: models.ListOptions{Page: 1, PerPage: 10}}
|
||||
|
||||
calledList := false
|
||||
store.Measurements.(*models.MockMeasurementsService).List_ = func(opt *models.MeasurementListOptions) ([]*models.Measurement, error) {
|
||||
if !normalizeDeepEqual(wantOpt, opt) {
|
||||
t.Errorf("wanted options %d but got %d", wantOpt, opt)
|
||||
}
|
||||
calledList = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
measurements, err := apiClient.Measurements.List(wantOpt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledList {
|
||||
t.Error("!calledList")
|
||||
}
|
||||
|
||||
if !normalizeDeepEqual(&want, &measurements) {
|
||||
t.Errorf("got measurements %+v but wanted measurements %+v", measurements, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMeasurement_Update(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newMeasurement()
|
||||
|
||||
calledPut := false
|
||||
store.Measurements.(*models.MockMeasurementsService).Update_ = func(id int64, measurement *models.Measurement) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for measurement %d but got %d", want.Id, id)
|
||||
}
|
||||
if !normalizeDeepEqual(want, measurement) {
|
||||
t.Errorf("wanted request for measurement %d but got %d", want, measurement)
|
||||
}
|
||||
calledPut = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Measurements.Update(want.Id, want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPut {
|
||||
t.Error("!calledPut")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMeasurement_Delete(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newMeasurement()
|
||||
|
||||
calledDelete := false
|
||||
store.Measurements.(*models.MockMeasurementsService).Delete_ = func(id int64) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for measurement %d but got %d", want.Id, id)
|
||||
}
|
||||
calledDelete = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Measurements.Delete(want.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledDelete {
|
||||
t.Error("!calledDelete")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
|
||||
"github.com/thermokarst/bactdb/datastore"
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
"github.com/thermokarst/bactdb/router"
|
||||
)
|
||||
|
||||
func init() {
|
||||
signKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAyXi+Q3rVv+NkBi3UWBXyylUN5SyHxQUtZvhbA6TwcF2fk3Io
|
||||
Di3kipVWbfYAYijIxczACieCnadSynJpH4zNVJsRxp8DTG67Nx/K5n3TJyg5hLpa
|
||||
PE+46lOS7E0O9JPT119zKCGHtHldpgjsPCXGHRXKZdFafSv8ktFhwvK5ZQO1NjH2
|
||||
+NOsfhp2ubuQXL7O/45fC5wTCj0lLatdXtlTcIxJb7FUj3AsAC7TlKhtkKe+Syox
|
||||
n1xNMQiYK1R24+goW44JO5uZDYP85ufgRn+DdOQF9DskmiQN9/REhH/5VQjEIYZ3
|
||||
kjmKlNnjz3Jd1eOdtGALxTq3+neVawWMPBXOcQIDAQABAoIBAHMAYhKgrhxPTwwb
|
||||
4ua4+JK4BCt5xLIYp3bscv9cigaJ2onOksCtP5Q/dEtmLYfaYehOXJwvO2aEWUTI
|
||||
E+t3cslFjtsCb16UonbvxeDVl871LgfuW42rsBDJzcbmoY/IRhbdHB2fLhg9YtBg
|
||||
rYATy8dUZejCnNVwY0bnD9e4t0zJ0lXUVy+dMvl69uNyP8f12LwvLGgCmAOWXh5p
|
||||
NpGmT8/jRF9BrQvr9bhwxpV2JGsGEEyGvu+ayVR01AiyQ04kh9gZOJOVtsGa1fjx
|
||||
AvgxzhkfLyAbCAgFTTUuhEbZoxXyCNBdOM0V3PXSbIbW+7gwLwXi71Czo08V050z
|
||||
5SK9p2UCgYEA8JW+xIaAzYT+ZwPaJ/Ir1+WcisEI+AyCD1c5gblHrCmSwYHdKSX4
|
||||
ZcX0QAcj+dzuF6SyQStoy1pIooUzadDZxXeyBoeOjGdyobqJpmaEHb9g594w2inS
|
||||
AsEb4waxvrKlTuhFXnI2JbJrbMyjRBTKWZw4K/FT73IE8hQL9ivXYN8CgYEA1mFu
|
||||
uLD95N/KOFtQ0JcLUelPZK7gYSdq21YHSbABeeesvabnn3hFEzDl5cXqKFJ/4Ltf
|
||||
2QhpO4JGgHYNlrsfCvvivV5dRxFKfleoojL/0qlJxOqQVfulscT0XB3wUpoyP+Qr
|
||||
8AdyvZwUfLWpSaYxDUB7w77U1VayP5JLuULKKq8CgYBOge8QnnullUKXRzCHXIVm
|
||||
HG1q8fcFSr+eVe5UIKv8yEw1jTUoWlWmkGRWCH566NdhK8NndMzrnviY4DKY0yhd
|
||||
QeP8MXwY4SENGZwVitqOAoeS4nS6nG8FqxJ4kRSrkAxVpYINgeOdhY18oYKdktM9
|
||||
Trcdz9B+EI0Amf4VRNUxrQKBgQCTBXTagr9MhFF5vt44fy3LOhcxtGC7ID4/N8t9
|
||||
tI/+m2yzD9DPY7rzg1hW8Rk6GAINDFOaUxNgNWLGXK/LDH8omEASoLGVuHz/Enza
|
||||
5+DcBy9JNZhQ72jd9nWi6wFSlN8bRA8B6Qm+kVjXgfocQTZooS1/u9LYkEFkKZ92
|
||||
6SAejwKBgH6V+dLUefC9w6N99VWpOAom9gE96imo1itTKxIB1WPdFsSDDe/CGXDG
|
||||
W+l7ZiSjXaAfNF5UtuhO6yY0ob++Aa/d+l+Zo7CWn4SrmwTAp1CdRHxX3KxkqHNi
|
||||
BsuYClbQh5Z9lOKn8FCNW3NyahJdYeWGhb/ZdeS0n+F6Ov4V+grc
|
||||
-----END RSA PRIVATE KEY-----`)
|
||||
|
||||
verifyKey = []byte(`-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyXi+Q3rVv+NkBi3UWBXy
|
||||
ylUN5SyHxQUtZvhbA6TwcF2fk3IoDi3kipVWbfYAYijIxczACieCnadSynJpH4zN
|
||||
VJsRxp8DTG67Nx/K5n3TJyg5hLpaPE+46lOS7E0O9JPT119zKCGHtHldpgjsPCXG
|
||||
HRXKZdFafSv8ktFhwvK5ZQO1NjH2+NOsfhp2ubuQXL7O/45fC5wTCj0lLatdXtlT
|
||||
cIxJb7FUj3AsAC7TlKhtkKe+Syoxn1xNMQiYK1R24+goW44JO5uZDYP85ufgRn+D
|
||||
dOQF9DskmiQN9/REhH/5VQjEIYZ3kjmKlNnjz3Jd1eOdtGALxTq3+neVawWMPBXO
|
||||
cQIDAQAB
|
||||
-----END PUBLIC KEY-----`)
|
||||
|
||||
serveMux.Handle("/", http.StripPrefix("/api", Handler()))
|
||||
}
|
||||
|
||||
var (
|
||||
serveMux = http.NewServeMux()
|
||||
httpClient = http.Client{
|
||||
Transport: (*muxTransport)(serveMux),
|
||||
}
|
||||
apiClient = models.NewClient(&httpClient)
|
||||
testToken models.UserSession
|
||||
)
|
||||
|
||||
func setup() {
|
||||
store = datastore.NewMockDatastore()
|
||||
u, _ := apiClient.URL(router.GetToken, nil, nil)
|
||||
resp, _ := httpClient.PostForm(u.String(),
|
||||
url.Values{"username": {"test_user"}, "password": {"password"}})
|
||||
defer resp.Body.Close()
|
||||
|
||||
if err := json.NewDecoder(resp.Body).Decode(&testToken); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
type muxTransport http.ServeMux
|
||||
|
||||
// RoundTrip is for testing API requests. It intercepts all requests during testing
|
||||
// to serve up a local/internal response.
|
||||
func (t *muxTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
rw := httptest.NewRecorder()
|
||||
rw.Body = new(bytes.Buffer)
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", testToken.Token))
|
||||
(*http.ServeMux)(t).ServeHTTP(rw, req)
|
||||
return &http.Response{
|
||||
StatusCode: rw.Code,
|
||||
Status: http.StatusText(rw.Code),
|
||||
Header: rw.HeaderMap,
|
||||
Body: ioutil.NopCloser(rw.Body),
|
||||
ContentLength: int64(rw.Body.Len()),
|
||||
Request: req,
|
||||
}, nil
|
||||
}
|
111
api/species.go
111
api/species.go
|
@ -1,111 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func serveSpecies(w http.ResponseWriter, r *http.Request) error {
|
||||
id, err := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
species, err := store.Species.Get(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeJSON(w, models.SpeciesJSON{species})
|
||||
}
|
||||
|
||||
func serveCreateSpecies(w http.ResponseWriter, r *http.Request) error {
|
||||
var species models.SpeciesJSON
|
||||
err := json.NewDecoder(r.Body).Decode(&species)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
created, err := store.Species.Create(species.Species)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if created {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
||||
return writeJSON(w, species)
|
||||
}
|
||||
|
||||
func serveSpeciesList(w http.ResponseWriter, r *http.Request) error {
|
||||
var opt models.SpeciesListOptions
|
||||
if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
species, err := store.Species.List(&opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if species == nil {
|
||||
species = []*models.Species{}
|
||||
}
|
||||
|
||||
return writeJSON(w, models.SpeciesListJSON{Species: species})
|
||||
}
|
||||
|
||||
func serveUpdateSpecies(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
var species models.SpeciesJSON
|
||||
err := json.NewDecoder(r.Body).Decode(&species)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updated, err := store.Species.Update(id, species.Species)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if updated {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, species)
|
||||
}
|
||||
|
||||
func serveDeleteSpecies(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
|
||||
deleted, err := store.Species.Delete(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if deleted {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, nil)
|
||||
}
|
||||
|
||||
func serveSubrouterSpeciesList(w http.ResponseWriter, r *http.Request) error {
|
||||
var opt models.SpeciesListOptions
|
||||
if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opt.Genus = mux.Vars(r)["genus"]
|
||||
|
||||
species, err := store.Species.List(&opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if species == nil {
|
||||
species = []*models.Species{}
|
||||
}
|
||||
|
||||
return writeJSON(w, models.SpeciesListJSON{Species: species})
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func newSpecies() *models.Species {
|
||||
species := models.NewSpecies()
|
||||
species.Id = 1
|
||||
species.GenusId = 1
|
||||
return species
|
||||
}
|
||||
|
||||
func TestSpecies_Get(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newSpecies()
|
||||
|
||||
calledGet := false
|
||||
store.Species.(*models.MockSpeciesService).Get_ = func(id int64) (*models.Species, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for species %d but got %d", want.Id, id)
|
||||
}
|
||||
calledGet = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
got, err := apiClient.Species.Get(want.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledGet {
|
||||
t.Error("!calledGet")
|
||||
}
|
||||
if !normalizeDeepEqual(want, got) {
|
||||
t.Errorf("got species %+v but wanted species %+v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpecies_Create(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newSpecies()
|
||||
|
||||
calledPost := false
|
||||
store.Species.(*models.MockSpeciesService).Create_ = func(species *models.Species) (bool, error) {
|
||||
if !normalizeDeepEqual(want, species) {
|
||||
t.Errorf("wanted request for species %d but got %d", want, species)
|
||||
}
|
||||
calledPost = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Species.Create(want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPost {
|
||||
t.Error("!calledPost")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpecies_List(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := []*models.Species{newSpecies()}
|
||||
wantOpt := &models.SpeciesListOptions{ListOptions: models.ListOptions{Page: 1, PerPage: 10}}
|
||||
|
||||
calledList := false
|
||||
store.Species.(*models.MockSpeciesService).List_ = func(opt *models.SpeciesListOptions) ([]*models.Species, error) {
|
||||
if !normalizeDeepEqual(wantOpt, opt) {
|
||||
t.Errorf("wanted options %d but got %d", wantOpt, opt)
|
||||
}
|
||||
calledList = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
species, err := apiClient.Species.List(wantOpt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledList {
|
||||
t.Error("!calledList")
|
||||
}
|
||||
|
||||
if !normalizeDeepEqual(&want, &species) {
|
||||
t.Errorf("got species %+v but wanted species %+v", species, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpecies_Update(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newSpecies()
|
||||
|
||||
calledPut := false
|
||||
store.Species.(*models.MockSpeciesService).Update_ = func(id int64, species *models.Species) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for species %d but got %d", want.Id, id)
|
||||
}
|
||||
if !normalizeDeepEqual(want, species) {
|
||||
t.Errorf("wanted request for species %d but got %d", want, species)
|
||||
}
|
||||
calledPut = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Species.Update(1, want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPut {
|
||||
t.Error("!calledPut")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpecies_Delete(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newSpecies()
|
||||
|
||||
calledDelete := false
|
||||
store.Species.(*models.MockSpeciesService).Delete_ = func(id int64) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for species %d but got %d", want.Id, id)
|
||||
}
|
||||
calledDelete = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Species.Delete(1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledDelete {
|
||||
t.Error("!calledDelete")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
111
api/strains.go
111
api/strains.go
|
@ -1,111 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func serveStrain(w http.ResponseWriter, r *http.Request) error {
|
||||
id, err := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
strain, err := store.Strains.Get(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeJSON(w, models.StrainJSON{Strain: strain})
|
||||
}
|
||||
|
||||
func serveCreateStrain(w http.ResponseWriter, r *http.Request) error {
|
||||
var strain models.StrainJSON
|
||||
err := json.NewDecoder(r.Body).Decode(&strain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
created, err := store.Strains.Create(strain.Strain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if created {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
||||
return writeJSON(w, strain)
|
||||
}
|
||||
|
||||
func serveStrainList(w http.ResponseWriter, r *http.Request) error {
|
||||
var opt models.StrainListOptions
|
||||
if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
strains, err := store.Strains.List(&opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if strains == nil {
|
||||
strains = []*models.Strain{}
|
||||
}
|
||||
|
||||
return writeJSON(w, models.StrainsJSON{Strains: strains})
|
||||
}
|
||||
|
||||
func serveUpdateStrain(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
var strain models.StrainJSON
|
||||
err := json.NewDecoder(r.Body).Decode(&strain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updated, err := store.Strains.Update(id, strain.Strain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if updated {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, strain)
|
||||
}
|
||||
|
||||
func serveDeleteStrain(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
|
||||
deleted, err := store.Strains.Delete(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if deleted {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, nil)
|
||||
}
|
||||
|
||||
func serveSubrouterStrainsList(w http.ResponseWriter, r *http.Request) error {
|
||||
var opt models.StrainListOptions
|
||||
if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opt.Genus = mux.Vars(r)["genus"]
|
||||
|
||||
strains, err := store.Strains.List(&opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if strains == nil {
|
||||
strains = []*models.Strain{}
|
||||
}
|
||||
|
||||
return writeJSON(w, models.StrainsJSON{Strains: strains})
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func newStrain() *models.Strain {
|
||||
strain := models.NewStrain()
|
||||
strain.Id = 1
|
||||
strain.SpeciesId = 1
|
||||
return strain
|
||||
}
|
||||
|
||||
func TestStrain_Get(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newStrain()
|
||||
|
||||
calledGet := false
|
||||
|
||||
store.Strains.(*models.MockStrainsService).Get_ = func(id int64) (*models.Strain, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for strain %d but got %d", want.Id, id)
|
||||
}
|
||||
calledGet = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
got, err := apiClient.Strains.Get(want.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledGet {
|
||||
t.Error("!calledGet")
|
||||
}
|
||||
if !normalizeDeepEqual(want, got) {
|
||||
t.Errorf("got strain %+v but wanted strain %+v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrain_Create(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newStrain()
|
||||
|
||||
calledPost := false
|
||||
store.Strains.(*models.MockStrainsService).Create_ = func(strain *models.Strain) (bool, error) {
|
||||
if !normalizeDeepEqual(want, strain) {
|
||||
t.Errorf("wanted request for strain %d but got %d", want, strain)
|
||||
}
|
||||
calledPost = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Strains.Create(want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPost {
|
||||
t.Error("!calledPost")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrain_List(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := []*models.Strain{newStrain()}
|
||||
wantOpt := &models.StrainListOptions{ListOptions: models.ListOptions{Page: 1, PerPage: 10}}
|
||||
|
||||
calledList := false
|
||||
store.Strains.(*models.MockStrainsService).List_ = func(opt *models.StrainListOptions) ([]*models.Strain, error) {
|
||||
if !normalizeDeepEqual(wantOpt, opt) {
|
||||
t.Errorf("wanted options %d but got %d", wantOpt, opt)
|
||||
}
|
||||
calledList = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
strains, err := apiClient.Strains.List(wantOpt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledList {
|
||||
t.Error("!calledList")
|
||||
}
|
||||
|
||||
if !normalizeDeepEqual(&want, &strains) {
|
||||
t.Errorf("got strains %+v but wanted strains %+v", strains, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrain_Update(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newStrain()
|
||||
|
||||
calledPut := false
|
||||
store.Strains.(*models.MockStrainsService).Update_ = func(id int64, strain *models.Strain) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for strain %d but got %d", want.Id, id)
|
||||
}
|
||||
if !normalizeDeepEqual(want, strain) {
|
||||
t.Errorf("wanted request for strain %d but got %d", want, strain)
|
||||
}
|
||||
calledPut = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Strains.Update(1, want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPut {
|
||||
t.Error("!calledPut")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrain_Delete(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newStrain()
|
||||
|
||||
calledDelete := false
|
||||
store.Strains.(*models.MockStrainsService).Delete_ = func(id int64) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for strain %d but got %d", want.Id, id)
|
||||
}
|
||||
calledDelete = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Strains.Delete(1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledDelete {
|
||||
t.Error("!calledDelete")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func serveTextMeasurementType(w http.ResponseWriter, r *http.Request) error {
|
||||
id, err := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
text_measurement_type, err := store.TextMeasurementTypes.Get(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeJSON(w, text_measurement_type)
|
||||
}
|
||||
|
||||
func serveCreateTextMeasurementType(w http.ResponseWriter, r *http.Request) error {
|
||||
var text_measurement_type models.TextMeasurementType
|
||||
err := json.NewDecoder(r.Body).Decode(&text_measurement_type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
created, err := store.TextMeasurementTypes.Create(&text_measurement_type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if created {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
||||
return writeJSON(w, text_measurement_type)
|
||||
}
|
||||
|
||||
func serveTextMeasurementTypeList(w http.ResponseWriter, r *http.Request) error {
|
||||
var opt models.TextMeasurementTypeListOptions
|
||||
if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
text_measurement_types, err := store.TextMeasurementTypes.List(&opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if text_measurement_types == nil {
|
||||
text_measurement_types = []*models.TextMeasurementType{}
|
||||
}
|
||||
|
||||
return writeJSON(w, text_measurement_types)
|
||||
}
|
||||
|
||||
func serveUpdateTextMeasurementType(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
var text_measurement_type models.TextMeasurementType
|
||||
err := json.NewDecoder(r.Body).Decode(&text_measurement_type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updated, err := store.TextMeasurementTypes.Update(id, &text_measurement_type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if updated {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, text_measurement_type)
|
||||
}
|
||||
|
||||
func serveDeleteTextMeasurementType(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
|
||||
deleted, err := store.TextMeasurementTypes.Delete(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if deleted {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, &models.TextMeasurementType{})
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func newTextMeasurementType() *models.TextMeasurementType {
|
||||
text_measurement_type := models.NewTextMeasurementType()
|
||||
return text_measurement_type
|
||||
}
|
||||
|
||||
func TestTextMeasurementType_Get(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newTextMeasurementType()
|
||||
|
||||
calledGet := false
|
||||
|
||||
store.TextMeasurementTypes.(*models.MockTextMeasurementTypesService).Get_ = func(id int64) (*models.TextMeasurementType, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for text_measurement_type %d but got %d", want.Id, id)
|
||||
}
|
||||
calledGet = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
got, err := apiClient.TextMeasurementTypes.Get(want.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledGet {
|
||||
t.Error("!calledGet")
|
||||
}
|
||||
if !normalizeDeepEqual(want, got) {
|
||||
t.Errorf("got %+v but wanted %+v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTextMeasurementType_Create(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newTextMeasurementType()
|
||||
|
||||
calledPost := false
|
||||
store.TextMeasurementTypes.(*models.MockTextMeasurementTypesService).Create_ = func(text_measurement_type *models.TextMeasurementType) (bool, error) {
|
||||
if !normalizeDeepEqual(want, text_measurement_type) {
|
||||
t.Errorf("wanted request for text_measurement_type %d but got %d", want, text_measurement_type)
|
||||
}
|
||||
calledPost = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.TextMeasurementTypes.Create(want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPost {
|
||||
t.Error("!calledPost")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTextMeasurementType_List(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := []*models.TextMeasurementType{newTextMeasurementType()}
|
||||
wantOpt := &models.TextMeasurementTypeListOptions{ListOptions: models.ListOptions{Page: 1, PerPage: 10}}
|
||||
|
||||
calledList := false
|
||||
store.TextMeasurementTypes.(*models.MockTextMeasurementTypesService).List_ = func(opt *models.TextMeasurementTypeListOptions) ([]*models.TextMeasurementType, error) {
|
||||
if !normalizeDeepEqual(wantOpt, opt) {
|
||||
t.Errorf("wanted options %d but got %d", wantOpt, opt)
|
||||
}
|
||||
calledList = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
text_measurement_types, err := apiClient.TextMeasurementTypes.List(wantOpt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledList {
|
||||
t.Error("!calledList")
|
||||
}
|
||||
|
||||
if !normalizeDeepEqual(&want, &text_measurement_types) {
|
||||
t.Errorf("got text_measurement_types %+v but wanted text_measurement_types %+v", text_measurement_types, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTextMeasurementType_Update(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newTextMeasurementType()
|
||||
|
||||
calledPut := false
|
||||
store.TextMeasurementTypes.(*models.MockTextMeasurementTypesService).Update_ = func(id int64, text_measurement_type *models.TextMeasurementType) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for text_measurement_type %d but got %d", want.Id, id)
|
||||
}
|
||||
if !normalizeDeepEqual(want, text_measurement_type) {
|
||||
t.Errorf("wanted request for text_measurement_type %d but got %d", want, text_measurement_type)
|
||||
}
|
||||
calledPut = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.TextMeasurementTypes.Update(want.Id, want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPut {
|
||||
t.Error("!calledPut")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTextMeasurementType_Delete(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newTextMeasurementType()
|
||||
|
||||
calledDelete := false
|
||||
store.TextMeasurementTypes.(*models.MockTextMeasurementTypesService).Delete_ = func(id int64) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for text_measurement_type %d but got %d", want.Id, id)
|
||||
}
|
||||
calledDelete = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.TextMeasurementTypes.Delete(want.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledDelete {
|
||||
t.Error("!calledDelete")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func serveUnitType(w http.ResponseWriter, r *http.Request) error {
|
||||
id, err := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
unit_type, err := store.UnitTypes.Get(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeJSON(w, unit_type)
|
||||
}
|
||||
|
||||
func serveCreateUnitType(w http.ResponseWriter, r *http.Request) error {
|
||||
var unit_type models.UnitType
|
||||
err := json.NewDecoder(r.Body).Decode(&unit_type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
created, err := store.UnitTypes.Create(&unit_type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if created {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
||||
return writeJSON(w, unit_type)
|
||||
}
|
||||
|
||||
func serveUnitTypeList(w http.ResponseWriter, r *http.Request) error {
|
||||
var opt models.UnitTypeListOptions
|
||||
if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
unit_types, err := store.UnitTypes.List(&opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if unit_types == nil {
|
||||
unit_types = []*models.UnitType{}
|
||||
}
|
||||
|
||||
return writeJSON(w, unit_types)
|
||||
}
|
||||
|
||||
func serveUpdateUnitType(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
var unit_type models.UnitType
|
||||
err := json.NewDecoder(r.Body).Decode(&unit_type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updated, err := store.UnitTypes.Update(id, &unit_type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if updated {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, unit_type)
|
||||
}
|
||||
|
||||
func serveDeleteUnitType(w http.ResponseWriter, r *http.Request) error {
|
||||
id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
|
||||
deleted, err := store.UnitTypes.Delete(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if deleted {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
return writeJSON(w, &models.UnitType{})
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func newUnitType() *models.UnitType {
|
||||
unit_type := models.NewUnitType()
|
||||
return unit_type
|
||||
}
|
||||
|
||||
func TestUnitType_Get(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newUnitType()
|
||||
|
||||
calledGet := false
|
||||
|
||||
store.UnitTypes.(*models.MockUnitTypesService).Get_ = func(id int64) (*models.UnitType, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for unit_type %d but got %d", want.Id, id)
|
||||
}
|
||||
calledGet = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
got, err := apiClient.UnitTypes.Get(want.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledGet {
|
||||
t.Error("!calledGet")
|
||||
}
|
||||
if !normalizeDeepEqual(want, got) {
|
||||
t.Errorf("got %+v but wanted %+v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnitType_Create(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newUnitType()
|
||||
|
||||
calledPost := false
|
||||
store.UnitTypes.(*models.MockUnitTypesService).Create_ = func(unit_type *models.UnitType) (bool, error) {
|
||||
if !normalizeDeepEqual(want, unit_type) {
|
||||
t.Errorf("wanted request for unit_type %d but got %d", want, unit_type)
|
||||
}
|
||||
calledPost = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.UnitTypes.Create(want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPost {
|
||||
t.Error("!calledPost")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnitType_List(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := []*models.UnitType{newUnitType()}
|
||||
wantOpt := &models.UnitTypeListOptions{ListOptions: models.ListOptions{Page: 1, PerPage: 10}}
|
||||
|
||||
calledList := false
|
||||
store.UnitTypes.(*models.MockUnitTypesService).List_ = func(opt *models.UnitTypeListOptions) ([]*models.UnitType, error) {
|
||||
if !normalizeDeepEqual(wantOpt, opt) {
|
||||
t.Errorf("wanted options %d but got %d", wantOpt, opt)
|
||||
}
|
||||
calledList = true
|
||||
return want, nil
|
||||
}
|
||||
|
||||
unit_types, err := apiClient.UnitTypes.List(wantOpt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledList {
|
||||
t.Error("!calledList")
|
||||
}
|
||||
|
||||
if !normalizeDeepEqual(&want, &unit_types) {
|
||||
t.Errorf("got unit_types %+v but wanted unit_types %+v", unit_types, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnitType_Update(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newUnitType()
|
||||
|
||||
calledPut := false
|
||||
store.UnitTypes.(*models.MockUnitTypesService).Update_ = func(id int64, unit_type *models.UnitType) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for unit_type %d but got %d", want.Id, id)
|
||||
}
|
||||
if !normalizeDeepEqual(want, unit_type) {
|
||||
t.Errorf("wanted request for unit_type %d but got %d", want, unit_type)
|
||||
}
|
||||
calledPut = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.UnitTypes.Update(want.Id, want)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPut {
|
||||
t.Error("!calledPut")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnitType_Delete(t *testing.T) {
|
||||
setup()
|
||||
|
||||
want := newUnitType()
|
||||
|
||||
calledDelete := false
|
||||
store.UnitTypes.(*models.MockUnitTypesService).Delete_ = func(id int64) (bool, error) {
|
||||
if id != want.Id {
|
||||
t.Errorf("wanted request for unit_type %d but got %d", want.Id, id)
|
||||
}
|
||||
calledDelete = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.UnitTypes.Delete(want.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledDelete {
|
||||
t.Error("!calledDelete")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
87
api/users.go
87
api/users.go
|
@ -1,87 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"net/http"
|
||||
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func serveUser(w http.ResponseWriter, r *http.Request) error {
|
||||
id, err := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
user, err := store.Users.Get(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeJSON(w, models.UserJSON{user})
|
||||
}
|
||||
|
||||
func serveCreateUser(w http.ResponseWriter, r *http.Request) error {
|
||||
var user models.UserJSON
|
||||
err := json.NewDecoder(r.Body).Decode(&user)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
created, err := store.Users.Create(user.User)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if created {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
||||
return writeJSON(w, user)
|
||||
}
|
||||
|
||||
func serveUsers(w http.ResponseWriter, r *http.Request) error {
|
||||
var opt models.UserListOptions
|
||||
if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
users, err := store.Users.List(&opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if users == nil {
|
||||
users = []*models.User{}
|
||||
}
|
||||
|
||||
return writeJSON(w, models.UsersJSON{Users: users})
|
||||
}
|
||||
|
||||
func serveAuthenticateUser(w http.ResponseWriter, r *http.Request) error {
|
||||
username := r.FormValue("username")
|
||||
password := r.FormValue("password")
|
||||
|
||||
user_session, err := store.Users.Authenticate(username, password)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return err
|
||||
}
|
||||
|
||||
t := jwt.New(jwt.GetSigningMethod("RS256"))
|
||||
t.Claims["auth_level"] = user_session.AccessLevel
|
||||
t.Claims["genus"] = user_session.Genus
|
||||
t.Claims["exp"] = time.Now().Add(time.Minute * 60 * 24).Unix()
|
||||
tokenString, err := t.SignedString(signKey)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return err
|
||||
}
|
||||
user_session.Token = tokenString
|
||||
|
||||
return writeJSON(w, user_session)
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
)
|
||||
|
||||
func newUser() *models.User {
|
||||
user := models.NewUser()
|
||||
user.Id = 1
|
||||
return user
|
||||
}
|
||||
|
||||
func TestUser_Get(t *testing.T) {
|
||||
setup()
|
||||
|
||||
wantUser := newUser()
|
||||
|
||||
calledGet := false
|
||||
store.Users.(*models.MockUsersService).Get_ = func(id int64) (*models.User, error) {
|
||||
if id != wantUser.Id {
|
||||
t.Errorf("wanted request for user %d but got %d", wantUser.Id, id)
|
||||
}
|
||||
calledGet = true
|
||||
return wantUser, nil
|
||||
}
|
||||
|
||||
gotUser, err := apiClient.Users.Get(wantUser.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledGet {
|
||||
t.Error("!calledGet")
|
||||
}
|
||||
if !normalizeDeepEqual(wantUser, gotUser) {
|
||||
t.Errorf("got user %+v but wanted user %+v", wantUser, gotUser)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUser_Create(t *testing.T) {
|
||||
setup()
|
||||
|
||||
wantUser := newUser()
|
||||
|
||||
calledPost := false
|
||||
store.Users.(*models.MockUsersService).Create_ = func(user *models.User) (bool, error) {
|
||||
if !normalizeDeepEqual(wantUser, user) {
|
||||
t.Errorf("wanted request for user %d but got %d", wantUser, user)
|
||||
}
|
||||
calledPost = true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
success, err := apiClient.Users.Create(wantUser)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledPost {
|
||||
t.Error("!calledPost")
|
||||
}
|
||||
if !success {
|
||||
t.Error("!success")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUser_List(t *testing.T) {
|
||||
setup()
|
||||
|
||||
wantUsers := []*models.User{newUser()}
|
||||
wantOpt := &models.UserListOptions{ListOptions: models.ListOptions{Page: 1, PerPage: 10}}
|
||||
|
||||
calledList := false
|
||||
store.Users.(*models.MockUsersService).List_ = func(opt *models.UserListOptions) ([]*models.User, error) {
|
||||
if !normalizeDeepEqual(wantOpt, opt) {
|
||||
t.Errorf("wanted options %d but got %d", wantOpt, opt)
|
||||
}
|
||||
calledList = true
|
||||
return wantUsers, nil
|
||||
}
|
||||
|
||||
users, err := apiClient.Users.List(wantOpt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledList {
|
||||
t.Error("!calledList")
|
||||
}
|
||||
|
||||
if !normalizeDeepEqual(&wantUsers, &users) {
|
||||
t.Errorf("got users %+v but wanted users %+v", users, wantUsers)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUser_Authenticate(t *testing.T) {
|
||||
setup()
|
||||
|
||||
test_user := newUser()
|
||||
test_user.Username = "test_user"
|
||||
|
||||
var user_session_want models.UserSession
|
||||
|
||||
calledAuthenticate := false
|
||||
store.Users.(*models.MockUsersService).Authenticate_ = func(username string, password string) (*models.UserSession, error) {
|
||||
calledAuthenticate = true
|
||||
user_session_want.AccessLevel = "read"
|
||||
user_session_want.Genus = "hymenobacter"
|
||||
|
||||
return &user_session_want, nil
|
||||
}
|
||||
|
||||
user_session, err := apiClient.Users.Authenticate(test_user.Username, "password")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledAuthenticate {
|
||||
t.Error("!calledAuthenticate")
|
||||
}
|
||||
|
||||
if !normalizeDeepEqual(user_session, &user_session_want) {
|
||||
t.Errorf("got session %+v but wanted session %+v", user_session, user_session_want)
|
||||
}
|
||||
}
|
Reference in a new issue