def test_loan_becomes_hold_if_no_available_copies_and_preexisting_loan(
            self):
        # Once upon a time, we had a loan for this book.
        loan, ignore = self.pool.loan_to(self.patron)
        loan.start = self.YESTERDAY

        # But no longer! What's more, other patrons have taken all the
        # copies!
        self.remote.queue_checkout(NoAvailableCopies())
        holdinfo = HoldInfo(self.pool.collection, self.pool.data_source,
                            self.identifier.type, self.identifier.identifier,
                            None, None, 10)
        self.remote.queue_hold(holdinfo)

        eq_([], self.remote.availability_updated_for)

        # As such, an attempt to renew our loan results in us actually
        # placing a hold on the book.
        loan, hold, is_new = self.borrow()
        eq_(None, loan)
        eq_(True, is_new)
        eq_(self.pool, hold.license_pool)
        eq_(self.patron, hold.patron)

        # When NoAvailableCopies was raised, the circulation
        # information for the book was immediately updated, to reduce
        # the risk that other patrons would encounter the same
        # problem.
        eq_([self.pool], self.remote.availability_updated_for)
    def test_hold_sends_analytics_event(self):
        self.remote.queue_checkout(NoAvailableCopies())
        holdinfo = HoldInfo(self.pool.collection, self.pool.data_source,
                            self.identifier.type, self.identifier.identifier,
                            None, None, 10)
        self.remote.queue_hold(holdinfo)

        loan, hold, is_new = self.borrow()

        # The Hold looks good.
        eq_(holdinfo.identifier, hold.license_pool.identifier.identifier)
        eq_(self.patron, hold.patron)
        eq_(None, loan)
        eq_(True, is_new)

        # An analytics event was created.
        eq_(1, self.analytics.count)
        eq_(CirculationEvent.CM_HOLD_PLACE, self.analytics.event_type)

        # Try to 'borrow' the same book again.
        self.remote.queue_checkout(AlreadyOnHold())
        loan, hold, is_new = self.borrow()
        eq_(False, is_new)

        # Since the hold already existed, no new analytics event was
        # sent.
        eq_(1, self.analytics.count)
Esempio n. 3
0
    def test_loan_becomes_hold_if_no_available_copies(self):
        # We want to borrow this book but there are no copies.
        self.remote.queue_checkout(NoAvailableCopies())
        self.remote.queue_hold(
            HoldInfo(self.identifier.type, self.identifier.identifier, None,
                     None, 10))

        # As such, an attempt to renew our loan results in us actually
        # placing a hold on the book.
        loan, hold, is_new = self.borrow()
        eq_(None, loan)
        eq_(True, is_new)
        eq_(self.pool, hold.license_pool)
        eq_(self.patron, hold.patron)
Esempio n. 4
0
    def test_borrow_creates_hold_if_api_returns_hold_info(self):
        # There are no available copies, but the remote API
        # places a hold for us right away instead of raising
        # an error.
        holdinfo = HoldInfo(self.pool.collection, self.pool.data_source,
                            self.identifier.type, self.identifier.identifier,
                            None, None, 10)
        self.remote.queue_checkout(holdinfo)

        # As such, an attempt to borrow results in us actually
        # placing a hold on the book.
        loan, hold, is_new = self.borrow()
        eq_(None, loan)
        eq_(True, is_new)
        eq_(self.pool, hold.license_pool)
        eq_(self.patron, hold.patron)
    def test_borrow_hold_limit_reached(self):
        # The hold limit is 1, and the patron has a previous hold.
        self.patron.library.setting(Configuration.HOLD_LIMIT).value = 1
        other_pool = self._licensepool(None)
        other_pool.open_access = False
        other_pool.on_hold_to(self.patron)

        now = datetime.now()
        holdinfo = HoldInfo(self.pool.collection, self.pool.data_source,
                            self.pool.identifier.type,
                            self.pool.identifier.identifier, now,
                            now + timedelta(seconds=3600), 10)
        self.remote.queue_checkout(NoAvailableCopies())
        self.remote.queue_hold(holdinfo)

        assert_raises(PatronHoldLimitReached, self.borrow)

        # If we increase the limit, borrow succeeds.
        self.patron.library.setting(Configuration.HOLD_LIMIT).value = 2
        self.remote.queue_checkout(NoAvailableCopies())
        loan, hold, is_new = self.borrow()
        assert hold != None
Esempio n. 6
0
    def test_hold_sends_analytics_event(self):
        self.remote.queue_checkout(NoAvailableCopies())
        holdinfo = HoldInfo(self.identifier.type, self.identifier.identifier,
                            None, None, 10)
        self.remote.queue_hold(holdinfo)

        config = {
            Configuration.POLICIES: {
                Configuration.ANALYTICS_POLICY:
                ["core.mock_analytics_provider"]
            }
        }
        with temp_config(config) as config:
            provider = MockAnalyticsProvider()
            analytics = Analytics.initialize(['core.mock_analytics_provider'],
                                             config)
            loan, hold, is_new = self.borrow()

            # The Hold looks good.
            eq_(holdinfo.identifier, hold.license_pool.identifier.identifier)
            eq_(self.patron, hold.patron)
            eq_(None, loan)
            eq_(True, is_new)

            # An analytics event was created.
            mock = Analytics.instance().providers[0]
            eq_(1, mock.count)
            eq_(CirculationEvent.CM_HOLD_PLACE, mock.event_type)

            # Try to 'borrow' the same book again.
            self.remote.queue_checkout(AlreadyOnHold())
            loan, hold, is_new = self.borrow()
            eq_(False, is_new)

            # Since the hold already existed, no new analytics event was
            # sent.
            eq_(1, mock.count)
Esempio n. 7
0
 def add_remote_hold(self, *args, **kwargs):
     self.remote_holds.append(HoldInfo(*args, **kwargs))