can remove owned/wanted items from item page
This commit is contained in:
parent
bb46c1f184
commit
3a20deba09
5 changed files with 492 additions and 4845 deletions
|
@ -25,7 +25,7 @@ GRANT INSERT, UPDATE ON swf_assets TO impress2020;
|
||||||
GRANT INSERT ON modeling_logs TO impress2020;
|
GRANT INSERT ON modeling_logs TO impress2020;
|
||||||
|
|
||||||
-- User data tables
|
-- User data tables
|
||||||
GRANT SELECT, INSERT ON closet_hangers TO impress2020;
|
GRANT SELECT, INSERT, DELETE ON closet_hangers TO impress2020;
|
||||||
GRANT SELECT ON closet_lists TO impress2020;
|
GRANT SELECT ON closet_lists TO impress2020;
|
||||||
GRANT SELECT ON item_outfit_relationships TO impress2020;
|
GRANT SELECT ON item_outfit_relationships TO impress2020;
|
||||||
GRANT SELECT ON outfits TO impress2020;
|
GRANT SELECT ON outfits TO impress2020;
|
||||||
|
|
|
@ -373,6 +373,28 @@ function ItemPageOwnButton({ itemId, isChecked }) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [sendRemoveMutation] = useMutation(
|
||||||
|
gql`
|
||||||
|
mutation ItemPageOwnButtonRemove($itemId: ID!) {
|
||||||
|
removeFromItemsCurrentUserOwns(itemId: $itemId) {
|
||||||
|
id
|
||||||
|
currentUserOwnsThis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
variables: { itemId },
|
||||||
|
optimisticResponse: {
|
||||||
|
__typename: "Mutation",
|
||||||
|
removeFromItemsCurrentUserOwns: {
|
||||||
|
__typename: "Item",
|
||||||
|
id: itemId,
|
||||||
|
currentUserOwnsThis: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box as="label">
|
<Box as="label">
|
||||||
<VisuallyHidden
|
<VisuallyHidden
|
||||||
|
@ -391,10 +413,14 @@ function ItemPageOwnButton({ itemId, isChecked }) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
toast({
|
sendRemoveMutation().catch((e) => {
|
||||||
title: "Todo: This doesn't actually work yet!",
|
console.error(e);
|
||||||
status: "info",
|
toast({
|
||||||
duration: 1500,
|
title: "We had trouble removing this from the items you own.",
|
||||||
|
description: "Check your internet connection, and try again.",
|
||||||
|
status: "error",
|
||||||
|
duration: 5000,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
@ -448,6 +474,28 @@ function ItemPageWantButton({ itemId, isChecked }) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [sendRemoveMutation] = useMutation(
|
||||||
|
gql`
|
||||||
|
mutation ItemPageWantButtonRemove($itemId: ID!) {
|
||||||
|
removeFromItemsCurrentUserWants(itemId: $itemId) {
|
||||||
|
id
|
||||||
|
currentUserWantsThis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
variables: { itemId },
|
||||||
|
optimisticResponse: {
|
||||||
|
__typename: "Mutation",
|
||||||
|
removeFromItemsCurrentUserWants: {
|
||||||
|
__typename: "Item",
|
||||||
|
id: itemId,
|
||||||
|
currentUserWantsThis: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box as="label">
|
<Box as="label">
|
||||||
<VisuallyHidden
|
<VisuallyHidden
|
||||||
|
@ -466,10 +514,14 @@ function ItemPageWantButton({ itemId, isChecked }) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
toast({
|
sendRemoveMutation().catch((e) => {
|
||||||
title: "Todo: This doesn't actually work yet!",
|
console.error(e);
|
||||||
status: "info",
|
toast({
|
||||||
duration: 1500,
|
title: "We had trouble removing this from the items you want.",
|
||||||
|
description: "Check your internet connection, and try again.",
|
||||||
|
status: "error",
|
||||||
|
duration: 5000,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -790,4 +790,134 @@ describe("Item", () => {
|
||||||
|
|
||||||
expect(getDbCalls()).toMatchSnapshot("db");
|
expect(getDbCalls()).toMatchSnapshot("db");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("removes item from items user owns", async () => {
|
||||||
|
useTestDb();
|
||||||
|
await Promise.all([logInAsTestUser(), createItem("1")]);
|
||||||
|
|
||||||
|
// First, add the item.
|
||||||
|
let res = await mutate({
|
||||||
|
mutation: gql`
|
||||||
|
mutation {
|
||||||
|
item: addToItemsCurrentUserOwns(itemId: "1") {
|
||||||
|
currentUserOwnsThis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
expect(res).toHaveNoErrors();
|
||||||
|
expect(res.data.item.currentUserOwnsThis).toBe(true);
|
||||||
|
|
||||||
|
// Then, remove the item.
|
||||||
|
res = await mutate({
|
||||||
|
mutation: gql`
|
||||||
|
mutation {
|
||||||
|
item: removeFromItemsCurrentUserOwns(itemId: "1") {
|
||||||
|
currentUserOwnsThis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
expect(res).toHaveNoErrors();
|
||||||
|
expect(res.data.item.currentUserOwnsThis).toBe(false);
|
||||||
|
|
||||||
|
// Finally, confirm the removal was persisted.
|
||||||
|
res = await query({
|
||||||
|
query: gql`
|
||||||
|
query {
|
||||||
|
item(id: "1") {
|
||||||
|
currentUserOwnsThis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
expect(res).toHaveNoErrors();
|
||||||
|
expect(res.data.item.currentUserOwnsThis).toBe(false);
|
||||||
|
|
||||||
|
expect(getDbCalls()).toMatchSnapshot("db");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does nothing when removing an item we don't own", async () => {
|
||||||
|
useTestDb();
|
||||||
|
await Promise.all([logInAsTestUser(), createItem("1")]);
|
||||||
|
|
||||||
|
let res = await mutate({
|
||||||
|
mutation: gql`
|
||||||
|
mutation {
|
||||||
|
item: removeFromItemsCurrentUserOwns(itemId: "1") {
|
||||||
|
currentUserOwnsThis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
expect(res).toHaveNoErrors();
|
||||||
|
expect(res.data.item.currentUserOwnsThis).toBe(false);
|
||||||
|
|
||||||
|
expect(getDbCalls()).toMatchSnapshot("db");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("removes item from items user wants", async () => {
|
||||||
|
useTestDb();
|
||||||
|
await Promise.all([logInAsTestUser(), createItem("1")]);
|
||||||
|
|
||||||
|
// First, add the item.
|
||||||
|
let res = await mutate({
|
||||||
|
mutation: gql`
|
||||||
|
mutation {
|
||||||
|
item: addToItemsCurrentUserWants(itemId: "1") {
|
||||||
|
currentUserWantsThis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
expect(res).toHaveNoErrors();
|
||||||
|
expect(res.data.item.currentUserWantsThis).toBe(true);
|
||||||
|
|
||||||
|
// Then, remove the item.
|
||||||
|
res = await mutate({
|
||||||
|
mutation: gql`
|
||||||
|
mutation {
|
||||||
|
item: removeFromItemsCurrentUserWants(itemId: "1") {
|
||||||
|
currentUserWantsThis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
expect(res).toHaveNoErrors();
|
||||||
|
expect(res.data.item.currentUserWantsThis).toBe(false);
|
||||||
|
|
||||||
|
// Finally, confirm the removal was persisted.
|
||||||
|
res = await query({
|
||||||
|
query: gql`
|
||||||
|
query {
|
||||||
|
item(id: "1") {
|
||||||
|
currentUserWantsThis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
expect(res).toHaveNoErrors();
|
||||||
|
expect(res.data.item.currentUserWantsThis).toBe(false);
|
||||||
|
|
||||||
|
expect(getDbCalls()).toMatchSnapshot("db");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does nothing when removing an item we don't want", async () => {
|
||||||
|
useTestDb();
|
||||||
|
await Promise.all([logInAsTestUser(), createItem("1")]);
|
||||||
|
|
||||||
|
let res = await mutate({
|
||||||
|
mutation: gql`
|
||||||
|
mutation {
|
||||||
|
item: removeFromItemsCurrentUserWants(itemId: "1") {
|
||||||
|
currentUserWantsThis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
expect(res).toHaveNoErrors();
|
||||||
|
expect(res.data.item.currentUserWantsThis).toBe(false);
|
||||||
|
|
||||||
|
expect(getDbCalls()).toMatchSnapshot("db");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -316,8 +316,27 @@ const resolvers = {
|
||||||
|
|
||||||
return { id: itemId };
|
return { id: itemId };
|
||||||
},
|
},
|
||||||
removeFromItemsCurrentUserOwns: () => {
|
removeFromItemsCurrentUserOwns: async (
|
||||||
throw new Error("TODO: Not yet implemented");
|
_,
|
||||||
|
{ itemId },
|
||||||
|
{ currentUserId, db, itemLoader }
|
||||||
|
) => {
|
||||||
|
if (currentUserId == null) {
|
||||||
|
throw new Error(`must be logged in`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const item = await itemLoader.load(itemId);
|
||||||
|
if (item == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.query(
|
||||||
|
`DELETE FROM closet_hangers
|
||||||
|
WHERE item_id = ? AND user_id = ? AND owned = ?;`,
|
||||||
|
[itemId, currentUserId, true]
|
||||||
|
);
|
||||||
|
|
||||||
|
return { id: itemId };
|
||||||
},
|
},
|
||||||
addToItemsCurrentUserWants: async (
|
addToItemsCurrentUserWants: async (
|
||||||
_,
|
_,
|
||||||
|
@ -362,8 +381,27 @@ const resolvers = {
|
||||||
|
|
||||||
return { id: itemId };
|
return { id: itemId };
|
||||||
},
|
},
|
||||||
removeFromItemsCurrentUserWants: () => {
|
removeFromItemsCurrentUserWants: async (
|
||||||
throw new Error("TODO: Not yet implemented");
|
_,
|
||||||
|
{ itemId },
|
||||||
|
{ currentUserId, db, itemLoader }
|
||||||
|
) => {
|
||||||
|
if (currentUserId == null) {
|
||||||
|
throw new Error(`must be logged in`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const item = await itemLoader.load(itemId);
|
||||||
|
if (item == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.query(
|
||||||
|
`DELETE FROM closet_hangers
|
||||||
|
WHERE item_id = ? AND user_id = ? AND owned = ?;`,
|
||||||
|
[itemId, currentUserId, false]
|
||||||
|
);
|
||||||
|
|
||||||
|
return { id: itemId };
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue