<commit_before>package http

import (
	"bytes"
	"context"
	"errors"
	"io"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/go-kit/kit/log"
	"github.com/nicolasparada/nakama"
	"github.com/nicolasparada/nakama/testutil"
	"github.com/nicolasparada/nakama/transport"
)

func Test_handler_sendMagicLink(t *testing.T) {
	type call struct {
		Ctx         context.Context
		Email       string
		RedirectURI string
	}

	tt := []struct {
		name     string
		body     []byte
		svc      *transport.ServiceMock
		testResp func(*testing.T, *http.Response)
		testCall func(*testing.T, call)
	}{
		{
			name: "empty_request_body",
			testResp: func(t *testing.T, resp *http.Response) {
				testutil.AssertEqual(t, http.StatusBadRequest, resp.StatusCode, "status code")
				testutil.AssertEqual(t, "bad request", string(readAllAndTrim(t, resp.Body)), "body")
			},
		},
		{
			name: "malformed_request_body",
			body: []byte(`nope`),
			testResp: func(t *testing.T, resp *http.Response) {
				testutil.AssertEqual(t, http.StatusBadRequest, resp.StatusCode, "status code")
				testutil.AssertEqual(t, "bad request", string(readAllAndTrim(t, resp.Body)), "body")
			},
		},
		{
			name: "invalid_email",
			body: []byte(`{}`),
			svc: &transport.ServiceMock{
				SendMagicLinkFunc: func(context.Context, string, string) error {
					return nakama.ErrInvalidEmail
				},
			},
			testResp: func(t *testing.T, resp *http.Response) {
				testutil.AssertEqual(t, http.StatusUnprocessableEntity, resp.StatusCode, "status code")
				testutil.AssertEqual(t, "invalid email", string(readAllAndTrim(t, resp.Body)), "body")
			},
		},
		{
			name: "invalid_redirect_uri",
			body: []byte(`{}`),
			svc: &transport.ServiceMock{
				SendMagicLinkFunc: func(context.Context, string, string) error {
					return nakama.ErrInvalidRedirectURI
				},
			},
			testResp: func(t *testing.T, resp *http.Response) {
				testutil.AssertEqual(t, http.StatusUnprocessableEntity, resp.StatusCode, "status code")
				testutil.AssertEqual(t, "invalid redirect URI", string(readAllAndTrim(t, resp.Body)), "body")
			},
		},
		{
			name: "untrusted_redirect_uri",
			body: []byte(`{}`),
			svc: &transport.ServiceMock{
				SendMagicLinkFunc: func(context.Context, string, string) error {
					return nakama.ErrUntrustedRedirectURI
				},
			},
			testResp: func(t *testing.T, resp *http.Response) {
				testutil.AssertEqual(t, http.StatusForbidden, resp.StatusCode, "status code")
				testutil.AssertEqual(t, "untrusted redirect URI", string(readAllAndTrim(t, resp.Body)), "body")
			},
		},
		{
			name: "internal_error",
			body: []byte(`{}`),
			svc: &transport.ServiceMock{
				SendMagicLinkFunc: func(context.Context, string, string) error {
					return errors.New("internal error")
				},
			},
			testResp: func(t *testing.T, resp *http.Response) {
				testutil.AssertEqual(t, http.StatusInternalServerError, resp.StatusCode, "status code")
				testutil.AssertEqual(t, "internal server error", string(readAllAndTrim(t, resp.Body)), "body")
			},
		},
		{
			name: "ok",
			body: []byte(`{"email":"<EMAIL>","redirectURI":"https://example.org"}`),
			svc: &transport.ServiceMock{
				SendMagicLinkFunc: func(context.Context, string, string) error {
					return nil
				},
			},
			testResp: func(t *testing.T, resp *http.Response) {
				testutil.AssertEqual(t, http.StatusNoContent, resp.StatusCode, "status code")
			},
			testCall: func(t *testing.T, call call) {
				testutil.AssertEqual(t, "<EMAIL>", call.Email, "email")
				testutil.AssertEqual(t, "https://example.org", call.RedirectURI, "redirect URI")
			},
		},
	}
	for _, tc := range tt {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			h := New(tc.svc, nil, log.NewNopLogger(), nil, nil, true)
			srv := httptest.NewServer(h)
			defer srv.Close()

			req, err := http.NewRequest(http.MethodPost, srv.URL+"/api/send_magic_link", bytes.NewReader(tc.body))
			if err != nil {
				t.Fatalf("failed to create request to send magic link: %v", err)
			}

			resp, err := http.DefaultClient.Do(req)
			if err != nil {
				t.Fatalf("failed to do request to send magic link: %v", err)
			}

			defer resp.Body.Close()

			tc.testResp(t, resp)
			if tc.testCall != nil {
				tc.testCall(t, tc.svc.SendMagicLinkCalls()[0])
			}
		})
	}<commit_msg>transport/http: fix test build<commit_after>package http

