public function testEncode_FullQuestionWithAnswersAndComments_DtoReturnsExpectedData()
 {
     $project = self::$environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $text = new TextModel($project);
     $text->title = "Text 1";
     $usx = MongoTestEnvironment::usxSample();
     $text->content = $usx;
     $textId = $text->write();
     $user1Id = self::$environ->createUser("user1", "user1", "*****@*****.**");
     $user2Id = self::$environ->createUser("user2", "user2", "*****@*****.**");
     $user3Id = self::$environ->createUser("user3", "user3", "*****@*****.**");
     // Workflow is first to create a question
     $question = new QuestionModel($project);
     $question->title = "the question";
     $question->description = "question description";
     $question->textRef->id = $textId;
     $questionId = $question->write();
     // Then to add an answer to a question
     $answer = new AnswerModel();
     $answer->content = "first answer";
     $answer->score = 10;
     $answer->userRef->id = $user3Id;
     $answer->textHightlight = "text highlight";
     $answerId = $question->writeAnswer($answer);
     // Followed by comments
     $comment1 = new CommentModel();
     $comment1->content = "first comment";
     $comment1->userRef->id = $user1Id;
     $comment1Id = QuestionModel::writeComment($project->databaseName(), $questionId, $answerId, $comment1);
     $comment2 = new CommentModel();
     $comment2->content = "second comment";
     $comment2->userRef->id = $user2Id;
     $comment2Id = QuestionModel::writeComment($project->databaseName(), $questionId, $answerId, $comment2);
     $dto = QuestionCommentDto::encode($project->id->asString(), $questionId, $user1Id);
     //var_dump($dto);
     $aid = $answerId;
     $cid1 = $comment1Id;
     $cid2 = $comment2Id;
     $this->assertEquals($project->id, $dto['project']['id']);
     //$this->assertEquals($text->content, $dto['text']['content']);
     $this->assertEquals($questionId, $dto['question']['id']);
     $this->assertEquals('the question', $dto['question']['title']);
     $this->assertEquals('question description', $dto['question']['description']);
     $this->assertEquals('first answer', $dto['question']['answers'][$aid]['content']);
     $this->assertEquals(10, $dto['question']['answers'][$aid]['score']);
     $this->assertEquals('user3.png', $dto['question']['answers'][$aid]['userRef']['avatar_ref']);
     $this->assertEquals('user3', $dto['question']['answers'][$aid]['userRef']['username']);
     $this->assertEquals('first comment', $dto['question']['answers'][$aid]['comments'][$cid1]['content']);
     $this->assertEquals('user1', $dto['question']['answers'][$aid]['comments'][$cid1]['userRef']['username']);
     $this->assertEquals('user1.png', $dto['question']['answers'][$aid]['comments'][$cid1]['userRef']['avatar_ref']);
     $this->assertEquals('second comment', $dto['question']['answers'][$aid]['comments'][$cid2]['content']);
     $this->assertEquals('user2', $dto['question']['answers'][$aid]['comments'][$cid2]['userRef']['username']);
     $this->assertEquals('user2.png', $dto['question']['answers'][$aid]['comments'][$cid2]['userRef']['avatar_ref']);
 }
 public function testAnswerCRUD_Works()
 {
     $e = new MongoTestEnvironment();
     $e->clean();
     $textRef = MongoTestEnvironment::mockId();
     $project = $e->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     // Create Question
     $question = new QuestionModel($project);
     $question->title = "Some Question";
     $question->textRef->id = $textRef;
     $questionId = $question->write();
     // List
     $question->read($questionId);
     $this->assertCount(0, $question->answers);
     // Create
     $answer = new AnswerModel();
     $answer->content = 'Some answer';
     $id = $question->writeAnswer($answer);
     $comment = new CommentModel();
     $comment->content = 'Some comment';
     $commentId = QuestionModel::writeComment($project->databaseName(), $questionId, $id, $comment);
     $this->assertNotNull($id);
     $this->assertInternalType('string', $id);
     $this->assertEquals(24, strlen($id));
     $this->assertEquals($answer->id->asString(), $id);
     // Read back
     $otherQuestion = new QuestionModel($project, $questionId);
     $otherAnswer = $otherQuestion->answers[$id];
     $this->assertEquals($id, $otherAnswer->id->asString());
     $this->assertEquals('Some answer', $otherAnswer->content);
     $this->assertCount(1, $otherAnswer->comments);
     // Update
     $otherAnswer->content = 'Other answer';
     // Note: Updates to the AnswerModel should not clobber child nodes such as comments. Hence this test.
     // See https://github.com/sillsdev/sfwebchecks/issues/39
     unset($otherAnswer->comments[$commentId]);
     $otherQuestion->read($otherQuestion->id->asString());
     $otherId = $otherQuestion->writeAnswer($otherAnswer);
     $this->assertEquals($id, $otherId);
     // Read back
     $otherQuestion = new QuestionModel($project, $questionId);
     $otherAnswer = $otherQuestion->answers[$id];
     $this->assertEquals($id, $otherAnswer->id->asString());
     $this->assertEquals('Other answer', $otherAnswer->content);
     $this->assertCount(1, $otherAnswer->comments);
     // List
     $this->assertCount(1, $otherQuestion->answers);
     // Delete
     QuestionModel::removeAnswer($project->databaseName(), $questionId, $id);
     // List
     $otherQuestion->read($questionId);
     $this->assertCount(0, $otherQuestion->answers);
 }
 public function testAnswerCRUD_Works()
 {
     $environ = new MongoTestEnvironment();
     $environ->clean();
     $textRef = MongoTestEnvironment::mockId();
     $project = $environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     // Create Question
     $question = new QuestionModel($project);
     $question->title = "Some Question";
     $question->textRef->id = $textRef;
     $questionId = $question->write();
     // Create Answer
     $answer = new AnswerModel();
     $answer->content = 'Some answer';
     $answerId = $question->writeAnswer($answer);
     // List
     $question->read($questionId);
     $count = count($question->answers[$answerId]->comments);
     $this->assertEquals(0, $count);
     // Create
     $comment = new CommentModel();
     $comment->content = 'Some comment';
     $id = QuestionModel::writeComment($project->databaseName(), $questionId, $answerId, $comment);
     $this->assertNotNull($id);
     $this->assertInternalType('string', $id);
     $this->assertEquals(24, strlen($id));
     $this->assertEquals($comment->id->asString(), $id);
     // Read back
     $otherQuestion = new QuestionModel($project, $questionId);
     $otherComment = $otherQuestion->answers[$answerId]->comments[$id];
     $this->assertEquals($id, $otherComment->id->asString());
     $this->assertEquals('Some comment', $otherComment->content);
     // Update
     $otherComment->content = 'Other comment';
     $otherId = $question->writeComment($project->databaseName(), $questionId, $answerId, $otherComment);
     $this->assertEquals($id, $otherId);
     // Read back
     $otherQuestion = new QuestionModel($project, $questionId);
     $otherComment = $otherQuestion->answers[$answerId]->comments[$id];
     $this->assertEquals($id, $otherComment->id->asString());
     $this->assertEquals('Other comment', $otherComment->content);
     // List
     $count = count($otherQuestion->answers[$answerId]->comments);
     $this->assertEquals(1, $count);
     // Delete
     QuestionModel::removeComment($project->databaseName(), $questionId, $answerId, $id);
     // List
     $otherQuestion->read($questionId);
     $count = count($otherQuestion->answers[$answerId]->comments);
     $this->assertEquals(0, $count);
 }
 public function testUserEngagementReport_simpleProjectWithQuestionsAndAnswers_AsExpected()
 {
     $environ = new MongoTestEnvironment();
     $environ->clean();
     $project = $environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $text = new TextModel($project);
     $text->title = "Text 1";
     $usx = MongoTestEnvironment::usxSample();
     $text->content = $usx;
     $textId = $text->write();
     $user1Id = $environ->createUser("user1", "user1", "*****@*****.**");
     $user2Id = $environ->createUser("user2", "user2", "*****@*****.**");
     $user3Id = $environ->createUser("user3", "user3", "*****@*****.**");
     ProjectCommands::updateUserRole($project->id->asString(), $user1Id);
     ProjectCommands::updateUserRole($project->id->asString(), $user2Id);
     ProjectCommands::updateUserRole($project->id->asString(), $user3Id);
     // Workflow is first to create a question
     $question = new QuestionModel($project);
     $question->title = "the question";
     $question->description = "question description";
     $question->textRef->id = $textId;
     $questionId = $question->write();
     // Then to add an answer to a question
     $answer = new AnswerModel();
     $answer->content = "first answer";
     $answer->score = 10;
     $answer->userRef->id = $user3Id;
     $answer->textHightlight = "text highlight";
     $answerId = $question->writeAnswer($answer);
     // Followed by comments
     $comment1 = new CommentModel();
     $comment1->content = "first comment";
     $comment1->userRef->id = $user1Id;
     QuestionModel::writeComment($project->databaseName(), $questionId, $answerId, $comment1);
     $comment2 = new CommentModel();
     $comment2->content = "second comment";
     $comment2->userRef->id = $user2Id;
     QuestionModel::writeComment($project->databaseName(), $questionId, $answerId, $comment2);
     $data = SfchecksReports::UserEngagementReport($project->id->asString());
     $this->assertNotEmpty($data['output']);
 }
 public function testExportCommentsForText_ExportAll_AllExported()
 {
     $project = self::$environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $text = new TextModel($project);
     $text->title = 'Text 1';
     $usx = MongoTestEnvironment::usxSample();
     $text->content = $usx;
     $textId = $text->write();
     $user1Id = self::$environ->createUser('user1', 'user1', '*****@*****.**');
     $user2Id = self::$environ->createUser('user2', 'user2', '*****@*****.**');
     $user3Id = self::$environ->createUser('user3', 'user3', '*****@*****.**');
     // Workflow is first to create a question
     $question = new QuestionModel($project);
     $question->title = 'the question';
     $question->description = 'question description';
     $question->textRef->id = $textId;
     $questionId = $question->write();
     // Then to add an answer to a question
     $answer = new AnswerModel();
     $answer->content = 'first answer';
     $answer->score = 10;
     $answer->userRef->id = $user3Id;
     $answer->tags->exchangeArray(array('export', 'to review'));
     $answer->textHightlight = 'text highlight';
     $answerId = $question->writeAnswer($answer);
     // Followed by comments
     $comment1 = new CommentModel();
     $comment1->content = 'first comment';
     $comment1->userRef->id = $user1Id;
     QuestionModel::writeComment($project->databaseName(), $questionId, $answerId, $comment1);
     $comment2 = new CommentModel();
     $comment2->content = 'second comment';
     $comment2->userRef->id = $user2Id;
     QuestionModel::writeComment($project->databaseName(), $questionId, $answerId, $comment2);
     $params = array('textId' => $textId, 'exportComments' => true, 'exportFlagged' => false, 'tags' => array());
     $download = ParatextExport::exportCommentsForText($project->id->asString(), $textId, $params);
     $this->assertRegExp('/<Contents>first comment \\(by user1/', $download['xml']);
     $this->assertRegExp('/\\(Tags: export, to review\\) \\(10 Votes\\)<\\/Contents>/', $download['xml']);
 }
 public function testEncode_QuestionWithAnswers_DtoReturnsExpectedData()
 {
     $project = self::$environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $projectId = $project->id->asString();
     $text = new TextModel($project);
     $text->title = 'Chapter 3';
     $text->content = '<usx version="2.0"> <chapter number="1" style="c" /> <verse number="1" style="v" /> ' . '<para style="q1">Blessed is the man</para> ' . '<para style="q2">who does not walk in the counsel of the wicked</para> ' . '<para style="q1">or stand in the way of sinners</para> <usx>';
     $textId = $text->write();
     // Answers are tied to specific users, so let's create some sample users
     $user1Id = self::$environ->createUser('jcarter', 'John Carter', '*****@*****.**');
     $user2Id = self::$environ->createUser('dthoris', 'Dejah Thoris', '*****@*****.**');
     // Two questions, with different numbers of answers and different create dates
     $question1 = new QuestionModel($project);
     $question1->title = 'Who is speaking?';
     $question1->description = 'Who is telling the story in this text?';
     $question1->textRef->id = $textId;
     $question1->write();
     $question1->dateCreated->addSeconds(-date_interval_create_from_date_string('1 day')->s);
     $question1Id = $question1->write();
     $question2 = new QuestionModel($project);
     $question2->title = 'Where is the storyteller?';
     $question2->description = 'The person telling this story has just arrived somewhere. Where is he?';
     $question2->textRef->id = $textId;
     $question2Id = $question2->write();
     // One answer for question 1...
     $answer1 = new AnswerModel();
     $answer1->content = 'Me, John Carter.';
     $answer1->score = 10;
     $answer1->userRef->id = $user1Id;
     $answer1->textHightlight = 'I knew that I was on Mars';
     $question1->writeAnswer($answer1);
     // ... and two answers for question 2
     $answer2 = new AnswerModel();
     $answer2->content = 'On Mars.';
     $answer2->score = 1;
     $answer2->userRef->id = $user1Id;
     $answer2->textHightlight = 'I knew that I was on Mars';
     $question2->writeAnswer($answer2);
     $answer3 = new AnswerModel();
     $answer3->content = 'On the planet we call Barsoom, which you inhabitants of Earth normally call Mars.';
     $answer3->score = 7;
     $answer3->userRef->id = $user2Id;
     $answer3->textHightlight = 'I knew that I was on Mars';
     $answer3Id = $question2->writeAnswer($answer3);
     // Comments should NOT show up in the answer count; let's test this.
     $comment1 = new CommentModel();
     $comment1->content = 'By the way, our name for Earth is Jasoom.';
     $comment1->userRef->id = $user2Id;
     QuestionModel::writeComment($project->databaseName(), $question2Id, $answer3Id, $comment1);
     $dto = QuestionListDto::encode($projectId, $textId, $user1Id);
     // Now check that it all looks right, 1 Text & 2 Questions
     $this->assertEquals(2, $dto['count']);
     $this->assertInternalType('array', $dto['entries']);
     $entriesById = self::$environ->indexItemsBy($dto['entries'], 'id');
     $entry0 = $entriesById[$question1Id];
     $entry1 = $entriesById[$question2Id];
     $this->assertEquals('Who is speaking?', $entry0['title']);
     $this->assertEquals('Where is the storyteller?', $entry1['title']);
     $this->assertEquals(1, $entry0['answerCount']);
     $this->assertEquals(2, $entry1['answerCount']);
     // Specifically check if comments got included in answer count
     $this->assertNotEquals(3, $dto['entries'][1]['answerCount'], 'Comments should not be included in answer count.');
     $this->assertEquals(1, $entry0['responseCount']);
     $this->assertEquals(3, $entry1['responseCount']);
     // make sure our text content is coming down into the dto
     $this->assertTrue(strlen($dto['text']['content']) > 0);
     // archive 1 Question
     $question2->isArchived = true;
     $question2->write();
     $dto = QuestionListDto::encode($projectId, $textId, $user1Id);
     // Now check that it all still looks right, now only 1 Question
     $this->assertEquals(1, $dto['count']);
     $this->assertEquals($question1Id, $dto['entries'][0]['id']);
     $this->assertEquals('Who is speaking?', $dto['entries'][0]['title']);
 }
 public function testEncode_TextWithQuestions_DtoReturnsExpectedData()
 {
     $environ = new MongoTestEnvironment();
     $environ->clean();
     $project = $environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $projectId = $project->id->asString();
     // Two texts, with different numbers of questions for each text and different create dates
     $text1 = new TextModel($project);
     $text1->title = 'Chapter 3';
     $text1->content = 'I opened my eyes upon a strange and weird landscape. I knew that I was on Mars; …';
     $text1->write();
     $text1->dateCreated->addSeconds(-date_interval_create_from_date_string('1 day')->s);
     $text1Id = $text1->write();
     $text2 = new TextModel($project);
     $text2->title = 'Chapter 4';
     $text2->content = 'We had gone perhaps ten miles when the ground began to rise very rapidly. …';
     $text2Id = $text2->write();
     // Answers are tied to specific users, so let's create some sample users
     $user1Id = $environ->createUser('jcarter', 'John Carter', '*****@*****.**');
     $user2Id = $environ->createUser('dthoris', 'Dejah Thoris', '*****@*****.**');
     // Two questions for text 1...
     $question1 = new QuestionModel($project);
     $question1->title = 'Who is speaking?';
     $question1->description = 'Who is telling the story in this text?';
     $question1->textRef->id = $text1Id;
     $question1->write();
     $question2 = new QuestionModel($project);
     $question2->title = 'Where is the storyteller?';
     $question2->description = 'The person telling this story has just arrived somewhere. Where is he?';
     $question2->textRef->id = $text1Id;
     $question2Id = $question2->write();
     // ... and one question for text 2.
     $question3 = new QuestionModel($project);
     $question3->title = 'How far had they travelled?';
     $question3->description = 'How far had the group just travelled when this text begins?';
     $question3->textRef->id = $text2Id;
     $question3->write();
     // One answer for question 1...
     $answer1 = new AnswerModel();
     $answer1->content = 'Me, John Carter.';
     $answer1->score = 10;
     $answer1->userRef->id = $user1Id;
     $answer1->textHightlight = 'I knew that I was on Mars';
     $question1->writeAnswer($answer1);
     // ... and two answers for question 2...
     $answer2 = new AnswerModel();
     $answer2->content = 'On Mars.';
     $answer2->score = 1;
     $answer2->userRef->id = $user1Id;
     $answer2->textHightlight = 'I knew that I was on Mars';
     $question2->writeAnswer($answer2);
     $answer3 = new AnswerModel();
     $answer3->content = 'On the planet we call Barsoom, which you inhabitants of Earth normally call Mars.';
     $answer3->score = 7;
     $answer3->userRef->id = $user2Id;
     $answer3->textHightlight = 'I knew that I was on Mars';
     $answer3Id = $question2->writeAnswer($answer3);
     // ... and 1 comment.
     $comment1 = new CommentModel();
     $comment1->content = 'By the way, our name for Earth is Jasoom.';
     $comment1->userRef->id = $user2Id;
     QuestionModel::writeComment($project->databaseName(), $question2Id, $answer3Id, $comment1);
     $dto = ProjectPageDto::encode($projectId, $user1Id);
     $encodedTexts = MongoTestEnvironment::indexItemsBy($dto['texts'], 'id');
     $encodedText1 = $encodedTexts[$text1Id];
     $encodedText2 = $encodedTexts[$text2Id];
     // Now check that it all looks right
     $this->assertInternalType('array', $dto['texts']);
     $this->assertEquals($text2Id, $encodedText2['id']);
     $this->assertEquals($text1Id, $encodedText1['id']);
     $this->assertEquals('Chapter 4', $encodedText2['title']);
     $this->assertEquals('Chapter 3', $encodedText1['title']);
     $this->assertEquals(1, $encodedText2['questionCount']);
     $this->assertEquals(2, $encodedText1['questionCount']);
     $this->assertEquals(0, $encodedText2['responseCount']);
     $this->assertEquals(4, $encodedText1['responseCount']);
     // archive 1 Question
     $question2->isArchived = true;
     $question2->write();
     $dto = ProjectPageDto::encode($projectId, $user1Id);
     $encodedTexts = MongoTestEnvironment::indexItemsBy($dto['texts'], 'id');
     $encodedText1 = $encodedTexts[$text1Id];
     $encodedText2 = $encodedTexts[$text2Id];
     $this->assertEquals(1, $encodedText2['questionCount']);
     $this->assertEquals(1, $encodedText1['questionCount']);
     $this->assertEquals(0, $encodedText2['responseCount']);
     $this->assertEquals(1, $encodedText1['responseCount']);
 }
 /**
  * Creates / Updates a comment on the given answer.
  * @param string $projectId
  * @param string $questionId
  * @param string $answerId
  * @param array $comment
  * @param string $userId
  * @return array Dto
  */
 public static function updateComment($projectId, $questionId, $answerId, $comment, $userId)
 {
     $projectModel = new ProjectModel($projectId);
     ProjectCommands::checkIfArchivedAndThrow($projectModel);
     $questionModel = new QuestionModel($projectModel, $questionId);
     $authorId = $userId;
     if ($comment['id'] != '') {
         // update existing comment
         $oldComment = $questionModel->readComment($answerId, $comment['id']);
         $authorId = $oldComment->userRef->asString();
     }
     $commentModel = new CommentModel();
     JsonDecoder::decode($commentModel, $comment);
     $commentModel->userRef->id = $authorId;
     $commentId = QuestionModel::writeComment($projectModel->databaseName(), $questionId, $answerId, $commentModel);
     $questionModel->read($questionId);
     $newComment = $questionModel->readComment($answerId, $commentId);
     $commentDTO = QuestionCommentDto::encodeComment($newComment);
     if ($comment['id'] != '') {
         // TODO log the activity after we confirm that the comment was successfully updated ; cjh 2013-08
         ActivityCommands::updateComment($projectModel, $questionId, $answerId, $newComment);
     } else {
         ActivityCommands::addComment($projectModel, $questionId, $answerId, $newComment);
     }
     $dto = array();
     $dto[$commentId] = $commentDTO;
     return $dto;
 }
 public function run($mode = 'test')
 {
     $testMode = $mode == 'test';
     $message = "";
     $userList = new UserListModel();
     $userList->read();
     $userIds = array_map(function ($e) {
         return $e['id'];
     }, $userList->entries);
     $projectList = new ProjectListModel();
     $projectList->read();
     $projectIds = array_map(function ($e) {
         return $e['id'];
     }, $projectList->entries);
     $deadCommentUserRefs = 0;
     $deadAnswerUserRefs = 0;
     foreach ($projectIds as $projectId) {
         $project = new ProjectModel($projectId);
         $textList = new TextListModel($project);
         $textList->read();
         $textIds = array_map(function ($e) {
             return $e['id'];
         }, $textList->entries);
         foreach ($textIds as $textId) {
             $questionList = new QuestionListModel($project, $textId);
             $questionList->read();
             $questionIds = array_map(function ($e) {
                 return $e['id'];
             }, $questionList->entries);
             foreach ($questionIds as $questionId) {
                 $question = new QuestionModel($project, $questionId);
                 foreach ($question->answers as $answerId => $answer) {
                     foreach ($answer->comments as $commentId => $comment) {
                         /** @var IdReference $ref */
                         $ref = $comment->userRef;
                         if (!empty($ref->id) && !in_array($ref->asString(), $userIds)) {
                             $comment->userRef->id = '';
                             if (!$testMode) {
                                 $question->writeComment($project->databaseName(), $questionId, $answerId, $comment);
                             }
                             $deadCommentUserRefs++;
                             $message .= "Removed dead user-comment ref {$ref} from question {$questionId}, answer {$answerId}, comment {$commentId}\n";
                         }
                     }
                     $ref = $answer->userRef;
                     if (!empty($ref->id) && !in_array($ref->asString(), $userIds)) {
                         $answer->userRef->id = '';
                         if (!$testMode) {
                             $question->writeAnswer($answer);
                         }
                         $deadAnswerUserRefs++;
                         $message .= "Removed dead user-answer ref {$ref} from question {$questionId}, answer {$answerId}\n";
                     }
                 }
             }
         }
     }
     if ($deadAnswerUserRefs > 0) {
         $message .= "\n\nRemoved dead user references from {$deadAnswerUserRefs} answers\n\n";
     } else {
         $message .= "\n\nNo dead user references were found in answers\n\n";
     }
     if ($deadCommentUserRefs > 0) {
         $message .= "\n\nRemoved dead user references from {$deadCommentUserRefs} comments\n\n";
     } else {
         $message .= "\n\nNo dead user references were found in comments\n\n";
     }
     return $message;
 }
 public function testGetActivityForProject_ProjectWithTextQuestionAnswerAndComments_DtoAsExpected()
 {
     $environ = new MongoTestEnvironment();
     $environ->clean();
     $project = $environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $text = new TextModel($project);
     $text->title = "Text 1";
     $text->content = "text content";
     $textId = $text->write();
     $a1 = ActivityCommands::addText($project, $textId, $text);
     $user1Id = $environ->createUser("user1", "user1", "*****@*****.**");
     $user2Id = $environ->createUser("user2", "user2", "*****@*****.**");
     $user3Id = $environ->createUser("user3", "user3", "*****@*****.**");
     $a2 = ActivityCommands::addUserToProject($project, $user1Id);
     $a3 = ActivityCommands::addUserToProject($project, $user2Id);
     $a4 = ActivityCommands::addUserToProject($project, $user3Id);
     // Workflow is first to create a question
     $question = new QuestionModel($project);
     $question->title = "the question";
     $question->description = "question description";
     $question->textRef->id = $textId;
     $questionId = $question->write();
     $a5 = ActivityCommands::addQuestion($project, $questionId, $question);
     // Then to add an answer to a question
     $answer = new AnswerModel();
     $answer->content = "first answer";
     $answer->score = 10;
     $answer->userRef->id = $user3Id;
     $answer->textHightlight = "text highlight";
     $answerId = $question->writeAnswer($answer);
     $a6 = ActivityCommands::addAnswer($project, $questionId, $answer);
     // Followed by comments
     $comment1 = new CommentModel();
     $comment1->content = "first comment";
     $comment1->userRef->id = $user1Id;
     $comment1Id = QuestionModel::writeComment($project->databaseName(), $questionId, $answerId, $comment1);
     $a7 = ActivityCommands::addComment($project, $questionId, $answerId, $comment1);
     $comment2 = new CommentModel();
     $comment2->content = "second comment";
     $comment2->userRef->id = $user2Id;
     QuestionModel::writeComment($project->databaseName(), $questionId, $answerId, $comment2);
     $a8 = ActivityCommands::addComment($project, $questionId, $answerId, $comment2);
     // updated answer
     $question->read($questionId);
     $answer_updated = $question->readAnswer($answerId);
     $answer_updated->content = "first answer revised";
     $question->writeAnswer($answer_updated);
     $a9 = ActivityCommands::updateAnswer($project, $questionId, $answer_updated);
     // updated comment1
     $question->read($questionId);
     $comment1_updated = $question->readComment($answerId, $comment1Id);
     $comment1_updated->content = "first comment revised";
     QuestionModel::writeComment($project->databaseName(), $questionId, $answerId, $comment1_updated);
     $a10 = ActivityCommands::updateComment($project, $questionId, $answerId, $comment1_updated);
     $dto = ActivityListDto::getActivityForProject($project);
     $expectedProjectRef = ['id' => $project->id->asString(), 'type' => 'sfchecks'];
     $this->assertEquals('add_text', $dto[$a1]['action']);
     $this->assertEquals($expectedProjectRef, $dto[$a1]['projectRef']);
     $this->assertEquals($project->projectName, $dto[$a1]['content']['project']);
     $this->assertEquals($textId, $dto[$a1]['textRef']);
     $this->assertEquals($text->title, $dto[$a1]['content']['text']);
     $this->assertEquals('add_user_to_project', $dto[$a2]['action']);
     $this->assertEquals($expectedProjectRef, $dto[$a2]['projectRef']);
     $this->assertEquals($project->projectName, $dto[$a2]['content']['project']);
     $this->assertEquals($user1Id, $dto[$a2]['userRef']['id']);
     $this->assertEquals('user1', $dto[$a2]['userRef']['username']);
     $this->assertEquals('user1.png', $dto[$a2]['userRef']['avatar_ref']);
     $this->assertEquals('user1', $dto[$a2]['content']['user']);
     $this->assertEquals('add_user_to_project', $dto[$a3]['action']);
     $this->assertEquals($expectedProjectRef, $dto[$a3]['projectRef']);
     $this->assertEquals($project->projectName, $dto[$a3]['content']['project']);
     $this->assertEquals($user2Id, $dto[$a3]['userRef']['id']);
     $this->assertEquals('user2', $dto[$a3]['userRef']['username']);
     $this->assertEquals('user2.png', $dto[$a3]['userRef']['avatar_ref']);
     $this->assertEquals('user2', $dto[$a3]['content']['user']);
     $this->assertEquals('add_user_to_project', $dto[$a4]['action']);
     $this->assertEquals($expectedProjectRef, $dto[$a4]['projectRef']);
     $this->assertEquals($project->projectName, $dto[$a4]['content']['project']);
     $this->assertEquals($user3Id, $dto[$a4]['userRef']['id']);
     $this->assertEquals('user3', $dto[$a4]['userRef']['username']);
     $this->assertEquals('user3.png', $dto[$a4]['userRef']['avatar_ref']);
     $this->assertEquals('user3', $dto[$a4]['content']['user']);
     $this->assertEquals('add_question', $dto[$a5]['action']);
     $this->assertEquals($expectedProjectRef, $dto[$a5]['projectRef']);
     $this->assertEquals($project->projectName, $dto[$a5]['content']['project']);
     $this->assertEquals($textId, $dto[$a5]['textRef']);
     $this->assertEquals($text->title, $dto[$a5]['content']['text']);
     $this->assertEquals($questionId, $dto[$a5]['questionRef']);
     $this->assertEquals($question->title, $dto[$a5]['content']['question']);
     $this->assertEquals('add_answer', $dto[$a6]['action']);
     $this->assertEquals($expectedProjectRef, $dto[$a6]['projectRef']);
     $this->assertEquals($project->projectName, $dto[$a6]['content']['project']);
     $this->assertEquals($textId, $dto[$a6]['textRef']);
     $this->assertEquals($text->title, $dto[$a6]['content']['text']);
     $this->assertEquals($questionId, $dto[$a6]['questionRef']);
     $this->assertEquals($question->title, $dto[$a6]['content']['question']);
     $this->assertEquals($user3Id, $dto[$a6]['userRef']['id']);
     $this->assertEquals('user3', $dto[$a6]['userRef']['username']);
     $this->assertEquals('user3.png', $dto[$a6]['userRef']['avatar_ref']);
     $this->assertEquals($answer->content, $dto[$a6]['content']['answer']);
     $this->assertEquals('user3', $dto[$a6]['content']['user']);
     $this->assertEquals('add_comment', $dto[$a7]['action']);
     $this->assertEquals($expectedProjectRef, $dto[$a7]['projectRef']);
     $this->assertEquals($project->projectName, $dto[$a7]['content']['project']);
     $this->assertEquals($textId, $dto[$a7]['textRef']);
     $this->assertEquals($text->title, $dto[$a7]['content']['text']);
     $this->assertEquals($questionId, $dto[$a7]['questionRef']);
     $this->assertEquals($question->title, $dto[$a7]['content']['question']);
     $this->assertEquals($user1Id, $dto[$a7]['userRef']['id']);
     $this->assertEquals('user1', $dto[$a7]['userRef']['username']);
     $this->assertEquals('user1.png', $dto[$a7]['userRef']['avatar_ref']);
     $this->assertEquals('user1', $dto[$a7]['content']['user']);
     $this->assertEquals($user3Id, $dto[$a7]['userRef2']['id']);
     $this->assertEquals('user3', $dto[$a7]['userRef2']['username']);
     $this->assertEquals('user3.png', $dto[$a7]['userRef2']['avatar_ref']);
     $this->assertEquals('user3', $dto[$a7]['content']['user2']);
     $this->assertEquals($answer->content, $dto[$a7]['content']['answer']);
     $this->assertEquals($comment1->content, $dto[$a7]['content']['comment']);
     $this->assertEquals('add_comment', $dto[$a8]['action']);
     $this->assertEquals($expectedProjectRef, $dto[$a8]['projectRef']);
     $this->assertEquals($project->projectName, $dto[$a8]['content']['project']);
     $this->assertEquals($textId, $dto[$a8]['textRef']);
     $this->assertEquals($text->title, $dto[$a8]['content']['text']);
     $this->assertEquals($questionId, $dto[$a8]['questionRef']);
     $this->assertEquals($question->title, $dto[$a8]['content']['question']);
     $this->assertEquals($user2Id, $dto[$a8]['userRef']['id']);
     $this->assertEquals('user2', $dto[$a8]['userRef']['username']);
     $this->assertEquals('user2.png', $dto[$a8]['userRef']['avatar_ref']);
     $this->assertEquals('user2', $dto[$a8]['content']['user']);
     $this->assertEquals($user3Id, $dto[$a8]['userRef2']['id']);
     $this->assertEquals('user3', $dto[$a8]['userRef2']['username']);
     $this->assertEquals('user3.png', $dto[$a8]['userRef2']['avatar_ref']);
     $this->assertEquals('user3', $dto[$a8]['content']['user2']);
     $this->assertEquals($answer->content, $dto[$a8]['content']['answer']);
     $this->assertEquals($comment2->content, $dto[$a8]['content']['comment']);
     $this->assertEquals('update_answer', $dto[$a9]['action']);
     $this->assertEquals($expectedProjectRef, $dto[$a9]['projectRef']);
     $this->assertEquals($project->projectName, $dto[$a9]['content']['project']);
     $this->assertEquals($textId, $dto[$a9]['textRef']);
     $this->assertEquals($text->title, $dto[$a9]['content']['text']);
     $this->assertEquals($questionId, $dto[$a9]['questionRef']);
     $this->assertEquals($question->title, $dto[$a9]['content']['question']);
     $this->assertEquals($user3Id, $dto[$a9]['userRef']['id']);
     $this->assertEquals('user3', $dto[$a9]['userRef']['username']);
     $this->assertEquals('user3.png', $dto[$a9]['userRef']['avatar_ref']);
     $this->assertEquals('user3', $dto[$a9]['content']['user']);
     $this->assertEquals($answer_updated->content, $dto[$a9]['content']['answer']);
     $this->assertEquals('update_comment', $dto[$a10]['action']);
     $this->assertEquals($expectedProjectRef, $dto[$a10]['projectRef']);
     $this->assertEquals($project->projectName, $dto[$a10]['content']['project']);
     $this->assertEquals($textId, $dto[$a10]['textRef']);
     $this->assertEquals($text->title, $dto[$a10]['content']['text']);
     $this->assertEquals($questionId, $dto[$a10]['questionRef']);
     $this->assertEquals($question->title, $dto[$a10]['content']['question']);
     $this->assertEquals($user1Id, $dto[$a10]['userRef']['id']);
     $this->assertEquals('user1', $dto[$a10]['userRef']['username']);
     $this->assertEquals('user1.png', $dto[$a10]['userRef']['avatar_ref']);
     $this->assertEquals('user1', $dto[$a10]['content']['user']);
     $this->assertEquals($user3Id, $dto[$a10]['userRef2']['id']);
     $this->assertEquals('user3', $dto[$a10]['userRef2']['username']);
     $this->assertEquals('user3.png', $dto[$a10]['userRef2']['avatar_ref']);
     $this->assertEquals('user3', $dto[$a10]['content']['user2']);
     $this->assertEquals($answer_updated->content, $dto[$a10]['content']['answer']);
     $this->assertEquals($comment1_updated->content, $dto[$a10]['content']['comment']);
 }
 public function testUpdateComment_ExistingComment_OriginalAuthorIsPreserved()
 {
     $environ = new MongoTestEnvironment();
     $environ->clean();
     $project = $environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $text = new TextModel($project);
     $text->title = 'Text 1';
     $usx = MongoTestEnvironment::usxSample();
     $text->content = $usx;
     $textId = $text->write();
     $question = new QuestionModel($project);
     $question->textRef->id = $textId;
     $questionId = $question->write();
     $user1Id = $environ->createUser('user1', 'user1', 'user1');
     $user2Id = $environ->createUser('user2', 'user2', 'user2');
     $answer = new AnswerModel();
     $answer->content = 'the answer';
     $answer->userRef->id = $user2Id;
     $answerId = $question->writeAnswer($answer);
     $comment = new CommentModel();
     $comment->userRef->id = $user1Id;
     $comment->content = 'the comment';
     $commentId = $question->writeComment($project->databaseName(), $questionId, $answerId, $comment);
     $commentArray = array('id' => $commentId, 'content' => 'updated comment');
     QuestionCommands::updateComment($project->id->asString(), $questionId, $answerId, $commentArray, $user2Id);
     $question->read($questionId);
     $newComment = $question->readComment($answerId, $commentId);
     $this->assertEquals($user1Id, $newComment->userRef->asString());
 }