module github.com/aloussase/squad-rotation-bot
go 1.25.1
-
-require (
-)
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
-github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
-github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
-github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
-github.com/jackc/pgx/v5 v5.7.6 h1:rWQc5FwZSPX58r1OQmkuaNicxdmExaEz5A2DO2hUuTk=
-github.com/jackc/pgx/v5 v5.7.6/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
-golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
-golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
-golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
package main
import (
- "context"
"log"
"net/http"
- "time"
"github.com/aloussase/squad-rotation-bot/api"
"github.com/aloussase/squad-rotation-bot/config"
"github.com/aloussase/squad-rotation-bot/services"
- "github.com/jackc/pgx/v5"
)
-func connectDB(dbUrl string) *pgx.Conn {
- attempts := 0
-
- var conn *pgx.Conn
- var err error
-
- for attempts < 3 {
- conn, err = pgx.Connect(context.Background(), dbUrl)
- if err == nil {
- break
- }
- if attempts == 2 {
- log.Fatalf("There was an error while trying to connect to the database: %s", err)
- }
- log.Printf("Failed to connect to database, retrying in 3 seconds...")
- time.Sleep(3 * time.Second)
- }
-
- return conn
-}
-
func main() {
config, err := config.ReadConfig()
if err != nil {
log.Fatalf("There was an error while reading the config: %s", err)
}
- conn := connectDB(config.DatabaseUrl)
- defer conn.Close(context.Background())
-
- memberService := services.Create(conn)
- rotationService := services.CreateRotationService(conn)
+ memberService := services.Create()
+ rotationService := services.CreateRotationService()
messagingService := services.CreateMessagingService(config)
http.HandleFunc("/api/v1/rotation/trigger", api.TriggerBot(memberService, rotationService, messagingService))
func CreateRotationService() RotationService {
return &rotationServiceImpl{
- counter: 1,
+ counter: 0,
}
}
--- /dev/null
+package services
+
+import (
+ "sync"
+ "testing"
+
+ "github.com/aloussase/squad-rotation-bot/entities"
+)
+
+func TestChooseNextInRotationHandlesEmptyMembersListGracefully(t *testing.T) {
+ members := []entities.SquadMember{}
+
+ impl := CreateRotationService()
+
+ _, err := impl.ChooseNextInRotation(members)
+
+ if err == nil {
+ t.Errorf("Expected empty member list to return an error, but did not")
+ }
+}
+
+func TestChooseNextInRotationHandlesConcurrentRequests(t *testing.T) {
+ members := []entities.SquadMember{
+ {ID: 1},
+ {ID: 2},
+ {ID: 3},
+ }
+
+ impl := CreateRotationService()
+
+ var wg sync.WaitGroup
+
+ wg.Go(func() {
+ impl.ChooseNextInRotation(members)
+ })
+
+ wg.Go(func() {
+ impl.ChooseNextInRotation(members)
+ })
+
+ wg.Wait()
+
+ m, _ := impl.ChooseNextInRotation(members)
+
+ if m.ID != 3 {
+ t.Errorf("Choose rotation returned same member for concurrent requests!")
+ }
+}
+
+func TestChooseNextInRotationCyclesTheMembersList(t *testing.T) {
+ members := []entities.SquadMember{
+ {ID: 1},
+ {ID: 2},
+ {ID: 3},
+ }
+
+ expectedResults := []int{1, 2, 3, 1, 2}
+
+ impl := CreateRotationService()
+
+ for _, id := range expectedResults {
+ m, _ := impl.ChooseNextInRotation(members)
+ if m.ID != id {
+ t.Errorf("Expected ID to be %d, got %d", id, m.ID)
+ }
+ }
+}