twitch-bot-streak/pkg/database/query_test.go
Knut Ahlers f1d35ce7c0
Switch to properly tested database interface
and with that support all databases the bot does support

Signed-off-by: Knut Ahlers <knut@ahlers.me>
2024-03-24 13:29:57 +01:00

169 lines
5.0 KiB
Go

package database
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const testStreamOfflineGrace = 30 * time.Second
func TestCountStreak(t *testing.T) {
db, err := New("sqlite", "file::memory:?cache=shared")
require.NoError(t, err)
t.Cleanup(func() { assert.NoError(t, db.Close()) })
err = db.StartStream(testStreamOfflineGrace)
require.NoError(t, err)
// First time the user registers
user, err := db.CountStreak(1, "test")
require.NoError(t, err)
assert.Equal(t, uint64(1), user.TwitchID)
assert.Equal(t, "test", user.Username)
assert.Equal(t, uint64(1), user.StreamsCount)
assert.Equal(t, uint64(1), user.MaxStreak)
assert.Equal(t, uint64(1), user.CurrentStreak)
assert.Equal(t, StatusActive, user.StreakStatus)
// Register on the same stream should not change anything
user, err = db.CountStreak(1, "test")
assert.NoError(t, err)
assert.Equal(t, uint64(1), user.StreamsCount)
assert.Equal(t, uint64(1), user.MaxStreak)
assert.Equal(t, uint64(1), user.CurrentStreak)
assert.Equal(t, StatusActive, user.StreakStatus)
// Interrupt the stream for less than the grace
err = db.SetStreamOffline()
require.NoError(t, err)
err = db.StartStream(testStreamOfflineGrace)
require.NoError(t, err)
// Streak should still be active
err = db.db.First(&user).Error
require.NoError(t, err)
assert.Equal(t, StatusActive, user.StreakStatus)
// Register on the same stream should not change anything
user, err = db.CountStreak(1, "test")
assert.NoError(t, err)
assert.Equal(t, uint64(1), user.StreamsCount)
assert.Equal(t, uint64(1), user.MaxStreak)
assert.Equal(t, uint64(1), user.CurrentStreak)
assert.Equal(t, StatusActive, user.StreakStatus)
// Interrupt the stream and start a new one
err = db.SetStreamOffline()
require.NoError(t, err)
time.Sleep(20 * time.Millisecond)
err = db.StartStream(10 * time.Millisecond)
require.NoError(t, err)
// Streak should now be pending
err = db.db.First(&user).Error
require.NoError(t, err)
assert.Equal(t, StatusPending, user.StreakStatus)
// Register on the next stream should not break the streak
user, err = db.CountStreak(1, "test")
assert.NoError(t, err)
assert.Equal(t, uint64(2), user.StreamsCount)
assert.Equal(t, uint64(2), user.MaxStreak)
assert.Equal(t, uint64(2), user.CurrentStreak)
assert.Equal(t, StatusActive, user.StreakStatus)
// Interrupt the stream and start a new one
err = db.SetStreamOffline()
require.NoError(t, err)
time.Sleep(20 * time.Millisecond)
err = db.StartStream(10 * time.Millisecond)
require.NoError(t, err)
// Streak should now be pending
err = db.db.First(&user).Error
require.NoError(t, err)
assert.Equal(t, StatusPending, user.StreakStatus)
// Interrupt the stream and start a new one (twice)
err = db.SetStreamOffline()
require.NoError(t, err)
time.Sleep(20 * time.Millisecond)
err = db.StartStream(10 * time.Millisecond)
require.NoError(t, err)
// Streak should now be broken
err = db.db.First(&user).Error
require.NoError(t, err)
assert.Equal(t, StatusBroken, user.StreakStatus)
// Register with one stream left out should break the streak
user, err = db.CountStreak(1, "test")
assert.NoError(t, err)
assert.Equal(t, uint64(3), user.StreamsCount)
assert.Equal(t, uint64(2), user.MaxStreak)
assert.Equal(t, uint64(1), user.CurrentStreak)
assert.Equal(t, StatusActive, user.StreakStatus)
}
func TestMetaTimestore(t *testing.T) {
db, err := New("sqlite", "file::memory:?cache=shared")
require.NoError(t, err)
t.Cleanup(func() { assert.NoError(t, db.Close()) })
parsed, err := db.getTimeFromMeta(db.db, "test")
assert.NoError(t, err)
assert.True(t, defaultMetaTime.Equal(parsed))
now := time.Now()
err = db.storeTimeToMeta(db.db, "test", now)
assert.NoError(t, err)
var meta StreakMeta
err = db.db.First(&meta, "name = ?", "test").Error
assert.NoError(t, err)
assert.Equal(t, "test", meta.Name)
assert.Equal(t, now.Format(time.RFC3339Nano), meta.Value)
parsed, err = db.getTimeFromMeta(db.db, "test")
assert.NoError(t, err)
assert.True(t, now.Equal(parsed))
}
func TestStreamOffline(t *testing.T) {
db, err := New("sqlite", "file::memory:?cache=shared")
require.NoError(t, err)
t.Cleanup(func() { assert.NoError(t, db.Close()) })
parsed, err := db.getTimeFromMeta(db.db, "stream_offline")
assert.NoError(t, err)
assert.True(t, defaultMetaTime.Equal(parsed))
err = db.SetStreamOffline()
require.NoError(t, err)
parsed, err = db.getTimeFromMeta(db.db, "stream_offline")
assert.NoError(t, err)
assert.Less(t, time.Since(parsed), testStreamOfflineGrace)
}
func TestStreamOnline(t *testing.T) {
db, err := New("sqlite", "file::memory:?cache=shared")
require.NoError(t, err)
t.Cleanup(func() { assert.NoError(t, db.Close()) })
parsed, err := db.getTimeFromMeta(db.db, "stream_online")
assert.NoError(t, err)
assert.True(t, defaultMetaTime.Equal(parsed))
err = db.StartStream(testStreamOfflineGrace)
require.NoError(t, err)
parsed, err = db.getTimeFromMeta(db.db, "stream_online")
assert.NoError(t, err)
assert.Less(t, time.Since(parsed), testStreamOfflineGrace)
}