Пример #1
0
    def test_inbox_disowned(self):
        factories.InboxFactory(user=factories.UserFactory())
        disowned = factories.InboxFactory(user=None)

        qs = models.Inbox.objects.disowned()
        self.assertEqual(len(qs), 1)
        self.assertEqual(qs[0].id, disowned.id)
Пример #2
0
 def setUp(self):
     super(FlagTestCase, self).setUp()
     self.user = factories.UserFactory()
     self.inboxes = [
         factories.InboxFactory(user=self.user, flags=0),
         factories.InboxFactory(user=self.user, flags=models.Inbox.flags.new),
     ]
     self.emails = factories.EmailFactory.create_batch(10, inbox=self.inboxes[0])
     self.emails.extend(factories.EmailFactory.create_batch(10, inbox=self.inboxes[1]))
Пример #3
0
 def setUp(self):
     super(FlagTestCase, self).setUp()
     self.user = factories.UserFactory()
     profile = self.user.inboxenprofile
     profile.unified_has_new_messages = True
     profile.save()
     self.inboxes = [
         factories.InboxFactory(user=self.user, new=False),
         factories.InboxFactory(user=self.user, new=True),
     ]
     self.emails = factories.EmailFactory.create_batch(10, inbox=self.inboxes[0], seen=False)
     self.emails.extend(factories.EmailFactory.create_batch(10, inbox=self.inboxes[1], seen=False))
Пример #4
0
    def test_search_results(self):
        inboxes = factories.InboxFactory.create_batch(tasks.SEARCH_PAGE_SIZE,
                                                      user=self.user,
                                                      description="bizz")
        factories.InboxFactory.create_batch(tasks.SEARCH_PAGE_SIZE,
                                            user=self.user,
                                            description="fuzz")
        result = tasks.search(self.user.id, "bizz")
        expected_results = list(
            SearchEntry.objects.filter(
                object_id_int__in=[i.id for i in inboxes]).order_by(
                    "-id").values_list("id", flat=True))
        self.assertEqual(result["results"], expected_results)
        self.assertEqual(result["has_next"], False)
        self.assertEqual(result["has_previous"], False)
        # just assert that it's some value
        self.assertTrue(result["last"])
        self.assertTrue(result["first"])

        factories.InboxFactory(user=self.user, description="bizz")
        result_2nd = tasks.search(self.user.id, "bizz")
        self.assertNotEqual(result_2nd["results"], expected_results)
        self.assertEqual(result_2nd["has_next"], True)
        self.assertEqual(result_2nd["has_previous"], False)
        # just assert that it's some value
        self.assertTrue(result_2nd["last"])
        self.assertNotEqual(result["last"], result_2nd["last"])
        self.assertTrue(result_2nd["first"])
        self.assertNotEqual(result["first"], result_2nd["first"])
Пример #5
0
    def test_flag_setting(self):
        # import here, that way we don't have to fiddle with sys.path in the global scope
        from router.app.server import process_message

        user = factories.UserFactory()
        inbox = factories.InboxFactory(user=user)

        with mock.patch("router.app.server.make_email") as mock_make_email:
            process_message(None, inbox.inbox, inbox.domain.domain)
        self.assertTrue(mock_make_email.called)

        user = get_user_model().objects.get(id=user.id)
        profile = user.inboxenprofile
        inbox = models.Inbox.objects.get(id=inbox.id)

        self.assertTrue(inbox.flags.new)
        self.assertTrue(profile.flags.unified_has_new_messages)

        # reset some flags
        inbox.flags.new = False
        inbox.flags.exclude_from_unified = True
        inbox.save(update_fields=["flags"])
        profile.flags.unified_has_new_messages = False
        profile.save(update_fields=["flags"])

        with mock.patch("router.app.server.make_email") as mock_make_email:
            process_message(None, inbox.inbox, inbox.domain.domain)
        self.assertTrue(mock_make_email.called)

        user = get_user_model().objects.get(id=user.id)
        profile = user.inboxenprofile
        inbox = models.Inbox.objects.get(id=inbox.id)

        self.assertTrue(inbox.flags.new)
        self.assertFalse(profile.flags.unified_has_new_messages)
Пример #6
0
    def test_flag_setting(self):
        user = factories.UserFactory()
        inbox = factories.InboxFactory(user=user)

        with mock.patch(
                "inboxen.router.app.server.make_email") as mock_make_email:
            process_message(None, inbox.inbox, inbox.domain.domain)
        self.assertTrue(mock_make_email.called)

        user = get_user_model().objects.get(id=user.id)
        profile = user.inboxenprofile
        inbox = models.Inbox.objects.get(id=inbox.id)

        self.assertTrue(inbox.new)
        self.assertTrue(profile.unified_has_new_messages)

        # reset some bools
        inbox.new = False
        inbox.exclude_from_unified = True
        inbox.save(update_fields=["new", "exclude_from_unified"])
        profile.unified_has_new_messages = False
        profile.save(update_fields=["unified_has_new_messages"])

        with mock.patch(
                "inboxen.router.app.server.make_email") as mock_make_email:
            process_message(None, inbox.inbox, inbox.domain.domain)
        self.assertTrue(mock_make_email.called)

        user = get_user_model().objects.get(id=user.id)
        profile = user.inboxenprofile
        inbox = models.Inbox.objects.get(id=inbox.id)

        self.assertTrue(inbox.new)
        self.assertFalse(profile.unified_has_new_messages)
Пример #7
0
    def test_running_total(self):
        tasks.statistics.delay()
        stats = models.Statistic.objects.get()
        self.assertEqual(stats.emails["email_count__sum"], 0)
        self.assertEqual(stats.emails["running_total"], 0)

        stats.delete()

        factories.InboxFactory()
        factories.EmailFactory.create_batch(2)

        # first count
        tasks.statistics.delay()
        stats = models.Statistic.objects.get()
        self.assertEqual(stats.emails["email_count__sum"], 2)
        self.assertEqual(stats.emails["running_total"], 2)

        # running total should not have gone down
        models.Email.objects.first().delete()
        tasks.statistics.delay()
        stats = models.Statistic.objects.latest("date")
        self.assertEqual(stats.emails["email_count__sum"], 1)
        self.assertEqual(stats.emails["running_total"], 2)

        # running total should now increase
        factories.EmailFactory()
        tasks.statistics.delay()
        stats = models.Statistic.objects.latest("date")
        self.assertEqual(stats.emails["email_count__sum"], 2)
        self.assertEqual(stats.emails["running_total"], 3)
Пример #8
0
    def setUp(self):
        self.user = factories.UserFactory()
        self.inbox = factories.InboxFactory(user=self.user)

        login = self.client.login(username=self.user.username, password="******", request=MockRequest(self.user))

        if not login:
            raise Exception("Could not log in")
Пример #9
0
    def test_routes(self):
        from salmon.routing import Router

        user = factories.UserFactory()
        inbox = factories.InboxFactory(user=user)
        Router.load(['app.server'])

        with mock.patch("router.app.server.Relay") as relay_mock, \
                mock.patch("router.app.server.make_email") as mock_make_email, \
                mock.patch("salmon.server.smtplib.SMTP") as smtp_mock:

            deliver_mock = mock.Mock()
            relay_mock.return_value.deliver = deliver_mock
            message = MailRequest("locahost", "test@localhost", str(inbox), TEST_MSG)
            Router.deliver(message)

            self.assertEqual(mock_make_email.call_count, 1)
            self.assertEqual(relay_mock.call_count, 0)
            self.assertEqual(deliver_mock.call_count, 0)

            mock_make_email.reset_mock()
            relay_mock.reset_mock()
            deliver_mock.reset_mock()
            message = MailRequest("locahost", "test@localhost", "root@localhost", TEST_MSG)
            Router.deliver(message)

            self.assertEqual(mock_make_email.call_count, 0)
            self.assertEqual(relay_mock.call_count, 1)
            self.assertEqual(deliver_mock.call_count, 1)
            self.assertEqual(message, deliver_mock.call_args[0][0])

            mock_make_email.reset_mock()
            relay_mock.reset_mock()
            deliver_mock.reset_mock()
            message = MailRequest("locahost", "test@localhost", "root1@localhost", TEST_MSG)
            with self.assertRaises(SMTPError) as excp:
                Router.deliver(message)
            self.assertEqual(excp.exception.code, 550)
            self.assertEqual(excp.exception.message, "No such address")

            self.assertEqual(mock_make_email.call_count, 0)
            self.assertEqual(relay_mock.call_count, 0)
            self.assertEqual(deliver_mock.call_count, 0)

            mock_make_email.reset_mock()
            relay_mock.reset_mock()
            deliver_mock.reset_mock()
            smtp_mock.return_value.sendmail.side_effect = Exception()
            message = MailRequest("locahost", "test@localhost", "root@localhost", TEST_MSG)
            with self.assertRaises(SMTPError) as excp:
                Router.deliver(message)
            self.assertEqual(excp.exception.code, 450)
            self.assertEqual(excp.exception.message, "Error while forwarding admin message %s" % id(message))

            self.assertEqual(mock_make_email.call_count, 0)
            self.assertEqual(relay_mock.call_count, 0)
            self.assertEqual(deliver_mock.call_count, 0)
