def test_backward_last_page(self):
        # One result.
        partition_1 = self.create_results(1, 'B')
        # No results.
        partition_3 = []
        expected_page = [partition_1[0]]

        table_mock = MagicMock()
        table_mock.query.side_effect = [{
            'Items': partition_1
        }, {
            'Items': partition_3
        }]

        start_key = self.create_results(1, 'C')[0]
        page_token = dynamodb_pagination.PageToken(self.get_config(table_mock))
        page_token.forward = False
        page_token.set_start(1, start_key)
        # Partition 2 is is already at the end.
        page_token.set_start(3, start_key)

        search = dynamodb_pagination.PaginatedSearch(
            self.get_config(table_mock), page_token)

        page_size = 4
        page = search.get_next_page(page_size)

        self.assert_query_calls(table_mock.query, {
            'partition': 1,
            'key': start_key,
            'limit': page_size,
            'forward': False
        }, {
            'partition': 3,
            'key': start_key,
            'limit': page_size,
            'forward': False
        })

        self.assertEqual(page, expected_page)

        forward_page_token = search.get_page_token(forward=True)
        self.assertEqual(
            json.loads(base64.b64decode(forward_page_token)), {
                'direction': 'forward',
                'partitions': {
                    '1': {
                        'key': partition_1[0]
                    },
                    '2': {},
                    '3': {}
                }
            })
        backward_page_token = search.get_page_token(forward=False)
        if backward_page_token:
            print 'Page token was not None: ', json.loads(
                base64.b64decode(backward_page_token))
        self.assertIsNone(backward_page_token)
Beispiel #2
0
    def test_backward_inclusive(self):
        query_for_direction_change_1 = self.create_results(1, 'H')
        partition_1 = self.create_results(1, 'F', 'D', 'B')
        query_for_direction_change_2 = self.create_results(1, 'G')
        partition_2 = self.create_results(2, 'E', 'C', 'A')
        expected_page = [
            partition_2[1],
            partition_1[1],
            partition_2[0],
            partition_1[0],
        ]

        table_mock = MagicMock()
        table_mock.query.side_effect = [
            {'Items': query_for_direction_change_1},
            {'Items': partition_1},
            {'Items': query_for_direction_change_2},
            {'Items': partition_2}
        ]

        page_token = dynamodb_pagination.PageToken(self.get_config(table_mock))
        page_token.forward = False
        page_token.set_start(1, partition_1[0], True)
        page_token.set_start(2, partition_2[0], True)

        search = dynamodb_pagination.PaginatedSearch(self.get_config(table_mock), page_token)

        page_size = 4
        page = search.get_next_page(page_size)

        self.assert_query_calls(table_mock.query,
            {'partition': 1, 'key': partition_1[0], 'limit': 1, 'forward': True},
            {'partition': 1, 'key': query_for_direction_change_1[0], 'limit': page_size, 'forward': False},
            {'partition': 2, 'key': partition_2[0], 'limit': 1, 'forward': True},
            {'partition': 2, 'key': query_for_direction_change_2[0], 'limit': page_size, 'forward': False}
        )

        self.assertEqual(page, expected_page)

        forward_page_token = search.get_page_token(forward=True)
        self.assertEqual(json.loads(base64.b64decode(forward_page_token)), {
                'direction': 'forward',
                'partitions': {
                    '1': {'key': partition_1[0]},
                    '2': {'key': partition_2[0]},
                    '3': {}
                }
            }
        )
        backward_page_token = search.get_page_token(forward=False)
        self.assertEqual(json.loads(base64.b64decode(backward_page_token)), {
                'direction': 'backward',
                'partitions': {
                    '1': {'key': partition_1[1]},
                    '2': {'key': partition_2[1]}
                }
            }
        )
