Skip to content

Commit

Permalink
Merge branch 'main' into feat/modal-share-page
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewtavis authored Dec 20, 2024
2 parents 05ef792 + cf83551 commit 875f858
Show file tree
Hide file tree
Showing 33 changed files with 540 additions and 90 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"eslint.validate": ["javascript", "typescript", "vue"],
"eslint.useFlatConfig": true,
"typescript.tsdk": "./frontend/node_modules/typescript/lib"
"typescript.tsdk": "./frontend/node_modules/typescript/lib",
}
19 changes: 10 additions & 9 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -629,14 +629,15 @@ All branding elements such as logos, icons, colors and fonts should follow those
Nuxt uses auto imports to make frontend development more seamless, but at times these imports malfunction. For the `Property 'PROPERTY_NAME' does not exist on type...` errors, this is caused both by having an out of sync `yarn.lock` file and having Nuxt improperly installed.
Things to check are:
Please run [frontend/reset_local_env.sh](frontend/reset_local_env.sh) to reset the local frontend environment to allow for local testing. This can be done via the following commands:
1. Replace `yarn.lock` file with the one in main
2. Run `yarn cache clean` (this clears the yarn cache system wide and takes a long time)
3. Delete the `node_modules` folder
4. Load environment variables into your shell with `set -a && source ../.env.dev && set +a`
5. Rerun `yarn install`
6. Restart your IDE to assure that changes are picked up
```bash
# Linux:
sh frontend/reset_local_env.sh
> [!NOTE]
> Also make sure that the dependencies have been installed within the appropriate directory (`/backend` and `/frontend`).
# MacOS:
sh frontend/reset_local_env.sh
# Windows:
# Run the commands below found in frontend/reset_local_env.sh.
```
30 changes: 26 additions & 4 deletions backend/backend/management/commands/populate_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class Options(TypedDict):
orgs_per_user: int
groups_per_org: int
events_per_org: int
resources_per_entity: int
faq_entries_per_entity: int


class Command(BaseCommand):
Expand All @@ -33,12 +35,16 @@ def add_arguments(self, parser: ArgumentParser) -> None:
parser.add_argument("--orgs-per-user", type=int, default=1)
parser.add_argument("--groups-per-org", type=int, default=1)
parser.add_argument("--events-per-org", type=int, default=1)
parser.add_argument("--resources-per-entity", type=int, default=1)
parser.add_argument("--faq-entries-per-entity", type=int, default=1)

def handle(self, *args: str, **options: Unpack[Options]) -> None:
num_users = options["users"]
num_orgs_per_user = options["orgs_per_user"]
num_groups_per_org = options["groups_per_org"]
num_events_per_org = options["events_per_org"]
num_resources_per_entity = options["resources_per_entity"]
num_faq_entries_per_entity = options["faq_entries_per_entity"]

# Clear all tables before creating new data.
UserModel.objects.exclude(username="admin").delete()
Expand Down Expand Up @@ -77,7 +83,7 @@ def handle(self, *args: str, **options: Unpack[Options]) -> None:
created_by=user,
)

org_texts = OrganizationTextFactory(iso="wt", primary=True)
org_texts = OrganizationTextFactory(iso="en", primary=True)

user_org = OrganizationFactory(
created_by=user,
Expand All @@ -100,12 +106,28 @@ def handle(self, *args: str, **options: Unpack[Options]) -> None:
name=f"{user_topic.name} Group",
)

num_orgs = num_users * num_orgs_per_user
num_groups = num_users * num_orgs_per_user * num_groups_per_org
num_events = num_users * num_orgs_per_user * num_events_per_org
num_resources = num_users * (
num_orgs_per_user
+ num_orgs_per_user * num_events_per_org * num_resources_per_entity
+ num_orgs_per_user * num_groups_per_org * num_resources_per_entity
)
num_faq_entries = num_users * (
num_orgs_per_user
+ num_orgs_per_user * num_events_per_org * num_faq_entries_per_entity
+ num_orgs_per_user * num_groups_per_org * num_faq_entries_per_entity
)

