diff --git a/providers/azure/services/cache/client.go b/providers/azure/services/cache/client.go index b08c7a8b8..9b3c6acb7 100644 --- a/providers/azure/services/cache/client.go +++ b/providers/azure/services/cache/client.go @@ -354,8 +354,9 @@ func (c *CacheClient) ValidateOffering(ctx context.Context, rec common.Recommend return fmt.Errorf("failed to get valid SKUs: %w", err) } + resourceType := strings.TrimSpace(rec.ResourceType) for _, sku := range validSKUs { - if sku == rec.ResourceType { + if strings.EqualFold(sku, resourceType) { return nil } } diff --git a/providers/azure/services/cache/client_test.go b/providers/azure/services/cache/client_test.go index 7a950787a..f0c1ca304 100644 --- a/providers/azure/services/cache/client_test.go +++ b/providers/azure/services/cache/client_test.go @@ -399,6 +399,24 @@ func TestCacheClient_ValidateOffering_ValidSKU(t *testing.T) { assert.NoError(t, err) } +func TestCacheClient_ValidateOffering_CaseInsensitive(t *testing.T) { + ctx := context.Background() + + t.Run("case_insensitive", func(t *testing.T) { + client := NewClient(nil, "test-subscription", "eastus") + rec := common.Recommendation{ResourceType: "premium_p1"} + err := client.ValidateOffering(ctx, rec) + assert.NoError(t, err) + }) + + t.Run("whitespace_trimmed", func(t *testing.T) { + client := NewClient(nil, "test-subscription", "eastus") + rec := common.Recommendation{ResourceType: " Premium_P1 "} + err := client.ValidateOffering(ctx, rec) + assert.NoError(t, err) + }) +} + func TestCacheClient_GetRecommendations_WithMockPager(t *testing.T) { ctx := context.Background() client := NewClient(nil, "test-subscription", "eastus") diff --git a/providers/azure/services/compute/client.go b/providers/azure/services/compute/client.go index a336bcc4b..712ea7fc8 100644 --- a/providers/azure/services/compute/client.go +++ b/providers/azure/services/compute/client.go @@ -484,8 +484,9 @@ func (c *ComputeClient) ValidateOffering(ctx context.Context, rec common.Recomme return fmt.Errorf("failed to get valid SKUs: %w", err) } + resourceType := strings.TrimSpace(rec.ResourceType) for _, sku := range validSKUs { - if sku == rec.ResourceType { + if strings.EqualFold(sku, resourceType) { return nil } } diff --git a/providers/azure/services/compute/client_test.go b/providers/azure/services/compute/client_test.go index 426368ec9..ffc3e646f 100644 --- a/providers/azure/services/compute/client_test.go +++ b/providers/azure/services/compute/client_test.go @@ -324,6 +324,34 @@ func TestComputeClient_ValidateOffering_Invalid(t *testing.T) { assert.Contains(t, err.Error(), "invalid Azure VM SKU") } +func TestComputeClient_ValidateOffering_CaseInsensitive(t *testing.T) { + ctx := context.Background() + + t.Run("case_insensitive", func(t *testing.T) { + client := NewClient(nil, "test-subscription", "eastus") + mockPager := &mocks.MockResourceSKUsPager{ + Results: mocks.CreateSampleResourceSKUs("eastus"), + HasMore: true, + } + client.SetResourceSKUsPager(mockPager) + rec := common.Recommendation{ResourceType: "standard_d2s_v3"} + err := client.ValidateOffering(ctx, rec) + assert.NoError(t, err) + }) + + t.Run("whitespace_trimmed", func(t *testing.T) { + client := NewClient(nil, "test-subscription", "eastus") + mockPager := &mocks.MockResourceSKUsPager{ + Results: mocks.CreateSampleResourceSKUs("eastus"), + HasMore: true, + } + client.SetResourceSKUsPager(mockPager) + rec := common.Recommendation{ResourceType: " Standard_D2s_v3 "} + err := client.ValidateOffering(ctx, rec) + assert.NoError(t, err) + }) +} + func TestComputeClient_GetOfferingDetails_WithMock(t *testing.T) { ctx := context.Background() diff --git a/providers/azure/services/cosmosdb/client.go b/providers/azure/services/cosmosdb/client.go index af1db742c..8729c2fb0 100644 --- a/providers/azure/services/cosmosdb/client.go +++ b/providers/azure/services/cosmosdb/client.go @@ -351,8 +351,9 @@ func (c *CosmosDBClient) ValidateOffering(ctx context.Context, rec common.Recomm return fmt.Errorf("failed to get valid SKUs: %w", err) } + resourceType := strings.TrimSpace(rec.ResourceType) for _, sku := range validSKUs { - if sku == rec.ResourceType { + if strings.EqualFold(sku, resourceType) { return nil } } diff --git a/providers/azure/services/cosmosdb/client_test.go b/providers/azure/services/cosmosdb/client_test.go index 273873be8..eb40ccec8 100644 --- a/providers/azure/services/cosmosdb/client_test.go +++ b/providers/azure/services/cosmosdb/client_test.go @@ -679,6 +679,47 @@ func TestCosmosDBClient_ValidateOffering_Invalid(t *testing.T) { assert.Contains(t, err.Error(), "invalid Azure Cosmos DB SKU") } +func TestCosmosDBClient_ValidateOffering_CaseInsensitive(t *testing.T) { + ctx := context.Background() + + capability := "EnableCassandra" + mockPager := func() *MockCosmosAccountsPager { + return &MockCosmosAccountsPager{ + pages: []armcosmos.DatabaseAccountsClientListResponse{ + { + DatabaseAccountsListResult: armcosmos.DatabaseAccountsListResult{ + Value: []*armcosmos.DatabaseAccountGetResults{ + { + Properties: &armcosmos.DatabaseAccountGetProperties{ + Capabilities: []*armcosmos.Capability{ + {Name: &capability}, + }, + }, + }, + }, + }, + }, + }, + } + } + + t.Run("case_insensitive", func(t *testing.T) { + client := NewClient(nil, "test-subscription", "eastus") + client.SetCosmosAccountsPager(mockPager()) + rec := common.Recommendation{ResourceType: "enablecassandra"} + err := client.ValidateOffering(ctx, rec) + assert.NoError(t, err) + }) + + t.Run("whitespace_trimmed", func(t *testing.T) { + client := NewClient(nil, "test-subscription", "eastus") + client.SetCosmosAccountsPager(mockPager()) + rec := common.Recommendation{ResourceType: " EnableCassandra "} + err := client.ValidateOffering(ctx, rec) + assert.NoError(t, err) + }) +} + func TestCosmosDBClient_SetterMethods(t *testing.T) { client := NewClient(nil, "test-sub", "eastus") diff --git a/providers/azure/services/database/client.go b/providers/azure/services/database/client.go index 758f29901..089817425 100644 --- a/providers/azure/services/database/client.go +++ b/providers/azure/services/database/client.go @@ -359,8 +359,9 @@ func (c *DatabaseClient) ValidateOffering(ctx context.Context, rec common.Recomm return fmt.Errorf("failed to get valid SKUs: %w", err) } + resourceType := strings.TrimSpace(rec.ResourceType) for _, sku := range validSKUs { - if sku == rec.ResourceType { + if strings.EqualFold(sku, resourceType) { return nil } } diff --git a/providers/azure/services/database/client_test.go b/providers/azure/services/database/client_test.go index e52ee26ee..1888c9f0b 100644 --- a/providers/azure/services/database/client_test.go +++ b/providers/azure/services/database/client_test.go @@ -1020,3 +1020,42 @@ func TestDatabaseClient_ValidateOffering_Invalid(t *testing.T) { assert.Error(t, err) assert.Contains(t, err.Error(), "invalid Azure SQL Database SKU") } + +func TestDatabaseClient_ValidateOffering_CaseInsensitive(t *testing.T) { + ctx := context.Background() + + skuName := "GP_Gen5_8" + mockCapabilities := &MockCapabilitiesClient{ + response: armsql.CapabilitiesClientListByLocationResponse{ + LocationCapabilities: armsql.LocationCapabilities{ + SupportedServerVersions: []*armsql.ServerVersionCapability{ + { + SupportedEditions: []*armsql.EditionCapability{ + { + SupportedServiceLevelObjectives: []*armsql.ServiceObjectiveCapability{ + {SKU: &armsql.SKU{Name: &skuName}}, + }, + }, + }, + }, + }, + }, + }, + } + + t.Run("case_insensitive", func(t *testing.T) { + client := NewClient(nil, "test-subscription", "eastus") + client.SetCapabilitiesClient(mockCapabilities) + rec := common.Recommendation{ResourceType: "gp_gen5_8"} + err := client.ValidateOffering(ctx, rec) + assert.NoError(t, err) + }) + + t.Run("whitespace_trimmed", func(t *testing.T) { + client := NewClient(nil, "test-subscription", "eastus") + client.SetCapabilitiesClient(mockCapabilities) + rec := common.Recommendation{ResourceType: " GP_Gen5_8 "} + err := client.ValidateOffering(ctx, rec) + assert.NoError(t, err) + }) +} diff --git a/providers/azure/services/search/client.go b/providers/azure/services/search/client.go index 181a2150c..97bdbc765 100644 --- a/providers/azure/services/search/client.go +++ b/providers/azure/services/search/client.go @@ -327,8 +327,9 @@ func (c *SearchClient) ValidateOffering(ctx context.Context, rec common.Recommen return fmt.Errorf("failed to get valid SKUs: %w", err) } + resourceType := strings.TrimSpace(rec.ResourceType) for _, sku := range validSKUs { - if sku == rec.ResourceType { + if strings.EqualFold(sku, resourceType) { return nil } } diff --git a/providers/azure/services/search/client_test.go b/providers/azure/services/search/client_test.go index 5a9c00f63..460d073da 100644 --- a/providers/azure/services/search/client_test.go +++ b/providers/azure/services/search/client_test.go @@ -861,3 +861,38 @@ func TestSearchClient_PurchaseCommitment_IdempotentReDrive(t *testing.T) { assert.NotEqual(t, first.CommitmentID, other.CommitmentID) assert.NotEqual(t, firstURL, otherURL) } + +func TestSearchClient_ValidateOffering_CaseInsensitive(t *testing.T) { + ctx := context.Background() + + skuName := armsearch.SKUNameStandard + mockPager := func() *MockSearchServicesPager { + return &MockSearchServicesPager{ + pages: []armsearch.ServicesClientListBySubscriptionResponse{ + { + ServiceListResult: armsearch.ServiceListResult{ + Value: []*armsearch.Service{ + {SKU: &armsearch.SKU{Name: &skuName}}, + }, + }, + }, + }, + } + } + + t.Run("case_insensitive", func(t *testing.T) { + client := NewClient(nil, "test-subscription", "eastus") + client.SetSearchServicesPager(mockPager()) + rec := common.Recommendation{ResourceType: "STANDARD"} + err := client.ValidateOffering(ctx, rec) + assert.NoError(t, err) + }) + + t.Run("whitespace_trimmed", func(t *testing.T) { + client := NewClient(nil, "test-subscription", "eastus") + client.SetSearchServicesPager(mockPager()) + rec := common.Recommendation{ResourceType: " standard "} + err := client.ValidateOffering(ctx, rec) + assert.NoError(t, err) + }) +}