using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.Parser; using NzbDrone.Core.Qualities; using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.ParserTests { [TestFixture] public class QualityParserFixture : CoreTest { public static object[] SelfQualityParserCases = { new object[] { Quality.MP3_192 }, new object[] { Quality.MP3_VBR }, new object[] { Quality.MP3_256 }, new object[] { Quality.MP3_320 }, new object[] { Quality.MP3_VBR_V2 }, new object[] { Quality.WAV }, new object[] { Quality.WMA }, new object[] { Quality.AAC_192 }, new object[] { Quality.AAC_256 }, new object[] { Quality.AAC_320 }, new object[] { Quality.AAC_VBR }, new object[] { Quality.ALAC }, new object[] { Quality.FLAC }, }; [TestCase("", "MPEG Version 1 Audio, Layer 3", 96)] public void should_parse_mp3_96_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_096); } [TestCase("", "MPEG Version 1 Audio, Layer 3", 128)] public void should_parse_mp3_128_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_128); } [TestCase("", "MPEG Version 1 Audio, Layer 3", 160)] public void should_parse_mp3_160_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_160); } [TestCase("VA - The Best 101 Love Ballads (2017) MP3 [192 kbps]", null, 0)] [TestCase("ATCQ - The Love Movement 1998 2CD 192kbps RIP", null, 0)] [TestCase("A Tribe Called Quest - The Love Movement 1998 2CD [192kbps] RIP", null, 0)] [TestCase("Maula - Jism 2 [2012] Mp3 - 192Kbps [Extended]- TK", null, 0)] [TestCase("VA - Complete Clubland - The Ultimate Ride Of Your Lfe [2014][MP3][192 kbps]", null, 0)] [TestCase("Complete Clubland - The Ultimate Ride Of Your Lfe [2014][MP3](192kbps)", null, 0)] [TestCase("The Ultimate Ride Of Your Lfe [192 KBPS][2014][MP3]", null, 0)] [TestCase("Gary Clark Jr - Live North America 2016 (2017) MP3 192kbps", null, 0)] [TestCase("Some Song [192][2014][MP3]", null, 0)] [TestCase("Other Song (192)[2014][MP3]", null, 0)] [TestCase("", "MPEG Version 1 Audio, Layer 3", 192)] public void should_parse_mp3_192_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_192); } [TestCase("Caetano Veloso Discografia Completa MP3 @256", null, 0)] [TestCase("Ricky Martin - A Quien Quiera Escuchar (2015) 256 kbps [GloDLS]", null, 0)] [TestCase("Jake Bugg - Jake Bugg (Album) [2012] {MP3 256 kbps}", null, 0)] [TestCase("Clean Bandit - New Eyes [2014] [Mp3-256]-V3nom [GLT]", null, 0)] [TestCase("Armin van Buuren - A State Of Trance 810 (20.04.2017) 256 kbps", null, 0)] [TestCase("PJ Harvey - Let England Shake [mp3-256-2011][trfkad]", null, 0)] [TestCase("", "MPEG Version 1 Audio, Layer 3", 256)] public void should_parse_mp3_256_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_256); } [TestCase("Beyoncé Lemonade [320] 2016 Beyonce Lemonade [320] 2016", null, 0)] [TestCase("Childish Gambino - Awaken, My Love Album 2016 mp3 320 Kbps", null, 0)] [TestCase("Maluma – Felices Los 4 MP3 320 Kbps 2017 Download", null, 0)] [TestCase("Ricardo Arjona - APNEA (Single 2014) (320 kbps)", null, 0)] [TestCase("Kehlani - SweetSexySavage (Deluxe Edition) (2017) 320", null, 0)] [TestCase("Anderson Paak - Malibu (320)(2016)", null, 0)] [TestCase("Zeynep_Erbay-Flashlights_On_Love-WEB-2022-BABAS", null, 0)] [TestCase("", "MPEG Version 1 Audio, Layer 3", 320)] public void should_parse_mp3_320_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_320); } [TestCase("Sia - This Is Acting (Standard Edition) [2016-Web-MP3-V0(VBR)]", null, 0)] [TestCase("Mount Eerie - A Crow Looked at Me (2017) [MP3 V0 VBR)]", null, 0)] public void should_parse_mp3_vbr_v0_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_VBR); } // TODO Parser should look at bitrate range for quality to determine level of VBR [TestCase("", "MPEG Version 1 Audio, Layer 3 VBR", 298)] [Ignore("Parser should look at bitrate range for quality to determine level of VBR")] public void should_parse_mp3_vbr_v2_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_VBR_V2); } [TestCase("Kendrick Lamar - DAMN (2017) FLAC", null, 0)] [TestCase("Kid_Cudi-Entergalactic-WEBFLAC-2022-NACHOS", null, 0)] [TestCase("Alicia Keys - Vault Playlist Vol. 1 (2017) [FLAC CD]", null, 0)] [TestCase("Gorillaz - Humanz (Deluxe) - lossless FLAC Tracks - 2017 - CDrip", null, 0)] [TestCase("David Bowie - Blackstar (2016) [FLAC]", null, 0)] [TestCase("The Cure - Greatest Hits (2001) FLAC Soup", null, 0)] [TestCase("Slowdive- Souvlaki (FLAC)", null, 0)] [TestCase("John Coltrane - Kulu Se Mama (1965) [EAC-FLAC]", null, 0)] [TestCase("The Rolling Stones - The Very Best Of '75-'94 (1995) {FLAC}", null, 0)] [TestCase("Migos-No_Label_II-CD-FLAC-2014-FORSAKEN", null, 0)] [TestCase("ADELE 25 CD FLAC 2015 PERFECT", null, 0)] [TestCase("", "Flac Audio", 1057)] public void should_parse_flac_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.FLAC); } [TestCase("Beck.-.Guero.2005.[2016.Remastered].24bit.96kHz.LOSSLESS.FLAC", null, 0, 0)] [TestCase("[R.E.M - Lifes Rich Pageant(1986) [24bit192kHz 2016 Remaster]LOSSLESS FLAC]", null, 0, 0)] [TestCase("Kid_Cudi-Entergalactic-24BIT-WEBFLAC-2022-NACHOS", null, 0, 0)] [TestCase("", "Flac Audio", 5057, 24)] public void should_parse_flac_24bit_quality(string title, string desc, int bitrate, int sampleSize) { ParseAndVerifyQuality(title, desc, bitrate, Quality.FLAC_24, sampleSize); } [TestCase("", "Microsoft WMA2 Audio", 218)] public void should_parse_wma_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.WMA); } [TestCase("", "PCM Audio", 1411)] public void should_parse_wav_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.WAV); } [TestCase("Chuck Berry Discography ALAC", null, 0)] [TestCase("A$AP Rocky - LONG LIVE A$AP Deluxe asap[ALAC]", null, 0)] [TestCase("", "MPEG-4 Audio (alac)", 0)] public void should_parse_alac_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.ALAC); } [TestCase("Stevie Ray Vaughan Discography (1981-1987) [APE]", null, 0)] [TestCase("Brain Ape - Rig it [2014][ape]", null, 0)] [TestCase("", "Monkey's Audio", 0)] public void should_parse_ape_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.APE); } [TestCase("Arctic Monkeys - AM {2013-Album}", null, 0)] [TestCase("Audio Adrinaline - Audio Adrinaline", null, 0)] [TestCase("Audio Adrinaline - Audio Adrinaline [Mixtape FLAC]", null, 0)] [TestCase("Brain Ape - Rig it [2014][flac]", null, 0)] [TestCase("Coil - The Ape Of Naples(2005) (FLAC)", null, 0)] public void should_not_parse_ape_quality(string title, string desc, int bitrate) { var result = QualityParser.ParseQuality(title, desc, bitrate); result.Quality.Should().NotBe(Quality.APE); } [TestCase("Opus - Drums Unlimited (1966) [Flac]", null, 0)] public void should_not_parse_opus_quality(string title, string desc, int bitrate) { var result = QualityParser.ParseQuality(title, desc, bitrate); result.Quality.Should().Be(Quality.FLAC); } [TestCase("Max Roach - Drums Unlimited (1966) [WavPack]", null, 0)] [TestCase("Roxette - Charm School(2011) (2CD) [WV]", null, 0)] [TestCase("", "WavPack", 0)] public void should_parse_wavpack_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.WAVPACK); } [TestCase("Milky Chance - Sadnecessary [256 Kbps] [M4A]", null, 0)] [TestCase("Little Mix - Salute [Deluxe Edition] [2013] [M4A-256]-V3nom [GLT", null, 0)] [TestCase("X-Men Soundtracks (2006-2014) AAC, 256 kbps", null, 0)] [TestCase("The Weeknd - The Hills - Single[iTunes Plus AAC M4A]", null, 0)] [TestCase("Walk the Line Soundtrack (2005) [AAC, 256 kbps]", null, 0)] [TestCase("Firefly Soundtrack(2007 (2002-2003)) [AAC, 256 kbps VBR]", null, 0)] public void should_parse_aac_256_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.AAC_256); } [TestCase("", "MPEG-4 Audio (mp4a)", 320)] [TestCase("", "MPEG-4 Audio (drms)", 320)] public void should_parse_aac_320_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.AAC_320); } [TestCase("", "MPEG-4 Audio (mp4a)", 321)] [TestCase("", "MPEG-4 Audio (drms)", 321)] public void should_parse_aac_vbr_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.AAC_VBR); } [TestCase("Kirlian Camera - The Ice Curtain - Album 1998 - Ogg-Vorbis Q10", null, 0)] [TestCase("", "Vorbis Version 0 Audio", 500)] [TestCase("", "Opus Version 1 Audio", 501)] public void should_parse_vorbis_q10_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.VORBIS_Q10); } [TestCase("", "Vorbis Version 0 Audio", 320)] [TestCase("", "Opus Version 1 Audio", 321)] public void should_parse_vorbis_q9_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.VORBIS_Q9); } [TestCase("Various Artists - No New York [1978/Ogg/q8]", null, 0)] [TestCase("", "Vorbis Version 0 Audio", 256)] [TestCase("", "Opus Version 1 Audio", 257)] public void should_parse_vorbis_q8_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.VORBIS_Q8); } [TestCase("Masters_At_Work-Nuyorican_Soul-.Talkin_Loud.-1997-OGG.Q7", null, 0)] [TestCase("", "Vorbis Version 0 Audio", 224)] [TestCase("", "Opus Version 1 Audio", 225)] public void should_parse_vorbis_q7_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.VORBIS_Q7); } [TestCase("", "Vorbis Version 0 Audio", 192)] [TestCase("", "Opus Version 1 Audio", 193)] public void should_parse_vorbis_q6_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.VORBIS_Q6); } [TestCase("", "Vorbis Version 0 Audio", 160)] [TestCase("", "Opus Version 1 Audio", 161)] public void should_parse_vorbis_q5_quality(string title, string desc, int bitrate) { ParseAndVerifyQuality(title, desc, bitrate, Quality.VORBIS_Q5); } // Flack doesn't get match for 'FLAC' quality [TestCase("Roberta Flack 2006 - The Very Best of")] public void should_not_parse_flac_quality(string title) { ParseAndVerifyQuality(title, null, 0, Quality.Unknown); } [TestCase("The Chainsmokers & Coldplay - Something Just Like This")] [TestCase("Frank Ocean Blonde 2016")] // TODO: This should be parsed as Unknown and not MP3-96 // [TestCase("A - NOW Thats What I Call Music 96 (2017) [Mp3~Kbps]")] [TestCase("Queen - The Ultimate Best Of Queen(2011)[mp3]")] [TestCase("Maroon 5 Ft Kendrick Lamar -Dont Wanna Know MP3 2016")] public void quality_parse(string title) { ParseAndVerifyQuality(title, null, 0, Quality.Unknown); } [Test] [TestCaseSource(nameof(SelfQualityParserCases))] public void parsing_our_own_quality_enum_name(Quality quality) { var fileName = string.Format("Some album [{0}]", quality.Name); var result = QualityParser.ParseQuality(fileName, null, 0); result.Quality.Should().Be(quality); } [TestCase("Little Mix - Salute [Deluxe Edition] [2013] [M4A-256]-V3nom [GLT")] public void should_parse_quality_from_name(string title) { QualityParser.ParseQuality(title, null, 0).QualityDetectionSource.Should().Be(QualityDetectionSource.Name); } [TestCase("01. Kanye West - Ultralight Beam.mp3")] [TestCase("01. Kanye West - Ultralight Beam.ogg")] // These get detected by name as we are looking for the extensions as identifiers for release names // [TestCase("01. Kanye West - Ultralight Beam.m4a")] // [TestCase("01. Kanye West - Ultralight Beam.wma")] // [TestCase("01. Kanye West - Ultralight Beam.wav")] public void should_parse_quality_from_extension(string title) { QualityParser.ParseQuality(title, null, 0).QualityDetectionSource.Should().Be(QualityDetectionSource.Extension); } [Test] public void should_parse_null_quality_description_as_unknown() { QualityParser.ParseCodec(null, null).Should().Be(Codec.Unknown); } [TestCase("Artist Title - Album Title 2017 REPACK FLAC aAF", true)] [TestCase("Artist Title - Album Title 2017 RERIP FLAC aAF", true)] [TestCase("Artist Title - Album Title 2017 PROPER FLAC aAF", false)] public void should_be_able_to_parse_repack(string title, bool isRepack) { var result = QualityParser.ParseQuality(title, null, 0); result.Revision.Version.Should().Be(2); result.Revision.IsRepack.Should().Be(isRepack); } private void ParseAndVerifyQuality(string name, string desc, int bitrate, Quality quality, int sampleSize = 0) { var result = QualityParser.ParseQuality(name, desc, bitrate, sampleSize); result.Quality.Should().Be(quality); } } }