Skip to content

Commit

Permalink
refactor: improve settings helper functions
Browse files Browse the repository at this point in the history
  • Loading branch information
aeneasr committed Aug 26, 2020
1 parent 145fb20 commit fda17ca
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 132 deletions.
104 changes: 92 additions & 12 deletions internal/testhelpers/selfservice_settings.go
Expand Up @@ -6,12 +6,16 @@ import (
"context"
"encoding/json"
"net/http"
"net/url"
"strings"
"testing"
"time"

"github.com/gobuffalo/httptest"
"github.com/julienschmidt/httprouter"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tidwall/sjson"
"github.com/urfave/negroni"

"github.com/ory/x/urlx"
Expand All @@ -27,6 +31,7 @@ import (
"github.com/ory/kratos/internal/httpclient/models"
"github.com/ory/kratos/selfservice/flow/settings"
"github.com/ory/kratos/selfservice/strategy/password"
"github.com/ory/kratos/selfservice/strategy/profile"
"github.com/ory/kratos/x"
)

Expand Down Expand Up @@ -58,7 +63,34 @@ func InitializeSettingsFlowViaAPI(t *testing.T, client *http.Client, ts *httptes
return rs
}

func GetSettingsMethodConfig(t *testing.T, primaryUser *http.Client, ts *httptest.Server, id string) *models.FlowMethodConfig {
func EncodeFormAsJSON(t *testing.T, isApi bool, values url.Values) (payload string) {
if !isApi {
return values.Encode()
}
payload = "{}"
for k := range values {
var err error
payload, err = sjson.Set(payload, strings.ReplaceAll(k, ".", "\\."), values.Get(k))
require.NoError(t, err)
}
return payload
}

func ExpectStatusCode(isAPI bool, api, browser int) int {
if isAPI {
return api
}
return browser
}

func GetSettingsFlowMethodConfig(t *testing.T, rs *models.SettingsFlow, id string) *models.FlowMethodConfig {
require.NotEmpty(t, rs.Methods[id])
require.NotEmpty(t, rs.Methods[id].Config)
require.NotEmpty(t, rs.Methods[id].Config.Action)
return rs.Methods[id].Config
}

func GetSettingsFlowMethodConfigDeprecated(t *testing.T, primaryUser *http.Client, ts *httptest.Server, id string) *models.FlowMethodConfig {
rs := InitializeSettingsFlowViaBrowser(t, primaryUser, ts)

require.NotEmpty(t, rs.Payload.Methods[id])
Expand All @@ -85,6 +117,26 @@ func NewSettingsUITestServer(t *testing.T) *httptest.Server {
return ts
}

func NewSettingsUIEchoServer(t *testing.T, reg *driver.RegistryDefault) *httptest.Server {
router := httprouter.New()
router.GET("/settings", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
res, err := reg.SettingsFlowPersister().GetSettingsFlow(r.Context(), x.ParseUUID(r.URL.Query().Get("flow")))
require.NoError(t, err)
reg.Writer().Write(w, r, res)
})

router.GET("/login", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
w.WriteHeader(http.StatusUnauthorized)
})
ts := httptest.NewServer(router)
t.Cleanup(ts.Close)

viper.Set(configuration.ViperKeySelfServiceSettingsURL, ts.URL+"/settings")
viper.Set(configuration.ViperKeySelfServiceLoginUI, ts.URL+"/login")

return ts
}

func NewSettingsLoginAcceptAPIServer(t *testing.T, adminClient *client.OryKratos) *httptest.Server {
var called int
loginTS := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -184,29 +236,57 @@ func SettingsMakeRequest(
return string(x.MustReadAll(res.Body)), res
}

func SettingsSubmitForm(
// SubmitSettingsForm initiates a settings flow (for Browser and API!), fills out the form and modifies
// the form values with `withValues`, and submits the form. If completed, it will return the flow as JSON.
func SubmitSettingsForm(
t *testing.T,
isAPI bool,
f *models.FlowMethodConfig,
hc *http.Client,
values string,
publicTS *httptest.Server,
withValues func(v url.Values) url.Values,
method string,
expectedStatusCode int,
) (string, *common.GetSelfServiceSettingsFlowOK) {
b, res := SettingsMakeRequest(t,isAPI,f,hc,values)
) string {
hc.Transport = NewTransportWithLogger(hc.Transport , t)
var payload *models.SettingsFlow
if isAPI {
payload = InitializeSettingsFlowViaAPI(t, hc, publicTS).Payload
} else {
payload = InitializeSettingsFlowViaBrowser(t, hc, publicTS).Payload
}

time.Sleep(time.Millisecond) // add a bit of delay to allow `1ns` to time out.

config := GetSettingsFlowMethodConfig(t, payload, method)

b, res := SettingsMakeRequest(t, isAPI, config, hc, EncodeFormAsJSON(t, isAPI,
withValues(SDKFormFieldsToURLValues(config.Fields))))
assert.EqualValues(t, expectedStatusCode, res.StatusCode, "%s", b)

expectURL := viper.GetString(configuration.ViperKeySelfServiceSettingsURL)
if isAPI {
expectURL = password.RouteSettings
switch method {
case string(identity.CredentialsTypePassword):
expectURL = password.RouteSettings
case settings.StrategyProfile:
expectURL = profile.RouteSettings
default:
t.Logf("Expected method to be profile ior password but got: %s", method)
t.FailNow()
}
}

assert.Contains(t, res.Request.URL.String(), expectURL, "%+v\n\t%s", res.Request, b)

if isAPI {
return b
}
assert.Contains(t, res.Request.URL.String(), expectURL, "should end up at the settings URL, used: %s\n\t%s", pointerx.StringR(f.Action), b)

rs, err := NewSDKClientFromURL(viper.GetString(configuration.ViperKeyPublicBaseURL)).Common.GetSelfServiceSettingsFlow(
common.NewGetSelfServiceSettingsFlowParams().WithHTTPClient(hc).
WithID(res.Request.URL.Query().Get("flow")),
)
common.NewGetSelfServiceSettingsFlowParams().WithHTTPClient(hc).WithID(res.Request.URL.Query().Get("flow")))
require.NoError(t, err)

body, err := json.Marshal(rs.Payload)
require.NoError(t, err)
return string(body), rs
return string(body)
}
31 changes: 31 additions & 0 deletions internal/testhelpers/session.go
Expand Up @@ -61,6 +61,27 @@ func NewHTTPClientWithSessionCookie(t *testing.T, reg *driver.RegistryDefault, s
return c
}

func NewTransportWithLogger(parent http.RoundTripper, t *testing.T) *TransportWithLogger {
return &TransportWithLogger{
RoundTripper: parent,
t:t,
}
}

type TransportWithLogger struct {
http.RoundTripper
t *testing.T
}

func (ct *TransportWithLogger) RoundTrip(req *http.Request) (*http.Response, error) {
ct.t.Logf("Made request to: %s", req.URL.String())
if ct.RoundTripper == nil {
return http.DefaultTransport.RoundTrip(req)
}
return ct.RoundTripper.RoundTrip(req)
}


func NewHTTPClientWithSessionToken(t *testing.T, reg *driver.RegistryDefault, sess *session.Session) *http.Client {
maybePersistSession(t, reg, sess)

Expand All @@ -86,3 +107,13 @@ func NewHTTPClientWithArbitrarySessionCookie(t *testing.T, reg *driver.RegistryD
time.Now(),
))
}

func NewHTTPClientWithIdentitySessionCookie(t *testing.T, reg *driver.RegistryDefault, id *identity.Identity) *http.Client {
return NewHTTPClientWithSessionCookie(t, reg,
session.NewActiveSession(id, NewSessionLifespanProvider(time.Hour), time.Now()))
}

func NewHTTPClientWithIdentitySessionToken(t *testing.T, reg *driver.RegistryDefault, id *identity.Identity) *http.Client {
return NewHTTPClientWithSessionToken(t, reg,
session.NewActiveSession(id, NewSessionLifespanProvider(time.Hour), time.Now()))
}

0 comments on commit fda17ca

Please sign in to comment.