import feed_file_exporter as ffe from constants import database as db_consts, files as file_consts def _rows_for_file(file_name='Res.txt'): return [ { db_consts.RECORD_TYPE: 'H', db_consts.BODY_CONTENT: 'HEADER', db_consts.FILE_NAME: file_name, }, { db_consts.RECORD_TYPE: 'N', db_consts.BODY_CONTENT: 'BODY1', db_consts.FILE_NAME: file_name, }, { db_consts.RECORD_TYPE: 'T', db_consts.BODY_CONTENT: 'TAIL', db_consts.FILE_NAME: file_name, }, ] def test_split_rows_to_files_spy_write(tmp_path, mocker): rows = _rows_for_file('Res.txt') spy = mocker.spy(ffe, 'write_rows_to_file') count, upload_list, gen_list = ffe.split_rows_to_files(rows, str(tmp_path)) assert count == 3 assert upload_list == ['Res.txt'] assert len(gen_list) == 1 spy.assert_called_once() # Verify content written with open(gen_list[0], 'r', encoding='utf8') as f: content = f.read() expected = 'HEADER' + file_consts.LINE_TERMINATOR expected += 'BODY1' + file_consts.LINE_TERMINATOR expected += 'TAIL' assert content.replace('\r\n', '\n') == expected.replace('\r\n', '\n') def test_split_rows_to_files_mismatch_tail_raises(tmp_path, mocker): rows = _rows_for_file('A.txt') rows[-1][db_consts.FILE_NAME] = 'B.txt' spy = mocker.spy(ffe, 'write_rows_to_file') try: ffe.split_rows_to_files(rows, str(tmp_path)) assert False, 'Expected ValueError for mismatched tail' except ValueError: pass # write should not occur on mismatch assert spy.call_count == 0 class _Row: def __init__(self, d): self._d = d def keys(self): return list(self._d.keys()) def __iter__(self): return iter(self._d.values()) class _RP: def __init__(self, rows): self._rows = rows def fetchone(self): return _Row(self._rows[0]) def __iter__(self): for r in self._rows[1:]: yield _Row(r) def test_split_res_to_files_creates_file(tmp_path, mocker): rows = _rows_for_file('Z.txt') rp = _RP(rows) log_spy = mocker.spy(ffe.logger, 'info') count, gen_list = ffe.split_res_to_files(rp, str(tmp_path)) assert count == 3 assert len(gen_list) == 1 # Logger informed writing assert any( 'Writing File' in str(c.args[0]) for c in log_spy.call_args_list ) with open(gen_list[0], 'r', encoding='utf8') as f: content = f.read() expected = 'HEADER' + file_consts.LINE_TERMINATOR expected += 'BODY1' + file_consts.LINE_TERMINATOR expected += 'TAIL' assert content.replace('\r\n', '\n') == expected.replace('\r\n', '\n') def test_split_res_to_files_mismatch_raises(tmp_path): rows = _rows_for_file('A.txt') rows[-1][db_consts.FILE_NAME] = 'B.txt' rp = _RP(rows) try: ffe.split_res_to_files(rp, str(tmp_path)) assert False, 'Expected ValueError for mismatched tail' except ValueError: pass