Skip to content

Commit 5aa68eb

Browse files
committed
Re-add support for filtering by submitter name, user email
With v1.0 of the Patchwork API, we did not have the ability to directly filter (server-side) by email address or name so we made an initial query to the '/people' resource to find the matching submitter and extract the ID. With v1.1, we added support for searching by email address but not name. We don't want to add server-side name filtering because it's not unique. However, we can continue to do this client-side and fix the regression in behavior. Signed-off-by: Stephen Finucane <stephen@that.guru> Closes: #24
1 parent 3ed4644 commit 5aa68eb

7 files changed

Lines changed: 64 additions & 35 deletions

File tree

git_pw/bundle.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,11 @@ def list_cmd(owner, limit, page, sort, name):
136136

137137
params = []
138138

139-
if api.version() >= (1, 1):
140-
params.extend([('owner', own) for own in owner])
141-
else:
142-
for own in owner:
139+
for own in owner:
140+
# we support server-side filtering by username (but not email) in 1.1
141+
if api.version() >= (1, 1) and '@' not in own:
142+
params.append(('owner', own))
143+
else:
143144
users = api.index('users', [('q', own)])
144145
if len(users) == 0:
145146
LOG.error('No matching owner found: %s', own)

git_pw/patch.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,11 @@ def list_cmd(state, submitter, delegate, archived, limit, page, sort, name):
215215
for state in state:
216216
params.append(('state', state))
217217

218-
if api.version() >= (1, 1):
219-
params.extend([('submitter', subm) for subm in submitter])
220-
params.extend([('delegate', delg) for delg in delegate])
221-
else:
222-
for subm in submitter:
218+
for subm in submitter:
219+
# we support server-side filtering by email (but not name) in 1.1
220+
if api.version() >= (1, 1) and '@' in subm:
221+
params.append(('submitter', subm))
222+
else:
223223
people = api.index('people', [('q', subm)])
224224
if len(people) == 0:
225225
LOG.error('No matching submitter found: %s', subm)
@@ -230,7 +230,11 @@ def list_cmd(state, submitter, delegate, archived, limit, page, sort, name):
230230

231231
params.append(('submitter', people[0]['id']))
232232

233-
for delg in delegate:
233+
for delg in delegate:
234+
# we support server-side filtering by username (but not email) in 1.1
235+
if api.version() >= (1, 1) and '@' not in delg:
236+
params.append(('delegate', delg))
237+
else:
234238
users = api.index('users', [('q', delg)])
235239
if len(users) == 0:
236240
LOG.error('No matching delegates found: %s', delg)

git_pw/series.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,11 @@ def list_cmd(submitter, limit, page, sort, name):
123123

124124
params = []
125125

126-
if api.version() >= (1, 1):
127-
params.extend([('submitter', subm) for subm in submitter])
128-
else:
129-
for subm in submitter:
126+
for subm in submitter:
127+
# we support server-side filtering by email (but not name) in 1.1
128+
if api.version() >= (1, 1) and '@' in subm:
129+
params.append(('submitter', subm))
130+
else:
130131
people = api.index('people', [('q', subm)])
131132
if len(people) == 0:
132133
LOG.error('No matching submitter found: %s', subm)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
fixes:
3+
- |
4+
Resolve an issue that prevented the following filtering when using API
5+
v1.1:
6+
7+
- Filter patches or series by submitter using the submitter's name
8+
- Filter patches by delegate using the delegate's email
9+
- Filter bundles by owner using the owner's email

tests/test_bundle.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -277,21 +277,27 @@ def test_list_api_v1_1(self, mock_log, mock_index, mock_version):
277277

278278
mock_version.return_value = (1, 1)
279279

280+
user_rsp = [self._get_users()]
280281
bundle_rsp = [self._get_bundle()]
281-
mock_index.side_effect = [bundle_rsp]
282+
mock_index.side_effect = [user_rsp, bundle_rsp]
282283

283284
runner = CLIRunner()
284-
result = runner.invoke(bundle.list_cmd, ['--owner', 'john.doe',
285-
'--owner', 'user.b'])
285+
result = runner.invoke(bundle.list_cmd, [
286+
'--owner', 'john.doe',
287+
'--owner', 'user.b',
288+
'--owner', 'john@example.com'])
286289

287290
assert result.exit_code == 0, result
288291

