ci / node (pull_request) Skipped
ci / version (pull_request) Skipped
ci / docker-build (pull_request) Skipped
ci / publish (pull_request) Skipped
github/ci (branch) GitHub Actions
ci / github (pull_request) Successful in 3m5s
ci / announce (pull_request) Skipped
Recipient suggestions: - the words typed match in any order, each one the start of a word in the name, a nickname, the organization or the address: "jane smi" finds "Smith, Jane", and "globex" finds the people at Globex; - someone written to lately ranks a little above an equal match; - an address already in To, Cc or Bcc is no longer offered in the other two fields. Pasting: - a single web or mailto address pasted over selected words makes those words the link, instead of replacing them with the address; - a pasted or dropped image over 10 MB goes in as an attachment rather than inline, where it would swell every reply. No new strings.
61 lines
2.4 KiB
TypeScript
61 lines
2.4 KiB
TypeScript
import { beforeEach, describe, expect, it } from "vitest";
|
|
import { useContacts } from "@/store/contacts";
|
|
import type { ContactCard } from "@/jmap/types";
|
|
|
|
/*
|
|
* What the recipient field offers as you type. Matching used to take the
|
|
* typed text as one piece, so "jane smi" found nobody filed as "Smith, Jane",
|
|
* and a nickname or a company name found nothing at all.
|
|
*/
|
|
|
|
const card = (id: string, full: string, email: string, extra: Partial<ContactCard> = {}): ContactCard =>
|
|
({ id, uid: id, addressBookIds: { b1: true }, name: { full }, emails: { e: { address: email } }, ...extra }) as unknown as ContactCard;
|
|
|
|
beforeEach(() => {
|
|
useContacts.setState({
|
|
accountId: "a1",
|
|
available: false,
|
|
loaded: true,
|
|
loading: false,
|
|
principalsLoaded: true,
|
|
principals: [],
|
|
sharedCards: {},
|
|
recent: [],
|
|
cards: {
|
|
c1: card("c1", "Smith, Jane", "[email protected]"),
|
|
c2: card("c2", "Robert Jones", "[email protected]", { nicknames: { n: { name: "Bobby" } } } as Partial<ContactCard>),
|
|
c3: card("c3", "Ann Lee", "[email protected]", { organizations: { o: { name: "Globex Industries" } } } as Partial<ContactCard>),
|
|
c4: card("c4", "Ann Taylor", "[email protected]"),
|
|
},
|
|
});
|
|
});
|
|
|
|
const emails = async (q: string) => (await useContacts.getState().suggest(q)).map((s) => s.email);
|
|
|
|
describe("recipient suggestions", () => {
|
|
it("matches the words typed in any order", async () => {
|
|
expect(await emails("jane smi")).toEqual(["[email protected]"]);
|
|
expect(await emails("smi jan")).toEqual(["[email protected]"]);
|
|
});
|
|
|
|
it("does not match when one of the words fits nobody", async () => {
|
|
expect(await emails("jane xyz")).toEqual([]);
|
|
});
|
|
|
|
it("matches a nickname and an organization", async () => {
|
|
expect(await emails("bobby")).toEqual(["[email protected]"]);
|
|
expect(await emails("globex")).toEqual(["[email protected]"]);
|
|
});
|
|
|
|
it("puts someone written to lately ahead of an equal match", async () => {
|
|
expect(await emails("ann")).toEqual(["[email protected]", "[email protected]"]);
|
|
useContacts.setState({ recent: [{ name: "Ann Taylor", email: "[email protected]" }] });
|
|
expect((await emails("ann"))[0]).toBe("[email protected]");
|
|
});
|
|
|
|
it("still ranks a match at the start above a word inside the name", async () => {
|
|
// "jo" starts Jones's surname word; it starts no other card's name or address.
|
|
expect(await emails("jo")).toEqual(["[email protected]"]);
|
|
});
|
|
});
|