Merge branch 'development' of https://git.tau.aperturect.com/MassiveAtoms/calibre-web-companion into development
This commit is contained in:
		@@ -158,7 +158,7 @@ MIDDLEWARE = [
 | 
				
			|||||||
]
 | 
					]
 | 
				
			||||||
##                                                                    ##
 | 
					##                                                                    ##
 | 
				
			||||||
########################################################################
 | 
					########################################################################
 | 
				
			||||||
 | 
					DEFAULT_CHARSET = "utf-8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ROOT_URLCONF = 'CalibreWebCompanion.urls'
 | 
					ROOT_URLCONF = 'CalibreWebCompanion.urls'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ def filters(request):
 | 
				
			|||||||
    unique_authors = Author.objects.only('name', "id").annotate(num_books=Count('book')).order_by('name')
 | 
					    unique_authors = Author.objects.only('name', "id").annotate(num_books=Count('book')).order_by('name')
 | 
				
			||||||
    unique_tags = Tag.objects.annotate(num_books=Count('book')).order_by('name')
 | 
					    unique_tags = Tag.objects.annotate(num_books=Count('book')).order_by('name')
 | 
				
			||||||
    unique_publishers = Publisher.objects.annotate(num_books=Count('book')).order_by('name')
 | 
					    unique_publishers = Publisher.objects.annotate(num_books=Count('book')).order_by('name')
 | 
				
			||||||
    unique_languages = Language.objects.annotate(num_books=Count('book')).order_by('rating')
 | 
					    unique_languages = Language.objects.annotate(num_books=Count('book')).order_by('lang_code')
 | 
				
			||||||
    unique_ratings = Rating.objects.annotate(num_books=Count('book'))
 | 
					    unique_ratings = Rating.objects.annotate(num_books=Count('book'))
 | 
				
			||||||
    unique_series = Series.objects.annotate(num_books=Count('book')).order_by('sort')
 | 
					    unique_series = Series.objects.annotate(num_books=Count('book')).order_by('sort')
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,166 @@
 | 
				
			|||||||
from django.test import TestCase
 | 
					from django.test import Client, TestCase
 | 
				
			||||||
 | 
					from pprint import pprint
 | 
				
			||||||
 | 
					from django.test.utils import setup_test_environment
 | 
				
			||||||
 | 
					from .models import Book, Author, Publisher, Series, Rating, Tag, Identifier
 | 
				
			||||||
 | 
					from django.db.models import Count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Create your tests here.
 | 
					
 | 
				
			||||||
 | 
					client = Client()
 | 
				
			||||||
 | 
					client.login(username="testuser", password="dumbeasypassword")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def booklisttest():
 | 
				
			||||||
 | 
					    c = Client()
 | 
				
			||||||
 | 
					    c.login(username="testuser", password="dumbeasypassword")
 | 
				
			||||||
 | 
					    res = c.get("/books/")
 | 
				
			||||||
 | 
					    assert res.status_code == 200
 | 
				
			||||||
 | 
					    context = dict(res.context)
 | 
				
			||||||
 | 
					    assert sorted(context["book_list"], key=lambda x: x.id)== sorted(Book.objects.all(), key=lambda x: x.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def authorlisttest():
 | 
				
			||||||
 | 
					    c = Client()
 | 
				
			||||||
 | 
					    c.login(username="testuser", password="dumbeasypassword")
 | 
				
			||||||
 | 
					    res = c.get("/authors/")
 | 
				
			||||||
 | 
					    assert res.status_code == 200
 | 
				
			||||||
 | 
					    context = dict(res.context)
 | 
				
			||||||
 | 
					    assert sorted(context["author_list"], key=lambda x: x.id)== sorted(Author.objects.all(), key=lambda x: x.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def publisherlisttest():
 | 
				
			||||||
 | 
					    c = Client()
 | 
				
			||||||
 | 
					    c.login(username="testuser", password="dumbeasypassword")
 | 
				
			||||||
 | 
					    res = c.get("/publishers/")
 | 
				
			||||||
 | 
					    assert res.status_code == 200
 | 
				
			||||||
 | 
					    context = dict(res.context)
 | 
				
			||||||
 | 
					    assert sorted(context["publisher_list"], key=lambda x: x.id)== sorted(Publisher.objects.all(), key=lambda x: x.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def serieslisttest():
 | 
				
			||||||
 | 
					    c = Client()
 | 
				
			||||||
 | 
					    c.login(username="testuser", password="dumbeasypassword")
 | 
				
			||||||
 | 
					    res = c.get("/series/")
 | 
				
			||||||
 | 
					    assert res.status_code == 200
 | 
				
			||||||
 | 
					    context = dict(res.context)
 | 
				
			||||||
 | 
					    assert sorted(context["series_list"], key=lambda x: x.id)== sorted(Series.objects.all(), key=lambda x: x.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def ratinglisttest():
 | 
				
			||||||
 | 
					    c = Client()
 | 
				
			||||||
 | 
					    c.login(username="testuser", password="dumbeasypassword")
 | 
				
			||||||
 | 
					    res = c.get("/ratings/")
 | 
				
			||||||
 | 
					    assert res.status_code == 200
 | 
				
			||||||
 | 
					    context = dict(res.context)
 | 
				
			||||||
 | 
					    assert sorted(context["rating_list"], key=lambda x: x.id)== sorted(Rating.objects.all(), key=lambda x: x.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def taglisttest():
 | 
				
			||||||
 | 
					    c = Client()
 | 
				
			||||||
 | 
					    c.login(username="testuser", password="dumbeasypassword")
 | 
				
			||||||
 | 
					    res = c.get("/tags/")
 | 
				
			||||||
 | 
					    assert res.status_code == 200
 | 
				
			||||||
 | 
					    context = dict(res.context)
 | 
				
			||||||
 | 
					    assert sorted(context["tag_list"], key=lambda x: x.id)== sorted(Tag.objects.all(), key=lambda x: x.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def bookdetailtest():
 | 
				
			||||||
 | 
					    c = Client()
 | 
				
			||||||
 | 
					    c.login(username="testuser", password="dumbeasypassword")
 | 
				
			||||||
 | 
					    ids = [i.id for i in Book.objects.all()][:10]
 | 
				
			||||||
 | 
					    for i in ids:
 | 
				
			||||||
 | 
					        res = c.get(f"/book/{i}")
 | 
				
			||||||
 | 
					        assert res.status_code == 200
 | 
				
			||||||
 | 
					        context = dict(res.context)
 | 
				
			||||||
 | 
					        assert context["book"] == Book.objects.get(id=i)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def authordetailtest():
 | 
				
			||||||
 | 
					    c = Client()
 | 
				
			||||||
 | 
					    c.login(username="testuser", password="dumbeasypassword")
 | 
				
			||||||
 | 
					    ids = [i.id for i in Author.objects.all()][:10]
 | 
				
			||||||
 | 
					    for i in ids:
 | 
				
			||||||
 | 
					        res = c.get(f"/author/{i}")
 | 
				
			||||||
 | 
					        assert res.status_code == 200
 | 
				
			||||||
 | 
					        context = dict(res.context)
 | 
				
			||||||
 | 
					        assert context["author"] == Author.objects.get(id=i)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def publisherdetailtest():
 | 
				
			||||||
 | 
					    c = Client()
 | 
				
			||||||
 | 
					    c.login(username="testuser", password="dumbeasypassword")
 | 
				
			||||||
 | 
					    ids = [i.id for i in Publisher.objects.all()][:10]
 | 
				
			||||||
 | 
					    for i in ids:
 | 
				
			||||||
 | 
					        res = c.get(f"/publisher/{i}")
 | 
				
			||||||
 | 
					        assert res.status_code == 200
 | 
				
			||||||
 | 
					        context = dict(res.context)
 | 
				
			||||||
 | 
					        assert context["publisher"] == Publisher.objects.get(id=i)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def seriesdetailtest():
 | 
				
			||||||
 | 
					    c = Client()
 | 
				
			||||||
 | 
					    c.login(username="testuser", password="dumbeasypassword")
 | 
				
			||||||
 | 
					    ids = [i.id for i in Series.objects.all()][:10]
 | 
				
			||||||
 | 
					    for i in ids:
 | 
				
			||||||
 | 
					        res = c.get(f"/series/{i}")
 | 
				
			||||||
 | 
					        assert res.status_code == 200
 | 
				
			||||||
 | 
					        context = dict(res.context)
 | 
				
			||||||
 | 
					        assert context["series"] == Series.objects.get(id=i)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def ratingdetailtest():
 | 
				
			||||||
 | 
					    c = Client()
 | 
				
			||||||
 | 
					    c.login(username="testuser", password="dumbeasypassword")
 | 
				
			||||||
 | 
					    ids = [i.id for i in Rating.objects.all()][:10]
 | 
				
			||||||
 | 
					    for i in ids:
 | 
				
			||||||
 | 
					        res = c.get(f"/rating/{i}")
 | 
				
			||||||
 | 
					        assert res.status_code == 200
 | 
				
			||||||
 | 
					        context = dict(res.context)
 | 
				
			||||||
 | 
					        assert context["rating"] == Rating.objects.get(id=i)        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def tagdetailtest():
 | 
				
			||||||
 | 
					    c = Client()
 | 
				
			||||||
 | 
					    c.login(username="testuser", password="dumbeasypassword")
 | 
				
			||||||
 | 
					    ids = [i.id for i in Tag.objects.all()][:10]
 | 
				
			||||||
 | 
					    for i in ids:
 | 
				
			||||||
 | 
					        res = c.get(f"/tag/{i}")
 | 
				
			||||||
 | 
					        assert res.status_code == 200
 | 
				
			||||||
 | 
					        context = dict(res.context)
 | 
				
			||||||
 | 
					        assert context["tag"] == Tag.objects.get(id=i) 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def search_partial(key, value, book=None):
 | 
				
			||||||
 | 
					    c = Client()
 | 
				
			||||||
 | 
					    c.login(username="testuser", password="dumbeasypassword")
 | 
				
			||||||
 | 
					    res = c.get("/results/", {key : value})
 | 
				
			||||||
 | 
					    if not book:
 | 
				
			||||||
 | 
					        return dict(res.context)["book_list"]
 | 
				
			||||||
 | 
					    return book in dict(res.context)["book_list"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def searchtest():
 | 
				
			||||||
 | 
					    books = [i for i in Book.objects.all()][:10]
 | 
				
			||||||
 | 
					    for i in books:
 | 
				
			||||||
 | 
					        assert search_partial("title", i.title, i)
 | 
				
			||||||
 | 
					        assert search_partial("generic", i.title, i)
 | 
				
			||||||
 | 
					        assert search_partial("author", i.author_sort, i)
 | 
				
			||||||
 | 
					        author = i.authors.first()
 | 
				
			||||||
 | 
					        if author:
 | 
				
			||||||
 | 
					            assert search_partial("author", author.name, i)
 | 
				
			||||||
 | 
					            assert search_partial("generic", author.name, i)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert search_partial("generic", i.author_sort, i)
 | 
				
			||||||
 | 
					        id = Identifier.objects.filter(book=i.id).first()
 | 
				
			||||||
 | 
					        if id:
 | 
				
			||||||
 | 
					            assert search_partial("identifier", id, i)
 | 
				
			||||||
 | 
					            assert search_partial("generic", id, i)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					booklisttest()
 | 
				
			||||||
 | 
					bookdetailtest()
 | 
				
			||||||
 | 
					authorlisttest()
 | 
				
			||||||
 | 
					authordetailtest()
 | 
				
			||||||
 | 
					publisherdetailtest()
 | 
				
			||||||
 | 
					publisherlisttest()
 | 
				
			||||||
 | 
					seriesdetailtest()
 | 
				
			||||||
 | 
					serieslisttest()
 | 
				
			||||||
 | 
					ratingdetailtest()
 | 
				
			||||||
 | 
					ratinglisttest()
 | 
				
			||||||
 | 
					tagdetailtest()
 | 
				
			||||||
 | 
					taglisttest()
 | 
				
			||||||
 | 
					searchtest()
 | 
				
			||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					from django.utils.decorators import method_decorator
 | 
				
			||||||
from django.shortcuts import render
 | 
					from django.shortcuts import render
 | 
				
			||||||
from django.views import generic
 | 
					from django.views import generic
 | 
				
			||||||
from .models import Author, Book, Comment, Rating, BookAuthorLink, Publisher, Tag, BookTagLink, BookRatingLink, Data, Identifier, Series
 | 
					from .models import Author, Book, Comment, Rating, BookAuthorLink, Publisher, Tag, BookTagLink, BookRatingLink, Data, Identifier, Series
 | 
				
			||||||
@@ -13,7 +14,6 @@ import logging
 | 
				
			|||||||
logger = logging.getLogger(__name__)
 | 
					logger = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# might be helpful for vary headers later
 | 
					# might be helpful for vary headers later
 | 
				
			||||||
from django.utils.decorators import method_decorator
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
@@ -58,13 +58,29 @@ class ResultsView(generic.ListView):  # no clue if this is secure.
 | 
				
			|||||||
        if title:
 | 
					        if title:
 | 
				
			||||||
            books = books.filter(sort__icontains=title)
 | 
					            books = books.filter(sort__icontains=title)
 | 
				
			||||||
        if author:
 | 
					        if author:
 | 
				
			||||||
            books = books.filter(author_sort__icontains=author)
 | 
					            # authors are stored as author_sort and author, needs to be slightly more complex
 | 
				
			||||||
 | 
					            author_obj = Author.objects.filter(name__icontains=author).first()
 | 
				
			||||||
 | 
					            if not author_obj:
 | 
				
			||||||
 | 
					                author_id = -1
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                author_id = author_obj.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            books = books.filter(
 | 
				
			||||||
 | 
					                Q(author_sort__icontains=author) |
 | 
				
			||||||
 | 
					                Q(authors__id=author_id)
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
        if identifier:
 | 
					        if identifier:
 | 
				
			||||||
            books = books.filter(identifier__val=identifier)
 | 
					            books = books.filter(identifier__val=identifier)
 | 
				
			||||||
        if generic:
 | 
					        if generic:
 | 
				
			||||||
 | 
					            author_obj = Author.objects.filter(name__icontains=generic).first()
 | 
				
			||||||
 | 
					            if not author_obj:
 | 
				
			||||||
 | 
					                author_id = -1
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                author_id = author_obj.id
 | 
				
			||||||
            books = books.filter(
 | 
					            books = books.filter(
 | 
				
			||||||
                Q(sort__icontains=generic) |
 | 
					                Q(sort__icontains=generic) |
 | 
				
			||||||
                Q(author_sort__icontains=generic) |
 | 
					                Q(author_sort__icontains=generic) |
 | 
				
			||||||
 | 
					                Q(authors__id=author_id) |
 | 
				
			||||||
                Q(identifier__val=generic)
 | 
					                Q(identifier__val=generic)
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        return books
 | 
					        return books
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user