python-irceline/tests/test_belaqi.py

267 lines
9.4 KiB
Python

from datetime import date, timedelta, datetime
import pytest
from freezegun import freeze_time
from src.open_irceline.api import IrcelineForecastClient, IrcelineRioClient
from src.open_irceline.belaqi import belaqi_index_forecast_daily, belaqi_index_rio_hourly, belaqi_index_hourly, \
belaqi_index_daily
from src.open_irceline.data import BelAqiIndex
from tests.conftest import get_mock_session_many_csv, get_mock_session
@pytest.mark.parametrize("pm10, pm25, o3, no2, expected", [
(5, 2, 25, 5, BelAqiIndex.EXCELLENT),
(15, 5, 50, 12, BelAqiIndex.VERY_GOOD),
(30, 9, 70, 18, BelAqiIndex.GOOD),
(40, 13, 80, 25, BelAqiIndex.FAIRLY_GOOD),
(55, 18, 100, 35, BelAqiIndex.MODERATE),
(70, 25, 130, 43, BelAqiIndex.POOR),
(90, 45, 160, 48, BelAqiIndex.VERY_POOR),
(100, 55, 200, 55, BelAqiIndex.BAD),
(130, 70, 230, 70, BelAqiIndex.VERY_BAD),
(150, 80, 250, 80, BelAqiIndex.HORRIBLE),
(150, 80, 300, 80, BelAqiIndex.HORRIBLE),
(95, 5, 25, 5, BelAqiIndex.VERY_POOR),
(145, 5, 25, 5, BelAqiIndex.HORRIBLE),
(5, 55, 25, 5, BelAqiIndex.BAD),
(5, 85, 25, 5, BelAqiIndex.HORRIBLE),
(5, 5, 190, 5, BelAqiIndex.BAD),
(5, 5, 260, 5, BelAqiIndex.HORRIBLE),
(5, 5, 25, 65, BelAqiIndex.VERY_BAD),
(5, 5, 25, 85, BelAqiIndex.HORRIBLE),
(45, 15, 150, 10, BelAqiIndex.POOR),
(20, 25, 180, 15, BelAqiIndex.VERY_POOR),
(10, 7, 250, 70, BelAqiIndex.HORRIBLE),
(110, 3, 30, 25, BelAqiIndex.BAD),
(5, 0, 0, 0, BelAqiIndex.EXCELLENT),
(15, 0, 0, 0, BelAqiIndex.VERY_GOOD),
(30, 0, 0, 0, BelAqiIndex.GOOD),
(40, 0, 0, 0, BelAqiIndex.FAIRLY_GOOD),
(55, 0, 0, 0, BelAqiIndex.MODERATE),
(70, 0, 0, 0, BelAqiIndex.POOR),
(90, 0, 0, 0, BelAqiIndex.VERY_POOR),
(100, 0, 0, 0, BelAqiIndex.BAD),
(130, 0, 0, 0, BelAqiIndex.VERY_BAD),
(150, 0, 0, 0, BelAqiIndex.HORRIBLE),
(0, 2, 0, 0, BelAqiIndex.EXCELLENT),
(0, 5, 0, 0, BelAqiIndex.VERY_GOOD),
(0, 9, 0, 0, BelAqiIndex.GOOD),
(0, 13, 0, 0, BelAqiIndex.FAIRLY_GOOD),
(0, 18, 0, 0, BelAqiIndex.MODERATE),
(0, 25, 0, 0, BelAqiIndex.POOR),
(0, 45, 0, 0, BelAqiIndex.VERY_POOR),
(0, 55, 0, 0, BelAqiIndex.BAD),
(0, 70, 0, 0, BelAqiIndex.VERY_BAD),
(0, 80, 0, 0, BelAqiIndex.HORRIBLE),
(0, 0, 25, 0, BelAqiIndex.EXCELLENT),
(0, 0, 50, 0, BelAqiIndex.VERY_GOOD),
(0, 0, 70, 0, BelAqiIndex.GOOD),
(0, 0, 80, 0, BelAqiIndex.FAIRLY_GOOD),
(0, 0, 100, 0, BelAqiIndex.MODERATE),
(0, 0, 130, 0, BelAqiIndex.POOR),
(0, 0, 160, 0, BelAqiIndex.VERY_POOR),
(0, 0, 200, 0, BelAqiIndex.BAD),
(0, 0, 230, 0, BelAqiIndex.VERY_BAD),
(0, 0, 250, 0, BelAqiIndex.HORRIBLE),
(0, 0, 0, 5, BelAqiIndex.EXCELLENT),
(0, 0, 0, 12, BelAqiIndex.VERY_GOOD),
(0, 0, 0, 18, BelAqiIndex.GOOD),
(0, 0, 0, 25, BelAqiIndex.FAIRLY_GOOD),
(0, 0, 0, 35, BelAqiIndex.MODERATE),
(0, 0, 0, 43, BelAqiIndex.POOR),
(0, 0, 0, 48, BelAqiIndex.VERY_POOR),
(0, 0, 0, 55, BelAqiIndex.BAD),
(0, 0, 0, 70, BelAqiIndex.VERY_BAD),
(0, 0, 0, 80, BelAqiIndex.HORRIBLE)
])
def test_belaqi_index_hourly(pm10, pm25, o3, no2, expected):
assert belaqi_index_hourly(pm10, pm25, o3, no2) == expected
@pytest.mark.parametrize("pm10, pm25, o3, no2, expected_index", [
(5, 0, 0, 0, BelAqiIndex.EXCELLENT),
(15, 0, 0, 0, BelAqiIndex.VERY_GOOD),
(25, 0, 0, 0, BelAqiIndex.GOOD),
(35, 0, 0, 0, BelAqiIndex.FAIRLY_GOOD),
(45, 0, 0, 0, BelAqiIndex.MODERATE),
(60, 0, 0, 0, BelAqiIndex.POOR),
(70, 0, 0, 0, BelAqiIndex.VERY_POOR),
(80, 0, 0, 0, BelAqiIndex.BAD),
(100, 0, 0, 0, BelAqiIndex.VERY_BAD),
(101, 0, 0, 0, BelAqiIndex.HORRIBLE),
(0, 2.5, 0, 0, BelAqiIndex.EXCELLENT),
(0, 5, 0, 0, BelAqiIndex.VERY_GOOD),
(0, 7.5, 0, 0, BelAqiIndex.GOOD),
(0, 10, 0, 0, BelAqiIndex.FAIRLY_GOOD),
(0, 15, 0, 0, BelAqiIndex.MODERATE),
(0, 25, 0, 0, BelAqiIndex.POOR),
(0, 35, 0, 0, BelAqiIndex.VERY_POOR),
(0, 40, 0, 0, BelAqiIndex.BAD),
(0, 50, 0, 0, BelAqiIndex.VERY_BAD),
(0, 51, 0, 0, BelAqiIndex.HORRIBLE),
(0, 0, 30, 0, BelAqiIndex.EXCELLENT),
(0, 0, 60, 0, BelAqiIndex.VERY_GOOD),
(0, 0, 70, 0, BelAqiIndex.GOOD),
(0, 0, 80, 0, BelAqiIndex.FAIRLY_GOOD),
(0, 0, 100, 0, BelAqiIndex.MODERATE),
(0, 0, 130, 0, BelAqiIndex.POOR),
(0, 0, 160, 0, BelAqiIndex.VERY_POOR),
(0, 0, 190, 0, BelAqiIndex.BAD),
(0, 0, 220, 0, BelAqiIndex.VERY_BAD),
(0, 0, 221, 0, BelAqiIndex.HORRIBLE),
(0, 0, 0, 5, BelAqiIndex.EXCELLENT),
(0, 0, 0, 10, BelAqiIndex.VERY_GOOD),
(0, 0, 0, 15, BelAqiIndex.GOOD),
(0, 0, 0, 20, BelAqiIndex.FAIRLY_GOOD),
(0, 0, 0, 25, BelAqiIndex.MODERATE),
(0, 0, 0, 30, BelAqiIndex.POOR),
(0, 0, 0, 35, BelAqiIndex.VERY_POOR),
(0, 0, 0, 40, BelAqiIndex.BAD),
(0, 0, 0, 50, BelAqiIndex.VERY_BAD),
(0, 0, 0, 51, BelAqiIndex.HORRIBLE),
(3, 1, 20, 4, BelAqiIndex.EXCELLENT),
(10, 3, 50, 8, BelAqiIndex.VERY_GOOD),
(20, 6, 65, 12, BelAqiIndex.GOOD),
(30, 8, 75, 18, BelAqiIndex.FAIRLY_GOOD),
(40, 12, 90, 22, BelAqiIndex.MODERATE),
(50, 20, 110, 28, BelAqiIndex.POOR),
(65, 30, 140, 33, BelAqiIndex.VERY_POOR),
(75, 38, 180, 38, BelAqiIndex.BAD),
(90, 45, 200, 45, BelAqiIndex.VERY_BAD),
(110, 55, 230, 55, BelAqiIndex.HORRIBLE),
(3, 30, 20, 8, BelAqiIndex.VERY_POOR),
(110, 6, 65, 12, BelAqiIndex.HORRIBLE),
(3, 6, 230, 12, BelAqiIndex.HORRIBLE),
(3, 6, 65, 55, BelAqiIndex.HORRIBLE),
(50, 5, 65, 12, BelAqiIndex.POOR),
(10, 20, 65, 12, BelAqiIndex.POOR),
(10, 5, 110, 12, BelAqiIndex.POOR),
(10, 5, 65, 28, BelAqiIndex.POOR),
(75, 5, 30, 8, BelAqiIndex.BAD),
(10, 38, 30, 8, BelAqiIndex.BAD),
(10, 5, 180, 8, BelAqiIndex.BAD),
(10, 5, 30, 38, BelAqiIndex.BAD),
(65, 3, 20, 22, BelAqiIndex.VERY_POOR),
(3, 30, 20, 22, BelAqiIndex.VERY_POOR),
(3, 3, 140, 22, BelAqiIndex.VERY_POOR),
(3, 3, 20, 33, BelAqiIndex.VERY_POOR),
(90, 6, 20, 22, BelAqiIndex.VERY_BAD),
(10, 45, 20, 22, BelAqiIndex.VERY_BAD),
(10, 6, 200, 22, BelAqiIndex.VERY_BAD),
(10, 6, 20, 45, BelAqiIndex.VERY_BAD),
(3, 30, 20, 4, BelAqiIndex.VERY_POOR),
(110, 1, 20, 4, BelAqiIndex.HORRIBLE),
(3, 1, 230, 4, BelAqiIndex.HORRIBLE),
(3, 1, 20, 55, BelAqiIndex.HORRIBLE),
(50, 3, 20, 4, BelAqiIndex.POOR),
(3, 20, 20, 4, BelAqiIndex.POOR),
(3, 1, 110, 4, BelAqiIndex.POOR),
(3, 1, 20, 28, BelAqiIndex.POOR),
])
def test_belaqi_index_daily(pm10, pm25, o3, no2, expected_index):
assert belaqi_index_daily(pm10, pm25, o3, no2) == expected_index
def test_belaqi_hourly_value_error():
with pytest.raises(ValueError):
belaqi_index_hourly(-1, 0, 12, 8)
with pytest.raises(ValueError):
belaqi_index_hourly(1, -20, 12, 8)
with pytest.raises(ValueError):
belaqi_index_hourly(1, 0, -12, 8)
with pytest.raises(ValueError):
belaqi_index_hourly(1, 0, 12, -8888)
def test_belaqi_daily_value_error():
with pytest.raises(ValueError):
belaqi_index_daily(-1, 0, 12, 8)
with pytest.raises(ValueError):
belaqi_index_daily(1, -20, 12, 8)
with pytest.raises(ValueError):
belaqi_index_daily(1, 0, -12, 8)
with pytest.raises(ValueError):
belaqi_index_daily(1, 0, 12, -8888)
def test_belaqi_hourly_value_error_none():
with pytest.raises(ValueError):
belaqi_index_hourly(None, 0, 12, 8)
with pytest.raises(ValueError):
belaqi_index_hourly(1, None, 12, 8)
with pytest.raises(ValueError):
belaqi_index_hourly(1, 0, None, 8)
with pytest.raises(ValueError):
belaqi_index_hourly(1, 0, 12, None)
def test_belaqi_daily_value_error_none():
with pytest.raises(ValueError):
belaqi_index_daily(None, 0, 12, 8)
with pytest.raises(ValueError):
belaqi_index_daily(1, None, 12, 8)
with pytest.raises(ValueError):
belaqi_index_daily(1, 0, None, 8)
with pytest.raises(ValueError):
belaqi_index_daily(1, 0, 12, None)
@freeze_time(datetime.fromisoformat("2024-06-19T19:30:09.581Z"))
async def test_belaqi_index_forecast():
session = get_mock_session_many_csv()
client = IrcelineForecastClient(session)
pos = (50.55, 4.85)
result = await belaqi_index_forecast_daily(client, pos)
expected_days = {date(2024, 6, 19) + timedelta(days=i) for i in range(5)}
assert set(result.keys()) == expected_days
for v in result.values():
assert v == BelAqiIndex.MODERATE
async def test_belaqi_index_forecast_missing_day():
session = get_mock_session_many_csv()
client = IrcelineForecastClient(session)
pos = (50.55, 4.85)
result = await belaqi_index_forecast_daily(client, pos, date(2024, 6, 21))
expected_days = {date(2024, 6, 21) + timedelta(days=i) for i in range(5)}
assert set(result.keys()) == expected_days
for v in result.values():
assert v is None
@freeze_time(datetime.fromisoformat("2024-06-23T12:30:09.581Z"))
async def test_belaqi_index_actual():
session = get_mock_session(json_file='rio_wfs_for_belaqi.json')
client = IrcelineRioClient(session)
pos = (50.55, 4.85)
result = await belaqi_index_rio_hourly(client, pos)
assert result == BelAqiIndex.GOOD
@freeze_time(datetime.fromisoformat("2024-06-23T12:30:09.581Z"))
async def test_belaqi_index_actual_missing_value():
session = get_mock_session(json_file='rio_wfs.json')
client = IrcelineRioClient(session)
pos = (50.55, 4.85)
with pytest.raises(ValueError):
_ = await belaqi_index_rio_hourly(client, pos)