add itemsTheyWant to user GQL
This commit is contained in:
parent
c0f0e5688c
commit
45ffa92f1d
4 changed files with 212 additions and 13 deletions
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue