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