From 3c5e31b25a53268b413bc1e511b7486a2a1c80b9 Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Wed, 8 Sep 2021 15:23:50 +0200 Subject: Renamed TrainStop to simply Stop --- pkg/navitia_api_client/client.go | 2 +- pkg/navitia_api_client/stops.go | 70 +++++++++++++++++++ pkg/navitia_api_client/stops_test.go | 108 +++++++++++++++++++++++++++++ pkg/navitia_api_client/train_stops.go | 70 ------------------- pkg/navitia_api_client/train_stops_test.go | 108 ----------------------------- 5 files changed, 179 insertions(+), 179 deletions(-) create mode 100644 pkg/navitia_api_client/stops.go create mode 100644 pkg/navitia_api_client/stops_test.go delete mode 100644 pkg/navitia_api_client/train_stops.go delete mode 100644 pkg/navitia_api_client/train_stops_test.go (limited to 'pkg/navitia_api_client') diff --git a/pkg/navitia_api_client/client.go b/pkg/navitia_api_client/client.go index ccd7198..2ca0e5d 100644 --- a/pkg/navitia_api_client/client.go +++ b/pkg/navitia_api_client/client.go @@ -11,7 +11,7 @@ import ( type Client interface { GetDepartures(trainStop string) (departures []model.Departure, err error) - GetTrainStops() (trainStops []model.TrainStop, err error) + GetStops() (trainStops []model.Stop, err error) } type NavitiaClient struct { diff --git a/pkg/navitia_api_client/stops.go b/pkg/navitia_api_client/stops.go new file mode 100644 index 0000000..f0cbcf8 --- /dev/null +++ b/pkg/navitia_api_client/stops.go @@ -0,0 +1,70 @@ +package navitia_api_client + +import ( + "encoding/json" + "fmt" + "net/http" + + "git.adyxax.org/adyxax/trains/pkg/model" +) + +type StopsResponse struct { + Pagination struct { + StartPage int `json:"start_page"` + ItemsOnPage int `json:"items_on_page"` + ItemsPerPage int `json:"items_per_page"` + TotalResult int `json:"total_result"` + } `json:"pagination"` + StopAreas []struct { + Name string `json:"name"` + ID string `json:"id"` + Codes []interface{} `json:"codes"` + Links []interface{} `json:"links"` + Coord interface{} `json:"coord"` + Label string `json:"label"` + Timezone interface{} `json:"timezone"` + AdministrativeRegion interface{} `json:"administrative_regions"` + } `json:"stop_areas"` + Links []interface{} `json:"links"` + Disruptions []interface{} `json:"disruptions"` + FeedPublishers []interface{} `json:"feed_publishers"` + Context interface{} `json:"context"` +} + +func (c *NavitiaClient) GetStops() (trainStops []model.Stop, err error) { + return getStopsPage(c, 0) +} + +func getStopsPage(c *NavitiaClient, i int) (trainStops []model.Stop, err error) { + request := fmt.Sprintf("%s/coverage/sncf/stop_areas?count=1000&start_page=%d", c.baseURL, i) + req, err := http.NewRequest("GET", request, nil) + if err != nil { + return nil, newHttpClientError("http.NewRequest error", err) + } + resp, err := c.httpClient.Do(req) + if err != nil { + return nil, newHttpClientError("httpClient.Do error", err) + } + defer resp.Body.Close() + if resp.StatusCode == http.StatusOK { + var data StopsResponse + if err = json.NewDecoder(resp.Body).Decode(&data); err != nil { + return nil, newJsonDecodeError("GetStops ", err) + } + for i := 0; i < len(data.StopAreas); i++ { + if data.StopAreas[i].Label != "" { + trainStops = append(trainStops, model.Stop{data.StopAreas[i].ID, data.StopAreas[i].Label}) + } + } + if data.Pagination.ItemsOnPage+data.Pagination.ItemsPerPage*data.Pagination.StartPage < data.Pagination.TotalResult { + tss, err := getStopsPage(c, i+1) + if err != nil { + return nil, err + } + trainStops = append(trainStops, tss...) + } + } else { + err = newApiError(resp.StatusCode, "GetStops") + } + return +} diff --git a/pkg/navitia_api_client/stops_test.go b/pkg/navitia_api_client/stops_test.go new file mode 100644 index 0000000..0b94765 --- /dev/null +++ b/pkg/navitia_api_client/stops_test.go @@ -0,0 +1,108 @@ +package navitia_api_client + +import ( + "net/http" + "net/http/httptest" + "reflect" + "testing" + + "git.adyxax.org/adyxax/trains/pkg/model" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGetStops(t *testing.T) { + // Simple Test cases + testCases := []struct { + name string + inputNewCLient string + expected []model.Stop + expectedError interface{} + }{ + {"invalid characters in token should fail", "}", nil, &HttpClientError{}}, + {"unreachable server should fail", "https://", nil, &HttpClientError{}}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + client := NewClient(tc.inputNewCLient) + valid, err := client.GetStops() + if tc.expectedError != nil { + require.Error(t, err) + assert.Equalf(t, reflect.TypeOf(err), reflect.TypeOf(tc.expectedError), "Invalid error type. Got %s but expected %s", reflect.TypeOf(err), reflect.TypeOf(tc.expectedError)) + assert.Equal(t, tc.expected, valid) + } else { + require.NoError(t, err) + assert.Equal(t, tc.expected, valid) + } + }) + } + // Test cases with a filename + testCasesFilename := []struct { + name string + inputFilename string + expected []model.Stop + expectedError interface{} + }{ + {"invalid json should fail", "test_data/invalid.json", nil, &JsonDecodeError{}}, + } + for _, tc := range testCasesFilename { + t.Run(tc.name, func(t *testing.T) { + client, ts := newTestClientFromFilename(t, tc.inputFilename) + defer ts.Close() + valid, err := client.GetStops() + if tc.expectedError != nil { + require.Error(t, err) + assert.Equalf(t, reflect.TypeOf(err), reflect.TypeOf(tc.expectedError), "Invalid error type. Got %s but expected %s", reflect.TypeOf(err), reflect.TypeOf(tc.expectedError)) + assert.Equal(t, tc.expected, valid) + } else { + require.NoError(t, err) + assert.Equal(t, tc.expected, valid) + } + }) + } + // http error + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotFound) + })) + client := newTestClient(ts) + _, err := client.GetStops() + if err == nil { + t.Fatalf("404 should raise an error") + } + // normal working request + client, ts = newTestClientFromFilename(t, "test_data/4-train-stops.json") + defer ts.Close() + trainStops, err := client.GetStops() + if err != nil { + t.Fatalf("could not get train stops : %s", err) + } + // 4 records but one is empty (navitia api quirk) + if len(trainStops) != 3 { + t.Fatalf("did not decode train stops properly, got %d train stops when expected 4", len(trainStops)) + } + // normal request in multiple pages + client, ts = newTestClientFromFilenames(t, []testClientCase{ + testClientCase{"/coverage/sncf/stop_areas?count=1000&start_page=0", "test_data/4-train-stops-page-0.json"}, + testClientCase{"/coverage/sncf/stop_areas?count=1000&start_page=1", "test_data/4-train-stops-page-1.json"}, + testClientCase{"/coverage/sncf/stop_areas?count=1000&start_page=2", "test_data/4-train-stops-page-2.json"}, + }) + defer ts.Close() + trainStops, err = client.GetStops() + if err != nil { + t.Fatalf("could not get train stops : %+v", err) + } + // 12 records but one is empty (navitia api quirk) + if len(trainStops) != 11 { + t.Fatalf("did not decode train stops properly, got %d train stops when expected 4", len(trainStops)) + } + // failing request in multiple pages with last one missing + client, ts = newTestClientFromFilenames(t, []testClientCase{ + testClientCase{"/coverage/sncf/stop_areas?count=1000&start_page=0", "test_data/4-train-stops-page-0.json"}, + testClientCase{"/coverage/sncf/stop_areas?count=1000&start_page=1", "test_data/4-train-stops-page-1.json"}, + }) + defer ts.Close() + trainStops, err = client.GetStops() + if err == nil { + t.Fatalf("should not be able to get train stops : %+v", trainStops) + } +} diff --git a/pkg/navitia_api_client/train_stops.go b/pkg/navitia_api_client/train_stops.go deleted file mode 100644 index a31ccf7..0000000 --- a/pkg/navitia_api_client/train_stops.go +++ /dev/null @@ -1,70 +0,0 @@ -package navitia_api_client - -import ( - "encoding/json" - "fmt" - "net/http" - - "git.adyxax.org/adyxax/trains/pkg/model" -) - -type TrainStopsResponse struct { - Pagination struct { - StartPage int `json:"start_page"` - ItemsOnPage int `json:"items_on_page"` - ItemsPerPage int `json:"items_per_page"` - TotalResult int `json:"total_result"` - } `json:"pagination"` - StopAreas []struct { - Name string `json:"name"` - ID string `json:"id"` - Codes []interface{} `json:"codes"` - Links []interface{} `json:"links"` - Coord interface{} `json:"coord"` - Label string `json:"label"` - Timezone interface{} `json:"timezone"` - AdministrativeRegion interface{} `json:"administrative_regions"` - } `json:"stop_areas"` - Links []interface{} `json:"links"` - Disruptions []interface{} `json:"disruptions"` - FeedPublishers []interface{} `json:"feed_publishers"` - Context interface{} `json:"context"` -} - -func (c *NavitiaClient) GetTrainStops() (trainStops []model.TrainStop, err error) { - return getTrainStopsPage(c, 0) -} - -func getTrainStopsPage(c *NavitiaClient, i int) (trainStops []model.TrainStop, err error) { - request := fmt.Sprintf("%s/coverage/sncf/stop_areas?count=1000&start_page=%d", c.baseURL, i) - req, err := http.NewRequest("GET", request, nil) - if err != nil { - return nil, newHttpClientError("http.NewRequest error", err) - } - resp, err := c.httpClient.Do(req) - if err != nil { - return nil, newHttpClientError("httpClient.Do error", err) - } - defer resp.Body.Close() - if resp.StatusCode == http.StatusOK { - var data TrainStopsResponse - if err = json.NewDecoder(resp.Body).Decode(&data); err != nil { - return nil, newJsonDecodeError("GetTrainStops ", err) - } - for i := 0; i < len(data.StopAreas); i++ { - if data.StopAreas[i].Label != "" { - trainStops = append(trainStops, model.TrainStop{data.StopAreas[i].ID, data.StopAreas[i].Label}) - } - } - if data.Pagination.ItemsOnPage+data.Pagination.ItemsPerPage*data.Pagination.StartPage < data.Pagination.TotalResult { - tss, err := getTrainStopsPage(c, i+1) - if err != nil { - return nil, err - } - trainStops = append(trainStops, tss...) - } - } else { - err = newApiError(resp.StatusCode, "GetTrainStops") - } - return -} diff --git a/pkg/navitia_api_client/train_stops_test.go b/pkg/navitia_api_client/train_stops_test.go deleted file mode 100644 index 9e1c982..0000000 --- a/pkg/navitia_api_client/train_stops_test.go +++ /dev/null @@ -1,108 +0,0 @@ -package navitia_api_client - -import ( - "net/http" - "net/http/httptest" - "reflect" - "testing" - - "git.adyxax.org/adyxax/trains/pkg/model" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestGetTrainStops(t *testing.T) { - // Simple Test cases - testCases := []struct { - name string - inputNewCLient string - expected []model.TrainStop - expectedError interface{} - }{ - {"invalid characters in token should fail", "}", nil, &HttpClientError{}}, - {"unreachable server should fail", "https://", nil, &HttpClientError{}}, - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - client := NewClient(tc.inputNewCLient) - valid, err := client.GetTrainStops() - if tc.expectedError != nil { - require.Error(t, err) - assert.Equalf(t, reflect.TypeOf(err), reflect.TypeOf(tc.expectedError), "Invalid error type. Got %s but expected %s", reflect.TypeOf(err), reflect.TypeOf(tc.expectedError)) - assert.Equal(t, tc.expected, valid) - } else { - require.NoError(t, err) - assert.Equal(t, tc.expected, valid) - } - }) - } - // Test cases with a filename - testCasesFilename := []struct { - name string - inputFilename string - expected []model.TrainStop - expectedError interface{} - }{ - {"invalid json should fail", "test_data/invalid.json", nil, &JsonDecodeError{}}, - } - for _, tc := range testCasesFilename { - t.Run(tc.name, func(t *testing.T) { - client, ts := newTestClientFromFilename(t, tc.inputFilename) - defer ts.Close() - valid, err := client.GetTrainStops() - if tc.expectedError != nil { - require.Error(t, err) - assert.Equalf(t, reflect.TypeOf(err), reflect.TypeOf(tc.expectedError), "Invalid error type. Got %s but expected %s", reflect.TypeOf(err), reflect.TypeOf(tc.expectedError)) - assert.Equal(t, tc.expected, valid) - } else { - require.NoError(t, err) - assert.Equal(t, tc.expected, valid) - } - }) - } - // http error - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotFound) - })) - client := newTestClient(ts) - _, err := client.GetTrainStops() - if err == nil { - t.Fatalf("404 should raise an error") - } - // normal working request - client, ts = newTestClientFromFilename(t, "test_data/4-train-stops.json") - defer ts.Close() - trainStops, err := client.GetTrainStops() - if err != nil { - t.Fatalf("could not get train stops : %s", err) - } - // 4 records but one is empty (navitia api quirk) - if len(trainStops) != 3 { - t.Fatalf("did not decode train stops properly, got %d train stops when expected 4", len(trainStops)) - } - // normal request in multiple pages - client, ts = newTestClientFromFilenames(t, []testClientCase{ - testClientCase{"/coverage/sncf/stop_areas?count=1000&start_page=0", "test_data/4-train-stops-page-0.json"}, - testClientCase{"/coverage/sncf/stop_areas?count=1000&start_page=1", "test_data/4-train-stops-page-1.json"}, - testClientCase{"/coverage/sncf/stop_areas?count=1000&start_page=2", "test_data/4-train-stops-page-2.json"}, - }) - defer ts.Close() - trainStops, err = client.GetTrainStops() - if err != nil { - t.Fatalf("could not get train stops : %+v", err) - } - // 12 records but one is empty (navitia api quirk) - if len(trainStops) != 11 { - t.Fatalf("did not decode train stops properly, got %d train stops when expected 4", len(trainStops)) - } - // failing request in multiple pages with last one missing - client, ts = newTestClientFromFilenames(t, []testClientCase{ - testClientCase{"/coverage/sncf/stop_areas?count=1000&start_page=0", "test_data/4-train-stops-page-0.json"}, - testClientCase{"/coverage/sncf/stop_areas?count=1000&start_page=1", "test_data/4-train-stops-page-1.json"}, - }) - defer ts.Close() - trainStops, err = client.GetTrainStops() - if err == nil { - t.Fatalf("should not be able to get train stops : %+v", trainStops) - } -} -- cgit v1.2.3