FossilRepo

Comprehensive view tests (30 total)

ragelink 2026-04-07 04:07 trunk
Commit 2f0bbef916fc374b771dd9471412e0f9623ad7e59334e85c8bccb5e0d2a0499d
1 file changed +77 -38
+77 -38
--- fossil/tests.py
+++ fossil/tests.py
@@ -1,8 +1,7 @@
11
import shutil
22
from pathlib import Path
3
-from unittest.mock import PropertyMock, patch
43
54
import pytest
65
76
from .models import FossilRepository
87
from .reader import FossilReader, _apply_fossil_delta, _extract_wiki_content
@@ -155,52 +154,92 @@
155154
156155
157156
@pytest.mark.django_db
158157
class TestFossilViews:
159158
@pytest.fixture
160
- def repo_with_path(self, sample_project, admin_user, tmp_path):
159
+ def setup_repo(self, sample_project, admin_user, tmp_path):
160
+ """Set up a real .fossil file and point Constance FOSSIL_DATA_DIR to tmp."""
161161
src = Path("/tmp/fossil-setup/frontend-app.fossil")
162162
if not src.exists():
163163
pytest.skip("Test fossil repo not available")
164
- dest = tmp_path / "frontend-app.fossil"
165
- shutil.copy2(src, dest)
166
- # Get the auto-created repo from the signal and update its path
164
+ # Copy to tmp dir using the repo's expected filename
167165
repo = FossilRepository.objects.get(project=sample_project)
168
- return repo, dest
169
-
170
- def test_code_browser(self, admin_client, repo_with_path):
171
- repo, dest = repo_with_path
172
- with (
173
- patch.object(type(repo), "full_path", new_callable=PropertyMock, return_value=dest),
174
- patch("fossil.views.FossilRepository.objects") as mock_qs,
175
- ):
176
- mock_qs.filter.return_value.first.return_value = repo
177
- # Use get_object_or_404 mock approach
178
- response = admin_client.get(f"/projects/{repo.project.slug}/fossil/code/")
179
- # May 404 if constance config points elsewhere, but shouldn't error
180
- assert response.status_code in (200, 404)
181
-
182
- def test_timeline(self, admin_client, repo_with_path):
183
- repo, dest = repo_with_path
184
- response = admin_client.get(f"/projects/{repo.project.slug}/fossil/timeline/")
185
- assert response.status_code in (200, 404)
186
-
187
- def test_tickets(self, admin_client, repo_with_path):
188
- repo, dest = repo_with_path
189
- response = admin_client.get(f"/projects/{repo.project.slug}/fossil/tickets/")
190
- assert response.status_code in (200, 404)
191
-
192
- def test_wiki(self, admin_client, repo_with_path):
193
- repo, dest = repo_with_path
194
- response = admin_client.get(f"/projects/{repo.project.slug}/fossil/wiki/")
195
- assert response.status_code in (200, 404)
196
-
197
- def test_forum(self, admin_client, repo_with_path):
198
- repo, dest = repo_with_path
199
- response = admin_client.get(f"/projects/{repo.project.slug}/fossil/forum/")
200
- assert response.status_code in (200, 404)
166
+ dest = tmp_path / repo.filename
167
+ shutil.copy2(src, dest)
168
+ # Override Constance FOSSIL_DATA_DIR to point to our tmp dir
169
+ from constance import config
170
+
171
+ original_dir = config.FOSSIL_DATA_DIR
172
+ config.FOSSIL_DATA_DIR = str(tmp_path)
173
+ yield sample_project.slug
174
+ config.FOSSIL_DATA_DIR = original_dir
175
+
176
+ def test_code_browser_content(self, admin_client, setup_repo):
177
+ slug = setup_repo
178
+ response = admin_client.get(f"/projects/{slug}/fossil/code/")
179
+ assert response.status_code == 200
180
+ content = response.content.decode()
181
+ assert "CONTRIBUTING.md" in content or "README" in content or "utils" in content
182
+
183
+ def test_timeline_content(self, admin_client, setup_repo):
184
+ slug = setup_repo
185
+ response = admin_client.get(f"/projects/{slug}/fossil/timeline/")
186
+ assert response.status_code == 200
187
+ content = response.content.decode()
188
+ assert "ragelink" in content
189
+ assert "tl-row" in content
190
+
191
+ def test_checkin_detail(self, admin_client, setup_repo):
192
+ slug = setup_repo
193
+ response = admin_client.get(f"/projects/{slug}/fossil/timeline/")
194
+ # Extract a hash from the page
195
+ import re
196
+
197
+ hashes = re.findall(r"/checkin/([0-9a-f]{8,})/", response.content.decode())
198
+ if hashes:
199
+ detail = admin_client.get(f"/projects/{slug}/fossil/checkin/{hashes[0]}/")
200
+ assert detail.status_code == 200
201
+ assert "diff-table" in detail.content.decode() or "file" in detail.content.decode().lower()
202
+
203
+ def test_wiki_content(self, admin_client, setup_repo):
204
+ slug = setup_repo
205
+ response = admin_client.get(f"/projects/{slug}/fossil/wiki/")
206
+ assert response.status_code == 200
207
+ content = response.content.decode()
208
+ assert "Home" in content
209
+
210
+ def test_wiki_page_content(self, admin_client, setup_repo):
211
+ slug = setup_repo
212
+ response = admin_client.get(f"/projects/{slug}/fossil/wiki/page/Home")
213
+ assert response.status_code == 200
214
+ content = response.content.decode()
215
+ assert "prose" in content
216
+
217
+ def test_search(self, admin_client, setup_repo):
218
+ slug = setup_repo
219
+ response = admin_client.get(f"/projects/{slug}/fossil/search/?q=initial")
220
+ assert response.status_code == 200
221
+
222
+ def test_file_view(self, admin_client, setup_repo):
223
+ slug = setup_repo
224
+ response = admin_client.get(f"/projects/{slug}/fossil/code/file/CONTRIBUTING.md")
225
+ if response.status_code == 200:
226
+ content = response.content.decode()
227
+ assert "line-num" in content
228
+
229
+ def test_branches(self, admin_client, setup_repo):
230
+ slug = setup_repo
231
+ response = admin_client.get(f"/projects/{slug}/fossil/branches/")
232
+ assert response.status_code == 200
233
+ assert "trunk" in response.content.decode()
234
+
235
+ def test_stats(self, admin_client, setup_repo):
236
+ slug = setup_repo
237
+ response = admin_client.get(f"/projects/{slug}/fossil/stats/")
238
+ assert response.status_code == 200
239
+ assert "Checkins" in response.content.decode()
201240
202241
def test_views_denied_without_perm(self, no_perm_client, sample_project):
203242
slug = sample_project.slug
204243
for path in ["/fossil/code/", "/fossil/timeline/", "/fossil/tickets/", "/fossil/wiki/", "/fossil/forum/"]:
205244
response = no_perm_client.get(f"/projects/{slug}{path}")
206245
assert response.status_code == 403, f"Expected 403 for {path}"
207246
--- fossil/tests.py
+++ fossil/tests.py
@@ -1,8 +1,7 @@
1 import shutil
2 from pathlib import Path
3 from unittest.mock import PropertyMock, patch
4
5 import pytest
6
7 from .models import FossilRepository
8 from .reader import FossilReader, _apply_fossil_delta, _extract_wiki_content
@@ -155,52 +154,92 @@
155
156
157 @pytest.mark.django_db
158 class TestFossilViews:
159 @pytest.fixture
160 def repo_with_path(self, sample_project, admin_user, tmp_path):
 
