Move JSON Schema logic to Declaform instead of making another component.
This commit is contained in:
@@ -1,66 +1,69 @@
|
||||
import { Declaform } from '../src';
|
||||
|
||||
const MOVIE_FORM_NO_SRC = `
|
||||
<decla-form id="form">
|
||||
<form slot="form">
|
||||
<div class="input-group">
|
||||
<label for="name">Name</label>
|
||||
<input id="name" name="name" />
|
||||
</div>
|
||||
<select id="genre" name="genre">
|
||||
<option value="comedy">Comedy</option>
|
||||
<option value="horror">Horror</option>
|
||||
</select>
|
||||
<fieldset>
|
||||
<legend>Rating</legend>
|
||||
function initTestFormWithAttributes(attributes: Record<string, any>) {
|
||||
const attributeStr = Object.entries(attributes).map(x => x.join('=')).join(' ');
|
||||
return `
|
||||
<decla-form id="form" ${attributeStr}>
|
||||
<form slot="form">
|
||||
<div class="input-group">
|
||||
<label for="rating-type-user">Type</label>
|
||||
<input id="rating-type-user" name="rating.type" type="radio" value="user" />
|
||||
<label for="name">Name</label>
|
||||
<input id="name" name="name" />
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="rating-type-critic">Type</label>
|
||||
<input id="rating-type-critic" name="rating.type" type="radio" value="critic" />
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="rating-score">Score</label>
|
||||
<input id="rating-score" name="rating.score" type="number" />
|
||||
</div>
|
||||
</fieldset>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
</decla-form>
|
||||
`;
|
||||
<select id="genre" name="genre">
|
||||
<option value="comedy">Comedy</option>
|
||||
<option value="horror">Horror</option>
|
||||
</select>
|
||||
<fieldset>
|
||||
<legend>Rating</legend>
|
||||
<div class="input-group">
|
||||
<label for="rating-type-user">Type</label>
|
||||
<input id="rating-type-user" name="rating.type" type="radio" value="user" />
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="rating-type-critic">Type</label>
|
||||
<input id="rating-type-critic" name="rating.type" type="radio" value="critic" />
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="rating-score">Score</label>
|
||||
<input id="rating-score" name="rating.score" type="number" />
|
||||
</div>
|
||||
</fieldset>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
</decla-form>
|
||||
`
|
||||
|
||||
const MOVIE_FORM_HTTP = `
|
||||
<decla-form id="form" src="movie/jaws" action="movie/jaws" method="PUT">
|
||||
<form slot="form">
|
||||
<div class="input-group">
|
||||
<label for="name">Name</label>
|
||||
<input id="name" name="name" />
|
||||
</div>
|
||||
<select id="genre" name="genre">
|
||||
<option value="comedy">Comedy</option>
|
||||
<option value="horror">Horror</option>
|
||||
</select>
|
||||
<fieldset>
|
||||
<legend>Rating</legend>
|
||||
<div class="input-group">
|
||||
<label for="rating-type-user">Type</label>
|
||||
<input id="rating-type-user" name="rating.type" type="radio" value="user" />
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="rating-type-critic">Type</label>
|
||||
<input id="rating-type-critic" name="rating.type" type="radio" value="critic" />
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="rating-score">Score</label>
|
||||
<input id="rating-score" name="rating.score" type="number" />
|
||||
</div>
|
||||
</fieldset>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
</decla-form>
|
||||
`;
|
||||
}
|
||||
|
||||
const MOVIE_SCHEMA = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
},
|
||||
genre: {
|
||||
type: 'string',
|
||||
enum: ['comedy', 'horror'],
|
||||
},
|
||||
rating: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
type: {
|
||||
type: 'string',
|
||||
enum: ['critic', 'user'],
|
||||
},
|
||||
score: {
|
||||
type: 'number',
|
||||
minimum: 0,
|
||||
maximum: 5,
|
||||
},
|
||||
},
|
||||
required: ['type', 'score'],
|
||||
}
|
||||
},
|
||||
required: ['name', 'genre', 'rating']
|
||||
}
|
||||
|
||||
describe('Declaform', () => {
|
||||
afterEach(() => {
|
||||
@@ -68,12 +71,12 @@ describe('Declaform', () => {
|
||||
})
|
||||
|
||||
it('Should mount.', () => {
|
||||
document.body.innerHTML = MOVIE_FORM_NO_SRC;
|
||||
document.body.innerHTML = initTestFormWithAttributes({});
|
||||
expect(document.getElementById('form')).toBeTruthy();
|
||||
})
|
||||
|
||||
it('.toObject() should serialize form into a JS object', () => {
|
||||
document.body.innerHTML = MOVIE_FORM_NO_SRC;
|
||||
document.body.innerHTML = initTestFormWithAttributes({});
|
||||
const form = document.getElementById('form') as Declaform;
|
||||
setInputValue('name', 'Monty Python');
|
||||
setInputValue('genre', 'comedy');
|
||||
@@ -91,7 +94,7 @@ describe('Declaform', () => {
|
||||
});
|
||||
|
||||
it('.hydrate() should populate input fields from a JS object', () => {
|
||||
document.body.innerHTML = MOVIE_FORM_NO_SRC;
|
||||
document.body.innerHTML = initTestFormWithAttributes({});
|
||||
const form = document.getElementById('form') as Declaform;
|
||||
form.hydrate({
|
||||
name: 'Jaws',
|
||||
@@ -120,7 +123,11 @@ describe('Declaform', () => {
|
||||
}
|
||||
})
|
||||
})
|
||||
document.body.innerHTML = MOVIE_FORM_HTTP;
|
||||
document.body.innerHTML = initTestFormWithAttributes({
|
||||
src: 'movie/123',
|
||||
action: 'movie/123',
|
||||
method: 'PUT',
|
||||
});
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 0))
|
||||
|
||||
@@ -129,6 +136,25 @@ describe('Declaform', () => {
|
||||
expect(getInputValue('rating-score')).toBe('5');
|
||||
expect(document.getElementById('rating-type-critic')?.hasAttribute('checked')).toBe(true)
|
||||
});
|
||||
|
||||
it('Should be able to be validated against a JSON Schema', async () => {
|
||||
globalThis.fetch = jest.fn().mockResolvedValue({
|
||||
status: 200,
|
||||
ok: true,
|
||||
json: () => Promise.resolve(MOVIE_SCHEMA),
|
||||
});
|
||||
|
||||
document.body.innerHTML = initTestFormWithAttributes({
|
||||
schema: 'movie_schema'
|
||||
});
|
||||
|
||||
const form = document.getElementById('form') as Declaform;
|
||||
await form.ready;
|
||||
const isValid = await form.validate();
|
||||
|
||||
expect(isValid).toBe(false);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
function setInputValue(id: string, value: string) {
|
||||
|
||||
Reference in New Issue
Block a user