...

Source file src/github.com/go-openapi/strfmt/format_test.go

Documentation: github.com/go-openapi/strfmt

     1  // Copyright 2015 go-swagger maintainers
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package strfmt
    16  
    17  import (
    18  	"strings"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/mitchellh/mapstructure"
    23  	"github.com/stretchr/testify/assert"
    24  	"github.com/stretchr/testify/require"
    25  )
    26  
    27  type testFormat string
    28  
    29  func (t testFormat) MarshalText() ([]byte, error) {
    30  	return []byte(string(t)), nil
    31  }
    32  
    33  func (t *testFormat) UnmarshalText(b []byte) error {
    34  	*t = testFormat(string(b))
    35  	return nil
    36  }
    37  
    38  func (t testFormat) String() string {
    39  	return string(t)
    40  }
    41  
    42  func isTestFormat(s string) bool {
    43  	return strings.HasPrefix(s, "tf")
    44  }
    45  
    46  type tf2 string
    47  
    48  func (t tf2) MarshalText() ([]byte, error) {
    49  	return []byte(string(t)), nil
    50  }
    51  
    52  func (t *tf2) UnmarshalText(b []byte) error {
    53  	*t = tf2(string(b))
    54  	return nil
    55  }
    56  
    57  func istf2(s string) bool {
    58  	return strings.HasPrefix(s, "af")
    59  }
    60  
    61  func (t tf2) String() string {
    62  	return string(t)
    63  }
    64  
    65  type bf string
    66  
    67  func (t bf) MarshalText() ([]byte, error) {
    68  	return []byte(string(t)), nil
    69  }
    70  
    71  func (t *bf) UnmarshalText(b []byte) error {
    72  	*t = bf(string(b))
    73  	return nil
    74  }
    75  
    76  func (t bf) String() string {
    77  	return string(t)
    78  }
    79  
    80  func isbf(s string) bool {
    81  	return strings.HasPrefix(s, "bf")
    82  }
    83  
    84  func istf3(s string) bool {
    85  	return strings.HasPrefix(s, "ff")
    86  }
    87  
    88  func init() {
    89  	tf := testFormat("")
    90  	Default.Add("test-format", &tf, isTestFormat)
    91  }
    92  
    93  func TestFormatRegistry(t *testing.T) {
    94  	f2 := tf2("")
    95  	f3 := bf("")
    96  	registry := NewFormats()
    97  
    98  	assert.True(t, registry.ContainsName("test-format"))
    99  	assert.True(t, registry.ContainsName("testformat"))
   100  	assert.False(t, registry.ContainsName("ttt"))
   101  
   102  	assert.True(t, registry.Validates("testformat", "tfa"))
   103  	assert.False(t, registry.Validates("testformat", "ffa"))
   104  
   105  	assert.True(t, registry.Add("tf2", &f2, istf2))
   106  	assert.True(t, registry.ContainsName("tf2"))
   107  	assert.False(t, registry.ContainsName("tfw"))
   108  	assert.True(t, registry.Validates("tf2", "afa"))
   109  
   110  	assert.False(t, registry.Add("tf2", &f3, isbf))
   111  	assert.True(t, registry.ContainsName("tf2"))
   112  	assert.False(t, registry.ContainsName("tfw"))
   113  	assert.True(t, registry.Validates("tf2", "bfa"))
   114  	assert.False(t, registry.Validates("tf2", "afa"))
   115  
   116  	assert.False(t, registry.Add("tf2", &f2, istf2))
   117  	assert.True(t, registry.Add("tf3", &f2, istf3))
   118  	assert.True(t, registry.ContainsName("tf3"))
   119  	assert.True(t, registry.ContainsName("tf2"))
   120  	assert.False(t, registry.ContainsName("tfw"))
   121  	assert.True(t, registry.Validates("tf3", "ffa"))
   122  
   123  	assert.True(t, registry.DelByName("tf3"))
   124  	assert.True(t, registry.Add("tf3", &f2, istf3))
   125  
   126  	assert.True(t, registry.DelByName("tf3"))
   127  	assert.False(t, registry.DelByName("unknown"))
   128  	assert.False(t, registry.Validates("unknown", ""))
   129  }
   130  
   131  type testStruct struct {
   132  	D          Date       `json:"d,omitempty"`
   133  	DT         DateTime   `json:"dt,omitempty"`
   134  	Dur        Duration   `json:"dur,omitempty"`
   135  	URI        URI        `json:"uri,omitempty"`
   136  	Eml        Email      `json:"eml,omitempty"`
   137  	UUID       UUID       `json:"uuid,omitempty"`
   138  	UUID3      UUID3      `json:"uuid3,omitempty"`
   139  	UUID4      UUID4      `json:"uuid4,omitempty"`
   140  	UUID5      UUID5      `json:"uuid5,omitempty"`
   141  	Hn         Hostname   `json:"hn,omitempty"`
   142  	Ipv4       IPv4       `json:"ipv4,omitempty"`
   143  	Ipv6       IPv6       `json:"ipv6,omitempty"`
   144  	Cidr       CIDR       `json:"cidr,omitempty"`
   145  	Mac        MAC        `json:"mac,omitempty"`
   146  	Isbn       ISBN       `json:"isbn,omitempty"`
   147  	Isbn10     ISBN10     `json:"isbn10,omitempty"`
   148  	Isbn13     ISBN13     `json:"isbn13,omitempty"`
   149  	Creditcard CreditCard `json:"creditcard,omitempty"`
   150  	Ssn        SSN        `json:"ssn,omitempty"`
   151  	Hexcolor   HexColor   `json:"hexcolor,omitempty"`
   152  	Rgbcolor   RGBColor   `json:"rgbcolor,omitempty"`
   153  	B64        Base64     `json:"b64,omitempty"`
   154  	Pw         Password   `json:"pw,omitempty"`
   155  	ULID       ULID       `json:"ulid,omitempty"`
   156  }
   157  
   158  func TestDecodeHook(t *testing.T) {
   159  	registry := NewFormats()
   160  	m := map[string]interface{}{
   161  		"d":          "2014-12-15",
   162  		"dt":         "2012-03-02T15:06:05.999999999Z",
   163  		"dur":        "5s",
   164  		"uri":        "http://www.dummy.com",
   165  		"eml":        "dummy@dummy.com",
   166  		"uuid":       "a8098c1a-f86e-11da-bd1a-00112444be1e",
   167  		"uuid3":      "bcd02e22-68f0-3046-a512-327cca9def8f",
   168  		"uuid4":      "025b0d74-00a2-4048-bf57-227c5111bb34",
   169  		"uuid5":      "886313e1-3b8a-5372-9b90-0c9aee199e5d",
   170  		"hn":         "somewhere.com",
   171  		"ipv4":       "192.168.254.1",
   172  		"ipv6":       "::1",
   173  		"cidr":       "192.0.2.1/24",
   174  		"mac":        "01:02:03:04:05:06",
   175  		"isbn":       "0321751043",
   176  		"isbn10":     "0321751043",
   177  		"isbn13":     "978-0321751041",
   178  		"hexcolor":   "#FFFFFF",
   179  		"rgbcolor":   "rgb(255,255,255)",
   180  		"pw":         "super secret stuff here",
   181  		"ssn":        "111-11-1111",
   182  		"creditcard": "4111-1111-1111-1111",
   183  		"b64":        "ZWxpemFiZXRocG9zZXk=",
   184  		"ulid":       "7ZZZZZZZZZZZZZZZZZZZZZZZZZ",
   185  	}
   186  
   187  	date, _ := time.Parse(RFC3339FullDate, "2014-12-15")
   188  	dur, _ := ParseDuration("5s")
   189  	dt, _ := ParseDateTime("2012-03-02T15:06:05.999999999Z")
   190  	ulid, _ := ParseULID("7ZZZZZZZZZZZZZZZZZZZZZZZZZ")
   191  
   192  	exp := &testStruct{
   193  		D:          Date(date),
   194  		DT:         dt,
   195  		Dur:        Duration(dur),
   196  		URI:        URI("http://www.dummy.com"),
   197  		Eml:        Email("dummy@dummy.com"),
   198  		UUID:       UUID("a8098c1a-f86e-11da-bd1a-00112444be1e"),
   199  		UUID3:      UUID3("bcd02e22-68f0-3046-a512-327cca9def8f"),
   200  		UUID4:      UUID4("025b0d74-00a2-4048-bf57-227c5111bb34"),
   201  		UUID5:      UUID5("886313e1-3b8a-5372-9b90-0c9aee199e5d"),
   202  		Hn:         Hostname("somewhere.com"),
   203  		Ipv4:       IPv4("192.168.254.1"),
   204  		Ipv6:       IPv6("::1"),
   205  		Cidr:       CIDR("192.0.2.1/24"),
   206  		Mac:        MAC("01:02:03:04:05:06"),
   207  		Isbn:       ISBN("0321751043"),
   208  		Isbn10:     ISBN10("0321751043"),
   209  		Isbn13:     ISBN13("978-0321751041"),
   210  		Creditcard: CreditCard("4111-1111-1111-1111"),
   211  		Ssn:        SSN("111-11-1111"),
   212  		Hexcolor:   HexColor("#FFFFFF"),
   213  		Rgbcolor:   RGBColor("rgb(255,255,255)"),
   214  		B64:        Base64("ZWxpemFiZXRocG9zZXk="),
   215  		Pw:         Password("super secret stuff here"),
   216  		ULID:       ulid,
   217  	}
   218  
   219  	test := new(testStruct)
   220  	cfg := &mapstructure.DecoderConfig{
   221  		DecodeHook: registry.MapStructureHookFunc(),
   222  		// weakly typed will pass if this passes
   223  		WeaklyTypedInput: false,
   224  		Result:           test,
   225  	}
   226  	d, err := mapstructure.NewDecoder(cfg)
   227  	require.NoError(t, err)
   228  	err = d.Decode(m)
   229  	require.NoError(t, err)
   230  	assert.Equal(t, exp, test)
   231  }
   232  
   233  func TestDecodeDateTimeHook(t *testing.T) {
   234  	testCases := []struct {
   235  		Name  string
   236  		Input string
   237  	}{
   238  		{
   239  			"empty datetime",
   240  			"",
   241  		},
   242  		{
   243  			"invalid non empty datetime",
   244  			"2019-01-01abc",
   245  		},
   246  	}
   247  	registry := NewFormats()
   248  	type layout struct {
   249  		DateTime *DateTime `json:"datetime,omitempty"`
   250  	}
   251  	for i := range testCases {
   252  		tc := testCases[i]
   253  		t.Run(tc.Name, func(t *testing.T) {
   254  			test := new(layout)
   255  			cfg := &mapstructure.DecoderConfig{
   256  				DecodeHook:       registry.MapStructureHookFunc(),
   257  				WeaklyTypedInput: false,
   258  				Result:           test,
   259  			}
   260  			d, err := mapstructure.NewDecoder(cfg)
   261  			require.NoError(t, err)
   262  			input := make(map[string]interface{})
   263  			input["datetime"] = tc.Input
   264  			err = d.Decode(input)
   265  			require.Error(t, err, "error expected got none")
   266  		})
   267  	}
   268  }
   269  
   270  func TestDecode_ULID_Hook_Negative(t *testing.T) {
   271  	t.Parallel()
   272  	testCases := []struct {
   273  		Name  string
   274  		Input string
   275  	}{
   276  		{
   277  			"empty string for ulid",
   278  			"",
   279  		},
   280  		{
   281  			"invalid non empty ulid",
   282  			"8000000000YYYYYYYYYYYYYYYY",
   283  		},
   284  	}
   285  	registry := NewFormats()
   286  	type layout struct {
   287  		ULID *ULID `json:"ulid,omitempty"`
   288  	}
   289  	for i := range testCases {
   290  		tc := testCases[i]
   291  		t.Run(tc.Name, func(t *testing.T) {
   292  			t.Parallel()
   293  			test := new(layout)
   294  			cfg := &mapstructure.DecoderConfig{
   295  				DecodeHook:       registry.MapStructureHookFunc(),
   296  				WeaklyTypedInput: false,
   297  				Result:           test,
   298  			}
   299  			d, err := mapstructure.NewDecoder(cfg)
   300  			require.NoError(t, err)
   301  			input := make(map[string]interface{})
   302  			input["ulid"] = tc.Input
   303  			err = d.Decode(input)
   304  			require.Error(t, err, "error expected got none")
   305  		})
   306  	}
   307  }
   308  

View as plain text