Skip to content

Commit 4f17629

Browse files
author
사재혁
authored
Merge pull request #60 from pythonkr/feat/fallback-speaker-image-to-profile-image
feat: 발표자 이미지 미등록 시 프로필 이미지로 폴백
2 parents b3a8c74 + 64271f5 commit 4f17629

3 files changed

Lines changed: 61 additions & 2 deletions

File tree

app/event/presentation/models.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def get_all_nested_data(self):
2626
),
2727
models.Prefetch(
2828
lookup="speakers",
29-
queryset=PresentationSpeaker.objects.filter_active().select_related("user", "image"),
29+
queryset=PresentationSpeaker.objects.filter_active().select_related("user__image", "image"),
3030
to_attr="_prefetched_active_speakers",
3131
),
3232
models.Prefetch(
@@ -159,6 +159,11 @@ class PresentationSpeaker(BaseAbstractModel):
159159
image = models.ForeignKey(PublicFile, on_delete=models.PROTECT, null=True, blank=True)
160160
biography = MarkdownField(blank=True, default="")
161161

162+
@property
163+
def display_image(self) -> PublicFile | None:
164+
"""발표자 이미지를 따로 등록하지 않았다면 프로필 이미지로 대체한다."""
165+
return self.image or self.user.image
166+
162167

163168
class CallForPresentationSchedule(BaseAbstractModel):
164169
presentation_type = models.ForeignKey(PresentationType, on_delete=models.PROTECT)

app/event/presentation/serializers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class Meta:
5555

5656
class PresentationSpeakerSerializer(serializers.ModelSerializer):
5757
nickname = serializers.CharField(source="user.nickname", read_only=True)
58-
image = serializers.FileField(source="image.file", read_only=True, allow_null=True)
58+
image = serializers.FileField(source="display_image.file", read_only=True, allow_null=True)
5959

6060
class Meta:
6161
model = PresentationSpeaker

app/event/presentation/test/api_test.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from event.models import Event
88
from event.presentation.models import Presentation, PresentationType
99
from event.presentation.test.conftest import PresentationTestEntity
10+
from file.models import PublicFile
1011
from rest_framework.test import APIClient
1112
from user.models.organization import Organization
1213

@@ -86,3 +87,56 @@ def test_presentation_defaults_to_latest_event(api_client: APIClient):
8687
response_data = response.json()
8788
assert len(response_data) == 1
8889
assert response_data[0]["id"] == str(new_prst.id)
90+
91+
92+
def _make_public_file(name: str) -> PublicFile:
93+
return PublicFile.objects.create(file=f"public/{name}.png", mimetype="image/png", hash=name, size=0)
94+
95+
96+
def _get_speaker_image(api_client: APIClient) -> str | None:
97+
response = api_client.get(reverse("v1:presentation-list"))
98+
assert response.status_code == http.HTTPStatus.OK
99+
return response.json()[0]["speakers"][0]["image"]
100+
101+
102+
@pytest.mark.django_db
103+
def test_speaker_image_falls_back_to_profile_image(
104+
api_client: APIClient, create_presentation_set: PresentationTestEntity
105+
):
106+
# Given: 발표자 이미지는 비어 있고 프로필 이미지만 등록된 발표자
107+
user = create_presentation_set.user
108+
user.image = _make_public_file("profile")
109+
user.save()
110+
111+
# Then: 프로필 이미지가 대신 노출된다.
112+
image_url = _get_speaker_image(api_client)
113+
assert image_url is not None and image_url.endswith(user.image.file.url)
114+
115+
116+
@pytest.mark.django_db
117+
def test_speaker_image_takes_precedence_over_profile_image(
118+
api_client: APIClient, create_presentation_set: PresentationTestEntity
119+
):
120+
# Given: 발표자 이미지와 프로필 이미지가 모두 등록된 발표자
121+
user = create_presentation_set.user
122+
user.image = _make_public_file("profile")
123+
user.save()
124+
125+
speaker = create_presentation_set.presentation_speaker
126+
speaker.image = _make_public_file("speaker")
127+
speaker.save()
128+
129+
# Then: 발표자 이미지가 우선한다.
130+
image_url = _get_speaker_image(api_client)
131+
assert image_url is not None and image_url.endswith(speaker.image.file.url)
132+
133+
134+
@pytest.mark.django_db
135+
def test_speaker_image_is_null_without_any_image(
136+
api_client: APIClient, create_presentation_set: PresentationTestEntity
137+
):
138+
# Given: 발표자 이미지도 프로필 이미지도 없는 발표자
139+
assert create_presentation_set.presentation_speaker.image is None
140+
assert create_presentation_set.user.image is None
141+
142+
assert _get_speaker_image(api_client) is None

0 commit comments

Comments
 (0)