@ -1,8 +1,6 @@
""" The local owner imports synthetic files without sending source rows to the UI. """
from pathlib import Path
import random
import string
import pytest
from django . core import signing
@ -108,7 +106,7 @@ def test_mapping_prepares_then_explicit_commit_creates_with_local_human_actor(cl
payload = signing . loads ( prepared . context [ " prepared_token " ] , salt = " guided-imports-prepared " )
assert set ( payload [ 0 ] ) == { " name " , " document_hash " , " profile " , " sections " , " batch_id " , " revision " }
response = commit ( client , prepared )
assert response . redirect_chain == [ ( reverse ( " imports-index " ) , 302 ) ]
assert not response . redirect_chain
assert response . context [ " files " ] [ 0 ] [ " state " ] == " COMMITTED "
assert response . context [ " files " ] [ 0 ] [ " counts " ] [ " created " ] == 2
assert Transaction . objects . count ( ) == SourceRecord . objects . count ( ) == 2
@ -136,42 +134,10 @@ def test_scan_and_prepared_form_metadata_do_not_depend_on_session_payload(client
assert " batch_id " not in str ( dict ( client . session ) )
def test_oversized_scan_has_safe_result_and_leaves_every_file_untouched ( client , source , bank ) :
for index in range ( 20 ) :
( source / f " synthetic- { index } .csv " ) . write_bytes ( DATA )
response = scan ( client )
assert " SCAN_TOO_LARGE " in response . content . decode ( )
assert not response . context . get ( " scan_token " )
assert not ImportBatch . objects . exists ( )
assert len ( list ( source . iterdir ( ) ) ) == 21
if " sessionid " in client . cookies :
assert len ( client . cookies [ " sessionid " ] . value ) < 4096
def test_long_filename_summaries_fit_browser_cookie_and_do_not_accumulate_across_tabs ( client , source , bank ) :
( source / " bank.csv " ) . unlink ( )
names = random . Random ( 41 )
filenames = [ " " . join ( names . choices ( string . ascii_letters + string . digits , k = 250 ) ) + " .csv "
for _ in range ( 10 ) ]
for filename in filenames :
( source / filename ) . write_bytes ( DATA )
scanned = scan ( client )
fields = { f " file- { index } -section_0 " : str ( bank . pk ) for index in range ( 10 ) }
prepared = prepare ( client , scanned , bank , * * fields )
# A second tab scans other files before the first tab finishes its old form.
for filename in filenames :
( source / filename ) . unlink ( )
( source / filename . replace ( " .csv " , " .ofx " ) ) . write_text ( " Synthetic unsupported " )
scan ( client )
response = commit ( client , prepared )
assert len ( response . context [ " files " ] ) == 10
assert all ( row [ " code " ] == " UNREADABLE_FILE " for row in response . context [ " files " ] )
assert len ( client . cookies [ " sessionid " ] . OutputString ( ) . encode ( ) ) < 4096
assert not Transaction . objects . exists ( )
def test_exact_reimport_reports_skips_without_new_transactions ( client , source , bank ) :
commit ( client , prepare ( client , scan ( client ) , bank ) )
( source / " bank.csv " ) . write_bytes ( DATA )
prepared = prepare ( client , scan ( client ) , bank )
assert prepared . context [ " files " ] [ 0 ] [ " state " ] == " ALREADY_IMPORTED "
result = commit ( client , prepared )
@ -214,9 +180,9 @@ def test_review_exception_does_not_prevent_another_file_commit(client, source, b
( source / " ambiguous.csv " ) . write_bytes ( DATA + DATA . splitlines ( keepends = True ) [ 1 ] )
prepared = prepare ( client , scan ( client ) , bank , * * { " file-1-section_0 " : str ( bank . pk ) } )
assert [ row [ " state " ] for row in prepared . context [ " files " ] ] == [ " NEEDS_ATTENTION " , " READY " ]
assert prepared . context [ " files " ] [ 0 ] [ " code " ] == " REVIEW_REQUIRED "
result = commit ( client , prepared )
assert [ row [ " state " ] for row in result . context [ " files " ] ] == [ " NEEDS_ATTENTION " , " COMMITTED " ]
assert result . context [ " files " ] [ 0 ] [ " code " ] == " REVIEW_REQUIRED "
assert [ row [ " state " ] for row in result . context [ " files " ] ] == [ " COMMITTED " ]
assert Transaction . objects . count ( ) == 2
assert not ImportBatch . objects . filter ( state = " PREVIEW " ) . exists ( )
@ -241,13 +207,18 @@ def test_unexpected_per_file_error_never_exposes_source_or_blocks_next_file(clie
monkeypatch . setattr ( views . guided_imports , service_name , fail_one_file )
if stage == " prepare " :
prepared = prepare ( client , scanned , bank , * * { " file-1-section_0 " : str ( bank . pk ) } )
assert prepared . context [ " files " ] [ 0 ] [ " code " ] == " IMPORT_FAILED "
result = commit ( client , prepared )
assert [ row [ " state " ] for row in result . context [ " files " ] ] == [ " NEEDS_ATTENTION " , " COMMITTED " ]
assert result . context [ " files " ] [ 0 ] [ " code " ] == " IMPORT_FAILED "
assert " Synthetic private source text " not in result . content . decode ( )
assert " 1234.56 " not in result . content . decode ( )
if stage == " commit " :
assert [ row [ " state " ] for row in result . context [ " files " ] ] == [ " NEEDS_ATTENTION " , " COMMITTED " ]
assert result . context [ " files " ] [ 0 ] [ " code " ] == " IMPORT_FAILED "
else :
assert [ row [ " state " ] for row in result . context [ " files " ] ] == [ " COMMITTED " ]
response = prepared if stage == " prepare " else result
assert " Synthetic private source text " not in response . content . decode ( )
assert " 1234.56 " not in response . content . decode ( )
assert Transaction . objects . count ( ) == 2
assert_private ( result , source )
assert_private ( response , source )
@pytest . mark . parametrize ( " stage " , [ " prepare " , " commit " ] )
@ -281,7 +252,10 @@ def test_signed_workflow_rejects_altered_expired_and_wrong_stage_tokens(
def test_changed_source_rejects_previously_signed_metadata ( client , source , bank , stage ) :
scanned = scan ( client )
prepared = prepare ( client , scanned , bank ) if stage == " commit " else None
( source / " bank.csv " ) . write_bytes ( DATA . replace ( b " 12.34 " , b " 22.34 " ) )
changed = source / " bank.csv "
if stage == " commit " :
changed = source / " staging " / " bank.csv "
changed . write_bytes ( DATA . replace ( b " 12.34 " , b " 22.34 " ) )
response = commit ( client , prepared ) if prepared else prepare ( client , scanned , bank )
assert response . context [ " files " ] [ 0 ] [ " code " ] == " FILE_CHANGED "
assert not Transaction . objects . exists ( )