Skip to content

Commit

Permalink
Add Report class and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dalonsoa committed Jan 16, 2024
1 parent d78c635 commit c7e7d62
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 6 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ jobs:
run: |
python -m pip install --upgrade pip wheel
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Run migrations
run: python manage.py migrate
- name: Run tests
Expand Down
45 changes: 42 additions & 3 deletions measurement/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,51 @@ class Meta:
default_permissions = ()
abstract = True
indexes = [
models.Index(fields=["station", "variable", "time"]),
models.Index(fields=["variable", "station", "time"]),
models.Index(fields=["time", "station", "variable"]),
models.Index(fields=["station", "time", "variable"]),
]


class ReportType(models.TextChoices):
HOURLY = "hourly"
DAILY = "daily"
MONTLY = "monthly"


class Report(MeasurementBase):
"""Holds the different reporting data.
It also keeps track of which data has already been used when creating the reports.
"""

report_type = models.CharField(max_length=7, choices=ReportType.choices, null=False)
used_for_daily = models.BooleanField(
verbose_name="Has data been used already for a daily report?", default=False
)
used_for_monthly = models.BooleanField(
verbose_name="Has data been used already for a montly report?", default=False
)

class Meta:
default_permissions = ()
indexes = [
models.Index(fields=["report_type", "station", "time", "variable"]),
]

def clean(self) -> None:
"""Validate that the report type and use of the data is consistent."""
if self.used_for_daily and self.report_type != ReportType.HOURLY:
raise ValueError(
"Only hourly data can be used for daily report calculations."
)
if self.used_for_monthly and self.report_type != ReportType.DAILY:
raise ValueError(
"Only daily data can be used for monthly report calculations."
)


## Legacy models - to be removed


class PermissionsMeasurement(models.Model):
"""
Model used to define the permission "validar".
Expand Down
3 changes: 2 additions & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
black
isort
flake8
pre-commit
pre-commit
model_bakery
56 changes: 54 additions & 2 deletions tests/measurement/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import pytz
from django.test import TestCase
from model_bakery import baker


class TestModelCreation(TestCase):
Expand Down Expand Up @@ -46,8 +47,9 @@ def test_precipitation(self):
def test_timescale_query(self):
from measurement.models import Flow

start_time, end_time = datetime(2015, 1, 1, tzinfo=pytz.UTC), datetime(
2016, 11, 10, tzinfo=pytz.UTC
start_time, end_time = (
datetime(2015, 1, 1, tzinfo=pytz.UTC),
datetime(2016, 11, 10, tzinfo=pytz.UTC),
)
query = Flow.timescale.filter(time__range=[start_time, end_time], station_id=1)
self.assertEqual(len(query), 2)
Expand All @@ -65,3 +67,53 @@ def test_query_ordering(self):
query = Precipitation.timescale.filter(station_id=2).order_by("-time")
self.assertEqual(query[0].time.year, 2018)
self.assertEqual(query[1].time.year, 2017)


class TestReport(TestCase):
def setUp(self) -> None:
from measurement.models import Report, ReportType
from station.models import Station
from variable.models import Variable

station = baker.make(Station)
variable = baker.make(Variable)
self.model: Report = Report(
time=datetime(2018, 1, 9, 23, 55, 59, tzinfo=pytz.UTC),
station=station,
variable=variable,
value=42,
report_type=ReportType.HOURLY,
)

def test_clean(self):
from measurement.models import ReportType

# We check 'used_for_daily' compatibility
# Works if report type is Hourly
self.model.used_for_daily = True
self.model.clean()

# But fails for the other two
self.model.report_type = ReportType.DAILY
with self.assertRaises(ValueError):
self.model.clean()

self.model.report_type = ReportType.MONTLY
with self.assertRaises(ValueError):
self.model.clean()

# We check 'used_for_monthly' compatibility
# Works if report type is Daily
self.model.used_for_daily = False
self.model.used_for_monthly = True
self.model.report_type = ReportType.DAILY
self.model.clean()

# But not for the other two
self.model.report_type = ReportType.HOURLY
with self.assertRaises(ValueError):
self.model.clean()

self.model.report_type = ReportType.MONTLY
with self.assertRaises(ValueError):
self.model.clean()

0 comments on commit c7e7d62

Please sign in to comment.