161 src = Path("/tmp/fossil-setup/frontend-app.fossil")
162 if not src.exists():
163 pytest.skip("Test fossil repo not available")
164 dest = tmp_path / "frontend-app.fossil"
165 shutil.copy2(src, dest)
166 # Get the auto-created repo from the signal and update its path
167 repo = FossilRepository.objects.get(project=sample_project)
168 return repo, dest
169
170 def test_code_browser(self, admin_client, repo_with_path):
171 repo, dest = repo_with_path
172 with (
173 patch.object(type(repo), "full_path", new_callable=PropertyMock, return_value=dest),
174 patch("fossil.views.FossilRepository.objects") as mock_qs,
175 ):
176 mock_qs.filter.return_value.first.return_value = repo
177 # Use get_object_or_404 mock approach
178 response = admin_client.get(f"/projects/{repo.project.slug}/fossil/code/")
179 # May 404 if constance config points elsewhere, but shouldn't error
180 assert response.status_code in (200, 404)
181
182 def test_timeline(self, admin_client, repo_with_path):
183 repo, dest = repo_with_path
184 response = admin_client.get(f"/projects/{repo.project.slug}/fossil/timeline/")
185 assert response.status_code in (200, 404)
186
187 def test_tickets(self, admin_client, repo_with_path):
188 repo, dest = repo_with_path
189 response = admin_client.get(f"/projects/{repo.project.slug}/fossil/tickets/")
190 assert response.status_code in (200, 404)
191
192 def test_wiki(self, admin_client, repo_with_path):
193 repo, dest = repo_with_path
194 response = admin_client.get(f"/projects/{repo.project.slug}/fossil/wiki/")
195 assert response.status_code in (200, 404)
196
197 def test_forum(self, admin_client, repo_with_path):
198 repo, dest = repo_with_path
199 response = admin_client.get(f"/projects/{repo.project.slug}/fossil/forum/")
200 assert response.status_code in (200, 404)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
202 def test_views_denied_without_perm(self, no_perm_client, sample_project):
203 slug = sample_project.slug
204 for path in ["/fossil/code/", "/fossil/timeline/", "/fossil/tickets/", "/fossil/wiki/", "/fossil/forum/"]:
205 response = no_perm_client.get(f"/projects/{slug}{path}")
206 assert response.status_code == 403, f"Expected 403 for {path}"
207
--- fossil/tests.py
+++ fossil/tests.py
@@ -1,8 +1,7 @@
1 import shutil
2 from pathlib import Path
 
