"""Regression tests for the Add Space surrounding-quote strip. When users use macOS Finder's "Copy as Pathname" (Cmd+Option+C) the path arrives wrapped in single quotes by default — e.g. `'/Users/x/Documents/foo'`. Other shells and OS file managers do similar things with double quotes. The Add Space input would reject these as "not a directory" because the literal quote characters became part of the path. This file pins the behaviour: - Surrounding paired quotes (single or double) are stripped before validation. - Only the OUTERMOST pair is removed — internal quotes survive. - Mismatched / unpaired quotes are preserved (path may legitimately contain one). - Whitespace outside the quotes is also handled. """ import pytest from api.workspace import _strip_surrounding_quotes class TestStripSurroundingQuotes: def test_unwrapped_path_unchanged(self): assert _strip_surrounding_quotes("/Users/x/Documents/foo") == "/Users/x/Documents/foo" def test_single_quotes_stripped(self): # macOS Finder default assert _strip_surrounding_quotes("'/Users/x/Documents/foo'") == "/Users/x/Documents/foo" def test_double_quotes_stripped(self): assert _strip_surrounding_quotes('"/Users/x/Documents/foo"') == "/Users/x/Documents/foo" def test_outer_whitespace_stripped_first(self): # User pastes with trailing whitespace, then the quotes are visible assert ( _strip_surrounding_quotes(" '/Users/x/Documents/foo' ") == "/Users/x/Documents/foo" ) def test_only_outermost_pair_removed(self): # Paths can legitimately contain quote characters mid-string assert ( _strip_surrounding_quotes("'/Users/x/it's-mine/foo'") == "/Users/x/it's-mine/foo" ) def test_unpaired_leading_quote_preserved(self): # Lone quote that doesn't have a partner — assume it's part of the path assert _strip_surrounding_quotes("'/Users/x/foo") == "'/Users/x/foo" def test_unpaired_trailing_quote_preserved(self): assert _strip_surrounding_quotes("/Users/x/foo'") == "/Users/x/foo'" def test_mismatched_quote_pair_preserved(self): # ' on one side, " on the other — not a paired quote, leave alone assert _strip_surrounding_quotes("'/Users/x/foo\"") == "'/Users/x/foo\"" def test_empty_string(self): assert _strip_surrounding_quotes("") == "" def test_just_a_pair_of_quotes(self): # Edge case: someone pastes only the quotes — strip to empty assert _strip_surrounding_quotes("''") == "" assert _strip_surrounding_quotes('""') == "" def test_non_quote_paired_chars_preserved(self): # Don't strip arbitrary matching first-and-last chars assert _strip_surrounding_quotes("/foo/") == "/foo/" assert _strip_surrounding_quotes("aaa") == "aaa" class TestWorkspaceAddRouteStripsQuotes: """End-to-end: when a quoted path is POSTed to /api/workspaces/add, the server should accept it as if the quotes weren't there. This is a tiny smoke test using the validate_workspace_to_add helper directly (the route handler also calls _strip_surrounding_quotes via the import in api/routes.py — verified by the unit tests above). """ def test_validate_unwraps_quoted_path_for_existing_dir(self, tmp_path): from api.workspace import validate_workspace_to_add d = tmp_path / "my workspace with spaces" d.mkdir() # Quoted form — what Finder pastes quoted = f"'{d}'" p = validate_workspace_to_add(quoted) assert str(p) == str(d.resolve()) def test_validate_unwraps_double_quoted_path(self, tmp_path): from api.workspace import validate_workspace_to_add d = tmp_path / "my-workspace" d.mkdir() quoted = f'"{d}"' p = validate_workspace_to_add(quoted) assert str(p) == str(d.resolve()) def test_validate_quote_only_resolves_to_empty_after_strip(self): """`''` strips to `""`; the empty-string check belongs at the route handler layer (which returns "path is required"), not the validator. validate_workspace_to_add on `""` resolves to the process CWD, which may or may not be a directory — not the validator's responsibility. This test pins that the strip happens and the validator is then handed the empty form, not anything corrupted. """ # Direct strip check — confirms the layer responsible for the strip works. assert _strip_surrounding_quotes("''") == ""