Пример #10
0
    def test_make_email(self):
        inbox = factories.InboxFactory()
        message = MailRequest("locahost", "test@localhost", str(inbox), TEST_MSG)

        make_email(message, inbox)
        self.assertEqual(models.Email.objects.count(), 1)
        self.assertEqual(models.PartList.objects.count(), 6)

        bodies = [six.binary_type(part.body.data) for part in
                  models.PartList.objects.select_related("body").order_by("level", "lft")]
        self.assertEqual(bodies, BODIES)
Пример #11
0
    def setUp(self):
        """Create the client and grab the user"""
        super(InboxInlineEditTestCase, self).setUp()
        self.user = factories.UserFactory()
        self.inbox = factories.InboxFactory(user=self.user)

        login = self.client.login(username=self.user.username,
                                  password="******",
                                  request=MockRequest(self.user))

        if not login:
            raise Exception("Could not log in")
Пример #12
0
    def test_requests_are_requested(self):
        user = factories.UserFactory()
        profile = user.inboxenprofile
        profile.pool_amount = settings.MIN_INBOX_FOR_REQUEST
        profile.save()

        profile.available_inboxes()
        self.assertEqual(models.Request.objects.count(), 0)
        factories.InboxFactory(user=user)

        profile.available_inboxes()
        self.assertEqual(models.Request.objects.count(), 1)
        factories.InboxFactory(user=user)

        profile.available_inboxes()
        self.assertEqual(models.Request.objects.count(), 1)

        request = models.Request.objects.get()
        self.assertEqual(
            six.text_type(request),
            "Request for {} ({})".format(request.requester, request.succeeded))
Пример #13
0
    def test_inbox_from_string(self):
        user = factories.UserFactory()
        other_user = factories.UserFactory(username="******")

        inbox = factories.InboxFactory(user=user)
        email = "%s@%s" % (inbox.inbox, inbox.domain.domain)

        inbox2 = user.inbox_set.from_string(email=email)

        self.assertEqual(inbox, inbox2)

        with self.assertRaises(models.Inbox.DoesNotExist):
            other_user.inbox_set.from_string(email=email)
Пример #14
0
    def test_disown_inbox(self):
        inbox = factories.InboxFactory(user=self.user)
        result = tasks.disown_inbox(inbox.id)
        self.assertTrue(result)

        new_inbox = models.Inbox.objects.get(id=inbox.id)
        self.assertEqual(new_inbox.created, datetime.utcfromtimestamp(0).replace(tzinfo=utc))
        self.assertNotEqual(new_inbox.description, inbox.description)
        self.assertTrue(new_inbox.deleted)
        self.assertEqual(new_inbox.user, None)

        result = tasks.disown_inbox(inbox.id + 12)
        self.assertFalse(result)
Пример #15
0
    def test_inbox_viewable(self):
        user = factories.UserFactory()
        other_user = factories.UserFactory(username="******")

        # all the permutations of Inboxes that can be viewed
        params = (
            [0, models.Inbox.flags.deleted, ~models.Inbox.flags.deleted],
            [user, other_user, None],
        )
        for args in itertools.product(*params):
            factories.InboxFactory(flags=args[0], user=args[1])

        count = models.Inbox.objects.viewable(user).count()
        self.assertEqual(count, 2)
Пример #16
0
    def setUp(self):
        self.user = factories.UserFactory()

        login = self.client.login(username=self.user.username,
                                  password="******",
                                  request=MockRequest(self.user))
        assert login

        self.inbox = factories.InboxFactory(user=self.user)
        self.url = urls.reverse("inbox-disown",
                                kwargs={
                                    "inbox": self.inbox.inbox,
                                    "domain": self.inbox.domain.domain
                                })
