github.com/akamai/AkamaiOPEN-edgegrid-golang/v5@v5.0.0/pkg/papi/include_activations_test.go (about)

     1  package papi
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func TestActivateInclude(t *testing.T) {
    16  	tests := map[string]struct {
    17  		params              ActivateIncludeRequest
    18  		expectedRequestBody string
    19  		responseStatus      int
    20  		responseBody        string
    21  		expectedPath        string
    22  		expectedResponse    *ActivationIncludeResponse
    23  		withError           error
    24  		assertError         func(*testing.T, error)
    25  	}{
    26  		"201 Activate include acknowledging all the warnings": {
    27  			params: ActivateIncludeRequest{
    28  				IncludeID:              "inc_12345",
    29  				Version:                4,
    30  				Network:                ActivationNetworkStaging,
    31  				Note:                   "test activation",
    32  				NotifyEmails:           []string{"jbond@example.com"},
    33  				AcknowledgeAllWarnings: true,
    34  			},
    35  			expectedRequestBody: `{"acknowledgeAllWarnings":true,"activationType":"ACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"STAGING","note":"test activation","notifyEmails":["jbond@example.com"]}`,
    36  			expectedPath:        "/papi/v1/includes/inc_12345/activations",
    37  			responseStatus:      http.StatusCreated,
    38  			responseBody: `
    39  {
    40      "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id"
    41  }`,
    42  			expectedResponse: &ActivationIncludeResponse{
    43  				ActivationID:   "temporary-activation-id",
    44  				ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id",
    45  			},
    46  		},
    47  		"201 Activate include": {
    48  			params: ActivateIncludeRequest{
    49  				IncludeID:    "inc_12345",
    50  				Version:      4,
    51  				Network:      ActivationNetworkStaging,
    52  				Note:         "test activation",
    53  				NotifyEmails: []string{"jbond@example.com"},
    54  			},
    55  			expectedRequestBody: `{"acknowledgeAllWarnings":false,"activationType":"ACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"STAGING","note":"test activation","notifyEmails":["jbond@example.com"]}`,
    56  			expectedPath:        "/papi/v1/includes/inc_12345/activations",
    57  			responseStatus:      http.StatusCreated,
    58  			responseBody: `
    59  {
    60      "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id"
    61  }`,
    62  			expectedResponse: &ActivationIncludeResponse{
    63  				ActivationID:   "temporary-activation-id",
    64  				ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id",
    65  			},
    66  		},
    67  		"201 Activate include with ComplianceRecord None": {
    68  			params: ActivateIncludeRequest{
    69  				IncludeID:    "inc_12345",
    70  				Version:      4,
    71  				Network:      ActivationNetworkProduction,
    72  				Note:         "test activation",
    73  				NotifyEmails: []string{"jbond@example.com"},
    74  				ComplianceRecord: &ComplianceRecordNone{
    75  					CustomerEmail:  "sb@akamai.com",
    76  					PeerReviewedBy: "sb@akamai.com",
    77  					UnitTested:     true,
    78  					TicketID:       "123",
    79  				},
    80  			},
    81  			expectedRequestBody: `{"acknowledgeAllWarnings":false,"activationType":"ACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"PRODUCTION","note":"test activation","notifyEmails":["jbond@example.com"], "complianceRecord":{"customerEmail":"sb@akamai.com", "noncomplianceReason":"NONE", "peerReviewedBy":"sb@akamai.com", "unitTested":true, "ticketId":"123"}}`,
    82  			expectedPath:        "/papi/v1/includes/inc_12345/activations",
    83  			responseStatus:      http.StatusCreated,
    84  			responseBody: `
    85  {
    86      "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id"
    87  }`,
    88  			expectedResponse: &ActivationIncludeResponse{
    89  				ActivationID:   "temporary-activation-id",
    90  				ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id",
    91  			},
    92  		},
    93  		"201 Activate include with ComplianceRecord Other": {
    94  			params: ActivateIncludeRequest{
    95  				IncludeID:    "inc_12345",
    96  				Version:      4,
    97  				Network:      ActivationNetworkProduction,
    98  				Note:         "test activation",
    99  				NotifyEmails: []string{"jbond@example.com"},
   100  				ComplianceRecord: &ComplianceRecordOther{
   101  					OtherNoncomplianceReason: "some other reason",
   102  					TicketID:                 "123",
   103  				},
   104  			},
   105  			expectedRequestBody: `{"acknowledgeAllWarnings":false,"activationType":"ACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"PRODUCTION","note":"test activation","notifyEmails":["jbond@example.com"], "complianceRecord":{"otherNoncomplianceReason":"some other reason", "noncomplianceReason":"OTHER", "ticketId":"123"}}`,
   106  			expectedPath:        "/papi/v1/includes/inc_12345/activations",
   107  			responseStatus:      http.StatusCreated,
   108  			responseBody: `
   109  {
   110      "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id"
   111  }`,
   112  			expectedResponse: &ActivationIncludeResponse{
   113  				ActivationID:   "temporary-activation-id",
   114  				ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id",
   115  			},
   116  		},
   117  		"201 Activate include with ComplianceRecord No_Production_Traffic": {
   118  			params: ActivateIncludeRequest{
   119  				IncludeID:    "inc_12345",
   120  				Version:      4,
   121  				Network:      ActivationNetworkProduction,
   122  				Note:         "test activation",
   123  				NotifyEmails: []string{"jbond@example.com"},
   124  				ComplianceRecord: &ComplianceRecordNoProductionTraffic{
   125  					TicketID: "123",
   126  				},
   127  			},
   128  			expectedRequestBody: `{"acknowledgeAllWarnings":false,"activationType":"ACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"PRODUCTION","note":"test activation","notifyEmails":["jbond@example.com"], "complianceRecord":{"noncomplianceReason":"NO_PRODUCTION_TRAFFIC", "ticketId":"123"}}`,
   129  			expectedPath:        "/papi/v1/includes/inc_12345/activations",
   130  			responseStatus:      http.StatusCreated,
   131  			responseBody: `
   132  {
   133      "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id"
   134  }`,
   135  			expectedResponse: &ActivationIncludeResponse{
   136  				ActivationID:   "temporary-activation-id",
   137  				ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id",
   138  			},
   139  		},
   140  		"201 Activate include with ComplianceRecord Emergency": {
   141  			params: ActivateIncludeRequest{
   142  				IncludeID:    "inc_12345",
   143  				Version:      4,
   144  				Network:      ActivationNetworkProduction,
   145  				Note:         "test activation",
   146  				NotifyEmails: []string{"jbond@example.com"},
   147  				ComplianceRecord: &ComplianceRecordEmergency{
   148  					TicketID: "123",
   149  				},
   150  			},
   151  			expectedRequestBody: `{"acknowledgeAllWarnings":false,"activationType":"ACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"PRODUCTION","note":"test activation","notifyEmails":["jbond@example.com"], "complianceRecord":{"noncomplianceReason":"EMERGENCY", "ticketId":"123"}}`,
   152  			expectedPath:        "/papi/v1/includes/inc_12345/activations",
   153  			responseStatus:      http.StatusCreated,
   154  			responseBody: `
   155  {
   156      "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id"
   157  }`,
   158  			expectedResponse: &ActivationIncludeResponse{
   159  				ActivationID:   "temporary-activation-id",
   160  				ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id",
   161  			},
   162  		},
   163  		"500 internal server error": {
   164  			params: ActivateIncludeRequest{
   165  				IncludeID:              "inc_12345",
   166  				Version:                4,
   167  				Network:                ActivationNetworkStaging,
   168  				Note:                   "test activation",
   169  				NotifyEmails:           []string{"jbond@example.com"},
   170  				AcknowledgeAllWarnings: true,
   171  			},
   172  			expectedPath:   "/papi/v1/includes/inc_12345/activations",
   173  			responseStatus: http.StatusInternalServerError,
   174  			responseBody: `
   175  		{
   176  			"type": "internal_error",
   177  		   "title": "Internal Server Error",
   178  		   "detail": "Error getting include",
   179  		   "status": 500
   180  		}`,
   181  			withError: &Error{
   182  				Type:       "internal_error",
   183  				Title:      "Internal Server Error",
   184  				Detail:     "Error getting include",
   185  				StatusCode: http.StatusInternalServerError,
   186  			},
   187  		},
   188  		"validation error - missing include id": {
   189  			params: ActivateIncludeRequest{
   190  				Version:      4,
   191  				Network:      ActivationNetworkStaging,
   192  				NotifyEmails: []string{"jbond@example.com"},
   193  			},
   194  			withError: ErrStructValidation,
   195  		},
   196  		"validation error - missing version": {
   197  			params: ActivateIncludeRequest{
   198  				IncludeID:    "inc_12345",
   199  				Network:      ActivationNetworkStaging,
   200  				NotifyEmails: []string{"jbond@example.com"},
   201  			},
   202  			withError: ErrStructValidation,
   203  		},
   204  		"validation error - missing network": {
   205  			params: ActivateIncludeRequest{
   206  				IncludeID:    "inc_12345",
   207  				Version:      4,
   208  				NotifyEmails: []string{"jbond@example.com"},
   209  			},
   210  			withError: ErrStructValidation,
   211  		},
   212  		"validation error - missing notify emails": {
   213  			params: ActivateIncludeRequest{
   214  				IncludeID: "inc_12345",
   215  				Version:   4,
   216  				Network:   ActivationNetworkStaging,
   217  			},
   218  			withError: ErrStructValidation,
   219  		},
   220  		"validation error - not valid ComplianceRecordNone": {
   221  			params: ActivateIncludeRequest{
   222  				IncludeID:              "inc_12345",
   223  				Version:                4,
   224  				Network:                ActivationNetworkProduction,
   225  				Note:                   "test activation",
   226  				NotifyEmails:           []string{"jbond@example.com"},
   227  				AcknowledgeAllWarnings: true,
   228  				ComplianceRecord: &ComplianceRecordNone{
   229  					UnitTested: true,
   230  					TicketID:   "123",
   231  				},
   232  			},
   233  			withError: ErrStructValidation,
   234  			assertError: func(t *testing.T, err error) {
   235  				assert.Contains(t, err.Error(), "CustomerEmail: cannot be blank")
   236  				assert.Contains(t, err.Error(), "PeerReviewedBy: cannot be blank")
   237  			},
   238  		},
   239  		"validation error - not valid UnitTested field for PRODUCTION activation network and ComplianceRecordNone": {
   240  			params: ActivateIncludeRequest{
   241  				IncludeID:    "inc_12345",
   242  				Version:      4,
   243  				Network:      ActivationNetworkProduction,
   244  				Note:         "test activation",
   245  				NotifyEmails: []string{"jbond@example.com"},
   246  				ComplianceRecord: &ComplianceRecordNone{
   247  					CustomerEmail:  "sb@akamai.com",
   248  					PeerReviewedBy: "sb@akamai.com",
   249  					UnitTested:     false,
   250  					TicketID:       "123",
   251  				},
   252  			},
   253  			withError: ErrStructValidation,
   254  			assertError: func(t *testing.T, err error) {
   255  				assert.Contains(t, err.Error(), "for PRODUCTION activation network and nonComplianceRecord, UnitTested value has to be set to true, otherwise API will not work correctly")
   256  			},
   257  		},
   258  		"validation error - not valid ComplianceRecordOther": {
   259  			params: ActivateIncludeRequest{
   260  				IncludeID:              "inc_12345",
   261  				Version:                4,
   262  				Network:                ActivationNetworkProduction,
   263  				Note:                   "test activation",
   264  				NotifyEmails:           []string{"jbond@example.com"},
   265  				AcknowledgeAllWarnings: true,
   266  				ComplianceRecord:       &ComplianceRecordOther{},
   267  			},
   268  			withError: ErrStructValidation,
   269  			assertError: func(t *testing.T, err error) {
   270  				assert.Contains(t, err.Error(), "OtherNoncomplianceReason: cannot be blank")
   271  			},
   272  		},
   273  	}
   274  	for name, test := range tests {
   275  		t.Run(name, func(t *testing.T) {
   276  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   277  				assert.Equal(t, test.expectedPath, r.URL.String())
   278  				assert.Equal(t, http.MethodPost, r.Method)
   279  				w.WriteHeader(test.responseStatus)
   280  				_, err := w.Write([]byte(test.responseBody))
   281  				assert.NoError(t, err)
   282  
   283  				if len(test.expectedRequestBody) > 0 {
   284  					body, err := ioutil.ReadAll(r.Body)
   285  					require.NoError(t, err)
   286  					assert.JSONEq(t, test.expectedRequestBody, string(body))
   287  				}
   288  			}))
   289  			client := mockAPIClient(t, mockServer)
   290  			result, err := client.ActivateInclude(context.Background(), test.params)
   291  
   292  			if test.withError != nil || test.assertError != nil {
   293  				if test.withError != nil {
   294  					assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   295  				}
   296  				if test.assertError != nil {
   297  					test.assertError(t, err)
   298  				}
   299  				return
   300  			}
   301  
   302  			require.NoError(t, err)
   303  			assert.Equal(t, test.expectedResponse, result)
   304  		})
   305  	}
   306  }
   307  
   308  func TestDeactivateInclude(t *testing.T) {
   309  	tests := map[string]struct {
   310  		params              DeactivateIncludeRequest
   311  		expectedRequestBody string
   312  		responseStatus      int
   313  		responseBody        string
   314  		expectedPath        string
   315  		expectedResponse    *DeactivationIncludeResponse
   316  		withError           error
   317  	}{
   318  		"201 Activate include acknowledging all the warnings": {
   319  			params: DeactivateIncludeRequest{
   320  				IncludeID:              "inc_12345",
   321  				Version:                4,
   322  				Network:                ActivationNetworkStaging,
   323  				Note:                   "test activation",
   324  				NotifyEmails:           []string{"jbond@example.com"},
   325  				AcknowledgeAllWarnings: true,
   326  			},
   327  			expectedRequestBody: `{"acknowledgeAllWarnings":true,"activationType":"DEACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"STAGING","note":"test activation","notifyEmails":["jbond@example.com"]}`,
   328  			expectedPath:        "/papi/v1/includes/inc_12345/activations",
   329  			responseStatus:      http.StatusCreated,
   330  			responseBody: `
   331  {
   332      "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id"
   333  }`,
   334  			expectedResponse: &DeactivationIncludeResponse{
   335  				ActivationID:   "temporary-activation-id",
   336  				ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id",
   337  			},
   338  		},
   339  		"201 Activate include": {
   340  			params: DeactivateIncludeRequest{
   341  				IncludeID:    "inc_12345",
   342  				Version:      4,
   343  				Network:      ActivationNetworkStaging,
   344  				Note:         "test activation",
   345  				NotifyEmails: []string{"jbond@example.com"},
   346  			},
   347  			expectedRequestBody: `{"acknowledgeAllWarnings":false,"activationType":"DEACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"STAGING","note":"test activation","notifyEmails":["jbond@example.com"]}`,
   348  			expectedPath:        "/papi/v1/includes/inc_12345/activations",
   349  			responseStatus:      http.StatusCreated,
   350  			responseBody: `
   351  		{
   352  		   "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id"
   353  		}`,
   354  			expectedResponse: &DeactivationIncludeResponse{
   355  				ActivationID:   "temporary-activation-id",
   356  				ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id",
   357  			},
   358  		},
   359  		"422 Unprocessable entity - deactivate version which is not active on some network": {
   360  			params: DeactivateIncludeRequest{
   361  				IncludeID:              "inc_12345",
   362  				Version:                4,
   363  				Network:                ActivationNetworkProduction,
   364  				Note:                   "test activation",
   365  				NotifyEmails:           []string{"jbond@example.com"},
   366  				AcknowledgeAllWarnings: true,
   367  			},
   368  			expectedPath:   "/papi/v1/includes/inc_12345/activations",
   369  			responseStatus: http.StatusUnprocessableEntity,
   370  			responseBody: `
   371  {
   372      "type": "https://problems.luna.akamaiapis.net/papi/v0/deactivation/include-not-active-in-production",
   373      "title": "Include not active in PRODUCTION",
   374      "detail": "The include cannot be deactivated because it is not active in PRODUCTION.",
   375      "instance": "https://akaa-gcplhccxrheyl6kw-bcfnozqkbaydivqp.luna-dev.akamaiapis.net/papi/v1/includes/inc_12345/activations#12345",
   376      "status": 422
   377  }`,
   378  			withError: &Error{
   379  				Type:       "https://problems.luna.akamaiapis.net/papi/v0/deactivation/include-not-active-in-production",
   380  				Title:      "Include not active in PRODUCTION",
   381  				Detail:     "The include cannot be deactivated because it is not active in PRODUCTION.",
   382  				Instance:   "https://akaa-gcplhccxrheyl6kw-bcfnozqkbaydivqp.luna-dev.akamaiapis.net/papi/v1/includes/inc_12345/activations#12345",
   383  				StatusCode: http.StatusUnprocessableEntity,
   384  			},
   385  		},
   386  		"500 internal server error": {
   387  			params: DeactivateIncludeRequest{
   388  				IncludeID:              "inc_12345",
   389  				Version:                4,
   390  				Network:                ActivationNetworkStaging,
   391  				Note:                   "test activation",
   392  				NotifyEmails:           []string{"jbond@example.com"},
   393  				AcknowledgeAllWarnings: true,
   394  			},
   395  			expectedPath:   "/papi/v1/includes/inc_12345/activations",
   396  			responseStatus: http.StatusInternalServerError,
   397  			responseBody: `
   398  				{
   399  					"type": "internal_error",
   400  				   "title": "Internal Server Error",
   401  				   "detail": "Error getting include",
   402  				   "status": 500
   403  				}`,
   404  			withError: &Error{
   405  				Type:       "internal_error",
   406  				Title:      "Internal Server Error",
   407  				Detail:     "Error getting include",
   408  				StatusCode: http.StatusInternalServerError,
   409  			},
   410  		},
   411  		"validation error - missing include id": {
   412  			params: DeactivateIncludeRequest{
   413  				Version:      4,
   414  				Network:      ActivationNetworkStaging,
   415  				NotifyEmails: []string{"jbond@example.com"},
   416  			},
   417  			withError: ErrStructValidation,
   418  		},
   419  		"validation error - missing version": {
   420  			params: DeactivateIncludeRequest{
   421  				IncludeID:    "inc_12345",
   422  				Network:      ActivationNetworkStaging,
   423  				NotifyEmails: []string{"jbond@example.com"},
   424  			},
   425  			withError: ErrStructValidation,
   426  		},
   427  		"validation error - missing network": {
   428  			params: DeactivateIncludeRequest{
   429  				IncludeID:    "inc_12345",
   430  				Version:      4,
   431  				NotifyEmails: []string{"jbond@example.com"},
   432  			},
   433  			withError: ErrStructValidation,
   434  		},
   435  		"validation error - missing notify emails": {
   436  			params: DeactivateIncludeRequest{
   437  				IncludeID: "inc_12345",
   438  				Version:   4,
   439  				Network:   ActivationNetworkStaging,
   440  			},
   441  			withError: ErrStructValidation,
   442  		},
   443  	}
   444  	for name, test := range tests {
   445  		t.Run(name, func(t *testing.T) {
   446  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   447  				assert.Equal(t, test.expectedPath, r.URL.String())
   448  				assert.Equal(t, http.MethodPost, r.Method)
   449  				w.WriteHeader(test.responseStatus)
   450  				_, err := w.Write([]byte(test.responseBody))
   451  				assert.NoError(t, err)
   452  
   453  				if len(test.expectedRequestBody) > 0 {
   454  					body, err := ioutil.ReadAll(r.Body)
   455  					require.NoError(t, err)
   456  					assert.JSONEq(t, test.expectedRequestBody, string(body))
   457  				}
   458  			}))
   459  			client := mockAPIClient(t, mockServer)
   460  			result, err := client.DeactivateInclude(context.Background(), test.params)
   461  			if test.withError != nil {
   462  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   463  				return
   464  			}
   465  			require.NoError(t, err)
   466  			assert.Equal(t, test.expectedResponse, result)
   467  		})
   468  	}
   469  }
   470  
   471  func TestCancelIncludeActivation(t *testing.T) {
   472  	tests := map[string]struct {
   473  		params           CancelIncludeActivationRequest
   474  		responseStatus   int
   475  		responseBody     string
   476  		expectedPath     string
   477  		expectedResponse *CancelIncludeActivationResponse
   478  		withError        error
   479  	}{
   480  		"200 cancel include activation": {
   481  			params: CancelIncludeActivationRequest{
   482  				IncludeID:    "inc_12345",
   483  				ContractID:   "test_contract",
   484  				GroupID:      "test_group",
   485  				ActivationID: "test_activation_123",
   486  			},
   487  			expectedPath:   "/papi/v1/includes/inc_12345/activations/test_activation_123?contractId=test_contract&groupId=test_group",
   488  			responseStatus: http.StatusOK,
   489  			responseBody: `
   490  {
   491      "accountId": "test_account",
   492      "contractId": "test_contract",
   493      "groupId": "test_group",
   494      "activations": {
   495          "items": [
   496              {
   497                  "network": "STAGING",
   498                  "activationType": "ACTIVATE",
   499                  "status": "PENDING_CANCELLATION",
   500                  "submitDate": "2022-12-01T13:18:57Z",
   501                  "updateDate": "2022-12-01T13:19:04Z",
   502                  "note": "test_note_1",
   503                  "notifyEmails": [
   504                      "nomail@nomail.com"
   505                  ],
   506                  "fmaActivationState": "received",
   507                  "includeId": "inc_12345",
   508                  "includeName": "test_include_name",
   509                  "includeVersion": 1,
   510                  "includeActivationId": "test_activation_123"
   511              }
   512          ]
   513      }
   514  }`,
   515  			expectedResponse: &CancelIncludeActivationResponse{
   516  				AccountID:  "test_account",
   517  				ContractID: "test_contract",
   518  				GroupID:    "test_group",
   519  				Activations: IncludeActivationsRes{
   520  					Items: []IncludeActivation{
   521  						{
   522  							Network:             "STAGING",
   523  							ActivationType:      ActivationTypeActivate,
   524  							Status:              ActivationStatusCancelling,
   525  							SubmitDate:          "2022-12-01T13:18:57Z",
   526  							UpdateDate:          "2022-12-01T13:19:04Z",
   527  							Note:                "test_note_1",
   528  							NotifyEmails:        []string{"nomail@nomail.com"},
   529  							FMAActivationState:  "received",
   530  							IncludeID:           "inc_12345",
   531  							IncludeName:         "test_include_name",
   532  							IncludeVersion:      1,
   533  							IncludeActivationID: "test_activation_123",
   534  						},
   535  					},
   536  				},
   537  			},
   538  		},
   539  		"500 internal server error": {
   540  			params: CancelIncludeActivationRequest{
   541  				IncludeID:    "inc_12345",
   542  				ContractID:   "test_contract",
   543  				GroupID:      "test_group",
   544  				ActivationID: "test_activation_123",
   545  			},
   546  			expectedPath:   "/papi/v1/includes/inc_12345/activations/test_activation_123?contractId=test_contract&groupId=test_group",
   547  			responseStatus: http.StatusInternalServerError,
   548  			responseBody: `
   549  				{
   550  					"type": "internal_error",
   551  				   "title": "Internal Server Error",
   552  				   "detail": "Error cancelling include activation",
   553  				   "status": 500
   554  				}`,
   555  			withError: &Error{
   556  				Type:       "internal_error",
   557  				Title:      "Internal Server Error",
   558  				Detail:     "Error cancelling include activation",
   559  				StatusCode: http.StatusInternalServerError,
   560  			},
   561  		},
   562  		"validation error - missing include id": {
   563  			params: CancelIncludeActivationRequest{
   564  				ContractID:   "test_contract",
   565  				GroupID:      "test_group",
   566  				ActivationID: "test_activation_123",
   567  			},
   568  			withError: ErrStructValidation,
   569  		},
   570  		"validation error - contract id": {
   571  			params: CancelIncludeActivationRequest{
   572  				IncludeID:    "inc_12345",
   573  				GroupID:      "test_group",
   574  				ActivationID: "test_activation_123",
   575  			},
   576  			withError: ErrStructValidation,
   577  		},
   578  		"validation error - group id": {
   579  			params: CancelIncludeActivationRequest{
   580  				IncludeID:    "inc_12345",
   581  				ContractID:   "test_contract",
   582  				ActivationID: "test_activation_123",
   583  			},
   584  			withError: ErrStructValidation,
   585  		},
   586  		"validation error - activation id": {
   587  			params: CancelIncludeActivationRequest{
   588  				IncludeID:  "inc_12345",
   589  				ContractID: "test_contract",
   590  				GroupID:    "test_group",
   591  			},
   592  			withError: ErrStructValidation,
   593  		},
   594  	}
   595  	for name, test := range tests {
   596  		t.Run(name, func(t *testing.T) {
   597  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   598  				assert.Equal(t, test.expectedPath, r.URL.String())
   599  				assert.Equal(t, http.MethodDelete, r.Method)
   600  				w.WriteHeader(test.responseStatus)
   601  				_, err := w.Write([]byte(test.responseBody))
   602  				assert.NoError(t, err)
   603  			}))
   604  			client := mockAPIClient(t, mockServer)
   605  			result, err := client.CancelIncludeActivation(context.Background(), test.params)
   606  			if test.withError != nil {
   607  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   608  				return
   609  			}
   610  			require.NoError(t, err)
   611  			assert.Equal(t, test.expectedResponse, result)
   612  		})
   613  	}
   614  }
   615  
   616  func TestGetIncludeActivation(t *testing.T) {
   617  	tests := map[string]struct {
   618  		params           GetIncludeActivationRequest
   619  		responseStatus   int
   620  		responseBody     string
   621  		expectedPath     string
   622  		expectedResponse *GetIncludeActivationResponse
   623  		withError        error
   624  	}{
   625  		"200 Get include activation": {
   626  			params: GetIncludeActivationRequest{
   627  				IncludeID:    "inc_12345",
   628  				ActivationID: "atv_12345",
   629  			},
   630  			expectedPath:   "/papi/v1/includes/inc_12345/activations/atv_12345",
   631  			responseStatus: http.StatusOK,
   632  			responseBody: `
   633  {
   634      "accountId": "test_account",
   635      "contractId": "test_contract",
   636      "groupId": "test_group",
   637      "activations": {
   638          "items": [
   639              {
   640                  "activationId": "atv_12345",
   641                  "network": "STAGING",
   642                  "activationType": "ACTIVATE",
   643                  "status": "ACTIVE",
   644                  "submitDate": "2022-10-27T12:27:54Z",
   645                  "updateDate": "2022-10-27T12:28:54Z",
   646                  "note": "DXE test activation",
   647                  "notifyEmails": [
   648                      "test@example.com"
   649                  ],
   650                  "fmaActivationState": "steady",
   651                  "fallbackInfo": {
   652                      "fastFallbackAttempted": false,
   653                      "fallbackVersion": 3,
   654                      "canFastFallback": false,
   655                      "steadyStateTime": 1666873734,
   656                      "fastFallbackExpirationTime": 1666877334,
   657                      "fastFallbackRecoveryState": null
   658                  },
   659                  "includeId": "inc_12345",
   660                  "includeName": "tfp_test1",
   661                  "includeType": "MICROSERVICES",
   662                  "includeVersion": 4
   663              }
   664          ]
   665      }
   666  }`,
   667  			expectedResponse: &GetIncludeActivationResponse{
   668  				AccountID:  "test_account",
   669  				ContractID: "test_contract",
   670  				GroupID:    "test_group",
   671  				Activations: IncludeActivationsRes{
   672  					Items: []IncludeActivation{
   673  						{
   674  							ActivationID:       "atv_12345",
   675  							Network:            "STAGING",
   676  							ActivationType:     ActivationTypeActivate,
   677  							Status:             ActivationStatusActive,
   678  							SubmitDate:         "2022-10-27T12:27:54Z",
   679  							UpdateDate:         "2022-10-27T12:28:54Z",
   680  							Note:               "DXE test activation",
   681  							NotifyEmails:       []string{"test@example.com"},
   682  							FMAActivationState: "steady",
   683  							FallbackInfo: &ActivationFallbackInfo{
   684  								FastFallbackAttempted:      false,
   685  								FallbackVersion:            3,
   686  								CanFastFallback:            false,
   687  								SteadyStateTime:            1666873734,
   688  								FastFallbackExpirationTime: 1666877334,
   689  							},
   690  							IncludeID:      "inc_12345",
   691  							IncludeName:    "tfp_test1",
   692  							IncludeType:    "MICROSERVICES",
   693  							IncludeVersion: 4,
   694  						},
   695  					},
   696  				},
   697  				Activation: IncludeActivation{
   698  					ActivationID:       "atv_12345",
   699  					Network:            "STAGING",
   700  					ActivationType:     ActivationTypeActivate,
   701  					Status:             ActivationStatusActive,
   702  					SubmitDate:         "2022-10-27T12:27:54Z",
   703  					UpdateDate:         "2022-10-27T12:28:54Z",
   704  					Note:               "DXE test activation",
   705  					NotifyEmails:       []string{"test@example.com"},
   706  					FMAActivationState: "steady",
   707  					FallbackInfo: &ActivationFallbackInfo{
   708  						FastFallbackAttempted:      false,
   709  						FallbackVersion:            3,
   710  						CanFastFallback:            false,
   711  						SteadyStateTime:            1666873734,
   712  						FastFallbackExpirationTime: 1666877334,
   713  					},
   714  					IncludeID:      "inc_12345",
   715  					IncludeName:    "tfp_test1",
   716  					IncludeType:    "MICROSERVICES",
   717  					IncludeVersion: 4,
   718  				},
   719  			},
   720  		},
   721  		"200 Get include activation with includeActivationId": {
   722  			params: GetIncludeActivationRequest{
   723  				IncludeID:    "inc_12345",
   724  				ActivationID: "5e597860-1107-461e-8dbe-4e7526e8dd02",
   725  			},
   726  			expectedPath:   "/papi/v1/includes/inc_12345/activations/5e597860-1107-461e-8dbe-4e7526e8dd02",
   727  			responseStatus: http.StatusOK,
   728  			responseBody: `
   729  {
   730      "accountId": "test_account",
   731      "contractId": "test_contract",
   732      "groupId": "test_group",
   733      "activations": {
   734          "items": [
   735              {
   736                  "includeActivationId": "5e597860-1107-461e-8dbe-4e7526e8dd02",
   737                  "network": "STAGING",
   738                  "activationType": "ACTIVATE",
   739                  "status": "ACTIVE",
   740                  "submitDate": "2022-10-27T12:27:54Z",
   741                  "updateDate": "2022-10-27T12:28:54Z",
   742                  "note": "DXE test activation",
   743                  "notifyEmails": [
   744                      "test@example.com"
   745                  ],
   746                  "fmaActivationState": "steady",
   747                  "fallbackInfo": {
   748                      "fastFallbackAttempted": false,
   749                      "fallbackVersion": 3,
   750                      "canFastFallback": false,
   751                      "steadyStateTime": 1666873734,
   752                      "fastFallbackExpirationTime": 1666877334,
   753                      "fastFallbackRecoveryState": null
   754                  },
   755                  "includeId": "inc_12345",
   756                  "includeName": "tfp_test1",
   757                  "includeType": "MICROSERVICES",
   758                  "includeVersion": 4
   759              }
   760          ]
   761      }
   762  }`,
   763  			expectedResponse: &GetIncludeActivationResponse{
   764  				AccountID:  "test_account",
   765  				ContractID: "test_contract",
   766  				GroupID:    "test_group",
   767  				Activations: IncludeActivationsRes{
   768  					Items: []IncludeActivation{
   769  						{
   770  							IncludeActivationID: "5e597860-1107-461e-8dbe-4e7526e8dd02",
   771  							Network:             "STAGING",
   772  							ActivationType:      ActivationTypeActivate,
   773  							Status:              ActivationStatusActive,
   774  							SubmitDate:          "2022-10-27T12:27:54Z",
   775  							UpdateDate:          "2022-10-27T12:28:54Z",
   776  							Note:                "DXE test activation",
   777  							NotifyEmails:        []string{"test@example.com"},
   778  							FMAActivationState:  "steady",
   779  							FallbackInfo: &ActivationFallbackInfo{
   780  								FastFallbackAttempted:      false,
   781  								FallbackVersion:            3,
   782  								CanFastFallback:            false,
   783  								SteadyStateTime:            1666873734,
   784  								FastFallbackExpirationTime: 1666877334,
   785  							},
   786  							IncludeID:      "inc_12345",
   787  							IncludeName:    "tfp_test1",
   788  							IncludeType:    "MICROSERVICES",
   789  							IncludeVersion: 4,
   790  						},
   791  					},
   792  				},
   793  				Activation: IncludeActivation{
   794  					IncludeActivationID: "5e597860-1107-461e-8dbe-4e7526e8dd02",
   795  					Network:             "STAGING",
   796  					ActivationType:      ActivationTypeActivate,
   797  					Status:              ActivationStatusActive,
   798  					SubmitDate:          "2022-10-27T12:27:54Z",
   799  					UpdateDate:          "2022-10-27T12:28:54Z",
   800  					Note:                "DXE test activation",
   801  					NotifyEmails:        []string{"test@example.com"},
   802  					FMAActivationState:  "steady",
   803  					FallbackInfo: &ActivationFallbackInfo{
   804  						FastFallbackAttempted:      false,
   805  						FallbackVersion:            3,
   806  						CanFastFallback:            false,
   807  						SteadyStateTime:            1666873734,
   808  						FastFallbackExpirationTime: 1666877334,
   809  					},
   810  					IncludeID:      "inc_12345",
   811  					IncludeName:    "tfp_test1",
   812  					IncludeType:    "MICROSERVICES",
   813  					IncludeVersion: 4,
   814  				},
   815  			},
   816  		},
   817  		"500 internal server error": {
   818  			params: GetIncludeActivationRequest{
   819  				IncludeID:    "inc_12345",
   820  				ActivationID: "atv_12345",
   821  			},
   822  			expectedPath:   "/papi/v1/includes/inc_12345/activations/atv_12345",
   823  			responseStatus: http.StatusInternalServerError,
   824  			responseBody: `
   825  				{
   826  					"type": "internal_error",
   827  				   "title": "Internal Server Error",
   828  				   "detail": "Error getting include",
   829  				   "status": 500
   830  				}`,
   831  			withError: &Error{
   832  				Type:       "internal_error",
   833  				Title:      "Internal Server Error",
   834  				Detail:     "Error getting include",
   835  				StatusCode: http.StatusInternalServerError,
   836  			},
   837  		},
   838  		"validation error - missing include id": {
   839  			params: GetIncludeActivationRequest{
   840  				ActivationID: "atv_12345",
   841  			},
   842  			withError: ErrStructValidation,
   843  		},
   844  		"validation error - activation id": {
   845  			params: GetIncludeActivationRequest{
   846  				IncludeID: "inc_12345",
   847  			},
   848  			withError: ErrStructValidation,
   849  		},
   850  	}
   851  	for name, test := range tests {
   852  		t.Run(name, func(t *testing.T) {
   853  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   854  				assert.Equal(t, test.expectedPath, r.URL.String())
   855  				assert.Equal(t, http.MethodGet, r.Method)
   856  				w.WriteHeader(test.responseStatus)
   857  				_, err := w.Write([]byte(test.responseBody))
   858  				assert.NoError(t, err)
   859  			}))
   860  			client := mockAPIClient(t, mockServer)
   861  			result, err := client.GetIncludeActivation(context.Background(), test.params)
   862  			if test.withError != nil {
   863  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   864  				return
   865  			}
   866  			require.NoError(t, err)
   867  			assert.Equal(t, test.expectedResponse, result)
   868  		})
   869  	}
   870  }
   871  
   872  func TestListIncludeActivations(t *testing.T) {
   873  	tests := map[string]struct {
   874  		params           ListIncludeActivationsRequest
   875  		responseStatus   int
   876  		responseBody     string
   877  		expectedPath     string
   878  		expectedResponse *ListIncludeActivationsResponse
   879  		withError        error
   880  	}{
   881  		"200 List include activations": {
   882  			params: ListIncludeActivationsRequest{
   883  				IncludeID:  "inc_12345",
   884  				ContractID: "test_contract",
   885  				GroupID:    "test_group",
   886  			},
   887  			expectedPath:   "/papi/v1/includes/inc_12345/activations?contractId=test_contract&groupId=test_group",
   888  			responseStatus: http.StatusOK,
   889  			responseBody: `
   890  {
   891      "accountId": "test_account",
   892      "contractId": "test_contract",
   893      "groupId": "test_group",
   894      "activations": {
   895          "items": [
   896              {
   897                  "activationId": "atv_12344",
   898                  "network": "STAGING",
   899                  "activationType": "ACTIVATE",
   900                  "status": "ACTIVE",
   901                  "submitDate": "2022-10-27T12:27:54Z",
   902                  "updateDate": "2022-10-27T12:28:54Z",
   903                  "note": "test activation",
   904                  "notifyEmails": [
   905                      "test@example.com"
   906                  ],
   907                  "fmaActivationState": "steady",
   908                  "fallbackInfo": {
   909                      "fastFallbackAttempted": false,
   910                      "fallbackVersion": 3,
   911                      "canFastFallback": false,
   912                      "steadyStateTime": 1666873734,
   913                      "fastFallbackExpirationTime": 1666877334,
   914                      "fastFallbackRecoveryState": null
   915                  },
   916                  "includeId": "inc_12345",
   917                  "includeName": "tfp_test1",
   918                  "includeType": "MICROSERVICES",
   919                  "includeVersion": 4
   920              },
   921              {
   922                  "activationId": "atv_12343",
   923                  "network": "STAGING",
   924                  "activationType": "ACTIVATE",
   925                  "status": "ACTIVE",
   926                  "submitDate": "2022-10-27T11:21:40Z",
   927                  "updateDate": "2022-10-27T11:22:54Z",
   928                  "note": "test activation",
   929                  "notifyEmails": [
   930                      "test@example.com"
   931                  ],
   932                  "fmaActivationState": "steady",
   933                  "fallbackInfo": {
   934                      "fastFallbackAttempted": false,
   935                      "fallbackVersion": 4,
   936                      "canFastFallback": false,
   937                      "steadyStateTime": 1666869774,
   938                      "fastFallbackExpirationTime": 1666873374,
   939                      "fastFallbackRecoveryState": null
   940                  },
   941                  "includeId": "inc_12345",
   942                  "includeName": "tfp_test1",
   943                  "includeType": "MICROSERVICES",
   944                  "includeVersion": 3
   945              },
   946              {
   947                  "activationId": "atv_12343",
   948                  "network": "STAGING",
   949                  "activationType": "DEACTIVATE",
   950                  "status": "ACTIVE",
   951                  "submitDate": "2022-10-26T12:41:58Z",
   952                  "updateDate": "2022-10-26T13:03:04Z",
   953                  "note": "test activation",
   954                  "notifyEmails": [
   955                      "test@example.com"
   956                  ],
   957                  "includeId": "inc_12345",
   958                  "includeName": "tfp_test1",
   959                  "includeType": "MICROSERVICES",
   960                  "includeVersion": 3
   961              },
   962              {
   963                  "activationId": "atv_12342",
   964                  "network": "STAGING",
   965                  "activationType": "ACTIVATE",
   966                  "status": "ACTIVE",
   967                  "submitDate": "2022-10-26T12:37:49Z",
   968                  "updateDate": "2022-10-26T12:38:59Z",
   969                  "note": "test activation",
   970                  "notifyEmails": [
   971                      "test@example.com"
   972                  ],
   973                  "fmaActivationState": "steady",
   974                  "fallbackInfo": {
   975                      "fastFallbackAttempted": false,
   976                      "fallbackVersion": 4,
   977                      "canFastFallback": false,
   978                      "steadyStateTime": 1666787939,
   979                      "fastFallbackExpirationTime": 1666791539,
   980                      "fastFallbackRecoveryState": null
   981                  },
   982                  "includeId": "inc_12345",
   983                  "includeName": "tfp_test1",
   984                  "includeType": "MICROSERVICES",
   985                  "includeVersion": 2
   986              },
   987              {
   988                  "activationId": "atv_12341",
   989                  "network": "STAGING",
   990                  "activationType": "ACTIVATE",
   991                  "status": "ACTIVE",
   992                  "submitDate": "2022-08-17T09:13:18Z",
   993                  "updateDate": "2022-08-17T09:15:35Z",
   994                  "note": "test activation",
   995                  "notifyEmails": [
   996                      "test@example.com"
   997                  ],
   998                  "fmaActivationState": "steady",
   999                  "fallbackInfo": {
  1000                      "fastFallbackAttempted": false,
  1001                      "fallbackVersion": 4,
  1002                      "canFastFallback": false,
  1003                      "steadyStateTime": 1660727735,
  1004                      "fastFallbackExpirationTime": 1660731335,
  1005                      "fastFallbackRecoveryState": null
  1006                  },
  1007                  "includeId": "inc_12345",
  1008                  "includeName": "tfp_test1",
  1009                  "includeType": "MICROSERVICES",
  1010                  "includeVersion": 1
  1011              }
  1012          ]
  1013      }
  1014  }`,
  1015  			expectedResponse: &ListIncludeActivationsResponse{
  1016  				AccountID:  "test_account",
  1017  				ContractID: "test_contract",
  1018  				GroupID:    "test_group",
  1019  				Activations: IncludeActivationsRes{
  1020  					Items: []IncludeActivation{
  1021  						{
  1022  							ActivationID:       "atv_12344",
  1023  							Network:            "STAGING",
  1024  							ActivationType:     ActivationTypeActivate,
  1025  							Status:             ActivationStatusActive,
  1026  							SubmitDate:         "2022-10-27T12:27:54Z",
  1027  							UpdateDate:         "2022-10-27T12:28:54Z",
  1028  							Note:               "test activation",
  1029  							NotifyEmails:       []string{"test@example.com"},
  1030  							FMAActivationState: "steady",
  1031  							FallbackInfo: &ActivationFallbackInfo{
  1032  								FastFallbackAttempted:      false,
  1033  								FallbackVersion:            3,
  1034  								CanFastFallback:            false,
  1035  								SteadyStateTime:            1666873734,
  1036  								FastFallbackExpirationTime: 1666877334,
  1037  							},
  1038  							IncludeID:      "inc_12345",
  1039  							IncludeName:    "tfp_test1",
  1040  							IncludeType:    "MICROSERVICES",
  1041  							IncludeVersion: 4,
  1042  						},
  1043  						{
  1044  							ActivationID:       "atv_12343",
  1045  							Network:            "STAGING",
  1046  							ActivationType:     ActivationTypeActivate,
  1047  							Status:             ActivationStatusActive,
  1048  							SubmitDate:         "2022-10-27T11:21:40Z",
  1049  							UpdateDate:         "2022-10-27T11:22:54Z",
  1050  							Note:               "test activation",
  1051  							NotifyEmails:       []string{"test@example.com"},
  1052  							FMAActivationState: "steady",
  1053  							FallbackInfo: &ActivationFallbackInfo{
  1054  								FastFallbackAttempted:      false,
  1055  								FallbackVersion:            4,
  1056  								CanFastFallback:            false,
  1057  								SteadyStateTime:            1666869774,
  1058  								FastFallbackExpirationTime: 1666873374,
  1059  							},
  1060  							IncludeID:      "inc_12345",
  1061  							IncludeName:    "tfp_test1",
  1062  							IncludeType:    "MICROSERVICES",
  1063  							IncludeVersion: 3,
  1064  						},
  1065  						{
  1066  							ActivationID:   "atv_12343",
  1067  							Network:        "STAGING",
  1068  							ActivationType: ActivationTypeDeactivate,
  1069  							Status:         ActivationStatusActive,
  1070  							SubmitDate:     "2022-10-26T12:41:58Z",
  1071  							UpdateDate:     "2022-10-26T13:03:04Z",
  1072  							Note:           "test activation",
  1073  							NotifyEmails:   []string{"test@example.com"},
  1074  							IncludeID:      "inc_12345",
  1075  							IncludeName:    "tfp_test1",
  1076  							IncludeType:    "MICROSERVICES",
  1077  							IncludeVersion: 3,
  1078  						},
  1079  						{
  1080  							ActivationID:       "atv_12342",
  1081  							Network:            "STAGING",
  1082  							ActivationType:     ActivationTypeActivate,
  1083  							Status:             ActivationStatusActive,
  1084  							SubmitDate:         "2022-10-26T12:37:49Z",
  1085  							UpdateDate:         "2022-10-26T12:38:59Z",
  1086  							Note:               "test activation",
  1087  							NotifyEmails:       []string{"test@example.com"},
  1088  							FMAActivationState: "steady",
  1089  							FallbackInfo: &ActivationFallbackInfo{
  1090  								FastFallbackAttempted:      false,
  1091  								FallbackVersion:            4,
  1092  								CanFastFallback:            false,
  1093  								SteadyStateTime:            1666787939,
  1094  								FastFallbackExpirationTime: 1666791539,
  1095  							},
  1096  							IncludeID:      "inc_12345",
  1097  							IncludeName:    "tfp_test1",
  1098  							IncludeType:    "MICROSERVICES",
  1099  							IncludeVersion: 2,
  1100  						},
  1101  						{
  1102  							ActivationID:       "atv_12341",
  1103  							Network:            "STAGING",
  1104  							ActivationType:     ActivationTypeActivate,
  1105  							Status:             ActivationStatusActive,
  1106  							SubmitDate:         "2022-08-17T09:13:18Z",
  1107  							UpdateDate:         "2022-08-17T09:15:35Z",
  1108  							Note:               "test activation",
  1109  							NotifyEmails:       []string{"test@example.com"},
  1110  							FMAActivationState: "steady",
  1111  							FallbackInfo: &ActivationFallbackInfo{
  1112  								FastFallbackAttempted:      false,
  1113  								FallbackVersion:            4,
  1114  								CanFastFallback:            false,
  1115  								SteadyStateTime:            1660727735,
  1116  								FastFallbackExpirationTime: 1660731335,
  1117  							},
  1118  							IncludeID:      "inc_12345",
  1119  							IncludeName:    "tfp_test1",
  1120  							IncludeType:    "MICROSERVICES",
  1121  							IncludeVersion: 1,
  1122  						},
  1123  					},
  1124  				},
  1125  			},
  1126  		},
  1127  		"500 internal server error": {
  1128  			params: ListIncludeActivationsRequest{
  1129  				IncludeID:  "inc_12345",
  1130  				ContractID: "test_contract",
  1131  				GroupID:    "test_group",
  1132  			},
  1133  			expectedPath:   "/papi/v1/includes/inc_12345/activations?contractId=test_contract&groupId=test_group",
  1134  			responseStatus: http.StatusInternalServerError,
  1135  			responseBody: `
  1136  				{
  1137  					"type": "internal_error",
  1138  				   "title": "Internal Server Error",
  1139  				   "detail": "Error getting include",
  1140  				   "status": 500
  1141  				}`,
  1142  			withError: &Error{
  1143  				Type:       "internal_error",
  1144  				Title:      "Internal Server Error",
  1145  				Detail:     "Error getting include",
  1146  				StatusCode: http.StatusInternalServerError,
  1147  			},
  1148  		},
  1149  		"validation error - missing include id": {
  1150  			params: ListIncludeActivationsRequest{
  1151  				ContractID: "test_contract",
  1152  				GroupID:    "test_group",
  1153  			},
  1154  			withError: ErrStructValidation,
  1155  		},
  1156  		"validation error - contract id": {
  1157  			params: ListIncludeActivationsRequest{
  1158  				IncludeID: "inc_12345",
  1159  				GroupID:   "test_group",
  1160  			},
  1161  			withError: ErrStructValidation,
  1162  		},
  1163  		"validation error - group id": {
  1164  			params: ListIncludeActivationsRequest{
  1165  				IncludeID:  "inc_12345",
  1166  				ContractID: "test_contract",
  1167  			},
  1168  			withError: ErrStructValidation,
  1169  		},
  1170  	}
  1171  	for name, test := range tests {
  1172  		t.Run(name, func(t *testing.T) {
  1173  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1174  				assert.Equal(t, test.expectedPath, r.URL.String())
  1175  				assert.Equal(t, http.MethodGet, r.Method)
  1176  				w.WriteHeader(test.responseStatus)
  1177  				_, err := w.Write([]byte(test.responseBody))
  1178  				assert.NoError(t, err)
  1179  			}))
  1180  			client := mockAPIClient(t, mockServer)
  1181  			result, err := client.ListIncludeActivations(context.Background(), test.params)
  1182  			if test.withError != nil {
  1183  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
  1184  				return
  1185  			}
  1186  			require.NoError(t, err)
  1187  			assert.Equal(t, test.expectedResponse, result)
  1188  		})
  1189  	}
  1190  }