Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Fabian Vitt
good2go
Commits
80b57dce
Commit
80b57dce
authored
Jun 04, 2020
by
Can Maihofer
Browse files
refactored; rooms api is working
parent
13ae243d
Pipeline
#1848
failed with stages
in 55 seconds
Changes
16
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
api/rest/
router
.go
→
api/rest/
main
.go
View file @
80b57dce
...
...
@@ -9,7 +9,7 @@ import (
"github.com/gorilla/mux"
m
"git.coco.study/fvitt/good2go/api/rest/middlewares"
h
"git.coco.study/fvitt/good2go/api/rest/
sub
route
r
s"
h
"git.coco.study/fvitt/good2go/api/rest/routes"
)
func
getPort
()
string
{
...
...
@@ -31,7 +31,6 @@ func Init() {
r
.
Use
(
m
.
SentryHandler
)
// Register all the Routers
h
.
BuildingRouter
.
AttachRouter
(
r
)
h
.
AppointmentRouter
.
AttachRouter
(
r
)
h
.
RoomRouter
.
AttachRouter
(
r
)
h
.
HomeRouter
.
AttachRouter
(
r
)
...
...
api/rest/
sub
route
r
s/appointment_router.go
→
api/rest/routes/appointment_router.go
View file @
80b57dce
package
restapi
import
(
"encoding/json"
"fmt"
"net/http"
u
"git.coco.study/fvitt/good2go/api/rest/utils"
"git.coco.study/fvitt/good2go/internal/model"
s
"git.coco.study/fvitt/good2go/internal/services"
"github.com/gorilla/mux"
)
...
...
@@ -14,6 +19,26 @@ var (
)
func
createAppointment
(
res
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
type
appointmentDTO
struct
{
RoomID
int
}
var
r
model
.
Room
err
:=
json
.
NewDecoder
(
req
.
Body
)
.
Decode
(
&
r
)
if
err
!=
nil
{
http
.
Error
(
res
,
err
.
Error
(),
http
.
StatusBadRequest
)
return
}
room
,
err
:=
s
.
RoomService
.
CreateRoom
(
&
r
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
}
err
=
u
.
SendJSON
(
res
)
.
Encode
(
room
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
}
}
func
getAppointment
(
res
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
...
...
api/rest/
sub
route
r
s/building_router.go
→
api/rest/routes/building_router.go
.disabled
View file @
80b57dce
File moved
api/rest/
sub
route
r
s/home_router.go
→
api/rest/routes/home_router.go
View file @
80b57dce
File moved
api/rest/
sub
route
r
s/room_router.go
→
api/rest/routes/room_router.go
View file @
80b57dce
...
...
@@ -5,6 +5,7 @@ import (
"fmt"
"log"
"net/http"
"strconv"
u
"git.coco.study/fvitt/good2go/api/rest/utils"
"git.coco.study/fvitt/good2go/internal/model"
...
...
@@ -20,22 +21,18 @@ var (
)
func
createRoom
(
res
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
type
RoomDTO
struct
{
BuildingID
string
Room
model
.
Room
}
var
r
RoomDTO
var
r
model
.
Room
err
:=
json
.
NewDecoder
(
req
.
Body
)
.
Decode
(
&
r
)
if
err
!=
nil
{
http
.
Error
(
res
,
err
.
Error
(),
http
.
StatusBadRequest
)
return
}
room
,
err
:=
s
.
Building
Service
.
CreateRoom
(
r
.
BuildingID
,
&
r
.
Room
)
room
,
err
:=
s
.
Room
Service
.
CreateRoom
(
&
r
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
http
.
Error
(
res
,
err
.
Error
(),
http
.
StatusBadRequest
)
return
}
err
=
u
.
SendJSON
(
res
)
.
Encode
(
room
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
...
...
@@ -44,9 +41,11 @@ func createRoom(res http.ResponseWriter, req *http.Request) {
func
getRoom
(
res
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
room
ID
:=
mux
.
Vars
(
req
)[
"room
ID
"
]
room
NumberString
:=
mux
.
Vars
(
req
)[
"room
Number
"
]
room
,
roomErr
:=
s
.
BuildingService
.
GetRoom
(
roomID
)
roomNumber
,
_
:=
strconv
.
Atoi
(
roomNumberString
)
room
,
roomErr
:=
s
.
RoomService
.
GetRoomByNumber
(
roomNumber
)
if
roomErr
==
nil
{
u
.
SendJSON
(
res
)
.
Encode
(
room
)
...
...
@@ -57,7 +56,7 @@ func getRoom(res http.ResponseWriter, req *http.Request) {
func
getAllRooms
(
res
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
rooms
,
_
:=
s
.
Building
Service
.
GetAllRooms
()
rooms
:=
s
.
Room
Service
.
GetAllRooms
()
err
:=
u
.
SendJSON
(
res
)
.
Encode
(
rooms
)
if
err
!=
nil
{
...
...
@@ -67,7 +66,8 @@ func getAllRooms(res http.ResponseWriter, req *http.Request) {
func
updateRoom
(
res
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
roomID
:=
mux
.
Vars
(
req
)[
"roomID"
]
roomNumberString
:=
mux
.
Vars
(
req
)[
"roomNumber"
]
roomNumber
,
_
:=
strconv
.
Atoi
(
roomNumberString
)
var
r
model
.
Room
parseBodyErr
:=
json
.
NewDecoder
(
req
.
Body
)
.
Decode
(
&
r
)
...
...
@@ -76,7 +76,7 @@ func updateRoom(res http.ResponseWriter, req *http.Request) {
return
}
room
,
err
:=
s
.
Building
Service
.
UpdateRoomCapacity
(
room
ID
,
r
.
Capacity
)
room
,
err
:=
s
.
Room
Service
.
UpdateRoomCapacity
(
room
Number
,
r
.
Capacity
)
if
err
==
nil
{
err
:=
u
.
SendJSON
(
res
)
.
Encode
(
room
)
...
...
@@ -90,13 +90,15 @@ func updateRoom(res http.ResponseWriter, req *http.Request) {
func
deleteRoom
(
res
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
roomID
:=
mux
.
Vars
(
req
)[
"roomID"
]
roomNumberString
:=
mux
.
Vars
(
req
)[
"roomNumber"
]
roomNumber
,
_
:=
strconv
.
Atoi
(
roomNumberString
)
err
:=
s
.
Building
Service
.
DeleteRoom
(
room
ID
)
err
:=
s
.
Room
Service
.
DeleteRoom
(
room
Number
)
if
err
!=
nil
{
http
.
Error
(
res
,
err
.
Error
(),
http
.
StatusBadRequest
)
log
.
Fatal
(
err
)
}
res
.
Write
([]
byte
(
"deleted room with number "
+
roomNumberString
))
res
.
WriteHeader
(
http
.
StatusOK
)
}
...
...
@@ -104,19 +106,19 @@ func deleteRoom(res http.ResponseWriter, req *http.Request) {
func
(
a
roomRouter
)
AttachRouter
(
router
*
mux
.
Router
)
{
//todo addd single room route
r
:=
router
.
PathPrefix
(
"/rooms"
)
.
Subrouter
()
.
StrictSlash
(
true
)
multipleR
:=
router
.
PathPrefix
(
"/rooms"
)
.
Subrouter
()
.
StrictSlash
(
true
)
singleR
:=
router
.
PathPrefix
(
"/room"
)
.
Subrouter
()
.
StrictSlash
(
true
)
// CREATE
r
.
HandleFunc
(
"/"
,
createRoom
)
.
Methods
(
"POST"
)
singleR
.
HandleFunc
(
"/"
,
createRoom
)
.
Methods
(
"POST"
)
// READ
r
.
HandleFunc
(
"/{room
ID
}"
,
getRoom
)
.
Methods
(
"GET"
)
r
.
HandleFunc
(
"/"
,
getAllRooms
)
.
Methods
(
"GET"
)
singleR
.
HandleFunc
(
"/{room
Number
}"
,
getRoom
)
.
Methods
(
"GET"
)
multipleR
.
HandleFunc
(
"/"
,
getAllRooms
)
.
Methods
(
"GET"
)
// UPDATE
r
.
HandleFunc
(
"/{room
ID
}"
,
updateRoom
)
.
Methods
(
"PUT"
)
singleR
.
HandleFunc
(
"/{room
Number
}"
,
updateRoom
)
.
Methods
(
"PUT"
)
// DELETE
r
.
HandleFunc
(
"/{room
ID
}"
,
deleteRoom
)
.
Methods
(
"DELETE"
)
singleR
.
HandleFunc
(
"/{room
Number
}"
,
deleteRoom
)
.
Methods
(
"DELETE"
)
}
cmd/main.go
View file @
80b57dce
...
...
@@ -10,6 +10,9 @@ import (
)
func
main
()
{
log
.
SetFlags
(
log
.
LstdFlags
|
log
.
Lshortfile
)
// Sentry
initSentry
()
// Flush buffered events before the program terminates.
...
...
database/init.go
View file @
80b57dce
...
...
@@ -20,34 +20,13 @@ func Disconnect() {
func
CreateSampleData
()
{
// Get all buildings
buildings
,
err
:=
ownMongo
.
BuildingRepo
.
GetAllBuildings
()
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
var
building
*
model
.
Building
// Only create sample data if no sample data exists
if
len
(
buildings
)
==
0
{
// Add Building
building
=
&
model
.
Building
{}
building
,
err
:=
services
.
BuildingService
.
CreateBuilding
(
building
.
New
(
"08:00"
,
"10h"
,
[]
string
{
"mon"
,
"tue"
,
"wed"
,
"thu"
,
"fri"
,
"sat"
}))
if
err
!=
nil
{
log
.
Fatal
(
err
)
log
.
Print
(
building
)
}
}
else
{
building
=
buildings
[
0
]
}
rooms
:=
building
.
GetRooms
()
rooms
:=
ownMongo
.
RoomRepo
.
GetAllRooms
()
log
.
Print
(
"INIT"
,
rooms
,
len
(
rooms
))
if
len
(
rooms
)
==
0
{
services
.
Building
Service
.
CreateRoom
(
building
.
ID
.
Hex
(),
&
model
.
Room
{
services
.
Room
Service
.
CreateRoom
(
&
model
.
Room
{
Number
:
420
,
Capacity
:
69
,
})
...
...
database/mongo/repositories/building_repository.go
→
database/mongo/repositories/building_repository.go
.disabled
View file @
80b57dce
File moved
database/mongo/repositories/room_repository.go
View file @
80b57dce
...
...
@@ -17,33 +17,10 @@ import (
type
RoomRepository
interface
{
CreateRoom
(
r
*
model
.
Room
)
(
*
model
.
Room
,
error
)
UpdateRoom
(
r
*
model
.
Room
)
GetRoom
(
document
interface
{})
(
room
*
model
.
Room
,
err
error
)
GetAllRooms
()
[]
model
.
Room
ConnectTo
(
c
*
mongo
.
Collection
)
*
Repository
}
// func (repo *Repository) findByRoomNumber(roomNumber int) (*model.Room, error) {
// ctx, cancel := utils.CreateTimeoutCTX(5 * time.Second)
// defer cancel()
// // Find
// result, err := repo.Col.Find(ctx, bson.M{"number": roomNumber})
// if err != nil {
// return &model.Room{}, err
// }
// // Decode
// var r model.Room
// err = result.Decode(&r)
// if err != nil {
// return &model.Room{}, err
// }
// return &r, nil
// }
func
(
repo
*
Repository
)
GetRoomByID
(
roomID
string
)
(
*
model
.
Room
,
error
)
{
id
,
err
:=
primitive
.
ObjectIDFromHex
(
roomID
)
...
...
@@ -79,10 +56,7 @@ func (repo *Repository) insertOne(document interface{}) (*model.Room, error) {
}
// Find
result
,
err
:=
repo
.
Col
.
Find
(
ctx
,
bson
.
M
{
"_id"
:
insertResult
.
InsertedID
})
if
err
!=
nil
{
return
&
model
.
Room
{},
err
}
result
:=
repo
.
Col
.
FindOne
(
ctx
,
bson
.
M
{
"_id"
:
insertResult
.
InsertedID
})
// Decode
var
r
model
.
Room
...
...
@@ -106,10 +80,7 @@ func (repo *Repository) updateOne(document interface{}) (*model.Room, error) {
}
// Find
result
,
err
:=
repo
.
Col
.
Find
(
ctx
,
bson
.
M
{
"_id"
:
insertedResult
.
UpsertedID
})
if
err
!=
nil
{
return
&
model
.
Room
{},
err
}
result
:=
repo
.
Col
.
FindOne
(
ctx
,
bson
.
M
{
"_id"
:
insertedResult
.
UpsertedID
})
// Decode
var
r
model
.
Room
...
...
@@ -123,36 +94,13 @@ func (repo *Repository) updateOne(document interface{}) (*model.Room, error) {
}
func
(
repo
*
Repository
)
findOne
(
document
interface
{})
(
*
model
.
Room
,
error
)
{
ctx
,
cancel
:=
utils
.
CreateTimeoutCTX
(
5
*
time
.
Second
)
defer
cancel
()
result
:=
repo
.
Col
.
FindOne
(
ctx
,
document
)
var
room
model
.
Room
err
:=
result
.
Decode
(
&
room
)
return
&
room
,
err
}
func
(
repo
*
Repository
)
deleteByID
(
id
primitive
.
ObjectID
)
error
{
ctx
,
cancel
:=
utils
.
CreateTimeoutCTX
(
5
*
time
.
Second
)
defer
cancel
()
_
,
err
:=
repo
.
Col
.
DeleteOne
(
ctx
,
bson
.
M
{
"_id"
:
id
})
return
err
}
func
(
repo
*
Repository
)
CreateRoom
(
r
*
model
.
Room
)
(
*
model
.
Room
,
error
)
{
log
.
Print
(
"Create room "
,
r
.
Number
)
//Check if room with same room number exists
existingRoom
,
err
:=
repo
.
GetRoom
(
bson
.
M
{
"number"
:
r
.
Number
})
if
err
==
nil
{
t
:=
strconv
.
Itoa
(
r
.
Number
)
return
existingRoom
,
errors
.
New
(
"Room with number "
+
t
+
" already exists"
)
existingRoom
,
err
:=
repo
.
GetRoomByNumber
(
r
.
Number
)
if
existingRoom
!=
nil
{
return
existingRoom
,
errors
.
New
(
"Room with number "
+
strconv
.
Itoa
(
r
.
Number
)
+
" already exists"
)
}
room
,
err
:=
repo
.
insertOne
(
bson
.
M
{
...
...
@@ -174,13 +122,35 @@ func (repo *Repository) UpdateRoom(r *model.Room) (*model.Room, error) {
return
repo
.
updateOne
(
r
)
}
func
(
repo
*
Repository
)
GetRoom
(
document
interface
{})
(
room
*
model
.
Room
,
err
error
)
{
log
.
Print
(
"Finding room by "
,
document
)
return
repo
.
findOne
(
document
)
func
(
repo
*
Repository
)
DeleteRoom
(
roomNumber
int
)
(
err
error
)
{
ctx
,
cancel
:=
utils
.
CreateTimeoutCTX
(
5
*
time
.
Second
)
defer
cancel
()
_
,
err
=
repo
.
Col
.
DeleteOne
(
ctx
,
bson
.
M
{
"number"
:
roomNumber
})
if
err
!=
nil
{
return
err
}
return
nil
}
func
(
repo
*
Repository
)
DeleteRoom
(
roomID
string
)
(
room
*
model
.
Room
,
err
error
)
{
return
repo
.
GetRoomByID
(
roomID
)
func
(
repo
*
Repository
)
GetRoomByNumber
(
roomNumber
int
)
(
*
model
.
Room
,
error
)
{
ctx
,
cancel
:=
utils
.
CreateTimeoutCTX
(
5
*
time
.
Second
)
defer
cancel
()
// Find
result
:=
repo
.
Col
.
FindOne
(
ctx
,
bson
.
M
{
"number"
:
roomNumber
})
// Decode
var
r
model
.
Room
err
:=
result
.
Decode
(
&
r
)
if
err
!=
nil
{
return
&
model
.
Room
{},
err
}
return
&
r
,
nil
}
func
(
repo
*
Repository
)
GetAllRooms
()
[]
*
model
.
Room
{
...
...
database/mongo/repositories/room_repository_test.go
View file @
80b57dce
//
package repositories
package
repositories
//
import (
//
"fmt"
//
"testing"
import
(
"fmt"
"testing"
//
"git.coco.study/fvitt/good2go/internal/model"
//
"go.mongodb.org/mongo-driver/bson"
//
"go.mongodb.org/mongo-driver/mongo"
//
)
"git.coco.study/fvitt/good2go/internal/model"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
//
var repo Repository
var
repo
Repository
//
func TestMain(m *testing.M) {
func
TestMain
(
m
*
testing
.
M
)
{
//
// Mock the collection
//
repo = Repository{Col: &mongo.Collection{}}
// Mock the collection
repo
=
Repository
{
Col
:
&
mongo
.
Collection
{}}
//
}
}
//
func Test_roomRepository_CreateRoom(t *testing.T) {
func
Test_roomRepository_CreateRoom
(
t
*
testing
.
T
)
{
//
_, err := repo.CreateRoom(&model.Room{Number: 100, Capacity: 10})
//
if err != nil {
//
fmt.Println(err)
//
}
_
,
err
:=
repo
.
CreateRoom
(
&
model
.
Room
{
Number
:
100
,
Capacity
:
10
})
if
err
!=
nil
{
fmt
.
Println
(
err
)
}
//
room, err := repo.
findByRoomNumber
(100)
//
if err != nil {
//
t.Error(err)
//
}
room
,
err
:=
repo
.
GetRoomByID
(
100
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
//
if room.Number != 100 {
//
t.Error("Room was not created with the correct roomNumber")
//
}
if
room
.
Number
!=
100
{
t
.
Error
(
"Room was not created with the correct roomNumber"
)
}
//
}
}
//
func Test_roomRepository_UpdateRoom(t *testing.T) {
func
Test_roomRepository_UpdateRoom
(
t
*
testing
.
T
)
{
//
repo.UpdateRoom(&model.Room{
//
Number: 100,
//
Capacity: 22,
//
})
repo
.
UpdateRoom
(
&
model
.
Room
{
Number
:
100
,
Capacity
:
22
,
})
//
room, err := repo.
findByRoomNumber
(100)
//
if err != nil {
//
t.Error(err)
//
}
room
,
err
:=
repo
.
GetRoomByID
(
100
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
//
if room.Capacity != 22 {
//
t.Error("Room did not have the updated capacity")
//
}
if
room
.
Capacity
!=
22
{
t
.
Error
(
"Room did not have the updated capacity"
)
}
//
}
}
//
func Test_roomRepository_GetRoom(t *testing.T) {
func
Test_roomRepository_GetRoom
(
t
*
testing
.
T
)
{
//
_, err := repo.CreateRoom(&model.Room{Number: 420, Capacity: 22})
//
if err != nil {
//
fmt.Println(err)
//
panic(err)
//
}
//
_, err = repo.GetRoom(bson.M{
//
"number": 420,
//
})
_
,
err
:=
repo
.
CreateRoom
(
&
model
.
Room
{
Number
:
420
,
Capacity
:
22
})
if
err
!=
nil
{
fmt
.
Println
(
err
)
panic
(
err
)
}
_
,
err
=
repo
.
GetRoom
(
bson
.
M
{
"number"
:
420
,
})
//
if err != nil {
//
t.Error(err)
//
}
if
err
!=
nil
{
t
.
Error
(
err
)
}
//
}
}
//
func Test_roomRepository_GetAllRooms(t *testing.T) {
func
Test_roomRepository_GetAllRooms
(
t
*
testing
.
T
)
{
//
rooms := repo.GetAllRooms()
rooms
:=
repo
.
GetAllRooms
()
//
t.Log(rooms)
t
.
Log
(
rooms
)
//
}
}
internal/model/building_test.go
deleted
100644 → 0
View file @
13ae243d
package
model
import
(
"fmt"
"testing"
)
func
TestBuilding_New
(
t
*
testing
.
T
)
{
building1
:=
newBuilding
()
fmt
.
Println
(
building1
)
if
building1
.
OpeningHour
.
Hour
()
!=
8
{
t
.
Error
(
"Opening: Expected 8, got: "
,
building1
.
OpeningHour
.
Hour
())
}
if
building1
.
ClosingHour
.
Hour
()
!=
18
{
t
.
Error
(
"Closing: Expected 18, got: "
,
building1
.
ClosingHour
.
Hour
())
}
if
!
building1
.
ClosingHour
.
After
(
building1
.
OpeningHour
)
{
t
.
Error
(
"Closing Hour not after opening hour
\n
"
,
building1
.
ClosingHour
,
"
\n
"
,
building1
.
OpeningHour
)
}
}
func
TestBuilding_CreateRoom
(
t
*
testing
.
T
)
{
building1
:=
newBuilding
()
const
roomNumber
int
=
520
const
capacity
int
=
35
building1
.
CreateRoom
(
roomNumber
,
capacity
)
if
len
(
building1
.
Rooms
)
!=
1
{
t
.
Error
(
"
\n\n
Rooms slice still empty
\n
Did not add room to slide
\n
len: "
,
len
(
building1
.
Rooms
))
}
got
:=
building1
.
Rooms
[
0
]
if
got
.
Number
!=
roomNumber
{
t
.
Error
(
"
\n
Room Number does not match
\n
Expected: "
,
roomNumber
,
"
\n
got: "
,
got
.
Number
)
}
if
got
.
Capacity
!=
capacity
{
t
.
Error
(
"
\n
Room Capacity does not match
\n
Expected: "
,
capacity
,
"
\n
got: "
,
got
.
Capacity
)
}
}
func
TestBuilding_DeleteRoom
(
t
*
testing
.
T
)
{
building1
:=
newBuilding
()
// Add one – remove one
building1
.
CreateRoom
(
200
,
50
)
building1
.
DeleteRoom
(
200
)
if
len
(
building1
.
Rooms
)
>
0
{
t
.
Error
(
"Room not deleted"
)
}
// Add three – remove one
building1
.
CreateRoom
(
200
,
50
)
building1
.
CreateRoom
(
250
,
40
)
building1
.
CreateRoom
(
260
,
30
)
building1
.
DeleteRoom
(
250
)
for
_
,
room
:=
range
building1
.
Rooms
{
if
room
.
Number
==
250
{
t
.
Error
(
"Room not deleted: "
)
}
}
}
func
TestBuilding_GetRooms
(
t
*
testing
.
T
)
{
building1
:=
newBuilding
()
_
,
err
:=
building1
.
CreateRoom
(
200
,
20
)
_
,
err
=
building1
.
CreateRoom
(
210
,
40
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
rooms
:=
building1
.
GetRooms
()
if
len
(
rooms
)
!=
2
{
t
.
Error
(
"did not get all rooms, expected 2, got: "
,
rooms
)
}
}
func
TestBuilding_GetRoomByNo
(
t
*
testing
.
T
)
{
building1
:=
newBuilding
()
_
,
err
:=
building1
.
CreateRoom
(
200
,
50
)
_
,
err
=
building1
.
CreateRoom
(
250
,
40
)
room
,
err
:=
building1
.
GetRoomByNo
(
200
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
if
room
.
Number
!=
200
{
t
.
Error
(
"Wrong room came back, expected 200, got: "
,
room
.
Number
)
}
// room not found should return error
room
,
err
=
building1
.
GetRoomByNo
(
100
)
if
err
==
nil
{
t
.
Error
(
"no Error thrown, got: "
,
err
)
}