...

Source file src/edge-infra.dev/pkg/edge/api/services/integration/oi_service_int_test.go

Documentation: edge-infra.dev/pkg/edge/api/services/integration

     1  package integration
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  
     9  	"edge-infra.dev/pkg/edge/api/graph/model"
    10  	"edge-infra.dev/pkg/edge/api/services"
    11  	"edge-infra.dev/pkg/edge/api/sql/plugin"
    12  	"edge-infra.dev/test/f2"
    13  	"edge-infra.dev/test/f2/x/postgres"
    14  )
    15  
    16  // Seed Data used for tests. Initialised to the dev1 seed data
    17  var oiSeedData []plugin.Seed = func() []plugin.Seed {
    18  	type rule struct {
    19  		CommandName   string
    20  		PrivilegeName string
    21  	}
    22  	type command struct {
    23  		CommandName string
    24  	}
    25  	type privilege struct {
    26  		PrivilegeName string
    27  	}
    28  	type roleMapping struct {
    29  		BslRole     string
    30  		EaPrivilege string
    31  	}
    32  
    33  	return []plugin.Seed{
    34  		{
    35  			Name:     "seed-ea-default-rules.tmpl",
    36  			Priority: 5,
    37  			Data: []rule{
    38  				{CommandName: "ls", PrivilegeName: "ea-read"},
    39  				{CommandName: "hostname", PrivilegeName: "ea-read"},
    40  				{CommandName: "cat", PrivilegeName: "ea-read"},
    41  				{CommandName: "dmesg", PrivilegeName: "ea-read"},
    42  				{CommandName: "base64", PrivilegeName: "ea-read"},
    43  				{CommandName: "echo", PrivilegeName: "ea-read"},
    44  				{CommandName: "head", PrivilegeName: "ea-read"},
    45  				{CommandName: "tail", PrivilegeName: "ea-read"},
    46  				{CommandName: "df", PrivilegeName: "ea-read"},
    47  				{CommandName: "du", PrivilegeName: "ea-read"},
    48  				{CommandName: "free", PrivilegeName: "ea-read"},
    49  				{CommandName: "ps", PrivilegeName: "ea-read"},
    50  				{CommandName: "pwd", PrivilegeName: "ea-read"},
    51  				{CommandName: "ping", PrivilegeName: "ea-read"},
    52  				{CommandName: "date", PrivilegeName: "ea-read"},
    53  				{CommandName: "stat", PrivilegeName: "ea-read"},
    54  				{CommandName: "grep", PrivilegeName: "ea-read"},
    55  				{CommandName: "kubectl", PrivilegeName: "ea-write"},
    56  				{CommandName: "systemctl", PrivilegeName: "ea-dev"},
    57  				{CommandName: "journalctl", PrivilegeName: "ea-dev"},
    58  				{CommandName: "rm", PrivilegeName: "ea-dev"},
    59  				{CommandName: "mv", PrivilegeName: "ea-dev"},
    60  				{CommandName: "kill", PrivilegeName: "ea-dev"},
    61  				{CommandName: "wget", PrivilegeName: "ea-dev"},
    62  				{CommandName: "curl", PrivilegeName: "ea-dev"},
    63  				{CommandName: "cp", PrivilegeName: "ea-dev"},
    64  				{CommandName: "tar", PrivilegeName: "ea-dev"},
    65  				{CommandName: "timedatectl", PrivilegeName: "ea-dev"},
    66  			},
    67  		},
    68  		{
    69  			Name:     "seed-ea-commands.tmpl",
    70  			Priority: 4,
    71  			Data: []command{
    72  				{CommandName: "ls"},
    73  				{CommandName: "hostname"},
    74  				{CommandName: "cat"},
    75  				{CommandName: "dmesg"},
    76  				{CommandName: "base64"},
    77  				{CommandName: "echo"},
    78  				{CommandName: "head"},
    79  				{CommandName: "tail"},
    80  				{CommandName: "df"},
    81  				{CommandName: "du"},
    82  				{CommandName: "free"},
    83  				{CommandName: "ps"},
    84  				{CommandName: "pwd"},
    85  				{CommandName: "ping"},
    86  				{CommandName: "curl"},
    87  				{CommandName: "kubectl"},
    88  				{CommandName: "systemctl"},
    89  				{CommandName: "journalctl"},
    90  				{CommandName: "cp"},
    91  				{CommandName: "tar"},
    92  				{CommandName: "rm"},
    93  				{CommandName: "mv"},
    94  				{CommandName: "kill"},
    95  				{CommandName: "wget"},
    96  				{CommandName: "date"},
    97  				{CommandName: "timedatectl"},
    98  				{CommandName: "stat"},
    99  				{CommandName: "grep"},
   100  			},
   101  		},
   102  		{
   103  			Name:     "seed-ea-privileges.tmpl",
   104  			Priority: 4,
   105  			Data: []privilege{
   106  				{PrivilegeName: "ea-read"},
   107  				{PrivilegeName: "ea-write"},
   108  				{PrivilegeName: "ea-dev"},
   109  			},
   110  		},
   111  		{
   112  			Name:     "seed-ea-oi-role-privileges.tmpl",
   113  			Priority: 5,
   114  			Data: []roleMapping{
   115  				{BslRole: "EDGE_L1", EaPrivilege: "ea-read"},
   116  				{BslRole: "EDGE_L2", EaPrivilege: "ea-write"},
   117  				{BslRole: "EDGE_L2", EaPrivilege: "ea-read"},
   118  				{BslRole: "EDGE_L3", EaPrivilege: "ea-write"},
   119  				{BslRole: "EDGE_L3", EaPrivilege: "ea-read"},
   120  				{BslRole: "EDGE_L4", EaPrivilege: "ea-read"},
   121  				{BslRole: "EDGE_L4", EaPrivilege: "ea-write"},
   122  				{BslRole: "EDGE_L4", EaPrivilege: "ea-dev"},
   123  			},
   124  		},
   125  	}
   126  }()
   127  
   128  func TestOiRoleMappings(t *testing.T) {
   129  	var oiService services.OperatorInterventionService
   130  
   131  	feat := f2.NewFeature("Oi Role Mappings").
   132  		Setup("Load Data", postgres.WithData(oiSeedData)).
   133  		Setup("Create service", func(ctx f2.Context, t *testing.T) f2.Context {
   134  			db := postgres.FromContextT(ctx, t).DB()
   135  			oiService = services.NewOperatorInterventionService(db)
   136  
   137  			return ctx
   138  		}).
   139  		Test("Get All Role Mappings", func(ctx f2.Context, t *testing.T) f2.Context {
   140  			roleMappings, err := oiService.RoleMappings(ctx, nil)
   141  			assert.NoError(t, err)
   142  
   143  			var expectedRoleMappings = []*model.OiRoleMapping{
   144  				{Role: model.RoleEdgeL1, Privileges: []*model.Privilege{
   145  					{Name: "ea-read"},
   146  				}},
   147  				{Role: model.RoleEdgeL2, Privileges: []*model.Privilege{
   148  					{Name: "ea-write"},
   149  					{Name: "ea-read"},
   150  				}},
   151  				{Role: model.RoleEdgeL3, Privileges: []*model.Privilege{
   152  					{Name: "ea-write"},
   153  					{Name: "ea-read"},
   154  				}},
   155  				{Role: model.RoleEdgeL4, Privileges: []*model.Privilege{
   156  					{Name: "ea-read"},
   157  					{Name: "ea-write"},
   158  					{Name: "ea-dev"},
   159  				}},
   160  			}
   161  
   162  			assert.Equal(t, expectedRoleMappings, roleMappings)
   163  
   164  			return ctx
   165  		}).
   166  		Test("Get 1 Role Mapping", func(ctx f2.Context, t *testing.T) f2.Context {
   167  			roleMappings, err := oiService.RoleMappings(ctx, []string{"EDGE_L2"})
   168  			assert.NoError(t, err)
   169  
   170  			var expectedRoleMappings = []*model.OiRoleMapping{
   171  				{Role: model.RoleEdgeL2, Privileges: []*model.Privilege{
   172  					{Name: "ea-read"},
   173  					{Name: "ea-write"},
   174  				}},
   175  			}
   176  
   177  			assert.Equal(t, expectedRoleMappings, roleMappings)
   178  
   179  			return ctx
   180  		}).
   181  		Feature()
   182  
   183  	f.Test(t, feat)
   184  }
   185  
   186  func TestDeleteOperatorInterventionRoleMapping(t *testing.T) {
   187  	var oiService services.OperatorInterventionService
   188  
   189  	// annoying
   190  	var invalidEdgeRole = "INVALID_EDGE_ROLE"
   191  	var invalidPrivilege = "unknownprivilege"
   192  	var eaRead = "ea-read"
   193  	var edgeOrgAdmin = "EDGE_L4"
   194  
   195  	// Run table tests sequentially to verify behaviour of missing role mappings
   196  	var tests = []struct {
   197  		oirole   string
   198  		privName string
   199  		resp     *model.DeleteOperatorInterventionResponse
   200  	}{
   201  		{
   202  			// Should successfully delete
   203  			oirole:   edgeOrgAdmin,
   204  			privName: eaRead,
   205  			resp:     &model.DeleteOperatorInterventionResponse{},
   206  		},
   207  		{
   208  			// Same role and privilege should return error on second attempt
   209  			oirole:   edgeOrgAdmin,
   210  			privName: eaRead,
   211  			resp: &model.DeleteOperatorInterventionResponse{Errors: []*model.OperatorInterventionErrorResponse{
   212  				{
   213  					Type:      model.OperatorInterventionErrorTypeUnknownRoleMapping,
   214  					Privilege: &eaRead,
   215  					Role:      &edgeOrgAdmin,
   216  				},
   217  			}},
   218  		},
   219  		{
   220  			// Invalid Edge Role or missing privilege does not return an
   221  			// UNKNOWN_ROLE or UNKNOWN_PRIVILEGE error, it only ever returns
   222  			// UnknownRoleMapping
   223  			oirole:   "INVALID_EDGE_ROLE",
   224  			privName: "unknownprivilege",
   225  			resp: &model.DeleteOperatorInterventionResponse{Errors: []*model.OperatorInterventionErrorResponse{
   226  				{
   227  					Type:      model.OperatorInterventionErrorTypeUnknownRoleMapping,
   228  					Privilege: &invalidPrivilege,
   229  					Role:      &invalidEdgeRole,
   230  				},
   231  			}},
   232  		},
   233  	}
   234  
   235  	featureBuilder := f2.NewFeature("DeleteOIRoleMapping").
   236  		Setup("Load Data", postgres.WithData(oiSeedData)).
   237  		Setup("Create Service", func(ctx f2.Context, t *testing.T) f2.Context {
   238  			db := postgres.FromContextT(ctx, t).DB()
   239  			oiService = services.NewOperatorInterventionService(db)
   240  			return ctx
   241  		})
   242  
   243  	for idx, tc := range tests {
   244  		featureBuilder.
   245  			Test(fmt.Sprintf("Test %d", idx), func(ctx f2.Context, t *testing.T) f2.Context {
   246  				out, err := oiService.DeleteRoleMapping(ctx, model.DeleteOperatorInterventionMappingInput{
   247  					Privilege: &model.OperatorInterventionPrivilegeInput{Name: tc.privName},
   248  					Role:      tc.oirole,
   249  				})
   250  
   251  				assert.NoError(t, err)
   252  
   253  				assert.Equal(t, tc.resp, out)
   254  
   255  				return ctx
   256  			})
   257  	}
   258  
   259  	f.Test(t, featureBuilder.Feature())
   260  }
   261  
   262  func TestAddOiRoleMappings(t *testing.T) {
   263  	var oiService services.OperatorInterventionService
   264  
   265  	roleMappingInput := []*model.UpdateOperatorInterventionRoleMappingInput{
   266  		{
   267  			Role: "EDGE_L3",
   268  			Privileges: []*model.OperatorInterventionPrivilegeInput{
   269  				{Name: "ea-read"},
   270  				{Name: "ea-write"},
   271  			},
   272  		},
   273  		{
   274  			Role: "EDGE_L4",
   275  			Privileges: []*model.OperatorInterventionPrivilegeInput{
   276  				{Name: "ea-read"},
   277  			},
   278  		},
   279  	}
   280  
   281  	verifyRoles := func(ctx f2.Context, t *testing.T) f2.Context {
   282  		out, err := oiService.RoleMappings(ctx, nil)
   283  		assert.NoError(t, err)
   284  
   285  		exp := []*model.OiRoleMapping{
   286  			{Role: model.RoleEdgeL3, Privileges: []*model.Privilege{
   287  				{Name: "ea-read"},
   288  				{Name: "ea-write"},
   289  			}},
   290  			{Role: model.RoleEdgeL4, Privileges: []*model.Privilege{
   291  				{Name: "ea-read"},
   292  			}},
   293  		}
   294  		assert.Equal(t, exp, out)
   295  
   296  		return ctx
   297  	}
   298  
   299  	feat := f2.NewFeature("Add Oi Role Mappings").
   300  		Setup("Add Privileges", func(ctx f2.Context, t *testing.T) f2.Context {
   301  			db := postgres.FromContextT(ctx, t).DB()
   302  			privs := []any{"ea-read", "ea-write", "ea-dev"}
   303  			_, err := db.ExecContext(ctx, `INSERT INTO ea_rules_privileges (name) VALUES ($1), ($2), ($3)`, privs...)
   304  			assert.NoError(t, err)
   305  
   306  			return ctx
   307  		}).
   308  		Setup("Create Service", func(ctx f2.Context, t *testing.T) f2.Context {
   309  			db := postgres.FromContextT(ctx, t).DB()
   310  			oiService = services.NewOperatorInterventionService(db)
   311  			return ctx
   312  		}).
   313  		Test("Add new Role Mappings", func(ctx f2.Context, t *testing.T) f2.Context {
   314  			roleMappings, err := oiService.UpdateRoleMappings(ctx, roleMappingInput)
   315  			assert.NoError(t, err)
   316  
   317  			assert.Empty(t, roleMappings.Errors)
   318  			for _, errResp := range roleMappings.Errors {
   319  				// This test isn't strictly necessary due to the Empty check
   320  				// above, however it's useful to have full details printed out
   321  				// when debugging
   322  				assert.Zero(t, errResp)
   323  			}
   324  
   325  			return ctx
   326  		}).
   327  		Test("Verify DB Contents", verifyRoles).
   328  		Test("Insert Duplicates", func(ctx f2.Context, t *testing.T) f2.Context {
   329  			roleMappings, err := oiService.UpdateRoleMappings(ctx, roleMappingInput)
   330  			assert.NoError(t, err)
   331  
   332  			assert.Empty(t, roleMappings.Errors)
   333  			for _, errResp := range roleMappings.Errors {
   334  				// This test isn't strictly necessary due to the Empty check
   335  				// above, however it's useful to have full details printed out
   336  				// when debugging
   337  				assert.Zero(t, errResp)
   338  			}
   339  
   340  			return ctx
   341  		}).
   342  		Test("Verify DB Contents on duplicates", verifyRoles).
   343  		Test("Insert empty", func(ctx f2.Context, t *testing.T) f2.Context {
   344  			db := postgres.FromContextT(ctx, t).DB()
   345  			oiService := services.NewOperatorInterventionService(db)
   346  
   347  			roleMappings, err := oiService.UpdateRoleMappings(ctx, []*model.UpdateOperatorInterventionRoleMappingInput{})
   348  			assert.NoError(t, err)
   349  
   350  			assert.Empty(t, roleMappings.Errors)
   351  			for _, errResp := range roleMappings.Errors {
   352  				// This test isn't strictly necessary due to the Empty check
   353  				// above, however it's useful to have full details printed out
   354  				// when debugging
   355  				assert.Zero(t, errResp)
   356  			}
   357  
   358  			return ctx
   359  		}).
   360  		Test("Verify DB Contents on Empty insert", verifyRoles).
   361  		Test("Insert invalid values", func(ctx f2.Context, t *testing.T) f2.Context {
   362  			roleMappings, err := oiService.UpdateRoleMappings(ctx,
   363  				[]*model.UpdateOperatorInterventionRoleMappingInput{
   364  					{
   365  						Role:       "Invalid_Role",
   366  						Privileges: []*model.OperatorInterventionPrivilegeInput{{Name: "ea-read"}},
   367  					},
   368  					{
   369  						Role:       "EDGE_L4",
   370  						Privileges: []*model.OperatorInterventionPrivilegeInput{{Name: "invalid_privilege"}},
   371  					},
   372  				},
   373  			)
   374  			assert.NoError(t, err)
   375  
   376  			var invalidRole = "Invalid_Role"
   377  			var invalidPrivilege = "invalid_privilege"
   378  
   379  			expRoleMappings := model.UpdateOperatorInterventionRoleMappingResponse{
   380  				Errors: []*model.OperatorInterventionErrorResponse{
   381  					{Type: model.OperatorInterventionErrorTypeUnknownRole, Role: &invalidRole},
   382  					{Type: model.OperatorInterventionErrorTypeUnknownPrivilege, Privilege: &invalidPrivilege},
   383  				},
   384  			}
   385  
   386  			assert.Equal(t, expRoleMappings.Errors, roleMappings.Errors)
   387  
   388  			return ctx
   389  		}).
   390  		Feature()
   391  
   392  	f.Test(t, feat)
   393  }
   394  
   395  func TestReadOperatorInterventionCommands(t *testing.T) {
   396  	feat := f2.NewFeature("Read OI Commands").
   397  		Setup("Load Data", postgres.WithData(oiSeedData)).
   398  		Test("Read a Command", func(ctx f2.Context, t *testing.T) f2.Context {
   399  			db := postgres.FromContextT(ctx, t).DB()
   400  			oiService := services.NewOperatorInterventionService(db)
   401  
   402  			payload := []*model.OperatorInterventionCommandInput{{Name: "ls"}}
   403  			result, err := oiService.ReadCommands(ctx, payload)
   404  			assert.NoError(t, err)
   405  
   406  			assert.Len(t, result, 1)
   407  			assert.Equal(t, "ls", result[0].Name)
   408  
   409  			return ctx
   410  		}).
   411  		Test("Read Multiple Commands", func(ctx f2.Context, t *testing.T) f2.Context {
   412  			db := postgres.FromContextT(ctx, t).DB()
   413  			oiService := services.NewOperatorInterventionService(db)
   414  
   415  			payload := []*model.OperatorInterventionCommandInput{{Name: "ls"}, {Name: "echo"}, {Name: "cat"}}
   416  			result, err := oiService.ReadCommands(ctx, payload)
   417  			assert.NoError(t, err)
   418  
   419  			assert.Len(t, result, 3)
   420  			for _, command := range payload {
   421  				assert.Contains(t, result, &model.Command{Name: command.Name})
   422  			}
   423  
   424  			return ctx
   425  		}).
   426  		Test("Read All Commands", func(ctx f2.Context, t *testing.T) f2.Context {
   427  			db := postgres.FromContextT(ctx, t).DB()
   428  			oiService := services.NewOperatorInterventionService(db)
   429  
   430  			result, err := oiService.ReadCommands(ctx, nil)
   431  			assert.NoError(t, err)
   432  
   433  			assert.Greater(t, len(result), 0)
   434  
   435  			return ctx
   436  		}).
   437  		Test("No Command Found", func(ctx f2.Context, t *testing.T) f2.Context {
   438  			db := postgres.FromContextT(ctx, t).DB()
   439  			oiService := services.NewOperatorInterventionService(db)
   440  
   441  			payload := []*model.OperatorInterventionCommandInput{{Name: "nonexistant-command"}}
   442  			result, err := oiService.ReadCommands(ctx, payload)
   443  			assert.NoError(t, err)
   444  
   445  			assert.Len(t, result, 0)
   446  
   447  			return ctx
   448  		}).
   449  		Test("Some Commands Found", func(ctx f2.Context, t *testing.T) f2.Context {
   450  			db := postgres.FromContextT(ctx, t).DB()
   451  			oiService := services.NewOperatorInterventionService(db)
   452  
   453  			//names := []string{"ls", "nonexistant-command", "echo"}
   454  			payload := []*model.OperatorInterventionCommandInput{
   455  				{Name: "ls"},
   456  				{Name: "nonexistant-command"},
   457  				{Name: "echo"},
   458  			}
   459  			result, err := oiService.ReadCommands(ctx, payload)
   460  			assert.NoError(t, err)
   461  
   462  			assert.Len(t, result, 2)
   463  			assert.Contains(t, result, &model.Command{Name: payload[0].Name})
   464  			assert.Contains(t, result, &model.Command{Name: payload[2].Name})
   465  			assert.NotContains(t, result, &model.Command{Name: payload[1].Name})
   466  
   467  			return ctx
   468  		}).
   469  		Feature()
   470  
   471  	f.Test(t, feat)
   472  }
   473  
   474  //nolint:dupl
   475  func TestOperatorInterventionCreateCommands(t *testing.T) {
   476  	feat := f2.NewFeature("Create OI Commands").
   477  		Setup("Load Data", postgres.WithData(oiSeedData)).
   478  		Test("Add One Command", func(ctx f2.Context, t *testing.T) f2.Context {
   479  			db := postgres.FromContextT(ctx, t).DB()
   480  			oiService := services.NewOperatorInterventionService(db)
   481  
   482  			payload := []*model.OperatorInterventionCommandInput{
   483  				{Name: "a-command-that-is-not-in-yet"},
   484  			}
   485  			response, err := oiService.CreateCommands(ctx, payload)
   486  			assert.NoError(t, err)
   487  			assert.Empty(t, response)
   488  			return ctx
   489  		}).
   490  		Test("Add Multiple Commands", func(ctx f2.Context, t *testing.T) f2.Context {
   491  			db := postgres.FromContextT(ctx, t).DB()
   492  			oiService := services.NewOperatorInterventionService(db)
   493  
   494  			payload := []*model.OperatorInterventionCommandInput{
   495  				{Name: "a-command-that-is-not-in-yet-1"},
   496  				{Name: "a-command-that-is-not-in-yet-2"},
   497  				{Name: "a-command-that-is-not-in-yet-3"},
   498  			}
   499  			response, err := oiService.CreateCommands(ctx, payload)
   500  			assert.NoError(t, err)
   501  			assert.Empty(t, response)
   502  			return ctx
   503  		}).
   504  		Test("Conflicts", func(ctx f2.Context, t *testing.T) f2.Context {
   505  			db := postgres.FromContextT(ctx, t).DB()
   506  			oiService := services.NewOperatorInterventionService(db)
   507  
   508  			conflictCommand1 := "ls"
   509  			conflictCommand2 := "echo"
   510  			payload := []*model.OperatorInterventionCommandInput{
   511  				{Name: conflictCommand1},
   512  				{Name: "a-command-that-is-definitely-not-in-yet"},
   513  				{Name: conflictCommand2},
   514  			}
   515  			response, err := oiService.CreateCommands(ctx, payload)
   516  			assert.NoError(t, err)
   517  			assert.Empty(t, response)
   518  			return ctx
   519  		}).
   520  		Feature()
   521  
   522  	f.Test(t, feat)
   523  }
   524  
   525  //nolint:dupl
   526  func TestDeleteOperatorInterventionCommand(t *testing.T) {
   527  	feat := f2.NewFeature("Create OI Commands").
   528  		Setup("Load Data", postgres.WithData(oiSeedData)).
   529  		Setup("Add Command To Be Deleted In Test", func(ctx f2.Context, t *testing.T) f2.Context {
   530  			db := postgres.FromContextT(ctx, t).DB()
   531  			oiService := services.NewOperatorInterventionService(db)
   532  
   533  			payload := []*model.OperatorInterventionCommandInput{
   534  				{Name: "a-command-that-is-not-in-yet"},
   535  			}
   536  			response, err := oiService.CreateCommands(ctx, payload)
   537  			assert.NoError(t, err)
   538  
   539  			assert.Empty(t, response)
   540  
   541  			return ctx
   542  		}).
   543  		Test("Delete Command", func(ctx f2.Context, t *testing.T) f2.Context {
   544  			db := postgres.FromContextT(ctx, t).DB()
   545  			oiService := services.NewOperatorInterventionService(db)
   546  
   547  			payload := model.OperatorInterventionCommandInput{
   548  				Name: "a-command-that-is-not-in-yet",
   549  			}
   550  			response, err := oiService.DeleteCommand(ctx, payload)
   551  			assert.NoError(t, err)
   552  
   553  			assert.Empty(t, response)
   554  
   555  			return ctx
   556  		}).
   557  		Test("Fail to Delete Non-Existing Command", func(ctx f2.Context, t *testing.T) f2.Context {
   558  			db := postgres.FromContextT(ctx, t).DB()
   559  			oiService := services.NewOperatorInterventionService(db)
   560  
   561  			command := "a-command-that-was-never-there"
   562  			payload := model.OperatorInterventionCommandInput{
   563  				Name: command,
   564  			}
   565  			response, err := oiService.DeleteCommand(ctx, payload)
   566  			assert.NoError(t, err)
   567  
   568  			assert.NotEmpty(t, response)
   569  			assert.Equal(t, command, *response.Errors[0].Command)
   570  			assert.Equal(t, model.OperatorInterventionErrorTypeUnknownCommand, response.Errors[0].Type)
   571  
   572  			return ctx
   573  		}).
   574  		Test("Fail to Delete Command with an active rule", func(ctx f2.Context, t *testing.T) f2.Context {
   575  			db := postgres.FromContextT(ctx, t).DB()
   576  			oiService := services.NewOperatorInterventionService(db)
   577  
   578  			command := "ls"
   579  			payload := model.OperatorInterventionCommandInput{
   580  				Name: command,
   581  			}
   582  			response, err := oiService.DeleteCommand(ctx, payload)
   583  			assert.NoError(t, err)
   584  
   585  			assert.NotEmpty(t, response)
   586  			assert.Equal(t, command, *response.Errors[0].Command)
   587  			assert.Equal(t, model.OperatorInterventionErrorTypeConflict, response.Errors[0].Type)
   588  
   589  			return ctx
   590  		}).
   591  		Feature()
   592  
   593  	f.Test(t, feat)
   594  }
   595  
   596  //nolint:dupl
   597  func TestDeleteOperatorInterventionPrivilege(t *testing.T) {
   598  	feat := f2.NewFeature("Delete OI Privileges").
   599  		Setup("Load Data", postgres.WithData(oiSeedData)).
   600  		Setup("Add Privilege to be used in delete tests", func(ctx f2.Context, t *testing.T) f2.Context {
   601  			db := postgres.FromContextT(ctx, t).DB()
   602  			oiService := services.NewOperatorInterventionService(db)
   603  			payload := []*model.OperatorInterventionPrivilegeInput{
   604  				{Name: "test-priv"},
   605  			}
   606  			response, err := oiService.CreatePrivileges(ctx, payload)
   607  			assert.NoError(t, err)
   608  
   609  			assert.Empty(t, response)
   610  			return ctx
   611  		}).
   612  		Test("Delete Privilege", func(ctx f2.Context, t *testing.T) f2.Context {
   613  			db := postgres.FromContextT(ctx, t).DB()
   614  			oiService := services.NewOperatorInterventionService(db)
   615  
   616  			payload := model.OperatorInterventionPrivilegeInput{
   617  				Name: "test-priv",
   618  			}
   619  			response, err := oiService.DeletePrivilege(ctx, payload)
   620  			assert.NoError(t, err)
   621  
   622  			assert.Empty(t, response)
   623  
   624  			return ctx
   625  		}).
   626  		Test("Fail to Delete Non-Existing Privilege", func(ctx f2.Context, t *testing.T) f2.Context {
   627  			db := postgres.FromContextT(ctx, t).DB()
   628  			oiService := services.NewOperatorInterventionService(db)
   629  
   630  			privilege := "a-privilege-that-was-never-there"
   631  			payload := model.OperatorInterventionPrivilegeInput{
   632  				Name: privilege,
   633  			}
   634  			response, err := oiService.DeletePrivilege(ctx, payload)
   635  			assert.NoError(t, err)
   636  
   637  			assert.NotEmpty(t, response)
   638  			assert.Equal(t, privilege, *response.Errors[0].Privilege)
   639  			assert.Equal(t, model.OperatorInterventionErrorTypeUnknownPrivilege, response.Errors[0].Type)
   640  
   641  			return ctx
   642  		}).
   643  		Test("Fail to Delete Privilege with an active rule", func(ctx f2.Context, t *testing.T) f2.Context {
   644  			db := postgres.FromContextT(ctx, t).DB()
   645  			oiService := services.NewOperatorInterventionService(db)
   646  
   647  			privilege := "ea-read"
   648  			payload := model.OperatorInterventionPrivilegeInput{
   649  				Name: privilege,
   650  			}
   651  			response, err := oiService.DeletePrivilege(ctx, payload)
   652  			assert.NoError(t, err)
   653  
   654  			assert.NotEmpty(t, response)
   655  			assert.Equal(t, privilege, *response.Errors[0].Privilege)
   656  			assert.Equal(t, model.OperatorInterventionErrorTypeConflict, response.Errors[0].Type)
   657  
   658  			return ctx
   659  		}).
   660  		Feature()
   661  	f.Test(t, feat)
   662  }
   663  
   664  func TestOperatorInterventionReadPrivilege(t *testing.T) {
   665  	const (
   666  		privilegeName = "ea-read"
   667  	)
   668  	feat := f2.NewFeature("Read Privilege").
   669  		Setup("Load Data", postgres.WithData(oiSeedData)).
   670  		Test("Read one privilege", func(ctx f2.Context, t *testing.T) f2.Context {
   671  			db := postgres.FromContextT(ctx, t).DB()
   672  			oiService := services.NewOperatorInterventionService(db)
   673  			privileges, err := oiService.ReadPrivileges(ctx, []*model.OperatorInterventionPrivilegeInput{
   674  				{Name: privilegeName},
   675  			})
   676  			assert.NoError(t, err)
   677  			assert.Len(t, privileges, 1)
   678  			assert.Equal(t, privilegeName, privileges[0].Name)
   679  
   680  			return ctx
   681  		}).
   682  		Test("Read multiple privileges", func(ctx f2.Context, t *testing.T) f2.Context {
   683  			db := postgres.FromContextT(ctx, t).DB()
   684  			oiService := services.NewOperatorInterventionService(db)
   685  
   686  			//privileges, err := oiService.ReadPrivileges(ctx, []string{"ea-read", "ea-write"})
   687  			privileges, err := oiService.ReadPrivileges(ctx, []*model.OperatorInterventionPrivilegeInput{
   688  				{Name: "ea-read"},
   689  				{Name: "ea-write"},
   690  			})
   691  			assert.NoError(t, err)
   692  			assert.Len(t, privileges, 2)
   693  			returnedPrivileges := []string{privileges[0].Name, privileges[1].Name}
   694  			assert.EqualValues(t, []string{privilegeName, "ea-write"}, returnedPrivileges)
   695  			return ctx
   696  		}).
   697  		Feature()
   698  	f.Test(t, feat)
   699  }
   700  
   701  //nolint:dupl
   702  func TestOperatorInterventionCreatePrivileges(t *testing.T) {
   703  	feat := f2.NewFeature("Create Privileges").
   704  		Setup("Load Data", postgres.WithData(oiSeedData)).
   705  		Test("Create single privilege", func(ctx f2.Context, t *testing.T) f2.Context {
   706  			db := postgres.FromContextT(ctx, t).DB()
   707  			oiService := services.NewOperatorInterventionService(db)
   708  
   709  			payload := []*model.OperatorInterventionPrivilegeInput{
   710  				{Name: "test-priv"},
   711  			}
   712  			response, err := oiService.CreatePrivileges(ctx, payload)
   713  			assert.NoError(t, err)
   714  
   715  			assert.Empty(t, response)
   716  			return ctx
   717  		}).
   718  		Test("Create multiple privileges", func(ctx f2.Context, t *testing.T) f2.Context {
   719  			db := postgres.FromContextT(ctx, t).DB()
   720  			oiService := services.NewOperatorInterventionService(db)
   721  
   722  			payload := []*model.OperatorInterventionPrivilegeInput{
   723  				{Name: "test-priv-1"},
   724  				{Name: "test-priv-2"},
   725  				{Name: "test-priv-3"},
   726  			}
   727  			response, err := oiService.CreatePrivileges(ctx, payload)
   728  			assert.NoError(t, err)
   729  			assert.Empty(t, response)
   730  			return ctx
   731  		}).
   732  		Test("Create conflicting privileges", func(ctx f2.Context, t *testing.T) f2.Context {
   733  			db := postgres.FromContextT(ctx, t).DB()
   734  			oiService := services.NewOperatorInterventionService(db)
   735  
   736  			payload := []*model.OperatorInterventionPrivilegeInput{
   737  				{Name: "ea-read"},
   738  				{Name: "ea-write"},
   739  			}
   740  			response, err := oiService.CreatePrivileges(ctx, payload)
   741  			assert.NoError(t, err)
   742  
   743  			assert.Empty(t, response)
   744  
   745  			return ctx
   746  		}).
   747  		Feature()
   748  	f.Test(t, feat)
   749  }
   750  
   751  func TestDeleteOperatorInterventionRules(t *testing.T) {
   752  	feat := f2.NewFeature("Delete OI Rules").
   753  		Setup("Load Data", postgres.WithData(oiSeedData)).
   754  		Test("Delete Rule", func(ctx f2.Context, t *testing.T) f2.Context {
   755  			db := postgres.FromContextT(ctx, t).DB()
   756  			oiService := services.NewOperatorInterventionService(db)
   757  
   758  			payload := model.DeleteOperatorInterventionRuleInput{
   759  				Privilege: "ea-read",
   760  				Command:   "ls",
   761  			}
   762  			response, err := oiService.DeleteRule(ctx, payload)
   763  			assert.NoError(t, err)
   764  
   765  			assert.Empty(t, response)
   766  
   767  			return ctx
   768  		}).
   769  		Test("Fail to Delete Rule with non-existing command", func(ctx f2.Context, t *testing.T) f2.Context {
   770  			db := postgres.FromContextT(ctx, t).DB()
   771  			oiService := services.NewOperatorInterventionService(db)
   772  			command := "non-existent-command"
   773  			payload := model.DeleteOperatorInterventionRuleInput{
   774  				Command:   command,
   775  				Privilege: "ea-read",
   776  			}
   777  			response, err := oiService.DeleteRule(ctx, payload)
   778  			assert.NoError(t, err)
   779  
   780  			assert.NotEmpty(t, response)
   781  			assert.Equal(t, []*model.OperatorInterventionErrorResponse{
   782  				{
   783  					Type:    model.OperatorInterventionErrorTypeUnknownCommand,
   784  					Command: &command,
   785  				},
   786  			}, response.Errors)
   787  
   788  			return ctx
   789  		}).
   790  		Test("Fail to Delete Rule with non-existing privilege", func(ctx f2.Context, t *testing.T) f2.Context {
   791  			db := postgres.FromContextT(ctx, t).DB()
   792  			oiService := services.NewOperatorInterventionService(db)
   793  			privilege := "non-existent-privilege"
   794  			payload := model.DeleteOperatorInterventionRuleInput{
   795  				Command:   "ls",
   796  				Privilege: privilege,
   797  			}
   798  			response, err := oiService.DeleteRule(ctx, payload)
   799  			assert.NoError(t, err)
   800  
   801  			assert.NotEmpty(t, response)
   802  			assert.Equal(t, []*model.OperatorInterventionErrorResponse{
   803  				{
   804  					Type:      model.OperatorInterventionErrorTypeUnknownPrivilege,
   805  					Privilege: &privilege,
   806  				},
   807  			}, response.Errors)
   808  
   809  			return ctx
   810  		}).
   811  		Test("Fail to Delete Rule with non-existing command and privilege", func(ctx f2.Context, t *testing.T) f2.Context {
   812  			db := postgres.FromContextT(ctx, t).DB()
   813  			oiService := services.NewOperatorInterventionService(db)
   814  			command := "a-non-existent-command"
   815  			privilege := "a-non-existent-privilege"
   816  			payload := model.DeleteOperatorInterventionRuleInput{
   817  				Command:   command,
   818  				Privilege: privilege,
   819  			}
   820  			response, err := oiService.DeleteRule(ctx, payload)
   821  			assert.NoError(t, err)
   822  
   823  			assert.NotEmpty(t, response)
   824  			assert.Equal(t, []*model.OperatorInterventionErrorResponse{
   825  				{
   826  					Type:    model.OperatorInterventionErrorTypeUnknownCommand,
   827  					Command: &command,
   828  				},
   829  				{
   830  					Type:      model.OperatorInterventionErrorTypeUnknownPrivilege,
   831  					Privilege: &privilege,
   832  				},
   833  			}, response.Errors)
   834  
   835  			return ctx
   836  		}).
   837  		Test("Fail to delete non-existing rule", func(ctx f2.Context, t *testing.T) f2.Context {
   838  			db := postgres.FromContextT(ctx, t).DB()
   839  			oiService := services.NewOperatorInterventionService(db)
   840  			payload := model.DeleteOperatorInterventionRuleInput{
   841  				Command:   "ls",
   842  				Privilege: "ea-read",
   843  			}
   844  			response, err := oiService.DeleteRule(ctx, payload)
   845  			assert.NoError(t, err)
   846  
   847  			assert.NotEmpty(t, response)
   848  			assert.Equal(t, []*model.OperatorInterventionErrorResponse{
   849  				{
   850  					Type:      model.OperatorInterventionErrorTypeUnknownRule,
   851  					Privilege: func() *string { s := "ea-read"; return &s }(),
   852  					Command:   func() *string { s := "ls"; return &s }(),
   853  				},
   854  			}, response.Errors)
   855  
   856  			return ctx
   857  		}).
   858  		Feature()
   859  	f.Test(t, feat)
   860  }
   861  
   862  func TestUpdateOperatorInterventionRules(t *testing.T) {
   863  	feat := f2.NewFeature("Create OI Rules").
   864  		Setup("Add Commands", func(ctx f2.Context, t *testing.T) f2.Context {
   865  			db := postgres.FromContextT(ctx, t).DB()
   866  			oiService := services.NewOperatorInterventionService(db)
   867  			payload := []*model.OperatorInterventionCommandInput{
   868  				{Name: "testCommand1"},
   869  				{Name: "testCommand2"},
   870  				{Name: "testCommand3"},
   871  			}
   872  			response, err := oiService.CreateCommands(ctx, payload)
   873  			assert.NoError(t, err)
   874  
   875  			assert.Empty(t, response)
   876  			return ctx
   877  		}).
   878  		Setup("Add Privileges", func(ctx f2.Context, t *testing.T) f2.Context {
   879  			db := postgres.FromContextT(ctx, t).DB()
   880  			oiService := services.NewOperatorInterventionService(db)
   881  			payload := []*model.OperatorInterventionPrivilegeInput{
   882  				{Name: "testPriv1"},
   883  				{Name: "testPriv2"},
   884  				{Name: "testPriv3"},
   885  			}
   886  			response, err := oiService.CreatePrivileges(ctx, payload)
   887  			assert.NoError(t, err)
   888  
   889  			assert.Empty(t, response)
   890  			return ctx
   891  		}).
   892  		Test("Create Rule", func(ctx f2.Context, t *testing.T) f2.Context {
   893  			payload := []*model.UpdateOperatorInterventionRuleInput{{
   894  				//{Commands: []string{"testCommand1"}, Privilege: "testPriv1"},
   895  				Privilege: &model.OperatorInterventionPrivilegeInput{Name: "testPriv1"},
   896  				Commands: []*model.OperatorInterventionCommandInput{
   897  					{Name: "testCommand1"},
   898  				},
   899  			},
   900  			}
   901  			db := postgres.FromContextT(ctx, t).DB()
   902  			oiService := services.NewOperatorInterventionService(db)
   903  			response, err := oiService.UpdateRules(ctx, payload)
   904  			assert.NoError(t, err)
   905  
   906  			assert.Empty(t, response)
   907  
   908  			assertRulesInDB(ctx, t, []*model.Rule{
   909  				{
   910  					Commands: []*model.Command{
   911  						{Name: "testCommand1"}},
   912  					Privilege: &model.Privilege{
   913  						Name: "testPriv1",
   914  					},
   915  				},
   916  			})
   917  			return ctx
   918  		}).
   919  		Test("Conflicting Rule", func(ctx f2.Context, t *testing.T) f2.Context {
   920  			payload := []*model.UpdateOperatorInterventionRuleInput{
   921  				{
   922  					Privilege: &model.OperatorInterventionPrivilegeInput{Name: "testPriv1"},
   923  					Commands: []*model.OperatorInterventionCommandInput{
   924  						{Name: "testCommand1"},
   925  					},
   926  				},
   927  			}
   928  			db := postgres.FromContextT(ctx, t).DB()
   929  			oiService := services.NewOperatorInterventionService(db)
   930  			response, err := oiService.UpdateRules(ctx, payload)
   931  			assert.NoError(t, err)
   932  
   933  			assert.Empty(t, response)
   934  			assertRulesInDB(ctx, t, []*model.Rule{
   935  				{
   936  					Commands: []*model.Command{
   937  						{Name: "testCommand1"}},
   938  					Privilege: &model.Privilege{
   939  						Name: "testPriv1",
   940  					},
   941  				},
   942  			})
   943  			return ctx
   944  		}).
   945  		Test("Create Rule with multiple commands", func(ctx f2.Context, t *testing.T) f2.Context {
   946  			payload := []*model.UpdateOperatorInterventionRuleInput{
   947  				{
   948  					// Commands: []string{
   949  					// 	"testCommand2",
   950  					// 	"testCommand3",
   951  					// },
   952  					// Privilege: "testPriv1"
   953  					Privilege: &model.OperatorInterventionPrivilegeInput{Name: "testPriv1"},
   954  					Commands: []*model.OperatorInterventionCommandInput{
   955  						{Name: "testCommand2"},
   956  						{Name: "testCommand3"},
   957  					},
   958  				},
   959  			}
   960  			db := postgres.FromContextT(ctx, t).DB()
   961  			oiService := services.NewOperatorInterventionService(db)
   962  			response, err := oiService.UpdateRules(ctx, payload)
   963  			assert.NoError(t, err)
   964  
   965  			assert.Empty(t, response)
   966  			assertRulesInDB(ctx, t, []*model.Rule{
   967  				{
   968  					Commands: []*model.Command{
   969  						{Name: "testCommand1"},
   970  						{Name: "testCommand2"}, //new
   971  						{Name: "testCommand3"}, //new
   972  					},
   973  					Privilege: &model.Privilege{
   974  						Name: "testPriv1",
   975  					},
   976  				},
   977  			})
   978  			return ctx
   979  		}).
   980  		Test("Create Rule with multiple privileges", func(ctx f2.Context, t *testing.T) f2.Context {
   981  			payload := []*model.UpdateOperatorInterventionRuleInput{
   982  				{
   983  					Privilege: &model.OperatorInterventionPrivilegeInput{Name: "testPriv2"},
   984  					Commands: []*model.OperatorInterventionCommandInput{
   985  						{Name: "testCommand1"},
   986  					},
   987  				},
   988  				{
   989  					Privilege: &model.OperatorInterventionPrivilegeInput{Name: "testPriv3"},
   990  					Commands: []*model.OperatorInterventionCommandInput{
   991  						{Name: "testCommand1"},
   992  					},
   993  				},
   994  			}
   995  			db := postgres.FromContextT(ctx, t).DB()
   996  			oiService := services.NewOperatorInterventionService(db)
   997  			response, err := oiService.UpdateRules(ctx, payload)
   998  			assert.NoError(t, err)
   999  
  1000  			assert.Empty(t, response)
  1001  			assertRulesInDB(ctx, t, []*model.Rule{
  1002  				{
  1003  					Commands: []*model.Command{
  1004  						{Name: "testCommand1"},
  1005  						{Name: "testCommand2"},
  1006  						{Name: "testCommand3"},
  1007  					},
  1008  					Privilege: &model.Privilege{
  1009  						Name: "testPriv1",
  1010  					},
  1011  				},
  1012  				{ //new
  1013  					Commands: []*model.Command{
  1014  						{Name: "testCommand1"},
  1015  					},
  1016  					Privilege: &model.Privilege{
  1017  						Name: "testPriv2",
  1018  					},
  1019  				},
  1020  				{ //new
  1021  					Commands: []*model.Command{
  1022  						{Name: "testCommand1"},
  1023  					},
  1024  					Privilege: &model.Privilege{
  1025  						Name: "testPriv3",
  1026  					},
  1027  				},
  1028  			})
  1029  			return ctx
  1030  		}).
  1031  		Test("Fail to create rule with non-existing command", func(ctx f2.Context, t *testing.T) f2.Context {
  1032  			payload := []*model.UpdateOperatorInterventionRuleInput{
  1033  				{
  1034  					Privilege: &model.OperatorInterventionPrivilegeInput{Name: "testPriv1"},
  1035  					Commands: []*model.OperatorInterventionCommandInput{
  1036  						{Name: "non-existent-command"},
  1037  					},
  1038  				},
  1039  			}
  1040  			db := postgres.FromContextT(ctx, t).DB()
  1041  			oiService := services.NewOperatorInterventionService(db)
  1042  			response, err := oiService.UpdateRules(ctx, payload)
  1043  			assert.NoError(t, err)
  1044  
  1045  			assert.NotEmpty(t, response)
  1046  			assert.Equal(t, []*model.OperatorInterventionErrorResponse{
  1047  				{
  1048  					Type:    model.OperatorInterventionErrorTypeUnknownCommand,
  1049  					Command: func() *string { s := "non-existent-command"; return &s }(),
  1050  				},
  1051  			}, response.Errors)
  1052  			return ctx
  1053  		}).
  1054  		Test("Fail to create rule with non-existing privilege", func(ctx f2.Context, t *testing.T) f2.Context {
  1055  			payload := []*model.UpdateOperatorInterventionRuleInput{
  1056  				{
  1057  					Privilege: &model.OperatorInterventionPrivilegeInput{Name: "non-existent-privilege"},
  1058  					Commands: []*model.OperatorInterventionCommandInput{
  1059  						{Name: "testCommand1"},
  1060  					},
  1061  				},
  1062  			}
  1063  			db := postgres.FromContextT(ctx, t).DB()
  1064  			oiService := services.NewOperatorInterventionService(db)
  1065  			response, err := oiService.UpdateRules(ctx, payload)
  1066  			assert.NoError(t, err)
  1067  
  1068  			assert.NotEmpty(t, response)
  1069  			assert.Equal(t, []*model.OperatorInterventionErrorResponse{
  1070  				{
  1071  					Type:      model.OperatorInterventionErrorTypeUnknownPrivilege,
  1072  					Privilege: func() *string { s := "non-existent-privilege"; return &s }(),
  1073  				},
  1074  			}, response.Errors)
  1075  			return ctx
  1076  		}).
  1077  		Test("Create rule despite conflicting rule", func(ctx f2.Context, t *testing.T) f2.Context {
  1078  			payload := []*model.UpdateOperatorInterventionRuleInput{
  1079  				// {Commands: []string{"testCommand1"}, Privilege: "testPriv1"}, // already present
  1080  				// {Commands: []string{"testCommand2"}, Privilege: "testPriv2"}, // new
  1081  				{
  1082  					Privilege: &model.OperatorInterventionPrivilegeInput{Name: "testPriv1"}, //already present
  1083  					Commands: []*model.OperatorInterventionCommandInput{
  1084  						{Name: "testCommand1"},
  1085  					},
  1086  				},
  1087  				{
  1088  					Privilege: &model.OperatorInterventionPrivilegeInput{Name: "testPriv2"}, //new
  1089  					Commands: []*model.OperatorInterventionCommandInput{
  1090  						{Name: "testCommand2"},
  1091  					},
  1092  				},
  1093  			}
  1094  			db := postgres.FromContextT(ctx, t).DB()
  1095  			oiService := services.NewOperatorInterventionService(db)
  1096  			response, err := oiService.UpdateRules(ctx, payload)
  1097  			assert.NoError(t, err)
  1098  
  1099  			assert.Empty(t, response)
  1100  			assertRulesInDB(ctx, t, []*model.Rule{
  1101  				{
  1102  					Commands: []*model.Command{
  1103  						{Name: "testCommand1"},
  1104  						{Name: "testCommand2"},
  1105  						{Name: "testCommand3"},
  1106  					},
  1107  					Privilege: &model.Privilege{
  1108  						Name: "testPriv1",
  1109  					},
  1110  				},
  1111  				{
  1112  					Commands: []*model.Command{
  1113  						{Name: "testCommand1"},
  1114  						{Name: "testCommand2"}, //new
  1115  					},
  1116  					Privilege: &model.Privilege{
  1117  						Name: "testPriv2",
  1118  					},
  1119  				},
  1120  				{
  1121  					Commands: []*model.Command{
  1122  						{Name: "testCommand1"},
  1123  					},
  1124  					Privilege: &model.Privilege{
  1125  						Name: "testPriv3",
  1126  					},
  1127  				},
  1128  			})
  1129  			return ctx
  1130  		}).
  1131  		Feature()
  1132  	f.Test(t, feat)
  1133  }
  1134  
  1135  func assertRulesInDB(ctx f2.Context, t *testing.T, expectedRules []*model.Rule) {
  1136  	db := postgres.FromContextT(ctx, t).DB()
  1137  	oiService := services.NewOperatorInterventionService(db)
  1138  
  1139  	rules, err := oiService.ReadRules(ctx, nil)
  1140  	assert.NoError(t, err)
  1141  	assert.ElementsMatch(t, expectedRules, rules)
  1142  }
  1143  
  1144  func TestReadOperatorInterventionRules(t *testing.T) {
  1145  	feat := f2.NewFeature("Read OI Rules").
  1146  		Setup("Load Data", postgres.WithData(oiSeedData)).
  1147  		Test("Read all rules", func(ctx f2.Context, t *testing.T) f2.Context {
  1148  			db := postgres.FromContextT(ctx, t).DB()
  1149  			oiService := services.NewOperatorInterventionService(db)
  1150  			rules, err := oiService.ReadRules(ctx, nil)
  1151  			assert.NoError(t, err)
  1152  			assert.Greater(t, len(rules), 0)
  1153  			return ctx
  1154  		}).
  1155  		Test("Read one rule", func(ctx f2.Context, t *testing.T) f2.Context {
  1156  			db := postgres.FromContextT(ctx, t).DB()
  1157  			oiService := services.NewOperatorInterventionService(db)
  1158  			rules, err := oiService.ReadRules(ctx, []*model.OperatorInterventionPrivilegeInput{
  1159  				{Name: "ea-read"},
  1160  			})
  1161  			assert.NoError(t, err)
  1162  			assert.Len(t, rules, 1)
  1163  			assert.Equal(t, "ea-read", rules[0].Privilege.Name)
  1164  			return ctx
  1165  		}).
  1166  		Test("Read multiple rules", func(ctx f2.Context, t *testing.T) f2.Context {
  1167  			db := postgres.FromContextT(ctx, t).DB()
  1168  			oiService := services.NewOperatorInterventionService(db)
  1169  			rules, err := oiService.ReadRules(ctx, []*model.OperatorInterventionPrivilegeInput{
  1170  				{Name: "ea-read"},
  1171  				{Name: "ea-write"},
  1172  			})
  1173  			assert.NoError(t, err)
  1174  			assert.Len(t, rules, 2)
  1175  			return ctx
  1176  		}).
  1177  		Feature()
  1178  	f.Test(t, feat)
  1179  }
  1180  

View as plain text