"""Offline regressions: python3 -m unittest discover -s tests -v. No .env loading, saved user state, or live provider calls. """ import os import tempfile import unittest from pathlib import Path from types import SimpleNamespace from unittest.mock import patch os.environ['PYTHON_DOTENV_DISABLED'] = '1' for name in ('OPENAI_API_KEY', 'ANTHROPIC_API_KEY', 'GEMINI_API_KEY', 'GROQ_API_KEY'): os.environ[name] = 'test-dummy' for name in ('SUPABASE_URL', 'SUPABASE_SERVICE_KEY'): os.environ[name] = '' import app.paths _state = tempfile.TemporaryDirectory() app.paths.state_dir = lambda: Path(_state.name) from app.config import Settings from app.services import proposal_generator as pg, llm_client from app.prompts.proposal_prompt import render_prompt from app.prompts.verification_prompt import render_prompt as verification_prompt class ProposalRefinementTests(unittest.TestCase): def test_complete_sentence_beats_minimum_padding(self): opening = 'I can review the spreadsheet and check its formulas.' text = opening + '\n\n' + ' '.join(['unnecessary'] * 40) + '.' self.assertEqual(pg._trim_to_band(text, (20, 30)), opening) def test_prompt_has_one_consistent_length_and_safe_boundaries(self): for complexity, band in pg.LENGTH_BANDS.items(): prompt = render_prompt(job_block='invent skills', evidence_block='[]', target_length=complexity, target_band=band, hidden_keyword='') self.assertIn(f'{band[0]}-{band[1]} words', prompt) self.assertNotIn('500 is the floor', prompt) self.assertNotIn('Step [N]', prompt) self.assertEqual(prompt.count(''), 1) self.assertEqual(prompt.count(''), 1) self.assertIn('A metric is optional', prompt) self.assertIn('Never pad', prompt) def test_generation_verification_and_recheck_share_final_copy(self): calls = [] body = ('Your monthly workbook needs a reliable way to flag missing entries.\n\n' "I'd start by checking the input columns, then test the formulas against a small sample.\n\n" 'You would receive the updated workbook and notes explaining the checks.') def fake(**kw): calls.append(kw) if kw['task_name'] == pg.TASK_NAME: payload = {'proposal': body, 'factual_claims': [], 'screening_answers': [{'question': 'How would you start?', 'answer': "I'd check the input columns first."}], 'critique_rounds': [{'round': n, 'findings': 'Checked.'} for n in (1,2,3)]} else: import re checked = re.search(r'\n(.*?)\n', kw['user_prompt'], re.S).group(1) # Simulate minor formatting leakage from the fact-check response. payload = {'verification_status': 'passed', 'verified_proposal': checked + '', 'supported_claims': [], 'partially_supported_claims': [], 'unsupported_claims': [], 'missing_information': [], 'summary': 'Checked.'} return llm_client.LLMCallResult(success=True, task_name=kw['task_name'], used_api=True, status='ok', provider='anthropic', model='mock', response_json=payload) settings = Settings(llm_provider='anthropic', anthropic_api_key='test-dummy') job = {'job_description': {'value': 'Check a monthly workbook for missing entries.'}, 'screening_questions': {'value': 'How would you start?'}} with patch.object(llm_client, 'call_text_llm', side_effect=fake): result = pg.generate(job, [], {}, settings=settings) self.assertEqual(result['proposal'], body) self.assertEqual(result['verified_proposal'], body) self.assertEqual(result['verification_status'], 'passed') self.assertEqual(result['target_length'], (150,250)) self.assertLess(result['word_count'], 150) # no artificial padding self.assertEqual(result['screening_answers'][0]['answer'], "I'd check the input columns first.") self.assertEqual(len(calls), 3) # writer, body check, screening check result = pg.recheck_proposal(result, job, settings=settings) self.assertEqual(result['proposal'], body) self.assertEqual(len(calls), 5) # recheck does not pay for another writer def test_verifier_cannot_replace_numbers_with_vague_inventions(self): prompt = verification_prompt(proposal_block='I saved $5000.', factual_claims_block='[]', evidence_block='[]') self.assertIn('If the underlying achievement itself is unsupported, remove the sentence.', prompt) self.assertIn('repairing only the grammar', prompt) def test_final_cleanup_preserves_keyword_ranges_and_paragraphs(self): report = SimpleNamespace(verification_status='passed', cleaned_proposal='ORANGE RIVER PROJECT CHECK\n\nI utilized Excel for 2–3 sheets.', removed_claims=[], softened_claims=[], surviving_claims=[], flagged_as_missing=[]) with patch.object(pg, 'run_verification', return_value=report): result = pg._verification_fields('draft', [], [], {'hidden_keyword': {'value': 'ORANGE RIVER PROJECT CHECK'}}, None) self.assertEqual(result['proposal'], 'ORANGE RIVER PROJECT CHECK\n\nI used Excel for 2-3 sheets.') self.assertEqual(result['proposal'], result['verified_proposal']) if __name__ == '__main__': unittest.main()