API & Client - display only active sports when adding an activity
This commit is contained in:
parent
a9cbe220ac
commit
8a4b114af8
@ -135,6 +135,9 @@
|
||||
</pre></div>
|
||||
</div>
|
||||
<p><strong>Example response</strong>:</p>
|
||||
<ul class="simple">
|
||||
<li><p>for non admin user :</p></li>
|
||||
</ul>
|
||||
<div class="highlight-http notranslate"><div class="highlight"><pre><span></span><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span> <span class="m">200</span> <span class="ne">OK</span>
|
||||
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/json</span>
|
||||
|
||||
@ -142,42 +145,93 @@
|
||||
<span class="nt">"data"</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="nt">"sports"</span><span class="p">:</span> <span class="p">[</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"_can_be_disabled"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/cycling-sport.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
<span class="nt">"label"</span><span class="p">:</span> <span class="s2">"Cycling (Sport)"</span>
|
||||
<span class="p">},</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"_can_be_disabled"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/cycling-transport.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
<span class="nt">"label"</span><span class="p">:</span> <span class="s2">"Cycling (Transport)"</span>
|
||||
<span class="p">},</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"_can_be_disabled"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/hiking.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
<span class="nt">"label"</span><span class="p">:</span> <span class="s2">"Hiking"</span>
|
||||
<span class="p">},</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"_can_be_disabled"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/mountain-biking.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
<span class="nt">"label"</span><span class="p">:</span> <span class="s2">"Mountain Biking"</span>
|
||||
<span class="p">},</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"_can_be_disabled"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/running.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
<span class="nt">"label"</span><span class="p">:</span> <span class="s2">"Running"</span>
|
||||
<span class="p">},</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"_can_be_disabled"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">6</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/walking.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
<span class="nt">"label"</span><span class="p">:</span> <span class="s2">"Walking"</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">]</span>
|
||||
<span class="p">},</span>
|
||||
<span class="nt">"status"</span><span class="p">:</span> <span class="s2">"success"</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>for admin user :</p></li>
|
||||
</ul>
|
||||
<div class="highlight-http notranslate"><div class="highlight"><pre><span></span><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span> <span class="m">200</span> <span class="ne">OK</span>
|
||||
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/json</span>
|
||||
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"data"</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="nt">"sports"</span><span class="p">:</span> <span class="p">[</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"has_activities"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/cycling-sport.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
<span class="nt">"label"</span><span class="p">:</span> <span class="s2">"Cycling (Sport)"</span>
|
||||
<span class="p">},</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"has_activities"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/cycling-transport.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
<span class="nt">"label"</span><span class="p">:</span> <span class="s2">"Cycling (Transport)"</span>
|
||||
<span class="p">},</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"has_activities"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/hiking.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
<span class="nt">"label"</span><span class="p">:</span> <span class="s2">"Hiking"</span>
|
||||
<span class="p">},</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"has_activities"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/mountain-biking.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
<span class="nt">"label"</span><span class="p">:</span> <span class="s2">"Mountain Biking"</span>
|
||||
<span class="p">},</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"has_activities"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/running.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
<span class="nt">"label"</span><span class="p">:</span> <span class="s2">"Running"</span>
|
||||
<span class="p">},</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"has_activities"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">6</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/walking.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
@ -225,7 +279,7 @@
|
||||
</div>
|
||||
<p><strong>Example response</strong>:</p>
|
||||
<ul class="simple">
|
||||
<li><p>success</p></li>
|
||||
<li><p>success for non admin user :</p></li>
|
||||
</ul>
|
||||
<div class="highlight-http notranslate"><div class="highlight"><pre><span></span><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span> <span class="m">200</span> <span class="ne">OK</span>
|
||||
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/json</span>
|
||||
@ -234,7 +288,28 @@
|
||||
<span class="nt">"data"</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="nt">"sports"</span><span class="p">:</span> <span class="p">[</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"_can_be_disabled"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/cycling-sport.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
<span class="nt">"label"</span><span class="p">:</span> <span class="s2">"Cycling (Sport)"</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">]</span>
|
||||
<span class="p">},</span>
|
||||
<span class="nt">"status"</span><span class="p">:</span> <span class="s2">"success"</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>success for admin user :</p></li>
|
||||
</ul>
|
||||
<div class="highlight-http notranslate"><div class="highlight"><pre><span></span><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span> <span class="m">200</span> <span class="ne">OK</span>
|
||||
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/json</span>
|
||||
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"data"</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="nt">"sports"</span><span class="p">:</span> <span class="p">[</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"has_activities"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/cycling-sport.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||||
@ -290,7 +365,8 @@
|
||||
<dl class="patch">
|
||||
<dt id="patch--api-sports-(int-sport_id)">
|
||||
<code class="sig-name descname">PATCH </code><code class="sig-name descname">/api/sports/</code><span class="sig-paren">(</span><em class="property">int: </em><em class="sig-param">sport_id</em><span class="sig-paren">)</span><a class="headerlink" href="#patch--api-sports-(int-sport_id)" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Update a sport</p>
|
||||
<dd><p>Update a sport
|
||||
Authenticated user must be an admin</p>
|
||||
<p><strong>Example request</strong>:</p>
|
||||
<div class="highlight-http notranslate"><div class="highlight"><pre><span></span><span class="nf">PATCH</span> <span class="nn">/api/sports/1</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
|
||||
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/json</span>
|
||||
@ -307,7 +383,7 @@
|
||||
<span class="nt">"data"</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="nt">"sports"</span><span class="p">:</span> <span class="p">[</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"_can_be_disabled"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"has_activities"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
|
||||
<span class="nt">"img"</span><span class="p">:</span> <span class="s2">"/img/sports/cycling-sport.png"</span><span class="p">,</span>
|
||||
<span class="nt">"is_active"</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
@ -360,6 +436,7 @@
|
||||
<li><p>Invalid token. Please log in again.</p></li>
|
||||
</ul>
|
||||
</p></li>
|
||||
<li><p><a class="reference external" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4">403 Forbidden</a> – You do not have permissions.</p></li>
|
||||
<li><p><a class="reference external" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5">404 Not Found</a> – sport not found</p></li>
|
||||
<li><p><a class="reference external" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1">500 Internal Server Error</a> – </p></li>
|
||||
</ul>
|
||||
|
File diff suppressed because one or more lines are too long
@ -74,16 +74,16 @@ class Sport(db.Model):
|
||||
def __init__(self, label):
|
||||
self.label = label
|
||||
|
||||
def serialize(self):
|
||||
return {
|
||||
def serialize(self, is_admin=False):
|
||||
serialized_sport = {
|
||||
'id': self.id,
|
||||
'label': self.label,
|
||||
'img': self.img,
|
||||
'is_active': self.is_active,
|
||||
'_can_be_disabled': not (
|
||||
len(self.activities) > 0 and self.is_active
|
||||
),
|
||||
}
|
||||
if is_admin:
|
||||
serialized_sport['has_activities'] = len(self.activities) > 0
|
||||
return serialized_sport
|
||||
|
||||
|
||||
class Activity(db.Model):
|
||||
|
@ -2,6 +2,7 @@ from fittrackee_api import appLog, db
|
||||
from flask import Blueprint, jsonify, request
|
||||
from sqlalchemy import exc
|
||||
|
||||
from ..users.models import User
|
||||
from ..users.utils import authenticate, authenticate_as_admin
|
||||
from .models import Sport
|
||||
|
||||
@ -23,6 +24,8 @@ def get_sports(auth_user_id):
|
||||
|
||||
**Example response**:
|
||||
|
||||
- for non admin user :
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
@ -32,42 +35,93 @@ def get_sports(auth_user_id):
|
||||
"data": {
|
||||
"sports": [
|
||||
{
|
||||
"_can_be_disabled": false,
|
||||
"id": 1,
|
||||
"img": "/img/sports/cycling-sport.png",
|
||||
"is_active": true,
|
||||
"label": "Cycling (Sport)"
|
||||
},
|
||||
{
|
||||
"_can_be_disabled": false,
|
||||
"id": 2,
|
||||
"img": "/img/sports/cycling-transport.png",
|
||||
"is_active": true,
|
||||
"label": "Cycling (Transport)"
|
||||
},
|
||||
{
|
||||
"_can_be_disabled": false,
|
||||
"id": 3,
|
||||
"img": "/img/sports/hiking.png",
|
||||
"is_active": true,
|
||||
"label": "Hiking"
|
||||
},
|
||||
{
|
||||
"_can_be_disabled": false,
|
||||
"id": 4,
|
||||
"img": "/img/sports/mountain-biking.png",
|
||||
"is_active": true,
|
||||
"label": "Mountain Biking"
|
||||
},
|
||||
{
|
||||
"_can_be_disabled": false,
|
||||
"id": 5,
|
||||
"img": "/img/sports/running.png",
|
||||
"is_active": true,
|
||||
"label": "Running"
|
||||
},
|
||||
{
|
||||
"_can_be_disabled": false,
|
||||
"id": 6,
|
||||
"img": "/img/sports/walking.png",
|
||||
"is_active": true,
|
||||
"label": "Walking"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": "success"
|
||||
}
|
||||
|
||||
- for admin user :
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"data": {
|
||||
"sports": [
|
||||
{
|
||||
"has_activities": true,
|
||||
"id": 1,
|
||||
"img": "/img/sports/cycling-sport.png",
|
||||
"is_active": true,
|
||||
"label": "Cycling (Sport)"
|
||||
},
|
||||
{
|
||||
"has_activities": false,
|
||||
"id": 2,
|
||||
"img": "/img/sports/cycling-transport.png",
|
||||
"is_active": true,
|
||||
"label": "Cycling (Transport)"
|
||||
},
|
||||
{
|
||||
"has_activities": false,
|
||||
"id": 3,
|
||||
"img": "/img/sports/hiking.png",
|
||||
"is_active": true,
|
||||
"label": "Hiking"
|
||||
},
|
||||
{
|
||||
"has_activities": false,
|
||||
"id": 4,
|
||||
"img": "/img/sports/mountain-biking.png",
|
||||
"is_active": true,
|
||||
"label": "Mountain Biking"
|
||||
},
|
||||
{
|
||||
"has_activities": false,
|
||||
"id": 5,
|
||||
"img": "/img/sports/running.png",
|
||||
"is_active": true,
|
||||
"label": "Running"
|
||||
},
|
||||
{
|
||||
"has_activities": false,
|
||||
"id": 6,
|
||||
"img": "/img/sports/walking.png",
|
||||
"is_active": true,
|
||||
@ -90,10 +144,11 @@ def get_sports(auth_user_id):
|
||||
|
||||
"""
|
||||
|
||||
user = User.query.filter_by(id=int(auth_user_id)).first()
|
||||
sports = Sport.query.order_by(Sport.id).all()
|
||||
response_object = {
|
||||
'status': 'success',
|
||||
'data': {'sports': [sport.serialize() for sport in sports]},
|
||||
'data': {'sports': [sport.serialize(user.admin) for sport in sports]},
|
||||
}
|
||||
return jsonify(response_object), 200
|
||||
|
||||
@ -101,7 +156,8 @@ def get_sports(auth_user_id):
|
||||
@sports_blueprint.route('/sports/<int:sport_id>', methods=['GET'])
|
||||
@authenticate
|
||||
def get_sport(auth_user_id, sport_id):
|
||||
"""Get a sport
|
||||
"""
|
||||
Get a sport
|
||||
|
||||
**Example request**:
|
||||
|
||||
@ -112,7 +168,7 @@ def get_sport(auth_user_id, sport_id):
|
||||
|
||||
**Example response**:
|
||||
|
||||
- success
|
||||
- success for non admin user :
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
@ -123,7 +179,28 @@ def get_sport(auth_user_id, sport_id):
|
||||
"data": {
|
||||
"sports": [
|
||||
{
|
||||
"_can_be_disabled": false,
|
||||
"id": 1,
|
||||
"img": "/img/sports/cycling-sport.png",
|
||||
"is_active": true,
|
||||
"label": "Cycling (Sport)"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": "success"
|
||||
}
|
||||
|
||||
- success for admin user :
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"data": {
|
||||
"sports": [
|
||||
{
|
||||
"has_activities": false,
|
||||
"id": 1,
|
||||
"img": "/img/sports/cycling-sport.png",
|
||||
"is_active": true,
|
||||
@ -162,11 +239,12 @@ def get_sport(auth_user_id, sport_id):
|
||||
|
||||
"""
|
||||
|
||||
user = User.query.filter_by(id=int(auth_user_id)).first()
|
||||
sport = Sport.query.filter_by(id=sport_id).first()
|
||||
if sport:
|
||||
response_object = {
|
||||
'status': 'success',
|
||||
'data': {'sports': [sport.serialize()]},
|
||||
'data': {'sports': [sport.serialize(user.admin)]},
|
||||
}
|
||||
code = 200
|
||||
else:
|
||||
@ -178,7 +256,9 @@ def get_sport(auth_user_id, sport_id):
|
||||
@sports_blueprint.route('/sports/<int:sport_id>', methods=['PATCH'])
|
||||
@authenticate_as_admin
|
||||
def update_sport(auth_user_id, sport_id):
|
||||
"""Update a sport
|
||||
"""
|
||||
Update a sport
|
||||
Authenticated user must be an admin
|
||||
|
||||
**Example request**:
|
||||
|
||||
@ -200,7 +280,7 @@ def update_sport(auth_user_id, sport_id):
|
||||
"data": {
|
||||
"sports": [
|
||||
{
|
||||
"_can_be_disabled": false,
|
||||
"has_activities": false,
|
||||
"id": 1,
|
||||
"img": "/img/sports/cycling-sport.png",
|
||||
"is_active": false,
|
||||
@ -238,6 +318,7 @@ def update_sport(auth_user_id, sport_id):
|
||||
- Provide a valid auth token.
|
||||
- Signature expired. Please log in again.
|
||||
- Invalid token. Please log in again.
|
||||
:statuscode 403: You do not have permissions.
|
||||
:statuscode 404: sport not found
|
||||
:statuscode 500:
|
||||
|
||||
@ -250,24 +331,13 @@ def update_sport(auth_user_id, sport_id):
|
||||
try:
|
||||
sport = Sport.query.filter_by(id=sport_id).first()
|
||||
if sport:
|
||||
if not (
|
||||
not sport_data.get('is_active')
|
||||
and sport.is_active
|
||||
and len(sport.activities) > 0
|
||||
):
|
||||
sport.is_active = sport_data.get('is_active')
|
||||
db.session.commit()
|
||||
response_object = {
|
||||
'status': 'success',
|
||||
'data': {'sports': [sport.serialize()]},
|
||||
}
|
||||
code = 200
|
||||
else:
|
||||
response_object = {
|
||||
'status': 'fail',
|
||||
'message': 'Sport can not be disabled, activities exist.',
|
||||
}
|
||||
code = 400
|
||||
sport.is_active = sport_data.get('is_active')
|
||||
db.session.commit()
|
||||
response_object = {
|
||||
'status': 'success',
|
||||
'data': {'sports': [sport.serialize(True)]},
|
||||
}
|
||||
code = 200
|
||||
else:
|
||||
response_object = {'status': 'not found', 'data': {'sports': []}}
|
||||
code = 404
|
||||
|
@ -107,6 +107,15 @@ def sport_1_cycling():
|
||||
return sport
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def sport_1_cycling_inactive():
|
||||
sport = Sport(label='Cycling')
|
||||
sport.is_active = False
|
||||
db.session.add(sport)
|
||||
db.session.commit()
|
||||
return sport
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def sport_2_running():
|
||||
sport = Sport(label='Running')
|
||||
|
@ -5,16 +5,29 @@ expected_sport_1_cycling_result = {
|
||||
'label': 'Cycling',
|
||||
'img': None,
|
||||
'is_active': True,
|
||||
'_can_be_disabled': True,
|
||||
}
|
||||
expected_sport_1_cycling_admin_result = expected_sport_1_cycling_result.copy()
|
||||
expected_sport_1_cycling_admin_result['has_activities'] = False
|
||||
|
||||
expected_sport_2_running_result = {
|
||||
'id': 2,
|
||||
'label': 'Running',
|
||||
'img': None,
|
||||
'is_active': True,
|
||||
'_can_be_disabled': True,
|
||||
}
|
||||
expected_sport_2_running_admin_result = expected_sport_2_running_result.copy()
|
||||
expected_sport_2_running_admin_result['has_activities'] = False
|
||||
|
||||
expected_sport_1_cycling_inactive_result = {
|
||||
'id': 1,
|
||||
'label': 'Cycling',
|
||||
'img': None,
|
||||
'is_active': False,
|
||||
}
|
||||
expected_sport_1_cycling_inactive_admin_result = (
|
||||
expected_sport_1_cycling_inactive_result.copy()
|
||||
)
|
||||
expected_sport_1_cycling_inactive_admin_result['has_activities'] = False
|
||||
|
||||
|
||||
def test_get_all_sports(app, user_1, sport_1_cycling, sport_2_running):
|
||||
@ -41,6 +54,63 @@ def test_get_all_sports(app, user_1, sport_1_cycling, sport_2_running):
|
||||
assert data['data']['sports'][1] == expected_sport_2_running_result
|
||||
|
||||
|
||||
def test_get_all_sports_with_inactive_one(
|
||||
app, user_1, sport_1_cycling_inactive, sport_2_running
|
||||
):
|
||||
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',
|
||||
)
|
||||
response = client.get(
|
||||
'/api/sports',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
|
||||
assert len(data['data']['sports']) == 2
|
||||
assert (
|
||||
data['data']['sports'][0] == expected_sport_1_cycling_inactive_result
|
||||
)
|
||||
assert data['data']['sports'][1] == expected_sport_2_running_result
|
||||
|
||||
|
||||
def test_get_all_sports_admin(
|
||||
app, user_1_admin, sport_1_cycling_inactive, sport_2_running
|
||||
):
|
||||
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',
|
||||
)
|
||||
response = client.get(
|
||||
'/api/sports',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
|
||||
assert len(data['data']['sports']) == 2
|
||||
assert (
|
||||
data['data']['sports'][0]
|
||||
== expected_sport_1_cycling_inactive_admin_result
|
||||
)
|
||||
assert data['data']['sports'][1] == expected_sport_2_running_admin_result
|
||||
|
||||
|
||||
def test_get_a_sport(app, user_1, sport_1_cycling):
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
@ -85,6 +155,59 @@ def test_get_a_sport_invalid(app, user_1):
|
||||
assert len(data['data']['sports']) == 0
|
||||
|
||||
|
||||
def test_get_a_inactive_sport(app, user_1, sport_1_cycling_inactive):
|
||||
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',
|
||||
)
|
||||
response = client.get(
|
||||
'/api/sports/1',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
)
|
||||
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] == expected_sport_1_cycling_inactive_result
|
||||
)
|
||||
|
||||
|
||||
def test_get_a_inactive_sport_as_admin(
|
||||
app, user_1_admin, sport_1_cycling_inactive
|
||||
):
|
||||
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',
|
||||
)
|
||||
response = client.get(
|
||||
'/api/sports/1',
|
||||
headers=dict(
|
||||
Authorization='Bearer '
|
||||
+ json.loads(resp_login.data.decode())['auth_token']
|
||||
),
|
||||
)
|
||||
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]
|
||||
== expected_sport_1_cycling_inactive_admin_result
|
||||
)
|
||||
|
||||
|
||||
def test_update_a_sport(app, user_1_admin, sport_1_cycling):
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
@ -108,6 +231,7 @@ def test_update_a_sport(app, user_1_admin, sport_1_cycling):
|
||||
|
||||
assert len(data['data']['sports']) == 1
|
||||
assert data['data']['sports'][0]['is_active'] is False
|
||||
assert data['data']['sports'][0]['has_activities'] is False
|
||||
|
||||
response = client.patch(
|
||||
'/api/sports/1',
|
||||
@ -125,9 +249,10 @@ def test_update_a_sport(app, user_1_admin, sport_1_cycling):
|
||||
|
||||
assert len(data['data']['sports']) == 1
|
||||
assert data['data']['sports'][0]['is_active'] is True
|
||||
assert data['data']['sports'][0]['has_activities'] is False
|
||||
|
||||
|
||||
def test_disable_a_sport_with_activities(
|
||||
def test_update_a_sport_with_activities(
|
||||
app, user_1_admin, sport_1_cycling, activity_cycling_user_1
|
||||
):
|
||||
client = app.test_client()
|
||||
@ -147,9 +272,30 @@ def test_disable_a_sport_with_activities(
|
||||
)
|
||||
data = json.loads(response.data.decode())
|
||||
|
||||
assert response.status_code == 400
|
||||
assert 'fail' in data['status']
|
||||
assert 'Sport can not be disabled, activities exist.' in data['message']
|
||||
assert response.status_code == 200
|
||||
assert 'success' in data['status']
|
||||
|
||||
assert len(data['data']['sports']) == 1
|
||||
assert data['data']['sports'][0]['is_active'] is False
|
||||
assert data['data']['sports'][0]['has_activities'] is 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']
|
||||
),
|
||||
)
|
||||
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]['is_active'] is True
|
||||
assert data['data']['sports'][0]['has_activities'] is True
|
||||
|
||||
|
||||
def test_update_a_sport_not_admin(app, user_1, sport_1_cycling):
|
||||
|
@ -1,24 +1,29 @@
|
||||
def test_sport_model(app, sport_1_cycling):
|
||||
assert 1 == sport_1_cycling.id
|
||||
assert 'Cycling' == sport_1_cycling.label
|
||||
assert '<Sport \'Cycling\'>' == str(sport_1_cycling)
|
||||
def assert_sport_model(sport, is_admin=False):
|
||||
assert 1 == sport.id
|
||||
assert 'Cycling' == sport.label
|
||||
assert '<Sport \'Cycling\'>' == str(sport)
|
||||
|
||||
serialized_sport = sport_1_cycling.serialize()
|
||||
serialized_sport = sport.serialize(is_admin)
|
||||
assert 1 == serialized_sport['id']
|
||||
assert 'Cycling' == serialized_sport['label']
|
||||
assert serialized_sport['is_active'] is True
|
||||
assert serialized_sport['_can_be_disabled'] is True
|
||||
return serialized_sport
|
||||
|
||||
|
||||
def test_sport_model(app, sport_1_cycling):
|
||||
serialized_sport = assert_sport_model(sport_1_cycling)
|
||||
assert 'has_activities' not in serialized_sport
|
||||
|
||||
|
||||
def test_sport_model_with_activity(
|
||||
app, sport_1_cycling, user_1, activity_cycling_user_1
|
||||
):
|
||||
assert 1 == sport_1_cycling.id
|
||||
assert 'Cycling' == sport_1_cycling.label
|
||||
assert '<Sport \'Cycling\'>' == str(sport_1_cycling)
|
||||
serialized_sport = assert_sport_model(sport_1_cycling)
|
||||
assert 'has_activities' not in serialized_sport
|
||||
|
||||
serialized_sport = sport_1_cycling.serialize()
|
||||
assert 1 == serialized_sport['id']
|
||||
assert 'Cycling' == serialized_sport['label']
|
||||
assert serialized_sport['is_active'] is True
|
||||
assert serialized_sport['_can_be_disabled'] is False
|
||||
|
||||
def test_sport_model_with_activity_admin(
|
||||
app, sport_1_cycling, user_1, activity_cycling_user_1
|
||||
):
|
||||
serialized_sport = assert_sport_model(sport_1_cycling, True)
|
||||
assert serialized_sport['has_activities'] is True
|
||||
|
@ -11,7 +11,7 @@ import { translateSports } from '../../../utils/activities'
|
||||
function FormWithGpx(props) {
|
||||
const { activity, loading, onAddActivity, onEditActivity, sports, t } = props
|
||||
const sportId = activity ? activity.sport_id : ''
|
||||
const translatedSports = translateSports(sports, t)
|
||||
const translatedSports = translateSports(sports, t, true)
|
||||
// prettier-ignore
|
||||
const zipTooltip =
|
||||
`${t('activities:no folder inside')}, ${gpxLimit} ${
|
||||
|
@ -10,7 +10,7 @@ import { formatActivityDate, translateSports } from '../../../utils/activities'
|
||||
|
||||
function FormWithoutGpx(props) {
|
||||
const { activity, onAddOrEdit, sports, t } = props
|
||||
const translatedSports = translateSports(sports, t)
|
||||
const translatedSports = translateSports(sports, t, true)
|
||||
let activityDate,
|
||||
activityTime,
|
||||
sportId = ''
|
||||
|
@ -62,23 +62,26 @@ class AdminSports extends React.Component {
|
||||
)}
|
||||
</td>
|
||||
<td>
|
||||
{sport._can_be_disabled ? (
|
||||
<input
|
||||
type="submit"
|
||||
className={`btn btn-${
|
||||
sport.is_active ? 'dark' : 'primary'
|
||||
} btn-sm`}
|
||||
value={
|
||||
sport.is_active
|
||||
? t('administration:Disable')
|
||||
: t('administration:Enable')
|
||||
}
|
||||
onClick={() =>
|
||||
updateSport(sport.id, !sport.is_active)
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<input
|
||||
type="submit"
|
||||
className={`btn btn-${
|
||||
sport.is_active ? 'dark' : 'primary'
|
||||
} btn-sm`}
|
||||
value={
|
||||
sport.is_active
|
||||
? t('administration:Disable')
|
||||
: t('administration:Enable')
|
||||
}
|
||||
onClick={() =>
|
||||
updateSport(sport.id, !sport.is_active)
|
||||
}
|
||||
/>
|
||||
{sport.has_activities && (
|
||||
<span className="admin-message">
|
||||
<i
|
||||
className="fa fa-warning custom-fa"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
{t('administration:activities exist')}
|
||||
</span>
|
||||
)}
|
||||
|
@ -167,13 +167,14 @@ label {
|
||||
}
|
||||
|
||||
.admin-items {
|
||||
list-style-type: square;
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
.admin-message {
|
||||
color: #7c7c7d;
|
||||
font-size: 0.9em;
|
||||
font-style: italic;
|
||||
font-size: 0.9em;
|
||||
font-style: italic;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.card {
|
||||
|
@ -64,18 +64,6 @@ class NavBar extends React.PureComponent {
|
||||
</Link>
|
||||
</li>
|
||||
)}
|
||||
{isAuthenticated && (
|
||||
<li className="nav-item">
|
||||
<Link
|
||||
className="nav-link"
|
||||
to={{
|
||||
pathname: '/activities/add',
|
||||
}}
|
||||
>
|
||||
<strong>{t('common:Add workout')}</strong>
|
||||
</Link>
|
||||
</li>
|
||||
)}
|
||||
{admin && (
|
||||
<li className="nav-item">
|
||||
<Link
|
||||
@ -88,6 +76,18 @@ class NavBar extends React.PureComponent {
|
||||
</Link>
|
||||
</li>
|
||||
)}
|
||||
{isAuthenticated && (
|
||||
<li className="nav-item">
|
||||
<Link
|
||||
className="nav-link"
|
||||
to={{
|
||||
pathname: '/activities/add',
|
||||
}}
|
||||
>
|
||||
<strong>{t('common:Add workout')}</strong>
|
||||
</Link>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
{/* prettier-ignore */}
|
||||
<ul
|
||||
|
@ -93,8 +93,9 @@ const sortSports = (a, b) => {
|
||||
return sportALabel > sportBLabel ? 1 : sportALabel < sportBLabel ? -1 : 0
|
||||
}
|
||||
|
||||
export const translateSports = (sports, t) =>
|
||||
export const translateSports = (sports, t, onlyActive = false) =>
|
||||
sports
|
||||
.filter(sport => (onlyActive ? sport.is_active : true))
|
||||
.map(sport => ({
|
||||
...sport,
|
||||
label: t(`sports:${sport.label}`),
|
||||
|
Loading…
Reference in New Issue
Block a user