mirror of
https://git.rwth-aachen.de/acs/public/villas/web-backend-go/
synced 2025-03-30 00:00:12 +01:00
- revise testing of file endpoints
- revise documentation for swaggo - clean up testdata - delete serializers and responses files - revise file endpoint implementations
This commit is contained in:
parent
7544c863de
commit
f339c0d135
8 changed files with 478 additions and 300 deletions
|
@ -1,27 +0,0 @@
|
|||
package common
|
||||
|
||||
type FileResponse struct {
|
||||
Name string `json:"name"`
|
||||
ID uint `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Size uint `json:"size"`
|
||||
ImageWidth uint `json:"imageHeight"`
|
||||
ImageHeight uint `json:"imageWidth"`
|
||||
Date string `json:"date"`
|
||||
WidgetID uint `json:"widgetID"`
|
||||
SimulationModelID uint `json:"simulationModelID"`
|
||||
}
|
||||
|
||||
// Response messages
|
||||
|
||||
type ResponseMsg struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type ResponseMsgFiles struct {
|
||||
Files []FileResponse `json:"files"`
|
||||
}
|
||||
|
||||
type ResponseMsgFile struct {
|
||||
File FileResponse `json:"file"`
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// File/s Serializers
|
||||
|
||||
type FilesSerializerNoAssoc struct {
|
||||
Ctx *gin.Context
|
||||
Files []File
|
||||
}
|
||||
|
||||
func (self *FilesSerializerNoAssoc) Response() []FileResponse {
|
||||
response := []FileResponse{}
|
||||
for _, files := range self.Files {
|
||||
serializer := FileSerializerNoAssoc{self.Ctx, files}
|
||||
response = append(response, serializer.Response())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type FileSerializerNoAssoc struct {
|
||||
Ctx *gin.Context
|
||||
File
|
||||
}
|
||||
|
||||
func (self *FileSerializerNoAssoc) Response() FileResponse {
|
||||
response := FileResponse{
|
||||
Name: self.Name,
|
||||
ID: self.ID,
|
||||
//Path: self.Path,
|
||||
Type: self.Type,
|
||||
Size: self.Size,
|
||||
ImageHeight: self.ImageHeight,
|
||||
ImageWidth: self.ImageWidth,
|
||||
Date: self.Date,
|
||||
WidgetID: self.WidgetID,
|
||||
SimulationModelID: self.SimulationModelID,
|
||||
}
|
||||
return response
|
||||
}
|
|
@ -7,12 +7,6 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// Generic
|
||||
|
||||
var MsgOK = ResponseMsg{
|
||||
Message: "OK.",
|
||||
}
|
||||
|
||||
// Users
|
||||
var StrPassword0 = "xyz789"
|
||||
var StrPasswordA = "abc123"
|
||||
|
@ -160,16 +154,6 @@ var FileA = File{
|
|||
Date: time.Now().String(),
|
||||
}
|
||||
|
||||
var FileA_response = FileResponse{
|
||||
ID: 1,
|
||||
Name: FileA.Name,
|
||||
Type: FileA.Type,
|
||||
Size: FileA.Size,
|
||||
ImageWidth: FileA.ImageWidth,
|
||||
ImageHeight: FileA.ImageHeight,
|
||||
Date: FileA.Date,
|
||||
}
|
||||
|
||||
var FileB = File{
|
||||
Name: "File_B",
|
||||
Type: "text/plain",
|
||||
|
@ -179,16 +163,6 @@ var FileB = File{
|
|||
Date: time.Now().String(),
|
||||
}
|
||||
|
||||
var FileB_response = FileResponse{
|
||||
ID: 2,
|
||||
Name: FileB.Name,
|
||||
Type: FileB.Type,
|
||||
Size: FileB.Size,
|
||||
ImageWidth: FileB.ImageWidth,
|
||||
ImageHeight: FileB.ImageHeight,
|
||||
Date: FileB.Date,
|
||||
}
|
||||
|
||||
var FileC = File{
|
||||
Name: "File_C",
|
||||
Type: "text/plain",
|
||||
|
|
|
@ -72,3 +72,11 @@ type ResponseSignals struct {
|
|||
type ResponseSignal struct {
|
||||
signal common.Signal
|
||||
}
|
||||
|
||||
type ResponseFiles struct {
|
||||
files []common.File
|
||||
}
|
||||
|
||||
type ResponseFile struct {
|
||||
file common.File
|
||||
}
|
||||
|
|
|
@ -25,11 +25,10 @@ func RegisterFileEndpoints(r *gin.RouterGroup) {
|
|||
// @ID getFiles
|
||||
// @Tags files
|
||||
// @Produce json
|
||||
// @Success 200 {array} common.FileResponse "File parameters requested by user"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Success 200 {object} docs.ResponseFiles "Files which belong to simulation model or widget"
|
||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||
// @Param objectType query string true "Set to model for files of model, set to widget for files of widget"
|
||||
// @Param objectID query int true "ID of either model or widget of which files are requested"
|
||||
// @Router /files [get]
|
||||
|
@ -37,18 +36,18 @@ func getFiles(c *gin.Context) {
|
|||
|
||||
objectType := c.Request.URL.Query().Get("objectType")
|
||||
if objectType != "model" && objectType != "widget" {
|
||||
errormsg := fmt.Sprintf("Bad request. Object type not supported for files: %s", objectType)
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
"success": false,
|
||||
"message": fmt.Sprintf("Bad request. Object type not supported for files: %s", objectType),
|
||||
})
|
||||
return
|
||||
}
|
||||
objectID_s := c.Request.URL.Query().Get("objectID")
|
||||
objectID, err := strconv.Atoi(objectID_s)
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. Error on ID conversion: %s", err.Error())
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
"success": false,
|
||||
"message": fmt.Sprintf("Bad request. Error on ID conversion: %s", err.Error()),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -85,9 +84,8 @@ func getFiles(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
serializer := common.FilesSerializerNoAssoc{c, files}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"files": serializer.Response(),
|
||||
"files": files,
|
||||
})
|
||||
|
||||
}
|
||||
|
@ -103,11 +101,11 @@ func getFiles(c *gin.Context) {
|
|||
// @Accept gif
|
||||
// @Accept model/x-cim
|
||||
// @Accept model/x-cim.zip
|
||||
// @Success 200 "OK"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Success 200 {object} docs.ResponseFile "File that was added"
|
||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||
// @Param inputFile formData file true "File to be uploaded"
|
||||
// @Param objectType query string true "Set to model for files of model, set to widget for files of widget"
|
||||
// @Param objectID query int true "ID of either model or widget of which files are requested"
|
||||
|
@ -116,18 +114,18 @@ func addFile(c *gin.Context) {
|
|||
|
||||
objectType := c.Request.URL.Query().Get("objectType")
|
||||
if objectType != "model" && objectType != "widget" {
|
||||
errormsg := fmt.Sprintf("Bad request. Object type not supported for files: %s", objectType)
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
"success": false,
|
||||
"message": fmt.Sprintf("Bad request. Object type not supported for files: %s", objectType),
|
||||
})
|
||||
return
|
||||
}
|
||||
objectID_s := c.Request.URL.Query().Get("objectID")
|
||||
objectID, err := strconv.Atoi(objectID_s)
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. Error on ID conversion: %s", err.Error())
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
"success": false,
|
||||
"message": fmt.Sprintf("Bad request. Error on ID conversion: %s", err.Error()),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -149,20 +147,23 @@ func addFile(c *gin.Context) {
|
|||
// Extract file from POST request form
|
||||
file_header, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. Get form error: %s", err.Error())
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
"success": false,
|
||||
"message": fmt.Sprintf("Bad request. Get form error: %s", err.Error()),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var newFile File
|
||||
err = newFile.register(file_header, objectType, uint(objectID))
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK.",
|
||||
})
|
||||
if err != nil {
|
||||
common.ProvideErrorResponse(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"file": newFile.File,
|
||||
})
|
||||
}
|
||||
|
||||
// getFile godoc
|
||||
|
@ -175,11 +176,11 @@ func addFile(c *gin.Context) {
|
|||
// @Produce gif
|
||||
// @Produce model/x-cim
|
||||
// @Produce model/x-cim.zip
|
||||
// @Success 200 "OK"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Success 200 {object} docs.ResponseFile "File that was requested"
|
||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||
// @Param fileID path int true "ID of the file to download"
|
||||
// @Router /files/{fileID} [get]
|
||||
func getFile(c *gin.Context) {
|
||||
|
@ -191,9 +192,15 @@ func getFile(c *gin.Context) {
|
|||
}
|
||||
|
||||
err := f.download(c)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
if err != nil {
|
||||
common.ProvideErrorResponse(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"file": f.File,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// updateFile godoc
|
||||
|
@ -207,11 +214,11 @@ func getFile(c *gin.Context) {
|
|||
// @Accept gif
|
||||
// @Accept model/x-cim
|
||||
// @Accept model/x-cim.zip
|
||||
// @Success 200 "OK"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Success 200 {object} docs.ResponseFile "File that was updated"
|
||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||
// @Param inputFile formData file true "File to be uploaded"
|
||||
// @Param fileID path int true "ID of the file to update"
|
||||
// @Router /files/{fileID} [put]
|
||||
|
@ -226,28 +233,31 @@ func updateFile(c *gin.Context) {
|
|||
// Extract file from PUT request form
|
||||
err := c.Request.ParseForm()
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. Get form error: %s", err.Error())
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
"success": false,
|
||||
"message": fmt.Sprintf("Bad request. Get form error: %s", err.Error()),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
file_header, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. Get form error: %s", err.Error())
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
"success": false,
|
||||
"error": fmt.Sprintf("Bad request. Get form error: %s", err.Error()),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err = f.update(file_header)
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK.",
|
||||
})
|
||||
if err != nil {
|
||||
common.ProvideErrorResponse(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"file": f.File,
|
||||
})
|
||||
}
|
||||
|
||||
// deleteFile godoc
|
||||
|
@ -255,11 +265,11 @@ func updateFile(c *gin.Context) {
|
|||
// @ID deleteFile
|
||||
// @Tags files
|
||||
// @Produce json
|
||||
// @Success 200 "OK"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Success 200 {object} docs.ResponseFile "File that was deleted"
|
||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||
// @Param fileID path int true "ID of the file to update"
|
||||
// @Router /files/{fileID} [delete]
|
||||
func deleteFile(c *gin.Context) {
|
||||
|
@ -271,9 +281,12 @@ func deleteFile(c *gin.Context) {
|
|||
}
|
||||
|
||||
err := f.delete()
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK.",
|
||||
})
|
||||
if err != nil {
|
||||
common.ProvideErrorResponse(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"file": f.File,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ func (f *File) byPath(path string) error {
|
|||
db := common.GetDB()
|
||||
err := db.Where("Path = ?", path).Find(f).Error
|
||||
if err != nil {
|
||||
return fmt.Errorf("File with path=%s does not exist", path)
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ func (f *File) byID(id uint) error {
|
|||
db := common.GetDB()
|
||||
err := db.Find(f, id).Error
|
||||
if err != nil {
|
||||
return fmt.Errorf("File with id=%v does not exist", id)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -137,7 +137,6 @@ func (f *File) update(fileHeader *multipart.FileHeader) error {
|
|||
}
|
||||
|
||||
fileData, err := ioutil.ReadAll(fileContent)
|
||||
fmt.Println("File content: ", string(fileData))
|
||||
defer fileContent.Close()
|
||||
|
||||
db := common.GetDB()
|
||||
|
|
|
@ -16,15 +16,18 @@ func checkPermissions(c *gin.Context, operation common.CRUD) (bool, File) {
|
|||
|
||||
err := common.ValidateRole(c, common.ModelFile, operation)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnprocessableEntity, "Access denied (role validation failed).")
|
||||
c.JSON(http.StatusUnprocessableEntity, gin.H{
|
||||
"success": false,
|
||||
"message": fmt.Sprintf("Access denied (role validation failed): %v", err),
|
||||
})
|
||||
return false, f
|
||||
}
|
||||
|
||||
fileID, err := strconv.Atoi(c.Param("fileID"))
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. No or incorrect format of fileID path parameter")
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
"success": false,
|
||||
"error": fmt.Sprintf("Bad request. No or incorrect format of fileID path parameter"),
|
||||
})
|
||||
return false, f
|
||||
}
|
||||
|
|
|
@ -2,11 +2,15 @@ package file
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/scenario"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulationmodel"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulator"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/user"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/jinzhu/gorm/dialects/postgres"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
@ -17,185 +21,431 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
// Test /files endpoints
|
||||
func TestSignalEndpoints(t *testing.T) {
|
||||
var router *gin.Engine
|
||||
var db *gorm.DB
|
||||
|
||||
var token string
|
||||
var filecontent = "This is my testfile"
|
||||
var filecontent_update = "This is my updated testfile with a dot at the end."
|
||||
var filename = "testfile.txt"
|
||||
var filename_update = "testfileupdate.txt"
|
||||
type SimulationModelRequest struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
ScenarioID uint `json:"scenarioID,omitempty"`
|
||||
SimulatorID uint `json:"simulatorID,omitempty"`
|
||||
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
||||
}
|
||||
|
||||
var myFiles = []common.FileResponse{common.FileA_response, common.FileB_response}
|
||||
var msgFiles = common.ResponseMsgFiles{Files: myFiles}
|
||||
type SimulatorRequest struct {
|
||||
UUID string `json:"uuid,omitempty"`
|
||||
Host string `json:"host,omitempty"`
|
||||
Modeltype string `json:"modelType,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
Properties postgres.Jsonb `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
db := common.DummyInitDB()
|
||||
type ScenarioRequest struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Running bool `json:"running,omitempty"`
|
||||
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
||||
}
|
||||
|
||||
func addScenarioAndSimulatorAndSimulationModel() (scenarioID uint, simulatorID uint, simulationModelID uint) {
|
||||
|
||||
// authenticate as admin
|
||||
token, _ := common.NewAuthenticateForTest(router,
|
||||
"/api/authenticate", "POST", common.AdminCredentials)
|
||||
|
||||
// POST $newSimulatorA
|
||||
newSimulatorA := SimulatorRequest{
|
||||
UUID: common.SimulatorA.UUID,
|
||||
Host: common.SimulatorA.Host,
|
||||
Modeltype: common.SimulatorA.Modeltype,
|
||||
State: common.SimulatorA.State,
|
||||
Properties: common.SimulatorA.Properties,
|
||||
}
|
||||
_, resp, _ := common.NewTestEndpoint(router, token,
|
||||
"/api/simulators", "POST", common.KeyModels{"simulator": newSimulatorA})
|
||||
|
||||
// Read newSimulator's ID from the response
|
||||
newSimulatorID, _ := common.GetResponseID(resp)
|
||||
|
||||
// authenticate as normal user
|
||||
token, _ = common.NewAuthenticateForTest(router,
|
||||
"/api/authenticate", "POST", common.UserACredentials)
|
||||
|
||||
// POST $newScenario
|
||||
newScenario := ScenarioRequest{
|
||||
Name: common.ScenarioA.Name,
|
||||
Running: common.ScenarioA.Running,
|
||||
StartParameters: common.ScenarioA.StartParameters,
|
||||
}
|
||||
_, resp, _ = common.NewTestEndpoint(router, token,
|
||||
"/api/scenarios", "POST", common.KeyModels{"scenario": newScenario})
|
||||
|
||||
// Read newScenario's ID from the response
|
||||
newScenarioID, _ := common.GetResponseID(resp)
|
||||
|
||||
// test POST models/ $newSimulationModel
|
||||
newSimulationModel := SimulationModelRequest{
|
||||
Name: common.SimulationModelA.Name,
|
||||
ScenarioID: uint(newScenarioID),
|
||||
SimulatorID: uint(newSimulatorID),
|
||||
StartParameters: common.SimulationModelA.StartParameters,
|
||||
}
|
||||
_, resp, _ = common.NewTestEndpoint(router, token,
|
||||
"/api/models", "POST", common.KeyModels{"model": newSimulationModel})
|
||||
|
||||
// Read newSimulationModel's ID from the response
|
||||
newSimulationModelID, _ := common.GetResponseID(resp)
|
||||
|
||||
return uint(newScenarioID), uint(newSimulatorID), uint(newSimulationModelID)
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
|
||||
db = common.DummyInitDB()
|
||||
defer db.Close()
|
||||
common.DummyPopulateDB(db)
|
||||
|
||||
// create a testfile in local folder
|
||||
c1 := []byte(filecontent)
|
||||
c2 := []byte(filecontent_update)
|
||||
err := ioutil.WriteFile(filename, c1, 0644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = ioutil.WriteFile(filename_update, c2, 0644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
router := gin.Default()
|
||||
router = gin.Default()
|
||||
api := router.Group("/api")
|
||||
|
||||
// All endpoints require authentication except when someone wants to
|
||||
// login (POST /authenticate)
|
||||
user.RegisterAuthenticate(api.Group("/authenticate"))
|
||||
|
||||
api.Use(user.Authentication(true))
|
||||
|
||||
// simulationmodel endpoints required here to first add a simulation to the DB
|
||||
// that can be associated with a new signal model
|
||||
simulationmodel.RegisterSimulationModelEndpoints(api.Group("/models"))
|
||||
// scenario endpoints required here to first add a scenario to the DB
|
||||
// that can be associated with a new simulation model
|
||||
scenario.RegisterScenarioEndpoints(api.Group("/scenarios"))
|
||||
// simulator endpoints required here to first add a simulator to the DB
|
||||
// that can be associated with a new simulation model
|
||||
simulator.RegisterSimulatorEndpoints(api.Group("/simulators"))
|
||||
RegisterFileEndpoints(api.Group("/files"))
|
||||
|
||||
credjson, err := json.Marshal(common.CredUser)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
msgOKjson, err := json.Marshal(common.MsgOK)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
func TestAddFile(t *testing.T) {
|
||||
common.DropTables(db)
|
||||
common.MigrateModels(db)
|
||||
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db)
|
||||
|
||||
msgFilesjson, err := json.Marshal(msgFiles)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// prepare the content of the DB for testing
|
||||
// by adding a scenario and a simulator to the DB
|
||||
// using the respective endpoints of the API
|
||||
_, _, simulationModelID := addScenarioAndSimulatorAndSimulationModel()
|
||||
|
||||
token = common.AuthenticateForTest(t, router, "/api/authenticate", "POST", credjson, 200)
|
||||
// authenticate as normal user
|
||||
token, err := common.NewAuthenticateForTest(router,
|
||||
"/api/authenticate", "POST", common.UserACredentials)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// test GET files
|
||||
common.TestEndpoint(t, router, token, "/api/files?objectID=1&objectType=widget", "GET", nil, 200, msgFilesjson)
|
||||
// create a testfile.txt in local folder
|
||||
c1 := []byte("This is my testfile\n")
|
||||
err = ioutil.WriteFile("testfile.txt", c1, 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// test POST files
|
||||
bodyBuf := &bytes.Buffer{}
|
||||
bodyWriter := multipart.NewWriter(bodyBuf)
|
||||
fileWriter, err := bodyWriter.CreateFormFile("file", "testuploadfile.txt")
|
||||
if err != nil {
|
||||
fmt.Println("error writing to buffer")
|
||||
panic(err)
|
||||
}
|
||||
assert.NoError(t, err, "writing to buffer")
|
||||
|
||||
// open file handle
|
||||
fh, err := os.Open(filename)
|
||||
if err != nil {
|
||||
fmt.Println("error opening file")
|
||||
panic(err)
|
||||
}
|
||||
fh, err := os.Open("testfile.txt")
|
||||
assert.NoError(t, err, "opening file")
|
||||
defer fh.Close()
|
||||
|
||||
// io copy
|
||||
_, err = io.Copy(fileWriter, fh)
|
||||
if err != nil {
|
||||
fmt.Println("error on IO copy")
|
||||
panic(err)
|
||||
}
|
||||
assert.NoError(t, err, "IO copy")
|
||||
|
||||
contentType := bodyWriter.FormDataContentType()
|
||||
bodyWriter.Close()
|
||||
//req, err := http.NewRequest("POST", "/api/files?objectID=1&objectType=widget", bodyBuf)
|
||||
|
||||
// Create the request
|
||||
w := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("POST", "/api/files?objectID=1&objectType=widget", bodyBuf)
|
||||
req.Header.Add("Authorization", "Bearer "+token)
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
if err != nil {
|
||||
fmt.Println("error creating post request")
|
||||
panic(err)
|
||||
}
|
||||
req, err := http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), bodyBuf)
|
||||
assert.NoError(t, err, "create request")
|
||||
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
req.Header.Add("Authorization", "Bearer "+token)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
fmt.Println(w.Body.String())
|
||||
assert.Equal(t, string(msgOKjson), w.Body.String())
|
||||
assert.Equalf(t, 200, w.Code, "Response body: \n%v\n", w.Body)
|
||||
fmt.Println(w.Body)
|
||||
|
||||
// test GET files/:fileID
|
||||
w2 := httptest.NewRecorder()
|
||||
req2, _ := http.NewRequest("GET", "/api/files/5", nil)
|
||||
req2.Header.Add("Authorization", "Bearer "+token)
|
||||
router.ServeHTTP(w2, req2)
|
||||
newFileID, err := common.GetResponseID(w.Body)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, 200, w2.Code)
|
||||
fmt.Println(w2.Body.String())
|
||||
assert.Equal(t, filecontent, w2.Body.String())
|
||||
|
||||
//common.TestEndpoint(t, router, token, "/api/files?objectID=1&objectType=widget", "GET", nil, 200, string(msgFilesjson))
|
||||
|
||||
// test PUT files/:fileID
|
||||
bodyBuf_update := &bytes.Buffer{}
|
||||
bodyWriter_update := multipart.NewWriter(bodyBuf_update)
|
||||
fileWriter_update, err := bodyWriter_update.CreateFormFile("file", "testuploadfile.txt")
|
||||
if err != nil {
|
||||
fmt.Println("error writing to buffer")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// open file handle
|
||||
fh_update, err := os.Open(filename_update)
|
||||
if err != nil {
|
||||
fmt.Println("error opening file")
|
||||
panic(err)
|
||||
}
|
||||
defer fh_update.Close()
|
||||
|
||||
// io copy
|
||||
_, err = io.Copy(fileWriter_update, fh_update)
|
||||
if err != nil {
|
||||
fmt.Println("error on IO copy")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
contentType_update := bodyWriter_update.FormDataContentType()
|
||||
bodyWriter_update.Close()
|
||||
w_update := httptest.NewRecorder()
|
||||
req_update, err := http.NewRequest("PUT", "/api/files/5", bodyBuf_update)
|
||||
req_update.Header.Add("Authorization", "Bearer "+token)
|
||||
req_update.Header.Set("Content-Type", contentType_update)
|
||||
if err != nil {
|
||||
fmt.Println("error creating post request")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
router.ServeHTTP(w_update, req_update)
|
||||
|
||||
assert.Equal(t, 200, w_update.Code)
|
||||
fmt.Println(w_update.Body.String())
|
||||
assert.Equal(t, string(msgOKjson), w_update.Body.String())
|
||||
|
||||
// Test GET on updated file content
|
||||
w3 := httptest.NewRecorder()
|
||||
req3, _ := http.NewRequest("GET", "/api/files/5", nil)
|
||||
req3.Header.Add("Authorization", "Bearer "+token)
|
||||
router.ServeHTTP(w3, req3)
|
||||
|
||||
assert.Equal(t, 200, w3.Code)
|
||||
fmt.Println(w3.Body.String())
|
||||
assert.Equal(t, filecontent_update, w3.Body.String())
|
||||
|
||||
// test DELETE files/:fileID
|
||||
common.TestEndpoint(t, router, token, "/api/files/5", "DELETE", nil, 200, msgOKjson)
|
||||
common.TestEndpoint(t, router, token, "/api/files?objectID=1&objectType=widget", "GET", nil, 200, msgFilesjson)
|
||||
|
||||
// TODO add testing for other return codes
|
||||
|
||||
// clean up temporary file
|
||||
err = os.Remove(filename)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = os.Remove(filename_update)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Get the new file
|
||||
code, resp, err := common.NewTestEndpoint(router, token,
|
||||
fmt.Sprintf("/api/files/%v", newFileID), "GET", nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||
|
||||
}
|
||||
|
||||
func TestUpdateFile(t *testing.T) {
|
||||
|
||||
common.DropTables(db)
|
||||
common.MigrateModels(db)
|
||||
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db)
|
||||
|
||||
// prepare the content of the DB for testing
|
||||
// by adding a scenario and a simulator to the DB
|
||||
// using the respective endpoints of the API
|
||||
_, _, simulationModelID := addScenarioAndSimulatorAndSimulationModel()
|
||||
|
||||
// authenticate as normal user
|
||||
token, err := common.NewAuthenticateForTest(router,
|
||||
"/api/authenticate", "POST", common.UserACredentials)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// create a testfile.txt in local folder
|
||||
c1 := []byte("This is my testfile\n")
|
||||
err = ioutil.WriteFile("testfile.txt", c1, 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
bodyBuf := &bytes.Buffer{}
|
||||
bodyWriter := multipart.NewWriter(bodyBuf)
|
||||
fileWriter, err := bodyWriter.CreateFormFile("file", "testfile.txt")
|
||||
assert.NoError(t, err, "writing to buffer")
|
||||
|
||||
// open file handle
|
||||
fh, err := os.Open("testfile.txt")
|
||||
assert.NoError(t, err, "opening file")
|
||||
defer fh.Close()
|
||||
|
||||
// io copy
|
||||
_, err = io.Copy(fileWriter, fh)
|
||||
assert.NoError(t, err, "IO copy")
|
||||
|
||||
contentType := bodyWriter.FormDataContentType()
|
||||
bodyWriter.Close()
|
||||
//req, err := http.NewRequest("POST", "/api/files?objectID=1&objectType=widget", bodyBuf)
|
||||
|
||||
// Create the POST request
|
||||
w := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), bodyBuf)
|
||||
assert.NoError(t, err, "create request")
|
||||
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
req.Header.Add("Authorization", "Bearer "+token)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equalf(t, 200, w.Code, "Response body: \n%v\n", w.Body)
|
||||
fmt.Println(w.Body)
|
||||
|
||||
newFileID, err := common.GetResponseID(w.Body)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Prepare update
|
||||
|
||||
// create a testfile_updated.txt in local folder
|
||||
c2 := []byte("This is my updated testfile\n")
|
||||
err = ioutil.WriteFile("testfileupdated.txt", c2, 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
bodyBufUpdated := &bytes.Buffer{}
|
||||
bodyWriterUpdated := multipart.NewWriter(bodyBufUpdated)
|
||||
fileWriterUpdated, err := bodyWriterUpdated.CreateFormFile("file", "testfileupdated.txt")
|
||||
assert.NoError(t, err, "writing to buffer")
|
||||
|
||||
// open file handle for updated file
|
||||
fh_updated, err := os.Open("testfileupdated.txt")
|
||||
assert.NoError(t, err, "opening file")
|
||||
defer fh_updated.Close()
|
||||
|
||||
// io copy
|
||||
_, err = io.Copy(fileWriterUpdated, fh_updated)
|
||||
assert.NoError(t, err, "IO copy")
|
||||
|
||||
contentType = bodyWriterUpdated.FormDataContentType()
|
||||
bodyWriterUpdated.Close()
|
||||
|
||||
// Create the PUT request
|
||||
w_updated := httptest.NewRecorder()
|
||||
req, err = http.NewRequest("PUT", fmt.Sprintf("/api/files/%v", newFileID), bodyBufUpdated)
|
||||
assert.NoError(t, err, "create request")
|
||||
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
req.Header.Add("Authorization", "Bearer "+token)
|
||||
router.ServeHTTP(w_updated, req)
|
||||
|
||||
assert.Equalf(t, 200, w_updated.Code, "Response body: \n%v\n", w_updated.Body)
|
||||
fmt.Println(w_updated.Body)
|
||||
|
||||
newFileIDUpdated, err := common.GetResponseID(w_updated.Body)
|
||||
|
||||
assert.Equal(t, newFileID, newFileIDUpdated)
|
||||
|
||||
// Get the updated file
|
||||
code, resp, err := common.NewTestEndpoint(router, token,
|
||||
fmt.Sprintf("/api/files/%v", newFileIDUpdated), "GET", nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||
|
||||
}
|
||||
|
||||
func TestDeleteFile(t *testing.T) {
|
||||
common.DropTables(db)
|
||||
common.MigrateModels(db)
|
||||
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db)
|
||||
|
||||
// prepare the content of the DB for testing
|
||||
// by adding a scenario and a simulator to the DB
|
||||
// using the respective endpoints of the API
|
||||
_, _, simulationModelID := addScenarioAndSimulatorAndSimulationModel()
|
||||
|
||||
// authenticate as normal user
|
||||
token, err := common.NewAuthenticateForTest(router,
|
||||
"/api/authenticate", "POST", common.UserACredentials)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// create a testfile.txt in local folder
|
||||
c1 := []byte("This is my testfile\n")
|
||||
err = ioutil.WriteFile("testfile.txt", c1, 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// test POST files
|
||||
bodyBuf := &bytes.Buffer{}
|
||||
bodyWriter := multipart.NewWriter(bodyBuf)
|
||||
fileWriter, err := bodyWriter.CreateFormFile("file", "testuploadfile.txt")
|
||||
assert.NoError(t, err, "writing to buffer")
|
||||
|
||||
// open file handle
|
||||
fh, err := os.Open("testfile.txt")
|
||||
assert.NoError(t, err, "opening file")
|
||||
defer fh.Close()
|
||||
|
||||
// io copy
|
||||
_, err = io.Copy(fileWriter, fh)
|
||||
assert.NoError(t, err, "IO copy")
|
||||
|
||||
contentType := bodyWriter.FormDataContentType()
|
||||
bodyWriter.Close()
|
||||
//req, err := http.NewRequest("POST", "/api/files?objectID=1&objectType=widget", bodyBuf)
|
||||
|
||||
// Create the request
|
||||
w := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), bodyBuf)
|
||||
assert.NoError(t, err, "create request")
|
||||
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
req.Header.Add("Authorization", "Bearer "+token)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equalf(t, 200, w.Code, "Response body: \n%v\n", w.Body)
|
||||
//fmt.Println(w.Body)
|
||||
|
||||
newFileID, err := common.GetResponseID(w.Body)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Count the number of all files returned for simulation model
|
||||
initialNumber, err := common.LengthOfResponse(router, token,
|
||||
fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), "GET", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Delete the added file
|
||||
code, resp, err := common.NewTestEndpoint(router, token,
|
||||
fmt.Sprintf("/api/files/%v", newFileID), "DELETE", nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||
|
||||
// Again count the number of all the files returned for simulation model
|
||||
finalNumber, err := common.LengthOfResponse(router, token,
|
||||
fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), "GET", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, initialNumber-1, finalNumber)
|
||||
}
|
||||
|
||||
func TestGetAllFilesOfSimulationModel(t *testing.T) {
|
||||
|
||||
common.DropTables(db)
|
||||
common.MigrateModels(db)
|
||||
common.DummyAddOnlyUserTableWithAdminAndUsersDB(db)
|
||||
|
||||
// prepare the content of the DB for testing
|
||||
// by adding a scenario and a simulator to the DB
|
||||
// using the respective endpoints of the API
|
||||
_, _, simulationModelID := addScenarioAndSimulatorAndSimulationModel()
|
||||
|
||||
// authenticate as normal user
|
||||
token, err := common.NewAuthenticateForTest(router,
|
||||
"/api/authenticate", "POST", common.UserACredentials)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Count the number of all files returned for simulation model
|
||||
initialNumber, err := common.LengthOfResponse(router, token,
|
||||
fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), "GET", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// create a testfile.txt in local folder
|
||||
c1 := []byte("This is my testfile\n")
|
||||
err = ioutil.WriteFile("testfile.txt", c1, 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// test POST files
|
||||
bodyBuf := &bytes.Buffer{}
|
||||
bodyWriter := multipart.NewWriter(bodyBuf)
|
||||
fileWriter, err := bodyWriter.CreateFormFile("file", "testuploadfile.txt")
|
||||
assert.NoError(t, err, "writing to buffer")
|
||||
|
||||
// open file handle
|
||||
fh, err := os.Open("testfile.txt")
|
||||
assert.NoError(t, err, "opening file")
|
||||
defer fh.Close()
|
||||
|
||||
// io copy
|
||||
_, err = io.Copy(fileWriter, fh)
|
||||
assert.NoError(t, err, "IO copy")
|
||||
|
||||
contentType := bodyWriter.FormDataContentType()
|
||||
bodyWriter.Close()
|
||||
//req, err := http.NewRequest("POST", "/api/files?objectID=1&objectType=widget", bodyBuf)
|
||||
|
||||
// Create the request
|
||||
w := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), bodyBuf)
|
||||
assert.NoError(t, err, "create request")
|
||||
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
req.Header.Add("Authorization", "Bearer "+token)
|
||||
router.ServeHTTP(w, req)
|
||||
assert.Equalf(t, 200, w.Code, "Response body: \n%v\n", w.Body)
|
||||
//fmt.Println(w.Body)
|
||||
|
||||
// POST a second file
|
||||
|
||||
bodyBuf2 := &bytes.Buffer{}
|
||||
bodyWriter2 := multipart.NewWriter(bodyBuf2)
|
||||
fileWriter2, err := bodyWriter2.CreateFormFile("file", "testuploadfile2.txt")
|
||||
assert.NoError(t, err, "writing to buffer")
|
||||
|
||||
// open file handle
|
||||
fh2, err := os.Open("testfile.txt")
|
||||
assert.NoError(t, err, "opening file")
|
||||
defer fh2.Close()
|
||||
|
||||
// io copy
|
||||
_, err = io.Copy(fileWriter2, fh2)
|
||||
assert.NoError(t, err, "IO copy")
|
||||
|
||||
contentType = bodyWriter2.FormDataContentType()
|
||||
bodyWriter2.Close()
|
||||
|
||||
w2 := httptest.NewRecorder()
|
||||
req, err = http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), bodyBuf2)
|
||||
assert.NoError(t, err, "create request")
|
||||
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
req.Header.Add("Authorization", "Bearer "+token)
|
||||
router.ServeHTTP(w2, req)
|
||||
assert.Equalf(t, 200, w2.Code, "Response body: \n%v\n", w2.Body)
|
||||
|
||||
// Again count the number of all the files returned for simulation model
|
||||
finalNumber, err := common.LengthOfResponse(router, token,
|
||||
fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), "GET", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, initialNumber+2, finalNumber)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue