コード例 #1
0
    def test_update_existing_licensepool(self):
        data, raw = self.sample_json("overdrive_availability_information.json")

        # Create a LicensePool.
        wr, pool = self._edition(data_source_name=DataSource.OVERDRIVE,
                                 identifier_type=Identifier.OVERDRIVE_ID,
                                 with_license_pool=True)

        # Make it look like the availability information is for the
        # newly created LicensePool.
        raw['id'] = pool.identifier.identifier

        wr.title = "The real title."
        eq_(1, pool.licenses_owned)
        eq_(1, pool.licenses_available)
        eq_(0, pool.licenses_reserved)
        eq_(0, pool.patrons_in_hold_queue)

        api = MockOverdriveAPI(self._db)
        p2, was_new, changed = api.update_licensepool_with_book_info(
            raw, pool, False)
        eq_(False, was_new)
        eq_(True, changed)
        eq_(p2, pool)
        # The title didn't change to that title given in the availability
        # information, because we already set a title for that work.
        eq_("The real title.", wr.title)
        eq_(raw['copiesOwned'], pool.licenses_owned)
        eq_(raw['copiesAvailable'], pool.licenses_available)
        eq_(0, pool.licenses_reserved)
        eq_(raw['numberOfHolds'], pool.patrons_in_hold_queue)
コード例 #2
0
    def test_update_new_licensepool(self):
        data, raw = self.sample_json("overdrive_availability_information.json")

        # Create an identifier
        identifier = self._identifier(identifier_type=Identifier.OVERDRIVE_ID)

        # Make it look like the availability information is for the
        # newly created Identifier.
        raw['id'] = identifier.identifier

        api = MockOverdriveAPI(self._db)
        pool, was_new = LicensePool.for_foreign_id(self._db,
                                                   DataSource.OVERDRIVE,
                                                   identifier.type,
                                                   identifier.identifier)

        pool, was_new, changed = api.update_licensepool_with_book_info(
            raw, pool, was_new)
        eq_(True, was_new)
        eq_(True, changed)

        self._db.commit()

        eq_(raw['copiesOwned'], pool.licenses_owned)
        eq_(raw['copiesAvailable'], pool.licenses_available)
        eq_(0, pool.licenses_reserved)
        eq_(raw['numberOfHolds'], pool.patrons_in_hold_queue)
コード例 #3
0
    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
コード例 #4
0
    def test_process_checkout_data(self):
        data, json = self.sample_json("shelf_with_book_already_fulfilled_on_kindle.json")
        [on_kindle, not_on_kindle] = json["checkouts"]

        # The book already fulfilled on Kindle doesn't get turned into
        # LoanInfo at all.
        eq_(None, MockOverdriveAPI.process_checkout_data(on_kindle, self.collection))

        # The book not yet fulfilled does show up as a LoanInfo.
        loan_info = MockOverdriveAPI.process_checkout_data(not_on_kindle, self.collection)
        eq_("2fadd2ac-a8ec-4938-a369-4c3260e8922b", loan_info.identifier)

        # Since there are two usable formats (Adobe EPUB and Adobe
        # PDF), the LoanInfo is not locked to any particular format.
        eq_(None, loan_info.locked_to)

        # A book that's on loan and locked to a specific format has a
        # DeliveryMechanismInfo associated with that format.
        data, format_locked_in = self.sample_json("checkout_response_locked_in_format.json")
        loan_info = MockOverdriveAPI.process_checkout_data(format_locked_in, self.collection)
        delivery = loan_info.locked_to
        eq_(Representation.EPUB_MEDIA_TYPE, delivery.content_type)
        eq_(DeliveryMechanism.ADOBE_DRM, delivery.drm_scheme)

        # This book is on loan and the choice between Kindle and Adobe
        # EPUB has not yet been made, but as far as we're concerned,
        # Adobe EPUB is the only *usable* format, so it's effectively
        # locked.
        data, no_format_locked_in = self.sample_json("checkout_response_no_format_locked_in.json")
        loan_info = MockOverdriveAPI.process_checkout_data(no_format_locked_in, self.collection)
        assert loan_info != None
        delivery = loan_info.locked_to
        eq_(Representation.EPUB_MEDIA_TYPE, delivery.content_type)
        eq_(DeliveryMechanism.ADOBE_DRM, delivery.drm_scheme)
コード例 #5
0
    def test_process_checkout_data(self):
        data, json = self.sample_json("shelf_with_book_already_fulfilled_on_kindle.json")
        [on_kindle, not_on_kindle] = json["checkouts"]

        # The book already fulfilled on Kindle doesn't get turned into
        # LoanInfo at all.
        eq_(None, MockOverdriveAPI.process_checkout_data(on_kindle, self.collection))

        # The book not yet fulfilled does show up as a LoanInfo.
        loan_info = MockOverdriveAPI.process_checkout_data(not_on_kindle, self.collection)
        eq_("2fadd2ac-a8ec-4938-a369-4c3260e8922b", loan_info.identifier)

        # Since there are two usable formats (Adobe EPUB and Adobe
        # PDF), the LoanInfo is not locked to any particular format.
        eq_(None, loan_info.locked_to)

        # A book that's on loan and locked to a specific format has a
        # DeliveryMechanismInfo associated with that format.
        data, format_locked_in = self.sample_json("checkout_response_locked_in_format.json")
        loan_info = MockOverdriveAPI.process_checkout_data(format_locked_in, self.collection)
        delivery = loan_info.locked_to
        eq_(Representation.EPUB_MEDIA_TYPE, delivery.content_type)
        eq_(DeliveryMechanism.ADOBE_DRM, delivery.drm_scheme)

        # This book is on loan and the choice between Kindle and Adobe
        # EPUB has not yet been made, but as far as we're concerned,
        # Adobe EPUB is the only *usable* format, so it's effectively
        # locked.
        data, no_format_locked_in = self.sample_json("checkout_response_no_format_locked_in.json")
        loan_info = MockOverdriveAPI.process_checkout_data(no_format_locked_in, self.collection)
        assert loan_info != None
        delivery = loan_info.locked_to
        eq_(Representation.EPUB_MEDIA_TYPE, delivery.content_type)
        eq_(DeliveryMechanism.ADOBE_DRM, delivery.drm_scheme)
コード例 #6
0
    def test_process_checkout_data(self):
        data, json = self.sample_json(
            "shelf_with_book_already_fulfilled_on_kindle.json")
        [on_kindle, not_on_kindle] = json["checkouts"]

        # The book already fulfilled on Kindle doesn't get turned into
        # LoanInfo.
        eq_(None, MockOverdriveAPI.process_checkout_data(on_kindle))

        # The book not yet fulfilled does show up as a LoanInfo.
        loan_info = MockOverdriveAPI.process_checkout_data(not_on_kindle)
        eq_("2fadd2ac-a8ec-4938-a369-4c3260e8922b", loan_info.identifier)

        data, format_locked_in = self.sample_json(
            "checkout_response_locked_in_format.json")

        # A book that's on loan with a format locked in shows up.
        loan_info = MockOverdriveAPI.process_checkout_data(format_locked_in)
        assert loan_info != None

        data, no_format_locked_in = self.sample_json(
            "checkout_response_no_format_locked_in.json")

        # A book that's on loan with no format locked in also shows up.
        loan_info = MockOverdriveAPI.process_checkout_data(no_format_locked_in)
        assert loan_info != None
コード例 #7
0
 def test_update_licensepool_error(self):
     # Create an identifier.
     identifier = self._identifier(identifier_type=Identifier.OVERDRIVE_ID)
     ignore, availability = self.sample_json(
         "overdrive_availability_information.json")
     api = MockOverdriveAPI(self._db)
     api.queue_response(500, content="An error occured.")
     book = dict(id=identifier.identifier, availability_link=self._url)
     pool, was_new, changed = api.update_licensepool(book)
     eq_(None, pool)
コード例 #8
0
    def test_circulation_lookup(self):
        """Test the method that actually looks up Overdrive circulation
        information.
        """
        api = MockOverdriveAPI(self._db)
        api.queue_response(200, content="foo")

        book, (status_code, headers,
               content) = api.circulation_lookup("an identifier")
        eq_(dict(id="an identifier"), book)
        eq_(200, status_code)
        eq_("foo", content)
