emilepharand/Babilonia

View on GitHub
tests/api/ideas/utils.ts

Summary

Maintainability
A
35 mins
Test Coverage
import {ExpressionForAdding} from '../../../server/model/ideas/expression';
import {Idea, validate} from '../../../server/model/ideas/idea';
import {IdeaForAdding, getIdeaForAddingFromIdea} from '../../../server/model/ideas/ideaForAdding';
import {Language} from '../../../server/model/languages/language';
import * as ApiUtils from '../../utils/api-utils';
import {addAnyLanguage} from '../../utils/api-utils';
import * as FetchUtils from '../../utils/fetch-utils';
import {FIRST_IDEA_ID} from '../../utils/fetch-utils';
import {getRandomString} from '../../utils/utils';

export async function getBasicIdeaForAdding() {
    const language1 = 'l1' + getRandomString();
    const language2 = 'l2' + getRandomString();
    const language3 = 'l3' + getRandomString();
    return makeIdeaForAdding({
        ee: [
            {language: language1, text: 'l1 e1', known: true},
            {language: language1, text: 'l1 e2'},
            {language: language2, text: 'l2 e1'},
            {language: language3, text: 'l3 e1', known: false},
            {language: language3, text: 'l3 e2'},
        ],
    });
}

export async function addAnyIdeaAndTest() {
    const idea = await getBasicIdeaForAdding();
    await addValidIdeaAndTest(idea);
}

export async function editAnyIdeaAndTest() {
    const ideaForAdding = await getBasicIdeaForAdding();
    const idea = await ApiUtils.addIdea(ideaForAdding);
    const editedIdea = ideaForAdding;
    editedIdea.ee[0].text = 'a new expression 1';
    editedIdea.ee[1].text = 'a new expression 2';
    editedIdea.ee[2] = {languageId: editedIdea.ee[0].languageId, text: 'a new expression 3', known: true};
    editedIdea.ee[3] = {languageId: editedIdea.ee[2].languageId, text: 'a new expression 4', known: false};
    await editValidIdeaAndTest(idea, editedIdea);
}

export async function makeIdeaForAdding(i: {
    ee:(Omit<ExpressionForAdding, 'languageId'> & {language: string;})[]
}): Promise<IdeaForAdding> {
    const uniqueLanguages = Array.from(new Set(i.ee.map(e => e.language)));
    const ll = await Promise.all(uniqueLanguages.map(language => ApiUtils.addLanguage(language)));
    return {ee: i.ee.map(e => ({languageId: ll.find(lang => lang.name === e.language)!.id, text: e.text}))};
}

export async function addIdeaHavingExpressions(ee: string[]): Promise<Idea> {
    const ll = await Promise.all(ee.map(_ => addAnyLanguage()));
    return ApiUtils.addIdea({ee: ee.map((e, i) => ({languageId: ll[i].id, text: e}))});
}

export async function addIdeaHavingLanguages(...languages: Language[]): Promise<Idea> {
    const ee = await Promise.all(languages.map(language => ({languageId: language.id, text: 'e'})));
    return ApiUtils.addIdea({ee});
}

export async function addAnyIdea(): Promise<Idea> {
    return addIdeaHavingExpressions(['e']);
}

export async function testTransformExpressions(inputExpressions: string[], expectedExpressions: string[]) {
    // Adding
    const addedIdea = await addIdeaHavingExpressions(inputExpressions);
    expect(addedIdea.ee.map(e => e.text)).toEqual(expectedExpressions);

    // Editing
    const idea = {...addedIdea};
    idea.ee.forEach((e, i) => {
        e.text = inputExpressions[i];
    });
    const editedIdea = await ApiUtils.editIdea(getIdeaForAddingFromIdea(idea), addedIdea.id);
    expect(editedIdea.ee.map(e => e.text)).toEqual(expectedExpressions);
}

export async function addValidIdeaAndTest(ideaForAdding: IdeaForAdding, expressionsInOrder?: ExpressionForAdding[]): Promise<Idea> {
    const responseIdea = await FetchUtils.addIdea(ideaForAdding);
    expect(responseIdea.status).toEqual(201);
    const idea = await responseIdea.json() as Idea;
    await validateIdea(idea, ideaForAdding, expressionsInOrder);
    return idea;
}

export async function editValidIdeaAndTest(idea: Idea,    newIdea: IdeaForAdding,    expressionsInOrder?: ExpressionForAdding[]) {
    const r = await FetchUtils.editIdea(newIdea, idea.id);
    expect(r.status).toEqual(200);
    const responseIdea = await r.json() as Idea;
    await validateIdea(responseIdea, newIdea, expressionsInOrder);
    return responseIdea;
}

export async function validateIdea(responseIdea: Idea, ideaForAdding: IdeaForAdding, expressionsInOrder?: ExpressionForAdding[]): Promise<void> {
    expect(validate(responseIdea)).toEqual(true);

    const r = await FetchUtils.fetchIdea(responseIdea.id);
    const fetchedIdea = (await r.json()) as Idea;
    expect(r.status).toEqual(200);
    expect(validate(fetchedIdea)).toEqual(true);

    expect(responseIdea.ee.length).toEqual(ideaForAdding.ee.length);

    const languagePromises = [];
    for (let i = 0; i < ideaForAdding.ee.length; i++) {
        const e = expressionsInOrder ? expressionsInOrder[i] : ideaForAdding.ee[i];
        const fetchedExpression = fetchedIdea.ee[i];
        expect(fetchedExpression.text).toEqual(e.text);
        expect(fetchedExpression.language.id).toEqual(e.languageId);
        if (e.known) {
            expect(fetchedExpression.known).toEqual(e.known);
        } else {
            expect(fetchedExpression.known).toBeFalsy();
        }
        languagePromises.push(ApiUtils.fetchLanguage(fetchedExpression.language.id));
    }

    const languages = await Promise.all(languagePromises);
    for (let i = 0; i < ideaForAdding.ee.length; i++) {
        expect(languages[i]).toEqual(fetchedIdea.ee[i].language);
    }
}

export async function editInvalidIdeaAndTest(ideaForAdding: unknown, id: number): Promise<void> {
    const idea1 = await ApiUtils.fetchIdea(id);
    expect((await FetchUtils.editIdea(ideaForAdding, id)).status).toEqual(400);
    const idea2 = await ApiUtils.fetchIdea(id);
    expect(idea1).toEqual(idea2);
}

export async function addInvalidIdeaAndTest(invalidIdea: any): Promise<void> {
    const r = await FetchUtils.addIdea(invalidIdea);
    expect(r.status).toEqual(400);
    expect((await FetchUtils.fetchIdea(FIRST_IDEA_ID)).status).toEqual(404);
}

export async function addMultipleInvalidIdeasAndTest(expressions: string[]) {
    const ideaForAdding = await makeIdeaForAdding({ee: [{language: 'l', text: 'e'}]});
    await Promise.all(expressions.map(e => addInvalidIdeaAndTest({ee: [{...ideaForAdding.ee[0], text: e}]})));
    // Multiple expressions
    await Promise.all(expressions.map(e => addInvalidIdeaAndTest({ee: [{...ideaForAdding.ee[0], text: 'e2'}, {...ideaForAdding.ee[0], text: e}]})));
}

export async function editMultipleInvalidIdeasAndTest(expressions: string[]) {
    const idea = await addIdeaHavingExpressions(['e']);
    const ideaForAdding = getIdeaForAddingFromIdea(idea);

    await Promise.all(expressions.map(e => editInvalidIdeaAndTest({ee: [{...ideaForAdding.ee[0], text: e}]}, idea.id)));
    // Multiple expressions
    await Promise.all(expressions.map(e => editInvalidIdeaAndTest({ee: [{...ideaForAdding.ee[0], text: 'e2'}, {...ideaForAdding.ee[0], text: e}]}, idea.id)));
}