Skip to content

Commit

Permalink
fixtures logic is now kinda implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
AbdoAnss committed Dec 10, 2024
1 parent d24f5dd commit 4755308
Show file tree
Hide file tree
Showing 8 changed files with 449 additions and 11 deletions.
8 changes: 5 additions & 3 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ type Client struct {
rateLimit *rateLimiter

// services
Players *endpoints.PlayerService
Players *endpoints.PlayerService
Fixtures *endpoints.FixtureService
}

func NewClient(opts ...Option) *Client {
Expand All @@ -39,13 +40,14 @@ func NewClient(opts ...Option) *Client {
rateLimit: newRateLimiter(50, time.Minute),
}

// Apply options
for _, opt := range opts {
opt(c)
}

// Initialize services
// services

c.Players = endpoints.NewPlayerService(c)
c.Fixtures = endpoints.NewFixtureService(c)

return c
}
Expand Down
83 changes: 83 additions & 0 deletions endpoints/fixtures.go
Original file line number Diff line number Diff line change
@@ -1 +1,84 @@
package endpoints

import (
"encoding/json"
"fmt"
"time"

"github.com/AbdoAnss/go-fantasy-pl/api"
"github.com/AbdoAnss/go-fantasy-pl/internal/cache"
"github.com/AbdoAnss/go-fantasy-pl/models"
)

const (
fixturesEndpoint = "/fixtures/"
)

type FixtureService struct {
client api.Client
}

type FixtureNotFoundError struct {
ID int
}

func (e *FixtureNotFoundError) Error() string {
return fmt.Sprintf("fixture with ID %d not found", e.ID)
}

func NewFixtureService(client api.Client) *FixtureService {
return &FixtureService{
client: client,
}
}

var fixturesCache = cache.NewCache()

func init() {
fixturesCache.StartCleanupTask(5 * time.Minute)
}

func (fs *FixtureService) GetAllFixtures() ([]models.Fixture, error) {
if cached, found := fixturesCache.Get("fixtures"); found {
if fixtures, ok := cached.([]models.Fixture); ok {
return fixtures, nil
}
}

resp, err := fs.client.Get(fixturesEndpoint)
if err != nil {
return nil, fmt.Errorf("failed to get fixtures: %w", err)
}
defer resp.Body.Close()

var fixtures []models.Fixture
if err := json.NewDecoder(resp.Body).Decode(&fixtures); err != nil {
return nil, fmt.Errorf("failed to decode fixtures: %w", err)
}

fixturesCache.Set("fixtures", fixtures, defaultCacheTTL)

return fixtures, nil
}

func (fs *FixtureService) GetFixture(id int) (*models.Fixture, error) {
if cached, found := fixturesCache.Get(fmt.Sprintf("fixture_%d", id)); found {
if fixture, ok := cached.(*models.Fixture); ok {
return fixture, nil
}
}

fixtures, err := fs.GetAllFixtures()
if err != nil {
return nil, err
}

for _, f := range fixtures {
if f.ID == id {
fixturesCache.Set(fmt.Sprintf("fixture_%d", id), &f, defaultCacheTTL)
return &f, nil
}
}

return nil, &FixtureNotFoundError{ID: id}
}
106 changes: 106 additions & 0 deletions endpoints/fixtures_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package endpoints_test

import (
"testing"

"github.com/AbdoAnss/go-fantasy-pl/client"
"github.com/AbdoAnss/go-fantasy-pl/endpoints"
"github.com/stretchr/testify/assert"
)

var fixtureID int

func setupFixtureTestService() *endpoints.FixtureService {
c := client.NewClient()
fixtureID = 8

return endpoints.NewFixtureService(c)
}

func TestGetAllFixtures(t *testing.T) {
fs := setupFixtureTestService()
fixtures, err := fs.GetAllFixtures()

assert.NoError(t, err, "expected no error when getting all fixtures")
assert.NotEmpty(t, fixtures, "expected fixtures to be returned from API")

t.Logf("Retrieved %d fixtures from the API.", len(fixtures))

// TODO: tests to improve when adding teams logic
// convert ID to team ShortName for better readability

for i, fixture := range fixtures {
t.Logf("Fixture %d: ID: %d, Team A: %d, Team H: %d",
i+1,
fixture.ID,
fixture.TeamA,
fixture.TeamH)

if i >= 3 {
break
}
}
}

func TestGetFixture(t *testing.T) {
fs := setupFixtureTestService()

fixture, err := fs.GetFixture(fixtureID)

assert.NoError(t, err, "expected no error when getting fixture")
assert.NotNil(t, fixture, "expected fixture to be returned, got nil")

// Log fixture details
t.Logf("Fixture ID: %d", fixture.ID)
t.Logf("Team A: %d vs Team H: %d", fixture.TeamA, fixture.TeamH)
t.Logf("Fixture Finished: %v", fixture.Finished)
t.Logf("Kickoff Time: %v", fixture.KickoffTime)
}

func TestGetNonExistentFixture(t *testing.T) {
fs := setupFixtureTestService()

fixture, err := fs.GetFixture(999)

assert.Error(t, err, "expected an error when getting a non-existent fixture")
assert.Nil(t, fixture, "expected fixture to be nil for non-existent fixture")
assert.Equal(t, "fixture with ID 999 not found", err.Error())

t.Logf("Error encountered: %s", err.Error())
}

