Skip to content

Commit

Permalink
API & Client - add analysis visibility level
Browse files Browse the repository at this point in the history
  • Loading branch information
SamR1 committed Dec 23, 2024
1 parent 6c26e46 commit 33f4fc2
Show file tree
Hide file tree
Showing 29 changed files with 1,433 additions and 281 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""add analysis visibility level
Revision ID: 8a80bec0a410
Revises: 70f12f8c0218
Create Date: 2024-12-23 10:16:23.026455
"""

import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql


# revision identifiers, used by Alembic.
revision = '8a80bec0a410'
down_revision = '70f12f8c0218'
branch_labels = None
depends_on = None

visibility_levels = postgresql.ENUM(
'PUBLIC',
'FOLLOWERS_AND_REMOTE', # for a next version, not used for now
'FOLLOWERS',
'PRIVATE',
name='visibility_levels',
)


def upgrade():
visibility_levels.create(op.get_bind())
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.add_column(
sa.Column(
'analysis_visibility',
visibility_levels,
server_default='PRIVATE',
nullable=True,
)
)
op.execute("UPDATE users SET analysis_visibility = 'PRIVATE';")
op.alter_column('users', 'analysis_visibility', nullable=False)

with op.batch_alter_table('workouts', schema=None) as batch_op:
batch_op.add_column(
sa.Column(
'analysis_visibility',
visibility_levels,
server_default='PRIVATE',
nullable=True,
)
)
op.execute("UPDATE workouts SET analysis_visibility = 'PRIVATE';")
op.alter_column('workouts', 'analysis_visibility', nullable=False)


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('workouts', schema=None) as batch_op:
batch_op.drop_column('analysis_visibility')

with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.drop_column('analysis_visibility')

# ### end Alembic commands ###
44 changes: 28 additions & 16 deletions fittrackee/tests/test_visibility_levels.py
Original file line number Diff line number Diff line change
@@ -1,57 +1,69 @@
import pytest

from fittrackee.visibility_levels import VisibilityLevel, get_map_visibility
from fittrackee.visibility_levels import (
VisibilityLevel,
get_calculated_visibility,
)


class TestMapVisibility:
@pytest.mark.parametrize(
'input_map_visibility',
'input_visibility',
[
VisibilityLevel.PUBLIC,
VisibilityLevel.FOLLOWERS,
VisibilityLevel.PRIVATE,
],
)
def test_it_returns_map_visibility_when_workout_visibility_is_public(
def test_it_returns_visibility_when_parent_visibility_is_public(
self,
input_map_visibility: VisibilityLevel,
input_visibility: VisibilityLevel,
) -> None:
assert (
get_map_visibility(input_map_visibility, VisibilityLevel.PUBLIC)
== input_map_visibility
get_calculated_visibility(
visibility=input_visibility,
parent_visibility=VisibilityLevel.PUBLIC,
)
== input_visibility
)

@pytest.mark.parametrize(
'input_map_visibility, expected_map_visibility',
'input_visibility, expected_visibility',
[
(VisibilityLevel.PUBLIC, VisibilityLevel.FOLLOWERS),
(VisibilityLevel.FOLLOWERS, VisibilityLevel.FOLLOWERS),
(VisibilityLevel.PRIVATE, VisibilityLevel.PRIVATE),
],
)
def test_it_returns_map_visibility_when_workout_visibility_is_followers_only( # noqa
def test_it_returns_map_visibility_when_analysis_visibility_is_followers_only( # noqa
self,
input_map_visibility: VisibilityLevel,
expected_map_visibility: VisibilityLevel,
input_visibility: VisibilityLevel,
expected_visibility: VisibilityLevel,
) -> None:
assert (
get_map_visibility(input_map_visibility, VisibilityLevel.FOLLOWERS)
== expected_map_visibility
get_calculated_visibility(
visibility=input_visibility,
parent_visibility=VisibilityLevel.FOLLOWERS,
)
== expected_visibility
)

@pytest.mark.parametrize(
'input_map_visibility',
'input_visibility',
[
VisibilityLevel.PUBLIC,
VisibilityLevel.FOLLOWERS,
VisibilityLevel.PRIVATE,
],
)
def test_it_returns_map_visibility_when_workout_visibility_is_private(
def test_it_returns_visibility_when_parent_visibility_is_private(
self,
input_map_visibility: VisibilityLevel,
input_visibility: VisibilityLevel,
) -> None:
assert (
get_map_visibility(input_map_visibility, VisibilityLevel.PRIVATE)
get_calculated_visibility(
visibility=input_visibility,
parent_visibility=VisibilityLevel.PRIVATE,
)
== VisibilityLevel.PRIVATE
)
53 changes: 46 additions & 7 deletions fittrackee/tests/users/test_auth_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1598,7 +1598,8 @@ def test_it_updates_user_preferences(
use_dark_mode=True,
use_raw_gpx_speed=True,
date_format='yyyy-MM-dd',
map_visibility='followers_only',
map_visibility='private',
analysis_visibility='followers_only',
workouts_visibility='public',
manually_approves_followers=False,
hide_profile_in_users_directory=False,
Expand All @@ -1624,18 +1625,47 @@ def test_it_updates_user_preferences(
assert data['data']['hide_profile_in_users_directory'] is False

@pytest.mark.parametrize(
'input_map_visibility,input_workout_visibility',
'input_map_visibility,input_analysis_visibility,input_workout_visibility,expected_map_visibility,expected_analysis_visibility',
[
(VisibilityLevel.FOLLOWERS, VisibilityLevel.PRIVATE),
(VisibilityLevel.PUBLIC, VisibilityLevel.FOLLOWERS),
(
VisibilityLevel.FOLLOWERS,
VisibilityLevel.PRIVATE,
VisibilityLevel.PRIVATE,
VisibilityLevel.PRIVATE,
VisibilityLevel.PRIVATE,
),
(
VisibilityLevel.FOLLOWERS,
VisibilityLevel.PRIVATE,
VisibilityLevel.PRIVATE,
VisibilityLevel.PRIVATE,
VisibilityLevel.PRIVATE,
),
(
VisibilityLevel.PRIVATE,
VisibilityLevel.FOLLOWERS,
VisibilityLevel.PUBLIC,
VisibilityLevel.PRIVATE,
VisibilityLevel.FOLLOWERS,
),
(
VisibilityLevel.PUBLIC,
VisibilityLevel.PUBLIC,
VisibilityLevel.PUBLIC,
VisibilityLevel.PUBLIC,
VisibilityLevel.PUBLIC,
),
],
)
def test_it_updates_user_preferences_with_valid_map_visibility(
self,
app: Flask,
user_1: User,
input_map_visibility: VisibilityLevel,
input_analysis_visibility: VisibilityLevel,
input_workout_visibility: VisibilityLevel,
expected_map_visibility: VisibilityLevel,
expected_analysis_visibility: VisibilityLevel,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
Expand All @@ -1652,21 +1682,26 @@ def test_it_updates_user_preferences_with_valid_map_visibility(
imperial_units=True,
display_ascent=True,
date_format='MM/dd/yyyy',
map_visibility=input_map_visibility.value,
start_elevation_at_zero=False,
use_raw_gpx_speed=False,
workouts_visibility=input_workout_visibility.value,
manually_approves_followers=True,
hide_profile_in_users_directory=True,
use_dark_mode=None,
map_visibility=input_map_visibility.value,
analysis_visibility=input_analysis_visibility.value,
workouts_visibility=input_workout_visibility.value,
)
),
headers=dict(Authorization=f'Bearer {auth_token}'),
)

assert response.status_code == 200
data = json.loads(response.data.decode())
assert data['data']['map_visibility'] == input_workout_visibility.value
assert data['data']['map_visibility'] == expected_map_visibility.value
assert (
data['data']['analysis_visibility']
== expected_analysis_visibility.value
)
assert (
data['data']['workouts_visibility']
== input_workout_visibility.value
Expand All @@ -1686,6 +1721,7 @@ def test_it_updates_user_preferences_when_user_is_suspended(
content_type='application/json',
data=json.dumps(
dict(
analysis_visibility=VisibilityLevel.PUBLIC.value,
timezone='America/New_York',
weekm=True,
language='fr',
Expand All @@ -1707,6 +1743,9 @@ def test_it_updates_user_preferences_when_user_is_suspended(
assert response.status_code == 200
data = json.loads(response.data.decode())
assert data['data']['map_visibility'] == VisibilityLevel.PUBLIC.value
assert (
data['data']['analysis_visibility'] == VisibilityLevel.PUBLIC.value
)
assert (
data['data']['workouts_visibility'] == VisibilityLevel.PUBLIC.value
)
Expand Down
6 changes: 6 additions & 0 deletions fittrackee/tests/users/test_users_export_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ def test_it_returns_data_for_workout_without_gpx(
'description': None,
'liked': workout_cycling_user_1.liked_by(user_1),
'likes_count': workout_cycling_user_1.likes.count(),
'analysis_visibility': (
workout_cycling_user_1.calculated_analysis_visibility.value
),
'map_visibility': (
workout_cycling_user_1.calculated_map_visibility.value
),
Expand Down Expand Up @@ -140,6 +143,9 @@ def test_it_returns_data_for_workout_with_gpx(
'description': None,
'liked': workout.liked_by(user_1),
'likes_count': workout.likes.count(),
'analysis_visibility': (
workout.calculated_analysis_visibility.value
),
'map_visibility': workout.calculated_map_visibility.value,
'workout_visibility': workout.workout_visibility.value,
}
Expand Down
7 changes: 7 additions & 0 deletions fittrackee/tests/users/test_users_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ def test_it_returns_user_preferences(
serialized_user['workouts_visibility']
== user_1.workouts_visibility
)
assert (
serialized_user['analysis_visibility']
== user_1.analysis_visibility
)
assert serialized_user['map_visibility'] == user_1.map_visibility
assert (
serialized_user['manually_approves_followers']
Expand Down Expand Up @@ -299,6 +303,7 @@ def test_it_does_return_user_preferences(
assert 'use_raw_gpx_speed' not in serialized_user
assert 'use_dark_mode' not in serialized_user
assert 'workouts_visibility' not in serialized_user
assert 'analysis_visibility' not in serialized_user
assert 'map_visibility' not in serialized_user
assert 'manually_approves_followers' not in serialized_user
assert 'hide_profile_in_users_directory' not in serialized_user
Expand Down Expand Up @@ -383,6 +388,7 @@ def test_it_does_return_user_preferences(
assert 'use_raw_gpx_speed' not in serialized_user
assert 'use_dark_mode' not in serialized_user
assert 'workouts_visibility' not in serialized_user
assert 'analysis_visibility' not in serialized_user
assert 'map_visibility' not in serialized_user
assert 'manually_approves_followers' not in serialized_user
assert 'hide_profile_in_users_directory' not in serialized_user
Expand Down Expand Up @@ -460,6 +466,7 @@ def test_it_does_return_user_preferences(
assert 'timezone' not in serialized_user
assert 'weekm' not in serialized_user
assert 'workouts_visibility' not in serialized_user
assert 'analysis_visibility' not in serialized_user
assert 'map_visibility' not in serialized_user
assert 'manually_approves_followers' not in serialized_user
assert 'hide_profile_in_users_directory' not in serialized_user
Expand Down
1 change: 1 addition & 0 deletions fittrackee/tests/workouts/test_timeline_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ def test_it_returns_followed_user_workout_map_when_visibility_allows_it(
) -> None:
user_2.approves_follow_request_from(user_1)
workout_cycling_user_2.workout_visibility = input_visibility
workout_cycling_user_2.analysis_visibility = input_visibility
workout_cycling_user_2.map_visibility = input_visibility
map_id = self.random_string()
workout_cycling_user_2.map_id = map_id
Expand Down
Loading

0 comments on commit 33f4fc2

Please sign in to comment.