github.com/akamai/AkamaiOPEN-edgegrid-golang/v2@v2.17.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  	"/cps-api/enrollments/1/changes/2"
   106     ],
   107    "maxAllowedSanNames" : 100,
   108    "maxAllowedWildcardSanNames" : 100
   109  }, {
   110    "location" : "/cps-api/enrollments/2",
   111    "ra" : "lets-encrypt",
   112    "validationType" : "dv",
   113    "certificateType" : "san",
   114    "certificateChainType" : "default",
   115    "networkConfiguration" : {
   116      "geography" : "core",
   117      "secureNetwork" : "enhanced-tls",
   118      "mustHaveCiphers" : "ak-akamai-default-2017q3",
   119      "preferredCiphers" : "ak-akamai-default-2017q3",
   120      "disallowedTlsVersions" : [ "TLSv1", "TLSv1_1" ],
   121      "sniOnly" : true,
   122      "quicEnabled" : false,
   123      "dnsNameSettings" : {
   124        "cloneDnsNames" : true,
   125        "dnsNames" : [ "jmm.20210504-dsa12.faden.me" ]
   126      },
   127      "ocspStapling" : "on",
   128      "clientMutualAuthentication" : null
   129    },
   130    "signatureAlgorithm" : "SHA-256",
   131    "changeManagement" : false,
   132    "csr" : {
   133      "cn" : "jmm.20210504-dsa12.faden.me",
   134      "c" : "US",
   135      "st" : "MA",
   136      "l" : "Cambridge",
   137      "o" : "Akamai Technologies, Inc.",
   138      "ou" : null,
   139      "sans" : [ "jmm.20210504-dsa12.faden.me" ],
   140      "preferredTrustChain" : null
   141    },
   142    "org" : {
   143      "name" : "Akamai Technologies, Inc.",
   144      "addressLineOne" : "150 Broadway",
   145      "addressLineTwo" : null,
   146      "city" : "Cambridge",
   147      "region" : "MA",
   148      "postalCode" : "02142",
   149      "country" : "US",
   150      "phone" : "617-444-3000"
   151    },
   152    "adminContact" : {
   153      "firstName" : "R3",
   154      "lastName" : "D3",
   155      "phone" : "8577068086",
   156      "email" : "rd3@nomail-akamai.com",
   157      "addressLineOne" : null,
   158      "addressLineTwo" : null,
   159      "city" : null,
   160      "country" : null,
   161      "organizationName" : null,
   162      "postalCode" : null,
   163      "region" : null,
   164      "title" : null
   165    },
   166    "techContact" : {
   167      "firstName" : "R4",
   168      "lastName" : "D4",
   169      "phone" : "617-444-3000",
   170      "email" : "rd4@akamai.com",
   171      "addressLineOne" : null,
   172      "addressLineTwo" : null,
   173      "city" : null,
   174      "country" : null,
   175      "organizationName" : null,
   176      "postalCode" : null,
   177      "region" : null,
   178      "title" : null
   179    },
   180    "thirdParty" : null,
   181    "enableMultiStackedCertificates" : false,
   182    "autoRenewalStartTime" : null,
   183    "pendingChanges" : [ 
   184       "/cps-api/enrollments/2/changes/2"
   185     ],
   186    "maxAllowedSanNames" : 100,
   187    "maxAllowedWildcardSanNames" : 25
   188  },
   189  {
   190    "location" : "/cps-api/enrollments/3",
   191    "ra" : "third-party",
   192    "validationType" : "third-party",
   193    "certificateType" : "third-party",
   194    "certificateChainType" : "default",
   195    "networkConfiguration" : {
   196      "geography" : "core",
   197      "secureNetwork" : "enhanced-tls",
   198      "mustHaveCiphers" : "ak-akamai-2020q1",
   199      "preferredCiphers" : "ak-akamai-2020q1",
   200      "disallowedTlsVersions" : [ "TLSv1", "TLSv1_1" ],
   201      "sniOnly" : true,
   202      "quicEnabled" : false,
   203      "dnsNameSettings" : {
   204        "cloneDnsNames" : true,
   205        "dnsNames" : [ "san1-submishr-ghj1-mediatest.com", "san2-submishr-ghj1-mediatest.com", "submishr-ghj1-mediatest.com" ]
   206      },
   207      "ocspStapling" : "on",
   208      "clientMutualAuthentication" : null
   209    },
   210    "signatureAlgorithm" : null,
   211    "changeManagement" : false,
   212    "csr" : {
   213      "cn" : "submishr-ghj1-mediatest.com",
   214      "c" : "IN",
   215      "st" : "karnataka",
   216      "l" : "Bangalore",
   217      "o" : "Akamai",
   218      "ou" : "",
   219      "sans" : [ "san1-submishr-ghj1-mediatest.com", "san2-submishr-ghj1-mediatest.com", "submishr-ghj1-mediatest.com" ]
   220    },
   221    "org" : {
   222      "name" : "Akamai",
   223      "addressLineOne" : "EGL",
   224      "addressLineTwo" : "Bangalore",
   225      "city" : "Bangalore",
   226      "region" : "karnataka",
   227      "postalCode" : "560071",
   228      "country" : "IN",
   229      "phone" : "34234353453"
   230    },
   231    "adminContact" : {
   232      "firstName" : "DevQA",
   233      "lastName" : "Tester",
   234      "phone" : "6173000033",
   235      "email" : "devqa@tester.com",
   236      "addressLineOne" : null,
   237      "addressLineTwo" : null,
   238      "city" : null,
   239      "country" : null,
   240      "organizationName" : null,
   241      "postalCode" : null,
   242      "region" : null,
   243      "title" : null
   244    },
   245    "techContact" : {
   246      "firstName" : "John",
   247      "lastName" : "Doe",
   248      "phone" : "111000111",
   249      "email" : "john@example.com",
   250      "addressLineOne" : null,
   251      "addressLineTwo" : null,
   252      "city" : null,
   253      "country" : null,
   254      "organizationName" : null,
   255      "postalCode" : null,
   256      "region" : null,
   257      "title" : null
   258    },
   259    "thirdParty" : {
   260      "excludeSans" : false
   261    },
   262    "enableMultiStackedCertificates" : true,
   263    "autoRenewalStartTime" : null,
   264    "pendingChanges" : [ "/cps-api/enrollments/3/changes/30" ],
   265    "maxAllowedSanNames" : 100,
   266    "maxAllowedWildcardSanNames" : 100
   267  }
   268  ]}`,
   269  			expectedPath: "/cps/v2/enrollments?contractId=Contract-123",
   270  			expectedHeaders: map[string]string{
   271  				"Accept": "application/vnd.akamai.cps.enrollments.v9+json",
   272  			},
   273  			expectedResponse: &ListEnrollmentsResponse{Enrollments: []Enrollment{
   274  				{
   275  					AdminContact: &Contact{
   276  						AddressLineOne:   "EGL",
   277  						City:             "BLR",
   278  						Country:          "IN",
   279  						Email:            "rd1@akamai.com",
   280  						FirstName:        "R1",
   281  						LastName:         "D1",
   282  						OrganizationName: "Akamai",
   283  						Phone:            "4356",
   284  						PostalCode:       "71",
   285  						Region:           "KA",
   286  					},
   287  					CertificateChainType: "default",
   288  					CertificateType:      "third-party",
   289  					ChangeManagement:     false,
   290  					CSR: &CSR{
   291  						C:  "IN",
   292  						CN: "res-sqa2-3pss-4111-10-1-3CV382-ui.com",
   293  						L:  "BLR",
   294  						O:  "Akamai",
   295  						OU: "ETG",
   296  						SANS: []string{"san1.res-sqa2-3pss-4111-10-1-3CV382-ui.com",
   297  							"res-sqa2-3pss-4111-10-1-3CV382-ui.com"},
   298  						ST: "KA",
   299  					},
   300  					EnableMultiStackedCertificates: false,
   301  					Location:                       "/cps-api/enrollments/1",
   302  					MaxAllowedSanNames:             100,
   303  					MaxAllowedWildcardSanNames:     100,
   304  					NetworkConfiguration: &NetworkConfiguration{
   305  						DisallowedTLSVersions: []string{"TLSv1", "TLSv1_1"},
   306  						DNSNameSettings: &DNSNameSettings{
   307  							CloneDNSNames: true,
   308  							DNSNames: []string{"res-sqa2-3pss-4111-10-1-3CV382-ui.com",
   309  								"san1.res-sqa2-3pss-4111-10-1-3CV382-ui.com"},
   310  						},
   311  						Geography:        "core",
   312  						MustHaveCiphers:  "ak-akamai-2020q1",
   313  						OCSPStapling:     "on",
   314  						PreferredCiphers: "ak-akamai-2020q1",
   315  						QuicEnabled:      false,
   316  						SecureNetwork:    "standard-tls",
   317  						SNIOnly:          true,
   318  					},
   319  					Org: &Org{
   320  						AddressLineOne: "EGL",
   321  						City:           "BLR",
   322  						Country:        "IN",
   323  						Name:           "Akamai",
   324  						Phone:          "12",
   325  						PostalCode:     "71",
   326  						Region:         "KA",
   327  					},
   328  					PendingChanges: []string{"/cps-api/enrollments/1/changes/2"},
   329  					RA:             "third-party",
   330  					TechContact: &Contact{
   331  						AddressLineOne:   "150 Broadway",
   332  						City:             "Cambridge",
   333  						Country:          "US",
   334  						Email:            "rd2@akamai.com",
   335  						FirstName:        "R2",
   336  						LastName:         "D2",
   337  						OrganizationName: "Akamai Technologies",
   338  						Phone:            "6456",
   339  						PostalCode:       "02142",
   340  						Region:           "Massachusetts",
   341  					},
   342  					ThirdParty:     &ThirdParty{ExcludeSANS: true},
   343  					ValidationType: "third-party",
   344  				},
   345  				{
   346  					AdminContact: &Contact{
   347  						Email:     "rd3@nomail-akamai.com",
   348  						FirstName: "R3",
   349  						LastName:  "D3",
   350  						Phone:     "8577068086",
   351  					},
   352  					CertificateChainType: "default",
   353  					CertificateType:      "san",
   354  					ChangeManagement:     false,
   355  					CSR: &CSR{
   356  						C:    "US",
   357  						CN:   "jmm.20210504-dsa12.faden.me",
   358  						L:    "Cambridge",
   359  						O:    "Akamai Technologies, Inc.",
   360  						SANS: []string{"jmm.20210504-dsa12.faden.me"},
   361  						ST:   "MA",
   362  					},
   363  					EnableMultiStackedCertificates: false,
   364  					Location:                       "/cps-api/enrollments/2",
   365  					MaxAllowedSanNames:             100,
   366  					MaxAllowedWildcardSanNames:     25,
   367  					NetworkConfiguration: &NetworkConfiguration{
   368  						DisallowedTLSVersions: []string{"TLSv1", "TLSv1_1"},
   369  						DNSNameSettings: &DNSNameSettings{
   370  							CloneDNSNames: true,
   371  							DNSNames:      []string{"jmm.20210504-dsa12.faden.me"},
   372  						},
   373  						Geography:        "core",
   374  						MustHaveCiphers:  "ak-akamai-default-2017q3",
   375  						OCSPStapling:     "on",
   376  						PreferredCiphers: "ak-akamai-default-2017q3",
   377  						QuicEnabled:      false,
   378  						SecureNetwork:    "enhanced-tls",
   379  						SNIOnly:          true,
   380  					},
   381  					Org: &Org{
   382  						AddressLineOne: "150 Broadway",
   383  						City:           "Cambridge",
   384  						Country:        "US",
   385  						Name:           "Akamai Technologies, Inc.",
   386  						Phone:          "617-444-3000",
   387  						PostalCode:     "02142",
   388  						Region:         "MA",
   389  					},
   390  					PendingChanges: []string{"/cps-api/enrollments/2/changes/2"},
   391  					RA:             "lets-encrypt",
   392  					TechContact: &Contact{
   393  						Email:     "rd4@akamai.com",
   394  						FirstName: "R4",
   395  						LastName:  "D4",
   396  						Phone:     "617-444-3000",
   397  					},
   398  					ValidationType:     "dv",
   399  					SignatureAlgorithm: "SHA-256",
   400  				},
   401  				{
   402  					AdminContact: &Contact{
   403  						Email:     "devqa@tester.com",
   404  						FirstName: "DevQA",
   405  						LastName:  "Tester",
   406  						Phone:     "6173000033",
   407  					},
   408  					CertificateChainType: "default",
   409  					CertificateType:      "third-party",
   410  					ChangeManagement:     false,
   411  					CSR: &CSR{
   412  						C:  "IN",
   413  						CN: "submishr-ghj1-mediatest.com",
   414  						L:  "Bangalore",
   415  						O:  "Akamai",
   416  						SANS: []string{
   417  							"san1-submishr-ghj1-mediatest.com",
   418  							"san2-submishr-ghj1-mediatest.com",
   419  							"submishr-ghj1-mediatest.com"},
   420  						ST: "karnataka",
   421  					},
   422  					EnableMultiStackedCertificates: true,
   423  					Location:                       "/cps-api/enrollments/3",
   424  					MaxAllowedSanNames:             100,
   425  					MaxAllowedWildcardSanNames:     100,
   426  					NetworkConfiguration: &NetworkConfiguration{
   427  						DisallowedTLSVersions: []string{"TLSv1", "TLSv1_1"},
   428  						DNSNameSettings: &DNSNameSettings{
   429  							CloneDNSNames: true,
   430  							DNSNames: []string{
   431  								"san1-submishr-ghj1-mediatest.com",
   432  								"san2-submishr-ghj1-mediatest.com",
   433  								"submishr-ghj1-mediatest.com"},
   434  						},
   435  						Geography:        "core",
   436  						MustHaveCiphers:  "ak-akamai-2020q1",
   437  						OCSPStapling:     "on",
   438  						PreferredCiphers: "ak-akamai-2020q1",
   439  						QuicEnabled:      false,
   440  						SecureNetwork:    "enhanced-tls",
   441  						SNIOnly:          true,
   442  					},
   443  					Org: &Org{
   444  						AddressLineOne: "EGL",
   445  						AddressLineTwo: "Bangalore",
   446  						City:           "Bangalore",
   447  						Country:        "IN",
   448  						Name:           "Akamai",
   449  						Phone:          "34234353453",
   450  						PostalCode:     "560071",
   451  						Region:         "karnataka",
   452  					},
   453  					PendingChanges: []string{"/cps-api/enrollments/3/changes/30"},
   454  					RA:             "third-party",
   455  					TechContact: &Contact{
   456  						Email:     "john@example.com",
   457  						FirstName: "John",
   458  						LastName:  "Doe",
   459  						Phone:     "111000111",
   460  					},
   461  					ThirdParty:     &ThirdParty{ExcludeSANS: false},
   462  					ValidationType: "third-party",
   463  				},
   464  			}},
   465  		},
   466  		"500 internal server error": {
   467  			params:         ListEnrollmentsRequest{ContractID: "1"},
   468  			responseStatus: http.StatusInternalServerError,
   469  			responseBody: `
   470  {
   471  	"type": "internal_error",
   472     "title": "Internal Server Error",
   473     "detail": "Error making request",
   474     "status": 500
   475  }`,
   476  			expectedPath: "/cps/v2/enrollments?contractId=1",
   477  			expectedHeaders: map[string]string{
   478  				"Accept": "application/vnd.akamai.cps.enrollments.v9+json",
   479  			},
   480  			withError: func(t *testing.T, err error) {
   481  				want := &Error{
   482  					Type:       "internal_error",
   483  					Title:      "Internal Server Error",
   484  					Detail:     "Error making request",
   485  					StatusCode: http.StatusInternalServerError,
   486  				}
   487  				assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err)
   488  			},
   489  		},
   490  	}
   491  
   492  	for name, test := range tests {
   493  		t.Run(name, func(t *testing.T) {
   494  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   495  				assert.Equal(t, test.expectedPath, r.URL.String())
   496  				assert.Equal(t, http.MethodGet, r.Method)
   497  				for k, v := range test.expectedHeaders {
   498  					assert.Equal(t, v, r.Header.Get(k))
   499  				}
   500  				w.WriteHeader(test.responseStatus)
   501  				_, err := w.Write([]byte(test.responseBody))
   502  				assert.NoError(t, err)
   503  			}))
   504  			client := mockAPIClient(t, mockServer)
   505  			result, err := client.ListEnrollments(context.Background(), test.params)
   506  			if test.withError != nil {
   507  				test.withError(t, err)
   508  				return
   509  			}
   510  			require.NoError(t, err)
   511  			assert.Equal(t, test.expectedResponse, result)
   512  		})
   513  	}
   514  }
   515  
   516  func TestGetEnrollment(t *testing.T) {
   517  	tests := map[string]struct {
   518  		params           GetEnrollmentRequest
   519  		responseStatus   int
   520  		responseBody     string
   521  		expectedPath     string
   522  		expectedHeaders  map[string]string
   523  		expectedResponse *Enrollment
   524  		withError        func(*testing.T, error)
   525  	}{
   526  		"200 OK": {
   527  			params:         GetEnrollmentRequest{EnrollmentID: 1},
   528  			responseStatus: http.StatusOK,
   529  			responseBody: `
   530  {
   531      "location": "/cps-api/enrollments/1",
   532      "ra": "third-party",
   533      "validationType": "third-party",
   534      "certificateType": "third-party",
   535      "certificateChainType": "default",
   536      "networkConfiguration": {
   537          "geography": "core",
   538          "secureNetwork": "enhanced-tls",
   539          "mustHaveCiphers": "ak-akamai-default",
   540          "preferredCiphers": "ak-akamai-default-interim",
   541          "disallowedTlsVersions": [
   542              "TLSv1"
   543          ],
   544          "sniOnly": true,
   545          "quicEnabled": false,
   546          "dnsNameSettings": {
   547              "cloneDnsNames": false,
   548              "dnsNames": [
   549                  "san1.example.com"
   550              ]
   551          },
   552          "ocspStapling": "on",
   553          "clientMutualAuthentication": {
   554              "setId": "Custom_CPS-6134b_B-3-1AHBENT.xml",
   555              "authenticationOptions": {
   556                  "sendCaListToClient": false,
   557                  "ocsp": {
   558                      "enabled": false
   559                  }
   560              }
   561          }
   562      },
   563      "signatureAlgorithm": null,
   564      "changeManagement": true,
   565      "csr": {
   566          "cn": "www.example.com",
   567          "c": "US",
   568          "st": "MA",
   569          "l": "Cambridge",
   570          "o": "Akamai",
   571          "ou": "WebEx",
   572          "sans": [
   573              "www.example.com"
   574          ]
   575      },
   576      "org": {
   577          "name": "Akamai Technologies",
   578          "addressLineOne": "150 Broadway",
   579          "addressLineTwo": null,
   580          "city": "Cambridge",
   581          "region": "MA",
   582          "postalCode": "02142",
   583          "country": "US",
   584          "phone": "617-555-0111"
   585      },
   586      "adminContact": {
   587          "firstName": "R1",
   588          "lastName": "D1",
   589          "phone": "617-555-0111",
   590          "email": "r1d1@akamai.com",
   591          "addressLineOne": "150 Broadway",
   592          "addressLineTwo": null,
   593          "city": "Cambridge",
   594          "country": "US",
   595          "organizationName": "Akamai",
   596          "postalCode": "02142",
   597          "region": "MA",
   598          "title": "Administrator"
   599      },
   600      "techContact": {
   601          "firstName": "R2",
   602          "lastName": "D2",
   603          "phone": "617-555-0111",
   604          "email": "r2d2@akamai.com",
   605          "addressLineOne": "150 Broadway",
   606          "addressLineTwo": null,
   607          "city": "Cambridge",
   608          "country": "US",
   609          "organizationName": "Akamai",
   610          "postalCode": "02142",
   611          "region": "MA",
   612          "title": "Technical Engineer"
   613      },
   614      "thirdParty": {
   615          "excludeSans": false
   616      },
   617      "enableMultiStackedCertificates": false,
   618      "autoRenewalStartTime": null,
   619      "pendingChanges": [
   620          "/cps-api/enrollments/1/changes/2"
   621      ],
   622      "maxAllowedSanNames": 100,
   623      "maxAllowedWildcardSanNames": 100
   624  }`,
   625  			expectedPath: "/cps/v2/enrollments/1",
   626  			expectedHeaders: map[string]string{
   627  				"Accept": "application/vnd.akamai.cps.enrollment.v9+json",
   628  			},
   629  			expectedResponse: &Enrollment{
   630  				AdminContact: &Contact{
   631  					AddressLineOne:   "150 Broadway",
   632  					City:             "Cambridge",
   633  					Country:          "US",
   634  					Email:            "r1d1@akamai.com",
   635  					FirstName:        "R1",
   636  					LastName:         "D1",
   637  					OrganizationName: "Akamai",
   638  					Phone:            "617-555-0111",
   639  					PostalCode:       "02142",
   640  					Region:           "MA",
   641  					Title:            "Administrator",
   642  				},
   643  				CertificateChainType: "default",
   644  				CertificateType:      "third-party",
   645  				ChangeManagement:     true,
   646  				CSR: &CSR{
   647  					C:    "US",
   648  					CN:   "www.example.com",
   649  					L:    "Cambridge",
   650  					O:    "Akamai",
   651  					OU:   "WebEx",
   652  					SANS: []string{"www.example.com"},
   653  					ST:   "MA",
   654  				},
   655  				EnableMultiStackedCertificates: false,
   656  				Location:                       "/cps-api/enrollments/1",
   657  				MaxAllowedSanNames:             100,
   658  				MaxAllowedWildcardSanNames:     100,
   659  				NetworkConfiguration: &NetworkConfiguration{
   660  					ClientMutualAuthentication: &ClientMutualAuthentication{
   661  						AuthenticationOptions: &AuthenticationOptions{
   662  							OCSP:               &OCSP{BoolPtr(false)},
   663  							SendCAListToClient: BoolPtr(false),
   664  						},
   665  						SetID: "Custom_CPS-6134b_B-3-1AHBENT.xml",
   666  					},
   667  					DisallowedTLSVersions: []string{"TLSv1"},
   668  					DNSNameSettings: &DNSNameSettings{
   669  						CloneDNSNames: false,
   670  						DNSNames:      []string{"san1.example.com"},
   671  					},
   672  					Geography:        "core",
   673  					MustHaveCiphers:  "ak-akamai-default",
   674  					OCSPStapling:     "on",
   675  					PreferredCiphers: "ak-akamai-default-interim",
   676  					QuicEnabled:      false,
   677  					SecureNetwork:    "enhanced-tls",
   678  					SNIOnly:          true,
   679  				},
   680  				Org: &Org{
   681  					AddressLineOne: "150 Broadway",
   682  					City:           "Cambridge",
   683  					Country:        "US",
   684  					Name:           "Akamai Technologies",
   685  					Phone:          "617-555-0111",
   686  					PostalCode:     "02142",
   687  					Region:         "MA",
   688  				},
   689  				PendingChanges: []string{"/cps-api/enrollments/1/changes/2"},
   690  				RA:             "third-party",
   691  				TechContact: &Contact{
   692  					AddressLineOne:   "150 Broadway",
   693  					City:             "Cambridge",
   694  					Country:          "US",
   695  					Email:            "r2d2@akamai.com",
   696  					FirstName:        "R2",
   697  					LastName:         "D2",
   698  					OrganizationName: "Akamai",
   699  					Phone:            "617-555-0111",
   700  					PostalCode:       "02142",
   701  					Region:           "MA",
   702  					Title:            "Technical Engineer",
   703  				},
   704  				ThirdParty:     &ThirdParty{ExcludeSANS: false},
   705  				ValidationType: "third-party",
   706  			},
   707  		},
   708  		"500 internal server error": {
   709  			params:         GetEnrollmentRequest{EnrollmentID: 1},
   710  			responseStatus: http.StatusInternalServerError,
   711  			responseBody: `
   712  {
   713  	"type": "internal_error",
   714     "title": "Internal Server Error",
   715     "detail": "Error making request",
   716     "status": 500
   717  }`,
   718  			expectedPath: "/cps/v2/enrollments/1",
   719  			expectedHeaders: map[string]string{
   720  				"Accept": "application/vnd.akamai.cps.enrollment.v9+json",
   721  			},
   722  			withError: func(t *testing.T, err error) {
   723  				want := &Error{
   724  					Type:       "internal_error",
   725  					Title:      "Internal Server Error",
   726  					Detail:     "Error making request",
   727  					StatusCode: http.StatusInternalServerError,
   728  				}
   729  				assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err)
   730  			},
   731  		},
   732  	}
   733  
   734  	for name, test := range tests {
   735  		t.Run(name, func(t *testing.T) {
   736  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   737  				assert.Equal(t, test.expectedPath, r.URL.String())
   738  				assert.Equal(t, http.MethodGet, r.Method)
   739  				for k, v := range test.expectedHeaders {
   740  					assert.Equal(t, v, r.Header.Get(k))
   741  				}
   742  				w.WriteHeader(test.responseStatus)
   743  				_, err := w.Write([]byte(test.responseBody))
   744  				assert.NoError(t, err)
   745  			}))
   746  			client := mockAPIClient(t, mockServer)
   747  			result, err := client.GetEnrollment(context.Background(), test.params)
   748  			if test.withError != nil {
   749  				test.withError(t, err)
   750  				return
   751  			}
   752  			require.NoError(t, err)
   753  			assert.Equal(t, test.expectedResponse, result)
   754  		})
   755  	}
   756  }
   757  
   758  func TestCreateEnrollment(t *testing.T) {
   759  	tests := map[string]struct {
   760  		request          CreateEnrollmentRequest
   761  		responseStatus   int
   762  		responseBody     string
   763  		expectedPath     string
   764  		expectedResponse *CreateEnrollmentResponse
   765  		withError        error
   766  	}{
   767  		"202 accepted": {
   768  			request: CreateEnrollmentRequest{
   769  				Enrollment: Enrollment{
   770  					AdminContact: &Contact{
   771  						Email: "r1d1@akamai.com",
   772  					},
   773  					CertificateType: "third-party",
   774  					CSR: &CSR{
   775  						CN: "www.example.com",
   776  					},
   777  					NetworkConfiguration: &NetworkConfiguration{},
   778  					Org:                  &Org{Name: "Akamai"},
   779  					RA:                   "third-party",
   780  					TechContact: &Contact{
   781  						Email: "r2d2@akamai.com",
   782  					},
   783  					ValidationType: "third-party",
   784  				},
   785  				ContractID:      "ctr-1",
   786  				DeployNotAfter:  "12-12-2021",
   787  				DeployNotBefore: "12-07-2020",
   788  			},
   789  			responseStatus: http.StatusAccepted,
   790  			responseBody: `
   791  {
   792  	"enrollment": "/cps-api/enrollments/1",
   793  	"changes": ["/cps-api/enrollments/1/changes/10002"]
   794  }`,
   795  			expectedPath: "/cps/v2/enrollments?contractId=ctr-1&deploy-not-after=12-12-2021&deploy-not-before=12-07-2020",
   796  			expectedResponse: &CreateEnrollmentResponse{
   797  				Enrollment: "/cps-api/enrollments/1",
   798  				Changes:    []string{"/cps-api/enrollments/1/changes/10002"},
   799  				ID:         1,
   800  			},
   801  		},
   802  		"202 accepted allow duplicate cn": {
   803  			request: CreateEnrollmentRequest{
   804  				Enrollment: Enrollment{
   805  					AdminContact: &Contact{
   806  						Email: "r1d1@akamai.com",
   807  					},
   808  					CertificateType: "third-party",
   809  					CSR: &CSR{
   810  						CN: "www.example.com",
   811  					},
   812  					NetworkConfiguration: &NetworkConfiguration{},
   813  					Org:                  &Org{Name: "Akamai"},
   814  					RA:                   "third-party",
   815  					TechContact: &Contact{
   816  						Email: "r2d2@akamai.com",
   817  					},
   818  					ValidationType: "third-party",
   819  				},
   820  				ContractID:       "ctr-1",
   821  				DeployNotAfter:   "12-12-2021",
   822  				DeployNotBefore:  "12-07-2020",
   823  				AllowDuplicateCN: true,
   824  			},
   825  			responseStatus: http.StatusAccepted,
   826  			responseBody: `
   827  {
   828  	"enrollment": "/cps-api/enrollments/1",
   829  	"changes": ["/cps-api/enrollments/1/changes/10002"]
   830  }`,
   831  			expectedPath: "/cps/v2/enrollments?allow-duplicate-cn=true&contractId=ctr-1&deploy-not-after=12-12-2021&deploy-not-before=12-07-2020",
   832  			expectedResponse: &CreateEnrollmentResponse{
   833  				Enrollment: "/cps-api/enrollments/1",
   834  				Changes:    []string{"/cps-api/enrollments/1/changes/10002"},
   835  				ID:         1,
   836  			},
   837  		},
   838  		"500 internal server error": {
   839  			request: CreateEnrollmentRequest{
   840  				Enrollment: Enrollment{
   841  					AdminContact: &Contact{
   842  						Email: "r1d1@akamai.com",
   843  					},
   844  					CertificateType: "third-party",
   845  					CSR: &CSR{
   846  						CN: "www.example.com",
   847  					},
   848  					NetworkConfiguration: &NetworkConfiguration{},
   849  					Org:                  &Org{Name: "Akamai"},
   850  					RA:                   "third-party",
   851  					TechContact: &Contact{
   852  						Email: "r2d2@akamai.com",
   853  					},
   854  					ValidationType: "third-party",
   855  				},
   856  				ContractID:      "ctr-1",
   857  				DeployNotAfter:  "12-12-2021",
   858  				DeployNotBefore: "12-07-2020",
   859  			},
   860  			responseStatus: http.StatusInternalServerError,
   861  			responseBody: `
   862  {
   863    "type": "internal_error",
   864    "title": "Internal Server Error",
   865    "detail": "Error creating enrollment",
   866    "status": 500
   867  }`,
   868  			expectedPath: "/cps/v2/enrollments?contractId=ctr-1&deploy-not-after=12-12-2021&deploy-not-before=12-07-2020",
   869  			withError: &Error{
   870  				Type:       "internal_error",
   871  				Title:      "Internal Server Error",
   872  				Detail:     "Error creating enrollment",
   873  				StatusCode: http.StatusInternalServerError,
   874  			},
   875  		},
   876  		"validation error": {
   877  			request:   CreateEnrollmentRequest{},
   878  			withError: ErrStructValidation,
   879  		},
   880  		"invalid location": {
   881  			request: CreateEnrollmentRequest{
   882  				Enrollment: Enrollment{
   883  					AdminContact: &Contact{
   884  						Email: "r1d1@akamai.com",
   885  					},
   886  					CertificateType: "third-party",
   887  					CSR: &CSR{
   888  						CN: "www.example.com",
   889  					},
   890  					NetworkConfiguration: &NetworkConfiguration{},
   891  					Org:                  &Org{Name: "Akamai"},
   892  					RA:                   "third-party",
   893  					TechContact: &Contact{
   894  						Email: "r2d2@akamai.com",
   895  					},
   896  					ValidationType: "third-party",
   897  				},
   898  				ContractID:      "ctr-1",
   899  				DeployNotAfter:  "12-12-2021",
   900  				DeployNotBefore: "12-07-2020",
   901  			},
   902  			responseStatus: http.StatusAccepted,
   903  			responseBody: `
   904  {
   905  	"enrollment": "abc",
   906  	"changes": ["/cps-api/enrollments/1/changes/10002"]
   907  }`,
   908  			expectedPath: "/cps/v2/enrollments?contractId=ctr-1&deploy-not-after=12-12-2021&deploy-not-before=12-07-2020",
   909  			withError:    ErrInvalidLocation,
   910  		},
   911  	}
   912  
   913  	for name, test := range tests {
   914  		t.Run(name, func(t *testing.T) {
   915  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   916  				assert.Equal(t, test.expectedPath, r.URL.String())
   917  				assert.Equal(t, http.MethodPost, r.Method)
   918  				assert.Equal(t, "application/vnd.akamai.cps.enrollment-status.v1+json", r.Header.Get("Accept"))
   919  				assert.Equal(t, "application/vnd.akamai.cps.enrollment.v9+json", r.Header.Get("Content-Type"))
   920  				w.WriteHeader(test.responseStatus)
   921  				_, err := w.Write([]byte(test.responseBody))
   922  				assert.NoError(t, err)
   923  			}))
   924  			client := mockAPIClient(t, mockServer)
   925  			result, err := client.CreateEnrollment(context.Background(), test.request)
   926  			if test.withError != nil {
   927  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   928  				return
   929  			}
   930  			require.NoError(t, err)
   931  			assert.Equal(t, test.expectedResponse, result)
   932  		})
   933  	}
   934  }
   935  
   936  func TestUpdateEnrollment(t *testing.T) {
   937  	tests := map[string]struct {
   938  		request          UpdateEnrollmentRequest
   939  		responseStatus   int
   940  		responseBody     string
   941  		expectedPath     string
   942  		expectedResponse *UpdateEnrollmentResponse
   943  		withError        error
   944  	}{
   945  		"202 accepted": {
   946  			request: UpdateEnrollmentRequest{
   947  				EnrollmentID: 1,
   948  				Enrollment: Enrollment{
   949  					AdminContact: &Contact{
   950  						Email: "r1d1@akamai.com",
   951  					},
   952  					CertificateType: "third-party",
   953  					CSR: &CSR{
   954  						CN: "www.example.com",
   955  					},
   956  					NetworkConfiguration: &NetworkConfiguration{},
   957  					Org:                  &Org{Name: "Akamai"},
   958  					RA:                   "third-party",
   959  					TechContact: &Contact{
   960  						Email: "r2d2@akamai.com",
   961  					},
   962  					ValidationType: "third-party",
   963  				},
   964  				DeployNotAfter:            "12-12-2021",
   965  				DeployNotBefore:           "12-07-2020",
   966  				RenewalDateCheckOverride:  BoolPtr(true),
   967  				AllowCancelPendingChanges: BoolPtr(true),
   968  				AllowStagingBypass:        BoolPtr(true),
   969  				ForceRenewal:              BoolPtr(true),
   970  			},
   971  			responseStatus: http.StatusAccepted,
   972  			responseBody: `
   973  {
   974  	"enrollment": "/cps-api/enrollments/1",
   975  	"changes": ["/cps-api/enrollments/1/changes/10002"]
   976  }`,
   977  			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",
   978  			expectedResponse: &UpdateEnrollmentResponse{
   979  				Enrollment: "/cps-api/enrollments/1",
   980  				Changes:    []string{"/cps-api/enrollments/1/changes/10002"},
   981  				ID:         1,
   982  			},
   983  		},
   984  		"500 internal server error": {
   985  			request: UpdateEnrollmentRequest{
   986  				EnrollmentID: 1,
   987  				Enrollment: Enrollment{
   988  					AdminContact: &Contact{
   989  						Email: "r1d1@akamai.com",
   990  					},
   991  					CertificateType: "third-party",
   992  					CSR: &CSR{
   993  						CN: "www.example.com",
   994  					},
   995  					NetworkConfiguration: &NetworkConfiguration{},
   996  					Org:                  &Org{Name: "Akamai"},
   997  					RA:                   "third-party",
   998  					TechContact: &Contact{
   999  						Email: "r2d2@akamai.com",
  1000  					},
  1001  					ValidationType: "third-party",
  1002  				},
  1003  				DeployNotAfter:  "12-12-2021",
  1004  				DeployNotBefore: "12-07-2020",
  1005  			},
  1006  			responseStatus: http.StatusInternalServerError,
  1007  			responseBody: `
  1008  {
  1009  	"type": "internal_error",
  1010    "title": "Internal Server Error",
  1011    "detail": "Error updating enrollment",
  1012    "status": 500
  1013  }`,
  1014  			expectedPath: "/cps/v2/enrollments/1?deploy-not-after=12-12-2021&deploy-not-before=12-07-2020",
  1015  			withError: &Error{
  1016  				Type:       "internal_error",
  1017  				Title:      "Internal Server Error",
  1018  				Detail:     "Error updating enrollment",
  1019  				StatusCode: http.StatusInternalServerError,
  1020  			},
  1021  		},
  1022  		"validation error": {
  1023  			request:   UpdateEnrollmentRequest{},
  1024  			withError: ErrStructValidation,
  1025  		},
  1026  		"invalid location URL": {
  1027  			request: UpdateEnrollmentRequest{
  1028  				EnrollmentID: 1,
  1029  				Enrollment: Enrollment{
  1030  					AdminContact: &Contact{
  1031  						Email: "r1d1@akamai.com",
  1032  					},
  1033  					CertificateType: "third-party",
  1034  					CSR: &CSR{
  1035  						CN: "www.example.com",
  1036  					},
  1037  					NetworkConfiguration: &NetworkConfiguration{},
  1038  					Org:                  &Org{Name: "Akamai"},
  1039  					RA:                   "third-party",
  1040  					TechContact: &Contact{
  1041  						Email: "r2d2@akamai.com",
  1042  					},
  1043  					ValidationType: "third-party",
  1044  				},
  1045  				DeployNotAfter:            "12-12-2021",
  1046  				DeployNotBefore:           "12-07-2020",
  1047  				RenewalDateCheckOverride:  BoolPtr(true),
  1048  				AllowCancelPendingChanges: BoolPtr(true),
  1049  				AllowStagingBypass:        BoolPtr(true),
  1050  				ForceRenewal:              BoolPtr(true),
  1051  			},
  1052  			responseStatus: http.StatusAccepted,
  1053  			responseBody: `
  1054  {
  1055  	"enrollment": "abc",
  1056  	"changes": ["/cps-api/enrollments/1/changes/10002"]
  1057  }`,
  1058  			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",
  1059  			withError:    ErrInvalidLocation,
  1060  		},
  1061  	}
  1062  
  1063  	for name, test := range tests {
  1064  		t.Run(name, func(t *testing.T) {
  1065  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1066  				assert.Equal(t, test.expectedPath, r.URL.String())
  1067  				assert.Equal(t, http.MethodPut, r.Method)
  1068  				assert.Equal(t, "application/vnd.akamai.cps.enrollment-status.v1+json", r.Header.Get("Accept"))
  1069  				assert.Equal(t, "application/vnd.akamai.cps.enrollment.v9+json", r.Header.Get("Content-Type"))
  1070  				w.WriteHeader(test.responseStatus)
  1071  				_, err := w.Write([]byte(test.responseBody))
  1072  				assert.NoError(t, err)
  1073  			}))
  1074  			client := mockAPIClient(t, mockServer)
  1075  			result, err := client.UpdateEnrollment(context.Background(), test.request)
  1076  			if test.withError != nil {
  1077  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
  1078  				return
  1079  			}
  1080  			require.NoError(t, err)
  1081  			assert.Equal(t, test.expectedResponse, result)
  1082  		})
  1083  	}
  1084  }
  1085  
  1086  func TestRemoveEnrollment(t *testing.T) {
  1087  	tests := map[string]struct {
  1088  		request          RemoveEnrollmentRequest
  1089  		responseStatus   int
  1090  		responseBody     string
  1091  		expectedPath     string
  1092  		expectedResponse *RemoveEnrollmentResponse
  1093  		withError        error
  1094  	}{
  1095  		"200 OK": {
  1096  			request: RemoveEnrollmentRequest{
  1097  				EnrollmentID:              1,
  1098  				AllowCancelPendingChanges: BoolPtr(true),
  1099  				DeployNotAfter:            "12-12-2021",
  1100  				DeployNotBefore:           "12-07-2021",
  1101  			},
  1102  			responseStatus: http.StatusOK,
  1103  			responseBody: `
  1104  {
  1105  	"enrollment": "/cps-api/enrollments/1",
  1106  	"changes": ["/cps-api/enrollments/1/changes/10002"]
  1107  }`,
  1108  			expectedPath: "/cps/v2/enrollments/1?allow-cancel-pending-changes=true&deploy-not-after=12-12-2021&deploy-not-before=12-07-2021",
  1109  			expectedResponse: &RemoveEnrollmentResponse{
  1110  				Enrollment: "/cps-api/enrollments/1",
  1111  				Changes:    []string{"/cps-api/enrollments/1/changes/10002"},
  1112  			},
  1113  		},
  1114  		"500 internal server error": {
  1115  			request: RemoveEnrollmentRequest{
  1116  				EnrollmentID:              1,
  1117  				AllowCancelPendingChanges: BoolPtr(true),
  1118  				DeployNotAfter:            "12-12-2021",
  1119  				DeployNotBefore:           "12-07-2021",
  1120  			},
  1121  			responseStatus: http.StatusInternalServerError,
  1122  			responseBody: `
  1123  {
  1124  	"type": "internal_error",
  1125      "title": "Internal Server Error",
  1126      "detail": "Error removing enrollment",
  1127      "status": 500
  1128  }`,
  1129  			expectedPath: "/cps/v2/enrollments/1?allow-cancel-pending-changes=true&deploy-not-after=12-12-2021&deploy-not-before=12-07-2021",
  1130  			withError: &Error{
  1131  				Type:       "internal_error",
  1132  				Title:      "Internal Server Error",
  1133  				Detail:     "Error removing enrollment",
  1134  				StatusCode: http.StatusInternalServerError,
  1135  			},
  1136  		},
  1137  		"validation error": {
  1138  			request:   RemoveEnrollmentRequest{},
  1139  			withError: ErrStructValidation,
  1140  		},
  1141  	}
  1142  
  1143  	for name, test := range tests {
  1144  		t.Run(name, func(t *testing.T) {
  1145  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1146  				assert.Equal(t, test.expectedPath, r.URL.String())
  1147  				assert.Equal(t, http.MethodDelete, r.Method)
  1148  				assert.Equal(t, "application/vnd.akamai.cps.enrollment-status.v1+json", r.Header.Get("Accept"))
  1149  				w.WriteHeader(test.responseStatus)
  1150  				_, err := w.Write([]byte(test.responseBody))
  1151  				assert.NoError(t, err)
  1152  			}))
  1153  			client := mockAPIClient(t, mockServer)
  1154  			result, err := client.RemoveEnrollment(context.Background(), test.request)
  1155  			if test.withError != nil {
  1156  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
  1157  				return
  1158  			}
  1159  			require.NoError(t, err)
  1160  			assert.Equal(t, test.expectedResponse, result)
  1161  		})
  1162  	}
  1163  }
  1164  
  1165  func BoolPtr(b bool) *bool {
  1166  	return &b
  1167  }