Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions posts/services/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,12 @@ def approve_post(
],
)

# Now that the question timing fields are finalized, recompute global
# leaderboard tags — at create time these were skipped because the
# required open_time / scheduled_close_time were not yet set (relevant
# for duplicated posts in particular, whose timing fields are cleared).
update_global_leaderboard_tags(post)

# Automatically update secondary and default project forecasting end date
for project in post.get_related_projects():
if project.type in [
Expand Down
55 changes: 55 additions & 0 deletions tests/unit/test_posts/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from projects.permissions import ObjectPermission
from projects.services.common import get_site_main_project
from questions.models import Question
from scoring.constants import LeaderboardScoreTypes
from scoring.models import Leaderboard
from tests.unit.test_comments.factories import factory_comment
from tests.unit.test_posts.factories import factory_post
from tests.unit.test_projects.factories import factory_project
Expand Down Expand Up @@ -555,6 +557,59 @@ def test_approve_post(user1, user1_client, question_binary):
assert response.status_code == status.HTTP_400_BAD_REQUEST


@freeze_time("2024-11-17T12:00Z")
def test_approve_post__updates_global_leaderboard_tags(user1, user1_client):
# Set up a matching global leaderboard on the site-main project so that
# approval-time question dates fall inside its window.
site_main = get_site_main_project()
Leaderboard.objects.create(
project=site_main,
score_type=LeaderboardScoreTypes.PEER_GLOBAL,
start_time=make_aware(datetime(2024, 1, 1)),
end_time=make_aware(datetime(2025, 1, 1)),
)

tournament = factory_project(
type=Project.ProjectTypes.TOURNAMENT,
visibility=Project.Visibility.NORMAL,
override_permissions={user1.pk: ObjectPermission.ADMIN},
)
# Simulate a duplicated post: question has no open/close/resolve times set
# yet (frontend clears them for duplicates), so create-time tag update
# cannot compute a leaderboard window.
question = create_question(question_type=Question.QuestionType.BINARY)
question.open_time = None
question.scheduled_close_time = None
question.scheduled_resolve_time = None
question.save()
post = factory_post(
author=user1,
curation_status=Post.CurationStatus.PENDING,
default_project=tournament,
question=question,
)
# Pre-condition: create-time tag pass produced no leaderboard tag because
# the timing fields were null.
post.projects.set(post.projects.exclude(type=Project.ProjectTypes.LEADERBOARD_TAG))

url = reverse("post-approve", kwargs={"pk": post.pk})
response = user1_client.post(
url,
{
"published_at": "2024-11-17T11:00Z",
"open_time": "2024-11-17T11:00Z",
"cp_reveal_time": "2024-11-18T11:00Z",
"scheduled_close_time": "2024-11-19T11:00Z",
"scheduled_resolve_time": "2024-11-19T11:00Z",
},
)
assert response.status_code == status.HTTP_204_NO_CONTENT

post.refresh_from_db()
leaderboard_tags = post.projects.filter(type=Project.ProjectTypes.LEADERBOARD_TAG)
assert leaderboard_tags.count() == 1


def test_repost(user1, user1_client, user2, user2_client, question_binary):
default_project = factory_project(
type=Project.ProjectTypes.TOURNAMENT,
Expand Down
Loading