Filter the import search from the list of library books
The search through CWA gave no results for books that the full list shows. The search now filters the list that "Show all stories in the library" loads, by title, author and site. The buttons stay disabled until the answer comes. A book that the user imports leaves the list.
This commit is contained in:
+66
-25
@@ -252,48 +252,89 @@ test('library import sends only selected books and handles an empty candidate li
|
||||
assert.deepEqual(api.sent('POST', 'library/import')[0].body, { books: [{ id: 8, uuid: 'a', title: 'A' }], check: false });
|
||||
});
|
||||
|
||||
test('library import search trims the query, selects no book at first and imports the ticked books', async () => {
|
||||
test('library import search filters the loaded list, selects no book at first and imports the ticked books', async () => {
|
||||
await mountStories();
|
||||
const card = section(main, 'Import from the library');
|
||||
const form = nodes(card).find((el) => el.tagName === 'form');
|
||||
const submit = find(form, 'button', 'Search');
|
||||
assert.equal(form.className, 'library-search');
|
||||
assert.equal(find(form, 'button', 'Search').attributes.type, 'submit');
|
||||
emit(form, 'submit');
|
||||
field(card, 'Search the library').value = ' ';
|
||||
emit(form, 'submit');
|
||||
await settle();
|
||||
assert.equal(submit.attributes.type, 'submit');
|
||||
const search = async (text) => {
|
||||
field(card, 'Search the library').value = text;
|
||||
emit(form, 'submit');
|
||||
await settle();
|
||||
};
|
||||
const shown = () => ['Ash & Bone', 'Bright Sky', 'Ash Road'].filter((title) => field(card, title));
|
||||
await search(' ');
|
||||
assert.equal(api.requests.some((r) => r.path.startsWith('library/candidates')), false);
|
||||
field(card, 'Search the library').value = ' A & B ';
|
||||
api.on('GET', 'library/candidates?q=A%20%26%20B', []);
|
||||
emit(form, 'submit');
|
||||
await settle();
|
||||
const books = [
|
||||
{ id: 8, uuid: 'a', title: 'Ash & Bone', authors: ['Wren'], publisher: 'www.royalroad.com' },
|
||||
{ id: 9, uuid: 'b', title: 'Bright Sky', authors: ['Ashley Poe', 'Wren'], publisher: 'archiveofourown.org' },
|
||||
{ id: 10, uuid: 'c', title: 'Ash Road', authors: [], publisher: 'www.royalroad.com' },
|
||||
];
|
||||
api.on('GET', 'library/candidates', books);
|
||||
await search('nothing');
|
||||
assert.match(card.textContent, /No library books from a story site match/);
|
||||
assert.equal(find(card, 'button', 'Import selected'), undefined);
|
||||
const books = [{ id: 8, uuid: 'a', title: 'A', authors: ['W'] }, { id: 9, uuid: 'b', title: 'B', authors: [] }];
|
||||
api.on('GET', 'library/candidates?q=A%20%26%20B', books);
|
||||
emit(form, 'submit');
|
||||
await settle();
|
||||
assert.deepEqual(['Select all', 'A', 'B'].map((label) => field(card, label).checked), [false, false, false]);
|
||||
// Each word must be in the title, the authors or the site. Capitals do not matter.
|
||||
await search(' ASH ');
|
||||
assert.deepEqual(shown(), ['Ash & Bone', 'Bright Sky', 'Ash Road']);
|
||||
await search('ash royalroad');
|
||||
assert.deepEqual(shown(), ['Ash & Bone', 'Ash Road']);
|
||||
await search('wren sky');
|
||||
assert.deepEqual(shown(), ['Bright Sky']);
|
||||
assert.equal(api.sent('GET', 'library/candidates').length, 1, 'One load serves each search');
|
||||
await search('ash');
|
||||
assert.deepEqual(['Select all', ...shown()].map((label) => field(card, label).checked), [false, false, false, false]);
|
||||
await click(card, 'Import selected');
|
||||
assert.equal(writes().length, 0);
|
||||
change(field(card, 'B'), true);
|
||||
change(field(card, 'Bright Sky'), true);
|
||||
api.on('POST', 'library/import', [{ id: 'job' }]);
|
||||
await click(card, 'Import selected');
|
||||
assert.deepEqual(api.sent('POST', 'library/import')[0].body, { books: [{ id: 9, uuid: 'b', title: 'B' }], check: true });
|
||||
// The full list still selects each book.
|
||||
api.on('GET', 'library/candidates', books);
|
||||
assert.deepEqual(api.sent('POST', 'library/import')[0].body, { books: [{ id: 9, uuid: 'b', title: 'Bright Sky' }], check: true });
|
||||
// A queued book leaves the list, without another load.
|
||||
await search('ash');
|
||||
assert.deepEqual(shown(), ['Ash & Bone', 'Ash Road']);
|
||||
assert.equal(api.sent('GET', 'library/candidates').length, 1);
|
||||
// The full list loads again, and selects each book.
|
||||
await click(card, 'Show all stories in the library');
|
||||
assert.deepEqual(['Select all', 'A', 'B'].map((label) => field(card, label).checked), [true, true, true]);
|
||||
assert.equal(api.sent('GET', 'library/candidates').length, 2);
|
||||
assert.deepEqual(['Select all', ...shown()].map((label) => field(card, label).checked), [true, true, true, true]);
|
||||
});
|
||||
|
||||
test('a failed library import search shows the error', async () => {
|
||||
test('the library import buttons cannot be used again until the answer comes', async () => {
|
||||
await mountStories();
|
||||
const card = section(main, 'Import from the library');
|
||||
field(card, 'Search the library').value = 'A';
|
||||
api.on('GET', 'library/candidates?q=A', { error: 'CWA is offline' }, 502);
|
||||
emit(nodes(card).find((el) => el.tagName === 'form'), 'submit');
|
||||
const form = nodes(card).find((el) => el.tagName === 'form');
|
||||
const submit = find(form, 'button', 'Search');
|
||||
const all = find(card, 'button', 'Show all stories in the library');
|
||||
let answer;
|
||||
api.on('GET', 'library/candidates', () => new Promise((resolve) => { answer = resolve; }));
|
||||
field(card, 'Search the library').value = 'a';
|
||||
emit(form, 'submit');
|
||||
await settle();
|
||||
assert.equal(find(card, 'button', 'Import selected'), undefined);
|
||||
assert.equal(submit.disabled, true);
|
||||
emit(form, 'submit');
|
||||
await settle();
|
||||
assert.equal(api.sent('GET', 'library/candidates').length, 1);
|
||||
answer([{ id: 8, uuid: 'a', title: 'A', authors: [] }]);
|
||||
await settle();
|
||||
assert.equal(submit.disabled, false);
|
||||
assert.ok(field(card, 'A'));
|
||||
emit(all, 'click');
|
||||
await settle();
|
||||
assert.equal(all.disabled, true);
|
||||
answer([]);
|
||||
await settle();
|
||||
assert.equal(all.disabled, false);
|
||||
// A failed load frees the button, and the next search loads again.
|
||||
api.on('GET', 'library/candidates', { error: 'CWA is offline' }, 502);
|
||||
await click(card, 'Show all stories in the library');
|
||||
emit(form, 'submit');
|
||||
await settle();
|
||||
assert.equal(submit.disabled, false);
|
||||
assert.equal(all.disabled, false);
|
||||
assert.equal(api.sent('GET', 'library/candidates').length, 4);
|
||||
});
|
||||
|
||||
test('rules edits, moves, removal and paragraph choices are saved in order', async () => {
|
||||
|
||||
Reference in New Issue
Block a user