public function testEncode_ProjectWithTexts_DtoReturnsTextCount2() { $e = new MongoTestEnvironment(); $e->clean(); $userId = $e->createUser("User", "Name", "*****@*****.**"); $user = new UserModel($userId); $user->role = SystemRoles::SYSTEM_ADMIN; $user->write(); $project = $e->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE); $projectId = $project->id->asString(); $project->ownerRef->id = $userId; $project->write(); $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; …"; $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(); $dto = ProjectListDto::encode($userId, $e->website); $this->assertEqual($dto['count'], 1); $this->assertIsA($dto['entries'], 'array'); $this->assertEqual($dto['entries'][0]['id'], $projectId); $this->assertEqual($dto['entries'][0]['projectName'], SF_TESTPROJECT); $this->assertEqual($dto['entries'][0]['role'], ProjectRoles::NONE); }
public function testUpdateThenRemove_NewProject_CreatesThenRemovesProjectDatabase() { $e = new MongoTestEnvironment(); $e->clean(); $project = $e->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE); $databaseName = $project->databaseName(); $project->remove(); $db = MongoStore::connect($databaseName); $this->assertEqual(count($db->listCollections()), 0); $text = new TextModel($project); $text->title = 'Some Title'; $text->write(); $this->assertTrue(MongoStore::hasDB($databaseName)); $this->assertEqual(count($db->listCollections()), 1); $project->remove(); $this->assertEqual(count($db->listCollections()), 0); }
/** * @param string $projectId * @param JSON $object * @return ID of text updated/added */ public static function updateText($projectId, $object) { $projectModel = new \Api\Model\ProjectModel($projectId); $textModel = new \Api\Model\TextModel($projectModel); $isNewText = $object['id'] == ''; if (!$isNewText) { $textModel->read($object['id']); } JsonDecoder::decode($textModel, $object); TextCommands::makeValidRange($object); if (TextCommands::hasRange($object)) { $usxTrimHelper = new UsxTrimHelper($textModel->content, $object['startCh'] || 0, $object['startVs'] || 0, $object['endCh'] || 0, $object['endVs'] || 0); $textModel->content = $usxTrimHelper->trimUsx(); } $textId = $textModel->write(); if ($isNewText) { ActivityCommands::addText($projectModel, $textId, $textModel); } return $textId; }
public function encodeIdReference($key, $model) { if ($model->asString() == '') { return ''; } if ($key == 'userRef' || $key == 'userRef2') { $user = new UserModel(); if ($user->exists($model->asString())) { $user->read($model->asString()); return array('id' => $user->id->asString(), 'avatar_ref' => $user->avatar_ref, 'username' => $user->username); } else { return ''; } } elseif ($key == 'projectRef') { $project = new ProjectModel($model->asString()); return array('id' => $project->id->asString(), 'type' => $project->appName); } elseif ($key == 'textRef') { $text = new TextModel($this->_project); if ($text->exists($model->asString())) { return $model->asString(); } else { return ''; } } elseif ($key == 'questionRef') { $question = new QuestionModel($this->_project); if ($question->exists($model->asString())) { return $model->asString(); } else { return ''; } } elseif ($key == 'entryRef') { $entry = new LexEntryModel($this->_project); if ($entry->exists($model->asString())) { return $model->asString(); } else { return ''; } } else { return $model->asString(); } }
public function testUserEngagementReport_simpleProjectWithQuestionsAndAnswers_AsExpected() { $e = new MongoTestEnvironment(); $e->clean(); $project = $e->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE); $text = new TextModel($project); $text->title = "Text 1"; $usx = MongoTestEnvironment::usxSample(); $text->content = $usx; $textId = $text->write(); $user1Id = $e->createUser("user1", "user1", "*****@*****.**"); $user2Id = $e->createUser("user2", "user2", "*****@*****.**"); $user3Id = $e->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; $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); $data = SfchecksReports::UserEngagementReport($project->id->asString()); $this->assertTrue($data['output']); }
public function testEncode_ProjectWith2Users1Unvalidated_DtoCorrect1User() { $e = new MongoTestEnvironment(); $e->clean(); $user1Id = $e->createUser("", "", ""); $user1 = new UserModel($user1Id); $user1->role = SystemRoles::USER; $user2Id = $e->createUser("User", "Name", "*****@*****.**"); $user2 = new UserModel($user2Id); $user2->role = SystemRoles::USER; $project = $e->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE); $projectId = $project->id->asString(); $project->addUser($user1Id, ProjectRoles::CONTRIBUTOR); $user1->addProject($projectId); $user1->write(); $project->addUser($user2Id, ProjectRoles::CONTRIBUTOR); $user2->addProject($projectId); $user2->write(); $project->write(); $text1 = new TextModel($project); $text1->title = "Some Title"; $text1->write(); $text2 = new TextModel($project); $text2->title = "Archived Title"; $text2->isArchived = true; $text2->write(); $dto = ProjectSettingsDto::encode($projectId, $user2Id); $this->assertEqual($dto['count'], 1); $this->assertIsA($dto['entries'], 'array'); $this->assertEqual($dto['entries'][0]['id'], $user2Id); $this->assertEqual($dto['entries'][0]['name'], 'Name'); $this->assertEqual($dto['entries'][0]['role'], ProjectRoles::CONTRIBUTOR); $this->assertEqual(count($dto['archivedTexts']), 1); $this->assertEqual($dto['archivedTexts'][0]['title'], 'Archived Title'); $this->assertTrue(count($dto['rights']) > 0, "No rights in dto"); $this->assertEqual($dto['bcs']['op'], 'settings'); $this->assertEqual($dto['bcs']['project'], array('id' => $projectId, 'crumb' => SF_TESTPROJECT)); $this->assertFalse(isset($dto['project']['users'])); $this->assertEqual($dto['project']['id'], $projectId); }
public function testPublishTexts_2ArchivedTexts_1Published() { $e = new MongoTestEnvironment(); $e->clean(); $project = $e->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE); $text1 = new TextModel($project); $text1->title = "Some Title"; $text1->isArchived = true; $text1->write(); $text2 = new TextModel($project); $text2->title = "Another Title"; $text2->isArchived = true; $text2->write(); $this->assertEqual($text1->isArchived, true); $this->assertEqual($text2->isArchived, true); $count = TextCommands::publishTexts($project->id->asString(), array($text1->id->asString())); $text1->read($text1->id->asString()); $text2->read($text2->id->asString()); $this->assertEqual($count, 1); $this->assertEqual($text1->isArchived, false); $this->assertEqual($text2->isArchived, true); }
/** * @param string $projectId * @param string $userId * @returns array - the DTO array */ public static function encode($projectId, $userId) { $userModel = new UserModel($userId); $projectModel = new SfchecksProjectModel($projectId); $textList = new TextListModel($projectModel); $textList->read(); $list = $projectModel->listUsers(); $data = array(); $data['count'] = count($list->entries); $data['entries'] = array_values($list->entries); // re-index array $data['project'] = ProjectSettingsDtoEncoder::encode($projectModel); unset($data['project']['users']); $data['archivedTexts'] = array(); foreach ($textList->entries as $entry) { $textModel = new TextModel($projectModel, $entry['id']); if ($textModel->isArchived) { $questionList = $textModel->listQuestionsWithAnswers(); // Just want count of questions and responses, not whole list $entry['questionCount'] = $questionList->count; $responseCount = 0; // "Responses" = answers + comments foreach ($questionList->entries as $q) { foreach ($q['answers'] as $a) { $commentCount = count($a['comments']); $responseCount += $commentCount + 1; // +1 for this answer } } $entry['responseCount'] = $responseCount; $entry['dateModified'] = $textModel->dateModified->format(\DateTime::RFC2822); $data['archivedTexts'][] = $entry; } } $data['rights'] = RightsHelper::encode($userModel, $projectModel); $data['bcs'] = BreadCrumbHelper::encode('settings', $projectModel, null, null); return $data; }
function testCleanupFiles_4Files2Allowed_2Removed() { $environ = new MongoTestEnvironment(); $environ->clean(); $project = $environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE); $projectId = $project->write(); $text = new TextModel($project); $textId = $text->write(); $fakeId = new Id(); $fakeTextId = $fakeId->asString(); $folderPath = $project->getAssetsFolderPath(); FileUtilities::createAllFolders($folderPath); $allowedExtensions = array(".mp2", ".mp3"); // put a copy of the test files in the folderPath $fileName1 = 'TestAudio1.mp1'; $filePath1 = SfchecksUploadCommands::mediaFilePath($folderPath, $textId, $fileName1); copy(TestPath . 'common/TestAudio.mp3', $filePath1); $fileName2 = 'TestAudio2.mp2'; $filePath2 = SfchecksUploadCommands::mediaFilePath($folderPath, $textId, $fileName2); copy(TestPath . 'common/TestAudio.mp3', $filePath2); $fileName3 = 'TestAudio3.mp3'; $filePath3 = SfchecksUploadCommands::mediaFilePath($folderPath, $textId, $fileName3); copy(TestPath . 'common/TestAudio.mp3', $filePath3); $fileName4 = 'TestAudio4.mp3'; $filePath4 = SfchecksUploadCommands::mediaFilePath($folderPath, $fakeTextId, $fileName4); copy(TestPath . 'common/TestAudio.mp3', $filePath4); $this->assertTrue(file_exists($filePath1), 'File should exist before cleanup'); $this->assertTrue(file_exists($filePath2), 'File should exist before cleanup'); $this->assertTrue(file_exists($filePath3), 'File should exist before cleanup'); $this->assertTrue(file_exists($filePath4), 'File should exist before cleanup'); SfchecksUploadCommands::cleanupFiles($folderPath, $textId, $allowedExtensions); $this->assertTrue(file_exists($filePath1), 'File should exist after cleanup'); $this->assertFalse(file_exists($filePath2), 'File should not exist after cleanup'); $this->assertFalse(file_exists($filePath3), 'File should not exist after cleanup'); $this->assertTrue(file_exists($filePath4), 'File should exist after cleanup'); $environ->cleanupTestFiles($folderPath); }
public function testEncode_2Questions1Archived_DtoCorrect1ArchivedQuestion() { $e = new MongoTestEnvironment(); $e->clean(); $userId = $e->createUser("User", "Name", "*****@*****.**"); $user = new UserModel($userId); $user->role = SystemRoles::USER; $project = $e->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE); $projectId = $project->id->asString(); $project->addUser($userId, ProjectRoles::MANAGER); $user->addProject($projectId); $user->write(); $project->write(); $text = new TextModel($project); $text->title = "Text Title"; $textId = $text->write(); $question1 = new QuestionModel($project); $question1->title = "Some Title"; $question1->textRef->id = $textId; $question1->write(); $question2 = new QuestionModel($project); $question2->title = "Archived Title"; $question2->textRef->id = $textId; $question2->isArchived = true; $question2->write(); $dto = TextSettingsDto::encode($projectId, $textId, $userId); $this->assertIsA($dto['text'], 'array'); $this->assertEqual($dto['text']['id'], $textId); $this->assertEqual($dto['text']['title'], 'Text Title'); $this->assertIsA($dto['archivedQuestions'], 'array'); $this->assertEqual(count($dto['archivedQuestions']), 1); $this->assertEqual($dto['archivedQuestions'][0]['title'], 'Archived Title'); $this->assertTrue(count($dto['rights']) > 0, "No rights in dto"); $this->assertEqual($dto['bcs']['op'], 'settings'); $this->assertEqual($dto['bcs']['project'], array('id' => $projectId, 'crumb' => SF_TESTPROJECT)); }
public function testGetActivityForProject_ProjectWithTextQuestionAnswerAndComments_DtoAsExpected() { $e = new MongoTestEnvironment(); $e->clean(); $project = $e->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 = $e->createUser("user1", "user1", "*****@*****.**"); $user2Id = $e->createUser("user2", "user2", "*****@*****.**"); $user3Id = $e->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; $comment2Id = 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); $this->assertEqual($dto[$a1]['action'], 'add_text'); $this->assertEqual($dto[$a1]['projectRef'], array('id' => $project->id->asString(), 'type' => 'sfchecks')); $this->assertEqual($dto[$a1]['content']['project'], $project->projectName); $this->assertEqual($dto[$a1]['textRef'], $textId); $this->assertEqual($dto[$a1]['content']['text'], $text->title); $this->assertEqual($dto[$a2]['action'], 'add_user_to_project'); $this->assertEqual($dto[$a2]['projectRef'], array('id' => $project->id->asString(), 'type' => 'sfchecks')); $this->assertEqual($dto[$a2]['content']['project'], $project->projectName); $this->assertEqual($dto[$a2]['userRef']['id'], $user1Id); $this->assertEqual($dto[$a2]['userRef']['username'], 'user1'); $this->assertEqual($dto[$a2]['userRef']['avatar_ref'], 'user1.png'); $this->assertEqual($dto[$a2]['content']['user'], 'user1'); $this->assertEqual($dto[$a3]['action'], 'add_user_to_project'); $this->assertEqual($dto[$a3]['projectRef'], array('id' => $project->id->asString(), 'type' => 'sfchecks')); $this->assertEqual($dto[$a3]['content']['project'], $project->projectName); $this->assertEqual($dto[$a3]['userRef']['id'], $user2Id); $this->assertEqual($dto[$a3]['userRef']['username'], 'user2'); $this->assertEqual($dto[$a3]['userRef']['avatar_ref'], 'user2.png'); $this->assertEqual($dto[$a3]['content']['user'], 'user2'); $this->assertEqual($dto[$a4]['action'], 'add_user_to_project'); $this->assertEqual($dto[$a4]['projectRef'], array('id' => $project->id->asString(), 'type' => 'sfchecks')); $this->assertEqual($dto[$a4]['content']['project'], $project->projectName); $this->assertEqual($dto[$a4]['userRef']['id'], $user3Id); $this->assertEqual($dto[$a4]['userRef']['username'], 'user3'); $this->assertEqual($dto[$a4]['userRef']['avatar_ref'], 'user3.png'); $this->assertEqual($dto[$a4]['content']['user'], 'user3'); $this->assertEqual($dto[$a5]['action'], 'add_question'); $this->assertEqual($dto[$a5]['projectRef'], array('id' => $project->id->asString(), 'type' => 'sfchecks')); $this->assertEqual($dto[$a5]['content']['project'], $project->projectName); $this->assertEqual($dto[$a5]['textRef'], $textId); $this->assertEqual($dto[$a5]['content']['text'], $text->title); $this->assertEqual($dto[$a5]['questionRef'], $questionId); $this->assertEqual($dto[$a5]['content']['question'], $question->title); $this->assertEqual($dto[$a6]['action'], 'add_answer'); $this->assertEqual($dto[$a6]['projectRef'], array('id' => $project->id->asString(), 'type' => 'sfchecks')); $this->assertEqual($dto[$a6]['content']['project'], $project->projectName); $this->assertEqual($dto[$a6]['textRef'], $textId); $this->assertEqual($dto[$a6]['content']['text'], $text->title); $this->assertEqual($dto[$a6]['questionRef'], $questionId); $this->assertEqual($dto[$a6]['content']['question'], $question->title); $this->assertEqual($dto[$a6]['userRef']['id'], $user3Id); $this->assertEqual($dto[$a6]['userRef']['username'], 'user3'); $this->assertEqual($dto[$a6]['userRef']['avatar_ref'], 'user3.png'); $this->assertEqual($dto[$a6]['content']['answer'], $answer->content); $this->assertEqual($dto[$a6]['content']['user'], 'user3'); $this->assertEqual($dto[$a7]['action'], 'add_comment'); $this->assertEqual($dto[$a7]['projectRef'], array('id' => $project->id->asString(), 'type' => 'sfchecks')); $this->assertEqual($dto[$a7]['content']['project'], $project->projectName); $this->assertEqual($dto[$a7]['textRef'], $textId); $this->assertEqual($dto[$a7]['content']['text'], $text->title); $this->assertEqual($dto[$a7]['questionRef'], $questionId); $this->assertEqual($dto[$a7]['content']['question'], $question->title); $this->assertEqual($dto[$a7]['userRef']['id'], $user1Id); $this->assertEqual($dto[$a7]['userRef']['username'], 'user1'); $this->assertEqual($dto[$a7]['userRef']['avatar_ref'], 'user1.png'); $this->assertEqual($dto[$a7]['content']['user'], 'user1'); $this->assertEqual($dto[$a7]['userRef2']['id'], $user3Id); $this->assertEqual($dto[$a7]['userRef2']['username'], 'user3'); $this->assertEqual($dto[$a7]['userRef2']['avatar_ref'], 'user3.png'); $this->assertEqual($dto[$a7]['content']['user2'], 'user3'); $this->assertEqual($dto[$a7]['content']['answer'], $answer->content); $this->assertEqual($dto[$a7]['content']['comment'], $comment1->content); $this->assertEqual($dto[$a8]['action'], 'add_comment'); $this->assertEqual($dto[$a8]['projectRef'], array('id' => $project->id->asString(), 'type' => 'sfchecks')); $this->assertEqual($dto[$a8]['content']['project'], $project->projectName); $this->assertEqual($dto[$a8]['textRef'], $textId); $this->assertEqual($dto[$a8]['content']['text'], $text->title); $this->assertEqual($dto[$a8]['questionRef'], $questionId); $this->assertEqual($dto[$a8]['content']['question'], $question->title); $this->assertEqual($dto[$a8]['userRef']['id'], $user2Id); $this->assertEqual($dto[$a8]['userRef']['username'], 'user2'); $this->assertEqual($dto[$a8]['userRef']['avatar_ref'], 'user2.png'); $this->assertEqual($dto[$a8]['content']['user'], 'user2'); $this->assertEqual($dto[$a8]['userRef2']['id'], $user3Id); $this->assertEqual($dto[$a8]['userRef2']['username'], 'user3'); $this->assertEqual($dto[$a8]['userRef2']['avatar_ref'], 'user3.png'); $this->assertEqual($dto[$a8]['content']['user2'], 'user3'); $this->assertEqual($dto[$a8]['content']['answer'], $answer->content); $this->assertEqual($dto[$a8]['content']['comment'], $comment2->content); $this->assertEqual($dto[$a9]['action'], 'update_answer'); $this->assertEqual($dto[$a9]['projectRef'], array('id' => $project->id->asString(), 'type' => 'sfchecks')); $this->assertEqual($dto[$a9]['content']['project'], $project->projectName); $this->assertEqual($dto[$a9]['textRef'], $textId); $this->assertEqual($dto[$a9]['content']['text'], $text->title); $this->assertEqual($dto[$a9]['questionRef'], $questionId); $this->assertEqual($dto[$a9]['content']['question'], $question->title); $this->assertEqual($dto[$a9]['userRef']['id'], $user3Id); $this->assertEqual($dto[$a9]['userRef']['username'], 'user3'); $this->assertEqual($dto[$a9]['userRef']['avatar_ref'], 'user3.png'); $this->assertEqual($dto[$a9]['content']['user'], 'user3'); $this->assertEqual($dto[$a9]['content']['answer'], $answer_updated->content); $this->assertEqual($dto[$a10]['action'], 'update_comment'); $this->assertEqual($dto[$a10]['projectRef'], array('id' => $project->id->asString(), 'type' => 'sfchecks')); $this->assertEqual($dto[$a10]['content']['project'], $project->projectName); $this->assertEqual($dto[$a10]['textRef'], $textId); $this->assertEqual($dto[$a10]['content']['text'], $text->title); $this->assertEqual($dto[$a10]['questionRef'], $questionId); $this->assertEqual($dto[$a10]['content']['question'], $question->title); $this->assertEqual($dto[$a10]['userRef']['id'], $user1Id); $this->assertEqual($dto[$a10]['userRef']['username'], 'user1'); $this->assertEqual($dto[$a10]['userRef']['avatar_ref'], 'user1.png'); $this->assertEqual($dto[$a10]['content']['user'], 'user1'); $this->assertEqual($dto[$a10]['userRef2']['id'], $user3Id); $this->assertEqual($dto[$a10]['userRef2']['username'], 'user3'); $this->assertEqual($dto[$a10]['userRef2']['avatar_ref'], 'user3.png'); $this->assertEqual($dto[$a10]['content']['user2'], 'user3'); $this->assertEqual($dto[$a10]['content']['answer'], $answer_updated->content); $this->assertEqual($dto[$a10]['content']['comment'], $comment1_updated->content); }
public function testUpdateComment_ExistingComment_OriginalAuthorIsPreserved() { $e = new MongoTestEnvironment(); $e->clean(); $project = $e->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 = $e->createUser("user1", "user1", "user1"); $user2Id = $e->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->assertEqual($user1Id, $newComment->userRef->asString()); }
public function testEncode_ArchivedText_ManagerCanViewContributorCannot() { $project = $this->environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE); $projectId = $project->id->asString(); // archived Text $text = new TextModel($project); $text->title = "Chapter 3"; $text->isArchived = true; $textId = $text->write(); // Answers are tied to specific users, so let's create some sample users $managerId = $this->environ->createUser("jcarter", "John Carter", "*****@*****.**"); $contributorId = $this->environ->createUser("dthoris", "Dejah Thoris", "*****@*****.**"); $project->addUser($managerId, ProjectRoles::MANAGER); $project->addUser($contributorId, ProjectRoles::CONTRIBUTOR); $project->write(); $dto = QuestionListDto::encode($projectId, $textId, $managerId); // Manager can view archived Text $this->assertEqual($dto['text']['title'], "Chapter 3"); // Contributor cannot view archived Text, throw Exception $this->environ->inhibitErrorDisplay(); $this->expectException(); $dto = QuestionListDto::encode($projectId, $textId, $contributorId); // nothing runs in the current test function after an exception. IJH 2014-11 }
/** * * @param string $projectId * @param string $userId * @returns array - the DTO array */ public static function encode($projectId, $userId) { $user = new UserModel($userId); $project = new SfchecksProjectModel($projectId); if ($project->isArchived && $project->users[$userId]->role != ProjectRoles::MANAGER) { throw new ResourceNotAvailableException("This Project is no longer available. If this is incorrect contact your project manager."); } $textList = new TextListModel($project); $textList->read(); $data = array(); $data['rights'] = RightsHelper::encode($user, $project); $data['project'] = array('name' => $project->projectName, 'id' => $projectId); $data['texts'] = array(); foreach ($textList->entries as $entry) { $text = new TextModel($project, $entry['id']); if (!$text->isArchived) { $questionList = $text->listQuestionsWithAnswers(); // Just want count of questions and responses, not whole list $entry['questionCount'] = 0; $responseCount = 0; // "Responses" = answers + comments foreach ($questionList->entries as $q) { $question = new QuestionModel($project, $q['id']); if (!$question->isArchived) { $entry['questionCount']++; foreach ($q['answers'] as $a) { $commentCount = count($a['comments']); $responseCount += $commentCount + 1; // +1 for this answer } } } $entry['responseCount'] = $responseCount; $entry['dateCreated'] = $text->dateCreated->format(\DateTime::RFC2822); $data['texts'][] = $entry; } } // sort Texts with newest at the top usort($data['texts'], function ($a, $b) { $sortOn = 'dateCreated'; if (array_key_exists($sortOn, $a) && array_key_exists($sortOn, $b)) { return strtotime($a[$sortOn]) < strtotime($b[$sortOn]) ? 1 : -1; } else { return 0; } }); // future support for members $data['members'] = array(); // unread activity count $unreadActivity = new UnreadActivityModel($userId, $projectId); $unreadItems = $unreadActivity->unreadItems(); $data['activityUnreadCount'] = count($unreadItems); // unread broadcast messages $unreadMessages = new UnreadMessageModel($userId, $projectId); $messageIds = $unreadMessages->unreadItems(); $messages = array(); foreach ($messageIds as $messageId) { $message = new MessageModel($project, $messageId); $messages[] = array('id' => $message->id->asString(), 'subject' => $message->subject, 'content' => $message->content); } $data['broadcastMessages'] = $messages; return $data; }
public function run($mode = 'test') { $testMode = $mode != 'run'; $message = ""; $projectlist = new ProjectListModel(); $projectlist->read(); $textsExamined = 0; $textsUpdated = 0; // foreach existing project foreach ($projectlist->entries as $projectParams) { $projectId = $projectParams['id']; if ($projectParams['projectName'] == 'Jamaican Psalms') { $project = new SfchecksProjectModel($projectId); $textlist = new TextListModel($project); $textlist->read(); // foreach text in project foreach ($textlist->entries as $textParams) { $textsExamined++; $textId = $textParams['id']; $legacyText = new TextModel_sf_v0_9_18($project, $textId); $fileName = ''; if ($legacyText->audioUrl) { $text = new TextModel($project, $textId); if (!$testMode) { if (!$text->audioFileName) { // legacy audioUrl format "assets/<projectId>/<textId>_<fileName>" $fileNamePrefix = $textId . '_'; $pos = strpos($legacyText->audioUrl, $fileNamePrefix); $text->audioFileName = substr($legacyText->audioUrl, $pos + strlen($fileNamePrefix)); } $text->write(); } $message .= "Changed text: {$text->title}\n"; $textsUpdated++; } } if (!$testMode) { TextModel_sf_v0_9_18::removeAudioProperty($project->databaseName()); $message .= "Removed 'audioUrl' property from project: {$project->projectName}\n"; } } } if ($textsUpdated > 0) { $message .= "\n\nChanged {$textsUpdated} legacy texts to only store audio filename\n\n"; } else { $message .= "\n\nNo legacy text audio were found/changed. {$textsExamined} texts examined.\n\n"; } // re-arrange assets folder // - remove <siteName> from path for LF // - add <appName> to path for SF and change <projectId> in path to <projectSlug (databaseName)> $message .= "\n\nRe-arrange assets folder\n~~~~~~~~~~~~~~~~~~~~~~~~\n\n"; $project = new SfchecksProjectModel(); $assetsFolderPath = APPPATH . "assets"; $assetsSubfolders = glob($assetsFolderPath . '/*'); @mkdir($assetsFolderPath . '/lexicon'); @mkdir($assetsFolderPath . '/sfchecks'); foreach ($assetsSubfolders as $assetsSubfolder) { if (file_exists($assetsSubfolder) && is_dir($assetsSubfolder)) { $assetsSubfolderName = basename($assetsSubfolder); if (strpos($assetsSubfolderName, 'languageforge') !== false) { $message .= "Move into lexicon: {$assetsSubfolderName}\n"; $oldFolderPath = $assetsSubfolder . '/lexicon'; $newFolderPath = $assetsFolderPath . '/lexicon'; } elseif ($assetsSubfolderName == 'lexicon' || $assetsSubfolderName == 'sfchecks') { $message .= "No change: {$assetsSubfolderName}\n"; $oldFolderPath = ''; $newFolderPath = ''; $assetsSubfolder = ''; } elseif ($project->exists($assetsSubfolderName)) { $message .= "Move into sfchecks: {$assetsSubfolderName}\n"; $oldFolderPath = $assetsSubfolder; $project->read($assetsSubfolderName); $projectSlug = $project->databaseName(); $newFolderPath = $assetsFolderPath . "/sfchecks/{$projectSlug}"; if (!$testMode) { } } else { $message .= "Delete: {$assetsSubfolderName}\n"; $oldFolderPath = ''; $newFolderPath = ''; } if (!$testMode) { if (file_exists($oldFolderPath) && is_dir($oldFolderPath)) { if (!@rename($oldFolderPath, $newFolderPath)) { $oldFiles = glob($oldFolderPath . '/*'); foreach ($oldFiles as $oldFile) { $newFile = $newFolderPath . '/' . basename($oldFile); rename($oldFile, $newFile); } } } if (file_exists($assetsSubfolder) && is_dir($assetsSubfolder)) { $this->recursiveRemoveFolder($assetsSubfolder); } } } } return $message; }
public function testMultipleUnreadModels_multipleUsers_multipleUpdates_multipleVisitsToQuestionPage_usersHaveDifferentUnreadStates() { $e = new MongoTestEnvironment(); $e->clean(); $project = $e->createProject("unread_test", "unreadCode"); $projectId = $project->id->asString(); $userId1 = $e->createUser('user1', 'user1', 'user1'); $user1 = new UserModel($userId1); $user1->addProject($project->id->asString()); $user1->write(); $userId2 = $e->createUser('user2', 'user2', 'user2'); $user2 = new UserModel($userId2); $user2->addProject($project->id->asString()); $user2->write(); $userId3 = $e->createUser('user3', 'user3', 'user3'); $user3 = new UserModel($userId3); $user3->addProject($project->id->asString()); $user3->write(); $answer1 = array('content' => "test answer 1", 'id' => ''); $answer2 = array('content' => "test answer 2", 'id' => ''); $text = new TextModel($project); $text->title = "Text 1"; $usx = MongoTestEnvironment::usxSample(); $text->content = $usx; $textId = $text->write(); $question = new QuestionModel($project); $question->title = "test question"; $question->textRef->id = $textId; $questionId = $question->write(); $answer1Dto = QuestionCommands::updateAnswer($projectId, $questionId, $answer1, $userId1); $answer2Dto = QuestionCommands::updateAnswer($projectId, $questionId, $answer2, $userId2); $answer1 = array_pop($answer1Dto); $answer1Id = $answer1['id']; $answer2 = array_pop($answer2Dto); $answer2Id = $answer2['id']; // the answer author does NOT get their answer marked as unread $unreadModel = new UnreadAnswerModel($userId1, $projectId, $questionId); $this->assertEqual(count($unreadModel->unreadItems()), 1); // the answer author does NOT get their answer marked as unread $unreadModel = new UnreadAnswerModel($userId2, $projectId, $questionId); $this->assertEqual(count($unreadModel->unreadItems()), 1); $unreadModel = new UnreadAnswerModel($userId3, $projectId, $questionId); $this->assertEqual(count($unreadModel->unreadItems()), 2); // user1 visits question page $pageDto = QuestionCommentDto::encode($projectId, $questionId, $userId1); $unreadModel = new UnreadAnswerModel($userId1, $projectId, $questionId); $this->assertEqual(count($unreadModel->unreadItems()), 0); $unreadModel = new UnreadAnswerModel($userId2, $projectId, $questionId); $this->assertEqual(count($unreadModel->unreadItems()), 1); $unreadModel = new UnreadAnswerModel($userId3, $projectId, $questionId); $this->assertEqual(count($unreadModel->unreadItems()), 2); // user2 visits question page $pageDto = QuestionCommentDto::encode($projectId, $questionId, $userId2); $unreadModel = new UnreadAnswerModel($userId1, $projectId, $questionId); $this->assertEqual(count($unreadModel->unreadItems()), 0); $unreadModel = new UnreadAnswerModel($userId2, $projectId, $questionId); $this->assertEqual(count($unreadModel->unreadItems()), 0); $unreadModel = new UnreadAnswerModel($userId3, $projectId, $questionId); $this->assertEqual(count($unreadModel->unreadItems()), 2); // user2 visits question page $pageDto = QuestionCommentDto::encode($projectId, $questionId, $userId3); $unreadModel = new UnreadAnswerModel($userId1, $projectId, $questionId); $this->assertEqual(count($unreadModel->unreadItems()), 0); $unreadModel = new UnreadAnswerModel($userId2, $projectId, $questionId); $this->assertEqual(count($unreadModel->unreadItems()), 0); $unreadModel = new UnreadAnswerModel($userId3, $projectId, $questionId); $this->assertEqual(count($unreadModel->unreadItems()), 0); }
public function testExportCommentsForText_QuestionArchived_NoneExported() { $e = new MongoTestEnvironment(); $project = $e->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE); $text = new TextModel($project); $text->title = "Text 1"; $usx = MongoTestEnvironment::usxSample(); $text->content = $usx; $textId = $text->write(); $user1Id = $e->createUser("user1", "user1", "*****@*****.**"); $user2Id = $e->createUser("user2", "user2", "*****@*****.**"); $user3Id = $e->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; $question->isArchived = true; $questionId = $question->write(); // Then to add an answer to a question $answer = new AnswerModel(); $answer->content = "first answer"; $answer->score = 10; $answer->userRef->id = $user1Id; $answer->tags->exchangeArray(array('export', 'to review')); $answer->isToBeExported = true; $answerId = $question->writeAnswer($answer); // Then to add an answer to a question $answer = new AnswerModel(); $answer->content = "second answer - very long"; $answer->score = 2; $answer->userRef->id = $user2Id; $answer->tags->exchangeArray(array('to review')); $answer->isToBeExported = false; $answerId = $question->writeAnswer($answer); // Then to add an answer to a question $answer = new AnswerModel(); $answer->content = "third answer - very very very very long"; $answer->userRef->id = $user3Id; $answer->tags->exchangeArray(array('export')); $answer->isToBeExported = true; $answerId = $question->writeAnswer($answer); $params = array('textId' => $textId, 'exportComments' => true, 'exportFlagged' => true, 'tags' => array()); $download = ParatextExport::exportCommentsForText($project->id->asString(), $textId, $params); //echo "<pre>" . print_r($download) . "</pre>"; $this->assertNoPattern('/<Contents>third answer - very very very very long \\(by user3/', $download['xml']); $this->assertNoPattern('/<Contents>second answer/', $download['xml']); $this->assertNoPattern('/<Contents>first answer/', $download['xml']); }
public function testEncode_ArchivedText_ManagerCanViewContributorCannot() { $project = $this->environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE); $managerId = $this->environ->createUser("manager", "manager", "*****@*****.**"); $contributorId = $this->environ->createUser("contributor1", "contributor1", "*****@*****.**"); $project->addUser($managerId, ProjectRoles::MANAGER); $project->addUser($contributorId, ProjectRoles::CONTRIBUTOR); $project->write(); // Question not archived but Text is archived $text = new TextModel($project); $text->title = "Text 1"; $text->isArchived = true; $textId = $text->write(); $question = new QuestionModel($project); $question->title = "the question"; $question->description = "question description"; $question->textRef->id = $textId; $questionId = $question->write(); $dto = QuestionCommentDto::encode($project->id->asString(), $questionId, $managerId); // Manager can view Question of archived Text $this->assertEqual($dto['question']['title'], 'the question'); // Contributor cannot view Question of archived Text, throw Exception $this->environ->inhibitErrorDisplay(); $this->expectException(); $dto = QuestionCommentDto::encode($project->id->asString(), $questionId, $contributorId); // nothing runs in the current test function after an exception. IJH 2014-11 }
/** * Upload a file * * @param string $projectId * @param string $mediaType * @param string $tmpFilePath * @throws \Exception * @return \Api\Model\Shared\Command\UploadResponse */ public static function uploadFile($projectId, $mediaType, $tmpFilePath) { if ($mediaType != 'audio') { throw new \Exception("Unsupported upload type: {$mediaType}"); } if (!$tmpFilePath) { throw new \Exception("Upload controller did not move the uploaded file."); } $textId = $_POST['textId']; $file = $_FILES['file']; $fileName = $file['name']; $finfo = finfo_open(FILEINFO_MIME_TYPE); $fileType = finfo_file($finfo, $tmpFilePath); finfo_close($finfo); $fileName = FileUtilities::replaceSpecialCharacters($fileName); $fileExt = false === ($pos = strrpos($fileName, '.')) ? '' : substr($fileName, $pos); // allowed types: documented, observed $allowedTypes = array("audio/mpeg", "audio/mp3"); $allowedExtensions = array(".mp3"); $response = new UploadResponse(); if (in_array(strtolower($fileType), $allowedTypes) && in_array(strtolower($fileExt), $allowedExtensions)) { // make the folders if they don't exist $project = new SfchecksProjectModel($projectId); $folderPath = $project->getAssetsFolderPath(); FileUtilities::createAllFolders($folderPath); // cleanup previous files of any allowed extension self::cleanupFiles($folderPath, $textId, $allowedExtensions); // move uploaded file from tmp location to assets $filePath = self::mediaFilePath($folderPath, $textId, $fileName); $moveOk = copy($tmpFilePath, $filePath); @unlink($tmpFilePath); // update database with file location $text = new TextModel($project, $textId); $text->audioFileName = ''; if ($moveOk) { $text->audioFileName = $fileName; } $text->write(); // construct server response if ($moveOk && $tmpFilePath) { $data = new MediaResult(); $data->path = $project->getAssetsRelativePath(); $data->fileName = $fileName; $response->result = true; } else { $data = new ErrorResult(); $data->errorType = 'UserMessage'; $data->errorMessage = "{$fileName} could not be saved to the right location. Contact your Site Administrator."; $response->result = false; } } else { $allowedExtensionsStr = implode(", ", $allowedExtensions); $data = new ErrorResult(); $data->errorType = 'UserMessage'; if (count($allowedExtensions) < 1) { $data->errorMessage = "{$fileName} is not an allowed audio file. No audio file formats are currently enabled, contact your Site Administrator."; } elseif (count($allowedExtensions) == 1) { $data->errorMessage = "{$fileName} is not an allowed audio file. Ensure the file is a {$allowedExtensionsStr}."; } else { $data->errorMessage = "{$fileName} is not an allowed audio file. Ensure the file is one of the following types: {$allowedExtensionsStr}."; } $response->result = false; } $response->data = $data; return $response; }
public function testEncode_TextWithQuestions_DtoReturnsExpectedData() { $e = new MongoTestEnvironment(); $e->clean(); $project = $e->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->sub(date_interval_create_from_date_string('1 day')); $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 = $e->createUser("jcarter", "John Carter", "*****@*****.**"); $user2Id = $e->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; $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 = $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; $question3Id = $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"; $answer1Id = $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"; $answer2Id = $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; $comment1Id = QuestionModel::writeComment($project->databaseName(), $question2Id, $answer3Id, $comment1); $dto = ProjectPageDto::encode($projectId, $user1Id); // Now check that it all looks right $this->assertIsa($dto['texts'], 'array'); $this->assertEqual($dto['texts'][0]['id'], $text2Id); $this->assertEqual($dto['texts'][1]['id'], $text1Id); $this->assertEqual($dto['texts'][0]['title'], "Chapter 4"); $this->assertEqual($dto['texts'][1]['title'], "Chapter 3"); $this->assertEqual($dto['texts'][0]['questionCount'], 1); $this->assertEqual($dto['texts'][1]['questionCount'], 2); $this->assertEqual($dto['texts'][0]['responseCount'], 0); $this->assertEqual($dto['texts'][1]['responseCount'], 4); // archive 1 Question $question2->isArchived = true; $question2->write(); $dto = ProjectPageDto::encode($projectId, $user1Id); $this->assertEqual($dto['texts'][0]['questionCount'], 1); $this->assertEqual($dto['texts'][1]['questionCount'], 1); $this->assertEqual($dto['texts'][0]['responseCount'], 0); $this->assertEqual($dto['texts'][1]['responseCount'], 1); }
/** * @param string $projectId * @param array $textIds * @return int Total number of texts removed. */ public static function deleteTexts($projectId, $textIds) { $projectModel = new ProjectModel($projectId); $count = 0; foreach ($textIds as $textId) { TextModel::remove($projectModel->databaseName(), $textId); $count++; } return $count; }