Adds Handlers and Tests for devicetypes, devices, and files
This commit is contained in:
18
app.go
18
app.go
@@ -67,6 +67,24 @@ func (a *App) initializeRoutes() {
|
||||
a.Router.HandleFunc("/api/v1/dataType/{id:[0-9]+}", a.updateDataType).Methods("PUT")
|
||||
a.Router.HandleFunc("/api/v1/dataType/{id:[0-9]+}", a.deleteDataType).Methods("DELETE")
|
||||
|
||||
a.Router.HandleFunc("/api/v1/deviceTypes", a.getDeviceTypes).Methods("GET")
|
||||
a.Router.HandleFunc("/api/v1/deviceType", a.createDeviceType).Methods("POST")
|
||||
a.Router.HandleFunc("/api/v1/deviceType/{id:[0-9]+}", a.getDeviceType).Methods("GET")
|
||||
a.Router.HandleFunc("/api/v1/deviceType/{id:[0-9]+}", a.updateDeviceType).Methods("PUT")
|
||||
a.Router.HandleFunc("/api/v1/deviceType/{id:[0-9]+}", a.deleteDeviceType).Methods("DELETE")
|
||||
|
||||
a.Router.HandleFunc("/api/v1/devices", a.getDevices).Methods("GET")
|
||||
a.Router.HandleFunc("/api/v1/device", a.createDevice).Methods("POST")
|
||||
a.Router.HandleFunc("/api/v1/device/{id:[0-9]+}", a.getDevice).Methods("GET")
|
||||
a.Router.HandleFunc("/api/v1/device/{id:[0-9]+}", a.updateDevice).Methods("PUT")
|
||||
a.Router.HandleFunc("/api/v1/device/{id:[0-9]+}", a.deleteDevice).Methods("DELETE")
|
||||
|
||||
a.Router.HandleFunc("/api/v1/files", a.getFiles).Methods("GET")
|
||||
a.Router.HandleFunc("/api/v1/file", a.createFile).Methods("POST")
|
||||
a.Router.HandleFunc("/api/v1/file/{id:[0-9]+}", a.getFile).Methods("GET")
|
||||
a.Router.HandleFunc("/api/v1/file/{id:[0-9]+}", a.updateFile).Methods("PUT")
|
||||
a.Router.HandleFunc("/api/v1/file/{id:[0-9]+}", a.deleteFile).Methods("DELETE")
|
||||
|
||||
//Serve public files
|
||||
var dir string
|
||||
flag.StringVar(&dir, "dir", "./public", "the directory to serve files from. Defaults to the current dir")
|
||||
|
||||
110
handler_device.go
Normal file
110
handler_device.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func (a *App) getDevice(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid config ID")
|
||||
return
|
||||
}
|
||||
|
||||
c := Device{ID: id}
|
||||
if err := c.getDevice(a.DB); err != nil {
|
||||
switch err {
|
||||
case sql.ErrNoRows:
|
||||
respondWithError(w, http.StatusNotFound, "Device not found")
|
||||
default:
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusOK, c)
|
||||
}
|
||||
|
||||
func (a *App) getDevices(w http.ResponseWriter, r *http.Request) {
|
||||
count, _ := strconv.Atoi(r.FormValue("count"))
|
||||
start, _ := strconv.Atoi(r.FormValue("start"))
|
||||
|
||||
if count > 10 || count < 1 {
|
||||
count = 10
|
||||
}
|
||||
if start < 0 {
|
||||
start = 0
|
||||
}
|
||||
|
||||
configs, err := getDevices(a.DB, start, count)
|
||||
if err != nil {
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusOK, configs)
|
||||
}
|
||||
|
||||
func (a *App) createDevice(w http.ResponseWriter, r *http.Request) {
|
||||
var c Device
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
if err := decoder.Decode(&c); err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid request payload")
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
if err := c.createDevice(a.DB); err != nil {
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusCreated, c)
|
||||
}
|
||||
|
||||
func (a *App) updateDevice(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid config ID")
|
||||
return
|
||||
}
|
||||
|
||||
var c Device
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
if err := decoder.Decode(&c); err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid request payload")
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
c.ID = id
|
||||
|
||||
if err := c.updateDevice(a.DB); err != nil {
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusOK, c)
|
||||
}
|
||||
|
||||
func (a *App) deleteDevice(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid Device ID")
|
||||
return
|
||||
}
|
||||
|
||||
c := Device{ID: id}
|
||||
if err := c.deleteDevice(a.DB); err != nil {
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusOK, map[string]string{"result": "success"})
|
||||
}
|
||||
110
handler_devicetype.go
Normal file
110
handler_devicetype.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func (a *App) getDeviceType(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid config ID")
|
||||
return
|
||||
}
|
||||
|
||||
c := DeviceType{ID: id}
|
||||
if err := c.getDeviceType(a.DB); err != nil {
|
||||
switch err {
|
||||
case sql.ErrNoRows:
|
||||
respondWithError(w, http.StatusNotFound, "DeviceType not found")
|
||||
default:
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusOK, c)
|
||||
}
|
||||
|
||||
func (a *App) getDeviceTypes(w http.ResponseWriter, r *http.Request) {
|
||||
count, _ := strconv.Atoi(r.FormValue("count"))
|
||||
start, _ := strconv.Atoi(r.FormValue("start"))
|
||||
|
||||
if count > 10 || count < 1 {
|
||||
count = 10
|
||||
}
|
||||
if start < 0 {
|
||||
start = 0
|
||||
}
|
||||
|
||||
configs, err := getDeviceTypes(a.DB, start, count)
|
||||
if err != nil {
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusOK, configs)
|
||||
}
|
||||
|
||||
func (a *App) createDeviceType(w http.ResponseWriter, r *http.Request) {
|
||||
var c DeviceType
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
if err := decoder.Decode(&c); err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid request payload")
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
if err := c.createDeviceType(a.DB); err != nil {
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusCreated, c)
|
||||
}
|
||||
|
||||
func (a *App) updateDeviceType(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid config ID")
|
||||
return
|
||||
}
|
||||
|
||||
var c DeviceType
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
if err := decoder.Decode(&c); err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid request payload")
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
c.ID = id
|
||||
|
||||
if err := c.updateDeviceType(a.DB); err != nil {
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusOK, c)
|
||||
}
|
||||
|
||||
func (a *App) deleteDeviceType(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid DeviceType ID")
|
||||
return
|
||||
}
|
||||
|
||||
c := DeviceType{ID: id}
|
||||
if err := c.deleteDeviceType(a.DB); err != nil {
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusOK, map[string]string{"result": "success"})
|
||||
}
|
||||
110
handler_file.go
Normal file
110
handler_file.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func (a *App) getFile(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid file ID")
|
||||
return
|
||||
}
|
||||
|
||||
c := File{ID: id}
|
||||
if err := c.getFile(a.DB); err != nil {
|
||||
switch err {
|
||||
case sql.ErrNoRows:
|
||||
respondWithError(w, http.StatusNotFound, "File not found")
|
||||
default:
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusOK, c)
|
||||
}
|
||||
|
||||
func (a *App) getFiles(w http.ResponseWriter, r *http.Request) {
|
||||
count, _ := strconv.Atoi(r.FormValue("count"))
|
||||
start, _ := strconv.Atoi(r.FormValue("start"))
|
||||
|
||||
if count > 10 || count < 1 {
|
||||
count = 10
|
||||
}
|
||||
if start < 0 {
|
||||
start = 0
|
||||
}
|
||||
|
||||
files, err := getFiles(a.DB, start, count)
|
||||
if err != nil {
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusOK, files)
|
||||
}
|
||||
|
||||
func (a *App) createFile(w http.ResponseWriter, r *http.Request) {
|
||||
var c File
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
if err := decoder.Decode(&c); err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid request payload")
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
if err := c.createFile(a.DB); err != nil {
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusCreated, c)
|
||||
}
|
||||
|
||||
func (a *App) updateFile(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid file ID")
|
||||
return
|
||||
}
|
||||
|
||||
var c File
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
if err := decoder.Decode(&c); err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid request payload")
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
c.ID = id
|
||||
|
||||
if err := c.updateFile(a.DB); err != nil {
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusOK, c)
|
||||
}
|
||||
|
||||
func (a *App) deleteFile(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
respondWithError(w, http.StatusBadRequest, "Invalid File ID")
|
||||
return
|
||||
}
|
||||
|
||||
c := File{ID: id}
|
||||
if err := c.deleteFile(a.DB); err != nil {
|
||||
respondWithError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
respondWithJSON(w, http.StatusOK, map[string]string{"result": "success"})
|
||||
}
|
||||
8
main.go
8
main.go
@@ -10,5 +10,13 @@ func main() {
|
||||
os.Getenv("APP_DB_PASSWORD"),
|
||||
os.Getenv("APP_DB_NAME"))
|
||||
|
||||
ensureConfigTableExists(a.DB)
|
||||
ensureDataTypeTableExists(a.DB)
|
||||
ensureDeviceTypeTableExists(a.DB)
|
||||
ensureDeviceTableExists(a.DB)
|
||||
ensureFileTableExists(a.DB)
|
||||
|
||||
seedDeviceTypeData(a.DB)
|
||||
|
||||
a.Run(":8080")
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -17,6 +18,22 @@ type Config struct {
|
||||
// Configs : a list of Config items
|
||||
type Configs []Config
|
||||
|
||||
const configTableCreationQuery = `CREATE TABLE IF NOT EXISTS configs (
|
||||
id int(10) unsigned AUTO_INCREMENT,
|
||||
parameter varchar(255),
|
||||
val varchar(255),
|
||||
createdAt datetime,
|
||||
updatedAt datetime,
|
||||
UNIQUE KEY parameter (parameter),
|
||||
PRIMARY KEY (id)
|
||||
)`
|
||||
|
||||
func ensureConfigTableExists(db *sql.DB) {
|
||||
if _, err := db.Exec(configTableCreationQuery); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// getConfig : used during GET command
|
||||
func (c *Config) getConfig(db *sql.DB) error {
|
||||
return db.QueryRow("SELECT parameter, val, createdAt, updatedAt FROM configs WHERE id=?", c.ID).Scan(&c.Parameter, &c.Val, &c.CreatedAt, &c.UpdatedAt)
|
||||
@@ -68,7 +85,7 @@ func getConfigs(db *sql.DB, start, count int) (Configs, error) {
|
||||
|
||||
for rows.Next() {
|
||||
var c Config
|
||||
if err := rows.Scan(&c.ID, &c.Parameter, &c.CreatedAt, &c.UpdatedAt); err != nil {
|
||||
if err := rows.Scan(&c.ID, &c.Parameter, &c.Val, &c.CreatedAt, &c.UpdatedAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configs = append(configs, c)
|
||||
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -17,6 +18,22 @@ type DataType struct {
|
||||
// DataTypes : a list of DataType items
|
||||
type DataTypes []DataType
|
||||
|
||||
const dataTypeTableCreationQuery = `CREATE TABLE IF NOT EXISTS dataTypes (
|
||||
id int(10) unsigned AUTO_INCREMENT,
|
||||
dataType varchar(255),
|
||||
plcType varchar(255),
|
||||
createdAt datetime,
|
||||
updatedAt datetime,
|
||||
UNIQUE KEY dataType (dataType),
|
||||
PRIMARY KEY (id)
|
||||
)`
|
||||
|
||||
func ensureDataTypeTableExists(db *sql.DB) {
|
||||
if _, err := db.Exec(dataTypeTableCreationQuery); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// getDataType : used during GET command
|
||||
func (c *DataType) getDataType(db *sql.DB) error {
|
||||
return db.QueryRow("SELECT dataType, plcType, createdAt, updatedAt FROM dataTypes WHERE id=?", c.ID).Scan(&c.DataType, &c.PlcType, &c.CreatedAt, &c.UpdatedAt)
|
||||
@@ -68,7 +85,7 @@ func getDataTypes(db *sql.DB, start, count int) (DataTypes, error) {
|
||||
|
||||
for rows.Next() {
|
||||
var c DataType
|
||||
if err := rows.Scan(&c.ID, &c.DataType, &c.CreatedAt, &c.UpdatedAt); err != nil {
|
||||
if err := rows.Scan(&c.ID, &c.DataType, &c.PlcType, &c.CreatedAt, &c.UpdatedAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dataTypes = append(dataTypes, c)
|
||||
|
||||
125
model_device.go
125
model_device.go
@@ -1,15 +1,128 @@
|
||||
package main
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Device : holds information about a specific Device
|
||||
type Device struct {
|
||||
ID int `json:"id"`
|
||||
DeviceType DeviceType `json:"deviceType"`
|
||||
Address string `json:"address"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
DeviceTypeID int `json:"deviceTypeId"`
|
||||
DeviceType DeviceType `json:"deviceType"`
|
||||
Address string `json:"address"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
// Devices : a list of Device items
|
||||
type Devices []Device
|
||||
|
||||
const deviceTableCreationQuery = `CREATE TABLE IF NOT EXISTS devices (
|
||||
id int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
name varchar(255),
|
||||
deviceTypeId int(10) unsigned NOT NULL,
|
||||
address varchar(255),
|
||||
createdAt datetime,
|
||||
updatedAt datetime,
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT fk_devicetype FOREIGN KEY (deviceTypeId) REFERENCES deviceTypes(id)
|
||||
);`
|
||||
|
||||
func ensureDeviceTableExists(db *sql.DB) {
|
||||
if _, err := db.Exec(deviceTableCreationQuery); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// getDevice : used during GET command
|
||||
func (d *Device) getDevice(db *sql.DB) error {
|
||||
sqlQuery := `SELECT
|
||||
devices.name,
|
||||
devices.deviceTypeId,
|
||||
deviceTypes.id,
|
||||
deviceTypes.name,
|
||||
deviceTypes.createdAt,
|
||||
deviceTypes.updatedAt,
|
||||
devices.address,
|
||||
devices.createdAt,
|
||||
devices.updatedAt
|
||||
FROM devices
|
||||
LEFT JOIN deviceTypes
|
||||
ON devices.deviceTypeId = deviceTypes.id WHERE devices.id=?`
|
||||
return db.QueryRow(sqlQuery, d.ID).Scan(&d.Name, &d.DeviceTypeID, &d.DeviceType.ID, &d.DeviceType.Name, &d.DeviceType.CreatedAt, &d.DeviceType.UpdatedAt, &d.Address, &d.CreatedAt, &d.UpdatedAt)
|
||||
}
|
||||
|
||||
// updateDevice : used during PUT command
|
||||
func (d *Device) updateDevice(db *sql.DB) error {
|
||||
updStmt, updErr := db.Prepare("UPDATE devices SET name=?, deviceTypeId=?, address=?, updatedAt=? WHERE id=?")
|
||||
if updErr != nil {
|
||||
panic(updErr.Error()) // proper error handling instead of panic in your app
|
||||
}
|
||||
defer updStmt.Close() // Close the statement when we leave main() / the program terminates
|
||||
|
||||
_, err := updStmt.Exec(d.Name, d.DeviceTypeID, d.Address, time.Now(), d.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
// deleteDevice : used during DELETE command
|
||||
func (d *Device) deleteDevice(db *sql.DB) error {
|
||||
_, err := db.Exec("DELETE FROM devices WHERE id=?", d.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
// createDevice : used during PUSH command
|
||||
func (d *Device) createDevice(db *sql.DB) error {
|
||||
stmtIns, insErr := db.Prepare("INSERT INTO devices (name, deviceTypeId, address, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?);")
|
||||
if insErr != nil {
|
||||
panic(insErr.Error()) // proper error handling instead of panic in your app
|
||||
}
|
||||
defer stmtIns.Close() // Close the statement when we leave main() / the program terminates
|
||||
|
||||
_, err := stmtIns.Exec(d.Name, d.DeviceTypeID, d.Address, time.Now(), time.Now())
|
||||
return err
|
||||
}
|
||||
|
||||
// getDevices : used during GET command for all
|
||||
func getDevices(db *sql.DB, start, count int) (Devices, error) {
|
||||
sqlQuery := `SELECT
|
||||
devices.id,
|
||||
devices.name,
|
||||
devices.deviceTypeId,
|
||||
deviceTypes.id,
|
||||
deviceTypes.name,
|
||||
deviceTypes.createdAt,
|
||||
deviceTypes.updatedAt,
|
||||
devices.address,
|
||||
devices.createdAt,
|
||||
devices.updatedAt
|
||||
FROM devices LEFT JOIN deviceTypes ON devices.deviceTypeId = deviceTypes.id LIMIT ? OFFSET ?;`
|
||||
|
||||
getStmt, prepErr := db.Prepare(sqlQuery)
|
||||
if prepErr != nil {
|
||||
panic(prepErr.Error()) // proper error handling instead of panic in your app
|
||||
}
|
||||
defer getStmt.Close() // Close the statement when we leave main() / the program terminates
|
||||
|
||||
rows, err := getStmt.Query(count, start)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
devices := Devices{}
|
||||
|
||||
for rows.Next() {
|
||||
var d Device
|
||||
if err := rows.Scan(&d.ID, &d.Name, &d.DeviceTypeID, &d.DeviceType.ID, &d.DeviceType.Name, &d.DeviceType.CreatedAt, &d.DeviceType.UpdatedAt, &d.Address, &d.CreatedAt, &d.UpdatedAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
devices = append(devices, d)
|
||||
}
|
||||
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package main
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DeviceType : holds information about a specific DeviceType
|
||||
type DeviceType struct {
|
||||
@@ -12,3 +16,92 @@ type DeviceType struct {
|
||||
|
||||
// DeviceTypes : a list of DeviceType items
|
||||
type DeviceTypes []DeviceType
|
||||
|
||||
const deviceTypeTableCreationQuery = `CREATE TABLE IF NOT EXISTS deviceTypes (
|
||||
id int(10) unsigned AUTO_INCREMENT,
|
||||
name varchar(255),
|
||||
createdAt datetime,
|
||||
updatedAt datetime,
|
||||
UNIQUE KEY name (name),
|
||||
PRIMARY KEY (id)
|
||||
)`
|
||||
|
||||
func ensureDeviceTypeTableExists(db *sql.DB) {
|
||||
if _, err := db.Exec(deviceTypeTableCreationQuery); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func seedDeviceTypeData(db *sql.DB) {
|
||||
sqlQuery := `INSERT INTO deviceTypes VALUES
|
||||
(1,'CLX','2016-10-13 15:05:32','2016-10-13 15:05:32'),
|
||||
(2,'Micro800','2016-10-13 15:05:32','2016-10-13 15:05:32');`
|
||||
insStmt, insErr := db.Prepare(sqlQuery)
|
||||
|
||||
if insErr != nil {
|
||||
panic(insErr.Error()) // proper error handling instead of panic in your app
|
||||
}
|
||||
defer insStmt.Close() // Close the statement when we leave main() / the program terminates
|
||||
|
||||
insStmt.Exec()
|
||||
}
|
||||
|
||||
// getDeviceType : used during GET command
|
||||
func (c *DeviceType) getDeviceType(db *sql.DB) error {
|
||||
return db.QueryRow("SELECT name, createdAt, updatedAt FROM deviceTypes WHERE id=?", c.ID).Scan(&c.Name, &c.CreatedAt, &c.UpdatedAt)
|
||||
}
|
||||
|
||||
// updateDeviceType : used during PUT command
|
||||
func (c *DeviceType) updateDeviceType(db *sql.DB) error {
|
||||
updStmt, updErr := db.Prepare("UPDATE deviceTypes SET name=?, updatedAt=? WHERE id=?")
|
||||
if updErr != nil {
|
||||
panic(updErr.Error()) // proper error handling instead of panic in your app
|
||||
}
|
||||
defer updStmt.Close() // Close the statement when we leave main() / the program terminates
|
||||
|
||||
_, err := updStmt.Exec(c.Name, time.Now(), c.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
// deleteDeviceType : used during DELETE command
|
||||
func (c *DeviceType) deleteDeviceType(db *sql.DB) error {
|
||||
_, err := db.Exec("DELETE FROM deviceTypes WHERE id=?", c.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
// createDeviceType : used during PUSH command
|
||||
func (c *DeviceType) createDeviceType(db *sql.DB) error {
|
||||
stmtIns, insErr := db.Prepare("INSERT INTO deviceTypes (name, createdAt, updatedAt) VALUES (?, ?, ?);")
|
||||
if insErr != nil {
|
||||
panic(insErr.Error()) // proper error handling instead of panic in your app
|
||||
}
|
||||
defer stmtIns.Close() // Close the statement when we leave main() / the program terminates
|
||||
|
||||
_, err := stmtIns.Exec(c.Name, time.Now(), time.Now())
|
||||
return err
|
||||
}
|
||||
|
||||
// getDeviceTypes : used during GET command for all
|
||||
func getDeviceTypes(db *sql.DB, start, count int) (DeviceTypes, error) {
|
||||
rows, err := db.Query(
|
||||
"SELECT id, name, createdAt, updatedAt FROM deviceTypes LIMIT ? OFFSET ?",
|
||||
count, start)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
deviceTypes := DeviceTypes{}
|
||||
|
||||
for rows.Next() {
|
||||
var c DeviceType
|
||||
if err := rows.Scan(&c.ID, &c.Name, &c.CreatedAt, &c.UpdatedAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
deviceTypes = append(deviceTypes, c)
|
||||
}
|
||||
|
||||
return deviceTypes, nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package main
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
// File : holds information about a specific File
|
||||
type File struct {
|
||||
@@ -14,3 +18,86 @@ type File struct {
|
||||
|
||||
// Files : a list of File items
|
||||
type Files []File
|
||||
|
||||
const fileTableCreationQuery = `CREATE TABLE IF NOT EXISTS files (
|
||||
id int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
name varchar(255),
|
||||
location varchar(255),
|
||||
description varchar(255),
|
||||
createdAt datetime,
|
||||
updatedAt datetime,
|
||||
PRIMARY KEY (id)
|
||||
);`
|
||||
|
||||
func ensureFileTableExists(db *sql.DB) {
|
||||
if _, err := db.Exec(fileTableCreationQuery); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// getFile : used during GET command
|
||||
func (f *File) getFile(db *sql.DB) error {
|
||||
sqlQuery := `SELECT name, location, description, createdAt, updatedAt FROM files WHERE id=?`
|
||||
return db.QueryRow(sqlQuery, f.ID).Scan(&f.Name, &f.Location, &f.Description, &f.CreatedAt, &f.UpdatedAt)
|
||||
}
|
||||
|
||||
// updateFile : used during PUT command
|
||||
func (f *File) updateFile(db *sql.DB) error {
|
||||
updStmt, updErr := db.Prepare("UPDATE files SET name=?, location=?, description=?, updatedAt=? WHERE id=?")
|
||||
if updErr != nil {
|
||||
panic(updErr.Error()) // proper error handling instead of panic in your app
|
||||
}
|
||||
defer updStmt.Close() // Close the statement when we leave main() / the program terminates
|
||||
|
||||
_, err := updStmt.Exec(f.Name, f.Location, f.Description, time.Now(), f.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
// deleteFile : used during DELETE command
|
||||
func (f *File) deleteFile(db *sql.DB) error {
|
||||
_, err := db.Exec("DELETE FROM files WHERE id=?", f.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
// createFile : used during PUSH command
|
||||
func (f *File) createFile(db *sql.DB) error {
|
||||
stmtIns, insErr := db.Prepare("INSERT INTO files (name, location, description, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?);")
|
||||
if insErr != nil {
|
||||
panic(insErr.Error()) // proper error handling instead of panic in your app
|
||||
}
|
||||
defer stmtIns.Close() // Close the statement when we leave main() / the program terminates
|
||||
|
||||
_, err := stmtIns.Exec(f.Name, f.Location, f.Description, time.Now(), time.Now())
|
||||
return err
|
||||
}
|
||||
|
||||
// getFiles : used during GET command for all
|
||||
func getFiles(db *sql.DB, start, count int) (Files, error) {
|
||||
sqlQuery := `SELECT id, name, location, description, createdAt, updatedAt FROM files LIMIT ? OFFSET ?;`
|
||||
|
||||
getStmt, prepErr := db.Prepare(sqlQuery)
|
||||
if prepErr != nil {
|
||||
panic(prepErr.Error()) // proper error handling instead of panic in your app
|
||||
}
|
||||
defer getStmt.Close() // Close the statement when we leave main() / the program terminates
|
||||
|
||||
rows, err := getStmt.Query(count, start)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
files := Files{}
|
||||
|
||||
for rows.Next() {
|
||||
var f File
|
||||
if err := rows.Scan(&f.ID, &f.Name, &f.Location, &f.Description, &f.CreatedAt, &f.UpdatedAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
files = append(files, f)
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
|
||||
10
test_test.go
10
test_test.go
@@ -16,13 +16,19 @@ func TestMain(m *testing.M) {
|
||||
os.Getenv("TEST_DB_PASSWORD"),
|
||||
os.Getenv("TEST_DB_NAME"))
|
||||
|
||||
ensureConfigTableExists()
|
||||
ensureDataTypeTableExists()
|
||||
ensureConfigTableExists(a.DB)
|
||||
ensureDataTypeTableExists(a.DB)
|
||||
ensureDeviceTypeTableExists(a.DB)
|
||||
ensureDeviceTableExists(a.DB)
|
||||
ensureFileTableExists(a.DB)
|
||||
|
||||
code := m.Run()
|
||||
|
||||
clearConfigTable()
|
||||
clearDataTypeTable()
|
||||
clearDeviceTypeTable()
|
||||
clearDeviceTable()
|
||||
clearFileTable()
|
||||
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
@@ -3,29 +3,12 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
const configTableCreationQuery = `CREATE TABLE IF NOT EXISTS configs (
|
||||
id int(10) unsigned AUTO_INCREMENT,
|
||||
parameter varchar(255),
|
||||
val varchar(255),
|
||||
createdAt datetime,
|
||||
updatedAt datetime,
|
||||
UNIQUE KEY parameter (parameter),
|
||||
PRIMARY KEY (id)
|
||||
)`
|
||||
|
||||
func ensureConfigTableExists() {
|
||||
if _, err := a.DB.Exec(configTableCreationQuery); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func clearConfigTable() {
|
||||
a.DB.Exec("DELETE FROM configs")
|
||||
a.DB.Exec("ALTER TABLE configs AUTO_INCREMENT = 1")
|
||||
|
||||
@@ -3,29 +3,12 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
const dataTypeTableCreationQuery = `CREATE TABLE IF NOT EXISTS dataTypes (
|
||||
id int(10) unsigned AUTO_INCREMENT,
|
||||
dataType varchar(255),
|
||||
plcType varchar(255),
|
||||
createdAt datetime,
|
||||
updatedAt datetime,
|
||||
UNIQUE KEY dataType (dataType),
|
||||
PRIMARY KEY (id)
|
||||
)`
|
||||
|
||||
func ensureDataTypeTableExists() {
|
||||
if _, err := a.DB.Exec(dataTypeTableCreationQuery); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func clearDataTypeTable() {
|
||||
a.DB.Exec("DELETE FROM dataTypes")
|
||||
a.DB.Exec("ALTER TABLE dataTypes AUTO_INCREMENT = 1")
|
||||
|
||||
148
testdevice_test.go
Normal file
148
testdevice_test.go
Normal file
@@ -0,0 +1,148 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func clearDeviceTable() {
|
||||
a.DB.Exec("DELETE FROM devices")
|
||||
a.DB.Exec("ALTER TABLE devices AUTO_INCREMENT = 1")
|
||||
seedDeviceTypeData(a.DB)
|
||||
}
|
||||
|
||||
func TestEmptyDeviceTable(t *testing.T) {
|
||||
clearDeviceTable()
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/devices", nil)
|
||||
response := executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
|
||||
if body := response.Body.String(); body != "[]" {
|
||||
t.Errorf("Expected an empty array. Got %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetNonExistentDevice(t *testing.T) {
|
||||
clearDeviceTable()
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/device/11", nil)
|
||||
response := executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusNotFound, response.Code)
|
||||
|
||||
var m map[string]string
|
||||
json.Unmarshal(response.Body.Bytes(), &m)
|
||||
if m["error"] != "Device not found" {
|
||||
t.Errorf("Expected the 'error' key of the response to be set to 'Device not found'. Got '%s'", m["error"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateDevice(t *testing.T) {
|
||||
clearDeviceTable()
|
||||
|
||||
payload := []byte(`{"name":"TestDevice","deviceTypeId":1,"address":"192.168.1.10"}`)
|
||||
|
||||
req, _ := http.NewRequest("POST", "/api/v1/device", bytes.NewBuffer(payload))
|
||||
response := executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusCreated, response.Code)
|
||||
|
||||
var m map[string]interface{}
|
||||
json.Unmarshal(response.Body.Bytes(), &m)
|
||||
|
||||
if m["name"] != "TestDevice" {
|
||||
t.Errorf("Expected device name to be 'TestDevice'. Got '%v'", m["name"])
|
||||
}
|
||||
if m["address"] != "192.168.1.10" {
|
||||
t.Errorf("Expected device address to be '192.168.1.10'. Got '%v'", m["address"])
|
||||
}
|
||||
|
||||
if m["deviceTypeId"] != 1.0 {
|
||||
t.Errorf("Expected device deviceTypeId to be '1'. Got '%v'", m["deviceTypeId"])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGetDevice(t *testing.T) {
|
||||
clearDeviceTable()
|
||||
addDevices(1)
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/device/1", nil)
|
||||
response := executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
}
|
||||
|
||||
func addDevices(count int) {
|
||||
if count < 1 {
|
||||
count = 1
|
||||
}
|
||||
insStmt, insErr := a.DB.Prepare("INSERT INTO devices(name, deviceTypeId, address, createdAt, updatedAt) VALUES(?, ?, ?, ?, ?)")
|
||||
if insErr != nil {
|
||||
panic(insErr.Error()) // proper error handling instead of panic in your app
|
||||
}
|
||||
defer insStmt.Close() // Close the statement when we leave main() / the program terminates
|
||||
|
||||
for i := 0; i < count; i++ {
|
||||
insStmt.Exec("TESTDEVICE"+strconv.Itoa(i), 1, "192.168.1.10", time.Now(), time.Now())
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateDevice(t *testing.T) {
|
||||
clearDeviceTable()
|
||||
addDevices(1)
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/device/1", nil)
|
||||
response := executeRequest(req)
|
||||
var originalDevice map[string]interface{}
|
||||
json.Unmarshal(response.Body.Bytes(), &originalDevice)
|
||||
|
||||
payload := []byte(`{"name":"TestDevice2","deviceTypeId":2,"address":"192.168.1.11"}`)
|
||||
|
||||
req, _ = http.NewRequest("PUT", "/api/v1/device/1", bytes.NewBuffer(payload))
|
||||
response = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
|
||||
var m map[string]interface{}
|
||||
json.Unmarshal(response.Body.Bytes(), &m)
|
||||
|
||||
if m["id"] != originalDevice["id"] {
|
||||
t.Errorf("Expected the id to remain the same (%v). Got %v", originalDevice["id"], m["id"])
|
||||
}
|
||||
|
||||
if m["name"] == originalDevice["name"] {
|
||||
t.Errorf("Expected the name to change from '%v' to '%v'. Got '%v'", originalDevice["name"], m["name"], m["name"])
|
||||
}
|
||||
|
||||
if m["deviceTypeId"] == originalDevice["deviceTypeId"] {
|
||||
t.Errorf("Expected the deviceTypeId to change from '%v' to '%v'. Got '%v'", originalDevice["deviceTypeId"], m["deviceTypeId"], m["deviceTypeId"])
|
||||
}
|
||||
|
||||
if m["address"] == originalDevice["address"] {
|
||||
t.Errorf("Expected the address to change from '%v' to '%v'. Got '%v'", originalDevice["address"], m["address"], m["address"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteDevice(t *testing.T) {
|
||||
clearDeviceTable()
|
||||
addDevices(1)
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/device/1", nil)
|
||||
response := executeRequest(req)
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
|
||||
req, _ = http.NewRequest("DELETE", "/api/v1/device/1", nil)
|
||||
response = executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
|
||||
req, _ = http.NewRequest("GET", "/api/v1/device/1", nil)
|
||||
response = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusNotFound, response.Code)
|
||||
}
|
||||
131
testdevicetype_test.go
Normal file
131
testdevicetype_test.go
Normal file
@@ -0,0 +1,131 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func clearDeviceTypeTable() {
|
||||
a.DB.Exec("DELETE FROM deviceTypes")
|
||||
a.DB.Exec("ALTER TABLE deviceTypes AUTO_INCREMENT = 1")
|
||||
}
|
||||
|
||||
func TestEmptyDeviceTypeTable(t *testing.T) {
|
||||
clearDeviceTypeTable()
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/deviceTypes", nil)
|
||||
response := executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
|
||||
if body := response.Body.String(); body != "[]" {
|
||||
t.Errorf("Expected an empty array. Got %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetNonExistentDeviceType(t *testing.T) {
|
||||
clearDeviceTypeTable()
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/deviceType/11", nil)
|
||||
response := executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusNotFound, response.Code)
|
||||
|
||||
var m map[string]string
|
||||
json.Unmarshal(response.Body.Bytes(), &m)
|
||||
if m["error"] != "DeviceType not found" {
|
||||
t.Errorf("Expected the 'error' key of the response to be set to 'DeviceType not found'. Got '%s'", m["error"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateDeviceType(t *testing.T) {
|
||||
clearDeviceTypeTable()
|
||||
|
||||
payload := []byte(`{"name":"CLX"}`)
|
||||
|
||||
req, _ := http.NewRequest("POST", "/api/v1/deviceType", bytes.NewBuffer(payload))
|
||||
response := executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusCreated, response.Code)
|
||||
|
||||
var m map[string]interface{}
|
||||
json.Unmarshal(response.Body.Bytes(), &m)
|
||||
|
||||
if m["name"] != "CLX" {
|
||||
t.Errorf("Expected deviceType deviceType to be 'CLX'. Got '%v'", m["name"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDeviceType(t *testing.T) {
|
||||
clearDeviceTypeTable()
|
||||
addDeviceTypes(1)
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/deviceType/1", nil)
|
||||
response := executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
}
|
||||
|
||||
func addDeviceTypes(count int) {
|
||||
if count < 1 {
|
||||
count = 1
|
||||
}
|
||||
insStmt, insErr := a.DB.Prepare("INSERT INTO deviceTypes(name, createdAt, updatedAt) VALUES(?, ?, ?)")
|
||||
if insErr != nil {
|
||||
panic(insErr.Error()) // proper error handling instead of panic in your app
|
||||
}
|
||||
defer insStmt.Close() // Close the statement when we leave main() / the program terminates
|
||||
|
||||
for i := 0; i < count; i++ {
|
||||
insStmt.Exec("TESTDEVICETYPE"+strconv.Itoa(i), time.Now(), time.Now())
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateDeviceType(t *testing.T) {
|
||||
clearDeviceTypeTable()
|
||||
addDeviceTypes(1)
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/deviceType/1", nil)
|
||||
response := executeRequest(req)
|
||||
var originalDeviceType map[string]interface{}
|
||||
json.Unmarshal(response.Body.Bytes(), &originalDeviceType)
|
||||
|
||||
payload := []byte(`{"name":"E300"}`)
|
||||
|
||||
req, _ = http.NewRequest("PUT", "/api/v1/deviceType/1", bytes.NewBuffer(payload))
|
||||
response = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
|
||||
var m map[string]interface{}
|
||||
json.Unmarshal(response.Body.Bytes(), &m)
|
||||
|
||||
if m["id"] != originalDeviceType["id"] {
|
||||
t.Errorf("Expected the id to remain the same (%v). Got %v", originalDeviceType["id"], m["id"])
|
||||
}
|
||||
|
||||
if m["name"] == originalDeviceType["name"] {
|
||||
t.Errorf("Expected the name to change from '%v' to '%v'. Got '%v'", originalDeviceType["name"], m["name"], m["name"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteDeviceType(t *testing.T) {
|
||||
clearDeviceTypeTable()
|
||||
addDeviceTypes(1)
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/deviceType/1", nil)
|
||||
response := executeRequest(req)
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
|
||||
req, _ = http.NewRequest("DELETE", "/api/v1/deviceType/1", nil)
|
||||
response = executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
|
||||
req, _ = http.NewRequest("GET", "/api/v1/deviceType/1", nil)
|
||||
response = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusNotFound, response.Code)
|
||||
}
|
||||
147
testfile_test.go
Normal file
147
testfile_test.go
Normal file
@@ -0,0 +1,147 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func clearFileTable() {
|
||||
a.DB.Exec("DELETE FROM files")
|
||||
a.DB.Exec("ALTER TABLE files AUTO_INCREMENT = 1")
|
||||
}
|
||||
|
||||
func TestEmptyFileTable(t *testing.T) {
|
||||
clearFileTable()
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/files", nil)
|
||||
response := executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
|
||||
if body := response.Body.String(); body != "[]" {
|
||||
t.Errorf("Expected an empty array. Got %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetNonExistentFile(t *testing.T) {
|
||||
clearFileTable()
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/file/11", nil)
|
||||
response := executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusNotFound, response.Code)
|
||||
|
||||
var m map[string]string
|
||||
json.Unmarshal(response.Body.Bytes(), &m)
|
||||
if m["error"] != "File not found" {
|
||||
t.Errorf("Expected the 'error' key of the response to be set to 'File not found'. Got '%s'", m["error"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateFile(t *testing.T) {
|
||||
clearFileTable()
|
||||
|
||||
payload := []byte(`{"name":"test_filename","description":"Test Filename","location":"/this/path"}`)
|
||||
|
||||
req, _ := http.NewRequest("POST", "/api/v1/file", bytes.NewBuffer(payload))
|
||||
response := executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusCreated, response.Code)
|
||||
|
||||
var m map[string]interface{}
|
||||
json.Unmarshal(response.Body.Bytes(), &m)
|
||||
|
||||
if m["name"] != "test_filename" {
|
||||
t.Errorf("Expected file name to be 'test_filename'. Got '%v'", m["name"])
|
||||
}
|
||||
|
||||
if m["description"] != "Test Filename" {
|
||||
t.Errorf("Expected file description to be 'Test Filename'. Got '%v'", m["description"])
|
||||
}
|
||||
|
||||
if m["location"] != "/this/path" {
|
||||
t.Errorf("Expected file location to be '/this/path'. Got '%v'", m["location"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFile(t *testing.T) {
|
||||
clearFileTable()
|
||||
addFiles(1)
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/file/1", nil)
|
||||
response := executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
}
|
||||
|
||||
func addFiles(count int) {
|
||||
if count < 1 {
|
||||
count = 1
|
||||
}
|
||||
insStmt, insErr := a.DB.Prepare("INSERT INTO files(name, description, location, createdAt, updatedAt) VALUES(?, ?, ?, ?, ?)")
|
||||
if insErr != nil {
|
||||
panic(insErr.Error()) // proper error handling instead of panic in your app
|
||||
}
|
||||
defer insStmt.Close() // Close the statement when we leave main() / the program terminates
|
||||
|
||||
for i := 0; i < count; i++ {
|
||||
insStmt.Exec("testfile"+strconv.Itoa(i), "testfiledescription", "/this/location", time.Now(), time.Now())
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateFile(t *testing.T) {
|
||||
clearFileTable()
|
||||
addFiles(1)
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/file/1", nil)
|
||||
response := executeRequest(req)
|
||||
var originalFile map[string]interface{}
|
||||
json.Unmarshal(response.Body.Bytes(), &originalFile)
|
||||
|
||||
payload := []byte(`{"name":"test_filename1","description":"Test Filename1","location":"/this/path/1"}`)
|
||||
|
||||
req, _ = http.NewRequest("PUT", "/api/v1/file/1", bytes.NewBuffer(payload))
|
||||
response = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
|
||||
var m map[string]interface{}
|
||||
json.Unmarshal(response.Body.Bytes(), &m)
|
||||
|
||||
if m["id"] != originalFile["id"] {
|
||||
t.Errorf("Expected the id to remain the same (%v). Got %v", originalFile["id"], m["id"])
|
||||
}
|
||||
|
||||
if m["name"] == originalFile["name"] {
|
||||
t.Errorf("Expected the name to change from '%v' to '%v'. Got '%v'", originalFile["name"], m["name"], m["name"])
|
||||
}
|
||||
|
||||
if m["description"] == originalFile["description"] {
|
||||
t.Errorf("Expected the description to change from '%v' to '%v'. Got '%v'", originalFile["description"], m["description"], m["description"])
|
||||
}
|
||||
|
||||
if m["location"] == originalFile["location"] {
|
||||
t.Errorf("Expected the location to change from '%v' to '%v'. Got '%v'", originalFile["location"], m["location"], m["location"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteFile(t *testing.T) {
|
||||
clearFileTable()
|
||||
addFiles(1)
|
||||
|
||||
req, _ := http.NewRequest("GET", "/api/v1/file/1", nil)
|
||||
response := executeRequest(req)
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
|
||||
req, _ = http.NewRequest("DELETE", "/api/v1/file/1", nil)
|
||||
response = executeRequest(req)
|
||||
|
||||
checkResponseCode(t, http.StatusOK, response.Code)
|
||||
|
||||
req, _ = http.NewRequest("GET", "/api/v1/file/1", nil)
|
||||
response = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusNotFound, response.Code)
|
||||
}
|
||||
Reference in New Issue
Block a user