Skip to content

feat(speakers): add has_pending_presentations filter for speakers and submitters - #562

Merged
smarcet merged 5 commits into
mainfrom
feature/speakers-grid-new-filter
Sep 16, 2026
Merged

smarcet merged 5 commits into
mainfrom
feature/speakers-grid-new-filter

Conversation

@romanetar

@romanetar romanetar commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

ref https://app.clickup.com/t/86badvupk

Summary by CodeRabbit

  • New Features

    • Added filtering capability to filter speakers and submitters by pending presentation status across all relevant endpoints, including speakers list, submitters list, CSV exports, activity counts, and bulk email operations.
  • Tests

    • Added test coverage for pending presentation filtering functionality for both speakers and submitters.

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 869191ac-3dfc-48db-93b2-0c2b10e798ff

📝 Walkthrough

Walkthrough

The PR adds a has_pending_presentations boolean filter to speaker and submitter API endpoints (getSpeakers, getSpeakersActivitiesCount, getSpeakersCSV, getAllBySummit, getAllBySummitCSV, send, getSubmittersActivitiesCount). Repositories implement the filter via EXISTS/NOT EXISTS Doctrine SQL subqueries checking for unpublished, unselected presentations. Integration tests verify both paths.

Changes

has_pending_presentations filter

Layer / File(s) Summary
Repository EXISTS/NOT EXISTS predicate logic
app/Repositories/Summit/DoctrineSpeakerRepository.php, app/Repositories/Summit/DoctrineMemberRepository.php
Both repositories add a DoctrineSwitchFilterMapping for has_pending_presentations. For "true", EXISTS subqueries match unpublished presentations linked to speaker/member that are absent from SummitSelectedPresentation Group/Session lists; "false" inverts with NOT EXISTS. Both splice in $extraSelectionStatusFilter when available. The speaker variant handles both direct speaker links and moderator links.
Speaker controller filter parsing and validation
app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSpeakersApiController.php
Adds has_pending_presentations with == operator to filter parser configs and in:true,false validation rules across getSpeakers, getSpeakersActivitiesCount, and getSpeakersCSV. OpenAPI filter descriptions are updated for all three endpoints.
Submitter controller filter parsing and validation
app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSubmittersApiController.php
Adds has_pending_presentations with == operator and in:true,false validation across getAllBySummit, getAllBySummitCSV, send, and getSubmittersActivitiesCount. The getSubmittersActivitiesCount OpenAPI description is also updated.
Integration tests
tests/oauth2/OAuth2SummitSpeakersApiTest.php, tests/oauth2/OAuth2SummitSubmittersApiTest.php
New test methods create an unpublished, unselected presentation, call the list endpoint with has_pending_presentations==true, and assert HTTP 200 with non-empty data.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • OpenStackweb/summit-api#543: Adds the getSpeakersActivitiesCount / getSubmittersActivitiesCount endpoints and underlying repository logic that this PR extends with the has_pending_presentations filter.

Suggested reviewers

  • smarcet
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and concisely describes the main change: adding a new filter field has_pending_presentations to speakers and submitters endpoints, which is directly reflected in the changeset across controllers, repositories, and tests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/speakers-grid-new-filter

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

📘 OpenAPI / Swagger preview

➡️ https://OpenStackweb.github.io/summit-api/openapi/pr-562/

