1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/django-fmd_ynh.git synced 2024-09-03 18:26:27 +02:00

Merge pull request #8 from YunoHost-Apps/fix-tests

Fix and expand tests
This commit is contained in:
Jens Diemer 2022-07-12 18:41:07 +02:00 committed by GitHub
commit 8ec0ecde7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 324 additions and 17 deletions

33
poetry.lock generated
View file

@ -53,6 +53,21 @@ docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"]
[[package]]
name = "beautifulsoup4"
version = "4.11.1"
description = "Screen-scraping library"
category = "dev"
optional = false
python-versions = ">=3.6.0"
[package.dependencies]
soupsieve = ">1.2"
[package.extras]
html5lib = ["html5lib"]
lxml = ["lxml"]
[[package]] [[package]]
name = "black" name = "black"
version = "22.6.0" version = "22.6.0"
@ -746,6 +761,14 @@ category = "main"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
[[package]]
name = "soupsieve"
version = "2.3.2.post1"
description = "A modern CSS selector implementation for Beautiful Soup."
category = "dev"
optional = false
python-versions = ">=3.6"
[[package]] [[package]]
name = "sqlparse" name = "sqlparse"
version = "0.4.2" version = "0.4.2"
@ -880,7 +903,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = ">=3.7,<4.0.0" python-versions = ">=3.7,<4.0.0"
content-hash = "efbe068c32696bda78b96c5bc9d05217a92a8f19ef832d444cdd6e6b99a5223c" content-hash = "0262d33ea15ad4ec9e8234cd55634c1c34df4ce3f878c268fb1b3c8da5b94f7a"
[metadata.files] [metadata.files]
asgiref = [ asgiref = [
@ -902,6 +925,10 @@ attrs = [
{file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
{file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"},
] ]
beautifulsoup4 = [
{file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"},
{file = "beautifulsoup4-4.11.1.tar.gz", hash = "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"},
]
black = [ black = [
{file = "black-22.6.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f586c26118bc6e714ec58c09df0157fe2d9ee195c764f630eb0d8e7ccce72e69"}, {file = "black-22.6.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f586c26118bc6e714ec58c09df0157fe2d9ee195c764f630eb0d8e7ccce72e69"},
{file = "black-22.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b270a168d69edb8b7ed32c193ef10fd27844e5c60852039599f9184460ce0807"}, {file = "black-22.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b270a168d69edb8b7ed32c193ef10fd27844e5c60852039599f9184460ce0807"},
@ -1193,6 +1220,10 @@ six = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
] ]
soupsieve = [
{file = "soupsieve-2.3.2.post1-py3-none-any.whl", hash = "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759"},
{file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"},
]
sqlparse = [ sqlparse = [
{file = "sqlparse-0.4.2-py3-none-any.whl", hash = "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d"}, {file = "sqlparse-0.4.2-py3-none-any.whl", hash = "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d"},
{file = "sqlparse-0.4.2.tar.gz", hash = "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae"}, {file = "sqlparse-0.4.2.tar.gz", hash = "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae"},

View file

@ -30,6 +30,7 @@ flake8 = "*"
flynt = "*" flynt = "*"
darker = "*" # https://github.com/akaihola/darker darker = "*" # https://github.com/akaihola/darker
pyupgrade = "*" pyupgrade = "*"
beautifulsoup4 = "*"
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=1.0.0"]

View file

@ -1,8 +1,12 @@
from pathlib import Path from pathlib import Path
from bx_django_utils.test_utils.html_assertion import HtmlAssertionMixin from bx_django_utils.test_utils.html_assertion import (
HtmlAssertionMixin,
assert_html_response_snapshot,
)
from django.conf import LazySettings, settings from django.conf import LazySettings, settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.http import FileResponse, HttpResponse
from django.test import override_settings from django.test import override_settings
from django.test.testcases import TestCase from django.test.testcases import TestCase
from django.urls import NoReverseMatch from django.urls import NoReverseMatch
@ -10,7 +14,7 @@ from django.urls.base import reverse
from django_yunohost_integration.test_utils import generate_basic_auth from django_yunohost_integration.test_utils import generate_basic_auth
from django_yunohost_integration.views import request_media_debug_view from django_yunohost_integration.views import request_media_debug_view
import findmydevice from findmydevice import __version__
@override_settings(DEBUG=False) @override_settings(DEBUG=False)
@ -57,23 +61,43 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
) )
response = self.client.get('/app_path/', secure=True) response = self.client.get('/app_path/', secure=True)
self.assertRedirects( self.assertTemplateUsed(response, 'fmd/login_info.html')
response, expected_url='/app_path/group_management/', fetch_redirect_response=False self.assert_html_parts(
)
response = self.client.get('/app_path/group_management/', secure=True)
self.assertRedirects(
response, response,
expected_url='/app_path/admin/login/?next=/app_path/group_management/', parts=(
fetch_redirect_response=False, '<title>Log in | Find My Device</title>',
'<p class="errornote">To find your device, you must be logged in.</p>',
'<a href="/yunohost/sso/">Log in</a>',
),
) )
assert_html_response_snapshot(response, query_selector=None, validate=False)
response = self.client.get('/app_path/admin/', secure=True) def test_web_page_as_sso_user(self):
self.assertRedirects( assert User.objects.count() == 0
response, self.client.cookies['SSOwAuthUser'] = 'test'
expected_url='/app_path/admin/login/?next=/app_path/admin/', response = self.client.get(
fetch_redirect_response=False, path='/app_path/',
HTTP_REMOTE_USER='test',
HTTP_AUTH_USER='test',
HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz',
secure=True,
) )
assert isinstance(response, FileResponse)
assert User.objects.count() == 1
user = User.objects.first()
assert user.username == 'test'
response2 = HttpResponse(response.getvalue())
self.assert_html_parts(
response2,
parts=(
'<title>FMD</title>',
'<h2>Find My Device</h2>',
'<script src="./logic.js"></script>',
),
)
assert_html_response_snapshot(response2, query_selector=None, validate=False)
@override_settings(SECURE_SSL_REDIRECT=False) @override_settings(SECURE_SSL_REDIRECT=False)
def test_create_unknown_user(self): def test_create_unknown_user(self):
@ -99,8 +123,9 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
self.assert_html_parts( self.assert_html_parts(
response, response,
parts=( parts=(
'<title>Site administration | Find My Device</title>', '<title>Site administration | Find My Device admin</title>',
'<strong>test</strong>', '<strong>test</strong>',
f'<a href="/app_path/admin/">Django Find My Device v{__version__}</a>',
), ),
) )

View file

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<title>
Log in | Find My Device
</title>
<link href="/app_path/static/admin/css/base.css" rel="stylesheet" type="text/css"/>
<meta content="notranslate" name="google"/>
<meta content="noindex,nofollow" name="robots">
<meta content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0" name="viewport"/>
<link href="/app_path/static/admin/css/responsive.css" rel="stylesheet" type="text/css"/>
<meta content="NONE,NOARCHIVE" name="robots"/>
</meta>
</head>
<body class="" data-admin-utc-offset="7200">
<!-- Container -->
<div id="container">
<!-- Header -->
<div id="header">
<div id="branding">
<h1>
Find My Device
</h1>
</div>
</div>
<!-- END Header -->
<div class="main shifted" id="main">
<div class="content">
<!-- Content -->
<div class="colM" id="content">
<h1>
Log in
</h1>
<p class="errornote">
To find your device, you must be logged in.
</p>
<p>
<a href="/yunohost/sso/">
Log in
</a>
</p>
<br class="clear"/>
</div>
<!-- END Content -->
<div class="submit-row" id="footer">
<a href="https://gitlab.com/jedie/django-find-my-device">
gitlab.com/jedie/django-find-my-device
</a>
</div>
</div>
</div>
</div>
<!-- END Container -->
</body>
</html>

View file

@ -0,0 +1,195 @@
<!DOCTYPE html>
<html>
<head>
<title>
FMD
</title>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<meta content="no-cache, must-revalidate, post-check=0, pre-check=0" http-equiv="cache-control">
<meta content="max-age=0" http-equiv="cache-control"/>
<meta content="0" http-equiv="expires"/>
<link href="./style.css?t=123456" rel="stylesheet"/>
<script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js">
</script>
<link href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.js" type="text/javascript">
</script>
<script async="" src="https://cdnjs.cloudflare.com/ajax/libs/jsencrypt/2.3.1/jsencrypt.min.js">
</script>
<link href="https://unpkg.com/toastedjs/dist/toasted.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/toastedjs/dist/toasted.min.js">
</script>
<script src="./logic.js">
</script>
<body onload="init();">
<div id="head">
<div class="center">
<h2>
Find My Device
</h2>
</div>
<br/>
<div id="login">
<div class="center">
<p>
This server tracks all your registered devices.
<br/>
Please enter the device-id to receive the latest
location:
</p>
</div>
<br/>
<div class="center">
<input id="fmdid" name="fmdid" onkeypress="clickPress(event)" type="text"/>
<br/>
<br/>
</div>
<div class="center">
<button id="locateButton" onclick="prepareForLocate();" type="button">
LOCATE
</button>
</div>
</div>
</div>
<div id="dataView" onkeypress="switchWithKeys(event)">
<div id="map">
</div>
</div>
<footer>
<div>
<div class="deviceInfo" id="desktop">
<div class="row">
<div class="column-left">
<div class="center">
<img height="96" src="assets/Smartphone.png"/>
</div>
<div class="center" style="margin-top:1vw">
<p id="batView">
Data
</p>
</div>
</div>
<div class="column-middle">
<h3 id="idView" style="display:inline;">
ID
</h3>
<p>
-
</p>
<p id="providerView">
Data
</p>
<div>
<button class="imageButton" onclick="locateOlder()" type="button">
<img height="24" src="assets/Left.png"/>
</button>
<button class="imageButton" onclick="locateNewer()" type="button">
<img height="24" src="assets/Right.png"/>
</button>
</div>
<div>
<p id="datetime">
data from
</p>
<p id="dateView">
Date
</p>
<p id="timeView">
Time
</p>
</div>
<button class="imageButton" onclick="sendToPhone('locate')" title="Locate" type="button">
<img height="36" src="assets/Locate.png"/>
</button>
<button class="imageButton" onclick="sendToPhone('ring')" title="Ring" type="button">
<img height="36" src="assets/Ring.png"/>
</button>
<button class="imageButton" onclick="sendToPhone('lock')" title="Lock" type="button">
<img height="36" src="assets/Locked.png"/>
</button>
<button class="imageButton" onclick="sendToPhone('delete')" title="Delete" type="button">
<img height="36" src="assets/Delete.png"/>
</button>
<button class="imageButton" onclick="showPicture()" title="Picture" type="button">
<img height="36" src="assets/Picture.png"/>
</button>
</div>
</div>
</div>
<div class="deviceInfo" id="mobile">
<div class="row">
<div class="column-left">
<div class="center">
<img height="48" src="assets/Smartphone.png"/>
</div>
<div class="center" style="margin-top:1vw">
<p id="batView">
Data
</p>
</div>
</div>
<div class="column-middle">
<h3 id="idView" style="display:inline;">
ID
</h3>
<p>
-
</p>
<p id="providerView">
Data
</p>
<div>
<button class="imageButton" onclick="locateOlder()" type="button">
<img height="24" src="assets/Left.png"/>
</button>
<button class="imageButton" onclick="locateNewer()" type="button">
<img height="24" src="assets/Right.png"/>
</button>
</div>
<div>
<p id="datetime">
data from
</p>
<p id="dateView">
Date
</p>
<p id="timeView">
Time
</p>
</div>
<button class="imageButton" onclick="sendToPhone('locate')" title="Locate" type="button">
<img height="24" src="assets/Locate.png"/>
</button>
<button class="imageButton" onclick="sendToPhone('ring')" title="Ring" type="button">
<img height="24" src="assets/Ring.png"/>
</button>
<button class="imageButton" onclick="sendToPhone('lock')" title="Lock" type="button">
<img height="24" src="assets/Locked.png"/>
</button>
<button class="imageButton" onclick="sendToPhone('delete')" title="Delete" type="button">
<img height="24" src="assets/Delete.png"/>
</button>
<button class="imageButton" onclick="showPicture()" title="Picture" type="button">
<img height="24" src="assets/Picture.png"/>
</button>
</div>
</div>
</div>
<div class="center">
<p>
@Nulide FMDServer
</p>
<p id="version">
v
</p>
<a href="ds.html">
Privacy Notice
</a>
</div>
</div>
</footer>
</body>
</link>
</meta>
</head>
</html>