Пример #17
0
    def test_command_inbox(self, smtp_mock):
        inbox = factories.InboxFactory()

        messages = self.MboxMock()
        messages["a"] = Message()
        messages["a"]["To"] = "*****@*****.**"
        messages["a"]["From"] = "*****@*****.**"
        # if you specify an inbox, you don't need a To header
        messages["b"] = Message()
        messages["b"]["From"] = "*****@*****.**"

        with mock.patch("inboxen.management.commands.feeder.mailbox.mbox") as mock_box:
            mock_box.return_value = messages
            call_command("feeder", "/", inbox=str(inbox))
Пример #18
0
    def test_add_last_activity(self):
        now = timezone.now()

        email = factories.EmailFactory(received_date=now)
        email.inbox.created = now - datetime.timedelta(2)
        email.inbox.save()

        inbox = factories.InboxFactory()
        inbox.created = now - datetime.timedelta(1)
        inbox.save()

        inboxes = list(models.Inbox.objects.all().add_last_activity())
        self.assertEqual(inboxes[0].last_activity, now)
        self.assertEqual(inboxes[1].last_activity, now - datetime.timedelta(1))
Пример #19
0
    def test_counts(self):
        # test all the counting is done correctly
        domain = factories.DomainFactory()

        # user 1
        user1 = factories.UserFactory()
        inbox11 = factories.InboxFactory(domain=domain, user=user1)
        inbox12 = factories.InboxFactory(domain=domain, user=user1)
        factories.EmailFactory.create_batch(2, inbox=inbox11)
        factories.EmailFactory.create_batch(2, inbox=inbox12)

        # user 2
        user2 = factories.UserFactory()
        inbox21 = factories.InboxFactory(domain=domain, user=user2)
        inbox22 = factories.InboxFactory(domain=domain, user=user2)
        factories.EmailFactory.create_batch(2, inbox=inbox21)
        factories.EmailFactory.create_batch(2, inbox=inbox22)

        # user 3
        factories.UserFactory()

        tasks.statistics.delay()
        stats = models.Statistic.objects.get()

        self.assertEqual(stats.users["count"], 3)
        self.assertEqual(stats.users["new"], 3)
        self.assertEqual(stats.users["with_inboxes"], 2)

        self.assertEqual(stats.inboxes["inbox_count__sum"], 4)
        self.assertEqual(stats.inboxes["inbox_count__max"], 2)
        self.assertEqual(stats.inboxes["inbox_count__min"], 0)
        self.assertEqual(stats.inboxes["inbox_count__avg"], 4.0 / 3)

        self.assertEqual(stats.emails["email_count__sum"], 8)
        self.assertEqual(stats.emails["email_count__max"], 2)
        self.assertEqual(stats.emails["email_count__min"], 2)
        self.assertEqual(stats.emails["email_count__avg"], 2)
Пример #20
0
    def test_inbox_viewable(self):
        user = factories.UserFactory()
        other_user = factories.UserFactory(username="******")

        # all the permutations of Inboxes that can be viewed
        params = (
            [True, False],             # deleted
            [True, False],             # disabled
            [user, other_user, None],  # user
        )
        for args in itertools.product(*params):
            factories.InboxFactory(deleted=args[0], disabled=args[1], user=args[2])

        count = models.Inbox.objects.viewable(user).count()
        self.assertEqual(count, 2)
Пример #21
0
    def test_routes_deliver_to_inbox(self):
        user = factories.UserFactory()
        inbox = factories.InboxFactory(user=user)
        Router.load(['inboxen.router.app.server'])

        with mock.patch("inboxen.router.app.server.Relay") as relay_mock, \
                mock.patch("inboxen.router.app.server.make_email") as mock_make_email:
            deliver_mock = mock.Mock()
            relay_mock.return_value.deliver = deliver_mock
            message = MailRequest("locahost", "test@localhost", str(inbox),
                                  TEST_MSG)
            Router.deliver(message)

            self.assertEqual(mock_make_email.call_count, 1)
            self.assertEqual(relay_mock.call_count, 0)
            self.assertEqual(deliver_mock.call_count, 0)
