feat(REQ-014): add portfolio-create-user-required requirement and implementation
- Add docs/srs/Interface/req-014_portfolio-create-user-required.md with acceptance criteria - Create docs/batches/bat-004_20260502_portfolio-create-user-required/ delivery batch - Enhance app/cli/commands/portfolio.py: validate user_id parameter before portfolio creation - Add comprehensive CLI tests in tests/test_cli.py for portfolio create validation flows - Update docs/batches/index.md and docs/srs/index.md with new requirement/batch references - Update README.md documentation
This commit is contained in:
@@ -485,6 +485,7 @@ def test_cli_status_supports_json_output() -> None:
|
||||
|
||||
def test_cli_create_buy_and_delete_flow() -> None:
|
||||
repo = FakeRepo()
|
||||
user = repo.create_user("alice", permission="read")
|
||||
runner = build_runner(repo)
|
||||
|
||||
create_result = runner.invoke(
|
||||
@@ -495,6 +496,8 @@ def test_cli_create_buy_and_delete_flow() -> None:
|
||||
"005930:tv",
|
||||
"--symbol",
|
||||
"005930",
|
||||
"--user",
|
||||
"alice",
|
||||
"--cash-balance",
|
||||
"1000000",
|
||||
"--strategy-params",
|
||||
@@ -518,6 +521,7 @@ def test_cli_create_buy_and_delete_flow() -> None:
|
||||
],
|
||||
)
|
||||
assert repo.entries[0].action == "BUY"
|
||||
assert repo._portfolio.owner_user_id == user.id
|
||||
delete_result = runner.invoke(runner.app, ["portfolio", "delete", "005930:tv", "--keep-ledger", "--force"])
|
||||
|
||||
assert create_result.exit_code == 0
|
||||
@@ -528,6 +532,7 @@ def test_cli_create_buy_and_delete_flow() -> None:
|
||||
|
||||
def test_cli_write_command_prompts_before_create() -> None:
|
||||
repo = FakeRepo()
|
||||
repo.create_user("alice", permission="read")
|
||||
runner = build_runner(repo)
|
||||
|
||||
result = runner.invoke(
|
||||
@@ -538,6 +543,8 @@ def test_cli_write_command_prompts_before_create() -> None:
|
||||
"005930:tv",
|
||||
"--symbol",
|
||||
"005930",
|
||||
"--user",
|
||||
"alice",
|
||||
"--cash-balance",
|
||||
"1000000",
|
||||
],
|
||||
@@ -550,6 +557,7 @@ def test_cli_write_command_prompts_before_create() -> None:
|
||||
|
||||
def test_cli_write_command_can_abort() -> None:
|
||||
repo = FakeRepo()
|
||||
repo.create_user("alice", permission="read")
|
||||
runner = build_runner(repo)
|
||||
|
||||
result = runner.invoke(
|
||||
@@ -560,6 +568,8 @@ def test_cli_write_command_can_abort() -> None:
|
||||
"005930:tv",
|
||||
"--symbol",
|
||||
"005930",
|
||||
"--user",
|
||||
"alice",
|
||||
"--cash-balance",
|
||||
"1000000",
|
||||
],
|
||||
@@ -570,6 +580,47 @@ def test_cli_write_command_can_abort() -> None:
|
||||
assert repo._portfolio is None
|
||||
|
||||
|
||||
def test_cli_portfolio_create_without_user_exits_error() -> None:
|
||||
repo = FakeRepo()
|
||||
runner = build_runner(repo)
|
||||
|
||||
result = runner.invoke(
|
||||
runner.app,
|
||||
["portfolio", "create", "005930:tv", "--symbol", "005930", "--force"],
|
||||
)
|
||||
|
||||
assert result.exit_code == 1
|
||||
assert "--user" in result.stdout
|
||||
|
||||
|
||||
def test_cli_portfolio_create_with_valid_user_sets_owner() -> None:
|
||||
repo = FakeRepo()
|
||||
user = repo.create_user("alice", permission="read")
|
||||
runner = build_runner(repo)
|
||||
|
||||
result = runner.invoke(
|
||||
runner.app,
|
||||
["portfolio", "create", "005930:tv", "--symbol", "005930", "--user", "alice", "--force"],
|
||||
)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert repo._portfolio is not None
|
||||
assert repo._portfolio.owner_user_id == user.id
|
||||
|
||||
|
||||
def test_cli_portfolio_create_with_unknown_user_exits_error() -> None:
|
||||
repo = FakeRepo()
|
||||
runner = build_runner(repo)
|
||||
|
||||
result = runner.invoke(
|
||||
runner.app,
|
||||
["portfolio", "create", "005930:tv", "--symbol", "005930", "--user", "nobody", "--force"],
|
||||
)
|
||||
|
||||
assert result.exit_code == 1
|
||||
assert "nobody" in result.stdout
|
||||
|
||||
|
||||
def test_cli_health_check_reports_repository() -> None:
|
||||
repo = FakeRepo(_portfolio())
|
||||
runner = build_runner(repo)
|
||||
|
||||
Reference in New Issue
Block a user