diff --git a/openlobby/core/api/mutations.py b/openlobby/core/api/mutations.py index 4c92f8ec6cdba1dfc792a5935ff0c2af279f7726..fa4e3a276d46e8b22e7b17423c2f2a8671e2108f 100644 --- a/openlobby/core/api/mutations.py +++ b/openlobby/core/api/mutations.py @@ -123,10 +123,13 @@ class CreateReport(relay.ClientIDMutation): raise Exception("User must be logged in to perform this mutation.") author = info.context.user + now = arrow.utcnow().datetime report = Report.objects.create( author=author, date=input.get("date"), + published=now, + edited=now, title=strip_all_tags(input.get("title", "")), body=strip_all_tags(input.get("body", "")), received_benefit=strip_all_tags(input.get("received_benefit", "")), @@ -178,7 +181,11 @@ class UpdateReport(relay.ClientIDMutation): # TODO updating published report older than like a hour should create # new revision in history of report - report.published = arrow.utcnow().datetime + report.edited = arrow.utcnow().datetime + + if is_draft or report.is_draft: + report.published = report.edited + report.date = input.get("date") report.title = strip_all_tags(input.get("title", "")) report.body = strip_all_tags(input.get("body", "")) diff --git a/openlobby/core/api/types.py b/openlobby/core/api/types.py index 8d56829470f32fb7acc8eb75d898bdc9e18e029e..c4932b542b23db4c10d21fa7be5aae84ad1f20a9 100644 --- a/openlobby/core/api/types.py +++ b/openlobby/core/api/types.py @@ -29,6 +29,7 @@ class Report(graphene.ObjectType): other_participants = graphene.String() is_draft = graphene.Boolean() extra = JSONString() + edited = graphene.String() class Meta: interfaces = (relay.Node,) @@ -48,6 +49,7 @@ class Report(graphene.ObjectType): other_participants=get_higlighted(report, "other_participants"), is_draft=report.is_draft, extra=report.extra, + edited=report.edited, ) @classmethod @@ -65,6 +67,7 @@ class Report(graphene.ObjectType): other_participants=report.other_participants, is_draft=report.is_draft, extra=report.extra, + edited=report.edited, ) @classmethod diff --git a/openlobby/core/documents.py b/openlobby/core/documents.py index a5ef151bb69f888ac10ddf675819300e038bd35b..113c07384553aa74e7b5e5d7c31350b33e90743b 100644 --- a/openlobby/core/documents.py +++ b/openlobby/core/documents.py @@ -19,6 +19,7 @@ class ReportDoc(DocType): other_participants = fields.TextField(analyzer=settings.ES_TEXT_ANALYZER) # there is no support for JSONField now, so we serialize it to keyword extra_serialized = fields.KeywordField() + superseded_by = fields.IntegerField() def prepare_extra_serialized(self, instance): return json.dumps(instance.extra) @@ -30,4 +31,4 @@ class ReportDoc(DocType): class Meta: model = Report - fields = ["date", "published", "is_draft"] + fields = ["date", "published", "is_draft", "edited"] diff --git a/openlobby/core/migrations/0012_auto_20181020_1545.py b/openlobby/core/migrations/0012_auto_20181020_1545.py new file mode 100644 index 0000000000000000000000000000000000000000..66b84313b3362dad0bf5911c8cdbda22cccf28cc --- /dev/null +++ b/openlobby/core/migrations/0012_auto_20181020_1545.py @@ -0,0 +1,32 @@ +# Generated by Django 2.1.2 on 2018-10-20 13:45 + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import openlobby.core.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0011_report_is_draft'), + ] + + operations = [ + migrations.AlterModelManagers( + name='user', + managers=[ + ('objects', openlobby.core.models.CustomUserManager()), + ], + ), + migrations.AddField( + model_name='report', + name='edited', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AddField( + model_name='report', + name='superseded_by', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='core.Report'), + ), + ] diff --git a/openlobby/core/models.py b/openlobby/core/models.py index 127b624ac57311d6206bcf4392b7e2cbeb5fbcf6..7f528222209bf9a80127351d457a595d8b02830d 100644 --- a/openlobby/core/models.py +++ b/openlobby/core/models.py @@ -100,6 +100,8 @@ class Report(models.Model): other_participants = models.TextField(null=True, blank=True) extra = JSONField(null=True, blank=True) is_draft = models.BooleanField(default=False) + superseded_by = models.ForeignKey("self", on_delete=models.CASCADE, null=True) + edited = models.DateTimeField(default=timezone.now) def save(self, *args, **kwargs): super().save(*args, **kwargs) diff --git a/tests/dummy.py b/tests/dummy.py index 3cbe43ddf384bafd6b6d0608e3643decc34c6b0a..d17511334fc17fe26ada0f2b61fb5ecf198aea5a 100644 --- a/tests/dummy.py +++ b/tests/dummy.py @@ -33,6 +33,7 @@ reports = [ "id": 1, "date": arrow.get(2018, 1, 1).datetime, "published": arrow.get(2018, 1, 2).datetime, + "edited": arrow.get(2018, 1, 2, 3).datetime, "title": "The Fellowship of the Ring", "body": "Long story short: we got the Ring!", "received_benefit": "The Ring", @@ -44,6 +45,7 @@ reports = [ "id": 2, "date": arrow.get(2018, 1, 3).datetime, "published": arrow.get(2018, 1, 4).datetime, + "edited": arrow.get(2018, 1, 4, 5).datetime, "title": "The Two Towers", "body": "Another long story.", "received_benefit": "Mithrill Jacket", @@ -56,6 +58,7 @@ reports = [ "id": 3, "date": arrow.get(2018, 1, 5).datetime, "published": arrow.get(2018, 1, 6).datetime, + "edited": arrow.get(2018, 1, 6, 7).datetime, "title": "The Return of the King", "body": "Aragorn is the King. And we have lost the Ring.", "received_benefit": "", @@ -67,6 +70,7 @@ reports = [ "id": 4, "date": arrow.get(2018, 1, 7).datetime, "published": arrow.get(2018, 1, 8).datetime, + "edited": arrow.get(2018, 1, 8, 9).datetime, "title": "The Silmarillion", "body": "Not finished yet.", "received_benefit": "", @@ -79,6 +83,7 @@ reports = [ "id": 5, "date": arrow.get(2018, 1, 9).datetime, "published": arrow.get(2018, 1, 10).datetime, + "edited": arrow.get(2018, 1, 10, 11).datetime, "title": "The Hobbit", "body": "Work in progress...", "received_benefit": "", diff --git a/tests/mutations/snapshots/snap_test_create_report.py b/tests/mutations/snapshots/snap_test_create_report.py index 312d5c1a9bee0d160dabbad5198d2c627e4d2861..e8f730efe859339dd7f90da33f81ca369e1b71eb 100644 --- a/tests/mutations/snapshots/snap_test_create_report.py +++ b/tests/mutations/snapshots/snap_test_create_report.py @@ -31,6 +31,7 @@ snapshots["test_full_report 1"] = { }, "body": "I visited Tesla factory and talked with Elon Musk.", "date": "2018-01-01 00:00:00+00:00", + "edited": "__STRIPPED__", "extra": None, "id": "__STRIPPED__", "isDraft": False, @@ -58,6 +59,7 @@ snapshots["test_is_draft 1"] = { }, "body": "Niel deGrasse Tyson just visited me...", "date": "2018-01-03 00:00:00+00:00", + "edited": "__STRIPPED__", "extra": None, "id": "__STRIPPED__", "isDraft": True, diff --git a/tests/mutations/snapshots/snap_test_update_report.py b/tests/mutations/snapshots/snap_test_update_report.py index cbc6339801aa646d2293b3d0919294b811c167ae..77a4e76e6ecdf5813d397744c5159d9fed62e756 100644 --- a/tests/mutations/snapshots/snap_test_update_report.py +++ b/tests/mutations/snapshots/snap_test_update_report.py @@ -64,13 +64,14 @@ snapshots["test_update_draft_with_draft 1"] = { }, "body": "I visited Tesla factory and talked with Elon Musk.", "date": "2018-03-03 00:00:00+00:00", + "edited": "2018-03-08 12:00:00+00:00", "extra": None, "id": "UmVwb3J0OjE=", "isDraft": True, "otherParticipants": "Elon Musk", "ourParticipants": "me", "providedBenefit": "nothing", - "published": "2018-03-08 00:00:00+00:00", + "published": "2018-03-08 12:00:00+00:00", "receivedBenefit": "Tesla Model S", "title": "Free Tesla", } @@ -91,13 +92,14 @@ snapshots["test_update_draft_with_published 1"] = { }, "body": "I visited Tesla factory and talked with Elon Musk.", "date": "2018-03-03 00:00:00+00:00", + "edited": "2018-03-08 12:00:00+00:00", "extra": None, "id": "UmVwb3J0OjE=", "isDraft": False, "otherParticipants": "Elon Musk", "ourParticipants": "me", "providedBenefit": "nothing", - "published": "2018-03-08 00:00:00+00:00", + "published": "2018-03-08 12:00:00+00:00", "receivedBenefit": "Tesla Model S", "title": "Free Tesla", } @@ -118,13 +120,14 @@ snapshots["test_update_published_with_published 1"] = { }, "body": "I visited Tesla factory and talked with Elon Musk.", "date": "2018-03-03 00:00:00+00:00", + "edited": "2018-03-08 12:00:00+00:00", "extra": None, "id": "UmVwb3J0OjE=", "isDraft": False, "otherParticipants": "Elon Musk", "ourParticipants": "me", "providedBenefit": "nothing", - "published": "2018-03-08 00:00:00+00:00", + "published": "2018-01-02 00:00:00+00:00", "receivedBenefit": "Tesla Model S", "title": "Free Tesla", } @@ -145,13 +148,14 @@ snapshots["test_input_sanitization 1"] = { }, "body": "some link in body", "date": "2018-03-03 00:00:00+00:00", + "edited": "2018-03-08 12:00:00+00:00", "extra": None, "id": "UmVwb3J0OjE=", "isDraft": False, "otherParticipants": "you!", "ourParticipants": "me, myself", "providedBenefit": "tea", - "published": "2018-03-08 00:00:00+00:00", + "published": "2018-01-02 00:00:00+00:00", "receivedBenefit": "coffee", "title": "No tags", } diff --git a/tests/mutations/test_create_report.py b/tests/mutations/test_create_report.py index 32ccbf90394a1c05e66806d422645a046dd2b13e..d59a4b65024580031a2d6b4f0faf479d0aca0578 100644 --- a/tests/mutations/test_create_report.py +++ b/tests/mutations/test_create_report.py @@ -26,6 +26,7 @@ mutation createReport ($input: CreateReportInput!) { otherParticipants isDraft extra + edited author { id firstName @@ -75,6 +76,7 @@ def test_full_report(client, snapshot): response = call_api(client, query, input, "wolf") published = strip_value(response, "data", "createReport", "report", "published") + edited = strip_value(response, "data", "createReport", "report", "edited") id = strip_value(response, "data", "createReport", "report", "id") assert re.match(r"\w+", id) @@ -85,6 +87,7 @@ def test_full_report(client, snapshot): assert report.author_id == 1 assert report.date == date.datetime assert report.published == arrow.get(published).datetime + assert report.edited == arrow.get(edited).datetime assert report.title == title assert report.body == body assert report.received_benefit == received_benefit @@ -139,6 +142,7 @@ def test_is_draft(client, snapshot): response = call_api(client, query, input, "wolf") published = strip_value(response, "data", "createReport", "report", "published") + edited = strip_value(response, "data", "createReport", "report", "edited") id = strip_value(response, "data", "createReport", "report", "id") assert re.match(r"\w+", id) @@ -149,6 +153,7 @@ def test_is_draft(client, snapshot): assert report.author_id == 1 assert report.date == date.datetime assert report.published == arrow.get(published).datetime + assert report.edited == arrow.get(edited).datetime assert report.title == title assert report.body == body assert report.received_benefit == received_benefit diff --git a/tests/mutations/test_update_report.py b/tests/mutations/test_update_report.py index 3486c5ba59aed8df1d666ed701447342870a09fc..d68f23892f372b12ce7098bdebf30b53f32a781d 100644 --- a/tests/mutations/test_update_report.py +++ b/tests/mutations/test_update_report.py @@ -27,6 +27,7 @@ mutation updateReport ($input: UpdateReportInput!) { otherParticipants isDraft extra + edited author { id firstName @@ -39,7 +40,8 @@ mutation updateReport ($input: UpdateReportInput!) { } """ -published = arrow.get(2018, 3, 8) +published = arrow.get(2018, 1, 2) +edited = arrow.get(2018, 3, 8, 12) date = arrow.get(2018, 3, 3) title = "Free Tesla" @@ -64,11 +66,12 @@ def get_input(is_draft=False, id=1): } -def assert_report(is_draft=False): +def assert_report(is_draft, published, edited): report = Report.objects.get(id=1) assert report.author_id == 1 assert report.date == date.datetime assert report.published == published.datetime + assert report.edited == edited.datetime assert report.title == title assert report.body == body assert report.received_benefit == received_benefit @@ -111,28 +114,28 @@ def test_update_published_with_draft(client, snapshot): def test_update_draft_with_draft(client, snapshot): prepare_report(is_draft=True) input = get_input(is_draft=True) - with patch("openlobby.core.api.mutations.arrow.utcnow", return_value=published): + with patch("openlobby.core.api.mutations.arrow.utcnow", return_value=edited): response = call_api(client, query, input, "wolf") snapshot.assert_match(response) - assert_report(is_draft=True) + assert_report(True, edited, edited) def test_update_draft_with_published(client, snapshot): prepare_report(is_draft=True) input = get_input() - with patch("openlobby.core.api.mutations.arrow.utcnow", return_value=published): + with patch("openlobby.core.api.mutations.arrow.utcnow", return_value=edited): response = call_api(client, query, input, "wolf") snapshot.assert_match(response) - assert_report() + assert_report(False, edited, edited) def test_update_published_with_published(client, snapshot): prepare_report() input = get_input() - with patch("openlobby.core.api.mutations.arrow.utcnow", return_value=published): + with patch("openlobby.core.api.mutations.arrow.utcnow", return_value=edited): response = call_api(client, query, input, "wolf") snapshot.assert_match(response) - assert_report() + assert_report(False, published, edited) def test_input_sanitization(client, snapshot): @@ -148,7 +151,7 @@ def test_input_sanitization(client, snapshot): "date": date.isoformat(), } - with patch("openlobby.core.api.mutations.arrow.utcnow", return_value=published): + with patch("openlobby.core.api.mutations.arrow.utcnow", return_value=edited): response = call_api(client, query, input, "wolf") snapshot.assert_match(response) diff --git a/tests/schema/snapshots/snap_test_authors.py b/tests/schema/snapshots/snap_test_authors.py index 02bf97df2eff8d3c3d1c371d6b77a6a0534f72ea..43fa5c8e6f40bd788bd398abfafade943c68ad92 100644 --- a/tests/schema/snapshots/snap_test_authors.py +++ b/tests/schema/snapshots/snap_test_authors.py @@ -188,6 +188,7 @@ snapshots["test_with_reports 1"] = { "node": { "body": "Another long story.", "date": "2018-01-03 00:00:00+00:00", + "edited": "2018-01-04 05:00:00+00:00", "extra": '{"rings": 1}', "id": "UmVwb3J0OjI=", "isDraft": False, @@ -219,6 +220,7 @@ snapshots["test_with_reports 1"] = { "node": { "body": "Aragorn is the King. And we have lost the Ring.", "date": "2018-01-05 00:00:00+00:00", + "edited": "2018-01-06 07:00:00+00:00", "extra": None, "id": "UmVwb3J0OjM=", "isDraft": False, @@ -235,6 +237,7 @@ snapshots["test_with_reports 1"] = { "node": { "body": "Long story short: we got the Ring!", "date": "2018-01-01 00:00:00+00:00", + "edited": "2018-01-02 03:00:00+00:00", "extra": None, "id": "UmVwb3J0OjE=", "isDraft": False, diff --git a/tests/schema/snapshots/snap_test_node.py b/tests/schema/snapshots/snap_test_node.py index 91a0da5bbcb43c6c9b611b80b25dc02691ee9c63..de5bb83f0e09833b6f074ace481a5fb01f255498 100644 --- a/tests/schema/snapshots/snap_test_node.py +++ b/tests/schema/snapshots/snap_test_node.py @@ -39,6 +39,7 @@ snapshots["test_report 1"] = { }, "body": "Long story short: we got the Ring!", "date": "2018-01-01 00:00:00+00:00", + "edited": "2018-01-02 03:00:00+00:00", "extra": None, "id": "UmVwb3J0OjE=", "isDraft": False, diff --git a/tests/schema/snapshots/snap_test_report_drafts.py b/tests/schema/snapshots/snap_test_report_drafts.py index 1106c70e57b89e78676c395306c2effbae3912a3..c84c6c72ece09f448dfb9bbcfdb3ca066ab0d2e9 100644 --- a/tests/schema/snapshots/snap_test_report_drafts.py +++ b/tests/schema/snapshots/snap_test_report_drafts.py @@ -15,6 +15,7 @@ snapshots["test_authenticated 1"] = { { "body": "Not finished yet.", "date": "2018-01-07 00:00:00+00:00", + "edited": "2018-01-08 09:00:00+00:00", "id": "UmVwb3J0OjQ=", "isDraft": True, "otherParticipants": "", diff --git a/tests/schema/snapshots/snap_test_search_reports.py b/tests/schema/snapshots/snap_test_search_reports.py index 694fc552ce38b83d90dd303d3ab26b6bffe363a7..d817d541ca7c10a66a507c8cadfc013e759d7a3a 100644 --- a/tests/schema/snapshots/snap_test_search_reports.py +++ b/tests/schema/snapshots/snap_test_search_reports.py @@ -24,6 +24,7 @@ snapshots["test_all 1"] = { }, "body": "Aragorn is the King. And we have lost the Ring.", "date": "2018-01-05 00:00:00+00:00", + "edited": "2018-01-06 07:00:00+00:00", "extra": None, "id": "UmVwb3J0OjM=", "isDraft": False, @@ -48,6 +49,7 @@ snapshots["test_all 1"] = { }, "body": "Another long story.", "date": "2018-01-03 00:00:00+00:00", + "edited": "2018-01-04 05:00:00+00:00", "extra": '{"rings": 1}', "id": "UmVwb3J0OjI=", "isDraft": False, @@ -72,6 +74,7 @@ snapshots["test_all 1"] = { }, "body": "Long story short: we got the Ring!", "date": "2018-01-01 00:00:00+00:00", + "edited": "2018-01-02 03:00:00+00:00", "extra": None, "id": "UmVwb3J0OjE=", "isDraft": False, @@ -112,6 +115,7 @@ snapshots["test_query 1"] = { }, "body": "Another long story.", "date": "2018-01-03 00:00:00+00:00", + "edited": "2018-01-04 05:00:00+00:00", "extra": '{"rings": 1}', "id": "UmVwb3J0OjI=", "isDraft": False, @@ -146,6 +150,7 @@ snapshots["test_highlight 1"] = { }, "body": "Aragorn is the King. And we have lost the <mark>Ring</mark>.", "date": "2018-01-05 00:00:00+00:00", + "edited": "2018-01-06 07:00:00+00:00", "extra": None, "id": "UmVwb3J0OjM=", "isDraft": False, @@ -170,6 +175,7 @@ snapshots["test_highlight 1"] = { }, "body": "Long story short: we got the <mark>Ring</mark>!", "date": "2018-01-01 00:00:00+00:00", + "edited": "2018-01-02 03:00:00+00:00", "extra": None, "id": "UmVwb3J0OjE=", "isDraft": False, diff --git a/tests/schema/test_authors.py b/tests/schema/test_authors.py index 3d4bb07a7a857f0b383e7da94cba8c6dd01d3066..2a56952ae43cbf5f5f59c908a2fa397956b3835b 100644 --- a/tests/schema/test_authors.py +++ b/tests/schema/test_authors.py @@ -189,6 +189,7 @@ def test_with_reports(client, snapshot): otherParticipants isDraft extra + edited } } } diff --git a/tests/schema/test_node.py b/tests/schema/test_node.py index f13de1239c25b1b3de54b82906df11b18fd179d9..c386a6a3ca079915070e35882d5c5865c90e4a11 100644 --- a/tests/schema/test_node.py +++ b/tests/schema/test_node.py @@ -84,6 +84,7 @@ def test_report(client, snapshot): otherParticipants isDraft extra + edited author {{ id firstName diff --git a/tests/schema/test_report_drafts.py b/tests/schema/test_report_drafts.py index 013f6dab0c1b5e65ce06eb338f3ce830a94a8a3c..ce12831efc3b6b246cb84e242f6d444f378bcd33 100644 --- a/tests/schema/test_report_drafts.py +++ b/tests/schema/test_report_drafts.py @@ -35,6 +35,7 @@ def test_authenticated(client, snapshot): ourParticipants otherParticipants isDraft + edited } } """ diff --git a/tests/schema/test_search_reports.py b/tests/schema/test_search_reports.py index 68cbd11e76d8416281597cf1adbee8447c9df415..b3ac2d75546f5bc79b842ee2efa246f76f4d115e 100644 --- a/tests/schema/test_search_reports.py +++ b/tests/schema/test_search_reports.py @@ -27,6 +27,7 @@ def test_all(client, snapshot): otherParticipants isDraft extra + edited author { id firstName @@ -70,6 +71,7 @@ def test_query(client, snapshot): otherParticipants isDraft extra + edited author { id firstName @@ -107,6 +109,7 @@ def test_highlight(client, snapshot): otherParticipants isDraft extra + edited author { id firstName diff --git a/tests/test_models.py b/tests/test_models.py index 748ab929f347080f0da3483846097b21e54513c9..10469d4d01329b2361deafccadfe9769d174381e 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -33,11 +33,13 @@ def test_report__is_saved_in_elasticsearch(): author = User.objects.create(id=6) date = arrow.get(2018, 1, 1).datetime published = arrow.get(2018, 1, 2).datetime + edited = arrow.get(2018, 1, 3).datetime Report.objects.create( id=3, author=author, date=date, published=published, + edited=edited, title="It happened", body="Lorem ipsum.", received_benefit="coffee", @@ -54,6 +56,7 @@ def test_report__is_saved_in_elasticsearch(): assert doc.author_id == 6 assert doc.date == date assert doc.published == published + assert doc.edited == edited assert doc.title == "It happened" assert doc.body == "Lorem ipsum." assert doc.received_benefit == "coffee"