public function testCRUD_Works()
 {
     $environ = new MongoTestEnvironment();
     $environ->clean();
     $userId = $environ->mockId();
     $projectId = $environ->mockId();
     $questionId = $environ->mockId();
     $answerId = $environ->mockId();
     // Create
     $vote = new UserVoteModel($userId, $projectId, $questionId);
     $this->assertNotNull($vote);
     $this->assertTrue(empty($vote->id->id));
     // Has vote should fail, answer is not yet present.
     $result = $vote->hasVote($answerId);
     $this->assertFalse($result);
     // Add vote, should then be present.
     $vote->addVote($answerId);
     $result = $vote->hasVote($answerId);
     $this->assertTrue($result);
     $id = $vote->write();
     $this->assertNotNull($id);
     $this->assertInternalType('string', $id);
     $this->assertEquals($vote->id->asString(), $id);
     // Read back
     $otherVote = new UserVoteModel($userId, $projectId, $questionId);
     $this->assertInternalType('string', $otherVote->id->id);
     $this->assertEquals($vote->id->asString(), $id);
     $result = $otherVote->hasVote($answerId);
     $this->assertTrue($result);
     // Update
     $answer2Id = $environ->mockId();
     $otherVote->addVote($answer2Id);
     $otherVote->write();
     // Read back
     $otherVote = new UserVoteModel($userId, $projectId, $questionId);
     $result = $otherVote->hasVote($answerId);
     $this->assertTrue($result);
     $result = $otherVote->hasVote($answer2Id);
     $this->assertTrue($result);
     // Remove vote, should no longer be present.
     $vote->removeVote($answerId);
     $result = $vote->hasVote($answerId);
     $this->assertFalse($result);
     // UserVoteModel::remove($projectModel->databaseName(), $id);
 }
 public static function voteDown($userId, $projectId, $questionId, $answerId)
 {
     $projectModel = new ProjectModel($projectId);
     ProjectCommands::checkIfArchivedAndThrow($projectModel);
     $questionModel = new QuestionModel($projectModel, $questionId);
     // Check the vote lock.
     $vote = new UserVoteModel($userId, $projectId, $questionId);
     if (!$vote->hasVote($answerId)) {
         // Don't throw.  There's no harm in this, just don't decrement the vote.
         return self::encodeAnswer($questionModel->readAnswer($answerId));
     }
     // If ok down vote the question and remove the lock.
     $answerModel = $questionModel->readAnswer($answerId);
     $answerModel->score--;
     $questionModel->writeAnswer($answerModel);
     $vote->removeVote($answerId);
     $vote->write();
     // Return the answer dto.
     return self::encodeAnswer($answerModel);
 }