1package cloudflare
2
3import (
4	"context"
5	"fmt"
6	"io/ioutil"
7	"net/http"
8	"testing"
9	"time"
10
11	"github.com/stretchr/testify/assert"
12)
13
14func TestCreateSSL(t *testing.T) {
15	setup()
16	defer teardown()
17
18	handler := func(w http.ResponseWriter, r *http.Request) {
19		assert.Equal(t, http.MethodPost, r.Method, "Expected method 'POST', got %s", r.Method)
20		b, err := ioutil.ReadAll(r.Body)
21		defer r.Body.Close()
22
23		if assert.NoError(t, err) {
24			assert.JSONEq(t, `{"certificate":"-----BEGIN CERTIFICATE----- MIIDtTCCAp2gAwIBAgIJAM15n7fdxhRtMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwMzExMTkyMTU5WhcNMTQwNDEwMTkyMTU5WjBF MQswCQYDVQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvq3sKsHpeduJHimOK+fvQdKsI8z8A05MZyyLp2/R/GE8FjNv+hkVY1WQ LIyTNNQH7CJecE1nbTfo8Y56S7x/rhxC6/DJ8MIulapFPnorq46KU6yRxiM0MQ3N nTJHlHA2ozZta6YBBfVfhHWl1F0IfNbXCLKvGwWWMbCx43OfW6KTkbRnE6gFWKuO fSO5h2u5TaWVuSIzBvYs7Vza6m+gtYAvKAJV2nSZ+eSEFPDo29corOy8+huEOUL8 5FAw4BFPsr1TlrlGPFitduQUHGrSL7skk1ESGza0to3bOtrodKei2s9bk5MXm7lZ qI+WZJX4Zu9+mzZhc9pCVi8r/qlXuQIDAQABo4GnMIGkMB0GA1UdDgQWBBRvavf+ sWM4IwKiH9X9w1vl6nUVRDB1BgNVHSMEbjBsgBRvavf+sWM4IwKiH9X9w1vl6nUV RKFJpEcwRTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAM15n7fdxhRtMAwGA1UdEwQF MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABY2ZzBaW0dMsAAT7tPJzrVWVzQx6KU4 UEBLudIlWPlkAwTnINCWR/8eNjCCmGA4heUdHmazdpPa8RzwOmc0NT1NQqzSyktt vTqb4iHD7+8f9MqJ9/FssCfTtqr/Qst/hGH4Wmdf1EJ/6FqYAAb5iRlPgshFZxU8 uXtA8hWn6fK6eISD9HBdcAFToUvKNZ1BIDPvh9f95Ine8ar6yGd56TUNrHR8eHBs ESxz5ddVR/oWRysNJ+aGAyYqHS8S/ttmC7r4XCAHqXptkHPCGRqkAhsterYhd4I8 /cBzejUobNCjjHFbtkAL/SjxZOLW+pNkZwfeYdM8iPkD54Uua1v2tdw= -----END CERTIFICATE-----","geo_restrictions":{"label":"us"},"private_key":"-----BEGIN RSA PRIVATE KEY-----MIIEowIBAAKCAQEAl 1cSc0vfcJLI4ZdWjiZZqy86Eof4czCwilyjXdvHqbdgDjz9H6K/0FX78EzVdfyExESptPCDl5YYjvcZyAWlgNfYEpFpGeoh/pTFW3hlyKImh4EgBXbDrR251J Ew2Nf56X3duibI6X20gKZA6cvdmWeKh MOOXuh1bSPU3dkb4YOF/fng5iGrx0q3txdMQXTPMZ1uXHFcBH7idgViYesXUBhdll3GP1N Y8laq0yrqh 8HMsZK m27MebqonbNmjOqE218lVEvjCdRO6xvNXrO6vNJBoGn2eGwZ8BVd0mTA3Tj43/2cmxQFY9FLq56cCXqYI1fbRRib ZLrjSNkwIDAQABAoIBABfAjjsjjxc0NxcYvKOMUb9Rpj8Sx6U/o/tDC5u XmsGX37aaJmC5yw9BQiAxgvXtQryEl5uoNoqOdsxzKV6yM0vPcwKEJVBd4G6yx6AjVJZnc2qf72erR7BbA2CQh scMDRBKE041HhgTBRNP6roim0SOgYP5JZIrGAQXNIkyE0fZc5gZNUt388ne/mjWM6Xi08BDGurLC68nsdt7Nd UYqeBVxo2EqChp5vKYZYEcG8h9XBj4u4NIwg1Mty2JqX30uBjoHvF5w/pMs8lG uvj6JR9I 19wtCuccbAJl 4cUq03UQoIDmwejea oC8A8WJr3vVpODDWrvAsjllGPBECgYEAyQRa6edYO6bsSvgbM13qXW9OQTn9YmgzfN24Ux1D66TQU6sBSLdfSHshDhTCi Ax 698aJNRWujAakA2DDgspSx98aRnHbF zvY7i7iWGesN6uN0zL 6/MK5uWoieGZRjgk230fLk00l4/FK1mJIp0apr0Lis9xmDjP5AaUPTUUCgYEAwXuhTHZWPT6v8YwOksjbuK UDkIIvyMux53kb73vrkgMboS4DB1zMLNyG 9EghS414CFROUwGl4ZUKboH1Jo5G34y8VgDuHjirTqL2H6 zNpML iMrWCXjpFKkxwPbeQnEAZ 5Rud4d PTyXAt71blZHE9tZ4KHy8cU1iKc9APcCgYAIqKZd4vg7AZK2G//X85iv06aUSrIudfyZyVcyRVVyphPPNtOEVVnGXn9rAtvqeIrOo52BR68 cj4vlXp hkDuEH QVBuY/NdQhOzFtPrKPQTJdGjIlQ2x65Vidj7r3sRukNkLPyV2v D885zcpTkp83JFuWTYiIrg275DIuAI3QKBgAglM0IrzS g3vlVQxvM1ussgRgkkYeybHq82 wUW 3DXLqeXb0s1DedplUkuoabZriz0Wh4GZFSmtA5ZpZC uV697lkYsndmp2xRhaekllW7bu pY5q88URwO2p8CO5AZ6CWFWuBwSDML5VOapGRqDRgwaD oGpb7fb7IgHOls7AoGBAJnL6Q8t35uYJ8J8hY7wso88IE04z6VaT8WganxcndesWER9eFQDHDDy//ZYeyt6M41uIY CL Vkm9Kwl/bHLJKdnOE1a9NdE6mtfah0Bk2u/YOuzyu5mmcgZiX X/OZuEbGmmbZOR1FCuIyrNYfwYohhcZP7/r0Ia/1GpkHc3Bi-----END RSA PRIVATE KEY-----","bundle_method":"ubiquitous"}`, string(b))
25		}
26
27		w.Header().Set("content-type", "application/json")
28		fmt.Fprint(w, `{
29          "success": true,
30          "errors": [],
31          "messages": [],
32          "result": {
33            "id": "7e7b8deba8538af625850b7b2530034c",
34            "hosts": [
35              "example.com"
36            ],
37            "issuer": "GlobalSign",
38            "signature": "SHA256WithRSA",
39            "status": "active",
40            "bundle_method": "ubiquitous",
41            "geo_restrictions": {
42               "label": "us"
43            },
44            "zone_id": "023e105f4ecef8ad9ca31a8372d0c353",
45            "uploaded_on": "2014-01-01T05:20:00Z",
46            "modified_on": "2014-01-01T05:20:00Z",
47            "expires_on": "2016-01-01T05:20:00Z",
48            "priority": 1
49          }
50        }`)
51	}
52
53	mux.HandleFunc("/zones/023e105f4ecef8ad9ca31a8372d0c353/custom_certificates", handler)
54
55	hosts := make([]string, 1, 4)
56	hosts[0] = "example.com"
57	uploadedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
58	modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
59	expiresOn, _ := time.Parse(time.RFC3339, "2016-01-01T05:20:00Z")
60	want := ZoneCustomSSL{
61		ID:              "7e7b8deba8538af625850b7b2530034c",
62		Hosts:           hosts,
63		Issuer:          "GlobalSign",
64		Signature:       "SHA256WithRSA",
65		Status:          "active",
66		BundleMethod:    "ubiquitous",
67		GeoRestrictions: ZoneCustomSSLGeoRestrictions{Label: "us"},
68		ZoneID:          "023e105f4ecef8ad9ca31a8372d0c353",
69		UploadedOn:      uploadedOn,
70		ModifiedOn:      modifiedOn,
71		ExpiresOn:       expiresOn,
72		Priority:        1,
73	}
74
75	actual, err := client.CreateSSL(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", ZoneCustomSSLOptions{
76		Certificate:     "-----BEGIN CERTIFICATE----- MIIDtTCCAp2gAwIBAgIJAM15n7fdxhRtMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwMzExMTkyMTU5WhcNMTQwNDEwMTkyMTU5WjBF MQswCQYDVQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvq3sKsHpeduJHimOK+fvQdKsI8z8A05MZyyLp2/R/GE8FjNv+hkVY1WQ LIyTNNQH7CJecE1nbTfo8Y56S7x/rhxC6/DJ8MIulapFPnorq46KU6yRxiM0MQ3N nTJHlHA2ozZta6YBBfVfhHWl1F0IfNbXCLKvGwWWMbCx43OfW6KTkbRnE6gFWKuO fSO5h2u5TaWVuSIzBvYs7Vza6m+gtYAvKAJV2nSZ+eSEFPDo29corOy8+huEOUL8 5FAw4BFPsr1TlrlGPFitduQUHGrSL7skk1ESGza0to3bOtrodKei2s9bk5MXm7lZ qI+WZJX4Zu9+mzZhc9pCVi8r/qlXuQIDAQABo4GnMIGkMB0GA1UdDgQWBBRvavf+ sWM4IwKiH9X9w1vl6nUVRDB1BgNVHSMEbjBsgBRvavf+sWM4IwKiH9X9w1vl6nUV RKFJpEcwRTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAM15n7fdxhRtMAwGA1UdEwQF MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABY2ZzBaW0dMsAAT7tPJzrVWVzQx6KU4 UEBLudIlWPlkAwTnINCWR/8eNjCCmGA4heUdHmazdpPa8RzwOmc0NT1NQqzSyktt vTqb4iHD7+8f9MqJ9/FssCfTtqr/Qst/hGH4Wmdf1EJ/6FqYAAb5iRlPgshFZxU8 uXtA8hWn6fK6eISD9HBdcAFToUvKNZ1BIDPvh9f95Ine8ar6yGd56TUNrHR8eHBs ESxz5ddVR/oWRysNJ+aGAyYqHS8S/ttmC7r4XCAHqXptkHPCGRqkAhsterYhd4I8 /cBzejUobNCjjHFbtkAL/SjxZOLW+pNkZwfeYdM8iPkD54Uua1v2tdw= -----END CERTIFICATE-----",
77		PrivateKey:      "-----BEGIN RSA PRIVATE KEY-----MIIEowIBAAKCAQEAl 1cSc0vfcJLI4ZdWjiZZqy86Eof4czCwilyjXdvHqbdgDjz9H6K/0FX78EzVdfyExESptPCDl5YYjvcZyAWlgNfYEpFpGeoh/pTFW3hlyKImh4EgBXbDrR251J Ew2Nf56X3duibI6X20gKZA6cvdmWeKh MOOXuh1bSPU3dkb4YOF/fng5iGrx0q3txdMQXTPMZ1uXHFcBH7idgViYesXUBhdll3GP1N Y8laq0yrqh 8HMsZK m27MebqonbNmjOqE218lVEvjCdRO6xvNXrO6vNJBoGn2eGwZ8BVd0mTA3Tj43/2cmxQFY9FLq56cCXqYI1fbRRib ZLrjSNkwIDAQABAoIBABfAjjsjjxc0NxcYvKOMUb9Rpj8Sx6U/o/tDC5u XmsGX37aaJmC5yw9BQiAxgvXtQryEl5uoNoqOdsxzKV6yM0vPcwKEJVBd4G6yx6AjVJZnc2qf72erR7BbA2CQh scMDRBKE041HhgTBRNP6roim0SOgYP5JZIrGAQXNIkyE0fZc5gZNUt388ne/mjWM6Xi08BDGurLC68nsdt7Nd UYqeBVxo2EqChp5vKYZYEcG8h9XBj4u4NIwg1Mty2JqX30uBjoHvF5w/pMs8lG uvj6JR9I 19wtCuccbAJl 4cUq03UQoIDmwejea oC8A8WJr3vVpODDWrvAsjllGPBECgYEAyQRa6edYO6bsSvgbM13qXW9OQTn9YmgzfN24Ux1D66TQU6sBSLdfSHshDhTCi Ax 698aJNRWujAakA2DDgspSx98aRnHbF zvY7i7iWGesN6uN0zL 6/MK5uWoieGZRjgk230fLk00l4/FK1mJIp0apr0Lis9xmDjP5AaUPTUUCgYEAwXuhTHZWPT6v8YwOksjbuK UDkIIvyMux53kb73vrkgMboS4DB1zMLNyG 9EghS414CFROUwGl4ZUKboH1Jo5G34y8VgDuHjirTqL2H6 zNpML iMrWCXjpFKkxwPbeQnEAZ 5Rud4d PTyXAt71blZHE9tZ4KHy8cU1iKc9APcCgYAIqKZd4vg7AZK2G//X85iv06aUSrIudfyZyVcyRVVyphPPNtOEVVnGXn9rAtvqeIrOo52BR68 cj4vlXp hkDuEH QVBuY/NdQhOzFtPrKPQTJdGjIlQ2x65Vidj7r3sRukNkLPyV2v D885zcpTkp83JFuWTYiIrg275DIuAI3QKBgAglM0IrzS g3vlVQxvM1ussgRgkkYeybHq82 wUW 3DXLqeXb0s1DedplUkuoabZriz0Wh4GZFSmtA5ZpZC uV697lkYsndmp2xRhaekllW7bu pY5q88URwO2p8CO5AZ6CWFWuBwSDML5VOapGRqDRgwaD oGpb7fb7IgHOls7AoGBAJnL6Q8t35uYJ8J8hY7wso88IE04z6VaT8WganxcndesWER9eFQDHDDy//ZYeyt6M41uIY CL Vkm9Kwl/bHLJKdnOE1a9NdE6mtfah0Bk2u/YOuzyu5mmcgZiX X/OZuEbGmmbZOR1FCuIyrNYfwYohhcZP7/r0Ia/1GpkHc3Bi-----END RSA PRIVATE KEY-----",
78		BundleMethod:    "ubiquitous",
79		GeoRestrictions: &ZoneCustomSSLGeoRestrictions{Label: "us"},
80	})
81
82	if assert.NoError(t, err) {
83		assert.Equal(t, want, actual)
84	}
85
86	_, err = client.CreateSSL(context.Background(), "bar", ZoneCustomSSLOptions{})
87	assert.Error(t, err)
88}
89
90func TestListSSL(t *testing.T) {
91	setup()
92	defer teardown()
93
94	handler := func(w http.ResponseWriter, r *http.Request) {
95		assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
96		w.Header().Set("content-type", "application/json")
97		fmt.Fprint(w, `{
98          "success": true,
99          "errors": [],
100          "messages": [],
101          "result": [
102            {
103              "id": "7e7b8deba8538af625850b7b2530034c",
104              "hosts": [
105                "example.com"
106              ],
107              "issuer": "GlobalSign",
108              "signature": "SHA256WithRSA",
109              "status": "active",
110              "bundle_method": "ubiquitous",
111              "zone_id": "023e105f4ecef8ad9ca31a8372d0c353",
112              "uploaded_on": "2014-01-01T05:20:00Z",
113              "modified_on": "2014-01-01T05:20:00Z",
114              "expires_on": "2016-01-01T05:20:00Z",
115              "priority": 1
116            }
117          ],
118          "result_info": {
119            "page": 1,
120            "per_page": 20,
121            "count": 1,
122            "total_count": 2000
123          }
124        }`)
125	}
126
127	mux.HandleFunc("/zones/023e105f4ecef8ad9ca31a8372d0c353/custom_certificates", handler)
128
129	hosts := make([]string, 1, 4)
130	hosts[0] = "example.com"
131	uploadedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
132	modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
133	expiresOn, _ := time.Parse(time.RFC3339, "2016-01-01T05:20:00Z")
134
135	want := make([]ZoneCustomSSL, 1, 4)
136	want[0] = ZoneCustomSSL{
137		ID:           "7e7b8deba8538af625850b7b2530034c",
138		Hosts:        hosts,
139		Issuer:       "GlobalSign",
140		Signature:    "SHA256WithRSA",
141		Status:       "active",
142		BundleMethod: "ubiquitous",
143		ZoneID:       "023e105f4ecef8ad9ca31a8372d0c353",
144		UploadedOn:   uploadedOn,
145		ModifiedOn:   modifiedOn,
146		ExpiresOn:    expiresOn,
147		Priority:     1,
148	}
149
150	actual, err := client.ListSSL(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353")
151	if assert.NoError(t, err) {
152		assert.Equal(t, want, actual)
153	}
154
155	_, err = client.ListSSL(context.Background(), "bar")
156	assert.Error(t, err)
157}
158
159func TestSSLDetails(t *testing.T) {
160	setup()
161	defer teardown()
162
163	handler := func(w http.ResponseWriter, r *http.Request) {
164		w.Header().Set("content-type", "application/json")
165		fmt.Fprint(w, `{
166          "success": true,
167          "errors": [],
168          "messages": [],
169          "result": {
170            "id": "7e7b8deba8538af625850b7b2530034c",
171            "hosts": [
172              "example.com"
173            ],
174            "issuer": "GlobalSign",
175            "signature": "SHA256WithRSA",
176            "status": "active",
177            "bundle_method": "ubiquitous",
178            "zone_id": "023e105f4ecef8ad9ca31a8372d0c353",
179            "uploaded_on": "2014-01-01T05:20:00Z",
180            "modified_on": "2014-01-01T05:20:00Z",
181            "expires_on": "2016-01-01T05:20:00Z",
182            "priority": 1
183          }
184        }`)
185	}
186
187	mux.HandleFunc("/zones/023e105f4ecef8ad9ca31a8372d0c353/custom_certificates/7e7b8deba8538af625850b7b2530034c", handler)
188
189	hosts := make([]string, 1, 4)
190	hosts[0] = "example.com"
191	uploadedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
192	modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
193	expiresOn, _ := time.Parse(time.RFC3339, "2016-01-01T05:20:00Z")
194	want := ZoneCustomSSL{
195		ID:           "7e7b8deba8538af625850b7b2530034c",
196		Hosts:        hosts,
197		Issuer:       "GlobalSign",
198		Signature:    "SHA256WithRSA",
199		Status:       "active",
200		BundleMethod: "ubiquitous",
201		ZoneID:       "023e105f4ecef8ad9ca31a8372d0c353",
202		UploadedOn:   uploadedOn,
203		ModifiedOn:   modifiedOn,
204		ExpiresOn:    expiresOn,
205		Priority:     1,
206	}
207
208	actual, err := client.SSLDetails(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", "7e7b8deba8538af625850b7b2530034c")
209	if assert.NoError(t, err) {
210		assert.Equal(t, want, actual)
211	}
212
213	_, err = client.SSLDetails(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", "bar")
214	assert.Error(t, err)
215}
216
217func TestUpdateSSL(t *testing.T) {
218	setup()
219	defer teardown()
220
221	handler := func(w http.ResponseWriter, r *http.Request) {
222		assert.Equal(t, http.MethodPatch, r.Method, "Expected method 'PATCH', got %s", r.Method)
223		b, err := ioutil.ReadAll(r.Body)
224		defer r.Body.Close()
225		if assert.NoError(t, err) {
226			assert.JSONEq(t, `{"certificate":"-----BEGIN CERTIFICATE----- MIIDtTCCAp2gAwIBAgIJAM15n7fdxhRtMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwMzExMTkyMTU5WhcNMTQwNDEwMTkyMTU5WjBF MQswCQYDVQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvq3sKsHpeduJHimOK+fvQdKsI8z8A05MZyyLp2/R/GE8FjNv+hkVY1WQ LIyTNNQH7CJecE1nbTfo8Y56S7x/rhxC6/DJ8MIulapFPnorq46KU6yRxiM0MQ3N nTJHlHA2ozZta6YBBfVfhHWl1F0IfNbXCLKvGwWWMbCx43OfW6KTkbRnE6gFWKuO fSO5h2u5TaWVuSIzBvYs7Vza6m+gtYAvKAJV2nSZ+eSEFPDo29corOy8+huEOUL8 5FAw4BFPsr1TlrlGPFitduQUHGrSL7skk1ESGza0to3bOtrodKei2s9bk5MXm7lZ qI+WZJX4Zu9+mzZhc9pCVi8r/qlXuQIDAQABo4GnMIGkMB0GA1UdDgQWBBRvavf+ sWM4IwKiH9X9w1vl6nUVRDB1BgNVHSMEbjBsgBRvavf+sWM4IwKiH9X9w1vl6nUV RKFJpEcwRTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAM15n7fdxhRtMAwGA1UdEwQF MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABY2ZzBaW0dMsAAT7tPJzrVWVzQx6KU4 UEBLudIlWPlkAwTnINCWR/8eNjCCmGA4heUdHmazdpPa8RzwOmc0NT1NQqzSyktt vTqb4iHD7+8f9MqJ9/FssCfTtqr/Qst/hGH4Wmdf1EJ/6FqYAAb5iRlPgshFZxU8 uXtA8hWn6fK6eISD9HBdcAFToUvKNZ1BIDPvh9f95Ine8ar6yGd56TUNrHR8eHBs ESxz5ddVR/oWRysNJ+aGAyYqHS8S/ttmC7r4XCAHqXptkHPCGRqkAhsterYhd4I8 /cBzejUobNCjjHFbtkAL/SjxZOLW+pNkZwfeYdM8iPkD54Uua1v2tdw= -----END CERTIFICATE-----","geo_restrictions":{"label":"us"},"private_key":"-----BEGIN RSA PRIVATE KEY-----MIIEowIBAAKCAQEAl 1cSc0vfcJLI4ZdWjiZZqy86Eof4czCwilyjXdvHqbdgDjz9H6K/0FX78EzVdfyExESptPCDl5YYjvcZyAWlgNfYEpFpGeoh/pTFW3hlyKImh4EgBXbDrR251J Ew2Nf56X3duibI6X20gKZA6cvdmWeKh MOOXuh1bSPU3dkb4YOF/fng5iGrx0q3txdMQXTPMZ1uXHFcBH7idgViYesXUBhdll3GP1N Y8laq0yrqh 8HMsZK m27MebqonbNmjOqE218lVEvjCdRO6xvNXrO6vNJBoGn2eGwZ8BVd0mTA3Tj43/2cmxQFY9FLq56cCXqYI1fbRRib ZLrjSNkwIDAQABAoIBABfAjjsjjxc0NxcYvKOMUb9Rpj8Sx6U/o/tDC5u XmsGX37aaJmC5yw9BQiAxgvXtQryEl5uoNoqOdsxzKV6yM0vPcwKEJVBd4G6yx6AjVJZnc2qf72erR7BbA2CQh scMDRBKE041HhgTBRNP6roim0SOgYP5JZIrGAQXNIkyE0fZc5gZNUt388ne/mjWM6Xi08BDGurLC68nsdt7Nd UYqeBVxo2EqChp5vKYZYEcG8h9XBj4u4NIwg1Mty2JqX30uBjoHvF5w/pMs8lG uvj6JR9I 19wtCuccbAJl 4cUq03UQoIDmwejea oC8A8WJr3vVpODDWrvAsjllGPBECgYEAyQRa6edYO6bsSvgbM13qXW9OQTn9YmgzfN24Ux1D66TQU6sBSLdfSHshDhTCi Ax 698aJNRWujAakA2DDgspSx98aRnHbF zvY7i7iWGesN6uN0zL 6/MK5uWoieGZRjgk230fLk00l4/FK1mJIp0apr0Lis9xmDjP5AaUPTUUCgYEAwXuhTHZWPT6v8YwOksjbuK UDkIIvyMux53kb73vrkgMboS4DB1zMLNyG 9EghS414CFROUwGl4ZUKboH1Jo5G34y8VgDuHjirTqL2H6 zNpML iMrWCXjpFKkxwPbeQnEAZ 5Rud4d PTyXAt71blZHE9tZ4KHy8cU1iKc9APcCgYAIqKZd4vg7AZK2G//X85iv06aUSrIudfyZyVcyRVVyphPPNtOEVVnGXn9rAtvqeIrOo52BR68 cj4vlXp hkDuEH QVBuY/NdQhOzFtPrKPQTJdGjIlQ2x65Vidj7r3sRukNkLPyV2v D885zcpTkp83JFuWTYiIrg275DIuAI3QKBgAglM0IrzS g3vlVQxvM1ussgRgkkYeybHq82 wUW 3DXLqeXb0s1DedplUkuoabZriz0Wh4GZFSmtA5ZpZC uV697lkYsndmp2xRhaekllW7bu pY5q88URwO2p8CO5AZ6CWFWuBwSDML5VOapGRqDRgwaD oGpb7fb7IgHOls7AoGBAJnL6Q8t35uYJ8J8hY7wso88IE04z6VaT8WganxcndesWER9eFQDHDDy//ZYeyt6M41uIY CL Vkm9Kwl/bHLJKdnOE1a9NdE6mtfah0Bk2u/YOuzyu5mmcgZiX X/OZuEbGmmbZOR1FCuIyrNYfwYohhcZP7/r0Ia/1GpkHc3Bi-----END RSA PRIVATE KEY-----","bundle_method":"ubiquitous"}`, string(b))
227		}
228
229		w.Header().Set("content-type", "application/json")
230		fmt.Fprint(w, `{
231          "success": true,
232          "errors": [],
233          "messages": [],
234          "result": {
235            "id": "7e7b8deba8538af625850b7b2530034c",
236            "hosts": [
237              "example.com"
238            ],
239            "issuer": "GlobalSign",
240            "signature": "SHA256WithRSA",
241            "status": "active",
242            "bundle_method": "ubiquitous",
243			"geo_restrictions": {
244               "label": "us"
245            },
246            "zone_id": "023e105f4ecef8ad9ca31a8372d0c353",
247            "uploaded_on": "2014-01-01T05:20:00Z",
248            "modified_on": "2014-01-01T05:20:00Z",
249            "expires_on": "2016-01-01T05:20:00Z",
250            "priority": 1
251          }
252        }`)
253	}
254
255	mux.HandleFunc("/zones/023e105f4ecef8ad9ca31a8372d0c353/custom_certificates/7e7b8deba8538af625850b7b2530034c", handler)
256
257	hosts := make([]string, 1, 4)
258	hosts[0] = "example.com"
259	uploadedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
260	modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
261	expiresOn, _ := time.Parse(time.RFC3339, "2016-01-01T05:20:00Z")
262	want := ZoneCustomSSL{
263		ID:              "7e7b8deba8538af625850b7b2530034c",
264		Hosts:           hosts,
265		Issuer:          "GlobalSign",
266		Signature:       "SHA256WithRSA",
267		Status:          "active",
268		BundleMethod:    "ubiquitous",
269		GeoRestrictions: ZoneCustomSSLGeoRestrictions{Label: "us"},
270		ZoneID:          "023e105f4ecef8ad9ca31a8372d0c353",
271		UploadedOn:      uploadedOn,
272		ModifiedOn:      modifiedOn,
273		ExpiresOn:       expiresOn,
274		Priority:        1,
275	}
276
277	actual, err := client.UpdateSSL(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", "7e7b8deba8538af625850b7b2530034c", ZoneCustomSSLOptions{
278		Certificate:     "-----BEGIN CERTIFICATE----- MIIDtTCCAp2gAwIBAgIJAM15n7fdxhRtMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwMzExMTkyMTU5WhcNMTQwNDEwMTkyMTU5WjBF MQswCQYDVQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvq3sKsHpeduJHimOK+fvQdKsI8z8A05MZyyLp2/R/GE8FjNv+hkVY1WQ LIyTNNQH7CJecE1nbTfo8Y56S7x/rhxC6/DJ8MIulapFPnorq46KU6yRxiM0MQ3N nTJHlHA2ozZta6YBBfVfhHWl1F0IfNbXCLKvGwWWMbCx43OfW6KTkbRnE6gFWKuO fSO5h2u5TaWVuSIzBvYs7Vza6m+gtYAvKAJV2nSZ+eSEFPDo29corOy8+huEOUL8 5FAw4BFPsr1TlrlGPFitduQUHGrSL7skk1ESGza0to3bOtrodKei2s9bk5MXm7lZ qI+WZJX4Zu9+mzZhc9pCVi8r/qlXuQIDAQABo4GnMIGkMB0GA1UdDgQWBBRvavf+ sWM4IwKiH9X9w1vl6nUVRDB1BgNVHSMEbjBsgBRvavf+sWM4IwKiH9X9w1vl6nUV RKFJpEcwRTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAM15n7fdxhRtMAwGA1UdEwQF MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABY2ZzBaW0dMsAAT7tPJzrVWVzQx6KU4 UEBLudIlWPlkAwTnINCWR/8eNjCCmGA4heUdHmazdpPa8RzwOmc0NT1NQqzSyktt vTqb4iHD7+8f9MqJ9/FssCfTtqr/Qst/hGH4Wmdf1EJ/6FqYAAb5iRlPgshFZxU8 uXtA8hWn6fK6eISD9HBdcAFToUvKNZ1BIDPvh9f95Ine8ar6yGd56TUNrHR8eHBs ESxz5ddVR/oWRysNJ+aGAyYqHS8S/ttmC7r4XCAHqXptkHPCGRqkAhsterYhd4I8 /cBzejUobNCjjHFbtkAL/SjxZOLW+pNkZwfeYdM8iPkD54Uua1v2tdw= -----END CERTIFICATE-----",
279		PrivateKey:      "-----BEGIN RSA PRIVATE KEY-----MIIEowIBAAKCAQEAl 1cSc0vfcJLI4ZdWjiZZqy86Eof4czCwilyjXdvHqbdgDjz9H6K/0FX78EzVdfyExESptPCDl5YYjvcZyAWlgNfYEpFpGeoh/pTFW3hlyKImh4EgBXbDrR251J Ew2Nf56X3duibI6X20gKZA6cvdmWeKh MOOXuh1bSPU3dkb4YOF/fng5iGrx0q3txdMQXTPMZ1uXHFcBH7idgViYesXUBhdll3GP1N Y8laq0yrqh 8HMsZK m27MebqonbNmjOqE218lVEvjCdRO6xvNXrO6vNJBoGn2eGwZ8BVd0mTA3Tj43/2cmxQFY9FLq56cCXqYI1fbRRib ZLrjSNkwIDAQABAoIBABfAjjsjjxc0NxcYvKOMUb9Rpj8Sx6U/o/tDC5u XmsGX37aaJmC5yw9BQiAxgvXtQryEl5uoNoqOdsxzKV6yM0vPcwKEJVBd4G6yx6AjVJZnc2qf72erR7BbA2CQh scMDRBKE041HhgTBRNP6roim0SOgYP5JZIrGAQXNIkyE0fZc5gZNUt388ne/mjWM6Xi08BDGurLC68nsdt7Nd UYqeBVxo2EqChp5vKYZYEcG8h9XBj4u4NIwg1Mty2JqX30uBjoHvF5w/pMs8lG uvj6JR9I 19wtCuccbAJl 4cUq03UQoIDmwejea oC8A8WJr3vVpODDWrvAsjllGPBECgYEAyQRa6edYO6bsSvgbM13qXW9OQTn9YmgzfN24Ux1D66TQU6sBSLdfSHshDhTCi Ax 698aJNRWujAakA2DDgspSx98aRnHbF zvY7i7iWGesN6uN0zL 6/MK5uWoieGZRjgk230fLk00l4/FK1mJIp0apr0Lis9xmDjP5AaUPTUUCgYEAwXuhTHZWPT6v8YwOksjbuK UDkIIvyMux53kb73vrkgMboS4DB1zMLNyG 9EghS414CFROUwGl4ZUKboH1Jo5G34y8VgDuHjirTqL2H6 zNpML iMrWCXjpFKkxwPbeQnEAZ 5Rud4d PTyXAt71blZHE9tZ4KHy8cU1iKc9APcCgYAIqKZd4vg7AZK2G//X85iv06aUSrIudfyZyVcyRVVyphPPNtOEVVnGXn9rAtvqeIrOo52BR68 cj4vlXp hkDuEH QVBuY/NdQhOzFtPrKPQTJdGjIlQ2x65Vidj7r3sRukNkLPyV2v D885zcpTkp83JFuWTYiIrg275DIuAI3QKBgAglM0IrzS g3vlVQxvM1ussgRgkkYeybHq82 wUW 3DXLqeXb0s1DedplUkuoabZriz0Wh4GZFSmtA5ZpZC uV697lkYsndmp2xRhaekllW7bu pY5q88URwO2p8CO5AZ6CWFWuBwSDML5VOapGRqDRgwaD oGpb7fb7IgHOls7AoGBAJnL6Q8t35uYJ8J8hY7wso88IE04z6VaT8WganxcndesWER9eFQDHDDy//ZYeyt6M41uIY CL Vkm9Kwl/bHLJKdnOE1a9NdE6mtfah0Bk2u/YOuzyu5mmcgZiX X/OZuEbGmmbZOR1FCuIyrNYfwYohhcZP7/r0Ia/1GpkHc3Bi-----END RSA PRIVATE KEY-----",
280		BundleMethod:    "ubiquitous",
281		GeoRestrictions: &ZoneCustomSSLGeoRestrictions{Label: "us"},
282	})
283	if assert.NoError(t, err) {
284		assert.Equal(t, want, actual)
285	}
286
287	_, err = client.UpdateSSL(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", "bar", ZoneCustomSSLOptions{})
288	assert.Error(t, err)
289}
290
291func TestReprioritizeSSL(t *testing.T) {
292	setup()
293	defer teardown()
294
295	handler := func(w http.ResponseWriter, r *http.Request) {
296		assert.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method)
297		b, err := ioutil.ReadAll(r.Body)
298		defer r.Body.Close()
299		if assert.NoError(t, err) {
300			assert.JSONEq(t, `{"certificates":[{"ID":"5a7805061c76ada191ed06f989cc3dac","priority":2},{"ID":"9a7806061c88ada191ed06f989cc3dac","priority":1}]}`, string(b))
301		}
302
303		w.Header().Set("content-type", "application/json")
304		// XXX: Test response flow properly.
305		// Current response assertion uses generic example from the documentation,
306		// rather than responding to the actual PUT request.
307		// https://api.cloudflare.com/#custom-ssl-for-a-zone-re-prioritize-ssl-certificates
308		fmt.Fprint(w, `{
309          "success": true,
310          "errors": [],
311          "messages": [],
312          "result": [
313            {
314              "id": "7e7b8deba8538af625850b7b2530034c",
315              "hosts": [
316                "example.com"
317              ],
318              "issuer": "GlobalSign",
319              "signature": "SHA256WithRSA",
320              "status": "active",
321              "bundle_method": "ubiquitous",
322              "zone_id": "023e105f4ecef8ad9ca31a8372d0c353",
323              "uploaded_on": "2014-01-01T05:20:00Z",
324              "modified_on": "2014-01-01T05:20:00Z",
325              "expires_on": "2016-01-01T05:20:00Z",
326              "priority": 1
327            }
328          ],
329          "result_info": {
330            "page": 1,
331            "per_page": 20,
332            "count": 1,
333            "total_count": 2000
334          }
335        }`)
336	}
337
338	mux.HandleFunc("/zones/023e105f4ecef8ad9ca31a8372d0c353/custom_certificates/prioritize", handler)
339
340	hosts := make([]string, 1, 4)
341	hosts[0] = "example.com"
342	uploadedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
343	modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
344	expiresOn, _ := time.Parse(time.RFC3339, "2016-01-01T05:20:00Z")
345
346	want := make([]ZoneCustomSSL, 1, 4)
347	want[0] = ZoneCustomSSL{
348		ID:           "7e7b8deba8538af625850b7b2530034c",
349		Hosts:        hosts,
350		Issuer:       "GlobalSign",
351		Signature:    "SHA256WithRSA",
352		Status:       "active",
353		BundleMethod: "ubiquitous",
354		ZoneID:       "023e105f4ecef8ad9ca31a8372d0c353",
355		UploadedOn:   uploadedOn,
356		ModifiedOn:   modifiedOn,
357		ExpiresOn:    expiresOn,
358		Priority:     1,
359	}
360
361	actual, err := client.ReprioritizeSSL(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", []ZoneCustomSSLPriority{
362		{ID: "5a7805061c76ada191ed06f989cc3dac", Priority: 2},
363		{ID: "9a7806061c88ada191ed06f989cc3dac", Priority: 1},
364	})
365
366	if assert.NoError(t, err) {
367		assert.Equal(t, want, actual)
368	}
369}
370
371func TestDeleteSSL(t *testing.T) {
372	setup()
373	defer teardown()
374
375	handler := func(w http.ResponseWriter, r *http.Request) {
376		assert.Equal(t, http.MethodDelete, r.Method, "Expected method 'DELETE', got %s", r.Method)
377		w.Header().Set("content-type", "application/json")
378		fmt.Fprint(w, `{
379          "id": "7e7b8deba8538af625850b7b2530034c"
380        }`)
381	}
382
383	mux.HandleFunc("/zones/023e105f4ecef8ad9ca31a8372d0c353/custom_certificates/7e7b8deba8538af625850b7b2530034c", handler)
384
385	err := client.DeleteSSL(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", "7e7b8deba8538af625850b7b2530034c")
386	assert.NoError(t, err, "Expected to successfully delete certificate ID '7e7b8deba8538af625850b7b2530034c', received error instead")
387
388	err = client.DeleteSSL(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", "bar")
389	assert.Error(t, err, "Expected to error when attempting to delete certificate ID 'bar', did not receive error instead")
390}
391