From 9b591c3f1ba36f8aabee57d7ce46457acbb20794 Mon Sep 17 00:00:00 2001 From: rr- Date: Thu, 5 May 2016 13:46:57 +0200 Subject: [PATCH] server/posts: remember source for URL content --- server/szurubooru/api/post_api.py | 4 ++ .../tests/api/test_post_creating.py | 67 ++++++++++++++++++- .../tests/api/test_post_updating.py | 55 ++++++++++++++- 3 files changed, 124 insertions(+), 2 deletions(-) diff --git a/server/szurubooru/api/post_api.py b/server/szurubooru/api/post_api.py index 6200d706..ed049f36 100644 --- a/server/szurubooru/api/post_api.py +++ b/server/szurubooru/api/post_api.py @@ -9,6 +9,8 @@ class PostListApi(BaseApi): tag_names = ctx.get_param_as_list('tags', required=True) safety = ctx.get_param_as_string('safety', required=True) source = ctx.get_param_as_string('source', required=False, default=None) + if ctx.has_param('contentUrl') and not source: + source = ctx.get_param_as_string('contentUrl') relations = ctx.get_param_as_list('relations', required=False) or [] notes = ctx.get_param_as_list('notes', required=False) or [] flags = ctx.get_param_as_list('flags', required=False) or [] @@ -47,6 +49,8 @@ class PostDetailApi(BaseApi): if ctx.has_param('source'): auth.verify_privilege(ctx.user, 'posts:edit:source') posts.update_post_source(post, ctx.get_param_as_string('source')) + elif ctx.has_param('contentUrl'): + posts.update_post_source(post, ctx.get_param_as_string('contentUrl')) if ctx.has_param('relations'): auth.verify_privilege(ctx.user, 'posts:edit:relations') posts.update_post_relations(post, ctx.get_param_as_list('relations')) diff --git a/server/szurubooru/tests/api/test_post_creating.py b/server/szurubooru/tests/api/test_post_creating.py index 54e9a491..c60043c9 100644 --- a/server/szurubooru/tests/api/test_post_creating.py +++ b/server/szurubooru/tests/api/test_post_creating.py @@ -3,7 +3,7 @@ import os import unittest.mock import pytest from szurubooru import api, db, errors -from szurubooru.func import posts, tags, snapshots +from szurubooru.func import posts, tags, snapshots, net @pytest.fixture(autouse=True) def inject_config(config_injector): @@ -105,6 +105,71 @@ def test_creating_full_posts(context_factory, post_factory, user_factory): tags.export_to_json.assert_called_once_with() snapshots.save_entity_creation.assert_called_once_with(post, auth_user) +def test_creating_from_url_saves_source( + config_injector, context_factory, post_factory, user_factory): + auth_user = user_factory(rank='regular_user') + post = post_factory() + db.session.add(post) + db.session.flush() + + with unittest.mock.patch('szurubooru.func.net.download'), \ + unittest.mock.patch('szurubooru.func.tags.export_to_json'), \ + unittest.mock.patch('szurubooru.func.snapshots.save_entity_creation'), \ + unittest.mock.patch('szurubooru.func.posts.serialize_post_with_details'), \ + unittest.mock.patch('szurubooru.func.posts.create_post'), \ + unittest.mock.patch('szurubooru.func.posts.update_post_source'): + config_injector({ + 'ranks': ['anonymous', 'regular_user'], + 'privileges': {'posts:create': 'regular_user'}, + }) + net.download.return_value = b'content' + posts.create_post.return_value = post + api.PostListApi().post( + context_factory( + input={ + 'safety': 'safe', + 'tags': ['tag1', 'tag2'], + 'contentUrl': 'example.com', + }, + user=auth_user)) + net.download.assert_called_once_with('example.com') + posts.create_post.assert_called_once_with( + b'content', ['tag1', 'tag2'], auth_user) + posts.update_post_source.assert_called_once_with(post, 'example.com') + +def test_creating_from_url_with_source_specified( + config_injector, context_factory, post_factory, user_factory): + auth_user = user_factory(rank='regular_user') + post = post_factory() + db.session.add(post) + db.session.flush() + + with unittest.mock.patch('szurubooru.func.net.download'), \ + unittest.mock.patch('szurubooru.func.tags.export_to_json'), \ + unittest.mock.patch('szurubooru.func.snapshots.save_entity_creation'), \ + unittest.mock.patch('szurubooru.func.posts.serialize_post_with_details'), \ + unittest.mock.patch('szurubooru.func.posts.create_post'), \ + unittest.mock.patch('szurubooru.func.posts.update_post_source'): + config_injector({ + 'ranks': ['anonymous', 'regular_user'], + 'privileges': {'posts:create': 'regular_user'}, + }) + net.download.return_value = b'content' + posts.create_post.return_value = post + api.PostListApi().post( + context_factory( + input={ + 'safety': 'safe', + 'tags': ['tag1', 'tag2'], + 'contentUrl': 'example.com', + 'source': 'example2.com', + }, + user=auth_user)) + net.download.assert_called_once_with('example.com') + posts.create_post.assert_called_once_with( + b'content', ['tag1', 'tag2'], auth_user) + posts.update_post_source.assert_called_once_with(post, 'example2.com') + @pytest.mark.parametrize('field', ['tags', 'safety']) def test_trying_to_omit_mandatory_field(context_factory, user_factory, field): input = { diff --git a/server/szurubooru/tests/api/test_post_updating.py b/server/szurubooru/tests/api/test_post_updating.py index 7498f531..b241604e 100644 --- a/server/szurubooru/tests/api/test_post_updating.py +++ b/server/szurubooru/tests/api/test_post_updating.py @@ -3,7 +3,7 @@ import os import unittest.mock import pytest from szurubooru import api, db, errors -from szurubooru.func import posts, tags, snapshots +from szurubooru.func import posts, tags, snapshots, net def test_post_updating( config_injector, context_factory, post_factory, user_factory, fake_datetime): @@ -73,6 +73,59 @@ def test_post_updating( snapshots.save_entity_modification.assert_called_once_with(post, auth_user) assert post.last_edit_time == datetime.datetime(1997, 1, 1) +def test_uploading_from_url_saves_source( + config_injector, context_factory, post_factory, user_factory): + config_injector({ + 'ranks': ['anonymous', 'regular_user'], + 'privileges': {'posts:edit:content': 'regular_user'}, + }) + post = post_factory() + db.session.add(post) + db.session.flush() + with unittest.mock.patch('szurubooru.func.net.download'), \ + unittest.mock.patch('szurubooru.func.tags.export_to_json'), \ + unittest.mock.patch('szurubooru.func.snapshots.save_entity_modification'), \ + unittest.mock.patch('szurubooru.func.posts.serialize_post_with_details'), \ + unittest.mock.patch('szurubooru.func.posts.update_post_content'), \ + unittest.mock.patch('szurubooru.func.posts.update_post_source'): + net.download.return_value = b'content' + api.PostDetailApi().put( + context_factory( + input={'contentUrl': 'example.com'}, + user=user_factory(rank='regular_user')), + post.post_id) + net.download.assert_called_once_with('example.com') + posts.update_post_content.assert_called_once_with(post, b'content') + posts.update_post_source.assert_called_once_with(post, 'example.com') + +def test_uploading_from_url_with_source_specified( + config_injector, context_factory, post_factory, user_factory): + config_injector({ + 'ranks': ['anonymous', 'regular_user'], + 'privileges': { + 'posts:edit:content': 'regular_user', + 'posts:edit:source': 'regular_user', + }, + }) + post = post_factory() + db.session.add(post) + db.session.flush() + with unittest.mock.patch('szurubooru.func.net.download'), \ + unittest.mock.patch('szurubooru.func.tags.export_to_json'), \ + unittest.mock.patch('szurubooru.func.snapshots.save_entity_modification'), \ + unittest.mock.patch('szurubooru.func.posts.serialize_post_with_details'), \ + unittest.mock.patch('szurubooru.func.posts.update_post_content'), \ + unittest.mock.patch('szurubooru.func.posts.update_post_source'): + net.download.return_value = b'content' + api.PostDetailApi().put( + context_factory( + input={'contentUrl': 'example.com', 'source': 'example2.com'}, + user=user_factory(rank='regular_user')), + post.post_id) + net.download.assert_called_once_with('example.com') + posts.update_post_content.assert_called_once_with(post, b'content') + posts.update_post_source.assert_called_once_with(post, 'example2.com') + def test_trying_to_update_non_existing(context_factory, user_factory): with pytest.raises(posts.PostNotFoundError): api.PostDetailApi().put(