defmodule TeslaMate.VehicleCase do use ExUnit.CaseTemplate using do quote do import Ecto import Ecto.Changeset import Ecto.Query import TeslaMate.VehicleCase end end setup tags do pid = Ecto.Adapters.SQL.Sandbox.start_owner!(TeslaMate.Repo, shared: not tags[:async]) on_exit(fn -> Ecto.Adapters.SQL.Sandbox.stop_owner(pid) end) :ok rescue e in [MatchError] -> case e.term do {:error, {{:badmatch, :already_shared}, _}} -> :ok _ -> reraise e, __STACKTRACE__ end end alias TeslaMate.Vehicles.Vehicle alias TeslaMate.Settings.CarSettings alias TeslaMate.Log.{Car, Update} alias TeslaApi.Vehicle.State def start_vehicle(name, events, opts \\ []) when length(events) > 0 do mock_log? = Keyword.get(opts, :log, true) last = Keyword.get(opts, :last_update, %Update{version: "9999.99.99.0 lasjas234"}) log_name = :"log_#{name}" api_name = :"api_#{name}" settings_name = :"settings_#{name}" locations_name = :"locations_#{name}" vehicles_name = :"vehicles_#{name}" pubsub_name = :"pubsub_#{name}" {:ok, _pid} = start_supervised({LogMock, name: log_name, pid: self(), last_update: last}) {:ok, _pid} = start_supervised({ApiMock, name: api_name, events: events, pid: self()}) {:ok, _pid} = start_supervised({SettingsMock, name: settings_name, pid: self()}) {:ok, _pid} = start_supervised({VehiclesMock, name: vehicles_name, pid: self()}) {:ok, _pid} = start_supervised({PubSubMock, name: pubsub_name, pid: self()}) {:ok, _pid} = start_supervised({LocationsMock, name: locations_name, pid: self()}) opts = Keyword.put_new_lazy(opts, :car, fn -> settings = Keyword.get(opts, :settings, %{}) |> Map.put_new(:req_no_shift_state_reading, false) |> Map.put_new(:req_no_temp_reading, false) |> Map.put_new(:req_not_unlocked, true) %Car{ id: :rand.uniform(65536), eid: 0, vid: 1000, vin: "1000", model: "3", settings: struct(CarSettings, settings) } end) deps = [ name: name, deps_log: {LogMock, log_name}, deps_api: {ApiMock, api_name}, deps_settings: {SettingsMock, settings_name}, deps_locations: {LocationsMock, locations_name}, deps_vehicles: {VehiclesMock, vehicles_name}, deps_pubsub: {PubSubMock, pubsub_name} ] |> Enum.filter(fn {:deps_log, _} -> mock_log? _ -> true end) {:ok, _pid} = start_supervised({Vehicle, Keyword.merge(opts, deps)}) assert_receive {SettingsMock, :subscribe_to_changes} :ok end def online_event(opts \\ []) do now = DateTime.utc_now() |> DateTime.to_unix(:millisecond) drive_state = Keyword.get(opts, :drive_state, %{latitude: 0.0, longitude: 0.0}) |> Map.update(:timestamp, now, fn nil -> now ts -> ts end) charge_state = Keyword.get(opts, :charge_state, %{timestamp: 0}) climate_state = Keyword.get(opts, :climate_state, %{timestamp: 0}) vehicle_state = Keyword.get(opts, :vehicle_state, %{timestamp: 0, car_version: ""}) vehicle_config = Keyword.get(opts, :vehicle_config, %{timestamp: 0, car_type: "model3"}) %TeslaApi.Vehicle{ state: "online", display_name: Keyword.get(opts, :display_name), charge_state: struct(State.Charge, charge_state), drive_state: struct(State.Drive, drive_state), climate_state: struct(State.Climate, climate_state), vehicle_state: struct(State.VehicleState, vehicle_state), vehicle_config: struct(State.VehicleConfig, vehicle_config) } end def drive_event(ts, shift_state, speed_mph) do online_event( drive_state: %{ timestamp: ts, latitude: 0.1, longitude: 0.1, shift_state: shift_state, speed: speed_mph } ) end def charging_event(ts, charging_state, charge_energy_added, opts \\ []) do range = Keyword.get(opts, :range) online_event( charge_state: %{ timestamp: ts, charging_state: charging_state, charge_energy_added: charge_energy_added, ideal_battery_range: range, battery_range: range }, drive_state: %{timestamp: ts, latitude: 0.0, longitude: 0.0} ) end def update_event(ts, state, car_version, opts \\ []) do alias TeslaApi.Vehicle.State.VehicleState.SoftwareUpdate update_version = Keyword.get(opts, :update_version) online_event( vehicle_state: %{ timestamp: ts, car_version: car_version, software_update: %SoftwareUpdate{ expected_duration_sec: 2700, status: state, version: update_version } }, drive_state: %{timestamp: ts, latitude: 0.0, longitude: 0.0} ) end end