Merge branch 'scenario-is-locked' into 'master'

Introduce IsLocked Parameter for Scenario (instead of Running parameter)

See merge request acs/public/villas/web-backend-go!30
This commit is contained in:
Sonja Happ 2021-04-21 09:20:19 +00:00
commit aa9d01f230
19 changed files with 138 additions and 72 deletions

View file

@ -11,9 +11,6 @@ variables:
GOPATH: $CI_PROJECT_DIR/.go GOPATH: $CI_PROJECT_DIR/.go
before_script: before_script:
- mkdir -p .go - mkdir -p .go
cache:
paths:
- .go/pkg/mod/
stages: stages:
- build - build
@ -37,10 +34,6 @@ build:
--parseVendor --parseVendor
--parseDepth 2 --parseDepth 2
- go build - go build
artifacts:
paths:
- doc/api/swagger.json
- doc/api/docs.go
# Stage: test # Stage: test
############################################################################## ##############################################################################

View file

@ -60,8 +60,8 @@ type Scenario struct {
Model Model
// Name of scenario // Name of scenario
Name string `json:"name" gorm:"not null"` Name string `json:"name" gorm:"not null"`
// Running state of scenario // IsLocked state of scenario (true if scenario is locked by administrator)
Running bool `json:"running" gorm:"default:false" ` IsLocked bool `json:"isLocked" gorm:"default:false" `
// Start parameters of scenario as JSON // Start parameters of scenario as JSON
StartParameters postgres.Jsonb `json:"startParameters"` StartParameters postgres.Jsonb `json:"startParameters"`
// Users that have access to the scenario // Users that have access to the scenario

View file

@ -3727,9 +3727,6 @@ var doc = `{
"Name": { "Name": {
"type": "string" "type": "string"
}, },
"Running": {
"type": "boolean"
},
"StartParameters": { "StartParameters": {
"$ref": "#/definitions/postgres.Jsonb" "$ref": "#/definitions/postgres.Jsonb"
} }
@ -3738,12 +3735,12 @@ var doc = `{
"scenario.validUpdatedScenario": { "scenario.validUpdatedScenario": {
"type": "object", "type": "object",
"properties": { "properties": {
"IsLocked": {
"type": "boolean"
},
"Name": { "Name": {
"type": "string" "type": "string"
}, },
"Running": {
"type": "boolean"
},
"StartParameters": { "StartParameters": {
"$ref": "#/definitions/postgres.Jsonb" "$ref": "#/definitions/postgres.Jsonb"
} }

View file

@ -3711,9 +3711,6 @@
"Name": { "Name": {
"type": "string" "type": "string"
}, },
"Running": {
"type": "boolean"
},
"StartParameters": { "StartParameters": {
"$ref": "#/definitions/postgres.Jsonb" "$ref": "#/definitions/postgres.Jsonb"
} }
@ -3722,12 +3719,12 @@
"scenario.validUpdatedScenario": { "scenario.validUpdatedScenario": {
"type": "object", "type": "object",
"properties": { "properties": {
"IsLocked": {
"type": "boolean"
},
"Name": { "Name": {
"type": "string" "type": "string"
}, },
"Running": {
"type": "boolean"
},
"StartParameters": { "StartParameters": {
"$ref": "#/definitions/postgres.Jsonb" "$ref": "#/definitions/postgres.Jsonb"
} }

View file

@ -286,8 +286,6 @@ definitions:
properties: properties:
Name: Name:
type: string type: string
Running:
type: boolean
StartParameters: StartParameters:
$ref: '#/definitions/postgres.Jsonb' $ref: '#/definitions/postgres.Jsonb'
required: required:
@ -296,10 +294,10 @@ definitions:
type: object type: object
scenario.validUpdatedScenario: scenario.validUpdatedScenario:
properties: properties:
IsLocked:
type: boolean
Name: Name:
type: string type: string
Running:
type: boolean
StartParameters: StartParameters:
$ref: '#/definitions/postgres.Jsonb' $ref: '#/definitions/postgres.Jsonb'
type: object type: object

View file

@ -64,7 +64,6 @@ type ICRequest struct {
type ScenarioRequest struct { type ScenarioRequest struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Running bool `json:"running,omitempty"`
StartParameters postgres.Jsonb `json:"startParameters,omitempty"` StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
} }
@ -120,7 +119,6 @@ func addScenarioAndIC() (scenarioID uint, ICID uint) {
// POST $newScenario // POST $newScenario
newScenario := ScenarioRequest{ newScenario := ScenarioRequest{
Name: "Scenario1", Name: "Scenario1",
Running: true,
StartParameters: postgres.Jsonb{json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)}, StartParameters: postgres.Jsonb{json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)},
} }
code, resp, err = helper.TestEndpoint(router, token, code, resp, err = helper.TestEndpoint(router, token,

View file

@ -49,7 +49,6 @@ type DashboardRequest struct {
type ScenarioRequest struct { type ScenarioRequest struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Running bool `json:"running,omitempty"`
StartParameters postgres.Jsonb `json:"startParameters,omitempty"` StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
} }
@ -63,7 +62,6 @@ func addScenario(token string) (scenarioID uint) {
// POST $newScenario // POST $newScenario
newScenario := ScenarioRequest{ newScenario := ScenarioRequest{
Name: "Scenario1", Name: "Scenario1",
Running: true,
StartParameters: postgres.Jsonb{json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)}, StartParameters: postgres.Jsonb{json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)},
} }
_, resp, err := helper.TestEndpoint(router, token, _, resp, err := helper.TestEndpoint(router, token,

View file

@ -47,7 +47,6 @@ var router *gin.Engine
type ScenarioRequest struct { type ScenarioRequest struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Running bool `json:"running,omitempty"`
StartParameters postgres.Jsonb `json:"startParameters,omitempty"` StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
} }
@ -62,7 +61,6 @@ func addScenario() (scenarioID uint) {
// POST $newScenario // POST $newScenario
newScenario := ScenarioRequest{ newScenario := ScenarioRequest{
Name: "Scenario1", Name: "Scenario1",
Running: true,
StartParameters: postgres.Jsonb{RawMessage: json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)}, StartParameters: postgres.Jsonb{RawMessage: json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)},
} }
_, resp, _ := helper.TestEndpoint(router, token, _, resp, _ := helper.TestEndpoint(router, token,

View file

@ -52,6 +52,12 @@ func (s *InfrastructureComponent) update(updatedIC InfrastructureComponent) erro
db := database.GetDB() db := database.GetDB()
err := db.Model(s).Updates(updatedIC).Error err := db.Model(s).Updates(updatedIC).Error
if err != nil {
return err
}
// extra update for bool ManagedExternally since it is ignored if false
err = db.Model(s).Updates(map[string]interface{}{"ManagedExternally": updatedIC.ManagedExternally}).Error
return err return err
} }

View file

@ -65,7 +65,6 @@ type ICRequest struct {
type ScenarioRequest struct { type ScenarioRequest struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Running bool `json:"running,omitempty"`
StartParameters postgres.Jsonb `json:"startParameters,omitempty"` StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
} }
@ -829,7 +828,6 @@ func TestDeleteICViaAMQPRecv(t *testing.T) {
// add scenario // add scenario
newScenario := ScenarioRequest{ newScenario := ScenarioRequest{
Name: "ScenarioA", Name: "ScenarioA",
Running: true,
StartParameters: postgres.Jsonb{RawMessage: json.RawMessage(`{"parameter1" : "testValue1B", "parameter2" : "testValue2B", "parameter3" : 55}`)}, StartParameters: postgres.Jsonb{RawMessage: json.RawMessage(`{"parameter1" : "testValue1B", "parameter2" : "testValue2B", "parameter3" : 55}`)},
} }

View file

@ -50,7 +50,6 @@ var baseAPIResults = "/api/v2/results"
type ScenarioRequest struct { type ScenarioRequest struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Running bool `json:"running,omitempty"`
StartParameters postgres.Jsonb `json:"startParameters,omitempty"` StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
} }
@ -79,7 +78,6 @@ func addScenario() (scenarioID uint) {
// POST $newScenario // POST $newScenario
newScenario := ScenarioRequest{ newScenario := ScenarioRequest{
Name: "Scenario1", Name: "Scenario1",
Running: true,
StartParameters: postgres.Jsonb{RawMessage: json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)}, StartParameters: postgres.Jsonb{RawMessage: json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)},
} }
_, resp, _ := helper.TestEndpoint(router, token, _, resp, _ := helper.TestEndpoint(router, token,

View file

@ -182,7 +182,8 @@ func updateScenario(c *gin.Context) {
} }
// Create the updatedScenario from oldScenario // Create the updatedScenario from oldScenario
updatedScenario := req.updatedScenario(oldScenario) userRole, _ := c.Get(database.UserRoleCtx)
updatedScenario := req.updatedScenario(oldScenario, userRole.(string))
// Finally update the scenario // Finally update the scenario
err := oldScenario.update(updatedScenario) err := oldScenario.update(updatedScenario)

View file

@ -58,11 +58,17 @@ func (s *Scenario) update(updatedScenario Scenario) error {
// TODO: if the field is empty member shouldn't be updated // TODO: if the field is empty member shouldn't be updated
s.Name = updatedScenario.Name s.Name = updatedScenario.Name
s.Running = updatedScenario.Running s.IsLocked = updatedScenario.IsLocked
s.StartParameters = updatedScenario.StartParameters s.StartParameters = updatedScenario.StartParameters
db := database.GetDB() db := database.GetDB()
err := db.Model(s).Update(updatedScenario).Error err := db.Model(s).Update(updatedScenario).Error
if err != nil {
return err
}
// extra update for bool IsLocked since it is ignored if false
err = db.Model(s).Updates(map[string]interface{}{"IsLocked": updatedScenario.IsLocked}).Error
return err return err
} }
@ -146,20 +152,32 @@ func (s *Scenario) delete() error {
return nil return nil
} }
func (s *Scenario) checkAccess(userID uint, userRole string) bool { func (s *Scenario) checkAccess(userID uint, operation database.CRUD) bool {
if userRole == "Admin" { db := database.GetDB()
u := database.User{}
err := db.Find(&u, userID).Error
if err != nil {
return false
}
if u.Role == "Admin" {
return true return true
}
scenarioUser := database.User{}
err = db.Order("ID asc").Model(s).Where("ID = ?", userID).Related(&scenarioUser, "Users").Error
if err != nil {
return false
}
if !scenarioUser.Active {
return false
} else if s.IsLocked && operation != database.Read {
return false
} else { } else {
db := database.GetDB() return true
u := database.User{}
u.Username = ""
err := db.Order("ID asc").Model(s).Where("ID = ?", userID).Related(&u, "Users").Error
if err != nil || !u.Active {
return false
} else {
return true
}
} }
} }

View file

@ -49,15 +49,14 @@ func CheckPermissions(c *gin.Context, operation database.CRUD, scenarioIDsource
} }
userID, _ := c.Get(database.UserIDCtx) userID, _ := c.Get(database.UserIDCtx)
userRole, _ := c.Get(database.UserRoleCtx)
err = so.ByID(uint(scenarioID)) err = so.ByID(uint(scenarioID))
if helper.DBError(c, err) { if helper.DBError(c, err) {
return false, so return false, so
} }
if so.checkAccess(userID.(uint), userRole.(string)) == false { if so.checkAccess(userID.(uint), operation) == false {
helper.UnprocessableEntityError(c, "Access denied (for scenario ID).") helper.UnprocessableEntityError(c, "Access denied (user has no access or scenario is locked).")
return false, so return false, so
} }

View file

@ -40,7 +40,7 @@ var router *gin.Engine
type ScenarioRequest struct { type ScenarioRequest struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Running bool `json:"running,omitempty"` IsLocked bool `json:"isLocked,omitempty"`
StartParameters postgres.Jsonb `json:"startParameters,omitempty"` StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
} }
@ -54,13 +54,11 @@ type UserRequest struct {
var newScenario1 = ScenarioRequest{ var newScenario1 = ScenarioRequest{
Name: "Scenario1", Name: "Scenario1",
Running: true,
StartParameters: postgres.Jsonb{json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)}, StartParameters: postgres.Jsonb{json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)},
} }
var newScenario2 = ScenarioRequest{ var newScenario2 = ScenarioRequest{
Name: "Scenario2", Name: "Scenario2",
Running: false,
StartParameters: postgres.Jsonb{json.RawMessage(`{"parameter1" : "testValue1B", "parameter2" : "testValue2B", "parameter3" : 55}`)}, StartParameters: postgres.Jsonb{json.RawMessage(`{"parameter1" : "testValue1B", "parameter2" : "testValue2B", "parameter3" : 55}`)},
} }
@ -133,7 +131,7 @@ func TestAddScenario(t *testing.T) {
// try to POST a malformed scenario // try to POST a malformed scenario
// Required fields are missing // Required fields are missing
malformedNewScenario := ScenarioRequest{ malformedNewScenario := ScenarioRequest{
Running: false, IsLocked: false,
} }
// this should NOT work and return a unprocessable entity 442 status code // this should NOT work and return a unprocessable entity 442 status code
code, resp, err = helper.TestEndpoint(router, token, code, resp, err = helper.TestEndpoint(router, token,
@ -205,12 +203,6 @@ func TestUpdateScenario(t *testing.T) {
newScenarioID, err := helper.GetResponseID(resp) newScenarioID, err := helper.GetResponseID(resp)
assert.NoError(t, err) assert.NoError(t, err)
updatedScenario := ScenarioRequest{
Name: "Updated name",
Running: false,
StartParameters: postgres.Jsonb{RawMessage: json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)},
}
// try to update with non JSON body // try to update with non JSON body
// should return a bad request error // should return a bad request error
code, resp, err = helper.TestEndpoint(router, token, code, resp, err = helper.TestEndpoint(router, token,
@ -218,6 +210,24 @@ func TestUpdateScenario(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp) assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
updatedScenario := ScenarioRequest{
Name: "Updated name",
IsLocked: true,
StartParameters: postgres.Jsonb{RawMessage: json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)},
}
// try to change locked state as non admin user
// should return 200 but locked state not updated
code, resp, err = helper.TestEndpoint(router, token,
fmt.Sprintf("/api/v2/scenarios/%v", newScenarioID), "PUT", helper.KeyModels{"scenario": updatedScenario})
assert.NoError(t, err)
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
// Compare PUT's response with the updatedScenario (should result in error)
err = helper.CompareResponse(resp, helper.KeyModels{"scenario": updatedScenario})
assert.Error(t, err)
updatedScenario.IsLocked = false
code, resp, err = helper.TestEndpoint(router, token, code, resp, err = helper.TestEndpoint(router, token,
fmt.Sprintf("/api/v2/scenarios/%v", newScenarioID), "PUT", helper.KeyModels{"scenario": updatedScenario}) fmt.Sprintf("/api/v2/scenarios/%v", newScenarioID), "PUT", helper.KeyModels{"scenario": updatedScenario})
assert.NoError(t, err) assert.NoError(t, err)
@ -243,6 +253,63 @@ func TestUpdateScenario(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.Equalf(t, 404, code, "Response body: \n%v\n", resp) assert.Equalf(t, 404, code, "Response body: \n%v\n", resp)
// authenticate as admin user who has no access to everything
token, err = helper.AuthenticateForTest(router, helper.AdminCredentials)
assert.NoError(t, err)
// changed locked state of scenario as admin user (should work)
updatedScenario.IsLocked = true
code, resp, err = helper.TestEndpoint(router, token,
fmt.Sprintf("/api/v2/scenarios/%v", newScenarioID), "PUT", helper.KeyModels{"scenario": updatedScenario})
assert.NoError(t, err)
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
// Compare PUT's response with the updatedScenario
err = helper.CompareResponse(resp, helper.KeyModels{"scenario": updatedScenario})
assert.NoError(t, err)
// Get the updatedScenario
code, resp, err = helper.TestEndpoint(router, token,
fmt.Sprintf("/api/v2/scenarios/%v", newScenarioID), "GET", nil)
assert.NoError(t, err)
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
// Compare GET's response with the newScenario
err = helper.CompareResponse(resp, helper.KeyModels{"scenario": updatedScenario})
assert.NoError(t, err)
// change a locked scenario as admin user (should work)
updatedScenario.Name = "Updated as admin"
code, resp, err = helper.TestEndpoint(router, token,
fmt.Sprintf("/api/v2/scenarios/%v", newScenarioID), "PUT", helper.KeyModels{"scenario": updatedScenario})
assert.NoError(t, err)
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
// Compare GET's response with the updatedScenario
err = helper.CompareResponse(resp, helper.KeyModels{"scenario": updatedScenario})
assert.NoError(t, err)
// authenticate as normal user
token, err = helper.AuthenticateForTest(router, helper.UserACredentials)
assert.NoError(t, err)
// Get the updatedScenario
code, resp, err = helper.TestEndpoint(router, token,
fmt.Sprintf("/api/v2/scenarios/%v", newScenarioID), "GET", nil)
assert.NoError(t, err)
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
// Compare GET's response with the updatedScenario
err = helper.CompareResponse(resp, helper.KeyModels{"scenario": updatedScenario})
assert.NoError(t, err)
// try to change a locked scenario as normal user (should result in unprocessable entity error)
updatedScenario.Name = "another new name"
code, resp, err = helper.TestEndpoint(router, token,
fmt.Sprintf("/api/v2/scenarios/%v", newScenarioID), "PUT", helper.KeyModels{"scenario": updatedScenario})
assert.NoError(t, err)
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
} }
func TestGetAllScenariosAsAdmin(t *testing.T) { func TestGetAllScenariosAsAdmin(t *testing.T) {

View file

@ -32,13 +32,12 @@ var validate *validator.Validate
type validNewScenario struct { type validNewScenario struct {
Name string `form:"Name" validate:"required"` Name string `form:"Name" validate:"required"`
Running bool `form:"Running" validate:"omitempty"`
StartParameters postgres.Jsonb `form:"StartParameters" validate:"required"` StartParameters postgres.Jsonb `form:"StartParameters" validate:"required"`
} }
type validUpdatedScenario struct { type validUpdatedScenario struct {
Name string `form:"Name" validate:"omitempty"` Name string `form:"Name" validate:"omitempty"`
Running bool `form:"Running" validate:"omitempty"` IsLocked bool `form:"IsLocked" validate:"omitempty"`
StartParameters postgres.Jsonb `form:"StartParameters" validate:"omitempty"` StartParameters postgres.Jsonb `form:"StartParameters" validate:"omitempty"`
} }
@ -66,22 +65,24 @@ func (r *addScenarioRequest) createScenario() Scenario {
var s Scenario var s Scenario
s.Name = r.Scenario.Name s.Name = r.Scenario.Name
s.Running = r.Scenario.Running s.IsLocked = false // new scenarios are not locked
s.StartParameters = r.Scenario.StartParameters s.StartParameters = r.Scenario.StartParameters
return s return s
} }
func (r *updateScenarioRequest) updatedScenario(oldScenario Scenario) Scenario { func (r *updateScenarioRequest) updatedScenario(oldScenario Scenario, userRole string) Scenario {
// Use the old Scenario as a basis for the updated Scenario `s` // Use the old Scenario as a basis for the updated Scenario `s`
s := oldScenario s := oldScenario
if userRole == "Admin" { // only admin users can change isLocked status
s.IsLocked = r.Scenario.IsLocked
}
if r.Scenario.Name != "" { if r.Scenario.Name != "" {
s.Name = r.Scenario.Name s.Name = r.Scenario.Name
} }
s.Running = r.Scenario.Running
// only update Params if not empty // only update Params if not empty
var emptyJson postgres.Jsonb var emptyJson postgres.Jsonb
// Serialize empty json and params // Serialize empty json and params

View file

@ -72,7 +72,6 @@ type ICRequest struct {
type ScenarioRequest struct { type ScenarioRequest struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Running bool `json:"running,omitempty"`
StartParameters postgres.Jsonb `json:"startParameters,omitempty"` StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
} }
@ -118,7 +117,6 @@ func addScenarioAndICAndConfig() (scenarioID uint, ICID uint, configID uint) {
// POST $newScenario // POST $newScenario
newScenario := ScenarioRequest{ newScenario := ScenarioRequest{
Name: "Scenario1", Name: "Scenario1",
Running: true,
StartParameters: postgres.Jsonb{json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)}, StartParameters: postgres.Jsonb{json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)},
} }
_, resp, _ = helper.TestEndpoint(router, token, _, resp, _ = helper.TestEndpoint(router, token,

View file

@ -124,8 +124,11 @@ func (u *User) update(updatedUser User) error {
db := database.GetDB() db := database.GetDB()
err := db.Model(u).Update(updatedUser).Error err := db.Model(u).Update(updatedUser).Error
if err != nil {
return err
}
// extra update for bool active since it is ignored if false // extra update for bool Active since it is ignored if false
err = db.Model(u).Updates(map[string]interface{}{"Active": updatedUser.Active}).Error err = db.Model(u).Updates(map[string]interface{}{"Active": updatedUser.Active}).Error
return err return err

View file

@ -64,7 +64,6 @@ type DashboardRequest struct {
type ScenarioRequest struct { type ScenarioRequest struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Running bool `json:"running,omitempty"`
StartParameters postgres.Jsonb `json:"startParameters,omitempty"` StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
} }
@ -88,7 +87,6 @@ func addScenarioAndDashboard(token string) (scenarioID uint, dashboardID uint) {
// POST $newScenario // POST $newScenario
newScenario := ScenarioRequest{ newScenario := ScenarioRequest{
Name: "Scenario1", Name: "Scenario1",
Running: true,
StartParameters: postgres.Jsonb{json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)}, StartParameters: postgres.Jsonb{json.RawMessage(`{"parameter1" : "testValue1A", "parameter2" : "testValue2A", "parameter3" : 42}`)},
} }
_, resp, _ := helper.TestEndpoint(router, token, _, resp, _ := helper.TestEndpoint(router, token,