getCustomer()); /** @var \Illuminate\Database\Eloquent\Collection $questions */ $questions = Question::whereHas('brand', function ($q) use ($service) { $q->whereId($service->brand->id); })->with('answers')->get()->keyBy('id'); $response = $this->callApiWithToken($service, 'get', route('apiV2.questions.index')); $json = $response->decodeResponseJson(); $this->assertApiResponseStatusIs($json, ApiStatus::OK); $json->assertStructure([ 'data' => [ '*' => [ 'id', 'type', 'question', 'answers' => [ '*' => [ 'id', 'answer' ] ], ] ] ]); // Should contain questions with answers. foreach ($json->json('data') as $question) { $this->assertTrue($questions->contains($question['id'])); $DBquestion = $questions->get($question['id']); $this->assertEquals($DBquestion->type->value(), $question['type']); $this->assertEquals($DBquestion->question, $question['question']); foreach ($question['answers'] as $answer) { $answers = $DBquestion->answers->keyBy('id'); $this->assertTrue($answers->contains($answer['id'])); $DBanswer = $answers->get($answer['id']); $this->assertEquals($DBanswer->answer, $answer['answer']); } } } /** * Test get all service questions with customer answers. * route: apiV2.questions.indexWithResponse * * @return void */ public function testQuestionIndexWithAnswers(): void { extract($this->getCustomer(true, false)); /** @var \Illuminate\Database\Eloquent\Collection $questions */ $questions = Question::whereHas('brand', function ($q) use ($service) { $q->whereId($service->brand->id); })->with('answers')->get()->keyBy('id'); // * Make sure a customer answer is set. $firstAnswer = $questions->first()->answers->first(); $firstAnswer->load('question'); /** @var \App\Models\ModelAnswer $modelAnswer */ DB::table('model_answer')->insert([ 'model_type' => Customer::class, 'model_id' => $customer->getKey(), 'answer_id' => $firstAnswer->getKey(), ]); // * Call $response = $this->callApiWithToken($service, 'get', route( 'apiV2.questions.indexWithResponse', ['serviceCustomer' => $info->hashcode] )); $json = $response->decodeResponseJson(); $this->assertApiResponseStatusIs($json, ApiStatus::OK); $json->assertStructure([ 'data' => [ '*' => [ 'id', 'type', 'question', 'answers' => [ '*' => [ 'id', 'answer' ] ], 'customerAnswers' ] ] ]); // Should contain questions with answers. foreach ($json->json('data') as $question) { $this->assertTrue($questions->contains($question['id'])); $DBquestion = $questions->get($question['id']); $this->assertEquals($DBquestion->type->value(), $question['type']); $this->assertEquals($DBquestion->question, $question['question']); foreach ($question['answers'] as $answer) { $answers = $DBquestion->answers->keyBy('id'); $this->assertTrue($answers->contains($answer['id'])); $DBanswer = $answers->get($answer['id']); $this->assertEquals($DBanswer->answer, $answer['answer']); } if ($firstAnswer->question->id === $DBquestion->id) { $this->assertEquals($question['customerAnswers'][0]['id'], $firstAnswer->id); $this->assertEquals($question['customerAnswers'][0]['answer'], $firstAnswer->answer); } } } /** * Test get all service questions with customer answers when customer is unknown. * route: apiV2.questions.indexWithResponse * * @return void */ public function testQuestionIndexWithAnswersWhenCustomerNotFound(): void { extract($this->getCustomer(true, false)); $service = Service::whereHas('brand', function ($q) use ($brand) { $q->where('id', '!=', $brand->id); })->firstOrFail(); $response = $this->callApiWithToken($service, 'get', route( 'apiV2.questions.indexWithResponse', ['serviceCustomer' => $info->hashcode] )); $json = $response->decodeResponseJson(); $this->assertApiResponseStatusIs($json, ApiStatus::KO); $this->assertEquals(ApiError::modelNotFound->value(), $json->json('data.code')); } /** * Test get all service questions with customer answers when customer is unknown. * route: apiV2.questions.unAnsweredBy * * @return void */ public function testCustomerUnAnsweredIndex(): void { extract($this->getCustomer(true, false)); /** @var \Illuminate\Database\Eloquent\Collection $questions */ $questions = Question::whereHas('brand', function ($q) use ($service) { $q->whereId($service->brand->id); })->with('answers')->get()->keyBy('id'); // * Make sure a customer answer is set. $firstAnswer = $questions->first()->answers->first(); $firstAnswer->load('question'); /** @var \App\Models\ModelAnswer $modelAnswer */ DB::table('model_answer')->insert([ 'model_type' => Customer::class, 'model_id' => $customer->getKey(), 'answer_id' => $firstAnswer->getKey(), ]); // * Call $response = $this->callApiWithToken($service, 'get', route( 'apiV2.questions.unAnsweredBy', ['serviceCustomer' => $info->hashcode] )); $json = $response->decodeResponseJson(); $this->assertApiResponseStatusIs($json, ApiStatus::OK); $json->assertStructure([ 'data' => [ '*' => [ 'id', 'type', 'question', 'answers' => [ '*' => [ 'id', 'answer' ] ] ] ] ]); // Should contain questions with answers. foreach ($json->json('data') as $question) { $this->assertTrue($questions->contains($question['id'])); $DBquestion = $questions->get($question['id']); $this->assertEquals($DBquestion->type->value(), $question['type']); $this->assertEquals($DBquestion->question, $question['question']); foreach ($question['answers'] as $answer) { $answers = $DBquestion->answers->keyBy('id'); $this->assertTrue($answers->contains($answer['id'])); $DBanswer = $answers->get($answer['id']); $this->assertEquals($DBanswer->answer, $answer['answer']); } $this->assertNotEquals( $firstAnswer->question->id, $DBquestion->id, 'This question has been answered by our user' ); } } /** * Test get all service questions unanswered by customer when customer is unknown. * route: apiV2.questions.indexWithResponse * * @return void */ public function testUnAnsweredIndexWhenCustomerNotFound(): void { extract($this->getCustomer(true, false)); $service = Service::whereHas('brand', function ($q) use ($brand) { $q->where('id', '!=', $brand->id); })->firstOrFail(); $response = $this->callApiWithToken($service, 'get', route( 'apiV2.questions.unAnsweredBy', ['serviceCustomer' => $info->hashcode] )); $json = $response->decodeResponseJson(); $this->assertApiResponseStatusIs($json, ApiStatus::KO); $this->assertEquals(ApiError::modelNotFound->value(), $json->json('data.code')); } /** * Test save customer answer. * route: apiV2.customers.answers.store * * @return void */ public function testQuestionSetAnswer(): void { extract($this->getCustomer(true, false)); $question = Question::whereHas('brand', function ($q) use ($brand) { $q->whereId($brand->id); })->whereHas('answers', function ($q) use ($customer) { $q->whereDoesntHave('customers', function ($q) use ($customer) { $q->whereId($customer->id); }); })->inRandomOrder()->firstOrFail(); $answer = $question->answers->first(); $response = $this->callApiWithToken($service, 'post', route( 'apiV2.customers.answers.store', ['serviceCustomer' => $info->hashcode] ), [ 'question' => $question->id, 'answers' => [$answer->id] ]); $json = $response->decodeResponseJson(); $this->assertApiResponseStatusIs($json, ApiStatus::OK); $this->assertTrue( ModelAnswer::query()->where([ ['model_type', Customer::class], ['model_id', $customer->getKey()], ['answer_id', $answer->getKey()] ])->exists(), 'Question should have been answered.' ); } /** * Test get all save customer answers when customer is unknown. * route: apiV2.questions.indexWithResponse * * @return void */ public function testQuestionSetAnswerWhenCustomerNotFound(): void { extract($this->getCustomer(true, false)); $service = Service::whereHas('brand', function ($q) use ($brand) { $q->where('id', '!=', $brand->id); })->firstOrFail(); $response = $this->callApiWithToken($service, 'post', route( 'apiV2.customers.answers.store', ['serviceCustomer' => $info->hashcode] )); $json = $response->decodeResponseJson(); $this->assertApiResponseStatusIs($json, ApiStatus::KO); $this->assertEquals(ApiError::modelNotFound->value(), $json->json('data.code')); } }