Commit 67775bc7 authored by Ozzie Isaacs's avatar Ozzie Isaacs

Update requirements

Catch error for invalid oauth tokens
Fixes for displaying error messages on deleting books from list
Fixes for displaying error messages on deleting bookformats
parent d32b2ca5
......@@ -245,7 +245,7 @@ def list_users():
off = int(request.args.get("offset") or 0)
limit = int(request.args.get("limit") or 10)
search = request.args.get("search")
sort = request.args.get("sort", "state")
sort = request.args.get("sort", "id")
order = request.args.get("order", "").lower()
state = None
if sort == "state":
......@@ -254,7 +254,7 @@ def list_users():
if sort != "state" and order:
order = text(sort + " " + order)
elif not state:
order = ub.User.name.desc()
order = ub.User.id.asc()
all_user = ub.session.query(ub.User)
if not config.config_anonbrowse:
......@@ -371,7 +371,7 @@ def edit_list_user(param):
'message':_(u"No admin user remaining, can't remove admin role",
nick=user.name)}), mimetype='application/json')
user.role &= ~int(vals['field_index'])
elif param == 'sidebar_view':
elif param.startswith('sidebar'):
if user.name == "Guest" and int(vals['field_index']) == constants.SIDEBAR_READ_AND_UNREAD:
raise Exception(_("Guest can't have this view"))
if vals['value'] == 'true':
......
......@@ -315,19 +315,19 @@ def delete_book(book_id, book_format, jsonResponse):
result, error = helper.delete_book(book, config.config_calibre_dir, book_format=book_format.upper())
if not result:
if jsonResponse:
return json.dumps({"location": url_for("editbook.edit_book"),
"type": "alert",
return json.dumps([{"location": url_for("editbook.edit_book", book_id=book_id),
"type": "danger",
"format": "",
"error": error}),
"message": error}])
else:
flash(error, category="error")
return redirect(url_for('editbook.edit_book', book_id=book_id))
if error:
if jsonResponse:
warning = {"location": url_for("editbook.edit_book"),
warning = {"location": url_for("editbook.edit_book", book_id=book_id),
"type": "warning",
"format": "",
"error": error}
"message": error}
else:
flash(error, category="warning")
if not book_format:
......@@ -339,6 +339,15 @@ def delete_book(book_id, book_format, jsonResponse):
except Exception as ex:
log.debug_or_exception(ex)
calibre_db.session.rollback()
if jsonResponse:
return json.dumps([{"location": url_for("editbook.edit_book", book_id=book_id),
"type": "danger",
"format": "",
"message": ex}])
else:
flash(str(ex), category="error")
return redirect(url_for('editbook.edit_book', book_id=book_id))
else:
# book not found
log.error('Book with id "%s" could not be deleted: not found', book_id)
......
......@@ -30,6 +30,7 @@ from flask_babel import gettext as _
from flask_dance.consumer import oauth_authorized, oauth_error
from flask_dance.contrib.github import make_github_blueprint, github
from flask_dance.contrib.google import make_google_blueprint, google
from oauthlib.oauth2 import TokenExpiredError, InvalidGrantError
from flask_login import login_user, current_user, login_required
from sqlalchemy.orm.exc import NoResultFound
......@@ -146,6 +147,7 @@ def bind_oauth_or_register(provider_id, provider_user_id, redirect_url, provider
ub.session.add(oauth_entry)
ub.session.commit()
flash(_(u"Link to %(oauth)s Succeeded", oauth=provider_name), category="success")
log.info("Link to {} Succeeded".format(provider_name))
return redirect(url_for('web.profile'))
except Exception as ex:
log.debug_or_exception(ex)
......@@ -194,6 +196,7 @@ def unlink_oauth(provider):
ub.session.commit()
logout_oauth_user()
flash(_(u"Unlink to %(oauth)s Succeeded", oauth=oauth_check[provider]), category="success")
log.info("Unlink to {} Succeeded".format(oauth_check[provider]))
except Exception as ex:
log.debug_or_exception(ex)
ub.session.rollback()
......@@ -257,11 +260,13 @@ if ub.oauth_support:
def github_logged_in(blueprint, token):
if not token:
flash(_(u"Failed to log in with GitHub."), category="error")
log.error("Failed to log in with GitHub")
return False
resp = blueprint.session.get("/user")
if not resp.ok:
flash(_(u"Failed to fetch user info from GitHub."), category="error")
log.error("Failed to fetch user info from GitHub")
return False
github_info = resp.json()
......@@ -273,11 +278,13 @@ if ub.oauth_support:
def google_logged_in(blueprint, token):
if not token:
flash(_(u"Failed to log in with Google."), category="error")
log.error("Failed to log in with Google")
return False
resp = blueprint.session.get("/oauth2/v2/userinfo")
if not resp.ok:
flash(_(u"Failed to fetch user info from Google."), category="error")
log.error("Failed to fetch user info from Google")
return False
google_info = resp.json()
......@@ -318,11 +325,16 @@ if ub.oauth_support:
def github_login():
if not github.authorized:
return redirect(url_for('github.login'))
try:
account_info = github.get('/user')
if account_info.ok:
account_info_json = account_info.json()
return bind_oauth_or_register(oauthblueprints[0]['id'], account_info_json['id'], 'github.login', 'github')
flash(_(u"GitHub Oauth error, please retry later."), category="error")
log.error("GitHub Oauth error, please retry later")
except (InvalidGrantError, TokenExpiredError) as e:
flash(_(u"GitHub Oauth error: {}").format(e), category="error")
log.error(e)
return redirect(url_for('web.login'))
......@@ -337,11 +349,16 @@ def github_login_unlink():
def google_login():
if not google.authorized:
return redirect(url_for("google.login"))
try:
resp = google.get("/oauth2/v2/userinfo")
if resp.ok:
account_info_json = resp.json()
return bind_oauth_or_register(oauthblueprints[1]['id'], account_info_json['id'], 'google.login', 'google')
flash(_(u"Google Oauth error, please retry later."), category="error")
log.error("Google Oauth error, please retry later")
except (InvalidGrantError, TokenExpiredError) as e:
flash(_(u"Google Oauth error: {}").format(e), category="error")
log.error(e)
return redirect(url_for('web.login'))
......
......@@ -92,7 +92,7 @@
{% for message in get_flashed_messages(with_categories=True) %}
{%if message[0] == "error" %}
<div class="row-fluid text-center" style="margin-top: -20px;">
<div id="flash_alert" class="alert alert-danger">{{ message[1] }}</div>
<div id="flash_danger" class="alert alert-danger">{{ message[1] }}</div>
</div>
{%endif%}
{%if message[0] == "info" %}
......
......@@ -756,7 +756,7 @@ def list_books():
off = int(request.args.get("offset") or 0)
limit = int(request.args.get("limit") or config.config_books_per_page)
search = request.args.get("search")
sort = request.args.get("sort", "state")
sort = request.args.get("sort", "id")
order = request.args.get("order", "").lower()
state = None
......
......@@ -26,7 +26,7 @@ python-ldap>=3.0.0,<3.4.0
Flask-SimpleLDAP>=1.4.0,<1.5.0
#oauth
Flask-Dance>=1.4.0,<3.1.0
Flask-Dance>=1.4.0,<4.1.0
SQLAlchemy-Utils>=0.33.5,<0.38.0
# extracting metadata
......
......@@ -37,20 +37,20 @@
<div class="row">
<div class="col-xs-6 col-md-6 col-sm-offset-3" style="margin-top:50px;">
<p class='text-justify attribute'><strong>Start Time: </strong>2021-04-05 18:59:35</p>
<p class='text-justify attribute'><strong>Start Time: </strong>2021-04-12 21:44:07</p>
</div>
</div>
<div class="row">
<div class="col-xs-6 col-md-6 col-sm-offset-3">
<p class='text-justify attribute'><strong>Stop Time: </strong>2021-04-05 21:34:25</p>
<p class='text-justify attribute'><strong>Stop Time: </strong>2021-04-13 00:22:44</p>
</div>
</div>
<div class="row">
<div class="col-xs-6 col-md-6 col-sm-offset-3">
<p class='text-justify attribute'><strong>Duration: </strong>2h 5 min</p>
<p class='text-justify attribute'><strong>Duration: </strong>2h 7 min</p>
</div>
</div>
</div>
......@@ -1148,12 +1148,12 @@
<tr id="su" class="passClass">
<tr id="su" class="errorClass">
<td>TestEditBooksList</td>
<td class="text-center">10</td>
<td class="text-center">10</td>
<td class="text-center">0</td>
<td class="text-center">0</td>
<td class="text-center">6</td>
<td class="text-center">3</td>
<td class="text-center">1</td>
<td class="text-center">0</td>
<td class="text-center">
<a onclick="showClassDetail('c11', 10)">Detail</a>
......@@ -1171,20 +1171,74 @@
<tr id='pt11.2' class='hiddenRow bg-success'>
<tr id="et11.2" class="none bg-info">
<td>
<div class='testcase'>TestEditBooksList - test_bookslist_edit_categories</div>
</td>
<td colspan='6' align='center'>PASS</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et11.2')">ERROR</a>
</div>
<!--css div popup start-->
<div id="div_et11.2" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_et11.2').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_edit_books_list.py", line 138, in test_bookslist_edit_categories
bl = self.get_books_list(-1) # we are now back on page 1 again
File "/home/ozzie/Development/calibre-web-test/test/helper_ui.py", line 1632, in get_books_list
row_elements = element.find_elements_by_xpath("./td")
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 381, in find_elements_by_xpath
return self.find_elements(by=By.XPATH, value=xpath)
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 684, in find_elements
return self._execute(Command.FIND_CHILD_ELEMENTS,
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute
return self._parent.execute(command, params)
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: The element reference of <tr class="no-records-found"> is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id='pt11.3' class='hiddenRow bg-success'>
<tr id="ft11.3" class="none bg-danger">
<td>
<div class='testcase'>TestEditBooksList - test_bookslist_edit_languages</div>
</td>
<td colspan='6' align='center'>PASS</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft11.3')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_ft11.3" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_ft11.3').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_edit_books_list.py", line 211, in test_bookslist_edit_languages
self.assertEqual("+", bl['table'][4]['Languages']['text'])
AssertionError: '+' != 'English'
- +
+ English</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
......@@ -1207,11 +1261,33 @@
<tr id='pt11.6' class='hiddenRow bg-success'>
<tr id="ft11.6" class="none bg-danger">
<td>
<div class='testcase'>TestEditBooksList - test_bookslist_edit_seriesindex</div>
</td>
<td colspan='6' align='center'>PASS</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft11.6')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_ft11.6" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_ft11.6').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_edit_books_list.py", line 239, in test_bookslist_edit_seriesindex
self.assertEqual("+", bl['table'][6]['Series Index']['text'])
AssertionError: '+' != '3'
- +
+ 3</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
......@@ -1243,22 +1319,46 @@
<tr id='pt11.10' class='hiddenRow bg-success'>
<tr id="ft11.10" class="none bg-danger">
<td>
<div class='testcase'>TestEditBooksList - test_search_books_list</div>
</td>
<td colspan='6' align='center'>PASS</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft11.10')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_ft11.10" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_ft11.10').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_edit_books_list.py", line 53, in test_search_books_list
bl = self.check_search(bl, "HaLaG", 2, "Author Sort", "Beutlin, Frodo & Halagal, Norbert & Yang, Liu & Gonçalves, Hector")
File "/home/ozzie/Development/calibre-web-test/test/test_edit_books_list.py", line 44, in check_search
self.assertEqual(value, bl['table'][0][column]['text'])
AssertionError: 'Beutlin, Frodo & Halagal, Norbert & Yang, Liu & Gonçalves, Hector' != 'Halagal, Norbert'
- Beutlin, Frodo & Halagal, Norbert & Yang, Liu & Gonçalves, Hector
+ Halagal, Norbert</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id="su" class="failClass">
<tr id="su" class="errorClass">
<td>TestEditBooksOnGdrive</td>
<td class="text-center">20</td>
<td class="text-center">18</td>
<td class="text-center">2</td>
<td class="text-center">0</td>
<td class="text-center">1</td>
<td class="text-center">1</td>
<td class="text-center">0</td>
<td class="text-center">
<a onclick="showClassDetail('c12', 20)">Detail</a>
......@@ -1293,12 +1393,13 @@
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_edit_ebooks_gdrive.py", line 340, in test_edit_author
self.assertEqual(u'Sigurd Lindgren & Leo Baskerville', author.get_attribute('value'))
AssertionError: 'Sigurd Lindgren & Leo Baskerville' != 'Sigurd Lindgren&Leo Baskerville'
- Sigurd Lindgren & Leo Baskerville
? - -
+ Sigurd Lindgren&Leo Baskerville</pre>
File "/home/ozzie/Development/calibre-web-test/test/test_edit_ebooks_gdrive.py", line 369, in test_edit_author
self.assertEqual(u'Pipo, Pipe', author.get_attribute('value'))
AssertionError: 'Pipo, Pipe' != 'Pipo| Pipe'
- Pipo, Pipe
? ^
+ Pipo| Pipe
? ^</pre>
</div>
<div class="clearfix"></div>
</div>
......@@ -1425,11 +1526,31 @@ AssertionError: 'Sigurd Lindgren & Leo Baskerville' != 'Sigurd Lindgren&Leo Bask
<tr id='pt12.16' class='hiddenRow bg-success'>
<tr id="et12.16" class="none bg-info">
<td>
<div class='testcase'>TestEditBooksOnGdrive - test_edit_title</div>
</td>
<td colspan='6' align='center'>PASS</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et12.16')">ERROR</a>
</div>
<!--css div popup start-->
<div id="div_et12.16" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_et12.16').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_edit_ebooks_gdrive.py", line 239, in test_edit_title
self.assertEqual(ele.text, u'Very long extra super turbo cool title without any issue of displaying including ö utf-8 characters')
AttributeError: 'bool' object has no attribute 'text'</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
......@@ -1461,31 +1582,11 @@ AssertionError: 'Sigurd Lindgren & Leo Baskerville' != 'Sigurd Lindgren&Leo Bask
<tr id="ft12.20" class="none bg-danger">
<tr id='pt12.20' class='hiddenRow bg-success'>
<td>
<div class='testcase'>TestEditBooksOnGdrive - test_watch_metadata</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft12.20')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_ft12.20" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_ft12.20').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_edit_ebooks_gdrive.py", line 848, in test_watch_metadata
self.assertNotIn('series', book)
AssertionError: 'series' unexpectedly found in {'id': 5, 'reader': [], 'title': 'testbook', 'author': ['John Döe'], 'rating': 0, 'languages': ['English'], 'identifier': [], 'cover': '/cover/5?edit=18d56230-76a3-40ad-a368-d1fa776f385a', 'tag': [], 'publisher': ['Randomhäus'], 'comment': '<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p><p>Aenean commodo ligula eget dolor.</p><p>Aenean massa.</p><p>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p><p>Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.</p><p>Nulla consequat massa quis enim.</p><p>Donec pede justo, fringilla vel, aliquet nec, vulputate</p>', 'add_shelf': [], 'del_shelf': [], 'edit_enable': True, 'kindle': None, 'kindlebtn': None, 'download': ['EPUB (6.7 kB)'], 'read': False, 'archived': False, 'series_all': 'Book 1.0 of test', 'series_index': '1.0', 'series': 'test', 'cust_columns': []}</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
<td colspan='6' align='center'>PASS</td>
</tr>
......@@ -1701,13 +1802,13 @@ AssertionError: 'series' unexpectedly found in {'id': 5, 'reader': [], 'title':
<tr id="su" class="errorClass">
<tr id="su" class="failClass">
<td>TestKoboSync</td>
<td class="text-center">9</td>
<td class="text-center">8</td>
<td class="text-center">0</td>
<td class="text-center">1</td>
<td class="text-center">0</td>
<td class="text-center">0</td>
<td class="text-center">
<a onclick="showClassDetail('c18', 9)">Detail</a>
</td>
......@@ -1715,26 +1816,35 @@ AssertionError: 'series' unexpectedly found in {'id': 5, 'reader': [], 'title':
<tr id="et18.1" class="none bg-info">
<tr id="ft18.1" class="none bg-danger">
<td>
<div class='testcase'>TestKoboSync - test_book_download</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et18.1')">ERROR</a>
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft18.1')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_et18.1" class="popup_window test_output" style="display:none;">
<div id="div_ft18.1" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_et18.1').style.display='none'"><span
onclick='document.getElementById('div_ft18.1').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_kobo_sync.py", line 586, in test_book_download
download = downloadSession.get(data[0]['NewEntitlement']['BookMetadata']['DownloadUrls'][1]['Url'], headers=TestKoboSync.header)
IndexError: list index out of range</pre>
File "/home/ozzie/Development/calibre-web-test/test/test_kobo_sync.py", line 128, in inital_sync
self.assertEqual(data[3]['NewEntitlement']['BookMetadata']['DownloadUrls'][1]['Format'], 'EPUB')
IndexError: list index out of range
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_kobo_sync.py", line 578, in test_book_download
data = self.inital_sync()
File "/home/ozzie/Development/calibre-web-test/test/test_kobo_sync.py", line 140, in inital_sync
self.assertFalse(e, data)
AssertionError: IndexError('list index out of range') is not false : [{'NewEntitlement': {'BookEntitlement': {'Accessibility': 'Full', 'ActivePeriod': {'From': '2021-04-12T23:03:42Z'}, 'Created': '2017-01-20T20:10:53Z', 'CrossRevisionId': 'c1c739b4-000d-4475-8aaf-e10e5d7d6dfe', 'Id': 'c1c739b4-000d-4475-8aaf-e10e5d7d6dfe', 'IsHiddenFromArchive': False, 'IsLocked': False, 'IsRemoved': False, 'LastModified': '2019-01-12T11:18:51Z', 'OriginCategory': 'Imported', 'RevisionId': 'c1c739b4-000d-4475-8aaf-e10e5d7d6dfe', 'Status': 'Active'}, 'BookMetadata': {'Categories': ['00000000-0000-0000-0000-000000000001'], 'ContributorRoles': [{'Name': 'Leo Baskerville', 'Role': 'Author'}], 'Contributors': 'Leo Baskerville', 'CoverImageId': 'c1c739b4-000d-4475-8aaf-e10e5d7d6dfe', 'CrossRevisionId': 'c1c739b4-000d-4475-8aaf-e10e5d7d6dfe', 'CurrentDisplayPrice': {'CurrencyCode': 'USD', 'TotalAmount': 0}, 'CurrentLoveDisplayPrice': {'TotalAmount': 0}, 'Description': None, 'DownloadUrls': [{'Format': 'KEPUB', 'Platform': 'Generic', 'Size': 8391, 'Url': 'http://192.168.188.57:8083/kobo/9073998e0986717f096589fd81a6d31e/download/8/kepub'}], 'EntitlementId': 'c1c739b4-000d-4475-8aaf-e10e5d7d6dfe', 'ExternalIds': [], 'Genre': '00000000-0000-0000-0000-000000000001', 'IsEligibleForKoboLove': False, 'IsInternetArchive': False, 'IsPreOrder': False, 'IsSocialEnabled': True, 'Language': 'en', 'PhoneticPronunciations': {}, 'PublicationDate': 'Sat, 01 Jan 0101 00:00:00 GMT', 'Publisher': {'Imprint': '', 'Name': None}, 'RevisionId': 'c1c739b4-000d-4475-8aaf-e10e5d7d6dfe', 'Title': 'book8', 'WorkId': 'c1c739b4-000d-4475-8aaf-e10e5d7d6dfe'}, 'ReadingState': {'Created': '2017-01-20T20:10:53Z', 'CurrentBookmark': {'LastModified': '2021-04-12T21:03:42Z'}, 'EntitlementId': 'c1c739b4-000d-4475-8aaf-e10e5d7d6dfe', 'LastModified': '2021-04-12T21:03:42Z', 'PriorityTimestamp': '2021-04-12T21:03:42Z', 'Statistics': {'LastModified': '2021-04-12T21:03:42Z'}, 'StatusInfo': {'LastModified': '2021-04-12T21:03:42Z', 'Status': 'ReadyToRead', 'TimesStartedReading': 0}}}}, {'NewEntitlement': {'BookEntitlement': {'Accessibility': 'Full', 'ActivePeriod': {'From': '2021-04-12T23:03:42Z'}, 'Created': '2017-01-20T20:10:54Z', 'CrossRevisionId': 'da18a6c8-c1f2-4110-a4ad-344815961392', 'Id': 'da18a6c8-c1f2-4110-a4ad-344815961392', 'IsHiddenFromArchive': False, 'IsLocked': False, 'IsRemoved': False, 'LastModified': '2019-01-12T11:18:51Z', 'OriginCategory': 'Imported', 'RevisionId': 'da18a6c8-c1f2-4110-a4ad-344815961392', 'Status': 'Active'}, 'BookMetadata': {'Categories': ['00000000-0000-0000-0000-000000000001'], 'ContributorRoles': [{'Name': 'Peter Parker', 'Role': 'Author'}], 'Contributors': 'Peter Parker', 'CoverImageId': 'da18a6c8-c1f2-4110-a4ad-344815961392', 'CrossRevisionId': 'da18a6c8-c1f2-4110-a4ad-344815961392', 'CurrentDisplayPrice': {'CurrencyCode': 'USD', 'TotalAmount': 0}, 'CurrentLoveDisplayPrice': {'TotalAmount': 0}, 'Description': None, 'DownloadUrls': [{'Format': 'KEPUB', 'Platform': 'Generic', 'Size': 6104, 'Url': 'http://192.168.188.57:8083/kobo/9073998e0986717f096589fd81a6d31e/download/10/kepub'}], 'EntitlementId': 'da18a6c8-c1f2-4110-a4ad-344815961392', 'ExternalIds': [], 'Genre': '00000000-0000-0000-0000-000000000001', 'IsEligibleForKoboLove': False, 'IsInternetArchive': False, 'IsPreOrder': False, 'IsSocialEnabled': True, 'Language': 'en', 'PhoneticPronunciations': {}, 'PublicationDate': 'Sat, 01 Jan 0101 00:00:00 GMT', 'Publisher': {'Imprint': '', 'Name': None}, 'RevisionId': 'da18a6c8-c1f2-4110-a4ad-344815961392', 'Title': 'book7', 'WorkId': 'da18a6c8-c1f2-4110-a4ad-344815961392'}, 'ReadingState': {'Created': '2017-01-20T20:10:54Z', 'CurrentBookmark': {'LastModified': '2021-04-12T21:03:42Z'}, 'EntitlementId': 'da18a6c8-c1f2-4110-a4ad-344815961392', 'LastModified': '2021-04-12T21:03:42Z', 'PriorityTimestamp': '2021-04-12T21:03:42Z', 'Statistics': {'LastModified': '2021-04-12T21:03:42Z'}, 'StatusInfo': {'LastModified': '2021-04-12T21:03:42Z', 'Status': 'ReadyToRead', 'TimesStartedReading': 0}}}}, {'NewEntitlement': {'BookEntitlement': {'Accessibility': 'Full', 'ActivePeriod': {'From': '2021-04-12T23:03:42Z'}, 'Created': '2017-01-20T20:10:53Z', 'CrossRevisionId': '2593127f-b40e-42bf-a999-d042f67e5212', 'Id': '2593127f-b40e-42bf-a999-d042f67e5212', 'IsHiddenFromArchive': False, 'IsLocked': False, 'IsRemoved': False, 'LastModified': '2020-05-17T08:40:54Z', 'OriginCategory': 'Imported', 'RevisionId': '2593127f-b40e-42bf-a999-d042f67e5212', 'Status': 'Active'}, 'BookMetadata': {'Categories': ['00000000-0000-0000-0000-000000000001'], 'ContributorRoles': [{'Name': 'Sigurd Lindgren', 'Role': 'Author'}], 'Contributors': 'Sigurd Lindgren', 'CoverImageId': '2593127f-b40e-42bf-a999-d042f67e5212', 'CrossRevisionId': '2593127f-b40e-42bf-a999-d042f67e5212', 'CurrentDisplayPrice': {'CurrencyCode': 'USD', 'TotalAmount': 0}, 'CurrentLoveDisplayPrice': {'TotalAmount': 0}, 'Description': None, 'DownloadUrls': [{'Format': 'KEPUB', 'Platform': 'Generic', 'Size': 7592, 'Url': 'http://192.168.188.57:8083/kobo/9073998e0986717f096589fd81a6d31e/download/9/kepub'}], 'EntitlementId': '2593127f-b40e-42bf-a999-d042f67e5212', 'ExternalIds': [], 'Genre': '00000000-0000-0000-0000-000000000001', 'IsEligibleForKoboLove': False, 'IsInternetArchive': False, 'IsPreOrder': False, 'IsSocialEnabled': True, 'Language': 'en', 'PhoneticPronunciations': {}, 'PublicationDate': 'Sat, 01 Jan 0101 00:00:00 GMT', 'Publisher': {'Imprint': '', 'Name': None}, 'RevisionId': '2593127f-b40e-42bf-a999-d042f67e5212', 'Series': {'Id': 'cad7d6c3-f4e9-37e9-b9be-8b98c80bb5cc', 'Name': 'Loko', 'Number': 1, 'NumberFloat': 1.0}, 'Title': 'book6', 'WorkId': '2593127f-b40e-42bf-a999-d042f67e5212'}, 'ReadingState': {'Created': '2017-01-20T20:10:53Z', 'CurrentBookmark': {'LastModified': '2021-04-12T21:03:42Z'}, 'EntitlementId': '2593127f-b40e-42bf-a999-d042f67e5212', 'LastModified': '2021-04-12T21:03:42Z', 'PriorityTimestamp': '2021-04-12T21:03:42Z', 'Statistics': {'LastModified': '2021-04-12T21:03:42Z'}, 'StatusInfo': {'LastModified': '2021-04-12T21:03:42Z', 'Status': 'ReadyToRead', 'TimesStartedReading': 0}}}}, {'NewEntitlement': {'BookEntitlement': {'Accessibility': 'Full', 'ActivePeriod': {'From': '2021-04-12T23:03:42Z'}, 'Created': '2017-01-20T20:00:15Z', 'CrossRevisionId': '8f1b72c1-e9a4-4212-b538-8e4f4837d201', 'Id': '8f1b72c1-e9a4-4212-b538-8e4f4837d201', 'IsHiddenFromArchive': False, 'IsLocked': False, 'IsRemoved': False, 'LastModified': '2021-04-12T21:03:42Z', 'OriginCategory': 'Imported', 'RevisionId': '8f1b72c1-e9a4-4212-b538-8e4f4837d201', 'Status': 'Active'}, 'BookMetadata': {'Categories': ['00000000-0000-0000-0000-000000000001'], 'ContributorRoles': [{'Name': 'John Döe执', 'Role': 'Author'}, {'Name': 'Mon Go', 'Role': 'Author'}], 'Contributors': ['John Döe执', 'Mon Go'], 'CoverImageId': '8f1b72c1-e9a4-4212-b538-8e4f4837d201', 'CrossRevisionId': '8f1b72c1-e9a4-4212-b538-8e4f4837d201', 'CurrentDisplayPrice': {'CurrencyCode': 'USD', 'TotalAmount': 0}, 'CurrentLoveDisplayPrice': {'TotalAmount': 0}, 'Description': '<p>b物</p>', 'DownloadUrls': [{'Format': 'KEPUB', 'Platform': 'Generic', 'Size': 8572, 'Url': 'http://192.168.188.57:8083/kobo/9073998e0986717f096589fd81a6d31e/download/5/kepub'}], 'EntitlementId': '8f1b72c1-e9a4-4212-b538-8e4f4837d201', 'ExternalIds': [], 'Genre': '00000000-0000-0000-0000-000000000001', 'IsEligibleForKoboLove': False, 'IsInternetArchive': False, 'IsPreOrder': False, 'IsSocialEnabled': True, 'Language': 'en', 'PhoneticPronunciations': {}, 'PublicationDate': 'Thu, 19 Jan 2017 00:00:00 GMT', 'Publisher': {'Imprint': '', 'Name': 'Publish执'}, 'RevisionId': '8f1b72c1-e9a4-4212-b538-8e4f4837d201', 'Series': {'Id': '1c5d353f-e0cd-33cc-92b9-88db7329aaa9', 'Name': 'O0ü 执', 'Number': 1.5, 'NumberFloat': 1.5}, 'Title': 'testbook执', 'WorkId': '8f1b72c1-e9a4-4212-b538-8e4f4837d201'}, 'ReadingState': {'Created': '2017-01-20T20:00:15Z', 'CurrentBookmark': {'LastModified': '2021-04-12T21:03:42Z'}, 'EntitlementId': '8f1b72c1-e9a4-4212-b538-8e4f4837d201', 'LastModified': '2021-04-12T21:03:42Z', 'PriorityTimestamp': '2021-04-12T21:03:42Z', 'Statistics': {'LastModified': '2021-04-12T21:03:42Z'}, 'StatusInfo': {'LastModified': '2021-04-12T21:03:42Z', 'Status': 'ReadyToRead', 'TimesStartedReading': 0}}}}]</pre>
</div>
<div class="clearfix"></div>
</div>
......@@ -2185,11 +2295,11 @@ IndexError: list index out of range</pre>
<tr id="su" class="passClass">
<tr id="su" class="failClass">
<td>TestMergeBooksList</td>
<td class="text-center">2</td>
<td class="text-center">2</td>
<td class="text-center">0</td>
<td class="text-center">1</td>
<td class="text-center">1</td>
<td class="text-center">0</td>
<td class="text-center">0</td>
<td class="text-center">
......@@ -2199,11 +2309,31 @@ IndexError: list index out of range</pre>
<tr id='pt22.1' class='hiddenRow bg-success'>
<tr id="ft22.1" class="none bg-danger">
<td>
<div class='testcase'>TestMergeBooksList - test_delete_book</div>
</td>
<td colspan='6' align='center'>PASS</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft22.1')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_ft22.1" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_ft22.1').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_merge_books_list.py", line 59, in test_delete_book
self.assertTrue(self.check_element_on_page((By.ID, "flash_warning")))
AssertionError: False is not true</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
......@@ -2880,55 +3010,292 @@ IndexError: list index out of range</pre>
<tr id="su" class="errorClass">
<td>_ErrorHolder</td>
<td class="text-center">1</td>
<td class="text-center">0</td>
<td class="text-center">0</td>
<td>TestUserList</td>
<td class="text-center">11</td>
<td class="text-center">2</td>
<td class="text-center">6</td>
<td class="text-center">2</td>
<td class="text-center">1</td>
<td class="text-center">0</td>
<td class="text-center">
<a onclick="showClassDetail('c30', 1)">Detail</a>
<a onclick="showClassDetail('c30', 11)">Detail</a>
</td>
</tr>
<tr id="et30.1" class="none bg-info">
<tr id="ft30.1" class="none bg-danger">
<td>
<div class='testcase'>setUpClass (test_user_list)</div>
<div class='testcase'>TestUserList - test_list_visibility</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et30.1')">ERROR</a>
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft30.1')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_et30.1" class="popup_window test_output" style="display:none;">
<div id="div_ft30.1" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_et30.1').style.display='none'"><span
onclick='document.getElementById('div_ft30.1').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_user_list.py", line 50, in setUpClass
debug_startup(cls, cls.py_version, {'config_calibre_dir': TEST_DB})
File "/home/ozzie/Development/calibre-web-test/test/helper_func.py", line 109, in debug_startup
inst.driver.get(host)
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 333, in get
self.execute(Command.GET, {'url': url})
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: Reached error page: about:neterror?e=connectionFailure&u=http%3A//127.0.0.1%3A8083/&c=UTF-8&d=Firefox%20kann%20keine%20Verbindung%20zu%20dem%20Server%20unter%20127.0.0.1%3A8083%20aufbauen.
File "/home/ozzie/Development/calibre-web-test/test/test_user_list.py", line 103, in test_list_visibility
self.assertEqual(32, len(ul['column_elements']))
AssertionError: 32 != 33</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_user_list.py", line 55, in setUpClass
cls.p.kill()
AttributeError: 'NoneType' object has no attribute 'kill'</pre>
<tr id="ft30.2" class="none bg-danger">
<td>
<div class='testcase'>TestUserList - test_user_list_admin_role</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft30.2')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_ft30.2" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_ft30.2').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_user_list.py", line 251, in test_user_list_admin_role
self.assertTrue(ul['table'][0]['role_Admin']['element'].is_selected())
AssertionError: False is not true</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id="st30.3" class="none bg-warning">
<td>
<div class='testcase'>TestUserList - test_user_list_denied_tags</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_st30.3')">SKIP</a>
</div>
<!--css div popup start-->
<div id="div_st30.3" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_st30.3').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Not Implemented</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id="ft30.4" class="none bg-danger">
<td>
<div class='testcase'>TestUserList - test_user_list_download_role</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft30.4')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_ft30.4" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_ft30.4').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_user_list.py", line 267, in test_user_list_download_role
self.assertFalse(ul['table'][1]['role_Download']['element'].is_selected())
AssertionError: True is not false</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id="ft30.5" class="none bg-danger">
<td>
<div class='testcase'>TestUserList - test_user_list_edit_button</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft30.5')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_ft30.5" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_ft30.5').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_user_list.py", line 90, in test_user_list_edit_button
self.assertEqual("3_no", ul['table'][0]['Username']['text'])
AssertionError: '3_no' != '2_no'
- 3_no
? ^
+ 2_no
? ^</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id="et30.6" class="none bg-info">
<td>
<div class='testcase'>TestUserList - test_user_list_edit_email</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et30.6')">ERROR</a>
</div>
<!--css div popup start-->
<div id="div_et30.6" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_et30.6').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_user_list.py", line 182, in test_user_list_edit_email
self.assertTrue("existing account" in self.check_element_on_page((By.XPATH,
AttributeError: 'bool' object has no attribute 'text'</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id='pt30.7' class='hiddenRow bg-success'>
<td>
<div class='testcase'>TestUserList - test_user_list_edit_kindle</div>
</td>
<td colspan='6' align='center'>PASS</td>
</tr>
<tr id="ft30.8" class="none bg-danger">
<td>
<div class='testcase'>TestUserList - test_user_list_edit_language</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft30.8')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_ft30.8" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_ft30.8').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_user_list.py", line 235, in test_user_list_edit_language
self.assertEqual("English", ul['table'][1]['Locale']['element'].text)
AssertionError: 'English' != 'German'
- English
+ German</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id='pt30.9' class='hiddenRow bg-success'>
<td>
<div class='testcase'>TestUserList - test_user_list_edit_locale</div>
</td>
<td colspan='6' align='center'>PASS</td>
</tr>
<tr id="et30.10" class="none bg-info">
<td>
<div class='testcase'>TestUserList - test_user_list_edit_name</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et30.10')">ERROR</a>
</div>
<!--css div popup start-->
<div id="div_et30.10" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_et30.10').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_user_list.py", line 157, in test_user_list_edit_name
self.assertTrue("already taken" in self.check_element_on_page((By.XPATH,
AttributeError: 'bool' object has no attribute 'text'</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr>
<tr id="ft30.11" class="none bg-danger">
<td>
<div class='testcase'>TestUserList - test_user_list_edit_visiblility</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft30.11')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_ft30.11" class="popup_window test_output" style="display:none;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus='this.blur();'
onclick='document.getElementById('div_ft30.11').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File "/home/ozzie/Development/calibre-web-test/test/test_user_list.py", line 290, in test_user_list_edit_visiblility
self.assertFalse(ul['table'][4]['Show category selection']['element'].is_selected())
AssertionError: True is not false</pre>
</div>
<div class="clearfix"></div>
</div>
......@@ -3639,11 +4006,11 @@ AttributeError: 'NoneType' object has no attribute 'kill'</pre>
<tr id='total_row' class="text-center bg-grey">
<td>Total</td>
<td>312</td>
<td>301</td>
<td>2</td>
<td>2</td>
<td>7</td>
<td>322</td>
<td>298</td>
<td>12</td>
<td>4</td>
<td>8</td>
<td>&nbsp;</td>
</tr>
</table>
......@@ -3989,13 +4356,13 @@ AttributeError: 'NoneType' object has no attribute 'kill'</pre>
<tr>
<th>Flask-Dance</th>
<td>3.3.1</td>
<td>4.0.0</td>
<td>TestOAuthLogin</td>
</tr>
<tr>
<th>SQLAlchemy-Utils</th>
<td>0.36.8</td>
<td>0.37.0</td>
<td>TestOAuthLogin</td>
</tr>
......@@ -4013,7 +4380,7 @@ AttributeError: 'NoneType' object has no attribute 'kill'</pre>
</div>
<script>
drawCircle(301, 2, 2, 7);
drawCircle(298, 12, 4, 8);
</script>
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment