public function testEditProblem() { // Login $author = $this->createUserAndLogin(); // Create a problem $problemData = ProblemsFactory::createProblem(null, null, 1, $author); // Open problem create $this->open('/problemedit.php'); sleep(1); $this->type('name=edit-problem-list', $problemData["request"]["alias"]); $this->waitForValue('name=title', $problemData["request"]["title"]); $problemNewData = ProblemsFactory::getRequest(); $this->type('name=title', $problemNewData["request"]["title"]); $this->type('source', $problemNewData["request"]["source"]); $this->type('time_limit', '666'); $this->type('memory_limit', '1234'); $this->type('validator', 'token-caseless'); $this->type('public', '1'); // Click inicia sesion $this->clickAndWait("//input[@value='Actualizar problema']"); $this->assertElementContainsText('//*[@id="content"]/div[2]/div', "Problem updated succesfully!"); // Verify data in DB $problem_mask = new Problems(); $problem_mask->setTitle($problemNewData["request"]["title"]); $problems = ProblemsDAO::search($problem_mask); // Check that we only retreived 1 element $this->assertEquals(1, count($problems)); $this->assertEquals($problemNewData["request"]["source"], $problems[0]->getSource()); $this->assertEquals(666, $problems[0]->getTimeLimit()); $this->assertEquals(1234, $problems[0]->getMemoryLimit()); $this->assertEquals('token-caseless', $problems[0]->getValidator()); $this->assertEquals('1', $problems[0]->getPublic()); }
/** * Test that we can produce a valid alias from the title */ public function testConstructAliasFromTitle() { // Get the problem data $problemData = ProblemsFactory::getRequest(); $r = $problemData['request']; $problemAuthor = $problemData['author']; // Set a valid "complex" title $r['title'] = 'Lá Venganza Del Malvado Dr. Liraaa'; // Login user $r['auth_token'] = $this->login($problemAuthor); // Get File Uploader Mock and tell Omegaup API to use it FileHandler::SetFileUploader($this->createFileUploaderMock()); // Call the API $response = ProblemController::apiCreate($r); // Validate // Verify response $this->assertEquals('ok', $response['status']); $this->assertEquals('testplan', $response['uploaded_files'][10]); // Verify data in DB $problem_mask = new Problems(); $problem_mask->setTitle($r['title']); $problems = ProblemsDAO::search($problem_mask); // Check that we only retreived 1 element $this->assertEquals(1, count($problems)); $problem = $problems[0]; // Verify contest was found $this->assertNotNull($problem); $this->assertNotNull($problem->getProblemId()); // Verify DB data $this->assertEquals($r['title'], $problem->getTitle()); // Verify problem contents were copied $targetpath = PROBLEMS_PATH . DIRECTORY_SEPARATOR . $problem->getAlias() . DIRECTORY_SEPARATOR; $this->assertFileExists($targetpath . 'testplan'); $this->assertFileExists($targetpath . 'cases'); $this->assertFileExists($targetpath . 'statements' . DIRECTORY_SEPARATOR . 'en.html'); }
/** * Get list of my editable problems * * @param Request $r * @return string * @throws InvalidDatabaseOperationException */ public static function apiProblems(Request $r) { self::authenticateRequest($r); $response = array(); $response['problems'] = array(); try { $problems_key = new Problems(array('author_id' => $r['current_user_id'])); $problems = ProblemsDAO::search($problems_key); foreach ($problems as $problem) { $response['problems'][] = $problem->asArray(); } usort($response['problems'], function ($a, $b) { return $a['problem_id'] > $b['problem_id'] ? -1 : 1; }); } catch (Exception $e) { throw new InvalidDatabaseOperationException($e); } $response['status'] = 'ok'; return $response; }
/** * Update a Contest * * @param Request $r * @return array * @throws InvalidDatabaseOperationException */ public static function apiUpdate(Request $r) { if (OMEGAUP_LOCKDOWN) { throw new ForbiddenAccessException("lockdown"); } // Authenticate request self::authenticateRequest($r); // Validate request self::validateCreateOrUpdate($r, true); // Update contest DAO if (!is_null($r["public"])) { // If going public if ($r["public"] == 1) { self::validateContestCanBePublic($r["contest"]); } $r["contest"]->setPublic($r["public"]); } $valueProperties = array("title", "description", "start_time" => array("transform" => function ($value) { return gmdate('Y-m-d H:i:s', $value); }), "finish_time" => array("transform" => function ($value) { return gmdate('Y-m-d H:i:s', $value); }), "window_length" => array("transform" => function ($value) { return $value == "NULL" ? NULL : $value; }), "scoreboard", "points_decay_factor", "partial_score", "submissions_gap", "feedback", "penalty" => array("transform" => function ($value) { return max(0, intval($value)); }), "penalty_type", "penalty_calc_policy", "show_scoreboard_after", "contestant_must_register"); self::updateValueProperties($r, $r["contest"], $valueProperties); // Push changes try { // Begin a new transaction ContestsDAO::transBegin(); // Save the contest object with data sent by user to the database ContestsDAO::save($r["contest"]); // If the contest is private, add the list of allowed users if (!is_null($r["public"]) && $r["public"] != 1 && $r["hasPrivateUsers"]) { // Get current users $cu_key = new ContestsUsers(array("contest_id" => $r["contest"]->getContestId())); $current_users = ContestsUsersDAO::search($cu_key); $current_users_id = array(); foreach ($current_users as $cu) { array_push($current_users_id, $current_users->getUserId()); } // Check who needs to be deleted and who needs to be added $to_delete = array_diff($current_users_id, $r["private_users_list"]); $to_add = array_diff($r["private_users_list"], $current_users_id); // Add users in the request foreach ($to_add as $userkey) { // Create a temp DAO for the relationship $temp_user_contest = new ContestsUsers(array("contest_id" => $r["contest"]->getContestId(), "user_id" => $userkey, "access_time" => "0000-00-00 00:00:00", "score" => 0, "time" => 0)); // Save the relationship in the DB ContestsUsersDAO::save($temp_user_contest); } // Delete users foreach ($to_delete as $userkey) { // Create a temp DAO for the relationship $temp_user_contest = new ContestsUsers(array("contest_id" => $r["contest"]->getContestId(), "user_id" => $userkey)); // Delete the relationship in the DB ContestsUsersDAO::delete(ContestProblemsDAO::search($temp_user_contest)); } } if (!is_null($r['problems'])) { // Get current problems $p_key = new Problems(array("contest_id" => $r["contest"]->getContestId())); $current_problems = ProblemsDAO::search($p_key); $current_problems_id = array(); foreach ($current_problems as $p) { array_push($current_problems_id, $p->getProblemId()); } // Check who needs to be deleted and who needs to be added $to_delete = array_diff($current_problems_id, self::$problems_id); $to_add = array_diff(self::$problems_id, $current_problems_id); foreach ($to_add as $problem) { $contest_problem = new ContestProblems(array('contest_id' => $r["contest"]->getContestId(), 'problem_id' => $problem, 'points' => $r["problems"][$problem]['points'])); ContestProblemsDAO::save($contest_problem); } foreach ($to_delete as $problem) { $contest_problem = new ContestProblems(array('contest_id' => $r["contest"]->getContestId(), 'problem_id' => $problem)); ContestProblemsDAO::delete(ContestProblemsDAO::search($contest_problem)); } } // End transaction ContestsDAO::transEnd(); } catch (Exception $e) { // Operation failed in the data layer, rollback transaction ContestsDAO::transRollback(); throw new InvalidDatabaseOperationException($e); } // Expire contest-info cache Cache::deleteFromCache(Cache::CONTEST_INFO, $r["contest_alias"]); // Expire contest scoreboard cache Scoreboard::InvalidateScoreboardCache($r["contest"]->getContestId()); // Happy ending $response = array(); $response["status"] = 'ok'; self::$log->info("Contest updated (alias): " . $r['contest_alias']); return $response; }
/** * * Gets a list of problems where current user is the owner * * @param Request $r */ public static function apiMyList(Request $r) { self::authenticateRequest($r); self::validateList($r); $response = array(); $response['results'] = array(); try { $problems = null; if (Authorization::IsSystemAdmin($r['current_user_id'])) { $problems = ProblemsDAO::getAll(null, null, 'problem_id', 'DESC'); } else { $problem_mask = new Problems(array('author_id' => $r['current_user_id'])); $problems = ProblemsDAO::search($problem_mask, 'problem_id', 'DESC', $r['offset'], $r['rowcount']); } foreach ($problems as $problem) { $problemArray = $problem->asArray(); $problemArray['tags'] = ProblemsDAO::getTagsForProblem($problem, false); array_push($response['results'], $problemArray); } } catch (Exception $e) { throw new InvalidDatabaseOperationException($e); } $response['status'] = 'ok'; return $response; }
/** * Tests removed problem admin can't edit a problem anymore * * @expectedException ForbiddenAccessException */ public function testUpdateProblemWithRemovedProblemAdmin() { // Get a problem $problemData = ProblemsFactory::createProblem(); // Create our new admin $problemAdmin = UserFactory::createUser(); // Add admin to the problem $response = ProblemController::apiAddAdmin(new Request(array('usernameOrEmail' => $problemAdmin->username, 'problem_alias' => $problemData['request']['alias'], 'auth_token' => $this->login($problemData['author'])))); $this->assertEquals('ok', $response['status']); // Then remove the user $response = ProblemController::apiRemoveAdmin(new Request(array('usernameOrEmail' => $problemAdmin->username, 'problem_alias' => $problemData['request']['alias'], 'auth_token' => $this->login($problemData['author'])))); $this->assertEquals('ok', $response['status']); //Call API $newTitle = 'new title coadmin'; $response = ProblemController::apiUpdate(new Request(array('problem_alias' => $problemData['request']['alias'], 'title' => $newTitle, 'message' => 'Non-admin powers', 'auth_token' => $this->login($problemAdmin)))); // Verify data in DB $problem_mask = new Problems(); $problem_mask->setTitle($newTitle); $problems = ProblemsDAO::search($problem_mask); }
/** * Tests removed problem admin can't edit a problem anymore * * @expectedException ForbiddenAccessException */ public function testUpdateProblemWithRemovedProblemAdmin() { // Get a problem $problemData = ProblemsFactory::createProblem(); // Create our new admin $problemAdmin = UserFactory::createUser(); // Add admin to the problem $response = ProblemController::apiAddAdmin(new Request(array("usernameOrEmail" => $problemAdmin->username, "problem_alias" => $problemData["request"]["alias"], "auth_token" => $this->login($problemData["author"])))); $this->assertEquals("ok", $response["status"]); // Then remove the user $response = ProblemController::apiRemoveAdmin(new Request(array("usernameOrEmail" => $problemAdmin->username, "problem_alias" => $problemData["request"]["alias"], "auth_token" => $this->login($problemData["author"])))); $this->assertEquals("ok", $response["status"]); //Call API $newTitle = "new title coadmin"; $response = ProblemController::apiUpdate(new Request(array("problem_alias" => $problemData["request"]["alias"], "title" => $newTitle, "message" => 'Non-admin powers', "auth_token" => $this->login($problemAdmin)))); // Verify data in DB $problem_mask = new Problems(); $problem_mask->setTitle($newTitle); $problems = ProblemsDAO::search($problem_mask); }
/** * * Gets a list of problems where current user is the owner * * @param Request $r */ public static function apiMyList(Request $r) { self::authenticateRequest($r); self::validateList($r); $response = array(); $response["results"] = array(); try { $problems = NULL; if (Authorization::IsSystemAdmin($r["current_user_id"])) { $problems = ProblemsDAO::getAll(NULL, NULL, "problem_id", 'DESC'); } else { $problem_mask = new Problems(array("author_id" => $r["current_user_id"])); $problems = ProblemsDAO::search($problem_mask, "problem_id", 'DESC', $r["offset"], $r["rowcount"]); } foreach ($problems as $problem) { $problemArray = $problem->asArray(); $problemArray['tags'] = ProblemsDAO::getTagsForProblem($problem, false); array_push($response["results"], $problemArray); } } catch (Exception $e) { throw new InvalidDatabaseOperationException($e); } $response["status"] = "ok"; return $response; }