This commit is contained in:
parent
7bb0fa2e64
commit
05f0129025
9 changed files with 915 additions and 396 deletions
|
|
@ -11,45 +11,22 @@ from funkwhale_api.music import metadata
|
|||
DATA_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def test_get_all_metadata_at_once():
|
||||
path = os.path.join(DATA_DIR, "test.ogg")
|
||||
data = metadata.Metadata(path)
|
||||
|
||||
expected = {
|
||||
"title": "Peer Gynt Suite no. 1, op. 46: I. Morning",
|
||||
"artist": "Edvard Grieg",
|
||||
"album_artist": "Edvard Grieg",
|
||||
"album": "Peer Gynt Suite no. 1, op. 46",
|
||||
"date": datetime.date(2012, 8, 15),
|
||||
"track_number": 1,
|
||||
"disc_number": 1,
|
||||
"musicbrainz_albumid": uuid.UUID("a766da8b-8336-47aa-a3ee-371cc41ccc75"),
|
||||
"musicbrainz_recordingid": uuid.UUID("bd21ac48-46d8-4e78-925f-d9cc2a294656"),
|
||||
"musicbrainz_artistid": uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
|
||||
"musicbrainz_albumartistid": uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
|
||||
"license": "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/",
|
||||
"copyright": "Someone",
|
||||
}
|
||||
|
||||
assert data.all() == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"field,value",
|
||||
[
|
||||
("title", "Peer Gynt Suite no. 1, op. 46: I. Morning"),
|
||||
("artist", "Edvard Grieg"),
|
||||
("album_artist", "Edvard Grieg"),
|
||||
("album_artist", "Edvard Grieg; Musopen Symphony Orchestra"),
|
||||
("album", "Peer Gynt Suite no. 1, op. 46"),
|
||||
("date", datetime.date(2012, 8, 15)),
|
||||
("track_number", 1),
|
||||
("disc_number", 1),
|
||||
("musicbrainz_albumid", uuid.UUID("a766da8b-8336-47aa-a3ee-371cc41ccc75")),
|
||||
("musicbrainz_recordingid", uuid.UUID("bd21ac48-46d8-4e78-925f-d9cc2a294656")),
|
||||
("musicbrainz_artistid", uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823")),
|
||||
("date", "2012-08-15"),
|
||||
("position", "1"),
|
||||
("disc_number", "1"),
|
||||
("musicbrainz_albumid", "a766da8b-8336-47aa-a3ee-371cc41ccc75"),
|
||||
("mbid", "bd21ac48-46d8-4e78-925f-d9cc2a294656"),
|
||||
("musicbrainz_artistid", "013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
|
||||
(
|
||||
"musicbrainz_albumartistid",
|
||||
uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
|
||||
"013c8e5b-d72a-4cd3-8dee-6c64d6125823;5b4d7d2d-36df-4b38-95e3-a964234f520f",
|
||||
),
|
||||
("license", "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/"),
|
||||
("copyright", "Someone"),
|
||||
|
|
@ -62,22 +39,44 @@ def test_can_get_metadata_from_ogg_file(field, value):
|
|||
assert data.get(field) == value
|
||||
|
||||
|
||||
def test_can_get_metadata_all():
|
||||
path = os.path.join(DATA_DIR, "test.ogg")
|
||||
data = metadata.Metadata(path)
|
||||
|
||||
expected = {
|
||||
"title": "Peer Gynt Suite no. 1, op. 46: I. Morning",
|
||||
"artist": "Edvard Grieg",
|
||||
"album_artist": "Edvard Grieg; Musopen Symphony Orchestra",
|
||||
"album": "Peer Gynt Suite no. 1, op. 46",
|
||||
"date": "2012-08-15",
|
||||
"position": "1",
|
||||
"disc_number": "1",
|
||||
"musicbrainz_albumid": "a766da8b-8336-47aa-a3ee-371cc41ccc75",
|
||||
"mbid": "bd21ac48-46d8-4e78-925f-d9cc2a294656",
|
||||
"musicbrainz_artistid": "013c8e5b-d72a-4cd3-8dee-6c64d6125823",
|
||||
"musicbrainz_albumartistid": "013c8e5b-d72a-4cd3-8dee-6c64d6125823;5b4d7d2d-36df-4b38-95e3-a964234f520f",
|
||||
"license": "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/",
|
||||
"copyright": "Someone",
|
||||
}
|
||||
assert data.all() == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"field,value",
|
||||
[
|
||||
("title", "Peer Gynt Suite no. 1, op. 46: I. Morning"),
|
||||
("artist", "Edvard Grieg"),
|
||||
("album_artist", "Edvard Grieg"),
|
||||
("album_artist", "Edvard Grieg; Musopen Symphony Orchestra"),
|
||||
("album", "Peer Gynt Suite no. 1, op. 46"),
|
||||
("date", datetime.date(2012, 8, 15)),
|
||||
("track_number", 1),
|
||||
("disc_number", 1),
|
||||
("musicbrainz_albumid", uuid.UUID("a766da8b-8336-47aa-a3ee-371cc41ccc75")),
|
||||
("musicbrainz_recordingid", uuid.UUID("bd21ac48-46d8-4e78-925f-d9cc2a294656")),
|
||||
("musicbrainz_artistid", uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823")),
|
||||
("date", "2012-08-15"),
|
||||
("position", "1"),
|
||||
("disc_number", "1"),
|
||||
("musicbrainz_albumid", "a766da8b-8336-47aa-a3ee-371cc41ccc75"),
|
||||
("mbid", "bd21ac48-46d8-4e78-925f-d9cc2a294656"),
|
||||
("musicbrainz_artistid", "013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
|
||||
(
|
||||
"musicbrainz_albumartistid",
|
||||
uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
|
||||
"013c8e5b-d72a-4cd3-8dee-6c64d6125823;5b4d7d2d-36df-4b38-95e3-a964234f520f",
|
||||
),
|
||||
("license", "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/"),
|
||||
("copyright", "Someone"),
|
||||
|
|
@ -97,16 +96,13 @@ def test_can_get_metadata_from_opus_file(field, value):
|
|||
("artist", "Die Toten Hosen"),
|
||||
("album_artist", "Die Toten Hosen"),
|
||||
("album", "Ballast der Republik"),
|
||||
("date", datetime.date(2012, 5, 4)),
|
||||
("track_number", 1),
|
||||
("disc_number", 1),
|
||||
("musicbrainz_albumid", uuid.UUID("1f0441ad-e609-446d-b355-809c445773cf")),
|
||||
("musicbrainz_recordingid", uuid.UUID("124d0150-8627-46bc-bc14-789a3bc960c8")),
|
||||
("musicbrainz_artistid", uuid.UUID("c3bc80a6-1f4a-4e17-8cf0-6b1efe8302f1")),
|
||||
(
|
||||
"musicbrainz_albumartistid",
|
||||
uuid.UUID("c3bc80a6-1f4a-4e17-8cf0-6b1efe8302f1"),
|
||||
),
|
||||
("date", "2012-05-04"),
|
||||
("position", "1/16"),
|
||||
("disc_number", "1/2"),
|
||||
("musicbrainz_albumid", "1f0441ad-e609-446d-b355-809c445773cf"),
|
||||
("mbid", "124d0150-8627-46bc-bc14-789a3bc960c8"),
|
||||
("musicbrainz_artistid", "c3bc80a6-1f4a-4e17-8cf0-6b1efe8302f1"),
|
||||
("musicbrainz_albumartistid", "c3bc80a6-1f4a-4e17-8cf0-6b1efe8302f1"),
|
||||
# somehow, I cannot successfully create an ogg theora file
|
||||
# with the proper license field
|
||||
# ("license", "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/"),
|
||||
|
|
@ -126,16 +122,13 @@ def test_can_get_metadata_from_ogg_theora_file(field, value):
|
|||
("artist", "Binärpilot"),
|
||||
("album_artist", "Binärpilot"),
|
||||
("album", "You Can't Stop Da Funk"),
|
||||
("date", datetime.date(2006, 2, 7)),
|
||||
("track_number", 2),
|
||||
("disc_number", 1),
|
||||
("musicbrainz_albumid", uuid.UUID("ce40cdb1-a562-4fd8-a269-9269f98d4124")),
|
||||
("musicbrainz_recordingid", uuid.UUID("f269d497-1cc0-4ae4-a0c4-157ec7d73fcb")),
|
||||
("musicbrainz_artistid", uuid.UUID("9c6bddde-6228-4d9f-ad0d-03f6fcb19e13")),
|
||||
(
|
||||
"musicbrainz_albumartistid",
|
||||
uuid.UUID("9c6bddde-6228-4d9f-ad0d-03f6fcb19e13"),
|
||||
),
|
||||
("date", "2006-02-07"),
|
||||
("position", "2/4"),
|
||||
("disc_number", "1/1"),
|
||||
("musicbrainz_albumid", "ce40cdb1-a562-4fd8-a269-9269f98d4124"),
|
||||
("mbid", "f269d497-1cc0-4ae4-a0c4-157ec7d73fcb"),
|
||||
("musicbrainz_artistid", "9c6bddde-6228-4d9f-ad0d-03f6fcb19e13"),
|
||||
("musicbrainz_albumartistid", "9c6bddde-6228-4d9f-ad0d-03f6fcb19e13"),
|
||||
("license", "https://creativecommons.org/licenses/by-nc-nd/2.5/"),
|
||||
("copyright", "Someone"),
|
||||
],
|
||||
|
|
@ -144,7 +137,7 @@ def test_can_get_metadata_from_id3_mp3_file(field, value):
|
|||
path = os.path.join(DATA_DIR, "test.mp3")
|
||||
data = metadata.Metadata(path)
|
||||
|
||||
assert data.get(field) == value
|
||||
assert str(data.get(field)) == value
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
@ -170,16 +163,13 @@ def test_can_get_pictures(name):
|
|||
("artist", "Nine Inch Nails"),
|
||||
("album_artist", "Nine Inch Nails"),
|
||||
("album", "The Slip"),
|
||||
("date", datetime.date(2008, 5, 5)),
|
||||
("track_number", 1),
|
||||
("disc_number", 1),
|
||||
("musicbrainz_albumid", uuid.UUID("12b57d46-a192-499e-a91f-7da66790a1c1")),
|
||||
("musicbrainz_recordingid", uuid.UUID("30f3f33e-8d0c-4e69-8539-cbd701d18f28")),
|
||||
("musicbrainz_artistid", uuid.UUID("b7ffd2af-418f-4be2-bdd1-22f8b48613da")),
|
||||
(
|
||||
"musicbrainz_albumartistid",
|
||||
uuid.UUID("b7ffd2af-418f-4be2-bdd1-22f8b48613da"),
|
||||
),
|
||||
("date", "2008-05-05"),
|
||||
("position", "1"),
|
||||
("disc_number", "1"),
|
||||
("musicbrainz_albumid", "12b57d46-a192-499e-a91f-7da66790a1c1"),
|
||||
("mbid", "30f3f33e-8d0c-4e69-8539-cbd701d18f28"),
|
||||
("musicbrainz_artistid", "b7ffd2af-418f-4be2-bdd1-22f8b48613da"),
|
||||
("musicbrainz_albumartistid", "b7ffd2af-418f-4be2-bdd1-22f8b48613da"),
|
||||
("license", "http://creativecommons.org/licenses/by-nc-sa/3.0/us/"),
|
||||
("copyright", "2008 nin"),
|
||||
],
|
||||
|
|
@ -199,54 +189,18 @@ def test_can_get_metadata_from_flac_file_not_crash_if_empty():
|
|||
data.get("test")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"field_name",
|
||||
[
|
||||
"musicbrainz_artistid",
|
||||
"musicbrainz_albumid",
|
||||
"musicbrainz_recordingid",
|
||||
"musicbrainz_albumartistid",
|
||||
],
|
||||
)
|
||||
def test_mbid_clean_keeps_only_first(field_name):
|
||||
u1 = str(uuid.uuid4())
|
||||
u2 = str(uuid.uuid4())
|
||||
field = metadata.VALIDATION[field_name]
|
||||
result = field.to_python("/".join([u1, u2]))
|
||||
|
||||
assert str(result) == u1
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"raw,expected",
|
||||
[
|
||||
("2017", datetime.date(2017, 1, 1)),
|
||||
("2017-12-31", datetime.date(2017, 12, 31)),
|
||||
("2017-14-01 01:32", datetime.date(2017, 1, 14)), # deezer format
|
||||
("2017-02", datetime.date(2017, 1, 1)), # weird format that exists
|
||||
("nonsense", None),
|
||||
],
|
||||
)
|
||||
def test_date_parsing(raw, expected):
|
||||
assert metadata.get_date(raw) == expected
|
||||
|
||||
|
||||
def test_date_parsing_failure():
|
||||
with pytest.raises(metadata.ParseError):
|
||||
metadata.get_date("noop")
|
||||
|
||||
|
||||
def test_metadata_all_ignore_parse_errors_true(mocker):
|
||||
path = os.path.join(DATA_DIR, "sample.flac")
|
||||
data = metadata.Metadata(path)
|
||||
mocker.patch.object(data, "get", side_effect=metadata.ParseError("Failure"))
|
||||
assert data.all()["date"] is None
|
||||
|
||||
|
||||
def test_metadata_all_ignore_parse_errors_false(mocker):
|
||||
path = os.path.join(DATA_DIR, "sample.flac")
|
||||
data = metadata.Metadata(path)
|
||||
mocker.patch.object(data, "get", side_effect=metadata.ParseError("Failure"))
|
||||
with pytest.raises(metadata.ParseError):
|
||||
data.all(ignore_parse_errors=False)
|
||||
assert metadata.PermissiveDateField().to_internal_value(raw) == expected
|
||||
|
||||
|
||||
def test_metadata_fallback_ogg_theora(mocker):
|
||||
|
|
@ -264,3 +218,247 @@ def test_metadata_fallback_ogg_theora(mocker):
|
|||
assert data.get("pictures", "default") == expected_result
|
||||
|
||||
fallback_get.assert_called_once_with("pictures", "default")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"path, expected",
|
||||
[
|
||||
(
|
||||
"test.mp3",
|
||||
{
|
||||
"title": "Bend",
|
||||
"artists": [
|
||||
{
|
||||
"name": "Binärpilot",
|
||||
"mbid": uuid.UUID("9c6bddde-6228-4d9f-ad0d-03f6fcb19e13"),
|
||||
}
|
||||
],
|
||||
"album": {
|
||||
"title": "You Can't Stop Da Funk",
|
||||
"mbid": uuid.UUID("ce40cdb1-a562-4fd8-a269-9269f98d4124"),
|
||||
"release_date": datetime.date(2006, 2, 7),
|
||||
"artists": [
|
||||
{
|
||||
"name": "Binärpilot",
|
||||
"mbid": uuid.UUID("9c6bddde-6228-4d9f-ad0d-03f6fcb19e13"),
|
||||
}
|
||||
],
|
||||
},
|
||||
"position": 2,
|
||||
"disc_number": 1,
|
||||
"mbid": uuid.UUID("f269d497-1cc0-4ae4-a0c4-157ec7d73fcb"),
|
||||
"license": "https://creativecommons.org/licenses/by-nc-nd/2.5/",
|
||||
"copyright": "Someone",
|
||||
},
|
||||
),
|
||||
(
|
||||
"test.ogg",
|
||||
{
|
||||
"title": "Peer Gynt Suite no. 1, op. 46: I. Morning",
|
||||
"artists": [
|
||||
{
|
||||
"name": "Edvard Grieg",
|
||||
"mbid": uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
|
||||
}
|
||||
],
|
||||
"album": {
|
||||
"title": "Peer Gynt Suite no. 1, op. 46",
|
||||
"mbid": uuid.UUID("a766da8b-8336-47aa-a3ee-371cc41ccc75"),
|
||||
"release_date": datetime.date(2012, 8, 15),
|
||||
"artists": [
|
||||
{
|
||||
"name": "Edvard Grieg",
|
||||
"mbid": uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
|
||||
},
|
||||
{
|
||||
"name": "Musopen Symphony Orchestra",
|
||||
"mbid": uuid.UUID("5b4d7d2d-36df-4b38-95e3-a964234f520f"),
|
||||
},
|
||||
],
|
||||
},
|
||||
"position": 1,
|
||||
"disc_number": 1,
|
||||
"mbid": uuid.UUID("bd21ac48-46d8-4e78-925f-d9cc2a294656"),
|
||||
"license": "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/",
|
||||
"copyright": "Someone",
|
||||
},
|
||||
),
|
||||
(
|
||||
"test.opus",
|
||||
{
|
||||
"title": "Peer Gynt Suite no. 1, op. 46: I. Morning",
|
||||
"artists": [
|
||||
{
|
||||
"name": "Edvard Grieg",
|
||||
"mbid": uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
|
||||
}
|
||||
],
|
||||
"album": {
|
||||
"title": "Peer Gynt Suite no. 1, op. 46",
|
||||
"mbid": uuid.UUID("a766da8b-8336-47aa-a3ee-371cc41ccc75"),
|
||||
"release_date": datetime.date(2012, 8, 15),
|
||||
"artists": [
|
||||
{
|
||||
"name": "Edvard Grieg",
|
||||
"mbid": uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
|
||||
},
|
||||
{
|
||||
"name": "Musopen Symphony Orchestra",
|
||||
"mbid": uuid.UUID("5b4d7d2d-36df-4b38-95e3-a964234f520f"),
|
||||
},
|
||||
],
|
||||
},
|
||||
"position": 1,
|
||||
"disc_number": 1,
|
||||
"mbid": uuid.UUID("bd21ac48-46d8-4e78-925f-d9cc2a294656"),
|
||||
"license": "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/",
|
||||
"copyright": "Someone",
|
||||
},
|
||||
),
|
||||
(
|
||||
"test_theora.ogg",
|
||||
{
|
||||
"title": "Drei Kreuze (dass wir hier sind)",
|
||||
"artists": [
|
||||
{
|
||||
"name": "Die Toten Hosen",
|
||||
"mbid": uuid.UUID("c3bc80a6-1f4a-4e17-8cf0-6b1efe8302f1"),
|
||||
}
|
||||
],
|
||||
"album": {
|
||||
"title": "Ballast der Republik",
|
||||
"mbid": uuid.UUID("1f0441ad-e609-446d-b355-809c445773cf"),
|
||||
"release_date": datetime.date(2012, 5, 4),
|
||||
"artists": [
|
||||
{
|
||||
"name": "Die Toten Hosen",
|
||||
"mbid": uuid.UUID("c3bc80a6-1f4a-4e17-8cf0-6b1efe8302f1"),
|
||||
}
|
||||
],
|
||||
},
|
||||
"position": 1,
|
||||
"disc_number": 1,
|
||||
"mbid": uuid.UUID("124d0150-8627-46bc-bc14-789a3bc960c8"),
|
||||
# somehow, I cannot successfully create an ogg theora file
|
||||
# with the proper license field
|
||||
# ("license", "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/"),
|
||||
"copyright": "℗ 2012 JKP GmbH & Co. KG",
|
||||
},
|
||||
),
|
||||
(
|
||||
"sample.flac",
|
||||
{
|
||||
"title": "999,999",
|
||||
"artists": [
|
||||
{
|
||||
"name": "Nine Inch Nails",
|
||||
"mbid": uuid.UUID("b7ffd2af-418f-4be2-bdd1-22f8b48613da"),
|
||||
}
|
||||
],
|
||||
"album": {
|
||||
"title": "The Slip",
|
||||
"mbid": uuid.UUID("12b57d46-a192-499e-a91f-7da66790a1c1"),
|
||||
"release_date": datetime.date(2008, 5, 5),
|
||||
"artists": [
|
||||
{
|
||||
"name": "Nine Inch Nails",
|
||||
"mbid": uuid.UUID("b7ffd2af-418f-4be2-bdd1-22f8b48613da"),
|
||||
}
|
||||
],
|
||||
},
|
||||
"position": 1,
|
||||
"disc_number": 1,
|
||||
"mbid": uuid.UUID("30f3f33e-8d0c-4e69-8539-cbd701d18f28"),
|
||||
"license": "http://creativecommons.org/licenses/by-nc-sa/3.0/us/",
|
||||
"copyright": "2008 nin",
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_track_metadata_serializer(path, expected, mocker):
|
||||
path = os.path.join(DATA_DIR, path)
|
||||
data = metadata.Metadata(path)
|
||||
get_picture = mocker.patch.object(data, "get_picture")
|
||||
expected["cover_data"] = get_picture.return_value
|
||||
|
||||
serializer = metadata.TrackMetadataSerializer(data=data)
|
||||
assert serializer.is_valid(raise_exception=True) is True
|
||||
assert serializer.validated_data == expected
|
||||
|
||||
get_picture.assert_called_once_with("cover_front", "other")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"raw, expected",
|
||||
[
|
||||
(
|
||||
{
|
||||
"names": "Hello; World",
|
||||
"mbids": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcb; f269d497-1cc0-4ae4-a0c4-157ec7d73fcd ",
|
||||
},
|
||||
[
|
||||
{
|
||||
"name": "Hello",
|
||||
"mbid": uuid.UUID("f269d497-1cc0-4ae4-a0c4-157ec7d73fcb"),
|
||||
},
|
||||
{
|
||||
"name": "World",
|
||||
"mbid": uuid.UUID("f269d497-1cc0-4ae4-a0c4-157ec7d73fcd"),
|
||||
},
|
||||
],
|
||||
),
|
||||
(
|
||||
{
|
||||
"names": "Hello; World; Foo",
|
||||
"mbids": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcb; f269d497-1cc0-4ae4-a0c4-157ec7d73fcd ",
|
||||
},
|
||||
[
|
||||
{
|
||||
"name": "Hello",
|
||||
"mbid": uuid.UUID("f269d497-1cc0-4ae4-a0c4-157ec7d73fcb"),
|
||||
},
|
||||
{
|
||||
"name": "World",
|
||||
"mbid": uuid.UUID("f269d497-1cc0-4ae4-a0c4-157ec7d73fcd"),
|
||||
},
|
||||
{"name": "Foo", "mbid": None},
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_artists_cleaning(raw, expected):
|
||||
field = metadata.ArtistField()
|
||||
assert field.to_internal_value(raw) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"data, errored_field",
|
||||
[
|
||||
({"name": "Hello", "mbid": "wrong-uuid"}, "mbid"), # wrong uuid
|
||||
({"name": "", "mbid": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcd"}, "name"),
|
||||
],
|
||||
)
|
||||
def test_artist_serializer_validation(data, errored_field):
|
||||
serializer = metadata.ArtistSerializer(data=data)
|
||||
assert serializer.is_valid() is False
|
||||
|
||||
assert len(serializer.errors) == 1
|
||||
assert errored_field in serializer.errors
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"data, errored_field",
|
||||
[
|
||||
({"title": "Hello", "mbid": "wrong"}, "mbid"), # wrong uuid
|
||||
(
|
||||
{"title": "", "mbid": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcd"},
|
||||
"title",
|
||||
), # empty title
|
||||
],
|
||||
)
|
||||
def test_album_serializer_validation(data, errored_field):
|
||||
serializer = metadata.AlbumSerializer(data=data)
|
||||
assert serializer.is_valid() is False
|
||||
|
||||
assert len(serializer.errors) == 1
|
||||
assert errored_field in serializer.errors
|
||||
|
|
|
|||
|
|
@ -20,15 +20,13 @@ DATA_DIR = os.path.dirname(os.path.abspath(__file__))
|
|||
def test_can_create_track_from_file_metadata_no_mbid(db, mocker):
|
||||
metadata = {
|
||||
"title": "Test track",
|
||||
"artist": "Test artist",
|
||||
"album": "Test album",
|
||||
"date": datetime.date(2012, 8, 15),
|
||||
"track_number": 4,
|
||||
"artists": [{"name": "Test artist"}],
|
||||
"album": {"title": "Test album", "release_date": datetime.date(2012, 8, 15)},
|
||||
"position": 4,
|
||||
"disc_number": 2,
|
||||
"license": "Hello world: http://creativecommons.org/licenses/by-sa/4.0/",
|
||||
"copyright": "2018 Someone",
|
||||
}
|
||||
mocker.patch("funkwhale_api.music.metadata.Metadata.all", return_value=metadata)
|
||||
match_license = mocker.spy(licenses, "match")
|
||||
|
||||
track = tasks.get_track_from_import_metadata(metadata)
|
||||
|
|
@ -39,10 +37,10 @@ def test_can_create_track_from_file_metadata_no_mbid(db, mocker):
|
|||
assert track.disc_number == 2
|
||||
assert track.license.code == "cc-by-sa-4.0"
|
||||
assert track.copyright == metadata["copyright"]
|
||||
assert track.album.title == metadata["album"]
|
||||
assert track.album.title == metadata["album"]["title"]
|
||||
assert track.album.mbid is None
|
||||
assert track.album.release_date == datetime.date(2012, 8, 15)
|
||||
assert track.artist.name == metadata["artist"]
|
||||
assert track.artist.name == metadata["artists"][0]["name"]
|
||||
assert track.artist.mbid is None
|
||||
match_license.assert_called_once_with(metadata["license"], metadata["copyright"])
|
||||
|
||||
|
|
@ -50,33 +48,38 @@ def test_can_create_track_from_file_metadata_no_mbid(db, mocker):
|
|||
def test_can_create_track_from_file_metadata_mbid(factories, mocker):
|
||||
metadata = {
|
||||
"title": "Test track",
|
||||
"artist": "Test artist",
|
||||
"album_artist": "Test album artist",
|
||||
"album": "Test album",
|
||||
"date": datetime.date(2012, 8, 15),
|
||||
"track_number": 4,
|
||||
"musicbrainz_albumid": "ce40cdb1-a562-4fd8-a269-9269f98d4124",
|
||||
"musicbrainz_recordingid": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcb",
|
||||
"musicbrainz_artistid": "9c6bddde-6228-4d9f-ad0d-03f6fcb19e13",
|
||||
"musicbrainz_albumartistid": "9c6bddde-6478-4d9f-ad0d-03f6fcb19e13",
|
||||
"artists": [
|
||||
{"name": "Test artist", "mbid": "9c6bddde-6228-4d9f-ad0d-03f6fcb19e13"}
|
||||
],
|
||||
"album": {
|
||||
"title": "Test album",
|
||||
"release_date": datetime.date(2012, 8, 15),
|
||||
"mbid": "9c6bddde-6478-4d9f-ad0d-03f6fcb19e15",
|
||||
"artists": [
|
||||
{
|
||||
"name": "Test album artist",
|
||||
"mbid": "9c6bddde-6478-4d9f-ad0d-03f6fcb19e13",
|
||||
}
|
||||
],
|
||||
},
|
||||
"position": 4,
|
||||
"mbid": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcb",
|
||||
"cover_data": {"content": b"image_content", "mimetype": "image/png"},
|
||||
}
|
||||
|
||||
mocker.patch("funkwhale_api.music.metadata.Metadata.all", return_value=metadata)
|
||||
|
||||
track = tasks.get_track_from_import_metadata(metadata)
|
||||
|
||||
assert track.title == metadata["title"]
|
||||
assert track.mbid == metadata["musicbrainz_recordingid"]
|
||||
assert track.mbid == metadata["mbid"]
|
||||
assert track.position == 4
|
||||
assert track.disc_number is None
|
||||
assert track.album.title == metadata["album"]
|
||||
assert track.album.mbid == metadata["musicbrainz_albumid"]
|
||||
assert track.album.artist.mbid == metadata["musicbrainz_albumartistid"]
|
||||
assert track.album.artist.name == metadata["album_artist"]
|
||||
assert track.album.title == metadata["album"]["title"]
|
||||
assert track.album.mbid == metadata["album"]["mbid"]
|
||||
assert track.album.artist.mbid == metadata["album"]["artists"][0]["mbid"]
|
||||
assert track.album.artist.name == metadata["album"]["artists"][0]["name"]
|
||||
assert track.album.release_date == datetime.date(2012, 8, 15)
|
||||
assert track.artist.name == metadata["artist"]
|
||||
assert track.artist.mbid == metadata["musicbrainz_artistid"]
|
||||
assert track.artist.name == metadata["artists"][0]["name"]
|
||||
assert track.artist.mbid == metadata["artists"][0]["mbid"]
|
||||
|
||||
|
||||
def test_can_create_track_from_file_metadata_mbid_existing_album_artist(
|
||||
|
|
@ -85,22 +88,21 @@ def test_can_create_track_from_file_metadata_mbid_existing_album_artist(
|
|||
artist = factories["music.Artist"]()
|
||||
album = factories["music.Album"]()
|
||||
metadata = {
|
||||
"artist": "",
|
||||
"album": "",
|
||||
"album": {
|
||||
"mbid": album.mbid,
|
||||
"title": "",
|
||||
"artists": [{"name": "", "mbid": album.artist.mbid}],
|
||||
},
|
||||
"title": "Hello",
|
||||
"track_number": 4,
|
||||
"musicbrainz_albumid": album.mbid,
|
||||
"musicbrainz_recordingid": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcb",
|
||||
"musicbrainz_artistid": artist.mbid,
|
||||
"musicbrainz_albumartistid": album.artist.mbid,
|
||||
"position": 4,
|
||||
"artists": [{"mbid": artist.mbid, "name": ""}],
|
||||
"mbid": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcb",
|
||||
}
|
||||
|
||||
mocker.patch("funkwhale_api.music.metadata.Metadata.all", return_value=metadata)
|
||||
|
||||
track = tasks.get_track_from_import_metadata(metadata)
|
||||
|
||||
assert track.title == metadata["title"]
|
||||
assert track.mbid == metadata["musicbrainz_recordingid"]
|
||||
assert track.mbid == metadata["mbid"]
|
||||
assert track.position == 4
|
||||
assert track.album == album
|
||||
assert track.artist == artist
|
||||
|
|
@ -112,18 +114,17 @@ def test_can_create_track_from_file_metadata_fid_existing_album_artist(
|
|||
artist = factories["music.Artist"]()
|
||||
album = factories["music.Album"]()
|
||||
metadata = {
|
||||
"artist": "",
|
||||
"album": "",
|
||||
"artists": [{"name": "", "fid": artist.fid}],
|
||||
"album": {
|
||||
"title": "",
|
||||
"fid": album.fid,
|
||||
"artists": [{"name": "", "fid": album.artist.fid}],
|
||||
},
|
||||
"title": "Hello",
|
||||
"track_number": 4,
|
||||
"position": 4,
|
||||
"fid": "https://hello",
|
||||
"album_fid": album.fid,
|
||||
"artist_fid": artist.fid,
|
||||
"album_artist_fid": album.artist.fid,
|
||||
}
|
||||
|
||||
mocker.patch("funkwhale_api.music.metadata.Metadata.all", return_value=metadata)
|
||||
|
||||
track = tasks.get_track_from_import_metadata(metadata)
|
||||
|
||||
assert track.title == metadata["title"]
|
||||
|
|
@ -139,13 +140,11 @@ def test_can_create_track_from_file_metadata_distinct_release_mbid(factories):
|
|||
album = factories["music.Album"](artist=artist)
|
||||
track = factories["music.Track"](album=album, artist=artist)
|
||||
metadata = {
|
||||
"artist": artist.name,
|
||||
"album": album.title,
|
||||
"artists": [{"name": artist.name, "mbid": artist.mbid}],
|
||||
"album": {"title": album.title, "mbid": str(uuid.uuid4())},
|
||||
"title": track.title,
|
||||
"track_number": 4,
|
||||
"position": 4,
|
||||
"fid": "https://hello",
|
||||
"musicbrainz_artistid": artist.mbid,
|
||||
"musicbrainz_albumid": str(uuid.uuid4()),
|
||||
}
|
||||
|
||||
new_track = tasks.get_track_from_import_metadata(metadata)
|
||||
|
|
@ -162,12 +161,10 @@ def test_can_create_track_from_file_metadata_distinct_position(factories):
|
|||
album = factories["music.Album"](artist=artist)
|
||||
track = factories["music.Track"](album=album, artist=artist)
|
||||
metadata = {
|
||||
"artist": artist.name,
|
||||
"album": album.title,
|
||||
"artists": [{"name": artist.name, "mbid": artist.mbid}],
|
||||
"album": {"title": album.title, "mbid": album.mbid},
|
||||
"title": track.title,
|
||||
"track_number": track.position + 1,
|
||||
"musicbrainz_artistid": artist.mbid,
|
||||
"musicbrainz_albumid": album.mbid,
|
||||
"position": track.position + 1,
|
||||
}
|
||||
|
||||
new_track = tasks.get_track_from_import_metadata(metadata)
|
||||
|
|
@ -177,23 +174,28 @@ def test_can_create_track_from_file_metadata_distinct_position(factories):
|
|||
|
||||
def test_can_create_track_from_file_metadata_federation(factories, mocker, r_mock):
|
||||
metadata = {
|
||||
"artist": "Artist",
|
||||
"album": "Album",
|
||||
"album_artist": "Album artist",
|
||||
"artists": [
|
||||
{"name": "Artist", "fid": "https://artist.fid", "fdate": timezone.now()}
|
||||
],
|
||||
"album": {
|
||||
"title": "Album",
|
||||
"fid": "https://album.fid",
|
||||
"fdate": timezone.now(),
|
||||
"artists": [
|
||||
{
|
||||
"name": "Album artist",
|
||||
"fid": "https://album.artist.fid",
|
||||
"fdate": timezone.now(),
|
||||
}
|
||||
],
|
||||
},
|
||||
"title": "Hello",
|
||||
"track_number": 4,
|
||||
"position": 4,
|
||||
"fid": "https://hello",
|
||||
"album_fid": "https://album.fid",
|
||||
"artist_fid": "https://artist.fid",
|
||||
"album_artist_fid": "https://album.artist.fid",
|
||||
"fdate": timezone.now(),
|
||||
"album_fdate": timezone.now(),
|
||||
"album_artist_fdate": timezone.now(),
|
||||
"artist_fdate": timezone.now(),
|
||||
"cover_data": {"url": "https://cover/hello.png", "mimetype": "image/png"},
|
||||
}
|
||||
r_mock.get(metadata["cover_data"]["url"], body=io.BytesIO(b"coucou"))
|
||||
mocker.patch("funkwhale_api.music.metadata.Metadata.all", return_value=metadata)
|
||||
|
||||
track = tasks.get_track_from_import_metadata(metadata, update_cover=True)
|
||||
|
||||
|
|
@ -203,15 +205,15 @@ def test_can_create_track_from_file_metadata_federation(factories, mocker, r_moc
|
|||
assert track.position == 4
|
||||
assert track.album.cover.read() == b"coucou"
|
||||
assert track.album.cover.path.endswith(".png")
|
||||
assert track.album.fid == metadata["album_fid"]
|
||||
assert track.album.title == metadata["album"]
|
||||
assert track.album.creation_date == metadata["album_fdate"]
|
||||
assert track.album.artist.fid == metadata["album_artist_fid"]
|
||||
assert track.album.artist.name == metadata["album_artist"]
|
||||
assert track.album.artist.creation_date == metadata["album_artist_fdate"]
|
||||
assert track.artist.fid == metadata["artist_fid"]
|
||||
assert track.artist.name == metadata["artist"]
|
||||
assert track.artist.creation_date == metadata["artist_fdate"]
|
||||
assert track.album.fid == metadata["album"]["fid"]
|
||||
assert track.album.title == metadata["album"]["title"]
|
||||
assert track.album.creation_date == metadata["album"]["fdate"]
|
||||
assert track.album.artist.fid == metadata["album"]["artists"][0]["fid"]
|
||||
assert track.album.artist.name == metadata["album"]["artists"][0]["name"]
|
||||
assert track.album.artist.creation_date == metadata["album"]["artists"][0]["fdate"]
|
||||
assert track.artist.fid == metadata["artists"][0]["fid"]
|
||||
assert track.artist.name == metadata["artists"][0]["name"]
|
||||
assert track.artist.creation_date == metadata["artists"][0]["fdate"]
|
||||
|
||||
|
||||
def test_sort_candidates(factories):
|
||||
|
|
@ -391,7 +393,38 @@ def test_upload_import_error(factories, now, temp_signal):
|
|||
|
||||
assert upload.import_status == "errored"
|
||||
assert upload.import_date == now
|
||||
assert upload.import_details == {"error_code": "track_uuid_not_found"}
|
||||
assert upload.import_details == {
|
||||
"error_code": "track_uuid_not_found",
|
||||
"detail": None,
|
||||
}
|
||||
handler.assert_called_once_with(
|
||||
upload=upload,
|
||||
old_status="pending",
|
||||
new_status="errored",
|
||||
sender=None,
|
||||
signal=signals.upload_import_status_updated,
|
||||
)
|
||||
|
||||
|
||||
def test_upload_import_error_metadata(factories, now, temp_signal, mocker):
|
||||
path = os.path.join(DATA_DIR, "test.ogg")
|
||||
upload = factories["music.Upload"](audio_file__frompath=path)
|
||||
mocker.patch.object(
|
||||
metadata.AlbumField,
|
||||
"to_internal_value",
|
||||
side_effect=metadata.serializers.ValidationError("Hello"),
|
||||
)
|
||||
with temp_signal(signals.upload_import_status_updated) as handler:
|
||||
tasks.process_upload(upload_id=upload.pk)
|
||||
upload.refresh_from_db()
|
||||
|
||||
assert upload.import_status == "errored"
|
||||
assert upload.import_date == now
|
||||
assert upload.import_details == {
|
||||
"error_code": "invalid_metadata",
|
||||
"detail": {"album": ["Hello"]},
|
||||
"file_metadata": metadata.Metadata(path).all(),
|
||||
}
|
||||
handler.assert_called_once_with(
|
||||
upload=upload,
|
||||
old_status="pending",
|
||||
|
|
@ -494,31 +527,43 @@ def test_federation_audio_track_to_metadata(now):
|
|||
serializer = federation_serializers.TrackSerializer(data=payload)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
expected = {
|
||||
"artist": payload["artists"][0]["name"],
|
||||
"album": payload["album"]["name"],
|
||||
"album_artist": payload["album"]["artists"][0]["name"],
|
||||
"title": payload["name"],
|
||||
"date": released,
|
||||
"track_number": payload["position"],
|
||||
"position": payload["position"],
|
||||
"disc_number": payload["disc"],
|
||||
"license": "http://creativecommons.org/licenses/by-sa/4.0/",
|
||||
"copyright": "2018 Someone",
|
||||
# musicbrainz
|
||||
"musicbrainz_albumid": payload["album"]["musicbrainzId"],
|
||||
"musicbrainz_recordingid": payload["musicbrainzId"],
|
||||
"musicbrainz_artistid": payload["artists"][0]["musicbrainzId"],
|
||||
"musicbrainz_albumartistid": payload["album"]["artists"][0]["musicbrainzId"],
|
||||
# federation
|
||||
"fid": payload["id"],
|
||||
"album_fid": payload["album"]["id"],
|
||||
"artist_fid": payload["artists"][0]["id"],
|
||||
"album_artist_fid": payload["album"]["artists"][0]["id"],
|
||||
"mbid": payload["musicbrainzId"],
|
||||
"fdate": serializer.validated_data["published"],
|
||||
"artist_fdate": serializer.validated_data["artists"][0]["published"],
|
||||
"album_artist_fdate": serializer.validated_data["album"]["artists"][0][
|
||||
"published"
|
||||
"fid": payload["id"],
|
||||
"album": {
|
||||
"title": payload["album"]["name"],
|
||||
"release_date": released,
|
||||
"mbid": payload["album"]["musicbrainzId"],
|
||||
"fid": payload["album"]["id"],
|
||||
"fdate": serializer.validated_data["album"]["published"],
|
||||
"artists": [
|
||||
{
|
||||
"name": a["name"],
|
||||
"mbid": a["musicbrainzId"],
|
||||
"fid": a["id"],
|
||||
"fdate": serializer.validated_data["album"]["artists"][i][
|
||||
"published"
|
||||
],
|
||||
}
|
||||
for i, a in enumerate(payload["album"]["artists"])
|
||||
],
|
||||
},
|
||||
# musicbrainz
|
||||
# federation
|
||||
"artists": [
|
||||
{
|
||||
"name": a["name"],
|
||||
"mbid": a["musicbrainzId"],
|
||||
"fid": a["id"],
|
||||
"fdate": serializer.validated_data["artists"][i]["published"],
|
||||
}
|
||||
for i, a in enumerate(payload["artists"])
|
||||
],
|
||||
"album_fdate": serializer.validated_data["album"]["published"],
|
||||
"cover_data": {
|
||||
"mimetype": serializer.validated_data["album"]["cover"]["mediaType"],
|
||||
"url": serializer.validated_data["album"]["cover"]["href"],
|
||||
|
|
@ -528,10 +573,6 @@ def test_federation_audio_track_to_metadata(now):
|
|||
result = tasks.federation_audio_track_to_metadata(serializer.validated_data)
|
||||
assert result == expected
|
||||
|
||||
# ensure we never forget to test a mandatory field
|
||||
for k in metadata.ALL_FIELDS:
|
||||
assert k in result
|
||||
|
||||
|
||||
def test_scan_library_fetches_page_and_calls_scan_page(now, mocker, factories, r_mock):
|
||||
scan = factories["music.LibraryScan"]()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue