Move the test-only helpers out of the shipped db package (closes #248)
check / check (push) Waiting to run

The server binary carried exported names that only tests call, including
raw SQL access and a way to weaken the password hash.

Delete testing.go, GetDB and SetBcryptCost from the shipped code, so
passwords always hash at bcrypt.DefaultCost. Move GetDB, GetOrCreateChannel,
JoinChannel and HasChannelInvite into export_test.go. Delete
GetClientHostInfo, whose remaining check GetLatestClientForSession covers.

Tests in other packages now build the database with db.New and run raw SQL
through dbtest.Exec. Handler tests that need a password only to log in store
one hashed at bcrypt.MinCost. Tests of PASS itself keep the real cost.

Model: opus-5-5
This commit is contained in:
2026-11-03 09:05:07 +00:00
parent c12668226f
commit 51b151aa26
11 changed files with 182 additions and 272 deletions
+76
View File
@@ -6,6 +6,7 @@ import (
"fmt"
"log/slog"
"testing"
"time"
"sneak.berlin/go/neoirc/internal/dbtest"
)
@@ -67,3 +68,78 @@ func (database *Database) ExecForTest(
return nil
}
// GetDB returns the underlying sql.DB connection.
func (database *Database) GetDB() *sql.DB {
return database.conn
}
// GetOrCreateChannel returns channel id, creating if needed.
// Uses INSERT OR IGNORE to avoid TOCTOU races.
func (database *Database) GetOrCreateChannel(
ctx context.Context,
name string,
) (int64, error) {
now := time.Now()
_, err := database.conn.ExecContext(ctx,
`INSERT OR IGNORE INTO channels
(name, created_at, updated_at)
VALUES (?, ?, ?)`,
name, now, now)
if err != nil {
return 0, fmt.Errorf("create channel: %w", err)
}
var channelID int64
err = database.conn.QueryRowContext(
ctx,
"SELECT id FROM channels WHERE name = ?",
name,
).Scan(&channelID)
if err != nil {
return 0, fmt.Errorf("get channel: %w", err)
}
return channelID, nil
}
// JoinChannel adds a session to a channel.
func (database *Database) JoinChannel(
ctx context.Context,
channelID, sessionID int64,
) error {
_, err := database.conn.ExecContext(ctx,
`INSERT OR IGNORE INTO channel_members
(channel_id, session_id, joined_at)
VALUES (?, ?, ?)`,
channelID, sessionID, time.Now())
if err != nil {
return fmt.Errorf("join channel: %w", err)
}
return nil
}
// HasChannelInvite checks if a session has been invited
// to a channel.
func (database *Database) HasChannelInvite(
ctx context.Context,
channelID, sessionID int64,
) (bool, error) {
var count int
err := database.conn.QueryRowContext(ctx,
`SELECT COUNT(*) FROM channel_invites
WHERE channel_id = ? AND session_id = ?`,
channelID, sessionID,
).Scan(&count)
if err != nil {
return false, fmt.Errorf(
"check invite: %w", err,
)
}
return count > 0, nil
}