Refactor code structure and remove redundant sections for improved readability and maintainability
All checks were successful
Golan Testing / testing (1.24.x, ubuntu-latest) (push) Successful in 26s
All checks were successful
Golan Testing / testing (1.24.x, ubuntu-latest) (push) Successful in 26s
This commit is contained in:
43
README.md
43
README.md
@ -20,16 +20,47 @@ The following samples will assist you to become as comfortable as possible with
|
|||||||
import "git.savin.nyc/alex/mysubaru"
|
import "git.savin.nyc/alex/mysubaru"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Create a new MySubaru connection and get a car by VIN
|
#### Create a new MySubaru API Client
|
||||||
```go
|
```go
|
||||||
// Create a MySubaru Client
|
// Create a MySubaru Client
|
||||||
mysubaru, _ := New()
|
msc, err := mysubaru.New(cfg)
|
||||||
outback := mysubaru.GetVehicleByVIN("VIN-CODE-HERE")
|
if err != nil {
|
||||||
|
cfg.Logger.Error("cannot create MySubaru client", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Get a car by VIN
|
||||||
|
```go
|
||||||
|
outback, err := msc.GetVehicleByVIN("1HGCM82633A004352")
|
||||||
|
if err != nil {
|
||||||
|
cfg.Logger.Error("cannot get a vehicle by VIN", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Start/Stop Lights request
|
#### Start/Stop Lights request
|
||||||
```go
|
```go
|
||||||
outback.LightsStart()
|
// Execute a LightsStart command
|
||||||
time.Sleep(30 * time.Second)
|
events, err := outback.LightsStart()
|
||||||
outback.LightsStop()
|
if err != nil {
|
||||||
|
cfg.Logger.Error("cannot execute LightsStart command", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
for event := range events {
|
||||||
|
fmt.Printf("Lights Start Event: %+v\n", event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for a while to see the lights on
|
||||||
|
time.Sleep(20 * time.Second)
|
||||||
|
|
||||||
|
// Execute a LightsStop command
|
||||||
|
events, err = outback.LightsStop()
|
||||||
|
if err != nil {
|
||||||
|
cfg.Logger.Error("cannot execute LightsStop command", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
for event := range events {
|
||||||
|
fmt.Printf("Lights Stop Event: %+v\n", event)
|
||||||
|
}
|
||||||
```
|
```
|
32
client.go
32
client.go
@ -83,7 +83,7 @@ func New(config *config.Config) (*Client, error) {
|
|||||||
}
|
}
|
||||||
client.currentVin = client.listOfVins[0]
|
client.currentVin = client.listOfVins[0]
|
||||||
} else {
|
} else {
|
||||||
client.logger.Error("there no cars assigned to the account")
|
client.logger.Error("there are no cars assigned to the account")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return client, nil
|
return client, nil
|
||||||
@ -94,19 +94,21 @@ func (c *Client) SelectVehicle(vin string) (*VehicleData, error) {
|
|||||||
if vin == "" {
|
if vin == "" {
|
||||||
vin = c.currentVin
|
vin = c.currentVin
|
||||||
}
|
}
|
||||||
|
|
||||||
vinCheck(vin)
|
vinCheck(vin)
|
||||||
|
|
||||||
params := map[string]string{
|
params := map[string]string{
|
||||||
"vin": vin,
|
"vin": vin,
|
||||||
"_": timestamp()}
|
"_": timestamp()}
|
||||||
reqURL := MOBILE_API_VERSION + apiURLs["API_SELECT_VEHICLE"]
|
reqURL := MOBILE_API_VERSION + apiURLs["API_SELECT_VEHICLE"]
|
||||||
// TODO: Add error handling
|
resp, err := c.execute(GET, reqURL, params, false)
|
||||||
resp, _ := c.execute(GET, reqURL, params, false)
|
if err != nil {
|
||||||
|
c.logger.Error("error while executing SelectVehicle request", "request", "SelectVehicle", "error", err.Error())
|
||||||
|
return nil, errors.New("error while executing SelectVehicle request: " + err.Error())
|
||||||
|
}
|
||||||
// c.logger.Debug("http request output", "request", "SelectVehicle", "body", resp)
|
// c.logger.Debug("http request output", "request", "SelectVehicle", "body", resp)
|
||||||
|
|
||||||
var vd VehicleData
|
var vd VehicleData
|
||||||
err := json.Unmarshal(resp.Data, &vd)
|
err = json.Unmarshal(resp.Data, &vd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Error("error while parsing json", "request", "SelectVehicle", "error", err.Error())
|
c.logger.Error("error while parsing json", "request", "SelectVehicle", "error", err.Error())
|
||||||
return nil, errors.New("error while parsing json while vehicle selection")
|
return nil, errors.New("error while parsing json while vehicle selection")
|
||||||
@ -116,32 +118,36 @@ func (c *Client) SelectVehicle(vin string) (*VehicleData, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetVehicles .
|
// GetVehicles .
|
||||||
func (c *Client) GetVehicles() []*Vehicle {
|
func (c *Client) GetVehicles() ([]*Vehicle, error) {
|
||||||
var vehicles []*Vehicle
|
var vehicles []*Vehicle
|
||||||
for _, vin := range c.listOfVins {
|
for _, vin := range c.listOfVins {
|
||||||
vehicle, err := c.GetVehicleByVIN(vin)
|
vehicle, err := c.GetVehicleByVin(vin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Error("cannot get vehile data", "request", "SelectVehicle", "error", err.Error())
|
c.logger.Error("cannot get vehicle data", "request", "GetVehicles", "error", err.Error())
|
||||||
|
return nil, errors.New("cannot get vehicle data: " + err.Error())
|
||||||
}
|
}
|
||||||
vehicles = append(vehicles, vehicle)
|
vehicles = append(vehicles, vehicle)
|
||||||
}
|
}
|
||||||
return vehicles
|
return vehicles, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVehicleByVIN .
|
// GetVehicleByVIN .
|
||||||
func (c *Client) GetVehicleByVIN(vin string) (*Vehicle, error) {
|
func (c *Client) GetVehicleByVin(vin string) (*Vehicle, error) {
|
||||||
var vehicle *Vehicle
|
var vehicle *Vehicle
|
||||||
if slices.Contains(c.listOfVins, vin) {
|
if slices.Contains(c.listOfVins, vin) {
|
||||||
params := map[string]string{
|
params := map[string]string{
|
||||||
"vin": vin,
|
"vin": vin,
|
||||||
"_": timestamp()}
|
"_": timestamp()}
|
||||||
reqURL := MOBILE_API_VERSION + apiURLs["API_SELECT_VEHICLE"]
|
reqURL := MOBILE_API_VERSION + apiURLs["API_SELECT_VEHICLE"]
|
||||||
// TODO: Add error handling
|
resp, err := c.execute(GET, reqURL, params, false)
|
||||||
resp, _ := c.execute(GET, reqURL, params, false)
|
if err != nil {
|
||||||
|
c.logger.Error("error while executing GetVehicleByVIN request", "request", "GetVehicleByVIN", "error", err.Error())
|
||||||
|
return nil, errors.New("error while executing GetVehicleByVIN request: " + err.Error())
|
||||||
|
}
|
||||||
// c.logger.Debug("http request output", "request", "GetVehicleByVIN", "body", resp)
|
// c.logger.Debug("http request output", "request", "GetVehicleByVIN", "body", resp)
|
||||||
|
|
||||||
var vd VehicleData
|
var vd VehicleData
|
||||||
err := json.Unmarshal(resp.Data, &vd)
|
err = json.Unmarshal(resp.Data, &vd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Error("error while parsing json", "request", "GetVehicleByVIN", "error", err.Error())
|
c.logger.Error("error while parsing json", "request", "GetVehicleByVIN", "error", err.Error())
|
||||||
}
|
}
|
||||||
|
328
client_test.go
Normal file
328
client_test.go
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
package mysubaru
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.savin.nyc/alex/mysubaru/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func makeConfig(t *testing.T) *config.Config {
|
||||||
|
return &config.Config{
|
||||||
|
MySubaru: config.MySubaru{
|
||||||
|
Credentials: config.Credentials{
|
||||||
|
Username: "user",
|
||||||
|
Password: "pass",
|
||||||
|
DeviceID: "dev123",
|
||||||
|
DeviceName: "devname",
|
||||||
|
},
|
||||||
|
Region: "TEST",
|
||||||
|
AutoReconnect: true,
|
||||||
|
},
|
||||||
|
TimeZone: "America/New_York",
|
||||||
|
// Logger: slogt.New(t),
|
||||||
|
Logger: slog.New(slog.NewTextHandler(nil, nil)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mockMySubaruApi(t *testing.T, handler http.HandlerFunc) *httptest.Server {
|
||||||
|
|
||||||
|
// Create a listener with the desired port
|
||||||
|
l, err := net.Listen("tcp", "127.0.0.1:56765")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create listener: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ts := httptest.NewUnstartedServer(handler)
|
||||||
|
// http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// // Handle API_LOGIN endpoint
|
||||||
|
// if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_LOGIN"] && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"success":true,"errorCode":"BIOMETRICS_DISABLED","dataName":"sessionData","data":{"sessionChanged":false,"vehicleInactivated":false,"account":{"marketId":1,"createdDate":1476984644000,"firstName":"Tatiana","lastName":"Savin","zipCode":"07974","accountKey":765268,"lastLoginDate":1751738613000,"zipCode5":"07974"},"resetPassword":false,"deviceId":"JddMBQXvAkgutSmEP6uFsThbq4QgEBBQ","sessionId":"9D7FCDF274794346689D3FA0D693CBBF","deviceRegistered":true,"passwordToken":null,"vehicles":[{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":null,"modelCode":null,"engineSize":null,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"","licensePlateState":"","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":null,"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":null,"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":null,"authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":null,"subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":null,"sunsetUpgraded":true,"intDescrip":null,"transCode":null,"provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}],"rightToRepairEnabled":true,"rightToRepairStartYear":2022,"rightToRepairStates":"MA","enableXtime":true,"termsAndConditionsAccepted":true,"digitalGlobeConnectId":"0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeImageTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/DigitalGlobe:ImageryTileService@EPSG:3857@png/{z}/{x}/{y}.png?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeTransparentTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/Digitalglobe:OSMTransparentTMSTileService@EPSG:3857@png/{z}/{x}/{-y}.png/?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","tomtomKey":"DHH9SwEQ4MW55Hj2TfqMeldbsDjTdgAs","currentVehicleIndex":0,"handoffToken":"$2a$08$rOb/uqhm8I3QtSel2phOCOxNM51w43eqXDDksMkJ.1a5KsaQuLvEu$1751745334477","satelliteViewEnabled":true,"registeredDevicePermanent":true}}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_VALIDATE_SESSION endpoint
|
||||||
|
// if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_VALIDATE_SESSION"] && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"success":true,"data":{"vhsId":14662115789,"odometerValue":31694,"odometerValueKilometers":50996,"eventDate":1751742945000,"eventDateStr":"2025-07-05T19:15+0000","eventDateCarUser":1751742945000,"eventDateStrCarUser":"2025-07-05T19:15+0000","latitude":40.700153,"longitude":-74.401405,"positionHeadingDegree":"154","tirePressureFrontLeft":"2482","tirePressureFrontRight":"2482","tirePressureRearLeft":"2413","tirePressureRearRight":"2482","tirePressureFrontLeftPsi":"36","tirePressureFrontRightPsi":"36","tirePressureRearLeftPsi":"35","tirePressureRearRightPsi":"36","doorBootPosition":"CLOSED","doorEngineHoodPosition":"CLOSED","doorFrontLeftPosition":"CLOSED","doorFrontRightPosition":"CLOSED","doorRearLeftPosition":"CLOSED","doorRearRightPosition":"CLOSED","doorBootLockStatus":"LOCKED","doorFrontLeftLockStatus":"LOCKED","doorFrontRightLockStatus":"LOCKED","doorRearLeftLockStatus":"LOCKED","doorRearRightLockStatus":"LOCKED","distanceToEmptyFuelMiles":259.73,"distanceToEmptyFuelKilometers":418,"avgFuelConsumptionMpg":102.2,"avgFuelConsumptionLitersPer100Kilometers":2.3,"evStateOfChargePercent":null,"evDistanceToEmptyMiles":null,"evDistanceToEmptyKilometers":null,"evDistanceToEmptyByStateMiles":null,"evDistanceToEmptyByStateKilometers":null,"vehicleStateType":"IGNITION_OFF","windowFrontLeftStatus":"CLOSE","windowFrontRightStatus":"CLOSE","windowRearLeftStatus":"CLOSE","windowRearRightStatus":"CLOSE","windowSunroofStatus":"CLOSE","tyreStatusFrontLeft":"UNKNOWN","tyreStatusFrontRight":"UNKNOWN","tyreStatusRearLeft":"UNKNOWN","tyreStatusRearRight":"UNKNOWN","remainingFuelPercent":90,"distanceToEmptyFuelMiles10s":260,"distanceToEmptyFuelKilometers10s":420}}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_LOCATE endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_LOCATE"], "g1") || r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_LOCATE"], "g2")) && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"id": 1, "name": "John Doe"}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_LOCK endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_LOCK"], "g1") || r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_LOCK"], "g2")) && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"remoteServiceStatus","data":{"serviceRequestId":"1HGCM82633A004352_1751747301812_20_@NGTP","success":false,"cancelled":false,"remoteServiceType":"lock","remoteServiceState":"started","subState":null,"errorCode":null,"result":null,"updateTime":null,"vin":"1HGCM82633A004352","errorDescription":null}}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_LOCK_CANCEL endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_LOCK_CANCEL"], "g1") || r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_LOCK_CANCEL"], "g2")) && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"id": 1, "name": "John Doe"}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_UNLOCK endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_UNLOCK"], "g1") || r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_UNLOCK"], "g2")) && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"remoteServiceStatus","data":{"serviceRequestId":"1HGCM82633A004352_1751747271262_19_@NGTP","success":false,"cancelled":false,"remoteServiceType":"unlock","remoteServiceState":"started","subState":null,"errorCode":null,"result":null,"updateTime":null,"vin":"1HGCM82633A004352","errorDescription":null}}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_UNLOCK_CANCEL endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_UNLOCK_CANCEL"], "g1") || r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_UNLOCK_CANCEL"], "g2")) && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"id": 1, "name": "John Doe"}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_HORN_LIGHTS endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_HORN_LIGHTS"], "g1") || r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_HORN_LIGHTS"], "g2")) && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"remoteServiceStatus","data":{"serviceRequestId":"1HGCM82633A004352_1751746568969_47_@NGTP","success":true,"cancelled":false,"remoteServiceType":"hornLights","remoteServiceState":"started","subState":null,"errorCode":null,"result":null,"updateTime":1751746569000,"vin":"1HGCM82633A004352","errorDescription":null}}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_HORN_LIGHTS_CANCEL endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_HORN_LIGHTS_CANCEL"], "g1") || r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_HORN_LIGHTS_CANCEL"], "g2")) && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"remoteServiceStatus","data":{"serviceRequestId":"1HGCM82633A004352_1751746568969_47_@NGTP","success":true,"cancelled":false,"remoteServiceType":"hornLights","remoteServiceState":"cancelling","subState":null,"errorCode":null,"result":null,"updateTime":1751746569000,"vin":"1HGCM82633A004352","errorDescription":null}}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_HORN_LIGHTS_STOP endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_HORN_LIGHTS_STOP"], "g1") || r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_HORN_LIGHTS_STOP"], "g2")) && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"remoteServiceStatus","data":{"serviceRequestId":"1HGCM82633A004352_1751746568969_47_@NGTP","success":true,"cancelled":false,"remoteServiceType":"hornLights","remoteServiceState":"stopping","subState":null,"errorCode":null,"result":null,"updateTime":1751746569000,"vin":"1HGCM82633A004352","errorDescription":null}}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_LIGHTS endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_LIGHTS"], "g1") || r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_LIGHTS"], "g2")) && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"remoteServiceStatus","data":{"serviceRequestId":"1HGCM82633A004352_1751746568969_47_@NGTP","success":true,"cancelled":false,"remoteServiceType":"lightsOnly","remoteServiceState":"started","subState":null,"errorCode":null,"result":null,"updateTime":1751746569000,"vin":"1HGCM82633A004352","errorDescription":null}}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_LIGHTS_CANCEL endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_LIGHTS_CANCEL"], "g1") || r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_LIGHTS_CANCEL"], "g2")) && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"remoteServiceStatus","data":{"serviceRequestId":"1HGCM82633A004352_1751746568969_47_@NGTP","success":true,"cancelled":false,"remoteServiceType":"lightsOnly","remoteServiceState":"stopping","subState":null,"errorCode":null,"result":null,"updateTime":1751746569000,"vin":"1HGCM82633A004352","errorDescription":null}}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_LIGHTS_STOP endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_LIGHTS_STOP"], "g1") || r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_LIGHTS_STOP"], "g2")) && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"remoteServiceStatus","data":{"serviceRequestId":"1HGCM82633A004352_1751746568969_47_@NGTP","success":true,"cancelled":false,"remoteServiceType":"lightsOnly","remoteServiceState":"finished","subState":null,"errorCode":null,"result":null,"updateTime":1751746569000,"vin":"1HGCM82633A004352","errorDescription":null}}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_G2_REMOTE_ENGINE_START endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+apiURLs["API_G2_REMOTE_ENGINE_START"]) && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"id": 1, "name": "John Doe"}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_G2_REMOTE_ENGINE_START_CANCEL endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+apiURLs["API_G2_REMOTE_ENGINE_START_CANCEL"]) && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// fmt.Fprint(w, `{"id": 1, "name": "John Doe"}`)
|
||||||
|
// }
|
||||||
|
// // Handle API_G2_REMOTE_ENGINE_STOP endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+apiURLs["API_G2_REMOTE_ENGINE_STOP"]) && r.Method == http.MethodPost {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// json.NewEncoder(w).Encode(
|
||||||
|
// Response{
|
||||||
|
// Success: true,
|
||||||
|
// DataName: "remoteServiceStatus",
|
||||||
|
// Data: []byte(`{"serviceRequestId":"1HGCM82633A004352_1751745367457_47_@NGTP","success":true,"cancelled":false,"remoteServiceType":"lightsOnly","remoteServiceState":"started","subState":null,"errorCode":null,"result":null,"updateTime":1751745367000,"vin":"1HGCM82633A004352","errorDescription":null}`),
|
||||||
|
// },
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// // Handle API_REMOTE_SVC_STATUS endpoint
|
||||||
|
// if (r.URL.Path == MOBILE_API_VERSION+apiURLs["API_REMOTE_SVC_STATUS"]) && r.Method == http.MethodGet {
|
||||||
|
// w.Header().Set("Content-Type", "application/json")
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// json.NewEncoder(w).Encode(
|
||||||
|
// Response{
|
||||||
|
// Success: true,
|
||||||
|
// DataName: "remoteServiceStatus",
|
||||||
|
// Data: []byte(`{"remoteServiceState":"finished"}`),
|
||||||
|
// },
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Close the default listener created by NewUnstartedServer and replace it
|
||||||
|
// with our custom listener.
|
||||||
|
ts.Listener.Close()
|
||||||
|
ts.Listener = l
|
||||||
|
|
||||||
|
return ts
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNew_Success(t *testing.T) {
|
||||||
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Handle API_LOGIN endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_LOGIN"] && r.Method == http.MethodPost {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":"BIOMETRICS_DISABLED","dataName":"sessionData","data":{"sessionChanged":false,"vehicleInactivated":false,"account":{"marketId":1,"createdDate":1476984644000,"firstName":"Tatiana","lastName":"Savin","zipCode":"07974","accountKey":765268,"lastLoginDate":1751738613000,"zipCode5":"07974"},"resetPassword":false,"deviceId":"JddMBQXvAkgutSmEP6uFsThbq4QgEBBQ","sessionId":"9D7FCDF274794346689D3FA0D693CBBF","deviceRegistered":true,"passwordToken":null,"vehicles":[{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":null,"modelCode":null,"engineSize":null,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"","licensePlateState":"","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":null,"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":null,"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":null,"authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":null,"subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":null,"sunsetUpgraded":true,"intDescrip":null,"transCode":null,"provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}],"rightToRepairEnabled":true,"rightToRepairStartYear":2022,"rightToRepairStates":"MA","enableXtime":true,"termsAndConditionsAccepted":true,"digitalGlobeConnectId":"0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeImageTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/DigitalGlobe:ImageryTileService@EPSG:3857@png/{z}/{x}/{y}.png?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeTransparentTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/Digitalglobe:OSMTransparentTMSTileService@EPSG:3857@png/{z}/{x}/{-y}.png/?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","tomtomKey":"DHH9SwEQ4MW55Hj2TfqMeldbsDjTdgAs","currentVehicleIndex":0,"handoffToken":"$2a$08$rOb/uqhm8I3QtSel2phOCOxNM51w43eqXDDksMkJ.1a5KsaQuLvEu$1751745334477","satelliteViewEnabled":true,"registeredDevicePermanent":true}}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ts := mockMySubaruApi(t, handler)
|
||||||
|
ts.Start()
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
cfg := makeConfig(t)
|
||||||
|
|
||||||
|
msc, err := New(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
if msc == nil {
|
||||||
|
t.Fatalf("expected MySubaru API client, got nil")
|
||||||
|
}
|
||||||
|
if !msc.isAuthenticated || !msc.isRegistered {
|
||||||
|
t.Errorf("expected authenticated and registered true, got %v %v", msc.isAuthenticated, msc.isRegistered)
|
||||||
|
}
|
||||||
|
if msc.currentVin != "1HGCM82633A004352" {
|
||||||
|
t.Errorf("expected currentVin 1HGCM82633A004352, got %v", msc.currentVin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// func TestNew_Failure(t *testing.T) {
|
||||||
|
// ts := mockMySubaruApi(t)
|
||||||
|
// ts.Start()
|
||||||
|
// defer ts.Close() // Ensure the server is closed after the test
|
||||||
|
|
||||||
|
// cfg := makeConfig(t)
|
||||||
|
// cfg.MySubaru.Credentials.Username = "" // Invalid username
|
||||||
|
|
||||||
|
// client, err := New(cfg)
|
||||||
|
// if err == nil {
|
||||||
|
// t.Fatalf("expected error, got nil")
|
||||||
|
// }
|
||||||
|
// if client != nil {
|
||||||
|
// t.Fatalf("expected nil client, got %v", client)
|
||||||
|
// }
|
||||||
|
// if client.isAuthenticated || client.isRegistered {
|
||||||
|
// t.Errorf("expected authenticated and registered false, got %v %v", client.isAuthenticated, client.isRegistered)
|
||||||
|
// }
|
||||||
|
// if client.currentVin != "" {
|
||||||
|
// t.Errorf("expected currentVin empty, got %v", client.currentVin)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
func TestSelectVehicle_Success(t *testing.T) {
|
||||||
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Handle API_LOGIN endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_LOGIN"] && r.Method == http.MethodPost {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":"BIOMETRICS_DISABLED","dataName":"sessionData","data":{"sessionChanged":false,"vehicleInactivated":false,"account":{"marketId":1,"createdDate":1476984644000,"firstName":"Tatiana","lastName":"Savin","zipCode":"07974","accountKey":765268,"lastLoginDate":1751738613000,"zipCode5":"07974"},"resetPassword":false,"deviceId":"JddMBQXvAkgutSmEP6uFsThbq4QgEBBQ","sessionId":"9D7FCDF274794346689D3FA0D693CBBF","deviceRegistered":true,"passwordToken":null,"vehicles":[{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":null,"modelCode":null,"engineSize":null,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"","licensePlateState":"","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":null,"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":null,"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":null,"authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":null,"subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":null,"sunsetUpgraded":true,"intDescrip":null,"transCode":null,"provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}],"rightToRepairEnabled":true,"rightToRepairStartYear":2022,"rightToRepairStates":"MA","enableXtime":true,"termsAndConditionsAccepted":true,"digitalGlobeConnectId":"0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeImageTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/DigitalGlobe:ImageryTileService@EPSG:3857@png/{z}/{x}/{y}.png?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeTransparentTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/Digitalglobe:OSMTransparentTMSTileService@EPSG:3857@png/{z}/{x}/{-y}.png/?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","tomtomKey":"DHH9SwEQ4MW55Hj2TfqMeldbsDjTdgAs","currentVehicleIndex":0,"handoffToken":"$2a$08$rOb/uqhm8I3QtSel2phOCOxNM51w43eqXDDksMkJ.1a5KsaQuLvEu$1751745334477","satelliteViewEnabled":true,"registeredDevicePermanent":true}}`)
|
||||||
|
}
|
||||||
|
// Handle SELECT_VEHICLE endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_SELECT_VEHICLE"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"vehicle","data":{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":"2023","modelCode":"PDL","engineSize":2.4,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"8KV8","licensePlateState":"NJ","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":["REMOTE","SAFETY","Retail3"],"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":["ABS_MIL","ACCS","AHBL_MIL","ATF_MIL","AWD_MIL","BSD","BSDRCT_MIL","CEL_MIL","CP1_5HHU","EBD_MIL","EOL_MIL","EPAS_MIL","EPB_MIL","ESS_MIL","EYESIGHT","ISS_MIL","MOONSTAT","OPL_MIL","PANPM-TUIRWAOC","PWAAADWWAP","RAB_MIL","RCC","REARBRK","RES","RESCC","RES_HVAC_HFS","RES_HVAC_VFS","RHSF","RPOI","RPOIA","RTGU","RVFS","SRH_MIL","SRS_MIL","SXM360L","T23DCM","TEL_MIL","TIF_35","TIR_33","TLD","TPMS_MIL","VALET","VDC_MIL","WASH_MIL","WDWSTAT","g3"],"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":"ACTIVE","authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":"Outback","subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":"Cosmic Blue Pearl","sunsetUpgraded":true,"intDescrip":"Black","transCode":"CVT","provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ts := mockMySubaruApi(t, handler)
|
||||||
|
ts.Start()
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
cfg := makeConfig(t)
|
||||||
|
|
||||||
|
msc, err := New(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle, err := msc.SelectVehicle("1HGCM82633A004352")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
if vehicle == nil {
|
||||||
|
t.Fatalf("expected vehicle, got nil")
|
||||||
|
}
|
||||||
|
if vehicle.Vin != "1HGCM82633A004352" {
|
||||||
|
t.Errorf("expected vehicle VIN 1HGCM82633A004352, got %v", vehicle.Vin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetVehicleByVin_Success(t *testing.T) {
|
||||||
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Handle API_LOGIN endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_LOGIN"] && r.Method == http.MethodPost {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":"BIOMETRICS_DISABLED","dataName":"sessionData","data":{"sessionChanged":false,"vehicleInactivated":false,"account":{"marketId":1,"createdDate":1476984644000,"firstName":"Tatiana","lastName":"Savin","zipCode":"07974","accountKey":765268,"lastLoginDate":1751738613000,"zipCode5":"07974"},"resetPassword":false,"deviceId":"JddMBQXvAkgutSmEP6uFsThbq4QgEBBQ","sessionId":"9D7FCDF274794346689D3FA0D693CBBF","deviceRegistered":true,"passwordToken":null,"vehicles":[{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":null,"modelCode":null,"engineSize":null,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"","licensePlateState":"","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":null,"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":null,"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":null,"authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":null,"subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":null,"sunsetUpgraded":true,"intDescrip":null,"transCode":null,"provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}],"rightToRepairEnabled":true,"rightToRepairStartYear":2022,"rightToRepairStates":"MA","enableXtime":true,"termsAndConditionsAccepted":true,"digitalGlobeConnectId":"0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeImageTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/DigitalGlobe:ImageryTileService@EPSG:3857@png/{z}/{x}/{y}.png?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeTransparentTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/Digitalglobe:OSMTransparentTMSTileService@EPSG:3857@png/{z}/{x}/{-y}.png/?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","tomtomKey":"DHH9SwEQ4MW55Hj2TfqMeldbsDjTdgAs","currentVehicleIndex":0,"handoffToken":"$2a$08$rOb/uqhm8I3QtSel2phOCOxNM51w43eqXDDksMkJ.1a5KsaQuLvEu$1751745334477","satelliteViewEnabled":true,"registeredDevicePermanent":true}}`)
|
||||||
|
}
|
||||||
|
// Handle SELECT_VEHICLE endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_SELECT_VEHICLE"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"vehicle","data":{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":"2023","modelCode":"PDL","engineSize":2.4,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"8KV8","licensePlateState":"NJ","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":["REMOTE","SAFETY","Retail3"],"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":["ABS_MIL","ACCS","AHBL_MIL","ATF_MIL","AWD_MIL","BSD","BSDRCT_MIL","CEL_MIL","CP1_5HHU","EBD_MIL","EOL_MIL","EPAS_MIL","EPB_MIL","ESS_MIL","EYESIGHT","ISS_MIL","MOONSTAT","OPL_MIL","PANPM-TUIRWAOC","PWAAADWWAP","RAB_MIL","RCC","REARBRK","RES","RESCC","RES_HVAC_HFS","RES_HVAC_VFS","RHSF","RPOI","RPOIA","RTGU","RVFS","SRH_MIL","SRS_MIL","SXM360L","T23DCM","TEL_MIL","TIF_35","TIR_33","TLD","TPMS_MIL","VALET","VDC_MIL","WASH_MIL","WDWSTAT","g3"],"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":"ACTIVE","authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":"Outback","subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":"Cosmic Blue Pearl","sunsetUpgraded":true,"intDescrip":"Black","transCode":"CVT","provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}}`)
|
||||||
|
}
|
||||||
|
// Handle API_VEHICLE_HEALTH endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_VEHICLE_HEALTH"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":null,"data":{"lastUpdatedDate":1751742945000,"vehicleHealthItems":[{"warningCode":10,"b2cCode":"airbag","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"SRS_MIL"},{"warningCode":4,"b2cCode":"oilTemp","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"ATF_MIL"},{"warningCode":39,"b2cCode":"blindspot","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"BSDRCT_MIL"},{"warningCode":2,"b2cCode":"engineFail","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"CEL_MIL"},{"warningCode":44,"b2cCode":"pkgBrake","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"EPB_MIL"},{"warningCode":8,"b2cCode":"ebd","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"EBD_MIL"},{"warningCode":3,"b2cCode":"oilWarning","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"EOL_MIL"},{"warningCode":1,"b2cCode":"washer","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"WASH_MIL"},{"warningCode":50,"b2cCode":"iss","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"ISS_MIL"},{"warningCode":53,"b2cCode":"oilPres","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"OPL_MIL"},{"warningCode":11,"b2cCode":"epas","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"EPAS_MIL"},{"warningCode":69,"b2cCode":"revBrake","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"RAB_MIL"},{"warningCode":14,"b2cCode":"telematics","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"TEL_MIL"},{"warningCode":9,"b2cCode":"tpms","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"TPMS_MIL"},{"warningCode":7,"b2cCode":"vdc","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"VDC_MIL"},{"warningCode":6,"b2cCode":"abs","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"ABS_MIL"},{"warningCode":5,"b2cCode":"awd","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"AWD_MIL"},{"warningCode":12,"b2cCode":"eyesight","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"ESS_MIL"},{"warningCode":30,"b2cCode":"ahbl","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"AHBL_MIL"},{"warningCode":31,"b2cCode":"srh","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"SRH_MIL"}]}}`)
|
||||||
|
}
|
||||||
|
// Handle API_VEHICLE_STATUS endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_VEHICLE_STATUS"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":null,"data":{"vhsId":14662115789,"odometerValue":31694,"odometerValueKilometers":50996,"eventDate":1751742945000,"eventDateStr":"2025-07-05T19:15+0000","eventDateCarUser":1751742945000,"eventDateStrCarUser":"2025-07-05T19:15+0000","latitude":40.700153,"longitude":-74.401405,"positionHeadingDegree":"154","tirePressureFrontLeft":"2482","tirePressureFrontRight":"2482","tirePressureRearLeft":"2413","tirePressureRearRight":"2482","tirePressureFrontLeftPsi":"36","tirePressureFrontRightPsi":"36","tirePressureRearLeftPsi":"35","tirePressureRearRightPsi":"36","doorBootPosition":"CLOSED","doorEngineHoodPosition":"CLOSED","doorFrontLeftPosition":"CLOSED","doorFrontRightPosition":"CLOSED","doorRearLeftPosition":"CLOSED","doorRearRightPosition":"CLOSED","doorBootLockStatus":"LOCKED","doorFrontLeftLockStatus":"LOCKED","doorFrontRightLockStatus":"LOCKED","doorRearLeftLockStatus":"LOCKED","doorRearRightLockStatus":"LOCKED","distanceToEmptyFuelMiles":259.73,"distanceToEmptyFuelKilometers":418,"avgFuelConsumptionMpg":102.2,"avgFuelConsumptionLitersPer100Kilometers":2.3,"evStateOfChargePercent":null,"evDistanceToEmptyMiles":null,"evDistanceToEmptyKilometers":null,"evDistanceToEmptyByStateMiles":null,"evDistanceToEmptyByStateKilometers":null,"vehicleStateType":"IGNITION_OFF","windowFrontLeftStatus":"CLOSE","windowFrontRightStatus":"CLOSE","windowRearLeftStatus":"CLOSE","windowRearRightStatus":"CLOSE","windowSunroofStatus":"CLOSE","tyreStatusFrontLeft":"UNKNOWN","tyreStatusFrontRight":"UNKNOWN","tyreStatusRearLeft":"UNKNOWN","tyreStatusRearRight":"UNKNOWN","remainingFuelPercent":90,"distanceToEmptyFuelMiles10s":260,"distanceToEmptyFuelKilometers10s":420}}`)
|
||||||
|
}
|
||||||
|
// Handle API_CONDITION endpoint
|
||||||
|
if (r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_CONDITION"], "g1") || r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_CONDITION"], "g2")) && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"remoteServiceStatus","data":{"serviceRequestId":null,"success":true,"cancelled":false,"remoteServiceType":"condition","remoteServiceState":"finished","subState":null,"errorCode":null,"result":{"avgFuelConsumption":null,"avgFuelConsumptionUnit":"MPG","distanceToEmptyFuel":null,"distanceToEmptyFuelUnit":"MILES","odometer":31692,"odometerUnit":"MILES","tirePressureFrontLeft":null,"tirePressureFrontLeftUnit":"PSI","tirePressureFrontRight":null,"tirePressureFrontRightUnit":"PSI","tirePressureRearLeft":null,"tirePressureRearLeftUnit":"PSI","tirePressureRearRight":null,"tirePressureRearRightUnit":"PSI","lastUpdatedTime":"2025-07-05T19:15:45.000+0000","windowFrontLeftStatus":"CLOSE","windowFrontRightStatus":"CLOSE","windowRearLeftStatus":"CLOSE","windowRearRightStatus":"CLOSE","windowSunroofStatus":"CLOSE","remainingFuelPercent":"90","evDistanceToEmpty":null,"evDistanceToEmptyUnit":null,"evChargerStateType":null,"evIsPluggedIn":null,"evStateOfChargeMode":null,"evTimeToFullyCharged":null,"evStateOfChargePercent":null,"vehicleStateType":"IGNITION_OFF","doorBootLockStatus":"LOCKED","doorBootPosition":"CLOSED","doorEngineHoodPosition":"CLOSED","doorFrontLeftLockStatus":"LOCKED","doorFrontLeftPosition":"CLOSED","doorFrontRightLockStatus":"LOCKED","doorFrontRightPosition":"CLOSED","doorRearLeftLockStatus":"LOCKED","doorRearLeftPosition":"CLOSED","doorRearRightLockStatus":"LOCKED","doorRearRightPosition":"CLOSED"},"updateTime":null,"vin":"1HGCM82633A004352","errorDescription":null}}`)
|
||||||
|
}
|
||||||
|
// Handle API_G2_FETCH_RES_SUBARU_PRESETS endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_G2_FETCH_RES_SUBARU_PRESETS"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":null,"data":["{\"name\": \"Auto\", \"runTimeMinutes\": \"10\", \"climateZoneFrontTemp\": \"74\", \"climateZoneFrontAirMode\": \"AUTO\", \"climateZoneFrontAirVolume\": \"AUTO\", \"outerAirCirculation\": \"auto\", \"heatedRearWindowActive\": \"false\", \"airConditionOn\": \"false\", \"heatedSeatFrontLeft\": \"off\", \"heatedSeatFrontRight\": \"off\", \"startConfiguration\": \"START_ENGINE_ALLOW_KEY_IN_IGNITION\", \"canEdit\": \"true\", \"disabled\": \"false\", \"vehicleType\": \"gas\", \"presetType\": \"subaruPreset\" }","{\"name\":\"Full Cool\",\"runTimeMinutes\":\"10\",\"climateZoneFrontTemp\":\"60\",\"climateZoneFrontAirMode\":\"feet_face_balanced\",\"climateZoneFrontAirVolume\":\"7\",\"airConditionOn\":\"true\",\"heatedSeatFrontLeft\":\"high_cool\",\"heatedSeatFrontRight\":\"high_cool\",\"heatedRearWindowActive\":\"false\",\"outerAirCirculation\":\"outsideAir\",\"startConfiguration\":\"START_ENGINE_ALLOW_KEY_IN_IGNITION\",\"canEdit\":\"true\",\"disabled\":\"true\",\"vehicleType\":\"gas\",\"presetType\":\"subaruPreset\"}","{\"name\": \"Full Heat\", \"runTimeMinutes\": \"10\", \"climateZoneFrontTemp\": \"85\", \"climateZoneFrontAirMode\": \"feet_window\", \"climateZoneFrontAirVolume\": \"7\", \"airConditionOn\": \"false\", \"heatedSeatFrontLeft\": \"high_heat\", \"heatedSeatFrontRight\": \"high_heat\", \"heatedRearWindowActive\": \"true\", \"outerAirCirculation\": \"outsideAir\", \"startConfiguration\": \"START_ENGINE_ALLOW_KEY_IN_IGNITION\", \"canEdit\": \"true\", \"disabled\": \"true\", \"vehicleType\": \"gas\", \"presetType\": \"subaruPreset\" }","{\"name\": \"Full Cool\", \"runTimeMinutes\": \"10\", \"climateZoneFrontTemp\": \"60\", \"climateZoneFrontAirMode\": \"feet_face_balanced\", \"climateZoneFrontAirVolume\": \"7\", \"airConditionOn\": \"true\", \"heatedSeatFrontLeft\": \"OFF\", \"heatedSeatFrontRight\": \"OFF\", \"heatedRearWindowActive\": \"false\", \"outerAirCirculation\": \"outsideAir\", \"startConfiguration\": \"START_CLIMATE_CONTROL_ONLY_ALLOW_KEY_IN_IGNITION\", \"canEdit\": \"true\", \"disabled\": \"true\", \"vehicleType\": \"phev\", \"presetType\": \"subaruPreset\" }","{\"name\": \"Full Heat\", \"runTimeMinutes\": \"10\", \"climateZoneFrontTemp\": \"85\", \"climateZoneFrontAirMode\": \"feet_window\", \"climateZoneFrontAirVolume\": \"7\", \"airConditionOn\": \"false\", \"heatedSeatFrontLeft\": \"high_heat\", \"heatedSeatFrontRight\": \"high_heat\", \"heatedRearWindowActive\": \"true\", \"outerAirCirculation\": \"outsideAir\", \"startConfiguration\": \"START_CLIMATE_CONTROL_ONLY_ALLOW_KEY_IN_IGNITION\", \"canEdit\": \"true\", \"disabled\": \"true\", \"vehicleType\": \"phev\", \"presetType\": \"subaruPreset\" }"]}`)
|
||||||
|
}
|
||||||
|
// Handle API_G2_FETCH_RES_USER_PRESETS endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_G2_FETCH_RES_USER_PRESETS"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":null,"data":"[{\"name\":\"Cooling\",\"runTimeMinutes\":\"10\",\"climateZoneFrontTemp\":\"65\",\"climateZoneFrontAirMode\":\"FEET_FACE_BALANCED\",\"climateZoneFrontAirVolume\":\"7\",\"outerAirCirculation\":\"outsideAir\",\"heatedRearWindowActive\":\"false\",\"heatedSeatFrontLeft\":\"HIGH_COOL\",\"heatedSeatFrontRight\":\"HIGH_COOL\",\"airConditionOn\":\"false\",\"canEdit\":\"true\",\"disabled\":\"false\",\"presetType\":\"userPreset\",\"startConfiguration\":\"START_ENGINE_ALLOW_KEY_IN_IGNITION\"}]"}`)
|
||||||
|
}
|
||||||
|
// Handle API_G2_FETCH_RES_QUICK_START_SETTINGS endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_G2_FETCH_RES_QUICK_START_SETTINGS"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":null,"data":"{\"name\":\"Cooling\",\"runTimeMinutes\":\"10\",\"climateZoneFrontTemp\":\"65\",\"climateZoneFrontAirMode\":\"FEET_FACE_BALANCED\",\"climateZoneFrontAirVolume\":\"7\",\"outerAirCirculation\":\"outsideAir\",\"heatedRearWindowActive\":\"false\",\"heatedSeatFrontLeft\":\"HIGH_COOL\",\"airConditionOn\":\"false\",\"canEdit\":\"true\",\"disabled\":\"false\",\"presetType\":\"userPreset\",\"startConfiguration\":\"START_ENGINE_ALLOW_KEY_IN_IGNITION\"}"}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ts := mockMySubaruApi(t, handler)
|
||||||
|
ts.Start()
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
cfg := makeConfig(t)
|
||||||
|
|
||||||
|
msc, err := New(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
vehicle, err := msc.GetVehicleByVin("1HGCM82633A004352")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
if vehicle == nil {
|
||||||
|
t.Fatalf("expected vehicle, got nil")
|
||||||
|
}
|
||||||
|
if vehicle.Vin != "1HGCM82633A004352" {
|
||||||
|
t.Errorf("expected vehicle VIN 1HGCM82633A004352, got %v", vehicle.Vin)
|
||||||
|
}
|
||||||
|
}
|
10
consts.go
10
consts.go
@ -30,12 +30,12 @@ var apiURLs = map[string]string{
|
|||||||
"API_2FA_AUTH_VERIFY": "/twoStepAuthVerify.json",
|
"API_2FA_AUTH_VERIFY": "/twoStepAuthVerify.json",
|
||||||
"API_LOGIN": "/login.json", // Same API for g1 and g2
|
"API_LOGIN": "/login.json", // Same API for g1 and g2
|
||||||
"API_REFRESH_VEHICLES": "/refreshVehicles.json",
|
"API_REFRESH_VEHICLES": "/refreshVehicles.json",
|
||||||
"API_SELECT_VEHICLE": "/selectVehicle.json",
|
"API_SELECT_VEHICLE": "/selectVehicle.json", // Covered by test
|
||||||
"API_VALIDATE_SESSION": "/validateSession.json",
|
"API_VALIDATE_SESSION": "/validateSession.json", // Covered by test
|
||||||
"API_VEHICLE_STATUS": "/vehicleStatus.json",
|
"API_VEHICLE_STATUS": "/vehicleStatus.json", // Covered by test
|
||||||
"API_AUTHORIZE_DEVICE": "/authenticateDevice.json",
|
"API_AUTHORIZE_DEVICE": "/authenticateDevice.json",
|
||||||
"API_NAME_DEVICE": "/nameThisDevice.json",
|
"API_NAME_DEVICE": "/nameThisDevice.json",
|
||||||
"API_VEHICLE_HEALTH": "/vehicleHealth.json",
|
"API_VEHICLE_HEALTH": "/vehicleHealth.json", // Covered by test
|
||||||
"API_CONDITION": "/service/api_gen/condition/execute.json", // Similar API for g1 and g2 -- controller should replace 'api_gen' with either 'g1' or 'g2'
|
"API_CONDITION": "/service/api_gen/condition/execute.json", // Similar API for g1 and g2 -- controller should replace 'api_gen' with either 'g1' or 'g2'
|
||||||
"API_LOCATE": "/service/api_gen/locate/execute.json", // Get the last location the vehicle has reported to Subaru
|
"API_LOCATE": "/service/api_gen/locate/execute.json", // Get the last location the vehicle has reported to Subaru
|
||||||
"API_LOCK": "/service/api_gen/lock/execute.json",
|
"API_LOCK": "/service/api_gen/lock/execute.json",
|
||||||
@ -48,12 +48,12 @@ var apiURLs = map[string]string{
|
|||||||
"API_LIGHTS": "/service/api_gen/lightsOnly/execute.json",
|
"API_LIGHTS": "/service/api_gen/lightsOnly/execute.json",
|
||||||
"API_LIGHTS_CANCEL": "/service/api_gen/lightsOnly/cancel.json",
|
"API_LIGHTS_CANCEL": "/service/api_gen/lightsOnly/cancel.json",
|
||||||
"API_LIGHTS_STOP": "/service/api_gen/lightsOnly/stop.json",
|
"API_LIGHTS_STOP": "/service/api_gen/lightsOnly/stop.json",
|
||||||
"API_REMOTE_SVC_STATUS": "/service/g2/remoteService/status.json",
|
|
||||||
"API_G1_LOCATE_UPDATE": "/service/g1/vehicleLocate/execute.json", // Different API for g1 and g2
|
"API_G1_LOCATE_UPDATE": "/service/g1/vehicleLocate/execute.json", // Different API for g1 and g2
|
||||||
"API_G1_LOCATE_STATUS": "/service/g1/vehicleLocate/status.json",
|
"API_G1_LOCATE_STATUS": "/service/g1/vehicleLocate/status.json",
|
||||||
"API_G1_HORN_LIGHTS_STATUS": "/service/g1/hornLights/status.json", // g1-Only API
|
"API_G1_HORN_LIGHTS_STATUS": "/service/g1/hornLights/status.json", // g1-Only API
|
||||||
"API_G2_LOCATE_UPDATE": "/service/g2/vehicleStatus/execute.json",
|
"API_G2_LOCATE_UPDATE": "/service/g2/vehicleStatus/execute.json",
|
||||||
"API_G2_LOCATE_STATUS": "/service/g2/vehicleStatus/locationStatus.json",
|
"API_G2_LOCATE_STATUS": "/service/g2/vehicleStatus/locationStatus.json",
|
||||||
|
"API_REMOTE_SVC_STATUS": "/service/g2/remoteService/status.json",
|
||||||
"API_G2_SEND_POI": "/service/g2/sendPoi/execute.json", // g2-Only API
|
"API_G2_SEND_POI": "/service/g2/sendPoi/execute.json", // g2-Only API
|
||||||
"API_G2_SPEEDFENCE": "/service/g2/speedFence/execute.json",
|
"API_G2_SPEEDFENCE": "/service/g2/speedFence/execute.json",
|
||||||
"API_G2_GEOFENCE": "/service/g2/geoFence/execute.json",
|
"API_G2_GEOFENCE": "/service/g2/geoFence/execute.json",
|
||||||
|
@ -10,5 +10,5 @@ mysubaru:
|
|||||||
timezone: "America/New_York"
|
timezone: "America/New_York"
|
||||||
logging:
|
logging:
|
||||||
level: INFO
|
level: INFO
|
||||||
output: json
|
output: JSON
|
||||||
source: false
|
source: false
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.savin.nyc/alex/mysubaru"
|
"git.savin.nyc/alex/mysubaru"
|
||||||
"git.savin.nyc/alex/mysubaru/config"
|
"git.savin.nyc/alex/mysubaru/config"
|
||||||
@ -21,9 +22,13 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
cfg.Logger.Debug("printing config", "config", cfg)
|
// cfg.Logger.Debug("printing config", "config", cfg)
|
||||||
|
|
||||||
ms, _ := mysubaru.New(cfg)
|
msc, err := mysubaru.New(cfg)
|
||||||
|
if err != nil {
|
||||||
|
cfg.Logger.Error("cannot create MySubaru client", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
// subaru := ms.SelectVehicle("4S4BTGPD0P3199198")
|
// subaru := ms.SelectVehicle("4S4BTGPD0P3199198")
|
||||||
|
|
||||||
@ -37,48 +42,66 @@ func main() {
|
|||||||
// fmt.Printf("GEN #1: %+v\n\n", subaru1.getAPIGen())
|
// fmt.Printf("GEN #1: %+v\n\n", subaru1.getAPIGen())
|
||||||
|
|
||||||
// ABS_MIL ACCS AHBL_MIL ATF_MIL AWD_MIL BSD BSDRCT_MIL CEL_MIL EBD_MIL EOL_MIL EPAS_MIL EPB_MIL ESS_MIL EYESIGHT ISS_MIL OPL_MIL PANPM-TUIRWAOC PWAAADWWAP RAB_MIL RCC REARBRK RES RESCC RHSF RPOI RPOIA RTGU RVFS SRH_MIL SRS_MIL TEL_MIL TIF_35 TIR_33 TLD TPMS_MIL VALET VDC_MIL WASH_MIL g3
|
// ABS_MIL ACCS AHBL_MIL ATF_MIL AWD_MIL BSD BSDRCT_MIL CEL_MIL EBD_MIL EOL_MIL EPAS_MIL EPB_MIL ESS_MIL EYESIGHT ISS_MIL OPL_MIL PANPM-TUIRWAOC PWAAADWWAP RAB_MIL RCC REARBRK RES RESCC RHSF RPOI RPOIA RTGU RVFS SRH_MIL SRS_MIL TEL_MIL TIF_35 TIR_33 TLD TPMS_MIL VALET VDC_MIL WASH_MIL g3
|
||||||
outback := ms.GetVehicleByVIN("4S4BTGPD0P3199198")
|
outback, err := msc.GetVehicleByVIN("4S4BTGPD0P3199198")
|
||||||
// subaru.GetLocation(true)
|
if err != nil {
|
||||||
|
cfg.Logger.Error("cannot get a vehicle by VIN", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Printf("SUBARU #1 (Vehicle Status): %s\n", outback)
|
||||||
|
|
||||||
// subaru.EngineStart()
|
// // Execute a LightsStart command
|
||||||
fmt.Printf("SUBARU #1 (Vehicle Status):\n")
|
// events, err := outback.LightsStart()
|
||||||
// subaru.GetVehicleStatus()
|
// if err != nil {
|
||||||
// fmt.Printf("SUBARU #1 (Vehicle Condition):\n")
|
// cfg.Logger.Error("cannot execute LightsStart command", "error", err)
|
||||||
// subaru.GetVehicleCondition()
|
// os.Exit(1)
|
||||||
// fmt.Printf("SUBARU #1: %+v\n", subaru)
|
// }
|
||||||
// subaru.GetClimatePresets()
|
// for event := range events {
|
||||||
// subaru.GetClimateUserPresets()
|
// fmt.Printf("Lights Start Event: %+v\n", event)
|
||||||
// fmt.Printf("SUBARU #2: %+v\n", subaru)
|
// }
|
||||||
// subaru.GetVehicleHealth()
|
|
||||||
// subaru.GetFeaturesList()
|
|
||||||
// subaru := mysubaru.GetVehicles()[0]
|
|
||||||
|
|
||||||
// fmt.Printf("SUBARU: %+v\n", subaru)
|
// // Wait for a while to see the lights on
|
||||||
|
|
||||||
// fmt.Printf("Subaru Gen: %+v\n\n", subaru.getAPIGen())
|
|
||||||
|
|
||||||
// subaru.EngineOn()
|
|
||||||
// subaru.GetLocation(false)
|
|
||||||
|
|
||||||
// subaru.GetVehicleStatus()
|
|
||||||
// subaru.GetVehicleCondition()
|
|
||||||
|
|
||||||
// subaru.GetClimateQuickPresets()
|
|
||||||
// subaru.GetClimatePresets()
|
|
||||||
// subaru.GetClimateUserPresets()
|
|
||||||
|
|
||||||
// subaru.GetVehicleStatus()
|
|
||||||
|
|
||||||
// subaru.GetClimateSettings()
|
|
||||||
|
|
||||||
// subaru.EngineStart()
|
|
||||||
// time.Sleep(15 * time.Second)
|
|
||||||
// subaru.EngineStop()
|
|
||||||
|
|
||||||
// subaru.Unlock()
|
|
||||||
// time.Sleep(20 * time.Second)
|
// time.Sleep(20 * time.Second)
|
||||||
// subaru.Lock()
|
|
||||||
|
|
||||||
// subaru.GetLocation()
|
// // Execute a LightsStop command
|
||||||
fmt.Printf("SUBARU: %+v\n", outback)
|
// events, err = outback.LightsStop()
|
||||||
|
// if err != nil {
|
||||||
|
// cfg.Logger.Error("cannot execute LightsStop command", "error", err)
|
||||||
|
// os.Exit(1)
|
||||||
|
// }
|
||||||
|
// for event := range events {
|
||||||
|
// fmt.Printf("Lights Stop Event: %+v\n", event)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Execute a Unlock command
|
||||||
|
events, err := outback.Unlock()
|
||||||
|
if err != nil {
|
||||||
|
cfg.Logger.Error("cannot execute Unlock command", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
for event := range events {
|
||||||
|
fmt.Printf("Unlock Event: %+v\n", event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for a while to see the lights on
|
||||||
|
time.Sleep(20 * time.Second)
|
||||||
|
|
||||||
|
// Execute a Lock command
|
||||||
|
events, err = outback.Lock()
|
||||||
|
if err != nil {
|
||||||
|
cfg.Logger.Error("cannot execute Lock command", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
for event := range events {
|
||||||
|
fmt.Printf("Lock Event: %+v\n", event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute a forced GetLocation command
|
||||||
|
// events, err = outback.GetLocation(true)
|
||||||
|
// if err != nil {
|
||||||
|
// cfg.Logger.Error("cannot execute forced GetLocation command", "error", err)
|
||||||
|
// os.Exit(1)
|
||||||
|
// }
|
||||||
|
// for event := range events {
|
||||||
|
// fmt.Printf("GeoLocation Event: %+v\n", event)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,17 @@ func TestTimestamp(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTimestamp_Format(t *testing.T) {
|
||||||
|
ts := timestamp()
|
||||||
|
matched, err := regexp.MatchString(`^\d+$`, ts)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("regexp error: %v", err)
|
||||||
|
}
|
||||||
|
if !matched {
|
||||||
|
t.Errorf("timestamp() = %q, want only digits", ts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestUrlToGen(t *testing.T) {
|
func TestUrlToGen(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
url, gen, want string
|
url, gen, want string
|
||||||
@ -108,14 +119,3 @@ func TestUrlToGen_NoApiGen(t *testing.T) {
|
|||||||
t.Errorf("urlToGen(%q, %q) = %q, want %q", url, gen, got, url)
|
t.Errorf("urlToGen(%q, %q) = %q, want %q", url, gen, got, url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimestamp_Format(t *testing.T) {
|
|
||||||
ts := timestamp()
|
|
||||||
matched, err := regexp.MatchString(`^\d+$`, ts)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("regexp error: %v", err)
|
|
||||||
}
|
|
||||||
if !matched {
|
|
||||||
t.Errorf("timestamp() = %q, want only digits", ts)
|
|
||||||
}
|
|
||||||
}
|
|
158
vehicle.go
158
vehicle.go
@ -481,81 +481,6 @@ func (v *Vehicle) GetLocation(force bool) (chan string, error) {
|
|||||||
return ch, nil
|
return ch, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// executeServiceRequest
|
|
||||||
func (v *Vehicle) executeServiceRequest(params map[string]string, reqUrl, pollingUrl string, ch chan string, attempt int) error {
|
|
||||||
var maxAttempts = 15
|
|
||||||
|
|
||||||
if attempt >= maxAttempts {
|
|
||||||
v.client.logger.Error("maximum attempts reached for service request", "request", reqUrl, "attempts", attempt)
|
|
||||||
ch <- "error"
|
|
||||||
return errors.New("maximum attempts reached for service request")
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.Vin != v.client.currentVin {
|
|
||||||
v.selectVehicle()
|
|
||||||
}
|
|
||||||
|
|
||||||
var resp *Response
|
|
||||||
var err error
|
|
||||||
if attempt == 1 {
|
|
||||||
resp, err = v.client.execute(POST, reqUrl, params, true)
|
|
||||||
if err != nil {
|
|
||||||
v.client.logger.Error("error while executing service request", "request", reqUrl, "error", err.Error())
|
|
||||||
ch <- "error"
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
resp, err = v.client.execute(GET, pollingUrl, params, false)
|
|
||||||
if err != nil {
|
|
||||||
v.client.logger.Error("error while executing service request status polling", "request", reqUrl, "error", err.Error())
|
|
||||||
ch <- "error"
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// dataName field has the list of the states [ remoteServiceStatus | errorResponse ]
|
|
||||||
if resp.DataName == "remoteServiceStatus" {
|
|
||||||
if sr, ok := v.parseServiceRequest([]byte(resp.Data)); ok {
|
|
||||||
ch <- sr.RemoteServiceState
|
|
||||||
switch sr.RemoteServiceState {
|
|
||||||
|
|
||||||
case "finished":
|
|
||||||
// Finished RemoteServiceState Service Request does not include Service Request ID
|
|
||||||
v.client.logger.Debug("Remote service request completed successfully")
|
|
||||||
|
|
||||||
case "started":
|
|
||||||
time.Sleep(5 * time.Second)
|
|
||||||
v.client.logger.Debug("Subaru API reports remote service request (started) is in progress", "id", sr.ServiceRequestID)
|
|
||||||
v.executeServiceRequest(map[string]string{"serviceRequestId": sr.ServiceRequestID}, reqUrl, pollingUrl, ch, attempt+1)
|
|
||||||
|
|
||||||
case "stopping":
|
|
||||||
time.Sleep(5 * time.Second)
|
|
||||||
v.client.logger.Debug("Subaru API reports remote service request (stopping) is in progress", "id", sr.ServiceRequestID)
|
|
||||||
v.executeServiceRequest(map[string]string{"serviceRequestId": sr.ServiceRequestID}, reqUrl, pollingUrl, ch, attempt+1)
|
|
||||||
|
|
||||||
default:
|
|
||||||
v.client.logger.Debug("Subaru API reports remote service request (default)")
|
|
||||||
v.executeServiceRequest(map[string]string{"serviceRequestId": sr.ServiceRequestID}, reqUrl, pollingUrl, ch, attempt+1)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
v.client.logger.Error("error while parsing service request json", "request", reqUrl, "response", resp.Data)
|
|
||||||
return errors.New("error while parsing service request json")
|
|
||||||
}
|
|
||||||
return errors.New("response is not a service request")
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseServiceRequest .
|
|
||||||
func (v *Vehicle) parseServiceRequest(b []byte) (ServiceRequest, bool) {
|
|
||||||
var sr ServiceRequest
|
|
||||||
err := json.Unmarshal(b, &sr)
|
|
||||||
if err != nil {
|
|
||||||
v.client.logger.Error("error while parsing service request json", "error", err.Error())
|
|
||||||
return sr, false
|
|
||||||
}
|
|
||||||
return sr, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetClimatePresets connects to the MySubaru API to download available climate presets.
|
// GetClimatePresets connects to the MySubaru API to download available climate presets.
|
||||||
// It first attempts to establish a connection with the MySubaru API.
|
// It first attempts to establish a connection with the MySubaru API.
|
||||||
// If successful and climate presets are found for the user's vehicle,
|
// If successful and climate presets are found for the user's vehicle,
|
||||||
@ -710,11 +635,15 @@ func (v *Vehicle) GetVehicleStatus() error {
|
|||||||
v.selectVehicle()
|
v.selectVehicle()
|
||||||
}
|
}
|
||||||
reqUrl := MOBILE_API_VERSION + urlToGen(apiURLs["API_VEHICLE_STATUS"], v.getAPIGen())
|
reqUrl := MOBILE_API_VERSION + urlToGen(apiURLs["API_VEHICLE_STATUS"], v.getAPIGen())
|
||||||
resp, _ := v.client.execute(GET, reqUrl, map[string]string{}, false)
|
resp, err := v.client.execute(GET, reqUrl, map[string]string{}, false)
|
||||||
|
if err != nil {
|
||||||
|
v.client.logger.Error("error while executing GetVehicleStatus request", "request", "GetVehicleStatus", "error", err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
// v.client.logger.Info("http request output", "request", "GetVehicleStatus", "body", resp)
|
// v.client.logger.Info("http request output", "request", "GetVehicleStatus", "body", resp)
|
||||||
|
|
||||||
var vs VehicleStatus
|
var vs VehicleStatus
|
||||||
err := json.Unmarshal(resp.Data, &vs)
|
err = json.Unmarshal(resp.Data, &vs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.client.logger.Error("error while parsing json", "request", "GetVehicleStatus", "error", err.Error())
|
v.client.logger.Error("error while parsing json", "request", "GetVehicleStatus", "error", err.Error())
|
||||||
}
|
}
|
||||||
@ -855,6 +784,81 @@ func (v *Vehicle) GetFeaturesList() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// executeServiceRequest
|
||||||
|
func (v *Vehicle) executeServiceRequest(params map[string]string, reqUrl, pollingUrl string, ch chan string, attempt int) error {
|
||||||
|
var maxAttempts = 15
|
||||||
|
|
||||||
|
if attempt >= maxAttempts {
|
||||||
|
v.client.logger.Error("maximum attempts reached for service request", "request", reqUrl, "attempts", attempt)
|
||||||
|
ch <- "error"
|
||||||
|
return errors.New("maximum attempts reached for service request")
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Vin != v.client.currentVin {
|
||||||
|
v.selectVehicle()
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp *Response
|
||||||
|
var err error
|
||||||
|
if attempt == 1 {
|
||||||
|
resp, err = v.client.execute(POST, reqUrl, params, true)
|
||||||
|
if err != nil {
|
||||||
|
v.client.logger.Error("error while executing service request", "request", reqUrl, "error", err.Error())
|
||||||
|
ch <- "error"
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resp, err = v.client.execute(GET, pollingUrl, params, false)
|
||||||
|
if err != nil {
|
||||||
|
v.client.logger.Error("error while executing service request status polling", "request", reqUrl, "error", err.Error())
|
||||||
|
ch <- "error"
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dataName field has the list of the states [ remoteServiceStatus | errorResponse ]
|
||||||
|
if resp.DataName == "remoteServiceStatus" {
|
||||||
|
if sr, ok := v.parseServiceRequest([]byte(resp.Data)); ok {
|
||||||
|
ch <- sr.RemoteServiceState
|
||||||
|
switch sr.RemoteServiceState {
|
||||||
|
|
||||||
|
case "finished":
|
||||||
|
// Finished RemoteServiceState Service Request does not include Service Request ID
|
||||||
|
v.client.logger.Debug("Remote service request completed successfully")
|
||||||
|
|
||||||
|
case "started":
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
v.client.logger.Debug("Subaru API reports remote service request (started) is in progress", "id", sr.ServiceRequestID)
|
||||||
|
v.executeServiceRequest(map[string]string{"serviceRequestId": sr.ServiceRequestID}, reqUrl, pollingUrl, ch, attempt+1)
|
||||||
|
|
||||||
|
case "stopping":
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
v.client.logger.Debug("Subaru API reports remote service request (stopping) is in progress", "id", sr.ServiceRequestID)
|
||||||
|
v.executeServiceRequest(map[string]string{"serviceRequestId": sr.ServiceRequestID}, reqUrl, pollingUrl, ch, attempt+1)
|
||||||
|
|
||||||
|
default:
|
||||||
|
v.client.logger.Debug("Subaru API reports remote service request (default)")
|
||||||
|
v.executeServiceRequest(map[string]string{"serviceRequestId": sr.ServiceRequestID}, reqUrl, pollingUrl, ch, attempt+1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
v.client.logger.Error("error while parsing service request json", "request", reqUrl, "response", resp.Data)
|
||||||
|
return errors.New("error while parsing service request json")
|
||||||
|
}
|
||||||
|
return errors.New("response is not a service request")
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseServiceRequest .
|
||||||
|
func (v *Vehicle) parseServiceRequest(b []byte) (ServiceRequest, bool) {
|
||||||
|
var sr ServiceRequest
|
||||||
|
err := json.Unmarshal(b, &sr)
|
||||||
|
if err != nil {
|
||||||
|
v.client.logger.Error("error while parsing service request json", "error", err.Error())
|
||||||
|
return sr, false
|
||||||
|
}
|
||||||
|
return sr, true
|
||||||
|
}
|
||||||
|
|
||||||
// selectVehicle .
|
// selectVehicle .
|
||||||
func (v *Vehicle) selectVehicle() {
|
func (v *Vehicle) selectVehicle() {
|
||||||
if v.client.currentVin != v.Vin {
|
if v.client.currentVin != v.Vin {
|
||||||
|
265
vehicle_test.go
Normal file
265
vehicle_test.go
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
package mysubaru
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetClimatePresets_Success(t *testing.T) {
|
||||||
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Handle API_LOGIN endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_LOGIN"] && r.Method == http.MethodPost {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":"BIOMETRICS_DISABLED","dataName":"sessionData","data":{"sessionChanged":false,"vehicleInactivated":false,"account":{"marketId":1,"createdDate":1476984644000,"firstName":"Tatiana","lastName":"Savin","zipCode":"07974","accountKey":765268,"lastLoginDate":1751738613000,"zipCode5":"07974"},"resetPassword":false,"deviceId":"JddMBQXvAkgutSmEP6uFsThbq4QgEBBQ","sessionId":"9D7FCDF274794346689D3FA0D693CBBF","deviceRegistered":true,"passwordToken":null,"vehicles":[{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":null,"modelCode":null,"engineSize":null,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"","licensePlateState":"","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":null,"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":null,"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":null,"authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":null,"subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":null,"sunsetUpgraded":true,"intDescrip":null,"transCode":null,"provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}],"rightToRepairEnabled":true,"rightToRepairStartYear":2022,"rightToRepairStates":"MA","enableXtime":true,"termsAndConditionsAccepted":true,"digitalGlobeConnectId":"0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeImageTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/DigitalGlobe:ImageryTileService@EPSG:3857@png/{z}/{x}/{y}.png?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeTransparentTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/Digitalglobe:OSMTransparentTMSTileService@EPSG:3857@png/{z}/{x}/{-y}.png/?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","tomtomKey":"DHH9SwEQ4MW55Hj2TfqMeldbsDjTdgAs","currentVehicleIndex":0,"handoffToken":"$2a$08$rOb/uqhm8I3QtSel2phOCOxNM51w43eqXDDksMkJ.1a5KsaQuLvEu$1751745334477","satelliteViewEnabled":true,"registeredDevicePermanent":true}}`)
|
||||||
|
}
|
||||||
|
// Handle SELECT_VEHICLE endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_SELECT_VEHICLE"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"vehicle","data":{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":"2023","modelCode":"PDL","engineSize":2.4,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"8KV8","licensePlateState":"NJ","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":["REMOTE","SAFETY","Retail3"],"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":["ABS_MIL","ACCS","AHBL_MIL","ATF_MIL","AWD_MIL","BSD","BSDRCT_MIL","CEL_MIL","CP1_5HHU","EBD_MIL","EOL_MIL","EPAS_MIL","EPB_MIL","ESS_MIL","EYESIGHT","ISS_MIL","MOONSTAT","OPL_MIL","PANPM-TUIRWAOC","PWAAADWWAP","RAB_MIL","RCC","REARBRK","RES","RESCC","RES_HVAC_HFS","RES_HVAC_VFS","RHSF","RPOI","RPOIA","RTGU","RVFS","SRH_MIL","SRS_MIL","SXM360L","T23DCM","TEL_MIL","TIF_35","TIR_33","TLD","TPMS_MIL","VALET","VDC_MIL","WASH_MIL","WDWSTAT","g3"],"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":"ACTIVE","authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":"Outback","subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":"Cosmic Blue Pearl","sunsetUpgraded":true,"intDescrip":"Black","transCode":"CVT","provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}}`)
|
||||||
|
}
|
||||||
|
// Handle API_G2_FETCH_RES_SUBARU_PRESETS endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_G2_FETCH_RES_SUBARU_PRESETS"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":null,"data":["{\"name\": \"Auto\", \"runTimeMinutes\": \"10\", \"climateZoneFrontTemp\": \"74\", \"climateZoneFrontAirMode\": \"AUTO\", \"climateZoneFrontAirVolume\": \"AUTO\", \"outerAirCirculation\": \"auto\", \"heatedRearWindowActive\": \"false\", \"airConditionOn\": \"false\", \"heatedSeatFrontLeft\": \"off\", \"heatedSeatFrontRight\": \"off\", \"startConfiguration\": \"START_ENGINE_ALLOW_KEY_IN_IGNITION\", \"canEdit\": \"true\", \"disabled\": \"false\", \"vehicleType\": \"gas\", \"presetType\": \"subaruPreset\" }","{\"name\":\"Full Cool\",\"runTimeMinutes\":\"10\",\"climateZoneFrontTemp\":\"60\",\"climateZoneFrontAirMode\":\"feet_face_balanced\",\"climateZoneFrontAirVolume\":\"7\",\"airConditionOn\":\"true\",\"heatedSeatFrontLeft\":\"high_cool\",\"heatedSeatFrontRight\":\"high_cool\",\"heatedRearWindowActive\":\"false\",\"outerAirCirculation\":\"outsideAir\",\"startConfiguration\":\"START_ENGINE_ALLOW_KEY_IN_IGNITION\",\"canEdit\":\"true\",\"disabled\":\"true\",\"vehicleType\":\"gas\",\"presetType\":\"subaruPreset\"}","{\"name\": \"Full Heat\", \"runTimeMinutes\": \"10\", \"climateZoneFrontTemp\": \"85\", \"climateZoneFrontAirMode\": \"feet_window\", \"climateZoneFrontAirVolume\": \"7\", \"airConditionOn\": \"false\", \"heatedSeatFrontLeft\": \"high_heat\", \"heatedSeatFrontRight\": \"high_heat\", \"heatedRearWindowActive\": \"true\", \"outerAirCirculation\": \"outsideAir\", \"startConfiguration\": \"START_ENGINE_ALLOW_KEY_IN_IGNITION\", \"canEdit\": \"true\", \"disabled\": \"true\", \"vehicleType\": \"gas\", \"presetType\": \"subaruPreset\" }","{\"name\": \"Full Cool\", \"runTimeMinutes\": \"10\", \"climateZoneFrontTemp\": \"60\", \"climateZoneFrontAirMode\": \"feet_face_balanced\", \"climateZoneFrontAirVolume\": \"7\", \"airConditionOn\": \"true\", \"heatedSeatFrontLeft\": \"OFF\", \"heatedSeatFrontRight\": \"OFF\", \"heatedRearWindowActive\": \"false\", \"outerAirCirculation\": \"outsideAir\", \"startConfiguration\": \"START_CLIMATE_CONTROL_ONLY_ALLOW_KEY_IN_IGNITION\", \"canEdit\": \"true\", \"disabled\": \"true\", \"vehicleType\": \"phev\", \"presetType\": \"subaruPreset\" }","{\"name\": \"Full Heat\", \"runTimeMinutes\": \"10\", \"climateZoneFrontTemp\": \"85\", \"climateZoneFrontAirMode\": \"feet_window\", \"climateZoneFrontAirVolume\": \"7\", \"airConditionOn\": \"false\", \"heatedSeatFrontLeft\": \"high_heat\", \"heatedSeatFrontRight\": \"high_heat\", \"heatedRearWindowActive\": \"true\", \"outerAirCirculation\": \"outsideAir\", \"startConfiguration\": \"START_CLIMATE_CONTROL_ONLY_ALLOW_KEY_IN_IGNITION\", \"canEdit\": \"true\", \"disabled\": \"true\", \"vehicleType\": \"phev\", \"presetType\": \"subaruPreset\" }"]}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ts := mockMySubaruApi(t, handler)
|
||||||
|
ts.Start()
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
cfg := makeConfig(t)
|
||||||
|
|
||||||
|
msc, err := New(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
if msc == nil {
|
||||||
|
t.Fatalf("expected MySubaru API client, got nil")
|
||||||
|
}
|
||||||
|
if !msc.isAuthenticated || !msc.isRegistered {
|
||||||
|
t.Errorf("expected authenticated and registered true, got %v %v", msc.isAuthenticated, msc.isRegistered)
|
||||||
|
}
|
||||||
|
if msc.currentVin != "1HGCM82633A004352" {
|
||||||
|
t.Errorf("expected currentVin 1HGCM82633A004352, got %v", msc.currentVin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetClimateQuickPresets_Success(t *testing.T) {
|
||||||
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Handle API_LOGIN endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_LOGIN"] && r.Method == http.MethodPost {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":"BIOMETRICS_DISABLED","dataName":"sessionData","data":{"sessionChanged":false,"vehicleInactivated":false,"account":{"marketId":1,"createdDate":1476984644000,"firstName":"Tatiana","lastName":"Savin","zipCode":"07974","accountKey":765268,"lastLoginDate":1751738613000,"zipCode5":"07974"},"resetPassword":false,"deviceId":"JddMBQXvAkgutSmEP6uFsThbq4QgEBBQ","sessionId":"9D7FCDF274794346689D3FA0D693CBBF","deviceRegistered":true,"passwordToken":null,"vehicles":[{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":null,"modelCode":null,"engineSize":null,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"","licensePlateState":"","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":null,"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":null,"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":null,"authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":null,"subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":null,"sunsetUpgraded":true,"intDescrip":null,"transCode":null,"provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}],"rightToRepairEnabled":true,"rightToRepairStartYear":2022,"rightToRepairStates":"MA","enableXtime":true,"termsAndConditionsAccepted":true,"digitalGlobeConnectId":"0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeImageTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/DigitalGlobe:ImageryTileService@EPSG:3857@png/{z}/{x}/{y}.png?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeTransparentTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/Digitalglobe:OSMTransparentTMSTileService@EPSG:3857@png/{z}/{x}/{-y}.png/?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","tomtomKey":"DHH9SwEQ4MW55Hj2TfqMeldbsDjTdgAs","currentVehicleIndex":0,"handoffToken":"$2a$08$rOb/uqhm8I3QtSel2phOCOxNM51w43eqXDDksMkJ.1a5KsaQuLvEu$1751745334477","satelliteViewEnabled":true,"registeredDevicePermanent":true}}`)
|
||||||
|
}
|
||||||
|
// Handle SELECT_VEHICLE endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_SELECT_VEHICLE"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"vehicle","data":{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":"2023","modelCode":"PDL","engineSize":2.4,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"8KV8","licensePlateState":"NJ","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":["REMOTE","SAFETY","Retail3"],"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":["ABS_MIL","ACCS","AHBL_MIL","ATF_MIL","AWD_MIL","BSD","BSDRCT_MIL","CEL_MIL","CP1_5HHU","EBD_MIL","EOL_MIL","EPAS_MIL","EPB_MIL","ESS_MIL","EYESIGHT","ISS_MIL","MOONSTAT","OPL_MIL","PANPM-TUIRWAOC","PWAAADWWAP","RAB_MIL","RCC","REARBRK","RES","RESCC","RES_HVAC_HFS","RES_HVAC_VFS","RHSF","RPOI","RPOIA","RTGU","RVFS","SRH_MIL","SRS_MIL","SXM360L","T23DCM","TEL_MIL","TIF_35","TIR_33","TLD","TPMS_MIL","VALET","VDC_MIL","WASH_MIL","WDWSTAT","g3"],"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":"ACTIVE","authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":"Outback","subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":"Cosmic Blue Pearl","sunsetUpgraded":true,"intDescrip":"Black","transCode":"CVT","provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}}`)
|
||||||
|
}
|
||||||
|
// Handle API_G2_FETCH_RES_QUICK_START_SETTINGS endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_G2_FETCH_RES_QUICK_START_SETTINGS"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":null,"data":"{\"name\":\"Cooling\",\"runTimeMinutes\":\"10\",\"climateZoneFrontTemp\":\"65\",\"climateZoneFrontAirMode\":\"FEET_FACE_BALANCED\",\"climateZoneFrontAirVolume\":\"7\",\"outerAirCirculation\":\"outsideAir\",\"heatedRearWindowActive\":\"false\",\"heatedSeatFrontLeft\":\"HIGH_COOL\",\"airConditionOn\":\"false\",\"canEdit\":\"true\",\"disabled\":\"false\",\"presetType\":\"userPreset\",\"startConfiguration\":\"START_ENGINE_ALLOW_KEY_IN_IGNITION\"}"}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ts := mockMySubaruApi(t, handler)
|
||||||
|
ts.Start()
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
cfg := makeConfig(t)
|
||||||
|
|
||||||
|
msc, err := New(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
if msc == nil {
|
||||||
|
t.Fatalf("expected MySubaru API client, got nil")
|
||||||
|
}
|
||||||
|
if !msc.isAuthenticated || !msc.isRegistered {
|
||||||
|
t.Errorf("expected authenticated and registered true, got %v %v", msc.isAuthenticated, msc.isRegistered)
|
||||||
|
}
|
||||||
|
if msc.currentVin != "1HGCM82633A004352" {
|
||||||
|
t.Errorf("expected currentVin 1HGCM82633A004352, got %v", msc.currentVin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetClimateUserPresets_Success(t *testing.T) {
|
||||||
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Handle API_LOGIN endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_LOGIN"] && r.Method == http.MethodPost {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":"BIOMETRICS_DISABLED","dataName":"sessionData","data":{"sessionChanged":false,"vehicleInactivated":false,"account":{"marketId":1,"createdDate":1476984644000,"firstName":"Tatiana","lastName":"Savin","zipCode":"07974","accountKey":765268,"lastLoginDate":1751738613000,"zipCode5":"07974"},"resetPassword":false,"deviceId":"JddMBQXvAkgutSmEP6uFsThbq4QgEBBQ","sessionId":"9D7FCDF274794346689D3FA0D693CBBF","deviceRegistered":true,"passwordToken":null,"vehicles":[{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":null,"modelCode":null,"engineSize":null,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"","licensePlateState":"","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":null,"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":null,"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":null,"authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":null,"subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":null,"sunsetUpgraded":true,"intDescrip":null,"transCode":null,"provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}],"rightToRepairEnabled":true,"rightToRepairStartYear":2022,"rightToRepairStates":"MA","enableXtime":true,"termsAndConditionsAccepted":true,"digitalGlobeConnectId":"0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeImageTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/DigitalGlobe:ImageryTileService@EPSG:3857@png/{z}/{x}/{y}.png?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeTransparentTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/Digitalglobe:OSMTransparentTMSTileService@EPSG:3857@png/{z}/{x}/{-y}.png/?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","tomtomKey":"DHH9SwEQ4MW55Hj2TfqMeldbsDjTdgAs","currentVehicleIndex":0,"handoffToken":"$2a$08$rOb/uqhm8I3QtSel2phOCOxNM51w43eqXDDksMkJ.1a5KsaQuLvEu$1751745334477","satelliteViewEnabled":true,"registeredDevicePermanent":true}}`)
|
||||||
|
}
|
||||||
|
// Handle SELECT_VEHICLE endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_SELECT_VEHICLE"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"vehicle","data":{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":"2023","modelCode":"PDL","engineSize":2.4,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"8KV8","licensePlateState":"NJ","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":["REMOTE","SAFETY","Retail3"],"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":["ABS_MIL","ACCS","AHBL_MIL","ATF_MIL","AWD_MIL","BSD","BSDRCT_MIL","CEL_MIL","CP1_5HHU","EBD_MIL","EOL_MIL","EPAS_MIL","EPB_MIL","ESS_MIL","EYESIGHT","ISS_MIL","MOONSTAT","OPL_MIL","PANPM-TUIRWAOC","PWAAADWWAP","RAB_MIL","RCC","REARBRK","RES","RESCC","RES_HVAC_HFS","RES_HVAC_VFS","RHSF","RPOI","RPOIA","RTGU","RVFS","SRH_MIL","SRS_MIL","SXM360L","T23DCM","TEL_MIL","TIF_35","TIR_33","TLD","TPMS_MIL","VALET","VDC_MIL","WASH_MIL","WDWSTAT","g3"],"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":"ACTIVE","authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":"Outback","subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":"Cosmic Blue Pearl","sunsetUpgraded":true,"intDescrip":"Black","transCode":"CVT","provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}}`)
|
||||||
|
}
|
||||||
|
// Handle API_G2_FETCH_RES_USER_PRESETS endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_G2_FETCH_RES_USER_PRESETS"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":null,"data":"[{\"name\":\"Cooling\",\"runTimeMinutes\":\"10\",\"climateZoneFrontTemp\":\"65\",\"climateZoneFrontAirMode\":\"FEET_FACE_BALANCED\",\"climateZoneFrontAirVolume\":\"7\",\"outerAirCirculation\":\"outsideAir\",\"heatedRearWindowActive\":\"false\",\"heatedSeatFrontLeft\":\"HIGH_COOL\",\"heatedSeatFrontRight\":\"HIGH_COOL\",\"airConditionOn\":\"false\",\"canEdit\":\"true\",\"disabled\":\"false\",\"presetType\":\"userPreset\",\"startConfiguration\":\"START_ENGINE_ALLOW_KEY_IN_IGNITION\"}]"}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ts := mockMySubaruApi(t, handler)
|
||||||
|
ts.Start()
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
cfg := makeConfig(t)
|
||||||
|
|
||||||
|
msc, err := New(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
if msc == nil {
|
||||||
|
t.Fatalf("expected MySubaru API client, got nil")
|
||||||
|
}
|
||||||
|
if !msc.isAuthenticated || !msc.isRegistered {
|
||||||
|
t.Errorf("expected authenticated and registered true, got %v %v", msc.isAuthenticated, msc.isRegistered)
|
||||||
|
}
|
||||||
|
if msc.currentVin != "1HGCM82633A004352" {
|
||||||
|
t.Errorf("expected currentVin 1HGCM82633A004352, got %v", msc.currentVin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetVehicleStatus_Success(t *testing.T) {
|
||||||
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Handle API_LOGIN endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_LOGIN"] && r.Method == http.MethodPost {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":"BIOMETRICS_DISABLED","dataName":"sessionData","data":{"sessionChanged":false,"vehicleInactivated":false,"account":{"marketId":1,"createdDate":1476984644000,"firstName":"Tatiana","lastName":"Savin","zipCode":"07974","accountKey":765268,"lastLoginDate":1751738613000,"zipCode5":"07974"},"resetPassword":false,"deviceId":"JddMBQXvAkgutSmEP6uFsThbq4QgEBBQ","sessionId":"9D7FCDF274794346689D3FA0D693CBBF","deviceRegistered":true,"passwordToken":null,"vehicles":[{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":null,"modelCode":null,"engineSize":null,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"","licensePlateState":"","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":null,"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":null,"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":null,"authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":null,"subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":null,"sunsetUpgraded":true,"intDescrip":null,"transCode":null,"provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}],"rightToRepairEnabled":true,"rightToRepairStartYear":2022,"rightToRepairStates":"MA","enableXtime":true,"termsAndConditionsAccepted":true,"digitalGlobeConnectId":"0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeImageTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/DigitalGlobe:ImageryTileService@EPSG:3857@png/{z}/{x}/{y}.png?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeTransparentTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/Digitalglobe:OSMTransparentTMSTileService@EPSG:3857@png/{z}/{x}/{-y}.png/?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","tomtomKey":"DHH9SwEQ4MW55Hj2TfqMeldbsDjTdgAs","currentVehicleIndex":0,"handoffToken":"$2a$08$rOb/uqhm8I3QtSel2phOCOxNM51w43eqXDDksMkJ.1a5KsaQuLvEu$1751745334477","satelliteViewEnabled":true,"registeredDevicePermanent":true}}`)
|
||||||
|
}
|
||||||
|
// Handle SELECT_VEHICLE endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_SELECT_VEHICLE"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"vehicle","data":{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":"2023","modelCode":"PDL","engineSize":2.4,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"8KV8","licensePlateState":"NJ","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":["REMOTE","SAFETY","Retail3"],"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":["ABS_MIL","ACCS","AHBL_MIL","ATF_MIL","AWD_MIL","BSD","BSDRCT_MIL","CEL_MIL","CP1_5HHU","EBD_MIL","EOL_MIL","EPAS_MIL","EPB_MIL","ESS_MIL","EYESIGHT","ISS_MIL","MOONSTAT","OPL_MIL","PANPM-TUIRWAOC","PWAAADWWAP","RAB_MIL","RCC","REARBRK","RES","RESCC","RES_HVAC_HFS","RES_HVAC_VFS","RHSF","RPOI","RPOIA","RTGU","RVFS","SRH_MIL","SRS_MIL","SXM360L","T23DCM","TEL_MIL","TIF_35","TIR_33","TLD","TPMS_MIL","VALET","VDC_MIL","WASH_MIL","WDWSTAT","g3"],"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":"ACTIVE","authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":"Outback","subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":"Cosmic Blue Pearl","sunsetUpgraded":true,"intDescrip":"Black","transCode":"CVT","provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}}`)
|
||||||
|
}
|
||||||
|
// Handle API_VEHICLE_STATUS endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_VEHICLE_STATUS"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":null,"data":{"vhsId":14662115789,"odometerValue":31694,"odometerValueKilometers":50996,"eventDate":1751742945000,"eventDateStr":"2025-07-05T19:15+0000","eventDateCarUser":1751742945000,"eventDateStrCarUser":"2025-07-05T19:15+0000","latitude":40.700153,"longitude":-74.401405,"positionHeadingDegree":"154","tirePressureFrontLeft":"2482","tirePressureFrontRight":"2482","tirePressureRearLeft":"2413","tirePressureRearRight":"2482","tirePressureFrontLeftPsi":"36","tirePressureFrontRightPsi":"36","tirePressureRearLeftPsi":"35","tirePressureRearRightPsi":"36","doorBootPosition":"CLOSED","doorEngineHoodPosition":"CLOSED","doorFrontLeftPosition":"CLOSED","doorFrontRightPosition":"CLOSED","doorRearLeftPosition":"CLOSED","doorRearRightPosition":"CLOSED","doorBootLockStatus":"LOCKED","doorFrontLeftLockStatus":"LOCKED","doorFrontRightLockStatus":"LOCKED","doorRearLeftLockStatus":"LOCKED","doorRearRightLockStatus":"LOCKED","distanceToEmptyFuelMiles":259.73,"distanceToEmptyFuelKilometers":418,"avgFuelConsumptionMpg":102.2,"avgFuelConsumptionLitersPer100Kilometers":2.3,"evStateOfChargePercent":null,"evDistanceToEmptyMiles":null,"evDistanceToEmptyKilometers":null,"evDistanceToEmptyByStateMiles":null,"evDistanceToEmptyByStateKilometers":null,"vehicleStateType":"IGNITION_OFF","windowFrontLeftStatus":"CLOSE","windowFrontRightStatus":"CLOSE","windowRearLeftStatus":"CLOSE","windowRearRightStatus":"CLOSE","windowSunroofStatus":"CLOSE","tyreStatusFrontLeft":"UNKNOWN","tyreStatusFrontRight":"UNKNOWN","tyreStatusRearLeft":"UNKNOWN","tyreStatusRearRight":"UNKNOWN","remainingFuelPercent":90,"distanceToEmptyFuelMiles10s":260,"distanceToEmptyFuelKilometers10s":420}}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ts := mockMySubaruApi(t, handler)
|
||||||
|
ts.Start()
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
cfg := makeConfig(t)
|
||||||
|
|
||||||
|
msc, err := New(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
if msc == nil {
|
||||||
|
t.Fatalf("expected MySubaru API client, got nil")
|
||||||
|
}
|
||||||
|
if !msc.isAuthenticated || !msc.isRegistered {
|
||||||
|
t.Errorf("expected authenticated and registered true, got %v %v", msc.isAuthenticated, msc.isRegistered)
|
||||||
|
}
|
||||||
|
if msc.currentVin != "1HGCM82633A004352" {
|
||||||
|
t.Errorf("expected currentVin 1HGCM82633A004352, got %v", msc.currentVin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetVehicleCondition_Success(t *testing.T) {
|
||||||
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Handle API_LOGIN endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_LOGIN"] && r.Method == http.MethodPost {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":"BIOMETRICS_DISABLED","dataName":"sessionData","data":{"sessionChanged":false,"vehicleInactivated":false,"account":{"marketId":1,"createdDate":1476984644000,"firstName":"Tatiana","lastName":"Savin","zipCode":"07974","accountKey":765268,"lastLoginDate":1751738613000,"zipCode5":"07974"},"resetPassword":false,"deviceId":"JddMBQXvAkgutSmEP6uFsThbq4QgEBBQ","sessionId":"9D7FCDF274794346689D3FA0D693CBBF","deviceRegistered":true,"passwordToken":null,"vehicles":[{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":null,"modelCode":null,"engineSize":null,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"","licensePlateState":"","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":null,"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":null,"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":null,"authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":null,"subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":null,"sunsetUpgraded":true,"intDescrip":null,"transCode":null,"provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}],"rightToRepairEnabled":true,"rightToRepairStartYear":2022,"rightToRepairStates":"MA","enableXtime":true,"termsAndConditionsAccepted":true,"digitalGlobeConnectId":"0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeImageTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/DigitalGlobe:ImageryTileService@EPSG:3857@png/{z}/{x}/{y}.png?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeTransparentTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/Digitalglobe:OSMTransparentTMSTileService@EPSG:3857@png/{z}/{x}/{-y}.png/?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","tomtomKey":"DHH9SwEQ4MW55Hj2TfqMeldbsDjTdgAs","currentVehicleIndex":0,"handoffToken":"$2a$08$rOb/uqhm8I3QtSel2phOCOxNM51w43eqXDDksMkJ.1a5KsaQuLvEu$1751745334477","satelliteViewEnabled":true,"registeredDevicePermanent":true}}`)
|
||||||
|
}
|
||||||
|
// Handle SELECT_VEHICLE endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_SELECT_VEHICLE"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"vehicle","data":{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":"2023","modelCode":"PDL","engineSize":2.4,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"8KV8","licensePlateState":"NJ","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":["REMOTE","SAFETY","Retail3"],"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":["ABS_MIL","ACCS","AHBL_MIL","ATF_MIL","AWD_MIL","BSD","BSDRCT_MIL","CEL_MIL","CP1_5HHU","EBD_MIL","EOL_MIL","EPAS_MIL","EPB_MIL","ESS_MIL","EYESIGHT","ISS_MIL","MOONSTAT","OPL_MIL","PANPM-TUIRWAOC","PWAAADWWAP","RAB_MIL","RCC","REARBRK","RES","RESCC","RES_HVAC_HFS","RES_HVAC_VFS","RHSF","RPOI","RPOIA","RTGU","RVFS","SRH_MIL","SRS_MIL","SXM360L","T23DCM","TEL_MIL","TIF_35","TIR_33","TLD","TPMS_MIL","VALET","VDC_MIL","WASH_MIL","WDWSTAT","g3"],"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":"ACTIVE","authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":"Outback","subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":"Cosmic Blue Pearl","sunsetUpgraded":true,"intDescrip":"Black","transCode":"CVT","provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}}`)
|
||||||
|
}
|
||||||
|
// Handle API_CONDITION endpoint
|
||||||
|
if (r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_CONDITION"], "g1") || r.URL.Path == MOBILE_API_VERSION+urlToGen(apiURLs["API_CONDITION"], "g2")) && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"remoteServiceStatus","data":{"serviceRequestId":null,"success":true,"cancelled":false,"remoteServiceType":"condition","remoteServiceState":"finished","subState":null,"errorCode":null,"result":{"avgFuelConsumption":null,"avgFuelConsumptionUnit":"MPG","distanceToEmptyFuel":null,"distanceToEmptyFuelUnit":"MILES","odometer":31692,"odometerUnit":"MILES","tirePressureFrontLeft":null,"tirePressureFrontLeftUnit":"PSI","tirePressureFrontRight":null,"tirePressureFrontRightUnit":"PSI","tirePressureRearLeft":null,"tirePressureRearLeftUnit":"PSI","tirePressureRearRight":null,"tirePressureRearRightUnit":"PSI","lastUpdatedTime":"2025-07-05T19:15:45.000+0000","windowFrontLeftStatus":"CLOSE","windowFrontRightStatus":"CLOSE","windowRearLeftStatus":"CLOSE","windowRearRightStatus":"CLOSE","windowSunroofStatus":"CLOSE","remainingFuelPercent":"90","evDistanceToEmpty":null,"evDistanceToEmptyUnit":null,"evChargerStateType":null,"evIsPluggedIn":null,"evStateOfChargeMode":null,"evTimeToFullyCharged":null,"evStateOfChargePercent":null,"vehicleStateType":"IGNITION_OFF","doorBootLockStatus":"LOCKED","doorBootPosition":"CLOSED","doorEngineHoodPosition":"CLOSED","doorFrontLeftLockStatus":"LOCKED","doorFrontLeftPosition":"CLOSED","doorFrontRightLockStatus":"LOCKED","doorFrontRightPosition":"CLOSED","doorRearLeftLockStatus":"LOCKED","doorRearLeftPosition":"CLOSED","doorRearRightLockStatus":"LOCKED","doorRearRightPosition":"CLOSED"},"updateTime":null,"vin":"1HGCM82633A004352","errorDescription":null}}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ts := mockMySubaruApi(t, handler)
|
||||||
|
ts.Start()
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
cfg := makeConfig(t)
|
||||||
|
|
||||||
|
msc, err := New(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
if msc == nil {
|
||||||
|
t.Fatalf("expected MySubaru API client, got nil")
|
||||||
|
}
|
||||||
|
if !msc.isAuthenticated || !msc.isRegistered {
|
||||||
|
t.Errorf("expected authenticated and registered true, got %v %v", msc.isAuthenticated, msc.isRegistered)
|
||||||
|
}
|
||||||
|
if msc.currentVin != "1HGCM82633A004352" {
|
||||||
|
t.Errorf("expected currentVin 1HGCM82633A004352, got %v", msc.currentVin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetVehicleHealth_Success(t *testing.T) {
|
||||||
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Handle API_LOGIN endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_LOGIN"] && r.Method == http.MethodPost {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":"BIOMETRICS_DISABLED","dataName":"sessionData","data":{"sessionChanged":false,"vehicleInactivated":false,"account":{"marketId":1,"createdDate":1476984644000,"firstName":"Tatiana","lastName":"Savin","zipCode":"07974","accountKey":765268,"lastLoginDate":1751738613000,"zipCode5":"07974"},"resetPassword":false,"deviceId":"JddMBQXvAkgutSmEP6uFsThbq4QgEBBQ","sessionId":"9D7FCDF274794346689D3FA0D693CBBF","deviceRegistered":true,"passwordToken":null,"vehicles":[{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":null,"modelCode":null,"engineSize":null,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"","licensePlateState":"","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":null,"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":null,"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":null,"authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":null,"subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":null,"sunsetUpgraded":true,"intDescrip":null,"transCode":null,"provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}],"rightToRepairEnabled":true,"rightToRepairStartYear":2022,"rightToRepairStates":"MA","enableXtime":true,"termsAndConditionsAccepted":true,"digitalGlobeConnectId":"0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeImageTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/DigitalGlobe:ImageryTileService@EPSG:3857@png/{z}/{x}/{y}.png?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","digitalGlobeTransparentTileService":"https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/Digitalglobe:OSMTransparentTMSTileService@EPSG:3857@png/{z}/{x}/{-y}.png/?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132","tomtomKey":"DHH9SwEQ4MW55Hj2TfqMeldbsDjTdgAs","currentVehicleIndex":0,"handoffToken":"$2a$08$rOb/uqhm8I3QtSel2phOCOxNM51w43eqXDDksMkJ.1a5KsaQuLvEu$1751745334477","satelliteViewEnabled":true,"registeredDevicePermanent":true}}`)
|
||||||
|
}
|
||||||
|
// Handle SELECT_VEHICLE endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_SELECT_VEHICLE"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":"vehicle","data":{"customer":{"sessionCustomer":null,"email":null,"firstName":null,"lastName":null,"zip":null,"oemCustId":null,"phone":null},"vehicleName":"Subaru Outback TXT","stolenVehicle":false,"vin":"1HGCM82633A004352","modelYear":"2023","modelCode":"PDL","engineSize":2.4,"nickname":"Subaru Outback TXT","vehicleKey":8211380,"active":true,"licensePlate":"8KV8","licensePlateState":"NJ","email":null,"firstName":null,"lastName":null,"subscriptionFeatures":["REMOTE","SAFETY","Retail3"],"accessLevel":-1,"zip":null,"oemCustId":"CRM-41PLM-5TYE","vehicleMileage":null,"phone":null,"timeZone":"America/New_York","features":["ABS_MIL","ACCS","AHBL_MIL","ATF_MIL","AWD_MIL","BSD","BSDRCT_MIL","CEL_MIL","CP1_5HHU","EBD_MIL","EOL_MIL","EPAS_MIL","EPB_MIL","ESS_MIL","EYESIGHT","ISS_MIL","MOONSTAT","OPL_MIL","PANPM-TUIRWAOC","PWAAADWWAP","RAB_MIL","RCC","REARBRK","RES","RESCC","RES_HVAC_HFS","RES_HVAC_VFS","RHSF","RPOI","RPOIA","RTGU","RVFS","SRH_MIL","SRS_MIL","SXM360L","T23DCM","TEL_MIL","TIF_35","TIR_33","TLD","TPMS_MIL","VALET","VDC_MIL","WASH_MIL","WDWSTAT","g3"],"userOemCustId":"CRM-41PLM-5TYE","subscriptionStatus":"ACTIVE","authorizedVehicle":false,"preferredDealer":null,"cachedStateCode":"NJ","modelName":"Outback","subscriptionPlans":[],"crmRightToRepair":false,"needMileagePrompt":false,"phev":null,"extDescrip":"Cosmic Blue Pearl","sunsetUpgraded":true,"intDescrip":"Black","transCode":"CVT","provisioned":true,"remoteServicePinExist":true,"needEmergencyContactPrompt":false,"vehicleGeoPosition":null,"show3gSunsetBanner":false}}`)
|
||||||
|
}
|
||||||
|
// Handle API_VEHICLE_HEALTH endpoint
|
||||||
|
if r.URL.Path == MOBILE_API_VERSION+apiURLs["API_VEHICLE_HEALTH"] && r.Method == http.MethodGet {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, `{"success":true,"errorCode":null,"dataName":null,"data":{"lastUpdatedDate":1751742945000,"vehicleHealthItems":[{"warningCode":10,"b2cCode":"airbag","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"SRS_MIL"},{"warningCode":4,"b2cCode":"oilTemp","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"ATF_MIL"},{"warningCode":39,"b2cCode":"blindspot","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"BSDRCT_MIL"},{"warningCode":2,"b2cCode":"engineFail","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"CEL_MIL"},{"warningCode":44,"b2cCode":"pkgBrake","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"EPB_MIL"},{"warningCode":8,"b2cCode":"ebd","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"EBD_MIL"},{"warningCode":3,"b2cCode":"oilWarning","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"EOL_MIL"},{"warningCode":1,"b2cCode":"washer","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"WASH_MIL"},{"warningCode":50,"b2cCode":"iss","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"ISS_MIL"},{"warningCode":53,"b2cCode":"oilPres","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"OPL_MIL"},{"warningCode":11,"b2cCode":"epas","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"EPAS_MIL"},{"warningCode":69,"b2cCode":"revBrake","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"RAB_MIL"},{"warningCode":14,"b2cCode":"telematics","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"TEL_MIL"},{"warningCode":9,"b2cCode":"tpms","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"TPMS_MIL"},{"warningCode":7,"b2cCode":"vdc","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"VDC_MIL"},{"warningCode":6,"b2cCode":"abs","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"ABS_MIL"},{"warningCode":5,"b2cCode":"awd","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"AWD_MIL"},{"warningCode":12,"b2cCode":"eyesight","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"ESS_MIL"},{"warningCode":30,"b2cCode":"ahbl","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"AHBL_MIL"},{"warningCode":31,"b2cCode":"srh","isTrouble":false,"onDates":[],"onDaiId":0,"featureCode":"SRH_MIL"}]}}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ts := mockMySubaruApi(t, handler)
|
||||||
|
ts.Start()
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
cfg := makeConfig(t)
|
||||||
|
|
||||||
|
msc, err := New(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
if msc == nil {
|
||||||
|
t.Fatalf("expected MySubaru API client, got nil")
|
||||||
|
}
|
||||||
|
if !msc.isAuthenticated || !msc.isRegistered {
|
||||||
|
t.Errorf("expected authenticated and registered true, got %v %v", msc.isAuthenticated, msc.isRegistered)
|
||||||
|
}
|
||||||
|
if msc.currentVin != "1HGCM82633A004352" {
|
||||||
|
t.Errorf("expected currentVin 1HGCM82633A004352, got %v", msc.currentVin)
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user