Merge branch 'develop' into v2

This commit is contained in:
Matthew Penner 2021-09-11 16:13:11 -06:00
commit e384c0d5c3
No known key found for this signature in database
GPG key ID: 030E4AB751DC756F
9 changed files with 43 additions and 63 deletions

View file

@ -118,8 +118,8 @@ class AuditLog extends Model
'server_id' => null,
'action' => $action,
'device' => $request ? [
'ip_address' => $request->getClientIp(),
'user_agent' => $request->userAgent(),
'ip_address' => $request->getClientIp() ?? '127.0.0.1',
'user_agent' => $request->userAgent() ?? '',
] : [],
'metadata' => $metadata,
]);

View file

@ -4,7 +4,7 @@
"version": "PTDL_v1",
"update_url": null
},
"exported_at": "2021-07-27T14:14:20+03:00",
"exported_at": "2021-09-11T14:35:10-04:00",
"name": "Ark: Survival Evolved",
"author": "dev@shepper.fr",
"description": "As a man or woman stranded, naked, freezing, and starving on the unforgiving shores of a mysterious island called ARK, use your skill and cunning to kill or tame and ride the plethora of leviathan dinosaurs and other primeval creatures roaming the land. Hunt, harvest resources, craft items, grow crops, research technologies, and build shelters to withstand the elements and store valuables, all while teaming up with (or preying upon) hundreds of other players to survive, dominate... and escape! \u2014 Gamepedia: ARK",
@ -13,7 +13,7 @@
"quay.io\/parkervcp\/pterodactyl-images:debian_source"
],
"file_denylist": [],
"startup": "rmv() { echo -e \"stopping server\"; rcon -t rcon -a 127.0.0.1:${RCON_PORT} -p ${ARK_ADMIN_PASSWORD} -c saveworld && rcon -a 127.0.0.1:${RCON_PORT} -p ${ARK_ADMIN_PASSWORD} -c DoExit; }; trap rmv 15; cd ShooterGame\/Binaries\/Linux && .\/ShooterGameServer {{SERVER_MAP}}?listen?SessionName=\"{{SESSION_NAME}}\"?ServerPassword={{ARK_PASSWORD}}?ServerAdminPassword={{ARK_ADMIN_PASSWORD}}?Port={{SERVER_PORT}}?RCONPort={{RCON_PORT}}?QueryPort={{QUERY_PORT}}?RCONEnabled=True$( [ \"$BATTLE_EYE\" == \"0\" ] || printf %s '?-NoBattlEye' ) -server {{ARGS}} -log & until echo \"waiting for rcon connection...\"; rcon -t rcon -a 127.0.0.1:${RCON_PORT} -p ${ARK_ADMIN_PASSWORD}; do sleep 5; done",
"startup": "rmv() { echo -e \"stopping server\"; rcon -t rcon -a 127.0.0.1:${RCON_PORT} -p ${ARK_ADMIN_PASSWORD} -c saveworld && rcon -a 127.0.0.1:${RCON_PORT} -p ${ARK_ADMIN_PASSWORD} -c DoExit; }; trap rmv 15; cd ShooterGame\/Binaries\/Linux && .\/ShooterGameServer {{SERVER_MAP}}?listen?SessionName=\"{{SESSION_NAME}}\"?ServerPassword={{ARK_PASSWORD}}?ServerAdminPassword={{ARK_ADMIN_PASSWORD}}?Port={{SERVER_PORT}}?RCONPort={{RCON_PORT}}?QueryPort={{QUERY_PORT}}?RCONEnabled=True$( [ \"$BATTLE_EYE\" == \"1\" ] || printf %s ' -NoBattlEye' ) -server {{ARGS}} -log & until echo \"waiting for rcon connection...\"; rcon -t rcon -a 127.0.0.1:${RCON_PORT} -p ${ARK_ADMIN_PASSWORD}; do sleep 5; done",
"config": {
"files": "{}",
"startup": "{\r\n \"done\": \"Waiting commands for 127.0.0.1:\"\r\n}",

View file

@ -4,7 +4,7 @@
"version": "PTDL_v1",
"update_url": null
},
"exported_at": "2021-06-05T16:28:06-04:00",
"exported_at": "2021-08-27T00:12:31-04:00",
"name": "Garrys Mod",
"author": "support@pterodactyl.io",
"description": "Garrys Mod, is a sandbox physics game created by Garry Newman, and developed by his company, Facepunch Studios.",
@ -13,16 +13,16 @@
"ghcr.io\/pterodactyl\/games:source"
],
"file_denylist": [],
"startup": ".\/srcds_run -game garrysmod -console -port {{SERVER_PORT}} +ip 0.0.0.0 +host_workshop_collection {{WORKSHOP_ID}} +map {{SRCDS_MAP}} +gamemode {{GAMEMODE}} -strictportbind -norestart +sv_setsteamaccount {{STEAM_ACC}} +maxplayers {{MAX_PLAYERS}} -tickrate {{TICKRATE}}",
"startup": ".\/srcds_run -game garrysmod -console -port {{SERVER_PORT}} +ip 0.0.0.0 +host_workshop_collection {{WORKSHOP_ID}} +map {{SRCDS_MAP}} +gamemode {{GAMEMODE}} -strictportbind -norestart +sv_setsteamaccount {{STEAM_ACC}} +maxplayers {{MAX_PLAYERS}} -tickrate {{TICKRATE}} $( [ \"$LUA_REFRESH\" == \"1\" ] || printf %s '-disableluarefresh' )",
"config": {
"files": "{}",
"startup": "{\r\n \"done\": \"gameserver Steam ID\",\r\n \"userInteraction\": []\r\n}",
"logs": "{\r\n \"custom\": true,\r\n \"location\": \"logs\/latest.log\"\r\n}",
"startup": "{\r\n \"done\": \"gameserver Steam ID\"\r\n}",
"logs": "{}",
"stop": "quit"
},
"scripts": {
"installation": {
"script": "#!\/bin\/bash\r\n# steamcmd Base Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n# Image to install with is 'debian:buster-slim'\r\napt -y update\r\napt -y --no-install-recommends install curl lib32gcc1 ca-certificates\r\n\r\n## just in case someone removed the defaults.\r\nif [ \"${STEAM_USER}\" == \"\" ]; then\r\n echo -e \"steam user is not set.\\n\"\r\n echo -e \"Using anonymous user.\\n\"\r\n STEAM_USER=anonymous\r\n STEAM_PASS=\"\"\r\n STEAM_AUTH=\"\"\r\nelse\r\n echo -e \"user set to ${STEAM_USER}\"\r\nfi\r\n\r\n## download and install steamcmd\r\ncd \/tmp\r\nmkdir -p \/mnt\/server\/steamcmd\r\ncurl -sSL -o steamcmd.tar.gz https:\/\/steamcdn-a.akamaihd.net\/client\/installer\/steamcmd_linux.tar.gz\r\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/steamcmd\r\nmkdir -p \/mnt\/server\/steamapps # Fix steamcmd disk write error when this folder is missing\r\ncd \/mnt\/server\/steamcmd\r\n\r\n# SteamCMD fails otherwise for some reason, even running as root.\r\n# This is changed at the end of the install process anyways.\r\nchown -R root:root \/mnt\r\nexport HOME=\/mnt\/server\r\n\r\n## install game using steamcmd\r\n.\/steamcmd.sh +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} $( [[ \"${WINDOWS_INSTALL}\" == \"1\" ]] && printf %s '+@sSteamCmdForcePlatformType windows' ) +force_install_dir \/mnt\/server +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} validate +quit ## other flags may be needed depending on install. looking at you cs 1.6\r\n\r\n## set up 32 bit libraries\r\nmkdir -p \/mnt\/server\/.steam\/sdk32\r\ncp -v linux32\/steamclient.so ..\/.steam\/sdk32\/steamclient.so\r\n\r\n## set up 64 bit libraries\r\nmkdir -p \/mnt\/server\/.steam\/sdk64\r\ncp -v linux64\/steamclient.so ..\/.steam\/sdk64\/steamclient.so\r\n\r\n# Creating needed default files for the game\r\ncd \/mnt\/server\/garrysmod\/lua\/autorun\/server\r\necho '\r\n-- Docs: https:\/\/wiki.garrysmod.com\/page\/resource\/AddWorkshop\r\n-- Place the ID of the workshop addon you want to be downloaded to people who join your server, not the collection ID\r\n-- Use https:\/\/beta.configcreator.com\/create\/gmod\/resources.lua to easily create a list based on your collection ID\r\n\r\nresource.AddWorkshop( \"\" )\r\n' > workshop.lua\r\n\r\ncd \/mnt\/server\/garrysmod\/cfg\r\necho '\r\n\/\/ Please do not set RCon in here, use the startup parameters.\r\n\r\nhostname\t\t\"New Gmod Server\"\r\nsv_password\t\t\"\"\r\nsv_loadingurl \"\"\r\n\r\n\/\/ Steam Server List Settings\r\nsv_region \"255\"\r\nsv_lan \"0\"\r\nsv_max_queries_sec_global \"30000\"\r\nsv_max_queries_window \"45\"\r\nsv_max_queries_sec \"5\"\r\n\r\n\/\/ Server Limits\r\nsbox_maxprops\t\t100\r\nsbox_maxragdolls\t5\r\nsbox_maxnpcs\t\t10\r\nsbox_maxballoons\t10\r\nsbox_maxeffects\t\t10\r\nsbox_maxdynamite\t10\r\nsbox_maxlamps\t\t10\r\nsbox_maxthrusters\t10\r\nsbox_maxwheels\t\t10\r\nsbox_maxhoverballs\t10\r\nsbox_maxvehicles\t20\r\nsbox_maxbuttons\t\t10\r\nsbox_maxsents\t\t20\r\nsbox_maxemitters\t5\r\nsbox_godmode\t\t0\r\nsbox_noclip\t\t 0\r\n\r\n\/\/ Network Settings - Please keep these set to default.\r\n\r\nsv_minrate\t\t75000\r\nsv_maxrate\t\t0\r\ngmod_physiterations\t2\r\nnet_splitpacket_maxrate\t45000\r\ndecalfrequency\t\t12 \r\n\r\n\/\/ Execute Ban Files - Please do not edit\r\nexec banned_ip.cfg \r\nexec banned_user.cfg \r\n\r\n\/\/ Add custom lines under here\r\n' > server.cfg",
"script": "#!\/bin\/bash\r\n# steamcmd Base Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n# Image to install with is 'debian:buster-slim'\r\napt -y update\r\napt -y --no-install-recommends install curl lib32gcc1 ca-certificates\r\n\r\n## just in case someone removed the defaults.\r\nif [ \"${STEAM_USER}\" == \"\" ]; then\r\n echo -e \"steam user is not set.\\n\"\r\n echo -e \"Using anonymous user.\\n\"\r\n STEAM_USER=anonymous\r\n STEAM_PASS=\"\"\r\n STEAM_AUTH=\"\"\r\nelse\r\n echo -e \"user set to ${STEAM_USER}\"\r\nfi\r\n\r\n## download and install steamcmd\r\ncd \/tmp\r\nmkdir -p \/mnt\/server\/steamcmd\r\ncurl -sSL -o steamcmd.tar.gz https:\/\/steamcdn-a.akamaihd.net\/client\/installer\/steamcmd_linux.tar.gz\r\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/steamcmd\r\nmkdir -p \/mnt\/server\/steamapps # Fix steamcmd disk write error when this folder is missing\r\ncd \/mnt\/server\/steamcmd\r\n\r\n# SteamCMD fails otherwise for some reason, even running as root.\r\n# This is changed at the end of the install process anyways.\r\nchown -R root:root \/mnt\r\nexport HOME=\/mnt\/server\r\n\r\n## install game using steamcmd\r\n.\/steamcmd.sh +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} $( [[ \"${WINDOWS_INSTALL}\" == \"1\" ]] && printf %s '+@sSteamCmdForcePlatformType windows' ) +force_install_dir \/mnt\/server +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} validate +quit ## other flags may be needed depending on install. looking at you cs 1.6\r\n\r\n## set up 32 bit libraries\r\nmkdir -p \/mnt\/server\/.steam\/sdk32\r\ncp -v linux32\/steamclient.so ..\/.steam\/sdk32\/steamclient.so\r\n\r\n## set up 64 bit libraries\r\nmkdir -p \/mnt\/server\/.steam\/sdk64\r\ncp -v linux64\/steamclient.so ..\/.steam\/sdk64\/steamclient.so\r\n\r\n# Creating needed default files for the game\r\ncd \/mnt\/server\/garrysmod\/lua\/autorun\/server\r\necho '\r\n-- Docs: https:\/\/wiki.garrysmod.com\/page\/resource\/AddWorkshop\r\n-- Place the ID of the workshop addon you want to be downloaded to people who join your server, not the collection ID\r\n-- Use https:\/\/beta.configcreator.com\/create\/gmod\/resources.lua to easily create a list based on your collection ID\r\n\r\nresource.AddWorkshop( \"\" )\r\n' > workshop.lua\r\n\r\ncd \/mnt\/server\/garrysmod\/cfg\r\necho '\r\n\/\/ Please do not set RCon in here, use the startup parameters.\r\n\r\nhostname\t\t\"New Gmod Server\"\r\nsv_password\t\t\"\"\r\nsv_loadingurl \"\"\r\nsv_downloadurl \"\"\r\n\r\n\/\/ Steam Server List Settings\r\n\/\/ sv_location \"eu\"\r\nsv_region \"255\"\r\nsv_lan \"0\"\r\nsv_max_queries_sec_global \"30000\"\r\nsv_max_queries_window \"45\"\r\nsv_max_queries_sec \"5\"\r\n\r\n\/\/ Server Limits\r\nsbox_maxprops\t\t100\r\nsbox_maxragdolls\t5\r\nsbox_maxnpcs\t\t10\r\nsbox_maxballoons\t10\r\nsbox_maxeffects\t\t10\r\nsbox_maxdynamite\t10\r\nsbox_maxlamps\t\t10\r\nsbox_maxthrusters\t10\r\nsbox_maxwheels\t\t10\r\nsbox_maxhoverballs\t10\r\nsbox_maxvehicles\t20\r\nsbox_maxbuttons\t\t10\r\nsbox_maxsents\t\t20\r\nsbox_maxemitters\t5\r\nsbox_godmode\t\t0\r\nsbox_noclip\t\t 0\r\n\r\n\/\/ Network Settings - Please keep these set to default.\r\n\r\nsv_minrate\t\t75000\r\nsv_maxrate\t\t0\r\ngmod_physiterations\t2\r\nnet_splitpacket_maxrate\t45000\r\ndecalfrequency\t\t12 \r\n\r\n\/\/ Execute Ban Files - Please do not edit\r\nexec banned_ip.cfg \r\nexec banned_user.cfg \r\n\r\n\/\/ Add custom lines under here\r\n' > server.cfg",
"container": "ghcr.io\/pterodactyl\/installers:debian",
"entrypoint": "bash"
}
@ -90,6 +90,15 @@
"user_viewable": true,
"user_editable": true,
"rules": "required|integer|max:100"
},
{
"name": "Lua Refresh",
"description": "0 = disable Lua refresh,\r\n1 = enable Lua refresh",
"env_variable": "LUA_REFRESH",
"default_value": "0",
"user_viewable": true,
"user_editable": true,
"rules": "required|boolean"
}
]
}
}

