Exemplo n.º 1
0
def add_book(data):
    # add book to openlibrary.org

    # Define a Book Object
    authors = [
        common.Author(name=author) for author in data['authors'].split(', ')
    ]
    book = common.Book(
        title=data['title'],
        authors=authors,
        publisher=data['publisher'],
        publish_date=data['year'],
        pages=data['pages'],
    )

    # Add metadata like ISBN 10 and ISBN 13
    isbn = data['isbn']
    if is_isbn10(isbn):
        book.add_id('isbn_10', isbn)
    elif is_isbn13(isbn):
        book.add_id('isbn_13', isbn)

    # Create a new book
    ol = OpenLibrary()
    new_book = ol.create_book(book)

    new_book.add_bookcover(data['cover'])
    new_book.work.add_subject(data['categories'])
    new_book.save()

    return new_book
def main():
    # Defining an Open Library Object
    ol = OpenLibrary()

    # Define a Book Object
    book = common.Book(
        title="Warlight: A novel",
        authors=[common.Author(name="Michael Ondaatje")],
        publisher="Deckle Edge",
        publish_date="2018",
    )

    # Add metadata like ISBN 10 and ISBN 13
    book.add_id('isbn_10', '0525521194')
    book.add_id('isbn_13', '978-0525521198')

    # Create a new book
    new_book = ol.create_book(book)

    # Add a book cover for the given book
    new_book.add_bookcover(
        'https://images-na.ssl-images-amazon.com/images/I/51kmM%2BvVRJL._SX337_BO1,204,203,200_.jpg'
    )
Exemplo n.º 3
0
# Use the Wishlist ndjson file
with open(FILE) as f:
    data = ndjson.load(f)

# Iterates over the size of the data
for new_book in data:

    isbn10 = new_book.get('isbn10', u'')
    isbn13 = new_book.get('isbn13', u'')
    oclc = new_book.get('oclc', u'')

    added_book = row2book(new_book)

    # Add metadata like ISBN 10 and ISBN 13
    added_book.add_id(u'isbn_10', isbn10)
    added_book.add_id(u'isbn_13', isbn13)
    added_book.add_id(u'oclc', oclc)

    # Call create book to create the book
    newly_added_book = ol.create_book(added_book)

    # Add Bookcover if it is present
    bookcover_added = True
    if new_book['bookcover']:
        newly_added_book.add_bookcover(new_book['bookcover'])
    else:
        bookcover_added = False

    if not bookcover_added:
        print("Bookcover has not been found for the given book")