3
4 import pytest
5
6 from .models import FossilRepository
7 from .reader import FossilReader, _apply_fossil_delta, _extract_wiki_content
@@ -155,52 +154,92 @@
154
155
156 @pytest.mark.django_db
157 class TestFossilViews:
158 @pytest.fixture
159 def setup_repo(self, sample_project, admin_user, tmp_path):
160 """Set up a real .fossil file and point Constance FOSSIL_DATA_DIR to tmp."""
161 src = Path("/tmp/fossil-setup/frontend-app.fossil")
162 if not src.exists():
163 pytest.skip("Test fossil repo not available")
164 # Copy to tmp dir using the repo's expected filename
 
 
165 repo = FossilRepository.objects.get(project=sample_project)
166 dest = tmp_path / repo.filename
167 shutil.copy2(src, dest)
168 # Override Constance FOSSIL_DATA_DIR to point to our tmp dir
169 from constance import config
170
171 original_dir = config.FOSSIL_DATA_DIR
172 config.FOSSIL_DATA_DIR = str(tmp_path)
173 yield sample_project.slug
174 config.FOSSIL_DATA_DIR = original_dir
175
176 def test_code_browser_content(self, admin_client, setup_repo):
177 slug = setup_repo
178 response = admin_client.get(f"/projects/{slug}/fossil/code/")
179 assert response.status_code == 200
180 content = response.content.decode()
181 assert "CONTRIBUTING.md" in content or "README" in content or "utils" in content
182
183 def test_timeline_content(self, admin_client, setup_repo):
184 slug = setup_repo
185 response = admin_client.get(f"/projects/{slug}/fossil/timeline/")
186 assert response.status_code == 200
187 content = response.content.decode()
188 assert "ragelink" in content
189 assert "tl-row" in content
190
191 def test_checkin_detail(self, admin_client, setup_repo):
192 slug = setup_repo
193 response = admin_client.get(f"/projects/{slug}/fossil/timeline/")
194 # Extract a hash from the page
195 import re
196
197 hashes = re.findall(r"/checkin/([0-9a-f]{8,})/", response.content.decode())
198 if hashes:
199 detail = admin_client.get(f"/projects/{slug}/fossil/checkin/{hashes[0]}/")
200 assert detail.status_code == 200
201 assert "diff-table" in detail.content.decode() or "file" in detail.content.decode().lower()
202
203 def test_wiki_content(self, admin_client, setup_repo):
204 slug = setup_repo
205 response = admin_client.get(f"/projects/{slug}/fossil/wiki/")
206 assert response.status_code == 200
207 content = response.content.decode()
208 assert "Home" in content
209
210 def test_wiki_page_content(self, admin_client, setup_repo):
211 slug = setup_repo
212 response = admin_client.get(f"/projects/{slug}/fossil/wiki/page/Home")
213 assert response.status_code == 200
214 content = response.content.decode()
215 assert "prose" in content
216
217 def test_search(self, admin_client, setup_repo):
218 slug = setup_repo
219 response = admin_client.get(f"/projects/{slug}/fossil/search/?q=initial")
220 assert response.status_code == 200
221
222 def test_file_view(self, admin_client, setup_repo):
223 slug = setup_repo
224 response = admin_client.get(f"/projects/{slug}/fossil/code/file/CONTRIBUTING.md")
225 if response.status_code == 200:
226 content = response.content.decode()
227 assert "line-num" in content
228
229 def test_branches(self, admin_client, setup_repo):
230 slug = setup_repo
231 response = admin_client.get(f"/projects/{slug}/fossil/branches/")
232 assert response.status_code == 200
233 assert "trunk" in response.content.decode()
234
235 def test_stats(self, admin_client, setup_repo):
236 slug = setup_repo
237 response = admin_client.get(f"/projects/{slug}/fossil/stats/")
238 assert response.status_code == 200
239 assert "Checkins" in response.content.decode()
240
241 def test_views_denied_without_perm(self, no_perm_client, sample_project):
242 slug = sample_project.slug
243 for path in ["/fossil/code/", "/fossil/timeline/", "/fossil/tickets/", "/fossil/wiki/", "/fossil/forum/"]:
244 response = no_perm_client.get(f"/projects/{slug}{path}")
245 assert response.status_code == 403, f"Expected 403 for {path}"
246

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button