Skip to content

Commit 1ea19aa

Browse files
committed
test: add tests
- tests for locally writing files - tests for get_team_history - tests for get_dict_value - tests for get_config_file
1 parent 1c02017 commit 1ea19aa

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed

tests/test_main.py

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
get_team_history,
1919
handler,
2020
update_s3_object,
21+
get_dict_value,
22+
get_config_file,
2123
)
2224

2325

@@ -116,6 +118,22 @@ def test_get_and_update_copilot_teams_no_teams(self, mock_update_s3_object):
116118
assert args[2] == "copilot_teams.json"
117119
assert args[3] == []
118120

121+
def test_write_data_locally_creates_file(self, tmp_path):
122+
s3 = MagicMock()
123+
gh = MagicMock()
124+
response = MagicMock()
125+
response.links = {}
126+
gh.get.return_value = response
127+
128+
with patch("src.main.get_copilot_team_date", return_value=[{"name": "teamA"}]):
129+
with patch("src.main.os.makedirs") as mock_makedirs, \
130+
patch("src.main.open", create=True) as mock_open:
131+
result = get_and_update_copilot_teams(s3, gh, True)
132+
assert result == [{"name": "teamA"}]
133+
mock_makedirs.assert_called_once_with("output", exist_ok=True)
134+
mock_open.assert_called_once()
135+
s3.put_object.assert_not_called()
136+
119137

120138
class TestGetTeamHistory:
121139
def setup_method(self):
@@ -412,6 +430,28 @@ def test_get_and_update_historic_usage_no_new_dates(self):
412430
assert dates_added == []
413431
s3.put_object.assert_called_once()
414432

433+
def test_write_data_locally_creates_file(self, tmp_path):
434+
s3 = MagicMock()
435+
gh = MagicMock()
436+
usage_data = [{"date": "2024-01-01", "usage": 10}]
437+
gh.get.return_value.json.return_value = usage_data
438+
439+
# S3 get_object raises ClientError
440+
s3.get_object.side_effect = ClientError(
441+
error_response={"Error": {"Code": "404", "Message": "Not Found"}},
442+
operation_name="GetObject",
443+
)
444+
445+
# Patch os.makedirs and open to use tmp_path
446+
with patch("src.main.os.makedirs") as mock_makedirs, \
447+
patch("src.main.open", create=True) as mock_open:
448+
result, dates_added = get_and_update_historic_usage(s3, gh, True)
449+
assert result == [{"date": "2024-01-01", "usage": 10}]
450+
assert dates_added == ["2024-01-01"]
451+
mock_makedirs.assert_called_once_with("output", exist_ok=True)
452+
mock_open.assert_called_once()
453+
s3.put_object.assert_not_called()
454+
415455

416456
class TestCreateDictionary:
417457
def setup_method(self):
@@ -490,3 +530,107 @@ def test_create_dictionary_no_new_history(self, caplog):
490530
result = create_dictionary(gh, copilot_teams, existing_team_history)
491531
assert result == []
492532
assert mock_get_team_history.call_count == 1
533+
534+
535+
class TestGetTeamHistory:
536+
def setup_method(self):
537+
self.org_patch = patch("src.main.org", "test-org")
538+
self.org_patch.start()
539+
540+
def teardown_method(self):
541+
self.org_patch.stop()
542+
543+
def test_get_team_history_returns_metrics(self):
544+
gh = MagicMock()
545+
mock_response = MagicMock(spec=Response)
546+
mock_response.json.return_value = [{"date": "2024-01-01", "usage": 5}]
547+
gh.get.return_value = mock_response
548+
549+
result = get_team_history(gh, "dev-team", {"since": "2024-01-01"})
550+
gh.get.assert_called_once_with(
551+
"/orgs/test-org/team/dev-team/copilot/metrics", params={"since": "2024-01-01"}
552+
)
553+
assert result == [{"date": "2024-01-01", "usage": 5}]
554+
555+
def test_get_team_history_returns_empty_list(self):
556+
gh = MagicMock()
557+
mock_response = MagicMock(spec=Response)
558+
mock_response.json.return_value = []
559+
gh.get.return_value = mock_response
560+
561+
result = get_team_history(gh, "dev-team")
562+
gh.get.assert_called_once_with("/orgs/test-org/team/dev-team/copilot/metrics", params=None)
563+
assert result == []
564+
565+
def test_get_team_history_non_response_returns_none(self):
566+
gh = MagicMock()
567+
gh.get.return_value = "not_a_response"
568+
569+
result = get_team_history(gh, "dev-team")
570+
gh.get.assert_called_once_with("/orgs/test-org/team/dev-team/copilot/metrics", params=None)
571+
assert result is None
572+
573+
def test_get_team_history_with_query_params_none(self):
574+
gh = MagicMock()
575+
mock_response = MagicMock(spec=Response)
576+
mock_response.json.return_value = [{"date": "2024-01-01", "usage": 5}]
577+
gh.get.return_value = mock_response
578+
579+
result = get_team_history(gh, "dev-team", None)
580+
gh.get.assert_called_once_with("/orgs/test-org/team/dev-team/copilot/metrics", params=None)
581+
assert result == [{"date": "2024-01-01", "usage": 5}]
582+
583+
584+
class TestGetDictValue:
585+
def test_get_dict_value_returns_value(self):
586+
d = {"foo": "bar", "baz": 42}
587+
assert get_dict_value(d, "foo") == "bar"
588+
assert get_dict_value(d, "baz") == 42
589+
590+
def test_get_dict_value_raises_for_missing_key(self):
591+
d = {"foo": "bar"}
592+
try:
593+
get_dict_value(d, "missing")
594+
except ValueError as e:
595+
assert str(e) == "Key missing not found in the dictionary."
596+
else:
597+
assert False, "ValueError not raised for missing key"
598+
599+
def test_get_dict_value_returns_none_for_key_with_none_value(self):
600+
d = {"foo": None}
601+
try:
602+
get_dict_value(d, "foo")
603+
except ValueError as e:
604+
assert str(e) == "Key foo not found in the dictionary."
605+
else:
606+
assert False, "ValueError not raised for None value"
607+
608+
609+
class TestGetConfigFile:
610+
def test_get_config_file_success(self, tmp_path):
611+
config_data = {"features": {"show_log_locally": False}}
612+
config_path = tmp_path / "config.json"
613+
config_path.write_text(json.dumps(config_data), encoding="utf-8")
614+
615+
result = get_config_file(str(config_path))
616+
assert result == config_data
617+
618+
def test_get_config_file_file_not_found(self):
619+
missing_path = "nonexistent_config.json"
620+
try:
621+
get_config_file(missing_path)
622+
except FileNotFoundError as e:
623+
assert missing_path in str(e)
624+
else:
625+
assert False, "FileNotFoundError not raised"
626+
627+
def test_get_config_file_not_dict(self, tmp_path):
628+
config_path = tmp_path / "config.json"
629+
config_path.write_text(json.dumps([1, 2, 3]), encoding="utf-8")
630+
631+
try:
632+
get_config_file(str(config_path))
633+
except TypeError as e:
634+
assert "is not a dictionary" in str(e)
635+
else:
636+
assert False, "TypeError not raised for non-dict config"

0 commit comments

Comments
 (0)