Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missing limit param #5

Merged
merged 1 commit into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading