Skip to content

Commit

Permalink
Merge db9b6fc into f81ec53
Browse files Browse the repository at this point in the history
  • Loading branch information
johnchase committed Apr 20, 2020
2 parents f81ec53 + db9b6fc commit c621649
Show file tree
Hide file tree
Showing 9 changed files with 428 additions and 85 deletions.
15 changes: 7 additions & 8 deletions budget/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,17 @@ class Migration(migrations.Migration):

initial = True

dependencies = [
]
dependencies = []

operations = [
migrations.CreateModel(
name='Expenses',
name="Expenses",
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('amount', models.FloatField()),
('date', models.DateField()),
('category', models.CharField(max_length=50)),
('business', models.CharField(max_length=50, null=True)),
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("amount", models.FloatField()),
("date", models.DateField()),
("category", models.CharField(max_length=50)),
("business", models.CharField(max_length=50, null=True)),
],
),
]
43 changes: 43 additions & 0 deletions budget/migrations/0003_auto_20200411_0010.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Generated by Django 3.0.2 on 2020-04-11 00:10

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('budget', '0002_auto_20191121_0219'),
]

operations = [
migrations.AlterModelOptions(
name='expense',
options={'ordering': ['-date']},
),
migrations.AddField(
model_name='expense',
name='budget_calculation',
field=models.BooleanField(null=True),
),
migrations.AddField(
model_name='expense',
name='budget_category',
field=models.CharField(default='Purchase', max_length=50),
preserve_default=False,
),
migrations.AddField(
model_name='expense',
name='description',
field=models.CharField(blank=True, max_length=200, null=True),
),
migrations.AlterField(
model_name='expense',
name='business',
field=models.CharField(blank=True, max_length=50, null=True),
),
migrations.AlterField(
model_name='expense',
name='date',
field=models.DateTimeField(),
),
]
7 changes: 5 additions & 2 deletions budget/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ class Expense(models.Model):
"""Expense model class."""

amount = models.FloatField(null=False)
date = models.DateField(null=False)
date = models.DateTimeField(null=False)
category = models.CharField(max_length=50, null=False)
business = models.CharField(max_length=50, null=True)
budget_category = models.CharField(max_length=50, null=False)
business = models.CharField(max_length=50, blank=True, null=True)
description = models.CharField(max_length=200, blank=True, null=True)
budget_calculation = models.BooleanField(null=True)

def __str__(self):
"""Represent the model as a string."""
Expand Down
264 changes: 231 additions & 33 deletions budget/tests.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
"""Test module for all views."""
import datetime
import pytz

from rest_framework.test import APITestCase, APIClient
from rest_framework.views import status

from django.contrib.auth.models import User
from django.urls import reverse
from django.conf import settings

from budget.models import Expense
from budget.serializers import ExpenseSerializer
from budget.util import get_per_day, calculate_budgets

from freezegun import freeze_time

Expand All @@ -25,66 +28,261 @@ def setUp(self):

self.client.login(username="test_user", password="testing")

@staticmethod
def create_expense(amount="", date="", category="", business=""):
"""Create an expense object for testing."""
Expense.objects.create(amount=amount, date=date, category=category, business=business)

class TestUtil(BaseViewTest):
"""Test class for Util functions."""

def test_get_daily(self):
"""Ensure that all expensses added in the setUp method exist."""
Expense.objects.create(
amount=300,
date=datetime.datetime(2011, 8, 15, 8, 15, 12, 0, pytz.UTC),
budget_category="Income",
category="Paycheck",
budget_calculation=True,
)
queryset = Expense.objects.all()
result = get_per_day(queryset=queryset, month=8, year=2011)
expected = 300
self.assertEqual(result, expected)

@freeze_time("2020-03-20")
def test_calculate_budgets(self):
"""Check that calculate budgets does what it should."""
Expense.objects.create(
amount=3100,
date=datetime.datetime(2019, 12, 15, 8, 15, 12, 0, pytz.UTC),
category="Paycheck",
budget_category="Income",
budget_calculation=True,
)
Expense.objects.create(
amount=2900,
date=datetime.datetime(2020, 1, 27, 8, 15, 12, 0, pytz.UTC),
category="Paycheck",
budget_category="Income",
budget_calculation=True,
)

