22Test users API endpoints in the impress core app.
33"""
44
5+ from django .utils import timezone
6+
57import pytest
68from rest_framework .test import APIClient
79
@@ -121,12 +123,12 @@ def test_api_users_list_query_full_name():
121123 Authenticated users should be able to list users and filter by full name.
122124 Only results with a Trigram similarity greater than 0.2 with the query should be returned.
123125 """
124- user = factories .UserFactory ()
126+ user = factories .UserFactory (email = "user@example.com" )
125127
126128 client = APIClient ()
127129 client .force_login (user )
128130
129- dave = factories .UserFactory (email = "contact@work .com" , full_name = "David Bowman" )
131+ dave = factories .UserFactory (email = "contact@example .com" , full_name = "David Bowman" )
130132
131133 response = client .get (
132134 "/api/v1.0/users/?q=David" ,
@@ -166,13 +168,13 @@ def test_api_users_list_query_accented_full_name():
166168 Authenticated users should be able to list users and filter by full name with accents.
167169 Only results with a Trigram similarity greater than 0.2 with the query should be returned.
168170 """
169- user = factories .UserFactory ()
171+ user = factories .UserFactory (email = "user@example.com" )
170172
171173 client = APIClient ()
172174 client .force_login (user )
173175
174176 fred = factories .UserFactory (
175- email = "contact@work .com" , full_name = "Frédérique Lefèvre"
177+ email = "contact@example .com" , full_name = "Frédérique Lefèvre"
176178 )
177179
178180 response = client .get ("/api/v1.0/users/?q=Frédérique" )
@@ -201,12 +203,82 @@ def test_api_users_list_query_accented_full_name():
201203 assert users == []
202204
203205
206+ def test_api_users_list_sorted_by_closest_match ():
207+ """
208+ Authenticated users should be able to list users and the results should be
209+ sorted by closest match to the query.
210+
211+ Sorting criteria are :
212+ - Shared documents with the user (most recent first)
213+ - Same full email domain (example.gouv.fr)
214+
215+ Addresses that match neither criteria should be excluded from the results.
216+
217+ Case in point: the logged-in user has recently shared documents
218+ with pierre.dupont@beta.gouv.fr and less recently with pierre.durand@impots.gouv.fr.
219+
220+ Other users named Pierre also exist:
221+ - pierre.thomas@example.com
222+ - pierre.petit@anct.gouv.fr
223+ - pierre.robert@culture.gouv.fr
224+
225+ The search results should be ordered as follows:
226+
227+ # Shared with first
228+ - pierre.dupond@beta.gouv.fr # Most recent first
229+ - pierre.durand@impots.gouv.fr
230+ # Same full domain second
231+ - pierre.petit@anct.gouv.fr
232+ """
233+
234+ user = factories .UserFactory (
235+ email = "martin.bernard@anct.gouv.fr" , full_name = "Martin Bernard"
236+ )
237+
238+ client = APIClient ()
239+ client .force_login (user )
240+
241+ pierre_1 = factories .UserFactory (email = "pierre.dupont@beta.gouv.fr" )
242+ pierre_2 = factories .UserFactory (email = "pierre.durand@impots.gouv.fr" )
243+ _pierre_3 = factories .UserFactory (email = "pierre.thomas@example.com" )
244+ pierre_4 = factories .UserFactory (email = "pierre.petit@anct.gouv.fr" )
245+ _pierre_5 = factories .UserFactory (email = "pierre.robert@culture.gouv.fr" )
246+
247+ document_1 = factories .DocumentFactory (creator = user )
248+ document_2 = factories .DocumentFactory (creator = user )
249+ factories .UserDocumentAccessFactory (user = user , document = document_1 )
250+ factories .UserDocumentAccessFactory (user = user , document = document_2 )
251+
252+ now = timezone .now ()
253+ last_week = now - timezone .timedelta (days = 7 )
254+ last_month = now - timezone .timedelta (days = 30 )
255+
256+ # The factory cannot set the created_at directly, so we force it after creation
257+ p1_d1 = factories .UserDocumentAccessFactory (user = pierre_1 , document = document_1 )
258+ p1_d1 .created_at = last_week
259+ p1_d1 .save ()
260+
261+ p2_d2 = factories .UserDocumentAccessFactory (user = pierre_2 , document = document_2 )
262+ p2_d2 .created_at = last_month
263+ p2_d2 .save ()
264+
265+ response = client .get ("/api/v1.0/users/?q=Pierre" )
266+ assert response .status_code == 200
267+ user_ids = [user ["email" ] for user in response .json ()]
268+
269+ assert user_ids == [
270+ str (pierre_1 .email ),
271+ str (pierre_2 .email ),
272+ str (pierre_4 .email ),
273+ ]
274+
275+
204276def test_api_users_list_limit (settings ):
205277 """
206278 Authenticated users should be able to list users and the number of results
207- should be limited to 10 .
279+ should be limited to API_USERS_LIST_LIMIT (by default 5) .
208280 """
209- user = factories .UserFactory ()
281+ user = factories .UserFactory (email = "user@example.com" )
210282
211283 client = APIClient ()
212284 client .force_login (user )
@@ -309,28 +381,16 @@ def test_api_users_list_query_email_exclude_doc_user():
309381
310382def test_api_users_list_query_short_queries ():
311383 """
312- Queries shorter than 5 characters should return an empty result set .
384+ If API_USERS_SEARCH_QUERY_MIN_LENGTH is not set, the default minimum length should be 3 .
313385 """
314386 user = factories .UserFactory (email = "paul@example.com" , full_name = "Paul" )
315387 client = APIClient ()
316388 client .force_login (user )
317389
318- factories .UserFactory (email = "john.doe@example.com" )
319- factories .UserFactory (email = "john.lennon@example.com" )
320-
321- response = client .get ("/api/v1.0/users/?q=jo" )
322- assert response .status_code == 400
323- assert response .json () == {
324- "q" : ["Ensure this value has at least 5 characters (it has 2)." ]
325- }
326-
327- response = client .get ("/api/v1.0/users/?q=john" )
328- assert response .status_code == 400
329- assert response .json () == {
330- "q" : ["Ensure this value has at least 5 characters (it has 4)." ]
331- }
390+ factories .UserFactory (email = "john.doe@example.com" , full_name = "John Doe" )
391+ factories .UserFactory (email = "john.lennon@example.com" , full_name = "John Lennon" )
332392
333- response = client .get ("/api/v1.0/users/?q=john. " )
393+ response = client .get ("/api/v1.0/users/?q=joh " )
334394 assert response .status_code == 200
335395 assert len (response .json ()) == 2
336396
@@ -356,7 +416,7 @@ def test_api_users_list_query_long_queries():
356416
357417def test_api_users_list_query_inactive ():
358418 """Inactive users should not be listed."""
359- user = factories .UserFactory ()
419+ user = factories .UserFactory (email = "user@example.com" )
360420 client = APIClient ()
361421 client .force_login (user )
362422
0 commit comments