diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fc4c800..53111e0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,7 @@ variables: DEPLOY_USER: deploy DEPLOY_HOST: acs-os-fein-website DEPLOY_PATH: /var/www/villas/api/web/ - TEST_FOLDER: routes/simulation + TEST_FOLDER: routes/scenario stages: - prepare @@ -80,7 +80,7 @@ test:database: dependencies: - build:backend -test:simulation: +test:scenario: stage: test tags: - docker @@ -96,32 +96,32 @@ test:simulation: - build:backend test:simulationmodel: - extends: test:simulation + extends: test:scenario variables: TEST_FOLDER: routes/simulationmodel test:signal: - extends: test:simulation + extends: test:scenario variables: TEST_FOLDER: routes/signal test:dashboard: - extends: test:simulation + extends: test:scenario variables: TEST_FOLDER: routes/dashboard test:widget: - extends: test:simulation + extends: test:scenario variables: TEST_FOLDER: routes/widget test:simulator: - extends: test:simulation + extends: test:scenario variables: TEST_FOLDER: routes/simulator test:file: - extends: test:simulation + extends: test:scenario variables: TEST_FOLDER: routes/file diff --git a/common/database.go b/common/database.go index 15fbbfd..7505b91 100644 --- a/common/database.go +++ b/common/database.go @@ -60,7 +60,7 @@ func DropTables(db *gorm.DB) { db.DropTableIfExists(&Signal{}) db.DropTableIfExists(&SimulationModel{}) db.DropTableIfExists(&File{}) - db.DropTableIfExists(&Simulation{}) + db.DropTableIfExists(&Scenario{}) db.DropTableIfExists(&User{}) db.DropTableIfExists(&Dashboard{}) db.DropTableIfExists(&Widget{}) @@ -72,7 +72,7 @@ func MigrateModels(db *gorm.DB) { db.AutoMigrate(&Signal{}) db.AutoMigrate(&SimulationModel{}) db.AutoMigrate(&File{}) - db.AutoMigrate(&Simulation{}) + db.AutoMigrate(&Scenario{}) db.AutoMigrate(&User{}) db.AutoMigrate(&Dashboard{}) db.AutoMigrate(&Widget{}) @@ -127,10 +127,10 @@ func DummyPopulateDB(test_db *gorm.DB) { checkErr(test_db.Create(&file_C).Error) checkErr(test_db.Create(&file_D).Error) - simn_A := Simulation{Name: "Simulation_A"} - simn_B := Simulation{Name: "Simulation_B"} - checkErr(test_db.Create(&simn_A).Error) - checkErr(test_db.Create(&simn_B).Error) + so_A := Scenario{Name: "Scenario_A"} + so_B := Scenario{Name: "Scenario_B"} + checkErr(test_db.Create(&so_A).Error) + checkErr(test_db.Create(&so_B).Error) // Hash passwords with bcrypt algorithm var bcryptCost = 10 @@ -168,19 +168,19 @@ func DummyPopulateDB(test_db *gorm.DB) { // For `belongs to` use the model with id=1 // For `has many` use the models with id=1 and id=2 - // User HM Simulations, Simulation HM Users (Many-to-Many) - checkErr(test_db.Model(&simn_A).Association("Users").Append(&usr_A).Error) - checkErr(test_db.Model(&simn_A).Association("Users").Append(&usr_B).Error) - checkErr(test_db.Model(&simn_B).Association("Users").Append(&usr_A).Error) - checkErr(test_db.Model(&simn_B).Association("Users").Append(&usr_B).Error) + // User HM Scenarios, Scenario HM Users (Many-to-Many) + checkErr(test_db.Model(&so_A).Association("Users").Append(&usr_A).Error) + checkErr(test_db.Model(&so_A).Association("Users").Append(&usr_B).Error) + checkErr(test_db.Model(&so_B).Association("Users").Append(&usr_A).Error) + checkErr(test_db.Model(&so_B).Association("Users").Append(&usr_B).Error) - // Simulation HM SimulationModels - checkErr(test_db.Model(&simn_A).Association("SimulationModels").Append(&mo_A).Error) - checkErr(test_db.Model(&simn_A).Association("SimulationModels").Append(&mo_B).Error) + // Scenario HM SimulationModels + checkErr(test_db.Model(&so_A).Association("SimulationModels").Append(&mo_A).Error) + checkErr(test_db.Model(&so_A).Association("SimulationModels").Append(&mo_B).Error) - // Simulation HM Dashboards - checkErr(test_db.Model(&simn_A).Association("Dashboards").Append(&dab_A).Error) - checkErr(test_db.Model(&simn_A).Association("Dashboards").Append(&dab_B).Error) + // Scenario HM Dashboards + checkErr(test_db.Model(&so_A).Association("Dashboards").Append(&dab_A).Error) + checkErr(test_db.Model(&so_A).Association("Dashboards").Append(&dab_B).Error) // Dashboard HM Widget checkErr(test_db.Model(&dab_A).Association("Widgets").Append(&widg_A).Error) diff --git a/common/database_test.go b/common/database_test.go index 7c538a5..d5f8cc7 100644 --- a/common/database_test.go +++ b/common/database_test.go @@ -31,7 +31,7 @@ func TestDummyDBAssociations(t *testing.T) { var simr Simulator var mo SimulationModel var file File - var simn Simulation + var so Scenario var usr User var usrs []User var dab Dashboard @@ -41,7 +41,7 @@ func TestDummyDBAssociations(t *testing.T) { var mos []SimulationModel var files []File var files_sm []File - var simns []Simulation + var sos []Scenario var dabs []Dashboard var widgs []Widget @@ -52,34 +52,34 @@ func TestDummyDBAssociations(t *testing.T) { // User Associations - a.NoError(db.Model(&usr).Related(&simns, "Simulations").Error) - if len(simns) != 2 { + a.NoError(db.Model(&usr).Related(&sos, "Scenarios").Error) + if len(sos) != 2 { a.Fail("User Associations", - "Expected to have %v Simulations. Has %v.", 2, len(simns)) + "Expected to have %v Scenarios. Has %v.", 2, len(sos)) } - // Simulation + // Scenario - a.NoError(db.Find(&simn, 1).Error, fM("Simulation")) - a.EqualValues("Simulation_A", simn.Name) + a.NoError(db.Find(&so, 1).Error, fM("Scenario")) + a.EqualValues("Scenario_A", so.Name) - // Simulation Associations + // Scenario Associations - a.NoError(db.Model(&simn).Association("Users").Find(&usrs).Error) + a.NoError(db.Model(&so).Association("Users").Find(&usrs).Error) if len(usrs) != 2 { - a.Fail("Simulations Associations", + a.Fail("Scenario Associations", "Expected to have %v Users. Has %v.", 2, len(usrs)) } - a.NoError(db.Model(&simn).Related(&mos, "SimulationModels").Error) + a.NoError(db.Model(&so).Related(&mos, "SimulationModels").Error) if len(mos) != 2 { - a.Fail("Simulation Associations", + a.Fail("Scenario Associations", "Expected to have %v simulation models. Has %v.", 2, len(mos)) } - a.NoError(db.Model(&simn).Related(&dabs, "Dashboards").Error) + a.NoError(db.Model(&so).Related(&dabs, "Dashboards").Error) if len(dabs) != 2 { - a.Fail("Simulation Associations", + a.Fail("Scenario Associations", "Expected to have %v Dashboards. Has %v.", 2, len(dabs)) } diff --git a/common/models.go b/common/models.go index 918bd41..bbfff25 100644 --- a/common/models.go +++ b/common/models.go @@ -12,26 +12,26 @@ type User struct { Mail string `gorm:"default:''"` // Role of user Role string `gorm:"default:'user'"` - // Simulations to which user has access - Simulations []*Simulation `gorm:"many2many:user_simulations"` + // Scenarios to which user has access + Scenarios []*Scenario `gorm:"many2many:user_scenarios"` } -// Simulation data model -type Simulation struct { - // ID of simulation +// Scenario data model +type Scenario struct { + // ID of scenario ID uint `gorm:"primary_key;auto_increment"` - // Name of simulation + // Name of scenario Name string `gorm:"not null"` - // Running state of simulation + // Running state of scenario Running bool `gorm:"default:false"` - // Start parameters of simulation as JSON string + // Start parameters of scenario as JSON string StartParameters string - // Users that have access to the simulation - Users []*User `gorm:"not null;many2many:user_simulations"` - // SimulationModels that belong to the simulation - SimulationModels []SimulationModel `gorm:"foreignkey:SimulationID"` - // Dashboards that belong to the simulation - Dashboards []Dashboard `gorm:"foreignkey:SimulationID"` + // Users that have access to the scenario + Users []*User `gorm:"not null;many2many:user_scenarios"` + // SimulationModels that belong to the scenario + SimulationModels []SimulationModel `gorm:"foreignkey:ScenarioID"` + // Dashboards that belong to the Scenario + Dashboards []Dashboard `gorm:"foreignkey:ScenarioID"` } // SimulationModel data model @@ -46,8 +46,8 @@ type SimulationModel struct { InputLength int `gorm:"default:1"` // Start parameters of simulation model as JSON string StartParameters string - // ID of simulation to which simulation model belongs - SimulationID uint + // ID of Scenario to which simulation model belongs + ScenarioID uint // ID of simulator associated with simulation model SimulatorID uint // Mapping of output signals of the simulation model, order of signals is important @@ -106,8 +106,8 @@ type Dashboard struct { Name string `gorm:"not null"` // Grid of dashboard Grid int `gorm:"default:15"` - // ID of simulation to which dashboard belongs - SimulationID uint + // ID of scenario to which dashboard belongs + ScenarioID uint // Widgets that belong to dashboard Widgets []Widget `gorm:"foreignkey:DashboardID"` } diff --git a/common/responses.go b/common/responses.go index 116d00b..a5d013f 100644 --- a/common/responses.go +++ b/common/responses.go @@ -7,7 +7,7 @@ type UserResponse struct { ID uint `json:"ID"` } -type SimulationResponse struct { +type ScenarioResponse struct { Name string `json:"Name"` ID uint `json:"ID"` Running bool `json:"Running"` @@ -19,7 +19,7 @@ type SimulationModelResponse struct { Name string `json:"Name"` OutputLength int `json:"OutputLength"` InputLength int `json:"InputLength"` - SimulationID uint `json:"SimulationID"` + ScenarioID uint `json:"ScenarioID"` SimulatorID uint `json:"SimulatorID"` StartParams string `json:"StartParams"` } @@ -37,10 +37,10 @@ type SimulatorResponse struct { } type DashboardResponse struct { - ID uint `json:"ID"` - Name string `json:"Name"` - Grid int `json:"Grid"` - SimulationID uint `json:"SimulationID"` + ID uint `json:"ID"` + Name string `json:"Name"` + Grid int `json:"Grid"` + ScenarioID uint `json:"ScenarioID"` } type WidgetResponse struct { @@ -93,12 +93,12 @@ type ResponseMsgUser struct { User UserResponse `json:"user"` } -type ResponseMsgSimulations struct { - Simulations []SimulationResponse `json:"simulations"` +type ResponseMsgScenarios struct { + Scenarios []ScenarioResponse `json:"scenarios"` } -type ResponseMsgSimulation struct { - Simulation SimulationResponse `json:"simulation"` +type ResponseMsgScenario struct { + Scenario ScenarioResponse `json:"scenario"` } type ResponseMsgSimulationModels struct { diff --git a/common/roles.go b/common/roles.go index 80669bc..120e344 100644 --- a/common/roles.go +++ b/common/roles.go @@ -15,7 +15,7 @@ import ( type ModelName string const ModelUser = ModelName("user") -const ModelSimulation = ModelName("simulation") +const ModelScenario = ModelName("scenario") const ModelSimulator = ModelName("simulator") const ModelSimulatorAction = ModelName("simulatoraction") const ModelDashboard = ModelName("dashboard") @@ -51,7 +51,7 @@ var _r__ = Permission{Create: false, Read: true, Update: false, Delete: false} var Roles = RoleActions{ "Admin": { ModelUser: crud, - ModelSimulation: crud, + ModelScenario: crud, ModelSimulationModel: crud, ModelSimulator: crud, ModelSimulatorAction: crud, @@ -62,7 +62,7 @@ var Roles = RoleActions{ }, "User": { ModelUser: __u_, - ModelSimulation: crud, + ModelScenario: crud, ModelSimulationModel: crud, ModelSimulator: _r__, ModelSimulatorAction: _ru_, @@ -72,7 +72,7 @@ var Roles = RoleActions{ ModelFile: crud, }, "Guest": { - ModelSimulation: _r__, + ModelScenario: _r__, ModelSimulationModel: _r__, ModelDashboard: _r__, ModelWidget: _r__, diff --git a/common/serializers.go b/common/serializers.go index a06b3da..99813dc 100644 --- a/common/serializers.go +++ b/common/serializers.go @@ -40,40 +40,40 @@ func (self *UserSerializer) Response(assoc bool) UserResponse { // TODO: maybe all those should be made in one transaction - //simulations, _, _ := simulation.FindUserSimulations(&self.User) - //simulationsSerializer := - // SimulationsSerializer{self.Ctx, simulations} + //scenarios, _, _ := scenario.FindUserScenarios(&self.User) + //scenariosSerializer := + // ScenariosSerializer{self.Ctx, scenarios} // Add the associated models to the response - //response.Simulations = simulationsSerializer.Response() + //response.Scenarios = scenariosSerializer.Response() } return response } -// Simulation/s Serializers +// Scenario/s Serializers -type SimulationsSerializer struct { - Ctx *gin.Context - Simulations []Simulation +type ScenariosSerializer struct { + Ctx *gin.Context + Scenarios []Scenario } -func (self *SimulationsSerializer) Response() []SimulationResponse { - response := []SimulationResponse{} - for _, simulation := range self.Simulations { - serializer := SimulationSerializer{self.Ctx, simulation} +func (self *ScenariosSerializer) Response() []ScenarioResponse { + response := []ScenarioResponse{} + for _, so := range self.Scenarios { + serializer := ScenarioSerializer{self.Ctx, so} response = append(response, serializer.Response()) } return response } -type SimulationSerializer struct { +type ScenarioSerializer struct { Ctx *gin.Context - Simulation + Scenario } -func (self *SimulationSerializer) Response() SimulationResponse { - response := SimulationResponse{ +func (self *ScenarioSerializer) Response() ScenarioResponse { + response := ScenarioResponse{ Name: self.Name, ID: self.ID, Running: self.Running, @@ -109,7 +109,7 @@ func (self *SimulationModelSerializer) Response() SimulationModelResponse { Name: self.Name, OutputLength: self.OutputLength, InputLength: self.InputLength, - SimulationID: self.SimulationID, + ScenarioID: self.ScenarioID, SimulatorID: self.SimulatorID, StartParams: self.StartParameters, } @@ -175,10 +175,10 @@ type DashboardSerializer struct { func (self *DashboardSerializer) Response() DashboardResponse { response := DashboardResponse{ - Name: self.Name, - Grid: self.Grid, - SimulationID: self.SimulationID, - ID: self.ID, + Name: self.Name, + Grid: self.Grid, + ScenarioID: self.ScenarioID, + ID: self.ID, } return response } diff --git a/routes/dashboard/dashboard_endpoints.go b/routes/dashboard/dashboard_endpoints.go index 7afbae1..b8a6e5d 100644 --- a/routes/dashboard/dashboard_endpoints.go +++ b/routes/dashboard/dashboard_endpoints.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" - "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation" + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/scenario" ) func RegisterDashboardEndpoints(r *gin.RouterGroup) { @@ -19,20 +19,20 @@ func RegisterDashboardEndpoints(r *gin.RouterGroup) { } // getDashboards godoc -// @Summary Get all dashboards of simulation +// @Summary Get all dashboards of scenario // @ID getDashboards // @Produce json // @Tags dashboards -// @Success 200 {array} common.DashboardResponse "Array of dashboards to which belong to simulation" +// @Success 200 {array} common.DashboardResponse "Array of dashboards to which belong to scenario" // @Failure 401 "Unauthorized Access" // @Failure 403 "Access forbidden." // @Failure 404 "Not found" // @Failure 500 "Internal server error" -// @Param simulationID query int true "Simulation ID" +// @Param scenarioID query int true "Scenario ID" // @Router /dashboards [get] func getDashboards(c *gin.Context) { - ok, sim := simulation.CheckPermissions(c, common.Read, "query", -1) + ok, sim := scenario.CheckPermissions(c, common.Read, "query", -1) if !ok { return } @@ -51,12 +51,12 @@ func getDashboards(c *gin.Context) { } // addDashboard godoc -// @Summary Add a dashboard to a simulation +// @Summary Add a dashboard to a scenario // @ID addDashboard // @Accept json // @Produce json // @Tags dashboards -// @Param inputDab body common.DashboardResponse true "Dashboard to be added incl. ID of simulation" +// @Param inputDab body common.DashboardResponse true "Dashboard to be added incl. ID of Scenario" // @Success 200 "OK." // @Failure 401 "Unauthorized Access" // @Failure 403 "Access forbidden." @@ -75,13 +75,13 @@ func addDashboard(c *gin.Context) { return } - ok, _ := simulation.CheckPermissions(c, common.Create, "body", int(newDab.SimulationID)) + ok, _ := scenario.CheckPermissions(c, common.Create, "body", int(newDab.ScenarioID)) if !ok { return } - // add dashboard to DB and add association to simulation - err = newDab.addToSimulation() + // add dashboard to DB and add association to scenario + err = newDab.addToScenario() if common.ProvideErrorResponse(c, err) == false { c.JSON(http.StatusOK, gin.H{ "message": "OK.", diff --git a/routes/dashboard/dashboard_methods.go b/routes/dashboard/dashboard_methods.go index 1c0ef90..33c94bf 100644 --- a/routes/dashboard/dashboard_methods.go +++ b/routes/dashboard/dashboard_methods.go @@ -4,7 +4,7 @@ import ( "fmt" "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" - "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation" + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/scenario" ) type Dashboard struct { @@ -26,10 +26,10 @@ func (d *Dashboard) ByID(id uint) error { return nil } -func (d *Dashboard) addToSimulation() error { +func (d *Dashboard) addToScenario() error { db := common.GetDB() - var sim simulation.Simulation - err := sim.ByID(d.SimulationID) + var sim scenario.Scenario + err := sim.ByID(d.ScenarioID) if err != nil { return err } @@ -40,7 +40,7 @@ func (d *Dashboard) addToSimulation() error { return err } - // associate dashboard with simulation + // associate dashboard with scenario err = db.Model(&sim).Association("Dashboards").Append(d).Error return err @@ -61,13 +61,13 @@ func (d *Dashboard) update(modifiedDab Dashboard) error { func (d *Dashboard) delete() error { db := common.GetDB() - var sim simulation.Simulation - err := sim.ByID(d.SimulationID) + var sim scenario.Scenario + err := sim.ByID(d.ScenarioID) if err != nil { return err } - // remove association between Dashboard and Simulation + // remove association between Dashboard and Scenario // Dashboard itself is not deleted from DB, it remains as "dangling" err = db.Model(&sim).Association("Dashboards").Delete(d).Error diff --git a/routes/dashboard/dashboard_middleware.go b/routes/dashboard/dashboard_middleware.go index be14a73..956d9ef 100644 --- a/routes/dashboard/dashboard_middleware.go +++ b/routes/dashboard/dashboard_middleware.go @@ -2,13 +2,13 @@ package dashboard import ( "fmt" + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/scenario" "net/http" "strconv" "github.com/gin-gonic/gin" "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" - "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation" ) func CheckPermissions(c *gin.Context, operation common.CRUD, dabIDSource string, dabIDBody int) (bool, Dashboard) { @@ -49,7 +49,7 @@ func CheckPermissions(c *gin.Context, operation common.CRUD, dabIDSource string, return false, dab } - ok, _ := simulation.CheckPermissions(c, operation, "body", int(dab.SimulationID)) + ok, _ := scenario.CheckPermissions(c, operation, "body", int(dab.ScenarioID)) if !ok { return false, dab } diff --git a/routes/dashboard/dashboard_test.go b/routes/dashboard/dashboard_test.go index 19193fb..8162df6 100644 --- a/routes/dashboard/dashboard_test.go +++ b/routes/dashboard/dashboard_test.go @@ -27,45 +27,45 @@ var msgOK = common.ResponseMsg{ } var dabA = common.DashboardResponse{ - ID: 1, - Name: "Dashboard_A", - Grid: 15, - SimulationID: 1, + ID: 1, + Name: "Dashboard_A", + Grid: 15, + ScenarioID: 1, } var dabB = common.DashboardResponse{ - ID: 2, - Name: "Dashboard_B", - Grid: 15, - SimulationID: 1, + ID: 2, + Name: "Dashboard_B", + Grid: 15, + ScenarioID: 1, } var dabC = common.Dashboard{ - ID: 3, - Name: "Dashboard_C", - Grid: 99, - SimulationID: 1, + ID: 3, + Name: "Dashboard_C", + Grid: 99, + ScenarioID: 1, } var dabCupdated = common.Dashboard{ - ID: dabC.ID, - Name: "Dashboard_CUpdated", - SimulationID: dabC.SimulationID, - Grid: dabC.Grid, + ID: dabC.ID, + Name: "Dashboard_CUpdated", + ScenarioID: dabC.ScenarioID, + Grid: dabC.Grid, } var dabC_response = common.DashboardResponse{ - ID: dabC.ID, - Name: dabC.Name, - Grid: dabC.Grid, - SimulationID: dabC.SimulationID, + ID: dabC.ID, + Name: dabC.Name, + Grid: dabC.Grid, + ScenarioID: dabC.ScenarioID, } var dabC_responseUpdated = common.DashboardResponse{ - ID: dabCupdated.ID, - Name: dabCupdated.Name, - Grid: dabCupdated.Grid, - SimulationID: dabCupdated.SimulationID, + ID: dabCupdated.ID, + Name: dabCupdated.Name, + Grid: dabCupdated.Grid, + ScenarioID: dabCupdated.ScenarioID, } var myDashboards = []common.DashboardResponse{ @@ -140,22 +140,22 @@ func TestEndpoints(t *testing.T) { token = common.AuthenticateForTest(t, router, "/api/authenticate", "POST", credjson, 200) - // test GET models - common.TestEndpoint(t, router, token, "/api/dashboards?simulationID=1", "GET", nil, 200, string(msgDashboardsjson)) + // test GET dashboards + common.TestEndpoint(t, router, token, "/api/dashboards?scenarioID=1", "GET", nil, 200, string(msgDashboardsjson)) - // test POST models + // test POST dashboards common.TestEndpoint(t, router, token, "/api/dashboards", "POST", dabCjson, 200, string(msgOKjson)) - // test GET models/:ModelID to check if previous POST worked correctly + // test GET dashboards/:dashboardID to check if previous POST worked correctly common.TestEndpoint(t, router, token, "/api/dashboards/3", "GET", nil, 200, string(msgDabjson)) - // test PUT models/:ModelID + // test PUT dashboards/:dashboardID common.TestEndpoint(t, router, token, "/api/dashboards/3", "PUT", dabCupdatedjson, 200, string(msgOKjson)) common.TestEndpoint(t, router, token, "/api/dashboards/3", "GET", nil, 200, string(msgDabupdatedjson)) - // test DELETE models/:ModelID + // test DELETE dashboards/:dashboardID common.TestEndpoint(t, router, token, "/api/dashboards/3", "DELETE", nil, 200, string(msgOKjson)) - common.TestEndpoint(t, router, token, "/api/dashboards?simulationID=1", "GET", nil, 200, string(msgDashboardsjson)) + common.TestEndpoint(t, router, token, "/api/dashboards?scenarioID=1", "GET", nil, 200, string(msgDashboardsjson)) // TODO add testing for other return codes diff --git a/routes/simulation/simulation_endpoints.go b/routes/scenario/scenario_endpoints.go similarity index 50% rename from routes/simulation/simulation_endpoints.go rename to routes/scenario/scenario_endpoints.go index 97066ef..b1dab79 100644 --- a/routes/simulation/simulation_endpoints.go +++ b/routes/scenario/scenario_endpoints.go @@ -1,4 +1,4 @@ -package simulation +package scenario import ( "net/http" @@ -9,29 +9,29 @@ import ( "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/user" ) -func RegisterSimulationEndpoints(r *gin.RouterGroup) { - r.GET("", getSimulations) - r.POST("", addSimulation) - r.PUT("/:simulationID", updateSimulation) - r.GET("/:simulationID", getSimulation) - r.DELETE("/:simulationID", deleteSimulation) - r.GET("/:simulationID/users", getUsersOfSimulation) - r.PUT("/:simulationID/user", addUserToSimulation) - r.DELETE("/:simulationID/user", deleteUserFromSimulation) +func RegisterScenarioEndpoints(r *gin.RouterGroup) { + r.GET("", getScenarios) + r.POST("", addScenario) + r.PUT("/:scenarioID", updateScenario) + r.GET("/:scenarioID", getScenario) + r.DELETE("/:scenarioID", deleteScenario) + r.GET("/:scenarioID/users", getUsersOfScenario) + r.PUT("/:scenarioID/user", addUserToScenario) + r.DELETE("/:scenarioID/user", deleteUserFromScenario) } -// getSimulations godoc -// @Summary Get all simulations -// @ID getSimulations +// getScenarios godoc +// @Summary Get all scenarios +// @ID getScenarios // @Produce json -// @Tags simulations -// @Success 200 {array} common.SimulationResponse "Array of simulations to which user has access" +// @Tags scenarios +// @Success 200 {array} common.ScenarioResponse "Array of scenarios to which user has access" // @Failure 401 "Unauthorized Access" // @Failure 403 "Access forbidden." // @Failure 404 "Not found" // @Failure 500 "Internal server error" -// @Router /simulations [get] -func getSimulations(c *gin.Context) { +// @Router /scenarios [get] +func getScenarios(c *gin.Context) { ok, _ := CheckPermissions(c, common.Read, "none", -1) if !ok { @@ -48,42 +48,42 @@ func getSimulations(c *gin.Context) { return } - // get all simulations for the user who issues the request + // get all scenarios for the user who issues the request db := common.GetDB() - var simulations []common.Simulation - if userRole == "Admin" { // Admin can see all simulations - err = db.Order("ID asc").Find(&simulations).Error + var scenarios []common.Scenario + if userRole == "Admin" { // Admin can see all scenarios + err = db.Order("ID asc").Find(&scenarios).Error if common.ProvideErrorResponse(c, err) { return } - } else { // User or Guest roles see only their simulations - err = db.Order("ID asc").Model(&u).Related(&simulations, "Simulations").Error + } else { // User or Guest roles see only their scenarios + err = db.Order("ID asc").Model(&u).Related(&scenarios, "Scenarios").Error if common.ProvideErrorResponse(c, err) { return } } - serializer := common.SimulationsSerializer{c, simulations} + serializer := common.ScenariosSerializer{c, scenarios} c.JSON(http.StatusOK, gin.H{ - "simulations": serializer.Response(), + "scenarios": serializer.Response(), }) } -// addSimulation godoc -// @Summary Add a simulation -// @ID addSimulation +// addScenario godoc +// @Summary Add a scenario +// @ID addScenario // @Accept json // @Produce json -// @Tags simulations -// @Param inputSimulation body common.SimulationResponse true "Simulation to be added" +// @Tags scenarios +// @Param inputScenario body common.ScenarioResponse true "Scenario to be added" // @Success 200 "OK." // @Failure 401 "Unauthorized Access" // @Failure 403 "Access forbidden." // @Failure 404 "Not found" // @Failure 500 "Internal server error" -// @Router /simulations [post] -func addSimulation(c *gin.Context) { +// @Router /scenarios [post] +func addScenario(c *gin.Context) { ok, _ := CheckPermissions(c, common.Create, "none", -1) if !ok { @@ -98,8 +98,8 @@ func addSimulation(c *gin.Context) { return } - var sim Simulation - err = c.BindJSON(&sim) + var so Scenario + err = c.BindJSON(&so) if err != nil { errormsg := "Bad request. Error binding form data to JSON: " + err.Error() c.JSON(http.StatusBadRequest, gin.H{ @@ -108,14 +108,14 @@ func addSimulation(c *gin.Context) { return } - // save new simulation to DB - err = sim.save() + // save new scenario to DB + err = so.save() if common.ProvideErrorResponse(c, err) { return } - // add user to new simulation - err = sim.addUser(&(u.User)) + // add user to new scenario + err = so.addUser(&(u.User)) if common.ProvideErrorResponse(c, err) == false { c.JSON(http.StatusOK, gin.H{ "message": "OK.", @@ -123,29 +123,29 @@ func addSimulation(c *gin.Context) { } } -// updateSimulation godoc -// @Summary Update a simulation -// @ID updateSimulation -// @Tags simulations +// updateScenario godoc +// @Summary Update a scenario +// @ID updateScenario +// @Tags scenarios // @Accept json // @Produce json -// @Param inputSimulation body common.SimulationResponse true "Simulation to be updated" +// @Param inputScenario body common.ScenarioResponse true "Scenario to be updated" // @Success 200 "OK." // @Failure 401 "Unauthorized Access" // @Failure 403 "Access forbidden." // @Failure 404 "Not found" // @Failure 500 "Internal server error" -// @Param simulationID path int true "Simulation ID" -// @Router /simulations/{simulationID} [put] -func updateSimulation(c *gin.Context) { +// @Param scenarioID path int true "Scenario ID" +// @Router /scenarios/{scenarioID} [put] +func updateScenario(c *gin.Context) { - ok, sim := CheckPermissions(c, common.Update, "path", -1) + ok, so := CheckPermissions(c, common.Update, "path", -1) if !ok { return } - var modifiedSim Simulation - err := c.BindJSON(&modifiedSim) + var modifiedSo Scenario + err := c.BindJSON(&modifiedSo) if err != nil { errormsg := "Bad request. Error binding form data to JSON: " + err.Error() c.JSON(http.StatusBadRequest, gin.H{ @@ -154,7 +154,7 @@ func updateSimulation(c *gin.Context) { return } - err = sim.update(modifiedSim) + err = so.update(modifiedSo) if common.ProvideErrorResponse(c, err) == false { c.JSON(http.StatusOK, gin.H{ "message": "OK.", @@ -162,51 +162,51 @@ func updateSimulation(c *gin.Context) { } } -// getSimulation godoc -// @Summary Get simulation -// @ID getSimulation +// getScenario godoc +// @Summary Get scenario +// @ID getScenario // @Produce json -// @Tags simulations -// @Success 200 {object} common.SimulationResponse "Simulation requested by user" +// @Tags scenarios +// @Success 200 {object} common.ScenarioResponse "Scenario requested by user" // @Failure 401 "Unauthorized Access" // @Failure 403 "Access forbidden." // @Failure 404 "Not found" // @Failure 500 "Internal server error" -// @Param simulationID path int true "Simulation ID" -// @Router /simulations/{simulationID} [get] -func getSimulation(c *gin.Context) { +// @Param scenarioID path int true "Scenario ID" +// @Router /scenarios/{scenarioID} [get] +func getScenario(c *gin.Context) { - ok, sim := CheckPermissions(c, common.Read, "path", -1) + ok, so := CheckPermissions(c, common.Read, "path", -1) if !ok { return } - serializer := common.SimulationSerializer{c, sim.Simulation} + serializer := common.ScenarioSerializer{c, so.Scenario} c.JSON(http.StatusOK, gin.H{ - "simulation": serializer.Response(), + "scenario": serializer.Response(), }) } -// deleteSimulation godoc -// @Summary Delete a simulation -// @ID deleteSimulation -// @Tags simulations +// deleteScenario godoc +// @Summary Delete a scenario +// @ID deleteScenario +// @Tags scenarios // @Produce json // @Success 200 "OK." // @Failure 401 "Unauthorized Access" // @Failure 403 "Access forbidden." // @Failure 404 "Not found" // @Failure 500 "Internal server error" -// @Param simulationID path int true "Simulation ID" -// @Router /simulations/{simulationID} [delete] -func deleteSimulation(c *gin.Context) { +// @Param scenarioID path int true "Scenario ID" +// @Router /scenarios/{scenarioID} [delete] +func deleteScenario(c *gin.Context) { - ok, sim := CheckPermissions(c, common.Delete, "path", -1) + ok, so := CheckPermissions(c, common.Delete, "path", -1) if !ok { return } - err := sim.delete() + err := so.delete() if common.ProvideErrorResponse(c, err) == false { c.JSON(http.StatusOK, gin.H{ "message": "OK.", @@ -214,27 +214,27 @@ func deleteSimulation(c *gin.Context) { } } -// getUsersOfSimulation godoc -// @Summary Get users of simulation -// @ID getUsersOfSimulation +// getUsersOfScenario godoc +// @Summary Get users of a scenario +// @ID getUsersOfScenario // @Produce json -// @Tags simulations -// @Success 200 {array} common.UserResponse "Array of users that have access to the simulation" +// @Tags scenarios +// @Success 200 {array} common.UserResponse "Array of users that have access to the scenario" // @Failure 401 "Unauthorized Access" // @Failure 403 "Access forbidden." // @Failure 404 "Not found" // @Failure 500 "Internal server error" -// @Param simulationID path int true "Simulation ID" -// @Router /simulations/{simulationID}/users/ [get] -func getUsersOfSimulation(c *gin.Context) { +// @Param scenarioID path int true "Scenario ID" +// @Router /scenarios/{scenarioID}/users/ [get] +func getUsersOfScenario(c *gin.Context) { - ok, sim := CheckPermissions(c, common.Read, "path", -1) + ok, so := CheckPermissions(c, common.Read, "path", -1) if !ok { return } - // Find all users of simulation - allUsers, _, err := sim.getUsers() + // Find all users of scenario + allUsers, _, err := so.getUsers() if common.ProvideErrorResponse(c, err) { return } @@ -245,22 +245,22 @@ func getUsersOfSimulation(c *gin.Context) { }) } -// addUserToSimulation godoc -// @Summary Add a user to a a simulation -// @ID addUserToSimulation -// @Tags simulations +// addUserToScenario godoc +// @Summary Add a user to a a scenario +// @ID addUserToScenario +// @Tags scenarios // @Produce json // @Success 200 "OK." // @Failure 401 "Unauthorized Access" // @Failure 403 "Access forbidden." // @Failure 404 "Not found" // @Failure 500 "Internal server error" -// @Param simulationID path int true "Simulation ID" +// @Param scenarioID path int true "Scenario ID" // @Param username query string true "User name" -// @Router /simulations/{simulationID}/user [put] -func addUserToSimulation(c *gin.Context) { +// @Router /scenarios/{scenarioID}/user [put] +func addUserToScenario(c *gin.Context) { - ok, sim := CheckPermissions(c, common.Update, "path", -1) + ok, so := CheckPermissions(c, common.Update, "path", -1) if !ok { return } @@ -273,7 +273,7 @@ func addUserToSimulation(c *gin.Context) { return } - err = sim.addUser(&(u.User)) + err = so.addUser(&(u.User)) if common.ProvideErrorResponse(c, err) { return } @@ -283,29 +283,29 @@ func addUserToSimulation(c *gin.Context) { }) } -// deleteUserFromSimulation godoc -// @Summary Delete a user from a simulation -// @ID deleteUserFromSimulation -// @Tags simulations +// deleteUserFromScenario godoc +// @Summary Delete a user from a scenario +// @ID deleteUserFromScenario +// @Tags scenarios // @Produce json // @Success 200 "OK." // @Failure 401 "Unauthorized Access" // @Failure 403 "Access forbidden." // @Failure 404 "Not found" // @Failure 500 "Internal server error" -// @Param simulationID path int true "Simulation ID" +// @Param scenarioID path int true "Scenario ID" // @Param username query string true "User name" -// @Router /simulations/{simulationID}/user [delete] -func deleteUserFromSimulation(c *gin.Context) { +// @Router /scenarios/{scenarioID}/user [delete] +func deleteUserFromScenario(c *gin.Context) { - ok, sim := CheckPermissions(c, common.Update, "path", -1) + ok, so := CheckPermissions(c, common.Update, "path", -1) if !ok { return } username := c.Request.URL.Query().Get("username") - err := sim.deleteUser(username) + err := so.deleteUser(username) if common.ProvideErrorResponse(c, err) { return } diff --git a/routes/simulation/simulation_methods.go b/routes/scenario/scenario_methods.go similarity index 58% rename from routes/simulation/simulation_methods.go rename to routes/scenario/scenario_methods.go index 7a3d5b1..745cb7e 100644 --- a/routes/simulation/simulation_methods.go +++ b/routes/scenario/scenario_methods.go @@ -1,4 +1,4 @@ -package simulation +package scenario import ( "fmt" @@ -7,46 +7,46 @@ import ( "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/user" ) -type Simulation struct { - common.Simulation +type Scenario struct { + common.Scenario } -func (s *Simulation) ByID(id uint) error { +func (s *Scenario) ByID(id uint) error { db := common.GetDB() err := db.Find(s, id).Error if err != nil { - return fmt.Errorf("simulation with id=%v does not exist", id) + return fmt.Errorf("scenario with id=%v does not exist", id) } return nil } -func (s *Simulation) getUsers() ([]common.User, int, error) { +func (s *Scenario) getUsers() ([]common.User, int, error) { db := common.GetDB() var users []common.User err := db.Order("ID asc").Model(s).Related(&users, "Users").Error return users, len(users), err } -func (s *Simulation) save() error { +func (s *Scenario) save() error { db := common.GetDB() err := db.Create(s).Error return err } -func (s *Simulation) update(modifiedSimulation Simulation) error { +func (s *Scenario) update(modifiedScenario Scenario) error { db := common.GetDB() - err := db.Model(s).Update(modifiedSimulation).Error + err := db.Model(s).Update(modifiedScenario).Error return err } -func (s *Simulation) addUser(u *common.User) error { +func (s *Scenario) addUser(u *common.User) error { db := common.GetDB() err := db.Model(s).Association("Users").Append(u).Error return err } -func (s *Simulation) deleteUser(username string) error { +func (s *Scenario) deleteUser(username string) error { db := common.GetDB() var deletedUser user.User @@ -58,27 +58,27 @@ func (s *Simulation) deleteUser(username string) error { no_users := db.Model(s).Association("Users").Count() if no_users > 1 { - // remove user from simulation + // remove user from scenario err = db.Model(s).Association("Users").Delete(&deletedUser.User).Error if err != nil { return err } - // remove simulation from user - err = db.Model(&deletedUser.User).Association("Simulations").Delete(s).Error + // remove scenario from user + err = db.Model(&deletedUser.User).Association("Scenarios").Delete(s).Error if err != nil { return err } } else { - return fmt.Errorf("cannot delete last user from simulation without deleting simulation itself, doing nothing") + return fmt.Errorf("cannot delete last user from scenario without deleting scenario itself, doing nothing") } return nil } -func (s *Simulation) delete() error { +func (s *Scenario) delete() error { db := common.GetDB() - // delete simulation from all users and vice versa + // delete scenario from all users and vice versa users, no_users, err := s.getUsers() if err != nil { @@ -87,23 +87,23 @@ func (s *Simulation) delete() error { if no_users > 0 { for _, u := range users { - // remove user from simulation + // remove user from scenario err = db.Model(s).Association("Users").Delete(&u).Error if err != nil { return err } - // remove simulation from user - err = db.Model(&u).Association("Simulations").Delete(s).Error + // remove scenario from user + err = db.Model(&u).Association("Scenarios").Delete(s).Error if err != nil { return err } } } - // Simulation is not deleted from DB, only associations with users are removed - // Simulation remains "dangling" in DB + // Scenario is not deleted from DB, only associations with users are removed + // Scenario remains "dangling" in DB - // Delete simulation + // Delete scenario //err = db.Delete(s).Error //if err != nil { // return err @@ -112,7 +112,7 @@ func (s *Simulation) delete() error { return nil } -func (s *Simulation) checkAccess(userID uint, userRole string) bool { +func (s *Scenario) checkAccess(userID uint, userRole string) bool { if userRole == "Admin" { return true diff --git a/routes/simulation/simulation_middleware.go b/routes/scenario/scenario_middleware.go similarity index 60% rename from routes/simulation/simulation_middleware.go rename to routes/scenario/scenario_middleware.go index d2231a1..be83ba4 100644 --- a/routes/simulation/simulation_middleware.go +++ b/routes/scenario/scenario_middleware.go @@ -1,4 +1,4 @@ -package simulation +package scenario import ( "fmt" @@ -10,62 +10,62 @@ import ( "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" ) -func CheckPermissions(c *gin.Context, operation common.CRUD, simIDSource string, simIDBody int) (bool, Simulation) { +func CheckPermissions(c *gin.Context, operation common.CRUD, simIDSource string, simIDBody int) (bool, Scenario) { - var sim Simulation + var so Scenario - err := common.ValidateRole(c, common.ModelSimulation, operation) + err := common.ValidateRole(c, common.ModelScenario, operation) if err != nil { c.JSON(http.StatusUnprocessableEntity, "Access denied (role validation failed).") - return false, sim + return false, so } if operation == common.Create || (operation == common.Read && simIDSource == "none") { - return true, sim + return true, so } var simID int if simIDSource == "path" { - simID, err = strconv.Atoi(c.Param("simulationID")) + simID, err = strconv.Atoi(c.Param("scenarioID")) if err != nil { - errormsg := fmt.Sprintf("Bad request. No or incorrect format of simulationID path parameter") + errormsg := fmt.Sprintf("Bad request. No or incorrect format of scenarioID path parameter") c.JSON(http.StatusBadRequest, gin.H{ "error": errormsg, }) - return false, sim + return false, so } } else if simIDSource == "query" { - simID, err = strconv.Atoi(c.Request.URL.Query().Get("simulationID")) + simID, err = strconv.Atoi(c.Request.URL.Query().Get("scenarioID")) if err != nil { - errormsg := fmt.Sprintf("Bad request. No or incorrect format of simulationID query parameter") + errormsg := fmt.Sprintf("Bad request. No or incorrect format of scenarioID query parameter") c.JSON(http.StatusBadRequest, gin.H{ "error": errormsg, }) - return false, sim + return false, so } } else if simIDSource == "body" { simID = simIDBody } else { - errormsg := fmt.Sprintf("Bad request. The following source of your simulation ID is not valid: %s", simIDSource) + errormsg := fmt.Sprintf("Bad request. The following source of your scenario ID is not valid: %s", simIDSource) c.JSON(http.StatusBadRequest, gin.H{ "error": errormsg, }) - return false, sim + return false, so } userID, _ := c.Get(common.UserIDCtx) userRole, _ := c.Get(common.UserRoleCtx) - err = sim.ByID(uint(simID)) + err = so.ByID(uint(simID)) if common.ProvideErrorResponse(c, err) { - return false, sim + return false, so } - if sim.checkAccess(userID.(uint), userRole.(string)) == false { - c.JSON(http.StatusUnprocessableEntity, "Access denied (for simulation ID).") - return false, sim + if so.checkAccess(userID.(uint), userRole.(string)) == false { + c.JSON(http.StatusUnprocessableEntity, "Access denied (for scenario ID).") + return false, so } - return true, sim + return true, so } diff --git a/routes/scenario/scenario_test.go b/routes/scenario/scenario_test.go new file mode 100644 index 0000000..b591876 --- /dev/null +++ b/routes/scenario/scenario_test.go @@ -0,0 +1,180 @@ +package scenario + +import ( + "encoding/json" + "testing" + + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/user" + + "github.com/gin-gonic/gin" + + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" +) + +var token string + +type credentials struct { + Username string `json:"username"` + Password string `json:"password"` +} + +var cred = credentials{ + Username: "User_A", + Password: "abc123", +} + +var msgOK = common.ResponseMsg{ + Message: "OK.", +} + +var user_A = common.UserResponse{ + Username: "User_A", + Role: "User", + Mail: "", + ID: 2, +} + +var user_B = common.UserResponse{ + Username: "User_B", + Role: "User", + Mail: "", + ID: 3, +} + +var myUsers = []common.UserResponse{ + user_A, + user_B, +} + +var myUserA = []common.UserResponse{ + user_A, +} + +var msgUsers = common.ResponseMsgUsers{ + Users: myUsers, +} + +var msgUserA = common.ResponseMsgUsers{ + Users: myUserA, +} + +var scenarioA = common.ScenarioResponse{ + Name: "Scenario_A", + ID: 1, + Running: false, +} + +var scenarioB = common.ScenarioResponse{ + Name: "Scenario_B", + ID: 2, + Running: false, +} + +var scenarioC = common.Scenario{ + Name: "Scenario_C", + Running: false, + StartParameters: "test", +} + +var scenarioC_response = common.ScenarioResponse{ + ID: 3, + Name: scenarioC.Name, + Running: scenarioC.Running, + StartParams: scenarioC.StartParameters, +} + +var myScenarios = []common.ScenarioResponse{ + scenarioA, + scenarioB, +} + +var msgScenarios = common.ResponseMsgScenarios{ + Scenarios: myScenarios, +} + +var msgScenario = common.ResponseMsgScenario{ + Scenario: scenarioC_response, +} + +// Test /scenarios endpoints +func TestScenarioEndpoints(t *testing.T) { + + db := common.DummyInitDB() + defer db.Close() + common.DummyPopulateDB(db) + + router := gin.Default() + api := router.Group("/api") + + // All endpoints require authentication except when someone wants to + // login (POST /authenticate) + user.VisitorAuthenticate(api.Group("/authenticate")) + + api.Use(user.Authentication(true)) + + RegisterScenarioEndpoints(api.Group("/scenarios")) + + credjson, err := json.Marshal(cred) + + msgOKjson, err := json.Marshal(msgOK) + if err != nil { + panic(err) + } + + msgUsersjson, err := json.Marshal(msgUsers) + if err != nil { + panic(err) + } + + msgUserAjson, err := json.Marshal(msgUserA) + if err != nil { + panic(err) + } + + msgScenariosjson, err := json.Marshal(msgScenarios) + if err != nil { + panic(err) + } + + msgScenariojson, err := json.Marshal(msgScenario) + if err != nil { + panic(err) + } + + scenarioCjson, err := json.Marshal(scenarioC) + if err != nil { + panic(err) + } + + token = common.AuthenticateForTest(t, router, "/api/authenticate", "POST", credjson, 200) + + // test GET scenarios/ + common.TestEndpoint(t, router, token, "/api/scenarios", "GET", nil, 200, string(msgScenariosjson)) + + // test POST scenarios/ + common.TestEndpoint(t, router, token, "/api/scenarios", "POST", scenarioCjson, 200, string(msgOKjson)) + + // test GET scenarios/:ScenarioID + common.TestEndpoint(t, router, token, "/api/scenarios/3", "GET", nil, 200, string(msgScenariojson)) + + // test DELETE scenarios/:ScenarioID + common.TestEndpoint(t, router, token, "/api/scenarios/3", "DELETE", nil, 200, string(msgOKjson)) + common.TestEndpoint(t, router, token, "/api/scenarios", "GET", nil, 200, string(msgScenariosjson)) + + // test GET scenarios/:ScenarioID/users + common.TestEndpoint(t, router, token, "/api/scenarios/1/users", "GET", nil, 200, string(msgUsersjson)) + + // test DELETE scenarios/:ScenarioID/user + common.TestEndpoint(t, router, token, "/api/scenarios/1/user?username=User_B", "DELETE", nil, 200, string(msgOKjson)) + common.TestEndpoint(t, router, token, "/api/scenarios/1/users", "GET", nil, 200, string(msgUserAjson)) + + // test PUT scenarios/:ScenarioID/user + common.TestEndpoint(t, router, token, "/api/scenarios/1/user?username=User_B", "PUT", nil, 200, string(msgOKjson)) + common.TestEndpoint(t, router, token, "/api/scenarios/1/users", "GET", nil, 200, string(msgUsersjson)) + + // test DELETE scenarios/:ScenarioID/user for logged in user User_A + common.TestEndpoint(t, router, token, "/api/scenarios/1/user?username=User_A", "DELETE", nil, 200, string(msgOKjson)) + common.TestEndpoint(t, router, token, "/api/scenarios/1/users", "GET", nil, 422, "\"Access denied (for scenario ID).\"") + + // TODO add tests for other return codes +} diff --git a/routes/simulation/simulation_test.go b/routes/simulation/simulation_test.go deleted file mode 100644 index a51d4bb..0000000 --- a/routes/simulation/simulation_test.go +++ /dev/null @@ -1,180 +0,0 @@ -package simulation - -import ( - "encoding/json" - "testing" - - "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/user" - - "github.com/gin-gonic/gin" - - "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" -) - -var token string - -type credentials struct { - Username string `json:"username"` - Password string `json:"password"` -} - -var cred = credentials{ - Username: "User_A", - Password: "abc123", -} - -var msgOK = common.ResponseMsg{ - Message: "OK.", -} - -var user_A = common.UserResponse{ - Username: "User_A", - Role: "User", - Mail: "", - ID: 2, -} - -var user_B = common.UserResponse{ - Username: "User_B", - Role: "User", - Mail: "", - ID: 3, -} - -var myUsers = []common.UserResponse{ - user_A, - user_B, -} - -var myUserA = []common.UserResponse{ - user_A, -} - -var msgUsers = common.ResponseMsgUsers{ - Users: myUsers, -} - -var msgUserA = common.ResponseMsgUsers{ - Users: myUserA, -} - -var simulationA = common.SimulationResponse{ - Name: "Simulation_A", - ID: 1, - Running: false, -} - -var simulationB = common.SimulationResponse{ - Name: "Simulation_B", - ID: 2, - Running: false, -} - -var simulationC = common.Simulation{ - Name: "Simulation_C", - Running: false, - StartParameters: "test", -} - -var simulationC_response = common.SimulationResponse{ - ID: 3, - Name: simulationC.Name, - Running: simulationC.Running, - StartParams: simulationC.StartParameters, -} - -var mySimulations = []common.SimulationResponse{ - simulationA, - simulationB, -} - -var msgSimulations = common.ResponseMsgSimulations{ - Simulations: mySimulations, -} - -var msgSimulation = common.ResponseMsgSimulation{ - Simulation: simulationC_response, -} - -// Test /simulation endpoints -func TestSimulationEndpoints(t *testing.T) { - - db := common.DummyInitDB() - defer db.Close() - common.DummyPopulateDB(db) - - router := gin.Default() - api := router.Group("/api") - - // All endpoints require authentication except when someone wants to - // login (POST /authenticate) - user.VisitorAuthenticate(api.Group("/authenticate")) - - api.Use(user.Authentication(true)) - - RegisterSimulationEndpoints(api.Group("/simulations")) - - credjson, err := json.Marshal(cred) - - msgOKjson, err := json.Marshal(msgOK) - if err != nil { - panic(err) - } - - msgUsersjson, err := json.Marshal(msgUsers) - if err != nil { - panic(err) - } - - msgUserAjson, err := json.Marshal(msgUserA) - if err != nil { - panic(err) - } - - msgSimulationsjson, err := json.Marshal(msgSimulations) - if err != nil { - panic(err) - } - - msgSimulationjson, err := json.Marshal(msgSimulation) - if err != nil { - panic(err) - } - - simulationCjson, err := json.Marshal(simulationC) - if err != nil { - panic(err) - } - - token = common.AuthenticateForTest(t, router, "/api/authenticate", "POST", credjson, 200) - - // test GET simulations/ - common.TestEndpoint(t, router, token, "/api/simulations", "GET", nil, 200, string(msgSimulationsjson)) - - // test POST simulations/ - common.TestEndpoint(t, router, token, "/api/simulations", "POST", simulationCjson, 200, string(msgOKjson)) - - // test GET simulations/:SimulationID - common.TestEndpoint(t, router, token, "/api/simulations/3", "GET", nil, 200, string(msgSimulationjson)) - - // test DELETE simulations/:SimulationID - common.TestEndpoint(t, router, token, "/api/simulations/3", "DELETE", nil, 200, string(msgOKjson)) - common.TestEndpoint(t, router, token, "/api/simulations", "GET", nil, 200, string(msgSimulationsjson)) - - // test GET simulations/:SimulationID/users - common.TestEndpoint(t, router, token, "/api/simulations/1/users", "GET", nil, 200, string(msgUsersjson)) - - // test DELETE simulations/:SimulationID/user - common.TestEndpoint(t, router, token, "/api/simulations/1/user?username=User_B", "DELETE", nil, 200, string(msgOKjson)) - common.TestEndpoint(t, router, token, "/api/simulations/1/users", "GET", nil, 200, string(msgUserAjson)) - - // test PUT simulations/:SimulationID/user - common.TestEndpoint(t, router, token, "/api/simulations/1/user?username=User_B", "PUT", nil, 200, string(msgOKjson)) - common.TestEndpoint(t, router, token, "/api/simulations/1/users", "GET", nil, 200, string(msgUsersjson)) - - // test DELETE simulations/:SimulationID/user for logged in user User_A - common.TestEndpoint(t, router, token, "/api/simulations/1/user?username=User_A", "DELETE", nil, 200, string(msgOKjson)) - common.TestEndpoint(t, router, token, "/api/simulations/1/users", "GET", nil, 422, "\"Access denied (for simulation ID).\"") - - // TODO add tests for other return codes -} diff --git a/routes/simulationmodel/simulationmodel_endpoints.go b/routes/simulationmodel/simulationmodel_endpoints.go index a5cd4cd..ad08d4a 100644 --- a/routes/simulationmodel/simulationmodel_endpoints.go +++ b/routes/simulationmodel/simulationmodel_endpoints.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" - "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation" + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/scenario" ) func RegisterSimulationModelEndpoints(r *gin.RouterGroup) { @@ -18,27 +18,27 @@ func RegisterSimulationModelEndpoints(r *gin.RouterGroup) { } // getSimulationModels godoc -// @Summary Get all simulation models of simulation +// @Summary Get all simulation models of scenario // @ID getSimulationModels // @Produce json // @Tags models -// @Success 200 {array} common.SimulationModelResponse "Array of models to which belong to simulation" +// @Success 200 {array} common.SimulationModelResponse "Array of models to which belong to scenario" // @Failure 401 "Unauthorized Access" // @Failure 403 "Access forbidden." // @Failure 404 "Not found" // @Failure 500 "Internal server error" -// @Param simulationID query int true "Simulation ID" +// @Param scenarioID query int true "Scenario ID" // @Router /models [get] func getSimulationModels(c *gin.Context) { - ok, sim := simulation.CheckPermissions(c, common.Read, "query", -1) + ok, so := scenario.CheckPermissions(c, common.Read, "query", -1) if !ok { return } db := common.GetDB() var models []common.SimulationModel - err := db.Order("ID asc").Model(sim).Related(&models, "Models").Error + err := db.Order("ID asc").Model(so).Related(&models, "Models").Error if common.ProvideErrorResponse(c, err) { return } @@ -50,12 +50,12 @@ func getSimulationModels(c *gin.Context) { } // addSimulationModel godoc -// @Summary Add a simulation model to a simulation +// @Summary Add a simulation model to a scenario // @ID addSimulationModel // @Accept json // @Produce json // @Tags models -// @Param inputSimulationModel body common.SimulationModelResponse true "Simulation model to be added incl. IDs of simulation and simulator" +// @Param inputSimulationModel body common.SimulationModelResponse true "Simulation model to be added incl. IDs of scenario and simulator" // @Success 200 "OK." // @Failure 401 "Unauthorized Access" // @Failure 403 "Access forbidden." @@ -74,12 +74,12 @@ func addSimulationModel(c *gin.Context) { return } - ok, _ := simulation.CheckPermissions(c, common.Create, "body", int(newModel.SimulationID)) + ok, _ := scenario.CheckPermissions(c, common.Create, "body", int(newModel.ScenarioID)) if !ok { return } - err = newModel.addToSimulation() + err = newModel.addToScenario() if common.ProvideErrorResponse(c, err) == false { c.JSON(http.StatusOK, gin.H{ "message": "OK.", diff --git a/routes/simulationmodel/simulationmodel_methods.go b/routes/simulationmodel/simulationmodel_methods.go index a1e7879..9564a0c 100644 --- a/routes/simulationmodel/simulationmodel_methods.go +++ b/routes/simulationmodel/simulationmodel_methods.go @@ -4,7 +4,7 @@ import ( "fmt" "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" - "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation" + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/scenario" "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulator" ) @@ -27,10 +27,10 @@ func (m *SimulationModel) ByID(id uint) error { return nil } -func (m *SimulationModel) addToSimulation() error { +func (m *SimulationModel) addToScenario() error { db := common.GetDB() - var sim simulation.Simulation - err := sim.ByID(m.SimulationID) + var so scenario.Scenario + err := so.ByID(m.ScenarioID) if err != nil { return err } @@ -49,8 +49,8 @@ func (m *SimulationModel) addToSimulation() error { return err } - // associate simulation model with simulation - err = db.Model(&sim).Association("SimulationModels").Append(m).Error + // associate simulation model with scenario + err = db.Model(&so).Association("SimulationModels").Append(m).Error return err } @@ -96,15 +96,15 @@ func (m *SimulationModel) Update(modifiedSimulationModel SimulationModel) error func (m *SimulationModel) delete() error { db := common.GetDB() - var sim simulation.Simulation - err := sim.ByID(m.SimulationID) + var so scenario.Scenario + err := so.ByID(m.ScenarioID) if err != nil { return err } - // remove association between SimulationModel and Simulation + // remove association between SimulationModel and Scenario // SimulationModel itself is not deleted from DB, it remains as "dangling" - err = db.Model(&sim).Association("SimulationModels").Delete(m).Error + err = db.Model(&so).Association("SimulationModels").Delete(m).Error return err } diff --git a/routes/simulationmodel/simulationmodel_middleware.go b/routes/simulationmodel/simulationmodel_middleware.go index b0df013..ee18883 100644 --- a/routes/simulationmodel/simulationmodel_middleware.go +++ b/routes/simulationmodel/simulationmodel_middleware.go @@ -8,7 +8,7 @@ import ( "github.com/gin-gonic/gin" "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" - "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation" + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/scenario" ) func CheckPermissions(c *gin.Context, operation common.CRUD, modelIDSource string, modelIDBody int) (bool, SimulationModel) { @@ -49,7 +49,7 @@ func CheckPermissions(c *gin.Context, operation common.CRUD, modelIDSource strin return false, m } - ok, _ := simulation.CheckPermissions(c, operation, "body", int(m.SimulationID)) + ok, _ := scenario.CheckPermissions(c, operation, "body", int(m.ScenarioID)) if !ok { return false, m } diff --git a/routes/simulationmodel/simulationmodel_test.go b/routes/simulationmodel/simulationmodel_test.go index ad45276..45e5b59 100644 --- a/routes/simulationmodel/simulationmodel_test.go +++ b/routes/simulationmodel/simulationmodel_test.go @@ -31,7 +31,7 @@ var modelA = common.SimulationModelResponse{ Name: "SimulationModel_A", OutputLength: 1, InputLength: 1, - SimulationID: 1, + ScenarioID: 1, SimulatorID: 1, StartParams: "", } @@ -41,7 +41,7 @@ var modelB = common.SimulationModelResponse{ Name: "SimulationModel_B", OutputLength: 1, InputLength: 1, - SimulationID: 1, + ScenarioID: 1, SimulatorID: 1, StartParams: "", } @@ -51,7 +51,7 @@ var modelC = common.SimulationModel{ Name: "SimulationModel_C", OutputLength: 1, InputLength: 1, - SimulationID: 1, + ScenarioID: 1, SimulatorID: 1, StartParameters: "test", InputMapping: nil, @@ -63,7 +63,7 @@ var modelCupdated = common.SimulationModel{ Name: "SimulationModel_CUpdated", OutputLength: modelC.OutputLength, InputLength: modelC.InputLength, - SimulationID: modelC.SimulationID, + ScenarioID: modelC.ScenarioID, SimulatorID: 2, StartParameters: modelC.StartParameters, InputMapping: modelC.InputMapping, @@ -75,7 +75,7 @@ var modelC_response = common.SimulationModelResponse{ Name: modelC.Name, InputLength: modelC.InputLength, OutputLength: modelC.OutputLength, - SimulationID: modelC.SimulationID, + ScenarioID: modelC.ScenarioID, SimulatorID: modelC.SimulatorID, StartParams: modelC.StartParameters, } @@ -85,7 +85,7 @@ var modelC_responseUpdated = common.SimulationModelResponse{ Name: modelCupdated.Name, InputLength: modelC.InputLength, OutputLength: modelC.OutputLength, - SimulationID: modelC.SimulationID, + ScenarioID: modelC.ScenarioID, SimulatorID: modelCupdated.SimulatorID, StartParams: modelC.StartParameters, } @@ -163,7 +163,7 @@ func TestSimulationModelEndpoints(t *testing.T) { token = common.AuthenticateForTest(t, router, "/api/authenticate", "POST", credjson, 200) // test GET models - common.TestEndpoint(t, router, token, "/api/models?simulationID=1", "GET", nil, 200, string(msgModelsjson)) + common.TestEndpoint(t, router, token, "/api/models?scenarioID=1", "GET", nil, 200, string(msgModelsjson)) // test POST models common.TestEndpoint(t, router, token, "/api/models", "POST", modelCjson, 200, string(msgOKjson)) @@ -177,7 +177,7 @@ func TestSimulationModelEndpoints(t *testing.T) { // test DELETE models/:ModelID common.TestEndpoint(t, router, token, "/api/models/3", "DELETE", nil, 200, string(msgOKjson)) - common.TestEndpoint(t, router, token, "/api/models?simulationID=1", "GET", nil, 200, string(msgModelsjson)) + common.TestEndpoint(t, router, token, "/api/models?scenarioID=1", "GET", nil, 200, string(msgModelsjson)) // TODO add testing for other return codes diff --git a/start.go b/start.go index 3880486..6d38eb2 100644 --- a/start.go +++ b/start.go @@ -2,8 +2,6 @@ package main import ( "fmt" - "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/file" - "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/signal" "time" "github.com/gin-gonic/gin" @@ -13,7 +11,9 @@ import ( "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" _ "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/doc/api" // doc/api folder is used by Swag CLI, you have to import it "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/dashboard" - "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation" + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/file" + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/scenario" + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/signal" "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" @@ -54,7 +54,7 @@ func main() { api.Use(user.Authentication(true)) - simulation.RegisterSimulationEndpoints(api.Group("/simulations")) + scenario.RegisterScenarioEndpoints(api.Group("/scenarios")) simulationmodel.RegisterSimulationModelEndpoints(api.Group("/models")) signal.RegisterSignalEndpoints(api.Group("/signals")) dashboard.RegisterDashboardEndpoints(api.Group("/dashboards"))