Expense.objects.create(
amount=1000,
date=datetime.datetime(2020, 2, 10, 8, 15, 12, 0, pytz.UTC),
category="Item",
budget_category="Purchase",
)
queryset = Expense.objects.all()
result = calculate_budgets(queryset, month=1, year=2020)
expected = 3100
self.assertEqual(result["saved"], expected)


class GetAllExpensesTest(BaseViewTest):
class TestListCreateExpenseView(BaseViewTest):
"""Test class for Expense view."""

def test_get_all_expenses(self):
"""Ensure that all expensses added in the setUp method exist."""
self.create_expense(10, "2019-01-01", "item", "Amazon")
self.create_expense(0.01, "2018-10-26", "gas", "shell")
Expense.objects.create(
amount=10, date=datetime.datetime(2011, 8, 15, 8, 15, 12, 0, pytz.UTC), category="item",
)
Expense.objects.create(
amount=0.01, date=datetime.datetime(2011, 8, 15, 8, 15, 12, 0, pytz.UTC), category="item",
)

response = self.client.get(reverse("expenses"), secure=True)
expected = Expense.objects.all()
serialized = ExpenseSerializer(expected, many=True)
self.assertEqual(response.data['results'], serialized.data)
self.assertEqual(response.data["results"], serialized.data)
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test_post_expense_view(self):
"""Test that post an expense works as expected."""
data = {
"date": "2018-03-12T19:00:00",
"amount": 50,
"category": "Restaurants",
"budget_category": "Expenses",
"business": "",
"description": "",
"budget_calculation": "",
}
url = "expenses"