Beispiel #3
0
    def test_first_page(self):
        partition_1 = self.create_results(1, 'A', 'D')
        partition_2 = self.create_results(2, 'B', 'E', 'G')
        partition_3 = self.create_results(3, 'C', 'F', 'H')
        expected_page = [
            partition_1[0],
            partition_2[0],
            partition_3[0],
            partition_1[1],
            partition_2[1]
        ]

        table_mock = MagicMock()
        table_mock.query.side_effect = [
            {'Items': partition_1, 'LastEvaluatedKey': partition_1[1]},
            {'Items': partition_2},
            {'Items': partition_3}
        ]

        page_token = dynamodb_pagination.PageToken(self.get_config(table_mock))
        page_token.set_start(1, None)
        page_token.set_start(2, None)
        page_token.set_start(3, None)

        search = dynamodb_pagination.PaginatedSearch(self.get_config(table_mock), page_token)

        page_size = 5
        page = search.get_next_page(page_size)

        self.assert_query_calls(table_mock.query,
            {'partition': 1, 'limit': page_size, 'forward': True},
            {'partition': 2, 'limit': page_size, 'forward': True},
            {'partition': 3, 'limit': page_size, 'forward': True}
        )

        self.assertEqual(page, expected_page)

        forward_page_token = search.get_page_token(forward=True)
        self.assertEqual(json.loads(base64.b64decode(forward_page_token)), {
                'direction': 'forward',
                'partitions': {
                    '1': {'key': partition_1[1]},
                    '2': {'key': partition_2[1]},
                    '3': {'key': partition_3[0]}
                }
            }
        )
        backward_page_token = search.get_page_token(forward=False)
        self.assertEqual(json.loads(base64.b64decode(backward_page_token)), {
                'direction': 'backward',
                'partitions': {
                    '1': {'key': partition_1[0]},
                    '2': {'key': partition_2[0]},
                    '3': {'key': partition_3[0]}
                }
            }
        )
Beispiel #4
0
    def test_forward_exclusive(self):
        """Test a forward search using an exclusive page token"""
        partition_1 = self.create_results(1, 'F', 'H', 'J')
        partition_2 = self.create_results(2, 'E', 'G', 'I')
        expected_page = [
            partition_2[0],
            partition_1[0],
            partition_2[1],
            partition_1[1],
        ]

        table_mock = MagicMock()
        table_mock.query.side_effect = [
            {'Items': partition_1},
            {'Items': partition_2}
        ]

        start_key_1 = self.create_results(1, 'E')[0]
        start_key_2 = self.create_results(2, 'D')[0]
        page_token = dynamodb_pagination.PageToken(self.get_config(table_mock))
        page_token.set_start(1, start_key_1, False)
        page_token.set_start(2, start_key_2, False)

        search = dynamodb_pagination.PaginatedSearch(self.get_config(table_mock), page_token)

        page_size = 4
        page = search.get_next_page(page_size)

        self.assert_query_calls(table_mock.query,
            {'partition': 1, 'key': start_key_1, 'limit': page_size, 'forward': True},
            {'partition': 2, 'key': start_key_2, 'limit': page_size, 'forward': True},
        )

        self.assertEqual(page, expected_page)

        forward_page_token = search.get_page_token(forward=True)
        self.assertEqual(json.loads(base64.b64decode(forward_page_token)), {
                'direction': 'forward',
                'partitions': {
                    '1': {'key': partition_1[1]},
                    '2': {'key': partition_2[1]}
                }
            }
        )
        backward_page_token = search.get_page_token(forward=False)
        self.assertEqual(json.loads(base64.b64decode(backward_page_token)), {
                'direction': 'backward',
                'partitions': {
                    '1': {'key': partition_1[0]},
                    '2': {'key': partition_2[0]},
                    '3': {}
                }
            }
        )
    def test_forward_last_page_single_partition(self):
        partition_1 = self.create_results(1, 'A', 'B', 'C', 'D')
        expected_page = partition_1

        table_mock = MagicMock()
        table_mock.query.side_effect = [{'Items': partition_1}]

        page_token = dynamodb_pagination.PageToken(self.get_config(table_mock))
        page_token.set_start(1, None)

        search = dynamodb_pagination.PaginatedSearch(
            self.get_config(table_mock), page_token)

        page_size = 4
        page = search.get_next_page(page_size)

        self.assert_query_calls(table_mock.query, {
            'partition': 1,
            'limit': page_size,
            'forward': True
        })

        self.assertEqual(page, expected_page)

        forward_page_token = search.get_page_token(forward=True)
        if forward_page_token:
            print 'Page token was not None: ', json.loads(
                base64.b64decode(forward_page_token))
        self.assertIsNone(forward_page_token)

        backward_page_token = search.get_page_token(forward=False)
        self.assertEqual(
            json.loads(base64.b64decode(backward_page_token)), {
                'direction': 'backward',
                'partitions': {
                    '1': {
                        'key': partition_1[0]
                    },
                    '2': {},
                    '3': {}
                }
            })
