Skip to content

Commit 2058090

Browse files
authored
API V3: Filter build notifications by current project (#11458)
1 parent 57e7132 commit 2058090

File tree

4 files changed

+53
-7
lines changed

4 files changed

+53
-7
lines changed

readthedocs/api/v3/mixins.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,9 @@ def _get_parent_project(self):
9494
return get_object_or_404(Project, slug=slug)
9595

9696
def _get_parent_build(self):
97-
pk = self._get_parent_object_lookup(self.BUILD_LOOKUP_NAMES)
98-
return get_object_or_404(Build, pk=pk)
97+
project_slug = self._get_parent_object_lookup(self.PROJECT_LOOKUP_NAMES)
98+
build_pk = self._get_parent_object_lookup(self.BUILD_LOOKUP_NAMES)
99+
return get_object_or_404(Build, pk=build_pk, project__slug=project_slug)
99100

100101
def _get_parent_version(self):
101102
project_slug = self._get_parent_object_lookup(self.PROJECT_LOOKUP_NAMES)

readthedocs/api/v3/tests/mixins.py

+24-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from rest_framework.authtoken.models import Token
1313
from rest_framework.test import APIClient
1414

15-
from readthedocs.builds.constants import TAG
15+
from readthedocs.builds.constants import LATEST, TAG
1616
from readthedocs.builds.models import Build, Version
1717
from readthedocs.core.notifications import MESSAGE_EMAIL_VALIDATION_PENDING
1818
from readthedocs.doc_builder.exceptions import BuildCancelled
@@ -98,6 +98,7 @@ def setUp(self):
9898

9999
self.build = fixture.get(
100100
Build,
101+
id=1,
101102
date=self.created,
102103
type="html",
103104
state="finished",
@@ -125,6 +126,21 @@ def setUp(self):
125126
external_builds_privacy_level=PUBLIC,
126127
privacy_level=PUBLIC,
127128
)
129+
self.others_version = self.others_project.versions.get(slug=LATEST)
130+
self.others_build = fixture.get(
131+
Build,
132+
date=self.created,
133+
type="html",
134+
state="finished",
135+
error="",
136+
success=True,
137+
_config={"property": "test value"},
138+
version=self.others_version,
139+
project=self.others_project,
140+
builder="builder01",
141+
commit="a1b2c3",
142+
length=60,
143+
)
128144

129145
# Make all non-html true so responses are complete
130146
self.project.versions.update(
@@ -171,6 +187,13 @@ def setUp(self):
171187
message_id=MESSAGE_EMAIL_VALIDATION_PENDING,
172188
)
173189

190+
self.notification_others_build = fixture.get(
191+
Notification,
192+
attached_to_content_type=ContentType.objects.get_for_model(Build),
193+
attached_to_id=self.others_build.pk,
194+
message_id=BuildCancelled.CANCELLED_BY_USER,
195+
)
196+
174197
self.client = APIClient()
175198

176199
def tearDown(self):

readthedocs/api/v3/tests/responses/projects-versions-builds-list_POST.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
"duration": null,
66
"error": "",
77
"finished": null,
8-
"id": 2,
8+
"id": 3,
99
"_links": {
10-
"_self": "https://readthedocs.org/api/v3/projects/project/builds/2/",
11-
"notifications": "https://readthedocs.org/api/v3/projects/project/builds/2/notifications/",
10+
"_self": "https://readthedocs.org/api/v3/projects/project/builds/3/",
11+
"notifications": "https://readthedocs.org/api/v3/projects/project/builds/3/notifications/",
1212
"project": "https://readthedocs.org/api/v3/projects/project/",
1313
"version": "https://readthedocs.org/api/v3/projects/project/versions/v1.0/"
1414
},
1515
"urls": {
16-
"build": "https://readthedocs.org/projects/project/builds/2/",
16+
"build": "https://readthedocs.org/projects/project/builds/3/",
1717
"project": "https://readthedocs.org/projects/project/",
1818
"version": "https://readthedocs.org/dashboard/project/version/v1.0/edit/"
1919
},

readthedocs/api/v3/tests/test_builds.py

+22
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,28 @@ def test_projects_builds_notifications_list_other_user(self):
149149
response = self.client.get(url)
150150
self.assertEqual(response.status_code, 403)
151151

152+
# User can see their own notifications.
153+
url = reverse(
154+
"projects-builds-notifications-list",
155+
kwargs={
156+
"parent_lookup_project__slug": self.others_project.slug,
157+
"parent_lookup_build__id": self.others_build.pk,
158+
},
159+
)
160+
response = self.client.get(url)
161+
self.assertEqual(response.status_code, 200)
162+
163+
# User can't see notifications from other users through his project.
164+
url = reverse(
165+
"projects-builds-notifications-list",
166+
kwargs={
167+
"parent_lookup_project__slug": self.others_project.slug,
168+
"parent_lookup_build__id": self.build.pk,
169+
},
170+
)
171+
response = self.client.get(url)
172+
self.assertEqual(response.status_code, 404)
173+
152174
def test_projects_builds_notifications_list_post(self):
153175
url = reverse(
154176
"projects-builds-notifications-list",

0 commit comments

Comments
 (0)