github.com/opentelekomcloud/gophertelekomcloud@v0.9.3/testing/params_test.go (about)

     1  package testing
     2  
     3  import (
     4  	"net/url"
     5  	"reflect"
     6  	"testing"
     7  
     8  	golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
     9  	th "github.com/opentelekomcloud/gophertelekomcloud/testhelper"
    10  )
    11  
    12  func TestMaybeString(t *testing.T) {
    13  	testString := ""
    14  	var expected *string
    15  	actual := golangsdk.MaybeString(testString)
    16  	th.CheckDeepEquals(t, expected, actual)
    17  
    18  	testString = "carol"
    19  	expected = &testString
    20  	actual = golangsdk.MaybeString(testString)
    21  	th.CheckDeepEquals(t, expected, actual)
    22  }
    23  
    24  func TestMaybeInt(t *testing.T) {
    25  	testInt := 0
    26  	var expected *int
    27  	actual := golangsdk.MaybeInt(testInt)
    28  	th.CheckDeepEquals(t, expected, actual)
    29  
    30  	testInt = 4
    31  	expected = &testInt
    32  	actual = golangsdk.MaybeInt(testInt)
    33  	th.CheckDeepEquals(t, expected, actual)
    34  }
    35  
    36  func TestBuildQueryString(t *testing.T) {
    37  	type testVar string
    38  	iFalse := false
    39  	opts := struct {
    40  		J  int               `q:"j"`
    41  		R  string            `q:"r,required"`
    42  		C  bool              `q:"c"`
    43  		S  []string          `q:"s"`
    44  		TS []testVar         `q:"ts"`
    45  		TI []int             `q:"ti"`
    46  		F  *bool             `q:"f"`
    47  		M  map[string]string `q:"m"`
    48  	}{
    49  		J:  2,
    50  		R:  "red",
    51  		C:  true,
    52  		S:  []string{"one", "two", "three"},
    53  		TS: []testVar{"a", "b"},
    54  		TI: []int{1, 2},
    55  		F:  &iFalse,
    56  		M:  map[string]string{"k1": "success1"},
    57  	}
    58  	expected := &url.URL{RawQuery: "c=true&f=false&j=2&m=%7B%27k1%27%3A%27success1%27%7D&r=red&s=one&s=two&s=three&ti=1&ti=2&ts=a&ts=b"}
    59  	actual, err := golangsdk.BuildQueryString(&opts)
    60  	if err != nil {
    61  		t.Errorf("Error building query string: %v", err)
    62  	}
    63  	th.CheckDeepEquals(t, expected, actual)
    64  
    65  	opts = struct {
    66  		J  int               `q:"j"`
    67  		R  string            `q:"r,required"`
    68  		C  bool              `q:"c"`
    69  		S  []string          `q:"s"`
    70  		TS []testVar         `q:"ts"`
    71  		TI []int             `q:"ti"`
    72  		F  *bool             `q:"f"`
    73  		M  map[string]string `q:"m"`
    74  	}{
    75  		J: 2,
    76  		C: true,
    77  	}
    78  	_, err = golangsdk.BuildQueryString(&opts)
    79  	if err == nil {
    80  		t.Errorf("Expected error: 'Required field not set'")
    81  	}
    82  	th.CheckDeepEquals(t, expected, actual)
    83  
    84  	_, err = golangsdk.BuildQueryString(map[string]interface{}{"Number": 4})
    85  	if err == nil {
    86  		t.Errorf("Expected error: 'Options type is not a struct'")
    87  	}
    88  }
    89  
    90  func TestBuildHeaders(t *testing.T) {
    91  	testStruct := struct {
    92  		Accept string `h:"Accept"`
    93  		Num    int    `h:"Number,required"`
    94  		Style  bool   `h:"Style"`
    95  	}{
    96  		Accept: "application/json",
    97  		Num:    4,
    98  		Style:  true,
    99  	}
   100  	expected := map[string]string{"Accept": "application/json", "Number": "4", "Style": "true"}
   101  	actual, err := golangsdk.BuildHeaders(&testStruct)
   102  	th.CheckNoErr(t, err)
   103  	th.CheckDeepEquals(t, expected, actual)
   104  
   105  	testStruct.Num = 0
   106  	_, err = golangsdk.BuildHeaders(&testStruct)
   107  	if err == nil {
   108  		t.Errorf("Expected error: 'Required header not set'")
   109  	}
   110  
   111  	_, err = golangsdk.BuildHeaders(map[string]interface{}{"Number": 4})
   112  	if err == nil {
   113  		t.Errorf("Expected error: 'Options type is not a struct'")
   114  	}
   115  }
   116  
   117  func TestQueriesAreEscaped(t *testing.T) {
   118  	type foo struct {
   119  		Name  string `q:"something"`
   120  		Shape string `q:"else"`
   121  	}
   122  
   123  	expected := &url.URL{RawQuery: "else=Triangl+e&something=blah%2B%3F%21%21foo"}
   124  
   125  	actual, err := golangsdk.BuildQueryString(foo{Name: "blah+?!!foo", Shape: "Triangl e"})
   126  	th.AssertNoErr(t, err)
   127  
   128  	th.AssertDeepEquals(t, expected, actual)
   129  }
   130  
   131  func TestBuildRequestBody(t *testing.T) {
   132  	type PasswordCredentials struct {
   133  		Username string `json:"username" required:"true"`
   134  		Password string `json:"password" required:"true"`
   135  	}
   136  
   137  	type TokenCredentials struct {
   138  		ID string `json:"id,omitempty" required:"true"`
   139  	}
   140  
   141  	type orFields struct {
   142  		Filler int `json:"filler,omitempty"`
   143  		F1     int `json:"f1,omitempty" or:"F2"`
   144  		F2     int `json:"f2,omitempty" or:"F1"`
   145  	}
   146  
   147  	// AuthOptions wraps a golangsdk AuthOptions in order to adhere to the AuthOptionsBuilder
   148  	// interface.
   149  	type AuthOptions struct {
   150  		PasswordCredentials *PasswordCredentials `json:"passwordCredentials,omitempty" xor:"TokenCredentials"`
   151  
   152  		// The TenantID and TenantName fields are optional for the Identity V2 API.
   153  		// Some providers allow you to specify a TenantName instead of the TenantId.
   154  		// Some require both. Your provider's authentication policies will determine
   155  		// how these fields influence authentication.
   156  		TenantID   string `json:"tenantId,omitempty"`
   157  		TenantName string `json:"tenantName,omitempty"`
   158  
   159  		// TokenCredentials allows users to authenticate (possibly as another user) with an
   160  		// authentication token ID.
   161  		TokenCredentials *TokenCredentials `json:"token,omitempty" xor:"PasswordCredentials"`
   162  
   163  		OrFields *orFields `json:"or_fields,omitempty"`
   164  	}
   165  
   166  	var successCases = []struct {
   167  		opts     AuthOptions
   168  		expected map[string]interface{}
   169  	}{
   170  		{
   171  			AuthOptions{
   172  				PasswordCredentials: &PasswordCredentials{
   173  					Username: "me",
   174  					Password: "swordfish",
   175  				},
   176  			},
   177  			map[string]interface{}{
   178  				"auth": map[string]interface{}{
   179  					"passwordCredentials": map[string]interface{}{
   180  						"password": "swordfish",
   181  						"username": "me",
   182  					},
   183  				},
   184  			},
   185  		},
   186  		{
   187  			AuthOptions{
   188  				TokenCredentials: &TokenCredentials{
   189  					ID: "1234567",
   190  				},
   191  			},
   192  			map[string]interface{}{
   193  				"auth": map[string]interface{}{
   194  					"token": map[string]interface{}{
   195  						"id": "1234567",
   196  					},
   197  				},
   198  			},
   199  		},
   200  	}
   201  
   202  	for _, successCase := range successCases {
   203  		actual, err := golangsdk.BuildRequestBody(successCase.opts, "auth")
   204  		th.AssertNoErr(t, err)
   205  		th.AssertDeepEquals(t, successCase.expected, actual)
   206  	}
   207  
   208  	var failCases = []struct {
   209  		opts     AuthOptions
   210  		expected error
   211  	}{
   212  		{
   213  			AuthOptions{
   214  				TenantID:   "987654321",
   215  				TenantName: "me",
   216  			},
   217  			golangsdk.ErrMissingInput{},
   218  		},
   219  		{
   220  			AuthOptions{
   221  				TokenCredentials: &TokenCredentials{
   222  					ID: "1234567",
   223  				},
   224  				PasswordCredentials: &PasswordCredentials{
   225  					Username: "me",
   226  					Password: "swordfish",
   227  				},
   228  			},
   229  			golangsdk.ErrMissingInput{},
   230  		},
   231  		{
   232  			AuthOptions{
   233  				PasswordCredentials: &PasswordCredentials{
   234  					Password: "swordfish",
   235  				},
   236  			},
   237  			golangsdk.ErrMissingInput{},
   238  		},
   239  		{
   240  			AuthOptions{
   241  				PasswordCredentials: &PasswordCredentials{
   242  					Username: "me",
   243  					Password: "swordfish",
   244  				},
   245  				OrFields: &orFields{
   246  					Filler: 2,
   247  				},
   248  			},
   249  			golangsdk.ErrMissingInput{},
   250  		},
   251  	}
   252  
   253  	for _, failCase := range failCases {
   254  		_, err := golangsdk.BuildRequestBody(failCase.opts, "auth")
   255  		th.AssertDeepEquals(t, reflect.TypeOf(failCase.expected), reflect.TypeOf(err))
   256  	}
   257  }