def search_by_start_name(start_player_name=None, serialized_page_token=None):
    page_size = 20

    config = dynamodb_pagination.PartitionedIndexConfig(
        table=account_utils.get_account_table(),
        index_name='PlayerNameIndex',
        partition_key_name='PlayerNameSortKey',
        sort_key_name='IndexedPlayerName',
        partition_count=account_utils.get_name_sort_key_count(),
        required_fields={'AccountId': ' '})

    if serialized_page_token:
        page_token = dynamodb_pagination.PageToken(config,
                                                   serialized_page_token)
    else:
        page_token = dynamodb_pagination.get_page_token_for_inclusive_start(
            config, start_player_name, forward=True)

    search = dynamodb_pagination.PaginatedSearch(config, page_token,
                                                 start_player_name)

    raw_account_items = search.get_next_page(page_size)

    accounts = [
        account_utils.convert_account_from_dynamo_to_admin_model(item)
        for item in raw_account_items
    ]
    populate_identity_providers(accounts)

    result = {'Accounts': accounts}

    forward_token = search.get_page_token(forward=True)
    if forward_token:
        result['next'] = forward_token

    backward_token = search.get_page_token(forward=False)
    if backward_token:
        result['previous'] = backward_token

    return result
    def test_forward_inclusive_match_sort_key(self):
        # 'D' is found on the second page and used as the exclusive start.
        query_for_direction_change_1A = self.create_results(1, 'F', 'F')
        query_for_direction_change_1B = self.create_results(1, 'F', 'D')
        partition_1 = self.create_results(1, 'F', 'H', 'J')
        # 'C' is found on the first page and used as the exclusive start.
        query_for_direction_change_2 = self.create_results(1, 'C')
        partition_2 = self.create_results(2, 'E', 'G', 'I')
        # All pages include matching keys.
        query_for_direction_change_3 = self.create_results(1, 'F', 'F')
        partition_3 = []
        expected_page = [
            partition_2[0],
            partition_1[0],
            partition_2[1],
            partition_1[1],
        ]

        table_mock = MagicMock()
        table_mock.query.side_effect = [{
            'Items':
            query_for_direction_change_1A,
            'LastEvaluatedKey':
            query_for_direction_change_1A[-1]
        }, {
            'Items': query_for_direction_change_1B
        }, {
            'Items': partition_1
        }, {
            'Items': query_for_direction_change_2
        }, {
            'Items': partition_2
        }, {
            'Items':
            query_for_direction_change_3,
            'LastEvaluatedKey':
            query_for_direction_change_3[-1]
        }, {
            'Items':
            query_for_direction_change_3,
            'LastEvaluatedKey':
            query_for_direction_change_3[-1]
        }, {
            'Items':
            query_for_direction_change_3,
            'LastEvaluatedKey':
            query_for_direction_change_3[-1]
        }, {
            'Items': partition_3
        }]

        page_token = dynamodb_pagination.PageToken(self.get_config(table_mock))
        page_token.set_start(1, partition_1[0], 'match_sort_key')
        page_token.set_start(2, partition_2[0], 'match_sort_key')
        page_token.set_start(3, partition_1[0], 'match_sort_key')

        search = dynamodb_pagination.PaginatedSearch(
            self.get_config(table_mock), page_token)

        page_size = 4
        page = search.get_next_page(page_size)

        self.assert_query_calls(table_mock.query, {
            'partition': 1,
            'key': partition_1[0],
            'limit': 20,
            'forward': False
        }, {
            'partition': 1,
            'key': query_for_direction_change_1A[-1],
            'limit': 20,
            'forward': False
        }, {
            'partition': 1,
            'key': query_for_direction_change_1B[-1],
            'limit': page_size,
            'forward': True
        }, {
            'partition': 2,
            'key': partition_2[0],
            'limit': 20,
            'forward': False
        }, {
            'partition': 2,
            'key': query_for_direction_change_2[0],
            'limit': page_size,
            'forward': True
        }, {
            'partition': 3,
            'key': partition_1[0],
            'limit': 20,
            'forward': False
        }, {
            'partition': 3,
            'key': query_for_direction_change_3[-1],
            'limit': 20,
            'forward': False
        }, {
            'partition': 3,
            'key': query_for_direction_change_3[-1],
            'limit': 20,
            'forward': False
        }, {
            'partition': 3,
            'key': query_for_direction_change_3[-1],
            'limit': page_size,
            'forward': True
        })

        self.assertEqual(page, expected_page)

        forward_page_token = search.get_page_token(forward=True)
        self.assertEqual(
            json.loads(base64.b64decode(forward_page_token)), {
                'direction': 'forward',
                'partitions': {
                    '1': {
                        'key': partition_1[1]
                    },
                    '2': {
                        'key': partition_2[1]
                    }
                }
            })
        backward_page_token = search.get_page_token(forward=False)
        self.assertEqual(
            json.loads(base64.b64decode(backward_page_token)), {
                'direction': 'backward',
                'partitions': {
                    '1': {
                        'key': partition_1[0]
                    },
                    '2': {
                        'key': partition_2[0]
                    },
                    '3': {}
                }
            })