Skip to content

Fixing some small Honeybager alerts#54

Open
ericvanjohnson wants to merge 1 commit intophparch:mainfrom
ericvanjohnson:main
Open

Fixing some small Honeybager alerts#54
ericvanjohnson wants to merge 1 commit intophparch:mainfrom
ericvanjohnson:main

Conversation

@ericvanjohnson
Copy link
Copy Markdown
Member

@ericvanjohnson ericvanjohnson commented Mar 31, 2026

Summary by CodeRabbit

  • New Features

    • Website information for sponsors is now optional. The partner section interface gracefully displays sponsor details whether or not a website link is provided, enabling more flexible sponsor management.
  • Tests

    • Added comprehensive test coverage for sponsor display functionality, validating that sponsors render correctly both with and without associated website information across various configuration scenarios.

Copy link
Copy Markdown

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 31, 2026

Walkthrough

This PR adds support for optional website fields on Sponsor records. It introduces a database migration to make the website column nullable, adds a factory method to generate sponsors without websites, updates the view to conditionally display website links, and includes comprehensive tests verifying the functionality across different scenarios.

Changes

Cohort / File(s) Summary
Factory Enhancement
database/factories/SponsorFactory.php
Added withoutWebsite() state method to generate Sponsor records with website set to null.
Database Migration
database/migrations/2026_03_31_004613_make_sponsor_website_nullable.php
Migration to alter the sponsors table and make the website column nullable.
View Logic
resources/views/components/partners-section.blade.php
Updated sponsor modal to conditionally render the website link based on sponsor.website presence; hides link container when website is absent.
Test Coverage
tests/Feature/Http/Controllers/SponsorControllerTest.php
Replaced placeholder test with three feature tests verifying sponsor rendering: with website, without website, and mixed scenarios. Added database refresh and conference fixture setup.

Suggested reviewers

  • johncongdon
  • svpernova09

Poem

🐰 A sponsor's site need not always show,
With factories and migrations we go,
The views now check with care and grace,
Displaying links in the proper place! 🌐✨


🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Fixing some small Honeybager alerts' is vague and does not clearly describe the specific changes made. The PR actually implements nullable website support for sponsors (migration, factory method, view updates, tests), but the title provides no indication of this functionality. Revise the title to be more specific about the changes, such as 'Make sponsor website field nullable' or 'Add support for sponsors without websites', which would better reflect the actual implementation.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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 (2)
tests/Feature/Http/Controllers/SponsorControllerTest.php (1)

29-33: Simplify attach() call by removing redundant foreign keys.

Laravel's BelongsToMany::attach() automatically handles the foreign keys (sponsor_uuid, conference_uuid) based on the relationship definition. Only pivot-specific data like sponsorship_level needs to be passed.

♻️ Proposed simplification
     $this->conference->sponsors()->attach($sponsor->uuid, [
-        'sponsor_uuid' => $sponsor->uuid,
-        'conference_uuid' => $this->conference->uuid,
         'sponsorship_level' => 'gold',
     ]);

Apply the same simplification to the other attach() calls on lines 45-49, 64-68, and 70-74.

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

In `@tests/Feature/Http/Controllers/SponsorControllerTest.php` around lines 29 -
33, The attach() calls in SponsorControllerTest.php pass redundant pivot foreign
keys; update each occurrence of $this->conference->sponsors()->attach(...)
(including the other three similar calls) to only pass the related model id/uuid
and the pivot-specific data (remove 'sponsor_uuid' and 'conference_uuid'), e.g.
call attach($sponsor->uuid, ['sponsorship_level' => 'gold']) so Laravel's
BelongsToMany relationship supplies the foreign keys automatically.
database/migrations/2026_03_31_004613_make_sponsor_website_nullable.php (1)

7-17: Consider adding a down() method for rollback capability.

The migration lacks a down() method to reverse the schema change. While Laravel allows this, it prevents clean rollbacks during development or if issues arise in production.

🔧 Proposed fix to add rollback support
     public function up(): void
     {
         Schema::table('sponsors', function (Blueprint $table) {
             $table->string('website')->nullable()->change();
         });
     }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('sponsors', function (Blueprint $table) {
+            $table->string('website')->nullable(false)->change();
+        });
+    }
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@database/migrations/2026_03_31_004613_make_sponsor_website_nullable.php`
around lines 7 - 17, Add a down() method to the anonymous Migration class to
reverse the up() change: in down() call Schema::table('sponsors', function
(Blueprint $table) { ... }) and change the 'website' column back to non-nullable
(undo the ->nullable()->change() applied in up()). Reference the same migration
class and methods (up(), down(), Schema::table, Blueprint) and ensure the
change() call mirrors the up() but removes nullability so rollbacks restore the
original state.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/Feature/Http/Controllers/SponsorControllerTest.php`:
- Around line 35-39: The test in SponsorControllerTest is hitting the model's
logoUrl accessor which calls Storage::disk('s3')->url() because the factory
produced a relative logo path; to fix, update the test to either use the
phpArchitect() factory state (so the factory returns a full HTTP logo URL), add
a new factory state that sets a non-S3 or absolute logo path, or mock the
storage by calling Storage::fake() before creating the Sponsor so logoUrl won’t
call the real S3 disk; adjust the test setup accordingly to use phpArchitect()
or Storage::fake() and then assertSee as before.

