def test_paginated_viewset(self):
        observer = QueryObserver(
            request(views.PaginatedViewSet, offset=0, limit=10))
        items = observer.subscribe('test-session')

        self.assertEqual(len(items), 0)

        items = []
        for index in range(20):
            items.append(
                models.ExampleItem.objects.create(name='Example',
                                                  enabled=True))

        # Evaluate the observer again (in reality this would be done automatically, triggered by signals
        # from Django ORM).
        added, changed, removed = observer._evaluate()

        self.assertEqual(len(added), 10)
        expected_serialized_item = {
            'id': items[0].pk,
            'name': items[0].name,
            'enabled': items[0].enabled,
        }
        self.assertEqual(added[0]['data'], expected_serialized_item)
        self.assertEqual(len(changed), 0)
        self.assertEqual(len(removed), 0)
    def test_paginated_viewset(self):
        observer = QueryObserver(request(views.PaginatedViewSet, offset=0, limit=10))
        items = observer.subscribe('test-session')

        self.assertEqual(len(items), 0)

        items = []
        for index in range(20):
            items.append(
                models.ExampleItem.objects.create(name='Example', enabled=True)
            )

        # Evaluate the observer again (in reality this would be done automatically, triggered by signals
        # from Django ORM).
        added, changed, removed = observer._evaluate()

        self.assertEqual(len(added), 10)
        expected_serialized_item = {
            'id': items[0].pk,
            'name': items[0].name,
            'enabled': items[0].enabled,
        }
        self.assertEqual(added[0]['data'], expected_serialized_item)
        self.assertEqual(len(changed), 0)
        self.assertEqual(len(removed), 0)
    def test_conditions(self):
        observer = QueryObserver(
            request(views.ExampleItemViewSet, enabled=True))
        items = observer.subscribe('test-session')

        self.assertEqual(
            observer.id,
            '5333b85599fd24ed4e2f7eeaefb599cbbd39894b437e9b9d3b80d5d21639b4bb',
        )
        self.assertEqual(len(items), 0)

        item = models.ExampleItem()
        item.name = 'Example'
        item.enabled = False
        item.save()

        shortcuts.assign_perm(
            'rest_framework_reactive.view_exampleitem',
            auth_models.AnonymousUser(),
            item,
        )

        added, changed, removed = observer._evaluate()

        self.assertEqual(len(added), 0)
        self.assertEqual(len(changed), 0)
        self.assertEqual(len(removed), 0)

        item.enabled = True
        item.save()

        added, changed, removed = observer._evaluate()

        self.assertEqual(len(added), 1)
        self.assertEqual(
            added[0]['data'],
            {
                'id': item.pk,
                'name': item.name,
                'enabled': item.enabled
            },
        )
        self.assertEqual(len(changed), 0)
        self.assertEqual(len(removed), 0)
    def test_conditions(self):
        observer = QueryObserver(request(views.ExampleItemViewSet, enabled=True))
        items = observer.subscribe('test-session')

        self.assertEqual(
            observer.id,
            '5333b85599fd24ed4e2f7eeaefb599cbbd39894b437e9b9d3b80d5d21639b4bb',
        )
        self.assertEqual(len(items), 0)

        item = models.ExampleItem()
        item.name = 'Example'
        item.enabled = False
        item.save()

        shortcuts.assign_perm(
            'rest_framework_reactive.view_exampleitem',
            auth_models.AnonymousUser(),
            item,
        )

        added, changed, removed = observer._evaluate()

        self.assertEqual(len(added), 0)
        self.assertEqual(len(changed), 0)
        self.assertEqual(len(removed), 0)

        item.enabled = True
        item.save()

        added, changed, removed = observer._evaluate()

        self.assertEqual(len(added), 1)
        self.assertEqual(
            added[0]['data'],
            {'id': item.pk, 'name': item.name, 'enabled': item.enabled},
        )
        self.assertEqual(len(changed), 0)
        self.assertEqual(len(removed), 0)
    def test_observe_viewset(self):
        # Create a request and an observer for it.
        observer = QueryObserver(request(views.ExampleItemViewSet))
        items = observer.subscribe('test-session')

        self.assertEqual(
            observer.id,
            'fa87c86f1e032942b699e9902ac38ca232ce3566724b3891914c80083b676ed4',
        )
        self.assertEqual(len(items), 0)

        # Add an item into the database.
        item = models.ExampleItem()
        item.name = 'Example'
        item.enabled = True
        item.save()

        shortcuts.assign_perm(
            'rest_framework_reactive.view_exampleitem',
            auth_models.AnonymousUser(),
            item,
        )

        # Evaluate the observer again (in reality this would be done automatically, triggered by signals
        # from Django ORM).
        added, changed, removed = observer._evaluate()

        self.assertEqual(len(added), 1)
        expected_serialized_item = {
            'id': item.pk,
            'name': item.name,
            'enabled': item.enabled,
        }
        self.assertEqual(added[0]['data'], expected_serialized_item)
        self.assertEqual(len(changed), 0)
        self.assertEqual(len(removed), 0)

        # Change the existing item.
        item.enabled = False
        expected_serialized_item['enabled'] = False
        item.save()

        added, changed, removed = observer._evaluate()
        self.assertEqual(len(added), 0)
        self.assertEqual(len(changed), 1)
        self.assertEqual(changed[0]['data'], expected_serialized_item)
        self.assertEqual(len(removed), 0)

        # Remove the first item.
        item.delete()

        # Add another two items.
        item2 = models.ExampleItem()
        item2.name = 'Example 2'
        item2.enabled = True
        item2.save()

        item3 = models.ExampleItem()
        item3.name = 'Example 3'
        item3.enabled = True
        item3.save()

        shortcuts.assign_perm(
            'rest_framework_reactive.view_exampleitem',
            auth_models.AnonymousUser(),
            item2,
        )
        shortcuts.assign_perm(
            'rest_framework_reactive.view_exampleitem',
            auth_models.AnonymousUser(),
            item3,
        )

        added, changed, removed = observer._evaluate()
        self.assertEqual(len(added), 2)
        self.assertEqual(
            added[0]['data'],
            {'id': item2.pk, 'name': item2.name, 'enabled': item2.enabled},
        )
        self.assertEqual(
            added[1]['data'],
            {'id': item3.pk, 'name': item3.name, 'enabled': item3.enabled},
        )
        self.assertEqual(len(changed), 0)
        self.assertEqual(len(removed), 1)
        self.assertEqual(removed[0]['data'], expected_serialized_item)
    def test_order(self):
        observer = QueryObserver(request(views.ExampleItemViewSet, ordering='name'))
        items = observer.subscribe('test-session')

        self.assertEqual(len(items), 0)

        item = models.ExampleItem()
        item.name = 'D'
        item.enabled = False
        item.save()

        shortcuts.assign_perm(
            'rest_framework_reactive.view_exampleitem',
            auth_models.AnonymousUser(),
            item,
        )

        added, changed, removed = observer._evaluate()

        self.assertEqual(len(added), 1)
        self.assertEqual(
            added[0]['data'],
            {'id': item.pk, 'name': item.name, 'enabled': item.enabled},
        )
        self.assertEqual(added[0]['order'], 0)
        self.assertEqual(len(changed), 0)
        self.assertEqual(len(removed), 0)

        item2 = models.ExampleItem()
        item2.name = 'A'
        item2.enabled = True
        item2.save()

        shortcuts.assign_perm(
            'rest_framework_reactive.view_exampleitem',
            auth_models.AnonymousUser(),
            item2,
        )

        added, changed, removed = observer._evaluate()

        self.assertEqual(len(added), 1)
        self.assertEqual(
            added[0]['data'],
            {'id': item2.pk, 'name': item2.name, 'enabled': item2.enabled},
        )
        self.assertEqual(added[0]['order'], 0)
        # Check that the first item has changed, because its order has changed.
        self.assertEqual(len(changed), 1)
        self.assertEqual(
            changed[0]['data'],
            {'id': item.pk, 'name': item.name, 'enabled': item.enabled},
        )
        self.assertEqual(changed[0]['order'], 1)
        self.assertEqual(len(removed), 0)

        item3 = models.ExampleItem()
        item3.name = 'C'
        item3.enabled = True
        item3.save()

        shortcuts.assign_perm(
            'rest_framework_reactive.view_exampleitem',
            auth_models.AnonymousUser(),
            item3,
        )

        added, changed, removed = observer._evaluate()
        self.assertEqual(len(added), 1)
        self.assertEqual(
            added[0]['data'],
            {'id': item3.pk, 'name': item3.name, 'enabled': item3.enabled},
        )
        self.assertEqual(added[0]['order'], 1)
        self.assertEqual(len(changed), 1)
        self.assertEqual(
            changed[0]['data'],
            {'id': item.pk, 'name': item.name, 'enabled': item.enabled},
        )
        self.assertEqual(changed[0]['order'], 2)
        self.assertEqual(len(removed), 0)

        # Check order change between two existing items.

        item.name = 'B'
        item.save()

        added, changed, removed = observer._evaluate()

        self.assertEqual(len(added), 0)
        self.assertEqual(len(changed), 2)
        self.assertEqual(
            changed[0]['data'],
            {'id': item3.pk, 'name': item3.name, 'enabled': item3.enabled},
        )
        self.assertEqual(changed[0]['order'], 2)
        self.assertEqual(
            changed[1]['data'],
            {'id': item.pk, 'name': item.name, 'enabled': item.enabled},
        )
        self.assertEqual(changed[1]['order'], 1)
        self.assertEqual(len(removed), 0)
    def test_observe_viewset(self):
        # Create a request and an observer for it.
        observer = QueryObserver(request(views.ExampleItemViewSet))
        items = observer.subscribe('test-session')

        self.assertEqual(
            observer.id,
            'fa87c86f1e032942b699e9902ac38ca232ce3566724b3891914c80083b676ed4',
        )
        self.assertEqual(len(items), 0)

        # Add an item into the database.
        item = models.ExampleItem()
        item.name = 'Example'
        item.enabled = True
        item.save()

        shortcuts.assign_perm(
            'rest_framework_reactive.view_exampleitem',
            auth_models.AnonymousUser(),
            item,
        )

        # Evaluate the observer again (in reality this would be done automatically, triggered by signals
        # from Django ORM).
        added, changed, removed = observer._evaluate()

        self.assertEqual(len(added), 1)
        expected_serialized_item = {
            'id': item.pk,
            'name': item.name,
            'enabled': item.enabled,
        }
        self.assertEqual(added[0]['data'], expected_serialized_item)
        self.assertEqual(len(changed), 0)
        self.assertEqual(len(removed), 0)

        # Change the existing item.
        item.enabled = False
        expected_serialized_item['enabled'] = False
        item.save()

        added, changed, removed = observer._evaluate()
        self.assertEqual(len(added), 0)
        self.assertEqual(len(changed), 1)
        self.assertEqual(changed[0]['data'], expected_serialized_item)
        self.assertEqual(len(removed), 0)

        # Remove the first item.
        item.delete()

        # Add another two items.
        item2 = models.ExampleItem()
        item2.name = 'Example 2'
        item2.enabled = True
        item2.save()

        item3 = models.ExampleItem()
        item3.name = 'Example 3'
        item3.enabled = True
        item3.save()

        shortcuts.assign_perm(
            'rest_framework_reactive.view_exampleitem',
            auth_models.AnonymousUser(),
            item2,
        )
        shortcuts.assign_perm(
            'rest_framework_reactive.view_exampleitem',
            auth_models.AnonymousUser(),
            item3,
        )

        added, changed, removed = observer._evaluate()
        self.assertEqual(len(added), 2)
        self.assertEqual(
            added[0]['data'],
            {
                'id': item2.pk,
                'name': item2.name,
                'enabled': item2.enabled
            },
        )
        self.assertEqual(
            added[1]['data'],
            {
                'id': item3.pk,
                'name': item3.name,
                'enabled': item3.enabled
            },
        )
        self.assertEqual(len(changed), 0)
        self.assertEqual(len(removed), 1)
        self.assertEqual(removed[0]['data'], expected_serialized_item)
    def test_order(self):
        observer = QueryObserver(
            request(views.ExampleItemViewSet, ordering='name'))
        items = observer.subscribe('test-session')

        self.assertEqual(len(items), 0)

        item = models.ExampleItem()
        item.name = 'D'
        item.enabled = False
        item.save()

        shortcuts.assign_perm(
            'rest_framework_reactive.view_exampleitem',
            auth_models.AnonymousUser(),
            item,
        )

        added, changed, removed = observer._evaluate()

        self.assertEqual(len(added), 1)
        self.assertEqual(
            added[0]['data'],
            {
                'id': item.pk,
                'name': item.name,
                'enabled': item.enabled
            },
        )
        self.assertEqual(added[0]['order'], 0)
        self.assertEqual(len(changed), 0)
        self.assertEqual(len(removed), 0)

        item2 = models.ExampleItem()
        item2.name = 'A'
        item2.enabled = True
        item2.save()

        shortcuts.assign_perm(
            'rest_framework_reactive.view_exampleitem',
            auth_models.AnonymousUser(),
            item2,
        )

        added, changed, removed = observer._evaluate()

        self.assertEqual(len(added), 1)
        self.assertEqual(
            added[0]['data'],
            {
                'id': item2.pk,
                'name': item2.name,
                'enabled': item2.enabled
            },
        )
        self.assertEqual(added[0]['order'], 0)
        # Check that the first item has changed, because its order has changed.
        self.assertEqual(len(changed), 1)
        self.assertEqual(
            changed[0]['data'],
            {
                'id': item.pk,
                'name': item.name,
                'enabled': item.enabled
            },
        )
        self.assertEqual(changed[0]['order'], 1)
        self.assertEqual(len(removed), 0)

        item3 = models.ExampleItem()
        item3.name = 'C'
        item3.enabled = True
        item3.save()

        shortcuts.assign_perm(
            'rest_framework_reactive.view_exampleitem',
            auth_models.AnonymousUser(),
            item3,
        )

        added, changed, removed = observer._evaluate()
        self.assertEqual(len(added), 1)
        self.assertEqual(
            added[0]['data'],
            {
                'id': item3.pk,
                'name': item3.name,
                'enabled': item3.enabled
            },
        )
        self.assertEqual(added[0]['order'], 1)
        self.assertEqual(len(changed), 1)
        self.assertEqual(
            changed[0]['data'],
            {
                'id': item.pk,
                'name': item.name,
                'enabled': item.enabled
            },
        )
        self.assertEqual(changed[0]['order'], 2)
        self.assertEqual(len(removed), 0)

        # Check order change between two existing items.

        item.name = 'B'
        item.save()

        added, changed, removed = observer._evaluate()

        self.assertEqual(len(added), 0)
        self.assertEqual(len(changed), 2)
        self.assertEqual(
            changed[0]['data'],
            {
                'id': item3.pk,
                'name': item3.name,
                'enabled': item3.enabled
            },
        )
        self.assertEqual(changed[0]['order'], 2)
        self.assertEqual(
            changed[1]['data'],
            {
                'id': item.pk,
                'name': item.name,
                'enabled': item.enabled
            },
        )
        self.assertEqual(changed[1]['order'], 1)
        self.assertEqual(len(removed), 0)