prsm/packages/arc-degit/tests/specs/options/join.test.ts
2024-08-28 09:08:11 -04:00

319 lines
9.4 KiB
TypeScript

import { testSuite, expect } from "manten";
import { nrml, testCollection } from "../../common";
export default testSuite(async ({ describe }) => {
describe("join", ({ test }) => {
test("works", () => {
const users = testCollection();
const tickets = testCollection({ name: "tickets", integerIds: true, timestamps: false });
users.insert({ name: "Jonathan", tickets: [3, 4] });
tickets.insert({ title: "Ticket 0", description: "Ticket 0 description" });
tickets.insert({ title: "Ticket 1", description: "Ticket 1 description" });
tickets.insert({ title: "Ticket 2", description: "Ticket 2 description" });
const res = nrml(users.find({ name: "Jonathan" }, {
join: [{
collection: tickets,
from: "tickets",
on: "_id",
as: "userTickets",
options: {
project: { _id: 0 },
},
}],
}))[0];
expect(res).toEqual({
name: "Jonathan",
tickets: [3, 4],
userTickets: [
{ title: "Ticket 0", description: "Ticket 0 description" },
{ title: "Ticket 1", description: "Ticket 1 description" },
],
});
});
test("will overwrite original property", () => {
const users = testCollection();
const tickets = testCollection({ name: "tickets", integerIds: true, timestamps: false });
users.insert({ name: "Jonathan", tickets: [3, 4] });
tickets.insert({ title: "Ticket 0", description: "Ticket 0 description" });
tickets.insert({ title: "Ticket 1", description: "Ticket 1 description" });
tickets.insert({ title: "Ticket 2", description: "Ticket 2 description" });
const res = nrml(users.find({ name: "Jonathan" }, {
join: [{
collection: tickets,
from: "tickets",
on: "_id",
as: "tickets",
options: {
project: { _id: 0 },
}
}],
}))[0];
const tks = tickets.find({ _id: { $oneOf: [3, 4] } });
expect(res).toEqual({
name: "Jonathan",
tickets: [
{ title: "Ticket 0", description: "Ticket 0 description" },
{ title: "Ticket 1", description: "Ticket 1 description" },
],
});
});
test("creates the 'as' property even when nothing matches", () => {
const users = testCollection();
const tickets = testCollection({ name: "tickets" });
users.insert({ name: "Jonathan", tickets: [] });
const res = nrml(users.find({ name: "Jonathan" }, {
join: [{
collection: tickets,
from: "tickets",
on: "_id",
as: "userTickets",
}],
}))[0];
expect(res).toHaveProperty("userTickets");
expect((res as any).userTickets).toEqual([]);
});
test("creates the 'as' property even when nothing matches, dot notation", () => {
const users = testCollection();
const tickets = testCollection({ name: "tickets" });
users.insert({ name: "Jonathan", tickets: [] });
const res = nrml(users.find({ name: "Jonathan" }, {
join: [{
collection: tickets,
from: "tickets",
on: "_id",
as: "user.tickets",
}],
}))[0];
expect(res).toHaveProperty("user.tickets");
expect((res as any).user.tickets).toEqual([]);
});
test("respects QueryOptions", () => {
const users = testCollection();
const tickets = testCollection({ name: "tickets", integerIds: true });
users.insert({ name: "Jonathan", tickets: [3, 4] });
tickets.insert({ title: "Ticket 0", description: "Ticket 0 description" });
tickets.insert({ title: "Ticket 1", description: "Ticket 1 description" });
tickets.insert({ title: "Ticket 2", description: "Ticket 2 description" });
const res = nrml(users.find({ name: "Jonathan" }, {
join: [{
collection: tickets,
from: "tickets",
on: "_id",
as: "userTickets",
options: { project: { title: 1 } },
}],
}))[0];
expect(res).toEqual({
name: "Jonathan",
tickets: [3, 4],
userTickets: [{ title: "Ticket 0" }, { title: "Ticket 1" }],
});
});
test("multiple joins", () => {
const users = testCollection();
const skills = testCollection({ name: "skills", integerIds: true });
const items = testCollection({ name: "items", integerIds: true });
users.insert({ name: "Jonathan", skills: [3, 4], items: [4, 5] });
skills.insert({ title: "Skill 0" });
skills.insert({ title: "Skill 1" });
skills.insert({ title: "Skill 2" });
items.insert({ title: "Item 0" });
items.insert({ title: "Item 1" });
items.insert({ title: "Item 2" });
const res = nrml(
users.find(
{ name: "Jonathan" },
{
join: [
{
collection: skills,
from: "skills",
on: "_id",
as: "userSkills",
},
{
collection: items,
from: "items",
on: "_id",
as: "userItems",
},
],
}
)
)[0];
const sks = skills.find({ _id: { $oneOf: [3, 4] } });
const its = items.find({ _id: { $oneOf: [4, 5] } });
expect(res).toEqual({
name: "Jonathan",
skills: [3, 4],
items: [4, 5],
userSkills: [...sks],
userItems: [...its],
});
});
test("nested joins", () => {
const users = testCollection({ timestamps: false });
const tickets = testCollection({ name: "tickets", integerIds: true, timestamps: false });
const seats = testCollection({ name: "seats", integerIds: true, timestamps: false });
users.insert({ name: "Jonathan", tickets: [3, 4] });
tickets.insert({ title: "Ticket 0", seat: 3 });
tickets.insert({ title: "Ticket 1", seat: 5 });
tickets.insert({ title: "Ticket 2" });
seats.insert({ seat: "S3" });
seats.insert({ seat: "S4" });
seats.insert({ seat: "S5" });
const res = nrml(users.find({ name: "Jonathan" }, {
join: [{
collection: tickets,
from: "tickets",
on: "_id",
as: "userTickets",
options: {
project: { _id: 0 },
join: [{
collection: seats,
from: "seat",
on: "_id",
as: "ticketSeats",
options: {
project: { _id: 0 },
}
}]
},
}],
project: { _id: 0 },
}))[0];
expect(res).toEqual({
name: "Jonathan",
tickets: [3, 4],
userTickets: [
{
title: "Ticket 0",
seat: 3,
ticketSeats: [{ seat: "S3" }],
},
{
title: "Ticket 1",
seat: 5,
ticketSeats: [{ seat: "S5" }],
},
]
});
});
test("with join.from and join.as dot notation, accessing array index on join.as", () => {
const inventory = testCollection();
const items = testCollection({ name: "items", integerIds: true });
inventory.insert({
name: "Jonathan",
items: [
{ itemId: 3, quantity: 1 },
{ itemId: 5, quantity: 2 },
],
});
items.insert({ name: "The Unstoppable Force", atk: 100 }); // id 3
items.insert({ name: "Sneakers", agi: 100 }); // id 4
items.insert({ name: "The Immovable Object", def: 100 }); // id 5
const res = nrml(inventory.find({ name: "Jonathan" }, {
join: [{
collection: items,
from: "items.*.itemId",
on: "_id",
as: "items.*.itemData",
options: {
project: { _id: 0, _created_at: 0, _updated_at: 0 },
}
}],
}))[0];
expect(res).toEqual({
name: "Jonathan",
items: [
{ itemId: 3, quantity: 1, itemData: { name: "The Unstoppable Force", atk: 100 } },
{ itemId: 5, quantity: 2, itemData: { name: "The Immovable Object", def: 100 } },
],
})
});
test("with join.from and join.as dot notation, no array '*' on join.as", () => {
const inventory = testCollection();
const items = testCollection({ name: "items", integerIds: true });
inventory.insert({
name: "Jonathan",
items: [
{ itemId: 3, quantity: 1 },
{ itemId: 5, quantity: 2 },
],
meta: {
data: [],
}
});
items.insert({ name: "The Unstoppable Force", atk: 100 }); // id 3
items.insert({ name: "Sneakers", agi: 100 }); // id 4
items.insert({ name: "The Immovable Object", def: 100 }); // id 5
const res = nrml(inventory.find({ name: "Jonathan" }, {
join: [{
collection: items,
from: "items.*.itemId",
on: "_id",
as: "meta.data",
options: {
project: { _id: 0, _created_at: 0, _updated_at: 0 },
}
}],
}))[0];
expect(res).toEqual({
name: "Jonathan",
items: [
{ itemId: 3, quantity: 1 },
{ itemId: 5, quantity: 2 },
],
meta: {
data: [
{ name: "The Unstoppable Force", atk: 100 },
{ name: "The Immovable Object", def: 100 }
],
},
});
})
});
});