diff --git a/app/Http/Requests/Task/StoreTaskRequest.php b/app/Http/Requests/Task/StoreTaskRequest.php index a1de7bec3f75..8d0d7af7b85e 100644 --- a/app/Http/Requests/Task/StoreTaskRequest.php +++ b/app/Http/Requests/Task/StoreTaskRequest.php @@ -12,6 +12,7 @@ namespace App\Http\Requests\Task; use App\Http\Requests\Request; +use App\Models\Project; use App\Models\Task; use App\Utils\Traits\MakesHash; use Illuminate\Validation\Rule; @@ -38,19 +39,49 @@ class StoreTaskRequest extends Request $rules['number'] = Rule::unique('tasks')->where('company_id', auth()->user()->company()->id); } + if(isset($this->client_id)) + $rules['client_id'] = 'bail|required|exists:clients,id,company_id,'.auth()->user()->company()->id.',is_deleted,0'; + + if(isset($this->project_id)) + $rules['project_id'] = 'bail|required|exists:projects,id,company_id,'.auth()->user()->company()->id.',is_deleted,0'; + + $rules['timelog'] = ['bail','array',function ($attribute, $values, $fail) { + + foreach($values as $k) + { + if(!is_int($k[0]) || !is_int($k[1])) + $fail('The '.$attribute.' - '.print_r($k,1).' is invalid. Unix timestamps only.'); + } + + }]; + + return $this->globalRules($rules); } public function prepareForValidation() { $input = $this->all(); - $input = $this->decodePrimaryKeys($this->all()); if (array_key_exists('status_id', $input) && is_string($input['status_id'])) { $input['status_id'] = $this->decodePrimaryKey($input['status_id']); } + /* Ensure the project is related */ + if (array_key_exists('project_id', $input) && isset($input['project_id'])) { + $project = Project::withTrashed()->find($input['project_id'])->company()->first(); + + if($project){ + $input['client_id'] = $project->client_id; + } + else + { + unset($input['project_id']); + } + + } + $this->replace($input); } } diff --git a/app/Http/Requests/Task/UpdateTaskRequest.php b/app/Http/Requests/Task/UpdateTaskRequest.php index 1389f5ce4124..c60924df0b71 100644 --- a/app/Http/Requests/Task/UpdateTaskRequest.php +++ b/app/Http/Requests/Task/UpdateTaskRequest.php @@ -12,6 +12,7 @@ namespace App\Http\Requests\Task; use App\Http\Requests\Request; +use App\Models\Project; use App\Utils\Traits\ChecksEntityStatus; use App\Utils\Traits\MakesHash; use Illuminate\Validation\Rule; @@ -39,6 +40,22 @@ class UpdateTaskRequest extends Request $rules['number'] = Rule::unique('tasks')->where('company_id', auth()->user()->company()->id)->ignore($this->task->id); } + if(isset($this->client_id)) + $rules['client_id'] = 'bail|required|exists:clients,id,company_id,'.auth()->user()->company()->id.',is_deleted,0'; + + if(isset($this->project_id)) + $rules['project_id'] = 'bail|required|exists:projects,id,company_id,'.auth()->user()->company()->id.',is_deleted,0'; + + $rules['timelog'] = ['bail','array',function ($attribute, $values, $fail) { + + foreach($values as $k) + { + if(!is_int($k[0]) || !is_int($k[1])) + $fail('The '.$attribute.' - '.print_r($k,1).' is invalid. Unix timestamps only.'); + } + + }]; + return $this->globalRules($rules); } @@ -50,6 +67,20 @@ class UpdateTaskRequest extends Request $input['status_id'] = $this->decodePrimaryKey($input['status_id']); } + /* Ensure the project is related */ + if (array_key_exists('project_id', $input) && isset($input['project_id'])) { + $project = Project::withTrashed()->find($input['project_id'])->company()->first(); + + if($project){ + $input['client_id'] = $project->client_id; + } + else + { + unset($input['project_id']); + } + + } + if (array_key_exists('color', $input) && is_null($input['color'])) { $input['color'] = ''; } diff --git a/tests/Feature/TaskApiTest.php b/tests/Feature/TaskApiTest.php index 2343a5d562de..0a7cd00545ba 100644 --- a/tests/Feature/TaskApiTest.php +++ b/tests/Feature/TaskApiTest.php @@ -42,6 +42,97 @@ class TaskApiTest extends TestCase Model::reguard(); } + public function testTimeLogValidation() + { + $data = [ + 'timelog' => $this->faker->firstName(), + ]; + + try { + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/tasks', $data); + + $arr = $response->json(); + } catch (ValidationException $e) { + $response->assertStatus(302); + } + + } + + public function testTimeLogValidation1() + { + $data = [ + 'timelog' => [[1,2],[3,4]], + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/tasks', $data); + + $arr = $response->json(); + $response->assertStatus(200); + + + } + + public function testTimeLogValidation2() + { + $data = [ + 'timelog' => [], + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/tasks', $data); + + $arr = $response->json(); + $response->assertStatus(200); + + + } + + public function testTimeLogValidation3() + { + $data = [ + 'timelog' => [["a","b"],["c","d"]], + ]; + + try { + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/tasks', $data); + + $arr = $response->json(); + } catch (ValidationException $e) { + $response->assertStatus(302); + } + + } + + public function testTimeLogValidation4() + { + $data = [ + 'timelog' => [[1,2],[3,0]], + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/tasks', $data); + + $arr = $response->json(); + $response->assertStatus(200); + + + } + + + public function testStartTask() { $log = [ @@ -76,6 +167,7 @@ class TaskApiTest extends TestCase $data = [ 'description' => $this->faker->firstName(), 'number' => 'taskynumber', + 'client_id' => $this->client->id, ]; $response = $this->withHeaders([ @@ -126,6 +218,24 @@ class TaskApiTest extends TestCase $this->assertNotEmpty($arr['data']['number']); } + public function testTaskWithBadClientId() + { + $data = [ + 'client_id' => $this->faker->firstName(), + ]; + + try { + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/tasks', $data); + $arr = $response->json(); + } catch (ValidationException $e) { + $response->assertStatus(302); + } + + } + public function testTaskPostWithActionStart() { $data = [