Skip to content

Commit

Permalink
more coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
koukihai committed Mar 1, 2024
1 parent d64ee7f commit 5e118e7
Show file tree
Hide file tree
Showing 8 changed files with 489 additions and 2 deletions.
4 changes: 2 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import logging
import os
import tempfile
from contextlib import contextmanager

import pytest
import yaml
import pytest
import logging


@contextmanager
Expand Down
82 changes: 82 additions & 0 deletions tests/test_ajax_ecowatt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import ast
import logging
from datetime import datetime
from json import JSONDecodeError
from dateutil.relativedelta import relativedelta
import pytest

from db_schema import Ecowatt
from tests.conftest import contains_logline


@pytest.mark.parametrize("response, status_code, expect_exception, expect_success", [
(None, 200, False, False),
(None, 500, True, False),
({"2099-01-01": {"value": 9000, "message": "mock message", "detail": "mock detail"}}, 200, False, True)
])
def test_fetch_ecowatt_empty(mocker, caplog, requests_mock, response, status_code, expect_exception, expect_success):
from models.ajax import Ajax
from config import URL

start = (datetime.now() - relativedelta(years=3)).strftime("%Y-%m-%d")
end = (datetime.now() + relativedelta(days=3)).strftime("%Y-%m-%d")

m_db_get_ecowatt = mocker.patch("models.database.Database.get_ecowatt")
m_db_set_ecowatt = mocker.patch("models.database.Database.set_ecowatt")

m_db_get_ecowatt.return_value = []
requests_mock.get(f"{URL}/rte/ecowatt/{start}/{end}", json=response, status_code=status_code)

ajax = Ajax()

# FIXME: In case the status_code is not 200 and the response is not a valid json, an exception is raised
if expect_exception:
with pytest.raises(JSONDecodeError):
ajax.fetch_ecowatt()
else:
res = ajax.fetch_ecowatt()
if expect_success:
assert res == response

assert m_db_get_ecowatt.call_count == 1
assert m_db_set_ecowatt.call_count == 1

assert not contains_logline(caplog, "{'error': True, 'description': 'Erreur "
"lors de la récupération des données Ecowatt.'}", logging.ERROR)
else:
assert res == "OK"

assert m_db_get_ecowatt.call_count == 1
assert m_db_set_ecowatt.call_count == 0

assert contains_logline(caplog, "{'error': True, 'description': 'Erreur "
"lors de la récupération des données Ecowatt.'}", logging.ERROR)


@pytest.mark.parametrize("response, expect_exception, expect_success", [
(None, True, False),
([Ecowatt(date="2099-01-01", value=9000, message="mock message", detail="{'detail': 'mock detail'}")], False, True)
])
def test_get_ecowatt(mocker, caplog, response, expect_exception, expect_success):
from models.ajax import Ajax

m_db_get_ecowatt = mocker.patch("models.database.Database.get_ecowatt")
m_db_get_ecowatt.return_value = response
m_db_set_ecowatt = mocker.patch("models.database.Database.set_ecowatt")

ajax = Ajax()

# FIXME: In case the status_code is not 200 and the response is not a valid json, an exception is raised
if expect_exception:
with pytest.raises(TypeError):
ajax.get_ecowatt()
else:
res = ajax.get_ecowatt()
assert res == {r.date: {"value": r.value, "message": r.message, "detail": ast.literal_eval(r.detail)} for r in
response}

assert m_db_get_ecowatt.call_count == 1
assert m_db_set_ecowatt.call_count == 0

assert not contains_logline(caplog, "{'error': True, 'description': 'Erreur "
"lors de la récupération des données Ecowatt.'}", logging.ERROR)
87 changes: 87 additions & 0 deletions tests/test_ajax_get_account_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import logging

import pytest

from tests.conftest import contains_logline


@pytest.mark.parametrize("usage_point_id", ["pdl1"])
@pytest.mark.parametrize(
"status_response, status_code",
[
({"detail": "truthy response"}, 300),
({"detail": "falsy response"}, 500),
(
{
"consent_expiration_date": "2099-01-01T00:00:00",
"call_number": 42,
"quota_limit": 42,
"quota_reached": 42,
"quota_reset_at": "2099-01-01T00:00:00.000000",
"ban": False,
},
200,
),
],
)
def test_get_account_status(mocker, usage_point_id, caplog, status_response, status_code, requests_mock):
from models.ajax import Ajax
from config import URL

default_error_message = 'Erreur lors de la récupération du statut du compte.'

m_usage_point_update = mocker.patch("models.database.Database.usage_point_update")
m_set_error_log = mocker.patch("models.database.Database.set_error_log")

requests_mocks = list()
requests_mocks.append(requests_mock.get(
f"{URL}/valid_access/{usage_point_id}/cache", json=status_response, status_code=status_code
))

ajax = Ajax(usage_point_id=usage_point_id) if usage_point_id else Ajax()

is_complete = {
"consent_expiration_date",
"call_number",
"quota_limit",
"quota_reached",
"quota_reset_at",
"ban",
}.issubset(set(status_response.keys()))
is_truthy_response = 200 <= status_code < 400

res = ajax.account_status()

if is_truthy_response:
if status_code != 200 or not is_complete:
assert contains_logline(caplog, status_response.get('detail', default_error_message), logging.ERROR)
assert res == {'description': status_response.get('detail', default_error_message), 'error': True, 'last_call': None}

# db.usage_point_update is not called
assert 0 == m_usage_point_update.call_count
# FIXME: db.set_error_log is not called, because returned errors are missing status_code and description.detail
assert 0 == m_set_error_log.call_count

if is_complete and status_code == 200:
# Successful case: db is updated & set_error_log is called with None
assert 1 == m_usage_point_update.call_count
# FIXME: Ajax does not use set_error_log while Job does
assert 0 == m_set_error_log.call_count
assert res == {**status_response, "last_call": None}

