API - store export request in database
This commit is contained in:
		@@ -29,11 +29,30 @@ def upgrade():
 | 
			
		||||
               existing_type=sa.VARCHAR(length=50),
 | 
			
		||||
               nullable=True)
 | 
			
		||||
 | 
			
		||||
    op.create_table('users_data_export',
 | 
			
		||||
    sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
 | 
			
		||||
    sa.Column('user_id', sa.Integer(), nullable=True),
 | 
			
		||||
    sa.Column('created_at', sa.DateTime(), nullable=False),
 | 
			
		||||
    sa.Column('updated_at', sa.DateTime(), nullable=True),
 | 
			
		||||
    sa.Column('completed', sa.Boolean(), nullable=False),
 | 
			
		||||
    sa.Column('file_name', sa.String(length=100), nullable=True),
 | 
			
		||||
    sa.Column('file_size', sa.Integer(), nullable=True),
 | 
			
		||||
    sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
 | 
			
		||||
    sa.PrimaryKeyConstraint('id')
 | 
			
		||||
    )
 | 
			
		||||
    with op.batch_alter_table('users_data_export', schema=None) as batch_op:
 | 
			
		||||
        batch_op.create_index(batch_op.f('ix_users_data_export_user_id'), ['user_id'], unique=True)
 | 
			
		||||
 | 
			
		||||
    # ### end Alembic commands ###
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def downgrade():
 | 
			
		||||
    # ### commands auto generated by Alembic - please adjust! ###
 | 
			
		||||
    with op.batch_alter_table('users_data_export', schema=None) as batch_op:
 | 
			
		||||
        batch_op.drop_index(batch_op.f('ix_users_data_export_user_id'))
 | 
			
		||||
 | 
			
		||||
    op.drop_table('users_data_export')
 | 
			
		||||
 | 
			
		||||
    with op.batch_alter_table('users', schema=None) as batch_op:
 | 
			
		||||
        batch_op.alter_column('date_format',
 | 
			
		||||
               existing_type=sa.VARCHAR(length=50),
 | 
			
		||||
 
 | 
			
		||||
@@ -6,9 +6,14 @@ from flask import Flask
 | 
			
		||||
from freezegun import freeze_time
 | 
			
		||||
 | 
			
		||||
from fittrackee import db
 | 
			
		||||
from fittrackee.tests.utils import random_string
 | 
			
		||||
from fittrackee.tests.utils import random_int, random_string
 | 
			
		||||
from fittrackee.users.exceptions import UserNotFoundException
 | 
			
		||||
from fittrackee.users.models import BlacklistedToken, User, UserSportPreference
 | 
			
		||||
from fittrackee.users.models import (
 | 
			
		||||
    BlacklistedToken,
 | 
			
		||||
    User,
 | 
			
		||||
    UserDataExport,
 | 
			
		||||
    UserSportPreference,
 | 
			
		||||
)
 | 
			
		||||
from fittrackee.workouts.models import Sport, Workout
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -381,3 +386,44 @@ class TestUserSportModel:
 | 
			
		||||
        assert serialized_user_sport['color'] is None
 | 
			
		||||
        assert serialized_user_sport['is_active']
 | 
			
		||||
        assert serialized_user_sport['stopped_speed_threshold'] == 1
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestUserDataExportSerializer:
 | 
			
		||||
    def test_it_returns_ongoing_export(self, app: Flask, user_1: User) -> None:
 | 
			
		||||
        created_at = datetime.utcnow()
 | 
			
		||||
        data_export = UserDataExport(user_id=user_1.id, created_at=created_at)
 | 
			
		||||
 | 
			
		||||
        serialized_data_export = data_export.serialize()
 | 
			
		||||
 | 
			
		||||
        assert serialized_data_export["created_at"] == created_at
 | 
			
		||||
        assert serialized_data_export["status"] == "in_progress"
 | 
			
		||||
        assert serialized_data_export["file_name"] is None
 | 
			
		||||
        assert serialized_data_export["file_size"] is None
 | 
			
		||||
 | 
			
		||||
    def test_it_returns_successful_export(
 | 
			
		||||
        self, app: Flask, user_1: User
 | 
			
		||||
    ) -> None:
 | 
			
		||||
        created_at = datetime.utcnow()
 | 
			
		||||
        data_export = UserDataExport(user_id=user_1.id, created_at=created_at)
 | 
			
		||||
        data_export.completed = True
 | 
			
		||||
        data_export.file_name = random_string()
 | 
			
		||||
        data_export.file_size = random_int()
 | 
			
		||||
 | 
			
		||||
        serialized_data_export = data_export.serialize()
 | 
			
		||||
 | 
			
		||||
        assert serialized_data_export["created_at"] == created_at
 | 
			
		||||
        assert serialized_data_export["status"] == "successful"
 | 
			
		||||
        assert serialized_data_export["file_name"] == data_export.file_name
 | 
			
		||||
        assert serialized_data_export["file_size"] == data_export.file_size
 | 
			
		||||
 | 
			
		||||
    def test_it_returns_errored_export(self, app: Flask, user_1: User) -> None:
 | 
			
		||||
        created_at = datetime.utcnow()
 | 
			
		||||
        data_export = UserDataExport(user_id=user_1.id, created_at=created_at)
 | 
			
		||||
        data_export.completed = True
 | 
			
		||||
 | 
			
		||||
        serialized_data_export = data_export.serialize()
 | 
			
		||||
 | 
			
		||||
        assert serialized_data_export["created_at"] == created_at
 | 
			
		||||
        assert serialized_data_export["status"] == "errored"
 | 
			
		||||
        assert serialized_data_export["file_name"] is None
 | 
			
		||||
        assert serialized_data_export["file_size"] is None
 | 
			
		||||
 
 | 
			
		||||
@@ -276,3 +276,46 @@ class BlacklistedToken(BaseModel):
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def check(cls, auth_token: str) -> bool:
 | 
			
		||||
        return cls.query.filter_by(token=str(auth_token)).first() is not None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserDataExport(BaseModel):
 | 
			
		||||
    __tablename__ = 'users_data_export'
 | 
			
		||||
 | 
			
		||||
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
 | 
			
		||||
    user_id = db.Column(
 | 
			
		||||
        db.Integer,
 | 
			
		||||
        db.ForeignKey('users.id'),
 | 
			
		||||
        index=True,
 | 
			
		||||
        unique=True,
 | 
			
		||||
    )
 | 
			
		||||
    created_at = db.Column(
 | 
			
		||||
        db.DateTime, nullable=False, default=datetime.utcnow
 | 
			
		||||
    )
 | 
			
		||||
    updated_at = db.Column(
 | 
			
		||||
        db.DateTime, nullable=True, onupdate=datetime.utcnow
 | 
			
		||||
    )
 | 
			
		||||
    completed = db.Column(db.Boolean, nullable=False, default=False)
 | 
			
		||||
    file_name = db.Column(db.String(100), nullable=True)
 | 
			
		||||
    file_size = db.Column(db.Integer, nullable=True)
 | 
			
		||||
 | 
			
		||||
    def __init__(
 | 
			
		||||
        self,
 | 
			
		||||
        user_id: int,
 | 
			
		||||
        created_at: Optional[datetime] = None,
 | 
			
		||||
    ):
 | 
			
		||||
        self.user_id = user_id
 | 
			
		||||
        self.created_at = (
 | 
			
		||||
            datetime.utcnow() if created_at is None else created_at
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def serialize(self) -> Dict:
 | 
			
		||||
        if self.completed:
 | 
			
		||||
            status = "successful" if self.file_name else "errored"
 | 
			
		||||
        else:
 | 
			
		||||
            status = "in_progress"
 | 
			
		||||
        return {
 | 
			
		||||
            "created_at": self.created_at,
 | 
			
		||||
            "status": status,
 | 
			
		||||
            "file_name": self.file_name if status == "successful" else None,
 | 
			
		||||
            "file_size": self.file_size if status == "successful" else None,
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user