diff --git a/CalibreWebCompanion/CalibreWebCompanion/settings.py b/CalibreWebCompanion/CalibreWebCompanion/settings.py index caef3df..c9c5b40 100644 --- a/CalibreWebCompanion/CalibreWebCompanion/settings.py +++ b/CalibreWebCompanion/CalibreWebCompanion/settings.py @@ -158,7 +158,7 @@ MIDDLEWARE = [ ] ## ## ######################################################################## - +DEFAULT_CHARSET = "utf-8" ROOT_URLCONF = 'CalibreWebCompanion.urls' diff --git a/CalibreWebCompanion/library/context_processors.py b/CalibreWebCompanion/library/context_processors.py index b2fb1af..c71f0d7 100644 --- a/CalibreWebCompanion/library/context_processors.py +++ b/CalibreWebCompanion/library/context_processors.py @@ -15,7 +15,7 @@ def filters(request): 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_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_series = Series.objects.annotate(num_books=Count('book')).order_by('sort') diff --git a/CalibreWebCompanion/library/tests.py b/CalibreWebCompanion/library/tests.py index 7ce503c..2e76edb 100644 --- a/CalibreWebCompanion/library/tests.py +++ b/CalibreWebCompanion/library/tests.py @@ -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() \ No newline at end of file diff --git a/CalibreWebCompanion/library/views.py b/CalibreWebCompanion/library/views.py index 62128ba..5756a77 100644 --- a/CalibreWebCompanion/library/views.py +++ b/CalibreWebCompanion/library/views.py @@ -1,3 +1,4 @@ +from django.utils.decorators import method_decorator from django.shortcuts import render from django.views import generic 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__) # might be helpful for vary headers later -from django.utils.decorators import method_decorator @login_required @@ -58,13 +58,29 @@ class ResultsView(generic.ListView): # no clue if this is secure. if title: books = books.filter(sort__icontains=title) 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: books = books.filter(identifier__val=identifier) 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( Q(sort__icontains=generic) | Q(author_sort__icontains=generic) | + Q(authors__id=author_id) | Q(identifier__val=generic) ) return books