Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test httpstatus 302 on resty OnAfterResponse not expected #130

Closed
daviyang35 opened this issue Jun 1, 2022 · 3 comments
Closed

test httpstatus 302 on resty OnAfterResponse not expected #130

daviyang35 opened this issue Jun 1, 2022 · 3 comments

Comments

@daviyang35
Copy link

I want use resty OnAfterResponse interface disable 302 auto redirect and replace with my own error.
when i tested this goal, then return "no responder found"

import (
	"errors"
	"fmt"
	"github.com/go-resty/resty/v2"
	"github.com/jarcoal/httpmock"
	"github.com/stretchr/testify/assert"
	"net/http"
	"strings"
	"testing"
	"time"
)

var ErrNoAuth = errors.New("no auth")

func createClient() *resty.Client {
	client := resty.New()
	client.EnableTrace()
	client.SetTimeout(time.Second * 60)
	client.SetRetryCount(0)
	client.SetBaseURL("http://mock.server")

	client.OnAfterResponse(func(client *resty.Client, response *resty.Response) error {
		switch response.StatusCode() {
		case http.StatusFound:
			location := response.Header().Get("Location")
			if strings.Contains(location, "/account/login") {
				fmt.Printf("matched 302 location. return ErrNoAuth\n")
				return ErrNoAuth
			}
		}
		return nil
	})

	return client
}

func TestForResty302(t *testing.T) {
	client := createClient()

	httpmock.Activate()
	httpmock.ActivateNonDefault(client.GetClient())
	defer httpmock.DeactivateAndReset()

	httpmock.RegisterResponder("POST", "/api/v1/some_action", func(request *http.Request) (*http.Response, error) {
		response := httpmock.NewStringResponse(http.StatusFound, "")
		response.Header.Set("Location", "https://new.server/account/login")
		return response, nil
	})

	post, err := client.R().Post("/api/v1/some_action")
	_ = post
	_ = err
	// Output: Post "https://new.server/account/login": no responder found
	fmt.Printf("%+v\n", err)

	// Expect
	assert.ErrorIs(t, err, ErrNoAuth)
}
@maxatome
Copy link
Collaborator

maxatome commented Jun 1, 2022

Hello,
You set a "Location" header in your mocked response of POST /api/v1/some_action, so you have to provide a responder for this new URL...

@daviyang35
Copy link
Author

I found a way to skip this problem.

import (
	"errors"
	"fmt"
	"github.com/go-resty/resty/v2"
	"github.com/jarcoal/httpmock"
	"github.com/stretchr/testify/assert"
	"net/http"
	"strings"
	"testing"
	"time"
)

var ErrNoAuth = errors.New("no auth")

func createClient() *resty.Client {
	client := resty.New()
	client.EnableTrace()
	client.SetTimeout(time.Second * 60)
	client.SetRetryCount(0)
	client.SetBaseURL("http://mock.server")

	client.SetRedirectPolicy(resty.RedirectPolicyFunc(func(request *http.Request, requests []*http.Request) error {
		if strings.Contains(request.URL.Path, "/account/login") {
			fmt.Printf("RedirectPolicy matched 302 location. return ErrNoAuth\n")
			return ErrNoAuth
		}
		return nil
	}))

	//client.OnAfterResponse(func(client *resty.Client, response *resty.Response) error {
	//	switch response.StatusCode() {
	//	case http.StatusFound:
	//		location := response.Header().Get("Location")
	//		if strings.Contains(location, "/account/login") {
	//			fmt.Printf("OnAfterResponse matched 302 location. return ErrNoAuth\n")
	//			return ErrNoAuth
	//		}
	//	}
	//	return nil
	//})

	return client
}

func TestForResty302(t *testing.T) {
	client := createClient()

	httpmock.Activate()
	httpmock.ActivateNonDefault(client.GetClient())
	defer httpmock.DeactivateAndReset()

	httpmock.RegisterResponder("POST", "/api/v1/some_action", func(request *http.Request) (*http.Response, error) {
		response := httpmock.NewStringResponse(http.StatusFound, "")
		response.Header.Set("Location", "https://new.server/account/login")
		return response, nil
	})

	_, err := client.R().Post("/api/v1/some_action")

	// Expect
	assert.ErrorIs(t, err, ErrNoAuth)
}

@daviyang35
Copy link
Author

Hello, You set a "Location" header in your mocked response of POST /api/v1/some_action, so you have to provide a responder for this new URL...

Using a new Responder is a bit counterintuitive. This is because I originally intended to test whether OnAfterResponse was in effect.

Only 302 redirects are special and can be intercepted by the SetRedirectPolicy interface provided by resty.
In this case, use httpmock to set the server response message to get the correct result.

Thanks for your work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants