package authentication import ( "context" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "ruben/inventory2/consts" "ruben/inventory2/internal/testdb" ) func TestDevLogin(t *testing.T) { pool := testdb.Pool(t) auth := &Authenticator{db: pool} ctx := context.Background() userID := testdb.NewUserID(t) t.Cleanup(func() { pool.Exec(context.Background(), "DELETE FROM oauth_tokens WHERE id_token_subject = $1", userID) pool.Exec(context.Background(), "DELETE FROM oauth_users WHERE user_id = $1", userID) }) accessToken, expiration, err := auth.DevLogin(ctx, userID, "Test User") require.NoError(t, err, "DevLogin()") require.NotEmpty(t, accessToken, "DevLogin() returned an empty access token") assert.True(t, expiration.After(time.Now().Add(30*24*time.Hour)), "DevLogin() expiration = %v, want something far enough out to avoid the near-expiry refresh path", expiration) claims, err := auth.GetAccessTokenClaimsAndExpiration(ctx, accessToken) require.NoError(t, err, "GetAccessTokenClaimsAndExpiration()") assert.Equal(t, "Test User", claims.Name, "claims.Name") // Postgres timestamptz has microsecond precision, so the round-tripped // value loses the sub-microsecond portion of Go's nanosecond clock. assert.WithinDuration(t, expiration, claims.Expiration, time.Millisecond, "claims.Expiration") _, tokenType, err := auth.getRefreshTokenForAccessToken(ctx, accessToken) require.NoError(t, err, "getRefreshTokenForAccessToken()") assert.Equal(t, "dev", tokenType, "tokenType") } // DevLogin should be safe to call more than once for the same user_id - // e.g. testing multiple times as the same dev identity - since oauth_users // is keyed on user_id but each call mints its own oauth_tokens row. func TestDevLogin_SameUserIDTwice(t *testing.T) { pool := testdb.Pool(t) auth := &Authenticator{db: pool} ctx := context.Background() userID := testdb.NewUserID(t) t.Cleanup(func() { pool.Exec(context.Background(), "DELETE FROM oauth_tokens WHERE id_token_subject = $1", userID) pool.Exec(context.Background(), "DELETE FROM oauth_users WHERE user_id = $1", userID) }) token1, _, err := auth.DevLogin(ctx, userID, "Test User") require.NoError(t, err, "first DevLogin()") token2, _, err := auth.DevLogin(ctx, userID, "Test User") require.NoError(t, err, "second DevLogin()") assert.NotEqual(t, token1, token2, "DevLogin() returned the same access token twice") } func TestGetAccessTokenClaimsAndExpiration_UnknownToken(t *testing.T) { pool := testdb.Pool(t) auth := &Authenticator{db: pool} ctx := context.Background() _, err := auth.GetAccessTokenClaimsAndExpiration(ctx, "no-such-token-"+testdb.NewUserID(t)) require.ErrorIs(t, err, consts.ErrNotFound, "GetAccessTokenClaimsAndExpiration()") }