github.com/akamai/AkamaiOPEN-edgegrid-golang/v4@v4.1.0/pkg/cps/enrollments_test.go (about)

     1  package cps
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestListEnrollments(t *testing.T) {
    15  	tests := map[string]struct {
    16  		params           ListEnrollmentsRequest
    17  		responseStatus   int
    18  		responseBody     string
    19  		expectedPath     string
    20  		expectedHeaders  map[string]string
    21  		expectedResponse *ListEnrollmentsResponse
    22  		withError        func(*testing.T, error)
    23  	}{
    24  		"200 OK": {
    25  			params:         ListEnrollmentsRequest{ContractID: "Contract-123"},
    26  			responseStatus: http.StatusOK,
    27  			responseBody: ` 
    28  {"enrollments":[ {
    29    "location" : "/cps-api/enrollments/1",
    30    "ra" : "third-party",
    31    "validationType" : "third-party",
    32    "certificateType" : "third-party",
    33    "certificateChainType" : "default",
    34    "networkConfiguration" : {
    35      "geography" : "core",
    36      "secureNetwork" : "standard-tls",
    37      "mustHaveCiphers" : "ak-akamai-2020q1",
    38      "preferredCiphers" : "ak-akamai-2020q1",
    39      "disallowedTlsVersions" : [ "TLSv1", "TLSv1_1" ],
    40      "sniOnly" : true,
    41      "quicEnabled" : false,
    42      "dnsNameSettings" : {
    43        "cloneDnsNames" : true,
    44        "dnsNames" : [ "res-sqa2-3pss-4111-10-1-3CV382-ui.com", "san1.res-sqa2-3pss-4111-10-1-3CV382-ui.com" ]
    45      },
    46      "ocspStapling" : "on",
    47      "clientMutualAuthentication" : null
    48    },
    49    "signatureAlgorithm" : null,
    50    "changeManagement" : false,
    51    "csr" : {
    52      "cn" : "res-sqa2-3pss-4111-10-1-3CV382-ui.com",
    53      "c" : "IN",
    54      "st" : "KA",
    55      "l" : "BLR",
    56      "o" : "Akamai",
    57      "ou" : "ETG",
    58      "sans" : [ "san1.res-sqa2-3pss-4111-10-1-3CV382-ui.com", "res-sqa2-3pss-4111-10-1-3CV382-ui.com" ],
    59      "preferredTrustChain" : null
    60    },
    61    "org" : {
    62      "name" : "Akamai",
    63      "addressLineOne" : "EGL",
    64      "addressLineTwo" : "",
    65      "city" : "BLR",
    66      "region" : "KA",
    67      "postalCode" : "71",
    68      "country" : "IN",
    69      "phone" : "12"
    70    },
    71    "adminContact" : {
    72      "firstName" : "R1",
    73      "lastName" : "D1",
    74      "phone" : "4356",
    75      "email" : "rd1@akamai.com",
    76      "addressLineOne" : "EGL",
    77      "addressLineTwo" : "",
    78      "city" : "BLR",
    79      "country" : "IN",
    80      "organizationName" : "Akamai",
    81      "postalCode" : "71",
    82      "region" : "KA",
    83      "title" : null
    84    },
    85    "techContact" : {
    86      "firstName" : "R2",
    87      "lastName" : "D2",
    88      "phone" : "6456",
    89      "email" : "rd2@akamai.com",
    90      "addressLineOne" : "150 Broadway",
    91      "addressLineTwo" : "",
    92      "city" : "Cambridge",
    93      "country" : "US",
    94      "organizationName" : "Akamai Technologies",
    95      "postalCode" : "02142",
    96      "region" : "Massachusetts",
    97      "title" : null
    98    },
    99    "thirdParty" : {
   100      "excludeSans" : true
   101    },
   102    "enableMultiStackedCertificates" : false,
   103    "autoRenewalStartTime" : null,
   104    "pendingChanges": [
   105      {
   106       "location": "/cps-api/enrollments/1/changes/2",
   107       "changeType": "new-certificate"
   108      }
   109    ],
   110    "maxAllowedSanNames" : 100,
   111    "maxAllowedWildcardSanNames" : 100
   112  }, {
   113    "location" : "/cps-api/enrollments/2",
   114    "ra" : "lets-encrypt",
   115    "validationType" : "dv",
   116    "certificateType" : "san",
   117    "certificateChainType" : "default",
   118    "networkConfiguration" : {
   119      "geography" : "core",
   120      "secureNetwork" : "enhanced-tls",
   121      "mustHaveCiphers" : "ak-akamai-default-2017q3",
   122      "preferredCiphers" : "ak-akamai-default-2017q3",
   123      "disallowedTlsVersions" : [ "TLSv1", "TLSv1_1" ],
   124      "sniOnly" : true,
   125      "quicEnabled" : false,
   126      "dnsNameSettings" : {
   127        "cloneDnsNames" : true,
   128        "dnsNames" : [ "jmm.20210504-dsa12.faden.me" ]
   129      },
   130      "ocspStapling" : "on",
   131      "clientMutualAuthentication" : null
   132    },
   133    "signatureAlgorithm" : "SHA-256",
   134    "changeManagement" : false,
   135    "csr" : {
   136      "cn" : "jmm.20210504-dsa12.faden.me",
   137      "c" : "US",
   138      "st" : "MA",
   139      "l" : "Cambridge",
   140      "o" : "Akamai Technologies, Inc.",
   141      "ou" : null,
   142      "sans" : [ "jmm.20210504-dsa12.faden.me" ],
   143      "preferredTrustChain" : null
   144    },
   145    "org" : {
   146      "name" : "Akamai Technologies, Inc.",
   147      "addressLineOne" : "150 Broadway",
   148      "addressLineTwo" : null,
   149      "city" : "Cambridge",
   150      "region" : "MA",
   151      "postalCode" : "02142",
   152      "country" : "US",
   153      "phone" : "617-444-3000"
   154    },
   155    "adminContact" : {
   156      "firstName" : "R3",
   157      "lastName" : "D3",
   158      "phone" : "8577068086",
   159      "email" : "rd3@nomail-akamai.com",
   160      "addressLineOne" : null,
   161      "addressLineTwo" : null,
   162      "city" : null,
   163      "country" : null,
   164      "organizationName" : null,
   165      "postalCode" : null,
   166      "region" : null,
   167      "title" : null
   168    },
   169    "techContact" : {
   170      "firstName" : "R4",
   171      "lastName" : "D4",
   172      "phone" : "617-444-3000",
   173      "email" : "rd4@akamai.com",
   174      "addressLineOne" : null,
   175      "addressLineTwo" : null,
   176      "city" : null,
   177      "country" : null,
   178      "organizationName" : null,
   179      "postalCode" : null,
   180      "region" : null,
   181      "title" : null
   182    },
   183    "thirdParty" : null,
   184    "enableMultiStackedCertificates" : false,
   185    "autoRenewalStartTime" : null,
   186    "pendingChanges": [
   187      {
   188       "location": "/cps-api/enrollments/2/changes/2",
   189       "changeType": "new-certificate"
   190      }
   191    ],
   192    "maxAllowedSanNames" : 100,
   193    "maxAllowedWildcardSanNames" : 25
   194  },
   195  {
   196    "location" : "/cps-api/enrollments/3",
   197    "ra" : "third-party",
   198    "validationType" : "third-party",
   199    "certificateType" : "third-party",
   200    "certificateChainType" : "default",
   201    "networkConfiguration" : {
   202      "geography" : "core",
   203      "secureNetwork" : "enhanced-tls",
   204      "mustHaveCiphers" : "ak-akamai-2020q1",
   205      "preferredCiphers" : "ak-akamai-2020q1",
   206      "disallowedTlsVersions" : [ "TLSv1", "TLSv1_1" ],
   207      "sniOnly" : true,
   208      "quicEnabled" : false,
   209      "dnsNameSettings" : {
   210        "cloneDnsNames" : true,
   211        "dnsNames" : [ "san1-submishr-ghj1-mediatest.com", "san2-submishr-ghj1-mediatest.com", "submishr-ghj1-mediatest.com" ]
   212      },
   213      "ocspStapling" : "on",
   214      "clientMutualAuthentication" : null
   215    },
   216    "signatureAlgorithm" : null,
   217    "changeManagement" : false,
   218    "csr" : {
   219      "cn" : "submishr-ghj1-mediatest.com",
   220      "c" : "IN",
   221      "st" : "karnataka",
   222      "l" : "Bangalore",
   223      "o" : "Akamai",
   224      "ou" : "",
   225      "sans" : [ "san1-submishr-ghj1-mediatest.com", "san2-submishr-ghj1-mediatest.com", "submishr-ghj1-mediatest.com" ]
   226    },
   227    "org" : {
   228      "name" : "Akamai",
   229      "addressLineOne" : "EGL",
   230      "addressLineTwo" : "Bangalore",
   231      "city" : "Bangalore",
   232      "region" : "karnataka",
   233      "postalCode" : "560071",
   234      "country" : "IN",
   235      "phone" : "34234353453"
   236    },
   237    "adminContact" : {
   238      "firstName" : "DevQA",
   239      "lastName" : "Tester",
   240      "phone" : "6173000033",
   241      "email" : "devqa@tester.com",
   242      "addressLineOne" : null,
   243      "addressLineTwo" : null,
   244      "city" : null,
   245      "country" : null,
   246      "organizationName" : null,
   247      "postalCode" : null,
   248      "region" : null,
   249      "title" : null
   250    },
   251    "techContact" : {
   252      "firstName" : "John",
   253      "lastName" : "Doe",
   254      "phone" : "111000111",
   255      "email" : "john@example.com",
   256      "addressLineOne" : null,
   257      "addressLineTwo" : null,
   258      "city" : null,
   259      "country" : null,
   260      "organizationName" : null,
   261      "postalCode" : null,
   262      "region" : null,
   263      "title" : null
   264    },
   265    "thirdParty" : {
   266      "excludeSans" : false
   267    },
   268    "enableMultiStackedCertificates" : true,
   269    "autoRenewalStartTime" : null,
   270    "pendingChanges": [
   271      {
   272       "location": "/cps-api/enrollments/3/changes/30",
   273       "changeType": "new-certificate"
   274      }
   275    ],
   276    "maxAllowedSanNames" : 100,
   277    "maxAllowedWildcardSanNames" : 100
   278  }
   279  ]}`,
   280  			expectedPath: "/cps/v2/enrollments?contractId=Contract-123",
   281  			expectedHeaders: map[string]string{
   282  				"Accept": "application/vnd.akamai.cps.enrollments.v11+json",
   283  			},
   284  			expectedResponse: &ListEnrollmentsResponse{Enrollments: []Enrollment{
   285  				{
   286  					AdminContact: &Contact{
   287  						AddressLineOne:   "EGL",
   288  						City:             "BLR",
   289  						Country:          "IN",
   290  						Email:            "rd1@akamai.com",
   291  						FirstName:        "R1",
   292  						LastName:         "D1",
   293  						OrganizationName: "Akamai",
   294  						Phone:            "4356",
   295  						PostalCode:       "71",
   296  						Region:           "KA",
   297  					},
   298  					CertificateChainType: "default",
   299  					CertificateType:      "third-party",
   300  					ChangeManagement:     false,
   301  					CSR: &CSR{
   302  						C:  "IN",
   303  						CN: "res-sqa2-3pss-4111-10-1-3CV382-ui.com",
   304  						L:  "BLR",
   305  						O:  "Akamai",
   306  						OU: "ETG",
   307  						SANS: []string{"san1.res-sqa2-3pss-4111-10-1-3CV382-ui.com",
   308  							"res-sqa2-3pss-4111-10-1-3CV382-ui.com"},
   309  						ST: "KA",
   310  					},
   311  					EnableMultiStackedCertificates: false,
   312  					Location:                       "/cps-api/enrollments/1",
   313  					MaxAllowedSanNames:             100,
   314  					MaxAllowedWildcardSanNames:     100,
   315  					NetworkConfiguration: &NetworkConfiguration{
   316  						DisallowedTLSVersions: []string{"TLSv1", "TLSv1_1"},
   317  						DNSNameSettings: &DNSNameSettings{
   318  							CloneDNSNames: true,
   319  							DNSNames: []string{"res-sqa2-3pss-4111-10-1-3CV382-ui.com",
   320  								"san1.res-sqa2-3pss-4111-10-1-3CV382-ui.com"},
   321  						},
   322  						Geography:        "core",
   323  						MustHaveCiphers:  "ak-akamai-2020q1",
   324  						OCSPStapling:     "on",
   325  						PreferredCiphers: "ak-akamai-2020q1",
   326  						QuicEnabled:      false,
   327  						SecureNetwork:    "standard-tls",
   328  						SNIOnly:          true,
   329  					},
   330  					Org: &Org{
   331  						AddressLineOne: "EGL",
   332  						City:           "BLR",
   333  						Country:        "IN",
   334  						Name:           "Akamai",
   335  						Phone:          "12",
   336  						PostalCode:     "71",
   337  						Region:         "KA",
   338  					},
   339  					PendingChanges: []PendingChange{
   340  						{
   341  							Location:   "/cps-api/enrollments/1/changes/2",
   342  							ChangeType: "new-certificate",
   343  						},
   344  					},
   345  					RA: "third-party",
   346  					TechContact: &Contact{
   347  						AddressLineOne:   "150 Broadway",
   348  						City:             "Cambridge",
   349  						Country:          "US",
   350  						Email:            "rd2@akamai.com",
   351  						FirstName:        "R2",
   352  						LastName:         "D2",
   353  						OrganizationName: "Akamai Technologies",
   354  						Phone:            "6456",
   355  						PostalCode:       "02142",
   356  						Region:           "Massachusetts",
   357  					},
   358  					ThirdParty:     &ThirdParty{ExcludeSANS: true},
   359  					ValidationType: "third-party",
   360  				},
   361  				{
   362  					AdminContact: &Contact{
   363  						Email:     "rd3@nomail-akamai.com",
   364  						FirstName: "R3",
   365  						LastName:  "D3",
   366  						Phone:     "8577068086",
   367  					},
   368  					CertificateChainType: "default",
   369  					CertificateType:      "san",
   370  					ChangeManagement:     false,
   371  					CSR: &CSR{
   372  						C:    "US",
   373  						CN:   "jmm.20210504-dsa12.faden.me",
   374  						L:    "Cambridge",
   375  						O:    "Akamai Technologies, Inc.",
   376  						SANS: []string{"jmm.20210504-dsa12.faden.me"},
   377  						ST:   "MA",
   378  					},
   379  					EnableMultiStackedCertificates: false,
   380  					Location:                       "/cps-api/enrollments/2",
   381  					MaxAllowedSanNames:             100,
   382  					MaxAllowedWildcardSanNames:     25,
   383  					NetworkConfiguration: &NetworkConfiguration{
   384  						DisallowedTLSVersions: []string{"TLSv1", "TLSv1_1"},
   385  						DNSNameSettings: &DNSNameSettings{
   386  							CloneDNSNames: true,
   387  							DNSNames:      []string{"jmm.20210504-dsa12.faden.me"},
   388  						},
   389  						Geography:        "core",
   390  						MustHaveCiphers:  "ak-akamai-default-2017q3",
   391  						OCSPStapling:     "on",
   392  						PreferredCiphers: "ak-akamai-default-2017q3",
   393  						QuicEnabled:      false,
   394  						SecureNetwork:    "enhanced-tls",
   395  						SNIOnly:          true,
   396  					},
   397  					Org: &Org{
   398  						AddressLineOne: "150 Broadway",
   399  						City:           "Cambridge",
   400  						Country:        "US",
   401  						Name:           "Akamai Technologies, Inc.",
   402  						Phone:          "617-444-3000",
   403  						PostalCode:     "02142",
   404  						Region:         "MA",
   405  					},
   406  					PendingChanges: []PendingChange{
   407  						{
   408  							Location:   "/cps-api/enrollments/2/changes/2",
   409  							ChangeType: "new-certificate",
   410  						},
   411  					},
   412  					RA: "lets-encrypt",
   413  					TechContact: &Contact{
   414  						Email:     "rd4@akamai.com",
   415  						FirstName: "R4",
   416  						LastName:  "D4",
   417  						Phone:     "617-444-3000",
   418  					},
   419  					ValidationType:     "dv",
   420  					SignatureAlgorithm: "SHA-256",
   421  				},
   422  				{
   423  					AdminContact: &Contact{
   424  						Email:     "devqa@tester.com",
   425  						FirstName: "DevQA",
   426  						LastName:  "Tester",
   427  						Phone:     "6173000033",
   428  					},
   429  					CertificateChainType: "default",
   430  					CertificateType:      "third-party",
   431  					ChangeManagement:     false,
   432  					CSR: &CSR{
   433  						C:  "IN",
   434  						CN: "submishr-ghj1-mediatest.com",
   435  						L:  "Bangalore",
   436  						O:  "Akamai",
   437  						SANS: []string{
   438  							"san1-submishr-ghj1-mediatest.com",
   439  							"san2-submishr-ghj1-mediatest.com",
   440  							"submishr-ghj1-mediatest.com"},
   441  						ST: "karnataka",
   442  					},
   443  					EnableMultiStackedCertificates: true,
   444  					Location:                       "/cps-api/enrollments/3",
   445  					MaxAllowedSanNames:             100,
   446  					MaxAllowedWildcardSanNames:     100,
   447  					NetworkConfiguration: &NetworkConfiguration{
   448  						DisallowedTLSVersions: []string{"TLSv1", "TLSv1_1"},
   449  						DNSNameSettings: &DNSNameSettings{
   450  							CloneDNSNames: true,
   451  							DNSNames: []string{
   452  								"san1-submishr-ghj1-mediatest.com",
   453  								"san2-submishr-ghj1-mediatest.com",
   454  								"submishr-ghj1-mediatest.com"},
   455  						},
   456  						Geography:        "core",
   457  						MustHaveCiphers:  "ak-akamai-2020q1",
   458  						OCSPStapling:     "on",
   459  						PreferredCiphers: "ak-akamai-2020q1",
   460  						QuicEnabled:      false,
   461  						SecureNetwork:    "enhanced-tls",
   462  						SNIOnly:          true,
   463  					},
   464  					Org: &Org{
   465  						AddressLineOne: "EGL",
   466  						AddressLineTwo: "Bangalore",
   467  						City:           "Bangalore",
   468  						Country:        "IN",
   469  						Name:           "Akamai",
   470  						Phone:          "34234353453",
   471  						PostalCode:     "560071",
   472  						Region:         "karnataka",
   473  					},
   474  					PendingChanges: []PendingChange{
   475  						{
   476  							Location:   "/cps-api/enrollments/3/changes/30",
   477  							ChangeType: "new-certificate",
   478  						},
   479  					},
   480  					RA: "third-party",
   481  					TechContact: &Contact{
   482  						Email:     "john@example.com",
   483  						FirstName: "John",
   484  						LastName:  "Doe",
   485  						Phone:     "111000111",
   486  					},
   487  					ThirdParty:     &ThirdParty{ExcludeSANS: false},
   488  					ValidationType: "third-party",
   489  				},
   490  			}},
   491  		},
   492  		"500 internal server error": {
   493  			params:         ListEnrollmentsRequest{ContractID: "1"},
   494  			responseStatus: http.StatusInternalServerError,
   495  			responseBody: `
   496  {
   497  	"type": "internal_error",
   498     "title": "Internal Server Error",
   499     "detail": "Error making request",
   500     "status": 500
   501  }`,
   502  			expectedPath: "/cps/v2/enrollments?contractId=1",
   503  			expectedHeaders: map[string]string{
   504  				"Accept": "application/vnd.akamai.cps.enrollments.v11+json",
   505  			},
   506  			withError: func(t *testing.T, err error) {
   507  				want := &Error{
   508  					Type:       "internal_error",
   509  					Title:      "Internal Server Error",
   510  					Detail:     "Error making request",
   511  					StatusCode: http.StatusInternalServerError,
   512  				}
   513  				assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err)
   514  			},
   515  		},
   516  	}
   517  
   518  	for name, test := range tests {
   519  		t.Run(name, func(t *testing.T) {
   520  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   521  				assert.Equal(t, test.expectedPath, r.URL.String())
   522  				assert.Equal(t, http.MethodGet, r.Method)
   523  				for k, v := range test.expectedHeaders {
   524  					assert.Equal(t, v, r.Header.Get(k))
   525  				}
   526  				w.WriteHeader(test.responseStatus)
   527  				_, err := w.Write([]byte(test.responseBody))
   528  				assert.NoError(t, err)
   529  			}))
   530  			client := mockAPIClient(t, mockServer)
   531  			result, err := client.ListEnrollments(context.Background(), test.params)
   532  			if test.withError != nil {
   533  				test.withError(t, err)
   534  				return
   535  			}
   536  			require.NoError(t, err)
   537  			assert.Equal(t, test.expectedResponse, result)
   538  		})
   539  	}
   540  }
   541  
   542  func TestGetEnrollment(t *testing.T) {
   543  	tests := map[string]struct {
   544  		params           GetEnrollmentRequest
   545  		responseStatus   int
   546  		responseBody     string
   547  		expectedPath     string
   548  		expectedHeaders  map[string]string
   549  		expectedResponse *Enrollment
   550  		withError        func(*testing.T, error)
   551  	}{
   552  		"200 OK": {
   553  			params:         GetEnrollmentRequest{EnrollmentID: 1},
   554  			responseStatus: http.StatusOK,
   555  			responseBody: `
   556  {
   557      "location": "/cps-api/enrollments/1",
   558      "ra": "third-party",
   559      "validationType": "third-party",
   560      "certificateType": "third-party",
   561      "certificateChainType": "default",
   562      "networkConfiguration": {
   563          "geography": "core",
   564          "secureNetwork": "enhanced-tls",
   565          "mustHaveCiphers": "ak-akamai-default",
   566          "preferredCiphers": "ak-akamai-default-interim",
   567          "disallowedTlsVersions": [
   568              "TLSv1"
   569          ],
   570          "sniOnly": true,
   571          "quicEnabled": false,
   572          "dnsNameSettings": {
   573              "cloneDnsNames": false,
   574              "dnsNames": [
   575                  "san1.example.com"
   576              ]
   577          },
   578          "ocspStapling": "on",
   579          "clientMutualAuthentication": {
   580              "setId": "Custom_CPS-6134b_B-3-1AHBENT.xml",
   581              "authenticationOptions": {
   582                  "sendCaListToClient": false,
   583                  "ocsp": {
   584                      "enabled": false
   585                  }
   586              }
   587          }
   588      },
   589      "signatureAlgorithm": null,
   590      "changeManagement": true,
   591      "csr": {
   592          "cn": "www.example.com",
   593          "c": "US",
   594          "st": "MA",
   595          "l": "Cambridge",
   596          "o": "Akamai",
   597          "ou": "WebEx",
   598          "sans": [
   599              "www.example.com"
   600          ],
   601  		"preferredTrustChain": null
   602      },
   603      "org": {
   604          "name": "Akamai Technologies",
   605          "addressLineOne": "150 Broadway",
   606          "addressLineTwo": null,
   607          "city": "Cambridge",
   608          "region": "MA",
   609          "postalCode": "02142",
   610          "country": "US",
   611          "phone": "617-555-0111"
   612      },
   613      "adminContact": {
   614          "firstName": "R1",
   615          "lastName": "D1",
   616          "phone": "617-555-0111",
   617          "email": "r1d1@akamai.com",
   618          "addressLineOne": "150 Broadway",
   619          "addressLineTwo": null,
   620          "city": "Cambridge",
   621          "country": "US",
   622          "organizationName": "Akamai",
   623          "postalCode": "02142",
   624          "region": "MA",
   625          "title": "Administrator"
   626      },
   627      "techContact": {
   628          "firstName": "R2",
   629          "lastName": "D2",
   630          "phone": "617-555-0111",
   631          "email": "r2d2@akamai.com",
   632          "addressLineOne": "150 Broadway",
   633          "addressLineTwo": null,
   634          "city": "Cambridge",
   635          "country": "US",
   636          "organizationName": "Akamai",
   637          "postalCode": "02142",
   638          "region": "MA",
   639          "title": "Technical Engineer"
   640      },
   641      "thirdParty": {
   642          "excludeSans": false
   643      },
   644      "enableMultiStackedCertificates": false,
   645      "autoRenewalStartTime": null,
   646      "pendingChanges": [
   647        {
   648         "location": "/cps-api/enrollments/1/changes/2",
   649         "changeType": "new-certificate"
   650        }
   651      ],
   652      "maxAllowedSanNames": 100,
   653      "maxAllowedWildcardSanNames": 100
   654  }`,
   655  			expectedPath: "/cps/v2/enrollments/1",
   656  			expectedHeaders: map[string]string{
   657  				"Accept": "application/vnd.akamai.cps.enrollment.v11+json",
   658  			},
   659  			expectedResponse: &Enrollment{
   660  				AdminContact: &Contact{
   661  					AddressLineOne:   "150 Broadway",
   662  					City:             "Cambridge",
   663  					Country:          "US",
   664  					Email:            "r1d1@akamai.com",
   665  					FirstName:        "R1",
   666  					LastName:         "D1",
   667  					OrganizationName: "Akamai",
   668  					Phone:            "617-555-0111",
   669  					PostalCode:       "02142",
   670  					Region:           "MA",
   671  					Title:            "Administrator",
   672  				},
   673  				CertificateChainType: "default",
   674  				CertificateType:      "third-party",
   675  				ChangeManagement:     true,
   676  				CSR: &CSR{
   677  					C:    "US",
   678  					CN:   "www.example.com",
   679  					L:    "Cambridge",
   680  					O:    "Akamai",
   681  					OU:   "WebEx",
   682  					SANS: []string{"www.example.com"},
   683  					ST:   "MA",
   684  				},
   685  				EnableMultiStackedCertificates: false,
   686  				Location:                       "/cps-api/enrollments/1",
   687  				MaxAllowedSanNames:             100,
   688  				MaxAllowedWildcardSanNames:     100,
   689  				NetworkConfiguration: &NetworkConfiguration{
   690  					ClientMutualAuthentication: &ClientMutualAuthentication{
   691  						AuthenticationOptions: &AuthenticationOptions{
   692  							OCSP:               &OCSP{BoolPtr(false)},
   693  							SendCAListToClient: BoolPtr(false),
   694  						},
   695  						SetID: "Custom_CPS-6134b_B-3-1AHBENT.xml",
   696  					},
   697  					DisallowedTLSVersions: []string{"TLSv1"},
   698  					DNSNameSettings: &DNSNameSettings{
   699  						CloneDNSNames: false,
   700  						DNSNames:      []string{"san1.example.com"},
   701  					},
   702  					Geography:        "core",
   703  					MustHaveCiphers:  "ak-akamai-default",
   704  					OCSPStapling:     "on",
   705  					PreferredCiphers: "ak-akamai-default-interim",
   706  					QuicEnabled:      false,
   707  					SecureNetwork:    "enhanced-tls",
   708  					SNIOnly:          true,
   709  				},
   710  				Org: &Org{
   711  					AddressLineOne: "150 Broadway",
   712  					City:           "Cambridge",
   713  					Country:        "US",
   714  					Name:           "Akamai Technologies",
   715  					Phone:          "617-555-0111",
   716  					PostalCode:     "02142",
   717  					Region:         "MA",
   718  				},
   719  				PendingChanges: []PendingChange{
   720  					{
   721  						Location:   "/cps-api/enrollments/1/changes/2",
   722  						ChangeType: "new-certificate",
   723  					},
   724  				},
   725  				RA: "third-party",
   726  				TechContact: &Contact{
   727  					AddressLineOne:   "150 Broadway",
   728  					City:             "Cambridge",
   729  					Country:          "US",
   730  					Email:            "r2d2@akamai.com",
   731  					FirstName:        "R2",
   732  					LastName:         "D2",
   733  					OrganizationName: "Akamai",
   734  					Phone:            "617-555-0111",
   735  					PostalCode:       "02142",
   736  					Region:           "MA",
   737  					Title:            "Technical Engineer",
   738  				},
   739  				ThirdParty:     &ThirdParty{ExcludeSANS: false},
   740  				ValidationType: "third-party",
   741  			},
   742  		},
   743  		"200 OK - DV": {
   744  			params:         GetEnrollmentRequest{EnrollmentID: 1},
   745  			responseStatus: http.StatusOK,
   746  			responseBody: `
   747  {
   748      "id": 1,
   749      "productionSlots": [],
   750      "stagingSlots": [],
   751      "assignedSlots": [
   752          12345
   753      ],
   754      "location": "/cps/v2/enrollments/1",
   755      "ra": "lets-encrypt",
   756      "validationType": "dv",
   757      "certificateType": "san",
   758      "certificateChainType": "default",
   759      "networkConfiguration": {
   760          "geography": "core",
   761          "secureNetwork": "enhanced-tls",
   762          "mustHaveCiphers": "ak-akamai-default",
   763          "preferredCiphers": "ak-akamai-default-interim",
   764          "disallowedTlsVersions": [
   765              "TLSv1"
   766          ],
   767          "sniOnly": true,
   768          "quicEnabled": false,
   769          "dnsNameSettings": {
   770              "cloneDnsNames": false,
   771              "dnsNames": [
   772                  "san1.example.com"
   773              ]
   774          },
   775          "ocspStapling": "on",
   776          "clientMutualAuthentication": {
   777              "setId": "Custom_CPS-6134b_B-3-1AHBENT.xml",
   778              "authenticationOptions": {
   779                  "sendCaListToClient": false,
   780                  "ocsp": {
   781                      "enabled": false
   782                  }
   783              }
   784          }
   785      },
   786      "signatureAlgorithm": "SHA-256",
   787      "changeManagement": true,
   788      "csr": {
   789          "cn": "www.example-test.com",
   790          "c": "US",
   791          "st": "MA",
   792          "l": "Cambridge",
   793          "o": "Akamai",
   794          "ou": "WebEx",
   795          "sans": [
   796              "www.example-test.com"
   797          ],
   798          "preferredTrustChain": "intermediate-a"
   799      },
   800      "org": {
   801          "name": "Akamai Technologies",
   802          "addressLineOne": "1 Address",
   803          "addressLineTwo": null,
   804          "city": "Cambridge",
   805          "region": "MA",
   806          "postalCode": "012345",
   807          "country": "US",
   808          "phone": "555-111-1111"
   809      },
   810      "orgId": null,
   811      "adminContact": {
   812          "firstName": "R1",
   813          "lastName": "D1",
   814          "phone": "617-555-0111",
   815          "email": "r1d1@akamai.com",
   816          "addressLineOne": "150 Broadway",
   817          "addressLineTwo": null,
   818          "city": "Cambridge",
   819          "country": "US",
   820          "organizationName": "Akamai",
   821          "postalCode": "02142",
   822          "region": "MA",
   823          "title": "Administrator"
   824      },
   825      "techContact": {
   826          "firstName": "R2",
   827          "lastName": "D2",
   828          "phone": "617-555-0111",
   829          "email": "r2d2@akamai.com",
   830          "addressLineOne": "150 Broadway",
   831          "addressLineTwo": null,
   832          "city": "Cambridge",
   833          "country": "US",
   834          "organizationName": "Akamai",
   835          "postalCode": "02142",
   836          "region": "MA",
   837          "title": "Technical Engineer"
   838      },
   839      "thirdParty": null,
   840      "enableMultiStackedCertificates": false,
   841      "autoRenewalStartTime": null,
   842      "pendingChanges": [
   843        {
   844         "location": "/cps-api/enrollments/1/changes/1",
   845         "changeType": "new-certificate"
   846        }
   847      ],
   848      "maxAllowedSanNames": 100,
   849      "maxAllowedWildcardSanNames": 25
   850  }`,
   851  			expectedPath: "/cps/v2/enrollments/1",
   852  			expectedHeaders: map[string]string{
   853  				"Accept": "application/vnd.akamai.cps.enrollment.v11+json",
   854  			},
   855  			expectedResponse: &Enrollment{
   856  				AdminContact: &Contact{
   857  					AddressLineOne:   "150 Broadway",
   858  					City:             "Cambridge",
   859  					Country:          "US",
   860  					Email:            "r1d1@akamai.com",
   861  					FirstName:        "R1",
   862  					LastName:         "D1",
   863  					OrganizationName: "Akamai",
   864  					Phone:            "617-555-0111",
   865  					PostalCode:       "02142",
   866  					Region:           "MA",
   867  					Title:            "Administrator",
   868  				},
   869  				CertificateChainType: "default",
   870  				CertificateType:      "san",
   871  				ChangeManagement:     true,
   872  				CSR: &CSR{
   873  					CN: "www.example-test.com",
   874  					C:  "US",
   875  					ST: "MA",
   876  					L:  "Cambridge",
   877  					O:  "Akamai",
   878  					OU: "WebEx",
   879  					SANS: []string{
   880  						"www.example-test.com",
   881  					},
   882  					PreferredTrustChain: "intermediate-a",
   883  				},
   884  				EnableMultiStackedCertificates: false,
   885  				Location:                       "/cps/v2/enrollments/1",
   886  				MaxAllowedSanNames:             100,
   887  				MaxAllowedWildcardSanNames:     25,
   888  				NetworkConfiguration: &NetworkConfiguration{
   889  					ClientMutualAuthentication: &ClientMutualAuthentication{
   890  						AuthenticationOptions: &AuthenticationOptions{
   891  							OCSP:               &OCSP{BoolPtr(false)},
   892  							SendCAListToClient: BoolPtr(false),
   893  						},
   894  						SetID: "Custom_CPS-6134b_B-3-1AHBENT.xml",
   895  					},
   896  					DisallowedTLSVersions: []string{"TLSv1"},
   897  					DNSNameSettings: &DNSNameSettings{
   898  						CloneDNSNames: false,
   899  						DNSNames:      []string{"san1.example.com"},
   900  					},
   901  					Geography:        "core",
   902  					MustHaveCiphers:  "ak-akamai-default",
   903  					OCSPStapling:     "on",
   904  					PreferredCiphers: "ak-akamai-default-interim",
   905  					QuicEnabled:      false,
   906  					SecureNetwork:    "enhanced-tls",
   907  					SNIOnly:          true,
   908  				},
   909  				Org: &Org{
   910  					AddressLineOne: "1 Address",
   911  					City:           "Cambridge",
   912  					Country:        "US",
   913  					Name:           "Akamai Technologies",
   914  					Phone:          "555-111-1111",
   915  					PostalCode:     "012345",
   916  					Region:         "MA",
   917  				},
   918  				PendingChanges: []PendingChange{
   919  					{
   920  						Location:   "/cps-api/enrollments/1/changes/1",
   921  						ChangeType: "new-certificate",
   922  					},
   923  				},
   924  				RA:                 "lets-encrypt",
   925  				SignatureAlgorithm: "SHA-256",
   926  				TechContact: &Contact{
   927  					AddressLineOne:   "150 Broadway",
   928  					City:             "Cambridge",
   929  					Country:          "US",
   930  					Email:            "r2d2@akamai.com",
   931  					FirstName:        "R2",
   932  					LastName:         "D2",
   933  					OrganizationName: "Akamai",
   934  					Phone:            "617-555-0111",
   935  					PostalCode:       "02142",
   936  					Region:           "MA",
   937  					Title:            "Technical Engineer",
   938  				},
   939  				ThirdParty:     nil,
   940  				ValidationType: "dv",
   941  			},
   942  		},
   943  		"500 internal server error": {
   944  			params:         GetEnrollmentRequest{EnrollmentID: 1},
   945  			responseStatus: http.StatusInternalServerError,
   946  			responseBody: `
   947  {
   948  	"type": "internal_error",
   949     "title": "Internal Server Error",
   950     "detail": "Error making request",
   951     "status": 500
   952  }`,
   953  			expectedPath: "/cps/v2/enrollments/1",
   954  			expectedHeaders: map[string]string{
   955  				"Accept": "application/vnd.akamai.cps.enrollment.v11+json",
   956  			},
   957  			withError: func(t *testing.T, err error) {
   958  				want := &Error{
   959  					Type:       "internal_error",
   960  					Title:      "Internal Server Error",
   961  					Detail:     "Error making request",
   962  					StatusCode: http.StatusInternalServerError,
   963  				}
   964  				assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err)
   965  			},
   966  		},
   967  	}
   968  
   969  	for name, test := range tests {
   970  		t.Run(name, func(t *testing.T) {
   971  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   972  				assert.Equal(t, test.expectedPath, r.URL.String())
   973  				assert.Equal(t, http.MethodGet, r.Method)
   974  				for k, v := range test.expectedHeaders {
   975  					assert.Equal(t, v, r.Header.Get(k))
   976  				}
   977  				w.WriteHeader(test.responseStatus)
   978  				_, err := w.Write([]byte(test.responseBody))
   979  				assert.NoError(t, err)
   980  			}))
   981  			client := mockAPIClient(t, mockServer)
   982  			result, err := client.GetEnrollment(context.Background(), test.params)
   983  			if test.withError != nil {
   984  				test.withError(t, err)
   985  				return
   986  			}
   987  			require.NoError(t, err)
   988  			assert.Equal(t, test.expectedResponse, result)
   989  		})
   990  	}
   991  }
   992  
   993  func TestCreateEnrollment(t *testing.T) {
   994  	tests := map[string]struct {
   995  		request          CreateEnrollmentRequest
   996  		responseStatus   int
   997  		responseBody     string
   998  		expectedPath     string
   999  		expectedResponse *CreateEnrollmentResponse
  1000  		withError        error
  1001  	}{
  1002  		"202 accepted": {
  1003  			request: CreateEnrollmentRequest{
  1004  				Enrollment: Enrollment{
  1005  					AdminContact: &Contact{
  1006  						Email: "r1d1@akamai.com",
  1007  					},
  1008  					CertificateType: "third-party",
  1009  					CSR: &CSR{
  1010  						CN: "www.example.com",
  1011  					},
  1012  					NetworkConfiguration: &NetworkConfiguration{},
  1013  					Org:                  &Org{Name: "Akamai"},
  1014  					RA:                   "third-party",
  1015  					TechContact: &Contact{
  1016  						Email: "r2d2@akamai.com",
  1017  					},
  1018  					ValidationType: "third-party",
  1019  				},
  1020  				ContractID:      "ctr-1",
  1021  				DeployNotAfter:  "12-12-2021",
  1022  				DeployNotBefore: "12-07-2020",
  1023  			},
  1024  			responseStatus: http.StatusAccepted,
  1025  			responseBody: `
  1026  {
  1027  	"enrollment": "/cps-api/enrollments/1",
  1028  	"changes": ["/cps-api/enrollments/1/changes/10002"]
  1029  }`,
  1030  			expectedPath: "/cps/v2/enrollments?contractId=ctr-1&deploy-not-after=12-12-2021&deploy-not-before=12-07-2020",
  1031  			expectedResponse: &CreateEnrollmentResponse{
  1032  				Enrollment: "/cps-api/enrollments/1",
  1033  				Changes:    []string{"/cps-api/enrollments/1/changes/10002"},
  1034  				ID:         1,
  1035  			},
  1036  		},
  1037  		"202 accepted allow duplicate cn": {
  1038  			request: CreateEnrollmentRequest{
  1039  				Enrollment: Enrollment{
  1040  					AdminContact: &Contact{
  1041  						Email: "r1d1@akamai.com",
  1042  					},
  1043  					CertificateType: "third-party",
  1044  					CSR: &CSR{
  1045  						CN: "www.example.com",
  1046  					},
  1047  					NetworkConfiguration: &NetworkConfiguration{},
  1048  					Org:                  &Org{Name: "Akamai"},
  1049  					RA:                   "third-party",
  1050  					TechContact: &Contact{
  1051  						Email: "r2d2@akamai.com",
  1052  					},
  1053  					ValidationType: "third-party",
  1054  				},
  1055  				ContractID:       "ctr-1",
  1056  				DeployNotAfter:   "12-12-2021",
  1057  				DeployNotBefore:  "12-07-2020",
  1058  				AllowDuplicateCN: true,
  1059  			},
  1060  			responseStatus: http.StatusAccepted,
  1061  			responseBody: `
  1062  {
  1063  	"enrollment": "/cps-api/enrollments/1",
  1064  	"changes": ["/cps-api/enrollments/1/changes/10002"]
  1065  }`,
  1066  			expectedPath: "/cps/v2/enrollments?allow-duplicate-cn=true&contractId=ctr-1&deploy-not-after=12-12-2021&deploy-not-before=12-07-2020",
  1067  			expectedResponse: &CreateEnrollmentResponse{
  1068  				Enrollment: "/cps-api/enrollments/1",
  1069  				Changes:    []string{"/cps-api/enrollments/1/changes/10002"},
  1070  				ID:         1,
  1071  			},
  1072  		},
  1073  		"202 accepted dv enrollment": {
  1074  			request: CreateEnrollmentRequest{
  1075  				Enrollment: Enrollment{
  1076  					AdminContact: &Contact{
  1077  						Email: "r1d1@akamai.com",
  1078  					},
  1079  					CertificateType: "san",
  1080  					CSR: &CSR{
  1081  						CN:                  "www.example.com",
  1082  						PreferredTrustChain: "intermediate-a",
  1083  					},
  1084  					NetworkConfiguration: &NetworkConfiguration{},
  1085  					Org:                  &Org{Name: "Akamai"},
  1086  					RA:                   "lets-encrypt",
  1087  					TechContact: &Contact{
  1088  						Email: "r2d2@akamai.com",
  1089  					},
  1090  					ValidationType: "dv",
  1091  				},
  1092  				ContractID:      "ctr-1",
  1093  				DeployNotAfter:  "12-12-2021",
  1094  				DeployNotBefore: "12-07-2020",
  1095  			},
  1096  			responseStatus: http.StatusAccepted,
  1097  			responseBody: `
  1098  {
  1099  	"enrollment": "/cps-api/enrollments/1",
  1100  	"changes": ["/cps-api/enrollments/1/changes/10002"]
  1101  }`,
  1102  			expectedPath: "/cps/v2/enrollments?contractId=ctr-1&deploy-not-after=12-12-2021&deploy-not-before=12-07-2020",
  1103  			expectedResponse: &CreateEnrollmentResponse{
  1104  				Enrollment: "/cps-api/enrollments/1",
  1105  				Changes:    []string{"/cps-api/enrollments/1/changes/10002"},
  1106  				ID:         1,
  1107  			},
  1108  		},
  1109  		"500 internal server error": {
  1110  			request: CreateEnrollmentRequest{
  1111  				Enrollment: Enrollment{
  1112  					AdminContact: &Contact{
  1113  						Email: "r1d1@akamai.com",
  1114  					},
  1115  					CertificateType: "third-party",
  1116  					CSR: &CSR{
  1117  						CN: "www.example.com",
  1118  					},
  1119  					NetworkConfiguration: &NetworkConfiguration{},
  1120  					Org:                  &Org{Name: "Akamai"},
  1121  					RA:                   "third-party",
  1122  					TechContact: &Contact{
  1123  						Email: "r2d2@akamai.com",
  1124  					},
  1125  					ValidationType: "third-party",
  1126  				},
  1127  				ContractID:      "ctr-1",
  1128  				DeployNotAfter:  "12-12-2021",
  1129  				DeployNotBefore: "12-07-2020",
  1130  			},
  1131  			responseStatus: http.StatusInternalServerError,
  1132  			responseBody: `
  1133  {
  1134    "type": "internal_error",
  1135    "title": "Internal Server Error",
  1136    "detail": "Error creating enrollment",
  1137    "status": 500
  1138  }`,
  1139  			expectedPath: "/cps/v2/enrollments?contractId=ctr-1&deploy-not-after=12-12-2021&deploy-not-before=12-07-2020",
  1140  			withError: &Error{
  1141  				Type:       "internal_error",
  1142  				Title:      "Internal Server Error",
  1143  				Detail:     "Error creating enrollment",
  1144  				StatusCode: http.StatusInternalServerError,
  1145  			},
  1146  		},
  1147  		"validation error": {
  1148  			request:   CreateEnrollmentRequest{},
  1149  			withError: ErrStructValidation,
  1150  		},
  1151  		"validation error preferredTrustChain set for non dv enrollment": {
  1152  			request: CreateEnrollmentRequest{
  1153  				Enrollment: Enrollment{
  1154  					AdminContact: &Contact{
  1155  						Email: "r1d1@akamai.com",
  1156  					},
  1157  					CertificateType: "third-party",
  1158  					CSR: &CSR{
  1159  						CN:                  "www.example.com",
  1160  						PreferredTrustChain: "intermediate-a",
  1161  					},
  1162  					NetworkConfiguration: &NetworkConfiguration{},
  1163  					Org:                  &Org{Name: "Akamai"},
  1164  					RA:                   "third-party",
  1165  					TechContact: &Contact{
  1166  						Email: "r2d2@akamai.com",
  1167  					},
  1168  					ValidationType: "third-party",
  1169  				},
  1170  				ContractID:      "ctr-1",
  1171  				DeployNotAfter:  "12-12-2021",
  1172  				DeployNotBefore: "12-07-2020",
  1173  			},
  1174  			withError: ErrStructValidation,
  1175  		},
  1176  		"invalid location": {
  1177  			request: CreateEnrollmentRequest{
  1178  				Enrollment: Enrollment{
  1179  					AdminContact: &Contact{
  1180  						Email: "r1d1@akamai.com",
  1181  					},
  1182  					CertificateType: "third-party",
  1183  					CSR: &CSR{
  1184  						CN: "www.example.com",
  1185  					},
  1186  					NetworkConfiguration: &NetworkConfiguration{},
  1187  					Org:                  &Org{Name: "Akamai"},
  1188  					RA:                   "third-party",
  1189  					TechContact: &Contact{
  1190  						Email: "r2d2@akamai.com",
  1191  					},
  1192  					ValidationType: "third-party",
  1193  				},
  1194  				ContractID:      "ctr-1",
  1195  				DeployNotAfter:  "12-12-2021",
  1196  				DeployNotBefore: "12-07-2020",
  1197  			},
  1198  			responseStatus: http.StatusAccepted,
  1199  			responseBody: `
  1200  {
  1201  	"enrollment": "abc",
  1202  	"changes": ["/cps-api/enrollments/1/changes/10002"]
  1203  }`,
  1204  			expectedPath: "/cps/v2/enrollments?contractId=ctr-1&deploy-not-after=12-12-2021&deploy-not-before=12-07-2020",
  1205  			withError:    ErrInvalidLocation,
  1206  		},
  1207  	}
  1208  
  1209  	for name, test := range tests {
  1210  		t.Run(name, func(t *testing.T) {
  1211  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1212  				assert.Equal(t, test.expectedPath, r.URL.String())
  1213  				assert.Equal(t, http.MethodPost, r.Method)
  1214  				assert.Equal(t, "application/vnd.akamai.cps.enrollment-status.v1+json", r.Header.Get("Accept"))
  1215  				assert.Equal(t, "application/vnd.akamai.cps.enrollment.v11+json; charset=utf-8", r.Header.Get("Content-Type"))
  1216  				w.WriteHeader(test.responseStatus)
  1217  				_, err := w.Write([]byte(test.responseBody))
  1218  				assert.NoError(t, err)
  1219  			}))
  1220  			client := mockAPIClient(t, mockServer)
  1221  			result, err := client.CreateEnrollment(context.Background(), test.request)
  1222  			if test.withError != nil {
  1223  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
  1224  				return
  1225  			}
  1226  			require.NoError(t, err)
  1227  			assert.Equal(t, test.expectedResponse, result)
  1228  		})
  1229  	}
  1230  }
  1231  
  1232  func TestUpdateEnrollment(t *testing.T) {
  1233  	tests := map[string]struct {
  1234  		request          UpdateEnrollmentRequest
  1235  		responseStatus   int
  1236  		responseBody     string
  1237  		expectedPath     string
  1238  		expectedResponse *UpdateEnrollmentResponse
  1239  		withError        error
  1240  	}{
  1241  		"202 accepted": {
  1242  			request: UpdateEnrollmentRequest{
  1243  				EnrollmentID: 1,
  1244  				Enrollment: Enrollment{
  1245  					AdminContact: &Contact{
  1246  						Email: "r1d1@akamai.com",
  1247  					},
  1248  					CertificateType: "third-party",
  1249  					CSR: &CSR{
  1250  						CN: "www.example.com",
  1251  					},
  1252  					NetworkConfiguration: &NetworkConfiguration{},
  1253  					Org:                  &Org{Name: "Akamai"},
  1254  					RA:                   "third-party",
  1255  					TechContact: &Contact{
  1256  						Email: "r2d2@akamai.com",
  1257  					},
  1258  					ValidationType: "third-party",
  1259  				},
  1260  				DeployNotAfter:            "12-12-2021",
  1261  				DeployNotBefore:           "12-07-2020",
  1262  				RenewalDateCheckOverride:  BoolPtr(true),
  1263  				AllowCancelPendingChanges: BoolPtr(true),
  1264  				AllowStagingBypass:        BoolPtr(true),
  1265  				ForceRenewal:              BoolPtr(true),
  1266  			},
  1267  			responseStatus: http.StatusAccepted,
  1268  			responseBody: `
  1269  {
  1270  	"enrollment": "/cps-api/enrollments/1",
  1271  	"changes": ["/cps-api/enrollments/1/changes/10002"]
  1272  }`,
  1273  			expectedPath: "/cps/v2/enrollments/1?allow-cancel-pending-changes=true&allow-staging-bypass=true&deploy-not-after=12-12-2021&deploy-not-before=12-07-2020&force-renewal=true&renewal-date-check-override=true",
  1274  			expectedResponse: &UpdateEnrollmentResponse{
  1275  				Enrollment: "/cps-api/enrollments/1",
  1276  				Changes:    []string{"/cps-api/enrollments/1/changes/10002"},
  1277  				ID:         1,
  1278  			},
  1279  		},
  1280  		"500 internal server error": {
  1281  			request: UpdateEnrollmentRequest{
  1282  				EnrollmentID: 1,
  1283  				Enrollment: Enrollment{
  1284  					AdminContact: &Contact{
  1285  						Email: "r1d1@akamai.com",
  1286  					},
  1287  					CertificateType: "third-party",
  1288  					CSR: &CSR{
  1289  						CN: "www.example.com",
  1290  					},
  1291  					NetworkConfiguration: &NetworkConfiguration{},
  1292  					Org:                  &Org{Name: "Akamai"},
  1293  					RA:                   "third-party",
  1294  					TechContact: &Contact{
  1295  						Email: "r2d2@akamai.com",
  1296  					},
  1297  					ValidationType: "third-party",
  1298  				},
  1299  				DeployNotAfter:  "12-12-2021",
  1300  				DeployNotBefore: "12-07-2020",
  1301  			},
  1302  			responseStatus: http.StatusInternalServerError,
  1303  			responseBody: `
  1304  {
  1305  	"type": "internal_error",
  1306    "title": "Internal Server Error",
  1307    "detail": "Error updating enrollment",
  1308    "status": 500
  1309  }`,
  1310  			expectedPath: "/cps/v2/enrollments/1?deploy-not-after=12-12-2021&deploy-not-before=12-07-2020",
  1311  			withError: &Error{
  1312  				Type:       "internal_error",
  1313  				Title:      "Internal Server Error",
  1314  				Detail:     "Error updating enrollment",
  1315  				StatusCode: http.StatusInternalServerError,
  1316  			},
  1317  		},
  1318  		"validation error": {
  1319  			request:   UpdateEnrollmentRequest{},
  1320  			withError: ErrStructValidation,
  1321  		},
  1322  		"validation error preferredTrustChain set for non dv enrollment": {
  1323  			request: UpdateEnrollmentRequest{
  1324  				Enrollment: Enrollment{
  1325  					AdminContact: &Contact{
  1326  						Email: "r1d1@akamai.com",
  1327  					},
  1328  					CertificateType: "third-party",
  1329  					CSR: &CSR{
  1330  						CN:                  "www.example.com",
  1331  						PreferredTrustChain: "intermediate-a",
  1332  					},
  1333  					NetworkConfiguration: &NetworkConfiguration{},
  1334  					Org:                  &Org{Name: "Akamai"},
  1335  					RA:                   "third-party",
  1336  					TechContact: &Contact{
  1337  						Email: "r2d2@akamai.com",
  1338  					},
  1339  					ValidationType: "third-party",
  1340  				},
  1341  				DeployNotAfter:  "12-12-2021",
  1342  				DeployNotBefore: "12-07-2020",
  1343  			},
  1344  			withError: ErrStructValidation,
  1345  		},
  1346  		"invalid location URL": {
  1347  			request: UpdateEnrollmentRequest{
  1348  				EnrollmentID: 1,
  1349  				Enrollment: Enrollment{
  1350  					AdminContact: &Contact{
  1351  						Email: "r1d1@akamai.com",
  1352  					},
  1353  					CertificateType: "third-party",
  1354  					CSR: &CSR{
  1355  						CN: "www.example.com",
  1356  					},
  1357  					NetworkConfiguration: &NetworkConfiguration{},
  1358  					Org:                  &Org{Name: "Akamai"},
  1359  					RA:                   "third-party",
  1360  					TechContact: &Contact{
  1361  						Email: "r2d2@akamai.com",
  1362  					},
  1363  					ValidationType: "third-party",
  1364  				},
  1365  				DeployNotAfter:            "12-12-2021",
  1366  				DeployNotBefore:           "12-07-2020",
  1367  				RenewalDateCheckOverride:  BoolPtr(true),
  1368  				AllowCancelPendingChanges: BoolPtr(true),
  1369  				AllowStagingBypass:        BoolPtr(true),
  1370  				ForceRenewal:              BoolPtr(true),
  1371  			},
  1372  			responseStatus: http.StatusAccepted,
  1373  			responseBody: `
  1374  {
  1375  	"enrollment": "abc",
  1376  	"changes": ["/cps-api/enrollments/1/changes/10002"]
  1377  }`,
  1378  			expectedPath: "/cps/v2/enrollments/1?allow-cancel-pending-changes=true&allow-staging-bypass=true&deploy-not-after=12-12-2021&deploy-not-before=12-07-2020&force-renewal=true&renewal-date-check-override=true",
  1379  			withError:    ErrInvalidLocation,
  1380  		},
  1381  	}
  1382  
  1383  	for name, test := range tests {
  1384  		t.Run(name, func(t *testing.T) {
  1385  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1386  				assert.Equal(t, test.expectedPath, r.URL.String())
  1387  				assert.Equal(t, http.MethodPut, r.Method)
  1388  				assert.Equal(t, "application/vnd.akamai.cps.enrollment-status.v1+json", r.Header.Get("Accept"))
  1389  				assert.Equal(t, "application/vnd.akamai.cps.enrollment.v11+json; charset=utf-8", r.Header.Get("Content-Type"))
  1390  				w.WriteHeader(test.responseStatus)
  1391  				_, err := w.Write([]byte(test.responseBody))
  1392  				assert.NoError(t, err)
  1393  			}))
  1394  			client := mockAPIClient(t, mockServer)
  1395  			result, err := client.UpdateEnrollment(context.Background(), test.request)
  1396  			if test.withError != nil {
  1397  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
  1398  				return
  1399  			}
  1400  			require.NoError(t, err)
  1401  			assert.Equal(t, test.expectedResponse, result)
  1402  		})
  1403  	}
  1404  }
  1405  
  1406  func TestRemoveEnrollment(t *testing.T) {
  1407  	tests := map[string]struct {
  1408  		request          RemoveEnrollmentRequest
  1409  		responseStatus   int
  1410  		responseBody     string
  1411  		expectedPath     string
  1412  		expectedResponse *RemoveEnrollmentResponse
  1413  		withError        error
  1414  	}{
  1415  		"200 OK": {
  1416  			request: RemoveEnrollmentRequest{
  1417  				EnrollmentID:              1,
  1418  				AllowCancelPendingChanges: BoolPtr(true),
  1419  				DeployNotAfter:            "12-12-2021",
  1420  				DeployNotBefore:           "12-07-2021",
  1421  			},
  1422  			responseStatus: http.StatusOK,
  1423  			responseBody: `
  1424  {
  1425  	"enrollment": "/cps-api/enrollments/1",
  1426  	"changes": ["/cps-api/enrollments/1/changes/10002"]
  1427  }`,
  1428  			expectedPath: "/cps/v2/enrollments/1?allow-cancel-pending-changes=true&deploy-not-after=12-12-2021&deploy-not-before=12-07-2021",
  1429  			expectedResponse: &RemoveEnrollmentResponse{
  1430  				Enrollment: "/cps-api/enrollments/1",
  1431  				Changes:    []string{"/cps-api/enrollments/1/changes/10002"},
  1432  			},
  1433  		},
  1434  		"500 internal server error": {
  1435  			request: RemoveEnrollmentRequest{
  1436  				EnrollmentID:              1,
  1437  				AllowCancelPendingChanges: BoolPtr(true),
  1438  				DeployNotAfter:            "12-12-2021",
  1439  				DeployNotBefore:           "12-07-2021",
  1440  			},
  1441  			responseStatus: http.StatusInternalServerError,
  1442  			responseBody: `
  1443  {
  1444  	"type": "internal_error",
  1445      "title": "Internal Server Error",
  1446      "detail": "Error removing enrollment",
  1447      "status": 500
  1448  }`,
  1449  			expectedPath: "/cps/v2/enrollments/1?allow-cancel-pending-changes=true&deploy-not-after=12-12-2021&deploy-not-before=12-07-2021",
  1450  			withError: &Error{
  1451  				Type:       "internal_error",
  1452  				Title:      "Internal Server Error",
  1453  				Detail:     "Error removing enrollment",
  1454  				StatusCode: http.StatusInternalServerError,
  1455  			},
  1456  		},
  1457  		"validation error": {
  1458  			request:   RemoveEnrollmentRequest{},
  1459  			withError: ErrStructValidation,
  1460  		},
  1461  	}
  1462  
  1463  	for name, test := range tests {
  1464  		t.Run(name, func(t *testing.T) {
  1465  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1466  				assert.Equal(t, test.expectedPath, r.URL.String())
  1467  				assert.Equal(t, http.MethodDelete, r.Method)
  1468  				assert.Equal(t, "application/vnd.akamai.cps.enrollment-status.v1+json", r.Header.Get("Accept"))
  1469  				w.WriteHeader(test.responseStatus)
  1470  				_, err := w.Write([]byte(test.responseBody))
  1471  				assert.NoError(t, err)
  1472  			}))
  1473  			client := mockAPIClient(t, mockServer)
  1474  			result, err := client.RemoveEnrollment(context.Background(), test.request)
  1475  			if test.withError != nil {
  1476  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
  1477  				return
  1478  			}
  1479  			require.NoError(t, err)
  1480  			assert.Equal(t, test.expectedResponse, result)
  1481  		})
  1482  	}
  1483  }
  1484  
  1485  func BoolPtr(b bool) *bool {
  1486  	return &b
  1487  }