Skip to content

[Unit Tests] Add coverage for BucketEmpty/Fill objectives and Sound/Title rewards#308

Open
DiamondDagger590 wants to merge 1 commit into
recodefrom
claude/magical-cray-ms5a6i
Open

[Unit Tests] Add coverage for BucketEmpty/Fill objectives and Sound/Title rewards#308
DiamondDagger590 wants to merge 1 commit into
recodefrom
claude/magical-cray-ms5a6i

Conversation

@DiamondDagger590

@DiamondDagger590 DiamondDagger590 commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add BucketEmptyObjectiveTypeCoverageTest (19 tests): canProcess, processProgress with/without bucket filter, wrong context type handling, identity, parseConfig edge cases (empty list, invalid materials, no buckets key)
  • Add BucketFillObjectiveTypeCoverageTest (19 tests): same coverage pattern for the fill variant, correctly mocking getItemStack().getType() instead of getBucket()
  • Add SoundRewardTypeTest (~30 tests): identity, describeForDisplay, serializeConfig round-trips, fromSerializedConfig (missing/invalid sound, missing volume/pitch defaults, non-numeric fallbacks, case-insensitive sound names), parseConfig, grant smoke tests, default QuestRewardType methods
  • Add TitleRewardTypeTest (~28 tests): identity, describeForDisplay, serializeConfig with defaults and configured values, fromSerializedConfig (round-trips, missing fields, non-numeric timing fallbacks, empty config), parseConfig (all fields, missing fields, null getString), grant smoke tests, default QuestRewardType methods

Test plan

  • All 4 new test files compile and pass
  • Full test suite run — only pre-existing QuestRewardDistributionResolverPotBehaviorTest failures (6 tests, present on recode base branch)
  • Testing audit persona reviewed — addressed grant assertion gaps (assertDoesNotThrow) and assertNotSame(true, ...)assertFalse() fixes

🤖 Generated with Claude Code

https://claude.ai/code/session_01Die2JoeWQdKGfBiSQkXGvb


Generated by Claude Code

Summary by CodeRabbit

  • Tests
    • Added comprehensive automated coverage for bucket fill and bucket empty quest objectives, including filtering, configuration parsing, context handling, and identity metadata.
    • Added coverage for sound rewards, including serialization, configuration defaults, playback, and amount behavior.
    • Added coverage for title rewards, including serialization, defaults, configuration parsing, display behavior, and granting.

…and Sound/Title reward types

Add extended coverage test suites for four quest system classes:
- BucketEmptyObjectiveTypeCoverageTest: canProcess, processProgress with/without filter, parseConfig edge cases
- BucketFillObjectiveTypeCoverageTest: same coverage pattern for the fill variant
- SoundRewardTypeTest: identity, serialization round-trips, parseConfig, grant smoke tests, default methods
- TitleRewardTypeTest: identity, serialization round-trips, timing defaults, parseConfig, grant smoke tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Die2JoeWQdKGfBiSQkXGvb
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Added comprehensive JUnit 5 coverage for bucket fill/empty objectives and sound/title rewards, including context handling, filtering, identity, configuration parsing, serialization, granting, defaults, and invalid inputs.

Changes

Bucket objective coverage

