"""Tests for Orchard data source.""" from unittest.mock import MagicMock, patch import pytest from pymysql import Connection from gridgen.connectors import helper, mysql from gridgen.exceptions import ReleaseNotFound, TrackNotFound from gridgen.models import metadata from gridgen.models.datasource import orchard TEST_RELEASE = ((1001, 1234567890, "Release 1", 1, "01234567890"),) TEST_RELEASE_ARTIST = ( ("01234567890", "ReleaseArtist1", "performer"), ("01234567890", "ReleaseArtist2", "featuring"), ) TEST_RELEASE_GRID = ( (1001, "01234567890", "GRid#R01", "Prod#R01", "2016-05-12", "complete"), ) TEST_RELEASE_FORMAT = ((1, "digital"), (2, "physical")) TEST_RELEASE_META = metadata.ReleaseMeta( TEST_RELEASE[0][0], TEST_RELEASE[0][4], TEST_RELEASE_GRID[0][2], TEST_RELEASE_GRID[0][3], TEST_RELEASE[0][2], "", "", "", TEST_RELEASE_ARTIST[0][1], TEST_RELEASE_GRID[0][5], TEST_RELEASE_FORMAT[0][1], ) TEST_TRACK = ( (20001, 1001, "ABC12345", "Track 1", "Version A", "2016 PLine", "music", 3, 14), (20002, 1001, "DEF67890", "Track 2", "Version B", "2016 PLine", "music", 2, 56), (20003, 1001, "GHI12345", "Track 3", "Version C", "2016 PLine", "music", 1, 22), (20004, 1001, "JKL67890", "Track 4", "Version D", "2016 PLine", "music", 3, 18), (20005, 1001, None, "Track 5", "Version E", "2016 PLine", "music", 0, 30), ) TEST_TRACK_ARTIST = ( (20001, "TrackArtist1", "performer"), (20002, "TrackArtist2", "featuring"), ) TEST_TRACK_GRID = ( (20001, "ABC12345", "GRid#T01", "Prod#T01", "2012-05-12"), (20002, "ABC12345", "GRid#T02", "Prod#T02", "2016-05-31"), ) TEST_TRACK_META = metadata.TrackMeta( TEST_TRACK[0][0], TEST_RELEASE[0][4], TEST_TRACK[0][2], TEST_TRACK[0][3], TEST_TRACK[0][4], TEST_TRACK[0][5], "audio" if TEST_TRACK[0][6] == "music" else TEST_TRACK[0][6], TEST_TRACK[0][7] * 60 + TEST_TRACK[0][8], {metadata.ArtistMeta(TEST_TRACK_ARTIST[0][1], TEST_TRACK_ARTIST[0][2])}, {metadata.GridMeta(TEST_TRACK_GRID[1][2], TEST_TRACK_GRID[1][3])}, ) def create_temp_release_tables(db_conn: Connection) -> None: """Create temporary tables to query test release data. Args: db_conn (Connection): open database connection. """ helper.execute_query(db_conn, "SET FOREIGN_KEY_CHECKS = 0") helper.execute_query(db_conn, "TRUNCATE TABLE releases") helper.execute_query(db_conn, "TRUNCATE TABLE release_artist") helper.execute_query(db_conn, "TRUNCATE TABLE release_grid") helper.execute_query(db_conn, "TRUNCATE TABLE distribution_format") release_query = """ INSERT INTO releases ( release_id, upc, release_name, distribution_format_id, display_upc ) VALUES (%s, %s, %s, %s, %s) """ helper.execute_query(db_conn, release_query, TEST_RELEASE[0]) release_grid_query = """ INSERT INTO release_grid ( release_id, upc, grid, product_no, create_time, gras_status ) VALUES (%s, %s, %s, %s, %s, %s) """ helper.execute_query(db_conn, release_grid_query, TEST_RELEASE_GRID[0]) release_artist_query = """ INSERT INTO release_artist (upc, artist_name, role) VALUES (%s, %s, %s) """ helper.execute_query(db_conn, release_artist_query, TEST_RELEASE_ARTIST[0]) helper.execute_query(db_conn, release_artist_query, TEST_RELEASE_ARTIST[1]) release_format_query = """ INSERT INTO distribution_format (distribution_format_id, context_type) VALUES (%s, %s) """ helper.execute_query(db_conn, release_format_query, TEST_RELEASE_FORMAT[0]) helper.execute_query(db_conn, release_format_query, TEST_RELEASE_FORMAT[1]) helper.execute_query(db_conn, "SET FOREIGN_KEY_CHECKS = 1") def create_temp_track_tables(db_conn: Connection) -> None: """Create temporary tables to query test track data. Args: db_conn (Connection): open database connection. """ helper.execute_query(db_conn, "SET FOREIGN_KEY_CHECKS = 0") helper.execute_query(db_conn, "TRUNCATE TABLE releases") helper.execute_query(db_conn, "TRUNCATE TABLE track") helper.execute_query(db_conn, "TRUNCATE TABLE track_artist") helper.execute_query(db_conn, "TRUNCATE TABLE master_grid") release_query = """ INSERT INTO releases ( release_id, upc, release_name, distribution_format_id, display_upc ) VALUES (%s, %s, %s, %s, %s) """ helper.execute_query(db_conn, release_query, TEST_RELEASE[0]) track_query = """ INSERT INTO track ( id, release_id, isrc, track_name, version, p_line, track_type, length_minute, length_seconds ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) """ helper.execute_query(db_conn, track_query, TEST_TRACK[0]) helper.execute_query(db_conn, track_query, TEST_TRACK[1]) helper.execute_query(db_conn, track_query, TEST_TRACK[2]) helper.execute_query(db_conn, track_query, TEST_TRACK[3]) helper.execute_query(db_conn, track_query, TEST_TRACK[4]) track_grid_query = """ INSERT INTO master_grid (id, isrc, grid, product_no, create_time) VALUES (%s, %s, %s, %s, %s) """ helper.execute_query(db_conn, track_grid_query, TEST_TRACK_GRID[0]) helper.execute_query(db_conn, track_grid_query, TEST_TRACK_GRID[1]) track_artist_query = """ INSERT INTO track_artist (track_id, name, type) VALUES (%s, %s, %s) """ helper.execute_query(db_conn, track_artist_query, TEST_TRACK_ARTIST[0]) helper.execute_query(db_conn, track_artist_query, TEST_TRACK_ARTIST[1]) helper.execute_query(db_conn, "SET FOREIGN_KEY_CHECKS = 1") def create_temp_grid_table(db_conn: Connection) -> None: """Create temporary tables to query test release grid data. Args: db_conn (Connection): open database connection. """ helper.execute_query(db_conn, "SET FOREIGN_KEY_CHECKS = 0") helper.execute_query(db_conn, "TRUNCATE TABLE release_grid") db_insert_query = """ INSERT INTO release_grid ( release_id, upc, grid, product_no, create_time, gras_status ) VALUES (%s, %s, %s, %s, %s, %s) """ db_values = [ (1, 1, "G-ABC", "P-ABC", "2016-01-18T00:00:00", "unknown"), (2, 2, "G-DEF", "P-DEF", "2016-04-18T00:00:00", "incomplete"), (3, 3, "G-GHI", "P-GHI", "2016-07-18T00:00:00", "unknown"), (4, 4, "G-JKL", "P-JKL", "2016-09-18T00:00:00", "incomplete"), (5, 5, "G-MNO", "P-MNO", "2016-12-31T00:00:00", "complete"), (6, 6, "G-PQR", "P-PQR", "2017-01-01T00:00:00", "unknown"), ] for insert_row in db_values: helper.execute_query(db_conn, db_insert_query, insert_row) helper.execute_query(db_conn, "SET FOREIGN_KEY_CHECKS = 1") def test_lookup_release_identifiers() -> None: """Test lookup_release identifiers.""" create_temp_release_tables(mysql.get_connection()) result = orchard.lookup_release_identifiers(1001) assert result == metadata.ReleaseIdMeta(TEST_RELEASE[0][0], TEST_RELEASE[0][4]) def test_lookup_track_list() -> None: """Test lookup_track_list.""" create_temp_track_tables(mysql.get_connection()) result = orchard.lookup_track_list(metadata.ReleaseIdMeta(1001, "01234567890")) assert result == [ metadata.TrackIdMeta(20001, "ABC12345", "01234567890"), metadata.TrackIdMeta(20002, "DEF67890", "01234567890"), metadata.TrackIdMeta(20003, "GHI12345", "01234567890"), metadata.TrackIdMeta(20004, "JKL67890", "01234567890"), ] def test_lookup_track_list_error() -> None: """Test lookup_track_list.""" result = orchard.lookup_track_list(metadata.ReleaseIdMeta(None, "01234567890")) assert result == [] def test_lookup_release() -> None: """Test lookup_release.""" create_temp_release_tables(mysql.get_connection()) result = orchard.lookup_release(metadata.ReleaseIdMeta(1001, "01234567890")) assert result == TEST_RELEASE_META def test_lookup_release_empty() -> None: """Test lookup_release when UPC not found.""" create_temp_release_tables(mysql.get_connection()) with pytest.raises(ReleaseNotFound) as exc: orchard.lookup_release(metadata.ReleaseIdMeta(1002, "01234567891")) assert exc.value.description == "Release 1002 not found" def test_lookup_track() -> None: """Test lookup_track.""" create_temp_track_tables(mysql.get_connection()) result = orchard.lookup_track( metadata.TrackIdMeta(20001, "ABC12345", "01234567890") ) assert result == TEST_TRACK_META def test_lookup_track_empty() -> None: """Test lookup_track when UPC/ISRC combination not found.""" create_temp_track_tables(mysql.get_connection()) with pytest.raises(TrackNotFound) as exc: orchard.lookup_track(metadata.TrackIdMeta(20009, "XYZ12345", "01234567890")) assert exc.value.description == "Track XYZ12345 not found" @patch("gridgen.connectors.mysql.execute_query", return_value=()) def test_save_release(mock_query: MagicMock) -> None: """Test save_release.""" test_id = metadata.ReleaseIdMeta(1001, "01234567890") test_grid = metadata.GridMeta("GRid12345", "Prod12345") assert orchard.save_release(test_id, test_grid) == { "id": 1001, "grid": "GRid12345", "product_number": "Prod12345", } mock_query.assert_called_with( orchard.QUERY_RELEASE_SAVE, (test_id.release_id, test_grid.grid, test_grid.product_no), ) @patch( "gridgen.connectors.mysql.execute_query", side_effect=Exception("database_error"), ) def test_save_release_error(mock_query: MagicMock) -> None: """Test save_release.""" test_id = metadata.ReleaseIdMeta(1001, "01234567890") test_grid = metadata.GridMeta("GRid12345", "Prod12345") with pytest.raises(Exception) as exc: orchard.save_release(test_id, test_grid) assert str(exc.value) == "database_error" mock_query.assert_called_with( orchard.QUERY_RELEASE_SAVE, (test_id.release_id, test_grid.grid, test_grid.product_no), ) @patch("gridgen.connectors.mysql.execute_query", return_value=()) def test_save_track(mock_query: MagicMock) -> None: """Test save_track.""" test_id = metadata.TrackIdMeta(20001, "XYZ12345", "01234567890") test_grid = metadata.GridMeta("GRid12345", "Prod12345") assert orchard.save_track(test_id, test_grid) == { "id": 20001, "isrc": "XYZ12345", "grid": "GRid12345", "product_number": "Prod12345", } mock_query.assert_called_with( orchard.QUERY_TRACK_SAVE, (test_id.track_id, test_id.isrc, test_grid.grid, test_grid.product_no), ) @patch( "gridgen.connectors.mysql.execute_query", side_effect=Exception("database_error"), ) def test_save_track_error(mock_query: MagicMock) -> None: """Test save_track.""" test_id = metadata.TrackIdMeta(20001, "XYZ12345", "01234567890") test_grid = metadata.GridMeta("GRid12345", "Prod12345") with pytest.raises(Exception) as exc: orchard.save_track(test_id, test_grid) assert str(exc.value) == "database_error" mock_query.assert_called_with( orchard.QUERY_TRACK_SAVE, (test_id.track_id, test_id.isrc, test_grid.grid, test_grid.product_no), )