From e2b0a6a5f250d86b1e5ddf9f211ae80c916c05a0 Mon Sep 17 00:00:00 2001 From: "Soblow (Opale) Xaselgio" <113846014+Soblow@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:53:24 +0100 Subject: [PATCH] Blocklist: Add test drafts and required elements for future blocklist-related tests --- .../tests/api/test_post_blocklist.py | 139 ++++++++++++++++++ server/szurubooru/tests/conftest.py | 14 ++ 2 files changed, 153 insertions(+) create mode 100644 server/szurubooru/tests/api/test_post_blocklist.py diff --git a/server/szurubooru/tests/api/test_post_blocklist.py b/server/szurubooru/tests/api/test_post_blocklist.py new file mode 100644 index 000000000..7c4cf9cdd --- /dev/null +++ b/server/szurubooru/tests/api/test_post_blocklist.py @@ -0,0 +1,139 @@ +from datetime import datetime +from unittest.mock import patch + +import pytest + +from szurubooru import api, db, errors, model +from szurubooru.func import posts + + +## TODO: Add following tests: +## - Retrieve posts without blocklist active for current registered user +## - Retrieve posts with blocklist active for current registered user +## - Retrieve posts without blocklist active for anonymous user +## - Retrieve posts with blocklist active for anonymous user +## - Creation of user with default blocklist (test that user_blocklist entries are properly added to db, with right infos) +## - Modification of user with/without blocklist changes +## - Retrieve posts with a query including a blocklisted tag (it should include results with the tag) +## - Behavior when creating user with default blocklist and tags from this list don't exist (blocklist entry shouldn't be added) +## - Test all small functions used across blocklist features + + +def test_blocklist(user_factory, post_factory, context_factory, config_injector, user_blocklist_factory, tag_factory): + """ + Test that user blocklist is applied on post retrieval + """ + tag1 = tag_factory(names=['tag1']) + tag2 = tag_factory(names=['tag2']) + tag3 = tag_factory(names=['tag3']) + post1 = post_factory(id=11, tags=[tag1, tag2]) + post2 = post_factory(id=12, tags=[tag1]) + post3 = post_factory(id=13, tags=[tag2]) + post4 = post_factory(id=14, tags=[tag3]) + post5 = post_factory(id=15) + user1 = user_factory(rank=model.User.RANK_REGULAR) + blocklist1 = user_blocklist_factory(tag=tag1, user=user1) + config_injector({ + "privileges": { + "posts:list": model.User.RANK_REGULAR, + } + }) + db.session.add_all([tag1, tag2, tag3, user1, blocklist1, post1, post2, post3, post4, post5]) + db.session.flush() + # We can't check that the posts we retrieve are the ones we want + with patch("szurubooru.func.posts.serialize_post"): + posts.serialize_post.side_effect = ( + lambda post, *_args, **_kwargs: "serialized post %d" % post.post_id + ) + result = api.post_api.get_posts( + context_factory( + params={"query": "", "offset": 0}, + user=user1, + ) + ) + assert result == { + "query": "", + "offset": 0, + "limit": 100, + "total": 3, + "results": ["serialized post 15", "serialized post 14", "serialized post 13"], + } + + +# def test_blocklist_no_anonymous(user_factory, post_factory, context_factory, config_injector, tag_factory): +# """ +# Test that default blocklist isn't applied on anonymous users on post retrieval if disabled in configuration +# """ +# tag1 = tag_factory(names=['tag1']) +# post1 = post_factory(id=21, tags=[tag1]) +# post2 = post_factory(id=22, tags=[tag1]) +# post3 = post_factory(id=23) +# user1 = user_factory(rank=model.User.RANK_ANONYMOUS) +# config_injector({ +# "default_tag_blocklist": "tag1", +# "default_tag_blocklist_for_anonymous": False, +# "privileges": { +# "posts:list": model.User.RANK_ANONYMOUS, +# } +# }) +# db.session.add_all([tag1, post1, post2, post3]) +# db.session.flush() +# with patch("szurubooru.func.posts.serialize_post"): +# posts.serialize_post.side_effect = ( +# lambda post, *_args, **_kwargs: "serialized post %d" % post.post_id +# ) +# result = api.post_api.get_posts( +# context_factory( +# params={"query": "", "offset": 0}, +# user=user1, +# ) +# ) +# assert result == { +# "query": "", +# "offset": 0, +# "limit": 100, +# "total": 3, +# "results": ["serialized post 23", "serialized post 22", "serialized post 21"], +# } + + +def test_blocklist_anonymous(user_factory, post_factory, context_factory, config_injector, tag_factory): + """ + Test that default blocklist is applied on anonymous users on post retrieval if enabled in configuration + """ + tag1 = tag_factory(names=['tag1']) + tag2 = tag_factory(names=['tag2']) + tag3 = tag_factory(names=['tag3']) + post1 = post_factory(id=31, tags=[tag1, tag2]) + post2 = post_factory(id=32, tags=[tag1]) + post3 = post_factory(id=33, tags=[tag2]) + post4 = post_factory(id=34, tags=[tag3]) + post5 = post_factory(id=35) + config_injector({ + "default_tag_blocklist": "tag3", + "default_tag_blocklist_for_anonymous": True, + "privileges": { + "posts:list": model.User.RANK_ANONYMOUS, + } + }) + db.session.add_all([tag1, tag2, tag3, post1, post2, post3, post4, post5]) + db.session.flush() + with patch("szurubooru.func.posts.serialize_post"): + posts.serialize_post.side_effect = ( + lambda post, *_args, **_kwargs: "serialized post %d" % post.post_id + ) + result = api.post_api.get_posts( + context_factory( + params={"query": "", "offset": 0}, + user=user_factory(rank=model.User.RANK_ANONYMOUS), + ) + ) + assert result == { + "query": "", + "offset": 0, + "limit": 100, + "total": 4, + "results": ["serialized post 35", "serialized post 33", "serialized post 32", "serialized post 31"], + } + +## TODO: Test when we add blocklist items to the query diff --git a/server/szurubooru/tests/conftest.py b/server/szurubooru/tests/conftest.py index d5be0a69c..e2780ce1d 100644 --- a/server/szurubooru/tests/conftest.py +++ b/server/szurubooru/tests/conftest.py @@ -136,6 +136,20 @@ def factory( return factory +@pytest.fixture +def user_blocklist_factory(user_factory, tag_factory): + def factory(tag=None, user=None): + if user is None: + user = user_factory() + if tag is None: + tag = tag_factory() + return model.UserTagBlocklist( + tag=tag, user=user + ) + + return factory + + @pytest.fixture def tag_category_factory(): def factory(name=None, color="dummy", order=1, default=False):