// Copyright © 2023 Ory Corp // SPDX-License-Identifier: Apache-2.0 package code_test import ( "database/sql" "net/http" "testing" "time" "github.com/stretchr/testify/require" "github.com/ory/kratos/pkg" "github.com/ory/kratos/selfservice/flow" "github.com/ory/kratos/selfservice/flow/login" "github.com/ory/kratos/selfservice/strategy/code" "github.com/ory/kratos/x" "github.com/ory/x/urlx" ) func TestLoginCode(t *testing.T) { t.Parallel() _, reg := pkg.NewVeryFastRegistryWithoutDB(t) newCode := func(expiresIn time.Duration, f *login.Flow) *code.LoginCode { return &code.LoginCode{ ID: x.NewUUID(), FlowID: f.ID, ExpiresAt: time.Now().Add(expiresIn), } } req := &http.Request{URL: urlx.ParseOrPanic("https://www.ory.com/")} t.Run("method=Validate", func(t *testing.T) { t.Parallel() t.Run("case=returns error if code is expired", func(t *testing.T) { f, err := login.NewFlow(reg, req, flow.TypeBrowser) require.NoError(t, err) f.ExpiresAt = f.IssuedAt.Add(-time.Hour) c := newCode(-time.Hour, f) require.ErrorIs(t, c.Validate(reg.Clock()), code.ErrCodeNotFound()) }) t.Run("case=returns no error if flow is not expired", func(t *testing.T) { f, err := login.NewFlow(reg, req, flow.TypeBrowser) require.NoError(t, err) f.ExpiresAt = f.IssuedAt.Add(time.Hour) c := newCode(time.Hour, f) require.NoError(t, c.Validate(reg.Clock())) }) t.Run("case=returns error if flow has been used", func(t *testing.T) { f, err := login.NewFlow(reg, req, flow.TypeBrowser) require.NoError(t, err) f.ExpiresAt = f.IssuedAt.Add(-time.Hour) c := newCode(time.Hour, f) c.UsedAt = sql.NullTime{ Time: time.Now(), Valid: true, } require.ErrorIs(t, c.Validate(reg.Clock()), code.ErrCodeAlreadyUsed()) }) t.Run("case=returns no error if flow has not been used", func(t *testing.T) { f, err := login.NewFlow(reg, req, flow.TypeBrowser) require.NoError(t, err) f.ExpiresAt = f.IssuedAt.Add(-time.Hour) c := newCode(time.Hour, f) c.UsedAt = sql.NullTime{ Valid: false, } require.NoError(t, c.Validate(reg.Clock())) }) t.Run("case=returns error if flow is nil", func(t *testing.T) { var c *code.LoginCode require.ErrorIs(t, c.Validate(reg.Clock()), code.ErrCodeNotFound()) }) }) }