|
@@ -7,7 +7,7 @@ from misago.acl.testutils import override_acl
|
|
|
from misago.categories.models import Category
|
|
|
|
|
|
from .. import testutils
|
|
|
-from ..models import Thread
|
|
|
+from ..models import Poll, PollVote, Thread
|
|
|
from .test_threads_api import ThreadsApiTestCase
|
|
|
|
|
|
class ThreadMergeApiTests(ThreadsApiTestCase):
|
|
@@ -183,3 +183,225 @@ class ThreadMergeApiTests(ThreadsApiTestCase):
|
|
|
# first thread is gone
|
|
|
with self.assertRaises(Thread.DoesNotExist):
|
|
|
Thread.objects.get(pk=self.thread.pk)
|
|
|
+
|
|
|
+ def test_merge_threads_kept_poll(self):
|
|
|
+ """api merges two threads successfully, keeping poll from old thread"""
|
|
|
+ self.override_acl({
|
|
|
+ 'can_merge_threads': 1
|
|
|
+ })
|
|
|
+
|
|
|
+ self.override_other_acl({
|
|
|
+ 'can_merge_threads': 1
|
|
|
+ })
|
|
|
+
|
|
|
+ other_thread = testutils.post_thread(self.category_b)
|
|
|
+ poll = testutils.post_poll(other_thread, self.user)
|
|
|
+
|
|
|
+ response = self.client.post(self.api_link, {
|
|
|
+ 'thread_url': other_thread.get_absolute_url()
|
|
|
+ })
|
|
|
+ self.assertContains(response, other_thread.get_absolute_url(), status_code=200)
|
|
|
+
|
|
|
+ # other thread has two posts now
|
|
|
+ self.assertEqual(other_thread.post_set.count(), 3)
|
|
|
+
|
|
|
+ # first thread is gone
|
|
|
+ with self.assertRaises(Thread.DoesNotExist):
|
|
|
+ Thread.objects.get(pk=self.thread.pk)
|
|
|
+
|
|
|
+ # poll and its votes were kept
|
|
|
+ self.assertEqual(Poll.objects.filter(pk=poll.pk, thread=other_thread).count(), 1)
|
|
|
+ self.assertEqual(PollVote.objects.filter(poll=poll, thread=other_thread).count(), 4)
|
|
|
+
|
|
|
+ def test_merge_threads_moved_poll(self):
|
|
|
+ """api merges two threads successfully, moving poll from other thread"""
|
|
|
+ self.override_acl({
|
|
|
+ 'can_merge_threads': 1
|
|
|
+ })
|
|
|
+
|
|
|
+ self.override_other_acl({
|
|
|
+ 'can_merge_threads': 1
|
|
|
+ })
|
|
|
+
|
|
|
+ other_thread = testutils.post_thread(self.category_b)
|
|
|
+ poll = testutils.post_poll(self.thread, self.user)
|
|
|
+
|
|
|
+ response = self.client.post(self.api_link, {
|
|
|
+ 'thread_url': other_thread.get_absolute_url()
|
|
|
+ })
|
|
|
+ self.assertContains(response, other_thread.get_absolute_url(), status_code=200)
|
|
|
+
|
|
|
+ # other thread has two posts now
|
|
|
+ self.assertEqual(other_thread.post_set.count(), 3)
|
|
|
+
|
|
|
+ # first thread is gone
|
|
|
+ with self.assertRaises(Thread.DoesNotExist):
|
|
|
+ Thread.objects.get(pk=self.thread.pk)
|
|
|
+
|
|
|
+ # poll and its votes were moved
|
|
|
+ self.assertEqual(Poll.objects.filter(pk=poll.pk, thread=other_thread).count(), 1)
|
|
|
+ self.assertEqual(PollVote.objects.filter(poll=poll, thread=other_thread).count(), 4)
|
|
|
+
|
|
|
+ def test_threads_merge_conflict(self):
|
|
|
+ """api errors on merge conflict, returning list of available polls"""
|
|
|
+ self.override_acl({
|
|
|
+ 'can_merge_threads': 1
|
|
|
+ })
|
|
|
+
|
|
|
+ self.override_other_acl({
|
|
|
+ 'can_merge_threads': 1
|
|
|
+ })
|
|
|
+
|
|
|
+ other_thread = testutils.post_thread(self.category_b)
|
|
|
+ poll = testutils.post_poll(self.thread, self.user)
|
|
|
+ other_poll = testutils.post_poll(other_thread, self.user)
|
|
|
+
|
|
|
+ response = self.client.post(self.api_link, {
|
|
|
+ 'thread_url': other_thread.get_absolute_url()
|
|
|
+ })
|
|
|
+ self.assertEqual(response.status_code, 400)
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
+ 'polls': [
|
|
|
+ [0, "Delete all polls"],
|
|
|
+ [poll.pk, poll.question],
|
|
|
+ [other_poll.pk, other_poll.question]
|
|
|
+ ]
|
|
|
+ })
|
|
|
+
|
|
|
+ # poll and its votes were untouched
|
|
|
+ self.assertEqual(Poll.objects.count(), 2)
|
|
|
+ self.assertEqual(PollVote.objects.count(), 8)
|
|
|
+
|
|
|
+ def test_threads_merge_conflict_invalid_resolution(self):
|
|
|
+ """api errors on invalid merge conflict resolution"""
|
|
|
+ self.override_acl({
|
|
|
+ 'can_merge_threads': 1
|
|
|
+ })
|
|
|
+
|
|
|
+ self.override_other_acl({
|
|
|
+ 'can_merge_threads': 1
|
|
|
+ })
|
|
|
+
|
|
|
+ other_thread = testutils.post_thread(self.category_b)
|
|
|
+ poll = testutils.post_poll(self.thread, self.user)
|
|
|
+ other_poll = testutils.post_poll(other_thread, self.user)
|
|
|
+
|
|
|
+ response = self.client.post(self.api_link, {
|
|
|
+ 'thread_url': other_thread.get_absolute_url(),
|
|
|
+ 'poll': 'jhdkajshdsak'
|
|
|
+ })
|
|
|
+ self.assertEqual(response.status_code, 400)
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
+ 'detail': "Invalid choice."
|
|
|
+ })
|
|
|
+
|
|
|
+ # poll and its votes were untouched
|
|
|
+ self.assertEqual(Poll.objects.count(), 2)
|
|
|
+ self.assertEqual(PollVote.objects.count(), 8)
|
|
|
+
|
|
|
+ def test_threads_merge_conflict_delete_all(self):
|
|
|
+ """api deletes all polls when delete all choice is selected"""
|
|
|
+ self.override_acl({
|
|
|
+ 'can_merge_threads': 1
|
|
|
+ })
|
|
|
+
|
|
|
+ self.override_other_acl({
|
|
|
+ 'can_merge_threads': 1
|
|
|
+ })
|
|
|
+
|
|
|
+ other_thread = testutils.post_thread(self.category_b)
|
|
|
+ poll = testutils.post_poll(self.thread, self.user)
|
|
|
+ other_poll = testutils.post_poll(other_thread, self.user)
|
|
|
+
|
|
|
+ response = self.client.post(self.api_link, {
|
|
|
+ 'thread_url': other_thread.get_absolute_url(),
|
|
|
+ 'poll': 0
|
|
|
+ })
|
|
|
+ self.assertContains(response, other_thread.get_absolute_url(), status_code=200)
|
|
|
+
|
|
|
+ # other thread has two posts now
|
|
|
+ self.assertEqual(other_thread.post_set.count(), 3)
|
|
|
+
|
|
|
+ # first thread is gone
|
|
|
+ with self.assertRaises(Thread.DoesNotExist):
|
|
|
+ Thread.objects.get(pk=self.thread.pk)
|
|
|
+
|
|
|
+ # polls and votes are gone
|
|
|
+ self.assertEqual(Poll.objects.filter(pk=poll.pk, thread=other_thread).count(), 0)
|
|
|
+ self.assertEqual(PollVote.objects.filter(poll=poll, thread=other_thread).count(), 0)
|
|
|
+
|
|
|
+ def test_threads_merge_conflict_keep_first_poll(self):
|
|
|
+ """api deletes other poll on merge"""
|
|
|
+ self.override_acl({
|
|
|
+ 'can_merge_threads': 1
|
|
|
+ })
|
|
|
+
|
|
|
+ self.override_other_acl({
|
|
|
+ 'can_merge_threads': 1
|
|
|
+ })
|
|
|
+
|
|
|
+ other_thread = testutils.post_thread(self.category_b)
|
|
|
+ poll = testutils.post_poll(self.thread, self.user)
|
|
|
+ other_poll = testutils.post_poll(other_thread, self.user)
|
|
|
+
|
|
|
+ response = self.client.post(self.api_link, {
|
|
|
+ 'thread_url': other_thread.get_absolute_url(),
|
|
|
+ 'poll': poll.pk
|
|
|
+ })
|
|
|
+ self.assertContains(response, other_thread.get_absolute_url(), status_code=200)
|
|
|
+
|
|
|
+ # other thread has two posts now
|
|
|
+ self.assertEqual(other_thread.post_set.count(), 3)
|
|
|
+
|
|
|
+ # first thread is gone
|
|
|
+ with self.assertRaises(Thread.DoesNotExist):
|
|
|
+ Thread.objects.get(pk=self.thread.pk)
|
|
|
+
|
|
|
+ # other poll and its votes are gone
|
|
|
+ self.assertEqual(Poll.objects.filter(thread=self.thread).count(), 0)
|
|
|
+ self.assertEqual(PollVote.objects.filter(thread=self.thread).count(), 0)
|
|
|
+
|
|
|
+ self.assertEqual(Poll.objects.filter(thread=other_thread).count(), 1)
|
|
|
+ self.assertEqual(PollVote.objects.filter(thread=other_thread).count(), 4)
|
|
|
+
|
|
|
+ Poll.objects.get(pk=poll.pk)
|
|
|
+ with self.assertRaises(Poll.DoesNotExist):
|
|
|
+ Poll.objects.get(pk=other_poll.pk)
|
|
|
+
|
|
|
+ def test_threads_merge_conflict_keep_other_poll(self):
|
|
|
+ """api deletes first poll on merge"""
|
|
|
+ self.override_acl({
|
|
|
+ 'can_merge_threads': 1
|
|
|
+ })
|
|
|
+
|
|
|
+ self.override_other_acl({
|
|
|
+ 'can_merge_threads': 1
|
|
|
+ })
|
|
|
+
|
|
|
+ other_thread = testutils.post_thread(self.category_b)
|
|
|
+ poll = testutils.post_poll(self.thread, self.user)
|
|
|
+ other_poll = testutils.post_poll(other_thread, self.user)
|
|
|
+
|
|
|
+ response = self.client.post(self.api_link, {
|
|
|
+ 'thread_url': other_thread.get_absolute_url(),
|
|
|
+ 'poll': other_poll.pk
|
|
|
+ })
|
|
|
+ self.assertContains(response, other_thread.get_absolute_url(), status_code=200)
|
|
|
+
|
|
|
+ # other thread has two posts now
|
|
|
+ self.assertEqual(other_thread.post_set.count(), 3)
|
|
|
+
|
|
|
+ # first thread is gone
|
|
|
+ with self.assertRaises(Thread.DoesNotExist):
|
|
|
+ Thread.objects.get(pk=self.thread.pk)
|
|
|
+
|
|
|
+ # other poll and its votes are gone
|
|
|
+ self.assertEqual(Poll.objects.filter(thread=self.thread).count(), 0)
|
|
|
+ self.assertEqual(PollVote.objects.filter(thread=self.thread).count(), 0)
|
|
|
+
|
|
|
+ self.assertEqual(Poll.objects.filter(thread=other_thread).count(), 1)
|
|
|
+ self.assertEqual(PollVote.objects.filter(thread=other_thread).count(), 4)
|
|
|
+
|
|
|
+ Poll.objects.get(pk=other_poll.pk)
|
|
|
+ with self.assertRaises(Poll.DoesNotExist):
|
|
|
+ Poll.objects.get(pk=poll.pk)
|