add itemsTheyWant to user GQL

This commit is contained in:
Emi Matchu 2020-09-11 21:34:28 -07:00
parent c0f0e5688c
commit 45ffa92f1d
4 changed files with 212 additions and 13 deletions

View file

@ -24,12 +24,20 @@ function ItemsPage() {
user(id: $userId) { user(id: $userId) {
id id
username username
itemsTheyOwn { itemsTheyOwn {
id id
isNc isNc
name name
thumbnailUrl thumbnailUrl
} }
itemsTheyWant {
id
isNc
name
thumbnailUrl
}
} }
} }
`, `,
@ -66,6 +74,23 @@ function ItemsPage() {
/> />
))} ))}
</Wrap> </Wrap>
<Heading1 marginBottom="8" marginTop="8">
{isCurrentUser ? "Items you want" : `Items ${data.user.username} wants`}
</Heading1>
<Wrap justify="center">
{data.user.itemsTheyWant.map((item) => (
<ItemCard
key={item.id}
item={item}
badges={
<ItemBadgeList>
{item.isNc ? <NcBadge /> : <NpBadge />}
</ItemBadgeList>
}
/>
))}
</Wrap>
</Box> </Box>
); );
} }

View file

@ -488,7 +488,7 @@ const buildUserLoader = (db) =>
); );
}); });
const buildUserOwnedClosetHangersLoader = (db) => const buildUserClosetHangersLoader = (db) =>
new DataLoader(async (userIds) => { new DataLoader(async (userIds) => {
const qs = userIds.map((_) => "?").join(","); const qs = userIds.map((_) => "?").join(",");
const [rows, _] = await db.execute( const [rows, _] = await db.execute(
@ -496,7 +496,7 @@ const buildUserOwnedClosetHangersLoader = (db) =>
INNER JOIN items ON items.id = closet_hangers.item_id INNER JOIN items ON items.id = closet_hangers.item_id
INNER JOIN item_translations ON INNER JOIN item_translations ON
item_translations.item_id = items.id AND locale = "en" item_translations.item_id = items.id AND locale = "en"
WHERE user_id IN (${qs}) AND owned = 1 WHERE user_id IN (${qs})
ORDER BY item_name`, ORDER BY item_name`,
userIds userIds
); );
@ -604,7 +604,7 @@ function buildLoaders(db) {
loaders.speciesLoader = buildSpeciesLoader(db); loaders.speciesLoader = buildSpeciesLoader(db);
loaders.speciesTranslationLoader = buildSpeciesTranslationLoader(db); loaders.speciesTranslationLoader = buildSpeciesTranslationLoader(db);
loaders.userLoader = buildUserLoader(db); loaders.userLoader = buildUserLoader(db);
loaders.userOwnedClosetHangersLoader = buildUserOwnedClosetHangersLoader(db); loaders.userClosetHangersLoader = buildUserClosetHangersLoader(db);
loaders.userClosetListsLoader = buildUserClosetListsLoader(db); loaders.userClosetListsLoader = buildUserClosetListsLoader(db);
loaders.zoneLoader = buildZoneLoader(db); loaders.zoneLoader = buildZoneLoader(db);
loaders.zoneTranslationLoader = buildZoneTranslationLoader(db); loaders.zoneTranslationLoader = buildZoneTranslationLoader(db);

View file

@ -178,7 +178,7 @@ describe("User", () => {
INNER JOIN items ON items.id = closet_hangers.item_id INNER JOIN items ON items.id = closet_hangers.item_id
INNER JOIN item_translations ON INNER JOIN item_translations ON
item_translations.item_id = items.id AND locale = \\"en\\" item_translations.item_id = items.id AND locale = \\"en\\"
WHERE user_id IN (?) AND owned = 1 WHERE user_id IN (?)
ORDER BY item_name", ORDER BY item_name",
Array [ Array [
"44743", "44743",
@ -240,7 +240,141 @@ describe("User", () => {
INNER JOIN items ON items.id = closet_hangers.item_id INNER JOIN items ON items.id = closet_hangers.item_id
INNER JOIN item_translations ON INNER JOIN item_translations ON
item_translations.item_id = items.id AND locale = \\"en\\" item_translations.item_id = items.id AND locale = \\"en\\"
WHERE user_id IN (?) AND owned = 1 WHERE user_id IN (?)
ORDER BY item_name",
Array [
"44743",
],
],
Array [
"SELECT * FROM closet_lists
WHERE user_id IN (?)
ORDER BY name",
Array [
"44743",
],
],
]
`);
});
it("gets private items they want for current user", async () => {
await logInAsTestUser();
const res = await query({
query: gql`
query {
user(id: "44743") {
id
username
itemsTheyWant {
id
name
}
}
}
`,
});
expect(res).toHaveNoErrors();
expect(res.data).toMatchInlineSnapshot(`
Object {
"user": Object {
"id": "44743",
"itemsTheyWant": Array [
Object {
"id": "39945",
"name": "Altador Cup Background - Haunted Woods",
},
Object {
"id": "39956",
"name": "Altador Cup Background - Kreludor",
},
Object {
"id": "39947",
"name": "Altador Cup Background - Shenkuu",
},
],
"username": "dti-test",
},
}
`);
expect(getDbCalls()).toMatchInlineSnapshot(`
Array [
Array [
"SELECT * FROM users WHERE id IN (?)",
Array [
"44743",
],
],
Array [
"SELECT closet_hangers.*, item_translations.name as item_name FROM closet_hangers
INNER JOIN items ON items.id = closet_hangers.item_id
INNER JOIN item_translations ON
item_translations.item_id = items.id AND locale = \\"en\\"
WHERE user_id IN (?)
ORDER BY item_name",
Array [
"44743",
],
],
Array [
"SELECT * FROM closet_lists
WHERE user_id IN (?)
ORDER BY name",
Array [
"44743",
],
],
]
`);
});
it("hides private items they want from other users", async () => {
const res = await query({
query: gql`
query {
user(id: "44743") {
id
username
itemsTheyWant {
id
name
}
}
}
`,
});
expect(res).toHaveNoErrors();
expect(res.data).toMatchInlineSnapshot(`
Object {
"user": Object {
"id": "44743",
"itemsTheyWant": Array [
Object {
"id": "39947",
"name": "Altador Cup Background - Shenkuu",
},
],
"username": "dti-test",
},
}
`);
expect(getDbCalls()).toMatchInlineSnapshot(`
Array [
Array [
"SELECT * FROM users WHERE id IN (?)",
Array [
"44743",
],
],
Array [
"SELECT closet_hangers.*, item_translations.name as item_name FROM closet_hangers
INNER JOIN items ON items.id = closet_hangers.item_id
INNER JOIN item_translations ON
item_translations.item_id = items.id AND locale = \\"en\\"
WHERE user_id IN (?)
ORDER BY item_name", ORDER BY item_name",
Array [ Array [
"44743", "44743",

View file

@ -5,6 +5,7 @@ const typeDefs = gql`
id: ID! id: ID!
username: String! username: String!
itemsTheyOwn: [Item!]! itemsTheyOwn: [Item!]!
itemsTheyWant: [Item!]!
} }
extend type Query { extend type Query {
@ -19,6 +20,7 @@ const resolvers = {
const user = await userLoader.load(id); const user = await userLoader.load(id);
return user.name; return user.name;
}, },
itemsTheyOwn: async ( itemsTheyOwn: async (
{ id }, { id },
_, _,
@ -26,23 +28,61 @@ const resolvers = {
currentUserId, currentUserId,
userClosetListsLoader, userClosetListsLoader,
userLoader, userLoader,
userOwnedClosetHangersLoader, userClosetHangersLoader,
} }
) => { ) => {
const [allClosetHangers, closetLists, user] = await Promise.all([ const [allClosetHangers, closetLists, user] = await Promise.all([
userOwnedClosetHangersLoader.load(id), userClosetHangersLoader.load(id),
userClosetListsLoader.load(id), userClosetListsLoader.load(id),
userLoader.load(id), userLoader.load(id),
]); ]);
const closetListsById = new Map(closetLists.map((l) => [l.id, l])); const closetListsById = new Map(closetLists.map((l) => [l.id, l]));
const visibleClosetHangers = allClosetHangers.filter( const visibleClosetHangers = allClosetHangers
(h) => .filter((h) => h.owned)
user.id === currentUserId || .filter(
(h.listId == null && user.ownedClosetHangersVisibility >= 1) || (h) =>
(h.listId != null && closetListsById.get(h.listId).visibility >= 1) user.id === currentUserId ||
); (h.listId == null && user.ownedClosetHangersVisibility >= 1) ||
(h.listId != null && closetListsById.get(h.listId).visibility >= 1)
);
const items = visibleClosetHangers.map((h) => ({
id: h.itemId,
// We get this for the ORDER BY clause anyway - may as well include it
// here to avoid an extra lookup!
name: h.itemName,
}));
return items;
},
itemsTheyWant: async (
{ id },
_,
{
currentUserId,
userClosetListsLoader,
userLoader,
userClosetHangersLoader,
}
) => {
const [allClosetHangers, closetLists, user] = await Promise.all([
userClosetHangersLoader.load(id),
userClosetListsLoader.load(id),
userLoader.load(id),
]);
const closetListsById = new Map(closetLists.map((l) => [l.id, l]));
const visibleClosetHangers = allClosetHangers
.filter((h) => !h.owned)
.filter(
(h) =>
user.id === currentUserId ||
(h.listId == null && user.wantedClosetHangersVisibility >= 1) ||
(h.listId != null && closetListsById.get(h.listId).visibility >= 1)
);
const items = visibleClosetHangers.map((h) => ({ const items = visibleClosetHangers.map((h) => ({
id: h.itemId, id: h.itemId,