View file

@ -1,16 +1,16 @@
import useWebsocketEvent from '@/plugins/useWebsocketEvent';
import { ServerContext } from '@/state/server';
import { SocketEvent } from '@/components/server/events';
import useFileManagerSwr from '@/plugins/useFileManagerSwr';
import { mutate } from 'swr';
import { getDirectorySwrKey } from '@/plugins/useFileManagerSwr';
const InstallListener = () => {
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
const getServer = ServerContext.useStoreActions(actions => actions.server.getServer);
const { mutate } = useFileManagerSwr();
const setServerFromState = ServerContext.useStoreActions(actions => actions.server.setServerFromState);
useWebsocketEvent(SocketEvent.BACKUP_RESTORE_COMPLETED, async () => {
await mutate(undefined);
await mutate(getDirectorySwrKey(uuid, '/'), undefined);
setServerFromState(s => ({ ...s, status: null }));
});

View file

@ -13,7 +13,6 @@ export type SettableModalProps = Omit<ModalProps, 'appear' | 'visible' | 'onDism
interface State {
render: boolean;
visible: boolean;
showSpinnerOverlay?: boolean;
propOverrides: Partial<SettableModalProps>;
}
@ -31,7 +30,6 @@ function asModal<P extends {}> (modalProps?: SettableModalProps | ((props: P) =>
this.state = {
render: props.visible,
visible: props.visible,
showSpinnerOverlay: undefined,
propOverrides: {},
};
}
@ -39,7 +37,6 @@ function asModal<P extends {}> (modalProps?: SettableModalProps | ((props: P) =>
get computedModalProps (): Readonly<SettableModalProps & { visible: boolean }> {
return {
...(typeof modalProps === 'function' ? modalProps(this.props) : modalProps),
showSpinnerOverlay: this.state.showSpinnerOverlay,
...this.state.propOverrides,
visible: this.state.visible,
};
@ -50,7 +47,7 @@ function asModal<P extends {}> (modalProps?: SettableModalProps | ((props: P) =>
*/
componentDidUpdate (prevProps: Readonly<P & AsModalProps>, prevState: Readonly<State>) {
if (prevProps.visible && !this.props.visible) {
this.setState({ visible: false, showSpinnerOverlay: false });
this.setState({ visible: false, propOverrides: {} });
} else if (!prevProps.visible && this.props.visible) {
this.setState({ render: true, visible: true });
}

View file

@ -3,12 +3,14 @@ import loadDirectory, { FileObject } from '@/api/server/files/loadDirectory';
import { cleanDirectoryPath } from '@/helpers';
import { ServerContext } from '@/state/server';
export const getDirectorySwrKey = (uuid: string, directory: string): string => `${uuid}:files:${directory}`;
export default () => {
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
const directory = ServerContext.useStoreState(state => state.files.directory);
return useSWR<FileObject[]>(
`${uuid}:files:${directory}`,
getDirectorySwrKey(uuid, directory),
() => loadDirectory(uuid, cleanDirectoryPath(directory)),
{
focusThrottleInterval: 30000,

View file

@ -26,8 +26,7 @@ class BuildModificationServiceTest extends IntegrationTestCase
{
parent::setUp();
$this->daemonServerRepository = Mockery::mock(DaemonServerRepository::class);
$this->swap(DaemonServerRepository::class, $this->daemonServerRepository);
$this->daemonServerRepository = $this->mock(DaemonServerRepository::class);
}
/**
@ -50,7 +49,7 @@ class BuildModificationServiceTest extends IntegrationTestCase
$allocations[2]->update(['server_id' => $server2->id]);
$allocations[3]->update(['server_id' => $server2->id]);
$this->daemonServerRepository->expects('setServer->update')->andReturnUndefined();
$this->daemonServerRepository->expects('setServer->sync')->andReturnUndefined();
$response = $this->getService()->handle($server, [
// Attempt to add one new allocation, and an allocation assigned to another server. The
@ -113,20 +112,7 @@ class BuildModificationServiceTest extends IntegrationTestCase
return $s->id === $server->id;
}))->andReturnSelf();
$this->daemonServerRepository->expects('update')->with(Mockery::on(function ($data) {
$this->assertEquals([
'build' => [
'memory_limit' => 256,
'swap' => 128,
'io_weight' => 600,
'cpu_limit' => 150,
'threads' => '1,2',
'disk_space' => 1024,
],
], $data);
return true;
}))->andReturnUndefined();
$this->daemonServerRepository->expects('sync')->withNoArgs()->andReturnUndefined();
$response = $this->getService()->handle($server, [
'oom_disabled' => false,
@ -162,7 +148,7 @@ class BuildModificationServiceTest extends IntegrationTestCase
{
$server = $this->createServerModel();
$this->daemonServerRepository->expects('setServer->update')->andThrows(
$this->daemonServerRepository->expects('setServer->sync')->andThrows(
new DaemonConnectionException(
new RequestException('Bad request', new Request('GET', '/test'), new Response())
)
@ -186,7 +172,7 @@ class BuildModificationServiceTest extends IntegrationTestCase
/** @var \Pterodactyl\Models\Allocation $allocation */
$allocation = Allocation::factory()->create(['node_id' => $server->node_id, 'server_id' => $server->id]);
$this->daemonServerRepository->expects('setServer->update')->andReturnUndefined();
$this->daemonServerRepository->expects('setServer->sync')->andReturnUndefined();
$this->getService()->handle($server, [
'remove_allocations' => [$allocation->id],
@ -209,7 +195,7 @@ class BuildModificationServiceTest extends IntegrationTestCase
/** @var \Pterodactyl\Models\Allocation $allocation */
$allocation = Allocation::factory()->create(['node_id' => $server->node_id]);
$this->daemonServerRepository->expects('setServer->update')->andReturnUndefined();
$this->daemonServerRepository->expects('setServer->sync')->andReturnUndefined();
$this->getService()->handle($server, [
'add_allocations' => [$allocation->id],
@ -230,7 +216,7 @@ class BuildModificationServiceTest extends IntegrationTestCase
/** @var \Pterodactyl\Models\Allocation $allocation2 */
$allocation2 = Allocation::factory()->create(['node_id' => $server->node_id]);
$this->daemonServerRepository->expects('setServer->update')->andReturnUndefined();
$this->daemonServerRepository->expects('setServer->sync')->andReturnUndefined();
$this->getService()->handle($server, [
'add_allocations' => [$allocation2->id, $allocation2->id],
@ -253,7 +239,7 @@ class BuildModificationServiceTest extends IntegrationTestCase
/** @var \Pterodactyl\Models\Allocation $allocation */
$allocation = Allocation::factory()->create(['node_id' => $server->node_id]);
$this->daemonServerRepository->expects('setServer->update')->andThrows(new DisplayException('Test'));
$this->daemonServerRepository->expects('setServer->sync')->andThrows(new DisplayException('Test'));
$this->expectException(DisplayException::class);

View file

@ -67,7 +67,6 @@ class ServerCreationServiceTest extends IntegrationTestCase
$allocations[0]->port,
]);
/** @noinspection PhpParamsInspection */
$egg = $this->cloneEggAndVariables(Egg::query()->findOrFail(1));
// We want to make sure that the validator service runs as an admin, and not as a regular
// user when saving variables.
@ -94,19 +93,10 @@ class ServerCreationServiceTest extends IntegrationTestCase
'BUNGEE_VERSION' => '123',
'SERVER_JARFILE' => 'server2.jar',
],
'start_on_completion' => true,
];
$this->daemonServerRepository->expects('setServer')->andReturnSelf();
$this->daemonServerRepository->expects('create')->with(Mockery::on(function ($value) {
$this->assertIsArray($value);
// Just check for some keys to make sure we're getting the expected configuration
// structure back. Other tests exist to confirm it is the correct structure.
$this->assertArrayHasKey('uuid', $value);
$this->assertArrayHasKey('environment', $value);
$this->assertArrayHasKey('invocation', $value);
return true;
}))->andReturnUndefined();
$this->daemonServerRepository->expects('setServer->create')->with(true)->andReturnUndefined();
try {
$this->getService()->handle(array_merge($data, [
@ -115,7 +105,8 @@ class ServerCreationServiceTest extends IntegrationTestCase
'SERVER_JARFILE' => 'server2.jar',
],
]), $deployment);
$this->assertTrue(false, 'This statement should not be reached.');
$this->fail('This execution pathway should not be reached.');
} catch (ValidationException $exception) {
$this->assertCount(1, $exception->errors());
$this->assertArrayHasKey('environment.BUNGEE_VERSION', $exception->errors());
@ -133,11 +124,11 @@ class ServerCreationServiceTest extends IntegrationTestCase
$this->assertSame('server2.jar', $response->variables[1]->server_value);
foreach ($data as $key => $value) {
if (in_array($key, ['allocation_additional', 'environment'])) {
if (in_array($key, ['allocation_additional', 'environment', 'start_on_completion'])) {
continue;
}
$this->assertSame($value, $response->{$key});
$this->assertSame($value, $response->{$key}, "Failed asserting equality of '$key' in server response. Got: [{$response->{$key}}] Expected: [$value]");
}
$this->assertCount(2, $response->allocations);

View file

@ -29,20 +29,15 @@ class SuspensionServiceTest extends IntegrationTestCase
{
$server = $this->createServerModel();
$this->repository->expects('setServer')->twice()->andReturnSelf();
$this->repository->expects('suspend')->with(false)->andReturnUndefined();
$this->repository->expects('setServer->sync')->twice()->andReturnSelf();
$this->getService()->toggle($server, SuspensionService::ACTION_SUSPEND);
$server->refresh();
$this->assertTrue($server->isSuspended());
$this->repository->expects('suspend')->with(true)->andReturnUndefined();
$this->assertTrue($server->refresh()->isSuspended());
$this->getService()->toggle($server, SuspensionService::ACTION_UNSUSPEND);
$server->refresh();
$this->assertFalse($server->isSuspended());
$this->assertFalse($server->refresh()->isSuspended());
}
public function testNoActionIsTakenIfSuspensionStatusIsUnchanged()