289-
# We shouldn't have to make a call to '/users' since API v1.1 supports
290-
# filtering with usernames natively
292+
# We should have only made a single call to '/users' (for the user
293+
# specified by an email address) since API v1.1 supports filtering with
294+
# usernames natively
291295
calls = [
296+
mock.call('users', [('q', 'john@example.com')]),
292297
mock.call('bundles', [
293-
('owner', 'john.doe'), ('owner', 'user.b'), ('q', None),
294-
('page', None), ('per_page', None), ('order', 'name')])]
298+
('owner', 'john.doe'), ('owner', 'user.b'), ('owner', 1),
299+
('q', None), ('page', None), ('per_page', None),
300+
('order', 'name')])]
295301
mock_index.assert_has_calls(calls)
296302

297303
# We shouldn't see a warning about multiple versions either

tests/test_patch.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ def _get_users(**kwargs):
287287
rsp = {
288288
'id': 1,
289289
'username': 'john.doe',
290+
'email': 'john@example.com',
290291
}
291292
rsp.update(**kwargs)
292293
return rsp
@@ -385,23 +386,29 @@ def test_list_api_v1_1(self, mock_log, mock_index, mock_version):
385386

386387
mock_version.return_value = (1, 1)
387388

389+
people_rsp = [self._get_person()]
390+
user_rsp = [self._get_users()]
388391
patch_rsp = [self._get_patch()]
389-
mock_index.side_effect = [patch_rsp]
392+
mock_index.side_effect = [people_rsp, user_rsp, patch_rsp]
390393

391394
runner = CLIRunner()
392395
result = runner.invoke(patch.list_cmd, [
393-
'--submitter', 'John Doe', '--submitter', 'Jimmy Foo',
394-
'--delegate', 'foo', '--delegate', 'bar'])
396+
'--submitter', 'jimmy@example.com', '--submitter', 'John Doe',
397+
'--delegate', 'foo', '--delegate', 'john@example.com'])
395398

396399
assert result.exit_code == 0, result
397400

398-
# We shouldn't have to make calls to '/users' or '/people' since API
399-
# v1.1 supports filtering with (user)names natively
401+
# We should have only made a single call to each of '/users' and
402+
# '/people' (for the user specified by an email address and the
403+
# submitter specified by name, respectively) since API v1.1 supports
404+
# filtering of users with username and people with emails natively
400405
calls = [
406+
mock.call('people', [('q', 'John Doe')]),
407+
mock.call('users', [('q', 'john@example.com')]),
401408
mock.call('patches', [
402409
('state', 'under-review'), ('state', 'new'),
403-
('submitter', 'John Doe'), ('submitter', 'Jimmy Foo'),
404-
('delegate', 'foo'), ('delegate', 'bar'),
410+
('submitter', 'jimmy@example.com'), ('submitter', 1),
411+
('delegate', 'foo'), ('delegate', 1),
405412
('q', None), ('archived', 'false'), ('page', None),
406413
('per_page', None), ('order', '-date')])]
407414

tests/test_series.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -234,22 +234,23 @@ def test_list_api_v1_1(self, mock_log, mock_index, mock_version):
234234

235235
mock_version.return_value = (1, 1)
236236

237+
people_rsp = [self._get_people()]
237238
series_rsp = [self._get_series()]
238-
mock_index.side_effect = [series_rsp]
239+
mock_index.side_effect = [people_rsp, series_rsp]
239240

240241
runner = CLIRunner()
241242
result = runner.invoke(series.list_cmd, [
242-
'--submitter', 'john@example.com',
243-
'--submitter', 'jimmy@example.com'])
243+
'--submitter', 'jimmy@example.com',
244+
'--submitter', 'John Doe'])
244245

245246
assert result.exit_code == 0, result
246247

247-
# We shouldn't have to make a call to '/people' since API v1.1 supports
248-
# filtering with names natively
248+
# We should have only made a single call to '/people' since API v1.1
249+
# supports filtering with emails natively
249250
calls = [
251+
mock.call('people', [('q', 'John Doe')]),
250252
mock.call('series', [
251-
('submitter', 'john@example.com'),
252-
('submitter', 'jimmy@example.com'),
253+
('submitter', 'jimmy@example.com'), ('submitter', 1),
253254
('q', None), ('page', None), ('per_page', None),
254255
('order', '-date')])]
255256
mock_index.assert_has_calls(calls)

0 commit comments

Comments
 (0)