self.stdout.write(
self.style.ERROR(
f"Number of users created: {num_users}\n"
f"Number of organizations created: {num_users * num_orgs_per_user}\n"
f"Number of groups created: {num_users * num_orgs_per_user * num_groups_per_org}\n"
f"Number of events created: {num_users * num_orgs_per_user * num_events_per_org}\n"
f"Number of organizations created: {num_orgs}\n"
f"Number of groups created: {num_groups}\n"
f"Number of events created: {num_events}\n"
f"Number of resources created: {num_resources}\n"
f"Number of FAQ entries created: {num_faq_entries}\n"
)
)

Expand Down
4 changes: 2 additions & 2 deletions backend/entities/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ class Group(models.Model):
group_name = models.CharField(max_length=255)
name = models.CharField(max_length=255)
tagline = models.CharField(max_length=255, blank=True)
location = models.OneToOneField(
"content.Location", on_delete=models.CASCADE, null=False, blank=False
location = models.ForeignKey(
"content.Location", on_delete=models.CASCADE, blank=False, null=False
)
category = models.CharField(max_length=255)
get_involved_url = models.URLField(blank=True)
Expand Down
3 changes: 1 addition & 2 deletions backend/entities/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

from .factories import (
OrganizationFactory,
OrganizationApplicationFactory,
# OrganizationApplicationStatusFactory,
OrganizationEventFactory,
OrganizationMemberFactory,
OrganizationResourceFactory,
Expand All @@ -25,6 +23,7 @@


def test_str_methods() -> None:
"""Test the __str__ methods of the entities."""
organization = OrganizationFactory.create()
# Note: Needs to be updated to reflect the recent changes.
# organization_application = OrganizationApplicationFactory.create()
Expand Down
119 changes: 119 additions & 0 deletions backend/entities/tests/test_group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
"""
Testing for the Group model.
"""

# mypy: ignore-errors
from datetime import datetime
from uuid import UUID

import pytest
from django.core.exceptions import ValidationError
from faker import Faker

from authentication.factories import UserFactory
from content.factories import EntityLocationFactory
from entities.factories import OrganizationFactory
from entities.models import Group

pytestmark = pytest.mark.django_db


def test_group_creation() -> None:
"""Test complete group creation with all fields."""
user = UserFactory()
org = OrganizationFactory(created_by=user)
location = EntityLocationFactory()
fake = Faker()

group = Group.objects.create(
org_id=org,
created_by=user,
group_name=fake.company(),
name=fake.company(),
tagline=fake.catch_phrase(),
location=location,
category=fake.word(),
get_involved_url=fake.url(),
terms_checked=True,
)

assert isinstance(group.id, UUID)
assert group.org_id == org
assert group.created_by == user
assert isinstance(group.group_name, str)
assert isinstance(group.creation_date, datetime)
assert group.terms_checked is True


def test_url_validations() -> None:
"""Test that get_involved_url field is a valid URL."""
user = UserFactory()
org = OrganizationFactory(created_by=user)
location = EntityLocationFactory()
fake = Faker()

# 1. Test invalid URL.
with pytest.raises(ValidationError):
group = Group(
org_id=org,
created_by=user,
group_name=fake.company(),
name=fake.company(),
location=location,
category=fake.word(),
get_involved_url="not a url",
terms_checked=True,
)
group.full_clean()

# 2. Test valid URL.
group = Group.objects.create(
org_id=org,
created_by=user,
group_name=fake.company(),
name=fake.company(),
location=location,
category=fake.word(),
get_involved_url=fake.url(),
terms_checked=True,
)

group.full_clean()


def test_multiple_groups_per_org() -> None:
"""Test that multiple groups can be created per organization."""
user = UserFactory()
org = OrganizationFactory(created_by=user)
location = EntityLocationFactory()
fake = Faker()

group1 = Group.objects.create(
org_id=org,
created_by=user,
group_name=fake.company(),
name=fake.company(),
location=location,
category=fake.word(),
get_involved_url=fake.url(),
terms_checked=True,
)

group2 = Group.objects.create(
org_id=org,
created_by=user,
group_name=fake.company(),
name=fake.company(),
location=location,
category=fake.word(),
get_involved_url=fake.url(),
terms_checked=True,
)

assert Group.objects.count() == 2
assert group1.org_id == org
assert group2.org_id == org

org_groups = Group.objects.filter(org_id=org)
assert group1 in org_groups
assert group2 in org_groups
25 changes: 25 additions & 0 deletions backend/entities/tests/test_group_events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""
Test cases for the GroupEvents entity.
"""

import pytest

from entities.factories import GroupEventFactory, GroupFactory

pytestmark = pytest.mark.django_db


def test_group_event_str() -> None:
"""Test string representation of GroupEvent model."""
group_event = GroupEventFactory.build()
assert str(group_event) == f"{group_event.id}"


def test_multiple_events_per_group() -> None:
"""Test multiple events for a single group."""
group = GroupFactory()
events = [GroupEventFactory(group_id=group) for _ in range(3)]

assert len(events) == 3
for event in events:
assert event.group_id == group
57 changes: 57 additions & 0 deletions backend/entities/tests/test_group_member.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""
Test cases for the GroupMember model.
"""

import pytest

from authentication.factories import UserFactory
from entities.factories import GroupFactory, GroupMemberFactory

pytestmark = pytest.mark.django_db


def test_group_member_str() -> None:
"""Test string representation of GroupMember model."""
group_member = GroupMemberFactory.build()
assert str(group_member) == f"{group_member.id}"


def test_group_member_roles() -> None:
"""Test the different roles a group member can have."""
user = UserFactory()
group = GroupFactory()

# 1. Test owner role.
owner = GroupMemberFactory(
group_id=group, user_id=user, is_owner=True, is_admin=False, is_comms=False
)
assert owner.is_owner is True
assert owner.is_admin is False
assert owner.is_comms is False

# 2. Test admin role.
admin = GroupMemberFactory(
group_id=group, user_id=user, is_owner=False, is_admin=True, is_comms=False
)
assert admin.is_owner is False
assert admin.is_admin is True
assert admin.is_comms is False

# 3. Test comms role.
comms = GroupMemberFactory(
group_id=group, user_id=user, is_owner=False, is_admin=False, is_comms=True
)
assert comms.is_owner is False
assert comms.is_admin is False
assert comms.is_comms is True


def test_multiple_members_per_group() -> None:
"""Test multiple members in a single group."""
group = GroupFactory()
members = [GroupMemberFactory(group_id=group) for _ in range(3)]

assert len(members) == 3

for member in members:
assert member.group_id == group
50 changes: 50 additions & 0 deletions backend/entities/tests/test_group_resource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""
Test cases for GroupResource model.
"""

import pytest

from entities.factories import GroupFactory, GroupResourceFactory
from entities.models import GroupResource

pytestmark = pytest.mark.django_db


def test_group_resource_str() -> None:
"""Test string representation of GroupResource model."""
group_resource = GroupResourceFactory.build()
assert str(group_resource) == f"{group_resource.id}"


def test_group_resource_creation() -> None:
"""Test creating a GroupResource instance."""
group = GroupFactory()
resource = GroupResourceFactory(group_id=group)

assert isinstance(resource, GroupResource)
assert resource.group_id == group


def test_multiple_resources_per_group() -> None:
"""Test multiple resources for a single group."""
group = GroupFactory()
resources = [GroupResourceFactory(group_id=group) for _ in range(3)]

assert len(resources) == 3
for resource in resources:
assert resource.group_id == group


def test_group_resource_deletion() -> None:
"""Test cascade deletion when group is deleted."""
group = GroupFactory()
resource = GroupResourceFactory(group_id=group)

# Store resource ID for later verification.
resource_id = resource.id

# Delete the group.
group.delete()

# Verify resource is also deleted.
assert not GroupResource.objects.filter(id=resource_id).exists()
Loading

0 comments on commit 875f858

Please sign in to comment.