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

     1  package dns
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"testing"
     9  
    10  	"github.com/akamai/AkamaiOPEN-edgegrid-golang/v8/pkg/session"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func TestDNS_GetRecord(t *testing.T) {
    16  	tests := map[string]struct {
    17  		zone             string
    18  		name             string
    19  		recordType       string
    20  		responseStatus   int
    21  		responseBody     string
    22  		expectedPath     string
    23  		expectedResponse *RecordBody
    24  		withError        error
    25  	}{
    26  		"200 OK": {
    27  			zone:           "example.com",
    28  			name:           "www.example.com",
    29  			recordType:     "A",
    30  			responseStatus: http.StatusOK,
    31  			responseBody: `
    32  			{
    33  				"name": "www.example.com",
    34  				"type": "A",
    35  				"ttl": 300,
    36  				"rdata": [
    37  					"10.0.0.2",
    38  					"10.0.0.3"
    39  				]
    40  			}`,
    41  			expectedPath: "/config-dns/v2/zones/example.com/names/www.example.com/types/A",
    42  			expectedResponse: &RecordBody{
    43  				Name:       "www.example.com",
    44  				RecordType: "A",
    45  				TTL:        300,
    46  				Active:     false,
    47  				Target:     []string{"10.0.0.2", "10.0.0.3"},
    48  			},
    49  		},
    50  		"500 internal server error": {
    51  			zone:           "example.com",
    52  			name:           "www.example.com",
    53  			recordType:     "A",
    54  			responseStatus: http.StatusInternalServerError,
    55  			responseBody: `
    56  {
    57  	"type": "internal_error",
    58      "title": "Internal Server Error",
    59      "detail": "Error fetching authorities",
    60      "status": 500
    61  }`,
    62  			expectedPath: "/config-dns/v2/zones/example.com/names/www.example.com/types/A",
    63  			withError: &Error{
    64  				Type:       "internal_error",
    65  				Title:      "Internal Server Error",
    66  				Detail:     "Error fetching authorities",
    67  				StatusCode: http.StatusInternalServerError,
    68  			},
    69  		},
    70  	}
    71  
    72  	for name, test := range tests {
    73  		t.Run(name, func(t *testing.T) {
    74  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    75  				assert.Equal(t, test.expectedPath, r.URL.String())
    76  				assert.Equal(t, http.MethodGet, r.Method)
    77  				w.WriteHeader(test.responseStatus)
    78  				_, err := w.Write([]byte(test.responseBody))
    79  				assert.NoError(t, err)
    80  			}))
    81  			client := mockAPIClient(t, mockServer)
    82  			result, err := client.GetRecord(context.Background(), test.zone, test.name, test.recordType)
    83  			if test.withError != nil {
    84  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
    85  				return
    86  			}
    87  			require.NoError(t, err)
    88  			assert.Equal(t, test.expectedResponse, result)
    89  		})
    90  	}
    91  }
    92  
    93  func TestDNS_GetRecordList(t *testing.T) {
    94  	tests := map[string]struct {
    95  		zone             string
    96  		name             string
    97  		recordType       string
    98  		responseStatus   int
    99  		responseBody     string
   100  		expectedPath     string
   101  		expectedResponse *RecordSetResponse
   102  		withError        error
   103  	}{
   104  		"200 OK": {
   105  			zone:           "example.com",
   106  			recordType:     "A",
   107  			responseStatus: http.StatusOK,
   108  			responseBody: `
   109  {
   110  	"metadata": {
   111          "zone": "example.com",
   112          "page": 1,
   113          "pageSize": 25,
   114          "totalElements": 2,
   115          "types": [
   116              "A"
   117          ]
   118      },
   119      "recordsets": [
   120          {
   121              "name": "www.example.com",
   122              "type": "A",
   123              "ttl": 300,
   124              "rdata": [
   125                  "10.0.0.2",
   126                  "10.0.0.3"
   127              ]
   128          }
   129      ]
   130  }`,
   131  			expectedPath: "/config-dns/v2/zones/example.com/recordsets?showAll=true&types=A",
   132  			expectedResponse: &RecordSetResponse{
   133  				Metadata: Metadata{
   134  					LastPage:      0,
   135  					Page:          1,
   136  					PageSize:      25,
   137  					ShowAll:       false,
   138  					TotalElements: 2,
   139  				},
   140  				RecordSets: []RecordSet{
   141  					{
   142  						Name:  "www.example.com",
   143  						Type:  "A",
   144  						TTL:   300,
   145  						Rdata: []string{"10.0.0.2", "10.0.0.3"},
   146  					},
   147  				},
   148  			},
   149  		},
   150  		"500 internal server error": {
   151  			zone:           "example.com",
   152  			recordType:     "A",
   153  			responseStatus: http.StatusInternalServerError,
   154  			responseBody: `
   155  {
   156  	"type": "internal_error",
   157      "title": "Internal Server Error",
   158      "detail": "Error fetching authorities",
   159      "status": 500
   160  }`,
   161  			expectedPath: "/config-dns/v2/zones/example.com/recordsets?showAll=true&types=A",
   162  			withError: &Error{
   163  				Type:       "internal_error",
   164  				Title:      "Internal Server Error",
   165  				Detail:     "Error fetching authorities",
   166  				StatusCode: http.StatusInternalServerError,
   167  			},
   168  		},
   169  	}
   170  
   171  	for name, test := range tests {
   172  		t.Run(name, func(t *testing.T) {
   173  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   174  				assert.Equal(t, test.expectedPath, r.URL.String())
   175  				assert.Equal(t, http.MethodGet, r.Method)
   176  				w.WriteHeader(test.responseStatus)
   177  				_, err := w.Write([]byte(test.responseBody))
   178  				assert.NoError(t, err)
   179  			}))
   180  			client := mockAPIClient(t, mockServer)
   181  			result, err := client.GetRecordList(context.Background(), test.zone, test.name, test.recordType)
   182  			if test.withError != nil {
   183  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   184  				return
   185  			}
   186  			require.NoError(t, err)
   187  			assert.Equal(t, test.expectedResponse, result)
   188  		})
   189  	}
   190  }
   191  
   192  func TestDNS_GetRdata(t *testing.T) {
   193  	tests := map[string]struct {
   194  		zone             string
   195  		name             string
   196  		recordType       string
   197  		responseStatus   int
   198  		responseBody     string
   199  		expectedPath     string
   200  		expectedResponse []string
   201  		withError        error
   202  	}{
   203  		"ipv6 test": {
   204  			zone:           "example.com",
   205  			name:           "www.example.com",
   206  			recordType:     "AAAA",
   207  			responseStatus: http.StatusOK,
   208  			responseBody: `
   209  {
   210  	"metadata": {
   211          "zone": "example.com",
   212          "page": 1,
   213          "pageSize": 25,
   214          "totalElements": 1,
   215          "types": [
   216              "AAAA"
   217          ]
   218      },
   219      "recordsets": [
   220          {
   221              "name": "www.example.com",
   222              "type": "AAAA",
   223              "ttl": 300,
   224              "rdata": [
   225                  "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
   226              ]
   227  		}
   228      ]
   229  }`,
   230  			expectedPath:     "/config-dns/v2/zones/example.com/recordsets?showAll=true&types=AAAA",
   231  			expectedResponse: []string{"2001:0db8:85a3:0000:0000:8a2e:0370:7334"},
   232  		},
   233  		"loc test": {
   234  			zone:           "example.com",
   235  			name:           "www.example.com",
   236  			recordType:     "LOC",
   237  			responseStatus: http.StatusOK,
   238  			responseBody: `
   239  {
   240  	"metadata": {
   241          "zone": "example.com",
   242          "page": 1,
   243          "pageSize": 25,
   244          "totalElements": 1,
   245          "types": [
   246              "LOC"
   247          ]
   248      },
   249      "recordsets": [
   250  		{
   251              "name": "www.example.com",
   252              "type": "LOC",
   253              "ttl": 300,
   254              "rdata": [
   255                  "52 22 23.000 N 4 53 32.000 E -2.00m 0.00m 10000m 10m"
   256              ]
   257          }
   258      ]
   259  }`,
   260  			expectedPath:     "/config-dns/v2/zones/example.com/recordsets?showAll=true&types=LOC",
   261  			expectedResponse: []string{"52 22 23.000 N 4 53 32.000 E -2.00m 0.00m 10000.00m 10.00m"},
   262  		},
   263  		"500 internal server error": {
   264  			zone:           "example.com",
   265  			recordType:     "A",
   266  			responseStatus: http.StatusInternalServerError,
   267  			responseBody: `
   268  {
   269  	"type": "internal_error",
   270      "title": "Internal Server Error",
   271      "detail": "Error fetching authorities",
   272      "status": 500
   273  }`,
   274  			expectedPath: "/config-dns/v2/zones/example.com/recordsets?showAll=true&types=A",
   275  			withError: &Error{
   276  				Type:       "internal_error",
   277  				Title:      "Internal Server Error",
   278  				Detail:     "Error fetching authorities",
   279  				StatusCode: http.StatusInternalServerError,
   280  			},
   281  		},
   282  	}
   283  
   284  	for name, test := range tests {
   285  		t.Run(name, func(t *testing.T) {
   286  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   287  				assert.Equal(t, test.expectedPath, r.URL.String())
   288  				assert.Equal(t, http.MethodGet, r.Method)
   289  				w.WriteHeader(test.responseStatus)
   290  				_, err := w.Write([]byte(test.responseBody))
   291  				assert.NoError(t, err)
   292  			}))
   293  			client := mockAPIClient(t, mockServer)
   294  			result, err := client.GetRdata(context.Background(), test.zone, test.name, test.recordType)
   295  			if test.withError != nil {
   296  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   297  				return
   298  			}
   299  			require.NoError(t, err)
   300  			assert.Equal(t, test.expectedResponse, result)
   301  		})
   302  	}
   303  }
   304  
   305  func TestDNS_TestRdata(t *testing.T) {
   306  	client := Client(session.Must(session.New()))
   307  
   308  	out := client.ProcessRdata(context.Background(), []string{"2001:0db8:85a3:0000:0000:8a2e:0370:7334"}, "AAAA")
   309  
   310  	assert.Equal(t, []string{"2001:0db8:85a3:0000:0000:8a2e:0370:7334"}, out)
   311  
   312  	out = client.ProcessRdata(context.Background(), []string{"52 22 23.000 N 4 53 32.000 E -2.00m 0.00m 10000.00m 10.00m"}, "LOC")
   313  
   314  	assert.Equal(t, []string{"52 22 23.000 N 4 53 32.000 E -2.00m 0.00m 10000.00m 10.00m"}, out)
   315  }
   316  
   317  func TestDNS_ParseRData(t *testing.T) {
   318  	client := Client(session.Must(session.New()))
   319  
   320  	tests := map[string]struct {
   321  		rType  string
   322  		rdata  []string
   323  		expect map[string]interface{}
   324  	}{
   325  		"AFSDB": {
   326  			rType: "AFSDB",
   327  			rdata: []string{"1 bar.com"},
   328  			expect: map[string]interface{}{
   329  				"subtype": 1,
   330  				"target":  []string{"bar.com"},
   331  			},
   332  		},
   333  		"SVCB": {
   334  			rType: "SVCB",
   335  			rdata: []string{"0 svc4.example.com."},
   336  			expect: map[string]interface{}{
   337  				"target":       []string{},
   338  				"svc_priority": 0,
   339  				"target_name":  "svc4.example.com.",
   340  			},
   341  		},
   342  		"HTTPS": {
   343  			rType: "HTTPS",
   344  			rdata: []string{"3 https.example.com. alpn=bar port=8080"},
   345  			expect: map[string]interface{}{
   346  				"target":       []string{},
   347  				"svc_priority": 3,
   348  				"target_name":  "https.example.com.",
   349  				"svc_params":   "alpn=bar port=8080",
   350  			},
   351  		},
   352  		"SRV with default values": {
   353  			rType: "SRV",
   354  			rdata: []string{"10 60 5060 big.example.com.", "10 60 5060 small.example.com."},
   355  			expect: map[string]interface{}{
   356  				"port":     5060,
   357  				"priority": 10,
   358  				"weight":   60,
   359  				"target":   []string{"big.example.com.", "small.example.com."},
   360  			},
   361  		},
   362  		"SRV without default values": {
   363  			rType: "SRV",
   364  			rdata: []string{"10 60 5060 big.example.com.", "20 50 5060 small.example.com."},
   365  			expect: map[string]interface{}{
   366  				"target": []string{"10 60 5060 big.example.com.", "20 50 5060 small.example.com."},
   367  			},
   368  		},
   369  	}
   370  
   371  	for name, test := range tests {
   372  		t.Run(name, func(t *testing.T) {
   373  			out := client.ParseRData(context.Background(), test.rType, test.rdata)
   374  
   375  			assert.Equal(t, test.expect, out)
   376  		})
   377  	}
   378  }