"""Test for Rights Attribute Model.""" import pytest from backend.connectors import mysql from backend.constants.validation import VARIOUS_ARTISTS from backend.models.rights_attribute_query import RightsAttributeQuery from backend.models.rights_attribute import RightsAttributesSuggestionKeywords from backend.models.track import ReleaseArtist from backend.models.track import Releases from tests.testutils import db @db.test_schema def test_get_rights_attributes(): """Test get rights attributes.""" with mysql.db_session() as session: attributes = RightsAttributeQuery.get_rights_attributes(session=session) assert len(attributes.message['items']) == 9 @db.test_schema def test_get_track_rights_attributes(): """Test get track rights attributes.""" with mysql.db_session() as session: attributes = RightsAttributeQuery.get_track_rights_attributes( tuid=182, session=session) assert attributes.message['items'] == [ {'rights_attribute_id': 1, 'description': 'Public Domain', 'track_rights_attribute_id': 1}, {'rights_attribute_id': 2, 'description': 'Compilations', 'track_rights_attribute_id': 2}, {'rights_attribute_id': 3, 'description': 'Various Artists', 'track_rights_attribute_id': 3}, ] @db.test_schema def test_get_track_rights_attributes_edits(): """Test get track rights attributes edits.""" with mysql.db_session() as session: attributes = RightsAttributeQuery.get_track_rights_attributes_edits( tuid=182, session=session) assert attributes.message['items'] == [ {'rights_attribute_id': 1, 'description': 'Public Domain', 'track_rights_attribute_id': 1}, {'rights_attribute_id': 2, 'description': 'Compilations', 'track_rights_attribute_id': 2}, {'rights_attribute_id': 3, 'description': 'Various Artists', 'track_rights_attribute_id': 3}, ] @db.test_schema def test_get_track_suggested_rights_attributes_compilations(): """Test that Compilations is suggested for a multi-artist product.""" with mysql.db_session() as session: attributes = RightsAttributeQuery.get_suggested_rights_attributes( tuid=40, session=session) assert attributes.message['items'] == [ {'rights_attribute_id': 2, 'description': 'Compilations', 'track_rights_attribute_id': 0, 'reasons': [{'type': 'compilation_check'}]} ] @db.test_schema def test_compilations_suggested_for_release_artist_various_artists(): """Compilations suggested when release display artist is 'Various Artists'. tuid=43 is in release_id=10 which has 2 tracks and 'Various Artists' as release_artist. The distinct-performer check does not fire. The release_artist check triggers the suggestion with reason compilation_check_various_artists. """ with mysql.db_session() as session: attributes = RightsAttributeQuery.get_suggested_rights_attributes( tuid=43, session=session) assert attributes.message['items'] == [ {'rights_attribute_id': 2, 'description': 'Compilations', 'track_rights_attribute_id': 0, 'reasons': [{'type': 'compilation_check_various_artists'}]} ] @db.test_schema def test_compilations_not_suggested_for_single_track_release_with_various_artists(): """SR-1208: Compilations NOT suggested for single-track release even with Various Artists. tuid=39 is in release_id=7 which has only 1 track but has 'Various Artists' as the release display artist. Single-track products cannot be compilations. """ with mysql.db_session() as session: attributes = RightsAttributeQuery.get_suggested_rights_attributes( tuid=39, session=session) # Should NOT suggest Compilations for a single-track product compilation_items = [ item for item in attributes.message['items'] if item['rights_attribute_id'] == 2 ] assert compilation_items == [] @db.test_schema def test_compilations_suggested_for_project_artist_various_artists_variant(): """Compilations suggested when project artist is a non-English variant. tuid=45 is in release_id=11 (project_id=99). project_id=99 has artist_id=1 pointing to artist_info name 'Artisti Vari' (Italian variant). The distinct-performer check does not fire; the project-artist check triggers the suggestion with reason compilation_check_various_artists. """ with mysql.db_session() as session: attributes = RightsAttributeQuery.get_suggested_rights_attributes( tuid=45, session=session) assert attributes.message['items'] == [ {'rights_attribute_id': 2, 'description': 'Compilations', 'track_rights_attribute_id': 0, 'reasons': [{'type': 'compilation_check_various_artists'}]} ] @db.test_schema def test_compilations_not_suggested_for_single_track_project_artist_various_artists(): """SR-1208: Compilations NOT suggested for single-track with project Various Artists. tuid=38 is in release_id=6 (project_id=99). project_id=99 has artist_id=1 pointing to artist_info name 'Artisti Vari' (Italian variant). However, release_id=6 has only 1 track, so Compilations should NOT be suggested. """ with mysql.db_session() as session: attributes = RightsAttributeQuery.get_suggested_rights_attributes( tuid=38, session=session) # Compilations should NOT be suggested (only Video Game Content should appear) compilation_items = [ item for item in attributes.message['items'] if item['rights_attribute_id'] == 2 ] assert compilation_items == [] # Video Game Content should still be suggested based on track name keywords video_game_items = [ item for item in attributes.message['items'] if item['rights_attribute_id'] == 4 ] assert len(video_game_items) == 1 @db.test_schema def test_get_suggested_vendor_rights_attributes(): """Test get track rights attributes for a track without entry in tra table.""" with mysql.db_session() as session: attributes = RightsAttributeQuery.get_track_rights_attributes( tuid=39, session=session) assert attributes.message['items'] == [ {'track_rights_attribute_id': 0, 'description': 'UGC Allow', 'rights_attribute_id': 9, 'reasons': [{'type': 'entity_rules'}]} ] @db.test_schema def test_compilations_not_suggested_for_single_track_non_ascii_various_artists(): """SR-1208: Compilations NOT suggested for single-track with non-ASCII Various Artists. tuid=42 is in release_id=9 which has only 1 track. The release_artist has 'Multi-interprètes' (French non-ASCII variant). However, since it's a single-track release, Compilations should NOT be suggested. """ with mysql.db_session() as session: attributes = RightsAttributeQuery.get_suggested_rights_attributes( tuid=42, session=session) # Should NOT suggest Compilations for single-track product compilation_items = [ item for item in attributes.message['items'] if item['rights_attribute_id'] == 2 ] assert compilation_items == [] @db.test_schema def test_compilations_suggested_for_multi_track_non_ascii_various_artists(): """SR-1183 regression: non-ASCII release artist variant triggers suggestion. Dynamically adds a release_artist with 'Multi-interprètes' (French non-ASCII variant) to release_id=1 which has 9 tracks. Guards against regressing to embedded SQL literals, which break on MySQL latin1 connections. """ with mysql.db_session() as session: session.add(ReleaseArtist( release_artist_id=100, release_id=1, role='performer', artist_name='Multi-interprètes', )) session.flush() attributes = RightsAttributeQuery.get_suggested_rights_attributes( tuid=1, session=session) assert attributes.message['items'] == [ {'rights_attribute_id': 2, 'description': 'Compilations', 'track_rights_attribute_id': 0, 'reasons': [{'type': 'compilation_check_various_artists'}]} ] @db.test_schema def test_get_suggested_compilation_attributes(): """Test get track rights attributes for a track without entry in tra table.""" with mysql.db_session() as session: attributes = RightsAttributeQuery.get_suggested_rights_attributes( tuid=40, session=session) assert attributes.message['items'] == [ {'track_rights_attribute_id': 0, 'rights_attribute_id': 2, 'description': 'Compilations', 'reasons': [ {'type': 'compilation_check'} ]}] @pytest.mark.parametrize('artist_name', sorted(VARIOUS_ARTISTS)) @db.test_schema def test_compilations_suggested_for_every_various_artists_variant(artist_name): """Compilations is suggested for every recognised VARIOUS_ARTISTS variant. Uses tuid=1 (release_id=1, single performer) so the distinct-performer count check does not fire. A release_artist row is inserted dynamically for each variant, including non-ASCII strings, which exercises the expanding bindparam path and would catch any regression to raw SQL literals. """ with mysql.db_session() as session: session.add(ReleaseArtist( release_artist_id=99, release_id=1, role='performer', artist_name=artist_name, )) session.flush() attributes = RightsAttributeQuery.get_suggested_rights_attributes( tuid=1, session=session) assert attributes.message['items'] == [ {'rights_attribute_id': 2, 'description': 'Compilations', 'track_rights_attribute_id': 0, 'reasons': [{'type': 'compilation_check_various_artists'}]} ] @db.test_schema def test_compilations_not_suggested_for_keyword_match_without_multiple_performers(): """SR-1208/SR-1184: Compilations not suggested via keyword match unless both track count > 1 and distinct-performer count > 1 in the release. Two scenarios are verified with a dynamically-added "vol" keyword: 1. Single-track release (tuid=28, TEST_SINGLE_TRACK_PRODUCT_ID): only one track in its release, so the track-count guard suppresses the suggestion. 2. Multi-track single-performer release (tuid=1, TEST_PRODUCT_ID): nine tracks all share the same performer ("Snowball"). The track name contains "vol", so the old guard (count > 1 only) would have fired. The new guard requires distinct-performer count > 1, so the suggestion is still suppressed. """ with mysql.db_session() as session: session.add(Releases( release_id=4, release_name='Vol 1 Collection', project_id=1, release_status='in_content', distribution_format_id=0, genre_id=16, )) session.add(RightsAttributesSuggestionKeywords( id=999, rights_attribute_id=2, keyword='vol', )) session.flush() single_track_attrs = RightsAttributeQuery.get_suggested_rights_attributes( tuid=28, session=session) multi_track_single_performer_attrs = RightsAttributeQuery.get_suggested_rights_attributes( tuid=1, session=session) assert single_track_attrs.message['items'] == [] assert multi_track_single_performer_attrs.message['items'] == [] @db.test_schema def test_compilation_check_not_suggested_when_all_tracks_share_same_performers(): """compilation_check must NOT fire when every track in the release shares the same set of performer artists. tuid=1 is in a 9-track release (product_id=1) where every track has the same sole performer ('Snowball'). Even though there are multiple tracks, the performer-set count is 1 → the Compilations attribute must not be suggested via compilation_check. """ with mysql.db_session() as session: attributes = RightsAttributeQuery.get_suggested_rights_attributes( tuid=1, session=session) # Compilations (id=2) must NOT appear via compilation_check compilation_items = [ item for item in attributes.message['items'] if item['rights_attribute_id'] == 2 and any(r['type'] == 'compilation_check' for r in item.get('reasons', [])) ] assert compilation_items == [] @db.test_schema def test_compilation_check_suggested_when_tracks_have_differing_performers(): """compilation_check MUST fire when at least two tracks in the release have different performer-artist sets. tuid=40 is in the TEST_COMPILATION_PRODUCT_ID release (product_id=8) which has two tracks: even tuids get 'Artiste Uno' and odd tuids get 'Artiste Dos'. The performer sets therefore differ → compilation_check must be suggested. """ with mysql.db_session() as session: attributes = RightsAttributeQuery.get_suggested_rights_attributes( tuid=40, session=session) compilation_items = [ item for item in attributes.message['items'] if item['rights_attribute_id'] == 2 and any(r['type'] == 'compilation_check' for r in item.get('reasons', [])) ] assert len(compilation_items) == 1