<?php
/**
* SeekQuarry/Yioop --
* Open Source Pure PHP Search Engine, Crawler, and Indexer
*
* Copyright (C) 2009 - 2026 Chris Pollett chris@pollett.org
*
* LICENSE:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* END LICENSE
*
* @author Chris Pollett chris@pollett.org
* @license https://www.gnu.org/licenses/ GPL3
* @link https://www.seekquarry.com/
* @copyright 2009 - 2026
* @filesource
*/
namespace seekquarry\yioop\tests;
use seekquarry\yioop\library\JavascriptUnitTest;
/**
* Tests how register_validator.js treats a password box that the site
* drew holding a stand-in for a password nobody is changing, which is
* what the Manage Users screen does. Such a box must not be judged
* against the password rules and must not stop its form being sent,
* since every other change to that account travels on the same form.
*
* @author Chris Pollett
*/
class RegisterValidatorJavascriptTest extends JavascriptUnitTest
{
/**
* Checks that a box still holding the stand-in shows no missing
* requirement and lets its form be sent, that typing a password of
* one's own brings the judging back, and that a box which carries no
* stand-in is judged as it loads the way it always was.
*
* @return string html and Javascript that checks the answer in a
* browser or, from the command line, under node
*/
public function standInPasswordIsLeftAloneTestCase()
{
ob_start();
?>
<div id="passwordStandInTest"></div>
<script src="../scripts/basic.js" ></script>
<script src="../scripts/register_validator.js" ></script>
<script>
var unit_test_results = [];
/* The stand-in the Manage Users screen draws in both of its
password boxes, which the site reads back as "leave the
password alone". */
var stand_in = "5f4dcc3b5aa765d61d8327deb882cf99";
var missing_upper = "an upper-case letter";
/* The feedback opens the list of what is missing with a capital,
so what is looked for here carries one. */
var named_upper = "An upper-case letter";
/* Stands in for the note beside the box, which is the only place
the feedback is written. */
function makeMessage()
{
return {innerHTML: ""};
}
/* Stands in for the password box and the form around it. A form
keeps whatever was listened for so the check can call it and
see whether the send would have been stopped. */
function makeField(value)
{
var form = {
handlers: [],
addEventListener: function (kind, handler) {
this.handlers.push(handler);
}
};
return {value: value, form: form,
addEventListener: function () {},
focus: function () {}};
}
/* Stands in for the hint the helper draws, whose attributes
carry the rules and the wording. */
function makeContainer(message, stands_in)
{
var attributes = {
"data-pw-field": "pass-word",
"data-pw-min": "8",
"data-pw-max": "64",
"data-pw-lower": "0",
"data-pw-upper": "1",
"data-pw-digit": "0",
"data-pw-symbol": "0",
"data-pw-forbidden": "",
"data-pw-gate": "1",
"data-pw-standin": stands_in,
"data-pw-ok": "That password will do",
"data-pw-phrase-short": "too short",
"data-pw-phrase-lower": "a lower-case letter",
"data-pw-phrase-upper": missing_upper,
"data-pw-phrase-digit": "a digit",
"data-pw-phrase-symbol": "a symbol",
"data-pw-phrase-forbidden": "no space"
};
return {
getAttribute: function (name) {
return attributes[name];
},
getElementsByClassName: function () {
return [message];
}
};
}
/* The page these functions would reach is not here, so the box
is handed back directly and the two that only draw are made to
do nothing. */
var current_field = makeField(stand_in);
elt = function () {
return current_field;
};
setClass = function () {};
doMessage = function () {};
var message = makeMessage();
var container = makeContainer(message, "1");
wirePasswordRequirements(container);
unit_test_results.push(
{name: "a box holding the stand-in names nothing missing",
pass: message.innerHTML === ""});
var stopped = false;
current_field.form.handlers[0]({preventDefault: function () {
stopped = true;
}});
unit_test_results.push(
{name: "a box holding the stand-in lets its form be sent",
pass: stopped === false});
current_field.value = "shortone";
showPasswordFeedback(container);
unit_test_results.push(
{name: "a password typed in its place is judged again",
pass: message.innerHTML.indexOf(named_upper) >= 0});
stopped = false;
current_field.form.handlers[0]({preventDefault: function () {
stopped = true;
}});
unit_test_results.push(
{name: "a typed password that breaks a rule is held back",
pass: stopped === true});
var plain_message = makeMessage();
current_field = makeField("shortone");
var plain_container = makeContainer(plain_message, "0");
wirePasswordRequirements(plain_container);
unit_test_results.push(
{name: "a box carrying no stand-in is judged as it loads",
pass: plain_message.innerHTML.indexOf(named_upper) >= 0});
</script>
<?php
$out_data = ob_get_contents();
ob_end_clean();
return $out_data;
}
}