Пример #22
0
    def test_inbox_receiving(self):

        # all the permutations of Inboxes that can receive
        params = (
            [True, False],  # domain enabled
            [True, False],  # deleted
            [True, False],  # disabled
            [factories.UserFactory, None],  # user
            [models.UserProfile.REJECT_MAIL,
             models.UserProfile.DELETE_MAIL],  # quota options
            [99, 100, 101],  # quota percent
        )
        for args in itertools.product(*params):
            if args[3] is not None:
                user = args[3]()
                user.inboxenprofile.quota_options = args[4]
                user.inboxenprofile.quota_percent_usage = args[5]
                user.inboxenprofile.save()
            else:
                user = None

            factories.InboxFactory(domain__enabled=args[0],
                                   deleted=args[1],
                                   disabled=args[1],
                                   user=user)

        for inbox in models.Inbox.objects.receiving():
            truth_values = [
                inbox.deleted, inbox.disabled, not inbox.domain.enabled,
                inbox.user is None
                or inbox.user.inboxenprofile.quota_percent_usage > 99
            ]

            self.assertFalse(any(truth_values), truth_values)

        for inbox in models.Inbox.objects.exclude(
                id__in=models.Inbox.objects.receiving()):
            truth_values = [
                inbox.deleted, inbox.disabled, not inbox.domain.enabled,
                inbox.user is None
                or inbox.user.inboxenprofile.quota_percent_usage > 99
            ]

            self.assertTrue(any(truth_values), truth_values)

        self.assertEqual(models.Inbox.objects.receiving().count(), 4)
Пример #23
0
    def test_search_single_inbox(self):
        mock_result = mock.Mock()
        self.search_function.return_value = mock_result

        search_term = "bizz"
        inbox = factories.InboxFactory(description="bizz")

        expected_key = utils.create_search_cache_key(inbox.user_id, search_term, "inbox:{}".format(inbox), None, None)
        expected_sql = str(Email.objects.viewable(inbox.user_id).filter(inbox=inbox).search(search_term).query)

        result = tasks.search_single_inbox(inbox.user_id, search_term, str(inbox))
        self.assertEqual(result, mock_result)
        self.assertEqual(self.search_function.call_count, 1)
        self.assertEqual(self.search_function.call_args[0][0], expected_key)
        self.assertEqual(str(self.search_function.call_args[0][1].query), expected_sql)
        self.assertEqual(self.search_function.call_args[0][2:], (None, None))
        self.assertEqual(self.search_function.call_args[1], {})
Пример #24
0
    def test_inbox_receiving(self):
        user = factories.UserFactory()

        # all the permutations of Inboxes that can receive
        params = (
            [True, False],  # domain enabled
            [True, False],  # deleted
            [True, False],  # disabled
            [user, None],  # user
        )
        for args in itertools.product(*params):
            factories.InboxFactory(domain__enabled=args[0],
                                   deleted=args[1],
                                   disabled=args[1],
                                   user=args[3])

        count = models.Inbox.objects.receiving().count()
        self.assertEqual(count, 2)
Пример #25
0
    def test_make_email(self):
        inbox = factories.InboxFactory()
        message = MailRequest("locahost", "test@localhost", str(inbox),
                              TEST_MSG)

        router_utils.make_email(message, inbox)
        self.assertEqual(models.Email.objects.count(), 1)
        self.assertEqual(models.PartList.objects.count(), 6)

        email = models.Email.objects.first()
        self.assertEqual(email.inbox, inbox)
        self.assertNotEqual(email.search_tsv, None)

        bodies = [
            bytes(part.body.data)
            for part in models.PartList.objects.select_related(
                "body").order_by("level", "lft")
        ]
        self.assertEqual(bodies, BODIES)
Пример #26
0
    def test_get_cached_result(self, task_mock):
        inbox = factories.InboxFactory(user=self.user)

        task_mock.return_value.id = "abc"
        task_mock.return_value.get.side_effect = exceptions.TimeoutError

        cache.set(
            self.key, {
                "results": [inbox.id],
                "has_next": True,
                "has_previous": False,
                "first": "some-randomstring",
                "last": "somerandom-string",
            })

        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 200)

        self.assertEqual(task_mock.call_count, 0)
        self.assertEqual(response.context["has_next"], True)
        self.assertEqual(response.context["last"], "somerandom-string")
        self.assertEqual(response.context["has_previous"], False)
        self.assertEqual(response.context["first"], "some-randomstring")
        self.assertEqual(response.context["waiting"], False)

        cache.set(
            self.key, {
                "results": [],
                "has_next": True,
                "has_previous": False,
                "first": "some-randomstring",
                "last": "somerandom-string",
            })

        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 200)

        self.assertEqual(task_mock.call_count, 0)
        self.assertEqual(response.context["waiting"], False)
        self.assertNotIn("has_next", response.context)
        self.assertNotIn("has_previous", response.context)
        self.assertNotIn("first", response.context)
        self.assertNotIn("last", response.context)
