API - add route to get application statistics
This commit is contained in:
		@@ -1,10 +1,11 @@
 | 
			
		||||
from datetime import datetime, timedelta
 | 
			
		||||
 | 
			
		||||
from fittrackee_api import appLog
 | 
			
		||||
from fittrackee_api import appLog, db
 | 
			
		||||
from flask import Blueprint, jsonify, request
 | 
			
		||||
from sqlalchemy import func
 | 
			
		||||
 | 
			
		||||
from ..users.models import User
 | 
			
		||||
from ..users.utils import authenticate
 | 
			
		||||
from ..users.utils import authenticate, authenticate_as_admin
 | 
			
		||||
from .models import Activity, Sport
 | 
			
		||||
from .utils import get_datetime_with_tz
 | 
			
		||||
from .utils_format import convert_timedelta_to_integer
 | 
			
		||||
@@ -319,3 +320,62 @@ def get_activities_by_sport(auth_user_id, user_id):
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    return get_activities(user_id, 'by_sport')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@stats_blueprint.route('/stats/all', methods=['GET'])
 | 
			
		||||
@authenticate_as_admin
 | 
			
		||||
def get_application_stats(auth_user_id):
 | 
			
		||||
    """
 | 
			
		||||
    Get all application statistics
 | 
			
		||||
 | 
			
		||||
    **Example requests**:
 | 
			
		||||
 | 
			
		||||
    .. sourcecode:: http
 | 
			
		||||
 | 
			
		||||
      GET /api/stats/all HTTP/1.1
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    **Example responses**:
 | 
			
		||||
 | 
			
		||||
    .. sourcecode:: http
 | 
			
		||||
 | 
			
		||||
      HTTP/1.1 200 OK
 | 
			
		||||
      Content-Type: application/json
 | 
			
		||||
 | 
			
		||||
      {
 | 
			
		||||
        "data": {
 | 
			
		||||
          "activities": 3,
 | 
			
		||||
          "sports": 3,
 | 
			
		||||
          "users": 2
 | 
			
		||||
        },
 | 
			
		||||
        "status": "success"
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    :param integer auth_user_id: authenticate user id (from JSON Web Token)
 | 
			
		||||
 | 
			
		||||
    :reqheader Authorization: OAuth 2.0 Bearer Token
 | 
			
		||||
 | 
			
		||||
    :statuscode 200: success
 | 
			
		||||
    :statuscode 401:
 | 
			
		||||
        - Provide a valid auth token.
 | 
			
		||||
        - Signature expired. Please log in again.
 | 
			
		||||
        - Invalid token. Please log in again.
 | 
			
		||||
    :statuscode 403: You do not have permissions.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    nb_activities = Activity.query.filter().count()
 | 
			
		||||
    nb_users = User.query.filter().count()
 | 
			
		||||
    nb_sports = (
 | 
			
		||||
        db.session.query(func.count(Activity.sport_id))
 | 
			
		||||
        .group_by(Activity.sport_id)
 | 
			
		||||
        .count()
 | 
			
		||||
    )
 | 
			
		||||
    response_object = {
 | 
			
		||||
        'status': 'success',
 | 
			
		||||
        'data': {
 | 
			
		||||
            'activities': nb_activities,
 | 
			
		||||
            'sports': nb_sports,
 | 
			
		||||
            'users': nb_users,
 | 
			
		||||
        },
 | 
			
		||||
    }
 | 
			
		||||
    return jsonify(response_object), 200
 | 
			
		||||
 
 | 
			
		||||
@@ -947,3 +947,87 @@ def test_get_stats_by_sport_all_activities_error(
 | 
			
		||||
        'Error. Please try again or contact the administrator.'
 | 
			
		||||
        in data['message']
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_app_stats_without_activities(app, user_1_admin):
 | 
			
		||||
    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/stats/all',
 | 
			
		||||
        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 data['data'] == {'activities': 0, 'sports': 0, 'users': 1}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_app_stats_with_activities(
 | 
			
		||||
    app,
 | 
			
		||||
    user_1_admin,
 | 
			
		||||
    user_2,
 | 
			
		||||
    user_3,
 | 
			
		||||
    sport_1_cycling,
 | 
			
		||||
    sport_2_running,
 | 
			
		||||
    activity_cycling_user_1,
 | 
			
		||||
    activity_cycling_user_2,
 | 
			
		||||
    activity_running_user_1,
 | 
			
		||||
):
 | 
			
		||||
    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/stats/all',
 | 
			
		||||
        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 data['data'] == {'activities': 3, 'sports': 2, 'users': 3}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_app_stats_no_admin(
 | 
			
		||||
    app,
 | 
			
		||||
    user_1,
 | 
			
		||||
    user_2,
 | 
			
		||||
    user_3,
 | 
			
		||||
    sport_1_cycling,
 | 
			
		||||
    sport_2_running,
 | 
			
		||||
    activity_cycling_user_1,
 | 
			
		||||
    activity_cycling_user_2,
 | 
			
		||||
    activity_running_user_1,
 | 
			
		||||
):
 | 
			
		||||
    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/stats/all',
 | 
			
		||||
        headers=dict(
 | 
			
		||||
            Authorization='Bearer '
 | 
			
		||||
            + json.loads(resp_login.data.decode())['auth_token']
 | 
			
		||||
        ),
 | 
			
		||||
    )
 | 
			
		||||
    data = json.loads(response.data.decode())
 | 
			
		||||
 | 
			
		||||
    assert response.status_code == 403
 | 
			
		||||
    assert 'success' not in data['status']
 | 
			
		||||
    assert 'error' in data['status']
 | 
			
		||||
    assert 'You do not have permissions.' in data['message']
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user