test: les deux cas qui ne doivent pas bouger, et la course que la barriere asynchrone ouvre
(p) `graphs: ""` est l'autre orthographe du dataset entier, jamais un nom de document : le filtre reste seul a decider. C'est une garde, pas un test discriminant - `isNuri` ecarte deja la chaine vide -, et elle epingle le comportement plutot que le chemin. (q) se desabonner pendant que la barriere est en train d'etre franchie ne doit laisser aucune requete ouverte. La barriere rend l'ouverture asynchrone, donc il existe desormais une fenetre ou l'observable a des abonnes, pas de requete, et une ouverture en chemin ; verifie en retirant le controle de generation, ou la requete est creee apres le dernier auditeur et plus rien ne la ferme.
This commit is contained in:
@@ -609,6 +609,54 @@ describe("useShapeQuery", () => {
|
||||
unsub();
|
||||
});
|
||||
|
||||
it("(p) the empty-string `graphs` is the whole dataset too, and is not guarded either", async () => {
|
||||
const ng = makeFake();
|
||||
const orm = makeOrm();
|
||||
inject(ng, orm);
|
||||
setCurrentUser("omar");
|
||||
const mine = await createEntityDoc("omar", "protected");
|
||||
seedEvent(orm, mine, `${mine}:q:one`, "Mine");
|
||||
// Somebody else's, in the same local dataset: the filter is what keeps it out, and
|
||||
// must stay the one that decides here - `""` names no document to refuse.
|
||||
seedEvent(orm, "did:ng:o:not-omars", "did:ng:o:not-omars:q:one", "Theirs");
|
||||
|
||||
// `normalizeScope` maps `""` onto `did:ng:i` (`@ng-org/orm`'s `types.ts`), so the two
|
||||
// spellings are one marker. A barrier that treated `""` as a document name would
|
||||
// refuse the whole dataset for a reference nobody wrote.
|
||||
const obs = useShapeQuery(EventShape, { graphs: "" });
|
||||
const unsub = obs.subscribe(() => {});
|
||||
await tick();
|
||||
await tick();
|
||||
|
||||
const snap = obs.getSnapshot();
|
||||
expect(snap.isError).toBe(false);
|
||||
expect(snap.isSuccess).toBe(true);
|
||||
expect(titles(snap.data)).toEqual(["Mine"]);
|
||||
unsub();
|
||||
});
|
||||
|
||||
it("(q) unsubscribing while the barrier is still crossing leaves no query open", async () => {
|
||||
const ng = makeFake();
|
||||
const orm = makeOrm();
|
||||
inject(ng, orm);
|
||||
setCurrentUser("pia");
|
||||
const mine = await createEntityDoc("pia", "protected");
|
||||
seedEvent(orm, mine, `${mine}:q:one`, "Mine");
|
||||
|
||||
// The barrier is asynchronous now, so there is a window in which the observable has
|
||||
// subscribers, no query, and an open on its way. A teardown landing in that window
|
||||
// must not be overtaken by the open it superseded - otherwise the shape query is
|
||||
// created after the last listener left and nothing is ever going to close it.
|
||||
const obs = useShapeQuery(EventShape, { graphs: [mine] });
|
||||
const unsub = obs.subscribe(() => {});
|
||||
unsub(); // synchronously, while `ensureRepoOpen` is still awaiting the first `State`
|
||||
await tick();
|
||||
await tick();
|
||||
await tick();
|
||||
|
||||
expect(orm.openCount()).toBe(0);
|
||||
});
|
||||
|
||||
// -- teardown ------------------------------------------------------------
|
||||
|
||||
it("(k) the last unsubscribe closes the shape query", async () => {
|
||||
|
||||
Reference in New Issue
Block a user