diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..b0338d0 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,7 @@ +[run] +parallel=True +concurrency=thread +omit = + psa_connectedcar/* + venv/* + test/* diff --git a/requirements-dev.txt b/requirements-dev.txt index 6bcd162..d0f5a46 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,3 +2,4 @@ prospector>=1.3.0 pre-commit coverage deepdiff +selenium \ No newline at end of file diff --git a/test/test_front.py b/test/test_front.py new file mode 100644 index 0000000..6767d1d --- /dev/null +++ b/test/test_front.py @@ -0,0 +1,116 @@ +# flake8: noqa +import os +import threading +import unittest +from time import sleep + +import flask +from flask import request +import requests as http_requests +from selenium.common.exceptions import WebDriverException +from selenium import webdriver +from selenium.webdriver.chrome.options import Options + +from libs.charging import Charging +from libs.elec_price import ElecPrice +from my_psacc import MyPSACC +from web.db import Database +from test.utils import get_new_test_db, record_position, DB_DIR, vehicule_list, record_charging + +IP = "localhost" +PORT = 5000 +URL = f"http://{IP}:{PORT}" + + +def wait_for_start(driver, url): + for _ in range(0, 20): + try: + driver.get(url) + break + except WebDriverException: + sleep(0.5) + + +def openTab(driver, n): + driver.find_element_by_id("tabs").find_elements_by_class_name("nav-item")[n].click() + + +def getDriver(): + chrome_options = Options() + if not os.environ.get("NO_HEADLESS", "0") == "1": + chrome_options.add_argument("--headless") + driver = webdriver.Chrome(options=chrome_options) + driver.implicitly_wait(10) + return driver + +def shutdown(): + """Shutdown the Werkzeug dev server, if we're using it. + From http://flask.pocoo.org/snippets/67/""" + func = flask.request.environ.get('werkzeug.server.shutdown') + if func is None: # pragma: no cover + raise RuntimeError('Not running with the Werkzeug Server') + func() + return 'Server shutting down...' + + +def shutdown_server(): + func = request.environ.get('werkzeug.server.shutdown') + if func is None: + raise RuntimeError('Not running with the Werkzeug Server') + func() + return "" + + +class ServerThread(threading.Thread): + init = False + + def run(self): + import web.app + web.app.myp = MyPSACC(None, "None", None, None, None, "clientsB2CPeugeot", "FR") + web.app.myp.vehicles_list = vehicule_list + Charging.elec_price = ElecPrice.read_config() + Database.DEFAULT_DB_FILE = DB_DIR + config = web.app.config_flask("My car info", "/", False, IP, PORT, reloader=False, unminified=False) + web.app.app.add_url_rule('/exit', 'home', view_func=shutdown_server) + web.app.run(config) + + def stop(self): + http_requests.get(URL + "/exit") + + +class FrontTest(unittest.TestCase): + def __init__(self, methodName='runTest'): + super().__init__(methodName) + + def test_trips_only(self): + get_new_test_db() + driver = getDriver() + flask_app = ServerThread() + record_position() + flask_app.start() + wait_for_start(driver, URL) + assert driver.find_element_by_id("avg_consum_kw").text == "24.2" + openTab(driver, 1) + assert "29 km/h" in driver.find_element_by_id("trips-table").text + flask_app.stop() + flask_app.join() + driver.quit() + + def test_charge_only(self): + get_new_test_db() + driver = getDriver() + flask_app = ServerThread() + record_charging() + flask_app.start() + wait_for_start(driver, URL) + assert "-" != driver.find_element_by_id("avg_emission_kw") + assert "18.6" == driver.find_element_by_id("avg_chg_speed").text + openTab(driver, 2) + assert "18.86 kWh" in driver.find_element_by_id("battery-table").text + flask_app.stop() + flask_app.join() + driver.quit() + + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_unit.py b/test/test_unit.py index c3141ea..a792ed6 100644 --- a/test/test_unit.py +++ b/test/test_unit.py @@ -12,23 +12,17 @@ from libs.elec_price import ElecPrice from my_psacc import MyPSACC from ecomix import Ecomix from libs.car_model import CarModel -from mylogger import my_logger, logger +from mylogger import my_logger from otp.otp import load_otp, save_otp from charge_control import ChargeControls +from test.utils import DATA_DIR, record_position, latitude, longitude, date0, date1, date2, date3, record_charging, \ + vehicule_list, get_new_test_db from trip import Trips from libs.utils import get_temp from web.db import Database from web.figures import get_figures, get_battery_curve_fig, get_altitude_fig -import pytz from deepdiff import DeepDiff -latitude = 47.2183 -longitude = -1.55362 -date3 = datetime.utcnow().replace(2021, 3, 1, 12, 00, 00, 00, tzinfo=pytz.UTC) -date2 = date3 - timedelta(minutes=20) -date1 = date3 - timedelta(minutes=40) -date0 = date3 - timedelta(minutes=60) -DATA_DIR = os.path.dirname(os.path.realpath(__file__)) + "/data/" def compare_dict(result, expected): @@ -50,20 +44,7 @@ class TestUnit(unittest.TestCase): def __init__(self, methodName='runTest'): super().__init__(methodName) self.test_online = os.environ.get("TEST_ONLINE", "0") == "1" - self.vehicule_list = Cars() - self.vehicule_list.extend( - [Car("VR3UHZKX", "vid", "Peugeot"), Car("VXXXXX", "XXXX", "Peugeot", label="SUV 3008")]) - - @staticmethod - def get_new_test_db(): - try: - os.remove(DATA_DIR + "tmp.db") - except: - pass - Database.DEFAULT_DB_FILE = DATA_DIR + "tmp.db" - Database.db_initialized = False - conn = Database.get_db() - return conn + self.vehicule_list = vehicule_list def test_car(self): car1 = Car("VRAAAAAAA", "1sdfdksnfk222", "Peugeot", "208", 46, 0) @@ -118,27 +99,12 @@ class TestUnit(unittest.TestCase): charge_control.save_config(force=True) def test_battery_curve(self): - from libs.car import Car - from libs.charging import Charging - try: - os.remove("tmp.db") - except: - pass - Database.DEFAULT_DB_FILE = "tmp.db" - conn = Database.get_db() - list(map(dict, conn.execute('PRAGMA database_list').fetchall())) - vin = "VR3UHZKXZL" - car = Car(vin, "id", "Peugeot") - Charging.record_charging(car, "InProgress", date0, 50, latitude, longitude, "FR", "slow",20,60) - Charging.record_charging(car, "InProgress", date1, 75, latitude, longitude, "FR", "slow",20,60) - Charging.record_charging(car, "InProgress", date2, 85, latitude, longitude, "FR", "slow",20,60) - Charging.record_charging(car, "InProgress", date3, 90, latitude, longitude, "FR", "slow",20,60) - - res = Database.get_battery_curve(Database.get_db(), date0, vin) + get_new_test_db() + record_charging() + res = Database.get_battery_curve(Database.get_db(), date0, self.vehicule_list[0].vin) assert len(res) == 3 def test_sdk(self): - res = { 'lastPosition': {'type': 'Feature', 'geometry': {'type': 'Point', 'coordinates': [9.65457, 49.96119, 21]}, 'properties': {'updatedAt': '2021-03-29T05:16:10Z', 'heading': 126, @@ -163,7 +129,7 @@ class TestUnit(unittest.TestCase): status: psacc.models.status.Status = api._ApiClient__deserialize(res, "Status") geocode_res = reverse_geocode.search([(status.last_position.geometry.coordinates[:2])[::-1]])[0] assert geocode_res["country_code"] == "DE" - TestUnit.get_new_test_db() + get_new_test_db() car = Car("XX", "vid", "Peugeot") car.status = status myp = MyPSACC.load_config(DATA_DIR + "config.json") @@ -173,12 +139,10 @@ class TestUnit(unittest.TestCase): assert car.status.energy[0].type == 'Electric' def test_record_position_charging(self): - TestUnit.get_new_test_db() + get_new_test_db() ElecPrice.CONFIG_FILENAME = DATA_DIR + "config.ini" car = self.vehicule_list[0] - Database.record_position(None, car.vin, 11, latitude, longitude - 0.05, None, date0, 40, None, False) - Database.record_position(None, car.vin, 20, latitude, longitude, 32, date1, 35, None, False) - Database.record_position(None, car.vin, 30, latitude, longitude, 42, date2, 30, None, False) + record_position() Database.add_altitude_to_db(Database.get_db()) data = json.loads(Database.get_recorded_position()) assert data["features"][1]["geometry"]["coordinates"] == [float(longitude), float(latitude)] @@ -221,7 +185,7 @@ class TestUnit(unittest.TestCase): assert get_altitude_fig(trip) is not None def test_fuel_car(self): - TestUnit.get_new_test_db() + get_new_test_db() ElecPrice.CONFIG_FILENAME = DATA_DIR + "config.ini" car = self.vehicule_list[1] Database.record_position(None, car.vin, 11, latitude, longitude, 22, date0, 40, 30, False) @@ -245,7 +209,7 @@ class TestUnit(unittest.TestCase): def test_db_callback(self): old_dummy_value = dummy_value - TestUnit.get_new_test_db() + get_new_test_db() Database.set_db_callback(callback_test) assert old_dummy_value == dummy_value Database.record_position(None, "xx", 11, latitude, longitude - 0.05, None, date0, 40, None, False) diff --git a/test/utils.py b/test/utils.py new file mode 100644 index 0000000..5dc2ab9 --- /dev/null +++ b/test/utils.py @@ -0,0 +1,46 @@ +# flake8: noqa + +import os +from datetime import timedelta, datetime + +import pytz + +from libs.car import Car, Cars +from libs.charging import Charging +from web.db import Database + +DATA_DIR = os.path.dirname(os.path.realpath(__file__)) + "/data/" +latitude = 47.2183 +longitude = -1.55362 +date3 = datetime.utcnow().replace(2021, 3, 1, 12, 00, 00, 00, tzinfo=pytz.UTC) +date2 = date3 - timedelta(minutes=20) +date1 = date3 - timedelta(minutes=40) +date0 = date3 - timedelta(minutes=60) +date4 = date3 + timedelta(minutes=1) + +vehicule_list = Cars() +vehicule_list.extend( + [Car("VR3UHZKX", "vid", "Peugeot"), Car("VXXXXX", "XXXX", "Peugeot", label="SUV 3008")]) +car=vehicule_list[0] +DB_DIR = DATA_DIR + "tmp.db" +def get_new_test_db(): + try: + os.remove(DATA_DIR + "tmp.db") + except: + pass + Database.DEFAULT_DB_FILE = DB_DIR + Database.db_initialized = False + conn = Database.get_db() + return conn + +def record_position(): + Database.record_position(None, car.vin, 11, latitude, longitude - 0.05, None, date0, 40, None, False) + Database.record_position(None, car.vin, 20, latitude, longitude, 32, date1, 35, None, False) + Database.record_position(None, car.vin, 30, latitude, longitude, 42, date2, 30, None, False) + +def record_charging(): + Charging.record_charging(car, "InProgress", date0, 50, latitude, longitude, "FR", "slow", 20, 60) + Charging.record_charging(car, "InProgress", date1, 75, latitude, longitude, "FR", "slow", 20, 60) + Charging.record_charging(car, "InProgress", date2, 85, latitude, longitude, "FR", "slow", 20, 60) + Charging.record_charging(car, "InProgress", date3, 90, latitude, longitude, "FR", "slow", 20, 60) + Charging.record_charging(car, "Stopped", date4, 91, latitude, longitude, "FR", "slow", 20, 60) \ No newline at end of file