Add depot, attendant, jetfire, optimus, ota services with kustomize overlays

This commit is contained in:
Chris Rai
2026-01-31 15:35:07 -05:00
parent a0ec642ca1
commit 9a5cb2f547
404 changed files with 38817 additions and 16 deletions

View File

@@ -0,0 +1,843 @@
package handlers_test
import (
"encoding/json"
"fmt"
"net/http"
"testing"
"github.com/fiskerinc/cloud-services/pkg/redis"
"otaupdate/handlers"
"otaupdate/services"
m "github.com/fiskerinc/cloud-services/pkg/common"
orm "github.com/fiskerinc/cloud-services/pkg/db/queries"
mo "github.com/fiskerinc/cloud-services/pkg/db/queries/mocks"
r "github.com/fiskerinc/cloud-services/pkg/redis"
rm "github.com/fiskerinc/cloud-services/pkg/redis/tester"
th "github.com/fiskerinc/cloud-services/pkg/testhelper"
"github.com/fiskerinc/cloud-services/pkg/utils/elptr"
)
type MockCarsCounted struct {
mo.MockCars
searchCounter int
countCounter int
}
func (m *MockCarsCounted) Search(s *m.CarSearch, q *orm.PageQueryOptions) ([]m.Car, error) {
m.searchCounter++
return m.MockCars.Search(s, q)
}
func (m *MockCarsCounted) SearchCount(s *m.CarSearch) (int, error) {
m.countCounter++
return m.MockCars.SearchCount(s)
}
func TestGetVehiclesCached(t *testing.T) {
r.MockRedisConnection()
mockRedis := rm.MockRedis{
GetSetResults: "[]",
GetCommandResult: map[string]map[string]interface{}{
"SMEMBERS": {redis.CarSessionsKey(): []interface{}{}},
},
}
services.SetRedisClientPool(rm.NewMockClientPool(&mockRedis))
mock := MockCarsCounted{}
services.GetDB().SetCars(&mock)
defaultOrder := "vin"
tests := []mo.DBHttpTest{
{
Name: "Default Limit 100",
Request: th.MakeTestRequest(http.MethodGet, "http://example.com/cars", nil),
ExpectedStatus: http.StatusOK,
ExpectedResponse: longListExpectedResultGen(longListData, 0, 0),
DBTestCase: mo.DBTestCase{
ExpectedFilter: m.CarSearch{},
ExpectedPage: &orm.PageQueryOptions{
Order: defaultOrder,
Limit: 100,
Offset: 0,
},
MockListResponse: longListData[:100],
},
},
{
Name: "Cached Limit 100",
Request: th.MakeTestRequest(http.MethodGet, "http://example.com/cars", nil),
ExpectedStatus: http.StatusOK,
ExpectedResponse: longListExpectedResultGen(longListData, 0, 0),
DBTestCase: mo.DBTestCase{
ExpectedFilter: m.CarSearch{},
ExpectedPage: &orm.PageQueryOptions{
Order: defaultOrder,
Limit: 100,
Offset: 0,
},
MockListResponse: longListData[:100],
},
},
}
mo.RunDBTests(t, tests, handlers.HandleVehiclesGet, &mock)
if mock.searchCounter != 2 && mock.countCounter != 2 {
t.Errorf("Expected search and count to be called only once, got %d and %d", mock.searchCounter, mock.countCounter)
}
}
func TestGetVehicles(t *testing.T) {
r.MockRedisConnection()
mockRedis := rm.MockRedis{
GetSetResults: "[]",
GetCommandResult: map[string]map[string]interface{}{
"SMEMBERS": {redis.CarSessionsKey(): []interface{}{}},
},
}
services.SetRedisClientPool(rm.NewMockClientPool(&mockRedis))
handlers.SetVehiclesCache(&rm.MockVehiclesCache{})
mock := mo.MockCars{}
services.GetDB().SetCars(&mock)
expectedResp := `{"data":[{"vin":"3C4PDCBG0ET127145","year":2021,"model":"Ocean"}],"total":1}`
expectedRespNoTotal := `{"data":[{"vin":"3C4PDCBG0ET127145","year":2021,"model":"Ocean"}]}`
defaultOrder := "vin"
listData := []m.Car{
{
VIN: "3C4PDCBG0ET127145",
Model: "Ocean",
Year: 2021,
},
}
tests := []mo.DBHttpTest{
{
Name: "No parameters",
Request: th.MakeTestRequest(http.MethodGet, "http://example.com/cars", nil),
ExpectedStatus: http.StatusOK,
ExpectedResponse: expectedResp,
DBTestCase: mo.DBTestCase{
ExpectedFilter: m.CarSearch{},
ExpectedPage: &orm.PageQueryOptions{
Order: defaultOrder,
Limit: 100,
Offset: 0,
},
MockListResponse: listData,
},
},
{
Name: "Default Limit 100",
Request: th.MakeTestRequest(http.MethodGet, "http://example.com/cars", nil),
ExpectedStatus: http.StatusOK,
ExpectedResponse: longListExpectedResultGen(longListData, 0, 0),
DBTestCase: mo.DBTestCase{
ExpectedFilter: m.CarSearch{},
ExpectedPage: &orm.PageQueryOptions{
Order: defaultOrder,
Limit: 100,
Offset: 0,
},
MockListResponse: longListData[:100],
},
},
{
Name: "Wrong limit, -100",
Request: th.MakeTestRequest(http.MethodGet, "http://example.com/cars?limit=-100", nil),
ExpectedStatus: http.StatusBadRequest,
ExpectedResponse: `{"message":"Limit less than 0","error":"Bad Request"}`,
},
{
Name: "Wrong limit, 1000",
Request: th.MakeTestRequest(http.MethodGet, "http://example.com/cars?limit=1000", nil),
ExpectedStatus: http.StatusBadRequest,
ExpectedResponse: `{"message":"Limit greater than 100","error":"Bad Request"}`,
},
{
Name: "Invalid VIN",
Request: th.MakeTestRequest(http.MethodGet, "http://example.com/cars?vin=FISKER123", nil),
ExpectedStatus: http.StatusBadRequest,
ExpectedResponse: `{"message":"VIN 'FISKER123' invalid","error":"Bad Request"}`,
},
{
Name: "Id parameter",
Request: th.MakeTestRequest(http.MethodGet, "http://example.com/cars?vin=3C4PDCBG0ET127145", nil),
ExpectedStatus: http.StatusOK,
ExpectedResponse: expectedRespNoTotal,
DBTestCase: mo.DBTestCase{
ExpectedFilter: m.CarSearch{
Car: m.Car{
VIN: "3C4PDCBG0ET127145",
},
},
ExpectedPage: &orm.PageQueryOptions{
Order: defaultOrder,
Limit: 100,
Offset: 0,
},
MockListResponse: listData,
},
},
{
Name: "Name, version, description parameters",
Request: th.MakeTestRequest(http.MethodGet, "http://example.com/cars?model=Ocean&year=2021", nil),
ExpectedStatus: http.StatusOK,
ExpectedResponse: expectedResp,
DBTestCase: mo.DBTestCase{
ExpectedFilter: m.CarSearch{
Car: m.Car{
Model: "Ocean",
Year: 2021,
},
},
ExpectedPage: &orm.PageQueryOptions{
Order: defaultOrder,
Limit: 100,
Offset: 0,
},
MockListResponse: listData,
},
},
{
Name: "Paging parameters",
Request: th.MakeTestRequest(http.MethodGet, "http://example.com/cars?offset=10&limit=5", nil),
ExpectedStatus: http.StatusOK,
ExpectedResponse: expectedRespNoTotal,
DBTestCase: mo.DBTestCase{
ExpectedFilter: m.CarSearch{},
ExpectedPage: &orm.PageQueryOptions{
Order: defaultOrder,
Limit: 5,
Offset: 10,
},
MockListResponse: listData,
},
},
{
// TODO: since the logic is on the db layer, we can't check the online/offline test here,
// it's whether we have to have a full mock database, or we have to expect the query to be
// equal to some string.
Name: "Online",
Request: th.MakeTestRequest(http.MethodGet, "http://example.com/cars?online=true", nil),
ExpectedStatus: http.StatusOK,
ExpectedResponse: expectedResp,
DBTestCase: mo.DBTestCase{
ExpectedFilter: m.CarSearch{
Online: &m.CarOnlineFilter{
Online: elptr.ElPtr(true),
},
},
ExpectedPage: &orm.PageQueryOptions{
Order: defaultOrder,
Limit: 100,
Offset: 0,
},
MockListResponse: listData,
},
},
{
Name: "Offline",
Request: th.MakeTestRequest(http.MethodGet, "http://example.com/cars?online=false", nil),
ExpectedStatus: http.StatusOK,
ExpectedResponse: expectedResp,
DBTestCase: mo.DBTestCase{
ExpectedFilter: m.CarSearch{
Online: &m.CarOnlineFilter{
Online: elptr.ElPtr(false),
},
},
ExpectedPage: &orm.PageQueryOptions{
Order: defaultOrder,
Limit: 100,
Offset: 0,
},
MockListResponse: listData,
},
},
{
Name: "Multiple VINs",
Request: th.MakeTestRequest(http.MethodGet, "http://example.com/cars?vins=SCAZD42A3HCX11779,SCAZD42A3HCX11850", nil),
ExpectedStatus: http.StatusOK,
ExpectedResponse: `{"data":[{"vin":"SCAZD42A3HCX11779","year":2021,"model":"Ocean"},{"vin":"SCAZD42A3HCX11850","year":2021,"model":"Ocean"}],"total":2}`,
DBTestCase: mo.DBTestCase{
ExpectedFilter: m.CarSearch{
VINs: "SCAZD42A3HCX11779,SCAZD42A3HCX11850",
},
ExpectedPage: &orm.PageQueryOptions{
Order: defaultOrder,
Limit: 100,
Offset: 0,
},
MockListResponse: longListData[:2],
},
},
{
Name: "Error",
Request: th.MakeTestRequest(http.MethodGet, "http://example.com/cars", nil),
ExpectedStatus: http.StatusServiceUnavailable,
ExpectedResponse: `{"message":"something went wrong","error":"Service Unavailable"}`,
DBTestCase: mo.DBTestCase{
ExpectedFilter: m.CarSearch{},
ExpectedPage: &orm.PageQueryOptions{
Order: defaultOrder,
Limit: 100,
Offset: 0,
},
MockError: fmt.Errorf("something went wrong"),
},
},
}
mo.RunDBTests(t, tests, handlers.HandleVehiclesGet, &mock)
}
// 105 entries
var longListData []m.Car = []m.Car{
{
VIN: "SCAZD42A3HCX11779",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX11850",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX16041",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX12984",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX11576",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX15688",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17778",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX10518",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17196",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17156",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX13043",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX13784",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX19371",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX19905",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX18835",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX11056",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX16812",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX13636",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX12874",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17360",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX13373",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX11933",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX11286",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX16703",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX12358",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX15157",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17005",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX10283",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX11247",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17714",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX16219",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX16036",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX19125",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX15079",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX18843",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX14722",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX16906",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX11601",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX14453",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX11028",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17184",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX12328",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX13860",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX15042",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17519",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX10309",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX10304",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17052",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX19086",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX15606",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX19217",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX16092",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17281",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX13886",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX19772",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX15135",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17306",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX16200",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX12910",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX10944",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX10117",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX16097",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX13145",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX19594",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX10200",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX14353",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX11049",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX10682",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX14547",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX14368",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX12021",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17152",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX19291",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX11513",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX13697",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX18883",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX14454",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX16767",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX14896",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX13477",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX14916",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX13866",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17261",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX15298",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17098",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX19128",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX15130",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX10156",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX19665",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX10477",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX18530",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX18158",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX14232",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX13238",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17683",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX11460",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX11272",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX14306",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX17241",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX13865",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX12546",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX19404",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX19747",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX13450",
Model: "Ocean",
Year: 2021,
},
{
VIN: "SCAZD42A3HCX19459",
Model: "Ocean",
Year: 2021,
},
}
type fakeResponse struct {
Data []m.Car `json:"data"`
Total int `json:"total"`
}
func longListExpectedResultGen(carList []m.Car, offset, limit int) string {
max := len(carList)
if limit <= 0 {
limit = 100
}
if offset+limit < max {
max = offset + limit
}
carSubset := carList[offset:max]
fakeRes := fakeResponse{Data: carSubset, Total: len(carSubset)}
fmt.Println()
b, _ := json.Marshal(fakeRes)
return string(b)
}