/**
 * Rule: belongsTo-shows-name-in-list
 *
 * A belongsTo FK column in a list view must render the parent entity's
 * human-readable DISPLAY NAME, not its raw UUID. This is the contract
 * behind the runtime's relationship resolution (RelatedModelFetcher →
 * resolveEntityDisplayName / getEntityDisplayName) — the exact behaviour
 * that regressed in the belongsTo label/ID bug (runtime 5.11.1).
 *
 * Strategy (composes existing state-sync steps, no new harness helper):
 *   1. seed each of the child's belongsTo parents (with a unique display
 *      marker), binding their ids,
 *   2. create the child with every FK threaded to its parent's id,
 *   3. navigate to the child's list,
 *   4. assert the TARGET parent's display marker is VISIBLE in the list —
 *      it only appears if the FK column resolved the name; a UUID would
 *      show the id instead, so the marker would be absent and the test
 *      fails.
 *
 * Scope (v1): only models whose belongsTo parents are ALL top-level
 * seedable (no required belongsTo of their own — one seed level). Deeper
 * chains (e.g. poll-app's Vote → Option → Poll) are skipped, mirroring
 * create-reflects-in-list's seedability gate. One TestCase per
 * (child-model, belongsTo-relationship) pair.
 */
import { pickDisplayAttribute, buildSeedData, buildSeedDataWithFks } from './_shared.js';
export const RULE_ID = 'belongsTo-shows-name-in-list';
export const belongsToShowsNameInList = (spec) => {
    const cases = [];
    const byName = new Map(spec.models.map(m => [m.name, m]));
    for (const child of spec.models) {
        const belongsTo = (child.relationships || []).filter(r => /belongsTo/i.test(String(r.type || '')));
        if (belongsTo.length === 0)
            continue;
        // Plan a seed for every belongsTo parent. Bail on the whole child if
        // any parent isn't top-level seedable or lacks a display attribute —
        // we can't create the child without all its FKs.
        const marker = `ct-belongsto-${child.name}`;
        const plans = belongsTo.map((rel, i) => {
            const parent = rel.target ? byName.get(rel.target) : undefined;
            const seed = parent ? buildSeedData(parent, `${marker}-${rel.name}`) : null;
            const display = parent ? pickDisplayAttribute(parent) : null;
            return { rel, parent, seed, display, idVar: `_p${i}`, dataVar: `_parent${i}` };
        });
        if (plans.some(p => !p.parent || !p.seed || !p.display))
            continue;
        // One test per belongsTo rel — each asserts that rel's parent resolves.
        for (const target of plans) {
            const steps = [{ action: 'bootRuntime' }];
            // Seed every parent first, so the child's list has the parent
            // entities loaded when it renders + the row appears via WebSocket.
            const fkValues = {};
            for (const p of plans) {
                steps.push({
                    action: 'createEntity',
                    modelName: p.parent.name,
                    data: p.seed,
                    bindAs: `{ id: ${p.idVar}, data: ${p.dataVar} }`,
                    uniqueField: p.display.name,
                });
                fkValues[`${p.rel.name}Id`] = `$expr:${p.idVar}`;
            }
            const childData = buildSeedDataWithFks(child, marker, fkValues);
            steps.push({ action: 'navigateToModel', modelName: child.name });
            steps.push({
                action: 'createEntity',
                modelName: child.name,
                data: childData,
                bindAs: '{ id: _childId, data: _child }',
            });
            // The target parent's display value must show in the child list —
            // i.e. the belongsTo column resolved the name, not the UUID.
            steps.push({
                action: 'expectEntityInList',
                modelName: child.name,
                displayExpr: `String(${target.dataVar}[${JSON.stringify(target.display.name)}])`,
            });
            cases.push({
                ruleId: RULE_ID,
                specElement: `${child.name}.${target.rel.name}`,
                name: `[${RULE_ID}] ${child.name}.${target.rel.name} resolves to the ${target.parent.name}'s name in the list view`,
                steps,
            });
        }
    }
    return cases;
};
//# sourceMappingURL=belongsto-shows-name-in-list.js.map