Aswinr24 commited on
Commit
a4c5366
·
1 Parent(s): 44f1a61

chore: add unit tests for GitHub issue management (#82)

Browse files
Files changed (1) hide show
  1. tests/test_github.py +220 -0
tests/test_github.py ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Unit tests for the classes under github.py.
3
+
4
+ These tests ensure the functionality of GitHub issue management,
5
+ issue chunking, and issue comments, including happy-path scenarios.
6
+
7
+ Dependencies:
8
+ pip install pytest
9
+ pip install pytest-mock
10
+ """
11
+
12
+ import pytest
13
+ import requests
14
+ from unittest.mock import patch, MagicMock
15
+ from sage.github import GitHubIssuesManager, GitHubIssue, GitHubIssueComment, GitHubIssuesChunker, IssueChunk
16
+
17
+ class TestGitHubIssuesManager:
18
+
19
+ @pytest.fixture(autouse=True)
20
+ def setup_method(self):
21
+ """Fixture to create a GitHubIssuesManager instance for each test."""
22
+ self.github_manager = GitHubIssuesManager(repo_id="random/random-repo", access_token="fake_token")
23
+
24
+ @staticmethod
25
+ def mock_issue_response():
26
+ """A mock response for GitHub issues."""
27
+ return MagicMock(json=lambda: [
28
+ {
29
+ "url": "https://api.github.com/repos/random/random-repo/issues/1",
30
+ "html_url": "https://github.com/random/random-repo/issues/1",
31
+ "title": "Found a bug",
32
+ "body": "I'm having a problem with this.",
33
+ "comments_url": "https://api.github.com/repos/random/random-repo/issues/1/comments",
34
+ "comments": 2
35
+ }
36
+ ])
37
+
38
+ @staticmethod
39
+ def mock_comment_response():
40
+ """Create a mock response for GitHub issue comments."""
41
+ return MagicMock(json=lambda: [
42
+ {
43
+ "url": "https://api.github.com/repos/random/random-repo/issues/comments/1",
44
+ "html_url": "https://github.com/random/random-repo/issues/comments/1",
45
+ "body": "This is a comment."
46
+ }
47
+ ])
48
+
49
+ @patch('github.requests.get')
50
+ def test_download_issues(self, mock_get):
51
+ """Test the download of issues from GitHub."""
52
+ mock_get.side_effect = [self.mock_issue_response(), self.mock_comment_response()]
53
+
54
+ self.github_manager.download()
55
+
56
+ assert len(self.github_manager.issues) == 1
57
+ assert self.github_manager.issues[0].title == "Found a bug"
58
+ assert self.github_manager.issues[0].body == "I'm having a problem with this."
59
+ assert self.github_manager.issues[0].url == "https://api.github.com/repos/random/random-repo/issues/1"
60
+
61
+ @patch('github.requests.get')
62
+ def test_walk_issues(self, mock_get):
63
+ """Test the walking through downloaded issues."""
64
+ self.github_manager.issues = [
65
+ GitHubIssue(url="issue_url", html_url="html_issue_url", title="Test Issue", body="Test Body", comments=[]),
66
+ GitHubIssue(url="issue_url_2", html_url="html_issue_url_2", title="Another Test Issue", body="Another Test Body", comments=[]),
67
+ ]
68
+
69
+ issues = list(self.github_manager.walk())
70
+
71
+ assert len(issues) == 2
72
+ assert issues[0][0].title == "Test Issue"
73
+ assert issues[1][0].title == "Another Test Issue"
74
+
75
+ @patch('github.requests.get')
76
+ def test_get_page_of_issues(self, mock_get):
77
+ """Test fetching a page of issues."""
78
+ mock_response = MagicMock()
79
+ mock_response.json.return_value = [
80
+ {
81
+ "url": "https://api.github.com/repos/random/random-repo/issues/1",
82
+ "html_url": "https://github.com/random/random-repo/issues/1",
83
+ "title": "Found a bug",
84
+ "body": "I'm having a problem with this.",
85
+ "comments_url": "https://api.github.com/repos/random/random-repo/issues/1/comments",
86
+ "comments": 2
87
+ }
88
+ ]
89
+ mock_get.return_value = mock_response
90
+
91
+ issues = self.github_manager._get_page_of_issues("https://api.github.com/repos/random/random-repo/issues?page=1").json()
92
+
93
+ assert len(issues) == 1
94
+
95
+ @patch('github.requests.get')
96
+ def test_get_comments(self, mock_get):
97
+ """Test retrieving comments for an issue."""
98
+ mock_get.return_value.json.return_value = self.mock_comment_response().json()
99
+
100
+ comments = self.github_manager._get_comments("comments_url")
101
+ assert len(comments) == 1
102
+ assert comments[0].body == "This is a comment."
103
+
104
+ def test_chunker(self):
105
+ """Test chunking of an issue into smaller parts."""
106
+ issue = GitHubIssue(
107
+ url="issue_url",
108
+ html_url="html_issue_url",
109
+ title="Test Issue",
110
+ body="This is a long body of the issue that needs to be chunked.",
111
+ comments=[
112
+ GitHubIssueComment(url="comment_url_1", html_url="html_comment_url_1", body="First comment."),
113
+ GitHubIssueComment(url="comment_url_2", html_url="html_comment_url_2", body="Second comment."),
114
+ ]
115
+ )
116
+
117
+ chunker = GitHubIssuesChunker(max_tokens=50)
118
+ chunks = chunker.chunk(content=issue, metadata={})
119
+
120
+ assert len(chunks) > 0
121
+ assert all(isinstance(chunk, IssueChunk) for chunk in chunks)
122
+ assert chunks[0].issue.title == "Test Issue"
123
+ assert chunks[0].start_comment == 0
124
+
125
+
126
+ class TestGitHubIssueComment:
127
+
128
+ def test_initialization(self):
129
+ """Test the initialization of the GitHubIssueComment class."""
130
+ comment = GitHubIssueComment(url="comment_url", html_url="html_comment_url", body="Sample comment")
131
+ assert comment.url == "comment_url"
132
+ assert comment.html_url == "html_comment_url"
133
+ assert comment.body == "Sample comment"
134
+
135
+ def test_pretty_property(self):
136
+ """Test the pretty property of the GitHubIssueComment class."""
137
+ comment = GitHubIssueComment(url="comment_url", html_url="html_comment_url", body="Sample comment")
138
+ assert comment.pretty == "## Comment: Sample comment"
139
+
140
+
141
+ class TestGitHubIssue:
142
+
143
+ def test_initialization(self):
144
+ """Test the initialization of the GitHubIssue class."""
145
+ issue = GitHubIssue(url="issue_url", html_url="html_issue_url", title="Test Issue", body="Test Body", comments=[])
146
+ assert issue.url == "issue_url"
147
+ assert issue.html_url == "html_issue_url"
148
+ assert issue.title == "Test Issue"
149
+ assert issue.body == "Test Body"
150
+ assert issue.comments == []
151
+
152
+ def test_pretty_property(self):
153
+ """Test the pretty property of the GitHubIssue class."""
154
+ issue = GitHubIssue(url="issue_url", html_url="html_issue_url", title="Test Issue", body="Test Body", comments=[])
155
+ assert issue.pretty == "# Issue: Test Issue\nTest Body"
156
+
157
+
158
+ class TestIssueChunk:
159
+
160
+ def test_initialization(self):
161
+ """Test the initialization of the IssueChunk class."""
162
+ issue = GitHubIssue(url="issue_url", html_url="html_issue_url", title="Test Issue", body="Test Body", comments=[])
163
+ chunk = IssueChunk(issue=issue, start_comment=0, end_comment=1)
164
+ assert chunk.issue == issue
165
+ assert chunk.start_comment == 0
166
+ assert chunk.end_comment == 1
167
+
168
+ def test_content_property(self):
169
+ """Test the content property of the IssueChunk class."""
170
+ issue = GitHubIssue(url="issue_url", html_url="html_issue_url", title="Test Issue", body="Test Body", comments=[])
171
+ chunk = IssueChunk(issue=issue, start_comment=0, end_comment=1)
172
+ assert chunk.content == "# Issue: Test Issue\nTest Body\n\n"
173
+
174
+ def test_metadata_property(self):
175
+ """Test the metadata property of the IssueChunk class."""
176
+ issue = GitHubIssue(url="issue_url", html_url="html_issue_url", title="Test Issue", body="Test Body", comments=[])
177
+ chunk = IssueChunk(issue=issue, start_comment=0, end_comment=1)
178
+ expected_metadata = {
179
+ "id": "html_issue_url_0_1",
180
+ "url": "html_issue_url",
181
+ "start_comment": 0,
182
+ "end_comment": 1,
183
+ 'text': '# Issue: Test Issue\nTest Body\n\n',
184
+ }
185
+ assert chunk.metadata == expected_metadata
186
+
187
+ def test_num_tokens_property(self):
188
+ """Test the num_tokens property of the IssueChunk class."""
189
+ issue = GitHubIssue(url="issue_url", html_url="html_issue_url", title="Test Issue", body="This is a test body.", comments=[])
190
+ chunk = IssueChunk(issue=issue, start_comment=0, end_comment=1)
191
+ assert chunk.num_tokens == 12
192
+
193
+
194
+ class TestGitHubIssuesChunker:
195
+
196
+ def test_initialization(self):
197
+ """Test the initialization of the GitHubIssuesChunker class."""
198
+ chunker = GitHubIssuesChunker(max_tokens=50)
199
+ assert chunker.max_tokens == 50
200
+
201
+ def test_chunk_method(self):
202
+ """Test the chunk method of the GitHubIssuesChunker class."""
203
+ issue = GitHubIssue(
204
+ url="issue_url",
205
+ html_url="html_issue_url",
206
+ title="Test Issue",
207
+ body="This is a long body of the issue that needs to be chunked.",
208
+ comments=[]
209
+ )
210
+
211
+ chunker = GitHubIssuesChunker(max_tokens=50)
212
+ chunks = chunker.chunk(content=issue, metadata={})
213
+
214
+ assert len(chunks) > 0
215
+
216
+ assert all(isinstance(chunk, IssueChunk) for chunk in chunks)
217
+
218
+
219
+ if __name__ == '__main__':
220
+ pytest.main()