0c9ea page break validation (#455)
* fix password reset bug * page break precognition validation * precognition validation tests --------- Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
parent
3b5b8f4e3b
commit
f40b95977d
|
|
@ -110,6 +110,7 @@
|
||||||
:theme="theme"
|
:theme="theme"
|
||||||
class="mt-2 px-8 mx-1"
|
class="mt-2 px-8 mx-1"
|
||||||
@click.stop="nextPage"
|
@click.stop="nextPage"
|
||||||
|
:loading="dataForm.busy"
|
||||||
>
|
>
|
||||||
{{ currentFieldsPageBreak.next_btn_text }}
|
{{ currentFieldsPageBreak.next_btn_text }}
|
||||||
</open-form-button>
|
</open-form-button>
|
||||||
|
|
@ -442,9 +443,17 @@ export default {
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
nextPage() {
|
nextPage() {
|
||||||
this.currentFieldGroupIndex += 1
|
const fieldsToValidate = this.currentFields.map(f => f.id)
|
||||||
window.scrollTo({top: 0, behavior: 'smooth'})
|
this.dataForm.busy = true
|
||||||
return false
|
this.dataForm.validate('POST', '/forms/' + this.form.slug + '/answer', {}, fieldsToValidate)
|
||||||
|
.then((data) => {
|
||||||
|
this.currentFieldGroupIndex += 1
|
||||||
|
this.dataForm.busy = false
|
||||||
|
window.scrollTo({top: 0, behavior: 'smooth'})
|
||||||
|
}).catch(err => {
|
||||||
|
this.dataForm.busy = false
|
||||||
|
})
|
||||||
|
return false;
|
||||||
},
|
},
|
||||||
isFieldHidden(field) {
|
isFieldHidden(field) {
|
||||||
return (new FormLogicPropertyResolver(field, this.dataFormValue)).isHidden()
|
return (new FormLogicPropertyResolver(field, this.dataFormValue)).isHidden()
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,43 @@ class Form {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validate(method, url, config = {}, fieldsToValidate = {}) {
|
||||||
|
this.startProcessing()
|
||||||
|
const headers = {
|
||||||
|
'Precognition': true,
|
||||||
|
'Precognition-Validate-Only': Array.from(fieldsToValidate).join(),
|
||||||
|
...config.headers
|
||||||
|
}
|
||||||
|
config = {
|
||||||
|
body: {},
|
||||||
|
params: {},
|
||||||
|
url: url,
|
||||||
|
method: method,
|
||||||
|
headers,
|
||||||
|
...config,
|
||||||
|
}
|
||||||
|
if (method.toLowerCase() === "get") {
|
||||||
|
config.params = { ...this.data(), ...config.params }
|
||||||
|
} else {
|
||||||
|
config.body = { ...this.data(), ...config.data }
|
||||||
|
|
||||||
|
if (hasFiles(config.data) && !config.transformRequest) {
|
||||||
|
config.transformRequest = [(data) => serialize(data)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
opnFetch(config.url, config)
|
||||||
|
.then((data) => {
|
||||||
|
this.finishProcessing()
|
||||||
|
resolve(data)
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.handleErrors(error)
|
||||||
|
reject(error)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
handleErrors(error) {
|
handleErrors(error) {
|
||||||
this.busy = false
|
this.busy = false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ use App\Http\Controllers\SubscriptionController;
|
||||||
use App\Http\Controllers\TemplateController;
|
use App\Http\Controllers\TemplateController;
|
||||||
use App\Http\Controllers\WorkspaceController;
|
use App\Http\Controllers\WorkspaceController;
|
||||||
use App\Http\Middleware\Form\ResolveFormMiddleware;
|
use App\Http\Middleware\Form\ResolveFormMiddleware;
|
||||||
|
use Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
@ -236,7 +237,7 @@ Route::group(['prefix' => 'appsumo'], function () {
|
||||||
*/
|
*/
|
||||||
Route::prefix('forms')->name('forms.')->group(function () {
|
Route::prefix('forms')->name('forms.')->group(function () {
|
||||||
Route::middleware('protected-form')->group(function () {
|
Route::middleware('protected-form')->group(function () {
|
||||||
Route::post('{slug}/answer', [PublicFormController::class, 'answer'])->name('answer');
|
Route::post('{slug}/answer', [PublicFormController::class, 'answer'])->name('answer')->middleware(HandlePrecognitiveRequests::class);
|
||||||
|
|
||||||
// Form content endpoints (user lists, relation lists etc.)
|
// Form content endpoints (user lists, relation lists etc.)
|
||||||
Route::get(
|
Route::get(
|
||||||
|
|
|
||||||
|
|
@ -237,3 +237,69 @@ it('can not submit form with failed custom validation condition', function () {
|
||||||
'message' => $validationMessage,
|
'message' => $validationMessage,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('can validate form answer with precognition', function () {
|
||||||
|
$user = $this->actingAsUser();
|
||||||
|
$workspace = $this->createUserWorkspace($user);
|
||||||
|
$form = $this->createForm($user, $workspace);
|
||||||
|
$properties = $form->properties;
|
||||||
|
$properties[0]['required'] = true;
|
||||||
|
$properties[3]['required'] = true;
|
||||||
|
$properties[6]['required'] = true;
|
||||||
|
$properties[9]['required'] = true;
|
||||||
|
|
||||||
|
$form->properties = $properties;
|
||||||
|
$form->update();
|
||||||
|
|
||||||
|
// Empty submission data should fail validation, with all 4 required fields
|
||||||
|
$response = $this->postJson(route('forms.answer', $form->slug), []);
|
||||||
|
$errors = $response->json()['errors'];
|
||||||
|
$this->assertEquals(sizeof($errors), 4);
|
||||||
|
$response->assertStatus(422);
|
||||||
|
|
||||||
|
// Fill in data for only Name.
|
||||||
|
$submissionData = [];
|
||||||
|
foreach ($properties as $property) {
|
||||||
|
if ($property['name'] == 'Name') {
|
||||||
|
$submissionData[$property['id']] = 'Name';
|
||||||
|
} else {
|
||||||
|
$submissionData[$property['id']] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select only first 3 fields for precognition validation
|
||||||
|
$validateOnlyFields = [
|
||||||
|
$properties[0]['id'],
|
||||||
|
$properties[1]['id'],
|
||||||
|
$properties[2]['id']
|
||||||
|
];
|
||||||
|
|
||||||
|
$precognitionValidateOnly = implode(',', $validateOnlyFields);
|
||||||
|
|
||||||
|
// Partial submission data should pass validation for the precognition only fields.
|
||||||
|
$response = $this->withPrecognition()->withHeaders([
|
||||||
|
'Precognition-Validate-Only' => $precognitionValidateOnly
|
||||||
|
])
|
||||||
|
->postJson(route('forms.answer', $form->slug), $submissionData);
|
||||||
|
|
||||||
|
$response->assertSuccessfulPrecognition();
|
||||||
|
|
||||||
|
|
||||||
|
// Select only next fields for precognition validation
|
||||||
|
$validateOnlyFields = $validateOnlyFields = [
|
||||||
|
$properties[3]['id'],
|
||||||
|
$properties[4]['id'],
|
||||||
|
$properties[5]['id']
|
||||||
|
];
|
||||||
|
$precognitionValidateOnly = implode(',', $validateOnlyFields);
|
||||||
|
|
||||||
|
// Partial submission data should fail validation, but for only one required field specified for precognition validation.
|
||||||
|
$response = $this->withPrecognition()->withHeaders([
|
||||||
|
'Precognition-Validate-Only' => $precognitionValidateOnly
|
||||||
|
])
|
||||||
|
->postJson(route('forms.answer', $form->slug), $submissionData);
|
||||||
|
$errors = $response->json()['errors'];
|
||||||
|
$this->assertEquals(sizeof($errors), 1);
|
||||||
|
$response->assertStatus(422);
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue