Skip to content

fix: reject empty name/ticker/description in launch command#10

Open
P-r-e-m-i-u-m wants to merge 4 commits intochainstacklabs:mainfrom
P-r-e-m-i-u-m:fix/validate-launch-inputs
Open

fix: reject empty name/ticker/description in launch command#10
P-r-e-m-i-u-m wants to merge 4 commits intochainstacklabs:mainfrom
P-r-e-m-i-u-m:fix/validate-launch-inputs

Conversation

@P-r-e-m-i-u-m
Copy link

@P-r-e-m-i-u-m P-r-e-m-i-u-m commented Mar 17, 2026

Closes #5

Added validation in launch.py to reject empty or whitespace-only values for --name, --ticker, and --desc before any RPC or IPFS calls are made.

Changes

src/pumpfun_cli/commands/launch.py

  • Added empty string validation for name, ticker, and desc after state = ctx.obj

tests/test_commands/test_launch_cmd.py

  • Added 6 tests covering empty and whitespace-only inputs for all three fields
  • What changed

    • Adds input validation in src/pumpfun_cli/commands/launch.py to reject empty or whitespace-only values for --name, --ticker, and --desc. Each check emits an error if the value is empty after stripping:
      • "Token name cannot be empty."
      • "Token ticker cannot be empty."
      • "Token description cannot be empty."
    • These checks run immediately after state = ctx.obj and before RPC config/wallet existence checks and before any calls to launch_token.
    • Adds six parametrized tests in tests/test_commands/test_launch_cmd.py that cover empty and whitespace-only values for name, ticker, and description. Tests assert non-zero exit codes, exact error-message substring matches (case-insensitive), and that launch_token is not invoked for invalid input.
    • Closes issue Reject empty name/ticker/description in launch command #5.
  • Security / funds / transaction implications

    • This change is confined to the CLI command layer and only adds input validation; it does not modify transaction construction, wallet handling, RPC client code, or core protocol modules.
    • The launch command continues to call pumpfun_cli.core.launch.launch_token for valid inputs — that is the code path that may send Solana transactions — but this PR does not change those transaction-sending code paths.
    • Positive outcome: prevents empty/whitespace metadata from being forwarded to IPFS/RPC/transaction logic, reducing the risk of malformed metadata or unnecessary RPC/IPFS calls.
  • Architecture / layering

    • Validation is implemented in the CLI layer before invoking core functionality; no architectural-layer violations detected.
    • No public/exported API changes.
  • Tests

    • Unit tests validate rejection behavior and assert launch_token is not called for invalid inputs.

@P-r-e-m-i-u-m P-r-e-m-i-u-m requested a review from smypmsa as a code owner March 17, 2026 11:39
@coderabbitai
Copy link

coderabbitai bot commented Mar 17, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d2e460c7-bcaf-4eb7-9205-c44728efd3e6

📥 Commits

Reviewing files that changed from the base of the PR and between 7f5a318 and 42466dd.

📒 Files selected for processing (2)
  • src/pumpfun_cli/commands/launch.py
  • tests/test_commands/test_launch_cmd.py

📝 Walkthrough

Walkthrough

Adds input validation to the CLI launch command to reject empty or whitespace-only name, ticker, and desc before RPC/config checks. Adds parametrized unit tests that assert non-zero exits and verify error messages for each empty-field case.

Changes

Cohort / File(s) Summary
Launch Command Validation
src/pumpfun_cli/commands/launch.py
Add pre-RPC checks that name, ticker, and desc are non-empty after .strip(), emitting errors: "Token name cannot be empty.", "Token ticker cannot be empty.", "Token description cannot be empty."
Test Suite
tests/test_commands/test_launch_cmd.py
Add parametrized tests covering empty and whitespace-only name, ticker, and description; assert non-zero CLI exit codes, verify error output mentions the relevant field, and ensure launch_token is not invoked.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • smypmsa
🚥 Pre-merge checks | ✅ 8
✅ Passed checks (8 passed)
Check name Status Explanation
Title check ✅ Passed Title follows conventional commits (fix:) and clearly describes the main change: validating empty inputs for name/ticker/description in the launch command.
Description check ✅ Passed Description covers the main changes but lacks some template sections. It clearly describes what was fixed and which files were changed, though it omits the 'Layers touched' and 'Test Plan' sections and doesn't explicitly indicate the issue number in the template format.
Linked Issues check ✅ Passed PR implementation matches issue #5 requirements: validates empty/whitespace values for name, ticker, and desc with exact error messages, applies checks after state = ctx.obj, and includes parametrized tests covering both empty and whitespace-only cases.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #5: input validation in launch.py and corresponding unit tests. No unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
No Print() Calls ✅ Passed The modified src/pumpfun_cli/commands/launch.py file contains no bare print() calls. All error messages use error() from pumpfun_cli.output, and output uses typer.echo().
Layer Separation ✅ Passed Files in src/pumpfun_cli/commands/ do not import directly from pumpfun_cli.protocol, maintaining proper layer separation.
Rpcclient Cleanup ✅ Passed PR adds input validation logic (6 lines in launch.py, 28 lines of tests) to reject empty/whitespace parameters before any RPC calls occur. No new RpcClient instantiations are introduced.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code
📝 Coding Plan
  • Generate coding plan for human review comments

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

@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

🤖 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/test_commands/test_launch_cmd.py`:
- Around line 8-53: Consolidate the six near-duplicate tests
(test_launch_empty_name, test_launch_whitespace_name, test_launch_empty_ticker,
test_launch_whitespace_ticker, test_launch_empty_desc,
test_launch_whitespace_desc) into a single parametrized pytest function that
iterates over tuples of (flag, value, expected_error_substring) and calls
runner.invoke(app, ["launch", flag_key_map[flag], value, ...]) or constructs the
args accordingly; use monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path)) once
per test, assert non-zero exit_code and that expected_error_substring is in
result.output.lower(); reference the existing runner.invoke call site and the
CLI flags "--name", "--ticker", "--desc" to locate where to build the param
list.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f079dfd3-642a-4c6a-946d-e82b2803b324

📥 Commits

Reviewing files that changed from the base of the PR and between 511fcb0 and 7cab4d6.

📒 Files selected for processing (2)
  • src/pumpfun_cli/commands/launch.py
  • tests/test_commands/test_launch_cmd.py

@P-r-e-m-i-u-m
Copy link
Author

"Refactored tests to use @pytest.mark.parametrize as suggested. Ready for re-review @smypmsa

Copy link

@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.

♻️ Duplicate comments (1)
tests/test_commands/test_launch_cmd.py (1)

17-22: ⚠️ Potential issue | 🟠 Major

Strengthen this test to prevent false positives and enforce no-network behavior.

This case currently passes if any error includes the keyword, and it does not explicitly guard against RPC execution. Assert the exact validation message and mock/guard RPC entrypoints so the test fails if network paths are reached.

Suggested patch
+from unittest.mock import Mock
 import pytest
 from typer.testing import CliRunner
 
 from pumpfun_cli.cli import app
@@
 def test_launch_rejects_empty_inputs(tmp_path, monkeypatch, name, ticker, desc, expected_error):
     """launch rejects empty or whitespace-only name, ticker, or description."""
     monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path))
+    launch_token_mock = Mock(side_effect=AssertionError("launch_token must not be called for invalid input"))
+    monkeypatch.setattr("pumpfun_cli.commands.launch.launch_token", launch_token_mock)
+
     result = runner.invoke(app, ["launch", "--name", name, "--ticker", ticker, "--desc", desc])
     assert result.exit_code != 0
-    assert expected_error in result.output.lower()
+    assert f"token {expected_error} cannot be empty." in result.output.lower()
+    launch_token_mock.assert_not_called()

As per coding guidelines, "Tests must use mocks for RPC calls, no real network."

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

In `@tests/test_commands/test_launch_cmd.py` around lines 17 - 22, The test
test_launch_rejects_empty_inputs should assert the exact validation message and
ensure no network/RPC code is executed: use monkeypatch to replace the RPC
entrypoint(s) the CLI uses (the module/method the launch command calls; e.g.,
the RPC client or caller used by app/launch) with a stub that raises
AssertionError if invoked, invoke runner.invoke(app, ["launch", ...]) as before,
assert result.exit_code != 0, and assert the normalized output equals the exact
expected_error string (e.g., result.output.strip().lower() == expected_error) so
the test fails on wrong messages or if RPC paths are reached. Include the test
function name test_launch_rejects_empty_inputs and the caller runner.invoke(app,
...) to locate where to add these monkeypatches.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@tests/test_commands/test_launch_cmd.py`:
- Around line 17-22: The test test_launch_rejects_empty_inputs should assert the
exact validation message and ensure no network/RPC code is executed: use
monkeypatch to replace the RPC entrypoint(s) the CLI uses (the module/method the
launch command calls; e.g., the RPC client or caller used by app/launch) with a
stub that raises AssertionError if invoked, invoke runner.invoke(app, ["launch",
...]) as before, assert result.exit_code != 0, and assert the normalized output
equals the exact expected_error string (e.g., result.output.strip().lower() ==
expected_error) so the test fails on wrong messages or if RPC paths are reached.
Include the test function name test_launch_rejects_empty_inputs and the caller
runner.invoke(app, ...) to locate where to add these monkeypatches.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: cca55149-ef14-4128-a885-dd04fae19d40

