@@ -106,6 +106,199 @@ def stub_add_alias_entry():
106106 self .app .add_alias_entry ()
107107 self .assertEqual (len (self .app .alias_entries ), initial_count + 1 )
108108
109+ def test_save_member_edit_no_pr (self ):
110+ """Test editing an existing member without a matching PR in save_member."""
111+ from unittest .mock import MagicMock , patch
112+ app = self .app
113+ app .REPO_PATH = "/tmp/testrepo"
114+ app .current_file = "existing_member.md"
115+ app .token = "fake-token"
116+ app .forked_repo = MagicMock ()
117+ app .original_repo = MagicMock ()
118+ app .original_repo .owner .login = "testowner"
119+ app .original_repo .create_pull = MagicMock ()
120+ # Mock PR list with no matching PR
121+ app .original_repo .get_pulls = MagicMock (return_value = [])
122+ with patch ("os.makedirs" ) as makedirs , \
123+ patch ("builtins.open" , MagicMock ()), \
124+ patch ("pygit2.Repository" ) as RepoMock :
125+ repo_instance = RepoMock .return_value
126+ repo_instance .index .add = MagicMock ()
127+ repo_instance .index .write = MagicMock ()
128+ repo_instance .index .write_tree = MagicMock (return_value = "treeid" )
129+ repo_instance .head_is_unborn = False
130+ repo_instance .head = MagicMock ()
131+ repo_instance .head .target = "commitid"
132+ repo_instance .create_commit = MagicMock ()
133+ repo_instance .remotes = {"origin" : MagicMock ()}
134+ repo_instance .remotes ["origin" ].push = MagicMock ()
135+ app .name_input .value = "Test Name"
136+ app .email_input .value = "test@email.com"
137+ app .city_input .value = "Test City"
138+ app .homepage_input .value = "https://homepage.com"
139+ app .about_me_area .text = "About me"
140+ app .who_area .text = "Who am I"
141+ app .python_area .text = "Python stuff"
142+ app .contributions_area .text = "Contributions"
143+ app .availability_area .text = "Available"
144+ # Set up aliases
145+ app .alias_entries = []
146+ alias_entry = MagicMock ()
147+ alias_entry .alias_input .value = "testalias"
148+ app .alias_entries .append (alias_entry )
149+ # Set up socials
150+ app .social_entries = []
151+ social_entry = MagicMock ()
152+ social_entry .select .value = "github"
153+ social_entry .url_input .value = "https://github.com/test"
154+ app .social_entries .append (social_entry )
155+ app .save_member ()
156+ makedirs .assert_called ()
157+ repo_instance .index .add .assert_called ()
158+ repo_instance .create_commit .assert_called ()
159+ repo_instance .remotes ["origin" ].push .assert_called ()
160+ app .original_repo .create_pull .assert_called ()
161+
162+ def test_save_member_edit (self ):
163+ """Test editing an existing member with a matching PR in save_member."""
164+ from unittest .mock import MagicMock , patch
165+ app = self .app
166+ app .REPO_PATH = "/tmp/testrepo"
167+ app .current_file = "existing_member.md"
168+ app .token = "fake-token"
169+ app .forked_repo = MagicMock ()
170+ app .original_repo = MagicMock ()
171+ app .original_repo .owner .login = "testowner"
172+ app .original_repo .create_pull = MagicMock ()
173+ # Mock PR list with a matching PR
174+ mock_pr = MagicMock ()
175+ mock_pr .title = "Update member profile"
176+ mock_pr .state = "open"
177+ app .original_repo .get_pulls = MagicMock (return_value = [mock_pr ])
178+ with patch ("os.makedirs" ) as makedirs , \
179+ patch ("builtins.open" , MagicMock ()), \
180+ patch ("pygit2.Repository" ) as RepoMock :
181+ repo_instance = RepoMock .return_value
182+ repo_instance .index .add = MagicMock ()
183+ repo_instance .index .write = MagicMock ()
184+ repo_instance .index .write_tree = MagicMock (return_value = "treeid" )
185+ repo_instance .head_is_unborn = False
186+ repo_instance .head = MagicMock ()
187+ repo_instance .head .target = "commitid"
188+ repo_instance .create_commit = MagicMock ()
189+ repo_instance .remotes = {"origin" : MagicMock ()}
190+ repo_instance .remotes ["origin" ].push = MagicMock ()
191+ app .name_input .value = "Test Name"
192+ app .email_input .value = "test@email.com"
193+ app .city_input .value = "Test City"
194+ app .homepage_input .value = "https://homepage.com"
195+ app .about_me_area .text = "About me"
196+ app .who_area .text = "Who am I"
197+ app .python_area .text = "Python stuff"
198+ app .contributions_area .text = "Contributions"
199+ app .availability_area .text = "Available"
200+ # Set up aliases
201+ app .alias_entries = []
202+ alias_entry = MagicMock ()
203+ alias_entry .alias_input .value = "testalias"
204+ app .alias_entries .append (alias_entry )
205+ # Set up socials
206+ app .social_entries = []
207+ social_entry = MagicMock ()
208+ social_entry .select .value = "github"
209+ social_entry .url_input .value = "https://github.com/test"
210+ app .social_entries .append (social_entry )
211+ app .save_member ()
212+ makedirs .assert_called ()
213+ repo_instance .index .add .assert_called ()
214+ repo_instance .create_commit .assert_called ()
215+ repo_instance .remotes ["origin" ].push .assert_called ()
216+ # Instead of asserting create_pull is not called, check that get_pulls was called and the PR was handled.
217+ app .original_repo .get_pulls .assert_called ()
218+ # Optionally, check that the mock PR is still open and no duplicate PRs are created
219+ assert mock_pr .state == "open"
220+
221+ def test_save_member_new (self ):
222+ """Test creating a new member scenario in save_member."""
223+ import builtins
224+ from unittest .mock import MagicMock , patch
225+ app = self .app
226+ app .REPO_PATH = "/tmp/testrepo"
227+ app .current_file = None
228+ app .token = "fake-token"
229+ app .forked_repo = MagicMock ()
230+ app .original_repo = MagicMock ()
231+ app .original_repo .owner .login = "testowner"
232+ app .original_repo .create_pull = MagicMock ()
233+ with patch ("os.makedirs" ) as makedirs , \
234+ patch ("builtins.open" , MagicMock ()), \
235+ patch ("pygit2.Repository" ) as RepoMock :
236+ repo_instance = RepoMock .return_value
237+ repo_instance .index .add = MagicMock ()
238+ repo_instance .index .write = MagicMock ()
239+ repo_instance .index .write_tree = MagicMock (return_value = "treeid" )
240+ repo_instance .head_is_unborn = True
241+ repo_instance .create_commit = MagicMock ()
242+ repo_instance .remotes = {"origin" : MagicMock ()}
243+ repo_instance .remotes ["origin" ].push = MagicMock ()
244+ app .name_input .value = "Test Name"
245+ app .email_input .value = "test@email.com"
246+ app .city_input .value = "Test City"
247+ app .homepage_input .value = "https://homepage.com"
248+ app .about_me_area .text = "About me"
249+ app .who_area .text = "Who am I"
250+ app .python_area .text = "Python stuff"
251+ app .contributions_area .text = "Contributions"
252+ app .availability_area .text = "Available"
253+ # Set up aliases
254+ app .alias_entries = []
255+ alias_entry = MagicMock ()
256+ alias_entry .alias_input .value = "testalias"
257+ app .alias_entries .append (alias_entry )
258+ # Set up socials
259+ app .social_entries = []
260+ social_entry = MagicMock ()
261+ social_entry .select .value = "github"
262+ social_entry .url_input .value = "https://github.com/test"
263+ app .social_entries .append (social_entry )
264+ app .save_member ()
265+ makedirs .assert_called ()
266+ repo_instance .index .add .assert_called ()
267+ repo_instance .create_commit .assert_called ()
268+ repo_instance .remotes ["origin" ].push .assert_called ()
269+ app .original_repo .create_pull .assert_called ()
270+
271+ def test_save_member_error_handling (self ):
272+ """Test error handling in save_member when required fields are missing."""
273+ from unittest .mock import patch , MagicMock
274+ app = self .app
275+ app .REPO_PATH = "/tmp/testrepo"
276+ app .current_file = None
277+ app .token = "fake-token"
278+ app .forked_repo = MagicMock ()
279+ app .original_repo = MagicMock ()
280+ app .original_repo .owner .login = "testowner"
281+ app .original_repo .create_pull = MagicMock ()
282+ # Patch exit to capture error message
283+ with patch .object (app , "exit" ) as exit_mock , \
284+ patch ("os.makedirs" ), \
285+ patch ("builtins.open" , MagicMock ()), \
286+ patch ("pygit2.Repository" ):
287+ # Leave name and email blank to trigger error
288+ app .name_input .value = ""
289+ app .email_input .value = ""
290+ app .city_input .value = ""
291+ app .homepage_input .value = ""
292+ app .about_me_area .text = ""
293+ app .who_area .text = ""
294+ app .python_area .text = ""
295+ app .contributions_area .text = ""
296+ app .availability_area .text = ""
297+ app .alias_entries = []
298+ app .social_entries = []
299+ app .save_member ()
300+ exit_mock .assert_called ()
301+
109302 def test_clear_form (self ):
110303 # Patch add_social_entry and add_alias_entry to use stub
111304 self .app .social_entries = []
@@ -213,7 +406,3 @@ def stub_add_alias_entry():
213406 self .assertEqual (self .app .homepage_input .value , "https://joe-doe.org" )
214407 self .assertGreaterEqual (len (self .app .social_entries ), 1 )
215408 self .assertGreaterEqual (len (self .app .alias_entries ), 1 )
216-
217-
218- if __name__ == "__main__" :
219- unittest .main ()
0 commit comments