This page is automatically updated on each push to this PR.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSpeakersApiController.php`:
- Line 254: The protected route's OpenAPI parameter description for the speakers
endpoint needs to be updated to match the filter options added on line 254.
Locate the description field for the protected speakers route (the authenticated
`/api/v1/summits/{id}/speakers` endpoint) and add `has_pending_presentations` to
the list of supported filters in the same format as the public route, ensuring
both routes advertise the same available filter parameters.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fdcf26d7-1680-4902-b468-48a4e28f67df

📥 Commits

Reviewing files that changed from the base of the PR and between 5a64bc5 and 7ce716b.

📒 Files selected for processing (6)
  • app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSpeakersApiController.php
  • app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSubmittersApiController.php
  • app/Repositories/Summit/DoctrineMemberRepository.php
  • app/Repositories/Summit/DoctrineSpeakerRepository.php
  • tests/oauth2/OAuth2SummitSpeakersApiTest.php
  • tests/oauth2/OAuth2SummitSubmittersApiTest.php

Comment thread app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSpeakersApiController.php Outdated
@romanetar
romanetar force-pushed the feature/speakers-grid-new-filter branch from 7ce716b to 1dc2b14 Compare June 22, 2026 14:13
@github-actions

Copy link
Copy Markdown

📘 OpenAPI / Swagger preview

➡️ https://OpenStackweb.github.io/summit-api/openapi/pr-562/

This page is automatically updated on each push to this PR.

@romanetar
romanetar requested a review from smarcet June 22, 2026 14:35
Comment thread app/Repositories/Summit/DoctrineSpeakerRepository.php
Comment thread tests/oauth2/OAuth2SummitSpeakersApiTest.php Outdated
Comment thread app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSpeakersApiController.php Outdated

@smarcet smarcet left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@romanetar please review

… submitters

Signed-off-by: romanetar <roman_ag@hotmail.com>
…ntations

The filter only checked published=0 and the absence of a selection-list
entry, so a speaker/submitter whose presentation was already
complete/received (PHASE_COMPLETE/STATUS_RECEIVED) still matched
pending==true whenever it hadn't been selected yet by a track chair.
During an open CFP this matched nearly every submission, which would
have sent "finish your submission" reminders to people who already had.

Adds a check on Presentation.progress/status so the filter now also
requires the submission itself to be unfinished, in both
DoctrineSpeakerRepository and the equivalent mapping in
DoctrineMemberRepository.
The list/count tests for has_pending_presentations only asserted
count > 0 or baseline + 1, which held true even if the filter were a
complete no-op: the base speaker/submitter query already returns
everyone with summit activity, and getUniqueActivitiesCountBySummit
would just count "all activities" if the filter were ignored, still
landing on baseline + 1 after adding one presentation.

Add a published-presentation negative control to each test and assert
on the exact set of returned/counted IDs, so the tests actually fail
if the pending filter stops filtering.
…siblings

The protected getSpeakers filter parameter still had the stale, truncated
description ("...has_accepted_presentations, etc.") while the public
getSpeakersPublic and the submitters endpoints were already updated with
the full enumerated filter list, including has_pending_presentations and
has_published_presentations. Align it so the generated docs advertise
the same filters on both routes.
@romanetar
romanetar force-pushed the feature/speakers-grid-new-filter branch from 1dc2b14 to 2324cb9 Compare September 7, 2026 14:47
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown

📘 OpenAPI / Swagger preview

➡️ https://OpenStackweb.github.io/summit-api/openapi/pr-562/

This page is automatically updated on each push to this PR.

@romanetar
romanetar requested a review from smarcet September 7, 2026 15:30
$this->assertTrue(!is_null($speakers));
}

public function testGetCurrentSummitSpeakersWithPendingPresentations()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@romanetar The new tests only exercise has_pending_presentations==true through the speaker-role branch on the list endpoints; the false case, the moderator branch, the submitters count endpoint and both send endpoints ship with no coverage.

Why it matters: the speaker false case in DoctrineSpeakerRepository is a hand-assembled NOT EXISTS (...) AND NOT EXISTS (...) string that no test ever executes, so an OR/AND slip or an unbalanced paren there leaves the whole suite green while the "No Pending Submissions" option summit-admin PR 989 adds (pendingSubmissionsDDL) returns wrong rows or a 500. Same for the moderator EXISTS (__p42): dropping or mis-joining it would go unnoticed. And the ticket's stated goal is the reminder email through PUT .../speakers/all/send and .../submitters/all/send, yet nothing asserts the chunk handed to ProcessSpeakersEmailRequestJob / ProcessSubmittersEmailRequestJob is narrowed by this filter.

All four have a precedent in these files to copy from:

  • false branch: testGetSubmittersWithSubmittedMediaUploadsWithType (OAuth2SummitSubmittersApiTest.php:336) already queries has_alternate_presentations==false. Reuse the seeding of this test, query has_pending_presentations==false, and assert the complete/received speaker is returned and the incomplete one is not. Twin test in the submitters suite.
  • Moderator branch: testGetCurrentSummitSpeakersActivitiesCount (:2633) seeds a moderated presentation via setModerator. Seed an incomplete presentation whose only link to the speaker is setModerator($speaker), assert it is returned for ==true and excluded for ==false.
  • send: testSendSpeakersBulkEmailFilteredByMemberUserExternalId (:1040) is the template: Queue::fake(), call send with has_pending_presentations==true, then Queue::assertPushed(ProcessSpeakersEmailRequestJob::class, fn($job) => chunk === [pending speaker id]) with a complete/received control speaker that must not be in the chunk. Twin test in OAuth2SummitSubmittersApiTest next to testSendSpeakersBulkEmail (:299).
  • Submitters count: mirror testGetCurrentSummitSpeakersActivitiesCountWithPendingPresentations (:2774) against OAuth2SummitSubmittersApiController@getSubmittersActivitiesCount, with the published control on defaultMember2.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the four gaps you flagged, all passing against a real DB run:

  • has_pending_presentations==false for speakers (testGetCurrentSummitSpeakersWithPendingPresentationsFalse) and submitters (testGetCurrentSummitSubmittersWithPendingPresentationsFalse) - complete/received control returned, unfinished submission excluded.
  • Moderator-only branch (__p42): testGetCurrentSummitSpeakersWithPendingPresentationsModeratorOnly seeds a presentation linked only via setModerator(), asserted for both ==true and ==false.
  • send endpoints: testSendSpeakersBulkEmailFilteredByHasPendingPresentations asserts the chunk handed to ProcessSpeakersEmailRequestJob is exactly the pending speaker, not the complete/received control. For submitters, SubmitterService::triggerSendEmails forwards the raw filter to ProcessSubmittersEmailRequestJob instead of pre-resolving it to ids (unlike the speaker flow), so testSendSubmittersBulkEmailFilteredByHasPendingPresentations asserts the filter reaches the job unmodified via reflection on its private filter property - noted in the test's docblock.
  • Submitters activities count: testGetCurrentSummitSubmittersActivitiesCountWithPendingPresentations mirrors the speakers one, baseline via direct repository call, defaultMember2 as the published control.

Pushed as 58f9ac6.

@smarcet smarcet left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@romanetar please review

…count gaps

Adds the coverage flagged in PR #562 review: the false branch and the
moderator-only branch of has_pending_presentations in
DoctrineSpeakerRepository/DoctrineMemberRepository, the narrowed chunk
handed to ProcessSpeakersEmailRequestJob on PUT speakers/all/send, the
filter forwarded to ProcessSubmittersEmailRequestJob on PUT
submitters/all/send, and the submitters activities count endpoint.
@romanetar
romanetar requested a review from smarcet September 15, 2026 14:40
@github-actions

Copy link
Copy Markdown

📘 OpenAPI / Swagger preview

➡️ https://OpenStackweb.github.io/summit-api/openapi/pr-562/

This page is automatically updated on each push to this PR.

@smarcet smarcet left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@smarcet
smarcet merged commit dd92877 into main Sep 16, 2026
35 of 36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants