diff --git a/ci_cd_sanity_tests/cmd/sanity/main.go b/ci_cd_sanity_tests/cmd/sanity/main.go index 3249a3c2..f6ecf0ca 100644 --- a/ci_cd_sanity_tests/cmd/sanity/main.go +++ b/ci_cd_sanity_tests/cmd/sanity/main.go @@ -11,10 +11,18 @@ import ( "github.com/LeanerCloud/cloud-commitments-go/ci_cd_sanity_tests/pkg/sanity/aws" ) +// validateInt32Range reports an error when n is outside [1, math.MaxInt32]. +func validateInt32Range(flagName string, n int) error { + if n < 1 || n > math.MaxInt32 { + return fmt.Errorf("%s must be between 1 and %d, got %d", flagName, math.MaxInt32, n) + } + return nil +} + // requireInt32Range exits with an error when n is outside [1, math.MaxInt32]. func requireInt32Range(flagName string, n int) { - if n < 1 || n > (1<<31-1) { - fmt.Fprintf(os.Stderr, "ERROR: %s must be between 1 and math.MaxInt32\n", flagName) + if err := validateInt32Range(flagName, n); err != nil { + fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) os.Exit(2) } } @@ -29,11 +37,6 @@ func main() { flag.Parse() requireInt32Range("--max-list", *maxList) - if *maxList < 1 || *maxList > math.MaxInt32 { - fmt.Fprintf(os.Stderr, "ERROR: --max-list must be between 1 and %d, got %d\n", math.MaxInt32, *maxList) - os.Exit(2) - } - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute) rep, err := aws.Run(ctx, aws.Options{ diff --git a/ci_cd_sanity_tests/cmd/sanity/main_test.go b/ci_cd_sanity_tests/cmd/sanity/main_test.go new file mode 100644 index 00000000..158112f3 --- /dev/null +++ b/ci_cd_sanity_tests/cmd/sanity/main_test.go @@ -0,0 +1,40 @@ +package main + +import ( + "math" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestValidateInt32Range(t *testing.T) { + // Computed at run time so the test still compiles where int is 32 bits; + // there it wraps to math.MinInt32, which is rejected as well. + aboveMax := math.MaxInt32 + aboveMax++ + + tests := []struct { + name string + n int + wantErr bool + }{ + {name: "zero", n: 0, wantErr: true}, + {name: "negative", n: -1, wantErr: true}, + {name: "lower bound", n: 1, wantErr: false}, + {name: "default", n: 5, wantErr: false}, + {name: "upper bound", n: math.MaxInt32, wantErr: false}, + {name: "above upper bound", n: aboveMax, wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validateInt32Range("--max-list", tt.n) + if !tt.wantErr { + assert.NoError(t, err) + return + } + require.Error(t, err) + assert.Contains(t, err.Error(), "--max-list must be between 1 and 2147483647") + }) + } +} diff --git a/providers/azure/services/cache/client_test.go b/providers/azure/services/cache/client_test.go index d4c7ee21..29941057 100644 --- a/providers/azure/services/cache/client_test.go +++ b/providers/azure/services/cache/client_test.go @@ -90,27 +90,6 @@ func (m *MockRedisCachesPager) NextPage(ctx context.Context) (armredis.ClientLis return page, nil } -// MockHTTPClient mocks HTTP client for testing. -type MockHTTPClient struct { - mock.Mock -} - -func (m *MockHTTPClient) Do(req *http.Request) (*http.Response, error) { - args := m.Called(req) - if args.Get(0) == nil { - return nil, args.Error(1) - } - return args.Get(0).(*http.Response), args.Error(1) -} - -func createMockHTTPResponse(statusCode int, body string) *http.Response { - return &http.Response{ - StatusCode: statusCode, - Body: io.NopCloser(bytes.NewBufferString(body)), - Header: make(http.Header), - } -} - func createSampleRedisPricingResponse() string { return `{ "Items": [ @@ -273,7 +252,7 @@ func TestRedisPricingStructure(t *testing.T) { func TestNewClientWithHTTP(t *testing.T) { t.Parallel() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) require.NotNil(t, client) @@ -285,10 +264,10 @@ func TestNewClientWithHTTP(t *testing.T) { func TestCacheClient_GetOfferingDetails_WithMock(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response1 := createMockHTTPResponse(http.StatusOK, createSampleRedisPricingResponse()) + response1 := mocks.CreateMockHTTPResponse(http.StatusOK, createSampleRedisPricingResponse()) t.Cleanup(func() { require.NoError(t, response1.Body.Close()) }) @@ -313,10 +292,10 @@ func TestCacheClient_GetOfferingDetails_WithMock(t *testing.T) { func TestCacheClient_GetOfferingDetails_3YearTerm(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response2 := createMockHTTPResponse(http.StatusOK, createSampleRedisPricingResponse()) + response2 := mocks.CreateMockHTTPResponse(http.StatusOK, createSampleRedisPricingResponse()) t.Cleanup(func() { require.NoError(t, response2.Body.Close()) }) @@ -340,10 +319,10 @@ func TestCacheClient_GetOfferingDetails_3YearTerm(t *testing.T) { func TestCacheClient_GetOfferingDetails_NoUpfront(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response3 := createMockHTTPResponse(http.StatusOK, createSampleRedisPricingResponse()) + response3 := mocks.CreateMockHTTPResponse(http.StatusOK, createSampleRedisPricingResponse()) t.Cleanup(func() { require.NoError(t, response3.Body.Close()) }) @@ -367,10 +346,10 @@ func TestCacheClient_GetOfferingDetails_NoUpfront(t *testing.T) { func TestCacheClient_GetOfferingDetails_APIError(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response4 := createMockHTTPResponse(http.StatusInternalServerError, "Internal Server Error") + response4 := mocks.CreateMockHTTPResponse(http.StatusInternalServerError, "Internal Server Error") t.Cleanup(func() { require.NoError(t, response4.Body.Close()) }) @@ -392,10 +371,10 @@ func TestCacheClient_GetOfferingDetails_APIError(t *testing.T) { func TestCacheClient_GetOfferingDetails_NoPricing(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response5 := createMockHTTPResponse(http.StatusOK, `{"Items": []}`) + response5 := mocks.CreateMockHTTPResponse(http.StatusOK, `{"Items": []}`) t.Cleanup(func() { require.NoError(t, response5.Body.Close()) }) @@ -437,9 +416,9 @@ func TestCacheClient_GetOfferingDetails_NoReservationPricing(t *testing.T) { "NextPageLink": "" }` - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response6 := createMockHTTPResponse(http.StatusOK, onDemandOnly) + response6 := mocks.CreateMockHTTPResponse(http.StatusOK, onDemandOnly) t.Cleanup(func() { require.NoError(t, response6.Body.Close()) }) @@ -1090,18 +1069,18 @@ func calcPriceRespJSON(orderID string) string { func TestCacheClient_PurchaseCommitment_Success(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp7 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cache-order-001")) + calculateResp7 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cache-order-001")) t.Cleanup(func() { require.NoError(t, calculateResp7.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp7, nil).Once() - purchaseResp8 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp8 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp8.Body.Close()) }) @@ -1129,18 +1108,18 @@ func TestCacheClient_PurchaseCommitment_Success(t *testing.T) { func TestCacheClient_PurchaseCommitment_3YearTerm(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp9 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cache-order-3yr")) + calculateResp9 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cache-order-3yr")) t.Cleanup(func() { require.NoError(t, calculateResp9.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp9, nil).Once() - purchaseResp10 := createMockHTTPResponse(http.StatusCreated, `{}`) + purchaseResp10 := mocks.CreateMockHTTPResponse(http.StatusCreated, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp10.Body.Close()) }) @@ -1166,18 +1145,18 @@ func TestCacheClient_PurchaseCommitment_3YearTerm(t *testing.T) { func TestCacheClient_PurchaseCommitment_Accepted(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp11 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cache-order-202")) + calculateResp11 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cache-order-202")) t.Cleanup(func() { require.NoError(t, calculateResp11.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp11, nil).Once() - purchaseResp12 := createMockHTTPResponse(http.StatusAccepted, `{}`) + purchaseResp12 := mocks.CreateMockHTTPResponse(http.StatusAccepted, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp12.Body.Close()) }) @@ -1202,7 +1181,7 @@ func TestCacheClient_PurchaseCommitment_Accepted(t *testing.T) { func TestCacheClient_PurchaseCommitment_TokenError(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{err: errors.New("token error")} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1222,7 +1201,7 @@ func TestCacheClient_PurchaseCommitment_TokenError(t *testing.T) { func TestCacheClient_PurchaseCommitment_HTTPError(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1246,18 +1225,18 @@ func TestCacheClient_PurchaseCommitment_HTTPError(t *testing.T) { func TestCacheClient_PurchaseCommitment_BadStatus(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp13 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cache-order-bad")) + calculateResp13 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cache-order-bad")) t.Cleanup(func() { require.NoError(t, calculateResp13.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp13, nil).Once() - purchaseResp14 := createMockHTTPResponse(http.StatusBadRequest, `{"error": "invalid request"}`) + purchaseResp14 := mocks.CreateMockHTTPResponse(http.StatusBadRequest, `{"error": "invalid request"}`) t.Cleanup(func() { require.NoError(t, purchaseResp14.Body.Close()) }) @@ -1291,12 +1270,12 @@ func TestCacheClient_PurchaseCommitment_TagInjection(t *testing.T) { const source = common.PurchaseSourceWeb ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) var capturedBody []byte - calculateResp15 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) + calculateResp15 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) t.Cleanup(func() { require.NoError(t, calculateResp15.Body.Close()) }) @@ -1308,7 +1287,7 @@ func TestCacheClient_PurchaseCommitment_TagInjection(t *testing.T) { r.Body = io.NopCloser(bytes.NewReader(capturedBody)) return true })).Return(calculateResp15, nil).Once() - purchaseResp16 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp16 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp16.Body.Close()) }) @@ -1352,7 +1331,7 @@ func TestCacheClient_PurchaseCommitment_BillingPlan(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1369,7 +1348,7 @@ func TestCacheClient_PurchaseCommitment_BillingPlan(t *testing.T) { const orderID = "cache-billingplan-test" var capturedBody []byte - calculateResp17 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) + calculateResp17 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) t.Cleanup(func() { require.NoError(t, calculateResp17.Body.Close()) }) @@ -1381,7 +1360,7 @@ func TestCacheClient_PurchaseCommitment_BillingPlan(t *testing.T) { r.Body = io.NopCloser(bytes.NewReader(capturedBody)) return true })).Return(calculateResp17, nil).Once() - purchaseResp18 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp18 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp18.Body.Close()) }) @@ -1418,7 +1397,7 @@ func TestCacheClient_PurchaseCommitment_BillingPlan(t *testing.T) { func TestCacheClient_PurchaseCommitment_RequiresSource(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1437,13 +1416,13 @@ func TestCacheClient_PurchaseCommitment_RequiresSource(t *testing.T) { func TestCacheClient_PurchaseCommitment_DisplayNameConformsToAzureAllowlist(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) const orderID = "azure-cache-displayname" var capturedDisplayName string - calculateResp19 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) + calculateResp19 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) t.Cleanup(func() { require.NoError(t, calculateResp19.Body.Close()) }) @@ -1466,7 +1445,7 @@ func TestCacheClient_PurchaseCommitment_DisplayNameConformsToAzureAllowlist(t *t } return true })).Return(calculateResp19, nil).Once() - purchaseResp20 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp20 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp20.Body.Close()) }) diff --git a/providers/azure/services/cosmosdb/client_test.go b/providers/azure/services/cosmosdb/client_test.go index 07e0cb58..06a846bf 100644 --- a/providers/azure/services/cosmosdb/client_test.go +++ b/providers/azure/services/cosmosdb/client_test.go @@ -101,27 +101,6 @@ func (m *MockCosmosAccountsPager) NextPage(ctx context.Context) (armcosmos.Datab return page, nil } -// MockHTTPClient mocks HTTP client for testing. -type MockHTTPClient struct { - mock.Mock -} - -func (m *MockHTTPClient) Do(req *http.Request) (*http.Response, error) { - args := m.Called(req) - if args.Get(0) == nil { - return nil, args.Error(1) - } - return args.Get(0).(*http.Response), args.Error(1) -} - -func createMockHTTPResponse(statusCode int, body string) *http.Response { - return &http.Response{ - StatusCode: statusCode, - Body: io.NopCloser(bytes.NewBufferString(body)), - Header: make(http.Header), - } -} - // Synthetic totals retained for existing quote tests; reservation identity follows the captured catalog. func createSampleCosmosPricingResponse() string { return `{ @@ -272,7 +251,7 @@ func TestNewClient(t *testing.T) { func TestNewClientWithHTTP(t *testing.T) { t.Parallel() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) require.NotNil(t, client) @@ -331,10 +310,10 @@ func TestCosmosDBClient_Fields(t *testing.T) { func TestCosmosDBClient_GetOfferingDetails_WithMock(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response1 := createMockHTTPResponse(http.StatusOK, createSampleCosmosPricingResponse()) + response1 := mocks.CreateMockHTTPResponse(http.StatusOK, createSampleCosmosPricingResponse()) t.Cleanup(func() { require.NoError(t, response1.Body.Close()) }) @@ -359,10 +338,10 @@ func TestCosmosDBClient_GetOfferingDetails_WithMock(t *testing.T) { func TestCosmosDBClient_GetOfferingDetails_3YearTerm(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response2 := createMockHTTPResponse(http.StatusOK, createSampleCosmosPricingResponse()) + response2 := mocks.CreateMockHTTPResponse(http.StatusOK, createSampleCosmosPricingResponse()) t.Cleanup(func() { require.NoError(t, response2.Body.Close()) }) @@ -386,10 +365,10 @@ func TestCosmosDBClient_GetOfferingDetails_3YearTerm(t *testing.T) { func TestCosmosDBClient_GetOfferingDetails_NoUpfront(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response3 := createMockHTTPResponse(http.StatusOK, createSampleCosmosPricingResponse()) + response3 := mocks.CreateMockHTTPResponse(http.StatusOK, createSampleCosmosPricingResponse()) t.Cleanup(func() { require.NoError(t, response3.Body.Close()) }) @@ -413,10 +392,10 @@ func TestCosmosDBClient_GetOfferingDetails_NoUpfront(t *testing.T) { func TestCosmosDBClient_GetOfferingDetails_APIError(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response4 := createMockHTTPResponse(http.StatusInternalServerError, "Internal Server Error") + response4 := mocks.CreateMockHTTPResponse(http.StatusInternalServerError, "Internal Server Error") t.Cleanup(func() { require.NoError(t, response4.Body.Close()) }) @@ -438,10 +417,10 @@ func TestCosmosDBClient_GetOfferingDetails_APIError(t *testing.T) { func TestCosmosDBClient_GetOfferingDetails_NoPricing(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response5 := createMockHTTPResponse(http.StatusOK, `{"Items": []}`) + response5 := mocks.CreateMockHTTPResponse(http.StatusOK, `{"Items": []}`) t.Cleanup(func() { require.NoError(t, response5.Body.Close()) }) @@ -485,9 +464,9 @@ func TestCosmosDBClient_GetOfferingDetails_NoReservationPricing(t *testing.T) { "NextPageLink": "" }` - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response6 := createMockHTTPResponse(http.StatusOK, onDemandOnly) + response6 := mocks.CreateMockHTTPResponse(http.StatusOK, onDemandOnly) t.Cleanup(func() { require.NoError(t, response6.Body.Close()) }) @@ -511,10 +490,10 @@ func TestCosmosDBClient_GetOfferingDetails_NoReservationPricing(t *testing.T) { func TestCosmosDBClient_GetOfferingDetails_MixedSKUsPicksRequestedSKU(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response := createMockHTTPResponse(http.StatusOK, createMixedSKUCosmosPricingResponse()) + response := mocks.CreateMockHTTPResponse(http.StatusOK, createMixedSKUCosmosPricingResponse()) t.Cleanup(func() { require.NoError(t, response.Body.Close()) }) @@ -541,10 +520,10 @@ func TestCosmosDBClient_GetOfferingDetails_MixedSKUsPicksRequestedSKU(t *testing func TestCosmosDBClient_GetOfferingDetails_NoMatchingSKU_FailsClosed(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response := createMockHTTPResponse(http.StatusOK, createOnlyOtherSKUCosmosPricingResponse()) + response := mocks.CreateMockHTTPResponse(http.StatusOK, createOnlyOtherSKUCosmosPricingResponse()) t.Cleanup(func() { require.NoError(t, response.Body.Close()) }) @@ -567,10 +546,10 @@ func TestCosmosDBClient_GetOfferingDetails_NoMatchingSKU_FailsClosed(t *testing. func TestCosmosDBClient_GetOfferingDetails_RequestsSKUFilter(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response := createMockHTTPResponse(http.StatusOK, createSampleCosmosPricingResponse()) + response := mocks.CreateMockHTTPResponse(http.StatusOK, createSampleCosmosPricingResponse()) t.Cleanup(func() { require.NoError(t, response.Body.Close()) }) @@ -1077,18 +1056,18 @@ func calcPriceRespJSON(orderID string) string { func TestCosmosDBClient_PurchaseCommitment_Success(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp7 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cosmos-order-001")) + calculateResp7 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cosmos-order-001")) t.Cleanup(func() { require.NoError(t, calculateResp7.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp7, nil).Once() - purchaseResp8 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp8 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp8.Body.Close()) }) @@ -1116,18 +1095,18 @@ func TestCosmosDBClient_PurchaseCommitment_Success(t *testing.T) { func TestCosmosDBClient_PurchaseCommitment_3YearTerm(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp9 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cosmos-order-3yr")) + calculateResp9 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cosmos-order-3yr")) t.Cleanup(func() { require.NoError(t, calculateResp9.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp9, nil).Once() - purchaseResp10 := createMockHTTPResponse(http.StatusCreated, `{}`) + purchaseResp10 := mocks.CreateMockHTTPResponse(http.StatusCreated, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp10.Body.Close()) }) @@ -1153,18 +1132,18 @@ func TestCosmosDBClient_PurchaseCommitment_3YearTerm(t *testing.T) { func TestCosmosDBClient_PurchaseCommitment_Accepted(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp11 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cosmos-order-202")) + calculateResp11 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cosmos-order-202")) t.Cleanup(func() { require.NoError(t, calculateResp11.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp11, nil).Once() - purchaseResp12 := createMockHTTPResponse(http.StatusAccepted, `{}`) + purchaseResp12 := mocks.CreateMockHTTPResponse(http.StatusAccepted, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp12.Body.Close()) }) @@ -1189,7 +1168,7 @@ func TestCosmosDBClient_PurchaseCommitment_Accepted(t *testing.T) { func TestCosmosDBClient_PurchaseCommitment_TokenError(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{err: errors.New("token error")} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1209,7 +1188,7 @@ func TestCosmosDBClient_PurchaseCommitment_TokenError(t *testing.T) { func TestCosmosDBClient_PurchaseCommitment_HTTPError(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1233,18 +1212,18 @@ func TestCosmosDBClient_PurchaseCommitment_HTTPError(t *testing.T) { func TestCosmosDBClient_PurchaseCommitment_BadStatus(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp13 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cosmos-order-bad")) + calculateResp13 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("cosmos-order-bad")) t.Cleanup(func() { require.NoError(t, calculateResp13.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp13, nil).Once() - purchaseResp14 := createMockHTTPResponse(http.StatusBadRequest, `{"error": "invalid request"}`) + purchaseResp14 := mocks.CreateMockHTTPResponse(http.StatusBadRequest, `{"error": "invalid request"}`) t.Cleanup(func() { require.NoError(t, purchaseResp14.Body.Close()) }) @@ -1278,12 +1257,12 @@ func TestCosmosDBClient_PurchaseCommitment_TagInjection(t *testing.T) { const source = common.PurchaseSourceWeb ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) var capturedBody []byte - calculateResp15 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) + calculateResp15 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) t.Cleanup(func() { require.NoError(t, calculateResp15.Body.Close()) }) @@ -1295,7 +1274,7 @@ func TestCosmosDBClient_PurchaseCommitment_TagInjection(t *testing.T) { r.Body = io.NopCloser(bytes.NewReader(capturedBody)) return true })).Return(calculateResp15, nil).Once() - purchaseResp16 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp16 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp16.Body.Close()) }) @@ -1339,7 +1318,7 @@ func TestCosmosDBClient_PurchaseCommitment_BillingPlan(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1356,7 +1335,7 @@ func TestCosmosDBClient_PurchaseCommitment_BillingPlan(t *testing.T) { const orderID = "cosmos-billingplan-test" var capturedBody []byte - calculateResp17 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) + calculateResp17 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) t.Cleanup(func() { require.NoError(t, calculateResp17.Body.Close()) }) @@ -1368,7 +1347,7 @@ func TestCosmosDBClient_PurchaseCommitment_BillingPlan(t *testing.T) { r.Body = io.NopCloser(bytes.NewReader(capturedBody)) return true })).Return(calculateResp17, nil).Once() - purchaseResp18 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp18 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp18.Body.Close()) }) @@ -1405,7 +1384,7 @@ func TestCosmosDBClient_PurchaseCommitment_BillingPlan(t *testing.T) { func TestCosmosDBClient_PurchaseCommitment_RequiresSource(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1682,13 +1661,13 @@ func TestDetailsFromCosmosSKU(t *testing.T) { func TestCosmosDBClient_PurchaseCommitment_DisplayNameConformsToAzureAllowlist(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) const orderID = "azure-cosmos-displayname" var capturedDisplayName string - calculateResp19 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) + calculateResp19 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) t.Cleanup(func() { require.NoError(t, calculateResp19.Body.Close()) }) @@ -1711,7 +1690,7 @@ func TestCosmosDBClient_PurchaseCommitment_DisplayNameConformsToAzureAllowlist(t } return true })).Return(calculateResp19, nil).Once() - purchaseResp20 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp20 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp20.Body.Close()) }) @@ -1771,7 +1750,7 @@ func TestNewClientWithHTTP_NilFallbackIsHardened(t *testing.T) { func TestGetCosmosPricing_RejectsInjectedSKU(t *testing.T) { t.Parallel() - client := NewClientWithHTTP(nil, "sub", "eastus", &MockHTTPClient{}) + client := NewClientWithHTTP(nil, "sub", "eastus", &mocks.MockHTTPClient{}) _, err := client.getCosmosPricing(context.Background(), "Cosmos_DB_x' or armSkuName ne '", "eastus", 1) require.Error(t, err) assert.Contains(t, err.Error(), "Retail Prices filter") @@ -1779,9 +1758,9 @@ func TestGetCosmosPricing_RejectsInjectedSKU(t *testing.T) { func TestGetCosmosPricing_LegitimateSKUBuildsExactFilter(t *testing.T) { t.Parallel() - response := createMockHTTPResponse(http.StatusOK, `{"Items":[]}`) + response := mocks.CreateMockHTTPResponse(http.StatusOK, `{"Items":[]}`) t.Cleanup(func() { require.NoError(t, response.Body.Close()) }) - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockHTTP.On("Do", mock.Anything).Return(response, nil).Once() _, err := NewClientWithHTTP(nil, "sub", "eastus", mockHTTP).getCosmosPricing(context.Background(), "100RU", "eastus", 1) require.Error(t, err) diff --git a/providers/azure/services/database/client_test.go b/providers/azure/services/database/client_test.go index 9d7c5a29..bbf7ee93 100644 --- a/providers/azure/services/database/client_test.go +++ b/providers/azure/services/database/client_test.go @@ -83,27 +83,6 @@ func (m *MockCapabilitiesClient) ListByLocation(ctx context.Context, locationNam return m.response, nil } -// MockHTTPClient mocks HTTP client for testing. -type MockHTTPClient struct { - mock.Mock -} - -func (m *MockHTTPClient) Do(req *http.Request) (*http.Response, error) { - args := m.Called(req) - if args.Get(0) == nil { - return nil, args.Error(1) - } - return args.Get(0).(*http.Response), args.Error(1) -} - -func createMockHTTPResponse(statusCode int, body string) *http.Response { - return &http.Response{ - StatusCode: statusCode, - Body: io.NopCloser(bytes.NewBufferString(body)), - Header: make(http.Header), - } -} - // This vCore catalog row is synthetic; it tests selection, not live SKU availability. func createSampleSQLPricingResponse() string { return `{ @@ -243,7 +222,7 @@ func TestDatabaseClient_Fields(t *testing.T) { func TestNewClientWithHTTP(t *testing.T) { t.Parallel() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) require.NotNil(t, client) @@ -255,10 +234,10 @@ func TestNewClientWithHTTP(t *testing.T) { func TestDatabaseClient_GetOfferingDetails_WithMock(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response1 := createMockHTTPResponse(http.StatusOK, createSampleSQLPricingResponse()) + response1 := mocks.CreateMockHTTPResponse(http.StatusOK, createSampleSQLPricingResponse()) t.Cleanup(func() { require.NoError(t, response1.Body.Close()) }) @@ -288,10 +267,10 @@ func TestDatabaseClient_GetOfferingDetails_WithMock(t *testing.T) { func TestDatabaseClient_GetOfferingDetails_3YearTerm(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response2 := createMockHTTPResponse(http.StatusOK, createSampleSQLPricingResponse()) + response2 := mocks.CreateMockHTTPResponse(http.StatusOK, createSampleSQLPricingResponse()) t.Cleanup(func() { require.NoError(t, response2.Body.Close()) }) @@ -319,10 +298,10 @@ func TestDatabaseClient_GetOfferingDetails_3YearTerm(t *testing.T) { func TestDatabaseClient_GetOfferingDetails_NoUpfront(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response3 := createMockHTTPResponse(http.StatusOK, createSampleSQLPricingResponse()) + response3 := mocks.CreateMockHTTPResponse(http.StatusOK, createSampleSQLPricingResponse()) t.Cleanup(func() { require.NoError(t, response3.Body.Close()) }) @@ -347,10 +326,10 @@ func TestDatabaseClient_GetOfferingDetails_NoUpfront(t *testing.T) { func TestDatabaseClient_GetOfferingDetails_APIError(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response4 := createMockHTTPResponse(http.StatusInternalServerError, "Internal Server Error") + response4 := mocks.CreateMockHTTPResponse(http.StatusInternalServerError, "Internal Server Error") t.Cleanup(func() { require.NoError(t, response4.Body.Close()) }) @@ -372,10 +351,10 @@ func TestDatabaseClient_GetOfferingDetails_APIError(t *testing.T) { func TestDatabaseClient_GetOfferingDetails_NoPricing(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response5 := createMockHTTPResponse(http.StatusOK, `{"Items": []}`) + response5 := mocks.CreateMockHTTPResponse(http.StatusOK, `{"Items": []}`) t.Cleanup(func() { require.NoError(t, response5.Body.Close()) }) @@ -417,9 +396,9 @@ func TestDatabaseClient_GetOfferingDetails_NoReservationPricing(t *testing.T) { "NextPageLink": "" }` - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response6 := createMockHTTPResponse(http.StatusOK, onDemandOnly) + response6 := mocks.CreateMockHTTPResponse(http.StatusOK, onDemandOnly) t.Cleanup(func() { require.NoError(t, response6.Body.Close()) }) @@ -519,8 +498,8 @@ func TestDatabaseClient_GetOfferingDetails_SelectsSyntheticVCoreRow(t *testing.T t.Run(tt.name, func(t *testing.T) { body, err := json.Marshal(AzureRetailPrice{Items: tt.items}) require.NoError(t, err) - mockHTTP := &MockHTTPClient{} - response := createMockHTTPResponse(http.StatusOK, string(body)) + mockHTTP := &mocks.MockHTTPClient{} + response := mocks.CreateMockHTTPResponse(http.StatusOK, string(body)) t.Cleanup(func() { require.NoError(t, response.Body.Close()) }) @@ -572,7 +551,7 @@ func TestDatabaseClient_GetOfferingDetails_RejectsQuoteInRegionAndSKU(t *testing t.Parallel() // Quote characters are rejected outright (not escaped); the mock has no // expectations, so any request would panic. - client := NewClientWithHTTP(nil, "sub", "east'us", &MockHTTPClient{}) + client := NewClientWithHTTP(nil, "sub", "east'us", &mocks.MockHTTPClient{}) details, err := client.GetOfferingDetails(context.Background(), common.Recommendation{ ResourceType: "GeneralPurpose_Gen5_'2", Term: "1yr", PaymentOption: "upfront", }) @@ -606,12 +585,12 @@ func TestDatabaseClient_GetOfferingDetails_ReservationAcrossPages(t *testing.T) require.NoError(t, err) secondBody, err := json.Marshal(AzureRetailPrice{Items: []azpricing.RetailPriceItem{tt.second}}) require.NoError(t, err) - mockHTTP := &MockHTTPClient{} - firstResponse := createMockHTTPResponse(http.StatusOK, string(firstBody)) + mockHTTP := &mocks.MockHTTPClient{} + firstResponse := mocks.CreateMockHTTPResponse(http.StatusOK, string(firstBody)) t.Cleanup(func() { require.NoError(t, firstResponse.Body.Close()) }) - secondResponse := createMockHTTPResponse(http.StatusOK, string(secondBody)) + secondResponse := mocks.CreateMockHTTPResponse(http.StatusOK, string(secondBody)) t.Cleanup(func() { require.NoError(t, secondResponse.Body.Close()) }) @@ -1182,18 +1161,18 @@ func calcPriceRespJSON(orderID string) string { func TestDatabaseClient_PurchaseCommitment_Success(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp7 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("db-order-001")) + calculateResp7 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("db-order-001")) t.Cleanup(func() { require.NoError(t, calculateResp7.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp7, nil).Once() - purchaseResp8 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp8 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp8.Body.Close()) }) @@ -1221,18 +1200,18 @@ func TestDatabaseClient_PurchaseCommitment_Success(t *testing.T) { func TestDatabaseClient_PurchaseCommitment_3YearTerm(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp9 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("db-order-3yr")) + calculateResp9 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("db-order-3yr")) t.Cleanup(func() { require.NoError(t, calculateResp9.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp9, nil).Once() - purchaseResp10 := createMockHTTPResponse(http.StatusCreated, `{}`) + purchaseResp10 := mocks.CreateMockHTTPResponse(http.StatusCreated, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp10.Body.Close()) }) @@ -1258,18 +1237,18 @@ func TestDatabaseClient_PurchaseCommitment_3YearTerm(t *testing.T) { func TestDatabaseClient_PurchaseCommitment_Accepted(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp11 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("db-order-202")) + calculateResp11 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("db-order-202")) t.Cleanup(func() { require.NoError(t, calculateResp11.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp11, nil).Once() - purchaseResp12 := createMockHTTPResponse(http.StatusAccepted, `{}`) + purchaseResp12 := mocks.CreateMockHTTPResponse(http.StatusAccepted, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp12.Body.Close()) }) @@ -1294,7 +1273,7 @@ func TestDatabaseClient_PurchaseCommitment_Accepted(t *testing.T) { func TestDatabaseClient_PurchaseCommitment_TokenError(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{err: errors.New("token error")} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1314,7 +1293,7 @@ func TestDatabaseClient_PurchaseCommitment_TokenError(t *testing.T) { func TestDatabaseClient_PurchaseCommitment_HTTPError(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1338,18 +1317,18 @@ func TestDatabaseClient_PurchaseCommitment_HTTPError(t *testing.T) { func TestDatabaseClient_PurchaseCommitment_BadStatus(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp13 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("db-order-bad")) + calculateResp13 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("db-order-bad")) t.Cleanup(func() { require.NoError(t, calculateResp13.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp13, nil).Once() - purchaseResp14 := createMockHTTPResponse(http.StatusBadRequest, `{"error": "invalid request"}`) + purchaseResp14 := mocks.CreateMockHTTPResponse(http.StatusBadRequest, `{"error": "invalid request"}`) t.Cleanup(func() { require.NoError(t, purchaseResp14.Body.Close()) }) @@ -1383,12 +1362,12 @@ func TestDatabaseClient_PurchaseCommitment_TagInjection(t *testing.T) { const source = common.PurchaseSourceWeb ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) var capturedBody []byte - calculateResp15 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) + calculateResp15 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) t.Cleanup(func() { require.NoError(t, calculateResp15.Body.Close()) }) @@ -1400,7 +1379,7 @@ func TestDatabaseClient_PurchaseCommitment_TagInjection(t *testing.T) { r.Body = io.NopCloser(bytes.NewReader(capturedBody)) return true })).Return(calculateResp15, nil).Once() - purchaseResp16 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp16 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp16.Body.Close()) }) @@ -1443,7 +1422,7 @@ func TestDatabaseClient_PurchaseCommitment_BillingPlan(t *testing.T) { } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1460,7 +1439,7 @@ func TestDatabaseClient_PurchaseCommitment_BillingPlan(t *testing.T) { const orderID = "db-billingplan-test" var capturedBody []byte - calculateResp17 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) + calculateResp17 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) t.Cleanup(func() { require.NoError(t, calculateResp17.Body.Close()) }) @@ -1472,7 +1451,7 @@ func TestDatabaseClient_PurchaseCommitment_BillingPlan(t *testing.T) { r.Body = io.NopCloser(bytes.NewReader(capturedBody)) return true })).Return(calculateResp17, nil).Once() - purchaseResp18 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp18 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp18.Body.Close()) }) @@ -1509,7 +1488,7 @@ func TestDatabaseClient_PurchaseCommitment_BillingPlan(t *testing.T) { func TestDatabaseClient_PurchaseCommitment_RequiresSource(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1636,13 +1615,13 @@ func TestDatabaseClient_ValidateOffering_CaseInsensitive(t *testing.T) { func TestDatabaseClient_PurchaseCommitment_DisplayNameConformsToAzureAllowlist(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) const orderID = "azure-db-displayname" var capturedDisplayName string - calculateResp19 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) + calculateResp19 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) t.Cleanup(func() { require.NoError(t, calculateResp19.Body.Close()) }) @@ -1665,7 +1644,7 @@ func TestDatabaseClient_PurchaseCommitment_DisplayNameConformsToAzureAllowlist(t } return true })).Return(calculateResp19, nil).Once() - purchaseResp20 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp20 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp20.Body.Close()) }) @@ -1698,13 +1677,13 @@ func TestDatabaseClient_PurchaseCommitment_DisplayNameConformsToAzureAllowlist(t func TestDatabaseClient_PurchaseCommitment_CanonicalReservedResourceType(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) const orderID = "azure-db-rrt" var capturedRRT string - calculateResp21 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) + calculateResp21 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) t.Cleanup(func() { require.NoError(t, calculateResp21.Body.Close()) }) @@ -1727,7 +1706,7 @@ func TestDatabaseClient_PurchaseCommitment_CanonicalReservedResourceType(t *test } return true })).Return(calculateResp21, nil).Once() - purchaseResp22 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp22 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp22.Body.Close()) }) @@ -2162,7 +2141,7 @@ func TestGetSQLPricing_RejectsInjectedFilterValues(t *testing.T) { {"region", "GP_Gen5_2", "eastus' or '1' eq '1"}, } { t.Run(tc.name, func(t *testing.T) { - client := NewClientWithHTTP(nil, "test-subscription", "eastus", &MockHTTPClient{}) + client := NewClientWithHTTP(nil, "test-subscription", "eastus", &mocks.MockHTTPClient{}) _, err := client.getSQLPricing(context.Background(), tc.sku, tc.region, 1) require.Error(t, err) assert.Contains(t, err.Error(), "Retail Prices filter") @@ -2180,8 +2159,8 @@ func TestDatabaseClient_GetOfferingDetails_ExactReservationFilter(t *testing.T) } body, err := json.Marshal(AzureRetailPrice{Items: []azpricing.RetailPriceItem{row}}) require.NoError(t, err) - mockHTTP := &MockHTTPClient{} - response := createMockHTTPResponse(http.StatusOK, string(body)) + mockHTTP := &mocks.MockHTTPClient{} + response := mocks.CreateMockHTTPResponse(http.StatusOK, string(body)) t.Cleanup(func() { require.NoError(t, response.Body.Close()) }) diff --git a/providers/azure/services/search/client_test.go b/providers/azure/services/search/client_test.go index f9dd6b42..cfda5ecd 100644 --- a/providers/azure/services/search/client_test.go +++ b/providers/azure/services/search/client_test.go @@ -88,27 +88,6 @@ func (m *MockSearchServicesPager) NextPage(ctx context.Context) (armsearch.Servi return page, nil } -// MockHTTPClient mocks HTTP client for testing. -type MockHTTPClient struct { - mock.Mock -} - -func (m *MockHTTPClient) Do(req *http.Request) (*http.Response, error) { - args := m.Called(req) - if args.Get(0) == nil { - return nil, args.Error(1) - } - return args.Get(0).(*http.Response), args.Error(1) -} - -func createMockHTTPResponse(statusCode int, body string) *http.Response { - return &http.Response{ - StatusCode: statusCode, - Body: io.NopCloser(bytes.NewBufferString(body)), - Header: make(http.Header), - } -} - // createSampleSearchPricingResponse is synthetic; the captured eastus catalog has no Reservation rows. func createSampleSearchPricingResponse() string { return `{ @@ -164,7 +143,7 @@ func TestNewClient(t *testing.T) { func TestNewClientWithHTTP(t *testing.T) { t.Parallel() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) require.NotNil(t, client) @@ -223,10 +202,10 @@ func TestSearchClient_Fields(t *testing.T) { func TestSearchClient_GetOfferingDetails_WithMock(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response1 := createMockHTTPResponse(http.StatusOK, createSampleSearchPricingResponse()) + response1 := mocks.CreateMockHTTPResponse(http.StatusOK, createSampleSearchPricingResponse()) t.Cleanup(func() { require.NoError(t, response1.Body.Close()) }) @@ -253,10 +232,10 @@ func TestSearchClient_GetOfferingDetails_WithMock(t *testing.T) { func TestSearchClient_GetOfferingDetails_3YearTerm(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response2 := createMockHTTPResponse(http.StatusOK, createSampleSearchPricingResponse()) + response2 := mocks.CreateMockHTTPResponse(http.StatusOK, createSampleSearchPricingResponse()) t.Cleanup(func() { require.NoError(t, response2.Body.Close()) }) @@ -283,10 +262,10 @@ func TestSearchClient_GetOfferingDetails_3YearTerm(t *testing.T) { func TestSearchClient_GetOfferingDetails_NoUpfront(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response3 := createMockHTTPResponse(http.StatusOK, createSampleSearchPricingResponse()) + response3 := mocks.CreateMockHTTPResponse(http.StatusOK, createSampleSearchPricingResponse()) t.Cleanup(func() { require.NoError(t, response3.Body.Close()) }) @@ -310,10 +289,10 @@ func TestSearchClient_GetOfferingDetails_NoUpfront(t *testing.T) { func TestSearchClient_GetOfferingDetails_APIError(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response4 := createMockHTTPResponse(http.StatusInternalServerError, "Internal Server Error") + response4 := mocks.CreateMockHTTPResponse(http.StatusInternalServerError, "Internal Server Error") t.Cleanup(func() { require.NoError(t, response4.Body.Close()) }) @@ -335,10 +314,10 @@ func TestSearchClient_GetOfferingDetails_APIError(t *testing.T) { func TestSearchClient_GetOfferingDetails_NoPricing(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response5 := createMockHTTPResponse(http.StatusOK, `{"Items": []}`) + response5 := mocks.CreateMockHTTPResponse(http.StatusOK, `{"Items": []}`) t.Cleanup(func() { require.NoError(t, response5.Body.Close()) }) @@ -378,9 +357,9 @@ func TestSearchClient_GetOfferingDetails_NoReservationPricing(t *testing.T) { ] }` - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} client := NewClientWithHTTP(nil, "test-subscription", "eastus", mockHTTP) - response6 := createMockHTTPResponse(http.StatusOK, onDemandOnly) + response6 := mocks.CreateMockHTTPResponse(http.StatusOK, onDemandOnly) t.Cleanup(func() { require.NoError(t, response6.Body.Close()) }) @@ -411,9 +390,9 @@ func TestSearchClient_GetOfferingDetails_SearchDisplaySKUs(t *testing.T) { "unitOfMeasure": "1 Hour", "retailPrice": 600, "currencyCode": "USD", }}}) require.NoError(t, err) - response := createMockHTTPResponse(http.StatusOK, string(body)) + response := mocks.CreateMockHTTPResponse(http.StatusOK, string(body)) t.Cleanup(func() { require.NoError(t, response.Body.Close()) }) - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockHTTP.On("Do", mock.Anything).Return(response, nil).Once() details, err := NewClientWithHTTP(nil, "sub", "eastus", mockHTTP).GetOfferingDetails(context.Background(), common.Recommendation{ ResourceType: tc.sdk, Term: "1yr", PaymentOption: "upfront", @@ -449,9 +428,9 @@ func TestSearchClient_GetOfferingDetails_MixedTermsBothOrders(t *testing.T) { t.Run(tc.name, func(t *testing.T) { body, err := json.Marshal(AzureRetailPrice{Items: tc.items}) require.NoError(t, err) - response := createMockHTTPResponse(http.StatusOK, string(body)) + response := mocks.CreateMockHTTPResponse(http.StatusOK, string(body)) t.Cleanup(func() { require.NoError(t, response.Body.Close()) }) - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockHTTP.On("Do", mock.Anything).Return(response, nil).Once() details, err := NewClientWithHTTP(nil, "sub", "eastus", mockHTTP).GetOfferingDetails(context.Background(), common.Recommendation{ ResourceType: "standard", Term: tc.term, PaymentOption: tc.payment, @@ -522,9 +501,9 @@ func TestSearchClient_GetOfferingDetails_ReservationSelection(t *testing.T) { t.Run(tc.name, func(t *testing.T) { body, err := json.Marshal(map[string]any{"Items": tc.items}) require.NoError(t, err) - response := createMockHTTPResponse(http.StatusOK, string(body)) + response := mocks.CreateMockHTTPResponse(http.StatusOK, string(body)) t.Cleanup(func() { require.NoError(t, response.Body.Close()) }) - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockHTTP.On("Do", mock.Anything).Return(response, nil).Once() details, err := NewClientWithHTTP(nil, "sub", "eastus", mockHTTP).GetOfferingDetails(context.Background(), common.Recommendation{ ResourceType: "standard", Term: "1yr", PaymentOption: "all-upfront", Count: 3, @@ -569,13 +548,13 @@ func TestSearchClient_GetOfferingDetails_Pagination(t *testing.T) { require.NoError(t, err) secondBody, err := json.Marshal(AzureRetailPrice{Items: []pricing.RetailPriceItem{tc.second}}) require.NoError(t, err) - firstResponse := createMockHTTPResponse(http.StatusOK, string(firstBody)) - secondResponse := createMockHTTPResponse(http.StatusOK, string(secondBody)) + firstResponse := mocks.CreateMockHTTPResponse(http.StatusOK, string(firstBody)) + secondResponse := mocks.CreateMockHTTPResponse(http.StatusOK, string(secondBody)) t.Cleanup(func() { require.NoError(t, firstResponse.Body.Close()) require.NoError(t, secondResponse.Body.Close()) }) - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockHTTP.On("Do", mock.MatchedBy(func(req *http.Request) bool { return req.URL.Query().Get("$skip") == "" })).Return(firstResponse, nil).Once() mockHTTP.On("Do", mock.MatchedBy(func(req *http.Request) bool { return req.URL.String() == nextURL })).Return(secondResponse, nil).Once() details, err := NewClientWithHTTP(nil, "sub", "eastus", mockHTTP).GetOfferingDetails(context.Background(), common.Recommendation{ @@ -597,7 +576,7 @@ func TestSearchClient_GetOfferingDetails_Pagination(t *testing.T) { func TestGetSearchPricing_RejectsInjectedRegion(t *testing.T) { t.Parallel() - client := NewClientWithHTTP(nil, "sub", "eastus", &MockHTTPClient{}) + client := NewClientWithHTTP(nil, "sub", "eastus", &mocks.MockHTTPClient{}) _, err := client.getSearchPricing(context.Background(), "standard", "eastus' or '1' eq '1", 1) require.Error(t, err) assert.Contains(t, err.Error(), "Retail Prices filter") @@ -606,9 +585,9 @@ func TestGetSearchPricing_RejectsInjectedRegion(t *testing.T) { func TestSearchClient_GetOfferingDetails_BuildsExactFilterAndRejectsUnknownTier(t *testing.T) { t.Parallel() const region = "eastus" - response := createMockHTTPResponse(http.StatusOK, `{"Items":[{"serviceName":"Azure Cognitive Search","armRegionName":"eastus","skuName":"Standard S1","type":"Reservation","reservationTerm":"1 Year","unitOfMeasure":"1 Hour","retailPrice":800,"currencyCode":"USD"}]}`) + response := mocks.CreateMockHTTPResponse(http.StatusOK, `{"Items":[{"serviceName":"Azure Cognitive Search","armRegionName":"eastus","skuName":"Standard S1","type":"Reservation","reservationTerm":"1 Year","unitOfMeasure":"1 Hour","retailPrice":800,"currencyCode":"USD"}]}`) t.Cleanup(func() { require.NoError(t, response.Body.Close()) }) - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockHTTP.On("Do", mock.Anything).Return(response, nil).Once() details, err := NewClientWithHTTP(nil, "sub", region, mockHTTP).GetOfferingDetails(context.Background(), common.Recommendation{ ResourceType: "standard", Term: "1yr", PaymentOption: "upfront", @@ -620,7 +599,7 @@ func TestSearchClient_GetOfferingDetails_BuildsExactFilterAndRejectsUnknownTier( assert.Contains(t, req.URL.RawQuery, "%24filter=") mockHTTP.AssertExpectations(t) - unknownHTTP := &MockHTTPClient{} + unknownHTTP := &mocks.MockHTTPClient{} _, err = NewClientWithHTTP(nil, "sub", "eastus", unknownHTTP).GetOfferingDetails(context.Background(), common.Recommendation{ ResourceType: "Standard_S1", Term: "1yr", PaymentOption: "upfront", }) @@ -1046,18 +1025,18 @@ func calcPriceRespJSON(orderID string) string { func TestSearchClient_PurchaseCommitment_Success(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp7 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("search-order-001")) + calculateResp7 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("search-order-001")) t.Cleanup(func() { require.NoError(t, calculateResp7.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp7, nil).Once() - purchaseResp8 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp8 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp8.Body.Close()) }) @@ -1085,18 +1064,18 @@ func TestSearchClient_PurchaseCommitment_Success(t *testing.T) { func TestSearchClient_PurchaseCommitment_3YearTerm(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp9 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("search-order-3yr")) + calculateResp9 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("search-order-3yr")) t.Cleanup(func() { require.NoError(t, calculateResp9.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp9, nil).Once() - purchaseResp10 := createMockHTTPResponse(http.StatusCreated, `{}`) + purchaseResp10 := mocks.CreateMockHTTPResponse(http.StatusCreated, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp10.Body.Close()) }) @@ -1122,18 +1101,18 @@ func TestSearchClient_PurchaseCommitment_3YearTerm(t *testing.T) { func TestSearchClient_PurchaseCommitment_Accepted(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp11 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("search-order-202")) + calculateResp11 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("search-order-202")) t.Cleanup(func() { require.NoError(t, calculateResp11.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp11, nil).Once() - purchaseResp12 := createMockHTTPResponse(http.StatusAccepted, `{}`) + purchaseResp12 := mocks.CreateMockHTTPResponse(http.StatusAccepted, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp12.Body.Close()) }) @@ -1158,7 +1137,7 @@ func TestSearchClient_PurchaseCommitment_Accepted(t *testing.T) { func TestSearchClient_PurchaseCommitment_TokenError(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{err: errors.New("token error")} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1178,7 +1157,7 @@ func TestSearchClient_PurchaseCommitment_TokenError(t *testing.T) { func TestSearchClient_PurchaseCommitment_HTTPError(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1202,18 +1181,18 @@ func TestSearchClient_PurchaseCommitment_HTTPError(t *testing.T) { func TestSearchClient_PurchaseCommitment_BadStatus(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) - calculateResp13 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON("search-order-bad")) + calculateResp13 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON("search-order-bad")) t.Cleanup(func() { require.NoError(t, calculateResp13.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp13, nil).Once() - purchaseResp14 := createMockHTTPResponse(http.StatusBadRequest, `{"error": "invalid request"}`) + purchaseResp14 := mocks.CreateMockHTTPResponse(http.StatusBadRequest, `{"error": "invalid request"}`) t.Cleanup(func() { require.NoError(t, purchaseResp14.Body.Close()) }) @@ -1301,20 +1280,20 @@ func TestSearchClient_ValidateOffering_Invalid(t *testing.T) { func TestSearchClient_PurchaseCommitment_TwoStepFlow(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) const azureMintedOrderID = "azure-search-order-677" - calculateResp15 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON(azureMintedOrderID)) + calculateResp15 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON(azureMintedOrderID)) t.Cleanup(func() { require.NoError(t, calculateResp15.Body.Close()) }) mockHTTP.On("Do", mock.MatchedBy(func(r *http.Request) bool { return r.Method == http.MethodPost && r.URL.Path == "/providers/Microsoft.Capacity/calculatePrice" })).Return(calculateResp15, nil).Once() - purchaseResp16 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp16 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp16.Body.Close()) }) @@ -1351,12 +1330,12 @@ func TestSearchClient_PurchaseCommitment_TagInjection(t *testing.T) { const source = "cudly-web" ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) var capturedBody []byte - calculateResp17 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) + calculateResp17 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) t.Cleanup(func() { require.NoError(t, calculateResp17.Body.Close()) }) @@ -1368,7 +1347,7 @@ func TestSearchClient_PurchaseCommitment_TagInjection(t *testing.T) { r.Body = io.NopCloser(bytes.NewReader(capturedBody)) return true })).Return(calculateResp17, nil).Once() - purchaseResp18 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp18 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp18.Body.Close()) }) @@ -1417,7 +1396,7 @@ func TestSearchClient_PurchaseCommitment_BillingPlan(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1434,7 +1413,7 @@ func TestSearchClient_PurchaseCommitment_BillingPlan(t *testing.T) { const orderID = "search-billingplan-test" var capturedBody []byte - calculateResp19 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) + calculateResp19 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) t.Cleanup(func() { require.NoError(t, calculateResp19.Body.Close()) }) @@ -1446,7 +1425,7 @@ func TestSearchClient_PurchaseCommitment_BillingPlan(t *testing.T) { r.Body = io.NopCloser(bytes.NewReader(capturedBody)) return true })).Return(calculateResp19, nil).Once() - purchaseResp20 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp20 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp20.Body.Close()) }) @@ -1483,7 +1462,7 @@ func TestSearchClient_PurchaseCommitment_BillingPlan(t *testing.T) { func TestSearchClient_PurchaseCommitment_RequiresSource(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) @@ -1537,13 +1516,13 @@ func TestSearchClient_ValidateOffering_CaseInsensitive(t *testing.T) { func TestSearchClient_PurchaseCommitment_DisplayNameConformsToAzureAllowlist(t *testing.T) { t.Parallel() ctx := context.Background() - mockHTTP := &MockHTTPClient{} + mockHTTP := &mocks.MockHTTPClient{} mockCred := &MockTokenCredential{token: "test-token"} client := NewClientWithHTTP(mockCred, "test-subscription", "eastus", mockHTTP) const orderID = "azure-search-displayname" var capturedDisplayName string - calculateResp21 := createMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) + calculateResp21 := mocks.CreateMockHTTPResponse(http.StatusOK, calcPriceRespJSON(orderID)) t.Cleanup(func() { require.NoError(t, calculateResp21.Body.Close()) }) @@ -1566,7 +1545,7 @@ func TestSearchClient_PurchaseCommitment_DisplayNameConformsToAzureAllowlist(t * } return true })).Return(calculateResp21, nil).Once() - purchaseResp22 := createMockHTTPResponse(http.StatusOK, `{}`) + purchaseResp22 := mocks.CreateMockHTTPResponse(http.StatusOK, `{}`) t.Cleanup(func() { require.NoError(t, purchaseResp22.Body.Close()) })