コード例 #9
0
    def test_update_licensepool_with_holds(self):
        data, raw = self.sample_json(
            "overdrive_availability_information_holds.json")
        identifier = self._identifier(identifier_type=Identifier.OVERDRIVE_ID)
        raw['id'] = identifier.identifier

        api = MockOverdriveAPI(self._db)
        license_pool, is_new = LicensePool.for_foreign_id(
            self._db, DataSource.OVERDRIVE, identifier.type,
            identifier.identifier)
        pool, was_new, changed = api.update_licensepool_with_book_info(
            raw, license_pool, is_new)
        eq_(10, pool.patrons_in_hold_queue)
        eq_(True, changed)
コード例 #10
0
    def test_refresh_patron_access_token(self):
        """Verify that patron information is included in the request
        when refreshing a patron access token.
        """
        api = MockOverdriveAPI(self._db)
        patron = self._patron()
        patron.authorization_identifier = 'barcode'
        credential = self._credential(patron=patron)

        data, raw = self.sample_json("patron_token.json")
        api.queue_response(200, content=raw)

        # Try to refresh the patron access token with a PIN, and
        # then without a PIN.
        api.refresh_patron_access_token(credential, patron, "a pin")

        api.refresh_patron_access_token(credential, patron, None)

        # Verify that the requests that were made correspond to what
        # Overdrive is expecting.
        initial, with_pin, without_pin = api.access_token_requests
        url, payload, headers, kwargs = with_pin
        eq_("https://oauth-patron.overdrive.com/patrontoken", url)
        eq_("barcode", payload['username'])
        eq_("websiteid:d authorizationname:default", payload['scope'])
        eq_("a pin", payload['password'])
        assert not 'password_required' in payload

        url, payload, headers, kwargs = without_pin
        eq_("https://oauth-patron.overdrive.com/patrontoken", url)
        eq_("barcode", payload['username'])
        eq_("websiteid:d authorizationname:default", payload['scope'])
        eq_("false", payload['password_required'])
        eq_("[ignore]", payload['password'])
コード例 #11
0
 def test_extract_data_from_checkout_resource(self):
     data, json = self.sample_json("checkout_response_locked_in_format.json")
     expires, url = MockOverdriveAPI.extract_data_from_checkout_response(
         json, "ebook-epub-adobe", "http://foo.com/")
     eq_(2013, expires.year)
     eq_(10, expires.month)
     eq_(4, expires.day)
     eq_("http://patron.api.overdrive.com/v1/patrons/me/checkouts/76C1B7D0-17F4-4C05-8397-C66C17411584/formats/ebook-epub-adobe/downloadlink?errorpageurl=http://foo.com/", url)
コード例 #12
0
 def setup(self):
     super(OverdriveAPITest, self).setup()
     library = self._default_library
     self.collection = MockOverdriveAPI.mock_collection(self._db)
     self.circulation = CirculationAPI(
         self._db, library, api_map={ExternalIntegration.OVERDRIVE:MockOverdriveAPI}
     )
     self.api = self.circulation.api_for_collection[self.collection.id]
コード例 #13
0
 def setup(self):
     super(OverdriveAPITest, self).setup()
     library = self._default_library
     self.collection = MockOverdriveAPI.mock_collection(self._db)
     self.circulation = CirculationAPI(
         self._db, library, api_map={ExternalIntegration.OVERDRIVE:MockOverdriveAPI}
     )
     self.api = self.circulation.api_for_collection[self.collection.id]
コード例 #14
0
 def test_extract_data_from_checkout_resource(self):
     data, json = self.sample_json("checkout_response_locked_in_format.json")
     expires, url = MockOverdriveAPI.extract_data_from_checkout_response(
         json, "ebook-epub-adobe", "http://foo.com/")
     eq_(2013, expires.year)
     eq_(10, expires.month)
     eq_(4, expires.day)
     eq_("http://patron.api.overdrive.com/v1/patrons/me/checkouts/76C1B7D0-17F4-4C05-8397-C66C17411584/formats/ebook-epub-adobe/downloadlink?errorpageurl=http://foo.com/", url)
