Feature: Validation test fixtures As a QA engineer I want to validate that code sanitization, model validation, and input coercion handle edge cases So that edge case project structures and malformed input data are properly rejected # NOTE: Sections 1, 1b, 2, and 2b (AST security validation, RestrictedPython, # Lambda AST validation) were removed as part of SEC1. eval()/exec() are no # longer used in stream_router.py; the SEC1 approach uses named operation and # transform registries instead. See features/security_eval.feature for the # replacement tests. # ────────────────────────────────────────────────── # Section 3: Invalid code samples - Python content sanitization # ────────────────────────────────────────────────── Scenario: Sanitize valid Python passes through unchanged Given I have a plan service for sanitization tests When I sanitize the python content "x = 1 + 2" Then the sanitized content should be "x = 1 + 2" And the sanitization error should be None And the sanitization reason should be None Scenario: Sanitize Python with markdown code fences Given I have a plan service for sanitization tests When I sanitize the python content with code fences wrapping "x = 42" Then the sanitized content should be "x = 42" And the sanitization error should be None And the sanitization reason should be "code_fence_removed" Scenario: Sanitize non-Python prose falls back to docstring wrapping Given I have a plan service for sanitization tests When I sanitize the python content "This is just plain English text, not code." Then the sanitization error should be None And the sanitization reason should be "docstring_wrapped" Scenario: Sanitize irrecoverable syntax returns error Given I have a plan service for sanitization tests When I sanitize python content containing a null byte Then the sanitization error should not be None # ────────────────────────────────────────────────── # Section 4: Edge case project structures - Project model validation # ────────────────────────────────────────────────── Scenario: Project rejects name with special characters When I try to create a project with name "my@project" Then a project validation error should be raised mentioning "alphanumeric" Scenario: Project rejects name with slashes When I try to create a project with name "my/project" Then a project validation error should be raised mentioning "alphanumeric" Scenario: Project rejects name with exclamation When I try to create a project with name "project!" Then a project validation error should be raised mentioning "alphanumeric" Scenario: Project accepts name with hyphens underscores and spaces When I create a project fixture with name "my-project_v2 final" Then the project should be created with that name Scenario: Project resolves relative path to absolute When I create a project with relative path "relative/path" Then the project fixture path should be absolute Scenario: Project rejects empty name When I try to create a project with empty name Then a project validation error should be raised # ────────────────────────────────────────────────── # Section 5: Malformed input data - Change list coercion # ────────────────────────────────────────────────── Scenario: Coerce empty change list returns empty list Given I have a plan service for coercion tests When I coerce an empty change list Then the coerced result should be an empty list Scenario: Coerce mixed dict and Change entries Given I have a plan service for coercion tests When I coerce a list with one dict entry and one Change entry Then the coerced result should have 2 changes Scenario: Coerce non-list input raises PlanError Given I have a plan service for coercion tests When I try to coerce a non-list input Then a PlanError should be raised mentioning "invalid change payload" Scenario: Coerce list with non-change non-dict entry raises PlanError Given I have a plan service for coercion tests When I try to coerce a list containing an integer Then a PlanError should be raised mentioning "non-change entry" # ────────────────────────────────────────────────── # Section 6: Malformed input data - ActionArgument parsing # ────────────────────────────────────────────────── Scenario: Parse argument with too few parts When I try to parse action argument fixture "onlyname" Then an argument fixture parse error should be raised Scenario: Parse argument with invalid type When I try to parse action argument fixture "name:badtype:required:desc" Then an argument fixture parse error should be raised Scenario: Parse argument with invalid requirement When I try to parse action argument fixture "name:str:sometimes:desc" Then an argument fixture parse error should be raised Scenario: Parse argument with reserved keyword name When I try to create argument with name "class" Then the argument name should be accepted as valid identifier