Skip to content

fix(audit): allow nullable sponsor in SummitSponsorExtraQuestionType::getSponsor#531

Merged
smarcet merged 4 commits into
mainfrom
hotfix/delete-extra-question-error
Apr 16, 2026
Merged

fix(audit): allow nullable sponsor in SummitSponsorExtraQuestionType::getSponsor#531
smarcet merged 4 commits into
mainfrom
hotfix/delete-extra-question-error

Conversation

@romanetar
Copy link
Copy Markdown
Collaborator

@romanetar romanetar commented Apr 16, 2026

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

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling when a sponsor is missing or removed across emails, serializers, CSV exports and event payloads to prevent errors and provide sensible defaults.
  • Tests
    • Added unit coverage for audit log formatting when sponsor data is absent; made a test deterministic by replacing randomness.
  • Chores
    • Extended CI test matrix to include additional audit unit tests.

…:getSponsor

Signed-off-by: romanetar <roman_ag@hotmail.com>
@romanetar romanetar requested a review from smarcet April 16, 2026 13:12
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 16, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8150266b-1373-4219-9723-6a5ffcc4d239

📥 Commits

Reviewing files that changed from the base of the PR and between a8e3824 and 5b4b960.

📒 Files selected for processing (3)
  • .github/workflows/push.yml
  • tests/Unit/Audit/SummitSponsorExtraQuestionTypeAuditLogFormatterTest.php
  • tests/oauth2/OAuth2SummitLocationsApiTest.php

📝 Walkthrough

Walkthrough

Nullable sponsor relationships were formalized across models, serializers, events, and email/job logic: method signatures and PHPDoc now allow null for sponsor associations, and callers were updated with guards/null-safe access to avoid dereferencing absent sponsors.

Changes