コード例 #15
0
    def test_place_hold_raises_exception_if_patron_over_hold_limit(self):
        over_hold_limit = self.error_message(
            "PatronExceededHoldLimit",
            "Patron cannot place any more holds, already has maximum holds placed."
        )

        edition, pool = self._edition(identifier_type=Identifier.OVERDRIVE_ID,
                                      data_source_name=DataSource.OVERDRIVE,
                                      with_license_pool=True)
        api = MockOverdriveAPI(self._db)
        api.queue_response(400, content=over_hold_limit)
        assert_raises(PatronHoldLimitReached,
                      api.place_hold,
                      self._patron(),
                      'pin',
                      pool,
                      notification_email_address='*****@*****.**')
コード例 #16
0
    def test_place_hold_looks_up_notification_address(self):
        edition, pool = self._edition(identifier_type=Identifier.OVERDRIVE_ID,
                                      data_source_name=DataSource.OVERDRIVE,
                                      with_license_pool=True)

        # The first request we make will be to get patron info,
        # so that we know that the most recent email address used
        # to put a book on hold is [email protected].
        ignore, patron_with_email = self.sample_json("patron_info.json")

        # The second request we make will be to put a book on hold,
        # and when we do so we will ask for the notification to be
        # sent to [email protected].
        ignore, successful_hold = self.sample_json("successful_hold.json")

        api = MockOverdriveAPI(self._db)
        api.queue_response(200, content=patron_with_email)
        api.queue_response(200, content=successful_hold)
        with temp_config() as config:
            config[
                'default_notification_email_address'] = "*****@*****.**"
            hold = api.place_hold(self._patron(),
                                  'pin',
                                  pool,
                                  notification_email_address=None)

        # The book was placed on hold.
        eq_(1, hold.hold_position)
        eq_(pool.identifier.identifier, hold.identifier)

        # And when we placed it on hold, we passed in [email protected]
        # as the email address -- not [email protected].
        url, positional_args, kwargs = api.requests[-1]
        headers, body = positional_args
        assert '{"name": "emailAddress", "value": "*****@*****.**"}' in body
コード例 #17
0
    def test_get_fulfillment_link_from_download_link(self):
        patron = self._patron()

        ignore, streaming_fulfill_link = self.sample_json(
            "streaming_fulfill_link_response.json")

        api = MockOverdriveAPI(self._db)
        api.queue_response(200, content=streaming_fulfill_link)

        href, type = api.get_fulfillment_link_from_download_link(
            patron,
            '1234',
            "http://download-link",
            fulfill_url="http://fulfill")
        eq_(
            "https://fulfill.contentreserve.com/PerfectLife9780345530967.epub-sample.overdrive.com?RetailerID=nypl&Expires=1469825647&Token=dd0e19b4-eb70-439d-8c50-a65201060f4c&Signature=asl67/G154KeeUsL1mHPwEbZfgc=",
            href)
        eq_("text/html", type)
コード例 #18
0
    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
コード例 #19
0
    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
コード例 #20
0
    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
コード例 #21
0
    def test_get_download_link(self):
        data, json = self.sample_json(
            "checkout_response_locked_in_format.json")
        url = MockOverdriveAPI.get_download_link(json, "ebook-epub-adobe",
                                                 "http://foo.com/")
        eq_(
            "http://patron.api.overdrive.com/v1/patrons/me/checkouts/76C1B7D0-17F4-4C05-8397-C66C17411584/formats/ebook-epub-adobe/downloadlink?errorpageurl=http://foo.com/",
            url)

        assert_raises(NoAcceptableFormat, MockOverdriveAPI.get_download_link,
                      json, "no-such-format", "http://foo.com/")
コード例 #22
0
    def test_get_download_link(self):
        data, json = self.sample_json("checkout_response_locked_in_format.json")
        url = MockOverdriveAPI.get_download_link(
            json, "ebook-epub-adobe", "http://foo.com/")
        eq_("http://patron.api.overdrive.com/v1/patrons/me/checkouts/76C1B7D0-17F4-4C05-8397-C66C17411584/formats/ebook-epub-adobe/downloadlink?errorpageurl=http://foo.com/", url)

        assert_raises(
            NoAcceptableFormat,
            MockOverdriveAPI.get_download_link,
            json, "no-such-format", "http://foo.com/"
        )
コード例 #23
0
    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)
