mirror of https://github.com/snachodog/mybuddy.git
513: Make nap user toggleable (#641)
* Add `nap` field, remove `napping` field. * Default `nap` property to NULL * Update existing tests * Format the code!! * Allow `Sleep.nap` to be blank * Migrate settings from `NAP_START_MIN` AND `NAP_START_MAX` * Remove `active` class from boolean fields * Correct test method name and user config * Add forms test * Use settings for Sleep nap model tests
This commit is contained in:
parent
a669decc88
commit
31a0aa4741
12
api/tests.py
12
api/tests.py
|
@ -527,15 +527,15 @@ class SleepAPITestCase(TestBase.BabyBuddyAPITestCaseBase):
|
|||
def test_get(self):
|
||||
response = self.client.get(self.endpoint)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(
|
||||
self.assertDictEqual(
|
||||
response.data["results"][0],
|
||||
{
|
||||
"id": 4,
|
||||
"child": 1,
|
||||
"start": "2017-11-18T19:00:00-05:00",
|
||||
"end": "2017-11-18T23:00:00-05:00",
|
||||
"duration": "04:00:00",
|
||||
"nap": False,
|
||||
"start": "2017-11-19T03:00:00-05:00",
|
||||
"end": "2017-11-19T04:30:00-05:00",
|
||||
"duration": "01:30:00",
|
||||
"nap": True,
|
||||
"notes": "lots of squirming",
|
||||
"tags": [],
|
||||
},
|
||||
|
@ -558,7 +558,7 @@ class SleepAPITestCase(TestBase.BabyBuddyAPITestCaseBase):
|
|||
endpoint = "{}{}/".format(self.endpoint, 4)
|
||||
response = self.client.get(endpoint)
|
||||
entry = response.data
|
||||
entry["end"] = "2017-11-18T23:30:00-05:00"
|
||||
entry["end"] = "2017-11-19T08:30:00-05:00"
|
||||
response = self.client.patch(
|
||||
endpoint,
|
||||
{
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
import os
|
||||
|
||||
from django.apps import AppConfig
|
||||
from django.conf import settings
|
||||
from django.db.models.signals import post_migrate
|
||||
|
||||
from dbsettings.loading import set_setting_value, setting_in_db
|
||||
|
||||
from babybuddy import VERSION
|
||||
|
||||
|
||||
|
@ -14,6 +17,39 @@ def create_read_only_group(sender, **kwargs):
|
|||
Group.objects.get_or_create(name=settings.BABY_BUDDY["READ_ONLY_GROUP_NAME"])
|
||||
|
||||
|
||||
def set_default_site_settings(sender, **kwargs):
|
||||
"""
|
||||
Sets default values for site-wide settings.
|
||||
|
||||
Based on `dbsettings.utils.set_defaults` which no longer seem to work in
|
||||
the latest versions of Django.
|
||||
"""
|
||||
from core import models
|
||||
|
||||
# Removed `NAP_START_MIN` and `NAP_START_MAX` values are referenced here
|
||||
# for pre-2.0.0 migrations.
|
||||
try:
|
||||
nap_start_min = datetime.datetime.strptime(
|
||||
os.environ.get("NAP_START_MIN"), "%H:%M"
|
||||
).time()
|
||||
except (TypeError, ValueError):
|
||||
nap_start_min = models.Sleep.settings.nap_start_min
|
||||
try:
|
||||
nap_start_max = datetime.datetime.strptime(
|
||||
os.environ.get("NAP_START_MAX"), "%H:%M"
|
||||
).time()
|
||||
except (TypeError, ValueError):
|
||||
nap_start_max = models.Sleep.settings.nap_start_max
|
||||
|
||||
defaults = (
|
||||
("Sleep", "nap_start_min", nap_start_min),
|
||||
("Sleep", "nap_start_max", nap_start_max),
|
||||
)
|
||||
for class_name, attribute_name, value in defaults:
|
||||
if not setting_in_db("core.models", class_name, attribute_name):
|
||||
set_setting_value("core.models", class_name, attribute_name, value)
|
||||
|
||||
|
||||
class BabyBuddyConfig(AppConfig):
|
||||
name = "babybuddy"
|
||||
verbose_name = "Baby Buddy"
|
||||
|
@ -25,3 +61,4 @@ class BabyBuddyConfig(AppConfig):
|
|||
commit = open(".git/refs/heads/master").read()
|
||||
self.version_string += " ({})".format(commit[0:7])
|
||||
post_migrate.connect(create_read_only_group, sender=self)
|
||||
post_migrate.connect(set_default_site_settings, sender=self)
|
||||
|
|
|
@ -332,10 +332,10 @@
|
|||
"fields":
|
||||
{
|
||||
"child": 1,
|
||||
"start": "2017-11-18T04:30:00Z",
|
||||
"start": "2017-11-17T20:30:00Z",
|
||||
"end": "2017-11-18T05:30:00Z",
|
||||
"duration": "01:00:00",
|
||||
"napping": false
|
||||
"duration": "09:00:00",
|
||||
"nap": false
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -347,7 +347,7 @@
|
|||
"start": "2017-11-18T15:00:00Z",
|
||||
"end": "2017-11-18T17:00:00Z",
|
||||
"duration": "02:00:00",
|
||||
"napping": true
|
||||
"nap": true
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -357,9 +357,9 @@
|
|||
{
|
||||
"child": 1,
|
||||
"start": "2017-11-18T19:00:00Z",
|
||||
"end": "2017-11-18T19:30:00Z",
|
||||
"duration": "00:30:00",
|
||||
"napping": false
|
||||
"end": "2017-11-19T04:30:00Z",
|
||||
"duration": "09:30:00",
|
||||
"nap": false
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -368,11 +368,11 @@
|
|||
"fields":
|
||||
{
|
||||
"child": 1,
|
||||
"start": "2017-11-19T00:00:00Z",
|
||||
"end": "2017-11-19T04:00:00Z",
|
||||
"duration": "04:00:00",
|
||||
"start": "2017-11-19T08:00:00Z",
|
||||
"end": "2017-11-19T09:30:00Z",
|
||||
"duration": "01:30:00",
|
||||
"notes": "lots of squirming",
|
||||
"napping": false
|
||||
"nap": true
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -8,6 +8,8 @@ from django.core.management import call_command
|
|||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.core.management.commands.flush import Command as Flush
|
||||
|
||||
from dbsettings.models import Setting
|
||||
|
||||
from .fake import Command as Fake
|
||||
from .migrate import Command as Migrate
|
||||
|
||||
|
@ -38,6 +40,9 @@ class Command(BaseCommand):
|
|||
if verbosity > 0:
|
||||
self.stdout.write(self.style.SUCCESS("Database flushed."))
|
||||
|
||||
# Remove all site-wide settings.
|
||||
Setting.objects.all().delete()
|
||||
|
||||
# Run migrations for all Baby Buddy apps.
|
||||
for config in apps.app_configs.values():
|
||||
if path.split(path.split(config.path)[0])[1] == "babybuddy":
|
||||
|
|
|
@ -19,3 +19,8 @@ EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
|
|||
# See https://django-axes.readthedocs.io/en/latest/4_configuration.html
|
||||
|
||||
AXES_ENABLED = False
|
||||
|
||||
# DBSettings configuration
|
||||
# See https://github.com/zlorf/django-dbsettings#a-note-about-caching
|
||||
|
||||
DBSETTINGS_USE_CACHE = False
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
{% else %}
|
||||
{{ field|add_class:"btn-check" }}
|
||||
{% endif %}
|
||||
<label for="id_{{ field.name }}" class="btn btn-outline-light btn-no-hover{% if field.value %} active{% endif %}">
|
||||
<label for="id_{{ field.name }}" class="btn btn-outline-light btn-no-hover">
|
||||
{{ field.label }}
|
||||
</label>
|
||||
{% elif 'choice' in field|field_type %}
|
||||
|
|
|
@ -27,7 +27,7 @@ class SiteSettingsTestCase(TestCase):
|
|||
is_superuser=True, is_staff=True, **cls.credentials
|
||||
)
|
||||
|
||||
def test_default_settings(self):
|
||||
def test_settings_default(self):
|
||||
self.c.login(**self.credentials)
|
||||
page = self.c.get("/settings/")
|
||||
self.assertEqual(page.status_code, 200)
|
||||
|
@ -40,9 +40,8 @@ class SiteSettingsTestCase(TestCase):
|
|||
"06:00:00",
|
||||
)
|
||||
|
||||
def test_nap_start_settings(self):
|
||||
def test_settings_nap_start(self):
|
||||
self.c.login(**self.credentials)
|
||||
self.assert_naps()
|
||||
params = {
|
||||
"core.models__Sleep__nap_start_max": "20:00:00",
|
||||
"core.models__Sleep__nap_start_min": "09:00:00",
|
||||
|
@ -57,17 +56,3 @@ class SiteSettingsTestCase(TestCase):
|
|||
Sleep.settings.nap_start_min.strftime("%H:%M:%S"),
|
||||
params["core.models__Sleep__nap_start_min"],
|
||||
)
|
||||
self.assert_naps()
|
||||
|
||||
def assert_naps(self):
|
||||
"""
|
||||
Asserts sleep instances filtered with nap start min and max match nap instances.
|
||||
"""
|
||||
instances = Sleep.objects.filter(
|
||||
start__time__range=(
|
||||
Sleep.settings.nap_start_min.strftime("%H:%M:%S"),
|
||||
Sleep.settings.nap_start_max.strftime("%H:%M:%S"),
|
||||
)
|
||||
)
|
||||
naps = Sleep.naps.all()
|
||||
self.assertQuerySetEqual(instances, naps)
|
||||
|
|
|
@ -21,9 +21,9 @@ class TemplateTagsTestCase(TestCase):
|
|||
)
|
||||
self.assertEqual(babybuddy.get_child_count(), 2)
|
||||
|
||||
def user_is_read_only(self):
|
||||
def test_user_is_read_only(self):
|
||||
user = get_user_model().objects.create_user(
|
||||
username="readonly", password="readonly", is_superuser=False, is_staf=False
|
||||
username="readonly", password="readonly", is_superuser=False, is_staff=False
|
||||
)
|
||||
self.assertFalse(babybuddy.user_is_read_only(user))
|
||||
|
||||
|
|
|
@ -62,7 +62,20 @@ def set_initial_values(kwargs, form_type):
|
|||
last_feed_args["method"] = last_method
|
||||
kwargs["initial"].update(last_feed_args)
|
||||
|
||||
# Remove custom kwargs so they do not interfere with `super` calls.
|
||||
# Set default "nap" value for Sleep instances.
|
||||
if form_type == SleepForm and "nap" not in kwargs["initial"]:
|
||||
try:
|
||||
start = timezone.localtime(kwargs["initial"]["start"]).time()
|
||||
except KeyError:
|
||||
start = timezone.localtime().time()
|
||||
nap = (
|
||||
models.Sleep.settings.nap_start_min
|
||||
<= start
|
||||
<= models.Sleep.settings.nap_start_max
|
||||
)
|
||||
kwargs["initial"].update({"nap": nap})
|
||||
|
||||
# Remove custom kwargs, so they do not interfere with `super` calls.
|
||||
for key in ["child", "timer"]:
|
||||
try:
|
||||
kwargs.pop(key)
|
||||
|
@ -181,7 +194,7 @@ class NoteForm(CoreModelForm, TaggableModelForm):
|
|||
class SleepForm(CoreModelForm, TaggableModelForm):
|
||||
class Meta:
|
||||
model = models.Sleep
|
||||
fields = ["child", "start", "end", "notes", "tags"]
|
||||
fields = ["child", "start", "end", "nap", "notes", "tags"]
|
||||
widgets = {
|
||||
"child": ChildRadioSelect,
|
||||
"start": DateTimeInput(),
|
||||
|
|
|
@ -20,7 +20,8 @@ class Migration(migrations.Migration):
|
|||
name="napping",
|
||||
field=models.BooleanField(null=True, verbose_name="Napping"),
|
||||
),
|
||||
migrations.RunPython(set_napping, reverse_code=migrations.RunPython.noop),
|
||||
# Migration superseded by 0028_alter_sleep_options_remove_sleep_napping_sleep_nap.py
|
||||
# migrations.RunPython(set_napping, reverse_code=migrations.RunPython.noop),
|
||||
migrations.AlterField(
|
||||
model_name="sleep",
|
||||
name="napping",
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
# Generated by Django 4.2 on 2023-05-07 00:28
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
def set_sleep_nap_values(apps, schema_editor):
|
||||
# The model must be imported to ensure its overridden `save` method is run.
|
||||
from core.models import Sleep
|
||||
|
||||
for sleep in Sleep.objects.all():
|
||||
sleep.nap = (
|
||||
Sleep.settings.nap_start_min
|
||||
<= timezone.localtime(sleep.start).time()
|
||||
<= Sleep.settings.nap_start_max
|
||||
)
|
||||
sleep.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("core", "0027_alter_timer_options_remove_timer_duration_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name="sleep",
|
||||
options={
|
||||
"default_permissions": ("view", "add", "change", "delete"),
|
||||
"ordering": ["-start"],
|
||||
"permissions": [("can_edit_sleep_settings", "Can edit Sleep settings")],
|
||||
"verbose_name": "Sleep",
|
||||
"verbose_name_plural": "Sleep",
|
||||
},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="sleep",
|
||||
name="napping",
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="sleep",
|
||||
name="nap",
|
||||
field=models.BooleanField(null=True, verbose_name="Nap"),
|
||||
),
|
||||
migrations.RunPython(
|
||||
set_sleep_nap_values, reverse_code=migrations.RunPython.noop
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="sleep",
|
||||
name="nap",
|
||||
field=models.BooleanField(blank=True, verbose_name="Nap"),
|
||||
),
|
||||
]
|
|
@ -418,12 +418,6 @@ class Note(models.Model):
|
|||
return str(_("Note"))
|
||||
|
||||
|
||||
class NapsManager(models.Manager):
|
||||
def get_queryset(self):
|
||||
qs = super(NapsManager, self).get_queryset()
|
||||
return qs.filter(id__in=[obj.id for obj in qs if obj.nap])
|
||||
|
||||
|
||||
class Pumping(models.Model):
|
||||
model_name = "pumping"
|
||||
child = models.ForeignKey(
|
||||
|
@ -459,7 +453,6 @@ class Sleep(models.Model):
|
|||
child = models.ForeignKey(
|
||||
"Child", on_delete=models.CASCADE, related_name="sleep", verbose_name=_("Child")
|
||||
)
|
||||
napping = models.BooleanField(editable=False, null=True, verbose_name=_("Napping"))
|
||||
start = models.DateTimeField(
|
||||
blank=False,
|
||||
default=timezone.localtime,
|
||||
|
@ -469,6 +462,7 @@ class Sleep(models.Model):
|
|||
end = models.DateTimeField(
|
||||
blank=False, default=timezone.localtime, null=False, verbose_name=_("End time")
|
||||
)
|
||||
nap = models.BooleanField(null=False, blank=True, verbose_name=_("Nap"))
|
||||
duration = models.DurationField(
|
||||
editable=False, null=True, verbose_name=_("Duration")
|
||||
)
|
||||
|
@ -476,7 +470,6 @@ class Sleep(models.Model):
|
|||
tags = TaggableManager(blank=True, through=Tagged)
|
||||
|
||||
objects = models.Manager()
|
||||
naps = NapsManager()
|
||||
settings = NapSettings(_("Nap settings"))
|
||||
|
||||
class Meta:
|
||||
|
@ -488,19 +481,15 @@ class Sleep(models.Model):
|
|||
def __str__(self):
|
||||
return str(_("Sleep"))
|
||||
|
||||
@property
|
||||
def nap(self):
|
||||
local_start_time = timezone.localtime(self.start).time()
|
||||
return (
|
||||
Sleep.settings.nap_start_min
|
||||
<= local_start_time
|
||||
<= Sleep.settings.nap_start_max
|
||||
)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.nap is None:
|
||||
self.nap = (
|
||||
Sleep.settings.nap_start_min
|
||||
<= timezone.localtime(self.start).time()
|
||||
<= Sleep.settings.nap_start_max
|
||||
)
|
||||
if self.start and self.end:
|
||||
self.duration = self.end - self.start
|
||||
self.napping = self.nap
|
||||
super(Sleep, self).save(*args, **kwargs)
|
||||
|
||||
def clean(self):
|
||||
|
|
|
@ -1,40 +1,40 @@
|
|||
child_id,start,end,notes
|
||||
1,2020-02-17 00:14:09,2020-02-17 02:48:09,
|
||||
1,2020-02-16 19:37:16,2020-02-16 22:43:16,
|
||||
1,2020-02-16 17:19:16,2020-02-16 19:00:16,
|
||||
1,2020-02-16 14:42:52,2020-02-16 16:35:52,
|
||||
1,2020-02-16 11:28:41,2020-02-16 13:21:41,
|
||||
1,2020-02-16 07:38:01,2020-02-16 08:55:01,
|
||||
1,2020-02-16 03:12:01,2020-02-16 06:17:01,
|
||||
1,2020-02-15 22:53:01,2020-02-16 01:21:01,Experience charge from woman fight. Court direction watch particular. Society price air difference chance consider find. Include word office story official statement life. Street kid develop enough need necessary.
|
||||
1,2020-02-15 17:37:21,2020-02-15 19:04:21,
|
||||
1,2020-02-15 14:32:21,2020-02-15 16:02:21,
|
||||
1,2020-02-15 11:38:21,2020-02-15 13:10:21,
|
||||
1,2020-02-15 07:51:45,2020-02-15 08:25:45,
|
||||
1,2020-02-15 03:06:24,2020-02-15 05:41:24,
|
||||
1,2020-02-14 21:58:58,2020-02-15 01:02:58,
|
||||
1,2020-02-14 18:41:28,2020-02-14 19:23:28,Chance rate see consider still according. Technology series key recognize. Rise avoid growth weight.
|
||||
1,2020-02-14 15:29:28,2020-02-14 16:57:28,Million tough many debate price. Tend south my home training free actually same. Mr imagine international.
|
||||
1,2020-02-14 12:12:28,2020-02-14 13:51:28,
|
||||
1,2020-02-14 07:41:40,2020-02-14 09:30:40,Mrs politics risk million education reach spring.
|
||||
1,2020-02-14 02:18:07,2020-02-14 05:29:07,
|
||||
1,2020-02-13 21:06:46,2020-02-13 23:40:46,
|
||||
1,2020-02-13 18:05:46,2020-02-13 19:40:46,
|
||||
1,2020-02-13 14:15:54,2020-02-13 15:40:54,
|
||||
1,2020-02-13 09:39:03,2020-02-13 11:38:03,
|
||||
1,2020-02-13 04:00:42,2020-02-13 08:03:42,
|
||||
1,2020-02-12 22:15:50,2020-02-13 01:46:50,
|
||||
1,2020-02-12 18:17:05,2020-02-12 19:35:05,
|
||||
1,2020-02-12 15:23:05,2020-02-12 16:43:05,
|
||||
1,2020-02-12 05:54:01,2020-02-12 11:48:01,Edge fact officer any.
|
||||
1,2020-02-11 21:00:14,2020-02-12 01:58:14,
|
||||
1,2020-02-11 17:33:04,2020-02-11 19:21:04,
|
||||
1,2020-02-11 14:51:04,2020-02-11 15:46:04,
|
||||
1,2020-02-11 12:49:10,2020-02-11 13:20:10,
|
||||
1,2020-02-11 08:30:34,2020-02-11 09:17:34,
|
||||
1,2020-02-11 06:35:34,2020-02-11 07:10:34,
|
||||
1,2020-02-10 23:56:34,2020-02-11 05:00:34,Image last next important. Style oil season talk family television.
|
||||
1,2020-02-10 18:39:49,2020-02-10 20:39:49,
|
||||
1,2020-02-10 14:44:33,2020-02-10 16:31:33,
|
||||
1,2020-02-10 10:25:06,2020-02-10 11:37:06,Other area cover military. Personal art decade guy. Traditional majority time term on life north. Leg drop most message within believe.
|
||||
1,2020-02-10 05:36:55,2020-02-10 07:48:55,
|
||||
child_id,start,nap,end,notes
|
||||
1,2020-02-17 00:14:09,0,2020-02-17 02:48:09,
|
||||
1,2020-02-16 19:37:16,0,2020-02-16 22:43:16,
|
||||
1,2020-02-16 17:19:16,1,2020-02-16 19:00:16,
|
||||
1,2020-02-16 14:42:52,1,2020-02-16 16:35:52,
|
||||
1,2020-02-16 11:28:41,1,2020-02-16 13:21:41,
|
||||
1,2020-02-16 07:38:01,1,2020-02-16 08:55:01,
|
||||
1,2020-02-16 03:12:01,0,2020-02-16 06:17:01,
|
||||
1,2020-02-15 22:53:01,0,2020-02-16 01:21:01,Experience charge from woman fight. Court direction watch particular. Society price air difference chance consider find. Include word office story official statement life. Street kid develop enough need necessary.
|
||||
1,2020-02-15 17:37:21,1,2020-02-15 19:04:21,
|
||||
1,2020-02-15 14:32:21,1,2020-02-15 16:02:21,
|
||||
1,2020-02-15 11:38:21,1,2020-02-15 13:10:21,
|
||||
1,2020-02-15 07:51:45,1,2020-02-15 08:25:45,
|
||||
1,2020-02-15 03:06:24,0,2020-02-15 05:41:24,
|
||||
1,2020-02-14 21:58:58,0,2020-02-15 01:02:58,
|
||||
1,2020-02-14 18:41:28,1,2020-02-14 19:23:28,Chance rate see consider still according. Technology series key recognize. Rise avoid growth weight.
|
||||
1,2020-02-14 15:29:28,1,2020-02-14 16:57:28,Million tough many debate price. Tend south my home training free actually same. Mr imagine international.
|
||||
1,2020-02-14 12:12:28,1,2020-02-14 13:51:28,
|
||||
1,2020-02-14 07:41:40,1,2020-02-14 09:30:40,Mrs politics risk million education reach spring.
|
||||
1,2020-02-14 02:18:07,0,2020-02-14 05:29:07,
|
||||
1,2020-02-13 21:06:46,0,2020-02-13 23:40:46,
|
||||
1,2020-02-13 18:05:46,0,2020-02-13 19:40:46,
|
||||
1,2020-02-13 14:15:54,1,2020-02-13 15:40:54,
|
||||
1,2020-02-13 09:39:03,1,2020-02-13 11:38:03,
|
||||
1,2020-02-13 04:00:42,0,2020-02-13 08:03:42,
|
||||
1,2020-02-12 22:15:50,0,2020-02-13 01:46:50,
|
||||
1,2020-02-12 18:17:05,1,2020-02-12 19:35:05,
|
||||
1,2020-02-12 15:23:05,1,2020-02-12 16:43:05,
|
||||
1,2020-02-12 05:54:01,0,2020-02-12 11:48:01,Edge fact officer any.
|
||||
1,2020-02-11 21:00:14,0,2020-02-12 01:58:14,
|
||||
1,2020-02-11 17:33:04,1,2020-02-11 19:21:04,
|
||||
1,2020-02-11 14:51:04,1,2020-02-11 15:46:04,
|
||||
1,2020-02-11 12:49:10,1,2020-02-11 13:20:10,
|
||||
1,2020-02-11 08:30:34,1,2020-02-11 09:17:34,
|
||||
1,2020-02-11 06:35:34,0,2020-02-11 07:10:34,
|
||||
1,2020-02-10 23:56:34,0,2020-02-11 05:00:34,Image last next important. Style oil season talk family television.
|
||||
1,2020-02-10 18:39:49,1,2020-02-10 20:39:49,
|
||||
1,2020-02-10 14:44:33,1,2020-02-10 16:31:33,
|
||||
1,2020-02-10 10:25:06,1,2020-02-10 11:37:06,Other area cover military. Personal art decade guy. Traditional majority time term on life north. Leg drop most message within believe.
|
||||
1,2020-02-10 05:36:55,0,2020-02-10 07:48:55,
|
||||
|
|
|
|
@ -545,6 +545,26 @@ class SleepFormsTestCase(FormsTestCaseBase):
|
|||
self.assertEqual(page.status_code, 200)
|
||||
self.assertContains(page, "Sleep entry deleted")
|
||||
|
||||
def test_nap_default(self):
|
||||
models.Sleep.settings.nap_start_min = (
|
||||
timezone.now() - timezone.timedelta(hours=1)
|
||||
).time()
|
||||
models.Sleep.settings.nap_start_max = (
|
||||
timezone.now() + timezone.timedelta(hours=1)
|
||||
).time()
|
||||
response = self.c.get("/sleep/add/")
|
||||
self.assertTrue(response.context["form"].initial["nap"])
|
||||
|
||||
def test_not_nap_default(self):
|
||||
models.Sleep.settings.nap_start_min = (
|
||||
timezone.now() + timezone.timedelta(hours=1)
|
||||
).time()
|
||||
models.Sleep.settings.nap_start_max = (
|
||||
timezone.now() + timezone.timedelta(hours=2)
|
||||
).time()
|
||||
response = self.c.get("/sleep/add/")
|
||||
self.assertFalse(response.context["form"].initial["nap"])
|
||||
|
||||
|
||||
class TaggedFormsTestCase(FormsTestCaseBase):
|
||||
@classmethod
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from datetime import datetime
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.core.management import call_command
|
||||
from django.test import TestCase
|
||||
|
@ -210,6 +212,42 @@ class SleepTestCase(TestCase):
|
|||
self.assertEqual(str(sleep), "Sleep")
|
||||
self.assertEqual(sleep.duration, sleep.end - sleep.start)
|
||||
|
||||
def test_sleep_nap(self):
|
||||
models.Sleep.settings.nap_start_min = (
|
||||
timezone.now() - timezone.timedelta(hours=1)
|
||||
).time()
|
||||
models.Sleep.settings.nap_start_max = (
|
||||
timezone.now() + timezone.timedelta(hours=1)
|
||||
).time()
|
||||
sleep = models.Sleep.objects.create(
|
||||
child=self.child,
|
||||
start=timezone.now(),
|
||||
end=(timezone.now() + timezone.timedelta(hours=2)),
|
||||
)
|
||||
self.assertTrue(sleep.nap)
|
||||
|
||||
def test_sleep_not_nap(self):
|
||||
models.Sleep.settings.nap_start_min = (
|
||||
timezone.now() + timezone.timedelta(hours=1)
|
||||
).time()
|
||||
models.Sleep.settings.nap_start_max = (
|
||||
timezone.now() + timezone.timedelta(hours=2)
|
||||
).time()
|
||||
sleep = models.Sleep.objects.create(
|
||||
child=self.child,
|
||||
start=timezone.now(),
|
||||
end=(timezone.now() + timezone.timedelta(hours=8)),
|
||||
)
|
||||
self.assertFalse(sleep.nap)
|
||||
|
||||
sleep = models.Sleep.objects.create(
|
||||
child=self.child,
|
||||
start=timezone.now(),
|
||||
end=(timezone.now() + timezone.timedelta(hours=8)),
|
||||
nap=True,
|
||||
)
|
||||
self.assertTrue(sleep.nap)
|
||||
|
||||
|
||||
class TagTestCase(TestCase):
|
||||
def setUp(self):
|
||||
|
|
|
@ -324,9 +324,9 @@ def card_sleep_naps_day(context, child, date=None):
|
|||
"""
|
||||
if not date:
|
||||
date = timezone.localtime().date()
|
||||
instances = models.Sleep.naps.filter(child=child).filter(
|
||||
instances = models.Sleep.objects.filter(child=child, nap=True).filter(
|
||||
start__year=date.year, start__month=date.month, start__day=date.day
|
||||
) | models.Sleep.naps.filter(child=child).filter(
|
||||
) | models.Sleep.objects.filter(child=child, nap=True).filter(
|
||||
end__year=date.year, end__month=date.month, end__day=date.day
|
||||
)
|
||||
empty = len(instances) == 0
|
||||
|
@ -548,7 +548,7 @@ def _nap_statistics(child):
|
|||
:param child: an instance of the Child model.
|
||||
:returns: a dictionary of statistics.
|
||||
"""
|
||||
instances = models.Sleep.naps.filter(child=child).order_by("start")
|
||||
instances = models.Sleep.objects.filter(child=child, nap=True).order_by("start")
|
||||
if len(instances) == 0:
|
||||
return False
|
||||
naps = {
|
||||
|
|
|
@ -216,10 +216,10 @@ class TemplateTagsTestCase(TestCase):
|
|||
self.assertEqual(data["type"], "sleep")
|
||||
self.assertFalse(data["empty"])
|
||||
self.assertFalse(data["hide_empty"])
|
||||
self.assertEqual(data["sleeps"][0]["total"], timezone.timedelta(hours=7))
|
||||
self.assertEqual(data["sleeps"][0]["count"], 4)
|
||||
self.assertEqual(data["sleeps"][0]["total"], timezone.timedelta(seconds=43200))
|
||||
self.assertEqual(data["sleeps"][0]["count"], 3)
|
||||
|
||||
self.assertEqual(data["sleeps"][1]["total"], timezone.timedelta(minutes=30))
|
||||
self.assertEqual(data["sleeps"][1]["total"], timezone.timedelta(seconds=30600))
|
||||
self.assertEqual(data["sleeps"][1]["count"], 1)
|
||||
|
||||
def test_card_sleep_naps_day(self):
|
||||
|
@ -227,8 +227,8 @@ class TemplateTagsTestCase(TestCase):
|
|||
self.assertEqual(data["type"], "sleep")
|
||||
self.assertFalse(data["empty"])
|
||||
self.assertFalse(data["hide_empty"])
|
||||
self.assertEqual(data["total"], timezone.timedelta(0, 9000))
|
||||
self.assertEqual(data["count"], 2)
|
||||
self.assertEqual(data["total"], timezone.timedelta(0, 7200))
|
||||
self.assertEqual(data["count"], 1)
|
||||
|
||||
def test_card_statistics(self):
|
||||
data = cards.card_statistics(self.context, self.child)
|
||||
|
@ -271,18 +271,18 @@ class TemplateTagsTestCase(TestCase):
|
|||
},
|
||||
{
|
||||
"title": "Average nap duration",
|
||||
"stat": timezone.timedelta(0, 4500),
|
||||
"stat": timezone.timedelta(0, 6300),
|
||||
"type": "duration",
|
||||
},
|
||||
{"title": "Average naps per day", "stat": 2.0, "type": "float"},
|
||||
{"title": "Average naps per day", "stat": 1.0, "type": "float"},
|
||||
{
|
||||
"title": "Average sleep duration",
|
||||
"stat": timezone.timedelta(0, 6750),
|
||||
"stat": timezone.timedelta(0, 19800),
|
||||
"type": "duration",
|
||||
},
|
||||
{
|
||||
"title": "Average awake duration",
|
||||
"stat": timezone.timedelta(0, 19200),
|
||||
"stat": timezone.timedelta(0, 18000),
|
||||
"type": "duration",
|
||||
},
|
||||
{"title": "Weight change per week", "stat": 1.0, "type": "float"},
|
||||
|
|
Loading…
Reference in New Issue