response = self.client.post(reverse(url), data, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(response.data["budget_category"], "Expenses")


class TestPerDiem(BaseViewTest):
"""Test class for perDiem endpoint."""

def test_get_per_diem(self):
"""Ensure that all expensses added in the setUp method exist."""
Expense.objects.create(
amount=1000,
date=datetime.datetime(2011, 8, 30, 8, 15, 12, 0, pytz.UTC),
budget_category="Income",
category="item",
budget_calculation=True,
)
Expense.objects.create(
amount=400,
date=datetime.datetime(2011, 8, 1, 8, 15, 12, 0, pytz.UTC),
category="item",
budget_category="Savings",
budget_calculation=True,
)

response = self.client.get("/perDiem/?month=8&year=2011", secure=True)
self.assertEqual(response.data, 20)
self.assertEqual(response.status_code, status.HTTP_200_OK)


class GetBudgetsTest(BaseViewTest):
"""Test class for budget view."""

@freeze_time("2020-01-01")
@freeze_time("2020-01-20")
def test_get_budget(self):
"""Ensure that all budget with no expenses is correct."""
Expense.objects.create(
amount=3100,
date=datetime.datetime(2019, 12, 15, 8, 15, 12, 0, pytz.UTC),
category="Paycheck",
budget_category="Income",
budget_calculation=True,
)
Expense.objects.create(
amount=710,
date=datetime.datetime(2020, 1, 1, 8, 15, 12, 0, pytz.UTC),
category="Items",
budget_category="Purchase",
)
response = self.client.get(reverse("budget"), secure=True)
saved = round(settings.ALLOWANCE * 3, 2)
left_per_day = round((settings.ALLOWANCE * 7) / 5, 2)
expected = {
"week": {"total": 0.0, "perDay": 0.0, "leftPerDay": left_per_day, "saved": saved},
"month": {"total": 0.0, "perDay": 0.0, "leftPerDay": settings.ALLOWANCE, "saved": settings.ALLOWANCE},
"year": {"leftPerDay": settings.ALLOWANCE, "perDay": 0.0, "saved": settings.ALLOWANCE, "total": 0.0},
}
expected = {"total": 710.0, "perDay": 35.5, "leftPerDay": 199.17, "saved": 1290.0}

self.assertEqual(response.data, expected)

@freeze_time("2020-01-01")
@freeze_time("2019-06-20")
def test_get_budget_1(self):
"""Ensure that all budget with no expenses is correct."""
Expense.objects.create(
amount=3000,
date=datetime.datetime(2019, 5, 15, 8, 15, 12, 0, pytz.UTC),
category="Paycheck",
budget_category="Income",
budget_calculation=True,
)
response = self.client.get(reverse("budget"), secure=True)
saved = round(settings.ALLOWANCE * 3, 2)
left_per_day = round((settings.ALLOWANCE * 7) / 5, 2)
expected = {
"week": {"total": 0.0, "perDay": 0.0, "leftPerDay": left_per_day, "saved": saved},
"month": {"total": 0.0, "perDay": 0.0, "leftPerDay": settings.ALLOWANCE, "saved": settings.ALLOWANCE},
"year": {"leftPerDay": settings.ALLOWANCE, "perDay": 0.0, "saved": settings.ALLOWANCE, "total": 0.0},
}
expected = {"total": 0.0, "perDay": 0.0, "leftPerDay": 272.73, "saved": 2000.0}

self.assertEqual(response.data, expected)

@freeze_time("2020-02-03")
@freeze_time("2020-04-11")
def test_get_budget_2(self):
"""Ensure that budgets in February are correct."""
self.create_expense(1000, "2020-01-02", "item", "Amazon")
"""Ensure that all budget with no expenses is correct."""
Expense.objects.create(
amount=3000,
date=datetime.datetime(2020, 3, 15, 8, 15, 12, 0, pytz.UTC),
category="Paycheck",
budget_category="Income",
budget_calculation=True,
)

Expense.objects.create(
amount=1000,
date=datetime.datetime(2020, 4, 11, 8, 15, 12, 0, pytz.UTC),
category="Items",
budget_category="Purchase",
)
response = self.client.get(reverse("budget"), secure=True)
expected = {
"week": {"total": 0.0, "perDay": 0.0, "leftPerDay": settings.ALLOWANCE, "saved": settings.ALLOWANCE},
"month": {"total": 0.0, "perDay": 0.0, "leftPerDay": 69.33, "saved": 193.65},
"year": {"leftPerDay": 67.95, "perDay": 29.41, "saved": 1194.7, "total": 1000},
}
expected = {"total": 1000.0, "perDay": 90.91, "leftPerDay": 100.0, "saved": 100.0}

self.assertEqual(response.data, expected)


class TestSummaryView(BaseViewTest):
"""Test class for summary endpoints."""

@freeze_time("2020-04-11")
def test_get_summary(self):
"""Ensure that summary is correct."""
Expense.objects.create(
amount=3000,
date=datetime.datetime(2020, 4, 15, 8, 15, 12, 0, pytz.UTC),
category="Paycheck",
budget_category="Income",
budget_calculation=True,
)

Expense.objects.create(
amount=1000,
date=datetime.datetime(2020, 4, 11, 8, 15, 12, 0, pytz.UTC),
category="Items",
budget_category="Purchase",
)
response = self.client.get(reverse("summary"), secure=True)
expected = {"Income": 3000, "Purchase": 1000}

self.assertEqual(response.data, expected)


class TestSavingsView(BaseViewTest):
"""Test class for savings endpoint."""

@freeze_time("2020-01-10")
def test_get_saved(self):
"""Ensure that saved is correct."""
Expense.objects.create(
amount=3100,
date=datetime.datetime(2019, 12, 15, 8, 15, 12, 0, pytz.UTC),
category="Paycheck",
budget_category="Income",
budget_calculation=True,
)
response = self.client.get(reverse("saved"), secure=True)
expected = 1000

self.assertEqual(response.data, expected)

@freeze_time("2020-02-11")
def test_get_saved_2(self):
"""Ensure that summary is correct."""
Expense.objects.create(
amount=3100,
date=datetime.datetime(2019, 12, 15, 8, 15, 12, 0, pytz.UTC),
category="Paycheck",
budget_category="Income",
budget_calculation=True,
)
Expense.objects.create(
amount=2900,
date=datetime.datetime(2020, 1, 27, 8, 15, 12, 0, pytz.UTC),
category="Paycheck",
budget_category="Income",
budget_calculation=True,
)

Expense.objects.create(
amount=1000,
date=datetime.datetime(2020, 2, 10, 8, 15, 12, 0, pytz.UTC),
category="Item",
budget_category="Purchase",
)
response = self.client.get(reverse("saved"), secure=True)
expected = 3200

self.assertEqual(response.data, expected)

@freeze_time("2020-01-01")
def test_get_saved_3(self):
"""Ensure that summary is correct."""
Expense.objects.create(
amount=3100,
date=datetime.datetime(2019, 12, 15, 8, 15, 12, 0, pytz.UTC),
category="Paycheck",
budget_category="Income",
budget_calculation=True,
)
response = self.client.get(reverse("saved"), secure=True)
expected = 100

self.assertEqual(response.data, expected)
Loading

0 comments on commit c621649

Please sign in to comment.