import copy,json,unittest
from pathlib import Path
from unittest.mock import patch
import verify
P=Path(__file__).resolve().parent
class OracleMutationTests(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.cases=verify.load(P/'cases.json')
        cls.wires={n:verify.load(P/'private/C'/f'wire-{n}.json') for n in cls.cases}
    def reject_response(self,name,mutation):
        wires=copy.deepcopy(self.wires);response=json.loads(wires[name]['raw']);mutation(response)
        wires[name]['raw']=json.dumps(response,ensure_ascii=False,separators=(',',':'))
        with self.assertRaises(AssertionError): verify.verify_lane('C',wires)
    def test_real_both(self): self.assertEqual(len(verify.all_verify()['lanes']),2)
    def test_round_high_integer(self): self.reject_response('LATEST_C',lambda r:r['data'].__setitem__('stoppedAt',9007199254740992))
    def test_string_high_integer(self): self.reject_response('LATEST_C',lambda r:r['data'].__setitem__('stoppedAt','9007199254740993'))
    def test_missing_full_field(self): self.reject_response('LATEST_A',lambda r:r['data'].pop('modeLabel'))
    def test_helper_leak(self): self.reject_response('LATEST_A',lambda r:r['data'].__setitem__('exact_stopped_at_internal','1790000000123'))
    def test_date_precision_change(self): self.reject_response('LATEST_A',lambda r:r['data'].__setitem__('dateKey','2097-11-02 00:00:00'))
    def test_wrong_latest_order(self): self.reject_response('LATEST_D',lambda r:r['data'].__setitem__('mac','CDXRE11D7C2_D'))
    def test_reversed_details(self): self.reject_response('LIST_P1',lambda r:r['data']['list']['data'][0]['list'].reverse())
    def test_reversed_groups(self): self.reject_response('LIST_ALL',lambda r:r['data']['list']['data'].reverse())
    def test_changed_sum(self): self.reject_response('LIST_P1',lambda r:r['data']['list']['data'][0].__setitem__('count',205))
    def test_changed_paginator(self): self.reject_response('LIST_P3',lambda r:r['data']['list'].__setitem__('current_page',3))
    def test_null_vs_empty(self): self.reject_response('EMPTY_LATEST',lambda r:r.__setitem__('data',None))
    def test_wrong_error_message(self): self.reject_response('INVALID_OVER',lambda r:r.__setitem__('message','success'))
    def test_wrong_auth_status(self): self.reject_response('CROSS_TOKEN',lambda r:r.__setitem__('status',200))
    def test_physical_loss_not_hidden_by_dto(self):
        original=verify.load
        def modified(path):
            r=original(path)
            if path.name=='final-independent.json' and path.parent.name=='C':r['rows'][2]['exact_stopped_at']='9007199254740992'
            return r
        with patch.object(verify,'load',modified),self.assertRaises(AssertionError):verify.verify_lane('C')
    def test_native_bind_loss(self):
        original=verify.parse_insert
        def modified(sql,bind):
            fields=original(sql,bind)
            if fields['mac']['value']=='CDXRE11D7C2_C': fields['stopped_at']['value']=9007199254740992
            return fields
        with patch.object(verify,'parse_insert',modified),self.assertRaises(AssertionError):verify.verify_lane('C')
if __name__=='__main__':unittest.main(verbosity=2)
