From 4d11bd2be540d5f0e2eca80bc1f3468b73cd8219 Mon Sep 17 00:00:00 2001
From: Valentin Rigal <rigal@teklia.com>
Date: Tue, 15 Dec 2020 12:25:40 +0100
Subject: [PATCH] Add tests

---
 arkindex/project/tests/test_acl_mixin.py      | 62 +++++++++++++++++--
 .../sql_validation/corpus_rights_filter.sql   |  3 +-
 .../corpus_rights_filter_public.sql           | 21 ++++---
 3 files changed, 68 insertions(+), 18 deletions(-)

diff --git a/arkindex/project/tests/test_acl_mixin.py b/arkindex/project/tests/test_acl_mixin.py
index 45af24dfcf..d63d47b98e 100644
--- a/arkindex/project/tests/test_acl_mixin.py
+++ b/arkindex/project/tests/test_acl_mixin.py
@@ -1,3 +1,6 @@
+import uuid
+
+from django.contrib.auth.models import AnonymousUser
 from django.contrib.contenttypes.models import ContentType
 
 from arkindex.dataimport.models import Repository, RepositoryType
@@ -35,8 +38,8 @@ class TestACLMixin(FixtureTestCase):
         cls.group2 = Group.objects.create(name='Group2')
 
         cls.repo1 = Repository.objects.create(type=RepositoryType.Worker, url='http://repo1')
