package service import ( "context" "fmt" "testing" "github.com/DATA-DOG/go-sqlmock" commonv3 "github.com/RafayLabs/rcloud-base/proto/types/commonpb/v3" infrav3 "github.com/RafayLabs/rcloud-base/proto/types/infrapb/v3" "github.com/google/uuid" ) func performBasicChecks(t *testing.T, metro *infrav3.Location, puuid string) { if metro.Metadata.Name != "metro-"+puuid { t.Error("invalid name returned") } } func TestCreateMetro(t *testing.T) { db, mock := getDB(t) defer db.Close() ps := NewMetroService(db) puuid := uuid.New().String() muuid := uuid.New().String() mock.ExpectQuery(`SELECT "partner"."id", "partner"."name"`). WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid)) mock.ExpectQuery(`INSERT INTO "cluster_metro"`). WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(muuid)) metro := &infrav3.Location{ Metadata: &commonv3.Metadata{Id: muuid, Name: "metro-" + muuid}, Spec: &infrav3.Metro{}, } metro, err := ps.Create(context.Background(), metro) if err != nil { t.Fatal("could not create metro:", err) } performBasicChecks(t, metro, muuid) } func TestCreateMetroDuplicate(t *testing.T) { db, mock := getDB(t) defer db.Close() gs := NewMetroService(db) muuid := uuid.New().String() metro := &infrav3.Location{ Metadata: &commonv3.Metadata{Id: muuid, Name: "metro-" + muuid}, Spec: &infrav3.Metro{}, } // Try to recreate mock.ExpectQuery(`INSERT INTO "cluster_metro"`). WithArgs().WillReturnError(fmt.Errorf("unique constraint violation")) _, err := gs.Create(context.Background(), metro) if err == nil { t.Fatal("should not be able to recreate metro with same name") } } func TestMetroDelete(t *testing.T) { db, mock := getDB(t) defer db.Close() ps := NewMetroService(db) puuid := uuid.New().String() mock.ExpectQuery(`SELECT "metro"."id", "metro"."name", .* FROM "cluster_metro" AS "metro" WHERE`). WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(puuid, "metro-"+puuid)) mock.ExpectExec(`UPDATE "cluster_metro" AS "metro" SET trash = TRUE WHERE`). WillReturnResult(sqlmock.NewResult(1, 1)) metro := &infrav3.Location{ Metadata: &commonv3.Metadata{Id: puuid, Name: "metro-" + puuid}, Spec: &infrav3.Metro{}, } _, err := ps.Delete(context.Background(), metro) if err != nil { t.Fatal("could not delete metro:", err) } } func TestMetroDeleteNonExist(t *testing.T) { db, mock := getDB(t) defer db.Close() ps := NewMetroService(db) puuid := uuid.New().String() mock.ExpectQuery(`SELECT "metro"."id", "metro"."name", .* FROM "cluster_metro" AS "metro" WHERE`). WithArgs().WillReturnError(fmt.Errorf("No data available")) metro := &infrav3.Location{ Metadata: &commonv3.Metadata{Id: puuid, Name: "metro-" + puuid}, Spec: &infrav3.Metro{}, } _, err := ps.Delete(context.Background(), metro) if err == nil { t.Fatal("deleted non existant metro") } } func TestMetroGetByName(t *testing.T) { db, mock := getDB(t) defer db.Close() ps := NewMetroService(db) muuid := uuid.New().String() mock.ExpectQuery(`SELECT "metro"."id", "metro"."name"`). WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(muuid)) metro := &infrav3.Location{ Metadata: &commonv3.Metadata{Id: muuid, Name: "metro-" + muuid}, Spec: &infrav3.Metro{}, } _, err := ps.GetByName(context.Background(), metro.Metadata.Name) if err != nil { t.Fatal("could not get metro:", err) } performBasicChecks(t, metro, muuid) } func TestMetroUpdate(t *testing.T) { db, mock := getDB(t) defer db.Close() ps := NewMetroService(db) puuid := uuid.New().String() mock.ExpectQuery(`SELECT "metro"."id", "metro"."name", .* FROM "cluster_metro" AS "metro" WHERE`). WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(puuid, "metro-"+puuid)) mock.ExpectExec(`UPDATE "cluster_metro"`). WillReturnResult(sqlmock.NewResult(1, 1)) metro := &infrav3.Location{ Metadata: &commonv3.Metadata{Id: puuid, Name: "metro-" + puuid}, Spec: &infrav3.Metro{}, } _, err := ps.Update(context.Background(), metro) if err != nil { t.Fatal("could not update metro:", err) } }