---

Nitpick comments:
In `@database/migrations/2026_03_31_004613_make_sponsor_website_nullable.php`:
- Around line 7-17: Add a down() method to the anonymous Migration class to
reverse the up() change: in down() call Schema::table('sponsors', function
(Blueprint $table) { ... }) and change the 'website' column back to non-nullable
(undo the ->nullable()->change() applied in up()). Reference the same migration
class and methods (up(), down(), Schema::table, Blueprint) and ensure the
change() call mirrors the up() but removes nullability so rollbacks restore the
original state.

In `@tests/Feature/Http/Controllers/SponsorControllerTest.php`:
- Around line 29-33: The attach() calls in SponsorControllerTest.php pass
redundant pivot foreign keys; update each occurrence of
$this->conference->sponsors()->attach(...) (including the other three similar
calls) to only pass the related model id/uuid and the pivot-specific data
(remove 'sponsor_uuid' and 'conference_uuid'), e.g. call attach($sponsor->uuid,
['sponsorship_level' => 'gold']) so Laravel's BelongsToMany relationship
supplies the foreign keys automatically.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 549df2be-1602-4547-be40-c97bd61fba2f

📥 Commits

Reviewing files that changed from the base of the PR and between 456e12f and c5acd52.

📒 Files selected for processing (4)
  • database/factories/SponsorFactory.php
  • database/migrations/2026_03_31_004613_make_sponsor_website_nullable.php
  • resources/views/components/partners-section.blade.php
  • tests/Feature/Http/Controllers/SponsorControllerTest.php

Comment on lines +35 to +39
$response = $this->get('/');

$response->assertStatus(200);
$response->assertSee($sponsor->name, false);
$response->assertSee('example.com', false);
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
# Check how other tests handle file storage/S3 dependencies
echo "=== Searching for Storage mocking patterns in existing tests ==="
rg -n "Storage::fake|fake\('s3'\)|mockery.*Storage" tests/ --type php -C 2

echo ""
echo "=== Check if there's a test trait for storage ==="
fd -t f "Storage" tests/ --exec head -30 {}

echo ""
echo "=== Looking at .env.testing or phpunit.xml for filesystem config ==="
cat .env.testing 2>/dev/null || echo ".env.testing not found"
cat phpunit.xml | grep -A2 -B2 "FILESYSTEM\|AWS" || echo "No filesystem env vars in phpunit.xml"

Repository: phparch/phptek-2026

Length of output: 309


🏁 Script executed:

#!/bin/bash
# Read the actual test file to understand the S3 issue
echo "=== Reading SponsorControllerTest.php ==="
wc -l tests/Feature/Http/Controllers/SponsorControllerTest.php
head -60 tests/Feature/Http/Controllers/SponsorControllerTest.php

echo ""
echo "=== Checking phpunit.xml for full configuration ==="
cat phpunit.xml

Repository: phparch/phptek-2026

Length of output: 3179


🏁 Script executed:

#!/bin/bash
# Check the Sponsor model and factory for storage/image usage
echo "=== Checking Sponsor model ==="
find app -name "Sponsor.php" -type f | head -1 | xargs cat -n

echo ""
echo "=== Checking Sponsor factory ==="
find database -name "*SponsorFactory*" -type f | head -1 | xargs cat -n

echo ""
echo "=== Searching for file/image/logo fields in migrations ==="
find database/migrations -name "*.php" | xargs rg -n "sponsor|Sponsor" | head -20

Repository: phparch/phptek-2026

Length of output: 6828


Use the phpArchitect() factory state or mock Storage to avoid S3 dependency in tests.

The sponsor logo paths in the factory default to relative paths (e.g., 'images/sponsors/acme.png'), which trigger the logoUrl accessor to call Storage::disk('s3')->url(). Since the test environment has no S3 configuration, the tests fail. Either use the existing phpArchitect() factory state which uses an HTTP URL, add a factory state for testing with a non-S3 logo, or mock the storage layer with Storage::fake().

🧰 Tools
🪛 GitHub Actions: tests

[error] 35-40: SponsorControllerTest > partners section renders sponsors with website: expected response status code [200] but received 500. Underlying exception: InvalidArgumentException: The GetObject operation requires non-empty parameter: Bucket (triggered while rendering /resources/views/components/partners-section.blade.php).

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

