package tripsgo import ( "bytes" "encoding/json" "fmt" "io/ioutil" "log" "os" "strings" "testing" "github.com/stretchr/testify/assert" ) var tripID string var apiTestList = []APITestCase{ { Tag: "t1 - Get all trips", Method: "GET", URL: "/api/trips", Status: 200, }, { Tag: "t2 - Get a nonexistent trip", Method: "GET", URL: "/api/trips/99999", Status: 404, }, { Tag: "t3 - Create a Trip", Method: "POST", URL: "/api/trips", Body: `{ "Name":"Trip CREATE TEST", "UserId":"GO_TEST", "RecordedTimeStamp": "2018-04-19T19:08:16.03Z", "EndTimeStamp": "2018-04-19T19:42:49.573Z", "Rating":95, "IsComplete":false, "HasSimulatedOBDData":true, "AverageSpeed":100, "FuelUsed":10.27193484, "HardStops":2, "HardAccelerations":4, "Distance":30.0275486, "CreatedAt":"2018-01-01T12:00:00Z", "UpdatedAt":"2001-01-01T12:00:00Z" }`, Status: 200, }, { Tag: "t4 - Update a trip", Method: "PATCH", URL: "/api/trips/{tripID}", Body: `{ "Name":"Trip UPDATE TEST", "UserId":"GO_TEST", "RecordedTimeStamp": "2018-04-19T19:08:16.03Z", "EndTimeStamp": "2018-04-19T19:42:49.573Z", "Rating":91005, "IsComplete":true, "HasSimulatedOBDData":true, "AverageSpeed":100, "FuelUsed":10.27193484, "HardStops":2, "HardAccelerations":4, "Distance":30.0275486, "CreatedAt":"2018-01-01T12:00:00Z", "UpdatedAt":"2001-01-01T12:00:00Z" }`, Status: 200, }, { Tag: "t5 - Create Trip Point", Method: "POST", URL: "/api/trips/{tripID}/trippoints", Body: `{ "TripId": "{tripID}", "Latitude": 47.67598, "Longitude": -122.10612, "Speed": -255, "RecordedTimeStamp": "2018-05-24T10:00:15.003Z", "Sequence": 2, "RPM": -255, "ShortTermFuelBank": -255, "LongTermFuelBank": -255, "ThrottlePosition": -255, "RelativeThrottlePosition": -255, "Runtime": -255, "DistanceWithMalfunctionLight": -255, "EngineLoad": -255, "EngineFuelRate": -255, "CreatedAt": "0001-01-01T00:00:00Z", "UpdatedAt": "0001-01-01T00:00:00Z" }`, Status: 200, }, { Tag: "t6 - Update Trip Point", Method: "PATCH", URL: "/api/trips/{tripID}/trippoints/{tripPointID}", Body: `{ "Id": "{tripPointID}", "TripId": "{tripID}", "Latitude": 47.67598, "Longitude": -122.10612, "Speed": -255, "RecordedTimeStamp": "2018-05-24T10:00:15.003Z", "Sequence": 2, "RPM": -255, "ShortTermFuelBank": -255, "LongTermFuelBank": -255, "ThrottlePosition": -255, "RelativeThrottlePosition": -255, "Runtime": -255, "DistanceWithMalfunctionLight": -255, "EngineLoad": -255, "EngineFuelRate": -255, "Created": "0001-01-01T00:00:00Z", "UpdatedAt": "0001-01-01T00:00:00Z" }`, ExpectedResponse: "", Status: 200, }, { Tag: "t7 - Read Trip Points for Trip", Method: "GET", URL: "/api/trips/{tripID}/trippoints", Status: 200, }, { Tag: "t8 - Read Trip Points By Trip Point ID", Method: "GET", URL: "/api/trips/{tripID}/trippoints/{tripPointID}", Status: 200, }, { Tag: "t9 - Delete Trip Point", Method: "DELETE", URL: "/api/trips/{tripID}/trippoints/{tripPointID}", Status: 200, }, { Tag: "t10 - Delete a Trip", Method: "DELETE", URL: "/api/trips/{tripID}", Status: 200, }, { Tag: "t11 - Get All Trips for User", Method: "GET", URL: "/api/trips/user/SomeUser", Status: 200, }, } func TestTripApis(t *testing.T) { router := NewRouter() var debug, present = os.LookupEnv("DEBUG_LOGGING") if present && debug == "true" { InitLogging(os.Stdout, os.Stdout, os.Stdout) } else { // if debug env is not present or false, do not log debug output to console InitLogging(os.Stdout, ioutil.Discard, os.Stdout) } RunAPITests(t, router, apiTestList[0:3]) // setup update trip test (URL, Body, expected Response) apiTestList[3].URL = strings.Replace(apiTestList[3].URL, "{tripID}", TripFromStr(apiTestList[2].ActualResponse).ID, 1) apiTestList[3].Body = GetUpdateTrip(apiTestList[2].ActualResponse, apiTestList[3].Body) apiTestList[3].ExpectedResponse = apiTestList[3].Body // setup create trip point test apiTestList[4].URL = strings.Replace(apiTestList[4].URL, "{tripID}", TripFromStr(apiTestList[2].ActualResponse).ID, 1) apiTestList[4].Body = strings.Replace(apiTestList[4].Body, "{tripID}", TripFromStr(apiTestList[2].ActualResponse).ID, 1) // run update trip and create trip point tests RunAPITests(t, router, apiTestList[3:5]) // setup update trip point test apiTestList[5].URL = strings.Replace(apiTestList[5].URL, "{tripID}", TripFromStr(apiTestList[2].ActualResponse).ID, 1) apiTestList[5].URL = strings.Replace(apiTestList[5].URL, "{tripPointID}", TripPointFromStr(apiTestList[4].ActualResponse).ID, 1) apiTestList[5].Body = GetUpdateTripPoint(apiTestList[4].ActualResponse, apiTestList[5].Body) // setup read trip points for trip test apiTestList[6].URL = strings.Replace(apiTestList[6].URL, "{tripID}", TripFromStr(apiTestList[2].ActualResponse).ID, 1) // // setup ready trip points by trip point id test apiTestList[7].URL = strings.Replace(apiTestList[7].URL, "{tripID}", TripFromStr(apiTestList[2].ActualResponse).ID, 1) apiTestList[7].URL = strings.Replace(apiTestList[7].URL, "{tripPointID}", TripPointFromStr(apiTestList[4].ActualResponse).ID, 1) // //setup delete trip point test apiTestList[8].URL = strings.Replace(apiTestList[8].URL, "{tripID}", TripFromStr(apiTestList[2].ActualResponse).ID, 1) apiTestList[8].URL = strings.Replace(apiTestList[8].URL, "{tripPointID}", TripPointFromStr(apiTestList[4].ActualResponse).ID, 1) // setup delete test (URL) apiTestList[9].URL = strings.Replace(apiTestList[9].URL, "{tripID}", TripFromStr(apiTestList[2].ActualResponse).ID, 1) // run update test RunAPITests(t, router, apiTestList[5:10]) RunAPITests(t, router, apiTestList[10:11]) } func TestGetAllTripsReturnsServerErrorIfBadDbConnection(t *testing.T) { defer t.Cleanup(resetDataAccessEnvVars) //arrange os.Setenv("SQL_DRIVER", "not_a_real_driver") RebindDataAccessEnvironmentVariables() info := new(bytes.Buffer) InitLogging(info, os.Stdout, os.Stdout) var tr bool = true debug = &tr //act router := NewRouter() RunAPITestsPlainText(t, router, []APITestCase{ { Tag: "t1 - Get all trips", Method: "GET", URL: "/api/trips", Status: 500, }, }) //assert actual := fmt.Sprint(info) assert.Contains(t, actual, "getAllTrips - Query Failed to Execute") } func TestGetAllTripsReturnsErrorScanningTripsIfMissingSqlFields(t *testing.T) { defer t.Cleanup(resetDataAccessEnvVars) //arrange //oldSelectAllTripsQuery := func(SelectAllTripsQuery) var OldSelectAllTripsQuery = SelectAllTripsQuery SelectAllTripsQuery = func() string { return `SELECT Id FROM Trips WHERE Deleted = 0` } defer func() { SelectAllTripsQuery = OldSelectAllTripsQuery }() info := new(bytes.Buffer) InitLogging(info, os.Stdout, os.Stdout) var tr bool = true debug = &tr //act router := NewRouter() RunAPITestsPlainText(t, router, []APITestCase{ { Tag: "t1 - Get all trips", Method: "GET", URL: "/api/trips", Status: 500, }, }) //assert actual := fmt.Sprint(info) assert.Contains(t, actual, "GetAllTrips - Error scanning Trips") } func TestGetAllTripsForUsersReturnsServerErrorIfBadDbConnection(t *testing.T) { defer t.Cleanup(resetDataAccessEnvVars) //arrange os.Setenv("SQL_DRIVER", "not_a_real_driver") RebindDataAccessEnvironmentVariables() info := new(bytes.Buffer) InitLogging(info, os.Stdout, os.Stdout) var tr bool = true debug = &tr //act router := NewRouter() RunAPITestsPlainText(t, router, []APITestCase{ { Tag: "t11 - Get All Trips for User", Method: "GET", URL: "/api/trips/user/SomeUser", Status: 500, }, }) //assert actual := fmt.Sprint(info) assert.Contains(t, actual, "getAllTripsForUser - Error while retrieving trips from database") } func TestGetAllTripsForUserReturnsErrorScanningTripsIfMissingSqlFields(t *testing.T) { defer t.Cleanup(resetDataAccessEnvVars) //arrange //oldSelectAllTripsQuery := func(SelectAllTripsQuery) var OldSelectAllTripsForUserQuery = SelectAllTripsForUserQuery SelectAllTripsForUserQuery = func(userID string) string { return `SELECT Id FROM Trips WHERE UserId ='` + userID + `' AND Deleted = 0` } defer func() { SelectAllTripsForUserQuery = OldSelectAllTripsForUserQuery }() info := new(bytes.Buffer) InitLogging(info, os.Stdout, os.Stdout) var tr bool = true debug = &tr //act router := NewRouter() RunAPITestsPlainText(t, router, []APITestCase{ { Tag: "t11 - Get All Trips for User", Method: "GET", URL: "/api/trips/user/SomeUser", Status: 500, }, }) //assert actual := fmt.Sprint(info) assert.Contains(t, actual, "getAllTripsForUser - Error scanning Trips") } func TestCreateTripReturnsErrorifInvalidJsonBody(t *testing.T) { info := new(bytes.Buffer) InitLogging(info, os.Stdout, os.Stdout) //act router := NewRouter() RunAPITestsPlainText(t, router, []APITestCase{ { Tag: "t3 - Create a Trip", Method: "POST", URL: "/api/trips", Body: `{ "Name":"Trip CREATE TEST", "UserId":"GO_TEST", "RecordedTimeStamp": "2018-04-19T19:08:16.03Z", "EndTimeStamp": "2018-04-19T19:42:49.573Z", "Rating":95, "IsComplete":`, Status: 500, }, }) //assert actual := fmt.Sprint(info) assert.Contains(t, actual, "Error while decoding json") } func TestUpdateTripReturnsErrorifInvalidJsonBody(t *testing.T) { info := new(bytes.Buffer) InitLogging(info, os.Stdout, os.Stdout) //act router := NewRouter() RunAPITestsPlainText(t, router, []APITestCase{ { Tag: "t4 - Update a trip", Method: "PATCH", URL: "/api/trips/{tripID}", Body: `{ "Name":"Trip UPDATE TEST", "UserId":"GO_TEST", "RecordedTimeStamp": "2018-04-19T19:08:16.03Z", "EndTimeStamp": "2018-04-19T19:42:49.573Z", "Rating":`, Status: 500, }, }) //assert actual := fmt.Sprint(info) assert.Contains(t, actual, "Update Trip - Error while decoding trip json") } func GetUpdateTrip(tripCreate string, tripUpdate string) string { tripC := TripFromStr(tripCreate) tripU := TripFromStr(tripUpdate) tripU.ID = tripC.ID serializedTripUpdate, _ := json.Marshal(tripU) return string(serializedTripUpdate) } func GetUpdateTripPoint(tripPointCreate string, tripPointUpdate string) string { tripPointC := TripPointFromStr(tripPointCreate) tripPointU := TripPointFromStr(tripPointUpdate) tripPointU.ID = tripPointC.ID tripPointU.TripID = tripPointC.TripID serializedTripUpdate, _ := json.Marshal(tripPointU) return string(serializedTripUpdate) } func TripFromStr(tripStr string) Trip { trip := Trip{} Debug.Println("DEBUG: TripFromStr - " + tripStr) errCreate := json.Unmarshal([]byte(tripStr), &trip) if errCreate != nil { log.Println("TripFromStr - Invalid trip string") log.Fatal(errCreate) } return trip } func TripPointFromStr(tripPointStr string) TripPoint { tripPoint := TripPoint{} Debug.Println("DEBUG: TripPointFromStr - " + tripPointStr) errCreate := json.Unmarshal([]byte(tripPointStr), &tripPoint) if errCreate != nil { log.Println("TripPointFromStr - Invalid trip point string") log.Fatal(errCreate) } Debug.Println(tripPointStr) return tripPoint }