public function testComplex()
{
$user = $this->getUser();
$adapter = $this->getAdapter('OrchestrationRules\\RoleScript');
//foreach iterates through values in order of ads
//we need to remove rules first, then - scripts
//we initialize data set for removal with non-existing rule
$this->ruleToDelete(-1);
/* @var $roles Role[] */
$roles = $this->getTestRoles();
/* @var $role Role */
$role = array_shift($roles);
if (empty($role)) {
$this->markTestSkipped('Not found roles to test role-script');
}
/* @var $scalrRole Role */
$scalrRole = Role::findOne([['envId' => null], ['accountId' => null]]);
/* @var $script Script */
$script = static::createEntity(new Script(), ['name' => 'test-role-scripts', 'description' => 'test-role-scripts']);
$isWindows = $role->getOs()->family == 'windows';
/* @var $version ScriptVersion */
$version = static::createEntity(new ScriptVersion(), ['scriptId' => $script->id, 'version' => $script->getLatestVersion()->version + 1, 'content' => $isWindows ? '#!cmd' : '#!/bin/sh']);
$script->os = $isWindows ? 'windows' : 'linux';
$script->save();
$scalrRoleScriptData = ['trigger' => ['triggerType' => RoleScriptAdapter::TRIGGER_SINGLE_EVENT, 'event' => ['id' => 'HostInit']], 'target' => ['targetType' => RoleScriptAdapter::TARGET_NAME_TRIGGERING_FARM_ROLE], 'action' => ['actionType' => RoleScriptAdapter::ACTION_SCRIPT, 'scriptVersion' => ['script' => ['id' => $script->id], 'version' => $version->version]]];
$localRoleScriptData = ['trigger' => ['triggerType' => RoleScriptAdapter::TRIGGER_ALL_EVENTS], 'target' => ['targetType' => RoleScriptAdapter::TARGET_NAME_NULL], 'action' => ['actionType' => RoleScriptAdapter::ACTION_URI, 'path' => 'https://example.com']];
//post scalr rule
$response = $this->postRule($role->id, $scalrRoleScriptData);
$this->assertEquals(201, $response->status, $this->printResponseError($response));
$ruleId = $response->getBody()->data->id;
/* @var $rule RoleScript */
$rule = RoleScript::findPk($ruleId);
$this->assertNotEmpty($rule);
$this->ruleToDelete($ruleId);
$this->assertObjectEqualsEntity($scalrRoleScriptData, $rule, $adapter);
//post local rule
$response = $this->postRule($role->id, $localRoleScriptData);
$this->assertEquals(201, $response->status, $this->printResponseError($response));
$ruleId = $response->getBody()->data->id;
/* @var $rule RoleScript */
$rule = RoleScript::findPk($ruleId);
$this->assertNotEmpty($rule);
$this->ruleToDelete($ruleId);
$this->assertObjectEqualsEntity($localRoleScriptData, $rule, $adapter);
//post rule to environment-scoped role
$response = $this->postRule($scalrRole->id, $scalrRoleScriptData);
$this->assertErrorMessageContains($response, 403, ErrorMessage::ERR_PERMISSION_VIOLATION);
//post rule already existing
$data = $scalrRoleScriptData;
$data['id'] = $ruleId;
$response = $this->postRule($role->id, $data);
$this->assertEquals(201, $response->status, $this->printResponseError($response));
$ruleId = $response->getBody()->data->id;
$this->ruleToDelete($ruleId);
$this->assertNotEquals($data['id'], $ruleId);
//post rule with script that does not exists
$data = $scalrRoleScriptData;
$data['action']['scriptVersion']['script']['id'] = Script::findOne([], null, ['id' => true])->id + 1;
$response = $this->postRule($role->id, $data);
$this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND);
//post rule with version that does not exists
$data = $scalrRoleScriptData;
$data['action']['scriptVersion']['version'] = Script::findPk($data['action']['scriptVersion']['script']['id'])->getLatestVersion()->version + 1;
$response = $this->postRule($role->id, $data);
$this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND);
//post rule with properties that not existing
$data = $scalrRoleScriptData;
$data['foo'] = 'bar';
$response = $this->postRule($role->id, $data);
$this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
//post rule without required fields
$data = $localRoleScriptData;
unset($data['action']);
$response = $this->postRule($role->id, $data);
$this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
//post rule with invalid field
$data = $localRoleScriptData;
$data['action'] = '';
$response = $this->postRule($role->id, $data);
$this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
//fetch rule
$response = $this->getRule($role->id, $rule->id);
$this->assertEquals(200, $response->status, $this->printResponseError($response));
$this->assertObjectEqualsEntity($response->getBody()->data, $rule, $adapter);
//fetch rule that doe not exists
$response = $this->getRule($role->id, RoleScript::findOne([], null, ['id' => false])->id + 1);
$this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND);
//fetch rule with missmatch role id
$response = $this->getRule(Role::findOne([], null, ['id' => false])->id + 1, $rule->id);
$this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_VALUE);
//test have access to all listed rules
$rules = $this->listRules($role->id);
foreach ($rules as $rule) {
$this->assertTrue(RoleScript::findPk($rule->id)->hasAccessPermissions($user));
}
$listUri = static::getUserApiUrl("/scripts");
//test invalid filters
$response = $this->request($listUri, Request::METHOD_GET, ['foo' => 'bar']);
$this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
//test invalid filters values
$response = $this->request($listUri, Request::METHOD_GET, ['scope' => 'foobar']);
$this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_VALUE);
//delete script
/* @var $rule RoleScript */
$rule = static::createEntity(new RoleScript(), ['roleId' => $role->id, 'scriptId' => $script->id]);
$response = $this->deleteRule($role->id, $rule->id);
$this->assertEquals(200, $response->status, $this->printResponseError($response));
//delete scalr-scoped script
/* @var $rule RoleScript */
$rule = static::createEntity(new RoleScript(), ['roleId' => $scalrRole->id, 'scriptId' => $script->id, 'version' => -1]);
$response = $this->deleteRule($scalrRole->id, $rule->id);
$this->assertErrorMessageContains($response, 403, ErrorMessage::ERR_PERMISSION_VIOLATION);
//delete script that does not exists
$response = $this->deleteRule($role->id, RoleScript::findOne([], null, ['id' => false])->id + 1);
$this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND);
}