In `@tests/Feature/Http/Controllers/SponsorControllerTest.php` around lines 35 -
39, The test in SponsorControllerTest is hitting the model's logoUrl accessor
which calls Storage::disk('s3')->url() because the factory produced a relative
logo path; to fix, update the test to either use the phpArchitect() factory
state (so the factory returns a full HTTP logo URL), add a new factory state
that sets a non-S3 or absolute logo path, or mock the storage by calling
Storage::fake() before creating the Sponsor so logoUrl won’t call the real S3
disk; adjust the test setup accordingly to use phpArchitect() or Storage::fake()
and then assertSee as before.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to address Honeybadger alerts by making sponsor websites optional end-to-end (DB/schema + factory/test data + UI rendering) so the partners modal doesn’t error when a sponsor has no website.

Changes:

  • Updates the partners modal JS to hide the “Website” block when sponsor.website is missing.
  • Makes sponsors.website nullable and adds a SponsorFactory::withoutWebsite() state.
  • Replaces the placeholder SponsorController test with feature tests covering sponsors with/without websites on the home page.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
tests/Feature/Http/Controllers/SponsorControllerTest.php Adds feature tests asserting the home page renders sponsors correctly when website is present/absent.
resources/views/components/partners-section.blade.php Prevents JS errors by conditionally rendering/hiding the sponsor website link in the modal.
database/migrations/2026_03_31_004613_make_sponsor_website_nullable.php Alters sponsors.website to be nullable.
database/factories/SponsorFactory.php Adds a factory state for sponsors with a null website.

Comment on lines +14 to +16
Schema::table('sponsors', function (Blueprint $table) {
$table->string('website')->nullable()->change();
});
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

This migration uses ->change() to alter an existing column, but doctrine/dbal is not installed (not present in composer.json). On common setups (including SQLite), this can cause migrations to fail at runtime. Consider adding the required dependency or rewriting the migration to avoid change() (e.g., a DB-specific alter statement or table rebuild strategy).

Suggested change
Schema::table('sponsors', function (Blueprint $table) {
$table->string('website')->nullable()->change();
});
$connection = Schema::getConnection();
$driver = $connection->getDriverName();
if ($driver === 'mysql') {
$connection->statement('ALTER TABLE sponsors MODIFY website VARCHAR(255) NULL');
} elseif ($driver === 'pgsql') {
$connection->statement('ALTER TABLE sponsors ALTER COLUMN website DROP NOT NULL');
} elseif ($driver === 'sqlsrv') {
$connection->statement('ALTER TABLE sponsors ALTER COLUMN website NVARCHAR(255) NULL');
}

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +17
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('sponsors', function (Blueprint $table) {
$table->string('website')->nullable()->change();
});
}
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

The migration is missing a down() method, which makes rollbacks impossible. Please add a down() that restores the previous NOT NULL constraint (and consider how to handle existing NULL website values before altering back).

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +12
beforeEach(function () {
$this->conference = Conference::create([
'uuid' => 'test-conference-uuid',
'name' => 'PHP Tek 2026',
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

beforeEach assigns $this->conference, which creates a dynamic property on Tests\TestCase. With PHP 8.4, dynamic properties are deprecated and may surface as test noise or failures depending on CI flags. Prefer a file-scoped variable captured by reference, or define a typed $conference property on the base test case if you want to keep using $this->....

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +8
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

uses(RefreshDatabase::class); is redundant for Feature Pest tests in this repo because RefreshDatabase is already applied globally in tests/Pest.php. Removing it will keep the file consistent with the existing test setup.

Suggested change
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +25
test('partners section renders sponsors with website', function () {
$sponsor = Sponsor::factory()->create([
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

This file path/name (Http/Controllers/SponsorControllerTest) doesn’t match what’s being tested (homepage partners section rendering). Renaming/moving the test file to reflect the behavior under test will make it easier to discover and maintain.

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +33
$this->conference->sponsors()->attach($sponsor->uuid, [
'sponsor_uuid' => $sponsor->uuid,
'conference_uuid' => $this->conference->uuid,
'sponsorship_level' => 'gold',
]);
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

When attaching sponsors to the conference, the pivot attributes include sponsor_uuid and conference_uuid, which the belongsToMany relationship will already populate. Keeping only the extra pivot fields (e.g., sponsorship_level) reduces redundancy and avoids accidental mismatches.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

@fwallen fwallen left a comment

Choose a reason for hiding this comment

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

Only one question. Not pulling the handbrake.

Comment on lines +164 to +170
websiteEl.href = sponsor.website;
websiteEl.textContent = sponsor.website;
websiteEl.parentElement.style.display = '';
} else {
websiteEl.href = '#';
websiteEl.textContent = '';
websiteEl.parentElement.style.display = 'none';
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should these references be sponsor.website?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't follow. They are.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In the if we check for sponsor.websiteEl. Assigning the values to the property should be something ilke:

sponsor.websiteEl.href = sponsor.website;
sponsor.websiteEl.textContent = sponsor.website;
sponsor.websiteEl.parentElement.style.display = '';

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.

5 participants