PNG  IHDR pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F@8N ' p @8N@8}' p '#@8N@8N pQ9p!i~}|6-ӪG` VP.@*j>[ K^<֐Z]@8N'KQ<Q(`s" 'hgpKB`R@Dqj '  'P$a ( `D$Na L?u80e J,K˷NI'0eݷ(NI'؀ 2ipIIKp`:O'`ʤxB8Ѥx Ѥx $ $P6 :vRNb 'p,>NB 'P]-->P T+*^h& p '‰a ‰ (ĵt#u33;Nt̵'ޯ; [3W ~]0KH1q@8]O2]3*̧7# *p>us p _6]/}-4|t'|Smx= DoʾM×M_8!)6lq':l7!|4} '\ne t!=hnLn (~Dn\+‰_4k)0e@OhZ`F `.m1} 'vp{F`ON7Srx 'D˸nV`><;yMx!IS钦OM)Ե٥x 'DSD6bS8!" ODz#R >S8!7ّxEh0m$MIPHi$IvS8IN$I p$O8I,sk&I)$IN$Hi$I^Ah.p$MIN$IR8I·N "IF9Ah0m$MIN$IR8IN$I 3jIU;kO$ɳN$+ q.x* tEXtComment

Viewing File: /opt/go/pkg/mod/github.com/go-openapi/runtime@v0.28.0/request_test.go

// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package runtime

import (
	"bufio"
	"bytes"
	"context"
	"io"
	"net/http"
	"net/url"
	"strings"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/stretchr/testify/assert"
)

type eofReader struct{}

func (e *eofReader) Read(_ []byte) (int, error) {
	return 0, io.EOF
}

func closeReader(rdr io.Reader) *closeCounting {
	return &closeCounting{
		rdr: rdr,
	}
}

type closeCounting struct {
	rdr    io.Reader
	closed int
}

func (c *closeCounting) Read(d []byte) (int, error) {
	return c.rdr.Read(d)
}

func (c *closeCounting) Close() error {
	c.closed++
	if cr, ok := c.rdr.(io.ReadCloser); ok {
		return cr.Close()
	}
	return nil
}

type countingBufioReader struct {
	buffereds int
	peeks     int
	reads     int

	br interface {
		Buffered() int
		Peek(int) ([]byte, error)
		Read([]byte) (int, error)
	}
}

func (c *countingBufioReader) Buffered() int {
	c.buffereds++
	return c.br.Buffered()
}

func (c *countingBufioReader) Peek(v int) ([]byte, error) {
	c.peeks++
	return c.br.Peek(v)
}

func (c *countingBufioReader) Read(p []byte) (int, error) {
	c.reads++
	return c.br.Read(p)
}

func TestPeekingReader(t *testing.T) {
	// just passes to original reader when nothing called
	exp1 := []byte("original")
	pr1 := newPeekingReader(closeReader(bytes.NewReader(exp1)))
	b1, err := io.ReadAll(pr1)
	require.NoError(t, err)
	assert.Equal(t, exp1, b1)

	// uses actual when there was some buffering
	exp2 := []byte("actual")
	pr2 := newPeekingReader(closeReader(bytes.NewReader(exp2)))
	peeked, err := pr2.underlying.Peek(1)
	require.NoError(t, err)
	require.Equal(t, "a", string(peeked))
	b2, err := io.ReadAll(pr2)
	require.NoError(t, err)
	assert.Equal(t, string(exp2), string(b2))

	// passes close call through to original reader
	cr := closeReader(closeReader(bytes.NewReader(exp2)))
	pr3 := newPeekingReader(cr)
	require.NoError(t, pr3.Close())
	require.Equal(t, 1, cr.closed)

	// returns false when the stream is empty
	pr4 := newPeekingReader(closeReader(&eofReader{}))
	require.False(t, pr4.HasContent())

	// returns true when the stream has content
	rdr := closeReader(strings.NewReader("hello"))
	pr := newPeekingReader(rdr)
	cbr := &countingBufioReader{
		br: bufio.NewReader(rdr),
	}
	pr.underlying = cbr

	require.True(t, pr.HasContent())
	require.Equal(t, 1, cbr.buffereds)
	require.Equal(t, 1, cbr.peeks)
	require.Equal(t, 0, cbr.reads)
	require.True(t, pr.HasContent())
	require.Equal(t, 2, cbr.buffereds)
	require.Equal(t, 1, cbr.peeks)
	require.Equal(t, 0, cbr.reads)

	b, err := io.ReadAll(pr)
	require.NoError(t, err)
	require.Equal(t, "hello", string(b))
	require.Equal(t, 2, cbr.buffereds)
	require.Equal(t, 1, cbr.peeks)
	require.Equal(t, 2, cbr.reads)
	require.Equal(t, 0, cbr.br.Buffered())

	t.Run("closing a closed peekingReader", func(t *testing.T) {
		const content = "content"
		r := newPeekingReader(io.NopCloser(strings.NewReader(content)))
		require.NoError(t, r.Close())

		require.NotPanics(t, func() {
			err := r.Close()
			require.Error(t, err)
		})
	})

	t.Run("reading from a closed peekingReader", func(t *testing.T) {
		const content = "content"
		r := newPeekingReader(io.NopCloser(strings.NewReader(content)))
		require.NoError(t, r.Close())

		require.NotPanics(t, func() {
			_, err := io.ReadAll(r)
			require.Error(t, err)
			require.ErrorIs(t, err, io.ErrUnexpectedEOF)
		})
	})

	t.Run("reading from a nil peekingReader", func(t *testing.T) {
		var r *peekingReader
		require.NotPanics(t, func() {
			buf := make([]byte, 10)
			_, err := r.Read(buf)
			require.Error(t, err)
			require.ErrorIs(t, err, io.EOF)
		})
	})
}

func TestJSONRequest(t *testing.T) {
	req, err := JSONRequest(http.MethodGet, "/swagger.json", nil)
	require.NoError(t, err)
	assert.Equal(t, http.MethodGet, req.Method)
	assert.Equal(t, JSONMime, req.Header.Get(HeaderContentType))
	assert.Equal(t, JSONMime, req.Header.Get(HeaderAccept))

	req, err = JSONRequest(http.MethodGet, "%2", nil)
	require.Error(t, err)
	assert.Nil(t, req)
}

func TestHasBody(t *testing.T) {
	req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "", nil)
	require.NoError(t, err)
	assert.False(t, HasBody(req))

	req.ContentLength = 123
	assert.True(t, HasBody(req))
}

func TestMethod(t *testing.T) {
	testcase := []struct {
		method      string
		canHaveBody bool
		allowsBody  bool
		isSafe      bool
	}{
		{"put", true, true, false},
		{"post", true, true, false},
		{"patch", true, true, false},
		{"delete", true, true, false},
		{"get", false, true, true},
		{"options", false, true, false},
		{"head", false, false, true},
		{"invalid", false, true, false},
		{"", false, true, false},
	}

	for _, tc := range testcase {
		t.Run(tc.method, func(t *testing.T) {
			assert.Equal(t, tc.canHaveBody, CanHaveBody(tc.method), "CanHaveBody")

			req := http.Request{Method: tc.method}
			assert.Equal(t, tc.allowsBody, AllowsBody(&req), "AllowsBody")
			assert.Equal(t, tc.isSafe, IsSafe(&req), "IsSafe")
		})
	}
}

func TestReadSingle(t *testing.T) {
	values := url.Values(make(map[string][]string))
	values.Add("something", "the thing")
	assert.Equal(t, "the thing", ReadSingleValue(Values(values), "something"))
	assert.Empty(t, ReadSingleValue(Values(values), "notthere"))
}

func TestReadCollection(t *testing.T) {
	values := url.Values(make(map[string][]string))
	values.Add("something", "value1,value2")
	assert.Equal(t, []string{"value1", "value2"}, ReadCollectionValue(Values(values), "something", "csv"))
	assert.Empty(t, ReadCollectionValue(Values(values), "notthere", ""))
}
Back to Directory=ceiIENDB`