Layer / File(s) Summary
Bucket event processing
src/test/java/us/eunoians/mcrpg/quest/objective/type/builtin/*Bucket*ObjectiveTypeCoverageTest.java
Tests cover accepted progress contexts, bucket material matching, non-matching materials, and unsupported context types.
Bucket objective identity and configuration
src/test/java/us/eunoians/mcrpg/quest/objective/type/builtin/*Bucket*ObjectiveTypeCoverageTest.java
Tests verify keys, expansion keys, new instances, optional bucket filters, valid materials, empty lists, and invalid entries.

Reward type coverage

Layer / File(s) Summary
Sound reward configuration and execution
src/test/java/us/eunoians/mcrpg/quest/reward/builtin/SoundRewardTypeTest.java
Tests cover sound identity, serialization, parsing defaults, invalid inputs, granting, and default reward methods.
Title reward configuration and execution
src/test/java/us/eunoians/mcrpg/quest/reward/builtin/TitleRewardTypeTest.java
Tests cover title identity, serialization, parsing defaults, invalid timing values, granting, and default reward methods.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the changes by describing added unit test coverage for bucket objectives and sound/title rewards.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ 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 claude/magical-cray-ms5a6i

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.

@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: 5

🤖 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
`@src/test/java/us/eunoians/mcrpg/quest/objective/type/builtin/BucketFillObjectiveTypeCoverageTest.java`:
- Around line 264-267: In the test setup around the PlayerBucketFillEvent,
replace the mocked ItemStack and its getType stubbing with a real ItemStack
initialized using filledBucketMaterial. Keep the event mock and configure it to
return the real stack via getItemStack, preserving the existing test behavior.

In
`@src/test/java/us/eunoians/mcrpg/quest/reward/builtin/SoundRewardTypeTest.java`:
- Around line 276-281: Update grant_configuredInstance_playsSound to verify the
PlayerMock heard the configured ENTITY_PLAYER_LEVELUP sound after
configured.grant(player). Retain the no-exception assertion if desired, and use
PlayerMock.assertSoundHeard with the configured sound, volume, and pitch.
- Around line 308-310: Update the withExactAmount_returnsSameInstance test to
use assertSame instead of assertEquals, matching the existing identity assertion
pattern in withAmountMultiplier_returnsSameInstance.
- Around line 290-292: Update withAmountMultiplier_returnsSameInstance in
SoundRewardTypeTest to use assertSame when verifying
baseType.withAmountMultiplier(2.0) returns the identical object, and add the
corresponding JUnit assertSame static import.

In
`@src/test/java/us/eunoians/mcrpg/quest/reward/builtin/TitleRewardTypeTest.java`:
- Around line 320-343: Replace assertEquals with assertSame in
withAmountMultiplier_returnsSameInstance and
withExactAmount_returnsSameInstance, and add the corresponding JUnit assertion
import. Preserve the existing method calls and test expectations.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b34d2946-42c1-4f39-8aad-df539c748929

📥 Commits

Reviewing files that changed from the base of the PR and between 6cd90a4 and c7f064c.

📒 Files selected for processing (4)
  • src/test/java/us/eunoians/mcrpg/quest/objective/type/builtin/BucketEmptyObjectiveTypeCoverageTest.java
  • src/test/java/us/eunoians/mcrpg/quest/objective/type/builtin/BucketFillObjectiveTypeCoverageTest.java
  • src/test/java/us/eunoians/mcrpg/quest/reward/builtin/SoundRewardTypeTest.java
  • src/test/java/us/eunoians/mcrpg/quest/reward/builtin/TitleRewardTypeTest.java

Comment on lines +264 to +267
PlayerBucketFillEvent event = mock(PlayerBucketFillEvent.class);
ItemStack itemStack = mock(ItemStack.class);
when(itemStack.getType()).thenReturn(filledBucketMaterial);
when(event.getItemStack()).thenReturn(itemStack);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use a real ItemStack instance instead of mocking it.

Since McRPGBaseTest initializes the MockBukkit environment, you can safely use a real ItemStack instance rather than mocking this data object. This reduces mock setup boilerplate and relies on actual Bukkit behavior.

♻️ Proposed refactor
     private PlayerBucketFillEvent createMockBucketFillEvent(Material filledBucketMaterial) {
         PlayerBucketFillEvent event = mock(PlayerBucketFillEvent.class);
-        ItemStack itemStack = mock(ItemStack.class);
-        when(itemStack.getType()).thenReturn(filledBucketMaterial);
-        when(event.getItemStack()).thenReturn(itemStack);
+        when(event.getItemStack()).thenReturn(new ItemStack(filledBucketMaterial));
         return event;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
PlayerBucketFillEvent event = mock(PlayerBucketFillEvent.class);
ItemStack itemStack = mock(ItemStack.class);
when(itemStack.getType()).thenReturn(filledBucketMaterial);
when(event.getItemStack()).thenReturn(itemStack);
PlayerBucketFillEvent event = mock(PlayerBucketFillEvent.class);
when(event.getItemStack()).thenReturn(new ItemStack(filledBucketMaterial));
🤖 Prompt for 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.

In
`@src/test/java/us/eunoians/mcrpg/quest/objective/type/builtin/BucketFillObjectiveTypeCoverageTest.java`
around lines 264 - 267, In the test setup around the PlayerBucketFillEvent,
replace the mocked ItemStack and its getType stubbing with a real ItemStack
initialized using filledBucketMaterial. Keep the event mock and configure it to
return the real stack via getItemStack, preserving the existing test behavior.

Comment on lines +276 to +281
public void grant_configuredInstance_playsSound() {
SoundRewardType configured = baseType.fromSerializedConfig(
Map.of("sound", "ENTITY_PLAYER_LEVELUP", "volume", 1.0f, "pitch", 1.0f));
PlayerMock player = server.addPlayer();
assertDoesNotThrow(() -> configured.grant(player));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Verify that the sound was actually played to the player.

While assertDoesNotThrow confirms the method doesn't crash, it doesn't verify the expected side effect. MockBukkit's PlayerMock provides assertSoundHeard to explicitly verify that the player received the sound, which makes the test much more robust.

♻️ Proposed refactor
         public void grant_configuredInstance_playsSound() {
             SoundRewardType configured = baseType.fromSerializedConfig(
                     Map.of("sound", "ENTITY_PLAYER_LEVELUP", "volume", 1.0f, "pitch", 1.0f));
             PlayerMock player = server.addPlayer();
             assertDoesNotThrow(() -> configured.grant(player));
+            player.assertSoundHeard(Sound.ENTITY_PLAYER_LEVELUP);
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public void grant_configuredInstance_playsSound() {
SoundRewardType configured = baseType.fromSerializedConfig(
Map.of("sound", "ENTITY_PLAYER_LEVELUP", "volume", 1.0f, "pitch", 1.0f));
PlayerMock player = server.addPlayer();
assertDoesNotThrow(() -> configured.grant(player));
}
public void grant_configuredInstance_playsSound() {
SoundRewardType configured = baseType.fromSerializedConfig(
Map.of("sound", "ENTITY_PLAYER_LEVELUP", "volume", 1.0f, "pitch", 1.0f));
PlayerMock player = server.addPlayer();
assertDoesNotThrow(() -> configured.grant(player));
player.assertSoundHeard(Sound.ENTITY_PLAYER_LEVELUP);
}
🤖 Prompt for 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.

In
`@src/test/java/us/eunoians/mcrpg/quest/reward/builtin/SoundRewardTypeTest.java`
around lines 276 - 281, Update grant_configuredInstance_playsSound to verify the
PlayerMock heard the configured ENTITY_PLAYER_LEVELUP sound after
configured.grant(player). Retain the no-exception assertion if desired, and use
PlayerMock.assertSoundHeard with the configured sound, volume, and pitch.

Comment on lines +290 to +292
public void withAmountMultiplier_returnsSameInstance() {
assertEquals(baseType, baseType.withAmountMultiplier(2.0));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use assertSame to explicitly check object identity.

Since the test name implies checking for the exact same instance (this), assertSame is semantically more precise than assertEquals.

💡 Proposed refactor
         public void withAmountMultiplier_returnsSameInstance() {
-            assertEquals(baseType, baseType.withAmountMultiplier(2.0));
+            assertSame(baseType, baseType.withAmountMultiplier(2.0));
         }

(Ensure you also add import static org.junit.jupiter.api.Assertions.assertSame; at the top of the file).

🤖 Prompt for 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.

In
`@src/test/java/us/eunoians/mcrpg/quest/reward/builtin/SoundRewardTypeTest.java`
around lines 290 - 292, Update withAmountMultiplier_returnsSameInstance in
SoundRewardTypeTest to use assertSame when verifying
baseType.withAmountMultiplier(2.0) returns the identical object, and add the
corresponding JUnit assertSame static import.

Comment on lines +308 to +310
public void withExactAmount_returnsSameInstance() {
assertEquals(baseType, baseType.withExactAmount(10));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use assertSame to explicitly check object identity.

Similar to withAmountMultiplier_returnsSameInstance, use assertSame here to perfectly match the test's intent of checking instance identity.

💡 Proposed refactor
         public void withExactAmount_returnsSameInstance() {
-            assertEquals(baseType, baseType.withExactAmount(10));
+            assertSame(baseType, baseType.withExactAmount(10));
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public void withExactAmount_returnsSameInstance() {
assertEquals(baseType, baseType.withExactAmount(10));
}
public void withExactAmount_returnsSameInstance() {
assertSame(baseType, baseType.withExactAmount(10));
}
🤖 Prompt for 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.

In
`@src/test/java/us/eunoians/mcrpg/quest/reward/builtin/SoundRewardTypeTest.java`
around lines 308 - 310, Update the withExactAmount_returnsSameInstance test to
use assertSame instead of assertEquals, matching the existing identity assertion
pattern in withAmountMultiplier_returnsSameInstance.

Comment on lines +320 to +343
@Test
@DisplayName("withAmountMultiplier returns this")
public void withAmountMultiplier_returnsSameInstance() {
assertEquals(baseType, baseType.withAmountMultiplier(2.0));
}

@Test
@DisplayName("isScalable returns false")
public void isScalable_returnsFalse() {
assertFalse(baseType.isScalable());
}

@Test
@DisplayName("getNumericAmount returns empty")
public void getNumericAmount_returnsEmpty() {
assertTrue(baseType.getNumericAmount().isEmpty());
}

@Test
@DisplayName("withExactAmount returns this")
public void withExactAmount_returnsSameInstance() {
assertEquals(baseType, baseType.withExactAmount(10));
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use assertSame to verify instance identity.

Since the intent of these tests is to verify that the methods return the exact same instance (this), assertSame is a more precise assertion than assertEquals. assertEquals only validates logical equivalence.

♻️ Proposed fixes

Add the import at the top of the file:

import static org.junit.jupiter.api.Assertions.assertSame;

And update the assertions:

         `@Test`
         `@DisplayName`("withAmountMultiplier returns this")
         public void withAmountMultiplier_returnsSameInstance() {
-            assertEquals(baseType, baseType.withAmountMultiplier(2.0));
+            assertSame(baseType, baseType.withAmountMultiplier(2.0));
         }

         `@Test`
         `@DisplayName`("isScalable returns false")
         public void isScalable_returnsFalse() {
             assertFalse(baseType.isScalable());
         }

         `@Test`
         `@DisplayName`("getNumericAmount returns empty")
         public void getNumericAmount_returnsEmpty() {
             assertTrue(baseType.getNumericAmount().isEmpty());
         }

         `@Test`
         `@DisplayName`("withExactAmount returns this")
         public void withExactAmount_returnsSameInstance() {
-            assertEquals(baseType, baseType.withExactAmount(10));
+            assertSame(baseType, baseType.withExactAmount(10));
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Test
@DisplayName("withAmountMultiplier returns this")
public void withAmountMultiplier_returnsSameInstance() {
assertEquals(baseType, baseType.withAmountMultiplier(2.0));
}
@Test
@DisplayName("isScalable returns false")
public void isScalable_returnsFalse() {
assertFalse(baseType.isScalable());
}
@Test
@DisplayName("getNumericAmount returns empty")
public void getNumericAmount_returnsEmpty() {
assertTrue(baseType.getNumericAmount().isEmpty());
}
@Test
@DisplayName("withExactAmount returns this")
public void withExactAmount_returnsSameInstance() {
assertEquals(baseType, baseType.withExactAmount(10));
}
}
`@Test`
`@DisplayName`("withAmountMultiplier returns this")
public void withAmountMultiplier_returnsSameInstance() {
assertSame(baseType, baseType.withAmountMultiplier(2.0));
}
`@Test`
`@DisplayName`("isScalable returns false")
public void isScalable_returnsFalse() {
assertFalse(baseType.isScalable());
}
`@Test`
`@DisplayName`("getNumericAmount returns empty")
public void getNumericAmount_returnsEmpty() {
assertTrue(baseType.getNumericAmount().isEmpty());
}
`@Test`
`@DisplayName`("withExactAmount returns this")
public void withExactAmount_returnsSameInstance() {
assertSame(baseType, baseType.withExactAmount(10));
}
}
🤖 Prompt for 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.

In
`@src/test/java/us/eunoians/mcrpg/quest/reward/builtin/TitleRewardTypeTest.java`
around lines 320 - 343, Replace assertEquals with assertSame in
withAmountMultiplier_returnsSameInstance and
withExactAmount_returnsSameInstance, and add the corresponding JUnit assertion
import. Preserve the existing method calls and test expectations.

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