1package domain
2
3import (
4	"errors"
5	"fmt"
6	"github.com/stretchr/testify/assert"
7	"github.com/stretchr/testify/require"
8	"github.com/transip/gotransip/v6"
9	"github.com/transip/gotransip/v6/repository"
10	"github.com/transip/gotransip/v6/rest"
11	"io/ioutil"
12	"net"
13	"net/http"
14	"net/http/httptest"
15	"testing"
16)
17
18const (
19	error404Response   = `{ "error": "Domain with name 'example2.com' not found" }`
20	domainsAPIResponse = `{ "domains": [
21    {
22      "name": "example.com",
23      "authCode": "kJqfuOXNOYQKqh/jO4bYSn54YDqgAt1ksCe+ZG4Ud",
24      "isTransferLocked": false,
25      "registrationDate": "2016-01-01",
26      "renewalDate": "2020-01-01",
27      "isWhitelabel": false,
28      "cancellationDate": "2020-01-01 12:00:00",
29      "cancellationStatus": "signed",
30      "isDnsOnly": false,
31      "tags": [ "customTag", "anotherTag" ]
32    }
33  ] }`
34	domainAPIResponse = `{ "domain": {
35    "name": "example.com",
36    "authCode": "kJqfuOXNOYQKqh/jO4bYSn54YDqgAt1ksCe+ZG4Ud",
37    "isTransferLocked": false,
38    "registrationDate": "2016-01-01",
39    "renewalDate": "2020-01-01",
40    "isWhitelabel": false,
41    "cancellationDate": "2020-01-01 12:00:00",
42    "cancellationStatus": "signed",
43    "isDnsOnly": false,
44    "tags": [ "customTag", "anotherTag" ]
45  } } `
46	brandingAPIResponse = `{
47		"branding": {
48		"companyName": "Example B.V.",
49		"supportEmail": "admin@example.com",
50		"companyUrl": "www.example.com",
51		"termsOfUsageUrl": "www.example.com/tou",
52		"bannerLine1": "Example B.V.",
53		"bannerLine2": "Example",
54		"bannerLine3": "http://www.example.com/products"
55	} }`
56	contactsAPIResponse = `{ "contacts": [ {
57      "type": "registrant",
58      "firstName": "John",
59      "lastName": "Doe",
60      "companyName": "Example B.V.",
61      "companyKvk": "83057825",
62      "companyType": "BV",
63      "street": "Easy street",
64      "number": "12",
65      "postalCode": "1337 XD",
66      "city": "Leiden",
67      "phoneNumber": "+31 715241919",
68      "faxNumber": "+31 715241919",
69      "email": "example@example.com",
70      "country": "nl"
71    } ] }`
72	dnsEntriesAPIResponse = `{ "dnsEntries": [
73    { "name": "www", "expire": 86400, "type": "A", "content": "127.0.0.1" }
74  ] }`
75	dnsSecEntriesAPIResponseRequest = `{ "dnsSecEntries": [ {
76      "keyTag": 67239,
77      "flags": 1,
78      "algorithm": 8,
79      "publicKey": "kljlfkjsdfkjasdklf="
80    } ] }`
81)
82
83// mockServer struct is used to test the how the client sends a request
84// and responds to a servers response
85type mockServer struct {
86	t                   *testing.T
87	expectedURL         string
88	expectedMethod      string
89	statusCode          int
90	expectedRequestBody string
91	response            string
92	skipRequestBody     bool
93}
94
95func (m *mockServer) getHTTPServer() *httptest.Server {
96	return httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
97		assert.Equal(m.t, m.expectedURL, req.URL.String()) // check if right expectedURL is called
98
99		if m.skipRequestBody == false && req.ContentLength != 0 {
100			// get the request body
101			// and check if the body matches the expected request body
102			body, err := ioutil.ReadAll(req.Body)
103			require.NoError(m.t, err)
104			assert.Equal(m.t, m.expectedRequestBody, string(body))
105		}
106
107		assert.Equal(m.t, m.expectedMethod, req.Method) // check if the right expectedRequestBody expectedMethod is used
108		rw.WriteHeader(m.statusCode)                    // respond with given status code
109
110		if m.response != "" {
111			_, err := rw.Write([]byte(m.response))
112			require.NoError(m.t, err, "error when writing mock response")
113		}
114	}))
115}
116
117func (m *mockServer) getClient() (*repository.Client, func()) {
118	httpServer := m.getHTTPServer()
119	config := gotransip.DemoClientConfiguration
120	config.URL = httpServer.URL
121	client, err := gotransip.NewClient(config)
122	require.NoError(m.t, err)
123
124	// return tearDown method with which will close the test server after the test
125	tearDown := func() {
126		httpServer.Close()
127	}
128
129	return &client, tearDown
130}
131
132func TestRepository_GetAll(t *testing.T) {
133	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/domains", statusCode: 200, response: domainsAPIResponse}
134	client, tearDown := server.getClient()
135	defer tearDown()
136	repo := Repository{Client: *client}
137
138	all, err := repo.GetAll()
139	require.NoError(t, err)
140	require.Equal(t, 1, len(all))
141	assert.Equal(t, "example.com", all[0].Name)
142	assert.Equal(t, "kJqfuOXNOYQKqh/jO4bYSn54YDqgAt1ksCe+ZG4Ud", all[0].AuthCode)
143	assert.Equal(t, false, all[0].IsTransferLocked)
144	assert.Equal(t, "2016-01-01 00:00:00", all[0].RegistrationDate.Format("2006-01-02 15:04:05"))
145	assert.Equal(t, "2020-01-01 00:00:00", all[0].RenewalDate.Format("2006-01-02 15:04:05"))
146	assert.Equal(t, false, all[0].IsWhitelabel)
147	assert.Equal(t, "2020-01-01 12:00:00", all[0].CancellationDate.Format("2006-01-02 15:04:05"))
148	assert.Equal(t, "signed", all[0].CancellationStatus)
149	assert.Equal(t, false, all[0].IsDNSOnly)
150	assert.Equal(t, []string{"customTag", "anotherTag"}, all[0].Tags)
151}
152
153func TestRepository_GetSelection(t *testing.T) {
154	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/domains?page=1&pageSize=25", statusCode: 200, response: domainsAPIResponse}
155	client, tearDown := server.getClient()
156	defer tearDown()
157	repo := Repository{Client: *client}
158
159	all, err := repo.GetSelection(1, 25)
160	require.NoError(t, err)
161	require.Equal(t, 1, len(all))
162	assert.Equal(t, "example.com", all[0].Name)
163	assert.Equal(t, "kJqfuOXNOYQKqh/jO4bYSn54YDqgAt1ksCe+ZG4Ud", all[0].AuthCode)
164	assert.Equal(t, false, all[0].IsTransferLocked)
165	assert.Equal(t, "2016-01-01 00:00:00", all[0].RegistrationDate.Format("2006-01-02 15:04:05"))
166	assert.Equal(t, "2020-01-01 00:00:00", all[0].RenewalDate.Format("2006-01-02 15:04:05"))
167	assert.Equal(t, false, all[0].IsWhitelabel)
168	assert.Equal(t, "2020-01-01 12:00:00", all[0].CancellationDate.Format("2006-01-02 15:04:05"))
169	assert.Equal(t, "signed", all[0].CancellationStatus)
170	assert.Equal(t, false, all[0].IsDNSOnly)
171	assert.Equal(t, []string{"customTag", "anotherTag"}, all[0].Tags)
172}
173
174func TestRepository_GetAllByTags(t *testing.T) {
175	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/domains?tags=customTag", statusCode: 200, response: domainsAPIResponse}
176	client, tearDown := server.getClient()
177	defer tearDown()
178	repo := Repository{Client: *client}
179
180	all, err := repo.GetAllByTags([]string{"customTag"})
181	require.NoError(t, err)
182	require.Equal(t, 1, len(all))
183
184	assert.Equal(t, "example.com", all[0].Name)
185	assert.Equal(t, "kJqfuOXNOYQKqh/jO4bYSn54YDqgAt1ksCe+ZG4Ud", all[0].AuthCode)
186	assert.Equal(t, false, all[0].IsTransferLocked)
187	assert.Equal(t, "2016-01-01 00:00:00", all[0].RegistrationDate.Format("2006-01-02 15:04:05"))
188	assert.Equal(t, "2020-01-01 00:00:00", all[0].RenewalDate.Format("2006-01-02 15:04:05"))
189	assert.Equal(t, false, all[0].IsWhitelabel)
190	assert.Equal(t, "2020-01-01 12:00:00", all[0].CancellationDate.Format("2006-01-02 15:04:05"))
191	assert.Equal(t, "signed", all[0].CancellationStatus)
192	assert.Equal(t, false, all[0].IsDNSOnly)
193	assert.Equal(t, []string{"customTag", "anotherTag"}, all[0].Tags)
194}
195
196func TestRepository_GetByDomainName(t *testing.T) {
197	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/domains/example.com", statusCode: 200, response: domainAPIResponse}
198	client, tearDown := server.getClient()
199	defer tearDown()
200	repo := Repository{Client: *client}
201
202	domain, err := repo.GetByDomainName("example.com")
203	require.NoError(t, err)
204	assert.Equal(t, "example.com", domain.Name)
205	assert.Equal(t, "kJqfuOXNOYQKqh/jO4bYSn54YDqgAt1ksCe+ZG4Ud", domain.AuthCode)
206	assert.Equal(t, false, domain.IsTransferLocked)
207	assert.Equal(t, "2016-01-01 00:00:00", domain.RegistrationDate.Format("2006-01-02 15:04:05"))
208	assert.Equal(t, "2020-01-01 00:00:00", domain.RenewalDate.Format("2006-01-02 15:04:05"))
209	assert.Equal(t, false, domain.IsWhitelabel)
210	assert.Equal(t, "2020-01-01 12:00:00", domain.CancellationDate.Format("2006-01-02 15:04:05"))
211	assert.Equal(t, "signed", domain.CancellationStatus)
212	assert.Equal(t, false, domain.IsDNSOnly)
213	assert.Equal(t, []string{"customTag", "anotherTag"}, domain.Tags)
214}
215
216func TestRepository_GetByDomainNameError(t *testing.T) {
217	domainName := "example2.com"
218	server := mockServer{t: t, expectedMethod: "GET", expectedURL: fmt.Sprintf("/domains/%s", domainName), statusCode: 404, response: error404Response}
219	client, tearDown := server.getClient()
220	defer tearDown()
221	repo := Repository{Client: *client}
222
223	domain, err := repo.GetByDomainName(domainName)
224	if assert.Errorf(t, err, "getbydomainname server response error not returned") {
225		require.Empty(t, domain.Name)
226		assert.Equal(t, &rest.Error{Message: "Domain with name 'example2.com' not found", StatusCode: 404}, err)
227	}
228}
229
230func TestRepository_Register(t *testing.T) {
231	expectedRequest := `{"domainName":"example.com"}`
232	server := mockServer{t: t, expectedMethod: "POST", expectedURL: "/domains", statusCode: 201, expectedRequestBody: expectedRequest}
233	client, tearDown := server.getClient()
234	defer tearDown()
235	repo := Repository{Client: *client}
236
237	register := Register{DomainName: "example.com"}
238	err := repo.Register(register)
239	require.NoError(t, err)
240}
241
242func TestRepository_RegisterError(t *testing.T) {
243	errorResponse := `{"error":"The domain 'example.com' is not free and thus cannot be registered"}`
244	server := mockServer{t: t, expectedMethod: "POST", expectedURL: "/domains", statusCode: 406, skipRequestBody: true, response: errorResponse}
245	client, tearDown := server.getClient()
246	defer tearDown()
247	repo := Repository{Client: *client}
248
249	register := Register{DomainName: "example.com"}
250	err := repo.Register(register)
251	if assert.Errorf(t, err, "register server response error not returned") {
252		assert.Error(t, errors.New("The domain 'example.com' is not free and thus cannot be registered"), err)
253	}
254}
255
256func TestRepository_Transfer(t *testing.T) {
257	expectedRequest := `{"domainName":"example.com","authCode":"test123"}`
258	server := mockServer{t: t, expectedMethod: "POST", expectedURL: "/domains", statusCode: 201, expectedRequestBody: expectedRequest}
259	client, tearDown := server.getClient()
260	defer tearDown()
261	repo := Repository{Client: *client}
262
263	transfer := Transfer{DomainName: "example.com", AuthCode: "test123"}
264
265	err := repo.Transfer(transfer)
266	require.NoError(t, err)
267}
268
269func TestRepository_TransferError(t *testing.T) {
270	errorResponse := `{"error":"The domain 'example.com' is not registered and thus cannot be transferred"}`
271	server := mockServer{t: t, expectedMethod: "POST", expectedURL: "/domains", statusCode: 409, skipRequestBody: true, response: errorResponse}
272	client, tearDown := server.getClient()
273	defer tearDown()
274	repo := Repository{Client: *client}
275
276	transfer := Transfer{DomainName: "example.com", AuthCode: "test123"}
277	err := repo.Transfer(transfer)
278
279	if assert.Errorf(t, err, "transfer server response error not returned") {
280		assert.Error(t, errors.New("The domain 'example.com' is not registered and thus cannot be transferred"), err)
281	}
282}
283
284func TestRepository_Update(t *testing.T) {
285	expectedRequest := `{"domain":{"tags":["test123","test1234"],"cancellationDate":"0001-01-01T00:00:00Z","isTransferLocked":false,"isWhitelabel":false,"name":"example.com","registrationDate":"0001-01-01T00:00:00Z","renewalDate":"0001-01-01T00:00:00Z"}}`
286	server := mockServer{t: t, expectedMethod: "PUT", expectedURL: "/domains/example.com", statusCode: 204, expectedRequestBody: expectedRequest}
287	client, tearDown := server.getClient()
288	defer tearDown()
289	repo := Repository{Client: *client}
290
291	domain := Domain{Tags: []string{"test123", "test1234"}, IsTransferLocked: false, IsWhitelabel: false, Name: "example.com"}
292
293	err := repo.Update(domain)
294	require.NoError(t, err)
295}
296
297func TestRepository_CancelEnd(t *testing.T) {
298	expectedRequest := `{"endTime":"end"}`
299	server := mockServer{t: t, expectedMethod: "DELETE", expectedURL: "/domains/example.com", statusCode: 204, expectedRequestBody: expectedRequest}
300	client, tearDown := server.getClient()
301	defer tearDown()
302	repo := Repository{Client: *client}
303
304	err := repo.Cancel("example.com", gotransip.CancellationTimeEnd)
305	require.NoError(t, err)
306}
307
308func TestRepository_Cancel(t *testing.T) {
309	expectedRequest := `{"endTime":"immediately"}`
310	server := mockServer{t: t, expectedMethod: "DELETE", expectedURL: "/domains/example.com", statusCode: 204, expectedRequestBody: expectedRequest}
311	client, tearDown := server.getClient()
312	defer tearDown()
313	repo := Repository{Client: *client}
314
315	err := repo.Cancel("example.com", gotransip.CancellationTimeImmediately)
316	require.NoError(t, err)
317}
318
319func TestRepository_GetDomainBranding(t *testing.T) {
320	domainName := "example2.com"
321	server := mockServer{t: t, expectedMethod: "GET", expectedURL: fmt.Sprintf("/domains/%s/branding", domainName), statusCode: 200, response: brandingAPIResponse}
322	client, tearDown := server.getClient()
323	defer tearDown()
324	repo := Repository{Client: *client}
325
326	branding, err := repo.GetBranding(domainName)
327	require.NoError(t, err)
328
329	assert.Equal(t, "Example B.V.", branding.CompanyName)
330	assert.Equal(t, "admin@example.com", branding.SupportEmail)
331	assert.Equal(t, "www.example.com", branding.CompanyURL)
332	assert.Equal(t, "www.example.com/tou", branding.TermsOfUsageURL)
333	assert.Equal(t, "Example B.V.", branding.BannerLine1)
334	assert.Equal(t, "Example", branding.BannerLine2)
335	assert.Equal(t, "http://www.example.com/products", branding.BannerLine3)
336}
337
338func TestRepository_UpdateDomainBranding(t *testing.T) {
339	expectedRequest := `{"branding":{"bannerLine1":"Example B.V.","bannerLine2":"admin@example.com","bannerLine3":"www.example.com","companyName":"www.example.com/tou","companyUrl":"Example B.V.","supportEmail":"Example","termsOfUsageUrl":"http://www.example.com/products"}}`
340	server := mockServer{t: t, expectedMethod: "PUT", expectedURL: "/domains/example.com/branding", statusCode: 204, expectedRequestBody: expectedRequest}
341	client, tearDown := server.getClient()
342	defer tearDown()
343	repo := Repository{Client: *client}
344
345	branding := Branding{
346		BannerLine1:     "Example B.V.",
347		BannerLine2:     "admin@example.com",
348		BannerLine3:     "www.example.com",
349		CompanyName:     "www.example.com/tou",
350		CompanyURL:      "Example B.V.",
351		SupportEmail:    "Example",
352		TermsOfUsageURL: "http://www.example.com/products",
353	}
354
355	err := repo.UpdateBranding("example.com", branding)
356	require.NoError(t, err)
357}
358
359func TestRepository_GetContacts(t *testing.T) {
360	domainName := "example.com"
361	server := mockServer{t: t, expectedMethod: "GET", expectedURL: fmt.Sprintf("/domains/%s/contacts", domainName), statusCode: 200, response: contactsAPIResponse}
362	client, tearDown := server.getClient()
363	defer tearDown()
364	repo := Repository{Client: *client}
365
366	contacts, err := repo.GetContacts(domainName)
367	require.NoError(t, err)
368	require.Equal(t, 1, len(contacts))
369
370	assert.Equal(t, "registrant", contacts[0].Type)
371	assert.Equal(t, "John", contacts[0].FirstName)
372	assert.Equal(t, "Doe", contacts[0].LastName)
373	assert.Equal(t, "Example B.V.", contacts[0].CompanyName)
374	assert.Equal(t, "83057825", contacts[0].CompanyKvk)
375	assert.Equal(t, "BV", contacts[0].CompanyType)
376	assert.Equal(t, "Easy street", contacts[0].Street)
377	assert.Equal(t, "12", contacts[0].Number)
378	assert.Equal(t, "1337 XD", contacts[0].PostalCode)
379	assert.Equal(t, "Leiden", contacts[0].City)
380	assert.Equal(t, "+31 715241919", contacts[0].PhoneNumber)
381	assert.Equal(t, "+31 715241919", contacts[0].FaxNumber)
382	assert.Equal(t, "example@example.com", contacts[0].Email)
383	assert.Equal(t, "nl", contacts[0].Country)
384}
385
386func TestRepository_UpdateContacts(t *testing.T) {
387	expectedRequest := `{"contacts":[{"type":"registrant","firstName":"John","lastName":"Doe","companyName":"Example B.V.","companyKvk":"83057825","companyType":"BV","street":"Easy street","number":"12","postalCode":"1337 XD","city":"Leiden","phoneNumber":"+31 715241919","faxNumber":"+31 715241919","email":"example@example.com","country":"nl"}]}`
388	server := mockServer{t: t, expectedMethod: "PUT", expectedURL: "/domains/example.com/contacts", statusCode: 204, expectedRequestBody: expectedRequest}
389	client, tearDown := server.getClient()
390	defer tearDown()
391	repo := Repository{Client: *client}
392
393	contacts := []WhoisContact{
394		{
395			Type:        "registrant",
396			FirstName:   "John",
397			LastName:    "Doe",
398			CompanyName: "Example B.V.",
399			CompanyKvk:  "83057825",
400			CompanyType: "BV",
401			Street:      "Easy street",
402			Number:      "12",
403			PostalCode:  "1337 XD",
404			City:        "Leiden",
405			PhoneNumber: "+31 715241919",
406			FaxNumber:   "+31 715241919",
407			Email:       "example@example.com",
408			Country:     "nl",
409		},
410	}
411
412	err := repo.UpdateContacts("example.com", contacts)
413	require.NoError(t, err)
414}
415
416func TestRepository_GetDnsEntries(t *testing.T) {
417	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/domains/example.com/dns", statusCode: 200, response: dnsEntriesAPIResponse}
418	client, tearDown := server.getClient()
419	defer tearDown()
420	repo := Repository{Client: *client}
421
422	entries, err := repo.GetDNSEntries("example.com")
423	require.Equal(t, 1, len(entries))
424	require.NoError(t, err)
425	assert.Equal(t, "www", entries[0].Name)
426	assert.Equal(t, 86400, entries[0].Expire)
427	assert.Equal(t, "A", entries[0].Type)
428	assert.Equal(t, "127.0.0.1", entries[0].Content)
429
430}
431
432func TestRepository_AddDnsEntry(t *testing.T) {
433	expectedRequest := `{"dnsEntry":{"name":"www","expire":1337,"type":"A","content":"127.0.0.1"}}`
434	server := mockServer{t: t, expectedMethod: "POST", expectedURL: "/domains/example.com/dns", statusCode: 201, expectedRequestBody: expectedRequest}
435	client, tearDown := server.getClient()
436	defer tearDown()
437	repo := Repository{Client: *client}
438
439	dnsEntry := DNSEntry{Content: "127.0.0.1", Expire: 1337, Name: "www", Type: "A"}
440	err := repo.AddDNSEntry("example.com", dnsEntry)
441	require.NoError(t, err)
442}
443
444func TestRepository_UpdateDnsEntry(t *testing.T) {
445	expectedRequest := `{"dnsEntry":{"name":"www","expire":1337,"type":"A","content":"127.0.0.1"}}`
446	server := mockServer{t: t, expectedMethod: "PATCH", expectedURL: "/domains/example.com/dns", statusCode: 204, expectedRequestBody: expectedRequest}
447	client, tearDown := server.getClient()
448	defer tearDown()
449	repo := Repository{Client: *client}
450
451	dnsEntry := DNSEntry{Content: "127.0.0.1", Expire: 1337, Name: "www", Type: "A"}
452	err := repo.UpdateDNSEntry("example.com", dnsEntry)
453	require.NoError(t, err)
454}
455
456func TestRepository_ReplaceDnsEntries(t *testing.T) {
457	expectedRequest := `{"dnsEntries":[{"name":"www","expire":1337,"type":"A","content":"127.0.0.1"}]}`
458	server := mockServer{t: t, expectedMethod: "PUT", expectedURL: "/domains/example.com/dns", statusCode: 204, expectedRequestBody: expectedRequest}
459	client, tearDown := server.getClient()
460	defer tearDown()
461	repo := Repository{Client: *client}
462
463	dnsEntries := []DNSEntry{{Content: "127.0.0.1", Expire: 1337, Name: "www", Type: "A"}}
464	err := repo.ReplaceDNSEntries("example.com", dnsEntries)
465	require.NoError(t, err)
466}
467
468func TestRepository_RemoveDnsEntry(t *testing.T) {
469	expectedRequest := `{"dnsEntry":{"name":"www","expire":1337,"type":"A","content":"127.0.0.1"}}`
470	server := mockServer{t: t, expectedMethod: "DELETE", expectedURL: "/domains/example.com/dns", statusCode: 204, expectedRequestBody: expectedRequest}
471	client, tearDown := server.getClient()
472	defer tearDown()
473	repo := Repository{Client: *client}
474
475	dnsEntry := DNSEntry{Content: "127.0.0.1", Expire: 1337, Name: "www", Type: "A"}
476	err := repo.RemoveDNSEntry("example.com", dnsEntry)
477	require.NoError(t, err)
478}
479
480func TestRepository_GetDnsSecEntries(t *testing.T) {
481	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/domains/example.com/dnssec", statusCode: 200, response: dnsSecEntriesAPIResponseRequest}
482	client, tearDown := server.getClient()
483	defer tearDown()
484	repo := Repository{Client: *client}
485
486	entries, err := repo.GetDNSSecEntries("example.com")
487	require.NoError(t, err)
488	require.Equal(t, 1, len(entries))
489
490	assert.Equal(t, 67239, entries[0].KeyTag)
491	assert.Equal(t, 1, entries[0].Flags)
492	assert.Equal(t, 8, entries[0].Algorithm)
493	assert.Equal(t, "kljlfkjsdfkjasdklf=", entries[0].PublicKey)
494}
495
496func TestRepository_ReplaceDnsSecEntries(t *testing.T) {
497	expectedRequestBody := `{"dnsSecEntries":[{"algorithm":8,"flags":1,"keyTag":67239,"publicKey":"test123"}]}`
498	server := mockServer{t: t, expectedMethod: "PUT", expectedURL: "/domains/example.com/dnssec", statusCode: 204, expectedRequestBody: expectedRequestBody}
499	client, tearDown := server.getClient()
500	defer tearDown()
501	repo := Repository{Client: *client}
502
503	dnsSecEntries := []DNSSecEntry{{KeyTag: 67239, Flags: 1, Algorithm: 8, PublicKey: "test123"}}
504	err := repo.ReplaceDNSSecEntries("example.com", dnsSecEntries)
505	require.NoError(t, err)
506}
507
508func TestRepository_GetNameservers(t *testing.T) {
509	apiResponse := `{"nameservers":[{"hostname":"ns0.transip.nl","ipv4":"127.0.0.1","ipv6":"2a01::1"}]}`
510	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/domains/example.com/nameservers", statusCode: 200, response: apiResponse}
511	client, tearDown := server.getClient()
512	defer tearDown()
513	repo := Repository{Client: *client}
514
515	nameservers, err := repo.GetNameservers("example.com")
516	require.NoError(t, err)
517	assert.Equal(t, 1, len(nameservers))
518	assert.Equal(t, "ns0.transip.nl", nameservers[0].Hostname)
519	assert.Equal(t, "127.0.0.1", nameservers[0].IPv4.String())
520	assert.Equal(t, "2a01::1", nameservers[0].IPv6.String())
521}
522
523func TestRepository_UpdateNameservers(t *testing.T) {
524	expectedRequest := `{"nameservers":[{"hostname":"ns0.transip.nl","ipv4":"127.0.0.1","ipv6":"2a01::1"}]}`
525	server := mockServer{t: t, expectedMethod: "PUT", expectedURL: "/domains/example.com/nameservers", statusCode: 204, expectedRequestBody: expectedRequest}
526	client, tearDown := server.getClient()
527	defer tearDown()
528	repo := Repository{Client: *client}
529
530	nameservers := []Nameserver{{
531		Hostname: "ns0.transip.nl",
532		IPv4:     net.ParseIP("127.0.0.1"),
533		IPv6:     net.ParseIP("2a01::1"),
534	}}
535	err := repo.UpdateNameservers("example.com", nameservers)
536	require.NoError(t, err)
537}
538
539func TestRepository_GetDomainAction(t *testing.T) {
540	apiResponse := `{"action":{"name":"changeNameservers","message":"success","hasFailed":false}}`
541	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/domains/example.com/actions", statusCode: 200, response: apiResponse}
542	client, tearDown := server.getClient()
543	defer tearDown()
544	repo := Repository{Client: *client}
545
546	action, err := repo.GetDomainAction("example.com")
547	require.NoError(t, err)
548	assert.Equal(t, "changeNameservers", action.Name)
549	assert.Equal(t, "success", action.Message)
550	assert.Equal(t, false, action.HasFailed)
551
552}
553
554func TestRepository_RetryDomainAction(t *testing.T) {
555	expectedRequest := `{"authCode":"test","dnsEntries":[{"name":"www","expire":86400,"type":"A","content":"127.0.0.1"}],"nameservers":[{"hostname":"ns0.transip.nl","ipv4":"127.0.0.1","ipv6":"2a01::1"}],"contacts":[{"type":"registrant","firstName":"John","lastName":"Doe","companyName":"Example B.V.","companyKvk":"83057825","companyType":"BV","street":"Easy street","number":"12","postalCode":"1337 XD","city":"Leiden","phoneNumber":"+31 715241919","faxNumber":"+31 715241919","email":"example@example.com","country":"nl"}]}`
556	server := mockServer{t: t, expectedMethod: "PATCH", expectedURL: "/domains/example.com/actions", statusCode: 204, expectedRequestBody: expectedRequest}
557	client, tearDown := server.getClient()
558	defer tearDown()
559	repo := Repository{Client: *client}
560
561	contacts := []WhoisContact{
562		{
563			Type:        "registrant",
564			FirstName:   "John",
565			LastName:    "Doe",
566			CompanyName: "Example B.V.",
567			CompanyKvk:  "83057825",
568			CompanyType: "BV",
569			Street:      "Easy street",
570			Number:      "12",
571			PostalCode:  "1337 XD",
572			City:        "Leiden",
573			PhoneNumber: "+31 715241919",
574			FaxNumber:   "+31 715241919",
575			Email:       "example@example.com",
576			Country:     "nl",
577		},
578	}
579
580	nameservers := []Nameserver{{
581		Hostname: "ns0.transip.nl",
582		IPv4:     net.ParseIP("127.0.0.1"),
583		IPv6:     net.ParseIP("2a01::1"),
584	}}
585
586	dnsEntries := []DNSEntry{{Content: "127.0.0.1", Expire: 86400, Name: "www", Type: "A"}}
587
588	err := repo.RetryDomainAction("example.com", "test", dnsEntries, nameservers, contacts)
589	require.NoError(t, err)
590}
591
592func TestRepository_CancelDomainAction(t *testing.T) {
593	server := mockServer{t: t, expectedMethod: "DELETE", expectedURL: "/domains/example.com/actions", statusCode: 204}
594	client, tearDown := server.getClient()
595	defer tearDown()
596	repo := Repository{Client: *client}
597
598	err := repo.CancelDomainAction("example.com")
599	require.NoError(t, err)
600}
601
602func TestRepository_GetSSLCertificates(t *testing.T) {
603	apiResponse := `{"certificates":[{"certificateId":12358,"commonName":"example.com","expirationDate":"2019-10-24 12:59:59","status":"active"}]}`
604	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/domains/example.com/ssl", statusCode: 200, response: apiResponse}
605	client, tearDown := server.getClient()
606	defer tearDown()
607	repo := Repository{Client: *client}
608
609	certificates, err := repo.GetSSLCertificates("example.com")
610	require.NoError(t, err)
611	require.Equal(t, 1, len(certificates))
612	assert.Equal(t, 12358, certificates[0].CertificateID)
613	assert.Equal(t, "example.com", certificates[0].CommonName)
614	assert.Equal(t, "2019-10-24 12:59:59", certificates[0].ExpirationDate)
615	assert.Equal(t, "active", certificates[0].Status)
616}
617
618func TestRepository_GetSSLCertificateByID(t *testing.T) {
619	apiResponse := `{"certificate":{"certificateId":12358,"commonName":"example.com","expirationDate":"2019-10-24 12:59:59","status":"active"}}`
620	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/domains/example.com/ssl/12358", statusCode: 200, response: apiResponse}
621	client, tearDown := server.getClient()
622	defer tearDown()
623	repo := Repository{Client: *client}
624
625	certificates, err := repo.GetSSLCertificateByID("example.com", 12358)
626	require.NoError(t, err)
627	assert.Equal(t, 12358, certificates.CertificateID)
628	assert.Equal(t, "example.com", certificates.CommonName)
629	assert.Equal(t, "2019-10-24 12:59:59", certificates.ExpirationDate)
630	assert.Equal(t, "active", certificates.Status)
631}
632
633func TestRepository_GetWHOIS(t *testing.T) {
634	apiResponse := `{"whois":"test123"}`
635	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/domains/example.com/whois", statusCode: 200, response: apiResponse}
636	client, tearDown := server.getClient()
637	defer tearDown()
638	repo := Repository{Client: *client}
639
640	whoisInfo, err := repo.GetWHOIS("example.com")
641	require.NoError(t, err)
642	assert.Equal(t, "test123", whoisInfo)
643}
644
645func TestRepository_OrderWhitelabel(t *testing.T) {
646	server := mockServer{t: t, expectedMethod: "POST", expectedURL: "/whitelabel", statusCode: 201}
647	client, tearDown := server.getClient()
648	defer tearDown()
649	repo := Repository{Client: *client}
650
651	err := repo.OrderWhitelabel()
652	require.NoError(t, err)
653}
654
655func TestRepository_GetAvailability(t *testing.T) {
656	apiResponse := `{"availability":{"domainName":"example.com","status":"free","actions":["register"]}}`
657	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/domain-availability/example.com", statusCode: 200, response: apiResponse}
658	client, tearDown := server.getClient()
659	defer tearDown()
660	repo := Repository{Client: *client}
661
662	availability, err := repo.GetAvailability("example.com")
663	require.NoError(t, err)
664	assert.Equal(t, "example.com", availability.DomainName)
665	assert.EqualValues(t, "free", availability.Status)
666	assert.Equal(t, []PerformAction{"register"}, availability.Actions)
667}
668
669func TestRepository_GetAvailabilityForMultipleDomains(t *testing.T) {
670	apiResponse := `{"availability":[{"domainName":"example.com","status":"free","actions":["register"]}]}`
671	expectedRequest := `{"domainNames":["example.com","example.nl"]}`
672	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/domain-availability", statusCode: 200, expectedRequestBody: expectedRequest, response: apiResponse}
673	client, tearDown := server.getClient()
674	defer tearDown()
675	repo := Repository{Client: *client}
676
677	availabilityList, err := repo.GetAvailabilityForMultipleDomains([]string{"example.com", "example.nl"})
678	require.NoError(t, err)
679	require.Equal(t, 1, len(availabilityList))
680	assert.Equal(t, "example.com", availabilityList[0].DomainName)
681	assert.EqualValues(t, "free", availabilityList[0].Status)
682	assert.Equal(t, []PerformAction{"register"}, availabilityList[0].Actions)
683}
684
685func TestRepository_GetTLDs(t *testing.T) {
686	apiResponse := `{"tlds":[{"name":".nl","price":399,"recurringPrice":749,"capabilities":["canRegister"],"minLength":2,"maxLength":63,"registrationPeriodLength":12,"cancelTimeFrame":1}]}`
687	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/tlds", statusCode: 200, response: apiResponse}
688	client, tearDown := server.getClient()
689	defer tearDown()
690	repo := Repository{Client: *client}
691
692	tlds, err := repo.GetTLDs()
693	require.NoError(t, err)
694	require.Equal(t, 1, len(tlds))
695	assert.Equal(t, ".nl", tlds[0].Name)
696	assert.Equal(t, 399, tlds[0].Price)
697	assert.Equal(t, 749, tlds[0].RecurringPrice)
698	assert.Equal(t, 2, tlds[0].MinLength)
699	assert.Equal(t, 63, tlds[0].MaxLength)
700	assert.Equal(t, 12, tlds[0].RegistrationPeriodLength)
701	assert.Equal(t, 1, tlds[0].CancelTimeFrame)
702
703	assert.Equal(t, []string{"canRegister"}, tlds[0].Capabilities)
704}
705
706func TestRepository_GetTldInfo(t *testing.T) {
707	apiResponse := `{"tld":{"name":".nl","price":399,"recurringPrice":749,"capabilities":["canRegister"],"minLength":2,"maxLength":63,"registrationPeriodLength":12,"cancelTimeFrame":1}}`
708	server := mockServer{t: t, expectedMethod: "GET", expectedURL: "/tlds/.nl", statusCode: 200, response: apiResponse}
709	client, tearDown := server.getClient()
710	defer tearDown()
711	repo := Repository{Client: *client}
712
713	tld, err := repo.GetTLDByTLD(".nl")
714	require.NoError(t, err)
715	assert.Equal(t, ".nl", tld.Name)
716	assert.Equal(t, 399, tld.Price)
717	assert.Equal(t, 749, tld.RecurringPrice)
718	assert.Equal(t, 2, tld.MinLength)
719	assert.Equal(t, 63, tld.MaxLength)
720	assert.Equal(t, 12, tld.RegistrationPeriodLength)
721	assert.Equal(t, 1, tld.CancelTimeFrame)
722
723	assert.Equal(t, []string{"canRegister"}, tld.Capabilities)
724}
725