Exemplo n.º 4
0
class TestOpenLibrary(unittest.TestCase):
    def setUp(self):
        ol_config = Config().get_config()['openlibrary']
        ol_creds = ol_config.get('credentials')
        self.ol = OpenLibrary(credentials=ol_creds)

    def test_get_olid_by_isbn(self):
        olid = self.ol.Edition.get_olid_by_isbn(u'0374202915')
        expected_olid = u'OL23575801M'
        self.assertTrue(olid == expected_olid,
                        "Expected olid %s, got %s" % (expected_olid, olid))

    def test_get_work_by_metadata(self):
        title = u"The Autobiography of Benjamin Franklin"
        book = self.ol.Work.get_by_metadata(title=title)
        canonical_title = book.canonical_title
        self.assertTrue('franklin' in canonical_title,
                        "Expected 'franklin' to appear in result title: %s" % \
                        canonical_title)

    def test_get_edition_by_isbn(self):
        book = self.ol.Edition.get(isbn=u'0374202915')
        expected_olid = u'OL23575801M'
        self.assertTrue(
            book.olid == expected_olid,
            "Expected olid %s, got %s" % (expected_olid, book.olid))

    def test_matching_authors_olid(self):
        name = u'Benjamin Franklin'
        got_olid = self.ol.Author.get_olid_by_name(name)
        expected_olid = u'OL26170A'
        self.assertTrue(got_olid == expected_olid,
                        "Expected olid %s, got %s" % (expected_olid, got_olid))

    def test_create_book(self):
        book = Book(publisher=u'Karamanolis',
                    title=u'Alles ber Mikrofone',
                    identifiers={'isbn_10': [u'3922238246']},
                    publish_date=1982,
                    authors=[Author(name=u'Karl Schwarzer')],
                    publish_location=u'Neubiberg bei Mnchen')
        got_result = self.ol.create_book(book, debug=True)
        expected_result = {
            '_save': '',
            'author_key': u'/authors/OL7292805A',
            'author_name': u'Karl Schwarzer',
            'id_name': 'isbn_10',
            'id_value': u'3922238246',
            'publish_date': 1982,
            'publisher': u'Karamanolis',
            'title': u'Alles ber Mikrofone'
        }
        self.assertTrue(got_result == expected_result,
                        "Expected create_book to return %s, got %s" \
                        % (got_result, expected_result))

    def test_get_work(self):
        work = self.ol.Work.get(u'OL12938932W')
        self.assertTrue(work.title.lower() == 'all quiet on the western front',
                        "Failed to retrieve work")

    def test_cli(self):
        expected = json.loads(
            """{"subtitle": "a modern approach", "series": ["Prentice Hall series in artificial intelligence"], "covers": [92018], "lc_classifications": ["Q335 .R86 2003"], "latest_revision": 6, "contributions": ["Norvig, Peter."], "py/object": "olclient.openlibrary.Edition", "edition_name": "2nd ed.", "title": "Artificial intelligence", "_work": null, "languages": [{"key": "/languages/eng"}], "subjects": ["Artificial intelligence."], "publish_country": "nju", "by_statement": "Stuart J. Russell and Peter Norvig ; contributing writers, John F. Canny ... [et al.].", "type": {"key": "/type/edition"}, "revision": 6, "cover_url": "", "last_modified": {"type": "/type/datetime", "value": "2010-08-03T18:56:51.333942"}, "authors": [{"py/object": "olclient.openlibrary.Author", "bio": "", "name": "Stuart J. Russell", "links": [], "created": "2008-04-01T03:28:50.625462", "identifiers": {}, "alternate_names": ["Stuart; Norvig, Peter Russell"], "birth_date": "", "olid": null}], "publish_places": ["Upper Saddle River, N.J"], "pages": 1080, "publisher": ["Prentice Hall/Pearson Education"], "pagination": "xxviii, 1080 p. :", "work_olid": "OL2896994W", "created": {"type": "/type/datetime", "value": "2008-04-01T03:28:50.625462"}, "dewey_decimal_class": ["006.3"], "notes": {"type": "/type/text", "value": "Includes bibliographical references (p. 987-1043) and index."}, "identifiers": {"librarything": ["43569"], "goodreads": ["27543"]}, "cover": "", "publish_date": "2003", "olid": "OL3702561M"}"""
        )

        actual = json.loads(
            jsonpickle.encode(self.ol.Edition.get(isbn=u'0137903952')))
        self.assertTrue(
            actual == expected,
            "Data didn't match: \n%s\n\nversus:\n\n %s" % (actual, expected))
        actual = json.loads(
            jsonpickle.encode(self.ol.Edition.get(olid=u'OL3702561M')))
        self.assertTrue(
            actual == expected,
            "Data didn't match: %s\n\nversus:\n\n %s" % (actual, expected))
Exemplo n.º 5
0
# Change the Python Run Time Path
import sys
sys.path.insert(0, '../')

# Import necessary libraries to use
from olclient.openlibrary import OpenLibrary
import olclient.common as common

# Defining an Open Library Object
ol = OpenLibrary()

# Define a Book Object
book = common.Book(title="Warlight: A novel",
                   authors=[common.Author(name="Michael Ondaatje")],
                   publisher="Deckle Edge",
                   publish_date="2018")

# Add metadata like ISBN 10 and ISBN 13
book.add_id('isbn_10', '0525521194')
book.add_id('isbn_13', '978-0525521198')

# Create a new book
new_book = ol.create_book(book)

# Add a book cover for the given book
new_book.add_bookcover(
    'https://images-na.ssl-images-amazon.com/images/I/51kmM%2BvVRJL._SX337_BO1,204,203,200_.jpg'
)
class TestOpenLibrary(unittest.TestCase):
    @patch('olclient.openlibrary.OpenLibrary.login')
    def setUp(self, mock_login):
        self.ol = OpenLibrary()

    @patch('requests.Session.get')
    def test_get_olid_by_isbn(self, mock_get):
        isbn_key = 'ISBN:0374202915'
        isbn_bibkeys = {
            isbn_key: {
                'info_url': 'https://openlibrary.org/books/OL23575801M/Marie_LaVeau'
            }
        }
        mock_get.return_value.json.return_value = isbn_bibkeys
        olid = self.ol.Edition.get_olid_by_isbn('0374202915')
        mock_get.assert_called_with(
            f"{self.ol.base_url}/api/books.json?bibkeys={isbn_key}"
        )
        expected_olid = 'OL23575801M'
        self.assertTrue(
            olid == expected_olid, f"Expected olid {expected_olid}, got {olid}"
        )

    @patch('requests.Session.get')
    def test_get_olid_notfound_by_bibkey(self, mock_get):
        mock_get.json_data = {}
        edition = self.ol.Edition.get(isbn='foobar')
        assert edition is None

    @patch('requests.Session.get')
    def test_get_work_by_metadata(self, mock_get):
        doc = {
            "key": "/works/OL2514747W",
            "title": "The Autobiography of Benjamin Franklin",
        }
        search_results = {'start': 0, 'num_found': 1, 'docs': [doc]}
        title = "The Autobiography of Benjamin Franklin"
        mock_get.return_value.json.return_value = search_results
        book = self.ol.Work.search(title=title)
        mock_get.assert_called_with(f"{self.ol.base_url}/search.json?title={title}")
        canonical_title = book.canonical_title
        self.assertTrue(
            'franklin' in canonical_title,
            "Expected 'franklin' to appear in result title: %s" % canonical_title,
        )

    @patch('requests.Session.get')
    def test_get_edition_by_isbn(self, mock_get):
        isbn_lookup_response = {
            'ISBN:0374202915': {
                'info_url': 'https://openlibrary.org/books/OL23575801M/Marie_LaVeau'
            }
        }
        edition_response = {'key': "/books/OL23575801M", 'title': 'test'}
        mock_get.return_value.json.side_effect = [
            isbn_lookup_response,
            edition_response,
        ]
        book = self.ol.Edition.get(isbn='0374202915')
        mock_get.assert_has_calls(
            [
                call("%s/api/books.json?bibkeys=ISBN:0374202915" % self.ol.base_url),
                call().raise_for_status(),
                call().json(),
                call("{}/books/OL23575801M.json".format(self.ol.base_url)),
                call().raise_for_status(),
                call().json(),
            ]
        )
        expected_olid = 'OL23575801M'
        self.assertTrue(
            book.olid == expected_olid,
            f"Expected olid {expected_olid}, got {book.olid}",
        )

    @patch('requests.Session.get')
    def test_matching_authors_olid(self, mock_get):
        author_autocomplete = [
            {'name': "Benjamin Franklin", 'key': "/authors/OL26170A"}
        ]
        mock_get.return_value.json.return_value = author_autocomplete
        name = 'Benjamin Franklin'
        got_olid = self.ol.Author.get_olid_by_name(name)
        expected_olid = 'OL26170A'
        self.assertTrue(
            got_olid == expected_olid, f"Expected olid {expected_olid}, got {got_olid}"
        )

    @patch('requests.Session.get')
    def test_create_book(self, mock_get):
        book = Book(
            publisher='Karamanolis',
            title='Alles ber Mikrofone',
            identifiers={'isbn_10': ['3922238246']},
            publish_date=1982,
            authors=[Author(name='Karl Schwarzer')],
            publish_location='Neubiberg bei Mnchen',
        )
        author_autocomplete = [{'name': "Karl Schwarzer", 'key': "/authors/OL7292805A"}]
        mock_get.return_value.json.return_value = author_autocomplete
        got_result = self.ol.create_book(book, debug=True)
        mock_get.assert_called_with(
            "{}/authors/_autocomplete?q={}&limit=1".format(
                self.ol.base_url, "Karl Schwarzer"
            )
        )
        expected_result = {
            '_save': '',
            'author_key': '/authors/OL7292805A',
            'author_name': 'Karl Schwarzer',
            'id_name': 'isbn_10',
            'id_value': '3922238246',
            'publish_date': 1982,
            'publisher': 'Karamanolis',
            'title': 'Alles ber Mikrofone',
        }
        self.assertTrue(
            got_result == expected_result,
            "Expected create_book to return %s, got %s" % (expected_result, got_result),
        )

    def test_get_work(self):
        work_json = {'title': 'All Quiet on the Western Front'}
        work = self.ol.Work('OL12938932W', **work_json)
        self.assertTrue(
            work.title.lower() == 'all quiet on the western front',
            "Failed to retrieve work",
        )

    def test_work_json(self):
        authors = [
            {"type": "/type/author_role", "author": {"key": "/authors/OL5864762A"}}
        ]
        work = self.ol.Work('OL12938932W', key='/works/OL12938932W', authors=authors)
        work_json = work.json()
        self.assertEqual(work_json['key'], "/works/OL12938932W")
        self.assertEqual(
            work_json['authors'][0]['author']['key'], "/authors/OL5864762A"
        )

    def test_work_validation(self):
        work = self.ol.Work(
            'OL123W',
            title='Test Title',
            type={'key': '/type/work'},
            revision=1,
            last_modified={
                'type': '/type/datetime',
                'value': '2016-10-12T00:48:04.453554',
            },
        )
        self.assertIsNone(work.validate())

    def test_edition_json(self):
        author = self.ol.Author('OL123A', 'Test Author')
        edition = self.ol.Edition(
            edition_olid='OL123M',
            work_olid='OL123W',
            title='Test Title',
            authors=[author],
        )
        edition_json = edition.json()
        self.assertEqual(edition_json['key'], "/books/OL123M")
        self.assertEqual(edition_json['works'][0], {'key': '/works/OL123W'})
        self.assertEqual(edition_json['authors'][0], {'key': '/authors/OL123A'})

        self.assertNotIn('work_olid', edition_json)
        self.assertNotIn(
            'cover',
            edition_json,
            "'cover' is not a valid Edition property, should be list: 'covers'",
        )

    def test_edition_validation(self):
        author = self.ol.Author('OL123A', 'Test Author')
        edition = self.ol.Edition(
            edition_olid='OL123M',
            work_olid='OL123W',
            title='Test Title',
            type={'key': '/type/edition'},
            revision=1,
            last_modified={
                'type': '/type/datetime',
                'value': '2016-10-12T00:48:04.453554',
            },
            authors=[author],
        )
        self.assertIsNone(edition.validate())
        orphaned_edition = self.ol.Edition(
            edition_olid='OL123M', work_olid=None, title='Test Title', authors=[author]
        )
        with self.assertRaises(jsonschema.exceptions.ValidationError):
            orphaned_edition.validate()

    @patch('requests.Session.get')
    def test_get_notfound(self, mock_get):
        # This tests that if requests.raise_for_status() raises an exception,
        # (e.g. 404 or 500 HTTP response) it is not swallowed by the client.
        mock_get.return_value.raise_for_status = raise_http_error
        suffixes = {'edition': 'M', 'work': 'W', 'author': 'A'}
        for _type, suffix in suffixes.items():
            target = "OLnotfound%s" % suffix
            with pytest.raises(requests.HTTPError):
                r = self.ol.get(target)
                pytest.fail(f"HTTPError not raised for {_type}: {target}")

    @patch('requests.Session.post')
    def test_save_many(self, mock_post):
        edition = self.ol.Edition(
            edition_olid='OL123M', work_olid='OL12W', title='minimal edition'
        )
        work = self.ol.Work(olid='OL12W', title='minimal work')
        self.ol.save_many([edition, work], "test comment")
        mock_post.assert_called_with(
            "%s/api/save_many" % self.ol.base_url, ANY, headers=ANY
        )
        called_with_json = json.loads(mock_post.call_args[0][1])
        called_with_headers = mock_post.call_args[1]['headers']
        assert len(called_with_json) == 2
        self.assertIn('ns=42', called_with_headers['Opt'])
        self.assertEqual('test comment', called_with_headers['42-comment'])

    def test_delete(self):
        delete = self.ol.Delete('OL1W')
        self.assertEqual(delete.olid, 'OL1W')
        self.assertEqual('/type/delete', delete.json()['type']['key'])
        self.assertEqual('/works/OL1W', delete.json()['key'])

    def test_redirect(self):
        redirect = self.ol.Redirect(f='OL1W', t='OL2W')
        self.assertEqual('/type/redirect', redirect.json()['type']['key'])
        self.assertIn('location', redirect.json())
