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

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