2020-09-11 07:20:30 +00:00
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System ;
using System.IO ;
using System.Linq ;
2021-10-20 07:48:32 +00:00
using System.Runtime.CompilerServices ;
2020-09-11 07:20:30 +00:00
using System.Threading.Tasks ;
using NUnit.Framework ;
using osu.Framework.Allocation ;
using osu.Framework.Platform ;
using osu.Game.IO.Archives ;
using osu.Game.Skinning ;
using SharpCompress.Archives.Zip ;
namespace osu.Game.Tests.Skins.IO
{
2020-09-18 09:05:33 +00:00
public class ImportSkinTest : ImportTest
2020-09-11 07:20:30 +00:00
{
2021-10-20 07:48:32 +00:00
#region Testing filename metadata inclusion
2020-09-11 07:20:30 +00:00
[Test]
2021-10-20 07:48:32 +00:00
public Task TestSingleImportDifferentFilename ( ) = > runSkinTest ( async osu = >
2020-09-11 07:20:30 +00:00
{
2021-10-20 07:48:32 +00:00
var imported = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( "test skin" , "skinner" ) , "skin.osk" ) ) ;
2020-09-11 07:20:30 +00:00
2021-10-20 07:48:32 +00:00
// When the import filename doesn't match, it should be appended (and update the skin.ini).
Assert . That ( imported . Name , Is . EqualTo ( "test skin [skin]" ) ) ;
Assert . That ( imported . Creator , Is . EqualTo ( "skinner" ) ) ;
} ) ;
2020-09-11 07:20:30 +00:00
[Test]
2021-10-20 07:48:32 +00:00
public Task TestSingleImportMatchingFilename ( ) = > runSkinTest ( async osu = >
2020-09-11 07:20:30 +00:00
{
2021-10-20 07:48:32 +00:00
var imported = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( "test skin" , "skinner" ) , "test skin.osk" ) ) ;
2020-09-11 07:20:30 +00:00
2021-10-20 07:48:32 +00:00
// When the import filename matches it shouldn't be appended.
Assert . That ( imported . Name , Is . EqualTo ( "test skin" ) ) ;
Assert . That ( imported . Creator , Is . EqualTo ( "skinner" ) ) ;
} ) ;
2020-09-11 07:20:30 +00:00
2021-10-20 07:48:32 +00:00
#endregion
2020-09-11 07:20:30 +00:00
2021-10-20 07:48:32 +00:00
#region Cases where imports should match existing
2021-10-20 06:22:47 +00:00
[Test]
2021-10-20 07:48:32 +00:00
public Task TestImportTwiceWithSameMetadataAndFilename ( ) = > runSkinTest ( async osu = >
2021-10-20 06:22:47 +00:00
{
2021-10-20 07:48:32 +00:00
var imported = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( "test skin" , "skinner" ) , "skin.osk" ) ) ;
var imported2 = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( "test skin" , "skinner" ) , "skin.osk" ) ) ;
2021-10-20 06:22:47 +00:00
2021-10-20 07:48:32 +00:00
assertImportedOnce ( imported , imported2 ) ;
} ) ;
2021-10-20 06:22:47 +00:00
2021-10-20 07:48:32 +00:00
[Test]
public Task TestImportTwiceWithNoMetadataSameDownloadFilename ( ) = > runSkinTest ( async osu = >
{
// if a user downloads two skins that do have skin.ini files but don't have any creator metadata in the skin.ini, they should both import separately just for safety.
var imported = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( string . Empty , string . Empty ) , "download.osk" ) ) ;
var imported2 = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( string . Empty , string . Empty ) , "download.osk" ) ) ;
2021-10-20 06:22:47 +00:00
2021-10-20 07:48:32 +00:00
assertImportedOnce ( imported , imported2 ) ;
} ) ;
2020-09-11 07:20:30 +00:00
2020-09-11 07:29:14 +00:00
[Test]
2021-10-20 07:48:32 +00:00
public Task TestImportUpperCasedOskArchive ( ) = > runSkinTest ( async osu = >
2020-09-11 07:29:14 +00:00
{
2021-10-20 07:48:32 +00:00
var imported = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( "name 1" , "author 1" ) , "name 1.OsK" ) ) ;
assertCorrectMetadata ( imported , "name 1" , "author 1" ) ;
2020-09-11 07:29:14 +00:00
2021-10-20 07:48:32 +00:00
var imported2 = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( "name 1" , "author 1" ) , "name 1.oSK" ) ) ;
2020-09-11 07:29:14 +00:00
2021-10-20 07:48:32 +00:00
assertImportedOnce ( imported , imported2 ) ;
} ) ;
2020-09-11 07:29:14 +00:00
2021-10-20 07:48:32 +00:00
#endregion
#region Cases where imports should be uniquely imported
2020-09-11 07:29:14 +00:00
2020-09-11 07:20:30 +00:00
[Test]
2021-10-20 07:48:32 +00:00
public Task TestImportTwiceWithSameMetadataButDifferentFilename ( ) = > runSkinTest ( async osu = >
2020-09-11 07:20:30 +00:00
{
2021-10-20 07:48:32 +00:00
var imported = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( "test skin" , "skinner" ) , "skin.osk" ) ) ;
var imported2 = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( "test skin" , "skinner" ) , "skin2.osk" ) ) ;
2020-09-11 07:20:30 +00:00
2021-10-20 07:48:32 +00:00
assertImportedBoth ( imported , imported2 ) ;
} ) ;
2020-09-11 07:20:30 +00:00
2021-10-20 07:48:32 +00:00
[Test]
public Task TestImportTwiceWithNoMetadataDifferentDownloadFilename ( ) = > runSkinTest ( async osu = >
{
// if a user downloads two skins that do have skin.ini files but don't have any creator metadata in the skin.ini, they should both import separately just for safety.
var imported = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( string . Empty , string . Empty ) , "download.osk" ) ) ;
var imported2 = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( string . Empty , string . Empty ) , "download2.osk" ) ) ;
2020-09-11 07:20:30 +00:00
2021-10-20 07:48:32 +00:00
assertImportedBoth ( imported , imported2 ) ;
} ) ;
2020-09-11 07:20:30 +00:00
2021-03-24 19:55:15 +00:00
[Test]
2021-10-20 07:48:32 +00:00
public Task TestImportTwiceWithSameFilenameDifferentMetadata ( ) = > runSkinTest ( async osu = >
2021-03-24 19:55:15 +00:00
{
2021-10-20 07:48:32 +00:00
var imported = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( "test skin v2" , "skinner" ) , "skin.osk" ) ) ;
var imported2 = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( "test skin v2.1" , "skinner" ) , "skin.osk" ) ) ;
2021-03-24 19:55:15 +00:00
2021-10-20 07:48:32 +00:00
assertImportedBoth ( imported , imported2 ) ;
assertCorrectMetadata ( imported , "test skin v2 [skin]" , "skinner" ) ;
assertCorrectMetadata ( imported2 , "test skin v2.1 [skin]" , "skinner" ) ;
} ) ;
2021-03-24 19:55:15 +00:00
2021-10-20 07:48:32 +00:00
[Test]
public Task TestSameMetadataNameDifferentFolderName ( ) = > runSkinTest ( async osu = >
{
var imported = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( "name 1" , "author 1" ) , "my custom skin 1" ) ) ;
var imported2 = await loadSkinIntoOsu ( osu , new ZipArchiveReader ( createOsk ( "name 1" , "author 1" ) , "my custom skin 2" ) ) ;
2021-03-24 19:55:15 +00:00
2021-10-20 07:48:32 +00:00
assertImportedBoth ( imported , imported2 ) ;
assertCorrectMetadata ( imported , "name 1 [my custom skin 2]" , "author 1" ) ;
assertCorrectMetadata ( imported , "name 1 [my custom skin 2]" , "author 1" ) ;
} ) ;
2021-03-24 19:55:15 +00:00
2021-10-20 07:48:32 +00:00
#endregion
2021-03-24 19:55:15 +00:00
2021-10-20 07:48:32 +00:00
private void assertCorrectMetadata ( SkinInfo imported , string name , string creator )
2021-08-23 11:25:46 +00:00
{
2021-10-20 07:48:32 +00:00
Assert . That ( imported . Name , Is . EqualTo ( name ) ) ;
Assert . That ( imported . Creator , Is . EqualTo ( creator ) ) ;
}
2021-08-23 11:25:46 +00:00
2021-10-20 07:48:32 +00:00
private void assertImportedBoth ( SkinInfo imported , SkinInfo imported2 )
{
Assert . That ( imported2 . ID , Is . Not . EqualTo ( imported . ID ) ) ;
Assert . That ( imported2 . Hash , Is . Not . EqualTo ( imported . Hash ) ) ;
Assert . That ( imported2 . Files . Select ( f = > f . FileInfoID ) , Is . Not . EquivalentTo ( imported . Files . Select ( f = > f . FileInfoID ) ) ) ;
}
2021-08-23 11:25:46 +00:00
2021-10-20 07:48:32 +00:00
private void assertImportedOnce ( SkinInfo imported , SkinInfo imported2 )
{
Assert . That ( imported2 . ID , Is . EqualTo ( imported . ID ) ) ;
Assert . That ( imported2 . Hash , Is . EqualTo ( imported . Hash ) ) ;
Assert . That ( imported2 . Files . Select ( f = > f . FileInfoID ) , Is . EquivalentTo ( imported . Files . Select ( f = > f . FileInfoID ) ) ) ;
2021-08-23 11:25:46 +00:00
}
2021-10-20 07:48:32 +00:00
private MemoryStream createOsk ( string name , string author , bool makeUnique = false )
2020-09-11 07:20:30 +00:00
{
var zipStream = new MemoryStream ( ) ;
using var zip = ZipArchive . Create ( ) ;
2021-08-23 11:25:46 +00:00
zip . AddEntry ( "skin.ini" , generateSkinIni ( name , author , makeUnique ) ) ;
2020-09-11 07:20:30 +00:00
zip . SaveTo ( zipStream ) ;
return zipStream ;
}
2021-08-23 11:25:46 +00:00
private MemoryStream generateSkinIni ( string name , string author , bool makeUnique = true )
2020-09-11 07:20:30 +00:00
{
var stream = new MemoryStream ( ) ;
var writer = new StreamWriter ( stream ) ;
writer . WriteLine ( "[General]" ) ;
writer . WriteLine ( $"Name: {name}" ) ;
writer . WriteLine ( $"Author: {author}" ) ;
2021-08-23 11:25:46 +00:00
if ( makeUnique )
{
writer . WriteLine ( ) ;
writer . WriteLine ( $"# unique {Guid.NewGuid()}" ) ;
}
2020-09-11 07:20:30 +00:00
writer . Flush ( ) ;
return stream ;
}
2021-10-20 07:48:32 +00:00
private async Task runSkinTest ( Func < OsuGameBase , Task > action , [ CallerMemberName ] string callingMethodName = @"" )
{
using ( HeadlessGameHost host = new CleanRunHeadlessGameHost ( callingMethodName ) )
{
try
{
var osu = LoadOsuIntoHost ( host ) ;
await action ( osu ) ;
}
finally
{
host . Exit ( ) ;
}
}
}
2020-09-18 09:05:33 +00:00
private async Task < SkinInfo > loadSkinIntoOsu ( OsuGameBase osu , ArchiveReader archive = null )
2020-09-11 07:20:30 +00:00
{
var skinManager = osu . Dependencies . Get < SkinManager > ( ) ;
2021-09-30 10:33:12 +00:00
return ( await skinManager . Import ( archive ) ) . Value ;
2020-09-11 07:20:30 +00:00
}
}
}