regluit/core/tests.py

977 lines
38 KiB
Python
Executable File

"""
external library imports
"""
from datetime import datetime, timedelta
from decimal import Decimal as D
from math import factorial
from time import sleep, mktime
from urlparse import parse_qs, urlparse
from tempfile import NamedTemporaryFile
from celery.task import chord
from celery.task.sets import TaskSet
import requests
import os
"""
django imports
"""
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.comments.models import Comment
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site
from django.core.files import File as DjangoFile
from django.db import IntegrityError
from django.http import Http404
from django.test import TestCase
from django.test.client import Client
from django.test.utils import override_settings
from django.utils import unittest
"""
regluit imports
"""
from regluit.core import (
isbn,
bookloader,
models,
search,
goodreads,
librarything,
tasks,
parameters,
)
from regluit.core.models import (
Campaign,
Work,
UnglueitError,
Edition,
RightsHolder,
Claim,
Key,
Ebook,
Premium,
Subject,
Publisher,
Offer,
EbookFile,
Acq,
Hold,
)
from regluit.libraryauth.models import Library
from regluit.core.parameters import TESTING, LIBRARY, RESERVE
from regluit.frontend.views import safe_get_work
from regluit.payment.models import Transaction
from regluit.payment.parameters import PAYMENT_TYPE_AUTHORIZATION
from regluit.utils.localdatetime import now, date_today
from regluit.pyepub import EPUB
from .epub import test_epub
from .pdf import ask_pdf, test_pdf
class BookLoaderTests(TestCase):
def setUp(self):
self.user = User.objects.create_user('core_test', 'test@example.org', 'core_test')
self.client = Client()
self.client.login(username='core_test', password='core_test')
def test_add_by_isbn(self):
# edition
edition = bookloader.add_by_isbn('0441007465')
self.assertEqual(edition.title, 'Neuromancer')
self.assertEqual(edition.publication_date, u'2000')
self.assertEqual(edition.publisher, u'Penguin')
self.assertEqual(edition.isbn_10, '0441007465')
self.assertEqual(edition.isbn_13, '9780441007462')
self.assertEqual(edition.googlebooks_id, 'IDFfMPW32hQC')
# authors
self.assertEqual(edition.authors.all().count(), 1)
self.assertEqual(edition.authors.all()[0].name, 'William Gibson')
# work
self.assertTrue(edition.work)
self.assertEqual(edition.work.googlebooks_id, 'IDFfMPW32hQC')
self.assertEqual(edition.work.first_isbn_13(), '9780441007462')
# publisher names
old_pub_name = edition.publisher_name
edition.set_publisher('test publisher name')
self.assertEqual(edition.publisher, u'test publisher name')
pub = Publisher(name=edition.publisher_name)
pub.save()
self.assertEqual(edition.work.publishers().count(), 1)
old_pub_name.publisher = pub
old_pub_name.save()
edition.set_publisher(u'Penguin')
self.assertEqual(edition.publisher, u'test publisher name') # Penguin has been aliased
# locale in language
# Obama Dreams from My Father, Chinese edition
# http://www.worldcat.org/title/oubama-de-meng-xiang-zhi-lu-yi-fu-zhi-ming/oclc/272997721&referer=brief_results
edition = bookloader.add_by_isbn('9789571349268')
self.assertEqual(edition.work.language, 'zh-TW')
# @unittest.expectedFailure
def test_update_edition(self):
w = models.Work(title='silly title', language='xx')
w.save()
e = models.Edition(title=w.title,work=w)
e.save()
models.Identifier(type='isbn', value='9780237540814', work=w, edition=e).save()
bookloader.update_edition(e)
self.assertEqual(e.work.language, 'en')
self.assertEqual(e.title, 'Call of the Wild')
def test_double_add(self):
bookloader.add_by_isbn('0441007465')
bookloader.add_by_isbn('0441007465')
self.assertEqual(models.Edition.objects.all().count(), 1)
self.assertEqual(models.Author.objects.all().count(), 1)
self.assertEqual(models.Work.objects.all().count(), 1)
def test_missing_isbn(self):
e = bookloader.add_by_isbn_from_google('0139391401')
self.assertEqual(e, None)
def test_thingisbn(self):
isbns = bookloader.thingisbn('0441007465')
self.assertTrue(len(isbns) > 20)
self.assertTrue('0441007465' in isbns)
self.assertTrue('3453313895' in isbns)
def test_add_related(self):
# add one edition
edition = bookloader.add_by_isbn('0441007465')
self.assertEqual(models.Edition.objects.count(), 1)
self.assertEqual(models.Work.objects.count(), 1)
lang=edition.work.language
# ask for related editions to be added using the work we just created
bookloader.add_related('0441007465')
self.assertTrue(models.Edition.objects.count() > 15)
self.assertEqual(models.Work.objects.filter(language=lang).count(), 1)
self.assertTrue(edition.work.editions.count() > 9)
def test_populate_edition(self):
edition = bookloader.add_by_googlebooks_id('c_dBPgAACAAJ')
edition = tasks.populate_edition.run(edition.isbn_13)
self.assertTrue(edition.work.editions.all().count() > 10)
self.assertTrue(edition.work.subjects.all().count() > 8)
self.assertTrue(edition.work.publication_date)
edition.publication_date = None
self.assertTrue(edition.work.publication_date)
self.assertTrue(len(edition.work.description) > 20)
self.assertTrue(edition.work.identifiers.filter(type='oclc')[0])
def test_merge_works_mechanics(self):
"""Make sure then merge_works is still okay when we try to merge works with themselves and with deleted works"""
sub1= Subject(name='test1')
sub1.save()
sub2= Subject(name='test2')
sub2.save()
w1 = Work(title="Work 1")
w1.save()
w1.subjects.add(sub1)
w2 = Work(title="Work 2")
w2.save()
w2.subjects.add(sub1,sub2)
e1 = Edition(work=w1)
e1.save()
e2 = Edition(work=w2)
e2.save()
e2a = Edition(work=w2)
e2a.save()
self.assertTrue(e1)
self.assertTrue(e2)
self.assertTrue(e2a)
self.assertTrue(e1.work)
self.assertTrue(e2.work)
self.assertEqual(models.Work.objects.count(), 2)
w1_id = w1.id
w2_id = w2.id
# first try to merge work 1 into itself -- should not do anything
bookloader.merge_works(w1,w1)
self.assertEqual(models.Work.objects.count(), 2)
# merge the second work into the first
bookloader.merge_works(e1.work, e2.work)
self.assertEqual(models.Work.objects.count(),1)
self.assertEqual(models.WasWork.objects.count(),1)
self.assertEqual(w1.subjects.count(),2)
# getting proper view?
anon_client = Client()
r = anon_client.get("/work/%s/" % w1_id)
self.assertEqual(r.status_code, 200)
r = anon_client.get("/work/%s/" % w2_id)
self.assertEqual(r.status_code, 200)
# try to do it twice -- nothing should happen
bookloader.merge_works(e1.work, e2a.work)
r = anon_client.get("/work/%s/" % w1_id)
self.assertEqual(r.status_code, 200)
r = anon_client.get("/work/%s/" % w2_id)
self.assertEqual(r.status_code, 200)
# if the work has a selected edition, then don't touch the work.
w3= Work(title='work 3')
e_pref= Edition(work=w1)
w1.selected_edition=e_pref
bookloader.merge_works(w3, w1)
self.assertTrue(w1.title=='Work 1')
def test_merge_works(self):
# add two editions and see that there are two stub works
# for this test, we need two isbns that are considered related in LibraryThing and are both
# recognized by Google Books API
# see http://nbviewer.ipython.org/70f0b17b9d0c8b9b651b for a way to calculate a match
# for a given input ISBN
# Crawfish Dreams by Nancy Rawles -- what could work once the LT thingisbn cache clears
#isbn1 = '0385722133'
#isbn2 = '0307425363'
# RY switched to Atwood's Handmaid's Tale for hopefully longer term resilience for this test
isbn1 = '9780395404256'
isbn2 = '9780547345666'
e1 = bookloader.add_by_isbn(isbn1)
e2 = bookloader.add_by_isbn(isbn2)
self.assertTrue(e1)
self.assertTrue(e2)
self.assertTrue(e1.work)
self.assertTrue(e2.work)
self.assertEqual(models.Work.objects.count(), 2)
# add the stub works to a wishlist
user = User.objects.create_user('test', 'test@example.org', 'testpass')
user.wishlist.add_work(e1.work, 'test')
user.wishlist.add_work(e2.work, 'test')
manager = User.objects.create_user('manager', 'manager@example.org', 'managerpass')
# create campaigns for the stub works
c1 = models.Campaign.objects.create(
name=e1.work.title,
work=e1.work,
description='Test Campaign 1',
deadline=now(),
target=D('1000.00'),
)
c2 = models.Campaign.objects.create(
name=e2.work.title,
work=e2.work,
description='Test Campaign 2',
deadline=now(),
target=D('1000.00'),
)
c2.managers.add(manager)
c2.save()
self.assertEqual(c2.pk, e2.work.last_campaign().pk)
# comment on the works
site = Site.objects.all()[0]
wct = ContentType.objects.get_for_model(models.Work)
comment1 = Comment(
content_type=wct,
object_pk=e1.work.pk,
comment="test comment1",
user=user,
site=site
)
comment1.save()
comment2 = Comment(
content_type=wct,
object_pk=e2.work.pk,
comment="test comment2",
user=user,
site=site
)
comment2.save()
comment3 = Comment(
content_type=wct,
object_pk=e2.work.pk,
comment="test comment3",
user=manager,
site=site
)
comment3.save()
# now add related edition to make sure Works get merged
bookloader.add_related(isbn1)
# non-zero
self.assertGreater(models.Work.objects.count(), 0)
w3 = models.Edition.get_by_isbn(isbn1).work
# and that relevant Campaigns and Wishlists are updated
c1=Campaign.objects.get(pk=c1.pk)
c2=Campaign.objects.get(pk=c2.pk)
self.assertEqual(c1.work, c2.work)
self.assertEqual(user.wishlist.works.all().count(), 1)
self.assertEqual(Comment.objects.for_model(w3).count(), 3)
anon_client = Client()
r = anon_client.get("/work/%s/" % w3.pk)
self.assertEqual(r.status_code, 200)
r = anon_client.get("/work/%s/" % e2.work.pk)
self.assertEqual(r.status_code, 200)
def test_ebook(self):
edition = bookloader.add_by_oclc('1246014')
# we've seen the public domain status of this book fluctuate -- and the OCLC number can disappear. So if the ebook count is 2 then test
if edition is not None and edition.ebooks.count() == 2:
#self.assertEqual(edition.ebooks.count(), 2)
#ebook_epub = edition.ebooks.all()[0]
ebook_epub = edition.ebooks.filter(format='epub')[0]
self.assertEqual(ebook_epub.format, 'epub')
#self.assertEqual(ebook_epub.url, 'http://books.google.com/books/download/The_Latin_language.epub?id=N1RfAAAAMAAJ&ie=ISO-8859-1&output=epub&source=gbs_api')
self.assertEqual(parse_qs(urlparse(ebook_epub.url).query).get("id"), ['N1RfAAAAMAAJ'])
self.assertEqual(parse_qs(urlparse(ebook_epub.url).query).get("output"), ['epub'])
self.assertEqual(ebook_epub.provider, 'Google Books')
self.assertEqual(ebook_epub.set_provider(), 'Google Books')
ebook_pdf = edition.ebooks.filter(format='pdf')[0]
self.assertEqual(ebook_pdf.format, 'pdf')
#self.assertEqual(ebook_pdf.url, 'http://books.google.com/books/download/The_Latin_language.pdf?id=N1RfAAAAMAAJ&ie=ISO-8859-1&output=pdf&sig=ACfU3U2yLt3nmTncB8ozxOWUc4iHKUznCA&source=gbs_api')
self.assertEqual(parse_qs(urlparse(ebook_pdf.url).query).get("id"), ['N1RfAAAAMAAJ'])
self.assertEqual(parse_qs(urlparse(ebook_pdf.url).query).get("output"), ['pdf'])
self.assertEqual(ebook_pdf.provider, 'Google Books')
w = edition.work
self.assertEqual(w.first_epub().url, ebook_epub.url)
self.assertEqual(w.first_pdf().url, ebook_pdf.url)
self.assertEqual(w.first_epub_url(), ebook_epub.url)
self.assertEqual(w.first_pdf_url(), ebook_pdf.url)
ebook_pdf.url='http://en.wikisource.org/wiki/Frankenstein'
self.assertEqual(ebook_pdf.set_provider(), 'Wikisource')
self.user.wishlist.add_work(w, 'test')
tasks.report_new_ebooks(date_today())
r = self.client.get("/notification/" )
self.assertEqual(r.status_code, 200)
ebook_pdf.increment()
updated_ebook = Ebook.objects.get(pk=ebook_pdf.pk)
self.assertEqual(int(updated_ebook.download_count), 1)
self.assertEqual(int(edition.work.download_count), 1)
def test_add_no_ebook(self):
# this edition lacks an ebook, but we should still be able to load it
# http://books.google.com/books?id=D-WjL_HRbNQC&printsec=frontcover#v=onepage&q&f=false
# Social Life of Information
e = bookloader.add_by_isbn('1578517087')
self.assertTrue(e)
@unittest.expectedFailure
def test_one_language(self):
# english edition for cat's cradle should only pull in other
# english editions
# expected failure right now because Google seems to have bad data about language of Cat's Cradle
# e.g., https://www.googleapis.com/books/v1/volumes?q=isbn:9789513033774
# title = "Kissan kehto" -- language according to API = English
work = bookloader.add_by_isbn('079530272X').work
self.assertEqual(work.language, 'en')
bookloader.add_related('079530272X')
for edition in work.editions.all():
self.assertEqual(edition.title.lower(), "cat's cradle")
def test_add_openlibrary(self):
work = bookloader.add_by_isbn('0441007465').work
bookloader.add_related('0441007465')
bookloader.add_openlibrary(work)
subjects = [s.name for s in work.subjects.all()]
self.assertTrue(len(subjects) > 10)
self.assertTrue('Science fiction' in subjects)
self.assertTrue('/works/OL27258W' in work.identifiers.filter(type='olwk').values_list('value',flat=True) )
self.assertTrue('888628' in work.identifiers.filter(type='gdrd').values_list('value',flat=True))
self.assertTrue('609' in work.identifiers.filter(type='ltwk').values_list('value',flat=True))
def test_unicode_openlibrary(self):
work = bookloader.add_by_isbn('9783894808358').work
bookloader.add_openlibrary(work)
self.assertTrue(work.description.startswith('Sie sind jung,'))
def test_load_gutenberg_edition(self):
"""Let's try this out for Moby Dick"""
title = "Moby Dick"
ol_work_id = "/works/OL102749W"
gutenberg_etext_id = 2701
epub_url = "http://www.gutenberg.org/cache/epub/2701/pg2701.epub"
license = 'http://www.gutenberg.org/license'
lang = 'en'
format = 'epub'
publication_date = datetime(2001,7,1)
seed_isbn = '9780142000083' # http://www.amazon.com/Moby-Dick-Whale-Penguin-Classics-Deluxe/dp/0142000086
ebook = bookloader.load_gutenberg_edition(title, gutenberg_etext_id, ol_work_id, seed_isbn, epub_url, format, license, lang, publication_date)
self.assertEqual(ebook.url, epub_url)
class SearchTests(TestCase):
def test_basic_search(self):
results = search.gluejar_search('melville')
self.assertEqual(len(results), 10)
r = results[0]
self.assertTrue(r.has_key('title'))
self.assertTrue(r.has_key('author'))
self.assertTrue(r.has_key('description'))
self.assertTrue(r.has_key('cover_image_thumbnail'))
self.assertTrue(r['cover_image_thumbnail'].startswith('https'))
self.assertTrue(r.has_key('publisher'))
self.assertTrue(r.has_key('isbn_13'))
self.assertTrue(r.has_key('googlebooks_id'))
def test_pagination(self):
r1 = search.gluejar_search('melville', page=1)
r2 = search.gluejar_search('melville', page=2)
isbns1 = set([r['isbn_13'] for r in r1])
isbns2 = set([r['isbn_13'] for r in r2])
self.assertTrue(isbns1 != isbns2)
def test_googlebooks_search(self):
response = search.googlebooks_search('melville', '69.243.24.29', 1)
self.assertEqual(len(response['items']), 10)
class CampaignTests(TestCase):
def test_b2u(self):
w = Work()
w.save()
c = Campaign(
target=D('12000.00'),
deadline=datetime(2013, 1, 1),
work=w, type=2,
cc_date_initial=datetime(2113, 1, 1),
)
self.assertTrue(c.set_dollar_per_day()<0.34)
self.assertTrue(c.dollar_per_day>0.31)
t = Transaction(type=1, campaign=c, approved=True, amount= D(6000.1), status="Complete")
t.save()
c.status = 'ACTIVE'
c.save()
c.update_left()
#print(w.percent_of_goal())
self.assertEqual(w.percent_unglued(),3)
self.assertTrue(w.percent_of_goal()>49)
ofr = Offer.objects.create(work=w,price=D(10),active=True)
self.assertTrue(c.days_per_copy <D(32.26))
self.assertTrue(c.days_per_copy >D(29.41))
def test_required_fields(self):
# a campaign must have a target, deadline and a work
c = Campaign()
self.assertRaises(IntegrityError, c.save)
c = Campaign(target=D('1000.00'))
self.assertRaises(IntegrityError, c.save)
c = Campaign(target=D('1000.00'), deadline=datetime(2013, 1, 1))
self.assertRaises(IntegrityError, c.save)
w = Work()
w.save()
c = Campaign(target=D('1000.00'), deadline=datetime(2013, 1, 1), work=w)
c.license = 'CC BY-NC'
c.save()
self.assertEqual(c.license_url, 'http://creativecommons.org/licenses/by-nc/3.0/')
self.assertEqual(c.license_badge, 'https://i.creativecommons.org/l/by-nc/3.0/88x31.png')
def test_campaign_status(self):
# need a user to associate with a transaction
user = User.objects.create_user('test', 'test@example.org', 'testpass')
w = Work()
w.save()
w2 = Work()
w2.save()
# INITIALIZED
c1 = Campaign(target=D('1000.00'),deadline=Campaign.latest_ending(),work=w)
c1.save()
self.assertEqual(c1.status, 'INITIALIZED')
# ACTIVATED
c2 = Campaign(target=D('1000.00'),deadline=datetime(2013,1,1),work=w,description='dummy description')
c2.save()
self.assertEqual(c2.status, 'INITIALIZED')
u = User.objects.create_user('claimer', 'claimer@example.org', 'claimer')
u.save()
rh = RightsHolder(owner = u, rights_holder_name = 'rights holder name')
rh.save()
cl = Claim(rights_holder = rh, work = w, user = u, status = 'active')
cl.save()
cl2 = Claim(rights_holder = rh, work = w2, user = u, status = 'active')
cl2.save()
c2.activate()
self.assertEqual(c2.status, 'ACTIVE')
# SUSPENDED
c2.suspend(reason="for testing")
self.assertEqual(c2.status, 'SUSPENDED')
# RESUMING
c2.resume(reason="for testing")
#self.assertEqual(c2.suspended, None)
self.assertEqual(c2.status,'ACTIVE')
# should not let me suspend a campaign that hasn't been initialized
self.assertRaises(UnglueitError, c1.suspend, "for testing")
# UNSUCCESSFUL
c3 = Campaign(target=D('1000.00'),deadline=now() - timedelta(days=1),work=w2,description='dummy description')
c3.save()
c3.activate()
self.assertEqual(c3.status, 'ACTIVE')
# at this point, since the deadline has passed, the status should change and be UNSUCCESSFUL
self.assertTrue(c3.update_status())
self.assertEqual(c3.status, 'UNSUCCESSFUL')
# premiums
pr1= Premium(type='CU', campaign=c3, amount=10, description='botsnack', limit=1)
pr1.save()
self.assertEqual(pr1.premium_remaining,1)
#cloning (note we changed c3 to w2 to make it clonable)
c7= c3.clone()
self.assertEqual(c7.status, 'INITIALIZED')
self.assertEqual(c7.premiums.all()[0].description , 'botsnack')
# SUCCESSFUL
c4 = Campaign(target=D('1000.00'),deadline=now() - timedelta(days=1),work=w,description='dummy description')
c4.save()
c4.activate()
t = Transaction()
t.amount = D('1234.00')
t.type = PAYMENT_TYPE_AUTHORIZATION
t.status = 'ACTIVE'
t.approved = True
t.campaign = c4
t.user = user
t.save()
self.assertTrue(c4.update_status())
self.assertEqual(c4.status, 'SUCCESSFUL')
# WITHDRAWN
c5 = Campaign(target=D('1000.00'),deadline=datetime(2013,1,1),work=w,description='dummy description')
c5.save()
c5.activate().withdraw('testing')
self.assertEqual(c5.status, 'WITHDRAWN')
# testing percent-of-goal
w2 = Work()
w2.save()
c6 = Campaign(target=D('1000.00'),deadline=now() + timedelta(days=1),work=w2,description='dummy description')
c6.save()
cl = Claim(rights_holder = rh, work = w2, user = u, status = 'active')
cl.save()
c6.activate()
t = Transaction()
t.amount = D('234.00')
t.type = PAYMENT_TYPE_AUTHORIZATION
t.status = 'ACTIVE'
t.approved = True
t.campaign = c6
t.user = user
t.save()
self.assertEqual(w2.percent_of_goal(), 23)
self.assertEqual(c1.launchable, False)
c1.description="description"
self.assertEqual(c1.launchable, True)
c1.work.create_offers()
self.assertEqual(c1.work.offers.count(), 2)
self.assertEqual(c1.work.offers.filter(license=2).count(), 1)
c1.type = 2
c1.save()
self.assertEqual(c1.launchable, False)
of1=c1.work.offers.get(license=2)
of1.price=D(2)
of1.active=True
of1.save()
self.assertEqual(c1.launchable, False)
e1= models.Edition(title="title",work=c1.work)
e1.save()
ebf1= models.EbookFile(edition=e1, format=1)
ebf1.save()
c1.set_cc_date_initial()
self.assertEqual(c1.cc_date, settings.MAX_CC_DATE)
c1.target = D(settings.UNGLUEIT_MAXIMUM_TARGET)
c1.save()
self.assertEqual(c1.launchable, True)
class WishlistTest(TestCase):
def test_add_remove(self):
# add a work to a user's wishlist
user = User.objects.create_user('test', 'test@example.org', 'testpass')
edition = bookloader.add_by_isbn('0441007465')
work = edition.work
num_wishes=work.num_wishes
user.wishlist.add_work(work, 'test')
self.assertEqual(user.wishlist.works.count(), 1)
self.assertEqual(work.num_wishes, num_wishes+1)
user.wishlist.remove_work(work)
self.assertEqual(user.wishlist.works.count(), 0)
self.assertEqual(work.num_wishes, num_wishes)
class CeleryTaskTest(TestCase):
def test_single_fac(self):
n = 10
task = tasks.fac.delay(n)
result = task.get(timeout=10)
self.assertEqual(result,factorial(n))
def test_subtask(self):
n = 30
subtasks = [tasks.fac.subtask(args=(x,)) for x in range(n)]
job = TaskSet(tasks=subtasks)
result = job.apply_async()
while not result.ready():
sleep(0.2)
self.assertEqual(result.join(),[factorial(x) for x in range(n)])
class GoodreadsTest(TestCase):
@unittest.skip("Goodreads down at the moment")
def test_goodreads_shelves(self):
# test to see whether the core undeletable shelves are on the list
gr_uid = "767708" # for Raymond Yee
gc = goodreads.GoodreadsClient(key=settings.GOODREADS_API_KEY, secret=settings.GOODREADS_API_SECRET)
shelves = gc.shelves_list(gr_uid)
shelf_names = [s['name'] for s in shelves['user_shelves']]
self.assertTrue('currently-reading' in shelf_names)
self.assertTrue('read' in shelf_names)
self.assertTrue('to-read' in shelf_names)
@unittest.skip("Goodreads down at the moment")
def test_review_list_unauth(self):
gr_uid = "767708" # for Raymond Yee
gc = goodreads.GoodreadsClient(key=settings.GOODREADS_API_KEY, secret=settings.GOODREADS_API_SECRET)
reviews = gc.review_list_unauth(user_id=gr_uid, shelf='read')
# test to see whether there is a book field in each of the review
# url for test is http://www.goodreads.com/review/list.xml?id=767708&shelf=read&page=1&per_page=20&order=a&v=2&key=[key]
self.assertTrue(all([r.has_key("book") for r in reviews]))
class LibraryThingTest(TestCase):
def test_scrape_test_lib(self):
# account yujx : has one book: 0471925675
lt_username = 'yujx'
lt = librarything.LibraryThing(username=lt_username)
books = list(lt.parse_user_catalog(view_style=5))
self.assertEqual(len(books),1)
self.assertEqual(books[0]['isbn'], '0471925675')
self.assertEqual(books[0]['work_id'], '80826')
self.assertEqual(books[0]['book_id'], '79883733')
class ISBNTest(TestCase):
def test_ISBN(self):
milosz_10 = '006019667X'
milosz_13 = '9780060196677'
python_10 = '0-672-32978-6'
python_10_wrong = '0-672-32978-7'
python_13 = '978-0-672-32978-4'
isbn_python_10 = isbn.ISBN(python_10)
isbn_python_13 = isbn.ISBN(python_13)
# return None for invalid characters
self.assertEqual(None, isbn.ISBN("978-0-M72-32978-X").to_string('13'))
self.assertEqual(isbn.ISBN("978-0-M72-32978-X").valid, False)
# check that only ISBN 13 starting with 978 or 979 are accepted
self.assertEqual(None, isbn.ISBN("111-0-M72-32978-X").to_string())
# right type?
self.assertEqual(isbn_python_10.type, '10')
self.assertEqual(isbn_python_13.type, '13')
# valid?
self.assertEqual(isbn_python_10.valid, True)
self.assertEqual(isbn.ISBN(python_10_wrong).valid, False)
# do conversion -- first the outside methods
self.assertEqual(isbn.convert_10_to_13(isbn.strip(python_10)),isbn.strip(python_13))
self.assertEqual(isbn.convert_13_to_10(isbn.strip(python_13)),isbn.strip(python_10))
# check formatting
self.assertEqual(isbn.ISBN(python_13).to_string(type='13'), '9780672329784')
self.assertEqual(isbn.ISBN(python_13).to_string('13',True), '978-0-672-32978-4')
self.assertEqual(isbn.ISBN(python_13).to_string(type='10'), '0672329786')
self.assertEqual(isbn.ISBN(python_10).to_string(type='13'), '9780672329784')
self.assertEqual(isbn.ISBN(python_10).to_string(10,True), '0-672-32978-6')
# complain if one tries to get ISBN-10 for a 979 ISBN 13
# making up a 979 ISBN
isbn_979 = isbn.ISBN("979-1-234-56789-0").validate()
self.assertEqual(isbn_979.to_string('10'), None)
# check casting to string -- ISBN 13
self.assertEqual(str(isbn.ISBN(python_10)), '0672329786')
# test __eq__ and __ne__ and validate
self.assertTrue(isbn.ISBN(milosz_10) == isbn.ISBN(milosz_13))
self.assertTrue(isbn.ISBN(milosz_10) == milosz_13)
self.assertFalse(isbn.ISBN(milosz_10) == 'ddds')
self.assertFalse(isbn.ISBN(milosz_10) != milosz_10)
self.assertTrue(isbn.ISBN(python_10) != python_10_wrong)
self.assertEqual(isbn.ISBN(python_10_wrong).validate(), python_10)
self.assertEqual(isbn.ISBN(python_13).validate(), python_10)
# curious about set membership
self.assertEqual(len(set([isbn.ISBN(milosz_10), isbn.ISBN(milosz_13)])),2)
self.assertEqual(len(set([str(isbn.ISBN(milosz_10)), str(isbn.ISBN(milosz_13))])),2)
self.assertEqual(len(set([isbn.ISBN(milosz_10).to_string(), isbn.ISBN(milosz_13).to_string()])),1)
class EncryptedKeyTest(TestCase):
def test_create_read_key(self):
name = "the great answer"
value = "42"
key = Key.objects.create(name=name, value=value)
key.save()
# do we get back the value?
self.assertEqual(Key.objects.filter(name=name)[0].value, value)
# just checking that the encrypted value is not the same as the value
self.assertNotEqual(key.encrypted_value, value) # is this always true?
class SafeGetWorkTest(TestCase):
def test_good_work(self):
w1 = models.Work()
w1.save()
w2 = models.Work()
w2.save()
w2_id = w2.id
bookloader.merge_works(w1, w2)
work = safe_get_work(w1.id)
self.assertEqual(work, w1)
work = safe_get_work(w2_id)
self.assertEqual(work, w1)
self.assertRaises(Http404, safe_get_work, 3)
class DownloadPageTest(TestCase):
def test_download_page(self):
w = models.Work()
w.save()
e1 = models.Edition()
e1.work = w
e1.unglued = True
e2 = models.Edition()
e2.work = w
e1.save()
e2.save()
eb1 = models.Ebook()
eb1.url = "http://example.org"
eb1.edition = e1
eb1.format = 'epub'
eb2 = models.Ebook()
eb2.url = "http://example2.com"
eb2.edition = e2
eb2.format = 'mobi'
eb1.save()
eb2.save()
anon_client = Client()
response = anon_client.get("/work/%s/download/" % w.id, follow=True)
self.assertContains(response, "/download_ebook/%s/"% eb1.id, count=10)
self.assertContains(response, "/download_ebook/%s/"% eb2.id, count=5)
class LocaldatetimeTest(TestCase):
@override_settings(LOCALDATETIME_NOW=None)
def test_LOCALDATETIME_NOW_none(self):
try:
localdatetime.now
except NameError:
from regluit.utils import localdatetime
else:
reload(localdatetime)
self.assertAlmostEqual(mktime(datetime.now().timetuple()), mktime(localdatetime.now().timetuple()), 1.0)
@override_settings(LOCALDATETIME_NOW=lambda : datetime.now() + timedelta(365))
def test_LOCALDATETIME_NOW_year_ahead(self):
try:
localdatetime.now
except NameError:
from regluit.utils import localdatetime
else:
reload(localdatetime)
self.assertAlmostEqual(mktime((datetime.now() + timedelta(365)).timetuple()), mktime(localdatetime.now().timetuple()), 1.0)
def test_no_time_override(self):
from regluit.utils import localdatetime
self.assertAlmostEqual(mktime(datetime.now().timetuple()), mktime(localdatetime.now().timetuple()), 1.0)
def tearDown(self):
# restore localdatetime.now() to what's in the settings file
try:
localdatetime.now
except NameError:
from regluit.utils import localdatetime
else:
reload(localdatetime)
class MailingListTests(TestCase):
#mostly to check that MailChimp account is setp correctly
def test_mailchimp(self):
from postmonkey import PostMonkey
pm = PostMonkey(settings.MAILCHIMP_API_KEY)
self.assertEqual(pm.ping(),"Everything's Chimpy!" )
self.user = User.objects.create_user('chimp_test', 'eric@gluejar.com', 'chimp_test')
self.assertTrue(self.user.profile.on_ml)
@override_settings(LOCAL_TEST=True)
class EbookFileTests(TestCase):
def test_badepub_errors(self):
textfile = NamedTemporaryFile(delete=False)
textfile.write("bad text file")
textfile.seek(0)
self.assertTrue(test_epub(textfile))
def test_ebookfile(self):
"""
Read the test epub file
"""
w = Work.objects.create(title="Work 1")
e = Edition.objects.create(title=w.title,work=w)
u = User.objects.create_user('test', 'test@example.org', 'testpass')
rh = RightsHolder.objects.create(owner = u, rights_holder_name = 'rights holder name')
cl = Claim.objects.create(rights_holder = rh, work = w, user = u, status = 'active')
c = Campaign.objects.create(work = w,
type = parameters.BUY2UNGLUE,
cc_date_initial = datetime(2020,1,1),
target = 1000,
deadline = datetime(2020,1,1),
license = 'CC BY',
description = "dummy description",
)
# download the test epub into a temp file
temp = NamedTemporaryFile(delete=False)
test_file_content = requests.get(settings.BOOXTREAM_TEST_EPUB_URL).content
temp.write(test_file_content)
temp.close()
try:
# now we can try putting the test epub file into Django storage
temp_file = open(temp.name)
dj_file = DjangoFile(temp_file)
ebf = EbookFile( format='epub', edition=e, file=dj_file)
ebf.save()
temp_file.close()
finally:
# make sure we get rid of temp file
os.remove(temp.name)
test_epub= EPUB(ebf.file, mode='a')
self.assertEqual(len(test_epub.opf) , 4)
self.assertTrue(len(test_epub.opf[2]) < 30)
acq=Acq.objects.create(user=u,work=w,license=TESTING)
self.assertIsNot(acq.nonce, None)
url= acq.get_watermarked().download_link_epub
self.assertRegexpMatches(url,'github.com/eshellman/42_ebook/blob/master/download/42')
#self.assertRegexpMatches(url,'booxtream.com/')
with self.assertRaises(UnglueitError) as cm:
c.activate()
off = Offer(price=10.00, work=w, active=True)
off.save()
c.activate()
#flip the campaign to success
c.cc_date_initial= datetime(2012,1,1)
c.update_status()
self.assertEqual( c.work.ebooks().count(),2 )
c.do_watermark=False
c.save()
url= acq.get_watermarked().download_link_epub
def test_ebookfile_pdf(self):
w = Work.objects.create(title="Work 2")
e = Edition.objects.create(title=w.title,work=w)
u = User.objects.create_user('test2', 'test@example.org', 'testpass')
rh = RightsHolder.objects.create(owner = u, rights_holder_name = 'rights holder name 2')
cl = Claim.objects.create(rights_holder = rh, work = w, user = u, status = 'active')
c = Campaign.objects.create(work = w,
type = parameters.THANKS,
license = 'CC BY-NC',
description = "Please send me money",
)
# download the test epub into a temp file
temp = NamedTemporaryFile(delete=False)
test_file_content = requests.get(settings.TEST_PDF_URL).content
temp.write(test_file_content)
temp.close()
try:
# now we can try putting the test pdf file into Django storage
temp_file = open(temp.name)
dj_file = DjangoFile(temp_file)
ebf = EbookFile( format='pdf', edition=e, file=dj_file)
ebf.save()
temp_file.close()
finally:
# make sure we get rid of temp file
os.remove(temp.name)
#test the ask-appender
c.add_ask_to_ebfs()
asking_pdf = c.work.ebookfiles().filter(asking = True)[0].file.url
assert test_pdf(asking_pdf)
from .signals import handle_transaction_charged
@override_settings(LOCAL_TEST=True)
class LibTests(TestCase):
class transaction:
pass
def test_purchase(self):
w = Work.objects.create(title="Work 1")
e = Edition.objects.create(title=w.title,work=w)
u = User.objects.create_user('test', 'test@example.org', 'testpass')
lu = User.objects.create_user('library', 'testu@example.org', 'testpass')
lib = Library.objects.create(user=lu,owner=u)
c = Campaign.objects.create(work=w, type = parameters.BUY2UNGLUE, cc_date_initial= datetime(2020,1,1),target=1000, deadline=datetime(2020,1,1))
new_acq = Acq.objects.create(user=lib.user,work=c.work,license= LIBRARY)
self.assertTrue(new_acq.borrowable)
reserve_acq = Acq.objects.create(user=u,work=c.work,license= RESERVE, lib_acq = new_acq)
self.assertTrue(reserve_acq.borrowable)
self.assertFalse(new_acq.borrowable)
self.assertTrue(reserve_acq.expires< now()+timedelta(hours=25))
reserve_acq.borrow()
self.assertTrue(reserve_acq.expires> now()+timedelta(hours=25))
u2 = User.objects.create_user('user2', 'test2@example.org', 'testpass')
Hold.objects.get_or_create(library=lib,work=w,user=u2)
reserve_acq.expire_in(timedelta(seconds=0))
tasks.refresh_acqs()
self.assertEqual(reserve_acq.holds.count(),0)