📥 Commits

Reviewing files that changed from the base of the PR and between 7cab4d6 and b17d7cb.

📒 Files selected for processing (1)
  • tests/test_commands/test_launch_cmd.py

smypmsa
smypmsa previously approved these changes Mar 17, 2026
@P-r-e-m-i-u-m
Copy link
Author

"Mocked launch_token to prevent RPC calls in tests and tightened assertions to exact error messages. Ready for re-review @smypmsa

Copy link

@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

🤖 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/test_commands/test_launch_cmd.py`:
- Around line 11-18: Update the pytest parametrization to use a tuple literal
for the argument names in the pytest.mark.parametrize decorator (replace the
comma-delimited string "name,ticker,desc,expected_error" with a tuple like
("name","ticker","desc","expected_error")) in the test function in
tests/test_commands/test_launch_cmd.py so it satisfies PT006 and leaves the
parameter value list unchanged; the change should be made where
pytest.mark.parametrize is used.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 66ff7c32-8cd2-44fd-83fa-05821e4cad30

📥 Commits

Reviewing files that changed from the base of the PR and between b17d7cb and 92b9ee4.

📒 Files selected for processing (1)
  • tests/test_commands/test_launch_cmd.py

@P-r-e-m-i-u-m
Copy link
Author

"Fixed PT006 — changed parametrize string to tuple form. Ready for re-review @smypmsa

Signed-off-by: 🄂ʏᴇᴅ 🄰ʙᴅᴜʟ 🄰ᴍᴀ🄝 ✧ <amanbaba9404522@gmail.com>
Signed-off-by: 🄂ʏᴇᴅ 🄰ʙᴅᴜʟ 🄰ᴍᴀ🄝 ✧ <amanbaba9404522@gmail.com>
Signed-off-by: 🄂ʏᴇᴅ 🄰ʙᴅᴜʟ 🄰ᴍᴀ🄝 ✧ <amanbaba9404522@gmail.com>
Signed-off-by: 🄂ʏᴇᴅ 🄰ʙᴅᴜʟ 🄰ᴍᴀ🄝 ✧ <amanbaba9404522@gmail.com>
@P-r-e-m-i-u-m P-r-e-m-i-u-m force-pushed the fix/validate-launch-inputs branch from 7f5a318 to 42466dd Compare March 18, 2026 10:04
@P-r-e-m-i-u-m
Copy link
Author

"Rebased onto latest main. Ready for merge @smypmsa

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reject empty name/ticker/description in launch command

2 participants