Пример #27
0
    def setUp(self):
        self.user = factories.UserFactory()

        login = self.client.login(username=self.user.username,
                                  password="******",
                                  request=MockRequest(self.user))

        if not login:
            raise Exception("Could not log in")

        self.inbox = factories.InboxFactory(user=self.user)
        self.emails = factories.EmailFactory.create_batch(30, inbox=self.inbox)
        self.not_mine = factories.EmailFactory.create(inbox__user=self.user)

        for email in self.emails:
            part = factories.PartListFactory(email=email)
            factories.HeaderFactory(part=part)
            factories.HeaderFactory(part=part, name="From")
            factories.HeaderFactory(part=part, name="Subject")
Пример #28
0
    def setUp(self):
        self.user = factories.UserFactory()
        self.inbox = factories.InboxFactory(user=self.user)

        login = self.client.login(username=self.user.username,
                                  password="******",
                                  request=MockRequest(self.user))

        self.url = urls.reverse("single-inbox-search",
                                kwargs={
                                    "q": "cheddär",
                                    "inbox": self.inbox.inbox,
                                    "domain": self.inbox.domain.domain
                                })
        self.key = create_search_cache_key(self.user.id, "cheddär",
                                           "inbox:{}".format(self.inbox), None,
                                           None)

        if not login:
            raise Exception("Could not log in")
Пример #29
0
    def test_disown_inbox(self):
        defaults = {
            field: models.Inbox._meta.get_field(field).get_default()
            for field in tasks.INBOX_RESET_FIELDS
        }

        inbox = factories.InboxFactory(user=self.user,
                                       description="hello",
                                       disabled=True,
                                       exclude_from_unified=True,
                                       new=True,
                                       pinned=True)
        inbox.update_search()
        inbox.save()

        # make sure the values we're interested in are actually set to a non-default value
        for field_name in tasks.INBOX_RESET_FIELDS:
            with self.subTest(field_name=field_name):
                self.assertNotEqual(getattr(inbox, field_name),
                                    defaults[field_name])

        result = tasks.disown_inbox(inbox.id)
        self.assertTrue(result)

        new_inbox = models.Inbox.objects.get(id=inbox.id)
        self.assertEqual(new_inbox.created,
                         datetime.utcfromtimestamp(0).replace(tzinfo=utc))
        self.assertNotEqual(new_inbox.description, inbox.description)
        self.assertTrue(new_inbox.deleted)
        self.assertEqual(new_inbox.user, None)

        for field_name in tasks.INBOX_RESET_FIELDS:
            with self.subTest(field_name=field_name):
                self.assertEqual(getattr(new_inbox, field_name),
                                 defaults[field_name])

        result = tasks.disown_inbox(inbox.id + 12)
        self.assertFalse(result)
Пример #30
0
    def test_search_results(self):
        user = factories.UserFactory()
        inboxes = factories.InboxFactory.create_batch(settings.SEARCH_PAGE_SIZE, user=user, description="bizz")
        result = utils.search(self.key, Inbox.objects.search("bizz"), None, None)
        expected_results = [i.id for i in inboxes]
        expected_results.reverse()
        self.assertEqual(result["results"], expected_results)
        self.assertEqual(result["has_next"], False)
        self.assertEqual(result["has_previous"], False)
        # just assert that it's some value
        self.assertTrue(result["last"])
        self.assertTrue(result["first"])

        factories.InboxFactory(user=user, description="bizz")
        result_2nd = utils.search(self.key, Inbox.objects.search("bizz"), None, None)
        self.assertNotEqual(result_2nd["results"], expected_results)
        self.assertEqual(result_2nd["has_next"], True)
        self.assertEqual(result_2nd["has_previous"], False)
        # just assert that it's some value
        self.assertTrue(result_2nd["last"])
        self.assertNotEqual(result["last"], result_2nd["last"])
        self.assertTrue(result_2nd["first"])
        self.assertNotEqual(result["first"], result_2nd["first"])