コード例 #24
0
    def test_update_availability(self):
        """Test the Overdrive implementation of the update_availability
        method defined by the CirculationAPI interface.
        """

        # Create a LicensePool that needs updating.
        edition, pool = self._edition(
            identifier_type=Identifier.OVERDRIVE_ID,
            # TODO: If this line is commented out, we get an error later
            # on which might or might not be worrisome.
            data_source_name=DataSource.OVERDRIVE,
            with_license_pool=True)

        # We have never checked the circulation information for this
        # LicensePool. Put some random junk in the pool to make sure
        # it gets replaced.
        pool.licenses_owned = 10
        pool.licenses_available = 4
        pool.patrons_in_hold_queue = 3
        eq_(None, pool.last_checked)

        # Prepare availability information.
        ignore, availability = self.sample_json(
            "overdrive_availability_information.json")
        # Since this is the first time we've seen this book,
        # we'll also be updating the bibliographic information.
        ignore, bibliographic = self.sample_json(
            "bibliographic_information.json")

        # To avoid a mismatch, make it look like the information is
        # for the new pool's Identifier.
        availability['id'] = pool.identifier.identifier
        bibliographic['id'] = pool.identifier.identifier

        api = MockOverdriveAPI(self._db)
        api.queue_response(200, content=availability)
        api.queue_response(200, content=bibliographic)

        api.update_availability(pool)

        # The availability information has been udpated, as has the
        # date the availability information was last checked.
        eq_(5, pool.licenses_owned)
        eq_(5, pool.licenses_available)
        eq_(0, pool.patrons_in_hold_queue)
        assert pool.last_checked is not None
コード例 #25
0
    def test_update_licensepool_provides_bibliographic_coverage(self):
        # Create an identifier.
        identifier = self._identifier(identifier_type=Identifier.OVERDRIVE_ID)

        # Prepare bibliographic and availability information
        # for this identifier.
        ignore, availability = self.sample_json(
            "overdrive_availability_information.json")
        ignore, bibliographic = self.sample_json(
            "bibliographic_information.json")

        # To avoid a mismatch, make it look like the information is
        # for the newly created Identifier.
        availability['id'] = identifier.identifier
        bibliographic['id'] = identifier.identifier

        api = MockOverdriveAPI(self._db)
        api.queue_response(200, content=availability)
        api.queue_response(200, content=bibliographic)

        # Now we're ready. When we call update_licensepool, the
        # OverdriveAPI will retrieve the availability information,
        # then the bibliographic information. It will then trigger the
        # OverdriveBibliographicCoverageProvider, which will
        # create an Edition and a presentation-ready Work.
        pool, was_new, changed = api.update_licensepool(identifier.identifier)
        eq_(True, was_new)
        eq_(availability['copiesOwned'], pool.licenses_owned)

        edition = pool.presentation_edition
        eq_("Ancillary Justice", edition.title)

        eq_(True, pool.work.presentation_ready)
        assert pool.work.cover_thumbnail_url.startswith(
            'http://images.contentreserve.com/')

        # The book has been run through the bibliographic coverage
        # provider.
        coverage = [
            x for x in identifier.coverage_records if x.operation is None
            and x.data_source.name == DataSource.OVERDRIVE
        ]
        eq_(1, len(coverage))
コード例 #26
0
    def test_update_formats(self):
        # Create a LicensePool with an inaccurate delivery mechanism.
        edition, pool = self._edition(identifier_type=Identifier.OVERDRIVE_ID,
                                      with_license_pool=True)

        # Add the bad delivery mechanism.
        pool.set_delivery_mechanism(Representation.PDF_MEDIA_TYPE,
                                    DeliveryMechanism.ADOBE_DRM,
                                    RightsStatus.IN_COPYRIGHT, None)

        # Prepare the bibliographic information.
        ignore, bibliographic = self.sample_json(
            "bibliographic_information.json")

        # To avoid a mismatch, make it look like the information is
        # for the new pool's Identifier.
        bibliographic['id'] = pool.identifier.identifier

        api = MockOverdriveAPI(self._db)
        api.queue_response(200, content=bibliographic)

        api.update_formats(pool)

        # The delivery mechanisms have been updated.
        eq_(3, len(pool.delivery_mechanisms))
        eq_(
            set([
                Representation.EPUB_MEDIA_TYPE,
                DeliveryMechanism.KINDLE_CONTENT_TYPE,
                DeliveryMechanism.STREAMING_TEXT_CONTENT_TYPE
            ]),
            set([
                lpdm.delivery_mechanism.content_type
                for lpdm in pool.delivery_mechanisms
            ]))
        eq_(
            set([
                DeliveryMechanism.ADOBE_DRM, DeliveryMechanism.KINDLE_DRM,
                DeliveryMechanism.OVERDRIVE_DRM
            ]),
            set([
                lpdm.delivery_mechanism.drm_scheme
                for lpdm in pool.delivery_mechanisms
            ]))
