assertIsArray($questions, 'Should have returned an array'); $this->assertNotEmpty($questions, 'Should have returned some questions'); collect($questions)->map(function ($question) { $this->assertIsObject($question, 'Question should be an object '); $this->assertTrue(\get_class($question) === Question::class, 'Question should be type ' . Question::class); $this->assertIsArray($question->answers); $this->assertNotEmpty($question->answers); collect($question->answers)->map(function ($answer) { $this->assertIsObject($answer, 'Answer should be an object '); $this->assertTrue(\get_class($answer) === Answer::class, 'Question should be type ' . Answer::class); }); }); } /** * Test customer is json serializable. * * @return void */ public function testJsonSerialize() { $questions = Question::all(); $this->assertIsArray($questions); $this->assertTrue((bool)count($questions)); foreach ($questions as $question) { $jsonDecoded = \json_decode(\json_encode($question), true); $this->assertArrayHasKey('id', $jsonDecoded); $this->assertEquals($question->id, $jsonDecoded['id']); $this->assertArrayHasKey('question', $jsonDecoded); $this->assertEquals($question->question, $jsonDecoded['question']); $this->assertArrayHasKey('type', $jsonDecoded); $this->assertEquals($question->type->value, $jsonDecoded['type']); $this->assertArrayHasKey('answers', $jsonDecoded); $this->assertIsArray($jsonDecoded['answers']); foreach ($jsonDecoded['answers'] as $key => $answer) { $this->assertArrayHasKey('id', $answer); $this->assertArrayHasKey('answer', $answer); $this->assertArrayHasKey($key, $question->answers); $this->assertEquals($question->answers[$key]->id, $answer['id']); $this->assertEquals($question->answers[$key]->answer, $answer['answer']); } } } /** * Get all question with user answers * * @return void */ public function testGetAllQuestionsWithCustomerAnswers() { /** @var \App\Models\Question $answeredQuestion */ $answeredQuestion = ModelsQuestion::whereHas('brand', function ($q) { $q->whereId(static::$brand->id); })->firstOrFail(); // * Make sure a customer answer is set. $firstAnswer = $answeredQuestion->answers->first(); $firstAnswer->load('question'); /** @var \App\Models\CustomerAnswer $custAnswer */ $custAnswer = CustomerAnswer::whereHas('customer', function ($q) { $q->whereId(static::$customer->id); })->whereHas('answer', function ($q) use ($firstAnswer) { $q->whereId($firstAnswer->id); })->firstOrNew(); $custAnswer->customer()->associate(static::$customer); $custAnswer->answer()->associate($firstAnswer); $custAnswer->saveOrFail(); $api = new CrmApiV2(); $customer = $api->getCustomerOrNew(static::$info->hashcode); $questions = Question::allWithCustomerAnswers($customer); $this->assertIsArray($questions, 'Should have returned an array'); $this->assertNotEmpty($questions, 'Should have returned some questions'); $hasCheckedCustomerAnswers = false; collect($questions)->map(function ($question) use ($answeredQuestion, &$hasCheckedCustomerAnswers) { $this->assertIsArray($question, 'Question should be an array'); $this->assertArrayHasKey('question', $question, 'Question should have a question key'); $this->assertIsObject($question['question'], 'Question should be an object'); $this->assertTrue( \get_class($question['question']) === Question::class, 'Question should be type ' . Question::class ); $this->assertIsArray($question['question']->answers); $this->assertNotEmpty($question['question']->answers); collect($question['question']->answers)->map(function ($answer) { $this->assertIsObject($answer, 'Answer should be an object '); $this->assertTrue(\get_class($answer) === Answer::class, 'Question should be type ' . Answer::class); }); if ($answeredQuestion->id === $question['question']->id) { $hasCheckedCustomerAnswers = true; $this->assertArrayHasKey('customerAnswers', $question, 'Question should have customer answers'); $this->assertIsArray($question['customerAnswers'], 'Question should have customer answers'); collect($question['customerAnswers'])->map(function ($custAnswer) { $this->assertIsObject($custAnswer, 'Customer answer should be an object '); $this->assertTrue( \get_class($custAnswer) === Answer::class, 'Customer answer should be type ' . Answer::class ); }); } }); $this->assertTrue( $hasCheckedCustomerAnswers, 'Should have checked that response has at least on customer answer we have set on this test.' ); } /** * Get all unanswered questions * * @return void */ public function testGetAllCustomerUnAnsweredQuestions() { /** @var \App\Models\Question $answeredQuestion */ $answeredQuestion = ModelsQuestion::whereHas('brand', function ($q) { $q->whereId(static::$brand->id); })->firstOrFail(); // * Make sure a customer answer is set. $firstAnswer = $answeredQuestion->answers->first(); $firstAnswer->load('question'); /** @var \App\Models\CustomerAnswer $custAnswer */ $custAnswer = CustomerAnswer::whereHas('customer', function ($q) { $q->whereId(static::$customer->id); })->whereHas('answer', function ($q) use ($firstAnswer) { $q->whereId($firstAnswer->id); })->firstOrNew(); $custAnswer->customer()->associate(static::$customer); $custAnswer->answer()->associate($firstAnswer); $custAnswer->saveOrFail(); $api = new CrmApiV2(); $customer = $api->getCustomerOrNew(static::$info->hashcode); $questions = Question::unansweredBy($customer); $this->assertIsArray($questions, 'Should have returned an array'); $this->assertNotEmpty($questions, 'Should have returned some questions'); collect($questions)->map(function ($question) use ($answeredQuestion) { $this->assertIsObject($question, 'Question should be an object'); $this->assertTrue( \get_class($question) === Question::class, 'Question should be type ' . Question::class ); $this->assertIsArray($question->answers); $this->assertNotEmpty($question->answers); collect($question->answers)->map(function ($answer) { $this->assertIsObject($answer, 'Answer should be an object '); $this->assertTrue(\get_class($answer) === Answer::class, 'Question should be type ' . Answer::class); }); $this->assertFalse( $answeredQuestion->id === $question->id, 'Questions should not have one we already answered' ); }); } /** * Test submit answers. * * @return void */ public function testSubmitCustomerAnswer() { /** @var \App\Models\Question $answeredQuestion */ $answeredQuestion = ModelsQuestion::whereHas('brand', function ($q) { $q->whereId(static::$brand->id); })->inRandomOrder()->firstOrFail(); $api = new CrmApiV2(); $customer = $api->getCustomerOrNew(static::$info->hashcode); $result = Answer::setQuestionAnswers( $customer->hashcode, $answeredQuestion->id, [ $answeredQuestion->answers->get(0)->id, $answeredQuestion->answers->get(1)->id, ] ); $this->assertTrue($result); $api = new CrmApiV2(); $customer = $api->getCustomerOrNew(static::$info->hashcode); $questions = Question::unansweredBy($customer); $this->assertIsArray($questions, 'Should have returned an array'); $this->assertNotEmpty($questions, 'Should have returned some questions'); collect($questions)->map(function ($question) use ($answeredQuestion) { $this->assertIsObject($question, 'Question should be an object'); $this->assertTrue( \get_class($question) === Question::class, 'Question should be type ' . Question::class ); $this->assertIsArray($question->answers); $this->assertNotEmpty($question->answers); collect($question->answers)->map(function ($answer) { $this->assertIsObject($answer, 'Answer should be an object '); $this->assertTrue(\get_class($answer) === Answer::class, 'Question should be type ' . Answer::class); }); $this->assertFalse( $answeredQuestion->id === $question->id, 'Questions should not have one we already answered' ); }); } /** * Test unansweredBy * * @return void */ public function testGetAllCustomerUnansweredQuestionsShouldNotContainFirst() { $unWantedQuestion = Question::all()[0]; $api = new CrmApiV2(); $customer = $api->getCustomerOrNew(static::$info->hashcode); $questions = Question::unansweredBy($customer); foreach ($questions as $question) { $this->assertFalse($unWantedQuestion->id === $question->id); } } /** * test allWithCustomerAnswers * * @return void */ public function testGetAllQuestionsWithCustomerAnswersShouldHaveAnswers() { $api = new CrmApiV2(); $customer = $api->getCustomerOrNew(static::$info->hashcode); $questions = Question::allWithCustomerAnswers($customer); $this->assertNotEmpty($questions[0]['customerAnswers'], 'Should have customer answers'); } }