Skip to content

Commit

Permalink
Fix missing limit param
Browse files Browse the repository at this point in the history
  • Loading branch information
ownerofglory committed Jun 17, 2024
1 parent 7b814e1 commit 688fcaa
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 27 deletions.
134 changes: 107 additions & 27 deletions api_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io/ioutil"
"net/http"
"net/url"
"strconv"
"time"
)

Expand All @@ -14,20 +15,26 @@ const (
baseURLWidgetDM = "http://www3.vvs.de/vvs/widget/XML_DM_REQUEST"
)

const (
defaultDepartureLimit = 100
defaultArrivalLimit = 100
defaultJourneyLimit = 100
)

// GetJourney initiates a request to retrieve journey information between two locations at a specified time.
// It uses the VVS (Verkehrs- und Tarifverbund Stuttgart) API to calculate routes, taking into account various transport options and preferences.
//
// Parameters:
// - r JourneyRequest: Struct containing the essential information for the journey request.
// - OrigId: The ID or code representing the origin location for the journey. This should be in the format recognized by the VVS API, e.g., "de:08111:2599".
// - DstId: The ID or code representing the destination location for the journey, formatted similarly to OrigId.
// - TimeAt: Pointer to a time.Time object specifying the desired departure or arrival time for the journey.
// - Limit: Pointer to an integer specifying the maximum number of journey options to return. If nil, a default value defined by the API will be used.
// - LangCode: Pointer to a string specifying the language code for the response, e.g., "de" for German. If nil, the API's default language will be used.
// - OrigId: The ID or code representing the origin location for the journey. This should be in the format recognized by the VVS API, e.g., "de:08111:2599".
// - DstId: The ID or code representing the destination location for the journey, formatted similarly to OrigId.
// - TimeAt: Pointer to a time.Time object specifying the desired departure or arrival time for the journey.
// - Limit: Pointer to an integer specifying the maximum number of journey options to return. If nil, a default value defined by the API will be used.
// - LangCode: Pointer to a string specifying the language code for the response, e.g., "de" for German. If nil, the API's default language will be used.
//
// - reqParams ...ReqParam: An optional slice of ReqParam structs allowing for additional parameters to be specified for the journey request. These can include:
// - Name: The name of the parameter, matching the constant names defined for VVS API parameters, e.g., ParamCalcOneDirection.
// - Value: The value of the parameter, as a string, e.g., "1" for true or specific values like "EPSG:4326" for coordinate formats.
// - Name: The name of the parameter, matching the constant names defined for VVS API parameters, e.g., ParamCalcOneDirection.
// - Value: The value of the parameter, as a string, e.g., "1" for true or specific values like "EPSG:4326" for coordinate formats.
//
// The function supports various optional parameters that can be used to refine the journey search, including but not limited to:
// - ChangeSpeed: Adjusts the assumed speed of changing between transport modes.
Expand All @@ -39,17 +46,21 @@ const (
// - error: An error object that will be non-nil if there was an issue processing the request or communicating with the VVS API.
//
// Example usage:
// journeyReq := JourneyRequest{
// OrigId: "de:08111:2599",
// DstId: "de:08111:6075",
// TimeAt: time.Now(),
// Limit: 10,
// LangCode: "de",
// }
//
// journeyReq := JourneyRequest{
// OrigId: "de:08111:2599",
// DstId: "de:08111:6075",
// TimeAt: time.Now(),
// Limit: 10,
// LangCode: "de",
// }
//
// journeyResp, err := GetJourney(journeyReq, ReqParam{Name: ParamRouteType, Value: "leasttime"})
// if err != nil {
// // Handle error
// }
//
// if err != nil {
// // Handle error
// }
//
// // Process journeyResp
func GetJourney(r JourneyRequest, reqParams ...ReqParam) (*JourneyResponse, error) {
// Prepare query parameters
Expand All @@ -59,6 +70,11 @@ func GetJourney(r JourneyRequest, reqParams ...ReqParam) (*JourneyResponse, erro
setDefaultJourneyReqParams(params)

// Set dynamic values separately
limit := defaultJourneyLimit
if r.Limit != nil {
limit = *r.Limit
}
limitParam := strconv.Itoa(limit)
timeAt := time.Now()
if r.TimeAt != nil {
timeAt = *r.TimeAt
Expand All @@ -70,6 +86,7 @@ func GetJourney(r JourneyRequest, reqParams ...ReqParam) (*JourneyResponse, erro
params.Set(ParamItdTime, timeAt.Format("1504"))
params.Set(ParamNameDestination, dst)
params.Set(ParamNameOrigin, orig)
params.Set(ParamLimit, limitParam)

// override optional params6
overrideReqParams(params, reqParams...)
Expand Down Expand Up @@ -110,49 +127,80 @@ func GetJourney(r JourneyRequest, reqParams ...ReqParam) (*JourneyResponse, erro
//
// Parameters:
// - r ArrivalRequest: A struct containing the base request parameters such as station ID and request time.
//
// - OrigId (string): The origin station identifier. Not used in this context but can be set for consistency.
//
// - DstId (string): The destination station identifier. This is typically the station ID for which arrivals are requested.
//
// - TimeAt (*time.Time): The specific date and time for which arrival information is requested. If nil, current time is assumed.
//
// - Limit (*int): The maximum number of arrival entries to retrieve. If nil, a default limit is applied.
//
// - LangCode (*string): The language code for the response (e.g., "de" for German). If nil, a default language is used.
//
// - reqParams ...ReqParam: Optional parameters to further customize the request. Each ReqParam consists of a Name and Value.
// Supported optional parameters (refer to constants for parameter names):
// - reqParams ...ReqParam: Optional parameters to further customize the request. Each ReqParam consists of a Name and Value.
// Supported optional parameters (refer to constants for parameter names):
//
// - ParamLocationServerActive: Activates the location server for processing the request.
//
// - ParamLsShowTrainsExplicit: Specifies whether trains should be shown explicitly in the response.
//
// - ParamStateless: Indicates if the request should be processed without maintaining state.
//
// - ParamLanguage: Sets the language of the response.
//
// - ParamSpEncId: Security parameter, typically "0".
//
// - ParamAnySigWhenPerfectNoOtherMatches: Used to refine search results.
//
// - ParamLimit: Controls the maximum number of results returned.
//
// - ParamDepArr: Indicates whether departure or arrival times are requested ("arrival" for arrivals).
//
// - ParamTypeDm: Specifies the type of data management request.
//
// - ParamAnyObjFilterDm: Filters objects based on specified criteria.
//
// - ParamDeleteAssignedStops: Indicates whether assigned stops should be removed from the response.
//
// - ParamNameDm: The name or ID of the station for which arrivals are being requested.
//
// - ParamMode: Specifies the mode of transport.
//
// - ParamDmLineSelectionAll: Determines if all lines should be selected in the request.
//
// - ParamUseRealtime: Specifies whether real-time data should be used.
//
// - ParamOutputFormat: Defines the output format of the response.
//
// - ParamCoordOutputFormat: Sets the coordinate format for the response.
//
// - ParamItdDateTimeDepArr: Specifies the desired time for departure or arrival.
//
// - Additional parameters related to date and time of the request: ParamItdDateYear, ParamItdDateMonth, ParamItdDateDay, ParamItdTimeHour, ParamItdTimeMinute.
//
// Returns:
// - (*ArrivalResponse, error): A pointer to an ArrivalResponse struct containing the requested arrival information, or an error if the request fails.
//
// Example usage:
// response, err := GetArrivals(ArrivalRequest{DstId: "stationID", TimeAt: &time.Now()}, ReqParam{Name: ParamLimit, Value: "5"})
// if err != nil {
// // handle error
// }
//
// if err != nil {
// // handle error
// }
//
// // process response
func GetArrivals(r ArrivalRequest, reqParams ...ReqParam) (*ArrivalResponse, error) {
// Prepare query parameters
params := url.Values{}

setDefaultArrivalReqParams(params)

limit := defaultArrivalLimit
if r.Limit != nil {
limit = *r.Limit
}
limitParam := strconv.Itoa(limit)
timeAt := time.Now()
if r.TimeAt != nil {
timeAt = *r.TimeAt
Expand All @@ -170,6 +218,7 @@ func GetArrivals(r ArrivalRequest, reqParams ...ReqParam) (*ArrivalResponse, err
params.Set(ParamItdTimeHour, hour)
params.Set(ParamItdTimeMinute, minute)
params.Set(ParamNameDm, stationId)
params.Set(ParamLimit, limitParam)

overrideReqParams(params, reqParams...)

Expand Down Expand Up @@ -209,48 +258,78 @@ func GetArrivals(r ArrivalRequest, reqParams ...ReqParam) (*ArrivalResponse, err
//
// Parameters:
// - r DepartureRequest: A struct containing the base request parameters such as station ID and request time.
//
// - OrigId (string): The origin station identifier. In the context of departures, this is the station ID from which departures are requested.
//
// - DstId (string): The destination station identifier. Not typically used for departure requests but can be set for API consistency.
//
// - TimeAt (*time.Time): The specific date and time for which departure information is requested. If nil, the current time is assumed.
//
// - Limit (*int): The maximum number of departure entries to retrieve. If nil, a default limit is applied.
//
// - LangCode (*string): The language code for the response (e.g., "de" for German). If nil, a default language is used.
//
// - reqParams ...ReqParam: Optional parameters to further customize the request. Each ReqParam consists of a Name and Value.
// Supported optional parameters (refer to constants for parameter names):
// - reqParams ...ReqParam: Optional parameters to further customize the request. Each ReqParam consists of a Name and Value.
// Supported optional parameters (refer to constants for parameter names):
//
// - ParamLocationServerActive: Activates the location server for processing the request.
//
// - ParamLsShowTrainsExplicit: Specifies whether trains should be shown explicitly in the response.
//
// - ParamStateless: Indicates if the request should be processed without maintaining state.
//
// - ParamLanguage: Sets the language of the response.
//
// - ParamSpEncId: Security parameter, typically "0".
//
// - ParamAnySigWhenPerfectNoOtherMatches: Used to refine search results.
//
// - ParamLimit: Controls the maximum number of results returned.
//
// - ParamDepArr: Indicates whether departure or arrival times are requested ("departure" for departures).
//
// - ParamTypeDm: Specifies the type of data management request.
//
// - ParamAnyObjFilterDm: Filters objects based on specified criteria.
//
// - ParamDeleteAssignedStops: Indicates whether assigned stops should be removed from the response.
//
// - ParamNameDm: The name or ID of the station for which departures are being requested.
//
// - ParamMode: Specifies the mode of transport.
//
// - ParamDmLineSelectionAll: Determines if all lines should be selected in the request.
//
// - ParamUseRealtime: Specifies whether real-time data should be used.
//
// - ParamOutputFormat: Defines the output format of the response.
//
// - ParamCoordOutputFormat: Sets the coordinate format for the response.
//
// - Additional parameters related to date and time of the request: ParamItdDateYear, ParamItdDateMonth, ParamItdDateDay, ParamItdTimeHour, ParamItdTimeMinute.
//
// Returns:
// - (*DepartureResponse, error): A pointer to a DepartureResponse struct containing the requested departure information, or an error if the request fails.
//
// Example usage:
// response, err := GetDepartures(DepartureRequest{OrigId: "stationID", TimeAt: &time.Now()}, ReqParam{Name: ParamLimit, Value: "10"})
// if err != nil {
// // handle error
// }
//
// if err != nil {
// // handle error
// }
//
// // process response
func GetDepartures(r DepartureRequest, reqParams ...ReqParam) (*DepartureResponse, error) {
// Assemble the query parameters
params := url.Values{}

setDefaultDepartureReqParams(params)

limit := defaultDepartureLimit
if r.Limit != nil {
limit = *r.Limit
}
limitParam := strconv.Itoa(limit)
timeAt := time.Now()
if r.TimeAt != nil {
timeAt = *r.TimeAt
Expand All @@ -268,6 +347,7 @@ func GetDepartures(r DepartureRequest, reqParams ...ReqParam) (*DepartureRespons
params.Set(ParamItdTimeHour, hour)
params.Set(ParamItdTimeMinute, minute)
params.Set(ParamNameDm, stationId)
params.Set(ParamLimit, limitParam)

overrideReqParams(params, reqParams...)

Expand Down
34 changes: 34 additions & 0 deletions api_wrapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
)

func TestGetJourney(t *testing.T) {
testLimit := 4
testCases := []struct {
name string
orig string
Expand All @@ -22,6 +23,13 @@ func TestGetJourney(t *testing.T) {
dst: station.HAUPTBAHNHOF_TIEF_STUTTGART,
errExpected: false,
},
{
name: "When required params and limit are given then journeys no more than limit are returned",
orig: station.BOPSER_STUTTGART,
dst: station.HAUPTBAHNHOF_TIEF_STUTTGART,
errExpected: false,
limit: &testLimit,
},
}

for _, tc := range testCases {
Expand All @@ -43,6 +51,10 @@ func TestGetJourney(t *testing.T) {
t.Fatalf("Error occured: %v\n", err)
}

if tc.limit != nil && len(res.Journeys) > *tc.limit {
t.Fatalf("Error occured: %v\n", err)
}

if res == nil {
t.Fatalf("Response is nil")
}
Expand All @@ -51,6 +63,7 @@ func TestGetJourney(t *testing.T) {
}

func TestGetArrivals(t *testing.T) {
testLimit := 4
testCases := []struct {
name string
stationId string
Expand All @@ -63,6 +76,12 @@ func TestGetArrivals(t *testing.T) {
stationId: station.BOPSER_STUTTGART,
errExpected: false,
},
{
name: "When required params and limit are given then arrivals no more than limit are returned",
stationId: station.BOPSER_STUTTGART,
errExpected: false,
limit: &testLimit,
},
}

for _, tc := range testCases {
Expand All @@ -83,6 +102,10 @@ func TestGetArrivals(t *testing.T) {
t.Fatalf("Error occured: %v\n", err)
}

if tc.limit != nil && len(res.ArrivalList) > *tc.limit {
t.Fatalf("Error occured: %v\n", err)
}

if res == nil {
t.Fatalf("Response is nil")
}
Expand All @@ -91,6 +114,7 @@ func TestGetArrivals(t *testing.T) {
}

func TestGetDepartures(t *testing.T) {
testLimit := 4
testCases := []struct {
name string
stationId string
Expand All @@ -103,6 +127,12 @@ func TestGetDepartures(t *testing.T) {
stationId: station.BOPSER_STUTTGART,
errExpected: false,
},
{
name: "When required params and limit are given then departures no more then limit are returned",
stationId: station.BOPSER_STUTTGART,
errExpected: false,
limit: &testLimit,
},
}

for _, tc := range testCases {
Expand All @@ -123,6 +153,10 @@ func TestGetDepartures(t *testing.T) {
t.Fatalf("Error occured: %v\n", err)
}

if tc.limit != nil && len(res.DepartureList) > *tc.limit {
t.Fatalf("Error occured: %v\n", err)
}

if res == nil {
t.Fatalf("Response is nil")
}
Expand Down

0 comments on commit 688fcaa

Please sign in to comment.