Skip to content

Commit

Permalink
Adds methods to fetch teams and persons from API. Refs #1
Browse files Browse the repository at this point in the history
  • Loading branch information
ariel17 committed Mar 6, 2023
1 parent 6f26550 commit 68c6f89
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 10 deletions.
34 changes: 27 additions & 7 deletions pkg/clients/football.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,21 @@ type Team struct {
Address string `json:"address"`
}

type Person struct {
ID int64 `json:"id"`
Name string `json:"name"`
Position string `json:"position"`
DateOfBirth string `json:"dateOfBirth"`
Nationality string `json:"nationality"`
}

// FootballAPIClient is the behavior contract that every implementation must
// comply. It offers access to football-data.org data with handy methods. It is
// NOT a full client implementation but access to required resources.
type FootballAPIClient interface {
GetLeagueByCode(code string) (*League, error)
GetTeamByID(id int64) (*Team, error)

// TODO GetTeam
// TODO GetPlayer
// TODO GetCoach
GetPersonByID(id int64) (*Person, error)
}

// NewFootballAPIClient creates a new instance of real API client.
Expand All @@ -68,7 +73,8 @@ type realAPIClient struct {
apiKey string
}

func (r *realAPIClient) get(url string) ([]byte, error) {
func (r *realAPIClient) get(path string) ([]byte, error) {
url := r.baseURL + path
request, _ := http.NewRequest(http.MethodGet, url, nil)
request.Header.Set("X-Auth-Token", r.apiKey)

Expand All @@ -92,7 +98,7 @@ func (r *realAPIClient) get(url string) ([]byte, error) {
}

func (r *realAPIClient) GetLeagueByCode(code string) (*League, error) {
url := fmt.Sprintf("%s/competitions/%s", r.baseURL, code)
url := fmt.Sprintf("/competitions/%s", code)
body, err := r.get(url)
if err != nil {
return nil, err
Expand All @@ -106,7 +112,7 @@ func (r *realAPIClient) GetLeagueByCode(code string) (*League, error) {
}

func (r *realAPIClient) GetTeamByID(id int64) (*Team, error) {
url := fmt.Sprintf("%s/teams/%d", r.baseURL, id)
url := fmt.Sprintf("/teams/%d", id)
body, err := r.get(url)
if err != nil {
return nil, err
Expand All @@ -119,6 +125,20 @@ func (r *realAPIClient) GetTeamByID(id int64) (*Team, error) {
return &team, nil
}

func (r *realAPIClient) GetPersonByID(id int64) (*Person, error) {
url := fmt.Sprintf("/persons/%d", id)
body, err := r.get(url)
if err != nil {
return nil, err
}
person := Person{}
err = json.Unmarshal(body, &person)
if err != nil {
return nil, err
}
return &person, nil
}

func init() {
client = &http.Client{
Timeout: time.Second,
Expand Down
78 changes: 75 additions & 3 deletions pkg/clients/football_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,37 @@ func TestNewFootballAPIClient(t *testing.T) {
})
}

func TestGet(t *testing.T) {
testCases := []struct {
name string
statusCode int
isSuccess bool
}{
{"not found", 404, false},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
apiContent := loadGoldenFile(t.Name())
server := newTestServer("/", tc.statusCode, apiContent)
defer server.Close()

c := &realAPIClient{
baseURL: server.URL,
client: httpClient,
apiKey: apiKey,
}
response, err := c.get("/")
assert.Equal(t, err == nil, tc.isSuccess)
assert.Equal(t, response != nil, tc.isSuccess)

if !tc.isSuccess {
assert.Contains(t, err.Error(), "failed to retrieve content:")
}
})
}
}

func TestGetLeagueByCode(t *testing.T) {
testCases := []struct {
name string
Expand All @@ -42,7 +73,6 @@ func TestGetLeagueByCode(t *testing.T) {
isSuccess bool
}{
{"ok", "PL", 200, true},
{"not found", "XXX", 404, false},
}

for _, tc := range testCases {
Expand Down Expand Up @@ -83,7 +113,6 @@ func TestGetTeamByID(t *testing.T) {
isSuccess bool
}{
{"ok", 2061, 200, true},
{"not found", 999, 404, false},
}

for _, tc := range testCases {
Expand All @@ -103,7 +132,7 @@ func TestGetTeamByID(t *testing.T) {

if tc.isSuccess {
assert.Equal(t, "CA Boca Juniors", response.Name)
assert.Equal(t, 2061, response.ID)
assert.Equal(t, int64(2061), response.ID)
assert.Equal(t, "Boca Juniors", response.ShortName)
assert.Equal(t, "BOC", response.TLA)
assert.Equal(t, "Brandsen 805, La Boca Buenos Aires, Buenos Aires 1161", response.Address)
Expand All @@ -115,6 +144,49 @@ func TestGetTeamByID(t *testing.T) {
}
}

func TestGetPersonByID(t *testing.T) {
client = &http.Client{
Timeout: time.Second,
}

testCases := []struct {
name string
id int64
statusCode int
isSuccess bool
}{
{"ok", 44, 200, true},
{"not found", 999, 404, false},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
apiContent := loadGoldenFile(t.Name())
server := newTestServer(fmt.Sprintf("/persons/%d", tc.id), tc.statusCode, apiContent)
defer server.Close()

c := &realAPIClient{
baseURL: server.URL,
client: httpClient,
apiKey: apiKey,
}
response, err := c.GetPersonByID(tc.id)
assert.Equal(t, err == nil, tc.isSuccess)
assert.Equal(t, response != nil, tc.isSuccess)

if tc.isSuccess {
assert.Equal(t, "Cristiano Ronaldo", response.Name)
assert.Equal(t, int64(44), response.ID)
assert.Equal(t, "Centre-Forward", response.Position)
assert.Equal(t, "1985-02-05", response.DateOfBirth)
assert.Equal(t, "Portugal", response.Nationality)
} else {
assert.True(t, strings.Contains(err.Error(), "failed to retrieve content:"))
}
})
}
}

// loadGoldenFiles uses the test name to load a JSON value as expected result.
func loadGoldenFile(testName string) []byte {
content, err := os.ReadFile("./golden/" + testName + ".json")
Expand Down

0 comments on commit 68c6f89

Please sign in to comment.