def get_teams( self, team_names: Optional[Iterable[str]] = None) -> Iterable[plug.Team]: """See :py:meth:`repobee_plug.PlatformAPI.get_teams`.""" team_names = set(team_names or {}) endpoint = f"/orgs/{self._org_name}/teams" response = self._request( requests.get, endpoint, error_msg="failed to fetch teams from organization: " f"'{self._org_name}'", ) for team_dict in response.json(): team_name = team_dict["name"] if team_names and team_name not in team_names: continue members_endpoint = f"/teams/{team_dict['id']}/members" members = [ d["login"] for d in self._request(requests.get, members_endpoint).json() ] yield plug.Team( name=team_name, members=members, id=team_dict["id"], implementation=team_dict, )
def to_plug_team(self) -> plug.Team: return plug.Team( name=self.name, members=[mem.username for mem in self.members], id=self.id, implementation=self, )
def create_team( self, name: str, members: Optional[List[str]] = None, permission: plug.TeamPermission = plug.TeamPermission.PUSH, ) -> plug.Team: """See :py:meth:`repobee_plug.PlatformAPI.create_team`.""" team_data = dict( description=name, includes_all_repositories=False, name=name, permission=_TEAM_PERMISSION_MAPPING[permission], units=[ "repo.code", "repo.issues", "repo.ext_issues", "repo.wiki", "repo.pulls", "repo.releases", "repo.ext_wiki", ], ) endpoint = f"/orgs/{self._org_name}/teams" response = self._request(requests.post, endpoint, data=team_data) team_id = response.json()["id"] team = plug.Team( name=name, members=members or [], id=team_id, implementation=response.json(), ) self.assign_members(team, members or []) return team
def _wrap_team(self, team: _Team) -> plug.Team: with _try_api_request(): return plug.Team( name=team.name, members=[m.login for m in team.get_members()], id=team.id, implementation=team, )
def _wrap_group(self, group) -> plug.Team: with _try_api_request(): return plug.Team( name=group.name, members=[ m.username for m in group.members.list(all=True) # we do not include the owner, as this is the person who # created the group (typically the teacher). Including # the creator of the group breaks RepoBee. if m.access_level != gitlab.OWNER_ACCESS ], id=group.id, implementation=group, )
def test_students_missing_from_grades_file_causes_crash( self, tmp_grades_file, mocked_hook_results): """Test that if a specified student is missing from the grades file, there is a crash. """ missing_team = plug.Team(members=["randomdude"]) args = argparse.Namespace( students=list(TEAMS) + [missing_team], hook_results_file="", # don't care, read_results_file is mocked grades_file=str(tmp_grades_file), master_repo_names="week-1 week-2 week-4 week-6".split(), edit_msg_file=str(tmp_grades_file.parent / "editmsg.txt"), teachers=list(TEACHERS), grade_specs=[PASS_GRADESPEC_FORMAT], allow_other_states=False, ) with pytest.raises(_exception.FileError) as exc_info: csvgrades.callback(args=args, api=None) assert "student(s) {} missing from the grades file".format( missing_team.members[0]) in str(exc_info.value)
import shutil from datetime import datetime from unittest import mock import pytest import repobee_plug as plug from _repobee import plugin from repobee_csvgrades import csvgrades from repobee_csvgrades import _file from repobee_csvgrades import _marker from repobee_csvgrades import _exception TEAMS = tuple([ plug.Team(members=members) for members in (["slarse"], ["glassey", "glennol"]) ]) DIR = pathlib.Path(__file__).parent GRADES_FILE = DIR / "grades.csv" EXPECTED_GRADES_FILE = DIR / "expected_grades.csv" EXPECTED_GRADES_MULTI_SPEC_FILE = DIR / "expected_grades_multi_spec.csv" EXPECTED_EDIT_MSG_FILE = DIR / "expected_edit_msg.txt" EXPECTED_EDIT_MSG_MULTI_SPEC_FILE = DIR / "expected_edit_msg_multi_spec.txt" SLARSE_TA = "ta_a" GLASSEY_GLENNOL_TA = "ta_b" TEACHERS = (SLARSE_TA, GLASSEY_GLENNOL_TA) PASS_GRADESPEC_FORMAT = "1:P:[Pp]ass" FAIL_GRADESPEC_FORMAT = "2:F:[Ff]ail"