Kenny
Kenny2mo ago

Text search not case insensitive in testing environment

Hi for some reason my case insensitive test doesn't pass despite it working when i run the function from the dashboard. Here's the test:
test("searchPacts - case insensitive search", async () => {
const { t, user1Id } = await setup();

await createPactWithMembership(t, user1Id, "MORNING YOGA", true);

await t.withIdentity({ subject: USER1_CLERK_ID }).run(async (ctx) => {
const results = await PactDiscoverModel.searchPacts(ctx, "morning");
expect(results).toHaveLength(1);
expect(results[0].title).toBe("MORNING YOGA");
});
});
test("searchPacts - case insensitive search", async () => {
const { t, user1Id } = await setup();

await createPactWithMembership(t, user1Id, "MORNING YOGA", true);

await t.withIdentity({ subject: USER1_CLERK_ID }).run(async (ctx) => {
const results = await PactDiscoverModel.searchPacts(ctx, "morning");
expect(results).toHaveLength(1);
expect(results[0].title).toBe("MORNING YOGA");
});
});
My schema:
pacts: defineTable({
title: v.string(),
category: v.string(),
frequency: v.string(),
fineAmount: v.number(),
proofDetails: v.string(),
selectedProofMethod: v.optional(v.string()),
selectedDataType: v.optional(v.string()),
minimumValue: v.optional(v.string()),
selectedJoinType: v.optional(joinTypeValidator),
selectedAccessRights: v.optional(v.string()),
createdBy: v.id("users"),
createdAt: v.optional(v.number()),
isArchived: v.optional(v.boolean()),
archivedAt: v.optional(v.number()),
})
.index("by_creator", ["createdBy"])
.index("by_category", ["category"])
.index("by_archived", ["isArchived"])
.index("by_join_type", ["selectedJoinType"])
.searchIndex("search_title", {
searchField: "title",
filterFields: ["isArchived", "selectedJoinType"],
}),
pacts: defineTable({
title: v.string(),
category: v.string(),
frequency: v.string(),
fineAmount: v.number(),
proofDetails: v.string(),
selectedProofMethod: v.optional(v.string()),
selectedDataType: v.optional(v.string()),
minimumValue: v.optional(v.string()),
selectedJoinType: v.optional(joinTypeValidator),
selectedAccessRights: v.optional(v.string()),
createdBy: v.id("users"),
createdAt: v.optional(v.number()),
isArchived: v.optional(v.boolean()),
archivedAt: v.optional(v.number()),
})
.index("by_creator", ["createdBy"])
.index("by_category", ["category"])
.index("by_archived", ["isArchived"])
.index("by_join_type", ["selectedJoinType"])
.searchIndex("search_title", {
searchField: "title",
filterFields: ["isArchived", "selectedJoinType"],
}),
My implementation:
const pactTitleResults = await ctx.db
.query("pacts")
.withSearchIndex("search_title", (q) =>
q.search("title", searchQuery).eq("isArchived", false)
)
.collect();
console.log("pactTitleResultss", pactTitleResults);
const pactTitleResults = await ctx.db
.query("pacts")
.withSearchIndex("search_title", (q) =>
q.search("title", searchQuery).eq("isArchived", false)
)
.collect();
console.log("pactTitleResultss", pactTitleResults);
3 Replies
Convex Bot
Convex Bot2mo ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
Kenny
KennyOP2mo ago
some extra info:
stdout | convex/pactDiscover.test.ts > Pact Discovery Business Logic Integration > searchPacts - case insensitive search
pactTitleResultss []

× Pact Discovery Business Logic Integration > searchPacts - case insensitive search 8ms
→ expected [] to have a length of 1 but got +0
stdout | convex/pactDiscover.test.ts > Pact Discovery Business Logic Integration > searchPacts - case insensitive search
pactTitleResultss []

× Pact Discovery Business Logic Integration > searchPacts - case insensitive search 8ms
→ expected [] to have a length of 1 but got +0
// Helper to create a pact with membership (mirroring the createPact mutation structure)
const createPactWithMembership = async (
t: ReturnType<typeof convexTest>,
creatorId: Id<"users">,
title: string,
isPublic: boolean = true,
memberIds: Id<"users">[] = []
) => {
// Create the pact following the same structure as the createPact mutation
const pactId = await t.run(async (ctx) => {
const id = await ctx.db.insert("pacts", {
title,
category: "fitness",
frequency: "daily",
fineAmount: 10,
proofDetails: "Take a photo",
selectedJoinType: isPublic ? "Everyone" : "Invite only",
createdBy: creatorId,
isArchived: false,
});

// Add creator as member (same as in createPact mutation)
await ctx.db.insert("pactMemberships", {
pactId: id,
userId: creatorId,
joinedAt: Date.now(),
isActive: true,
});

return id;
});
// Helper to create a pact with membership (mirroring the createPact mutation structure)
const createPactWithMembership = async (
t: ReturnType<typeof convexTest>,
creatorId: Id<"users">,
title: string,
isPublic: boolean = true,
memberIds: Id<"users">[] = []
) => {
// Create the pact following the same structure as the createPact mutation
const pactId = await t.run(async (ctx) => {
const id = await ctx.db.insert("pacts", {
title,
category: "fitness",
frequency: "daily",
fineAmount: 10,
proofDetails: "Take a photo",
selectedJoinType: isPublic ? "Everyone" : "Invite only",
createdBy: creatorId,
isArchived: false,
});

// Add creator as member (same as in createPact mutation)
await ctx.db.insert("pactMemberships", {
pactId: id,
userId: creatorId,
joinedAt: Date.now(),
isActive: true,
});

return id;
});
ian
ian2mo ago
I think convex-test is not handling case insensitive search. I cut https://github.com/get-convex/convex-test/pull/43 to address this - can you try that version and see if it fixes it?
npm i https://pkg.pr.new/get-convex/convex-test@43
npm i https://pkg.pr.new/get-convex/convex-test@43
GitHub
make text search case insensitive by ianmacartney · Pull Request #...
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Did you find this page helpful?