From d4b7343e4bf7cc005df0e2a113a3cab0908a9adc Mon Sep 17 00:00:00 2001 From: Rain Date: Mon, 16 Oct 2023 17:26:08 +0100 Subject: [PATCH] deleting cards from a deck --- src/__test__/deck/card/delete.test.ts | 65 +++++++++++++++++++++++++++ src/api/app/deck/delete.ts | 34 ++++++++++++++ src/api/app/deck/index.ts | 2 + 3 files changed, 101 insertions(+) create mode 100644 src/__test__/deck/card/delete.test.ts create mode 100644 src/api/app/deck/delete.ts diff --git a/src/__test__/deck/card/delete.test.ts b/src/__test__/deck/card/delete.test.ts new file mode 100644 index 0000000..7aafc91 --- /dev/null +++ b/src/__test__/deck/card/delete.test.ts @@ -0,0 +1,65 @@ +import { QueryResult } from 'pg'; +import supertest from 'supertest'; +import db from '../../../db'; +import loader from '../../../loader'; +import setupAuth from '../../setupAuth'; + +const decks: QueryResult[] = []; +const notOurDecks: QueryResult[] = []; +const cards: QueryResult[] = []; +let token: string; +beforeEach(async () => { + token = await setupAuth(); + decks[0] = await db.query(/* sql */ ` + INSERT INTO decks ("name", "public", "course") + VALUES ($1, $2, $3) + RETURNING deck_id;`, + ['foobar', false, null]); + + decks[1] = await db.query(/* sql */ ` + INSERT INTO decks ("name", "public", "course") + VALUES ($1, $2, $3) + RETURNING deck_id;`, + ['foobar2', false, null]); + + notOurDecks[0] = await db.query(/* sql */ ` + INSERT INTO decks ("name", "public", "course") + VALUES ($1, $2, $3) + RETURNING deck_id;`, + ['notOurs', false, null]); + + await db.query(/* sql */ ` + INSERT INTO "user_decks" ("user_id", "deck_id") + VALUES + (1, $1);`, // Our test user has an ID of 1. + [decks[0].rows[0].deck_id]); + + await db.query(/* sql */ ` + INSERT INTO "user_decks" ("user_id", "deck_id") + VALUES (999, $1);`, // This deck does not belong to our test user. + [decks[1].rows[0].deck_id]); + + cards[0] = await db.query(/* sql */` + INSERT INTO "cards" ("front", "back", "deck_id") + VALUES ($1, $2, $3), ($4, $5, $6) + RETURNING card_id;`, + ['front', 'back', decks[0].rows[0].deck_id, 'front2', 'back2', decks[0].rows[0].deck_id]); +}); + +afterAll(async () => { + await db.end(); +}); + +describe('deleting cards from a deck', () => { + it('should allow you to delete a card from a deck that belongs to you', async () => { + // send a DELETE request to /app/deck/:deck_id/:card_id to delete a card from this deck. + const res = await supertest(loader).delete(`/app/deck/${decks[0].rows[0].deck_id}/${cards[0].rows[0].card_id}`).set('Cookie', [`session=${token}`]); + expect(res.status).toBe(204); + + // check that the card was deleted from the database. + const card = await db.query(/* sql */ ` + SELECT * FROM cards WHERE card_id = $1;`, + [cards[0].rows[0].card_id]); + expect(card.rows[0]).toBe(undefined); + }); +}); diff --git a/src/api/app/deck/delete.ts b/src/api/app/deck/delete.ts new file mode 100644 index 0000000..75230fb --- /dev/null +++ b/src/api/app/deck/delete.ts @@ -0,0 +1,34 @@ +import express from 'express'; +import db from '../../../db'; + +const del = express.Router(); + +del.delete('/:deck_id/:card_id', async (req, res) => { + if (!req.params.deck_id.match(/^[0-9]+$/) || !req.params.card_id.match(/^[0-9]+$/)) { + res.status(400).send({ error: 'invalidId' }); + return; + } + const deck = await db.query(/* sql */ ` + SELECT "deck_id" FROM "user_decks" + WHERE "deck_id" = $1 AND "user_id" = $2; + `, [req.params.deck_id, req.user!.id]); + if (!deck.rows[0]) { + res.status(404).send({ error: 'deckNotFound' }); + return; + } + const card = await db.query(/* sql */ ` + SELECT "card_id" FROM "cards" + WHERE "card_id" = $1 AND "deck_id" = $2; + `, [req.params.card_id, req.params.deck_id]); + if (!card.rows[0]) { + res.status(404).send({ error: 'cardNotFound' }); + return; + } + await db.query(/* sql */ ` + DELETE FROM "cards" + WHERE "card_id" = $1; + `, [req.params.card_id]); + res.status(204).send(); +}); + +export default del; diff --git a/src/api/app/deck/index.ts b/src/api/app/deck/index.ts index 10a5399..8a64d49 100644 --- a/src/api/app/deck/index.ts +++ b/src/api/app/deck/index.ts @@ -2,11 +2,13 @@ import express from 'express'; import create from './post'; import patch from './patch'; import get from './get'; +import del from './delete'; const deck = express.Router(); deck.use('/', create); deck.use('/', patch); deck.use('/', get); +deck.use('/', del); export default deck;