-        cls.corpus1 = Corpus.objects.create(name="Corpus1")
-        cls.corpus2 = Corpus.objects.create(name="Corpus2")
+        cls.corpus1 = Corpus.objects.create(name="Corpus1", id=uuid.UUID('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'))
+        cls.corpus2 = Corpus.objects.create(name="Corpus2", id=uuid.UUID('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'))
 
         Right.objects.bulk_create([
             Right(user=cls.user1, content_object=cls.group1, level=100),
@@ -120,7 +123,7 @@ class TestACLMixin(FixtureTestCase):
             self.assertEqual(admin_access, access_check)
 
     def test_corpus_acl_mixin_readable(self):
-        # Corpora with the public attribute are accessible by any user
+        # Corpora with the public attribute are accessible by any user with guest rights
         corpus_acl_mixin = NewCorpusACLMixin(self.user1)
         params = {
             'user_id': self.user1.id,
@@ -131,13 +134,23 @@ class TestACLMixin(FixtureTestCase):
         }
         with self.assertExactQueries('corpus_rights_filter_public.sql', params=params):
             corpora = list(corpus_acl_mixin.readable_corpora)
-        self.assertCountEqual(corpora, [self.corpus, self.corpus1])
+        self.assertCountEqual(
+            [(corpus, corpus.max_level) for corpus in corpora],
+            [
+                (self.corpus1, 75),
+                # Defaults to guest role
+                (self.corpus, Role.Guest.value),
+            ]
+        )
 
     def test_corpus_acl_mixin_writable(self):
         corpus_acl_mixin = NewCorpusACLMixin(self.user1)
         with self.assertNumQueries(1):
             corpora = list(corpus_acl_mixin.writable_corpora)
-        self.assertCountEqual(corpora, [self.corpus1])
+        self.assertCountEqual(
+            [(corpus, corpus.max_level) for corpus in corpora],
+            [(self.corpus1, 75)]
+        )
 
     def test_repo_acl_mixin_has_read_access(self):
         repo_acl_mixin = RepositoryACLMixin(self.user2)
@@ -170,10 +183,47 @@ class TestACLMixin(FixtureTestCase):
         repo_acl_mixin = RepositoryACLMixin(self.user2)
         with self.assertNumQueries(1):
             repos = list(repo_acl_mixin.readable_repositories)
-        self.assertCountEqual(repos, [self.repo1])
+        self.assertCountEqual(
+            [(repo, repo.max_level) for repo in repos],
+            [(self.repo1, 10)]
+        )
 
     def test_repo_acl_mixin_executable(self):
         repo_acl_mixin = RepositoryACLMixin(self.user2)
         with self.assertNumQueries(1):
             repos = list(repo_acl_mixin.executable_repositories)
         self.assertEqual(repos, [])
+
+    def test_corpus_readable_orderable(self):
+        # Assert corpora retrieved via the mixin are still orderable
+        corpus_acl_mixin = NewCorpusACLMixin(self.user3, order_by_fields=('name',))
+        with self.assertNumQueries(1):
+            corpora = list(corpus_acl_mixin.readable_corpora)
+        self.assertListEqual(
+            [(c.name, str(c.id)[:4], c.max_level) for c in corpora],
+            [
+                ('Corpus1', 'bbbb', 100),
+                ('Corpus2', 'aaaa', 75),
+                ('Unit Tests', str(self.corpus.id)[:4], Role.Guest.value)
+            ]
+        )
+
+    def test_super_admin_readable_corpora(self):
+        # A super admin should retrieve all existing corpora with Admin rigths
+        corpus_acl_mixin = NewCorpusACLMixin(self.superuser)
+        with self.assertNumQueries(1):
+            corpora = list(corpus_acl_mixin.readable_corpora)
+        self.assertCountEqual(
+            [(c.name, c.max_level) for c in corpora],
+            [(c.name, Role.Admin.value) for c in Corpus.objects.all()]
+        )
+
+    def test_anonymous_user_readable_corpora(self):
+        # An anonymous user should have guest access to any public corpora
+        corpus_acl_mixin = NewCorpusACLMixin(AnonymousUser())
+        with self.assertNumQueries(1):
+            corpora = list(corpus_acl_mixin.readable_corpora)
+        self.assertCountEqual(
+            [(c.name, c.max_level) for c in corpora],
+            [(c.name, Role.Guest.value) for c in Corpus.objects.filter(public=True)]
+        )
diff --git a/arkindex/sql_validation/corpus_rights_filter.sql b/arkindex/sql_validation/corpus_rights_filter.sql
index b0b5f6ed6a..5f58b9c464 100644
--- a/arkindex/sql_validation/corpus_rights_filter.sql
+++ b/arkindex/sql_validation/corpus_rights_filter.sql
@@ -15,5 +15,4 @@ LEFT OUTER JOIN "users_right" T5 ON ("users_group"."id" = T5."content_id"
 WHERE (("users_right"."user_id" = {user_id}
         OR T5."user_id" = {user_id})
        AND LEAST("users_right"."level", T5."level") >= {level})
-ORDER BY "documents_corpus"."id" ASC,
-         "max_level" DESC
+ORDER BY "documents_corpus"."id" ASC
diff --git a/arkindex/sql_validation/corpus_rights_filter_public.sql b/arkindex/sql_validation/corpus_rights_filter_public.sql
index 5d10d04b52..844eb63468 100644
--- a/arkindex/sql_validation/corpus_rights_filter_public.sql
+++ b/arkindex/sql_validation/corpus_rights_filter_public.sql
@@ -1,11 +1,11 @@
-    (SELECT "documents_corpus"."created",
-            "documents_corpus"."updated",
-            "documents_corpus"."id",
-            "documents_corpus"."name",
-            "documents_corpus"."description",
-            "documents_corpus"."repository_id",
-            "documents_corpus"."public",
-            LEAST("users_right"."level", T5."level") AS "max_level"
+(SELECT DISTINCT ON ("documents_corpus"."id") "documents_corpus"."created",
+                        "documents_corpus"."updated",
+                        "documents_corpus"."id",
+                        "documents_corpus"."name",
+                        "documents_corpus"."description",
+                        "documents_corpus"."repository_id",
+                        "documents_corpus"."public",
+                        LEAST("users_right"."level", T5."level") AS "max_level"
      FROM "documents_corpus"
      INNER JOIN "users_right" ON ("documents_corpus"."id" = "users_right"."content_id"
                                   AND ("users_right"."content_type_id" = {corpus_type_id}))
@@ -14,7 +14,8 @@
                                           AND (T5."content_type_id" = {group_type_id}))
      WHERE (("users_right"."user_id" = {user_id}
              OR T5."user_id" = {user_id})
-            AND LEAST("users_right"."level", T5."level") >= {level}))
+            AND LEAST("users_right"."level", T5."level") >= {level})
+     ORDER BY "documents_corpus"."id" ASC, "max_level" DESC)
 UNION
     (SELECT "documents_corpus"."created",
             "documents_corpus"."updated",
@@ -26,4 +27,4 @@ UNION
             10 AS "max_level"
      FROM "documents_corpus"
      WHERE "documents_corpus"."public")
-ORDER BY (3) ASC, (8) DESC
+ORDER BY (3) ASC
-- 
GitLab