package auth

import (
	"html/template"
	"net/http"
	"net/http/httptest"
	"net/url"
	"testing"
)

const (
	scopeSet = 1 << iota
	stateSet
	uriSet
)

func TestGetGrantCodeSuccess(t *testing.T) {
	t.Parallel()
	store := NewMemstore()
	testContext := Context{
		template: template.Must(template.New(getGrantTemplateName).Parse("Get auth grant")),
		clients:  store,
		grants:   store,
		profiles: store,
		tokens:   store,
	}
	req, err := http.NewRequest("GET", "https://test.auth.secondbit.org/oauth2/grant", nil)
	if err != nil {
		t.Fatal("Can't build request:", err)
	}
	for i := 0; i < 1<<3; i++ {
		w := httptest.NewRecorder()
		params := url.Values{}
		// see OAuth 2.0 spec, section 4.1.1
		params.Set("response_type", "code")
		params.Set("client_id", "test_client_id")
		if i&uriSet != 0 {
			params.Set("redirect_uri", "https://test.secondbit.org/redirect")
		}
		if i&scopeSet != 0 {
			params.Set("scope", "testscope")
		}
		if i&stateSet != 0 {
			params.Set("state", "my super secure state string")
		}
		req.URL.RawQuery = params.Encode()
		GetGrantHandler(w, req, testContext)
		if w.Code != http.StatusOK {
			t.Errorf("Expected status code to be %d, got %d for %s", http.StatusOK, w.Code, req.URL.String())
		}
		if w.Body.String() != "Get auth grant" {
			t.Errorf("Expected body to be `%s`, got `%s` for %s", "Get auth grant", w.Body.String(), req.URL.String())
		}
	}
}
