def test_default_start_time(self):
        monitor = BibliothecaEventMonitor(self._db,
                                          self.collection,
                                          api_class=MockBibliothecaAPI)
        expected = datetime.datetime.utcnow() - monitor.DEFAULT_START_TIME

        # When the monitor has never been run before, the default
        # start time is a date long in the past.
        assert abs(
            (expected - monitor.default_start_time).total_seconds()) <= 1
        default_start_time = monitor.create_default_start_time(self._db, [])
        assert abs((expected - default_start_time).total_seconds()) <= 1

        # It's possible to override this by instantiating
        # BibliothecaEventMonitor with a specific date.
        monitor = BibliothecaEventMonitor(self._db,
                                          self.collection,
                                          api_class=MockBibliothecaAPI,
                                          cli_date="2011-01-01")
        expected = datetime.datetime(year=2011, month=1, day=1)
        eq_(expected, monitor.default_start_time)
        for cli_date in ('2011-01-01', ['2011-01-01']):
            default_start_time = monitor.create_default_start_time(
                self._db, cli_date)
            eq_(expected, default_start_time)

        # After Bibliotheca has been initialized,
        # create_default_start_time returns None, rather than a date
        # far in the bast, if no cli_date is passed in.
        Timestamp.stamp(self._db, monitor.service_name, self.collection)
        eq_(None, monitor.create_default_start_time(self._db, []))

        # Returns a date several years ago if args are formatted
        # improperly or the monitor has never been run before
        not_date_args = ['initialize']
        too_many_args = ['2013', '04', '02']
        for args in [not_date_args, too_many_args]:
            actual_default_start_time = monitor.create_default_start_time(
                self._db, args)
            eq_(True, isinstance(actual_default_start_time, datetime.datetime))
            assert (default_start_time -
                    actual_default_start_time).total_seconds() <= 1

        # Returns an appropriate date if command line arguments are passed
        # as expected
        proper_args = ['2013-04-02']
        default_start_time = monitor.create_default_start_time(
            self._db, proper_args)
        eq_(datetime.datetime(2013, 4, 2), default_start_time)
    def test_run_once(self):
        api = MockBibliothecaAPI(self._db, self.collection)
        api.queue_response(
            200, content=self.sample_data("empty_end_date_event.xml"))
        api.queue_response(
            200, content=self.sample_data("item_metadata_single.xml"))
        monitor = BibliothecaEventMonitor(self._db,
                                          self.collection,
                                          api_class=api)
        now = datetime.datetime.utcnow()
        yesterday = now - datetime.timedelta(days=1)

        new_timestamp = monitor.run_once(yesterday, now)

        # Two requests were made to the API -- one to find events
        # and one to look up detailed information about the book
        # whose event we learned of.
        eq_(2, len(api.requests))

        # The result, which will be used as the new timestamp, is very
        # close to the time we called run_once(). It represents the
        # point at which we should expect new events to start showing
        # up.
        assert (new_timestamp - now).seconds < 2

        # A LicensePool was created for the identifier referred to
        # in empty_end_date_event.xml.
        [pool] = self.collection.licensepools
        eq_("d5rf89", pool.identifier.identifier)

        # But since the metadata retrieved in the follow-up request
        # was for a different book, no Work and no Edition have been
        # created. (See test_handle_event for what happens when the
        # API cooperates.)
        eq_(None, pool.work)
        eq_(None, pool.presentation_edition)

        # If we tell run_once() to work through a zero amount of time,
        # it does nothing.
        new_timestamp = monitor.run_once(yesterday, yesterday)
        eq_(new_timestamp, yesterday)
示例#3
0
    def test_default_start_time(self):
        monitor = BibliothecaEventMonitor(
            self._db, self.collection, api_class=MockBibliothecaAPI
        )
        expected = datetime.datetime.utcnow() - monitor.DEFAULT_START_TIME

        # Returns a date long in the past if the monitor has never
        # been run before.
        default_start_time = monitor.create_default_start_time(self._db, [])
        assert abs((expected-default_start_time).total_seconds()) <= 1

        # After Bibliotheca has been initialized, it returns None if no
        # arguments are passed
        Timestamp.stamp(self._db, monitor.service_name, self.collection)
        eq_(None, monitor.create_default_start_time(self._db, []))

        # Returns a date several years ago if args are formatted
        # improperly or the monitor has never been run before
        not_date_args = ['initialize']
        too_many_args = ['2013', '04', '02']
        for args in [not_date_args, too_many_args]:
            actual_default_start_time = monitor.create_default_start_time(self._db, args)
            eq_(True, isinstance(actual_default_start_time, datetime.datetime))
            assert (default_start_time - actual_default_start_time).total_seconds() <= 1

        # Returns an appropriate date if command line arguments are passed
        # as expected
        proper_args = ['2013-04-02']
        default_start_time = monitor.create_default_start_time(self._db, proper_args)
        eq_(datetime.datetime(2013, 4, 2), default_start_time)
    def test_handle_event(self):
        api = MockBibliothecaAPI(self._db, self.collection)
        api.queue_response(
            200, content=self.sample_data("item_metadata_single.xml"))
        analytics = MockAnalyticsProvider()
        monitor = BibliothecaEventMonitor(self._db,
                                          self.collection,
                                          api_class=api,
                                          analytics=analytics)

        now = datetime.datetime.utcnow()
        monitor.handle_event("ddf4gr9", "9781250015280", None, now, None,
                             CirculationEvent.DISTRIBUTOR_LICENSE_ADD)

        # The collection now has a LicensePool corresponding to the book
        # we just loaded.
        [pool] = self.collection.licensepools
        eq_("ddf4gr9", pool.identifier.identifier)

        # The book has a presentation-ready work and we know its
        # bibliographic metadata.
        eq_(True, pool.work.presentation_ready)
        eq_("The Incense Game", pool.work.title)

        # The LicensePool's circulation information has been changed
        # to reflect what we know about the book -- that we have one
        # license which (as of the instant the event happened) is
        # available.
        eq_(1, pool.licenses_owned)
        eq_(1, pool.licenses_available)

        # Three analytics events were collected: one for the license add
        # event itself, one for the 'checkin' that made the new
        # license available, and one for the first appearance of a new
        # LicensePool.
        eq_(3, analytics.count)