Skip to content

Commit

Permalink
Add paper API tests, massage paper API
Browse files Browse the repository at this point in the history
  • Loading branch information
kohler committed Dec 2, 2024
1 parent 3bcc510 commit 851baef
Show file tree
Hide file tree
Showing 7 changed files with 271 additions and 91 deletions.
235 changes: 156 additions & 79 deletions src/api/api_paper.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ class Paper_API extends MessageSet {
* @readonly */
public $user;
/** @var bool */
private $notify = true;
/** @var bool */
private $disable_users = false;
/** @var bool */
private $dry_run = false;
/** @var ?ZipArchive */
private $ziparchive;
/** @var ?string */
Expand All @@ -24,86 +28,68 @@ function __construct(Contact $user) {
$this->user = $user;
}

/** @return JsonResult */
static function run_get(Contact $user, Qrequest $qreq, ?PaperInfo $prow) {
$ml = [];
if ($prow) {
$pids = [$prow->paperId];
$prows = PaperInfoSet::make_singleton($prow);
} else if (isset($qreq->q)) {
$srch = new PaperSearch($user, ["q" => $qreq->q, "t" => $qreq->t, "sort" => $qreq->sort]);
$pids = $srch->sorted_paper_ids();
$prows = $srch->conf->paper_set([
"paperId" => $pids,
"options" => true, "topics" => true, "allConflictType" => true
]);
$ml = $srch->message_list();
} else {
return JsonResult::make_parameter_error("p");
if ($prow && ($pj = (new PaperExport($user))->paper_json($prow))) {
return new JsonResult(["ok" => true, "papers" => [$pj]]);
}

$pex = new PaperExport($user);
if ($prow) {
$result = $pex->paper_json($prow);
} else {
$result = [];
foreach ($pids as $pid) {
if (($p = $pex->paper_json($prows->get($pid))))
$result[] = $p;
}
if (isset($qreq->p)) {
return Conf::paper_error_json_result($qreq->annex("paper_whynot"));
}

if (!isset($qreq->q)) {
return JsonResult::make_parameter_error("p");
}

if (!$result) {
return JsonResult::make_permission_error();
$srch = new PaperSearch($user, ["q" => $qreq->q, "t" => $qreq->t, "sort" => $qreq->sort]);
$pids = $srch->sorted_paper_ids();
$prows = $srch->conf->paper_set([
"paperId" => $pids,
"options" => true, "topics" => true, "allConflictType" => true
]);

$pex = new PaperExport($user);
$pjs = [];
foreach ($pids as $pid) {
if (($pj = $pex->paper_json($prows->get($pid))))
$pjs[] = $pj;
}

return ["ok" => true, "message_list" => $ml, "result" => $result];
return new JsonResult([
"ok" => true,
"message_list" => $srch->message_list(),
"papers" => $pjs
]);
}

/** @return array{string,?string} */
static function analyze_zip_contents($zip) {
// find common directory prefix
$dirpfx = null;
for ($i = 0; $i < $zip->numFiles; ++$i) {
$name = $zip->getNameIndex($i);
if ($dirpfx === null) {
$xslash = (int) strrpos($name, "/");
$dirpfx = $xslash ? substr($name, 0, $xslash + 1) : "";
/** @return JsonResult */
private function run_post(Qrequest $qreq, ?PaperInfo $prow) {
if ($this->user->privChair) {
if (friendly_boolean($qreq->disableusers)) {
$this->disable_users = true;
}
while ($dirpfx !== "" && !str_starts_with($name, $dirpfx)) {
$xslash = (int) strrpos($dirpfx, "/", -1);
$dirpfx = $xslash ? substr($dirpfx, 0, $xslash + 1) : "";
if (friendly_boolean($qreq->notify) === false) {
$this->notify = false;
}
if ($dirpfx === "") {
break;
if (friendly_boolean($qreq->addtopics)) {
$this->conf->topic_set()->set_auto_add(true);
$this->conf->options()->refresh_topics();
}
}

// find JSONs
$datas = $jsons = [];
for ($i = 0; $i < $zip->numFiles; ++$i) {
$name = $zip->getNameIndex($i);
if (!str_ends_with($name, ".json")
|| strpos($name, "/", strlen($dirpfx)) !== false
|| $name[strlen($dirpfx)] === ".") {
continue;
}
$jsons[] = $name;
if (preg_match('/\G(?:|.*[-_])data\.json\z/', $name, $m, 0, strlen($dirpfx))) {
$datas[] = $name;
}
if (friendly_boolean($qreq->dryrun)) {
$this->dry_run = true;
}

if (count($datas) === 1) {
return [$dirpfx, $datas[0]];
} else if (count($jsons) === 1) {
return [$dirpfx, $jsons[0]];
} else {
return [$dirpfx, null];
$ct = $qreq->body_content_type();
if ($ct === "application/x-www-form-urlencoded"
|| $ct === "multipart/form-data") {
return $this->run_post_form_data($qreq, $prow);
}
}

private function run_post(Qrequest $qreq, ?PaperInfo $prow) {
$ct = $qreq->body_content_type();
// below here not ready yet
return JsonResult::make_error(400, "<0>Nope");

if ($ct === "application/json") {
$jsonstr = $qreq->body();
} else if ($ct === "application/zip") {
Expand Down Expand Up @@ -132,18 +118,6 @@ private function run_post(Qrequest $qreq, ?PaperInfo $prow) {
return JsonResult::make_error(400, "<0>Expected array of objects");
}

if ($this->user->privChair) {
if ($qreq->disable_users) {
$this->disable_users = true;
}
if ($qreq->add_topics) {
foreach ($this->conf->options()->form_fields() as $opt) {
if ($opt instanceof Topics_PaperOption)
$opt->allow_new_topics(true);
}
}
}

$any_errors = $any_successes = false;
if (is_object($jp)) {
$result = $this->run_one_post(0, $jp);
Expand All @@ -164,7 +138,101 @@ private function run_post(Qrequest $qreq, ?PaperInfo $prow) {
}
}

return ["ok" => !$any_errors, "message_list" => $this->message_list(), "result" => $result];
return new JsonResult([
"ok" => !$any_errors,
"message_list" => $this->message_list(),
"result" => $result
]);
}

/** @return PaperStatus */
private function paper_status() {
return (new PaperStatus($this->user))
->set_disable_users($this->disable_users)
->set_notify($this->notify);
}

/** @return JsonResult */
private function run_post_form_data(Qrequest $qreq, ?PaperInfo $prow) {
if (!$prow) {
if ($qreq->p !== "new") {
return JsonResult::make_missing_error("p");
}
if (isset($qreq->sclass)
&& !$this->conf->submission_round_by_tag($qreq->sclass, true)) {
return JsonResult::make_message_list(MessageItem::error($this->conf->_("<0>{Submission} class ‘{}’ not found", $qreq->sclass)));
}
$prow = PaperInfo::make_new($this->user, $qreq->sclass);
}

$ps = $this->paper_status();
$ok = $ps->prepare_save_paper_web($qreq, $prow);
if (!$ok || $this->dry_run) {
return new JsonResult([
"ok" => $ok,
"message_list" => $ps->message_list(),
"change_list" => $ps->changed_keys()
]);
}

if (!$ps->execute_save()) {
return new JsonResult([
"ok" => false,
"message_list" => $ps->message_list()
]);
}

$ps->log_save_activity("via API");
$pj = (new PaperExport($this->user))->paper_json($ps->saved_prow());
return new JsonResult([
"ok" => true,
"message_list" => $ps->message_list(),
"change_list" => $ps->changed_keys(),
"paper" => $pj
]);
}

/** @return array{string,?string} */
static function analyze_zip_contents($zip) {
// find common directory prefix
$dirpfx = null;
for ($i = 0; $i < $zip->numFiles; ++$i) {
$name = $zip->getNameIndex($i);
if ($dirpfx === null) {
$xslash = (int) strrpos($name, "/");
$dirpfx = $xslash ? substr($name, 0, $xslash + 1) : "";
}
while ($dirpfx !== "" && !str_starts_with($name, $dirpfx)) {
$xslash = (int) strrpos($dirpfx, "/", -1);
$dirpfx = $xslash ? substr($dirpfx, 0, $xslash + 1) : "";
}
if ($dirpfx === "") {
break;
}
}

// find JSONs
$datas = $jsons = [];
for ($i = 0; $i < $zip->numFiles; ++$i) {
$name = $zip->getNameIndex($i);
if (!str_ends_with($name, ".json")
|| strpos($name, "/", strlen($dirpfx)) !== false
|| $name[strlen($dirpfx)] === ".") {
continue;
}
$jsons[] = $name;
if (preg_match('/\G(?:|.*[-_])data\.json\z/', $name, $m, 0, strlen($dirpfx))) {
$datas[] = $name;
}
}

if (count($datas) === 1) {
return [$dirpfx, $datas[0]];
} else if (count($jsons) === 1) {
return [$dirpfx, $jsons[0]];
} else {
return [$dirpfx, null];
}
}

/** @param object $j
Expand Down Expand Up @@ -279,12 +347,21 @@ private function run_one_post($index, $j) {
return $p;
}

/** @return JsonResult */
static function run(Contact $user, Qrequest $qreq, ?PaperInfo $prow) {
$old_overrides = $user->overrides();
if (friendly_boolean($qreq->forceShow) !== false) {
$user->add_overrides(Contact::OVERRIDE_CONFLICT);
}
if ($qreq->is_get()) {
return self::run_get($user, $qreq, $prow);
$jr = self::run_get($user, $qreq, $prow);
} else {
$papi = new Paper_API($user);
return $papi->run_post($qreq, $prow);
$jr = (new Paper_API($user))->run_post($qreq, $prow);
}
$user->set_overrides($old_overrides);
if (($jr->content["message_list"] ?? null) === []) {
unset($jr->content["message_list"]);
}
return $jr;
}
}
1 change: 1 addition & 0 deletions src/databaseidrandomizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,6 @@ function cleanup() {
foreach ($this->reservations as $type => $ids) {
$this->conf->qe("delete from IDReservation where type=? and id?a", $type, $ids);
}
$this->reservations = [];
}
}
2 changes: 1 addition & 1 deletion src/pages/p_paper.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ function handle_update() {
// actually update
$this->ps->execute_save();

$new_prow = $conf->paper_by_id($this->ps->paperId, $this->user, ["topics" => true, "options" => true]);
$new_prow = $this->ps->saved_prow();
if (!$new_prow) {
$this->ps->prepend_msg($conf->_("<0>{Submission} not saved; please correct these errors and try again"), MessageSet::ERROR);
$conf->feedback_msg($this->ps->decorated_message_list());
Expand Down
29 changes: 18 additions & 11 deletions src/paperstatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class PaperStatus extends MessageSet {
private $prow;
/** @var int */
public $paperId;
/** @var ?PaperInfo */
private $saved_prow;
/** @var ?string */
public $title;
/** @var ?list<string> */
Expand Down Expand Up @@ -662,18 +664,17 @@ function has_change() {
/** @param string|PaperOption $field
* @return bool */
function has_change_at($field) {
if (is_string($field)) {
if (in_array($field, $this->_xdiffs)) {
return true;
}
foreach ($this->conf->find_all_fields($field, Conf::MFLAG_OPTION) as $f) {
if (in_array($f, $this->_fdiffs))
return true;
}
return false;
} else {
if (!is_string($field)) {
return in_array($field, $this->_fdiffs);
}
if (in_array($field, $this->_xdiffs)) {
return true;
}
foreach ($this->conf->find_all_fields($field, Conf::MFLAG_OPTION) as $f) {
if (in_array($f, $this->_fdiffs))
return true;
}
return false;
}

/** @return list<string> */
Expand Down Expand Up @@ -1020,7 +1021,7 @@ private function _reset(PaperInfo $prow, $pid) {
assert($prow->paperId !== -1);
parent::clear();
$this->prow = $prow;
$this->paperId = $this->title = null;
$this->paperId = $this->saved_prow = $this->title = null;
$this->_fdiffs = $this->_xdiffs = [];
$this->_unknown_fields = $this->_resave_fields = null;
$this->_conflict_values = [];
Expand Down Expand Up @@ -1558,6 +1559,12 @@ function execute_save() {
return true;
}

/** @return PaperInfo */
function saved_prow() {
$this->saved_prow = $this->saved_prow ?? $this->conf->paper_by_id($this->paperId, $this->user, ["topics" => true, "options" => true]);
return $this->saved_prow;
}

function log_save_activity($via = null) {
// log message
assert(($this->_save_status & self::SAVE_STATUS_SAVED) !== 0);
Expand Down
1 change: 1 addition & 0 deletions test/check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ runcheck test/test07.php "$@"
if $all; then
runcheck test/test08.php "$@"
fi
runcheck test/test09.php "$@"

exit $a
Loading

0 comments on commit 851baef

Please sign in to comment.