package handlers_test import ( "fmt" "net/http" "otaupdate/handlers" "otaupdate/services" "testing" "github.com/fiskerinc/cloud-services/pkg/common" mo "github.com/fiskerinc/cloud-services/pkg/db/queries/mocks" "github.com/fiskerinc/cloud-services/pkg/httpclient/tester" "github.com/fiskerinc/cloud-services/pkg/redis" r "github.com/fiskerinc/cloud-services/pkg/redis" rm "github.com/fiskerinc/cloud-services/pkg/redis/tester" "github.com/fiskerinc/cloud-services/pkg/testhelper" "github.com/fiskerinc/cloud-services/pkg/testrunner" "github.com/go-pg/pg/v10" ) func TestCarUpdateVehicleCancel(t *testing.T) { r.MockRedisConnection() mockRedis := rm.MockRedis{ GetSetResults: "[]", } services.SetRedisClientPool(rm.NewMockClientPool(&mockRedis)) mock := mo.MockCarUpdates{} services.GetDB().SetCarUpdates(&mock) vin := "1G1FP87S3GN100062" mockCarUpdate := common.CarUpdate{ ID: 1000, VIN: vin, UpdateManifestID: 10, } trexKey := common.TRex.Key(vin) hmiKey := common.HMI.Key(vin) tests := []testrunner.TestCase{ { Name: "car update known to cloud", HttpTestCase: &tester.HttpTestCase{ Request: testhelper.MakeTestRequest(http.MethodPost, fmt.Sprintf("http://example.com/carupdate/1000/vehicle-cancel?vin=%s", vin), nil), ExpectedStatus: http.StatusServiceUnavailable, ExpectedResponse: `{"message":"car update was found in cloud, use /carupdate/1000/cancel","error":"Service Unavailable"}`, }, DBTestCase: &mo.DBTestCase{ MockLoadResponse: &mockCarUpdate, }, RedisTestCase: &rm.RedisTestCase{}, }, { Name: "non-numeric update id", HttpTestCase: &tester.HttpTestCase{ Request: testhelper.MakeTestRequest(http.MethodPost, fmt.Sprintf("http://example.com/carupdate/xxxx/vehicle-cancel?vin=%s", vin), nil), ExpectedStatus: http.StatusBadRequest, ExpectedResponse: `{"message":"strconv.ParseInt: parsing \"xxxx\": invalid syntax","error":"Bad Request"}`, }, DBTestCase: &mo.DBTestCase{}, RedisTestCase: &rm.RedisTestCase{}, }, { Name: "database error", HttpTestCase: &tester.HttpTestCase{ Request: testhelper.MakeTestRequest(http.MethodPost, fmt.Sprintf("http://example.com/carupdate/1000/vehicle-cancel?vin=%s", vin), nil), ExpectedStatus: http.StatusOK, ExpectedResponse: `{"message":"OK"}`, }, DBTestCase: &mo.DBTestCase{ MockError: someErr, }, RedisTestCase: &rm.RedisTestCase{ ExpectedMessages: map[string]string{ trexKey: `{"handler":"update_manifest_cancel","data":{"car_update_id":1000}}`, hmiKey: `{"handler":"update_manifest_cancel","data":{"car_update_id":1000}}`, }, ExpectedCaches: map[string]rm.ExpiringCacheResult{ redis.CarUpdateStatusHashKey(int64(1000)): { Value: `{"current_size":0,"ecu":"","errorcode":0,"file_size":0,"file_total":0,"id":1000,"installed":0,"status":"manifest_cancel_pending","total_files":0,"total_size":0}`, Expires: 3600, }, }, }, }, { Name: "redis error", HttpTestCase: &tester.HttpTestCase{ Request: testhelper.MakeTestRequest(http.MethodPost, fmt.Sprintf("http://example.com/carupdate/1000/vehicle-cancel?vin=%s", vin), nil), ExpectedStatus: http.StatusServiceUnavailable, ExpectedResponse: `{"message":"some err","error":"Service Unavailable"}`, }, DBTestCase: &mo.DBTestCase{ MockError: pg.ErrNoRows, }, RedisTestCase: &rm.RedisTestCase{ MockRedisError: someErr, }, }, { Name: "car update unknown to cloud", HttpTestCase: &tester.HttpTestCase{ Request: testhelper.MakeTestRequest(http.MethodPost, fmt.Sprintf("http://example.com/carupdate/1000/vehicle-cancel?vin=%s", vin), nil), ExpectedStatus: http.StatusOK, ExpectedResponse: `{"message":"OK"}`, }, DBTestCase: &mo.DBTestCase{ MockError: pg.ErrNoRows, }, RedisTestCase: &rm.RedisTestCase{ ExpectedMessages: map[string]string{ trexKey: `{"handler":"update_manifest_cancel","data":{"car_update_id":1000}}`, hmiKey: `{"handler":"update_manifest_cancel","data":{"car_update_id":1000}}`, }, ExpectedCaches: map[string]rm.ExpiringCacheResult{ redis.CarUpdateStatusHashKey(int64(1000)): { Value: `{"current_size":0,"ecu":"","errorcode":0,"file_size":0,"file_total":0,"id":1000,"installed":0,"status":"manifest_cancel_pending","total_files":0,"total_size":0}`, Expires: 3600, }, }, }, }, } schemaTesterTRex := testhelper.NewSchemaTestHelper(t, schemaToTRex) for _, test := range tests { mockRedis.Reset() if test.RedisTestCase != nil { test.RedisTestCase.SetupRedis(&mockRedis) } if test.DBTestCase != nil { test.DBTestCase.SetupDB(&mock) } if test.HttpTestCase != nil { w := test.HttpTestCase.TestWithParamPath(handlers.HandleCarUpdateVehicleCancel, "/carupdate/:id/vehicle-cancel") test.HttpTestCase.ValidateHttp(t, test.Name, w) } if test.DBTestCase != nil { test.DBTestCase.Validate(t, test.Name, &mock) } if test.RedisTestCase != nil { test.RedisTestCase.Validate(t, test.Name, &mockRedis) for _, mes := range test.RedisTestCase.ExpectedMessages { schemaTesterTRex.ValidateSchemaObject(test.Name, []byte(mes)) } } } }