public function testComplex()
{
$user = $this->getUser();
$environment = $this->getEnvironment();
$fictionController = new ApiController();
//test script post
$data = ['name' => 'test-post', 'description' => 'test-post', 'timeoutDefault' => 1000, 'blockingDefault' => true, 'osType' => 'linux'];
$response = $this->postScript($data);
$this->assertEquals(201, $response->status, $this->printResponseError($response));
$scriptId = $response->getBody()->data->id;
/* @var $script Script */
$script = Script::findPk($scriptId);
$this->assertNotEmpty($script);
$this->scriptToDelete($scriptId);
$this->assertObjectEqualsEntity($data, $script);
//post environment-scoped script
$data['scope'] = ScopeInterface::SCOPE_ENVIRONMENT;
$response = $this->postScript($data);
$this->assertEquals(201, $response->status, $this->printResponseError($response));
$scriptId = $response->getBody()->data->id;
$script = Script::findPk($scriptId);
$this->assertNotEmpty($script);
$this->scriptToDelete($scriptId);
$this->assertObjectEqualsEntity($data, $script);
//post script already existing
$data = ['id' => $script->id, 'name' => 'test-post-existing', 'description' => 'test-post-existing', 'osType' => 'linux', 'scope' => ScopeInterface::SCOPE_ENVIRONMENT];
$response = $this->postScript($data);
$this->assertEquals(201, $response->status, $this->printResponseError($response));
$scriptId = $response->getBody()->data->id;
$this->scriptToDelete($scriptId);
$this->assertNotEquals($data['id'], $scriptId);
unset($data['id']);
$scriptData = $data;
$scriptData['accountId'] = $user->getAccountId();
$scriptData['envId'] = $environment->id;
$scriptData['os'] = $data['osType'];
unset($scriptData['osType'], $scriptData['scope']);
$envScript = $this->createEntity(new Script(), $scriptData);
//post script with name already exists in current (environment) scope
$data['name'] = 'test-post-existing';
$response = $this->postScript($data);
$this->assertErrorMessageContains($response, 409, ErrorMessage::ERR_UNICITY_VIOLATION);
$envScript->delete();
//post script with properties that not existing
$data = ['name' => 'test-post-not-existing-field', 'description' => 'test-post-not-existing-field', 'foo' => 'bar', 'osType' => 'linux'];
$response = $this->postScript($data);
$this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
//post script without required fields
$data = ['name' => 'foobar', 'description' => 'test-post-no-scope'];
$response = $this->postScript($data);
$this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
//test script fetch
$response = $this->getScript($script->id);
$this->assertEquals(200, $response->status, $this->printResponseError($response));
$this->assertObjectEqualsEntity($response->getBody()->data, $script);
//test fetch script that doe not exists
$response = $this->getScript(Script::findOne([], null, ['id' => false])->id + 1);
$this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND);
//test script modify
$data = ['name' => 'test-modify', 'description' => 'test-modify', 'timeoutDefault' => 0, 'blockingDefault' => false];
$response = $this->modifyScript($script->id, $data);
$this->assertEquals(200, $response->status, $this->printResponseError($response));
$this->assertObjectEqualsEntity($response->getBody()->data, Script::findPk($script->id));
//modify property that does not exists
$data = ['foo' => 'bar'];
$response = $this->modifyScript($script->id, $data);
$this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
//modify properties that not alterable
$scriptAdapter = new ScriptAdapter($fictionController);
$adapterRules = $scriptAdapter->getRules();
$publicProperties = $adapterRules[BaseAdapter::RULE_TYPE_TO_DATA];
$alterableProperties = $adapterRules[ApiEntityAdapter::RULE_TYPE_ALTERABLE];
$nonAlterableProperties = array_diff(array_values($publicProperties), $alterableProperties);
foreach ($nonAlterableProperties as $property) {
$data = [$property => 'foo'];
$response = $this->modifyScript($script->id, $data);
$this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
}
//modify script that does not exists
$data = ['name' => 'test-modify-not-found'];
$response = $this->modifyScript(Script::findOne([], null, ['id' => false])->id + 1, $data);
$this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND);
//modify Scalr-scoped script
/* @var $script Script */
$script = static::createEntity(new Script(), ['name' => "{$this->uuid}-script", 'description' => "{$this->uuid}-description", 'createdById' => $user->getId()]);
//modify Scalr-scoped script
$data = ['name' => 'test-modify-scalr-scoped'];
$response = $this->modifyScript($script->id, $data);
$this->assertErrorMessageContains($response, 403, ErrorMessage::ERR_PERMISSION_VIOLATION, 'Insufficient permissions');
/* @var $script Script */
$script = static::createEntity(new Script(), ['name' => "{$this->uuid}-script", 'description' => "{$this->uuid}-description", 'accountId' => $user->getAccountId(), 'createdById' => $user->getId()]);
//test have access to all listed scripts
$scripts = $this->listScripts();
foreach ($scripts as $script) {
$this->assertTrue(Script::findPk($script->id)->hasAccessPermissions($user), "Script id: {$script->id}");
}
//test convertible data filters
$mergedLists = array_merge($this->listScripts(['scope' => ScopeInterface::SCOPE_SCALR]), $this->listScripts(['scope' => ScopeInterface::SCOPE_ENVIRONMENT]), $this->listScripts(['scope' => ScopeInterface::SCOPE_ACCOUNT]));
foreach ($mergedLists as $script) {
$this->assertTrue(Script::findPk($script->id)->hasAccessPermissions($user), "Script id: {$script->id}");
}
//test list scripts filters
$filterable = $scriptAdapter->getRules()[ApiEntityAdapter::RULE_TYPE_FILTERABLE];
/* @var $script Script */
foreach ($scripts as $script) {
foreach ($filterable as $property) {
$filterValue = $script->{$property};
$listResult = $this->listScripts([$property => $filterValue]);
if (!static::isRecursivelyEmpty($filterValue)) {
foreach ($listResult as $filtered) {
$this->assertEquals($filterValue, $filtered->{$property}, "Property '{$property}' mismatch");
}
}
}
$response = $this->getScript($script->id);
$this->assertEquals(200, $response->status, $this->printResponseError($response));
$dbScript = Script::findPk($script->id);
$this->assertObjectEqualsEntity($response->getBody()->data, $dbScript, $scriptAdapter);
}
//test have write access to environments and account scoped scripts
foreach (array_merge($this->listScripts(['scope' => ScopeInterface::SCOPE_ENVIRONMENT]), $this->listScripts(['scope' => ScopeInterface::SCOPE_ACCOUNT])) as $script) {
$this->assertTrue(Script::findPk($script->id)->hasAccessPermissions($user, null, true));
}
$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 $script Script */
$script = static::createEntity(new Script(), ['name' => "{$this->uuid}-script", 'description' => "{$this->uuid}-description", 'envId' => $environment->id, 'createdById' => $user->getId()]);
$response = $this->deleteScript($script->id);
$this->assertEquals(200, $response->status, $this->printResponseError($response));
//delete scalr-scoped script
$scripts = $this->listScripts(['scope' => ScopeInterface::SCOPE_SCALR]);
$script = array_shift($scripts);
$response = $this->deleteScript($script->id);
$this->assertErrorMessageContains($response, 403, ErrorMessage::ERR_PERMISSION_VIOLATION);
//delete script that does not exists
$response = $this->deleteScript(Script::findOne([], null, ['id' => false])->id + 1);
$this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND);
}