22from pathlib import Path
33import logging
44import tempfile
5+ from unittest .mock import MagicMock
56import pytest
67
78from pygeodiff import GeoDiff
89from mergin .client_push import push_project_finalize , UploadJob
910from mergin .common import ClientError
11+ from mergin .merginproject import MerginProject
12+ from mergin .client import MerginClient
1013
1114
1215@pytest .mark .parametrize ("status_code" , [502 , 504 ])
1316def test_push_finalize_logs_on_5xx_real_diff (caplog , status_code , tmp_path ):
14- # --- data ---
17+ # test data
1518 data_dir = Path (__file__ ).resolve ().parent / "test_data"
1619 base = data_dir / "base.gpkg"
1720 modified = data_dir / "inserted_1_A.gpkg"
18- assert base .exists ()
19- assert modified .exists ()
21+ assert base .exists () and modified .exists ()
2022
21- diff_path = tmp_path / "base_to_inserted_1_A.diff"
22- GeoDiff ().create_changeset (str (base ), str (modified ), str (diff_path ))
23- diff_size = diff_path .stat ().st_size
24- file_size = modified .stat ().st_size
23+ # real MerginProject in temp dir
24+ proj_dir = tmp_path / "proj"
25+ meta_dir = proj_dir / ".mergin"
26+ meta_dir .mkdir (parents = True )
27+ mp = MerginProject (str (proj_dir ))
2528
26- # --- logger ---
29+ # route MP logs into pytest caplog
2730 logger = logging .getLogger ("mergin_test" )
2831 logger .setLevel (logging .DEBUG )
2932 logger .propagate = True
3033 caplog .set_level (logging .ERROR , logger = "mergin_test" )
34+ mp .log = logger
3135
32- # --- fake MP/MC len tam, kde treba ---
33- class MP :
34- def __init__ (self , log ):
35- self .log = log
36-
37- def update_metadata (self , * a , ** k ):
38- pass
39-
40- def apply_push_changes (self , * a , ** k ):
41- pass
42-
43- def fpath_meta (self , rel ):
44- return str (diff_path ) if rel == diff_path .name else rel
36+ # generate a real diff into .mergin/
37+ diff_path = meta_dir / "base_to_inserted_1_A.diff"
38+ GeoDiff ().create_changeset (str (base ), str (modified ), str (diff_path ))
39+ diff_rel = diff_path .name
40+ diff_size = diff_path .stat ().st_size
41+ file_size = modified .stat ().st_size
4542
43+ # mock MerginClient: only patch post(); simulate 5xx on finish
4644 tx = "tx-1"
4745
48- class MC :
49- def post (self , url , * args , ** kwargs ):
50- if url .endswith (f"/v1/project/push/finish/{ tx } " ):
51- err = ClientError ("Gateway error" )
52- setattr (err , "http_error" , status_code )
53- raise err
54- if url .endswith (f"/v1/project/push/cancel/{ tx } " ):
55- return SimpleNamespace (msg = "cancelled" )
56- return SimpleNamespace (msg = "ok" )
46+ def mc_post (url , * args , ** kwargs ):
47+ if url .endswith (f"/v1/project/push/finish/{ tx } " ):
48+ err = ClientError ("Gateway error" )
49+ setattr (err , "http_error" , status_code ) # emulate HTTP code on the exception
50+ raise err
51+ if url .endswith (f"/v1/project/push/cancel/{ tx } " ):
52+ return SimpleNamespace (msg = "cancelled" )
53+ return SimpleNamespace (msg = "ok" )
54+
55+ mc = MagicMock (spec = MerginClient )
56+ mc .post .side_effect = mc_post
5757
5858 tmp_dir = tempfile .TemporaryDirectory (prefix = "python-api-client-test-" )
5959
60- # --- real UploadJob objekt ---
60+ # build a real UploadJob that references the diff/file sizes
6161 job = UploadJob (
6262 project_path = "u/p" ,
6363 changes = {
@@ -66,25 +66,24 @@ def post(self, url, *args, **kwargs):
6666 {
6767 "path" : modified .name ,
6868 "size" : file_size ,
69- "diff" : {"path" : diff_path . name , "size" : diff_size },
69+ "diff" : {"path" : diff_rel , "size" : diff_size },
7070 "chunks" : [1 ],
7171 }
7272 ],
7373 "removed" : [],
7474 },
7575 transaction_id = tx ,
76- mp = MP ( logger ) ,
77- mc = MC () ,
76+ mp = mp ,
77+ mc = mc ,
7878 tmp_dir = tmp_dir ,
7979 )
8080
81- # nastav to, čo finalize() očakáva
8281 job .total_size = 1234
8382 job .transferred_size = 1234
84- job .upload_queue_items = [1 ] # len pre log „Upload details“
83+ job .upload_queue_items = [1 ]
8584 job .executor = SimpleNamespace (shutdown = lambda wait = True : None )
8685 job .futures = [SimpleNamespace (done = lambda : True , exception = lambda : None , running = lambda : False )]
87- job .server_resp = {"version" : "n/a" } # aj tak sa 5xx vyhodí skôr
86+ job .server_resp = {"version" : "n/a" }
8887
8988 with pytest .raises (ClientError ):
9089 push_project_finalize (job )
0 commit comments