diff --git a/api/dbv1/get_events.sql.go b/api/dbv1/get_events.sql.go index e76fddc5..f93d710a 100644 --- a/api/dbv1/get_events.sql.go +++ b/api/dbv1/get_events.sql.go @@ -14,24 +14,26 @@ import ( const getEvents = `-- name: GetEvents :many SELECT - event_id, - entity_type::event_entity_type, - user_id, - entity_id, - event_type::event_type, - end_date, - is_deleted, - created_at, - updated_at, - event_data -FROM events + e.event_id AS event_id, + e.entity_type::event_entity_type AS entity_type, + e.user_id AS user_id, + e.entity_id AS entity_id, + e.event_type::event_type AS event_type, + e.end_date AS end_date, + e.is_deleted AS is_deleted, + e.created_at AS created_at, + e.updated_at AS updated_at, + e.event_data AS event_data +FROM events e +LEFT JOIN tracks t ON t.track_id = e.entity_id AND t.is_current = true AND e.entity_type = 'track' WHERE - ($1::int[] = '{}' OR entity_id = ANY($1::int[])) - AND ($2::int[] = '{}' OR event_id = ANY($2::int[])) - AND ($3::text = '' OR entity_type = $3::event_entity_type) - AND ($4::text = '' OR event_type = $4::event_type) - AND ($5::boolean IS NULL OR is_deleted = $5) -ORDER BY created_at DESC, event_id ASC + ($1::int[] = '{}' OR e.entity_id = ANY($1::int[])) + AND ($2::int[] = '{}' OR e.event_id = ANY($2::int[])) + AND ($3::text = '' OR e.entity_type = $3::event_entity_type) + AND ($4::text = '' OR e.event_type = $4::event_type) + AND ($5::boolean IS NULL OR e.is_deleted = $5) + AND (e.entity_type != 'track' OR (t.track_id IS NOT NULL AND t.is_delete = false)) +ORDER BY e.created_at DESC, e.event_id ASC LIMIT $7 OFFSET $6 ` diff --git a/api/dbv1/queries/get_events.sql b/api/dbv1/queries/get_events.sql index 1486253f..ac36d8f1 100644 --- a/api/dbv1/queries/get_events.sql +++ b/api/dbv1/queries/get_events.sql @@ -1,22 +1,24 @@ -- name: GetEvents :many SELECT - event_id, - entity_type::event_entity_type, - user_id, - entity_id, - event_type::event_type, - end_date, - is_deleted, - created_at, - updated_at, - event_data -FROM events + e.event_id AS event_id, + e.entity_type::event_entity_type AS entity_type, + e.user_id AS user_id, + e.entity_id AS entity_id, + e.event_type::event_type AS event_type, + e.end_date AS end_date, + e.is_deleted AS is_deleted, + e.created_at AS created_at, + e.updated_at AS updated_at, + e.event_data AS event_data +FROM events e +LEFT JOIN tracks t ON t.track_id = e.entity_id AND t.is_current = true AND e.entity_type = 'track' WHERE - (@entity_ids::int[] = '{}' OR entity_id = ANY(@entity_ids::int[])) - AND (@event_ids::int[] = '{}' OR event_id = ANY(@event_ids::int[])) - AND (@entity_type::text = '' OR entity_type = @entity_type::event_entity_type) - AND (@event_type::text = '' OR event_type = @event_type::event_type) - AND (@filter_deleted::boolean IS NULL OR is_deleted = @filter_deleted) -ORDER BY created_at DESC, event_id ASC + (@entity_ids::int[] = '{}' OR e.entity_id = ANY(@entity_ids::int[])) + AND (@event_ids::int[] = '{}' OR e.event_id = ANY(@event_ids::int[])) + AND (@entity_type::text = '' OR e.entity_type = @entity_type::event_entity_type) + AND (@event_type::text = '' OR e.event_type = @event_type::event_type) + AND (@filter_deleted::boolean IS NULL OR e.is_deleted = @filter_deleted) + AND (e.entity_type != 'track' OR (t.track_id IS NOT NULL AND t.is_delete = false)) +ORDER BY e.created_at DESC, e.event_id ASC LIMIT @limit_val OFFSET @offset_val; diff --git a/api/testdata/track_fixtures.go b/api/testdata/track_fixtures.go index 0e7a34f0..3083f78f 100644 --- a/api/testdata/track_fixtures.go +++ b/api/testdata/track_fixtures.go @@ -3,6 +3,7 @@ package testdata var TrackFixtures = []map[string]any{ {"track_id": 100, "genre": "Electronic", "owner_id": 1, "title": "T1", "is_unlisted": "f", "is_downloadable": "t"}, {"track_id": 101, "genre": "Alternative", "owner_id": 1, "title": "T2", "is_unlisted": "f", "is_downloadable": "f"}, + {"track_id": 102, "genre": "Alternative", "owner_id": 2, "title": "T3", "is_unlisted": "f", "is_downloadable": "f"}, {"track_id": 200, "genre": "Electronic", "owner_id": 2, "title": "Culca Canyon", "is_unlisted": "f", "is_downloadable": "f"}, {"track_id": 201, "genre": "Alternative", "owner_id": 2, "title": "Turkey Time DEMO", "is_unlisted": "t", "is_downloadable": "f"}, {"track_id": 202, "genre": "Alternative", "owner_id": 2, "title": "Turkey Time (live)", "is_unlisted": "f", "is_downloadable": "f"}, diff --git a/api/v1_events_test.go b/api/v1_events_test.go index e910e9aa..53665378 100644 --- a/api/v1_events_test.go +++ b/api/v1_events_test.go @@ -1,11 +1,13 @@ package api import ( + "context" "testing" "api.audius.co/api/dbv1" "api.audius.co/trashid" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestGetEvents(t *testing.T) { @@ -53,3 +55,34 @@ func TestGetEventsEntity(t *testing.T) { "data.0.entity_id": trashid.MustEncodeHashID(102), }) } + +func TestGetEventsExcludesDeletedTracks(t *testing.T) { + app := testAppWithFixtures(t) + ctx := context.Background() + require.NotNil(t, app.writePool, "test requires write pool") + + // Mark track 102 (which has event 6) as deleted + _, err := app.writePool.Exec(ctx, `UPDATE tracks SET is_delete = true WHERE track_id = 102 AND is_current = true`) + require.NoError(t, err) + + var eventsResponse struct { + Data []dbv1.FullEvent + } + status, body := testGet(t, app, "/v1/events", &eventsResponse) + assert.Equal(t, 200, status) + + // Event 6 is for entity_id 102; it must not appear when the track is deleted + entity102Hash := trashid.MustEncodeHashID(102) + for _, e := range eventsResponse.Data { + assert.NotEqual(t, entity102Hash, e.EntityId, "events for deleted track 102 must not be returned") + } + + // Should have 4 events (1,2,4,5), not 5 (event 6 excluded) + assert.Len(t, eventsResponse.Data, 4, "expected 4 events after excluding event for deleted track") + jsonAssert(t, body, map[string]any{ + "data.0.event_id": trashid.MustEncodeHashID(1), + "data.0.entity_id": trashid.MustEncodeHashID(100), + "data.3.event_id": trashid.MustEncodeHashID(5), + "data.3.entity_id": trashid.MustEncodeHashID(101), + }) +}