diff --git a/endpoints/classes.go b/endpoints/classes.go index 1319779..34012eb 100644 --- a/endpoints/classes.go +++ b/endpoints/classes.go @@ -18,29 +18,24 @@ type Class struct { const Classes = "classes" func (client *RestClient) GetClasses(ctx context.Context, sport string) ([]Class, error) { - classes := []Class{} - - err := Get(client, ctx, sport, Classes, url.Values{}, &classes) - - return classes, err + return getClasses(client, ctx, sport, "", nil) } func (client *RestClient) GetClassesByID(ctx context.Context, sport string, id int) ([]Class, error) { - classes := []Class{} - - values := url.Values{} - values.Set("id", fmt.Sprintf("eq.%v", id)) - - err := Get(client, ctx, sport, Classes, values, &classes) - - return classes, err + return getClasses(client, ctx, sport, "id", id) } func (client *RestClient) GetClassesByAlpha(ctx context.Context, sport string, alpha string) ([]Class, error) { + return getClasses(client, ctx, sport, "alpha", alpha) +} + +func getClasses(client *RestClient, ctx context.Context, sport string, query string, id any) ([]Class, error) { classes := []Class{} values := url.Values{} - values.Set("alpha", fmt.Sprintf("eq.%v", alpha)) + if query != "" && id != nil { + values.Set(query, fmt.Sprintf("eq.%v", id)) + } err := Get(client, ctx, sport, Classes, values, &classes) diff --git a/endpoints/client.go b/endpoints/client.go index 557e6bd..0e309c9 100644 --- a/endpoints/client.go +++ b/endpoints/client.go @@ -59,7 +59,9 @@ func Get[T any](client *RestClient, ctx context.Context, sport string, resource path := fmt.Sprintf("https://%v.sportdevs.com/%v", sport, resource) url := url.URL{Path: path, RawQuery: values.Encode()} - req, err := http.NewRequest("GET", url.RequestURI(), nil) + urlStr := url.RequestURI() + + req, err := http.NewRequest("GET", urlStr, nil) if err != nil { return err } @@ -69,11 +71,14 @@ func Get[T any](client *RestClient, ctx context.Context, sport string, resource return err } + if res.StatusCode != http.StatusOK { + return fmt.Errorf("%v failed: %v", urlStr, res.StatusCode) + } + defer res.Body.Close() - body, err := io.ReadAll(res.Body) - if err != nil { + if body, err := io.ReadAll(res.Body); err != nil { return err + } else { + return json.Unmarshal(body, &response) } - - return json.Unmarshal(body, &response) } diff --git a/endpoints/countries.go b/endpoints/countries.go index a84b3b6..c51784c 100644 --- a/endpoints/countries.go +++ b/endpoints/countries.go @@ -16,29 +16,24 @@ type Country struct { const Countries = "countries" func (client *RestClient) GetCountries(ctx context.Context, sport string) ([]Country, error) { - countries := []Country{} - - err := Get(client, ctx, sport, Countries, url.Values{}, &countries) - - return countries, err + return getCountries(client, ctx, sport, "", nil) } func (client *RestClient) GetCountriesByID(ctx context.Context, sport string, id int) ([]Country, error) { - countries := []Country{} - - values := url.Values{} - values.Set("id", fmt.Sprintf("eq.%v", id)) - - err := Get(client, ctx, sport, Countries, values, &countries) - - return countries, err + return getCountries(client, ctx, sport, "id", id) } func (client *RestClient) GetCountriesByAlpha(ctx context.Context, sport string, alpha string) ([]Country, error) { + return getCountries(client, ctx, sport, "alpha", alpha) +} + +func getCountries(client *RestClient, ctx context.Context, sport string, query string, id any) ([]Country, error) { countries := []Country{} values := url.Values{} - values.Set("alpha", fmt.Sprintf("eq.%v", alpha)) + if query != "" && id != nil { + values.Set(query, fmt.Sprintf("eq.%v", id)) + } err := Get(client, ctx, sport, Countries, values, &countries) diff --git a/endpoints/injuries.go b/endpoints/injuries.go new file mode 100644 index 0000000..a94a454 --- /dev/null +++ b/endpoints/injuries.go @@ -0,0 +1,49 @@ +package endpoints + +import ( + "context" + "fmt" + "net/url" + "time" +) + +type Injury struct { + PlayerID int `json:"player_id"` + PlayerName string `json:"player_name"` + PlayerHashImage string `json:"player_hash_image"` + Type string `json:"type"` + Reason string `json:"reason"` + MatchID int `json:"match_id"` + SeasonID int `json:"season_id"` + TournamentID int `json:"tournament_id"` + StartTimestamp time.Time `json:"start_timestamp"` +} + +const Injuries = "injuries" + +func (client *RestClient) GetInjuriesByPlayerID(ctx context.Context, sport string, id int) ([]Injury, error) { + return getInjuries(client, ctx, sport, "player_id", id) +} + +func (client *RestClient) GetInjuriesByMatchID(ctx context.Context, sport string, id int) ([]Injury, error) { + return getInjuries(client, ctx, sport, "match_id", id) +} + +func (client *RestClient) GetInjuriesBySeasonID(ctx context.Context, sport string, id int) ([]Injury, error) { + return getInjuries(client, ctx, sport, "season_id", id) +} + +func (client *RestClient) GetInjuriesByTournamentID(ctx context.Context, sport string, id int) ([]Injury, error) { + return getInjuries(client, ctx, sport, "tournament_id", id) +} + +func getInjuries(client *RestClient, ctx context.Context, sport string, query string, id int) ([]Injury, error) { + injuries := []Injury{} + + values := url.Values{} + values.Set(query, fmt.Sprintf("eq.%v", id)) + + err := Get(client, ctx, sport, Injuries, values, &injuries) + + return injuries, err +} diff --git a/endpoints/media.go b/endpoints/media.go new file mode 100644 index 0000000..4769f48 --- /dev/null +++ b/endpoints/media.go @@ -0,0 +1,50 @@ +package endpoints + +import ( + "context" + "fmt" + "net/url" + "time" +) + +type Media struct { + ID int `json:"id"` + TeamID int `json:"team_id,omitempty"` + PlayerID int `json:"player_id,omitempty"` + LeagueID int `json:"league_id,omitempty"` + Title string `json:"title"` + Subtitle string `json:"subtitle"` + URL string `json:"url"` + ThumbnailURL string `json:"thumbnail_url"` + DatePublished time.Time `json:"date_published"` + ChannelURL string `json:"channel_url"` +} + +const ( + MediaTeams = "media-teams" + MediaPlayers = "media-players" + MediaLeagues = "media-leagues" +) + +func (client *RestClient) GetMediaByTeamID(ctx context.Context, sport string, id int) ([]Media, error) { + return getMedia(client, ctx, sport, MediaTeams, "team_id", id) +} + +func (client *RestClient) GetMediaByPlayerID(ctx context.Context, sport string, id int) ([]Media, error) { + return getMedia(client, ctx, sport, MediaPlayers, "player_id", id) +} + +func (client *RestClient) GetMediaByLeagueID(ctx context.Context, sport string, id int) ([]Media, error) { + return getMedia(client, ctx, sport, MediaLeagues, "league_id", id) +} + +func getMedia(client *RestClient, ctx context.Context, sport string, resource string, query string, id int) ([]Media, error) { + media := []Media{} + + values := url.Values{} + values.Set(query, fmt.Sprintf("eq.%v", id)) + + err := Get(client, ctx, sport, resource, values, &media) + + return media, err +} diff --git a/endpoints/news.go b/endpoints/news.go new file mode 100644 index 0000000..71efe75 --- /dev/null +++ b/endpoints/news.go @@ -0,0 +1,83 @@ +package endpoints + +import ( + "context" + "fmt" + "net/url" + "time" +) + +type ( + Subtitle struct { + Text string `json:"text"` + Subtitle string `json:"subtitle"` + } + + News struct { + MatchID int `json:"match_id"` + Date time.Time `json:"date"` + Title string `json:"title"` + Subtitles []Subtitle `json:"subtitles"` + } +) + +type AggNews struct { + ID int `json:"id"` + TeamID int `json:"team_id,omitempty"` + MatchID int `json:"match_id,omitempty"` + PlayerID int `json:"player_id,omitempty"` + LeagueID int `json:"league_id,omitempty"` + Title string `json:"title"` + Link string `json:"link"` + ThumbnailURL string `json:"thumbnail_url"` + Description string `json:"description"` + PublishedDate time.Time `json:"published_date"` + SourceURL string `json:"source_url"` + Source string `json:"source"` +} + +const ( + NewsMatches = "news-matches" + AggNewsTeams = "news-agg-teams" + AggNewsMatches = "news-agg-matches" + AggNewsLeagues = "news-agg-leagues" + AggNewsPlayers = "news-agg-players" +) + +func (client *RestClient) GetNewsByMatchID(ctx context.Context, sport string, id int) ([]News, error) { + news := []News{} + + values := url.Values{} + values.Set("match_id", fmt.Sprintf("eq.%v", id)) + + err := Get(client, ctx, sport, NewsMatches, values, &news) + + return news, err +} + +func (client *RestClient) GetAggNewsByTeamID(ctx context.Context, sport string, id int) ([]AggNews, error) { + return getAggNews(client, ctx, sport, AggNewsTeams, "team_id", id) +} + +func (client *RestClient) GetAggNewsByMatchID(ctx context.Context, sport string, id int) ([]AggNews, error) { + return getAggNews(client, ctx, sport, AggNewsMatches, "match_id", id) +} + +func (client *RestClient) GetAggNewsByLeagueID(ctx context.Context, sport string, id int) ([]AggNews, error) { + return getAggNews(client, ctx, sport, AggNewsLeagues, "league_id", id) +} + +func (client *RestClient) GetAggNewsByPlayerID(ctx context.Context, sport string, id int) ([]AggNews, error) { + return getAggNews(client, ctx, sport, AggNewsPlayers, "player_id", id) +} + +func getAggNews(client *RestClient, ctx context.Context, sport string, resource string, query string, id int) ([]AggNews, error) { + news := []AggNews{} + + values := url.Values{} + values.Set(query, fmt.Sprintf("eq.%v", id)) + + err := Get(client, ctx, sport, resource, values, &news) + + return news, err +} diff --git a/endpoints/standings.go b/endpoints/standings.go new file mode 100644 index 0000000..db57ac7 --- /dev/null +++ b/endpoints/standings.go @@ -0,0 +1,81 @@ +package endpoints + +import ( + "context" + "fmt" + "net/url" +) + +type ( + Competitor struct { + Wins int `json:"wins"` + Draws int `json:"draws"` + Losses int `json:"losses"` + Points int `json:"points"` + Matches int `json:"matches"` + TeamID int `json:"team_id"` + Position int `json:"position"` + TeamName string `json:"team_name"` + ScoresFor int `json:"scores_for"` + ScoresAgainst int `json:"scores_against"` + TeamHashImage string `json:"team_hash_image"` + } + + Standing struct { + ID int `json:"id"` + TournamentID int `json:"tournament_id"` + Type string `json:"type"` + Name string `json:"name"` + SeasonID int `json:"season_id"` + SeasonName string `json:"season_name"` + LeagueID int `json:"league_id"` + LeagueName string `json:"league_name"` + LeagueHashImage string `json:"league_hash_image"` + Competitors []Competitor `json:"competitors"` + } +) + +const Standings = "standings" + +func (client *RestClient) GetStandings(ctx context.Context, sport string) ([]Standing, error) { + return getStandings(client, ctx, sport, "", nil) +} + +func (client *RestClient) GetStandingsByID(ctx context.Context, sport string, id int) ([]Standing, error) { + return getStandings(client, ctx, sport, "id", id) +} + +func (client *RestClient) GetStandingsByLeagueSeasonTypeID(ctx context.Context, sport string, id int, seasonID int, standingType string) ([]Standing, error) { + standings := []Standing{} + + values := url.Values{} + + if id != 0 { + values.Set("league_id", fmt.Sprintf("eq.%v", id)) + } + + if seasonID != 0 { + values.Set("season_id", fmt.Sprintf("eq.%v", seasonID)) + } + + if standingType != "" { + values.Set("type", fmt.Sprintf("eq.%v", standingType)) + } + + err := Get(client, ctx, sport, Standings, values, &standings) + + return standings, err +} + +func getStandings(client *RestClient, ctx context.Context, sport string, query string, id any) ([]Standing, error) { + standings := []Standing{} + + values := url.Values{} + if query != "" && id != nil { + values.Set(query, fmt.Sprintf("eq.%v", id)) + } + + err := Get(client, ctx, sport, Standings, values, &standings) + + return standings, err +} diff --git a/endpoints/tests/classes_test.go b/endpoints/tests/classes_test.go new file mode 100644 index 0000000..4fe1421 --- /dev/null +++ b/endpoints/tests/classes_test.go @@ -0,0 +1,60 @@ +package tests + +import ( + "context" + "testing" +) + +func TestGetClasses(t *testing.T) { + c := CreateClient(t) + + classes, err := c.GetClasses(context.Background(), "football") + + if err != nil { + t.Fatal(err) + } + + if len := len(classes); len == 0 { + t.Fatal(len) + } +} + +func TestGetClassesByID(t *testing.T) { + c := CreateClient(t) + + id := 121 + + classes, err := c.GetClassesByID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(classes); len == 0 { + t.Fatal(len) + } + + if classes[0].ID != id { + t.Fail() + } +} + +func TestGetClassesByAlpha(t *testing.T) { + c := CreateClient(t) + + alpha := "NX" + + classes, err := c.GetClassesByAlpha(context.Background(), "football", alpha) + + if err != nil { + t.Fatal(err) + } + + if len := len(classes); len == 0 { + t.Fatal(len) + } + + if classes[0].Alpha != alpha { + t.Fail() + } +} diff --git a/endpoints/tests/countries_test.go b/endpoints/tests/countries_test.go new file mode 100644 index 0000000..ce83910 --- /dev/null +++ b/endpoints/tests/countries_test.go @@ -0,0 +1,60 @@ +package tests + +import ( + "context" + "testing" +) + +func TestGetCountries(t *testing.T) { + c := CreateClient(t) + + countries, err := c.GetCountries(context.Background(), "football") + + if err != nil { + t.Fatal(err) + } + + if len := len(countries); len == 0 { + t.Fatal(len) + } +} + +func TestGetCountriesByID(t *testing.T) { + c := CreateClient(t) + + id := 1 + + countries, err := c.GetCountriesByID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(countries); len == 0 { + t.Fatal(len) + } + + if countries[0].ID != id { + t.Fail() + } +} + +func TestGetCountriesByAlpha(t *testing.T) { + c := CreateClient(t) + + alpha := "CA" + + countries, err := c.GetCountriesByAlpha(context.Background(), "football", alpha) + + if err != nil { + t.Fatal(err) + } + + if len := len(countries); len == 0 { + t.Fatal(len) + } + + if countries[0].Alpha != alpha { + t.Fail() + } +} diff --git a/endpoints/tests/helpers.go b/endpoints/tests/helpers.go new file mode 100644 index 0000000..b7d57a9 --- /dev/null +++ b/endpoints/tests/helpers.go @@ -0,0 +1,17 @@ +package tests + +import ( + "testing" + + "github.com/LonecastSystems/sportdev-go/endpoints" +) + +const apiKey = "" + +func CreateClient(t *testing.T) *endpoints.RestClient { + if apiKey == "" { + t.Skip("Invalid credentials") + } + + return endpoints.CreateClient(apiKey) +} diff --git a/endpoints/tests/injuries_test.go b/endpoints/tests/injuries_test.go new file mode 100644 index 0000000..2931866 --- /dev/null +++ b/endpoints/tests/injuries_test.go @@ -0,0 +1,86 @@ +package tests + +import ( + "context" + "testing" +) + +func TestGetInjuriesByPlayerID(t *testing.T) { + c := CreateClient(t) + + id := 21880 + + injuries, err := c.GetInjuriesByPlayerID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(injuries); len == 0 { + t.Fatal(len) + } + + if injuries[0].PlayerID != id { + t.Fail() + } +} + +func TestGetInjuriesByMatchID(t *testing.T) { + c := CreateClient(t) + + id := 28911 + + injuries, err := c.GetInjuriesByMatchID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(injuries); len == 0 { + t.Fatal(len) + } + + if injuries[0].MatchID != id { + t.Fail() + } +} + +func TestGetInjuriesBySeasonID(t *testing.T) { + c := CreateClient(t) + + id := 7172 + + injuries, err := c.GetInjuriesBySeasonID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(injuries); len == 0 { + t.Fatal(len) + } + + if injuries[0].SeasonID != id { + t.Fail() + } +} + +func TestGetInjuriesByTournamentID(t *testing.T) { + c := CreateClient(t) + + id := 269 + + injuries, err := c.GetInjuriesByTournamentID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(injuries); len == 0 { + t.Fatal(len) + } + + if injuries[0].TournamentID != id { + t.Fail() + } +} diff --git a/endpoints/tests/media_test.go b/endpoints/tests/media_test.go new file mode 100644 index 0000000..a2c223e --- /dev/null +++ b/endpoints/tests/media_test.go @@ -0,0 +1,66 @@ +package tests + +import ( + "context" + "testing" +) + +func TestGetMediaByTeamID(t *testing.T) { + c := CreateClient(t) + + id := 14 + + media, err := c.GetMediaByTeamID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(media); len == 0 { + t.Fatal(len) + } + + if media[0].TeamID != id { + t.Fail() + } +} + +func TestGetMediaByPlayerID(t *testing.T) { + c := CreateClient(t) + + id := 328523 + + media, err := c.GetMediaByPlayerID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(media); len == 0 { + t.Fatal(len) + } + + if media[0].PlayerID != id { + t.Fail() + } +} + +func TestGetMediaByLeagueID(t *testing.T) { + c := CreateClient(t) + + id := 21 + + media, err := c.GetMediaByLeagueID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(media); len == 0 { + t.Fatal(len) + } + + if media[0].LeagueID != id { + t.Fail() + } +} diff --git a/endpoints/tests/news_test.go b/endpoints/tests/news_test.go new file mode 100644 index 0000000..129916c --- /dev/null +++ b/endpoints/tests/news_test.go @@ -0,0 +1,106 @@ +package tests + +import ( + "context" + "testing" +) + +func TestGetNewsByMatchID(t *testing.T) { + c := CreateClient(t) + + id := 26100 + + news, err := c.GetNewsByMatchID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(news); len == 0 { + t.Fatal(len) + } + + if news[0].MatchID != id { + t.Fail() + } +} + +func TestGetAggNewsByTeamID(t *testing.T) { + c := CreateClient(t) + + id := 19829 + + news, err := c.GetAggNewsByTeamID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(news); len == 0 { + t.Fatal(len) + } + + if news[0].TeamID != id { + t.Fail() + } +} + +func TestGetAggNewsByMatchID(t *testing.T) { + c := CreateClient(t) + + id := 1911869 + + news, err := c.GetAggNewsByMatchID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(news); len == 0 { + t.Fatal(len) + } + + if news[0].TeamID != id { + t.Fail() + } +} + +func TestGetAggNewsByLeagueID(t *testing.T) { + c := CreateClient(t) + + id := 9963 + + news, err := c.GetAggNewsByLeagueID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(news); len == 0 { + t.Fatal(len) + } + + if news[0].LeagueID != id { + t.Fail() + } +} + +func TestGetAggNewsByPlayerID(t *testing.T) { + c := CreateClient(t) + + id := 213836 + + news, err := c.GetAggNewsByPlayerID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(news); len == 0 { + t.Fatal(len) + } + + if news[0].PlayerID != id { + t.Fail() + } +} diff --git a/endpoints/tests/standings_test.go b/endpoints/tests/standings_test.go new file mode 100644 index 0000000..735cec2 --- /dev/null +++ b/endpoints/tests/standings_test.go @@ -0,0 +1,70 @@ +package tests + +import ( + "context" + "testing" +) + +func TestGetStandings(t *testing.T) { + c := CreateClient(t) + + standings, err := c.GetStandings(context.Background(), "football") + + if err != nil { + t.Fatal(err) + } + + if len := len(standings); len == 0 { + t.Fatal(len) + } +} + +func TestGetStandingsByID(t *testing.T) { + c := CreateClient(t) + + id := 1 + + standings, err := c.GetStandingsByID(context.Background(), "football", id) + + if err != nil { + t.Fatal(err) + } + + if len := len(standings); len == 0 { + t.Fatal(len) + } + + if standings[0].ID != id { + t.Fail() + } +} + +func TestGetStandingsByLeagueSeasonTypeID(t *testing.T) { + c := CreateClient(t) + + id := 29 + seasonID := 2 + standingType := "total" + + standings, err := c.GetStandingsByLeagueSeasonTypeID(context.Background(), "football", id, seasonID, standingType) + + if err != nil { + t.Fatal(err) + } + + if len := len(standings); len == 0 { + t.Fatal(len) + } + + if standings[0].LeagueID != id { + t.Fail() + } + + if standings[0].SeasonID != seasonID { + t.Fail() + } + + if standings[0].Type != standingType { + t.Fail() + } +}