package handlers_test import ( "net/http" "otaupdate/handlers" "otaupdate/services" "testing" "github.com/fiskerinc/cloud-services/pkg/common" "github.com/fiskerinc/cloud-services/pkg/common/carupdatestatus" 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" 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 TestCarUpdateDeploy(t *testing.T) { redis.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, Status: carupdatestatus.ManifestSucceeded, } trexKey := common.TRex.Key(vin) hmiKey := common.HMI.Key(vin) tests := []testrunner.TestCase{ { Name: "invalid update id", HttpTestCase: &tester.HttpTestCase{ Request: testhelper.MakeTestRequest(http.MethodPost, "http://example.com/carupdate/1000/deploy", nil), ExpectedStatus: http.StatusNotFound, ExpectedResponse: `{"message":"pg: no rows in result set","error":"Not Found"}`, }, DBTestCase: &mo.DBTestCase{ MockError: pg.ErrNoRows, }, RedisTestCase: &rm.RedisTestCase{}, }, { Name: "non-numeric update id", HttpTestCase: &tester.HttpTestCase{ Request: testhelper.MakeTestRequest(http.MethodPost, "http://example.com/carupdate/xxxx/deploy", 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, "http://example.com/carupdate/1000/deploy", nil), ExpectedStatus: http.StatusServiceUnavailable, ExpectedResponse: `{"message":"some err","error":"Service Unavailable"}`, }, DBTestCase: &mo.DBTestCase{ MockError: someErr, }, }, { Name: "redis error", HttpTestCase: &tester.HttpTestCase{ Request: testhelper.MakeTestRequest(http.MethodPost, "http://example.com/carupdate/1000/deploy", nil), ExpectedStatus: http.StatusServiceUnavailable, ExpectedResponse: `{"message":"some err","error":"Service Unavailable"}`, }, DBTestCase: &mo.DBTestCase{ MockLoadResponse: &mockCarUpdate, }, RedisTestCase: &rm.RedisTestCase{ MockRedisError: someErr, }, }, { Name: "invalid status", HttpTestCase: &tester.HttpTestCase{ Request: testhelper.MakeTestRequest(http.MethodPost, "http://example.com/carupdate/1000/deploy", nil), ExpectedStatus: http.StatusUnprocessableEntity, ExpectedResponse: `{"message":"Unable to redeploy, CarUpdate is currently pending"}`, }, DBTestCase: &mo.DBTestCase{ MockLoadResponse: &common.CarUpdate{ ID: 1000, VIN: vin, UpdateManifestID: 10, Status: carupdatestatus.Pending, }, }, }, { Name: "good request", HttpTestCase: &tester.HttpTestCase{ Request: testhelper.MakeTestRequest(http.MethodPost, "http://example.com/carupdate/1000/deploy", nil), ExpectedStatus: http.StatusOK, ExpectedResponse: `{"message":"OK"}`, }, DBTestCase: &mo.DBTestCase{ MockLoadResponse: &mockCarUpdate, }, RedisTestCase: &rm.RedisTestCase{ ExpectedMessages: map[string]string{ trexKey: `{"handler":"update_manifest_install","data":{"car_update_id":1000}}`, hmiKey: `{"handler":"update_manifest_install","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":"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.HandleCarUpdateDeploy, "/carupdate/:id/deploy") 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)) } } } }