diff --git a/pyproject.toml b/pyproject.toml index 06682b9..117b450 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,7 +59,7 @@ show_missing = true [tool.coverage.run] branch = true -source = ["django_project"] +source = ["src/django_project"] omit = [ "django_project/manage.py", "django_project/core/asgi.py", @@ -83,14 +83,13 @@ exclude = [ ignore_missing_imports = true - [tool.pytest.ini_options] addopts = "-s -v -x --strict-markers -m 'not extra'" -testpaths = ["django_project"] +testpaths = ["src/django_project"] filterwarnings = [ "ignore::DeprecationWarning", "ignore::UserWarning", -] + ] [tool.ruff] diff --git a/src/django_project/core/settings.py b/src/django_project/core/settings.py index 39057a5..558107a 100644 --- a/src/django_project/core/settings.py +++ b/src/django_project/core/settings.py @@ -276,6 +276,4 @@ """spokane_python is a super awesome project powered, in part, by amazing code provided by DjangoAddicts.""" ) PROJECT_VERSION = env.str("PROJECT_VERSION", "0.0.1") -PROJECT_SOURCE = "https://github.com/djangoaddicts" - -PYGWALKER_THEME = "light" +PROJECT_SOURCE = "https://github.com/SpokaneTech/SpokanePythonWeb" diff --git a/src/django_project/tests/unit/web/__init__.py b/src/django_project/tests/unit/web/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/django_project/tests/unit/web/test_model_crud.py b/src/django_project/tests/unit/web/test_model_crud.py new file mode 100644 index 0000000..9752b36 --- /dev/null +++ b/src/django_project/tests/unit/web/test_model_crud.py @@ -0,0 +1,398 @@ +import os +import random +from pathlib import Path + +import django +from django.apps import apps +from django.test import TestCase + +BASE_DIR = Path(__file__).parents[4] +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings") +django.setup() +from model_bakery import baker # noqa: E402 + + +class EventTests(TestCase): + """test CRUD operations on Event""" + + def setUp(self): + self.model = apps.get_model("web", "event") + self.to_bake = "web.Event" + + def bake(self): + """add row""" + return baker.make( + self.to_bake, + ) + + def test_create(self): + """verify object can be created""" + before_count = self.model.objects.count() + row = self.bake() + after_count = self.model.objects.count() + self.assertTrue(isinstance(row, self.model)) + self.assertGreater(after_count, before_count) + + def test_read(self): + """verify object can be read""" + row = self.bake() + entry = self.model.objects.get(pk=row.pk) + self.assertTrue(isinstance(entry, self.model)) + self.assertEqual(row.pk, entry.pk) + + def test_delete(self): + """verify object can be deleted""" + row = self.bake() + before_count = self.model.objects.count() + row_pk = row.pk + row.delete() + after_count = self.model.objects.count() + with self.assertRaises(self.model.DoesNotExist): + self.model.objects.get(pk=row_pk) + self.assertLess(after_count, before_count) + + def test_update_description(self): + """verify description (TextField) can be updated""" + row = self.bake() + original_value = row.description + updated_value = baker.prepare(self.to_bake, _fill_optional=["description"]).description + setattr(row, "description", updated_value) + row.save() + self.assertEqual(getattr(row, "description"), updated_value) + self.assertNotEqual(getattr(row, "description"), original_value) + + def test_update_location(self): + """verify location (CharField) can be updated""" + row = self.bake() + original_value = row.location + updated_value = baker.prepare(self.to_bake, _fill_optional=["location"]).location + setattr(row, "location", updated_value) + row.save() + self.assertEqual(getattr(row, "location"), updated_value) + self.assertNotEqual(getattr(row, "location"), original_value) + + def test_update_name(self): + """verify name (CharField) can be updated""" + row = self.bake() + original_value = row.name + updated_value = baker.prepare(self.to_bake, _fill_optional=["name"]).name + setattr(row, "name", updated_value) + row.save() + self.assertEqual(getattr(row, "name"), updated_value) + self.assertNotEqual(getattr(row, "name"), original_value) + + def test_update_url(self): + """verify url (CharField) can be updated""" + row = self.bake() + original_value = row.url + updated_value = baker.prepare(self.to_bake, _fill_optional=["url"]).url + setattr(row, "url", updated_value) + row.save() + self.assertEqual(getattr(row, "url"), updated_value) + self.assertNotEqual(getattr(row, "url"), original_value) + + +class PresentationRequestTests(TestCase): + """test CRUD operations on PresentationRequest""" + + def setUp(self): + self.model = apps.get_model("web", "presentationrequest") + self.to_bake = "web.PresentationRequest" + + def bake(self): + """add row""" + return baker.make( + self.to_bake, + ) + + def test_create(self): + """verify object can be created""" + before_count = self.model.objects.count() + row = self.bake() + after_count = self.model.objects.count() + self.assertTrue(isinstance(row, self.model)) + self.assertGreater(after_count, before_count) + + def test_read(self): + """verify object can be read""" + row = self.bake() + entry = self.model.objects.get(pk=row.pk) + self.assertTrue(isinstance(entry, self.model)) + self.assertEqual(row.pk, entry.pk) + + def test_delete(self): + """verify object can be deleted""" + row = self.bake() + before_count = self.model.objects.count() + row_pk = row.pk + row.delete() + after_count = self.model.objects.count() + with self.assertRaises(self.model.DoesNotExist): + self.model.objects.get(pk=row_pk) + self.assertLess(after_count, before_count) + + def test_update_description(self): + """verify description (TextField) can be updated""" + row = self.bake() + original_value = row.description + updated_value = baker.prepare(self.to_bake, _fill_optional=["description"]).description + setattr(row, "description", updated_value) + row.save() + self.assertEqual(getattr(row, "description"), updated_value) + self.assertNotEqual(getattr(row, "description"), original_value) + + def test_update_email(self): + """verify email (CharField) can be updated""" + row = self.bake() + original_value = row.email + updated_value = baker.prepare(self.to_bake, _fill_optional=["email"]).email + setattr(row, "email", updated_value) + row.save() + self.assertEqual(getattr(row, "email"), updated_value) + self.assertNotEqual(getattr(row, "email"), original_value) + + def test_update_presenter(self): + """verify presenter (CharField) can be updated""" + row = self.bake() + original_value = row.presenter + updated_value = baker.prepare(self.to_bake, _fill_optional=["presenter"]).presenter + setattr(row, "presenter", updated_value) + row.save() + self.assertEqual(getattr(row, "presenter"), updated_value) + self.assertNotEqual(getattr(row, "presenter"), original_value) + + def test_update_skill_level(self): + """verify skill_level (CharField) can be updated""" + row = self.bake() + original_value = row.skill_level + choices = getattr(self.model.skill_level.field, "choices", None) + updated_value = random.choice([i[0] for i in choices if original_value not in i]) + setattr(row, "skill_level", updated_value) + row.save() + self.assertEqual(getattr(row, "skill_level"), updated_value) + self.assertNotEqual(getattr(row, "skill_level"), original_value) + + def test_update_title(self): + """verify title (CharField) can be updated""" + row = self.bake() + original_value = row.title + updated_value = baker.prepare(self.to_bake, _fill_optional=["title"]).title + setattr(row, "title", updated_value) + row.save() + self.assertEqual(getattr(row, "title"), updated_value) + self.assertNotEqual(getattr(row, "title"), original_value) + + +class ResourceTests(TestCase): + """test CRUD operations on Resource""" + + def setUp(self): + self.model = apps.get_model("web", "resource") + self.to_bake = "web.Resource" + + def bake(self): + """add row""" + return baker.make( + self.to_bake, + ) + + def test_create(self): + """verify object can be created""" + before_count = self.model.objects.count() + row = self.bake() + after_count = self.model.objects.count() + self.assertTrue(isinstance(row, self.model)) + self.assertGreater(after_count, before_count) + + def test_read(self): + """verify object can be read""" + row = self.bake() + entry = self.model.objects.get(pk=row.pk) + self.assertTrue(isinstance(entry, self.model)) + self.assertEqual(row.pk, entry.pk) + + def test_delete(self): + """verify object can be deleted""" + row = self.bake() + before_count = self.model.objects.count() + row_pk = row.pk + row.delete() + after_count = self.model.objects.count() + with self.assertRaises(self.model.DoesNotExist): + self.model.objects.get(pk=row_pk) + self.assertLess(after_count, before_count) + + def test_update_category(self): + """verify category (ForeignKey) can be updated""" + row = self.bake() + original_value = row.category + baker.make(self.model.category.field.related_model._meta.label, _fill_optional=True) + if original_value: + updated_value = random.choice(self.model.category.field.related_model.objects.exclude(pk=original_value.pk)) + else: + updated_value = random.choice(self.model.category.field.related_model.objects.all()) + setattr(row, "category", updated_value) + row.save() + self.assertEqual(getattr(row, "category"), updated_value) + self.assertNotEqual(getattr(row, "category"), original_value) + + def test_update_description(self): + """verify description (TextField) can be updated""" + row = self.bake() + original_value = row.description + updated_value = baker.prepare(self.to_bake, _fill_optional=["description"]).description + setattr(row, "description", updated_value) + row.save() + self.assertEqual(getattr(row, "description"), updated_value) + self.assertNotEqual(getattr(row, "description"), original_value) + + def test_update_name(self): + """verify name (CharField) can be updated""" + row = self.bake() + original_value = row.name + updated_value = baker.prepare(self.to_bake, _fill_optional=["name"]).name + setattr(row, "name", updated_value) + row.save() + self.assertEqual(getattr(row, "name"), updated_value) + self.assertNotEqual(getattr(row, "name"), original_value) + + def test_update_url(self): + """verify url (CharField) can be updated""" + row = self.bake() + original_value = row.url + updated_value = baker.prepare(self.to_bake, _fill_optional=["url"]).url + setattr(row, "url", updated_value) + row.save() + self.assertEqual(getattr(row, "url"), updated_value) + self.assertNotEqual(getattr(row, "url"), original_value) + + +class ResourceCategoryTests(TestCase): + """test CRUD operations on ResourceCategory""" + + def setUp(self): + self.model = apps.get_model("web", "resourcecategory") + self.to_bake = "web.ResourceCategory" + + def bake(self): + """add row""" + return baker.make( + self.to_bake, + ) + + def test_create(self): + """verify object can be created""" + before_count = self.model.objects.count() + row = self.bake() + after_count = self.model.objects.count() + self.assertTrue(isinstance(row, self.model)) + self.assertGreater(after_count, before_count) + + def test_read(self): + """verify object can be read""" + row = self.bake() + entry = self.model.objects.get(pk=row.pk) + self.assertTrue(isinstance(entry, self.model)) + self.assertEqual(row.pk, entry.pk) + + def test_delete(self): + """verify object can be deleted""" + row = self.bake() + before_count = self.model.objects.count() + row_pk = row.pk + row.delete() + after_count = self.model.objects.count() + with self.assertRaises(self.model.DoesNotExist): + self.model.objects.get(pk=row_pk) + self.assertLess(after_count, before_count) + + def test_update_name(self): + """verify name (CharField) can be updated""" + row = self.bake() + original_value = row.name + updated_value = baker.prepare(self.to_bake, _fill_optional=["name"]).name + setattr(row, "name", updated_value) + row.save() + self.assertEqual(getattr(row, "name"), updated_value) + self.assertNotEqual(getattr(row, "name"), original_value) + + +class TopicSuggestionTests(TestCase): + """test CRUD operations on TopicSuggestion""" + + def setUp(self): + self.model = apps.get_model("web", "topicsuggestion") + self.to_bake = "web.TopicSuggestion" + + def bake(self): + """add row""" + return baker.make( + self.to_bake, + ) + + def test_create(self): + """verify object can be created""" + before_count = self.model.objects.count() + row = self.bake() + after_count = self.model.objects.count() + self.assertTrue(isinstance(row, self.model)) + self.assertGreater(after_count, before_count) + + def test_read(self): + """verify object can be read""" + row = self.bake() + entry = self.model.objects.get(pk=row.pk) + self.assertTrue(isinstance(entry, self.model)) + self.assertEqual(row.pk, entry.pk) + + def test_delete(self): + """verify object can be deleted""" + row = self.bake() + before_count = self.model.objects.count() + row_pk = row.pk + row.delete() + after_count = self.model.objects.count() + with self.assertRaises(self.model.DoesNotExist): + self.model.objects.get(pk=row_pk) + self.assertLess(after_count, before_count) + + def test_update_description(self): + """verify description (TextField) can be updated""" + row = self.bake() + original_value = row.description + updated_value = baker.prepare(self.to_bake, _fill_optional=["description"]).description + setattr(row, "description", updated_value) + row.save() + self.assertEqual(getattr(row, "description"), updated_value) + self.assertNotEqual(getattr(row, "description"), original_value) + + def test_update_email(self): + """verify email (CharField) can be updated""" + row = self.bake() + original_value = row.email + updated_value = baker.prepare(self.to_bake, _fill_optional=["email"]).email + setattr(row, "email", updated_value) + row.save() + self.assertEqual(getattr(row, "email"), updated_value) + self.assertNotEqual(getattr(row, "email"), original_value) + + def test_update_skill_level(self): + """verify skill_level (CharField) can be updated""" + row = self.bake() + original_value = row.skill_level + choices = getattr(self.model.skill_level.field, "choices", None) + updated_value = random.choice([i[0] for i in choices if original_value not in i]) + setattr(row, "skill_level", updated_value) + row.save() + self.assertEqual(getattr(row, "skill_level"), updated_value) + self.assertNotEqual(getattr(row, "skill_level"), original_value) + + def test_update_title(self): + """verify title (CharField) can be updated""" + row = self.bake() + original_value = row.title + updated_value = baker.prepare(self.to_bake, _fill_optional=["title"]).title + setattr(row, "title", updated_value) + row.save() + self.assertEqual(getattr(row, "title"), updated_value) + self.assertNotEqual(getattr(row, "title"), original_value) diff --git a/src/django_project/web/forms.py b/src/django_project/web/forms.py index 3850e67..d8aca6c 100644 --- a/src/django_project/web/forms.py +++ b/src/django_project/web/forms.py @@ -7,7 +7,11 @@ class PresentationRequestForm(HtmxModelForm): hx_post: str = "/presentation_request" hx_target: str = "presentation-request-form" submit_button_text: str = "submit" - success_message: str = "presentation request submitted; thanks!" + success_message: str = """Presentation request received; thanks!
reset form
""" class Meta: model = PresentationRequest @@ -26,7 +30,11 @@ class TopicSuggestionForm(HtmxModelForm): hx_post: str = "/topic_suggestion" hx_target: str = "topic-suggestion-form" submit_button_text: str = "submit" - success_message: str = "topic suggestion submitted; thanks!" + success_message: str = """Topic suggestion received; thanks!
reset form
""" class Meta: model = TopicSuggestion diff --git a/src/django_project/web/templates/web/full/index.html b/src/django_project/web/templates/web/full/index.html index 5da45be..ee5312f 100644 --- a/src/django_project/web/templates/web/full/index.html +++ b/src/django_project/web/templates/web/full/index.html @@ -348,122 +348,14 @@
Get Involved

Help shape our community by suggesting topics or volunteering to present

-
-
-
-
-
- Suggest a Topic -
-
- {% csrf_token %} -
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
- -
-
-
-
-
- -
-
-
-
- Volunteer to Present -
-
- {% csrf_token %} -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
- -
-
-
-
-
+
+
- @@ -589,7 +481,6 @@
Community Guidelines
-