// Package database define database operation functions package database import ( "context" "database/sql" "database/sql/driver" "strings" "testing" "modelRT/constants" "modelRT/model" modelsql "modelRT/sql" "github.com/DATA-DOG/go-sqlmock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gorm.io/driver/postgres" "gorm.io/gorm" ) func TestParameterInitializationSQLUsesStationIDAndExcludesItFromComponentAttributes(t *testing.T) { dynamicSQL := compactParameterSQL(modelsql.DynamicParameterInitializationRows) componentSQL := compactParameterSQL(modelsql.ComponentParameterInitializationRows) assert.Contains(t, dynamicSQL, "component.station_id = station.id") assert.Contains(t, componentSQL, "component.station_id = station.id") assert.Contains(t, componentSQL, "to_jsonb(component) - 'station_id'") assert.Contains(t, dynamicSQL, "component.nspath <> ''") assert.Contains(t, dynamicSQL, "component.tag <> ''") assert.Contains(t, componentSQL, "component.nspath <> ''") assert.Contains(t, componentSQL, "component.tag <> ''") assert.NotContains(t, strings.ToLower(componentSQL), "component.station = station.tagname") } func TestQueryParameterInitializationRecordsJoinsHierarchyAndDynamicTable(t *testing.T) { sqlDB, mock, err := sqlmock.New() require.NoError(t, err) t.Cleanup(func() { _ = sqlDB.Close() }) db, err := gorm.Open(postgres.New(postgres.Config{Conn: sqlDB}), &gorm.Config{}) require.NoError(t, err) groups := constants.SupportedDynamicParameterAttributeGroups() routeArgs := make([]driver.Value, len(groups)) for index, group := range groups { routeArgs[index] = group } mock.ExpectQuery(`(?s)SELECT name, tag, group_name.*FROM project_manager.*WHERE group_name IN`). WithArgs(routeArgs...). WillReturnRows(sqlmock.NewRows([]string{"name", "tag", "group_name"}). AddRow("cable_cable_demo_base_extend", "cable_demo", "base_extend")) mock.ExpectQuery(`(?s)WITH dynamic_rows AS.*FROM public\."cable_cable_demo_base_extend".*FROM public\.grid.*INNER JOIN public\.zone.*INNER JOIN public\.station.*INNER JOIN public\.component.*INNER JOIN public\.project_manager.*jsonb_each`). WithArgs("cable_cable_demo_base_extend", "cable_demo", "base_extend"). WillReturnRows(parameterInitializationRows(). AddRow( "grid000", "zone000", "station000", true, "component-uuid", "nspath", "component", "base_extend", "vnom_kv", "220.0", "DOUBLE PRECISION", "额定电压", int64(1), int64(1), )) mock.ExpectQuery(`(?s)SELECT.*FROM public\.grid.*INNER JOIN public\.zone.*INNER JOIN public\.station.*INNER JOIN public\.component.*jsonb_each`). WillReturnRows(parameterInitializationRows(). AddRow( "grid000", "zone000", "station000", true, "component-uuid", "nspath", "component", "component", "description", `"组件"`, "CHARACTER VARYING(512)", "组件名称", int64(1), int64(1), )) records, err := QueryParameterInitializationRecords(context.Background(), db) require.NoError(t, err) require.Len(t, records, 2) assert.Equal(t, "vnom_kv", records[0].AttributeName) assert.Equal(t, "description", records[1].AttributeName) require.NoError(t, mock.ExpectationsWereMet()) } func TestValidateParameterInitializationRoutesRejectsAmbiguousMapping(t *testing.T) { routes := []parameterInitializationRoute{ {TableName: "cable_demo_stable", ModelName: "cable_demo", AttributeGroup: "stable"}, {TableName: "cable_other_stable", ModelName: "cable_demo", AttributeGroup: "stable"}, } err := validateParameterInitializationRoutes(routes) require.Error(t, err) assert.Contains(t, err.Error(), "more than one project_manager record") } func TestValidateParameterInitializationRecordsEnforcesDescriptionAndRowUniqueness(t *testing.T) { validRecord := modelParameterInitializationRecordForTest() missingDescription := validRecord missingDescription.Description = sql.NullString{} missingDescription.DescriptionCount = 0 err := validateParameterInitializationRecords([]model.ParameterInitializationRecord{missingDescription}) require.Error(t, err) assert.Contains(t, err.Error(), "description not found") duplicateRow := validRecord duplicateRow.DynamicRecordCount = 2 err = validateParameterInitializationRecords([]model.ParameterInitializationRecord{duplicateRow}) require.Error(t, err) assert.Contains(t, err.Error(), "has 2") } func parameterInitializationRows() *sqlmock.Rows { return sqlmock.NewRows([]string{ "grid_tag", "zone_tag", "station_tag", "station_is_local", "component_uuid", "component_nspath", "component_tag", "attribute_group", "attribute_name", "attribute_value", "attribute_type", "description", "description_count", "dynamic_record_count", }) } func modelParameterInitializationRecordForTest() model.ParameterInitializationRecord { return model.ParameterInitializationRecord{ ComponentTag: "component", AttributeGroup: "stable", AttributeName: "attribute", AttributeType: "INTEGER", Description: sql.NullString{String: "属性", Valid: true}, DescriptionCount: 1, DynamicRecordCount: 1, } }