1010 CodebaseGitRemote ,
1111 GithubIntegrationAppInstallation ,
1212 CodebaseRelease ,
13+ ImportedReleaseSyncState ,
1314)
1415from library .tests .base import CodebaseFactory
1516
@@ -77,62 +78,65 @@ def setUp(self):
7778 github_user_id = 123 ,
7879 )
7980 self .codebase = CodebaseFactory (submitter = self .user ).create ()
80- mirror = self .codebase .create_git_mirror ()
8181 self .remote = CodebaseGitRemote .objects .create (
82- mirror = mirror ,
82+ codebase = self . codebase ,
8383 owner = "testuser" ,
8484 repo_name = "test-repo" ,
8585 is_user_repo = True ,
86+ is_active = True ,
8687 )
8788 self .payload = SAMPLE_PAYLOAD .copy ()
89+ # create sync state from payload
90+ self .sync_state = ImportedReleaseSyncState .for_github_release (
91+ self .remote , self .payload ["release" ]
92+ )
8893
8994 def test_init_success (self ):
90- # should initialize successfully with a valid payload
91- importer = GitHubReleaseImporter (self .payload )
95+ # should initialize successfully with a valid remote and release id
96+ importer = GitHubReleaseImporter (self .remote , "12345" )
9297 self .assertEqual (importer .github_release_id , "12345" )
9398 self .assertEqual (importer .codebase , self .codebase )
94- self .assertTrue (importer .is_new_github_release )
9599
96100 def test_init_failures (self ):
97- # test various invalid payloads that should raise ValueError
98- test_cases = {
99- "draft" : ("release" , "draft" , True ),
100- "prerelease" : ("release" , "prerelease" , True ),
101- "private" : ("repository" , "private" , True ),
102- "wrong_action" : ("action" , None , "created" ),
103- "no_remote" : ("repository" , "name" , "non-existent-repo" ),
104- }
105- for name , (key1 , key2 , value ) in test_cases .items ():
106- with self .subTest (name = name ):
107- bad_payload = self .payload .copy ()
108- if key2 :
109- bad_payload [key1 ] = bad_payload [key1 ].copy ()
110- bad_payload [key1 ][key2 ] = value
111- else :
112- bad_payload [key1 ] = value
113- with self .assertRaises (ValueError ):
114- GitHubReleaseImporter (bad_payload )
101+ # test various invalid scenarios that should raise ValueError
102+ # missing sync state
103+ with self .assertRaises (ValueError ):
104+ GitHubReleaseImporter (self .remote , "99999" )
105+
106+ # sync state without download_url
107+ bad_sync_state = ImportedReleaseSyncState .objects .create (
108+ remote = self .remote ,
109+ github_release_id = "88888" ,
110+ download_url = "" , # empty download url
111+ )
112+ with self .assertRaises (ValueError ):
113+ GitHubReleaseImporter (self .remote , "88888" )
115114
116115 def test_extract_semver (self ):
117116 # test semantic version extraction
118- importer = GitHubReleaseImporter (self .payload )
117+ importer = GitHubReleaseImporter (self .remote , "12345" )
119118 self .assertEqual (importer .extract_semver ("v1.2.3" ), "1.2.3" )
120119 self .assertEqual (importer .extract_semver ("1.2.3" ), "1.2.3" )
121120 self .assertEqual (importer .extract_semver ("version 1.2.3-beta" ), "1.2.3" )
122121 self .assertIsNone (importer .extract_semver ("1.2" ))
123122 self .assertIsNone (importer .extract_semver ("invalid-version" ))
124123
124+ @patch ("library.github_integration.GitHubApi.get_repo_raw_for_remote" )
125125 @patch ("library.models.CodebaseRelease.get_fs_api" )
126126 @patch ("library.github_integration.GitHubApi.get_user_installation_access_token" )
127- def test_import_new_release (self , mock_get_token , mock_get_fs_api ):
127+ def test_import_new_release (self , mock_get_token , mock_get_fs_api , mock_get_repo ):
128128 # mock token and fs_api calls
129129 mock_get_token .return_value = "fake-token"
130+ mock_get_repo .return_value = {"name" : "test-repo" , "full_name" : "testuser/test-repo" }
130131 mock_fs_api = MagicMock ()
131132 mock_fs_api .import_release_package .return_value = ({}, {}) # codemeta, cff
132133 mock_get_fs_api .return_value = mock_fs_api
133134
135+ # create sync state first
136+ ImportedReleaseSyncState .for_github_release (self .remote , self .payload ["release" ])
137+
134138 # import a new release
135- importer = GitHubReleaseImporter (self .payload )
139+ importer = GitHubReleaseImporter (self .remote , "12345" )
136140 success = importer .import_new_release ()
137141
138142 # check that it was successful and objects were created
@@ -147,17 +151,25 @@ def test_import_new_release(self, mock_get_token, mock_get_fs_api):
147151 self .assertEqual (release .submitter , self .codebase .submitter )
148152 mock_fs_api .import_release_package .assert_called_once ()
149153
154+ @patch ("library.github_integration.GitHubApi.get_release_raw_for_remote" )
155+ @patch ("library.github_integration.GitHubApi.get_repo_raw_for_remote" )
150156 @patch ("library.models.CodebaseRelease.get_fs_api" )
151157 @patch ("library.github_integration.GitHubApi.get_user_installation_access_token" )
152- def test_reimport_release (self , mock_get_token , mock_get_fs_api ):
158+ def test_reimport_release (self , mock_get_token , mock_get_fs_api , mock_get_repo , mock_get_release ):
153159 # mock token and fs_api calls
154160 mock_get_token .return_value = "fake-token"
161+ mock_get_repo .return_value = {"name" : "test-repo" , "full_name" : "testuser/test-repo" }
155162 mock_fs_api = MagicMock ()
156163 mock_fs_api .import_release_package .return_value = ({}, {}) # codemeta, cff
157164 mock_get_fs_api .return_value = mock_fs_api
158165
166+ # create sync state first
167+ sync_state = ImportedReleaseSyncState .for_github_release (
168+ self .remote , self .payload ["release" ]
169+ )
170+
159171 # first, import a new release
160- importer = GitHubReleaseImporter (self .payload )
172+ importer = GitHubReleaseImporter (self .remote , "12345" )
161173 importer .import_or_reimport ()
162174
163175 self .assertEqual (CodebaseRelease .objects .count (), 1 )
@@ -175,8 +187,10 @@ def test_reimport_release(self, mock_get_token, mock_get_fs_api):
175187 "https://api.github.com/repos/testuser/test-repo/zipball/v1.0.0-updated"
176188 )
177189 reimport_payload ["release" ]["zipball_url" ] = new_url
190+ # mock get_release_raw_for_remote to return the updated payload
191+ mock_get_release .return_value = reimport_payload ["release" ]
178192
179- importer2 = GitHubReleaseImporter (reimport_payload )
193+ importer2 = GitHubReleaseImporter (self . remote , "12345" )
180194 success = importer2 .import_or_reimport ()
181195
182196 # assert that the re-import was successful and the release was updated
@@ -191,40 +205,4 @@ def test_reimport_release(self, mock_get_token, mock_get_fs_api):
191205 # release version number should NOT have changed
192206 self .assertEqual (release .version_number , "1.0.0" )
193207
194- # re-importing with no change does nothing
195- importer3 = GitHubReleaseImporter (reimport_payload )
196- success_no_change = importer3 .import_or_reimport ()
197- self .assertFalse (success_no_change )
198- # should still be 2, not called again
199- self .assertEqual (mock_fs_api .import_release_package .call_count , 2 )
200-
201- # re-importing a published release does nothing
202- release .status = CodebaseRelease .Status .PUBLISHED
203- release .save ()
204- published_reimport_payload = reimport_payload .copy ()
205- published_reimport_payload ["release" ][
206- "zipball_url"
207- ] = "https://another.url/zipball.zip"
208- importer4 = GitHubReleaseImporter (published_reimport_payload )
209- success_published = importer4 .import_or_reimport ()
210- self .assertFalse (success_published )
211- # fs_api should not be called again
212- self .assertEqual (mock_fs_api .import_release_package .call_count , 2 )
213- self .remote .refresh_from_db ()
214208
215- # re-importing an under_review release should work
216- release .status = CodebaseRelease .Status .UNDER_REVIEW
217- release .save ()
218- review_reimport_payload = self .payload .copy ()
219- review_reimport_payload ["action" ] = "edited"
220- review_reimport_payload ["release" ] = review_reimport_payload ["release" ].copy ()
221- review_url = (
222- "https://api.github.com/repos/testuser/test-repo/zipball/v1.0.0-review"
223- )
224- review_reimport_payload ["release" ]["zipball_url" ] = review_url
225- importer5 = GitHubReleaseImporter (review_reimport_payload )
226- success_review = importer5 .import_or_reimport ()
227- self .assertTrue (success_review )
228- self .assertEqual (mock_fs_api .import_release_package .call_count , 3 )
229- release .refresh_from_db ()
230- self .assertEqual (release .imported_release_sync_state .download_url , review_url )
0 commit comments