def test_sync_bookshelf_creates_local_loans(self): loans_data, json_loans = self.sample_json( "shelf_with_some_checked_out_books.json") holds_data, json_holds = self.sample_json("no_holds.json") overdrive = MockOverdriveAPI(self._db) overdrive.queue_response(200, content=loans_data) overdrive.queue_response(200, content=holds_data) patron = self._patron() circulation = CirculationAPI(self._db, overdrive=overdrive) loans, holds = circulation.sync_bookshelf(patron, "dummy pin") # All four loans in the sample data were created. eq_(4, len(loans)) eq_(loans, patron.loans) eq_([], holds) # Running the sync again leaves all four loans in place. overdrive.queue_response(200, content=loans_data) overdrive.queue_response(200, content=holds_data) loans, holds = circulation.sync_bookshelf(patron, "dummy pin") eq_(4, len(loans)) eq_(loans, patron.loans)
def test_sync_bookshelf(self): patron = self._patron() circulation = CirculationAPI( self._db, self._default_library, api_map={self.collection.protocol: MockBibliothecaAPI}) api = circulation.api_for_collection[self.collection.id] api.queue_response(200, content=self.sample_data("checkouts.xml")) circulation.sync_bookshelf(patron, "dummy pin") # The patron should have two loans and two holds. l1, l2 = patron.loans h1, h2 = patron.holds eq_(datetime.datetime(2015, 3, 20, 18, 50, 22), l1.start) eq_(datetime.datetime(2015, 4, 10, 18, 50, 22), l1.end) eq_(datetime.datetime(2015, 3, 13, 13, 38, 19), l2.start) eq_(datetime.datetime(2015, 4, 3, 13, 38, 19), l2.end) # This hold has no end date because there's no decision to be # made. The patron is fourth in line. eq_(datetime.datetime(2015, 3, 24, 15, 6, 56), h1.start) eq_(None, h1.end) eq_(4, h1.position) # The hold has an end date. It's time for the patron to decide # whether or not to check out this book. eq_(datetime.datetime(2015, 5, 25, 17, 5, 34), h2.start) eq_(datetime.datetime(2015, 5, 27, 17, 5, 34), h2.end) eq_(0, h2.position)
def basic_test(self): patron = self._patron() api = DummyThreeMAPI(self._db) api.queue_response(content=self.sample_data("checkouts.xml")) circulation = CirculationAPI(self._db, threem=api) circulation.sync_bookshelf(patron, "dummy pin") # The patron should have two loans and two holds. l1, l2 = patron.loans h1, h2 = patron.holds eq_(datetime.datetime(2015, 3, 20, 18, 50, 22), l1.start) eq_(datetime.datetime(2015, 4, 10, 18, 50, 22), l1.end) eq_(datetime.datetime(2015, 3, 13, 13, 38, 19), l2.start) eq_(datetime.datetime(2015, 4, 3, 13, 38, 19), l2.end) # This hold has no end date because there's no decision to be # made. The patron is fourth in line. eq_(datetime.datetime(2015, 3, 24, 15, 6, 56), h1.start) eq_(None, h1.end) eq_(4, h1.position) # The hold has an end date. It's time for the patron to decide # whether or not to check out this book. eq_(datetime.datetime(2015, 5, 25, 17, 5, 34), h2.start) eq_(datetime.datetime(2015, 5, 27, 17, 5, 34), h2.end) eq_(0, h2.position)
def test_sync_bookshelf_removes_loans_not_present_on_remote(self): loans_data, json_loans = self.sample_json( "shelf_with_some_checked_out_books.json") holds_data, json_holds = self.sample_json("no_holds.json") overdrive = MockOverdriveAPI(self._db) overdrive.queue_response(200, content=loans_data) overdrive.queue_response(200, content=holds_data) # Create a loan not present in the sample data. patron = self._patron() overdrive_edition, new = self._edition( data_source_name=DataSource.OVERDRIVE, with_license_pool=True) overdrive_loan, new = overdrive_edition.license_pool.loan_to(patron) yesterday = datetime.utcnow() - timedelta(days=1) overdrive_loan.start = yesterday # Sync with Overdrive, and the loan not present in the sample # data is removed. circulation = CirculationAPI(self._db, overdrive=overdrive) loans, holds = circulation.sync_bookshelf(patron, "dummy pin") eq_(4, len(loans)) eq_(loans, patron.loans) assert overdrive_loan not in patron.loans
def test_sync_bookshelf_creates_local_holds(self): loans_data, json_loans = self.sample_json("no_loans.json") holds_data, json_holds = self.sample_json("holds.json") overdrive = DummyOverdriveAPI(self._db) overdrive.queue_response(content=holds_data) overdrive.queue_response(content=loans_data) circulation = CirculationAPI(self._db, overdrive=overdrive) patron = self.default_patron loans, holds = circulation.sync_bookshelf(patron, "dummy pin") # All four loans in the sample data were created. eq_(4, len(holds)) eq_(holds, patron.holds) # Running the sync again leaves all four holds in place. overdrive.queue_response(content=holds_data) overdrive.queue_response(content=loans_data) circulation = CirculationAPI(self._db, overdrive=overdrive) loans, holds = circulation.sync_bookshelf(patron, "dummy pin") eq_(4, len(holds)) eq_(holds, patron.holds)
def test_sync_bookshelf_ignores_holds_from_other_sources(self): loans_data, json_loans = self.sample_json("no_loans.json") holds_data, json_holds = self.sample_json("holds.json") patron = self._patron() threem, new = self._edition(data_source_name=DataSource.THREEM, with_license_pool=True) threem_hold, new = threem.license_pool.on_hold_to(patron) overdrive = MockOverdriveAPI(self._db) overdrive.queue_response(200, content=loans_data) overdrive.queue_response(200, content=holds_data) # Overdrive doesn't know about the 3M hold, but it was # not destroyed, because it came from another source. circulation = CirculationAPI(self._db, overdrive=overdrive) loans, holds = circulation.sync_bookshelf(patron, "dummy pin") eq_(5, len(patron.holds)) assert threem_hold in patron.holds
def test_sync_bookshelf_removes_holds_not_present_on_remote(self): loans_data, json_loans = self.sample_json("no_loans.json") holds_data, json_holds = self.sample_json("holds.json") patron = self._patron() overdrive_edition, new = self._edition( data_source_name=DataSource.OVERDRIVE, with_license_pool=True) overdrive_hold, new = overdrive_edition.license_pool.on_hold_to(patron) overdrive = MockOverdriveAPI(self._db) overdrive.queue_response(200, content=loans_data) overdrive.queue_response(200, content=holds_data) # The hold not present in the sample data has been removed circulation = CirculationAPI(self._db, overdrive=overdrive) loans, holds = circulation.sync_bookshelf(patron, "dummy pin") eq_(4, len(holds)) eq_(holds, patron.holds) assert overdrive_hold not in patron.loans
def test_sync_bookshelf_ignores_loans_from_other_sources(self): patron = self._patron() gutenberg, new = self._edition(data_source_name=DataSource.GUTENBERG, with_license_pool=True) gutenberg_loan, new = gutenberg.license_pool.loan_to(patron) loans_data, json_loans = self.sample_json( "shelf_with_some_checked_out_books.json") holds_data, json_holds = self.sample_json("no_holds.json") # Overdrive doesn't know about the Gutenberg loan, but it was # not destroyed, because it came from another source. overdrive = MockOverdriveAPI(self._db) overdrive.queue_response(200, content=loans_data) overdrive.queue_response(200, content=holds_data) circulation = CirculationAPI(self._db, overdrive=overdrive) loans, holds = circulation.sync_bookshelf(patron, "dummy pin") eq_(5, len(patron.loans)) assert gutenberg_loan in patron.loans
def test_sync_bookshelf_ignores_holds_from_other_sources(self): loans_data, json_loans = self.sample_json("no_loans.json") holds_data, json_holds = self.sample_json("holds.json") patron = self.default_patron threem, new = self._edition(data_source_name=DataSource.THREEM, with_license_pool=True) threem_hold, new = threem.license_pool.on_hold_to(patron) overdrive = DummyOverdriveAPI(self._db) overdrive.queue_response(content=holds_data) overdrive.queue_response(content=loans_data) # Overdrive doesn't know about the 3M hold, but it was # not destroyed, because it came from another source. circulation = CirculationAPI(self._db, overdrive=overdrive) loans, holds = circulation.sync_bookshelf(patron, "dummy pin") eq_(5, len(patron.holds)) assert threem_hold in patron.holds
def test_sync_bookshelf_ignores_loans_from_other_sources(self): patron = self.default_patron gutenberg, new = self._edition(data_source_name=DataSource.GUTENBERG, with_license_pool=True) gutenberg_loan, new = gutenberg.license_pool.loan_to(patron) loans_data, json_loans = self.sample_json("shelf_with_some_checked_out_books.json") holds_data, json_holds = self.sample_json("no_holds.json") # Overdrive doesn't know about the Gutenberg loan, but it was # not destroyed, because it came from another source. overdrive = DummyOverdriveAPI(self._db) overdrive.queue_response(content=holds_data) overdrive.queue_response(content=loans_data) circulation = CirculationAPI(self._db, overdrive=overdrive) patron = self.default_patron loans, holds = circulation.sync_bookshelf(patron, "dummy pin") eq_(5, len(patron.loans)) assert gutenberg_loan in patron.loans
def test_sync_bookshelf_removes_holds_not_present_on_remote(self): loans_data, json_loans = self.sample_json("no_loans.json") holds_data, json_holds = self.sample_json("holds.json") patron = self.default_patron overdrive_edition, new = self._edition(data_source_name=DataSource.OVERDRIVE, with_license_pool=True) overdrive_hold, new = overdrive_edition.license_pool.on_hold_to(patron) overdrive = DummyOverdriveAPI(self._db) overdrive.queue_response(content=holds_data) overdrive.queue_response(content=loans_data) # The hold not present in the sample data has been removed circulation = CirculationAPI(self._db, overdrive=overdrive) loans, holds = circulation.sync_bookshelf(patron, "dummy pin") eq_(4, len(holds)) eq_(holds, patron.holds) assert overdrive_hold not in patron.loans
def test_sync_bookshelf_removes_loans_not_present_on_remote(self): loans_data, json_loans = self.sample_json("shelf_with_some_checked_out_books.json") holds_data, json_holds = self.sample_json("no_holds.json") overdrive = DummyOverdriveAPI(self._db) overdrive.queue_response(content=holds_data) overdrive.queue_response(content=loans_data) # Create a loan not present in the sample data. patron = self.default_patron overdrive_edition, new = self._edition( data_source_name=DataSource.OVERDRIVE, with_license_pool=True ) overdrive_loan, new = overdrive_edition.license_pool.loan_to(patron) # Sync with Overdrive, and the loan not present in the sample # data is removed. circulation = CirculationAPI(self._db, overdrive=overdrive) loans, holds = circulation.sync_bookshelf(patron, "dummy pin") eq_(4, len(loans)) eq_(loans, patron.loans) assert overdrive_loan not in patron.loans