Skip to content

Commit

Permalink
Update user listen history query to use new indexed table (#2185)
Browse files Browse the repository at this point in the history
* Update user listen history query to use new indexed table

* remove unnecessary args

* revert add users to tracks

* clean up integration test

* Add arg details

* add extra user id back

* sort imports

* sort test imports
  • Loading branch information
isaacsolo committed Jan 21, 2022
1 parent 72aa1b3 commit f13f1dd
Show file tree
Hide file tree
Showing 6 changed files with 298 additions and 197 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
from datetime import datetime, timedelta

from integration_tests.utils import populate_mock_db
from src.queries import response_name_constants
from src.queries.get_user_listening_history import (
GetUserListeningHistoryArgs,
_get_user_listening_history,
)
from src.tasks.user_listening_history.index_user_listening_history import (
_index_user_listening_history,
)
from src.utils.db_session import get_db

TIMESTAMP = datetime(2011, 1, 1)

test_entities = {
"plays": [
{"user_id": 1, "item_id": 1, "created_at": TIMESTAMP + timedelta(minutes=1)},
{"user_id": 1, "item_id": 2, "created_at": TIMESTAMP + timedelta(minutes=3)},
{
"user_id": 1,
"item_id": 1,
"created_at": TIMESTAMP + timedelta(minutes=2),
}, # duplicate play
{"user_id": 1, "item_id": 3, "created_at": TIMESTAMP + timedelta(minutes=4)},
{"user_id": 2, "item_id": 2, "created_at": TIMESTAMP},
],
"tracks": [
{"track_id": 1, "title": "track 1", "owner_id": 1, "is_delete": True},
{"track_id": 2, "title": "track 2", "owner_id": 2},
{"track_id": 3, "title": "track 3", "owner_id": 3},
],
"users": [
{"user_id": 1, "handle": "user-1"},
{"user_id": 2, "handle": "user-2"},
{"user_id": 3, "handle": "user-3"},
],
}


def test_get_user_listening_history_multiple_plays(app):
"""Tests listening history from user with multiple plays"""
with app.app_context():
db = get_db()

populate_mock_db(db, test_entities)

with db.scoped_session() as session:
_index_user_listening_history(session)

track_history = _get_user_listening_history(
session,
GetUserListeningHistoryArgs(
user_id=1,
current_user_id=1,
limit=10,
offset=0,
),
)

assert len(track_history) == 3
assert (
track_history[0][response_name_constants.user][response_name_constants.balance]
is not None
)
assert track_history[0][response_name_constants.track_id] == 3
assert track_history[0][response_name_constants.activity_timestamp] == str(
TIMESTAMP + timedelta(minutes=4)
)
assert (
track_history[1][response_name_constants.user][response_name_constants.balance]
is not None
)
assert track_history[1][response_name_constants.track_id] == 2
assert track_history[1][response_name_constants.activity_timestamp] == str(
TIMESTAMP + timedelta(minutes=3)
)
assert (
track_history[2][response_name_constants.user][response_name_constants.balance]
is not None
)
assert track_history[2][response_name_constants.track_id] == 1
assert track_history[2][response_name_constants.activity_timestamp] == str(
TIMESTAMP + timedelta(minutes=2)
)


def test_get_user_listening_history_no_plays(app):
"""Tests a listening history with no plays"""
with app.app_context():
db = get_db()

populate_mock_db(db, test_entities)

with db.scoped_session() as session:
_index_user_listening_history(session)

track_history = _get_user_listening_history(
session,
GetUserListeningHistoryArgs(
user_id=3,
current_user_id=3,
limit=10,
offset=0,
),
)

assert len(track_history) == 0


def test_get_user_listening_history_single_play(app):
"""Tests a listening history with a single play"""
with app.app_context():
db = get_db()

populate_mock_db(db, test_entities)

with db.scoped_session() as session:
_index_user_listening_history(session)

track_history = _get_user_listening_history(
session,
GetUserListeningHistoryArgs(
user_id=2,
current_user_id=2,
limit=10,
offset=0,
),
)

assert len(track_history) == 1
assert (
track_history[0][response_name_constants.user][response_name_constants.balance]
is not None
)
assert track_history[0][response_name_constants.track_id] == 2
assert track_history[0][response_name_constants.activity_timestamp] == str(
TIMESTAMP
)


def test_get_user_listening_history_pagination(app):
"""Tests a track history that's limit bounded"""
with app.app_context():
db = get_db()

populate_mock_db(db, test_entities)

with db.scoped_session() as session:
_index_user_listening_history(session)

track_history = _get_user_listening_history(
session,
GetUserListeningHistoryArgs(
user_id=1,
current_user_id=1,
limit=1,
offset=1,
),
)

assert len(track_history) == 1
assert (
track_history[0][response_name_constants.user][response_name_constants.balance]
is not None
)
assert track_history[0][response_name_constants.track_id] == 2
assert track_history[0][response_name_constants.activity_timestamp] == str(
TIMESTAMP + timedelta(minutes=3)
)


def test_get_user_listening_history_mismatch_user_id(app):
"""Tests a listening history with mismatching user ids"""
with app.app_context():
db = get_db()

populate_mock_db(db, test_entities)

with db.scoped_session() as session:
_index_user_listening_history(session)

track_history = _get_user_listening_history(
session,
GetUserListeningHistoryArgs(
user_id=1,
current_user_id=2,
limit=10,
offset=0,
),
)

assert len(track_history) == 0
26 changes: 14 additions & 12 deletions discovery-provider/src/api/v1/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@
from src.queries.get_top_genre_users import get_top_genre_users
from src.queries.get_top_user_track_tags import get_top_user_track_tags
from src.queries.get_top_users import get_top_users
from src.queries.get_track_history import get_track_history
from src.queries.get_tracks import get_tracks
from src.queries.get_user_listening_history import (
GetUserListeningHistoryArgs,
get_user_listening_history,
)
from src.queries.get_users import get_users
from src.queries.get_users_cnode import ReplicaType, get_users_cnode
from src.queries.search_queries import SearchKind, search
Expand Down Expand Up @@ -527,18 +530,15 @@ def get(self, user_id):
args = history_route_parser.parse_args()
decoded_id = decode_with_abort(user_id, ns)
current_user_id = get_current_user_id(args)

offset = format_offset(args)
limit = format_limit(args)
get_tracks_args = {
"filter_deleted": False,
"user_id": decoded_id,
"current_user_id": current_user_id,
"limit": limit,
"offset": offset,
"with_users": True,
}
track_history = get_track_history(get_tracks_args)
get_tracks_args = GetUserListeningHistoryArgs(
user_id=decoded_id,
current_user_id=current_user_id,
limit=limit,
offset=offset,
)
track_history = get_user_listening_history(get_tracks_args)
tracks = list(map(extend_activity, track_history))
return success_response(tracks)

Expand Down Expand Up @@ -816,7 +816,9 @@ def get(self, replica_type):
"""New route to call get_users_cnode with replica_type param (only consumed by content node)
- Leaving `/users/creator_node` above untouched for backwards-compatibility
Response = array of objects of schema { user_id, wallet, primary, secondary1, secondary2, primarySpId, secondary1SpID, secondary2SpID }
Response = array of objects of schema {
user_id, wallet, primary, secondary1, secondary2, primarySpId, secondary1SpID, secondary2SpID
}
"""
args = users_by_content_node_route_parser.parse_args()

Expand Down

0 comments on commit f13f1dd

Please sign in to comment.