def __init__(self, options, state=None, api_adaptor=None, extension_name='extension_name'): _print('init: Paginator') if (state is None): self.state = State() else: self.state = state self.extension_name = extension_name self.reset() try: self.max_pages = int(options['max_pages']) _print('about to load formatters') self.formatter = self.loadFormatter(options) except Exception as ex: _print(ex) _print('could not initialize Paginator.') raise if api_adaptor is not None: self.api_adaptor = api_adaptor else: _print('about to load api adaptor for extension ' + self.extension_name) api_adaptor_class = self.loadClass(options, 'api_adaptor') self.api_adaptor = api_adaptor_class(options)
def test_persist(): state = State(last_item_id='4') state.persist() #store ro disk restored_state = State() #loads from disk assert restored_state.last_item_id == '4' restored_state.setLastItemId('6') #also persist restored_second_state = State() #loads from disk assert restored_second_state.last_item_id == '6'
def test_no_new_items(): paginator = Paginator(options=options, api_adaptor=api_mock([first_page]), state=State(last_item_id='1')) paginator.next() assert unwrap(paginator.fetchPageItems()) == None paginator.next() assert unwrap(paginator.fetchPageItems()) == None
def test_negative_max_pages(): paginator = Paginator(options={ **options, **options_negative_max_page }, api_adaptor=api_mock(two_pages), state=State(last_item_id='5')) is_available = paginator.next() assert is_available == False
def test_one_item(): paginator = Paginator(options=options, api_adaptor=api_mock([first_page]), state=State(last_item_id='2')) paginator.next() assert unwrap(paginator.fetchPageItems()) == [{'id': '1'}] paginator.next() items = unwrap(paginator.fetchPageItems()) assert items == None
def test_4_items(): paginator = Paginator(options=options, api_adaptor=api_mock(two_pages), state=State(last_item_id='5')) paginator.next() items = unwrap(paginator.fetchPageItems()) assert items == first_page paginator.next() items = unwrap(paginator.fetchPageItems()) assert items == [{'id': '4'}] paginator.next() items = unwrap(paginator.fetchPageItems()) assert items == None
def test_state_based_pagination(): state = State() assert state.last_item_id == '' mocker = api_mock([first_page]) paginator = Paginator(options=options, api_adaptor=mocker, state=state) paginator.next() items = unwrap(paginator.fetchPageItems()) assert items == first_page mocker.setPages([second_page, first_page]) paginator.reset() paginator.next() items = unwrap(paginator.fetchPageItems()) assert items == second_page paginator.next() items = unwrap(paginator.fetchPageItems()) assert items == None mocker.setPages([fourth_page, third_page, second_page, first_page]) paginator.reset() paginator.next() items = unwrap(paginator.fetchPageItems()) assert items == fourth_page paginator.next() items = unwrap(paginator.fetchPageItems()) assert items == third_page paginator.next() items = unwrap(paginator.fetchPageItems()) assert items == None mocker.setPages([fourth_page]) paginator.reset() paginator.next() items = unwrap(paginator.fetchPageItems()) assert items == None
def test_max_pages(): paginator = Paginator(options={ **options, **options_two_page }, api_adaptor=api_mock(three_pages), state=State(last_item_id='100')) paginator.next() items = unwrap(paginator.fetchPageItems()) assert items == first_page is_available = paginator.next() assert is_available == True items = unwrap(paginator.fetchPageItems()) assert items == second_page is_available = paginator.next() assert is_available == False
def test_persist_invalid_path(): state = State(last_item_id='4', persit_path='/invalid_path/mock.obj') state.persist() #should persist to disk but fails due to bad path restored_state = State() #loads from disk assert restored_state.last_item_id == '' #value lost - due to invalid persist path
class Paginator: def __init__(self, options, state=None, api_adaptor=None, extension_name='extension_name'): _print('init: Paginator') if (state is None): self.state = State() else: self.state = state self.extension_name = extension_name self.reset() try: self.max_pages = int(options['max_pages']) _print('about to load formatters') self.formatter = self.loadFormatter(options) except Exception as ex: _print(ex) _print('could not initialize Paginator.') raise if api_adaptor is not None: self.api_adaptor = api_adaptor else: _print('about to load api adaptor for extension ' + self.extension_name) api_adaptor_class = self.loadClass(options, 'api_adaptor') self.api_adaptor = api_adaptor_class(options) def loadClass(self, options, type_name): _print('about to load ' + type_name + ' class...') module_name = options[self.extension_name + '.' + type_name + '_module'] class_name = options[self.extension_name + '.' + type_name + '_class'] _print('about to load from module:' + module_name) _print('about to load class:' + class_name) module = __import__(module_name, fromlist=[class_name]) _class = getattr(module, class_name) return _class def loadFormatter(self, options): _print('about to load formatter for extension ' + self.extension_name) formatter_class = self.loadClass(options, 'formatter') formatter_class.options = options return formatter_class def reset(self): try: self.state.setLastItemId(self.current_item_id) except: pass self.page_num = -1 self.current_item_id = '' self.is_end = False def isNextAvailable(self): is_not_maxed = self.max_pages >= 0 and ( self.max_pages == 0 or (self.page_num + 1) < self.max_pages) is_not_reached_end = not self.is_end return is_not_reached_end and is_not_maxed def next(self): if self.isNextAvailable(): self.page_num += 1 return True else: return False def filterItems(self, items): if items is None or len(items) == 0: return None filtered_items = [] if self.current_item_id == '': self.current_item_id = items[0].getID() for item in items: if item.getID() != self.state.last_item_id: filtered_items.append(item) else: #_print('Current Record ID: ' + item.getID() + ' matched last record id from state: ' + self.state.last_item_id ) self.state.setLastItemId(self.current_item_id) self.is_end = True break if len(filtered_items) == 0: return None else: return filtered_items def fetchPageItems(self): if self.is_end: return None response_json = self.api_adaptor.fetchItems(self.page_num) if response_json is not None: try: items = self.formatter.wrapItems(response_json) except Exception as ex: _print(ex) items = None return self.filterItems(items) else: return None