2024-03-17 00:06:13 +01:00
// ----------------------------------------------------------------------------------------------
2020-10-21 18:41:20 +02:00
// _ _ _ ____ _ _____
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
2024-03-17 00:06:13 +01:00
// ----------------------------------------------------------------------------------------------
2024-03-17 02:35:40 +01:00
// |
2025-01-05 02:40:56 +01:00
// Copyright 2015-2025 Łukasz "JustArchi" Domeradzki
2020-10-21 18:41:20 +02:00
// Contact: JustArchi@JustArchi.net
2024-03-17 02:35:40 +01:00
// |
2020-10-21 18:41:20 +02:00
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
2024-03-17 02:35:40 +01:00
// |
2020-10-21 18:41:20 +02:00
// http://www.apache.org/licenses/LICENSE-2.0
2024-03-17 02:35:40 +01:00
// |
2020-10-21 18:41:20 +02:00
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System ;
using System.Collections.Generic ;
2024-06-25 00:18:13 +02:00
using System.Diagnostics.CodeAnalysis ;
2020-10-21 18:41:20 +02:00
using System.Linq ;
2024-08-11 02:21:00 +02:00
using System.Reflection ;
using System.Text.Json.Nodes ;
using ArchiSteamFarm.Core ;
using ArchiSteamFarm.Helpers.Json ;
2021-05-08 01:37:22 +02:00
using ArchiSteamFarm.Steam.Data ;
2024-08-11 02:21:00 +02:00
using ArchiSteamFarm.Steam.Storage ;
using ArchiSteamFarm.Storage ;
2020-10-21 18:41:20 +02:00
using Microsoft.VisualStudio.TestTools.UnitTesting ;
2021-06-14 00:32:23 +02:00
using static ArchiSteamFarm . Steam . Bot ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
namespace ArchiSteamFarm.Tests ;
2024-06-25 00:18:13 +02:00
#pragma warning disable CA1812 // False positive, the class is used during MSTest
2021-11-10 21:23:24 +01:00
[TestClass]
2024-06-25 00:18:13 +02:00
internal sealed class Bot {
2024-09-22 20:42:44 +02:00
internal static Steam . Bot GenerateBot ( string botName = "Test" ) {
ArgumentException . ThrowIfNullOrEmpty ( botName ) ;
2024-08-11 02:21:00 +02:00
ConstructorInfo ? constructor = typeof ( Steam . Bot ) . GetConstructor ( BindingFlags . Instance | BindingFlags . NonPublic , [ typeof ( string ) , typeof ( BotConfig ) , typeof ( BotDatabase ) ] ) ;
if ( constructor = = null ) {
throw new InvalidOperationException ( nameof ( constructor ) ) ;
}
2025-03-08 15:00:38 +01:00
JsonObject emptyObject = new ( ) ;
2024-08-11 02:21:00 +02:00
BotConfig ? botConfig = emptyObject . ToJsonObject < BotConfig > ( ) ;
if ( botConfig = = null ) {
throw new InvalidOperationException ( nameof ( botConfig ) ) ;
}
BotDatabase ? botDatabase = emptyObject . ToJsonObject < BotDatabase > ( ) ;
if ( botDatabase = = null ) {
throw new InvalidOperationException ( nameof ( botDatabase ) ) ;
}
ASF . GlobalDatabase ? ? = emptyObject . ToJsonObject < GlobalDatabase > ( ) ;
2024-09-22 20:42:44 +02:00
if ( constructor . Invoke ( [ botName , botConfig , botDatabase ] ) is not Steam . Bot result ) {
2024-08-11 02:21:00 +02:00
throw new InvalidOperationException ( nameof ( result ) ) ;
}
return result ;
}
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void MaxItemsBarelyEnoughForOneSet ( ) {
2021-11-10 21:23:24 +01:00
const uint relevantAppID = 42 ;
2021-01-18 14:58:25 +01:00
2021-11-10 21:23:24 +01:00
Dictionary < uint , byte > itemsPerSet = new ( ) {
{ relevantAppID , MinCardsPerBadge } ,
{ 43 , MinCardsPerBadge + 1 }
} ;
2021-01-18 14:58:25 +01:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [ ] ;
2021-01-18 14:58:25 +01:00
2021-11-10 21:23:24 +01:00
foreach ( ( uint appID , byte cards ) in itemsPerSet ) {
for ( byte i = 1 ; i < = cards ; i + + ) {
2024-03-17 02:29:04 +01:00
items . Add ( CreateCard ( i , realAppID : appID ) ) ;
2021-11-10 21:23:24 +01:00
}
2021-01-18 14:58:25 +01:00
}
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , itemsPerSet , MinCardsPerBadge ) ;
2021-01-18 14:58:25 +01:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = items . Where ( static item = > item . RealAppID = = relevantAppID ) . GroupBy ( static item = > ( item . RealAppID , item . ContextID , item . ClassID ) ) . ToDictionary ( static group = > group . Key , static group = > ( uint ) group . Sum ( static item = > item . Amount ) ) ;
2021-01-18 14:58:25 +01:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2021-01-18 14:58:25 +01:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void MaxItemsTooSmall ( ) {
2021-11-10 21:23:24 +01:00
const uint appID = 42 ;
2021-01-18 14:58:25 +01:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID ) ,
CreateCard ( 2 , realAppID : appID )
2023-12-11 23:55:13 +01:00
] ;
2021-01-18 14:58:25 +01:00
2025-02-13 00:20:10 +01:00
Assert . ThrowsExactly < ArgumentOutOfRangeException > ( ( ) = > GetItemsForFullBadge ( items , 2 , appID , MinCardsPerBadge - 1 ) ) ;
2021-11-10 21:23:24 +01:00
}
2021-01-18 14:58:25 +01:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void MoreCardsThanNeeded ( ) {
2021-11-10 21:23:24 +01:00
const uint appID = 42 ;
2021-01-18 14:58:25 +01:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID ) ,
CreateCard ( 1 , realAppID : appID ) ,
CreateCard ( 2 , realAppID : appID ) ,
CreateCard ( 3 , realAppID : appID )
2023-12-11 23:55:13 +01:00
] ;
2021-01-18 14:58:25 +01:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , 3 , appID ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( ) {
{ ( appID , Asset . SteamCommunityContextID , 1 ) , 1 } ,
{ ( appID , Asset . SteamCommunityContextID , 2 ) , 1 } ,
{ ( appID , Asset . SteamCommunityContextID , 3 ) , 1 }
} ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void MultipleSets ( ) {
2021-11-10 21:23:24 +01:00
const uint appID = 42 ;
2020-10-21 18:41:20 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID ) ,
CreateCard ( 1 , realAppID : appID ) ,
CreateCard ( 2 , realAppID : appID ) ,
CreateCard ( 2 , realAppID : appID )
2023-12-11 23:55:13 +01:00
] ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , 2 , appID ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( ) {
{ ( appID , Asset . SteamCommunityContextID , 1 ) , 2 } ,
{ ( appID , Asset . SteamCommunityContextID , 2 ) , 2 }
} ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void MultipleSetsDifferentAmount ( ) {
2021-11-10 21:23:24 +01:00
const uint appID = 42 ;
2020-10-21 18:41:20 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , amount : 2 , realAppID : appID ) ,
CreateCard ( 2 , realAppID : appID ) ,
CreateCard ( 2 , realAppID : appID )
2023-12-11 23:55:13 +01:00
] ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , 2 , appID ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( ) {
{ ( appID , Asset . SteamCommunityContextID , 1 ) , 2 } ,
{ ( appID , Asset . SteamCommunityContextID , 2 ) , 2 }
} ;
2020-10-21 18:48:13 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2020-10-21 18:48:13 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void MutliRarityAndType ( ) {
2021-11-10 21:23:24 +01:00
const uint appID = 42 ;
2020-10-21 18:48:13 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID , type : EAssetType . TradingCard , rarity : EAssetRarity . Common ) ,
CreateCard ( 2 , realAppID : appID , type : EAssetType . TradingCard , rarity : EAssetRarity . Common ) ,
2020-10-21 18:48:13 +02:00
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID , type : EAssetType . FoilTradingCard , rarity : EAssetRarity . Uncommon ) ,
CreateCard ( 2 , realAppID : appID , type : EAssetType . FoilTradingCard , rarity : EAssetRarity . Uncommon ) ,
2020-10-21 18:48:13 +02:00
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID , type : EAssetType . FoilTradingCard , rarity : EAssetRarity . Rare ) ,
CreateCard ( 2 , realAppID : appID , type : EAssetType . FoilTradingCard , rarity : EAssetRarity . Rare ) ,
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
// for better readability and easier verification when thinking about this test the items that shall be selected for sending are the ones below this comment
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID , type : EAssetType . TradingCard , rarity : EAssetRarity . Uncommon ) ,
CreateCard ( 2 , realAppID : appID , type : EAssetType . TradingCard , rarity : EAssetRarity . Uncommon ) ,
CreateCard ( 3 , realAppID : appID , type : EAssetType . TradingCard , rarity : EAssetRarity . Uncommon ) ,
2020-10-21 18:41:20 +02:00
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID , type : EAssetType . FoilTradingCard , rarity : EAssetRarity . Common ) ,
CreateCard ( 3 , realAppID : appID , type : EAssetType . FoilTradingCard , rarity : EAssetRarity . Common ) ,
CreateCard ( 7 , realAppID : appID , type : EAssetType . FoilTradingCard , rarity : EAssetRarity . Common ) ,
2020-10-21 18:41:20 +02:00
2024-03-17 02:29:04 +01:00
CreateCard ( 2 , realAppID : appID , type : EAssetType . Unknown , rarity : EAssetRarity . Rare ) ,
CreateCard ( 3 , realAppID : appID , type : EAssetType . Unknown , rarity : EAssetRarity . Rare ) ,
CreateCard ( 4 , realAppID : appID , type : EAssetType . Unknown , rarity : EAssetRarity . Rare )
2023-12-11 23:55:13 +01:00
] ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , 3 , appID ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( ) {
{ ( appID , Asset . SteamCommunityContextID , 1 ) , 2 } ,
{ ( appID , Asset . SteamCommunityContextID , 2 ) , 2 } ,
{ ( appID , Asset . SteamCommunityContextID , 3 ) , 3 } ,
{ ( appID , Asset . SteamCommunityContextID , 4 ) , 1 } ,
{ ( appID , Asset . SteamCommunityContextID , 7 ) , 1 }
} ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void NotAllCardsPresent ( ) {
2021-11-10 21:23:24 +01:00
const uint appID = 42 ;
2020-10-21 18:48:13 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID ) ,
CreateCard ( 2 , realAppID : appID )
2023-12-11 23:55:13 +01:00
] ;
2020-10-21 18:48:13 +02:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , 3 , appID ) ;
2020-10-21 18:48:13 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( 0 ) ;
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2020-10-21 18:48:13 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void OneSet ( ) {
2021-11-10 21:23:24 +01:00
const uint appID = 42 ;
2020-10-21 18:48:13 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID ) ,
CreateCard ( 2 , realAppID : appID )
2023-12-11 23:55:13 +01:00
] ;
2020-10-21 18:48:13 +02:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , 2 , appID ) ;
2020-10-21 18:48:13 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( ) {
{ ( appID , Asset . SteamCommunityContextID , 1 ) , 1 } ,
{ ( appID , Asset . SteamCommunityContextID , 2 ) , 1 }
} ;
2020-10-21 18:48:13 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2020-10-21 18:48:13 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void OtherAppIDFullSets ( ) {
2021-11-10 21:23:24 +01:00
const uint appID0 = 42 ;
const uint appID1 = 43 ;
2020-10-21 18:48:13 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID0 ) ,
CreateCard ( 1 , realAppID : appID1 )
2023-12-11 23:55:13 +01:00
] ;
2020-10-21 18:48:13 +02:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge (
items , new Dictionary < uint , byte > {
{ appID0 , 1 } ,
{ appID1 , 1 }
}
) ;
2020-10-21 18:48:13 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( ) {
{ ( appID0 , Asset . SteamCommunityContextID , 1 ) , 1 } ,
{ ( appID1 , Asset . SteamCommunityContextID , 1 ) , 1 }
} ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void OtherAppIDNoSets ( ) {
2021-11-10 21:23:24 +01:00
const uint appID0 = 42 ;
const uint appID1 = 43 ;
2020-10-21 18:41:20 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID0 ) ,
CreateCard ( 1 , realAppID : appID1 )
2023-12-11 23:55:13 +01:00
] ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge (
items , new Dictionary < uint , byte > {
{ appID0 , 2 } ,
{ appID1 , 2 }
}
) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( 0 ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void OtherAppIDOneSet ( ) {
2021-11-10 21:23:24 +01:00
const uint appID0 = 42 ;
const uint appID1 = 43 ;
const uint appID2 = 44 ;
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID0 ) ,
CreateCard ( 2 , realAppID : appID0 ) ,
2021-11-10 21:23:24 +01:00
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID1 ) ,
CreateCard ( 2 , realAppID : appID1 ) ,
CreateCard ( 3 , realAppID : appID1 )
2023-12-11 23:55:13 +01:00
] ;
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge (
items , new Dictionary < uint , byte > {
{ appID0 , 3 } ,
{ appID1 , 3 } ,
{ appID2 , 3 }
}
) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( ) {
{ ( appID1 , Asset . SteamCommunityContextID , 1 ) , 1 } ,
{ ( appID1 , Asset . SteamCommunityContextID , 2 ) , 1 } ,
{ ( appID1 , Asset . SteamCommunityContextID , 3 ) , 1 }
} ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void OtherRarityFullSets ( ) {
2021-11-10 21:23:24 +01:00
const uint appID = 42 ;
2020-10-21 18:41:20 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID , rarity : EAssetRarity . Common ) ,
CreateCard ( 1 , realAppID : appID , rarity : EAssetRarity . Rare )
2023-12-11 23:55:13 +01:00
] ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , 1 , appID ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( ) {
{ ( appID , Asset . SteamCommunityContextID , 1 ) , 2 }
} ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void OtherRarityNoSets ( ) {
2021-11-10 21:23:24 +01:00
const uint appID = 42 ;
2020-10-21 18:41:20 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID , rarity : EAssetRarity . Common ) ,
CreateCard ( 1 , realAppID : appID , rarity : EAssetRarity . Rare )
2023-12-11 23:55:13 +01:00
] ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , 2 , appID ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( 0 ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void OtherRarityOneSet ( ) {
2021-11-10 21:23:24 +01:00
const uint appID = 42 ;
2020-10-21 18:41:20 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID , rarity : EAssetRarity . Common ) ,
CreateCard ( 2 , realAppID : appID , rarity : EAssetRarity . Common ) ,
CreateCard ( 1 , realAppID : appID , rarity : EAssetRarity . Uncommon ) ,
CreateCard ( 2 , realAppID : appID , rarity : EAssetRarity . Uncommon ) ,
CreateCard ( 3 , realAppID : appID , rarity : EAssetRarity . Uncommon )
2023-12-11 23:55:13 +01:00
] ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , 3 , appID ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( ) {
{ ( appID , Asset . SteamCommunityContextID , 1 ) , 1 } ,
{ ( appID , Asset . SteamCommunityContextID , 2 ) , 1 } ,
{ ( appID , Asset . SteamCommunityContextID , 3 ) , 1 }
} ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void OtherTypeFullSets ( ) {
2021-11-10 21:23:24 +01:00
const uint appID = 42 ;
2020-10-21 18:41:20 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID , type : EAssetType . TradingCard ) ,
CreateCard ( 1 , realAppID : appID , type : EAssetType . FoilTradingCard )
2023-12-11 23:55:13 +01:00
] ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , 1 , appID ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( ) {
{ ( appID , Asset . SteamCommunityContextID , 1 ) , 2 }
} ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void OtherTypeNoSets ( ) {
2021-11-10 21:23:24 +01:00
const uint appID = 42 ;
2020-10-21 18:41:20 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID , type : EAssetType . TradingCard ) ,
CreateCard ( 1 , realAppID : appID , type : EAssetType . FoilTradingCard )
2023-12-11 23:55:13 +01:00
] ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , 2 , appID ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( 0 ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void OtherTypeOneSet ( ) {
2021-11-10 21:23:24 +01:00
const uint appID = 42 ;
2020-10-21 18:41:20 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID , type : EAssetType . TradingCard ) ,
CreateCard ( 2 , realAppID : appID , type : EAssetType . TradingCard ) ,
CreateCard ( 1 , realAppID : appID , type : EAssetType . FoilTradingCard ) ,
CreateCard ( 2 , realAppID : appID , type : EAssetType . FoilTradingCard ) ,
CreateCard ( 3 , realAppID : appID , type : EAssetType . FoilTradingCard )
2023-12-11 23:55:13 +01:00
] ;
2021-04-11 00:33:32 +02:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , 3 , appID ) ;
2021-04-11 00:33:32 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( ) {
{ ( appID , Asset . SteamCommunityContextID , 1 ) , 1 } ,
{ ( appID , Asset . SteamCommunityContextID , 2 ) , 1 } ,
{ ( appID , Asset . SteamCommunityContextID , 3 ) , 1 }
} ;
2021-04-11 00:33:32 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
2021-04-11 00:33:32 +02:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void TooHighAmount ( ) {
2021-11-10 21:23:24 +01:00
const uint appID0 = 42 ;
2021-04-11 00:33:32 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , amount : 2 , realAppID : appID0 ) ,
CreateCard ( 2 , realAppID : appID0 )
2023-12-11 23:55:13 +01:00
] ;
2021-04-11 00:33:32 +02:00
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , 2 , appID0 ) ;
2021-04-11 00:33:32 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult = new ( ) {
{ ( appID0 , Asset . SteamCommunityContextID , 1 ) , 1 } ,
{ ( appID0 , Asset . SteamCommunityContextID , 2 ) , 1 }
} ;
2021-04-11 00:33:32 +02:00
2021-11-10 21:23:24 +01:00
AssertResultMatchesExpectation ( expectedResult , itemsToSend ) ;
}
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void TooManyCardsForSingleTrade ( ) {
2021-11-10 21:23:24 +01:00
const uint appID = 42 ;
2021-04-11 00:33:32 +02:00
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [ ] ;
2021-04-11 00:33:32 +02:00
2021-11-10 21:23:24 +01:00
for ( byte i = 0 ; i < Steam . Exchange . Trading . MaxItemsPerTrade ; i + + ) {
2024-03-17 02:29:04 +01:00
items . Add ( CreateCard ( 1 , realAppID : appID ) ) ;
items . Add ( CreateCard ( 2 , realAppID : appID ) ) ;
2021-04-11 00:33:32 +02:00
}
2021-11-10 21:23:24 +01:00
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , 2 , appID ) ;
2025-08-08 19:32:32 +02:00
Assert . IsLessThanOrEqualTo ( Steam . Exchange . Trading . MaxItemsPerTrade , itemsToSend . Count ) ;
2021-11-10 21:23:24 +01:00
}
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void TooManyCardsForSingleTradeMultipleAppIDs ( ) {
2021-11-10 21:23:24 +01:00
const uint appID0 = 42 ;
const uint appID1 = 43 ;
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [ ] ;
2021-11-10 21:23:24 +01:00
for ( byte i = 0 ; i < 100 ; i + + ) {
2024-03-17 02:29:04 +01:00
items . Add ( CreateCard ( 1 , realAppID : appID0 ) ) ;
items . Add ( CreateCard ( 2 , realAppID : appID0 ) ) ;
items . Add ( CreateCard ( 1 , realAppID : appID1 ) ) ;
items . Add ( CreateCard ( 2 , realAppID : appID1 ) ) ;
2020-10-21 18:41:20 +02:00
}
2021-11-10 21:23:24 +01:00
Dictionary < uint , byte > itemsPerSet = new ( ) {
{ appID0 , 2 } ,
{ appID1 , 2 }
} ;
HashSet < Asset > itemsToSend = GetItemsForFullBadge ( items , itemsPerSet ) ;
2025-08-08 19:32:32 +02:00
Assert . IsLessThanOrEqualTo ( Steam . Exchange . Trading . MaxItemsPerTrade , itemsToSend . Count ) ;
2021-11-10 21:23:24 +01:00
}
2020-11-14 22:37:00 +01:00
2021-11-10 21:23:24 +01:00
[TestMethod]
2024-06-25 00:18:13 +02:00
internal void TooManyCardsPerSet ( ) {
2021-11-10 21:23:24 +01:00
const uint appID0 = 42 ;
const uint appID1 = 43 ;
const uint appID2 = 44 ;
2023-12-11 23:55:13 +01:00
HashSet < Asset > items = [
2024-03-17 02:29:04 +01:00
CreateCard ( 1 , realAppID : appID0 ) ,
CreateCard ( 2 , realAppID : appID0 ) ,
CreateCard ( 3 , realAppID : appID0 ) ,
CreateCard ( 4 , realAppID : appID0 )
2023-12-11 23:55:13 +01:00
] ;
2021-11-10 21:23:24 +01:00
2025-03-31 00:06:05 +02:00
Assert . ThrowsExactly < InvalidOperationException > ( ( ) = > GetItemsForFullBadge (
2024-02-22 16:08:54 +01:00
items , new Dictionary < uint , byte > {
{ appID0 , 3 } ,
{ appID1 , 3 } ,
{ appID2 , 3 }
}
)
2021-11-10 21:23:24 +01:00
) ;
}
2024-06-25 00:18:13 +02:00
private static void AssertResultMatchesExpectation ( Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , uint > expectedResult , IReadOnlyCollection < Asset > itemsToSend ) {
2021-12-12 01:12:54 +01:00
ArgumentNullException . ThrowIfNull ( expectedResult ) ;
ArgumentNullException . ThrowIfNull ( itemsToSend ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
Dictionary < ( uint RealAppID , ulong ContextID , ulong ClassID ) , long > realResult = itemsToSend . GroupBy ( static asset = > ( asset . RealAppID , asset . ContextID , asset . ClassID ) ) . ToDictionary ( static group = > group . Key , static group = > group . Sum ( static asset = > asset . Amount ) ) ;
2025-10-07 22:12:51 +02:00
Assert . HasCount ( expectedResult . Count , realResult ) ;
2021-11-10 21:23:24 +01:00
Assert . IsTrue ( expectedResult . All ( expectation = > realResult . TryGetValue ( expectation . Key , out long reality ) & & ( expectation . Value = = reality ) ) ) ;
}
2024-03-17 02:29:04 +01:00
private static Asset CreateCard ( ulong classID , ulong instanceID = 0 , uint amount = 1 , bool marketable = false , bool tradable = false , uint realAppID = Asset . SteamAppID , EAssetType type = EAssetType . TradingCard , EAssetRarity rarity = EAssetRarity . Common ) = > new ( Asset . SteamAppID , Asset . SteamCommunityContextID , classID , amount , new InventoryDescription ( Asset . SteamAppID , classID , instanceID , marketable , tradable , realAppID , type , rarity ) ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
private static HashSet < Asset > GetItemsForFullBadge ( IReadOnlyCollection < Asset > inventory , byte cardsPerSet , uint appID , ushort maxItems = Steam . Exchange . Trading . MaxItemsPerTrade ) = > GetItemsForFullBadge ( inventory , new Dictionary < uint , byte > { { appID , cardsPerSet } } , maxItems ) ;
2020-10-21 18:41:20 +02:00
2024-06-25 00:18:13 +02:00
private static HashSet < Asset > GetItemsForFullBadge ( IReadOnlyCollection < Asset > inventory , [ SuppressMessage ( "ReSharper" , "SuggestBaseTypeForParameter" ) ] Dictionary < uint , byte > cardsPerSet , ushort maxItems = Steam . Exchange . Trading . MaxItemsPerTrade ) {
2024-03-17 02:29:04 +01:00
Dictionary < ( uint RealAppID , EAssetType Type , EAssetRarity Rarity ) , List < uint > > inventorySets = Steam . Exchange . Trading . GetInventorySets ( inventory ) ;
2020-10-21 18:41:20 +02:00
2021-11-10 21:23:24 +01:00
return GetItemsForFullSets ( inventory , inventorySets . ToDictionary ( static kv = > kv . Key , kv = > ( SetsToExtract : inventorySets [ kv . Key ] [ 0 ] , cardsPerSet [ kv . Key . RealAppID ] ) ) , maxItems ) . ToHashSet ( ) ;
2020-10-21 18:41:20 +02:00
}
}
2024-06-25 00:18:13 +02:00
#pragma warning restore CA1812 // False positive, the class is used during MSTest