Skip to content
Merged
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 AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ mvn -B -f VotifierPlus/pom.xml package

Confirm current CI/POM settings. Use `package`, not developer/install profiles that copy artifacts to a server. Verify the fresh shaded JAR, actual test discovery, and `git diff --check`.

## Test package organization

Put Java test classes and reusable test helpers under `com.bencodez.votifierplus.tests`, using subpackages for related areas. Match the directories below `src/test/java` to the declared package. Keep new and moved tests in this namespace and update imports, resource lookups, reflection references, and build selectors when relocating them.

Preserve every existing test assertion and test discovery. Use a narrow test-only access helper when testing package-private implementation details; do not widen production APIs merely to move a test. Before finishing, verify the package declarations and run the required test/package build so the reorganization cannot silently drop coverage.

## Architecture and trust boundaries

- Bukkit entry point: `com.vexsoftware.votifier.VotifierPlus`.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.bencodez.votifierplus.tests.net;

import com.vexsoftware.votifier.net.VoteForwarder;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.io.BufferedReader;
import java.io.StringReader;

import org.junit.jupiter.api.Test;

public class VoteForwarderHandshakeTest {
// Keep the production parser package-private while exercising the same method.
private static String readHandshakeLine(BufferedReader input) throws Exception {
Method parser = VoteForwarder.class.getDeclaredMethod("readHandshakeLine", BufferedReader.class);
parser.setAccessible(true);
try {
return (String) parser.invoke(null, input);
} catch (InvocationTargetException failure) {
if (failure.getCause() instanceof Exception cause) throw cause;
if (failure.getCause() instanceof Error cause) throw cause;
throw new AssertionError(failure.getCause());
}
}

@Test
public void crlfConsumesBothTerminatorBytesAndPreservesFollowingData() throws Exception {
BufferedReader input = new BufferedReader(new StringReader("VOTIFIER 2 challenge\r\nPAYLOAD\n"));
assertEquals("VOTIFIER 2 challenge", readHandshakeLine(input));
assertEquals("PAYLOAD", input.readLine());
}

@Test
public void lfAndBareCrPreserveFollowingData() throws Exception {
BufferedReader lf = new BufferedReader(new StringReader("VOTIFIER 2 challenge\nPAYLOAD\n"));
assertEquals("VOTIFIER 2 challenge", readHandshakeLine(lf));
assertEquals("PAYLOAD", lf.readLine());

BufferedReader cr = new BufferedReader(new StringReader("VOTIFIER 2 challenge\rPAYLOAD\n"));
assertEquals("VOTIFIER 2 challenge", readHandshakeLine(cr));
assertEquals("PAYLOAD", cr.readLine());
}

@Test
public void oversizedHandshakeIsStillRejected() {
BufferedReader input = new BufferedReader(new StringReader("X".repeat(513) + "\r\n"));
assertThrows(IllegalStateException.class, () -> readHandshakeLine(input));
}
}

This file was deleted.

Loading