Cohort / File(s) Summary
Models — sponsor nullable
app/Models/Foundation/Summit/ExtraQuestions/SummitSponsorExtraQuestionType.php, app/Models/Foundation/Summit/Registration/SponsorUserInfoGrant.php, app/Models/Foundation/Summit/SponsorMaterial.php, app/Models/Foundation/Summit/SponsorStatistics.php, app/Models/Foundation/Summit/SummitLeadReportSetting.php, app/Models/Foundation/Summit/SummitSponsorship.php
Updated $sponsor PHPDoc (Sponsor → `Sponsor
Promo code trait & models
app/Models/Foundation/Summit/Registration/PromoCodes/Traits/SponsorPromoCodeTrait.php
Changed getSponsor() return type and docblock to ?Sponsor / `Sponsor
Serializers — promo & CSV
app/ModelSerializers/Summit/Registration/PromoCodes/SponsorSummitRegistrationDiscountCodeSerializer.php, app/ModelSerializers/Summit/Registration/PromoCodes/SponsorSummitRegistrationPromoCodeSerializer.php, app/ModelSerializers/Summit/Registration/SponsorBadgeScanCSVSerializer.php, app/ModelSerializers/Summit/Registration/SponsorUserInfoGrantCSVSerializer.php
Added null checks/early returns or hasSponsor() guards before reading sponsor/company fields to prevent null deref; minor EOF newline fixes.
Events (DTOs)
app/Events/SponsorServices/SummitSponsorshipCreatedEventDTO.php, app/Events/SponsorServices/SummitSponsorshipAddOnCreatedEventDTO.php
Factory methods now fetch sponsor once and use null-safe access ($sponsor?->... ?? 0) to derive sponsor_id/summit_id safely.
Jobs / Emails
app/Jobs/Emails/Registration/PromoCodes/SponsorPromoCodeEmail.php
Made sponsor-dependent payload assembly null-safe (tier names/company access); EOF newline added.
CI workflow
.github/workflows/push.yml
Added AuditUnitTests entry to the matrix so additional unit tests under tests/Unit/Audit/ run in CI.
Tests
tests/Unit/Audit/SummitSponsorExtraQuestionTypeAuditLogFormatterTest.php, tests/oauth2/OAuth2SummitLocationsApiTest.php
Added audit-formatter tests covering cleared sponsors; made venue-floor number deterministic by replacing rand() with static sequence.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • smarcet

Poem

🐰 I nibble code with careful paw and cheer,
Sponsors can nap — nullable, have no fear,
Guards and safe calls keep crashes from sight,
Tests hop in line to prove everything's right,
A tiny hop for stable runtime delight! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary change: updating SummitSponsorExtraQuestionType::getSponsor() to allow nullable sponsors, which is the first and most direct modification in the changeset.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hotfix/delete-extra-question-error

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 and usage tips.

@github-actions
Copy link
Copy Markdown

📘 OpenAPI / Swagger preview

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

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
app/Models/Foundation/Summit/ExtraQuestions/SummitSponsorExtraQuestionType.php (1)

45-47: Make nullability annotations consistent across the model.

Lines 45/47 are nullable, but the property docblock at Line 38 still states @var Sponsor even though clearSponsor() sets it to null. Update it to Sponsor|null to keep static-analysis metadata aligned.

Suggested diff
-    /**
-     * `@var` Sponsor
-     */
+    /**
+     * `@var` Sponsor|null
+     */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/Models/Foundation/Summit/ExtraQuestions/SummitSponsorExtraQuestionType.php`
around lines 45 - 47, Update the docblock for the sponsor property in
SummitSponsorExtraQuestionType to match the nullable return/type usage: change
the property annotation from `@var` Sponsor to `@var` Sponsor|null so it aligns with
getSponsor(): ?Sponsor and clearSponsor() which sets the property to null;
locate the property docblock above the class field (currently annotated as
Sponsor) and make it Sponsor|null to keep static-analysis and IDE hints
consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@app/Models/Foundation/Summit/ExtraQuestions/SummitSponsorExtraQuestionType.php`:
- Around line 45-47: The property docblock for the sponsor field is inaccurate:
update the `@var` annotation (currently `@var` Sponsor) to `@var` Sponsor|null to
match the nullable return type of getSponsor(): ?Sponsor and the behavior of
clearSponsor() which can set the property to null; locate the property
declaration (the $sponsor property) in SummitSponsorExtraQuestionType and change
its docblock to include "|null".

---

Nitpick comments:
In
`@app/Models/Foundation/Summit/ExtraQuestions/SummitSponsorExtraQuestionType.php`:
- Around line 45-47: Update the docblock for the sponsor property in
SummitSponsorExtraQuestionType to match the nullable return/type usage: change
the property annotation from `@var` Sponsor to `@var` Sponsor|null so it aligns with
getSponsor(): ?Sponsor and clearSponsor() which sets the property to null;
locate the property docblock above the class field (currently annotated as
Sponsor) and make it Sponsor|null to keep static-analysis and IDE hints
consistent.
🪄 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: b02f750b-aba1-4599-88f3-de2a79ce0eda

📥 Commits

Reviewing files that changed from the base of the PR and between f3923fa and b430061.

📒 Files selected for processing (1)
  • app/Models/Foundation/Summit/ExtraQuestions/SummitSponsorExtraQuestionType.php

Signed-off-by: romanetar <roman_ag@hotmail.com>
@github-actions
Copy link
Copy Markdown

📘 OpenAPI / Swagger preview

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

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
app/Models/Foundation/Summit/Registration/PromoCodes/Traits/SponsorPromoCodeTrait.php (1)

74-77: Keep property PHPDoc consistent with nullable getter.

getSponsor() is now nullable, but the trait property doc still states non-null Sponsor. Aligning both avoids static-analysis drift.

Suggested doc consistency patch
-    /**
-     * `@var` Sponsor
-     */
+    /**
+     * `@var` Sponsor|null
+     */
     #[ORM\JoinColumn(name: 'SponsorID', referencedColumnName: 'ID')]
     #[ORM\ManyToOne(targetEntity: \models\summit\Sponsor::class)]
     protected $sponsor;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/Models/Foundation/Summit/Registration/PromoCodes/Traits/SponsorPromoCodeTrait.php`
around lines 74 - 77, Update the PHPDoc for the trait property that backs
getSponsor() to match the nullable return type; change the property's doc from
Sponsor to Sponsor|null so it aligns with the nullable getter getSponsor():
?Sponsor in SponsorPromoCodeTrait and avoids static-analysis warnings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/Models/Foundation/Summit/SponsorStatistics.php`:
- Around line 69-72: The serializers dereference
$code->getSponsor()->getCompany()->getName() without guarding for a null
sponsor; update SponsorSummitRegistrationDiscountCodeSerializer and
SponsorSummitRegistrationPromoCodeSerializer to check $code->hasSponsor() (or
$code->getSponsor() !== null) before calling getCompany()/getName(), mirroring
the pattern used in SponsorBadgeScanSerializer::hasSponsor(); if no sponsor,
return a safe fallback (e.g., null or empty string) or handle it explicitly in
the serialized output so the code never calls getCompany() on a null Sponsor.

---

Nitpick comments:
In
`@app/Models/Foundation/Summit/Registration/PromoCodes/Traits/SponsorPromoCodeTrait.php`:
- Around line 74-77: Update the PHPDoc for the trait property that backs
getSponsor() to match the nullable return type; change the property's doc from
Sponsor to Sponsor|null so it aligns with the nullable getter getSponsor():
?Sponsor in SponsorPromoCodeTrait and avoids static-analysis warnings.
🪄 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: 39c26aa1-8d25-47da-88af-3fcaada9b284

📥 Commits

Reviewing files that changed from the base of the PR and between b430061 and a8e3824.

📒 Files selected for processing (14)
  • app/Events/SponsorServices/SummitSponsorshipAddOnCreatedEventDTO.php
  • app/Events/SponsorServices/SummitSponsorshipCreatedEventDTO.php
  • app/Jobs/Emails/Registration/PromoCodes/SponsorPromoCodeEmail.php
  • app/ModelSerializers/Summit/Registration/PromoCodes/SponsorSummitRegistrationDiscountCodeSerializer.php
  • app/ModelSerializers/Summit/Registration/PromoCodes/SponsorSummitRegistrationPromoCodeSerializer.php
  • app/ModelSerializers/Summit/Registration/SponsorBadgeScanCSVSerializer.php
  • app/ModelSerializers/Summit/Registration/SponsorUserInfoGrantCSVSerializer.php
  • app/Models/Foundation/Summit/ExtraQuestions/SummitSponsorExtraQuestionType.php
  • app/Models/Foundation/Summit/Registration/PromoCodes/Traits/SponsorPromoCodeTrait.php
  • app/Models/Foundation/Summit/Registration/SponsorUserInfoGrant.php
  • app/Models/Foundation/Summit/SponsorMaterial.php
  • app/Models/Foundation/Summit/SponsorStatistics.php
  • app/Models/Foundation/Summit/SummitLeadReportSetting.php
  • app/Models/Foundation/Summit/SummitSponsorship.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/Models/Foundation/Summit/ExtraQuestions/SummitSponsorExtraQuestionType.php

Comment on lines +69 to 72
public function getSponsor(): ?Sponsor
{
return $this->sponsor;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect known call sites from current context.
fd -i 'SponsorUserInfoGrantService.php' app --exec sed -n '220,260p' {}
fd -i 'SponsorBadgeScanSerializer.php' app --exec sed -n '50,95p' {}

# Find direct dereferences after getSponsor() (unsafe with nullable contracts).
rg -nP --type=php '\->getSponsor\(\)\s*->' app

# Find getSponsor() passed as arguments for manual nullable-acceptance checks.
rg -nP --type=php '\->getSponsor\(\)\s*[,\)]' app

Repository: OpenStackweb/summit-api

Length of output: 5085


Fix unguarded getSponsor() dereferences that assume non-null return.

The following locations directly dereference getSponsor() results without null checks and will fail if sponsor is null:

  • app/ModelSerializers/Summit/Registration/PromoCodes/SponsorSummitRegistrationDiscountCodeSerializer.php:66$code->getSponsor()->getCompany()->getName()
  • app/ModelSerializers/Summit/Registration/PromoCodes/SponsorSummitRegistrationPromoCodeSerializer.php:67$code->getSponsor()->getCompany()->getName()

Add null checks or use hasSponsor() guards (as done in SponsorBadgeScanSerializer.php:69) before dereferencing. Alternatively, adjust callers to handle null values explicitly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/Models/Foundation/Summit/SponsorStatistics.php` around lines 69 - 72, The
serializers dereference $code->getSponsor()->getCompany()->getName() without
guarding for a null sponsor; update
SponsorSummitRegistrationDiscountCodeSerializer and
SponsorSummitRegistrationPromoCodeSerializer to check $code->hasSponsor() (or
$code->getSponsor() !== null) before calling getCompany()/getName(), mirroring
the pattern used in SponsorBadgeScanSerializer::hasSponsor(); if no sponsor,
return a safe fallback (e.g., null or empty string) or handle it explicitly in
the serialized output so the code never calls getCompany() on a null Sponsor.

@smarcet smarcet merged commit e1e4a8c into main Apr 16, 2026
16 of 17 checks passed
smarcet added a commit that referenced this pull request Apr 16, 2026
…:getSponsor (#531)

* fix(audit): allow nullable sponsor in SummitSponsorExtraQuestionType::getSponsor

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

* fix: update getSponsor return allowing nulls

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

* chore(unit-tests): fix location venue generator

* chore(unit-test): add regresion test

---------

Signed-off-by: romanetar <roman_ag@hotmail.com>
Co-authored-by: smarcet <smarcet@gmail.com>
@github-actions
Copy link
Copy Markdown

📘 OpenAPI / Swagger preview

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

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

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