コード例 #27
0
    def test_default_notification_email_address(self):
        """Test the ability of the Overdrive API to detect an email address
        previously given by the patron to Overdrive for the purpose of
        notifications.
        """
        ignore, patron_with_email = self.sample_json("patron_info.json")
        api = MockOverdriveAPI(self._db)
        api.queue_response(200, content=patron_with_email)
        patron = self._patron()
        # If the patron has used a particular email address to put
        # books on hold, use that email address, not the site default.
        with temp_config() as config:
            config[
                'default_notification_email_address'] = "*****@*****.**"
            eq_("*****@*****.**",
                api.default_notification_email_address(patron, 'pin'))

        # If the patron has never before put an Overdrive book on
        # hold, their JSON object has no `lastHoldEmail` key. In this
        # case we use the site default.
        patron_with_no_email = dict(patron_with_email)
        del patron_with_no_email['lastHoldEmail']
        api.queue_response(200, content=patron_with_no_email)
        with temp_config() as config:
            config[
                'default_notification_email_address'] = "*****@*****.**"
            eq_("*****@*****.**",
                api.default_notification_email_address(patron, 'pin'))

            # If there's an error getting the information, use the
            # site default.
            api.queue_response(404)
            eq_("*****@*****.**",
                api.default_notification_email_address(patron, 'pin'))
コード例 #28
0
    def test_fulfill_raises_exception_and_updates_formats_for_outdated_format(
            self):
        edition, pool = self._edition(identifier_type=Identifier.OVERDRIVE_ID,
                                      data_source_name=DataSource.OVERDRIVE,
                                      with_license_pool=True)

        # This pool has a format that's no longer available from overdrive.
        pool.set_delivery_mechanism(Representation.PDF_MEDIA_TYPE,
                                    DeliveryMechanism.ADOBE_DRM,
                                    RightsStatus.IN_COPYRIGHT, None)

        ignore, loan = self.sample_json("single_loan.json")

        ignore, lock_in_format_not_available = self.sample_json(
            "lock_in_format_not_available.json")

        # We will get the loan, try to lock in the format, and fail.
        api = MockOverdriveAPI(self._db)
        api.queue_response(200, content=loan)
        api.queue_response(400, content=lock_in_format_not_available)

        # Trying to get a fulfillment link raises an exception.
        assert_raises(FormatNotAvailable, api.get_fulfillment_link,
                      self._patron(), 'pin', pool.identifier.identifier,
                      'ebook-epub-adobe')

        # Fulfill will also update the formats.
        ignore, bibliographic = self.sample_json(
            "bibliographic_information.json")

        # If we have the LicensePool available (as opposed to just the
        # identifier), we will get the loan, try to lock in the
        # format, fail, and then update the bibliographic information.
        api.queue_response(200, content=loan)
        api.queue_response(400, content=lock_in_format_not_available)
        api.queue_response(200, content=bibliographic)

        assert_raises(FormatNotAvailable, api.fulfill, self._patron(), 'pin',
                      pool, 'ebook-epub-adobe')

        # The delivery mechanisms have been updated.
        eq_(3, len(pool.delivery_mechanisms))
        eq_(
            set([
                Representation.EPUB_MEDIA_TYPE,
                DeliveryMechanism.KINDLE_CONTENT_TYPE,
                DeliveryMechanism.STREAMING_TEXT_CONTENT_TYPE
            ]),
            set([
                lpdm.delivery_mechanism.content_type
                for lpdm in pool.delivery_mechanisms
            ]))
        eq_(
            set([
                DeliveryMechanism.ADOBE_DRM, DeliveryMechanism.KINDLE_DRM,
                DeliveryMechanism.OVERDRIVE_DRM
            ]),
            set([
                lpdm.delivery_mechanism.drm_scheme
                for lpdm in pool.delivery_mechanisms
            ]))