Skip to content
Snippets Groups Projects
Commit 1954d3da authored by Bastien Abadie's avatar Bastien Abadie
Browse files

Merge branch 'assert-exact-skip' into 'master'

Add skip option to assertExactQueries and test element deletion

See merge request !1074
parents e77eb717 faa710bc
No related branches found
No related tags found
1 merge request!1074Add skip option to assertExactQueries and test element deletion
......@@ -42,7 +42,13 @@ class TestDestroyElements(FixtureAPITestCase):
name='Castle story'
)
self.assertEqual(self.corpus.elements.filter(id=castle_story.id).exists(), True)
with self.assertNumQueries(13):
with self.assertExactQueries(
'element_deletion.sql',
params={
'id': str(castle_story.id),
'corpus_id': str(self.corpus.id),
'user_id': self.user.id
}, skip=1):
response = self.client.delete(reverse('api:element-retrieve', kwargs={'pk': str(castle_story.id)}))
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
self.assertEqual(self.corpus.elements.filter(id=castle_story.id).exists(), False)
......
......@@ -20,10 +20,11 @@ class _AssertExactQueriesContext(CaptureQueriesContext):
The implementation is inspired by assertNumQueries's own implementation.
"""
def __init__(self, test_case, path, params, connection):
def __init__(self, test_case, path, params, connection, skip=0):
self.test_case = test_case
self.path = settings.SQL_VALIDATION_DIR / Path(path)
self.params = params
self.skip = skip
super().__init__(connection)
def __exit__(self, exc_type, exc_value, traceback):
......@@ -34,7 +35,7 @@ class _AssertExactQueriesContext(CaptureQueriesContext):
# Django's logged queries are each on a single line without semicolons
# so we lint them and assemble them to build a more readable diff for humans.
actual_sql = sqlparse.format(
';'.join(query['sql'] for query in self),
';'.join(query['sql'] for query in self[self.skip:]),
reindent=True,
use_space_around_operators=True,
indent_width=4,
......@@ -93,6 +94,7 @@ class FixtureMixin(object):
*args,
using: str = DEFAULT_DB_ALIAS,
params: Union[Iterable, Mapping[str, Any]] = [],
skip: int = 0,
**kwargs) -> Optional[_AssertExactQueriesContext]:
"""
Assert that a function call causes exactly the SQL queries specified in a given file.
......@@ -118,8 +120,16 @@ class FixtureMixin(object):
To make first runs easier, when the expect SQL file does not exist, assertExactQueries will try to write
the current SQL queries to it and warn you using an `AssertionError`. Make sure to check this new SQL file
as subsequent runs of unit tests will no longer fail.
In API endpoint tests, some queries do not really need to be tested and are annoying to mock, such as
session queries that use the `django_session` table and are the first query to be made when you call an endpoint
using the test client. You can skip those queries and go straight to the point using `skip`.
This will skip the first query it finds:
>>> with self.assertExactQueries('my_endpoint.sql', skip=1):
... self.client.get(reverse('api:my-endpoint'))
"""
context = _AssertExactQueriesContext(self, path, params, connections[using])
context = _AssertExactQueriesContext(self, path, params, connections[using], skip=skip)
if func is None:
return context
......
SELECT "users_user"."id",
"users_user"."password",
"users_user"."last_login",
"users_user"."email",
"users_user"."transkribus_email",
"users_user"."is_active",
"users_user"."is_internal",
"users_user"."is_admin",
"users_user"."verified_email"
FROM "users_user"
WHERE "users_user"."id" = {user_id}
LIMIT 21;
SELECT "documents_element"."id",
"documents_element"."corpus_id",
"documents_corpus"."created",
"documents_corpus"."updated",
"documents_corpus"."id",
"documents_corpus"."name",
"documents_corpus"."description",
"documents_corpus"."repository_id",
"documents_corpus"."public"
FROM "documents_element"
INNER JOIN "documents_corpus" ON ("documents_element"."corpus_id" = "documents_corpus"."id")
WHERE ("documents_element"."corpus_id" IN
(SELECT DISTINCT U0."id"
FROM "documents_corpus" U0
LEFT OUTER JOIN "users_corpusright" U1 ON (U0."id" = U1."corpus_id")
WHERE (U0."public"
OR U1."user_id" = {user_id}))
AND "documents_element"."id" = '{id}'::uuid)
LIMIT 21;
SELECT "users_corpusright"."id",
"users_corpusright"."user_id",
"users_corpusright"."corpus_id",
"users_corpusright"."can_write",
"users_corpusright"."can_admin"
FROM "users_corpusright"
WHERE ("users_corpusright"."corpus_id" = '{corpus_id}'::uuid
AND "users_corpusright"."user_id" = {user_id})
LIMIT 21;
DELETE
FROM documents_transcriptionentity te
WHERE transcription_id IN
(SELECT t.id
FROM documents_transcription t
LEFT JOIN documents_elementpath elementpath USING (element_id)
WHERE t.element_id = '{id}'::uuid
OR elementpath.path && ARRAY['{id}'::uuid] ) ;
DELETE
FROM documents_transcription
WHERE element_id = '{id}'::uuid
OR element_id IN
(SELECT element_id
FROM documents_elementpath
WHERE path && ARRAY['{id}'::uuid] ) ;
DELETE
FROM documents_classification
WHERE element_id = '{id}'::uuid
OR element_id IN
(SELECT element_id
FROM documents_elementpath
WHERE path && ARRAY['{id}'::uuid] ) ;
DELETE
FROM documents_metadata
WHERE element_id = '{id}'::uuid
OR element_id IN
(SELECT element_id
FROM documents_elementpath
WHERE path && ARRAY['{id}'::uuid] ) ;
DELETE
FROM dataimport_dataimportelement
WHERE element_id = '{id}'::uuid
OR element_id IN
(SELECT element_id
FROM documents_elementpath
WHERE path && ARRAY['{id}'::uuid] ) ;
UPDATE dataimport_dataimport
SET element_id = NULL
WHERE element_id = '{id}'::uuid
OR element_id IN
(SELECT element_id
FROM documents_elementpath
WHERE path && ARRAY['{id}'::uuid] ) ;
DELETE
FROM documents_selection selection
WHERE element_id = '{id}'::uuid
OR element_id IN
(SELECT element_id
FROM documents_elementpath
WHERE path && ARRAY['{id}'::uuid] ) ;
WITH children_ids (id) AS
(DELETE
FROM documents_elementpath
WHERE element_id = '{id}'::uuid
OR path && ARRAY['{id}'::uuid] RETURNING element_id)
DELETE
FROM documents_element element USING children_ids
WHERE element.id = children_ids.id ;
DELETE
FROM "documents_element"
WHERE "documents_element"."id" = '{id}'::uuid
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment