diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 45a702c9d..7c977ce57 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -17,6 +17,7 @@ If you have questions or would like to communicate with the team, please [join u
- [Learning the tech stack](#learning-the-tech)
- [Development environment](#dev-env)
- [Style guide](#style-guide)
+- [Testing](#testing)
- [Linting](#linting)
- [Issues and projects](#issues-projects)
- [Bug reports](#bug-reports)
@@ -303,6 +304,35 @@ From there you'll be able to visit http://localhost:6006/ to view the documentat
Please see the [activist style guide](https://github.com/activist-org/activist/blob/main/STYLEGUIDE.md) for details about how to follow the code style for the project. We made these guidelines to assure that we as a community write clean, cohesive code that's easy to write and review. Suggestions for the style guide are welcome.
+
+
+## Testing [`⇧`](#contents)
+
+### Backend
+
+Please run the following commands from the project root to test the backend:
+
+```bash
+# Start the Docker container:
+docker compose --env-file .env.dev up backend --build -d # -d to hide logs
+
+# Enter the backend container:
+docker exec -it django_backend sh
+
+# Run backend tests:
+pytest
+
+# Once tests are finished:
+exit
+```
+
+### Frontend
+
+Running frontend tests locally is currently WIP.
+
+> [!NOTE]
+> When working on the frontend, activist recommends manual typechecking. From within the `frontend` directory run `yarn run postinstall` followed by `yarn nuxi typecheck` to confirm your changes are type-safe. Existing TS errors may be ignored. PRs to fix these are always welcome!
+
## Linting [`⇧`](#contents)
@@ -405,9 +435,6 @@ When making a contribution, adhering to the [GitHub flow](https://docs.github.co
git pull --rebase upstream
```
-> [!NOTE]
-> When working on the frontend, activist recommends manual typechecking. From within the `frontend` directory run `yarn run postinstall` followed by `yarn nuxi typecheck` to confirm your changes are type-safe. Existing TS errors may be ignored. PRs to fix these are always welcome!
-
6. Push your topic branch up to your fork:
```bash
diff --git a/README.md b/README.md
index 60c948dfa..db66a4ce4 100644
--- a/README.md
+++ b/README.md
@@ -203,7 +203,7 @@ git remote add upstream https://github.com/activist-org/activist.git
```bash
docker compose --env-file .env.dev up
- # Or with new dependencies:
+ # Or with new dependencies or backend model changes:
# docker compose --env-file .env.dev up --build
# And to stop the containers when you're done working:
diff --git a/backend/authentication/factories.py b/backend/authentication/factories.py
index fd8a9fcd0..e833d3782 100644
--- a/backend/authentication/factories.py
+++ b/backend/authentication/factories.py
@@ -60,8 +60,6 @@ def verification_partner(
if not create:
# Simple build, do nothing.
return
- if extracted:
- pass
# MARK: Bridge Tables
diff --git a/backend/authentication/models.py b/backend/authentication/models.py
index fec4f9e72..5f1f3d18b 100644
--- a/backend/authentication/models.py
+++ b/backend/authentication/models.py
@@ -56,7 +56,7 @@ def create_user(
class SupportEntityType(models.Model):
- id = models.IntegerField(primary_key=True)
+ id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
name = models.CharField(max_length=255)
def __str__(self) -> str:
diff --git a/backend/authentication/tests.py b/backend/authentication/tests.py
index 824549ab2..5756943bd 100644
--- a/backend/authentication/tests.py
+++ b/backend/authentication/tests.py
@@ -24,7 +24,9 @@
import uuid
-@pytest.mark.django_db
+pytestmark = pytest.mark.django_db
+
+
def test_str_methods() -> None:
support_entity_type = SupportEntityTypeFactory.build()
support = SupportFactory.build()
@@ -41,7 +43,6 @@ def test_str_methods() -> None:
assert str(user_topic) == str(user_topic.id)
-@pytest.mark.django_db
def test_signup(client: Client) -> None:
"""
Test the signup function.
@@ -152,14 +153,13 @@ def test_signup(client: Client) -> None:
assert user.verification_code is None
-@pytest.mark.django_db
def test_login(client: Client) -> None:
"""
Test login view.
Scenarios:
1. User that signed up with email, that has not confirmed their email
- 2. User that signed up with email, confimred email address. Is logged in successfully
+ 2. User that signed up with email, confirmed email address. Is logged in successfully
3. User exists but password is incorrect
4. User does not exists and tries to login
"""
@@ -174,7 +174,7 @@ def test_login(client: Client) -> None:
)
assert response.status_code == 400
- # 2. User that signed up with email, confimred email address. Is logged in successfully
+ # 2. User that signed up with email, confirmed email address. Is logged in successfully
user.is_confirmed = True
user.save()
response = client.post(
@@ -204,7 +204,6 @@ def test_login(client: Client) -> None:
assert response.status_code == 400
-@pytest.mark.django_db
def test_pwreset(client: Client) -> None:
"""
Test password reset view.
diff --git a/backend/backend/custom_settings.py b/backend/backend/custom_settings.py
index 79419fc02..7e2e62e40 100644
--- a/backend/backend/custom_settings.py
+++ b/backend/backend/custom_settings.py
@@ -4,6 +4,7 @@
please check the path: backend/backend/settings.py
"""
-# Pagination settings
+# MARK: Pagination
+
PAGINATION_PAGE_SIZE = 20
PAGINATION_MAX_PAGE_SIZE = 100
diff --git a/backend/backend/exception_handler.py b/backend/backend/exception_handler.py
index aeaca091b..e74bd8d0c 100644
--- a/backend/backend/exception_handler.py
+++ b/backend/backend/exception_handler.py
@@ -8,7 +8,7 @@
def bad_request_logger(exception: Any, context: dict[str, Any]) -> Response | None:
- # Get the DRF exception handler standard error response
+ # Get the DRF exception handler standard error response.
response = exception_handler(exception, context)
if response is not None:
diff --git a/backend/backend/management/commands/populate_db.py b/backend/backend/management/commands/populate_db.py
index e9f78415f..4791ec627 100644
--- a/backend/backend/management/commands/populate_db.py
+++ b/backend/backend/management/commands/populate_db.py
@@ -4,28 +4,58 @@
from django.core.management.base import BaseCommand
from authentication.factories import UserFactory
+from authentication.models import UserModel
+from entities.factories import GroupFactory, OrganizationFactory
+from entities.models import Group, Organization
+from events.factories import EventFactory
+from events.models import Event
class Options(TypedDict):
users: int
+ orgs: int
+ groups: int
+ events: int
+# ATTN: We're not actually putting texts into the DB.
class Command(BaseCommand):
help = "Populate the database with dummy data"
def add_arguments(self, parser: ArgumentParser) -> None:
- parser.add_argument("--users", type=int, default=100)
+ parser.add_argument("--users", type=int, default=10)
+ parser.add_argument("--orgs", type=int, default=10)
+ parser.add_argument("--groups", type=int, default=10)
+ parser.add_argument("--events", type=int, default=10)
def handle(self, *args: str, **options: Unpack[Options]) -> None:
- number_of_users = options["users"]
+ number_of_users = options.get("users")
+ number_of_orgs = options.get("orgs")
+ number_of_groups = options.get("groups")
+ number_of_events = options.get("events")
+
+ # Clear all tables before creating new data.
+ UserModel.objects.exclude(username="admin").delete()
+ Organization.objects.all().delete()
+ Group.objects.all().delete()
+ Event.objects.all().delete()
+
try:
- UserFactory.create_batch(number_of_users)
+ UserFactory.create_batch(size=number_of_users)
+ OrganizationFactory.create_batch(size=number_of_orgs)
+ GroupFactory.create_batch(size=number_of_groups)
+ EventFactory.create_batch(size=number_of_events)
self.stdout.write(
- self.style.ERROR(f"Number of users created: {number_of_users}")
+ self.style.ERROR(
+ f"Number of users created: {number_of_users}\n"
+ f"Number of organizations created: {number_of_orgs}\n"
+ f"Number of groups created: {number_of_groups}\n"
+ f"Number of events created: {number_of_events}\n"
+ )
)
except Exception as error:
self.stdout.write(
self.style.ERROR(
- f"An error occured during the creation of dummy data: {error}"
+ f"An error occurred during the creation of dummy data: {error}"
)
)
diff --git a/backend/backend/settings.py b/backend/backend/settings.py
index 0d7b8a701..c2f8f7237 100644
--- a/backend/backend/settings.py
+++ b/backend/backend/settings.py
@@ -165,7 +165,7 @@
EMAIL_PORT = os.getenv("EMAIL_PORT")
EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER")
EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD")
-EMAIL_USE_TLS = bool(os.getenv("EMAIL_USE_TLS") == "True")
+EMAIL_USE_TLS = os.getenv("EMAIL_USE_TLS") == "True"
# DEVELOPMENT ONLY
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
diff --git a/backend/backend/tests/unit/conftest.py b/backend/backend/tests/unit/conftest.py
index 12e287b8f..aa891de02 100644
--- a/backend/backend/tests/unit/conftest.py
+++ b/backend/backend/tests/unit/conftest.py
@@ -4,5 +4,4 @@
@pytest.fixture
def api_client() -> APIClient:
- client = APIClient()
- return client
+ return APIClient()
diff --git a/backend/content/factories.py b/backend/content/factories.py
index 7b6885af4..be8638570 100644
--- a/backend/content/factories.py
+++ b/backend/content/factories.py
@@ -24,8 +24,12 @@ class Meta:
url = factory.Faker("url")
is_private = factory.Faker("boolean")
created_by = factory.SubFactory("authentication.factories.UserFactory")
- creation_date = factory.LazyFunction(datetime.datetime.now)
- last_updated = factory.LazyFunction(datetime.datetime.now)
+ creation_date = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
+ last_updated = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
class TaskFactory(factory.django.DjangoModelFactory):
@@ -35,8 +39,12 @@ class Meta:
name = factory.Faker("word")
description = factory.Faker("text")
tags = factory.List([factory.Faker("word") for _ in range(10)])
- creation_date = factory.LazyFunction(datetime.datetime.now)
- deletion_date = factory.LazyFunction(datetime.datetime.now)
+ creation_date = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
+ deletion_date = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
class TopicFactory(factory.django.DjangoModelFactory):
@@ -46,7 +54,9 @@ class Meta:
name = factory.Faker("word")
active = factory.Faker("boolean")
description = factory.Faker("text")
- creation_date = factory.LazyFunction(datetime.datetime.now)
+ creation_date = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
deprecation_date = factory.Faker("date")
diff --git a/backend/content/models.py b/backend/content/models.py
index dd9452701..a3ae69940 100644
--- a/backend/content/models.py
+++ b/backend/content/models.py
@@ -70,7 +70,7 @@ def __str__(self) -> str:
class Tag(models.Model):
- id = models.IntegerField(primary_key=True)
+ id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
text = models.CharField(max_length=255)
creation_date = models.DateTimeField(auto_now_add=True)
diff --git a/backend/content/serializers.py b/backend/content/serializers.py
index 8c972ee19..7e9fb7000 100644
--- a/backend/content/serializers.py
+++ b/backend/content/serializers.py
@@ -66,10 +66,10 @@ def validate(self, data: Dict[str, Union[str, int]]) -> Dict[str, Union[str, int
with PilImage.open(data["image_location"]) as img:
img.verify()
img_format = img.format.lower()
- except Exception:
+ except Exception as e:
raise serializers.ValidationError(
_("The image is not valid."), code="corrupted_file"
- )
+ ) from e
if img_format not in image_extensions:
raise serializers.ValidationError(
diff --git a/backend/content/tests.py b/backend/content/tests.py
index fa76025bb..c4c345567 100644
--- a/backend/content/tests.py
+++ b/backend/content/tests.py
@@ -7,8 +7,9 @@
import pytest
+pytestmark = pytest.mark.django_db
+
-@pytest.mark.django_db
def test_str_methods() -> None:
resource = ResourceFactory.build()
task = TaskFactory.build()
diff --git a/backend/entities/factories.py b/backend/entities/factories.py
index 5ccc310f9..2bcf69b1b 100644
--- a/backend/entities/factories.py
+++ b/backend/entities/factories.py
@@ -28,12 +28,26 @@
class OrganizationFactory(factory.django.DjangoModelFactory):
class Meta:
model = Organization
+ django_get_or_create = ("created_by",)
name = factory.Faker("word")
tagline = factory.Faker("word")
- social_links = factory.List([factory.Faker("word") for _ in range(10)])
+ social_links = ["https://www.instagram.com/activist_org/"]
+ # Note: Version that accesses the database so we don't create new each time.
+ # created_by = factory.LazyAttribute(
+ # lambda x: (
+ # UserModel.objects.exclude(username="admin").first()
+ # if UserModel.objects.exclude(username="admin").exists()
+ # else factory.SubFactory("authentication.factories.UserFactory")
+ # )
+ # )
created_by = factory.SubFactory("authentication.factories.UserFactory")
+ status = factory.SubFactory("entities.factories.StatusTypeFactory", name="Active")
is_high_risk = factory.Faker("boolean")
+ location = factory.Faker("city")
+ acceptance_date = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
class GroupFactory(factory.django.DjangoModelFactory):
@@ -43,9 +57,13 @@ class Meta:
org_id = factory.SubFactory(OrganizationFactory)
name = factory.Faker("word")
tagline = factory.Faker("word")
- social_links = factory.List([factory.Faker("word") for _ in range(10)])
+ social_links = ["https://www.instagram.com/activist_org/"]
created_by = factory.SubFactory("authentication.factories.UserFactory")
- creation_date = factory.LazyFunction(datetime.datetime.now)
+ creation_date = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
+ category = factory.Faker("word")
+ location = factory.Faker("city")
# MARK: Bridge Tables
@@ -119,8 +137,12 @@ class Meta:
status = factory.SubFactory(OrganizationApplicationStatusFactory)
orgs_in_favor = factory.List([factory.Faker("word") for _ in range(10)])
orgs_against = factory.List([factory.Faker("word") for _ in range(10)])
- creation_date = factory.LazyFunction(datetime.datetime.now)
- status_updated = factory.LazyFunction(datetime.datetime.now)
+ creation_date = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
+ status_updated = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
class OrganizationEventFactory(factory.django.DjangoModelFactory):
@@ -185,3 +207,11 @@ class Meta:
org_id = factory.SubFactory(OrganizationFactory)
topic_id = factory.SubFactory("content.factories.TopicFactory")
+
+
+class StatusTypeFactory(factory.django.DjangoModelFactory):
+ class Meta:
+ model = "entities.StatusType"
+ django_get_or_create = ("name",)
+
+ name = "Active"
diff --git a/backend/entities/models.py b/backend/entities/models.py
index d366d3d29..56bbd64b5 100644
--- a/backend/entities/models.py
+++ b/backend/entities/models.py
@@ -158,7 +158,7 @@ def __str__(self) -> str:
class OrganizationApplicationStatus(models.Model):
- id = models.IntegerField(primary_key=True)
+ id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
status_name = models.CharField(max_length=255)
def __str__(self) -> str:
diff --git a/backend/entities/tests.py b/backend/entities/tests.py
index 0f794d75c..d3abe41cb 100644
--- a/backend/entities/tests.py
+++ b/backend/entities/tests.py
@@ -3,7 +3,7 @@
"""
# mypy: ignore-errors
-from django.urls import reverse
+import pytest
from .factories import (
OrganizationFactory,
@@ -21,21 +21,23 @@
GroupTopicFactory,
)
+pytestmark = pytest.mark.django_db
+
def test_str_methods() -> None:
- organization = OrganizationFactory.build()
- # Needs to be updated to reflect the recent changes
- # organization_application = OrganizationApplicationFactory.build()
- organization_event = OrganizationEventFactory.build()
- organization_member = OrganizationMemberFactory.build()
- organization_resource = OrganizationResourceFactory.build()
- organization_task = OrganizationTaskFactory.build()
- organization_topic = OrganizationTopicFactory.build()
- group = GroupFactory.build()
- group_event = GroupEventFactory.build()
- group_member = GroupMemberFactory.build()
- group_resource = GroupResourceFactory.build()
- group_topic = GroupTopicFactory.build()
+ organization = OrganizationFactory.create()
+ # Note: Needs to be updated to reflect the recent changes.
+ # organization_application = OrganizationApplicationFactory.create()
+ organization_event = OrganizationEventFactory.create()
+ organization_member = OrganizationMemberFactory.create()
+ organization_resource = OrganizationResourceFactory.create()
+ organization_task = OrganizationTaskFactory.create()
+ organization_topic = OrganizationTopicFactory.create()
+ group = GroupFactory.create()
+ group_event = GroupEventFactory.create()
+ group_member = GroupMemberFactory.create()
+ group_resource = GroupResourceFactory.create()
+ group_topic = GroupTopicFactory.create()
assert str(organization) == organization.name
# assert str(organization_application) == str(organization_application.creation_date)
diff --git a/backend/events/factories.py b/backend/events/factories.py
index 8b8e87f17..d23368c9f 100644
--- a/backend/events/factories.py
+++ b/backend/events/factories.py
@@ -1,4 +1,5 @@
import datetime
+import random
import factory
@@ -28,11 +29,26 @@ class Meta:
online_location_link = factory.Faker("url")
offline_location_lat = factory.Faker("latitude")
offline_location_long = factory.Faker("longitude")
- start_time = factory.LazyFunction(datetime.datetime.now)
- end_time = factory.Faker("future_date", end_date="+15d")
+ start_time = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
+ end_time = factory.LazyAttribute(
+ lambda x: (
+ datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(days=1)
+ )
+ )
created_by = factory.SubFactory("authentication.factories.UserFactory")
- creation_date = factory.LazyFunction(datetime.datetime.now)
- deletion_date = factory.Faker("future_date", end_date="+30d")
+ creation_date = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
+ deletion_date = random.choice(
+ [
+ None,
+ datetime.datetime.now(tz=datetime.timezone.utc)
+ + datetime.timedelta(days=30),
+ ]
+ )
+ is_private = factory.Faker("boolean")
class FormatFactory(factory.django.DjangoModelFactory):
@@ -41,8 +57,12 @@ class Meta:
name = factory.Faker("word")
description = factory.Faker("text")
- creation_date = factory.LazyFunction(datetime.datetime.now)
- last_updated = factory.LazyFunction(datetime.datetime.now)
+ creation_date = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
+ last_updated = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
deprecation_date = factory.Faker("future_date", end_date="+30d")
@@ -53,8 +73,12 @@ class Meta:
name = factory.Faker("word")
is_custom = factory.Faker("boolean")
description = factory.Faker("text")
- creation_date = factory.LazyFunction(datetime.datetime.now)
- last_updated = factory.LazyFunction(datetime.datetime.now)
+ creation_date = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
+ last_updated = factory.LazyFunction(
+ lambda: datetime.datetime.now(tz=datetime.timezone.utc)
+ )
deprecation_date = factory.Faker("future_date", end_date="+30d")
diff --git a/backend/events/models.py b/backend/events/models.py
index 8317857a3..7814b0a98 100644
--- a/backend/events/models.py
+++ b/backend/events/models.py
@@ -41,7 +41,7 @@ def __str__(self) -> str:
class Format(models.Model):
- id = models.IntegerField(primary_key=True)
+ id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
name = models.CharField(max_length=255)
description = models.TextField(max_length=500)
creation_date = models.DateTimeField(auto_now_add=True)
@@ -53,7 +53,7 @@ def __str__(self) -> str:
class Role(models.Model):
- id = models.IntegerField(primary_key=True)
+ id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
name = models.CharField(max_length=255)
is_custom = models.BooleanField(default=False)
description = models.TextField(max_length=500)
@@ -81,7 +81,7 @@ def __str__(self) -> str:
class EventAttendeeStatus(models.Model):
- id = models.IntegerField(primary_key=True)
+ id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
status_name = models.CharField(max_length=255)
def __str__(self) -> str:
diff --git a/backend/events/tests.py b/backend/events/tests.py
index 969fb27da..87dfe9423 100644
--- a/backend/events/tests.py
+++ b/backend/events/tests.py
@@ -3,6 +3,7 @@
"""
# mypy: ignore-errors
+import pytest
from .factories import (
EventFactory,
@@ -14,15 +15,18 @@
RoleFactory,
)
+pytestmark = pytest.mark.django_db
+
def test_str_methods() -> None:
- event = EventFactory.build()
- event_attendee = EventAttendeeFactory.build()
- event_format = EventFormatFactory.build()
- event_attendee_status = EventAttendeeStatusFactory.build()
- event_resource = EventResourceFactory.build()
- _format = FormatFactory.build()
- role = RoleFactory.build()
+ event = EventFactory.create()
+ event_attendee = EventAttendeeFactory.create()
+ event_format = EventFormatFactory.create()
+ event_attendee_status = EventAttendeeStatusFactory.create()
+ event_resource = EventResourceFactory.create()
+ _format = FormatFactory.create()
+ role = RoleFactory.create()
+
assert str(event) == event.name
assert (
str(event_attendee) == f"{event_attendee.user_id} - {event_attendee.event_id}"
diff --git a/docker-compose.yml b/docker-compose.yml
index 74c399df2..3a6551258 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,5 +1,3 @@
-version: "3.7"
-
services:
backend:
env_file:
@@ -14,7 +12,7 @@ services:
python manage.py loaddata fixtures/superuser.json &&
python manage.py loaddata fixtures/status_types.json &&
python manage.py loaddata fixtures/iso_code_map.json &&
- python manage.py populate_db --users=100 &&
+ python manage.py populate_db --users 10 --orgs 10 --groups 10 --events 10 &&
python manage.py runserver 0.0.0.0:${BACKEND_PORT}"
ports:
- "${BACKEND_PORT}:${BACKEND_PORT}"
diff --git a/frontend/components/sidebar/left/SidebarLeft.vue b/frontend/components/sidebar/left/SidebarLeft.vue
index 1f665941e..4311bacee 100644
--- a/frontend/components/sidebar/left/SidebarLeft.vue
+++ b/frontend/components/sidebar/left/SidebarLeft.vue
@@ -251,14 +251,16 @@ const applyTopShadow = ref(false);
function setSidebarContentScrollable(): void {
setTimeout(() => {
- sidebarContentScrollable.value =
- content.value.scrollHeight > content.value.clientHeight ? true : false;
+ if (content && content.value) {
+ sidebarContentScrollable.value =
+ content.value.scrollHeight > content.value.clientHeight ? true : false;
+ }
}, 50);
isAtTop();
}
function isAtTop(): void {
- if (sidebarContentScrollable) {
+ if (sidebarContentScrollable && content && content.value) {
applyTopShadow.value = !(content.value.scrollTop === 0);
}
}