import (
	"bytes"
	"context"
	"errors"
	"io"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/go-kit/kit/log"
	"github.com/nicolasparada/nakama"
	"github.com/nicolasparada/nakama/testutil"
	"github.com/nicolasparada/nakama/transport"
)

func Test_handler_sendMagicLink(t *testing.T) {
	type call struct {
		Ctx         context.Context
		Email       string
		RedirectURI string
	}

	tt := []struct {
		name     string
		body     []byte
		svc      *transport.ServiceMock
		testResp func(*testing.T, *http.Response)
		testCall func(*testing.T, call)
	}{
		{
			name: "empty_request_body",
			testResp: func(t *testing.T, resp *http.Response) {
				testutil.AssertEqual(t, http.StatusBadRequest, resp.StatusCode, "status code")
				testutil.AssertEqual(t, "bad request", string(readAllAndTrim(t, resp.Body)), "body")
			},
		},
		{
			name: "malformed_request_body",
			body: []byte(`nope`),
			testResp: func(t *testing.T, resp *http.Response) {
				testutil.AssertEqual(t, http.StatusBadRequest, resp.StatusCode, "status code")
				testutil.AssertEqual(t, "bad request", string(readAllAndTrim(t, resp.Body)), "body")
			},
		},
		{
			name: "invalid_email",
			body: []byte(`{}`),
			svc: &transport.ServiceMock{
				SendMagicLinkFunc: func(context.Context, string, string) error {
					return nakama.ErrInvalidEmail
				},
			},
			testResp: func(t *testing.T, resp *http.Response) {
				testutil.AssertEqual(t, http.StatusUnprocessableEntity, resp.StatusCode, "status code")
				testutil.AssertEqual(t, "invalid email", string(readAllAndTrim(t, resp.Body)), "body")
			},
		},
		{
			name: "invalid_redirect_uri",
			body: []byte(`{}`),
			svc: &transport.ServiceMock{
				SendMagicLinkFunc: func(context.Context, string, string) error {
					return nakama.ErrInvalidRedirectURI
				},
			},
			testResp: func(t *testing.T, resp *http.Response) {
				testutil.AssertEqual(t, http.StatusUnprocessableEntity, resp.StatusCode, "status code")
				testutil.AssertEqual(t, "invalid redirect URI", string(readAllAndTrim(t, resp.Body)), "body")
			},
		},
		{
			name: "untrusted_redirect_uri",
			body: []byte(`{}`),
			svc: &transport.ServiceMock{
				SendMagicLinkFunc: func(context.Context, string, string) error {
					return nakama.ErrUntrustedRedirectURI
				},
			},
			testResp: func(t *testing.T, resp *http.Response) {
				testutil.AssertEqual(t, http.StatusForbidden, resp.StatusCode, "status code")
				testutil.AssertEqual(t, "untrusted redirect URI", string(readAllAndTrim(t, resp.Body)), "body")
			},
		},
		{
			name: "internal_error",
			body: []byte(`{}`),
			svc: &transport.ServiceMock{
				SendMagicLinkFunc: func(context.Context, string, string) error {
					return errors.New("internal error")
				},
			},
			testResp: func(t *testing.T, resp *http.Response) {
				testutil.AssertEqual(t, http.StatusInternalServerError, resp.StatusCode, "status code")
				testutil.AssertEqual(t, "internal server error", string(readAllAndTrim(t, resp.Body)), "body")
			},
		},
		{
			name: "ok",
			body: []byte(`{"email":"<EMAIL>","redirectURI":"https://example.org"}`),
			svc: &transport.ServiceMock{
				SendMagicLinkFunc: func(context.Context, string, string) error {
					return nil
				},
			},
			testResp: func(t *testing.T, resp *http.Response) {
				testutil.AssertEqual(t, http.StatusNoContent, resp.StatusCode, "status code")
			},
			testCall: func(t *testing.T, call call) {
				testutil.AssertEqual(t, "user<EMAIL>", call.Email, "email")
				testutil.AssertEqual(t, "https://example.org", call.RedirectURI, "redirect URI")
			},
		},
	}
	for _, tc := range tt {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			h := New(tc.svc, nil, nil, log.NewNopLogger(), nil, nil, true)
			srv := httptest.NewServer(h)
			defer srv.Close()

			req, err := http.NewRequest(http.MethodPost, srv.URL+"/api/send_magic_link", bytes.NewReader(tc.body))
			if err != nil {
				t.Fatalf("failed to create request to send magic link: %v", err)
			}

			resp, err := http.DefaultClient.Do(req)
			if err != nil {
				t.Fatalf("failed to do request to send magic link: %v", err)
			}

			defer resp.Body.Close()

			tc.testResp(t, resp)
			if tc.testCall != nil {
				tc.testCall(t, tc.svc.SendMagicLinkCalls()[0])
			}
		})
	}
{'fraction_non_alphanumeric': 0.15852803738317758, 'fraction_numerical': 0.00023364485981308412, 'mean_word_length': 3.7987668161434978, 'pattern_counts': {'":': 4, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6786692', 'n_tokens_mistral': 3515, 'n_tokens_neox': 3019, 'n_words': 600}