Merge pull request #73 from SamR1/fix-app-config-update
Fix files upload configuration
This commit is contained in:
commit
e205ac3eda
@ -12,10 +12,14 @@ Administration
|
||||
|
||||
The following parameters can be set:
|
||||
|
||||
- active users limit (if 0, registration is enabled (no limit defined))
|
||||
- active users limit. If 0, registration is enabled (no limit defined)
|
||||
- maximum size of uploaded files
|
||||
- maximum size of zip archive
|
||||
- maximum number of files in the zip archive
|
||||
- maximum number of files in the zip archive. If an archive contains more files, only the configured number of files is processed, without raising errors.
|
||||
|
||||
.. warning::
|
||||
Updating server configuration may be necessary to handle large files (like `nginx <https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size>`_ for instance).
|
||||
|
||||
|
||||
- **Users**
|
||||
|
||||
|
@ -571,6 +571,9 @@ Examples (to update depending on your application configuration and given distri
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
.. note::
|
||||
More information on `Gunicorn documentation <https://docs.gunicorn.org/en/stable/deploy.html>`__
|
||||
|
||||
- for task queue workers: ``fittrackee_workers.service``
|
||||
|
||||
.. code-block::
|
||||
@ -635,7 +638,7 @@ Examples (to update depending on your application configuration and given distri
|
||||
}
|
||||
|
||||
.. note::
|
||||
More information on `Gunicorn documentation <https://docs.gunicorn.org/en/stable/deploy.html>`__
|
||||
If needed, update configuration to handle larger files (see `client_max_body_size <https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size>`_).
|
||||
|
||||
|
||||
Docker
|
||||
|
@ -196,11 +196,11 @@
|
||||
</dd>
|
||||
<dt class="field-even">Request JSON Object</dt>
|
||||
<dd class="field-even"><ul class="simple">
|
||||
<li><p><strong>gpx_limit_import</strong> (<em>integrer</em>) – max number of files in zip archive</p></li>
|
||||
<li><p><strong>gpx_limit_import</strong> (<em>integer</em>) – max number of files in zip archive</p></li>
|
||||
<li><p><strong>is_registration_enabled</strong> (<em>boolean</em>) – is registration enabled ?</p></li>
|
||||
<li><p><strong>max_single_file_size</strong> (<em>integrer</em>) – max size of a single file</p></li>
|
||||
<li><p><strong>max_zip_file_size</strong> (<em>integrer</em>) – max size of a zip archive</p></li>
|
||||
<li><p><strong>max_users</strong> (<em>integrer</em>) – max users allowed to register on instance</p></li>
|
||||
<li><p><strong>max_single_file_size</strong> (<em>integer</em>) – max size of a single file</p></li>
|
||||
<li><p><strong>max_zip_file_size</strong> (<em>integer</em>) – max size of a zip archive</p></li>
|
||||
<li><p><strong>max_users</strong> (<em>integer</em>) – max users allowed to register on instance</p></li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt class="field-odd">Request Headers</dt>
|
||||
|
@ -149,11 +149,15 @@
|
||||
<li><p><strong>Application</strong></p>
|
||||
<p>The following parameters can be set:</p>
|
||||
<ul class="simple">
|
||||
<li><p>active users limit (if 0, registration is enabled (no limit defined))</p></li>
|
||||
<li><p>active users limit. If 0, registration is enabled (no limit defined)</p></li>
|
||||
<li><p>maximum size of uploaded files</p></li>
|
||||
<li><p>maximum size of zip archive</p></li>
|
||||
<li><p>maximum number of files in the zip archive</p></li>
|
||||
<li><p>maximum number of files in the zip archive. If an archive contains more files, only the configured number of files is processed, without raising errors.</p></li>
|
||||
</ul>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">Warning</p>
|
||||
<p>Updating server configuration may be necessary to handle large files (like <a class="reference external" href="https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size">nginx</a> for instance).</p>
|
||||
</div>
|
||||
</li>
|
||||
<li><p><strong>Users</strong></p>
|
||||
<ul class="simple">
|
||||
|
@ -832,6 +832,10 @@ One way is to use a <strong>systemd</strong> services and <strong>Nginx</strong>
|
||||
<span class="n">WantedBy</span><span class="o">=</span><span class="n">multi</span><span class="o">-</span><span class="n">user</span><span class="o">.</span><span class="n">target</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">Note</p>
|
||||
<p>More information on <a class="reference external" href="https://docs.gunicorn.org/en/stable/deploy.html">Gunicorn documentation</a></p>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>for task queue workers: <code class="docutils literal notranslate"><span class="pre">fittrackee_workers.service</span></code></p></li>
|
||||
</ul>
|
||||
@ -897,7 +901,7 @@ server {
|
||||
</div>
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">Note</p>
|
||||
<p>More information on <a class="reference external" href="https://docs.gunicorn.org/en/stable/deploy.html">Gunicorn documentation</a></p>
|
||||
<p>If needed, update configuration to handle larger files (see <a class="reference external" href="https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size">client_max_body_size</a>).</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="docker">
|
||||
|
File diff suppressed because one or more lines are too long
@ -12,10 +12,14 @@ Administration
|
||||
|
||||
The following parameters can be set:
|
||||
|
||||
- active users limit (if 0, registration is enabled (no limit defined))
|
||||
- active users limit. If 0, registration is enabled (no limit defined)
|
||||
- maximum size of uploaded files
|
||||
- maximum size of zip archive
|
||||
- maximum number of files in the zip archive
|
||||
- maximum number of files in the zip archive. If an archive contains more files, only the configured number of files is processed, without raising errors.
|
||||
|
||||
.. warning::
|
||||
Updating server configuration may be necessary to handle large files (like `nginx <https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size>`_ for instance).
|
||||
|
||||
|
||||
- **Users**
|
||||
|
||||
|
@ -571,6 +571,9 @@ Examples (to update depending on your application configuration and given distri
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
.. note::
|
||||
More information on `Gunicorn documentation <https://docs.gunicorn.org/en/stable/deploy.html>`__
|
||||
|
||||
- for task queue workers: ``fittrackee_workers.service``
|
||||
|
||||
.. code-block::
|
||||
@ -635,7 +638,7 @@ Examples (to update depending on your application configuration and given distri
|
||||
}
|
||||
|
||||
.. note::
|
||||
More information on `Gunicorn documentation <https://docs.gunicorn.org/en/stable/deploy.html>`__
|
||||
If needed, update configuration to handle larger files (see `client_max_body_size <https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size>`_).
|
||||
|
||||
|
||||
Docker
|
||||
|
@ -12,7 +12,7 @@ from fittrackee.responses import (
|
||||
from fittrackee.users.decorators import authenticate_as_admin
|
||||
|
||||
from .models import AppConfig
|
||||
from .utils import update_app_config_from_database
|
||||
from .utils import update_app_config_from_database, verify_app_config
|
||||
|
||||
config_blueprint = Blueprint('config', __name__)
|
||||
|
||||
@ -96,11 +96,11 @@ def update_application_config(auth_user_id: int) -> Union[Dict, HttpResponse]:
|
||||
|
||||
:param integer auth_user_id: authenticate user id (from JSON Web Token)
|
||||
|
||||
:<json integrer gpx_limit_import: max number of files in zip archive
|
||||
:<json integer gpx_limit_import: max number of files in zip archive
|
||||
:<json boolean is_registration_enabled: is registration enabled ?
|
||||
:<json integrer max_single_file_size: max size of a single file
|
||||
:<json integrer max_zip_file_size: max size of a zip archive
|
||||
:<json integrer max_users: max users allowed to register on instance
|
||||
:<json integer max_single_file_size: max size of a single file
|
||||
:<json integer max_zip_file_size: max size of a zip archive
|
||||
:<json integer max_users: max users allowed to register on instance
|
||||
|
||||
:reqheader Authorization: OAuth 2.0 Bearer Token
|
||||
|
||||
@ -117,6 +117,10 @@ def update_application_config(auth_user_id: int) -> Union[Dict, HttpResponse]:
|
||||
if not config_data:
|
||||
return InvalidPayloadErrorResponse()
|
||||
|
||||
ret = verify_app_config(config_data)
|
||||
if ret:
|
||||
return InvalidPayloadErrorResponse(message=ret)
|
||||
|
||||
try:
|
||||
config = AppConfig.query.one()
|
||||
if 'gpx_limit_import' in config_data:
|
||||
@ -130,6 +134,11 @@ def update_application_config(auth_user_id: int) -> Union[Dict, HttpResponse]:
|
||||
if 'max_users' in config_data:
|
||||
config.max_users = config_data.get('max_users')
|
||||
|
||||
if config.max_zip_file_size < config.max_single_file_size:
|
||||
return InvalidPayloadErrorResponse(
|
||||
'Max. size of zip archive must be equal or greater than '
|
||||
'max. size of uploaded files'
|
||||
)
|
||||
db.session.commit()
|
||||
update_app_config_from_database(current_app, config)
|
||||
return {'status': 'success', 'data': config.serialize()}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import os
|
||||
from typing import Tuple
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
from flask import Flask
|
||||
|
||||
@ -49,3 +49,30 @@ def update_app_config_from_database(
|
||||
current_app.config[
|
||||
'is_registration_enabled'
|
||||
] = db_config.is_registration_enabled
|
||||
|
||||
|
||||
def verify_app_config(config_data: Dict) -> List:
|
||||
"""
|
||||
Verify if application config is valid.
|
||||
|
||||
If not, it returns not empty string
|
||||
"""
|
||||
ret = []
|
||||
if (
|
||||
'gpx_limit_import' in config_data
|
||||
and config_data['gpx_limit_import'] <= 0
|
||||
):
|
||||
ret.append('Max. files in a zip archive must be greater than 0')
|
||||
|
||||
if (
|
||||
'max_single_file_size' in config_data
|
||||
and config_data['max_single_file_size'] <= 0
|
||||
):
|
||||
ret.append('Max. size of uploaded files must be greater than 0')
|
||||
|
||||
if (
|
||||
'max_zip_file_size' in config_data
|
||||
and config_data['max_zip_file_size'] <= 0
|
||||
):
|
||||
ret.append('Max. size of zip archive must be greater than 0')
|
||||
return ret
|
||||
|
12
fittrackee/dist/asset-manifest.json
vendored
12
fittrackee/dist/asset-manifest.json
vendored
@ -1,14 +1,14 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.376b8924.chunk.css",
|
||||
"main.js": "/static/js/main.8faa878d.chunk.js",
|
||||
"main.js.map": "/static/js/main.8faa878d.chunk.js.map",
|
||||
"main.css": "/static/css/main.47c735b4.chunk.css",
|
||||
"main.js": "/static/js/main.75f806db.chunk.js",
|
||||
"main.js.map": "/static/js/main.75f806db.chunk.js.map",
|
||||
"runtime-main.js": "/static/js/runtime-main.1240af94.js",
|
||||
"runtime-main.js.map": "/static/js/runtime-main.1240af94.js.map",
|
||||
"static/js/2.301144a0.chunk.js": "/static/js/2.301144a0.chunk.js",
|
||||
"static/js/2.301144a0.chunk.js.map": "/static/js/2.301144a0.chunk.js.map",
|
||||
"index.html": "/index.html",
|
||||
"static/css/main.376b8924.chunk.css.map": "/static/css/main.376b8924.chunk.css.map",
|
||||
"static/css/main.47c735b4.chunk.css.map": "/static/css/main.47c735b4.chunk.css.map",
|
||||
"static/js/2.301144a0.chunk.js.LICENSE.txt": "/static/js/2.301144a0.chunk.js.LICENSE.txt",
|
||||
"static/media/en.9e6dbfb0.svg": "/static/media/en.9e6dbfb0.svg",
|
||||
"static/media/fr.d0f9280c.svg": "/static/media/fr.d0f9280c.svg",
|
||||
@ -18,7 +18,7 @@
|
||||
"entrypoints": [
|
||||
"static/js/runtime-main.1240af94.js",
|
||||
"static/js/2.301144a0.chunk.js",
|
||||
"static/css/main.376b8924.chunk.css",
|
||||
"static/js/main.8faa878d.chunk.js"
|
||||
"static/css/main.47c735b4.chunk.css",
|
||||
"static/js/main.75f806db.chunk.js"
|
||||
]
|
||||
}
|
2
fittrackee/dist/index.html
vendored
2
fittrackee/dist/index.html
vendored
@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="manifest" href="/manifest.json"><link rel="shortcut icon" href="/favicon.ico"><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.1.7/css/fork-awesome.min.css" integrity="sha256-gsmEoJAws/Kd3CjuOQzLie5Q3yshhvmo7YNtBG7aaEY=" crossorigin="anonymous"><link rel="stylesheet" href="https://cdn.jsdelivr.net/foundation-icons/3.0/foundation-icons.min.css"><link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""><title>FitTrackee</title><link href="/static/css/main.376b8924.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script><script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script><script type="text/javascript">$(document).ready((function(){$("li.nav-item").click((function(){$("button.navbar-toggler").toggleClass("collapsed"),$("#navbarSupportedContent").toggleClass("show")}))}))</script><script>!function(e){function t(t){for(var n,i,l=t[0],f=t[1],a=t[2],p=0,s=[];p<l.length;p++)i=l[p],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&s.push(o[i][0]),o[i]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(c&&c(t);s.length;)s.shift()();return u.push.apply(u,a||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,l=1;l<r.length;l++){var f=r[l];0!==o[f]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/";var l=this.webpackJsonpfittrackee_client=this.webpackJsonpfittrackee_client||[],f=l.push.bind(l);l.push=t,l=l.slice();for(var a=0;a<l.length;a++)t(l[a]);var c=f;r()}([])</script><script src="/static/js/2.301144a0.chunk.js"></script><script src="/static/js/main.8faa878d.chunk.js"></script></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="manifest" href="/manifest.json"><link rel="shortcut icon" href="/favicon.ico"><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.1.7/css/fork-awesome.min.css" integrity="sha256-gsmEoJAws/Kd3CjuOQzLie5Q3yshhvmo7YNtBG7aaEY=" crossorigin="anonymous"><link rel="stylesheet" href="https://cdn.jsdelivr.net/foundation-icons/3.0/foundation-icons.min.css"><link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""><title>FitTrackee</title><link href="/static/css/main.47c735b4.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script><script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script><script type="text/javascript">$(document).ready((function(){$("li.nav-item").click((function(){$("button.navbar-toggler").toggleClass("collapsed"),$("#navbarSupportedContent").toggleClass("show")}))}))</script><script>!function(e){function t(t){for(var n,i,l=t[0],f=t[1],a=t[2],p=0,s=[];p<l.length;p++)i=l[p],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&s.push(o[i][0]),o[i]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(c&&c(t);s.length;)s.shift()();return u.push.apply(u,a||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,l=1;l<r.length;l++){var f=r[l];0!==o[f]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/";var l=this.webpackJsonpfittrackee_client=this.webpackJsonpfittrackee_client||[],f=l.push.bind(l);l.push=t,l=l.slice();for(var a=0;a<l.length;a++)t(l[a]);var c=f;r()}([])</script><script src="/static/js/2.301144a0.chunk.js"></script><script src="/static/js/main.75f806db.chunk.js"></script></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
fittrackee/dist/static/css/main.47c735b4.chunk.css
vendored
Normal file
2
fittrackee/dist/static/css/main.47c735b4.chunk.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
fittrackee/dist/static/css/main.47c735b4.chunk.css.map
vendored
Normal file
1
fittrackee/dist/static/css/main.47c735b4.chunk.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
fittrackee/dist/static/js/main.75f806db.chunk.js
vendored
Normal file
2
fittrackee/dist/static/js/main.75f806db.chunk.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
fittrackee/dist/static/js/main.75f806db.chunk.js.map
vendored
Normal file
1
fittrackee/dist/static/js/main.75f806db.chunk.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -11,6 +11,21 @@ def get_empty_data_for_datatype(data_type: str) -> Union[str, List]:
|
||||
return '' if data_type in ['gpx', 'chart_data'] else []
|
||||
|
||||
|
||||
def display_readable_file_size(size_in_bytes: Union[float, int]) -> str:
|
||||
"""
|
||||
Return readable file size from size in bytes
|
||||
"""
|
||||
if size_in_bytes == 0:
|
||||
return '0 bytes'
|
||||
if size_in_bytes == 1:
|
||||
return '1 byte'
|
||||
for unit in [' bytes', 'KB', 'MB', 'GB', 'TB']:
|
||||
if abs(size_in_bytes) < 1024.0:
|
||||
return f'{size_in_bytes:3.1f}{unit}'
|
||||
size_in_bytes /= 1024.0
|
||||
return f'{size_in_bytes} bytes'
|
||||
|
||||
|
||||
class HttpResponse(Response):
|
||||
def __init__(
|
||||
self,
|
||||
@ -32,7 +47,10 @@ class HttpResponse(Response):
|
||||
|
||||
class GenericErrorResponse(HttpResponse):
|
||||
def __init__(
|
||||
self, status_code: int, message: str, status: Optional[str] = None
|
||||
self,
|
||||
status_code: int,
|
||||
message: Union[str, List],
|
||||
status: Optional[str] = None,
|
||||
) -> None:
|
||||
response = {
|
||||
'status': 'error' if status is None else status,
|
||||
@ -46,7 +64,9 @@ class GenericErrorResponse(HttpResponse):
|
||||
|
||||
class InvalidPayloadErrorResponse(GenericErrorResponse):
|
||||
def __init__(
|
||||
self, message: Optional[str] = None, status: Optional[str] = None
|
||||
self,
|
||||
message: Optional[Union[str, List]] = None,
|
||||
status: Optional[str] = None,
|
||||
) -> None:
|
||||
message = 'Invalid payload.' if message is None else message
|
||||
super().__init__(status_code=400, message=message, status=status)
|
||||
@ -101,7 +121,19 @@ class DataNotFoundErrorResponse(HttpResponse):
|
||||
|
||||
|
||||
class PayloadTooLargeErrorResponse(GenericErrorResponse):
|
||||
def __init__(self, message: str) -> None:
|
||||
def __init__(
|
||||
self, file_type: str, file_size: Optional[int], max_size: Optional[int]
|
||||
) -> None:
|
||||
readable_file_size = (
|
||||
f'({display_readable_file_size(file_size)}) ' if file_size else ''
|
||||
)
|
||||
readable_max_size = (
|
||||
display_readable_file_size(max_size) if max_size else 'limit'
|
||||
)
|
||||
message = (
|
||||
f'Error during {file_type} upload, file size {readable_file_size}'
|
||||
f'exceeds {readable_max_size}.'
|
||||
)
|
||||
super().__init__(status_code=413, message=message, status='fail')
|
||||
|
||||
|
||||
|
25
fittrackee/tests/api_test_case.py
Normal file
25
fittrackee/tests/api_test_case.py
Normal file
@ -0,0 +1,25 @@
|
||||
import json
|
||||
from typing import Tuple
|
||||
|
||||
from flask import Flask
|
||||
from flask.testing import FlaskClient
|
||||
|
||||
|
||||
class ApiTestCaseMixin:
|
||||
@staticmethod
|
||||
def get_test_client_and_auth_token(
|
||||
app: Flask, as_admin: bool = False
|
||||
) -> Tuple[FlaskClient, str]:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(
|
||||
email='admin@example.com' if as_admin else 'test@test.com',
|
||||
password='12345678',
|
||||
)
|
||||
),
|
||||
content_type='application/json',
|
||||
)
|
||||
auth_token = json.loads(resp_login.data.decode())['auth_token']
|
||||
return client, auth_token
|
@ -4,24 +4,18 @@ from flask import Flask
|
||||
|
||||
from fittrackee.users.models import User
|
||||
|
||||
from ..api_test_case import ApiTestCaseMixin
|
||||
|
||||
class TestGetConfig:
|
||||
|
||||
class TestGetConfig(ApiTestCaseMixin):
|
||||
def test_it_gets_application_config(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/config',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -41,22 +35,14 @@ class TestGetConfig:
|
||||
def test_it_returns_error_if_application_has_no_config(
|
||||
self, app_no_config: Flask, user_1_admin: User
|
||||
) -> None:
|
||||
client = app_no_config.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app_no_config, as_admin=True
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/config',
|
||||
content_type='application/json',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -67,22 +53,14 @@ class TestGetConfig:
|
||||
def test_it_returns_error_if_application_has_several_config(
|
||||
self, app: Flask, app_config: Flask, user_1_admin: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/config',
|
||||
content_type='application/json',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -91,26 +69,18 @@ class TestGetConfig:
|
||||
assert 'Error on getting configuration.' in data['message']
|
||||
|
||||
|
||||
class TestUpdateConfig:
|
||||
class TestUpdateConfig(ApiTestCaseMixin):
|
||||
def test_it_updates_config_when_user_is_admin(
|
||||
self, app: Flask, user_1_admin: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
response = client.patch(
|
||||
'/api/config',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(gpx_limit_import=100, max_users=10)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
@ -125,13 +95,8 @@ class TestUpdateConfig:
|
||||
def test_it_updates_all_config(
|
||||
self, app: Flask, user_1_admin: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
@ -145,10 +110,7 @@ class TestUpdateConfig:
|
||||
max_users=50,
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -163,21 +125,13 @@ class TestUpdateConfig:
|
||||
def test_it_returns_403_when_user_is_not_an_admin(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.patch(
|
||||
'/api/config',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(gpx_limit_import=100, max_users=10)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -189,23 +143,15 @@ class TestUpdateConfig:
|
||||
def test_it_returns_400_if_invalid_is_payload(
|
||||
self, app: Flask, user_1_admin: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/config',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict()),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -216,26 +162,125 @@ class TestUpdateConfig:
|
||||
def test_it_returns_error_on_update_if_application_has_no_config(
|
||||
self, app_no_config: Flask, user_1_admin: User
|
||||
) -> None:
|
||||
client = app_no_config.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app_no_config, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/config',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(gpx_limit_import=100, max_users=10)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 500
|
||||
assert 'error' in data['status']
|
||||
assert 'Error on updating configuration.' in data['message']
|
||||
|
||||
def test_it_raises_error_if_archive_max_size_is_below_files_max_size(
|
||||
self, app: Flask, user_1_admin: User
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/config',
|
||||
content_type='application/json',
|
||||
data=json.dumps(
|
||||
dict(
|
||||
gpx_limit_import=20,
|
||||
max_single_file_size=10000,
|
||||
max_zip_file_size=1000,
|
||||
max_users=50,
|
||||
)
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 400
|
||||
assert 'error' in data['status']
|
||||
assert (
|
||||
'Max. size of zip archive must be equal or greater than max. size '
|
||||
'of uploaded files'
|
||||
) in data['message']
|
||||
|
||||
def test_it_raises_error_if_archive_max_size_equals_0(
|
||||
self, app_with_max_file_size_equals_0: Flask, user_1_admin: User
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app_with_max_file_size_equals_0, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/config',
|
||||
content_type='application/json',
|
||||
data=json.dumps(
|
||||
dict(
|
||||
max_zip_file_size=0,
|
||||
)
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 400
|
||||
assert 'error' in data['status']
|
||||
assert (
|
||||
'Max. size of zip archive must be greater than 0'
|
||||
in data['message']
|
||||
)
|
||||
|
||||
def test_it_raises_error_if_files_max_size_equals_0(
|
||||
self, app: Flask, user_1_admin: User
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/config',
|
||||
content_type='application/json',
|
||||
data=json.dumps(
|
||||
dict(
|
||||
max_single_file_size=0,
|
||||
)
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 400
|
||||
assert 'error' in data['status']
|
||||
assert (
|
||||
'Max. size of uploaded files must be greater than 0'
|
||||
in data['message']
|
||||
)
|
||||
|
||||
def test_it_raises_error_if_gpx_limit_import_equals_0(
|
||||
self, app: Flask, user_1_admin: User
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/config',
|
||||
content_type='application/json',
|
||||
data=json.dumps(
|
||||
dict(
|
||||
gpx_limit_import=0,
|
||||
)
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 400
|
||||
assert 'error' in data['status']
|
||||
assert (
|
||||
'Max. files in a zip archive must be greater than 0'
|
||||
in data['message']
|
||||
)
|
||||
|
56
fittrackee/tests/fixtures/fixtures_app.py
vendored
56
fittrackee/tests/fixtures/fixtures_app.py
vendored
@ -1,5 +1,5 @@
|
||||
import os
|
||||
from typing import Generator, Optional
|
||||
from typing import Generator, Optional, Union
|
||||
|
||||
import pytest
|
||||
|
||||
@ -11,13 +11,24 @@ from fittrackee.application.utils import update_app_config_from_database
|
||||
def get_app_config(
|
||||
with_config: Optional[bool] = False,
|
||||
max_workouts: Optional[int] = None,
|
||||
max_single_file_size: Optional[Union[int, float]] = None,
|
||||
max_zip_file_size: Optional[Union[int, float]] = None,
|
||||
max_users: Optional[int] = None,
|
||||
) -> Optional[AppConfig]:
|
||||
if with_config:
|
||||
config = AppConfig()
|
||||
config.gpx_limit_import = 10 if max_workouts is None else max_workouts
|
||||
config.max_single_file_size = 1 * 1024 * 1024
|
||||
config.max_zip_file_size = 1 * 1024 * 1024 * 10
|
||||
config.max_users = 100
|
||||
config.max_single_file_size = (
|
||||
(1 if max_single_file_size is None else max_single_file_size)
|
||||
* 1024
|
||||
* 1024
|
||||
)
|
||||
config.max_zip_file_size = (
|
||||
(10 if max_zip_file_size is None else max_zip_file_size)
|
||||
* 1024
|
||||
* 1024
|
||||
)
|
||||
config.max_users = 100 if max_users is None else max_users
|
||||
db.session.add(config)
|
||||
db.session.commit()
|
||||
return config
|
||||
@ -27,12 +38,21 @@ def get_app_config(
|
||||
def get_app(
|
||||
with_config: Optional[bool] = False,
|
||||
max_workouts: Optional[int] = None,
|
||||
max_single_file_size: Optional[Union[int, float]] = None,
|
||||
max_zip_file_size: Optional[Union[int, float]] = None,
|
||||
max_users: Optional[int] = None,
|
||||
) -> Generator:
|
||||
app = create_app()
|
||||
with app.app_context():
|
||||
try:
|
||||
db.create_all()
|
||||
app_db_config = get_app_config(with_config, max_workouts)
|
||||
app_db_config = get_app_config(
|
||||
with_config,
|
||||
max_workouts,
|
||||
max_single_file_size,
|
||||
max_zip_file_size,
|
||||
max_users,
|
||||
)
|
||||
if app_db_config:
|
||||
update_app_config_from_database(app, app_db_config)
|
||||
yield app
|
||||
@ -64,6 +84,32 @@ def app_with_max_workouts(monkeypatch: pytest.MonkeyPatch) -> Generator:
|
||||
yield from get_app(with_config=True, max_workouts=2)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app_with_max_file_size_equals_0(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> Generator:
|
||||
monkeypatch.setenv('EMAIL_URL', 'smtp://none:none@0.0.0.0:1025')
|
||||
yield from get_app(with_config=True, max_single_file_size=0)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app_with_max_file_size(monkeypatch: pytest.MonkeyPatch) -> Generator:
|
||||
monkeypatch.setenv('EMAIL_URL', 'smtp://none:none@0.0.0.0:1025')
|
||||
yield from get_app(with_config=True, max_single_file_size=0.001)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app_with_max_zip_file_size(monkeypatch: pytest.MonkeyPatch) -> Generator:
|
||||
monkeypatch.setenv('EMAIL_URL', 'smtp://none:none@0.0.0.0:1025')
|
||||
yield from get_app(with_config=True, max_zip_file_size=0.001)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app_with_3_users_max(monkeypatch: pytest.MonkeyPatch) -> Generator:
|
||||
monkeypatch.setenv('EMAIL_URL', 'smtp://none:none@0.0.0.0:1025')
|
||||
yield from get_app(with_config=True, max_users=3)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app_no_config() -> Generator:
|
||||
yield from get_app(with_config=False)
|
||||
|
@ -3,10 +3,8 @@ from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
|
||||
from fittrackee.users.utils import (
|
||||
display_readable_file_size,
|
||||
get_readable_duration,
|
||||
)
|
||||
from fittrackee.responses import display_readable_file_size
|
||||
from fittrackee.utils import get_readable_duration
|
||||
|
||||
|
||||
class TestDisplayReadableFileSize:
|
@ -10,6 +10,8 @@ from fittrackee.users.models import User
|
||||
from fittrackee.users.utils_token import get_user_token
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
|
||||
from ..api_test_case import ApiTestCaseMixin
|
||||
|
||||
|
||||
class TestUserRegistration:
|
||||
def test_user_can_register(self, app: Flask) -> None:
|
||||
@ -356,21 +358,14 @@ class TestUserLogin:
|
||||
assert data['message'] == 'Invalid credentials.'
|
||||
|
||||
|
||||
class TestUserLogout:
|
||||
class TestUserLogout(ApiTestCaseMixin):
|
||||
def test_user_can_logout(self, app: Flask, user_1: User) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/auth/logout',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -381,20 +376,13 @@ class TestUserLogout:
|
||||
def test_it_returns_error_with_expired_token(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
now = datetime.utcnow()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
with freeze_time(now + timedelta(seconds=4)):
|
||||
response = client.get(
|
||||
'/api/auth/logout',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'error'
|
||||
@ -420,23 +408,17 @@ class TestUserLogout:
|
||||
assert response.status_code == 401
|
||||
|
||||
|
||||
class TestUserProfile:
|
||||
class TestUserProfile(ApiTestCaseMixin):
|
||||
def test_it_returns_user_minimal_profile(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/auth/profile',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'success'
|
||||
assert data['data'] is not None
|
||||
@ -457,19 +439,13 @@ class TestUserProfile:
|
||||
def test_it_returns_user_full_profile(
|
||||
self, app: Flask, user_1_full: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/auth/profile',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'success'
|
||||
assert data['data'] is not None
|
||||
@ -501,19 +477,13 @@ class TestUserProfile:
|
||||
workout_cycling_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/auth/profile',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'success'
|
||||
assert data['data'] is not None
|
||||
@ -540,14 +510,10 @@ class TestUserProfile:
|
||||
assert response.status_code == 401
|
||||
|
||||
|
||||
class TestUserProfileUpdate:
|
||||
class TestUserProfileUpdate(ApiTestCaseMixin):
|
||||
def test_it_updates_user_profile(self, app: Flask, user_1: User) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/auth/profile/edit',
|
||||
content_type='application/json',
|
||||
@ -565,11 +531,9 @@ class TestUserProfileUpdate:
|
||||
language='fr',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'success'
|
||||
assert data['message'] == 'User profile updated.'
|
||||
@ -595,12 +559,8 @@ class TestUserProfileUpdate:
|
||||
def test_it_updates_user_profile_without_password(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/auth/profile/edit',
|
||||
content_type='application/json',
|
||||
@ -616,11 +576,9 @@ class TestUserProfileUpdate:
|
||||
language='fr',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'success'
|
||||
assert data['message'] == 'User profile updated.'
|
||||
@ -646,21 +604,15 @@ class TestUserProfileUpdate:
|
||||
def test_it_returns_error_if_fields_are_missing(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/auth/profile/edit',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(first_name='John')),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'error'
|
||||
assert data['message'] == 'Invalid payload.'
|
||||
@ -669,21 +621,15 @@ class TestUserProfileUpdate:
|
||||
def test_it_returns_error_if_payload_is_empty(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/auth/profile/edit',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict()),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 400
|
||||
assert 'Invalid payload.' in data['message']
|
||||
@ -692,12 +638,8 @@ class TestUserProfileUpdate:
|
||||
def test_it_returns_error_if_passwords_mismatch(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/auth/profile/edit',
|
||||
content_type='application/json',
|
||||
@ -715,11 +657,9 @@ class TestUserProfileUpdate:
|
||||
language='en',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'error'
|
||||
assert (
|
||||
@ -731,12 +671,8 @@ class TestUserProfileUpdate:
|
||||
def test_it_returns_error_if_password_confirmation_is_missing(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/auth/profile/edit',
|
||||
content_type='application/json',
|
||||
@ -753,11 +689,9 @@ class TestUserProfileUpdate:
|
||||
language='en',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'error'
|
||||
assert (
|
||||
@ -767,23 +701,19 @@ class TestUserProfileUpdate:
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
class TestUserPicture:
|
||||
class TestUserPicture(ApiTestCaseMixin):
|
||||
def test_it_updates_user_picture(self, app: Flask, user_1: User) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/auth/picture',
|
||||
data=dict(file=(BytesIO(b'avatar'), 'avatar.png')),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'success'
|
||||
assert data['message'] == 'User picture updated.'
|
||||
@ -795,10 +725,10 @@ class TestUserPicture:
|
||||
data=dict(file=(BytesIO(b'avatar2'), 'avatar2.png')),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'success'
|
||||
assert data['message'] == 'User picture updated.'
|
||||
@ -809,20 +739,16 @@ class TestUserPicture:
|
||||
def test_it_returns_error_if_file_is_missing(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/auth/picture',
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'fail'
|
||||
assert data['message'] == 'No file part.'
|
||||
@ -831,49 +757,96 @@ class TestUserPicture:
|
||||
def test_it_returns_error_if_file_is_invalid(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/auth/picture',
|
||||
data=dict(file=(BytesIO(b'avatar'), 'avatar.bmp')),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'fail'
|
||||
assert data['message'] == 'File extension not allowed.'
|
||||
assert response.status_code == 400
|
||||
|
||||
def test_it_returns_error_if_image_size_exceeds_file_limit(
|
||||
self,
|
||||
app_with_max_file_size: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
gpx_file: str,
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app_with_max_file_size
|
||||
)
|
||||
|
||||
response = client.post(
|
||||
'/api/auth/picture',
|
||||
data=dict(
|
||||
file=(BytesIO(b'test_file_for_avatar' * 50), 'avatar.jpg')
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
print('data', data)
|
||||
assert response.status_code == 413
|
||||
assert 'fail' in data['status']
|
||||
assert (
|
||||
'Error during picture upload, file size (1.2KB) exceeds 1.0KB.'
|
||||
in data['message']
|
||||
)
|
||||
assert 'data' not in data
|
||||
|
||||
def test_it_returns_error_if_image_size_exceeds_archive_limit(
|
||||
self,
|
||||
app_with_max_zip_file_size: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
gpx_file: str,
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app_with_max_zip_file_size
|
||||
)
|
||||
|
||||
response = client.post(
|
||||
'/api/auth/picture',
|
||||
data=dict(
|
||||
file=(BytesIO(b'test_file_for_avatar' * 50), 'avatar.jpg')
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
print('data', data)
|
||||
assert response.status_code == 413
|
||||
assert 'fail' in data['status']
|
||||
assert (
|
||||
'Error during picture upload, file size (1.2KB) exceeds 1.0KB.'
|
||||
in data['message']
|
||||
)
|
||||
assert 'data' not in data
|
||||
|
||||
|
||||
class TestRegistrationConfiguration:
|
||||
def test_it_returns_error_if_it_exceeds_max_users(
|
||||
self, app: Flask, user_1_admin: User, user_2: User, user_3: User
|
||||
self,
|
||||
app_with_3_users_max: Flask,
|
||||
user_1_admin: User,
|
||||
user_2: User,
|
||||
user_3: User,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
)
|
||||
client.patch(
|
||||
'/api/config',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(max_users=3, registration=True)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
)
|
||||
client = app_with_3_users_max.test_client()
|
||||
|
||||
response = client.post(
|
||||
'/api/auth/register',
|
||||
@ -896,13 +869,11 @@ class TestRegistrationConfiguration:
|
||||
|
||||
def test_it_disables_registration_on_user_registration(
|
||||
self,
|
||||
app_no_config: Flask,
|
||||
app_config: Flask,
|
||||
app_with_3_users_max: Flask,
|
||||
user_1_admin: User,
|
||||
user_2: User,
|
||||
) -> None:
|
||||
app_config.max_users = 3
|
||||
client = app_no_config.test_client()
|
||||
client = app_with_3_users_max.test_client()
|
||||
client.post(
|
||||
'/api/auth/register',
|
||||
data=json.dumps(
|
||||
@ -915,6 +886,7 @@ class TestRegistrationConfiguration:
|
||||
),
|
||||
content_type='application/json',
|
||||
)
|
||||
|
||||
response = client.post(
|
||||
'/api/auth/register',
|
||||
data=json.dumps(
|
||||
@ -927,6 +899,7 @@ class TestRegistrationConfiguration:
|
||||
),
|
||||
content_type='application/json',
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
data = json.loads(response.data.decode())
|
||||
assert data['status'] == 'error'
|
||||
@ -934,13 +907,10 @@ class TestRegistrationConfiguration:
|
||||
|
||||
def test_it_does_not_disable_registration_on_user_registration(
|
||||
self,
|
||||
app_no_config: Flask,
|
||||
app_config: Flask,
|
||||
user_1_admin: User,
|
||||
user_2: User,
|
||||
app_with_3_users_max: Flask,
|
||||
user_1: User,
|
||||
) -> None:
|
||||
app_config.max_users = 4
|
||||
client = app_no_config.test_client()
|
||||
client = app_with_3_users_max.test_client()
|
||||
client.post(
|
||||
'/api/auth/register',
|
||||
data=json.dumps(
|
||||
|
@ -8,25 +8,19 @@ from flask import Flask
|
||||
from fittrackee.users.models import User
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
|
||||
from ..api_test_case import ApiTestCaseMixin
|
||||
|
||||
class TestGetUser:
|
||||
|
||||
class TestGetUser(ApiTestCaseMixin):
|
||||
def test_it_gets_single_user_without_workouts(
|
||||
self, app: Flask, user_1: User, user_2: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/users/{user_2.username}',
|
||||
content_type='application/json',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -61,20 +55,12 @@ class TestGetUser:
|
||||
workout_cycling_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/users/{user_1.username}',
|
||||
content_type='application/json',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -103,19 +89,12 @@ class TestGetUser:
|
||||
def test_it_returns_error_if_user_does_not_exist(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users/not_existing',
|
||||
content_type='application/json',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
@ -124,23 +103,15 @@ class TestGetUser:
|
||||
assert 'User does not exist.' in data['message']
|
||||
|
||||
|
||||
class TestGetUsers:
|
||||
class TestGetUsers(ApiTestCaseMixin):
|
||||
def test_it_get_users_list(
|
||||
self, app: Flask, user_1: User, user_2: User, user_3: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -200,19 +171,11 @@ class TestGetUsers:
|
||||
workout_running_user_1: Workout,
|
||||
workout_cycling_user_2: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -265,19 +228,11 @@ class TestGetUsers:
|
||||
user_2: User,
|
||||
user_3: User,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?page=1',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -300,19 +255,11 @@ class TestGetUsers:
|
||||
user_2: User,
|
||||
user_3: User,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?page=2',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -334,19 +281,11 @@ class TestGetUsers:
|
||||
user_2: User,
|
||||
user_3: User,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?page=2',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -368,19 +307,11 @@ class TestGetUsers:
|
||||
user_2: User,
|
||||
user_3: User,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?per_page=2',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -402,19 +333,11 @@ class TestGetUsers:
|
||||
user_2: User,
|
||||
user_3: User,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?page=2&per_page=2',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -432,18 +355,11 @@ class TestGetUsers:
|
||||
def test_it_gets_users_list_ordered_by_username(
|
||||
self, app: Flask, user_1: User, user_2: User, user_3: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?order_by=username',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -464,19 +380,11 @@ class TestGetUsers:
|
||||
def test_it_gets_users_list_ordered_by_username_ascending(
|
||||
self, app: Flask, user_1: User, user_2: User, user_3: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?order_by=username&order=asc',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -497,19 +405,11 @@ class TestGetUsers:
|
||||
def test_it_gets_users_list_ordered_by_username_descending(
|
||||
self, app: Flask, user_1: User, user_2: User, user_3: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?order_by=username&order=desc',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -533,21 +433,13 @@ class TestGetUsers:
|
||||
user_2.created_at = datetime.utcnow() - timedelta(days=1)
|
||||
user_3.created_at = datetime.utcnow() - timedelta(hours=1)
|
||||
user_1_admin.created_at = datetime.utcnow()
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?order_by=created_at',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -571,21 +463,13 @@ class TestGetUsers:
|
||||
user_2.created_at = datetime.utcnow() - timedelta(days=1)
|
||||
user_3.created_at = datetime.utcnow() - timedelta(hours=1)
|
||||
user_1_admin.created_at = datetime.utcnow()
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?order_by=created_at&order=asc',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -609,21 +493,13 @@ class TestGetUsers:
|
||||
user_2.created_at = datetime.utcnow() - timedelta(days=1)
|
||||
user_3.created_at = datetime.utcnow() - timedelta(hours=1)
|
||||
user_1_admin.created_at = datetime.utcnow()
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?order_by=created_at&order=desc',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -644,21 +520,13 @@ class TestGetUsers:
|
||||
def test_it_gets_users_list_ordered_by_admin_rights(
|
||||
self, app: Flask, user_2: User, user_1_admin: User, user_3: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?order_by=admin',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -679,21 +547,13 @@ class TestGetUsers:
|
||||
def test_it_gets_users_list_ordered_by_admin_rights_ascending(
|
||||
self, app: Flask, user_2: User, user_1_admin: User, user_3: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?order_by=admin&order=asc',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -714,21 +574,13 @@ class TestGetUsers:
|
||||
def test_it_gets_users_list_ordered_by_admin_rights_descending(
|
||||
self, app: Flask, user_2: User, user_3: User, user_1_admin: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?order_by=admin&order=desc',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -755,19 +607,11 @@ class TestGetUsers:
|
||||
sport_1_cycling: Sport,
|
||||
workout_cycling_user_2: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?order_by=workouts_count',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -797,19 +641,11 @@ class TestGetUsers:
|
||||
sport_1_cycling: Sport,
|
||||
workout_cycling_user_2: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?order_by=workouts_count&order=asc',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -839,19 +675,11 @@ class TestGetUsers:
|
||||
sport_1_cycling: Sport,
|
||||
workout_cycling_user_2: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?order_by=workouts_count&order=desc',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -875,19 +703,11 @@ class TestGetUsers:
|
||||
def test_it_gets_users_list_filtering_on_username(
|
||||
self, app: Flask, user_1: User, user_2: User, user_3: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?q=toto',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -906,19 +726,11 @@ class TestGetUsers:
|
||||
def test_it_returns_empty_users_list_filtering_on_username(
|
||||
self, app: Flask, user_1: User, user_2: User, user_3: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?q=not_existing',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -936,19 +748,11 @@ class TestGetUsers:
|
||||
def test_it_users_list_with_complex_query(
|
||||
self, app: Flask, user_1: User, user_2: User, user_3: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/users?order_by=username&order=desc&page=2&per_page=2',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -991,27 +795,19 @@ class TestGetUserPicture:
|
||||
assert 'User does not exist.' in data['message']
|
||||
|
||||
|
||||
class TestUpdateUser:
|
||||
class TestUpdateUser(ApiTestCaseMixin):
|
||||
def test_it_adds_admin_rights_to_a_user(
|
||||
self, app: Flask, user_1_admin: User, user_2: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/users/toto',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(admin=True)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1025,23 +821,15 @@ class TestUpdateUser:
|
||||
def test_it_removes_admin_rights_to_a_user(
|
||||
self, app: Flask, user_1_admin: User, user_2: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/users/toto',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(admin=False)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1056,23 +844,15 @@ class TestUpdateUser:
|
||||
def test_it_returns_error_if_payload_for_admin_rights_is_empty(
|
||||
self, app: Flask, user_1_admin: User, user_2: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/users/toto',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict()),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1083,23 +863,15 @@ class TestUpdateUser:
|
||||
def test_it_returns_error_if_payload_for_admin_rights_is_invalid(
|
||||
self, app: Flask, user_1_admin: User, user_2: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/users/toto',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(admin="")),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1113,21 +885,13 @@ class TestUpdateUser:
|
||||
def test_it_returns_error_if_user_can_not_change_admin_rights(
|
||||
self, app: Flask, user_1: User, user_2: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.patch(
|
||||
'/api/users/toto',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(admin=True)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1136,23 +900,15 @@ class TestUpdateUser:
|
||||
assert 'You do not have permissions.' in data['message']
|
||||
|
||||
|
||||
class TestDeleteUser:
|
||||
class TestDeleteUser(ApiTestCaseMixin):
|
||||
def test_user_can_delete_its_own_account(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.delete(
|
||||
'/api/users/test',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
assert response.status_code == 204
|
||||
@ -1160,12 +916,7 @@ class TestDeleteUser:
|
||||
def test_user_with_workout_can_delete_its_own_account(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
client.post(
|
||||
'/api/workouts',
|
||||
data=dict(
|
||||
@ -1174,17 +925,13 @@ class TestDeleteUser:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
response = client.delete(
|
||||
'/api/users/test',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
assert response.status_code == 204
|
||||
@ -1192,28 +939,19 @@ class TestDeleteUser:
|
||||
def test_user_with_picture_can_delete_its_own_account(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
client.post(
|
||||
'/api/auth/picture',
|
||||
data=dict(file=(BytesIO(b'avatar'), 'avatar.png')),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
response = client.delete(
|
||||
'/api/users/test',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
assert response.status_code == 204
|
||||
@ -1221,19 +959,11 @@ class TestDeleteUser:
|
||||
def test_user_can_not_delete_another_user_account(
|
||||
self, app: Flask, user_1: User, user_2: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.delete(
|
||||
'/api/users/toto',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1244,19 +974,11 @@ class TestDeleteUser:
|
||||
def test_it_returns_error_when_deleting_non_existing_user(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.delete(
|
||||
'/api/users/not_existing',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1267,21 +989,13 @@ class TestDeleteUser:
|
||||
def test_admin_can_delete_another_user_account(
|
||||
self, app: Flask, user_1_admin: User, user_2: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.delete(
|
||||
'/api/users/toto',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
assert response.status_code == 204
|
||||
@ -1289,21 +1003,13 @@ class TestDeleteUser:
|
||||
def test_admin_can_delete_its_own_account(
|
||||
self, app: Flask, user_1_admin: User, user_2_admin: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.delete(
|
||||
'/api/users/admin',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
assert response.status_code == 204
|
||||
@ -1311,20 +1017,13 @@ class TestDeleteUser:
|
||||
def test_admin_can_not_delete_its_own_account_if_no_other_admin(
|
||||
self, app: Flask, user_1_admin: User, user_2: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.delete(
|
||||
'/api/users/admin',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1337,29 +1036,19 @@ class TestDeleteUser:
|
||||
|
||||
def test_it_enables_registration_on_user_delete(
|
||||
self,
|
||||
app_no_config: Flask,
|
||||
app_config: Flask,
|
||||
app_with_3_users_max: Flask,
|
||||
user_1_admin: User,
|
||||
user_2: User,
|
||||
user_3: User,
|
||||
) -> None:
|
||||
app_config.max_users = 3
|
||||
client = app_no_config.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app_with_3_users_max, as_admin=True
|
||||
)
|
||||
|
||||
client.delete(
|
||||
'/api/users/toto',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
response = client.post(
|
||||
'/api/auth/register',
|
||||
data=json.dumps(
|
||||
@ -1376,28 +1065,19 @@ class TestDeleteUser:
|
||||
|
||||
def test_it_does_not_enable_registration_on_user_delete(
|
||||
self,
|
||||
app_no_config: Flask,
|
||||
app_config: Flask,
|
||||
app_with_3_users_max: Flask,
|
||||
user_1_admin: User,
|
||||
user_2: User,
|
||||
user_3: User,
|
||||
user_1_paris: User,
|
||||
) -> None:
|
||||
app_config.max_users = 2
|
||||
client = app_no_config.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app_with_3_users_max, as_admin=True
|
||||
)
|
||||
|
||||
client.delete(
|
||||
'/api/users/toto',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
response = client.post(
|
||||
'/api/auth/register',
|
||||
|
@ -5,8 +5,10 @@ from flask import Flask
|
||||
from fittrackee.users.models import User
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
|
||||
from ..api_test_case import ApiTestCaseMixin
|
||||
|
||||
class TestGetRecords:
|
||||
|
||||
class TestGetRecords(ApiTestCaseMixin):
|
||||
def test_it_gets_records_for_authenticated_user(
|
||||
self,
|
||||
app: Flask,
|
||||
@ -17,21 +19,14 @@ class TestGetRecords:
|
||||
workout_cycling_user_1: Workout,
|
||||
workout_cycling_user_2: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/records',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['records']) == 4
|
||||
@ -97,21 +92,14 @@ class TestGetRecords:
|
||||
sport_2_running: Sport,
|
||||
workout_cycling_user_2: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/records',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['records']) == 0
|
||||
@ -123,12 +111,8 @@ class TestGetRecords:
|
||||
sport_1_cycling: Sport,
|
||||
sport_2_running: Sport,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
client.post(
|
||||
'/api/workouts/no_gpx',
|
||||
content_type='application/json',
|
||||
@ -141,20 +125,15 @@ class TestGetRecords:
|
||||
title='Workout test',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/records',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['records']) == 0
|
||||
@ -162,12 +141,7 @@ class TestGetRecords:
|
||||
def test_it_gets_updated_records_after_workouts_post_and_patch(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
response = client.post(
|
||||
'/api/workouts/no_gpx',
|
||||
content_type='application/json',
|
||||
@ -180,26 +154,20 @@ class TestGetRecords:
|
||||
title='Workout test 1',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_1_short_id = data['data']['workouts'][0]['id']
|
||||
|
||||
response = client.get(
|
||||
'/api/records',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
assert len(data['data']['records']) == 4
|
||||
|
||||
assert (
|
||||
'Mon, 14 May 2018 14:05:00 GMT'
|
||||
== data['data']['records'][0]['workout_date']
|
||||
@ -254,19 +222,13 @@ class TestGetRecords:
|
||||
title='Workout test 2',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_2_short_id = data['data']['workouts'][0]['id']
|
||||
response = client.get(
|
||||
'/api/records',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
@ -327,19 +289,13 @@ class TestGetRecords:
|
||||
title='Workout test 3',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_3_short_id = data['data']['workouts'][0]['id']
|
||||
response = client.get(
|
||||
'/api/records',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
@ -393,17 +349,11 @@ class TestGetRecords:
|
||||
f'/api/workouts/{workout_3_short_id}',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(duration=4000)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
response = client.get(
|
||||
'/api/records',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
@ -454,17 +404,11 @@ class TestGetRecords:
|
||||
# delete workout 2 => AS and MS record update
|
||||
client.delete(
|
||||
f'/api/workouts/{workout_2_short_id}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
response = client.get(
|
||||
'/api/records',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
@ -526,19 +470,13 @@ class TestGetRecords:
|
||||
title='Workout test 4',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_4_short_id = data['data']['workouts'][0]['id']
|
||||
response = client.get(
|
||||
'/api/records',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
@ -602,19 +540,13 @@ class TestGetRecords:
|
||||
title='Workout test 5',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_5_short_id = data['data']['workouts'][0]['id']
|
||||
response = client.get(
|
||||
'/api/records',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
@ -665,38 +597,23 @@ class TestGetRecords:
|
||||
# delete all workouts - no more records
|
||||
client.delete(
|
||||
f'/api/workouts/{workout_1_short_id}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
client.delete(
|
||||
f'/api/workouts/{workout_3_short_id}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
client.delete(
|
||||
f'/api/workouts/{workout_4_short_id}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
client.delete(
|
||||
f'/api/workouts/{workout_5_short_id}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
response = client.get(
|
||||
'/api/records',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
@ -711,12 +628,8 @@ class TestGetRecords:
|
||||
sport_1_cycling: Sport,
|
||||
sport_2_running: Sport,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts/no_gpx',
|
||||
content_type='application/json',
|
||||
@ -729,10 +642,7 @@ class TestGetRecords:
|
||||
title='Workout test 1',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_1_short_id = data['data']['workouts'][0]['id']
|
||||
@ -748,10 +658,7 @@ class TestGetRecords:
|
||||
title='Workout test 2',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_2_short_id = data['data']['workouts'][0]['id']
|
||||
@ -767,10 +674,7 @@ class TestGetRecords:
|
||||
title='Workout test 3',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
response = client.post(
|
||||
'/api/workouts/no_gpx',
|
||||
@ -784,19 +688,13 @@ class TestGetRecords:
|
||||
title='Workout test 4',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_4_short_id = data['data']['workouts'][0]['id']
|
||||
response = client.get(
|
||||
'/api/records',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
@ -888,17 +786,11 @@ class TestGetRecords:
|
||||
f'/api/workouts/{workout_2_short_id}',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(sport_id=1)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
response = client.get(
|
||||
'/api/records',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
|
@ -5,6 +5,8 @@ from flask import Flask
|
||||
from fittrackee.users.models import User
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
|
||||
from ..api_test_case import ApiTestCaseMixin
|
||||
|
||||
expected_sport_1_cycling_result = {
|
||||
'id': 1,
|
||||
'label': 'Cycling',
|
||||
@ -35,7 +37,7 @@ expected_sport_1_cycling_inactive_admin_result = (
|
||||
expected_sport_1_cycling_inactive_admin_result['has_workouts'] = False
|
||||
|
||||
|
||||
class TestGetSports:
|
||||
class TestGetSports(ApiTestCaseMixin):
|
||||
def test_it_gets_all_sports(
|
||||
self,
|
||||
app: Flask,
|
||||
@ -43,19 +45,11 @@ class TestGetSports:
|
||||
sport_1_cycling: Sport,
|
||||
sport_2_running: Sport,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/sports',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -72,19 +66,11 @@ class TestGetSports:
|
||||
sport_1_cycling_inactive: Sport,
|
||||
sport_2_running: Sport,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/sports',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -104,21 +90,13 @@ class TestGetSports:
|
||||
sport_1_cycling_inactive: Sport,
|
||||
sport_2_running: Sport,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/sports',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -134,23 +112,15 @@ class TestGetSports:
|
||||
)
|
||||
|
||||
|
||||
class TestGetSport:
|
||||
class TestGetSport(ApiTestCaseMixin):
|
||||
def test_it_gets_a_sport(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/sports/1',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -162,19 +132,11 @@ class TestGetSport:
|
||||
def test_it_returns_404_if_sport_does_not_exist(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/sports/1',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -185,24 +147,16 @@ class TestGetSport:
|
||||
def test_it_gets_a_inactive_sport(
|
||||
self, app: Flask, user_1: User, sport_1_cycling_inactive: Sport
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/sports/1',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
|
||||
assert len(data['data']['sports']) == 1
|
||||
assert (
|
||||
data['data']['sports'][0]
|
||||
@ -212,26 +166,18 @@ class TestGetSport:
|
||||
def test_it_get_an_inactive_sport_with_admin_rights(
|
||||
self, app: Flask, user_1_admin: User, sport_1_cycling_inactive: Sport
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/sports/1',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
|
||||
assert len(data['data']['sports']) == 1
|
||||
assert (
|
||||
data['data']['sports'][0]
|
||||
@ -239,27 +185,19 @@ class TestGetSport:
|
||||
)
|
||||
|
||||
|
||||
class TestUpdateSport:
|
||||
class TestUpdateSport(ApiTestCaseMixin):
|
||||
def test_it_disables_a_sport(
|
||||
self, app: Flask, user_1_admin: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/sports/1',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(is_active=False)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -273,23 +211,15 @@ class TestUpdateSport:
|
||||
self, app: Flask, user_1_admin: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
sport_1_cycling.is_active = False
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/sports/1',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(is_active=True)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -306,23 +236,15 @@ class TestUpdateSport:
|
||||
sport_1_cycling: Sport,
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/sports/1',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(is_active=False)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -340,23 +262,15 @@ class TestUpdateSport:
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
sport_1_cycling.is_active = False
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/sports/1',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(is_active=True)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -369,23 +283,16 @@ class TestUpdateSport:
|
||||
def test_returns_error_if_user_has_no_admin_rights(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.patch(
|
||||
'/api/sports/1',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(is_active=False)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 403
|
||||
assert 'success' not in data['status']
|
||||
assert 'error' in data['status']
|
||||
@ -394,23 +301,15 @@ class TestUpdateSport:
|
||||
def test_returns_error_if_payload_is_invalid(
|
||||
self, app: Flask, user_1_admin: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/sports/1',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict()),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -421,25 +320,18 @@ class TestUpdateSport:
|
||||
def test_it_returns_error_if_sport_does_not_exist(
|
||||
self, app: Flask, user_1_admin: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.patch(
|
||||
'/api/sports/1',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(is_active=False)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 404
|
||||
assert 'not found' in data['status']
|
||||
assert len(data['data']['sports']) == 0
|
||||
|
@ -5,24 +5,18 @@ from flask import Flask
|
||||
from fittrackee.users.models import User
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
|
||||
from ..api_test_case import ApiTestCaseMixin
|
||||
|
||||
class TestGetStatsByTime:
|
||||
|
||||
class TestGetStatsByTime(ApiTestCaseMixin):
|
||||
def test_it_gets_no_stats_when_user_has_no_workouts(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_time',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -33,19 +27,11 @@ class TestGetStatsByTime:
|
||||
def test_it_returns_error_when_user_does_not_exists(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/stats/1000/by_time',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -62,19 +48,14 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_time?from="2018-04-01&to=2018-04-30', # noqa
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
(
|
||||
f'/api/stats/{user_1.username}/by_time'
|
||||
f'?from="2018-04-01&to=2018-04-30'
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -94,19 +75,11 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=day', # noqa
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -123,19 +96,11 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_time',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -172,19 +137,11 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30', # noqa
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -214,20 +171,12 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1_paris.username}/by_time?'
|
||||
f'from=2018-04-01&to=2018-04-30',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -257,19 +206,11 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_time?time=year',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -306,19 +247,11 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=year', # noqa
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -348,19 +281,12 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1_paris.username}/by_time?from=2018-04-01&to=2018-04-30&time=year', # noqa
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -390,19 +316,11 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_time?time=month',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -467,19 +385,11 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1_full.username}/by_time?time=month',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -544,19 +454,11 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=month', # noqa
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -586,19 +488,11 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1_full.username}/by_time?time=week',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -663,19 +557,11 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=week', # noqa
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -705,19 +591,11 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_time?time=weekm',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -782,19 +660,11 @@ class TestGetStatsByTime:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=weekm', # noqa
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -816,7 +686,7 @@ class TestGetStatsByTime:
|
||||
}
|
||||
|
||||
|
||||
class TestGetStatsBySport:
|
||||
class TestGetStatsBySport(ApiTestCaseMixin):
|
||||
def test_it_gets_stats_by_sport(
|
||||
self,
|
||||
app: Flask,
|
||||
@ -826,19 +696,11 @@ class TestGetStatsBySport:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_sport',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -866,19 +728,11 @@ class TestGetStatsBySport:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_sport?sport_id=1',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -901,19 +755,11 @@ class TestGetStatsBySport:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/stats/1000/by_sport?sport_id=1',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -930,19 +776,11 @@ class TestGetStatsBySport:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_sport?sport_id=999',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -959,19 +797,11 @@ class TestGetStatsBySport:
|
||||
seven_workouts_user_1: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/stats/{user_1.username}/by_sport?sport_id="999',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -983,25 +813,17 @@ class TestGetStatsBySport:
|
||||
)
|
||||
|
||||
|
||||
class TestGetAllStats:
|
||||
class TestGetAllStats(ApiTestCaseMixin):
|
||||
def test_it_returns_all_stats_when_users_have_no_workouts(
|
||||
self, app: Flask, user_1_admin: User, user_2: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/stats/all',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1024,21 +846,13 @@ class TestGetAllStats:
|
||||
workout_cycling_user_2: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='admin@example.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app, as_admin=True
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/stats/all',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1061,19 +875,11 @@ class TestGetAllStats:
|
||||
workout_cycling_user_2: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/stats/all',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
|
@ -7,10 +7,11 @@ from flask import Flask
|
||||
from fittrackee.users.models import User
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
|
||||
from ..api_test_case import ApiTestCaseMixin
|
||||
from .utils import get_random_short_id
|
||||
|
||||
|
||||
class TestGetWorkouts:
|
||||
class TestGetWorkouts(ApiTestCaseMixin):
|
||||
def test_it_gets_all_workouts_for_authenticated_user(
|
||||
self,
|
||||
app: Flask,
|
||||
@ -22,19 +23,11 @@ class TestGetWorkouts:
|
||||
workout_cycling_user_2: Workout,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -104,7 +97,7 @@ class TestGetWorkouts:
|
||||
assert 'Provide a valid auth token.' in data['message']
|
||||
|
||||
|
||||
class TestGetWorkoutsWithPagination:
|
||||
class TestGetWorkoutsWithPagination(ApiTestCaseMixin):
|
||||
def test_it_gets_workouts_with_default_pagination(
|
||||
self,
|
||||
app: Flask,
|
||||
@ -112,19 +105,11 @@ class TestGetWorkoutsWithPagination:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -151,19 +136,11 @@ class TestGetWorkoutsWithPagination:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?page=1',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -190,19 +167,11 @@ class TestGetWorkoutsWithPagination:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?page=2',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -229,19 +198,11 @@ class TestGetWorkoutsWithPagination:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?page=3',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -256,19 +217,11 @@ class TestGetWorkoutsWithPagination:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?page=A',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -287,19 +240,11 @@ class TestGetWorkoutsWithPagination:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?per_page=10',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -323,19 +268,11 @@ class TestGetWorkoutsWithPagination:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?per_page=3',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -352,7 +289,7 @@ class TestGetWorkoutsWithPagination:
|
||||
)
|
||||
|
||||
|
||||
class TestGetWorkoutsWithOrder:
|
||||
class TestGetWorkoutsWithOrder(ApiTestCaseMixin):
|
||||
def test_it_gets_workouts_with_default_order(
|
||||
self,
|
||||
app: Flask,
|
||||
@ -360,19 +297,11 @@ class TestGetWorkoutsWithOrder:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -395,19 +324,11 @@ class TestGetWorkoutsWithOrder:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?order=asc',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -430,19 +351,11 @@ class TestGetWorkoutsWithOrder:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?order=desc',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -459,7 +372,7 @@ class TestGetWorkoutsWithOrder:
|
||||
)
|
||||
|
||||
|
||||
class TestGetWorkoutsWithFilters:
|
||||
class TestGetWorkoutsWithFilters(ApiTestCaseMixin):
|
||||
def test_it_gets_workouts_with_date_filter(
|
||||
self,
|
||||
app: Flask,
|
||||
@ -467,19 +380,11 @@ class TestGetWorkoutsWithFilters:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?from=2018-02-01&to=2018-02-28',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -506,19 +411,11 @@ class TestGetWorkoutsWithFilters:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?from=2018-03-01&to=2018-03-30',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -533,19 +430,11 @@ class TestGetWorkoutsWithFilters:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?from=2018-04-01',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -569,19 +458,11 @@ class TestGetWorkoutsWithFilters:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?to=2017-12-31',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -604,19 +485,11 @@ class TestGetWorkoutsWithFilters:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?distance_from=5&distance_to=8',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -639,19 +512,11 @@ class TestGetWorkoutsWithFilters:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?duration_from=00:52&duration_to=01:20',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -670,19 +535,11 @@ class TestGetWorkoutsWithFilters:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?ave_speed_from=5&ave_speed_to=10',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -705,19 +562,11 @@ class TestGetWorkoutsWithFilters:
|
||||
) -> None:
|
||||
workout_cycling_user_1.max_speed = 25
|
||||
workout_running_user_1.max_speed = 11
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?max_speed_from=10&max_speed_to=20',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -738,19 +587,11 @@ class TestGetWorkoutsWithFilters:
|
||||
sport_2_running: Sport,
|
||||
workout_running_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?sport_id=2',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -763,7 +604,7 @@ class TestGetWorkoutsWithFilters:
|
||||
)
|
||||
|
||||
|
||||
class TestGetWorkoutsWithFiltersAndPagination:
|
||||
class TestGetWorkoutsWithFiltersAndPagination(ApiTestCaseMixin):
|
||||
def test_it_gets_page_2_with_date_filter(
|
||||
self,
|
||||
app: Flask,
|
||||
@ -771,19 +612,11 @@ class TestGetWorkoutsWithFiltersAndPagination:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?from=2017-01-01&page=2',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -806,19 +639,11 @@ class TestGetWorkoutsWithFiltersAndPagination:
|
||||
sport_1_cycling: Sport,
|
||||
seven_workouts_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts?from=2017-01-01&page=2&order=asc',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -835,7 +660,7 @@ class TestGetWorkoutsWithFiltersAndPagination:
|
||||
)
|
||||
|
||||
|
||||
class TestGetWorkout:
|
||||
class TestGetWorkout(ApiTestCaseMixin):
|
||||
def test_it_gets_an_workout(
|
||||
self,
|
||||
app: Flask,
|
||||
@ -843,19 +668,11 @@ class TestGetWorkout:
|
||||
sport_1_cycling: Sport,
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_cycling_user_1.short_id}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -880,19 +697,11 @@ class TestGetWorkout:
|
||||
sport_1_cycling: Sport,
|
||||
workout_cycling_user_2: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_cycling_user_2.short_id}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -903,19 +712,11 @@ class TestGetWorkout:
|
||||
def test_it_returns_404_if_workout_does_not_exist(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/workouts/{get_random_short_id()}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -927,19 +728,11 @@ class TestGetWorkout:
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
random_short_id = get_random_short_id()
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/workouts/{random_short_id}/gpx',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -952,19 +745,11 @@ class TestGetWorkout:
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
random_short_id = get_random_short_id()
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/workouts/{random_short_id}/chart_data',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -981,19 +766,11 @@ class TestGetWorkout:
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
workout_short_id = workout_cycling_user_1.short_id
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_short_id}/gpx',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1012,19 +789,11 @@ class TestGetWorkout:
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
workout_short_id = workout_cycling_user_1.short_id
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_short_id}/chart_data',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1043,19 +812,11 @@ class TestGetWorkout:
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
workout_cycling_user_1.gpx = "some path"
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_cycling_user_1.short_id}/gpx',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1075,19 +836,11 @@ class TestGetWorkout:
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
workout_cycling_user_1.gpx = 'some path'
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_cycling_user_1.short_id}/chart_data',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1102,18 +855,10 @@ class TestGetWorkout:
|
||||
def test_it_returns_404_if_workout_has_no_map(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
response = client.get(
|
||||
f'/api/workouts/map/{uuid4().hex}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
|
@ -10,6 +10,8 @@ from fittrackee.users.models import User
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
from fittrackee.workouts.utils_id import decode_short_id
|
||||
|
||||
from ..api_test_case import ApiTestCaseMixin
|
||||
|
||||
|
||||
def assert_workout_data_with_gpx(data: Dict) -> None:
|
||||
assert 'creation_date' in data['data']['workouts'][0]
|
||||
@ -201,16 +203,11 @@ def assert_workout_data_wo_gpx(data: Dict) -> None:
|
||||
assert records[3]['value'] == 10.0
|
||||
|
||||
|
||||
class TestPostWorkoutWithGpx:
|
||||
class TestPostWorkoutWithGpx(ApiTestCaseMixin):
|
||||
def test_it_adds_an_workout_with_gpx_file(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -220,8 +217,7 @@ class TestPostWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
@ -239,12 +235,7 @@ class TestPostWorkoutWithGpx:
|
||||
sport_1_cycling: Sport,
|
||||
gpx_file_wo_name: str,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -254,8 +245,7 @@ class TestPostWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
@ -277,12 +267,7 @@ class TestPostWorkoutWithGpx:
|
||||
gpx_file_wo_name: str,
|
||||
) -> None:
|
||||
user_1.timezone = 'Europe/Paris'
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -292,8 +277,7 @@ class TestPostWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
@ -310,12 +294,7 @@ class TestPostWorkoutWithGpx:
|
||||
def test_it_adds_get_an_workout_with_gpx_notes(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -325,8 +304,7 @@ class TestPostWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
@ -344,12 +322,7 @@ class TestPostWorkoutWithGpx:
|
||||
sport_1_cycling: Sport,
|
||||
gpx_file_wo_track: str,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -359,8 +332,7 @@ class TestPostWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
@ -377,12 +349,7 @@ class TestPostWorkoutWithGpx:
|
||||
sport_1_cycling: Sport,
|
||||
gpx_file_invalid_xml: str,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -395,8 +362,7 @@ class TestPostWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
@ -409,12 +375,7 @@ class TestPostWorkoutWithGpx:
|
||||
def test_it_returns_400_if_workout_gpx_has_invalid_extension(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -424,8 +385,7 @@ class TestPostWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
@ -437,12 +397,7 @@ class TestPostWorkoutWithGpx:
|
||||
def test_it_returns_400_if_sport_id_is_not_provided(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -451,8 +406,7 @@ class TestPostWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
@ -464,12 +418,7 @@ class TestPostWorkoutWithGpx:
|
||||
def test_it_returns_500_if_sport_id_does_not_exists(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -479,8 +428,7 @@ class TestPostWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
@ -492,20 +440,14 @@ class TestPostWorkoutWithGpx:
|
||||
def test_returns_400_if_no_gpx_file_is_provided(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
data=dict(data='{}'),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
@ -514,17 +456,43 @@ class TestPostWorkoutWithGpx:
|
||||
assert data['status'] == 'fail'
|
||||
assert data['message'] == 'No file part.'
|
||||
|
||||
def test_it_returns_error_if_file_size_exceeds_limit(
|
||||
self,
|
||||
app_with_max_file_size: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
gpx_file: str,
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app_with_max_file_size
|
||||
)
|
||||
|
||||
class TestPostWorkoutWithoutGpx:
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
data=dict(
|
||||
file=(BytesIO(str.encode(gpx_file)), 'example.gpx'),
|
||||
data='{"sport_id": 1}',
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 413
|
||||
assert 'fail' in data['status']
|
||||
assert (
|
||||
'Error during workout upload, file size (3.6KB) exceeds 1.0KB.'
|
||||
in data['message']
|
||||
)
|
||||
assert 'data' not in data
|
||||
|
||||
|
||||
class TestPostWorkoutWithoutGpx(ApiTestCaseMixin):
|
||||
def test_it_adds_an_workout_without_gpx(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts/no_gpx',
|
||||
@ -537,10 +505,7 @@ class TestPostWorkoutWithoutGpx:
|
||||
distance=10,
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -552,21 +517,13 @@ class TestPostWorkoutWithoutGpx:
|
||||
def test_it_returns_400_if_workout_date_is_missing(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts/no_gpx',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(sport_id=1, duration=3600, distance=10)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -577,12 +534,7 @@ class TestPostWorkoutWithoutGpx:
|
||||
def test_it_returns_500_if_workout_format_is_invalid(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts/no_gpx',
|
||||
@ -595,10 +547,7 @@ class TestPostWorkoutWithoutGpx:
|
||||
distance=10,
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -613,12 +562,7 @@ class TestPostWorkoutWithoutGpx:
|
||||
sport_1_cycling: Sport,
|
||||
sport_2_running: Sport,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts/no_gpx',
|
||||
@ -632,10 +576,7 @@ class TestPostWorkoutWithoutGpx:
|
||||
title='Workout test',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -666,21 +607,14 @@ class TestPostWorkoutWithoutGpx:
|
||||
assert len(data['data']['workouts'][0]['records']) == 0
|
||||
|
||||
|
||||
class TestPostWorkoutWithZipArchive:
|
||||
class TestPostWorkoutWithZipArchive(ApiTestCaseMixin):
|
||||
def test_it_adds_workouts_with_zip_archive(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
file_path = os.path.join(app.root_path, 'tests/files/gpx_test.zip')
|
||||
# 'gpx_test.zip' contains 3 gpx files (same data) and 1 non-gpx file
|
||||
with open(file_path, 'rb') as zip_file:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='test@test.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -689,8 +623,7 @@ class TestPostWorkoutWithZipArchive:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
@ -710,14 +643,7 @@ class TestPostWorkoutWithZipArchive:
|
||||
# 'gpx_test_folder.zip' contains 3 gpx files (same data) and 1 non-gpx
|
||||
# file in a folder
|
||||
with open(file_path, 'rb') as zip_file:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='test@test.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -727,8 +653,7 @@ class TestPostWorkoutWithZipArchive:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
@ -745,14 +670,7 @@ class TestPostWorkoutWithZipArchive:
|
||||
)
|
||||
# 'gpx_test_incorrect.zip' contains 2 gpx files, one is incorrect
|
||||
with open(file_path, 'rb') as zip_file:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='test@test.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -762,8 +680,7 @@ class TestPostWorkoutWithZipArchive:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
@ -784,13 +701,8 @@ class TestPostWorkoutWithZipArchive:
|
||||
)
|
||||
# 'gpx_test.zip' contains 3 gpx files (same data) and 1 non-gpx file
|
||||
with open(file_path, 'rb') as zip_file:
|
||||
client = app_with_max_workouts.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(
|
||||
dict(email='test@test.com', password='12345678')
|
||||
),
|
||||
content_type='application/json',
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app_with_max_workouts
|
||||
)
|
||||
|
||||
client.post(
|
||||
@ -800,33 +712,57 @@ class TestPostWorkoutWithZipArchive:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/api/workouts',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
assert len(data['data']['workouts']) == 2
|
||||
|
||||
|
||||
class TestPostAndGetWorkoutWithGpx:
|
||||
@staticmethod
|
||||
def workout_assertion(
|
||||
app: Flask, gpx_file: str, with_segments: bool
|
||||
def test_it_returns_error_if_archive_size_exceeds_limit(
|
||||
self,
|
||||
app_with_max_zip_file_size: Flask,
|
||||
user_1: User,
|
||||
sport_1_cycling: Sport,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
file_path = os.path.join(
|
||||
app_with_max_zip_file_size.root_path, 'tests/files/gpx_test.zip'
|
||||
)
|
||||
# 'gpx_test.zip' contains 3 gpx files (same data) and 1 non-gpx file
|
||||
with open(file_path, 'rb') as zip_file:
|
||||
client, auth_token = self.get_test_client_and_auth_token(
|
||||
app_with_max_zip_file_size
|
||||
)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
data=dict(
|
||||
file=(zip_file, 'gpx_test.zip'), data='{"sport_id": 1}'
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 413
|
||||
assert 'fail' in data['status']
|
||||
assert (
|
||||
'Error during workout upload, file size (2.5KB) exceeds 1.0KB.'
|
||||
in data['message']
|
||||
)
|
||||
assert 'data' not in data
|
||||
|
||||
|
||||
class TestPostAndGetWorkoutWithGpx(ApiTestCaseMixin):
|
||||
def workout_assertion(
|
||||
self, app: Flask, gpx_file: str, with_segments: bool
|
||||
) -> None:
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
data=dict(
|
||||
@ -835,8 +771,7 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
|
||||
@ -854,10 +789,7 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_short_id}/gpx',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -868,10 +800,7 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_short_id}/gpx/segment/1',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
@ -882,10 +811,7 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
|
||||
response = client.get(
|
||||
f'/api/workouts/map/{map_id}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
@ -901,10 +827,7 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
|
||||
response = client.get(
|
||||
f'/api/workouts/map/{map_id}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
@ -932,12 +855,7 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
def test_it_gets_chart_data_for_an_workout_created_with_gpx(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -947,18 +865,14 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_short_id = data['data']['workouts'][0]['id']
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_short_id}/chart_data',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -970,12 +884,7 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
def test_it_gets_segment_chart_data_for_an_workout_created_with_gpx(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -985,18 +894,14 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_short_id = data['data']['workouts'][0]['id']
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_short_id}/chart_data/segment/1',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1013,12 +918,7 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
sport_1_cycling: Sport,
|
||||
gpx_file: str,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
data=dict(
|
||||
@ -1027,8 +927,7 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1055,12 +954,7 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
def test_it_returns_500_on_invalid_segment_id(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -1070,18 +964,14 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_short_id = data['data']['workouts'][0]['id']
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_short_id}/chart_data/segment/0',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1093,12 +983,7 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
def test_it_returns_404_if_segment_id_does_not_exist(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts',
|
||||
@ -1108,18 +993,14 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
),
|
||||
headers=dict(
|
||||
content_type='multipart/form-data',
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token'],
|
||||
Authorization=f'Bearer {auth_token}',
|
||||
),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_short_id = data['data']['workouts'][0]['id']
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_short_id}/chart_data/segment/999999',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1129,16 +1010,11 @@ class TestPostAndGetWorkoutWithGpx:
|
||||
assert 'data' not in data
|
||||
|
||||
|
||||
class TestPostAndGetWorkoutWithoutGpx:
|
||||
class TestPostAndGetWorkoutWithoutGpx(ApiTestCaseMixin):
|
||||
def test_it_add_and_gets_an_workout_wo_gpx(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts/no_gpx',
|
||||
@ -1151,19 +1027,13 @@ class TestPostAndGetWorkoutWithoutGpx:
|
||||
distance=10,
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_short_id = data['data']['workouts'][0]['id']
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_short_id}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1175,12 +1045,7 @@ class TestPostAndGetWorkoutWithoutGpx:
|
||||
def test_it_adds_and_gets_an_workout_wo_gpx_notes(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts/no_gpx',
|
||||
@ -1194,19 +1059,13 @@ class TestPostAndGetWorkoutWithoutGpx:
|
||||
notes="new test with notes",
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_short_id = data['data']['workouts'][0]['id']
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_short_id}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1216,17 +1075,12 @@ class TestPostAndGetWorkoutWithoutGpx:
|
||||
assert 'new test with notes' == data['data']['workouts'][0]['notes']
|
||||
|
||||
|
||||
class TestPostAndGetWorkoutUsingTimezones:
|
||||
class TestPostAndGetWorkoutUsingTimezones(ApiTestCaseMixin):
|
||||
def test_it_add_and_gets_an_workout_wo_gpx_with_timezone(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
user_1.timezone = 'Europe/Paris'
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.post(
|
||||
'/api/workouts/no_gpx',
|
||||
@ -1239,19 +1093,13 @@ class TestPostAndGetWorkoutUsingTimezones:
|
||||
distance=10,
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
workout_short_id = data['data']['workouts'][0]['id']
|
||||
response = client.get(
|
||||
f'/api/workouts/{workout_short_id}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1270,12 +1118,7 @@ class TestPostAndGetWorkoutUsingTimezones:
|
||||
def test_it_adds_and_gets_workouts_date_filter_with_timezone_new_york(
|
||||
self, app: Flask, user_1_full: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
client.post(
|
||||
'/api/workouts/no_gpx',
|
||||
@ -1288,17 +1131,11 @@ class TestPostAndGetWorkoutUsingTimezones:
|
||||
distance=10,
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
response = client.get(
|
||||
'/api/workouts?from=2018-01-01&to=2018-01-31',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -1321,12 +1158,7 @@ class TestPostAndGetWorkoutUsingTimezones:
|
||||
sport_1_cycling: Sport,
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
client.post(
|
||||
'/api/workouts/no_gpx',
|
||||
@ -1339,10 +1171,7 @@ class TestPostAndGetWorkoutUsingTimezones:
|
||||
distance=10,
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
client.post(
|
||||
'/api/workouts/no_gpx',
|
||||
@ -1355,10 +1184,7 @@ class TestPostAndGetWorkoutUsingTimezones:
|
||||
distance=10,
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
workout_cycling_user_1.workout_date = datetime.strptime(
|
||||
@ -1377,17 +1203,11 @@ class TestPostAndGetWorkoutUsingTimezones:
|
||||
distance=10,
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
response = client.get(
|
||||
'/api/workouts?from=2018-01-01&to=2018-01-31',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
|
@ -7,6 +7,7 @@ from fittrackee.users.models import User
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
from fittrackee.workouts.utils_id import decode_short_id
|
||||
|
||||
from ..api_test_case import ApiTestCaseMixin
|
||||
from .utils import get_random_short_id, post_an_workout
|
||||
|
||||
|
||||
@ -53,7 +54,7 @@ def assert_workout_data_with_gpx(data: Dict, sport_id: int) -> None:
|
||||
assert records[3]['value'] == 4.61
|
||||
|
||||
|
||||
class TestEditWorkoutWithGpx:
|
||||
class TestEditWorkoutWithGpx(ApiTestCaseMixin):
|
||||
def test_it_updates_title_for_an_workout_with_gpx(
|
||||
self,
|
||||
app: Flask,
|
||||
@ -203,7 +204,7 @@ class TestEditWorkoutWithGpx:
|
||||
)
|
||||
|
||||
|
||||
class TestEditWorkoutWithoutGpx:
|
||||
class TestEditWorkoutWithoutGpx(ApiTestCaseMixin):
|
||||
def test_it_updates_an_workout_wo_gpx(
|
||||
self,
|
||||
app: Flask,
|
||||
@ -213,12 +214,7 @@ class TestEditWorkoutWithoutGpx:
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
workout_short_id = workout_cycling_user_1.short_id
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.patch(
|
||||
f'/api/workouts/{workout_short_id}',
|
||||
@ -232,10 +228,7 @@ class TestEditWorkoutWithoutGpx:
|
||||
title='Workout test',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -298,21 +291,13 @@ class TestEditWorkoutWithoutGpx:
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
workout_short_id = workout_cycling_user_1.short_id
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.patch(
|
||||
f'/api/workouts/{workout_short_id}',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(notes='test notes')),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -374,12 +359,7 @@ class TestEditWorkoutWithoutGpx:
|
||||
sport_1_cycling: Sport,
|
||||
workout_cycling_user_2: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.patch(
|
||||
f'/api/workouts/{workout_cycling_user_2.short_id}',
|
||||
@ -393,10 +373,7 @@ class TestEditWorkoutWithoutGpx:
|
||||
title='Workout test',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -413,12 +390,7 @@ class TestEditWorkoutWithoutGpx:
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
workout_short_id = workout_cycling_user_1.short_id
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.patch(
|
||||
f'/api/workouts/{workout_short_id}',
|
||||
@ -432,10 +404,7 @@ class TestEditWorkoutWithoutGpx:
|
||||
title='Workout test',
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
@ -494,21 +463,13 @@ class TestEditWorkoutWithoutGpx:
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
workout_short_id = workout_cycling_user_1.short_id
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.patch(
|
||||
f'/api/workouts/{workout_short_id}',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(sport_id=2, distance=20)),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -565,21 +526,13 @@ class TestEditWorkoutWithoutGpx:
|
||||
sport_1_cycling: Sport,
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
|
||||
response = client.patch(
|
||||
f'/api/workouts/{workout_cycling_user_1.short_id}',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict()),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -594,12 +547,7 @@ class TestEditWorkoutWithoutGpx:
|
||||
sport_1_cycling: Sport,
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
response = client.patch(
|
||||
f'/api/workouts/{workout_cycling_user_1.short_id}',
|
||||
content_type='application/json',
|
||||
@ -611,10 +559,7 @@ class TestEditWorkoutWithoutGpx:
|
||||
distance=10,
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
@ -629,12 +574,7 @@ class TestEditWorkoutWithoutGpx:
|
||||
def test_it_returns_404_if_edited_workout_does_not_exists(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
response = client.patch(
|
||||
f'/api/workouts/{get_random_short_id()}',
|
||||
content_type='application/json',
|
||||
@ -646,10 +586,7 @@ class TestEditWorkoutWithoutGpx:
|
||||
distance=10,
|
||||
)
|
||||
),
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
|
||||
data = json.loads(response.data.decode())
|
||||
|
@ -7,6 +7,7 @@ from fittrackee.users.models import User
|
||||
from fittrackee.workouts.models import Sport, Workout
|
||||
from fittrackee.workouts.utils import get_absolute_file_path
|
||||
|
||||
from ..api_test_case import ApiTestCaseMixin
|
||||
from .utils import get_random_short_id, post_an_workout
|
||||
|
||||
|
||||
@ -15,7 +16,7 @@ def get_gpx_filepath(workout_id: int) -> str:
|
||||
return workout.gpx
|
||||
|
||||
|
||||
class TestDeleteWorkoutWithGpx:
|
||||
class TestDeleteWorkoutWithGpx(ApiTestCaseMixin):
|
||||
def test_it_deletes_an_workout_with_gpx(
|
||||
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
|
||||
) -> None:
|
||||
@ -62,18 +63,10 @@ class TestDeleteWorkoutWithGpx:
|
||||
def test_it_returns_404_if_workout_does_not_exist(
|
||||
self, app: Flask, user_1: User
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
response = client.delete(
|
||||
f'/api/workouts/{get_random_short_id()}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
assert response.status_code == 404
|
||||
@ -103,7 +96,7 @@ class TestDeleteWorkoutWithGpx:
|
||||
)
|
||||
|
||||
|
||||
class TestDeleteWorkoutWithoutGpx:
|
||||
class TestDeleteWorkoutWithoutGpx(ApiTestCaseMixin):
|
||||
def test_it_deletes_an_workout_wo_gpx(
|
||||
self,
|
||||
app: Flask,
|
||||
@ -111,18 +104,10 @@ class TestDeleteWorkoutWithoutGpx:
|
||||
sport_1_cycling: Sport,
|
||||
workout_cycling_user_1: Workout,
|
||||
) -> None:
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(email='test@test.com', password='12345678')),
|
||||
content_type='application/json',
|
||||
)
|
||||
client, auth_token = self.get_test_client_and_auth_token(app)
|
||||
response = client.delete(
|
||||
f'/api/workouts/{workout_cycling_user_1.short_id}',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||
)
|
||||
assert response.status_code == 204
|
||||
|
||||
|
@ -18,17 +18,12 @@ from fittrackee.responses import (
|
||||
handle_error_and_return_response,
|
||||
)
|
||||
from fittrackee.tasks import reset_password_email
|
||||
from fittrackee.utils import get_readable_duration, verify_extension_and_size
|
||||
from fittrackee.workouts.utils_files import get_absolute_file_path
|
||||
|
||||
from .decorators import authenticate
|
||||
from .models import User
|
||||
from .utils import (
|
||||
check_passwords,
|
||||
display_readable_file_size,
|
||||
get_readable_duration,
|
||||
register_controls,
|
||||
verify_extension_and_size,
|
||||
)
|
||||
from .utils import check_passwords, register_controls
|
||||
from .utils_token import decode_user_token
|
||||
|
||||
auth_blueprint = Blueprint('auth', __name__)
|
||||
@ -524,10 +519,10 @@ def edit_picture(auth_user_id: int) -> Union[Dict, HttpResponse]:
|
||||
response_object = verify_extension_and_size('picture', request)
|
||||
except RequestEntityTooLarge as e:
|
||||
appLog.error(e)
|
||||
max_file_size = current_app.config['MAX_CONTENT_LENGTH']
|
||||
return PayloadTooLargeErrorResponse(
|
||||
'Error during picture update, file size exceeds '
|
||||
f'{display_readable_file_size(max_file_size)}.'
|
||||
file_type='picture',
|
||||
file_size=request.content_length,
|
||||
max_size=current_app.config['MAX_CONTENT_LENGTH'],
|
||||
)
|
||||
if response_object:
|
||||
return response_object
|
||||
|
@ -1,15 +1,11 @@
|
||||
import re
|
||||
from datetime import timedelta
|
||||
from typing import Optional, Tuple, Union
|
||||
from typing import Optional, Tuple
|
||||
|
||||
import humanize
|
||||
from flask import Request, current_app
|
||||
from flask import Request
|
||||
|
||||
from fittrackee.responses import (
|
||||
ForbiddenErrorResponse,
|
||||
HttpResponse,
|
||||
InvalidPayloadErrorResponse,
|
||||
PayloadTooLargeErrorResponse,
|
||||
UnauthorizedErrorResponse,
|
||||
)
|
||||
|
||||
@ -64,49 +60,6 @@ def register_controls(
|
||||
return ret
|
||||
|
||||
|
||||
def verify_extension_and_size(
|
||||
file_type: str, req: Request
|
||||
) -> Optional[HttpResponse]:
|
||||
"""
|
||||
Return error Response if file is invalid
|
||||
"""
|
||||
if 'file' not in req.files:
|
||||
return InvalidPayloadErrorResponse('No file part.', 'fail')
|
||||
|
||||
file = req.files['file']
|
||||
if file.filename == '':
|
||||
return InvalidPayloadErrorResponse('No selected file.', 'fail')
|
||||
|
||||
allowed_extensions = (
|
||||
'WORKOUT_ALLOWED_EXTENSIONS'
|
||||
if file_type == 'workout'
|
||||
else 'PICTURE_ALLOWED_EXTENSIONS'
|
||||
)
|
||||
|
||||
file_extension = (
|
||||
file.filename.rsplit('.', 1)[1].lower()
|
||||
if '.' in file.filename
|
||||
else None
|
||||
)
|
||||
max_file_size = current_app.config['max_single_file_size']
|
||||
|
||||
if not (
|
||||
file_extension
|
||||
and file_extension in current_app.config[allowed_extensions]
|
||||
):
|
||||
return InvalidPayloadErrorResponse(
|
||||
'File extension not allowed.', 'fail'
|
||||
)
|
||||
|
||||
if file_extension != 'zip' and req.content_length > max_file_size:
|
||||
return PayloadTooLargeErrorResponse(
|
||||
'Error during picture update, file size exceeds '
|
||||
f'{display_readable_file_size(max_file_size)}.'
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def verify_user(
|
||||
current_request: Request, verify_admin: bool
|
||||
) -> Tuple[Optional[HttpResponse], Optional[int]]:
|
||||
@ -139,35 +92,3 @@ def can_view_workout(
|
||||
if auth_user_id != workout_user_id:
|
||||
return ForbiddenErrorResponse()
|
||||
return None
|
||||
|
||||
|
||||
def display_readable_file_size(size_in_bytes: Union[float, int]) -> str:
|
||||
"""
|
||||
Return readable file size from size in bytes
|
||||
"""
|
||||
if size_in_bytes == 0:
|
||||
return '0 bytes'
|
||||
if size_in_bytes == 1:
|
||||
return '1 byte'
|
||||
for unit in [' bytes', 'KB', 'MB', 'GB', 'TB']:
|
||||
if abs(size_in_bytes) < 1024.0:
|
||||
return f'{size_in_bytes:3.1f}{unit}'
|
||||
size_in_bytes /= 1024.0
|
||||
return f'{size_in_bytes} bytes'
|
||||
|
||||
|
||||
def get_readable_duration(duration: int, locale: Optional[str] = None) -> str:
|
||||
"""
|
||||
Return readable and localized duration from duration in seconds
|
||||
"""
|
||||
if locale is None:
|
||||
locale = 'en'
|
||||
if locale != 'en':
|
||||
try:
|
||||
_t = humanize.i18n.activate(locale) # noqa
|
||||
except FileNotFoundError:
|
||||
locale = 'en'
|
||||
readable_duration = humanize.naturaldelta(timedelta(seconds=duration))
|
||||
if locale != 'en':
|
||||
humanize.i18n.deactivate()
|
||||
return readable_duration
|
||||
|
76
fittrackee/utils.py
Normal file
76
fittrackee/utils.py
Normal file
@ -0,0 +1,76 @@
|
||||
from datetime import timedelta
|
||||
from typing import Optional
|
||||
|
||||
import humanize
|
||||
from flask import Request, current_app
|
||||
|
||||
from .responses import (
|
||||
HttpResponse,
|
||||
InvalidPayloadErrorResponse,
|
||||
PayloadTooLargeErrorResponse,
|
||||
)
|
||||
|
||||
|
||||
def verify_extension_and_size(
|
||||
file_type: str, req: Request
|
||||
) -> Optional[HttpResponse]:
|
||||
"""
|
||||
Return error Response if file is invalid
|
||||
"""
|
||||
if 'file' not in req.files:
|
||||
return InvalidPayloadErrorResponse('No file part.', 'fail')
|
||||
|
||||
file = req.files['file']
|
||||
if file.filename == '':
|
||||
return InvalidPayloadErrorResponse('No selected file.', 'fail')
|
||||
|
||||
allowed_extensions = (
|
||||
'WORKOUT_ALLOWED_EXTENSIONS'
|
||||
if file_type == 'workout'
|
||||
else 'PICTURE_ALLOWED_EXTENSIONS'
|
||||
)
|
||||
|
||||
file_extension = (
|
||||
file.filename.rsplit('.', 1)[1].lower()
|
||||
if '.' in file.filename
|
||||
else None
|
||||
)
|
||||
max_file_size = current_app.config['max_single_file_size']
|
||||
|
||||
if not (
|
||||
file_extension
|
||||
and file_extension in current_app.config[allowed_extensions]
|
||||
):
|
||||
return InvalidPayloadErrorResponse(
|
||||
'File extension not allowed.', 'fail'
|
||||
)
|
||||
|
||||
if (
|
||||
file_extension != 'zip'
|
||||
and req.content_length is not None
|
||||
and req.content_length > max_file_size
|
||||
):
|
||||
return PayloadTooLargeErrorResponse(
|
||||
file_type=file_type,
|
||||
file_size=req.content_length,
|
||||
max_size=max_file_size,
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_readable_duration(duration: int, locale: Optional[str] = None) -> str:
|
||||
"""
|
||||
Return readable and localized duration from duration in seconds
|
||||
"""
|
||||
if locale is None:
|
||||
locale = 'en'
|
||||
if locale != 'en':
|
||||
try:
|
||||
_t = humanize.i18n.activate(locale) # noqa
|
||||
except FileNotFoundError:
|
||||
locale = 'en'
|
||||
readable_duration = humanize.naturaldelta(timedelta(seconds=duration))
|
||||
if locale != 'en':
|
||||
humanize.i18n.deactivate()
|
||||
return readable_duration
|
@ -7,6 +7,7 @@ from typing import Any, Dict, List, Optional, Tuple, Union
|
||||
import requests
|
||||
from flask import Blueprint, Response, current_app, request, send_file
|
||||
from sqlalchemy import exc
|
||||
from werkzeug.exceptions import RequestEntityTooLarge
|
||||
|
||||
from fittrackee import appLog, db
|
||||
from fittrackee.responses import (
|
||||
@ -16,14 +17,13 @@ from fittrackee.responses import (
|
||||
InternalServerErrorResponse,
|
||||
InvalidPayloadErrorResponse,
|
||||
NotFoundErrorResponse,
|
||||
PayloadTooLargeErrorResponse,
|
||||
handle_error_and_return_response,
|
||||
)
|
||||
from fittrackee.users.decorators import authenticate
|
||||
from fittrackee.users.utils import (
|
||||
User,
|
||||
can_view_workout,
|
||||
verify_extension_and_size,
|
||||
)
|
||||
from fittrackee.users.models import User
|
||||
from fittrackee.users.utils import can_view_workout
|
||||
from fittrackee.utils import verify_extension_and_size
|
||||
|
||||
from .models import Workout
|
||||
from .utils import (
|
||||
@ -880,7 +880,15 @@ def post_workout(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]:
|
||||
:statuscode 500:
|
||||
|
||||
"""
|
||||
error_response = verify_extension_and_size('workout', request)
|
||||
try:
|
||||
error_response = verify_extension_and_size('workout', request)
|
||||
except RequestEntityTooLarge as e:
|
||||
appLog.error(e)
|
||||
return PayloadTooLargeErrorResponse(
|
||||
file_type='workout',
|
||||
file_size=request.content_length,
|
||||
max_size=current_app.config['MAX_CONTENT_LENGTH'],
|
||||
)
|
||||
if error_response:
|
||||
return error_response
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
import FitTrackeeGenericApi from '../fitTrackeeApi'
|
||||
import { setError } from './index'
|
||||
import { history } from '../index'
|
||||
import { generateIds } from '../utils'
|
||||
import { emptyMessages, setError } from './index'
|
||||
|
||||
export const setAppConfig = data => ({
|
||||
type: 'SET_APP_CONFIG',
|
||||
@ -11,6 +13,8 @@ export const setAppStats = data => ({
|
||||
data,
|
||||
})
|
||||
|
||||
const SetAppErrors = messages => ({ type: 'APP_ERRORS', messages })
|
||||
|
||||
export const getAppData = target => dispatch =>
|
||||
FitTrackeeGenericApi.getData(target)
|
||||
.then(ret => {
|
||||
@ -26,13 +30,18 @@ export const getAppData = target => dispatch =>
|
||||
})
|
||||
.catch(error => dispatch(setError(`application|${error}`)))
|
||||
|
||||
export const updateAppConfig = formData => dispatch =>
|
||||
export const updateAppConfig = formData => dispatch => {
|
||||
dispatch(emptyMessages())
|
||||
FitTrackeeGenericApi.updateData('config', formData)
|
||||
.then(ret => {
|
||||
if (ret.status === 'success') {
|
||||
dispatch(setAppConfig(ret.data))
|
||||
history.push('/admin/application')
|
||||
} else if (Array.isArray(ret.message)) {
|
||||
dispatch(SetAppErrors(generateIds(ret.message)))
|
||||
} else {
|
||||
dispatch(setError(`application|${ret.message}`))
|
||||
dispatch(setError(ret.message))
|
||||
}
|
||||
})
|
||||
.catch(error => dispatch(setError(`application|${error}`)))
|
||||
}
|
||||
|
@ -3,11 +3,16 @@ import i18next from 'i18next'
|
||||
import FitTrackeeApi from '../fitTrackeeApi/index'
|
||||
import { history } from '../index'
|
||||
|
||||
export const emptyMessages = () => ({
|
||||
type: 'CLEAN_ALL_MESSAGES',
|
||||
})
|
||||
|
||||
export const setData = (target, data) => ({
|
||||
type: 'SET_DATA',
|
||||
data,
|
||||
target,
|
||||
})
|
||||
|
||||
export const setPaginatedData = (target, data, pagination) => ({
|
||||
type: 'SET_PAGINATED_DATA',
|
||||
data,
|
||||
@ -51,7 +56,7 @@ export const getOrUpdateData = (
|
||||
dispatch(setLoading(false))
|
||||
return dispatch(setError(`${target}|Incorrect id`))
|
||||
}
|
||||
dispatch(setError(''))
|
||||
dispatch(emptyMessages())
|
||||
return FitTrackeeApi[action](target, data)
|
||||
.then(ret => {
|
||||
if (ret.status === 'success') {
|
||||
|
@ -2,7 +2,7 @@ import React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import Message from '../Common/Message'
|
||||
import { updateAppConfig } from '../../actions/application'
|
||||
import { getAppData, updateAppConfig } from '../../actions/application'
|
||||
import { history } from '../../index'
|
||||
import { getFileSizeInMB } from '../../utils'
|
||||
|
||||
@ -11,7 +11,6 @@ class AdminApplication extends React.Component {
|
||||
super(props, context)
|
||||
this.state = {
|
||||
formData: {},
|
||||
isInEdition: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,18 +43,21 @@ class AdminApplication extends React.Component {
|
||||
this.setState(formData)
|
||||
}
|
||||
|
||||
toggleInEdition(e) {
|
||||
e.preventDefault()
|
||||
const { isInEdition } = this.state
|
||||
this.setState({ isInEdition: !isInEdition })
|
||||
}
|
||||
|
||||
render() {
|
||||
const { message, onHandleConfigFormSubmit, t } = this.props
|
||||
const { formData, isInEdition } = this.state
|
||||
const {
|
||||
isInEdition,
|
||||
loadAppConfig,
|
||||
message,
|
||||
messages,
|
||||
onHandleConfigFormSubmit,
|
||||
t,
|
||||
} = this.props
|
||||
const { formData } = this.state
|
||||
return (
|
||||
<div>
|
||||
{message && <Message message={message} t={t} />}
|
||||
{(message || messages) && (
|
||||
<Message message={message} messages={messages} t={t} />
|
||||
)}
|
||||
{Object.keys(formData).length > 0 && (
|
||||
<div className="row">
|
||||
<div className="col-md-12">
|
||||
@ -71,7 +73,7 @@ class AdminApplication extends React.Component {
|
||||
isInEdition ? '' : 'form-disabled'
|
||||
}`}
|
||||
onSubmit={e => {
|
||||
this.toggleInEdition(e)
|
||||
e.preventDefault()
|
||||
onHandleConfigFormSubmit(formData)
|
||||
}}
|
||||
>
|
||||
@ -169,7 +171,11 @@ class AdminApplication extends React.Component {
|
||||
<input
|
||||
type="submit"
|
||||
className="btn btn-secondary"
|
||||
onClick={e => this.toggleInEdition(e)}
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
loadAppConfig()
|
||||
history.push('/admin/application')
|
||||
}}
|
||||
value={t('common:Cancel')}
|
||||
/>
|
||||
</>
|
||||
@ -179,7 +185,8 @@ class AdminApplication extends React.Component {
|
||||
type="submit"
|
||||
className="btn btn-primary"
|
||||
onClick={e => {
|
||||
this.toggleInEdition(e)
|
||||
e.preventDefault()
|
||||
history.push('/admin/application/edit')
|
||||
}}
|
||||
value={t('common:Edit')}
|
||||
/>
|
||||
@ -205,8 +212,12 @@ class AdminApplication extends React.Component {
|
||||
export default connect(
|
||||
state => ({
|
||||
message: state.message,
|
||||
messages: state.messages,
|
||||
}),
|
||||
dispatch => ({
|
||||
loadAppConfig: () => {
|
||||
dispatch(getAppData('config'))
|
||||
},
|
||||
onHandleConfigFormSubmit: formData => {
|
||||
const data = Object.assign({}, formData)
|
||||
data.max_single_file_size *= 1048576
|
||||
|
@ -28,7 +28,20 @@ function Admin(props) {
|
||||
<Route
|
||||
exact
|
||||
path="/admin/application"
|
||||
render={() => <AdminApplication appConfig={appConfig} t={t} />}
|
||||
render={() => (
|
||||
<AdminApplication
|
||||
appConfig={appConfig}
|
||||
t={t}
|
||||
isInEdition={false}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/admin/application/edit"
|
||||
render={() => (
|
||||
<AdminApplication appConfig={appConfig} t={t} isInEdition />
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
|
@ -228,7 +228,7 @@ label {
|
||||
}
|
||||
|
||||
.error-message {
|
||||
margin-top: 10px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.fa-as-link {
|
||||
|
@ -14,15 +14,19 @@ export default class Message extends React.PureComponent {
|
||||
return (
|
||||
<div className="error-message">
|
||||
{singleMessage !== '' && <code>{singleMessage}</code>}
|
||||
{messages && messages.length > 0 && (
|
||||
<code>
|
||||
<ul>
|
||||
{messages.map(msg => (
|
||||
<li key={msg.id}>{t(`messages:${msg.value}`)}</li>
|
||||
))}
|
||||
</ul>
|
||||
</code>
|
||||
)}
|
||||
{messages &&
|
||||
messages.length > 0 &&
|
||||
(messages.length === 1 ? (
|
||||
<code>{messages[0].value}</code>
|
||||
) : (
|
||||
<code>
|
||||
<ul>
|
||||
{messages.map(msg => (
|
||||
<li key={msg.id}>{t(`messages:${msg.value}`)}</li>
|
||||
))}
|
||||
</ul>
|
||||
</code>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
"3 to 12 characters required for username.": "3 to 12 characters required for username.",
|
||||
"8 characters required for password.": "8 characters required for password.",
|
||||
"An error occurred. Please contact the administrator.": "An error occurred. Please contact the administrator.",
|
||||
"workouts": "workouts",
|
||||
"application": "application",
|
||||
"Error during picture deletion.": "Error during picture deletion.",
|
||||
"Error during picture update.": "Error during picture update.",
|
||||
"Error during picture update, file size exceeds max size.": "Error during picture update, file size exceeds max size.",
|
||||
@ -14,6 +14,10 @@
|
||||
"Invalid credentials.": "Invalid credentials.",
|
||||
"Invalid payload.": "Invalid payload.",
|
||||
"Invalid token. Please log in again.": "Invalid token. Please log in again.",
|
||||
"Max. files in a zip archive must be greater than 0": "Max. files in a zip archive must be greater than 0",
|
||||
"Max. size of uploaded files must be greater than 0": "Max. size of uploaded files must be greater than 0",
|
||||
"Max. size of zip archive must be equal or greater than max. size of uploaded files": "Max. size of zip archive must be equal or greater than max. size of uploaded files",
|
||||
"Max. size of zip archive must be greater than 0": "Max. size of zip archive must be greater than 0",
|
||||
"No file part.": "No file part.",
|
||||
"No picture.": "No picture.",
|
||||
"No selected file.": "No selected file.",
|
||||
@ -30,6 +34,7 @@
|
||||
"statistics": "statistiques",
|
||||
"User does not exist.": "User does not exist.",
|
||||
"Valid email must be provided.\n": "Valid email must be provided.",
|
||||
"workouts": "workouts",
|
||||
"You can not delete your account, no other user has admin rights.": "You can not delete your account, no other user has admin rights.",
|
||||
"You do not have permissions.": "You do not have permissions."
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
"3 to 12 characters required for username.": "3 à 12 caractères requis pour le nom.",
|
||||
"8 characters required for password.": "8 caractères minimum pour le mot de passe.",
|
||||
"An error occurred. Please contact the administrator.": "Une erreur s'est produite. Merci de contacter l'administrateur.",
|
||||
"workouts": "séances",
|
||||
"application": "application",
|
||||
"Error during picture deletion.": "Erreur lors de la suppression de l'image.",
|
||||
"Error during picture update.": "Erreur lors de la mise à jour de l'image.",
|
||||
"Error during picture update, file size exceeds max size.": "Erreur lors de la mise à jour de l'image, la taille du ficher dépasse la taille maximum autorisée",
|
||||
@ -14,6 +14,10 @@
|
||||
"Invalid credentials.": "Identifiants invalides.",
|
||||
"Invalid payload.": "Données incorrectes.",
|
||||
"Invalid token. Please log in again.": "Jeton invalide. Merci de vous reconnecter.",
|
||||
"Max. files in a zip archive must be greater than 0": "Le nombre max. de fichiers dans une archive doit être supérieur à 0",
|
||||
"Max. size of uploaded files must be greater than 0": "La taille max. des fichiers doit être supérieure à 0",
|
||||
"Max. size of zip archive must be equal or greater than max. size of uploaded files": "La taille max. d'une archive doit être supérieure ou égale à la taille max. d'un fichier",
|
||||
"Max. size of zip archive must be greater than 0": "La taille max. d'une archive doit être supérieure à 0",
|
||||
"No file part.": "Pas de fichier fourni.",
|
||||
"No picture.": "Pas d'image.",
|
||||
"No selected file.": "Pas de fichier sélectionné.",
|
||||
@ -30,6 +34,7 @@
|
||||
"statistics": "statistics",
|
||||
"User does not exist.": "L'utilisateur n'existe pas.",
|
||||
"Valid email must be provided.\n": "L'email fourni n'est pas valide.",
|
||||
"workouts": "séances",
|
||||
"You can not delete your account, no other user has admin rights.": "Vous ne pouvez pas supprimer votre compte, aucun autre utilisateur n'a des droits d'administration.",
|
||||
"You do not have permissions.": "Vous n'avez pas les permissions nécessaires."
|
||||
}
|
||||
|
@ -108,8 +108,10 @@ const message = (state = initial.message, action) => {
|
||||
case 'PICTURE_ERROR':
|
||||
case 'SET_ERROR':
|
||||
return action.message
|
||||
case 'CLEAN_ALL_MESSAGES':
|
||||
case 'LOGOUT':
|
||||
case 'PROFILE_SUCCESS':
|
||||
case 'SET_APP_CONFIG':
|
||||
case 'SET_RESULTS':
|
||||
case '@@router/LOCATION_CHANGE':
|
||||
return ''
|
||||
@ -121,7 +123,9 @@ const message = (state = initial.message, action) => {
|
||||
const messages = (state = initial.messages, action) => {
|
||||
switch (action.type) {
|
||||
case 'AUTH_ERRORS':
|
||||
case 'APP_ERRORS':
|
||||
return action.messages
|
||||
case 'CLEAN_ALL_MESSAGES':
|
||||
case 'LOGOUT':
|
||||
case 'PROFILE_SUCCESS':
|
||||
case '@@router/LOCATION_CHANGE':
|
||||
|
Loading…
Reference in New Issue
Block a user