package services import ( "context" "errors" "fmt" "testing" "github.com/DATA-DOG/go-sqlmock" "github.com/lib/pq" "github.com/stretchr/testify/assert" "edge-infra.dev/pkg/edge/api/graph/model" "edge-infra.dev/pkg/edge/api/services/artifacts" clustersvc "edge-infra.dev/pkg/edge/api/services/cluster" clusterlabel "edge-infra.dev/pkg/edge/api/services/cluster/label" sqlquery "edge-infra.dev/pkg/edge/api/sql" "edge-infra.dev/pkg/edge/capabilities" "edge-infra.dev/pkg/edge/constants/api/fleet" "edge-infra.dev/pkg/lib/runtime/version" ) var testLabelClusterEdgeID = "test-label-cluster-edge-id" var testLabelID = "123456" var testLabelID2 = "123457" var testLabelID3 = "123458" var testLabelID4 = "123459" var artifactName = "virtual-machines" func TestDeleteLabelSQLEntry(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() mock.ExpectExec(sqlquery.LabelDeleteQuery).WithArgs(testLabelID). WillReturnResult(sqlmock.NewResult(1, 1)) artifactsService := artifacts.NewArtifactsService(db, nil) service := NewLabelService(artifactsService, db) assert.NoError(t, service.DeleteLabels(context.Background(), testLabelID)) assert.NoError(t, mock.ExpectationsWereMet()) } func TestDeleteClusterLabelSQLEntrySadPath(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() // Delete "edge-fleet" label from this cluster mock.ExpectBegin() mock.ExpectQuery(fmt.Sprintf(sqlquery.ClusterLabelDeleteQuery, sqlquery.WhereClusterEdgeIDAndLabelID)).WithArgs(testLabelClusterEdgeID, testLabelID). WillReturnRows(mock.NewRows([]string{"cluster_edge_id", "label_edge_id"}). AddRow(testLabelClusterEdgeID, testLabelID)) mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID, "store", "#00000", true, false, "f2af0c5b-7412-4f81-b024-1741e01700a3", true, "test label", "edge-fleet")) mock.ExpectRollback() // Delete "edge-type" label from this cluster mock.ExpectBegin() mock.ExpectQuery(fmt.Sprintf(sqlquery.ClusterLabelDeleteQuery, sqlquery.WhereClusterEdgeIDAndLabelID)).WithArgs(testLabelClusterEdgeID, testLabelID). WillReturnRows(mock.NewRows([]string{"cluster_edge_id", "label_edge_id"}). AddRow(testLabelClusterEdgeID, testLabelID)) mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID, "generic", "#00000", true, false, "f2af0c5b-7412-4f81-b024-1741e01700a3", true, "test label", "edge-type")) mock.ExpectRollback() artifactsService := artifacts.NewArtifactsService(db, nil) service := NewLabelService(artifactsService, db) assert.Error(t, service.DeleteClusterLabels(context.Background(), nil, nil), "error was expected while deleting label without providing cluster_edge_id or label_id") // return an error when labelEdgeID is empty var empty = "" assert.Error(t, service.DeleteClusterLabels(context.Background(), &testLabelClusterEdgeID, &empty)) assert.Error(t, service.DeleteClusterLabels(context.Background(), &testLabelClusterEdgeID, nil)) assert.Error(t, service.DeleteClusterLabels(context.Background(), &testLabelClusterEdgeID, &testLabelID)) assert.Error(t, service.DeleteClusterLabels(context.Background(), &testLabelClusterEdgeID, &testLabelID)) assert.NoError(t, mock.ExpectationsWereMet()) } func TestDeleteClusterLabelSQLEntry(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() // Delete label from every cluster mock.ExpectBegin() mock.ExpectQuery(fmt.Sprintf(sqlquery.ClusterLabelDeleteQuery, sqlquery.WhereLabelID)).WithArgs(testLabelID). WillReturnRows(mock.NewRows([]string{"cluster_edge_id", "label_edge_id"}). AddRow("85b30e25-044b-47df-a3c6-ee35ce13da11", testLabelID). AddRow("00ab4628-457d-4f65-be6f-01029189de11", testLabelID). AddRow("1aa952d3-1123-435d-a433-d28304362cbb", testLabelID). AddRow("9c7e6c1b-1c0f-4b54-8571-46ba15357594", testLabelID)) mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID, "foo", "#00000", true, false, "f2af0c5b-7412-4f81-b024-1741e01700a3", true, "test label", "foo")) mock.ExpectCommit() // Delete edge capability label from every cluster mock.ExpectBegin() mock.ExpectQuery(fmt.Sprintf(sqlquery.ClusterLabelDeleteQuery, sqlquery.WhereLabelID)).WithArgs(testLabelID). WillReturnRows(mock.NewRows([]string{"cluster_edge_id", "label_edge_id"}). AddRow("85b30e25-044b-47df-a3c6-ee35ce13da11", testLabelID). AddRow("00ab4628-457d-4f65-be6f-01029189de11", testLabelID). AddRow("1aa952d3-1123-435d-a433-d28304362cbb", testLabelID). AddRow("9c7e6c1b-1c0f-4b54-8571-46ba15357594", testLabelID)) mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID, capabilities.EdgeCapabilities[0].ArtifactName, "#00000", true, false, "f2af0c5b-7412-4f81-b024-1741e01700a3", true, "test label", capabilities.EdgeCapabilitiesLabel)) mock.ExpectQuery(sqlquery.GetClusterArtifactVersions).WithArgs("85b30e25-044b-47df-a3c6-ee35ce13da11"). WillReturnRows(mock.NewRows([]string{"artifact_name", "artifact_version"}).AddRow(artifactName, version.New().SemVer)) mock.ExpectExec(sqlquery.DeleteClusterArtifactVersion).WithArgs("85b30e25-044b-47df-a3c6-ee35ce13da11", artifactName). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.GetClusterArtifactVersions).WithArgs("00ab4628-457d-4f65-be6f-01029189de11"). WillReturnRows(mock.NewRows([]string{"artifact_name", "artifact_version"}).AddRow(artifactName, version.New().SemVer)) mock.ExpectExec(sqlquery.DeleteClusterArtifactVersion).WithArgs("00ab4628-457d-4f65-be6f-01029189de11", artifactName). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.GetClusterArtifactVersions).WithArgs("1aa952d3-1123-435d-a433-d28304362cbb"). WillReturnRows(mock.NewRows([]string{"artifact_name", "artifact_version"}).AddRow(artifactName, version.New().SemVer)) mock.ExpectExec(sqlquery.DeleteClusterArtifactVersion).WithArgs("1aa952d3-1123-435d-a433-d28304362cbb", artifactName). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.GetClusterArtifactVersions).WithArgs("9c7e6c1b-1c0f-4b54-8571-46ba15357594"). WillReturnRows(mock.NewRows([]string{"artifact_name", "artifact_version"}).AddRow(artifactName, version.New().SemVer)) mock.ExpectExec(sqlquery.DeleteClusterArtifactVersion).WithArgs("9c7e6c1b-1c0f-4b54-8571-46ba15357594", artifactName). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() // Delete label from this cluster mock.ExpectBegin() mock.ExpectQuery(fmt.Sprintf(sqlquery.ClusterLabelDeleteQuery, sqlquery.WhereClusterEdgeIDAndLabelID)).WithArgs(testLabelClusterEdgeID, testLabelID). WillReturnRows(mock.NewRows([]string{"cluster_edge_id", "label_edge_id"}). AddRow(testLabelClusterEdgeID, testLabelID)) mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID, "foo", "#00000", true, false, "f2af0c5b-7412-4f81-b024-1741e01700a3", true, "test label", "foo")) mock.ExpectCommit() // Delete edge capability label from this cluster mock.ExpectBegin() mock.ExpectQuery(fmt.Sprintf(sqlquery.ClusterLabelDeleteQuery, sqlquery.WhereClusterEdgeIDAndLabelID)).WithArgs(testLabelClusterEdgeID, testLabelID). WillReturnRows(mock.NewRows([]string{"cluster_edge_id", "label_edge_id"}). AddRow(testLabelClusterEdgeID, testLabelID)) mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID, capabilities.EdgeCapabilities[0].ArtifactName, "#00000", true, false, "f2af0c5b-7412-4f81-b024-1741e01700a3", true, "test label", capabilities.EdgeCapabilitiesLabel)) mock.ExpectQuery(sqlquery.GetClusterArtifactVersions).WithArgs(testLabelClusterEdgeID). WillReturnRows(mock.NewRows([]string{"artifact_name", "artifact_version"}).AddRow(artifactName, version.New().SemVer)) mock.ExpectExec(sqlquery.DeleteClusterArtifactVersion).WithArgs(testLabelClusterEdgeID, artifactName). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() clusterLabelSvc := clustersvc.NewLabelService(db) artifactsService := artifacts.NewArtifactsService(db, clusterLabelSvc) service := NewLabelService(artifactsService, db) assert.NoError(t, service.DeleteClusterLabels(context.Background(), nil, &testLabelID)) assert.NoError(t, service.DeleteClusterLabels(context.Background(), nil, &testLabelID)) assert.NoError(t, service.DeleteClusterLabels(context.Background(), &testLabelClusterEdgeID, &testLabelID)) assert.NoError(t, service.DeleteClusterLabels(context.Background(), &testLabelClusterEdgeID, &testLabelID)) assert.NoError(t, mock.ExpectationsWereMet()) } func TestLabelService_CreateClusterLabelSQLEntry_Sad(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() // label with uniqeness conflict mock.ExpectBegin() mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID, capabilities.EdgeCapabilities[0].ArtifactName, "#00000", true, false, "f2af0c5b-7412-4f81-b024-1741e01700a3", true, "test label", capabilities.EdgeCapabilitiesLabel)) mock.ExpectExec(sqlquery.ClusterLabelInsertQuery).WithArgs(testClusterEdgeID, testLabelID). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.SelectClusterLabelsUniqueCount).WithArgs(testClusterEdgeID, capabilities.EdgeCapabilitiesLabel).WillReturnRows(mock.NewRows([]string{"count"}).AddRow(2)) mock.ExpectRollback() // banner-wide label mock.ExpectBegin() mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID, "foo", "#00000", true, false, "", true, "test label", "foo")) mock.ExpectRollback() // label with edge capabilities that is higher than the cluster version mock.ExpectBegin() mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID, capabilities.EdgeCapabilities[0].ArtifactName, "#00000", true, false, "f2af0c5b-7412-4f81-b024-1741e01700a3", true, "test label", capabilities.EdgeCapabilitiesLabel)) mock.ExpectExec(sqlquery.ClusterLabelInsertQuery).WithArgs(testClusterEdgeID, testLabelID). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.SelectClusterLabelsUniqueCount).WithArgs(testClusterEdgeID, capabilities.EdgeCapabilitiesLabel).WillReturnRows(mock.NewRows([]string{"count"}).AddRow(1)) mock.ExpectQuery(sqlquery.GetClusterFleetVersion).WillReturnRows(mock.NewRows([]string{"fleet_version"}).AddRow("0.19.0")) clusterLabelSvc := clustersvc.NewLabelService(db) artifactsService := artifacts.NewArtifactsService(db, clusterLabelSvc) service := NewLabelService(artifactsService, db) assert.Error(t, service.CreateClusterLabel(context.Background(), testClusterEdgeID, testLabelID)) assert.Error(t, service.CreateClusterLabel(context.Background(), testClusterEdgeID, testLabelID)) assert.Error(t, service.CreateClusterLabel(context.Background(), testClusterEdgeID, testLabelID)) } func TestLabelService_CreateClusterLabelSQLEntry(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() // label that is unique with edge capabilities mock.ExpectBegin() mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID, capabilities.EdgeCapabilities[0].ArtifactName, "#00000", true, false, "f2af0c5b-7412-4f81-b024-1741e01700a3", true, "test label", capabilities.EdgeCapabilitiesLabel)) mock.ExpectExec(sqlquery.ClusterLabelInsertQuery).WithArgs(testClusterEdgeID, testLabelID). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.SelectClusterLabelsUniqueCount).WithArgs(testClusterEdgeID, capabilities.EdgeCapabilitiesLabel).WillReturnRows(mock.NewRows([]string{"count"}).AddRow(1)) mock.ExpectQuery(sqlquery.GetClusterFleetVersion).WillReturnRows(mock.NewRows([]string{"fleet_version"}).AddRow("0.21.0")) mock.ExpectQuery(sqlquery.GetClusterArtifactVersions).WithArgs(testClusterEdgeID). WillReturnRows(mock.NewRows([]string{"artifact_name", "artifact_version"}).AddRow(fleet.Store, version.New().SemVer)) mock.ExpectQuery(clusterlabel.FetchFleetType).WithArgs(testClusterEdgeID). WillReturnRows(mock.NewRows([]string{"label_key"}).AddRow(fleet.Store)) mock.ExpectExec(sqlquery.CreateClusterArtifactVersion).WithArgs(testClusterEdgeID, artifactName, version.New().SemVer).WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() // label that is unique but is not edge capabilities mock.ExpectBegin() mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID, "foo", "#00000", true, false, "f2af0c5b-7412-4f81-b024-1741e01700a3", true, "test label", "foo")) mock.ExpectExec(sqlquery.ClusterLabelInsertQuery).WithArgs(testClusterEdgeID, testLabelID). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.SelectClusterLabelsUniqueCount).WithArgs(testClusterEdgeID, "foo").WillReturnRows(mock.NewRows([]string{"count"}).AddRow(1)) mock.ExpectCommit() // label that is not unique mock.ExpectBegin() mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID, "foo", "#00000", true, false, "f2af0c5b-7412-4f81-b024-1741e01700a3", false, "test label", "foo")) mock.ExpectExec(sqlquery.ClusterLabelInsertQuery).WithArgs(testClusterEdgeID, testLabelID). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() clusterLabelSvc := clustersvc.NewLabelService(db) artifactsService := artifacts.NewArtifactsService(db, clusterLabelSvc) service := NewLabelService(artifactsService, db) assert.NoError(t, service.CreateClusterLabel(context.Background(), testClusterEdgeID, testLabelID)) assert.NoError(t, service.CreateClusterLabel(context.Background(), testClusterEdgeID, testLabelID)) assert.NoError(t, service.CreateClusterLabel(context.Background(), testClusterEdgeID, testLabelID)) assert.NoError(t, mock.ExpectationsWereMet()) } func TestLabelService_CreateClusterLabels(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() // check that a failed insert rolls back entire call to CreateClusterLabels mock.ExpectBegin() mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID, "test-label", "#00000", true, true, "f2af0c5b-7412-4f81-b024-1741e01700a3", false, "test label", "")) mock.ExpectExec(sqlquery.ClusterLabelInsertQuery).WithArgs(testClusterEdgeID, testLabelID). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID2, capabilities.EdgeCapabilities[0].ArtifactName, "#00000", true, false, "f2af0c5b-7412-4f81-b024-1741e01700a3", true, "test label", capabilities.EdgeCapabilitiesLabel)) mock.ExpectExec(sqlquery.ClusterLabelInsertQuery).WithArgs(testClusterEdgeID, testLabelID2). WillReturnError(errors.New("error creating cluster label")) mock.ExpectRollback() // create a normal label (not unique), and a label with edge capabilities. mock.ExpectBegin() mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID, "test-label", "#00000", true, true, "f2af0c5b-7412-4f81-b024-1741e01700a3", false, "test label", "")) mock.ExpectExec(sqlquery.ClusterLabelInsertQuery).WithArgs(testClusterEdgeID, testLabelID). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.GetLabelQuery).WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(testLabelID2, capabilities.EdgeCapabilities[0].ArtifactName, "#00000", true, false, "f2af0c5b-7412-4f81-b024-1741e01700a3", true, "test label", capabilities.EdgeCapabilitiesLabel)) mock.ExpectExec(sqlquery.ClusterLabelInsertQuery).WithArgs(testClusterEdgeID, testLabelID2). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.SelectClusterLabelsUniqueCount).WithArgs(testClusterEdgeID, capabilities.EdgeCapabilitiesLabel).WillReturnRows(mock.NewRows([]string{"count"}).AddRow(1)) mock.ExpectQuery(sqlquery.GetClusterFleetVersion).WillReturnRows(mock.NewRows([]string{"fleet_version"}).AddRow("0.21.0")) mock.ExpectQuery(sqlquery.GetClusterArtifactVersions).WithArgs(testClusterEdgeID). WillReturnRows(mock.NewRows([]string{"artifact_name", "artifact_version"}).AddRow(fleet.Store, version.New().SemVer)) mock.ExpectQuery(clusterlabel.FetchFleetType).WithArgs(testClusterEdgeID). WillReturnRows(mock.NewRows([]string{"label_key"}).AddRow(fleet.Store)) mock.ExpectExec(sqlquery.CreateClusterArtifactVersion).WithArgs(testClusterEdgeID, artifactName, version.New().SemVer).WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() clusterLabelSvc := clustersvc.NewLabelService(db) artifactsService := artifacts.NewArtifactsService(db, clusterLabelSvc) service := NewLabelService(artifactsService, db) assert.Error(t, service.CreateClusterLabels(context.Background(), testClusterEdgeID, []string{testLabelID, testLabelID2})) assert.NoError(t, service.CreateClusterLabels(context.Background(), testClusterEdgeID, []string{testLabelID, testLabelID2})) assert.NoError(t, mock.ExpectationsWereMet()) } func TestGetClusterLabelSQLEntry(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() // get with cluster_edge_id mock.ExpectQuery(fmt.Sprintf(sqlquery.GetClusterLabelsQuery, sqlquery.WhereClusterEdgeID)).WithArgs(&testLabelClusterEdgeID). WillReturnRows(mock.NewRows([]string{"labelid", "cluster_edge_id"}). AddRow(testLabelClusterEdgeID, testLabelID)) // get with label_edge_id mock.ExpectQuery(fmt.Sprintf(sqlquery.GetClusterLabelsQuery, sqlquery.WhereLabelID)).WithArgs(&testLabelID). WillReturnRows(mock.NewRows([]string{"labelid", "cluster_edge_id"}). AddRow(testLabelClusterEdgeID, testLabelID). AddRow(testLabelClusterEdgeID+"-2", testLabelID)) // get with cluster_edge_id and label_edge_id mock.ExpectQuery(fmt.Sprintf(sqlquery.GetClusterLabelsQuery, sqlquery.WhereClusterEdgeIDAndLabelID)).WithArgs(&testLabelClusterEdgeID, &testLabelID). WillReturnRows(mock.NewRows([]string{"labelid", "cluster_edge_id"}). AddRow(testLabelClusterEdgeID, testLabelID)) artifactsService := artifacts.NewArtifactsService(db, nil) service := NewLabelService(artifactsService, db) vals, err := service.GetClusterLabels(context.Background(), &testLabelClusterEdgeID, nil) assert.NoError(t, err) assert.Equal(t, len(vals), 1) vals, err = service.GetClusterLabels(context.Background(), nil, &testLabelID) assert.NoError(t, err) assert.Equal(t, len(vals), 2) vals, err = service.GetClusterLabels(context.Background(), &testLabelClusterEdgeID, &testLabelID) assert.NoError(t, err) assert.Equal(t, len(vals), 1) _, err = service.GetClusterLabels(context.Background(), nil, nil) assert.Error(t, err, "cluster_edge_id and/or label_edge_id are required") assert.NoError(t, mock.ExpectationsWereMet()) } func TestCreateLabelSQLEntry_Sad(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() clusterLabelSvc := clustersvc.NewLabelService(db) artifactsService := artifacts.NewArtifactsService(db, clusterLabelSvc) service := NewLabelService(artifactsService, db) // banner-wide label assert.Error(t, service.CreateLabel(context.Background(), &model.LabelInput{ Key: "foo", Color: "#123456", Visible: true, Editable: true, BannerEdgeID: "", Unique: false, Description: "label description", Type: "foo", })) // unique label with missing type assert.Error(t, service.CreateLabel(context.Background(), &model.LabelInput{ Key: "baz", Color: "#123456", Visible: true, Editable: true, BannerEdgeID: "test-tenant", Unique: true, Description: "label description", Type: "", })) // label using reserved type values labelReservedType := &model.LabelInput{ Key: "bar", Color: "#123456", Visible: true, Editable: true, BannerEdgeID: "test-tenant", Unique: false, Description: "label description", } labelReservedType.Type = "edge-type" assert.Error(t, service.CreateLabel(context.Background(), labelReservedType)) labelReservedType.Type = "edge-fleet" assert.Error(t, service.CreateLabel(context.Background(), labelReservedType)) assert.NoError(t, mock.ExpectationsWereMet()) } func TestCreateLabelSQLEntry(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() labelVisible := &model.LabelInput{ Key: "test-label", Color: "#123456", Visible: true, Editable: true, BannerEdgeID: "test-tenant", Unique: false, Description: "label description", Type: "label type", } labelNotVisible := &model.LabelInput{ Key: "test-label", Color: "#123456", Visible: false, Editable: true, BannerEdgeID: "test-tenant", Unique: false, Description: "label description", Type: "label type", } // create visible label mock.ExpectExec(sqlquery.LabelInsertQuery).WithArgs(labelVisible.Key, labelVisible.Color, labelVisible.Visible, labelVisible.Editable, labelVisible.BannerEdgeID, labelVisible.Unique, labelVisible.Description, labelVisible.Type). WillReturnResult(sqlmock.NewResult(1, 1)) // create non-visible label mock.ExpectExec(sqlquery.LabelInsertQuery).WithArgs(labelNotVisible.Key, labelNotVisible.Color, labelNotVisible.Visible, labelNotVisible.Editable, labelNotVisible.BannerEdgeID, labelNotVisible.Unique, labelNotVisible.Description, labelNotVisible.Type). WillReturnResult(sqlmock.NewResult(1, 1)) clusterLabelSvc := clustersvc.NewLabelService(db) artifactsService := artifacts.NewArtifactsService(db, clusterLabelSvc) service := NewLabelService(artifactsService, db) assert.NoError(t, service.CreateLabel(context.Background(), labelVisible)) assert.NoError(t, service.CreateLabel(context.Background(), labelNotVisible)) assert.NoError(t, mock.ExpectationsWereMet()) } func TestUpdateLabelSQLEntry_Sad(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() label := &model.LabelUpdateInput{ LabelEdgeID: testLabelID, LabelValues: &model.LabelInput{ Key: "test-label", Color: "#123456", Editable: true, Visible: false, BannerEdgeID: "test-tenant", Unique: false, Description: "label description", Type: "label type", }, } newType := "some other type" // update banner-wide label mock.ExpectBegin() mock.ExpectQuery(sqlquery.GetLabelQuery).WithArgs(label.LabelEdgeID). WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(label.LabelEdgeID, label.LabelValues.Key, label.LabelValues.Color, label.LabelValues.Visible, label.LabelValues.Editable, "", label.LabelValues.Unique, label.LabelValues.Description, label.LabelValues.Type)) mock.ExpectRollback() // set label unique to true mock.ExpectBegin() mock.ExpectQuery(sqlquery.GetLabelQuery).WithArgs(label.LabelEdgeID). WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(label.LabelEdgeID, label.LabelValues.Key, label.LabelValues.Color, label.LabelValues.Visible, label.LabelValues.Editable, label.LabelValues.BannerEdgeID, label.LabelValues.Unique, label.LabelValues.Description, label.LabelValues.Type)) mock.ExpectExec(sqlquery.LabelUpdateQuery).WithArgs(label.LabelValues.Key, label.LabelValues.Color, label.LabelValues.Visible, label.LabelValues.Editable, label.LabelValues.BannerEdgeID, true, label.LabelValues.Description, label.LabelValues.Type, label.LabelEdgeID). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.SelectClusterLabelsUniqueConflicts).WithArgs(label.LabelValues.Type). WillReturnRows(mock.NewRows([]string{"cluster_edge_id"}). AddRow(testClusterEdgeID)) mock.ExpectRollback() // set label type whose unique value is already true mock.ExpectBegin() mock.ExpectQuery(sqlquery.GetLabelQuery).WithArgs(label.LabelEdgeID). WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(label.LabelEdgeID, label.LabelValues.Key, label.LabelValues.Color, label.LabelValues.Visible, label.LabelValues.Editable, label.LabelValues.BannerEdgeID, true, label.LabelValues.Description, label.LabelValues.Type)) mock.ExpectExec(sqlquery.LabelUpdateQuery).WithArgs(label.LabelValues.Key, label.LabelValues.Color, label.LabelValues.Visible, label.LabelValues.Editable, label.LabelValues.BannerEdgeID, true, label.LabelValues.Description, newType, label.LabelEdgeID). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.SelectClusterLabelsUniqueConflicts).WithArgs(newType). WillReturnRows(mock.NewRows([]string{"cluster_edge_id"}). AddRow(testClusterEdgeID)) mock.ExpectRollback() artifactsService := artifacts.NewArtifactsService(db, nil) service := NewLabelService(artifactsService, db) assert.Error(t, service.UpdateLabel(context.Background(), label)) label.LabelValues.Unique = true assert.Error(t, service.UpdateLabel(context.Background(), label)) label.LabelValues.Type = newType assert.Error(t, service.UpdateLabel(context.Background(), label)) // invalid label input will return an error before any sql queries are executed. label.LabelValues.BannerEdgeID = "" assert.Error(t, service.UpdateLabel(context.Background(), label)) assert.NoError(t, mock.ExpectationsWereMet()) } func TestUpdateLabelSQLEntry(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() label := &model.LabelUpdateInput{ LabelEdgeID: testLabelID, LabelValues: &model.LabelInput{ Key: "test-label", Color: "#123456", Editable: true, Visible: false, BannerEdgeID: "test-tenant", Unique: false, Description: "label description", Type: "label type", }, } newType := "some other type" // normal label mock.ExpectBegin() mock.ExpectQuery(sqlquery.GetLabelQuery).WithArgs(label.LabelEdgeID). WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(label.LabelEdgeID, label.LabelValues.Key, label.LabelValues.Color, label.LabelValues.Visible, label.LabelValues.Editable, label.LabelValues.BannerEdgeID, label.LabelValues.Unique, label.LabelValues.Description, label.LabelValues.Type)) mock.ExpectExec(sqlquery.LabelUpdateQuery).WithArgs(label.LabelValues.Key, label.LabelValues.Color, label.LabelValues.Visible, label.LabelValues.Editable, label.LabelValues.BannerEdgeID, label.LabelValues.Unique, label.LabelValues.Description, label.LabelValues.Type, label.LabelEdgeID). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() // set label unique to true (happy path) mock.ExpectBegin() mock.ExpectQuery(sqlquery.GetLabelQuery).WithArgs(label.LabelEdgeID). WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(label.LabelEdgeID, label.LabelValues.Key, label.LabelValues.Color, label.LabelValues.Visible, label.LabelValues.Editable, label.LabelValues.BannerEdgeID, label.LabelValues.Unique, label.LabelValues.Description, label.LabelValues.Type)) mock.ExpectExec(sqlquery.LabelUpdateQuery).WithArgs(label.LabelValues.Key, label.LabelValues.Color, label.LabelValues.Visible, label.LabelValues.Editable, label.LabelValues.BannerEdgeID, true, label.LabelValues.Description, label.LabelValues.Type, label.LabelEdgeID). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.SelectClusterLabelsUniqueConflicts).WithArgs(label.LabelValues.Type). WillReturnRows(sqlmock.NewRows([]string{"cluster_edge_id"})) // no rows mock.ExpectCommit() // set label type whose unique value is already true (happy path) mock.ExpectBegin() mock.ExpectQuery(sqlquery.GetLabelQuery).WithArgs(label.LabelEdgeID). WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow(label.LabelEdgeID, label.LabelValues.Key, label.LabelValues.Color, label.LabelValues.Visible, label.LabelValues.Editable, label.LabelValues.BannerEdgeID, true, label.LabelValues.Description, label.LabelValues.Type)) mock.ExpectExec(sqlquery.LabelUpdateQuery).WithArgs(label.LabelValues.Key, label.LabelValues.Color, label.LabelValues.Visible, label.LabelValues.Editable, label.LabelValues.BannerEdgeID, true, label.LabelValues.Description, newType, label.LabelEdgeID). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(sqlquery.SelectClusterLabelsUniqueConflicts).WithArgs(newType). WillReturnRows(sqlmock.NewRows([]string{"cluster_edge_id"})) // no rows mock.ExpectCommit() artifactsService := artifacts.NewArtifactsService(db, nil) service := NewLabelService(artifactsService, db) assert.NoError(t, service.UpdateLabel(context.Background(), label)) label.LabelValues.Unique = true assert.NoError(t, service.UpdateLabel(context.Background(), label)) label.LabelValues.Type = newType assert.NoError(t, service.UpdateLabel(context.Background(), label)) assert.NoError(t, mock.ExpectationsWereMet()) } func TestGetLabelSQLEntry(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() b := "test-tenant" labelVisible := &model.Label{ LabelEdgeID: testLabelID, Key: "test-label", Color: "#123456", Visible: true, BannerEdgeID: &b, Unique: false, Description: "label description", Type: "label type", } nb := "" labelNoBanner := &model.Label{ LabelEdgeID: testLabelID2, Key: "test-label", Color: "#123456", Visible: true, BannerEdgeID: &nb, Unique: false, Description: "label description", Type: "label type", } mock.ExpectQuery(sqlquery.GetLabelsByBannerQuery). WithArgs(b). WillReturnRows(mock.NewRows([]string{"labelid", "labelkey", "color", "visible", "editable", "banner", "unique", "description", "label_type"}). AddRow(labelVisible.LabelEdgeID, labelVisible.Key, labelVisible.Color, labelVisible.Visible, labelVisible.Editable, labelVisible.BannerEdgeID, labelVisible.Unique, labelVisible.Description, labelVisible.Type)) mock.ExpectQuery(sqlquery.GetNoBannerLabelsQuery). WillReturnRows(mock.NewRows([]string{"labelid", "labelkey", "color", "visible", "editable", "banner", "unique", "description", "label_type"}). AddRow(labelNoBanner.LabelEdgeID, labelNoBanner.Key, labelNoBanner.Color, labelNoBanner.Visible, labelNoBanner.Editable, labelNoBanner.BannerEdgeID, labelNoBanner.Unique, labelNoBanner.Description, labelNoBanner.Type)) mock.ExpectQuery(sqlquery.GetLabelsQuery). WillReturnRows(mock.NewRows([]string{"labelid", "labelkey", "color", "visible", "editable", "banner", "unique", "description", "label_type"}). AddRow(labelNoBanner.LabelEdgeID, labelNoBanner.Key, labelNoBanner.Color, labelNoBanner.Visible, labelNoBanner.Editable, labelNoBanner.BannerEdgeID, labelNoBanner.Unique, labelNoBanner.Description, labelNoBanner.Type). AddRow(labelVisible.LabelEdgeID, labelVisible.Key, labelVisible.Color, labelVisible.Visible, labelVisible.Editable, labelVisible.BannerEdgeID, labelVisible.Unique, labelVisible.Description, labelVisible.Type)) artifactsService := artifacts.NewArtifactsService(db, nil) service := NewLabelService(artifactsService, db) labels, err := service.GetLabels(context.Background(), labelVisible.BannerEdgeID) assert.NoError(t, err) assert.Equal(t, len(labels), 1) assert.Equal(t, labelVisible.LabelEdgeID, labels[0].LabelEdgeID) assert.Equal(t, labelVisible.Key, labels[0].Key) assert.Equal(t, labelVisible.Color, labels[0].Color) assert.Equal(t, labelVisible.Visible, labels[0].Visible) assert.Equal(t, labelVisible.BannerEdgeID, labels[0].BannerEdgeID) labels, err = service.GetLabels(context.Background(), labelNoBanner.BannerEdgeID) assert.NoError(t, err) assert.Equal(t, len(labels), 1) assert.Equal(t, labelNoBanner.LabelEdgeID, labels[0].LabelEdgeID) assert.Equal(t, labelNoBanner.Key, labels[0].Key) assert.Equal(t, labelNoBanner.Color, labels[0].Color) assert.Equal(t, labelNoBanner.Visible, labels[0].Visible) assert.Equal(t, labelNoBanner.BannerEdgeID, labels[0].BannerEdgeID) labels, err = service.GetLabels(context.Background(), nil) assert.NoError(t, err) assert.Equal(t, len(labels), 2) assert.NoError(t, mock.ExpectationsWereMet()) } func TestGetLabelTypes(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() testBanner := "test-banner" mock.ExpectQuery(sqlquery.SelectLabelTypesByBanner). WithArgs(testBanner). WillReturnRows(mock.NewRows([]string{"label_type"}). AddRow(pq.Array([]string{"type1", "type2", "type3"}))) artifactsService := artifacts.NewArtifactsService(db, nil) service := NewLabelService(artifactsService, db) typs, err := service.GetLabelTypes(context.Background(), &testBanner) assert.NoError(t, err) assert.Equal(t, 3, len(typs)) assert.Equal(t, typs[0], "type1") assert.Equal(t, typs[1], "type2") assert.Equal(t, typs[2], "type3") mock.ExpectQuery(sqlquery.SelectLabelTypes). WillReturnRows(mock.NewRows([]string{"label_type"}). AddRow(pq.Array([]string{}))) typs, err = service.GetLabelTypes(context.Background(), nil) assert.NoError(t, err) assert.Equal(t, []string{}, typs) } func TestGetLabelTypesNoBanner(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() mock.ExpectQuery(sqlquery.SelectLabelTypes). WillReturnRows(mock.NewRows([]string{"label_type"}). AddRow(pq.Array([]string{"type1", "type2", "type3"}))) artifactsService := artifacts.NewArtifactsService(db, nil) service := NewLabelService(artifactsService, db) typs, err := service.GetLabelTypes(context.Background(), nil) assert.NoError(t, err) assert.Equal(t, 3, len(typs)) assert.Equal(t, typs[0], "type1") assert.Equal(t, typs[1], "type2") assert.Equal(t, typs[2], "type3") } func TestGetLabel(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() mock.ExpectQuery(sqlquery.GetLabelQuery). WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}). AddRow("de3bacfb-1600-4665-bcda-a6ef19c8206b", "test-label", "#00000", true, true, "f2af0c5b-7412-4f81-b024-1741e01700a3", true, "test label", "")) artifactsService := artifacts.NewArtifactsService(db, nil) service := NewLabelService(artifactsService, db) label, err := service.GetLabel(context.Background(), "de3bacfb-1600-4665-bcda-a6ef19c8206b") assert.NoError(t, err) assert.Equal(t, label.LabelEdgeID, "de3bacfb-1600-4665-bcda-a6ef19c8206b") assert.Equal(t, label.Key, "test-label") assert.Equal(t, label.Color, "#00000") assert.Equal(t, label.Visible, true) assert.Equal(t, label.Editable, true) assert.Equal(t, *label.BannerEdgeID, "f2af0c5b-7412-4f81-b024-1741e01700a3") assert.Equal(t, label.Unique, true) assert.Equal(t, label.Description, "test label") assert.Equal(t, label.Type, "") } func TestGetLabelTenant(t *testing.T) { db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() mock.ExpectQuery(sqlquery.GetTenantLabelQuery). WillReturnRows(mock.NewRows([]string{"tenant_edge_id", "org_id", "org_name"}). AddRow("de3bacfb-1600-4665-bcda-a6ef19c8206b", "3c81acabf8b34f91b811553f2a3ef912", "edge-dev0-edge-b413cb")) artifactsService := artifacts.NewArtifactsService(db, nil) service := NewLabelService(artifactsService, db) tenant, err := service.GetLabelTenant(context.Background(), "de3bacfb-1600-4665-bcda-a6ef19c8206b") assert.NoError(t, err) assert.Equal(t, tenant.TenantEdgeID, "de3bacfb-1600-4665-bcda-a6ef19c8206b") assert.Equal(t, tenant.TenantBSLId, "3c81acabf8b34f91b811553f2a3ef912") assert.Equal(t, tenant.OrgName, "edge-dev0-edge-b413cb") }