func TestGetGoalscorers(t *testing.T) {
fs := setupFixtureTestService()
fixture, err := fs.GetFixture(fixtureID)

assert.NoError(t, err, "expected no error when getting fixture")
assert.NotNil(t, fixture, "expected fixture to be returned, got nil")

goalscorers, err := fixture.GetGoalscorers()
assert.NoError(t, err, "expected no error when getting goalscorers")
t.Logf("Goalscorers: %+v", goalscorers)
}

func TestGetAssisters(t *testing.T) {
fs := setupFixtureTestService()
fixture, err := fs.GetFixture(fixtureID)

assert.NoError(t, err, "expected no error when getting fixture")
assert.NotNil(t, fixture, "expected fixture to be returned, got nil")

assisters, err := fixture.GetAssisters()
assert.NoError(t, err, "expected no error when getting assisters")
t.Logf("Assisters: %+v", assisters)
}

func TestGetBonus(t *testing.T) {
fs := setupFixtureTestService()
fixture, err := fs.GetFixture(fixtureID)

assert.NoError(t, err, "expected no error when getting fixture")
assert.NotNil(t, fixture, "expected fixture to be returned, got nil")

bonus, err := fixture.GetBonus()
assert.NoError(t, err, "expected no error when getting bonus points")
t.Logf("Bonus Points: %+v", bonus)
}
8 changes: 4 additions & 4 deletions endpoints/players_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ import (

var playerID int

func setupTestService() *endpoints.PlayerService {
func setupPlayersTestService() *endpoints.PlayerService {
c := client.NewClient()
playerID = 328 // Example player ID for Mohamed Salah

return endpoints.NewPlayerService(c)
}

func TestGetAllPlayers(t *testing.T) {
ps := setupTestService()
ps := setupPlayersTestService()
players, err := ps.GetAllPlayers()

assert.NoError(t, err, "expected no error when getting all players")
Expand All @@ -39,7 +39,7 @@ func TestGetAllPlayers(t *testing.T) {
}

func TestGetPlayer(t *testing.T) {
ps := setupTestService()
ps := setupPlayersTestService()

player, err := ps.GetPlayer(playerID)

Expand All @@ -57,7 +57,7 @@ func TestGetPlayer(t *testing.T) {
}

func TestGetPlayerHistory(t *testing.T) {
ps := setupTestService()
ps := setupPlayersTestService()

history, err := ps.GetPlayerHistory(playerID)

Expand Down
72 changes: 72 additions & 0 deletions examples/fixtures/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package main

import (
"fmt"
"log"

"github.com/AbdoAnss/go-fantasy-pl/client"
)

func main() {
c := client.NewClient()

fixtureID := 8 // Example fixture ID

// Get fixture details
fmt.Printf("Getting fixture details for ID %d...\n", fixtureID)
fixture, err := c.Fixtures.GetFixture(fixtureID)
if err != nil {
log.Printf("Warning: Could not get fixture details: %v\n", err)
return
}

fmt.Println("----------------------------------------")
fmt.Printf("Fixture ID: %d\n", fixture.ID)
fmt.Printf("Team A: %d vs Team H: %d\n", fixture.TeamA, fixture.TeamH)
fmt.Printf("Kickoff Time: %v\n", fixture.KickoffTime)
fmt.Printf("Finished: %v\n", fixture.Finished)
fmt.Printf("Team A Score: %v, Team H Score: %v\n", fixture.GetTeamAScore(), fixture.GetTeamHScore())
fmt.Println("----------------------------------------")

// Get goalscorers
goalscorers, err := fixture.GetGoalscorers()
if err != nil {
log.Printf("Warning: Could not get goalscorers: %v\n", err)
} else {
fmt.Println("Goalscorers:")
for team, players := range goalscorers {
fmt.Printf("Team %s:\n", team)
for _, player := range players {
fmt.Printf("Player ID: %d, Goals: %d\n", player.Element, player.Value)
}
}
}

// Get assisters
assisters, err := fixture.GetAssisters()
if err != nil {
log.Printf("Warning: Could not get assisters: %v\n", err)
} else {
fmt.Println("Assisters:")
for team, players := range assisters {
fmt.Printf("Team %s:\n", team)
for _, player := range players {
fmt.Printf("Player ID: %d, Assists: %d\n", player.Element, player.Value)
}
}
}

// Get bonus points
bonus, err := fixture.GetBonus()
if err != nil {
log.Printf("Warning: Could not get bonus points: %v\n", err)
} else {
fmt.Println("Bonus Points:")
for team, players := range bonus {
fmt.Printf("Team %s:\n", team)
for _, player := range players {
fmt.Printf("Player ID: %d, Bonus Points: %d\n", player.Element, player.Value)
}
}
}
}
4 changes: 0 additions & 4 deletions examples/players/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,14 @@ import (
)

func main() {
// Initialize client
c := client.NewClient()
playerID := 328 // Salah's ID

// Get player details first
fmt.Printf("Getting player details for ID %d...\n", playerID)
player, err := c.Players.GetPlayer(playerID)
if err != nil {
log.Printf("Warning: Could not get player details: %v\n", err)
// Continue execution even if player details fail
} else {
// Print player details only if we got them
fmt.Println("----------------------------------------")
fmt.Printf("Mo Salah Details:\n")
fmt.Printf("Full Name: %s\n", player.GetDisplayName())
Expand Down
Loading

0 comments on commit 4755308

Please sign in to comment.