if not is_truthy_response:
# FIXME: If response(500), no error is displayed
assert not contains_logline(caplog, "Erreur lors de la récupération des informations du compte", logging.ERROR)
# FIXME: Ajax does not use set_error_log while Job does
assert 0 == m_set_error_log.call_count
assert res == {'description': status_response,
'error': True,
'last_call': None,
'status_code': status_code}

# Ensuring {URL}/valid_access/{usage_point_id} is called exactly as many times as enabled usage_points
# and only once per enabled usage_point
for rm in requests_mocks:
assert len(rm.request_history) == 1

assert contains_logline(caplog, "[PDL1] CHECK DU STATUT DU COMPTE.", logging.INFO)
41 changes: 41 additions & 0 deletions tests/test_ajax_get_gateway_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import logging
from json import JSONDecodeError

import pytest

from tests.conftest import contains_logline


@pytest.mark.parametrize("usage_point_id", [None, "pdl1"])
@pytest.mark.parametrize("response, status_code", [(None, 200), (None, 500), ({"mock": "response"}, 200)])
def test_get_gateway_status(caplog, requests_mock, response, status_code, usage_point_id):
from models.ajax import Ajax
from config import URL
from dependencies import get_version

requests_mock.get(f"{URL}/ping", json=response, status_code=status_code)

ajax = Ajax(usage_point_id=usage_point_id) if usage_point_id else Ajax()

# FIXME: In case the status_code is 200 and the response is not a valid json, an exception is raised
if status_code == 200 and not response:
with pytest.raises(JSONDecodeError):
ajax.gateway_status()
else:
res = ajax.gateway_status()
if status_code != 200:
assert res == {'information': 'MyElectricalData injoignable.',
'status': False,
'version': get_version()}
# FIXME: No error is logged
assert (
"ERROR root:jobs.py:170 Erreur lors de la récupération du statut de la passerelle :\n"
not in caplog.text
)
else:
assert res == {'mock': 'response', 'version': get_version()}

if usage_point_id:
assert contains_logline(caplog, f"[{usage_point_id.upper()}] CHECK DE L'ÉTAT DE LA PASSERELLE.", logging.INFO)
else:
assert contains_logline(caplog, f"CHECK DE L'ÉTAT DE LA PASSERELLE.", logging.INFO)
80 changes: 80 additions & 0 deletions tests/test_ajax_tempo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import logging
from datetime import datetime
from json import JSONDecodeError
from dateutil.relativedelta import relativedelta
import pytest

from db_schema import Tempo
from tests.conftest import contains_logline


@pytest.mark.parametrize("response, status_code",
[(None, 200), (None, 500), ({"mock": "response"}, 200), ({"2099-01-01": "turquoise"}, 200)])
def test_fetch_tempo(mocker, caplog, requests_mock, response, status_code):
from models.ajax import Ajax
from config import URL

start = (datetime.now() - relativedelta(years=3)).strftime("%Y-%m-%d")
end = (datetime.now() + relativedelta(days=2)).strftime("%Y-%m-%d")

m_db_get_tempo = mocker.patch("models.database.Database.get_tempo")
m_db_set_tempo_config = mocker.patch("models.database.Database.set_tempo_config")
m_db_set_tempo = mocker.patch("models.database.Database.set_tempo")

requests_mock.get(f"{URL}/rte/tempo/{start}/{end}", json=response, status_code=status_code)
requests_mock.get(f"{URL}/edf/tempo/days", json=response, status_code=status_code)
requests_mock.get(f"{URL}/edf/tempo/price", json=response, status_code=status_code)

ajax = Ajax()

# FIXME: In case the status_code is not 200 and the response is not a valid json, an exception is raised
if status_code != 200 and not response:
with pytest.raises(JSONDecodeError):
ajax.fetch_tempo()
else:
res = ajax.fetch_tempo()
if status_code == 200 and response and response.get("2099-01-01"):
assert res == response

assert m_db_get_tempo.call_count == 1
assert m_db_set_tempo.call_count == 1
assert m_db_set_tempo_config.call_count == 0

assert not contains_logline(caplog, "{'error': True, 'description': 'Erreur lors "
"de la récupération de données Tempo.'}", logging.ERROR)
else:
assert res == "OK"

assert m_db_get_tempo.call_count == 1
assert m_db_set_tempo.call_count == 0
assert m_db_set_tempo_config.call_count == 0

assert contains_logline(caplog, "{'error': True, 'description': 'Erreur lors "
"de la récupération de données Tempo.'}", logging.ERROR)


@pytest.mark.parametrize("response", [None, [Tempo(date="2099-01-01", color="turquoise")]])
def test_get_tempo(mocker, caplog, response):
from models.ajax import Ajax

m_db_get_tempo = mocker.patch("models.database.Database.get_tempo")
m_db_get_tempo.return_value = response
m_db_set_tempo_config = mocker.patch("models.database.Database.set_tempo_config")
m_db_set_tempo = mocker.patch("models.database.Database.set_tempo")

ajax = Ajax()

# FIXME: In case the status_code is not 200 and the response is not a valid json, an exception is raised
if not response:
with pytest.raises(TypeError):
ajax.get_tempo()
else:
res = ajax.get_tempo()
assert res == {r.date: r.color for r in response}

assert m_db_get_tempo.call_count == 1
assert m_db_set_tempo.call_count == 0
assert m_db_set_tempo_config.call_count == 0

assert not contains_logline(caplog, "{'error': True, 'description': 'Erreur lors "
"de la récupération de données Tempo.'}", logging.ERROR)
Loading

0 comments on commit 5e118e7

Please sign in to comment.