From a9bc61cb8a4d2a88b8178f86ea5161e9038cbd2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9=20Landr=C3=A9?= <68849024+DevNono@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:19:51 +0200 Subject: [PATCH] feat: add possibility to disable tickets generation (#244) * feat: add possibility to disable tickets generation * fix: pnpm lint --------- Co-authored-by: Antoine Dufils --- seed.sql | 3 ++- seed.test.sql | 3 ++- src/controllers/admin/settings/updateSetting.ts | 6 +++++- src/controllers/tickets/getTicket.ts | 6 ++++++ src/operations/settings.ts | 3 ++- src/types.ts | 1 + tests/admin/settings/updateSetting.test.ts | 15 ++++++++++++++- tests/root/settings.test.ts | 6 ++++-- tests/setup.ts | 4 +++- tests/tickets/getTicket.test.ts | 14 +++++++++++++- 10 files changed, 52 insertions(+), 9 deletions(-) diff --git a/seed.sql b/seed.sql index d8dd91e6..50c2d33c 100644 --- a/seed.sql +++ b/seed.sql @@ -17,7 +17,8 @@ INSERT INTO `items` (`id`, `name`, `category`, `attribute`, `price`, `reducedPri INSERT INTO `settings` (`id`, `value`) VALUES ('login', 0), ('shop', 0), -('trombi', 0); +('trombi', 0), +('tickets', 0); INSERT INTO `tournaments` (`id`, `name`, `maxPlayers`, `playersPerTeam`, `coachesPerTeam`, `cashprize`, `position`) VALUES ('lol', 'League of Legends', 160, 5, 2, 0, 1), diff --git a/seed.test.sql b/seed.test.sql index 8ee99911..e0098d05 100644 --- a/seed.test.sql +++ b/seed.test.sql @@ -17,7 +17,8 @@ INSERT INTO `items` (`id`, `name`, `category`, `attribute`, `price`, `reducedPri INSERT INTO `settings` (`id`, `value`) VALUES ('login', 0), ('shop', 0), -('trombi', 0); +('trombi', 0), +('tickets', 0); INSERT INTO `commission` (`id`, `name`, `nameOnBadge`, `position`, `color`, `masterCommissionId`) VALUES ('animation', 'Animation', 'Anim', 1, '#123456', NULL), diff --git a/src/controllers/admin/settings/updateSetting.ts b/src/controllers/admin/settings/updateSetting.ts index 70dcf46a..37ecef3d 100644 --- a/src/controllers/admin/settings/updateSetting.ts +++ b/src/controllers/admin/settings/updateSetting.ts @@ -4,7 +4,7 @@ import { hasPermission } from '../../../middlewares/authentication'; import { validateBody } from '../../../middlewares/validation'; import { notFound, success } from '../../../utils/responses'; import { Error, Permission } from '../../../types'; -import { setTrombiAllowed, setLoginAllowed, setShopAllowed } from '../../../operations/settings'; +import { setTrombiAllowed, setLoginAllowed, setShopAllowed, setTicketsAllowed } from '../../../operations/settings'; export default [ // Middlewares @@ -32,6 +32,10 @@ export default [ result = await setTrombiAllowed(request.body.value); break; } + case 'tickets': { + result = await setTicketsAllowed(request.body.value); + break; + } default: { return notFound(response, Error.NotFound); } diff --git a/src/controllers/tickets/getTicket.ts b/src/controllers/tickets/getTicket.ts index 08b773d8..eecd10f2 100644 --- a/src/controllers/tickets/getTicket.ts +++ b/src/controllers/tickets/getTicket.ts @@ -8,6 +8,7 @@ import { Error, ItemCategory, TransactionState, UserType } from '../../types'; import { generateTicket } from '../../utils/ticket'; import { forbidden, notFound } from '../../utils/responses'; import { getRequestInfo } from '../../utils/users'; +import { fetchSetting } from '../../operations/settings'; export default [ // Middlewares @@ -16,6 +17,11 @@ export default [ // Controller async (request: Request, response: Response, next: NextFunction) => { try { + const ticketsAllowed = (await fetchSetting('tickets')).value; + if (!ticketsAllowed) { + return forbidden(response, Error.TicketsNotAllowed); + } + const { cartItemId } = request.params; const { user } = getRequestInfo(response); const team = user.teamId && (await fetchTeam(user.teamId)); diff --git a/src/operations/settings.ts b/src/operations/settings.ts index ecec19b5..8309f777 100644 --- a/src/operations/settings.ts +++ b/src/operations/settings.ts @@ -4,7 +4,7 @@ import { Setting } from '../types'; export const fetchSettings = (): PrismaPromise => database.setting.findMany(); -export const fetchSetting = (id: 'login' | 'shop' | 'trombi'): PrismaPromise => +export const fetchSetting = (id: 'login' | 'shop' | 'trombi' | 'tickets'): PrismaPromise => database.setting.findUnique({ where: { id } }); const setSettingAllowed = (id: string, allowed: boolean): PrismaPromise => @@ -20,3 +20,4 @@ const setSettingAllowed = (id: string, allowed: boolean): PrismaPromise export const setLoginAllowed = (allowed: boolean): PrismaPromise => setSettingAllowed('login', allowed); export const setShopAllowed = (allowed: boolean): PrismaPromise => setSettingAllowed('shop', allowed); export const setTrombiAllowed = (allowed: boolean): PrismaPromise => setSettingAllowed('trombi', allowed); +export const setTicketsAllowed = (allowed: boolean): PrismaPromise => setSettingAllowed('tickets', allowed); diff --git a/src/types.ts b/src/types.ts index 30db1947..42af333b 100755 --- a/src/types.ts +++ b/src/types.ts @@ -313,6 +313,7 @@ export const enum Error { UserAlreadyScanned = "L'utilisateur a déjà scanné son billet", NotPaid = "Le billet n'a pas été payé", LoginNotAllowed = 'Tu ne peux pas te connecter actuellement', + TicketsNotAllowed = 'Tu ne peux pas voir ton billet actuellement', NotAdmin = "Tu n'es pas administrateur", ShopNotAllowed = 'La billetterie est fermée', TrombiNotAllowed = "Le trombinoscope n'est pas encore disponible", diff --git a/tests/admin/settings/updateSetting.test.ts b/tests/admin/settings/updateSetting.test.ts index e80d6c21..d54b9330 100644 --- a/tests/admin/settings/updateSetting.test.ts +++ b/tests/admin/settings/updateSetting.test.ts @@ -5,7 +5,7 @@ import { sandbox } from '../../setup'; import * as settingsOperations from '../../../src/operations/settings'; import database from '../../../src/services/database'; import { Error, Permission, User, UserType } from '../../../src/types'; -import { setLoginAllowed, setShopAllowed, setTrombiAllowed } from '../../../src/operations/settings'; +import { setLoginAllowed, setShopAllowed, setTrombiAllowed, setTicketsAllowed } from '../../../src/operations/settings'; import { createFakeUser } from '../../utils'; import { generateToken } from '../../../src/utils/users'; @@ -19,6 +19,7 @@ describe('PATCH /admin/settings', () => { await setLoginAllowed(true); await setShopAllowed(true); await setTrombiAllowed(true); + await setTicketsAllowed(true); await database.orga.deleteMany(); await database.user.deleteMany(); }); @@ -27,6 +28,7 @@ describe('PATCH /admin/settings', () => { await setLoginAllowed(true); await setShopAllowed(false); await setTrombiAllowed(false); + await setTicketsAllowed(false); admin = await createFakeUser({ permissions: [Permission.admin] }); orga = await createFakeUser({ permissions: [Permission.orga] }); nonAdminUser = await createFakeUser({ type: UserType.player }); @@ -99,6 +101,12 @@ describe('PATCH /admin/settings', () => { .set('Authorization', `Bearer ${adminToken}`) .expect(200, { id: 'trombi', value: false }); + await request(app) + .patch('/admin/settings/tickets') + .send({ value: false }) + .set('Authorization', `Bearer ${adminToken}`) + .expect(200, { id: 'tickets', value: false }); + const login = await settingsOperations.fetchSetting('login'); expect(login.id).to.be.equal('login'); @@ -113,5 +121,10 @@ describe('PATCH /admin/settings', () => { expect(trombi.id).to.be.equal('trombi'); expect(trombi.value).to.be.equal(false); + + const tickets = await settingsOperations.fetchSetting('tickets'); + + expect(tickets.id).to.be.equal('tickets'); + expect(tickets.value).to.be.equal(false); }); }); diff --git a/tests/root/settings.test.ts b/tests/root/settings.test.ts index 93e7173d..1dc017c9 100644 --- a/tests/root/settings.test.ts +++ b/tests/root/settings.test.ts @@ -9,16 +9,18 @@ describe('GET /settings', () => { await settingsOperations.setLoginAllowed(false); await settingsOperations.setShopAllowed(false); await settingsOperations.setTrombiAllowed(false); + await settingsOperations.setTicketsAllowed(false); - await request(app).get('/settings').expect(200, { shop: false, login: false, trombi: false }); + await request(app).get('/settings').expect(200, { shop: false, login: false, trombi: false, tickets: false }); }); it('should return the updated value', async () => { await settingsOperations.setLoginAllowed(true); await settingsOperations.setShopAllowed(true); await settingsOperations.setTrombiAllowed(true); + await settingsOperations.setTicketsAllowed(true); - await request(app).get('/settings').expect(200, { shop: true, login: true, trombi: true }); + await request(app).get('/settings').expect(200, { shop: true, login: true, trombi: true, tickets: true }); }); it('should return an internal server error', async () => { diff --git a/tests/setup.ts b/tests/setup.ts index a98b4311..3dc9245d 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -9,7 +9,7 @@ import chai, { expect } from 'chai'; import chaiString from 'chai-string'; import sinon from 'sinon'; import database from '../src/services/database'; -import { setLoginAllowed, setShopAllowed, setTrombiAllowed } from '../src/operations/settings'; +import { setLoginAllowed, setShopAllowed, setTicketsAllowed, setTrombiAllowed } from '../src/operations/settings'; import { transporter } from '../src/services/email'; import { disableFakeDiscordApi, enableFakeDiscordApi } from './discord'; import { disableFakeUploadApi, enableFakeUploadApi } from './upload'; @@ -33,6 +33,7 @@ before(async () => { await setLoginAllowed(true); await setShopAllowed(true); await setTrombiAllowed(true); + await setTicketsAllowed(true); enableFakeDiscordApi(); enableFakeUploadApi(); @@ -55,6 +56,7 @@ after(async () => { // Reset the database at it was await setLoginAllowed(false); await setShopAllowed(false); + await setTicketsAllowed(false); // Check that there is all tests where cleaning all their data. It is to prevent data concurrency // We check only tables that have dynamic data. (not seeded staticly) diff --git a/tests/tickets/getTicket.test.ts b/tests/tickets/getTicket.test.ts index 72a80e9a..01b5f5bc 100644 --- a/tests/tickets/getTicket.test.ts +++ b/tests/tickets/getTicket.test.ts @@ -11,8 +11,9 @@ import { generateToken } from '../../src/utils/users'; import { createCart, fetchCarts, updateCart } from '../../src/operations/carts'; import { fetchAllItems } from '../../src/operations/item'; import { fetchUser } from '../../src/operations/user'; +import { setTicketsAllowed } from '../../src/operations/settings'; -describe('POST /users/:userId/carts', () => { +describe('GET /tickets', () => { let user: User; let token: string; let team: Team; @@ -58,6 +59,17 @@ describe('POST /users/:userId/carts', () => { await database.user.deleteMany(); }); + it('should fail because tickets are not allowed', async () => { + await setTicketsAllowed(false); + + await request(app) + .get(`/tickets/${ticket.id}`) + .set('Authorization', `Bearer ${token}`) + .expect(403, { error: Error.TicketsNotAllowed }); + + await setTicketsAllowed(true); + }); + it("should fail because cart item doesn't belong to the user", async () => { const otherUser = await createFakeUser({ type: UserType.player }); const otherToken = generateToken(otherUser);