class TestOpenLibrary(unittest.TestCase):

    @patch('olclient.openlibrary.OpenLibrary.login')
    def setUp(self, mock_login):
        self.ol = OpenLibrary()

    @patch('requests.Session.get')
    def test_get_olid_by_isbn(self, mock_get):
        isbn_key = 'ISBN:0374202915'
        isbn_bibkeys = { isbn_key: { 'info_url': 'https://openlibrary.org/books/OL23575801M/Marie_LaVeau' } }
        mock_get.return_value.json.return_value = isbn_bibkeys
        olid = self.ol.Edition.get_olid_by_isbn(u'0374202915')
        mock_get.assert_called_with("%s/api/books.json?bibkeys=%s" % (self.ol.base_url, isbn_key))
        expected_olid = u'OL23575801M'
        self.assertTrue(olid == expected_olid,
                        "Expected olid %s, got %s" % (expected_olid, olid))

    @patch('requests.Session.get')
    def test_get_olid_notfound_by_bibkey(self, mock_get):
        mock_get.json_data = {}
        edition = self.ol.Edition.get(isbn='foobar')
        assert edition is None

    @patch('requests.Session.get')
    def test_get_work_by_metadata(self, mock_get):
        doc = {
            "key":    u"/works/OL2514747W",
            "title":  u"The Autobiography of Benjamin Franklin",
        }
        search_results = { 'start': 0, 'num_found': 1, 'docs': [doc] }
        title = u"The Autobiography of Benjamin Franklin"
        mock_get.return_value.json.return_value = search_results
        book = self.ol.Work.search(title=title)
        mock_get.assert_called_with("%s/search.json?title=%s" % (self.ol.base_url, title))
        canonical_title = book.canonical_title
        self.assertTrue('franklin' in canonical_title,
                        "Expected 'franklin' to appear in result title: %s" % \
                        canonical_title)

    @patch('requests.Session.get')
    def test_get_edition_by_isbn(self, mock_get):
        isbn_lookup_response = { u'ISBN:0374202915': { 'info_url': u'https://openlibrary.org/books/OL23575801M/Marie_LaVeau' } }
        edition_response = { 'key': u"/books/OL23575801M", 'title': 'test' }
        mock_get.return_value.json.side_effect = [isbn_lookup_response, edition_response]
        book = self.ol.Edition.get(isbn=u'0374202915')
        mock_get.assert_has_calls([
            call("%s/api/books.json?bibkeys=ISBN:0374202915" % self.ol.base_url),
            call().raise_for_status(),
            call().json(),
            call("%s%s.json" % (self.ol.base_url, "/books/OL23575801M")),
            call().raise_for_status(),
            call().json()
        ])
        expected_olid = u'OL23575801M'
        self.assertTrue(book.olid == expected_olid,
                        "Expected olid %s, got %s" % (expected_olid, book.olid))

    @patch('requests.Session.get')
    def test_matching_authors_olid(self, mock_get):
        author_autocomplete = [ {'name': u"Benjamin Franklin", 'key': u"/authors/OL26170A"} ]
        mock_get.return_value.json.return_value = author_autocomplete
        name = u'Benjamin Franklin'
        got_olid = self.ol.Author.get_olid_by_name(name)
        expected_olid = u'OL26170A'
        self.assertTrue(got_olid == expected_olid,
                        "Expected olid %s, got %s" % (expected_olid, got_olid))

    @patch('requests.Session.get')
    def test_create_book(self, mock_get):
        book = Book(publisher=u'Karamanolis', title=u'Alles ber Mikrofone',
                    identifiers={'isbn_10': [u'3922238246']}, publish_date=1982,
                    authors=[Author(name=u'Karl Schwarzer')],
                    publish_location=u'Neubiberg bei Mnchen')
        author_autocomplete = [ {'name': u"Karl Schwarzer", 'key': u"/authors/OL7292805A"} ]
        mock_get.return_value.json.return_value = author_autocomplete
        got_result = self.ol.create_book(book, debug=True)
        mock_get.assert_called_with("%s/authors/_autocomplete?q=%s&limit=1" % (self.ol.base_url, "Karl Schwarzer"))
        expected_result = {
            '_save': '',
            'author_key': u'/authors/OL7292805A',
            'author_name': u'Karl Schwarzer',
            'id_name': 'isbn_10',
            'id_value': u'3922238246',
            'publish_date': 1982,
            'publisher': u'Karamanolis',
            'title': u'Alles ber Mikrofone'
        }
        self.assertTrue(got_result == expected_result,
                        "Expected create_book to return %s, got %s" \
                        % (expected_result, got_result))

    def test_get_work(self):
        work_json = {u'title': u'All Quiet on the Western Front'}
        work = self.ol.Work(u'OL12938932W', **work_json)
        self.assertTrue(work.title.lower() == 'all quiet on the western front',
                        "Failed to retrieve work")

    def test_work_json(self):
        authors=[{ "type": "/type/author_role",
                   "author": { "key": "/authors/OL5864762A" }
                }]
        work = self.ol.Work('OL12938932W',
                            key='/works/OL12938932W',
                            authors=authors)
        work_json = work.json()
        self.assertEqual(work_json['key'], "/works/OL12938932W")
        self.assertEqual(work_json['authors'][0]['author']['key'], "/authors/OL5864762A")

    def test_work_validation(self):
        work = self.ol.Work('OL123W',
                            title='Test Title',
                            type={'key': '/type/work'},
                            revision=1,
                            last_modified={
                              'type': '/type/datetime',
                              'value': '2016-10-12T00:48:04.453554'
                            })
        self.assertIsNone(work.validate())

    def test_edition_json(self):
        author = self.ol.Author('OL123A', 'Test Author')
        edition = self.ol.Edition(edition_olid='OL123M',
                                  work_olid='OL123W',
                                  title='Test Title',
                                  authors=[author])
        edition_json = edition.json()
        self.assertEqual(edition_json['key'], "/books/OL123M")
        self.assertEqual(edition_json['works'][0], {'key': '/works/OL123W'})
        self.assertEqual(edition_json['authors'][0], {'key': '/authors/OL123A'})

        self.assertNotIn('work_olid', edition_json)
        self.assertNotIn('cover', edition_json,
                         "'cover' is not a valid Edition property, should be list: 'covers'")

    def test_edition_validation(self):
        author = self.ol.Author('OL123A', 'Test Author')
        edition = self.ol.Edition(edition_olid='OL123M',
                                  work_olid='OL123W',
                                  title='Test Title',
                                  type={'key': '/type/edition'},
                                  revision=1,
                                  last_modified={
                                      'type': '/type/datetime',
                                      'value': '2016-10-12T00:48:04.453554'
                                  },
                                  authors=[author])
        self.assertIsNone(edition.validate())
        orphaned_edition = self.ol.Edition(edition_olid='OL123M',
                                  work_olid=None,
                                  title='Test Title',
                                  authors=[author])
        with self.assertRaises(jsonschema.exceptions.ValidationError):
            orphaned_edition.validate()

    @patch('requests.Session.get')
    def test_get_notfound(self, mock_get):
        # This tests that if requests.raise_for_status() raises an exception,
        # (e.g. 404 or 500 HTTP response) it is not swallowed by the client.
        mock_get.return_value.raise_for_status = raise_http_error
        suffixes = {'edition': 'M', 'work': 'W', 'author': 'A'}
        for _type, suffix in suffixes.items():
            target = "OLnotfound%s" % suffix
            with pytest.raises(requests.HTTPError, message="HTTPError not raised for %s: %s" % (_type, target)):
                r = self.ol.get(target)

    @patch('requests.Session.post')
    def test_save_many(self, mock_post):
        edition = self.ol.Edition(edition_olid='OL123M', work_olid='OL12W', title='minimal edition')
        work    = self.ol.Work(olid='OL12W', title='minimal work')
        self.ol.save_many([edition, work], "test comment")
        mock_post.assert_called_with("%s/api/save_many" % self.ol.base_url, ANY, headers=ANY)
        called_with_json    = json.loads(mock_post.call_args[0][1])
        called_with_headers = mock_post.call_args[1]['headers']
        assert(len(called_with_json) == 2)
        self.assertIn('ns=42', called_with_headers['Opt'])
        self.assertEqual('test comment', called_with_headers['42-comment'])

    def test_delete(self):
        delete = self.ol.Delete('OL1W')
        self.assertEqual(delete.olid, 'OL1W')
        self.assertEqual('/type/delete', delete.json()['type']['key'])
        self.assertEqual('/works/OL1W', delete.json()['key'])

    def test_redirect(self):
        redirect = self.ol.Redirect(f='OL1W', t='OL2W')
        self.assertEqual('/type/redirect', redirect.json()['type']['key'])
        self.assertIn('location', redirect.json())