2023-01-01 18:42:56 -05:00
#nullable enable
using System.Collections.Generic ;
using Content.Server.VendingMachines ;
2023-10-10 20:06:24 -07:00
using Content.Server.Wires ;
2023-01-01 18:42:56 -05:00
using Content.Shared.Cargo.Prototypes ;
using Content.Shared.Damage ;
using Content.Shared.Damage.Prototypes ;
2023-08-05 16:16:48 +12:00
using Content.Shared.Prototypes ;
2023-09-11 21:20:46 +10:00
using Content.Shared.Storage.Components ;
2023-10-10 20:06:24 -07:00
using Content.Shared.VendingMachines ;
using Content.Shared.Wires ;
using Robust.Shared.GameObjects ;
using Robust.Shared.Map ;
using Robust.Shared.Prototypes ;
2023-01-01 18:42:56 -05:00
namespace Content.IntegrationTests.Tests
{
[TestFixture]
[TestOf(typeof(VendingMachineRestockComponent))]
2023-05-03 01:38:03 -04:00
[TestOf(typeof(VendingMachineSystem))]
2023-01-01 18:42:56 -05:00
public sealed class VendingMachineRestockTest : EntitySystem
{
2023-08-05 16:16:48 +12:00
[TestPrototypes]
2023-01-01 18:42:56 -05:00
private const string Prototypes = @ "
- type : entity
2023-08-05 16:16:48 +12:00
name : HumanVendingDummy
id : HumanVendingDummy
2023-01-01 18:42:56 -05:00
components :
- type : Hands
- type : Body
prototype : Human
- type : entity
parent : FoodSnackBase
id : TestRamen
name : TestRamen
- type : vendingMachineInventory
id : TestInventory
startingInventory :
TestRamen : 1
- type : vendingMachineInventory
id : OtherTestInventory
startingInventory :
TestRamen : 3
- type : vendingMachineInventory
id : BigTestInventory
startingInventory :
TestRamen : 4
- type : entity
parent : BaseVendingMachineRestock
id : TestRestockWrong
name : TestRestockWrong
components :
- type : VendingMachineRestock
canRestock :
- OtherTestInventory
- type : entity
parent : BaseVendingMachineRestock
id : TestRestockCorrect
name : TestRestockCorrect
components :
- type : VendingMachineRestock
canRestock :
- TestInventory
- type : entity
parent : BaseVendingMachineRestock
id : TestRestockExplode
name : TestRestockExplode
components :
- type : Damageable
damageContainer : Inorganic
damageModifierSet : Metallic
- type : Destructible
thresholds :
- trigger :
! type : DamageTrigger
damage : 20
behaviors :
- ! type : DumpRestockInventory
- ! type : DoActsBehavior
acts : [ ' Destruction ' ]
- type : VendingMachineRestock
canRestock :
- BigTestInventory
- type : entity
parent : VendingMachine
id : VendingMachineTest
name : Test Ramen
components :
- type : Wires
2023-10-10 20:06:24 -07:00
layoutId : Vending
2023-01-01 18:42:56 -05:00
- type : VendingMachine
pack : TestInventory
- type : Sprite
sprite : error . rsi
";
[Test]
public async Task TestAllRestocksAreAvailableToBuy ( )
{
2023-08-25 02:56:51 +02:00
await using var pair = await PoolManager . GetServerClient ( ) ;
var server = pair . Server ;
2023-01-01 18:42:56 -05:00
await server . WaitIdleAsync ( ) ;
var prototypeManager = server . ResolveDependency < IPrototypeManager > ( ) ;
await server . WaitAssertion ( ( ) = >
{
HashSet < string > restocks = new ( ) ;
Dictionary < string , List < string > > restockStores = new ( ) ;
// Collect all the prototypes with restock components.
foreach ( var proto in prototypeManager . EnumeratePrototypes < EntityPrototype > ( ) )
{
2023-08-05 16:16:48 +12:00
if ( proto . Abstract
2023-08-25 02:56:51 +02:00
| | pair . IsTestPrototype ( proto )
2023-08-05 16:16:48 +12:00
| | ! proto . HasComponent < VendingMachineRestockComponent > ( ) )
2023-01-01 18:42:56 -05:00
{
continue ;
}
restocks . Add ( proto . ID ) ;
}
// Collect all the prototypes with StorageFills referencing those entities.
foreach ( var proto in prototypeManager . EnumeratePrototypes < EntityPrototype > ( ) )
{
if ( ! proto . TryGetComponent < StorageFillComponent > ( out var storage ) )
continue ;
List < string > restockStore = new ( ) ;
foreach ( var spawnEntry in storage . Contents )
{
if ( spawnEntry . PrototypeId ! = null & & restocks . Contains ( spawnEntry . PrototypeId ) )
restockStore . Add ( spawnEntry . PrototypeId ) ;
}
if ( restockStore . Count > 0 )
restockStores . Add ( proto . ID , restockStore ) ;
}
// Iterate through every CargoProduct and make sure each
// prototype with a restock component is referenced in a
// purchaseable entity with a StorageFill.
foreach ( var proto in prototypeManager . EnumeratePrototypes < CargoProductPrototype > ( ) )
{
if ( restockStores . ContainsKey ( proto . Product ) )
{
foreach ( var entry in restockStores [ proto . Product ] )
restocks . Remove ( entry ) ;
restockStores . Remove ( proto . Product ) ;
}
}
2023-07-05 21:54:25 -07:00
Assert . Multiple ( ( ) = >
{
Assert . That ( restockStores , Has . Count . EqualTo ( 0 ) ,
$"Some entities containing entities with VendingMachineRestock components are unavailable for purchase: \n - {string.Join(" \ n - ", restockStores.Keys)}" ) ;
2023-01-01 18:42:56 -05:00
2023-07-05 21:54:25 -07:00
Assert . That ( restocks , Has . Count . EqualTo ( 0 ) ,
$"Some entities with VendingMachineRestock components are unavailable for purchase: \n - {string.Join(" \ n - ", restocks)}" ) ;
} ) ;
2023-01-01 18:42:56 -05:00
} ) ;
2023-08-25 02:56:51 +02:00
await pair . CleanReturnAsync ( ) ;
2023-01-01 18:42:56 -05:00
}
[Test]
public async Task TestCompleteRestockProcess ( )
{
2023-08-25 02:56:51 +02:00
await using var pair = await PoolManager . GetServerClient ( ) ;
var server = pair . Server ;
2023-01-01 18:42:56 -05:00
await server . WaitIdleAsync ( ) ;
var mapManager = server . ResolveDependency < IMapManager > ( ) ;
var entityManager = server . ResolveDependency < IEntityManager > ( ) ;
var entitySystemManager = server . ResolveDependency < IEntitySystemManager > ( ) ;
EntityUid packageRight ;
EntityUid packageWrong ;
EntityUid machine ;
EntityUid user ;
2023-07-05 21:54:25 -07:00
VendingMachineComponent machineComponent = default ! ;
VendingMachineRestockComponent restockRightComponent = default ! ;
VendingMachineRestockComponent restockWrongComponent = default ! ;
WiresPanelComponent machineWiresPanel = default ! ;
2023-01-01 18:42:56 -05:00
2023-08-25 04:13:11 +02:00
var testMap = await pair . CreateTestMap ( ) ;
2023-01-01 18:42:56 -05:00
await server . WaitAssertion ( ( ) = >
{
var coordinates = testMap . GridCoords ;
// Spawn the entities.
2023-08-05 16:16:48 +12:00
user = entityManager . SpawnEntity ( "HumanVendingDummy" , coordinates ) ;
2023-01-01 18:42:56 -05:00
machine = entityManager . SpawnEntity ( "VendingMachineTest" , coordinates ) ;
packageRight = entityManager . SpawnEntity ( "TestRestockCorrect" , coordinates ) ;
packageWrong = entityManager . SpawnEntity ( "TestRestockWrong" , coordinates ) ;
// Sanity test for components existing.
2023-07-05 21:54:25 -07:00
Assert . Multiple ( ( ) = >
{
Assert . That ( entityManager . TryGetComponent ( machine , out machineComponent ! ) , $"Machine has no {nameof(VendingMachineComponent)}" ) ;
Assert . That ( entityManager . TryGetComponent ( packageRight , out restockRightComponent ! ) , $"Correct package has no {nameof(VendingMachineRestockComponent)}" ) ;
Assert . That ( entityManager . TryGetComponent ( packageWrong , out restockWrongComponent ! ) , $"Wrong package has no {nameof(VendingMachineRestockComponent)}" ) ;
Assert . That ( entityManager . TryGetComponent ( machine , out machineWiresPanel ! ) , $"Machine has no {nameof(WiresPanelComponent)}" ) ;
} ) ;
2023-01-01 18:42:56 -05:00
var systemMachine = entitySystemManager . GetEntitySystem < VendingMachineSystem > ( ) ;
// Test that the panel needs to be opened first.
2023-07-05 21:54:25 -07:00
Assert . Multiple ( ( ) = >
{
Assert . That ( systemMachine . TryAccessMachine ( packageRight , restockRightComponent , machineComponent , user , machine ) , Is . False , "Right package is able to restock without opened access panel" ) ;
Assert . That ( systemMachine . TryAccessMachine ( packageWrong , restockWrongComponent , machineComponent , user , machine ) , Is . False , "Wrong package is able to restock without opened access panel" ) ;
} ) ;
2023-01-01 18:42:56 -05:00
2023-03-24 03:09:45 +03:00
var systemWires = entitySystemManager . GetEntitySystem < WiresSystem > ( ) ;
2023-01-01 18:42:56 -05:00
// Open the panel.
2023-03-24 03:09:45 +03:00
systemWires . TogglePanel ( machine , machineWiresPanel , true ) ;
2023-01-01 18:42:56 -05:00
2023-07-05 21:54:25 -07:00
Assert . Multiple ( ( ) = >
{
// Test that the right package works for the right machine.
Assert . That ( systemMachine . TryAccessMachine ( packageRight , restockRightComponent , machineComponent , user , machine ) , Is . True , "Correct package is unable to restock with access panel opened" ) ;
2023-01-01 18:42:56 -05:00
2023-07-05 21:54:25 -07:00
// Test that the wrong package does not work.
Assert . That ( systemMachine . TryMatchPackageToMachine ( packageWrong , restockWrongComponent , machineComponent , user , machine ) , Is . False , "Package with invalid canRestock is able to restock machine" ) ;
2023-01-01 18:42:56 -05:00
2023-07-05 21:54:25 -07:00
// Test that the right package does work.
Assert . That ( systemMachine . TryMatchPackageToMachine ( packageRight , restockRightComponent , machineComponent , user , machine ) , Is . True , "Package with valid canRestock is unable to restock machine" ) ;
2023-01-01 18:42:56 -05:00
2023-07-05 21:54:25 -07:00
// Make sure there's something in there to begin with.
Assert . That ( systemMachine . GetAvailableInventory ( machine , machineComponent ) , Has . Count . GreaterThan ( 0 ) ,
"Machine inventory is empty before emptying." ) ;
} ) ;
2023-01-01 18:42:56 -05:00
// Empty the inventory.
systemMachine . EjectRandom ( machine , false , true , machineComponent ) ;
2023-07-05 21:54:25 -07:00
Assert . That ( systemMachine . GetAvailableInventory ( machine , machineComponent ) , Has . Count . EqualTo ( 0 ) ,
2023-01-01 18:42:56 -05:00
"Machine inventory is not empty after ejecting." ) ;
// Test that the inventory is actually restocked.
systemMachine . TryRestockInventory ( machine , machineComponent ) ;
2023-07-05 21:54:25 -07:00
Assert . That ( systemMachine . GetAvailableInventory ( machine , machineComponent ) , Has . Count . GreaterThan ( 0 ) ,
2023-01-01 18:42:56 -05:00
"Machine available inventory count is not greater than zero after restock." ) ;
mapManager . DeleteMap ( testMap . MapId ) ;
} ) ;
2023-08-25 02:56:51 +02:00
await pair . CleanReturnAsync ( ) ;
2023-01-01 18:42:56 -05:00
}
[Test]
public async Task TestRestockBreaksOpen ( )
{
2023-08-25 02:56:51 +02:00
await using var pair = await PoolManager . GetServerClient ( ) ;
var server = pair . Server ;
2023-01-01 18:42:56 -05:00
await server . WaitIdleAsync ( ) ;
var prototypeManager = server . ResolveDependency < IPrototypeManager > ( ) ;
var mapManager = server . ResolveDependency < IMapManager > ( ) ;
var entityManager = server . ResolveDependency < IEntityManager > ( ) ;
var entitySystemManager = server . ResolveDependency < IEntitySystemManager > ( ) ;
var damageableSystem = entitySystemManager . GetEntitySystem < DamageableSystem > ( ) ;
2023-08-25 04:13:11 +02:00
var testMap = await pair . CreateTestMap ( ) ;
2023-01-01 18:42:56 -05:00
EntityUid restock = default ;
await server . WaitAssertion ( ( ) = >
{
var coordinates = testMap . GridCoords ;
var totalStartingRamen = 0 ;
foreach ( var meta in entityManager . EntityQuery < MetaDataComponent > ( ) )
if ( ! meta . Deleted & & meta . EntityPrototype ? . ID = = "TestRamen" )
totalStartingRamen + + ;
Assert . That ( totalStartingRamen , Is . EqualTo ( 0 ) ,
"Did not start with zero ramen." ) ;
restock = entityManager . SpawnEntity ( "TestRestockExplode" , coordinates ) ;
var damageSpec = new DamageSpecifier ( prototypeManager . Index < DamageTypePrototype > ( "Blunt" ) , 100 ) ;
var damageResult = damageableSystem . TryChangeDamage ( restock , damageSpec ) ;
2023-07-05 21:54:25 -07:00
#pragma warning disable NUnit2045
Assert . That ( damageResult , Is . Not . Null ,
2023-01-01 18:42:56 -05:00
"Received null damageResult when attempting to damage restock box." ) ;
2024-01-22 02:59:14 +01:00
Assert . That ( ( int ) damageResult ! . GetTotal ( ) , Is . GreaterThan ( 0 ) ,
2023-01-01 18:42:56 -05:00
"Box damage result was not greater than 0." ) ;
2023-07-05 21:54:25 -07:00
#pragma warning restore NUnit2045
2023-01-01 18:42:56 -05:00
} ) ;
await server . WaitRunTicks ( 15 ) ;
await server . WaitAssertion ( ( ) = >
{
Assert . That ( entityManager . Deleted ( restock ) ,
"Restock box was not deleted after being damaged." ) ;
var totalRamen = 0 ;
foreach ( var meta in entityManager . EntityQuery < MetaDataComponent > ( ) )
if ( ! meta . Deleted & & meta . EntityPrototype ? . ID = = "TestRamen" )
totalRamen + + ;
Assert . That ( totalRamen , Is . EqualTo ( 2 ) ,
"Did not find enough ramen after destroying restock box." ) ;
mapManager . DeleteMap ( testMap . MapId ) ;
} ) ;
2023-08-25 02:56:51 +02:00
await pair . CleanReturnAsync ( ) ;
2023-01-01 18:42:56 -05:00
}
[Test]
public async Task TestRestockInventoryBounds ( )
{
2023-08-25 02:56:51 +02:00
await using var pair = await PoolManager . GetServerClient ( ) ;
var server = pair . Server ;
2023-01-01 18:42:56 -05:00
await server . WaitIdleAsync ( ) ;
var mapManager = server . ResolveDependency < IMapManager > ( ) ;
var entityManager = server . ResolveDependency < IEntityManager > ( ) ;
var entitySystemManager = server . ResolveDependency < IEntitySystemManager > ( ) ;
var vendingMachineSystem = entitySystemManager . GetEntitySystem < SharedVendingMachineSystem > ( ) ;
2023-08-25 04:13:11 +02:00
var testMap = await pair . CreateTestMap ( ) ;
2023-01-01 18:42:56 -05:00
await server . WaitAssertion ( ( ) = >
{
var coordinates = testMap . GridCoords ;
2023-07-05 21:54:25 -07:00
var machine = entityManager . SpawnEntity ( "VendingMachineTest" , coordinates ) ;
2023-01-01 18:42:56 -05:00
2023-07-05 21:54:25 -07:00
Assert . That ( vendingMachineSystem . GetAvailableInventory ( machine ) , Has . Count . EqualTo ( 1 ) ,
2023-01-01 18:42:56 -05:00
"Machine's available inventory did not contain one entry." ) ;
Assert . That ( vendingMachineSystem . GetAvailableInventory ( machine ) [ 0 ] . Amount , Is . EqualTo ( 1 ) ,
"Machine's available inventory is not the expected amount." ) ;
vendingMachineSystem . RestockInventoryFromPrototype ( machine ) ;
Assert . That ( vendingMachineSystem . GetAvailableInventory ( machine ) [ 0 ] . Amount , Is . EqualTo ( 2 ) ,
"Machine's available inventory is not double its starting amount after a restock." ) ;
vendingMachineSystem . RestockInventoryFromPrototype ( machine ) ;
Assert . That ( vendingMachineSystem . GetAvailableInventory ( machine ) [ 0 ] . Amount , Is . EqualTo ( 3 ) ,
"Machine's available inventory is not triple its starting amount after two restocks." ) ;
vendingMachineSystem . RestockInventoryFromPrototype ( machine ) ;
Assert . That ( vendingMachineSystem . GetAvailableInventory ( machine ) [ 0 ] . Amount , Is . EqualTo ( 3 ) ,
"Machine's available inventory did not stay the same after a third restock." ) ;
} ) ;
2023-08-25 02:56:51 +02:00
await pair . CleanReturnAsync ( ) ;
2023-01-01 18:42:56 -05:00
}
}
}
#nullable disable