2525from weblate .trans .actions import ActionEvents
2626from weblate .trans .exceptions import FileParseError
2727from weblate .trans .models import (
28+ Change ,
2829 CommitPolicyChoices ,
2930 Component ,
3031 PendingUnitChange ,
@@ -2300,6 +2301,17 @@ def test_handle_restore_pending_translation_failure_without_translation(
23002301
23012302
23022303class ResetDiscardRevisionTest (ComponentTestCase ):
2304+ def assert_removed_translation_change (self , filename : str ) -> None :
2305+ change = Change .objects .get (
2306+ component = self .component ,
2307+ action = ActionEvents .REMOVE_TRANSLATION ,
2308+ target = filename ,
2309+ )
2310+ self .assertEqual (change .user , self .user )
2311+ self .assertEqual (change .author , self .user )
2312+ self .assertEqual (change .project , self .project )
2313+ self .assertIsNone (change .translation_id )
2314+
23032315 def test_reset_updates_stored_local_revision (self ) -> None :
23042316 start_rev = self .component .repository .last_revision
23052317
@@ -2317,6 +2329,43 @@ def test_reset_updates_stored_local_revision(self) -> None:
23172329 self .assertEqual (start_rev , self .component .repository .last_revision )
23182330 self .assertEqual (start_rev , self .component .local_revision )
23192331
2332+ def test_file_scan_removes_stale_translation_with_change (self ) -> None :
2333+ translation = self .component .translation_set .get (language_code = "cs" )
2334+ filename = translation .filename
2335+ pathlib .Path (cast ("str" , translation .get_filename ())).unlink ()
2336+
2337+ self .assertTrue (
2338+ self .component .create_translations_immediate (
2339+ force = True , request = self .get_request ()
2340+ )
2341+ )
2342+
2343+ self .assertFalse (
2344+ self .component .translation_set .filter (language_code = "cs" ).exists ()
2345+ )
2346+ self .assert_removed_translation_change (filename )
2347+ self .assertFalse (self .project .has_language (Language .objects .get (code = "cs" )))
2348+
2349+ def test_reset_removes_upstream_deleted_translation_with_change (self ) -> None :
2350+ translation = self .component .translation_set .get (language_code = "cs" )
2351+ filename = translation .filename
2352+
2353+ with self .component .repository .lock :
2354+ self .component .repository .remove ([filename ], "Remove Czech translation" )
2355+ self .component .repository .push (self .component .push_branch )
2356+
2357+ self .assertTrue (
2358+ self .component .translation_set .filter (language_code = "cs" ).exists ()
2359+ )
2360+
2361+ self .assertTrue (self .component .do_reset (self .get_request ()))
2362+
2363+ self .assertFalse (
2364+ self .component .translation_set .filter (language_code = "cs" ).exists ()
2365+ )
2366+ self .assert_removed_translation_change (filename )
2367+ self .assertFalse (self .project .has_language (Language .objects .get (code = "cs" )))
2368+
23202369
23212370class TranslationRemoveRevisionTest (ComponentTestCase ):
23222371 def test_remove_updates_stored_local_revision (self ) -> None :
@@ -2333,6 +2382,22 @@ def test_remove_updates_stored_local_revision(self) -> None:
23332382 self .component .local_revision , self .component .repository .last_revision
23342383 )
23352384
2385+ def test_remove_creates_change (self ) -> None :
2386+ translation = self .component .translation_set .get (language_code = "de" )
2387+ filename = translation .filename
2388+
2389+ translation .remove (self .user )
2390+
2391+ change = Change .objects .get (
2392+ component = self .component ,
2393+ action = ActionEvents .REMOVE_TRANSLATION ,
2394+ target = filename ,
2395+ )
2396+ self .assertEqual (change .user , self .user )
2397+ self .assertEqual (change .author , self .user )
2398+ self .assertEqual (change .project , self .project )
2399+ self .assertIsNone (change .translation_id )
2400+
23362401
23372402class LastCommitLookupTest (ComponentTestCase ):
23382403 def test_get_last_commit_keeps_stale_local_revision_unchanged (self ) -> None :
0 commit comments