diff --git a/budgetproject/budget/test_forms.py b/budgetproject/budget/test_forms.py new file mode 100644 index 00000000..795603ac --- /dev/null +++ b/budgetproject/budget/test_forms.py @@ -0,0 +1,21 @@ +from django.test import SimpleTestCase +from budget.forms import ExpenseForm + + +class TestForms(SimpleTestCase): + + def test_expense_form_valid_data(self): + form = ExpenseForm(data={ + 'title': 'expense1', + 'amount': 1000, + 'category': 'development' + }) + + self.assertTrue(form.is_valid()) + + + def test_expense_form_no_data(self): + form = ExpenseForm(data={}) + + self.assertFalse(form.is_valid()) + self.assertEquals(len(form.errors), 3) \ No newline at end of file diff --git a/budgetproject/budget/test_model.py b/budgetproject/budget/test_model.py new file mode 100644 index 00000000..cf47a53d --- /dev/null +++ b/budgetproject/budget/test_model.py @@ -0,0 +1,59 @@ +from django.test import TestCase +from budget.models import Project, Category, Expense + + +class TestModels(TestCase): + + def setUp(self): + self.project1 = Project.objects.create( + name='Project 1', + budget=10000 + ) + + + def test_project_is_assigned_slug_on_creation(self): + self.assertEquals(self.project1.slug, 'project-1') + + def test_budget_left(self): + category1 = Category.objects.create( + project=self.project1, + name='development' + ) + Expense.objects.create( + project=self.project1, + title='expense1', + amount=1000, + category=category1 + ) + Expense.objects.create( + project=self.project1, + title='expense2', + amount=2000, + category=category1 + ) + + self.assertEquals(self.project1.budget_left, 7000) + + def test_project_total_transactions(self): + project2 = Project.objects.create( + name='project2', + budget=10000 + ) + category1 = Category.objects.create( + project=self.project1, + name='development' + ) + Expense.objects.create( + project=self.project1, + title='expense1', + amount=1000, + category=category1 + ) + Expense.objects.create( + project=project2, + title='expense2', + amount=2000, + category=category1 + ) + + self.assertEquals(self.project1.total_transactions, 1) \ No newline at end of file diff --git a/budgetproject/budget/test_urls.py b/budgetproject/budget/test_urls.py new file mode 100644 index 00000000..34d61bae --- /dev/null +++ b/budgetproject/budget/test_urls.py @@ -0,0 +1,17 @@ +from django.test import TestCase, SimpleTestCase +from django.urls import reverse, resolve +from budget.views import project_list, project_detail, ProjectCreateView + +class TestUrls(SimpleTestCase): + + def test_list_url_is_resolved(self): + url = reverse('list') + self.assertEquals(resolve(url).func, project_list) + + def test_add_url_is_resolved(self): + url = reverse('add') + self.assertEquals(resolve(url).func.view_class, ProjectCreateView) + + def test_detail_url_is_resolved(self): + url = reverse('detail', args=['some-slug']) + self.assertEquals(resolve(url).func, project_detail) diff --git a/budgetproject/budget/test_views.py b/budgetproject/budget/test_views.py new file mode 100644 index 00000000..9381121e --- /dev/null +++ b/budgetproject/budget/test_views.py @@ -0,0 +1,111 @@ +from django.test import TestCase, Client +from django.urls import reverse +from budget.models import Project, Category, Expense +import json +from unittest import skip + + +class TestViews(TestCase): + + def setUp(self): + self.client = Client() + self.list_url = reverse('list') + self.detail_url = reverse('detail', args=['project1']) + self.project1 = Project.objects.create( + name='project1', + budget=10000 + ) + + def test_project_list_GET(self): + response = self.client.get(self.list_url) + + self.assertEquals(response.status_code, 200) + self.assertTemplateUsed(response, 'budget/project-list.html') + + + def test_project_detail_GET(self): + response = self.client.get(self.detail_url) + + self.assertEquals(response.status_code, 200) + self.assertTemplateUsed(response, 'budget/project-detail.html') + + + def test_project_detail_POST_adds_new_expense(self): + Category.objects.create( + project=self.project1, + name='development' + ) + + response = self.client.post(self.detail_url, { + 'title': 'expense1', + 'amount': 1000, + 'category': 'development' + }) + + self.assertEquals(response.status_code, 302) + self.assertEquals(self.project1.expenses.first().title, 'expense1') + + + def test_project_detail_POST_no_data(self): + response = self.client.post(self.detail_url) + + self.assertEquals(response.status_code, 302) + self.assertEquals(self.project1.expenses.count(), 0) + + def test_project_detail_DELETE_deletes_expense(self): + category1 = Category.objects.create( + project = self.project1, + name = 'development' + ) + Expense.objects.create( + project = self.project1, + title = 'expense1', + amount = 1000, + category=category1 + ) + + response = self.client.delete(self.detail_url, json.dumps({ + 'id':1 + })) + + self.assertEquals(response.status_code, 204) + self.assertEquals(self.project1.expenses.count(), 0) + + + @skip + def test_project_detail_DELETE_deletes_expense(self): + category1 = Category.objects.create( + project = self.project1, + name = 'development' + ) + Expense.objects.create( + project = self.project1, + title = 'expense1', + amount = 1000, + category=category1 + ) + + response = self.client.delete(self.detail_url) + + self.assertEquals(response.status_code, 404) + self.assertEquals(self.project1.expenses.count(), 1) + + + def test_project_create_POST(self): + url = reverse('add') + response = self.client.post(url, { + 'name':'project2', + 'budget':10000, + 'categoriesString':'design,development' + }) + + project2 = Project.objects.get(id=2) + + self.assertEqual(response.status_code, 302) + self.assertEqual(project2.name, 'project2') + + first_category = Category.objects.get(id=1) + self.assertEqual(first_category.name, 'design') + + second_category = Category.objects.get(id=2) + self.assertEqual(second_category.name, 'development') \ No newline at end of file diff --git a/budgetproject/functional_tests/__init__.py b/budgetproject/functional_tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/budgetproject/functional_tests/test_project_list_page.py b/budgetproject/functional_tests/test_project_list_page.py new file mode 100644 index 00000000..0bd79a32 --- /dev/null +++ b/budgetproject/functional_tests/test_project_list_page.py @@ -0,0 +1,63 @@ +from selenium import webdriver +from budget.models import Project +from django.contrib.staticfiles.testing import StaticLiveServerTestCase +from django.urls import reverse +import time + + + +class TestProjectListPage(StaticLiveServerTestCase): + + def setUp(self): + self.browser = webdriver.Chrome('functional_tests/chromedriver') + + def tearDown(self): + self.browser.refresh() #To avoid ConnectionResetError + self.browser.close() + + def test_no_projects_alert_is_displayed(self): + self.browser.get(self.live_server_url) + + # The user requests the page for the first time + alert = self.browser.find_element_by_class_name('noproject-wrapper') + self.assertEquals( + alert.find_element_by_tag_name('h3').text, + 'Sorry, you don\'t have any projects, yet.') + + def test_no_projects_alery_button_redirects_to_add_page(self): + self.browser.get(self.live_server_url) + + # The user requests the page for the first time + add_url = self.live_server_url + reverse('add') + self.browser.find_element_by_tag_name('a').click() + self.assertEquals( + self.browser.current_url, + add_url + ) + + def test_user_sees_project_list(self): + project1 = Project.objects.create( + name='project1', + budget=10000 + ) + self.browser.get(self.live_server_url) + + # The user sees the project on the screen + self.assertEquals( + self.browser.find_element_by_tag_name('h5').text, + 'project1') + + def test_user_is_redirected_to_project_detail(self): + project1 = Project.objects.create( + name='project1', + budget=10000 + ) + self.browser.get(self.live_server_url) + + # The user sees the project on the screen. He clicks the 'VISIT' link + # and is redirected to the detail page + detail_url = self.live_server_url + reverse('detail', args=[project1.slug]) + self.browser.find_element_by_link_text('VISIT').click() + self.assertEquals( + self.browser.current_url, + detail_url) \ No newline at end of file