Move the test-only helpers out of the shipped db package (closes #248)
check / check (push) Waiting to run
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. Model: opus-5-5
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user