...

Source file src/github.com/go-openapi/jsonreference/reference_test.go

Documentation: github.com/go-openapi/jsonreference

     1  // Copyright 2013 sigu-399 ( https://github.com/sigu-399 )
     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  // author       sigu-399
    16  // author-github  https://github.com/sigu-399
    17  // author-mail    sigu.399@gmail.com
    18  //
    19  // repository-name  jsonreference
    20  // repository-desc  An implementation of JSON Reference - Go language
    21  //
    22  // description    Automated tests on package.
    23  //
    24  // created        03-03-2013
    25  
    26  package jsonreference
    27  
    28  import (
    29  	"testing"
    30  
    31  	"github.com/go-openapi/jsonpointer"
    32  	"github.com/stretchr/testify/assert"
    33  	"github.com/stretchr/testify/require"
    34  )
    35  
    36  func TestIsRoot(t *testing.T) {
    37  	t.Run("with empty fragment", func(t *testing.T) {
    38  		in := "#"
    39  		r1, err := New(in)
    40  		require.NoError(t, err)
    41  		assert.True(t, r1.IsRoot())
    42  	})
    43  
    44  	t.Run("with fragment", func(t *testing.T) {
    45  		in := "#/ok"
    46  		r1 := MustCreateRef(in)
    47  		assert.False(t, r1.IsRoot())
    48  	})
    49  
    50  	t.Run("with invalid ref", func(t *testing.T) {
    51  		assert.Panics(t, assert.PanicTestFunc(func() {
    52  			MustCreateRef("%2")
    53  		}))
    54  	})
    55  }
    56  
    57  func TestFullURL(t *testing.T) {
    58  	t.Run("with fragment", func(t *testing.T) {
    59  		const (
    60  			in = "http://host/path/a/b/c#/f/a/b"
    61  		)
    62  
    63  		r1, err := New(in)
    64  		require.NoError(t, err)
    65  		assert.Equal(t, in, r1.String())
    66  		require.False(t, r1.HasFragmentOnly)
    67  		require.True(t, r1.HasFullURL)
    68  		require.False(t, r1.HasURLPathOnly)
    69  		require.False(t, r1.HasFileScheme)
    70  		require.Equal(t, "/f/a/b", r1.GetPointer().String())
    71  	})
    72  
    73  	t.Run("with empty fragment", func(t *testing.T) {
    74  		const in = "http://host/path/a/b/c"
    75  
    76  		r1, err := New(in)
    77  		require.NoError(t, err)
    78  		assert.Equal(t, in, r1.String())
    79  		require.False(t, r1.HasFragmentOnly)
    80  		require.True(t, r1.HasFullURL)
    81  		require.False(t, r1.HasURLPathOnly)
    82  		require.False(t, r1.HasFileScheme)
    83  		require.Empty(t, r1.GetPointer().String())
    84  	})
    85  }
    86  
    87  func TestFragmentOnly(t *testing.T) {
    88  	const in = "#/fragment/only"
    89  
    90  	r1, err := New(in)
    91  	require.NoError(t, err)
    92  	assert.Equal(t, in, r1.String())
    93  
    94  	require.True(t, r1.HasFragmentOnly)
    95  	require.False(t, r1.HasFullURL)
    96  	require.False(t, r1.HasURLPathOnly)
    97  	require.False(t, r1.HasFileScheme)
    98  	require.Equal(t, "/fragment/only", r1.GetPointer().String())
    99  
   100  	p, err := jsonpointer.New(r1.referenceURL.Fragment)
   101  	require.NoError(t, err)
   102  
   103  	t.Run("Ref with fragmentOnly", func(t *testing.T) {
   104  		r2 := Ref{referencePointer: p, HasFragmentOnly: true}
   105  		assert.Equal(t, in, r2.String())
   106  	})
   107  
   108  	t.Run("Ref without fragmentOnly", func(t *testing.T) {
   109  		r3 := Ref{referencePointer: p, HasFragmentOnly: false}
   110  		assert.Equal(t, in[1:], r3.String())
   111  	})
   112  }
   113  
   114  func TestURLPathOnly(t *testing.T) {
   115  	const in = "/documents/document.json"
   116  
   117  	r1, err := New(in)
   118  	require.NoError(t, err)
   119  	assert.Equal(t, in, r1.String())
   120  	require.False(t, r1.HasFragmentOnly)
   121  	require.False(t, r1.HasFullURL)
   122  	require.True(t, r1.HasURLPathOnly)
   123  	require.False(t, r1.HasFileScheme)
   124  	require.Empty(t, r1.GetPointer().String())
   125  }
   126  
   127  func TestURLRelativePathOnly(t *testing.T) {
   128  	const in = "document.json"
   129  
   130  	r1, err := New(in)
   131  	require.NoError(t, err)
   132  	assert.Equal(t, in, r1.String())
   133  	require.False(t, r1.HasFragmentOnly)
   134  	require.False(t, r1.HasFullURL)
   135  	require.True(t, r1.HasURLPathOnly)
   136  	require.False(t, r1.HasFileScheme)
   137  	require.Empty(t, r1.GetPointer().String())
   138  }
   139  
   140  func TestInheritsInValid(t *testing.T) {
   141  	const (
   142  		in1 = "http://www.test.com/doc.json"
   143  		in2 = "#/a/b"
   144  	)
   145  
   146  	r1, err := New(in1)
   147  	require.NoError(t, err)
   148  
   149  	t.Run("inherits from empty Ref", func(t *testing.T) {
   150  		r2 := Ref{}
   151  		result, err := r1.Inherits(r2)
   152  		require.Error(t, err)
   153  		assert.Nil(t, result)
   154  	})
   155  
   156  	t.Run("inherits from non-empty Ref", func(t *testing.T) {
   157  		r1 = Ref{}
   158  		r2, err := New(in2)
   159  		require.NoError(t, err)
   160  
   161  		result, err := r1.Inherits(r2)
   162  		require.NoError(t, err)
   163  		require.NotNil(t, result)
   164  		assert.Equal(t, r2, *result)
   165  	})
   166  }
   167  
   168  func TestInheritsValid(t *testing.T) {
   169  	const (
   170  		in1 = "http://www.test.com/doc.json"
   171  		in2 = "#/a/b"
   172  		out = in1 + in2
   173  	)
   174  
   175  	r1, err := New(in1)
   176  	require.NoError(t, err)
   177  	r2, err := New(in2)
   178  	require.NoError(t, err)
   179  
   180  	result, err := r1.Inherits(r2)
   181  	require.NoError(t, err)
   182  	require.NotNil(t, result)
   183  
   184  	assert.Equal(t, out, result.String())
   185  	assert.Equal(t, "/a/b", result.GetPointer().String())
   186  }
   187  
   188  func TestInheritsDifferentHost(t *testing.T) {
   189  	const (
   190  		in1 = "http://www.test.com/doc.json"
   191  		in2 = "http://www.test2.com/doc.json#bla"
   192  	)
   193  
   194  	r1, err := New(in1)
   195  	require.NoError(t, err)
   196  	r2, err := New(in2)
   197  	require.NoError(t, err)
   198  
   199  	result, err := r1.Inherits(r2)
   200  	require.NoError(t, err)
   201  	require.NotNil(t, result)
   202  
   203  	assert.Equal(t, in2, result.String())
   204  	assert.Empty(t, result.GetPointer().String())
   205  }
   206  
   207  func TestFileScheme(t *testing.T) {
   208  	const (
   209  		in1 = "file:///Users/mac/1.json#a"
   210  		in2 = "file:///Users/mac/2.json#b"
   211  	)
   212  
   213  	r1, err := New(in1)
   214  	require.NoError(t, err)
   215  	r2, err := New(in2)
   216  	require.NoError(t, err)
   217  
   218  	require.False(t, r1.HasFragmentOnly)
   219  	require.True(t, r1.HasFileScheme)
   220  	require.True(t, r1.HasFullFilePath)
   221  	require.True(t, r1.IsCanonical())
   222  	assert.Empty(t, r1.GetPointer().String())
   223  
   224  	result, err := r1.Inherits(r2)
   225  	require.NoError(t, err)
   226  	assert.Equal(t, in2, result.String())
   227  	assert.Empty(t, result.GetPointer().String())
   228  }
   229  
   230  func TestReferenceResolution(t *testing.T) {
   231  	// 5.4. Reference Resolution Examples
   232  	// http://tools.ietf.org/html/rfc3986#section-5.4
   233  	const base = "http://a/b/c/d;p?q"
   234  
   235  	baseRef, err := New(base)
   236  	require.NoError(t, err)
   237  	require.Equal(t, base, baseRef.String())
   238  
   239  	checks := []string{
   240  		// 5.4.1. Normal Examples
   241  		// http://tools.ietf.org/html/rfc3986#section-5.4.1
   242  
   243  		"g:h", "g:h",
   244  		"g", "http://a/b/c/g",
   245  		"./g", "http://a/b/c/g",
   246  		"g/", "http://a/b/c/g/",
   247  		"/g", "http://a/g",
   248  		"//g", "http://g",
   249  		"?y", "http://a/b/c/d;p?y",
   250  		"g?y", "http://a/b/c/g?y",
   251  		"#s", "http://a/b/c/d;p?q#s",
   252  		"g#s", "http://a/b/c/g#s",
   253  		"g?y#s", "http://a/b/c/g?y#s",
   254  		";x", "http://a/b/c/;x",
   255  		"g;x", "http://a/b/c/g;x",
   256  		"g;x?y#s", "http://a/b/c/g;x?y#s",
   257  		"", "http://a/b/c/d;p?q",
   258  		".", "http://a/b/c/",
   259  		"./", "http://a/b/c/",
   260  		"..", "http://a/b/",
   261  		"../", "http://a/b/",
   262  		"../g", "http://a/b/g",
   263  		"../..", "http://a/",
   264  		"../../", "http://a/",
   265  		"../../g", "http://a/g",
   266  
   267  		// 5.4.2. Abnormal Examples
   268  		// http://tools.ietf.org/html/rfc3986#section-5.4.2
   269  
   270  		"../../../g", "http://a/g",
   271  		"../../../../g", "http://a/g",
   272  
   273  		"/./g", "http://a/g",
   274  		"/../g", "http://a/g",
   275  		"g.", "http://a/b/c/g.",
   276  		".g", "http://a/b/c/.g",
   277  		"g..", "http://a/b/c/g..",
   278  		"..g", "http://a/b/c/..g",
   279  
   280  		"./../g", "http://a/b/g",
   281  		"./g/.", "http://a/b/c/g/",
   282  		"g/./h", "http://a/b/c/g/h",
   283  		"g/../h", "http://a/b/c/h",
   284  		"g;x=1/./y", "http://a/b/c/g;x=1/y",
   285  		"g;x=1/../y", "http://a/b/c/y",
   286  
   287  		"g?y/./x", "http://a/b/c/g?y/./x",
   288  		"g?y/../x", "http://a/b/c/g?y/../x",
   289  		"g#s/./x", "http://a/b/c/g#s/./x",
   290  		"g#s/../x", "http://a/b/c/g#s/../x",
   291  
   292  		"http:g", "http:g", // for strict parsers
   293  		// "http:g", "http://a/b/c/g", // for backward compatibility
   294  
   295  	}
   296  	for i := 0; i < len(checks); i += 2 {
   297  		child := checks[i]
   298  		expected := checks[i+1]
   299  
   300  		childRef, e := New(child)
   301  		require.NoErrorf(t, e, "test: %d: New(%s) failed error: %v", i/2, child, e)
   302  
   303  		res, e := baseRef.Inherits(childRef)
   304  		require.NoErrorf(t, e, "test: %d", i/2)
   305  		require.NotNilf(t, res, "test: %d", i/2)
   306  		assert.Equalf(t, expected, res.String(), "test: %d", i/2)
   307  	}
   308  }
   309  
   310  func TestIdenticalURLEncoded(t *testing.T) {
   311  	expected, err := New("https://localhost/🌭#/🍔")
   312  	require.NoErrorf(t, err, "failed to create jsonreference: %v", err)
   313  
   314  	actual, err := New("https://localhost/%F0%9F%8C%AD#/%F0%9F%8D%94")
   315  	require.NoErrorf(t, err, "failed to create jsonreference: %v", err)
   316  	require.Equal(t, expected, actual)
   317  }
   318  

View as plain text