diff --git a/backend/app.js b/backend/app.js index 7922ed5..6ea76e0 100644 --- a/backend/app.js +++ b/backend/app.js @@ -14,6 +14,7 @@ app.use(express.urlencoded({ extended: true })); require('./routes/info.routes')(app); require('./routes/auth.routes')(app); require('./routes/user.routes')(app); +require('./routes/player.routes')(app); require('./routes/pitchType.routes')(app); require('./routes/bullpenSession.routes')(app); diff --git a/backend/controllers/auth.controller.js b/backend/controllers/auth.controller.js index 98264c6..63baf98 100644 --- a/backend/controllers/auth.controller.js +++ b/backend/controllers/auth.controller.js @@ -1,45 +1,48 @@ const db = require("../models/index"); const config = require("../config/auth.config"); -const { Auth: Auth, User: User, Role: Role, RefreshToken: RefreshToken } = db; - -const Op = db.Sequelize.Op; +const { Auth: Auth, User: User, RefreshToken: RefreshToken } = db; const jwt = require("jsonwebtoken"); +const {registerUser} = require("../helper/user.helper"); exports.register = (req, res) => { - // Save User to Database - Auth.create({ - email: req.body.email, - password: req.body.password - }).then((auth) => { - User.create({ - firstName: req.body.firstName, - lastName: req.body.lastName, - dateOfBirth: new Date(req.body.dateOfBirth), - authId: auth.id, - gender: 'male', - handedness: 'right' - }).then(user => { - if (!req.body.roles || !req.body.roles.length === 0) { - req.body.roles = ['player']; - } - Role.findAll({ - where: { - name: { - [Op.or]: req.body.roles - } - } - }).then(roles => { - user.setRoles(roles).then(() => { - res.send({ message: "User registered successfully!" }); - }); - }); - }).catch(err => { - res.status(500).send({ message: err.message }); - }); - }).catch(err => { + // Ensure at least one role ist set + req.body.roles = req.body.roles?.length ? req.body.roles : ['player']; + + try { + registerUser(req.body); + res.send({ message: "User registered successfully!" }); + } catch (err) { res.status(500).send({ message: err.message }); - }); + } + // // Save User to Database + // Auth.create({ + // email: req.body.email, + // password: req.body.password + // }).then((auth) => { + // User.create({ + // firstName: req.body.firstName, + // lastName: req.body.lastName, + // dateOfBirth: new Date(req.body.dateOfBirth), + // authId: auth.id + // }).then(user => { + // Role.findAll({ + // where: { + // name: { + // [Op.or]: req.body.roles + // } + // } + // }).then(roles => { + // user.setRoles(roles).then(() => { + // res.send({ message: "User registered successfully!" }); + // }); + // }); + // }).catch(err => { + // res.status(500).send({ message: err.message }); + // }); + // }).catch(err => { + // res.status(500).send({ message: err.message }); + // }); }; exports.login = async (req, res) => { @@ -94,10 +97,6 @@ exports.login = async (req, res) => { } }; -// exports.logout = (req, res) => { -// -// } - exports.refreshToken = async (req, res) => { const { refreshToken: requestToken } = req.body; diff --git a/backend/controllers/player.controller.js b/backend/controllers/player.controller.js new file mode 100644 index 0000000..ce7252d --- /dev/null +++ b/backend/controllers/player.controller.js @@ -0,0 +1,63 @@ +const db = require("../models/index"); +const {registerUser} = require("../helper/user.helper"); +const Player = db.Player; +const User = db.User; +const Op = db.Sequelize.Op; + +exports.insert = (req, res) => { + registerUser(req.body).then(user => { + return Player.create({ + firstName: req.body.firstName, + lastName: req.body.lastName, + dateOfBirth: req.body.dateOfBirth, + gender: req.body.gender, + height: req.body.height ? req.body.height : null, + weight: req.body.weight ? req.body.weight : null, + bats: req.body.bats ? req.body.bats : 'right', + throws: req.body.throws ? req.body.throws : 'right', + state: req.body.state ? req.body.state : 'inactive', + jerseyNumber: req.body.jerseyNumber, + userId: user.id + }).then(player => { + return player.reload({ include: { model: User }}); + }); + }).then(player => { + res.status(201).send(player); + }).catch(err => { + res.status(500).send({message: err.message}); + }); +}; + +exports.findAll = (req, res) => { + const title = req.query.title; + const condition = title ? {title: {[Op.iLike]: `%${title}%`}} : null; + + Player.findAll({ + where: condition, + include: { + model: User + } + }).then(data => { + res.send(data); + }).catch(err => { + res.status(500).send({message:err.message || "Some error occurred while retrieving players."}); + }); +}; + +exports.findOne = (req, res) => { + const id = req.params.id; + + Player.findByPk(id, { + include: { + model: User + } + }).then(data => { + if (data) { + res.send(data); + } else { + res.status(404).send({message: `Cannot find user with id=${id}.`}); + } + }).catch(err => { + res.status(500).send({message: `Error retrieving user with id=${id}.`}); + }); +} \ No newline at end of file diff --git a/backend/helper/seeder.helper.js b/backend/helper/seeder.helper.js new file mode 100644 index 0000000..867aa28 --- /dev/null +++ b/backend/helper/seeder.helper.js @@ -0,0 +1,74 @@ +const bcrypt = require("bcryptjs"); + +export const createUsers = async (queryInterface, roles, users) => { + // Create Authentications + await queryInterface.bulkInsert('Authentications', users.map((player) => { + return { + email: player.email, + password: bcrypt.hashSync(player.password, 8), + createdAt: new Date(), + updatedAt: new Date() + } + })); + + const auths = await queryInterface.select(null, 'Authentications'); + + // Create Users + await queryInterface.bulkInsert('Users', users.map(player => { + const auth = auths.find(auth => auth.email === player.email); + return { + firstName: player.firstName, + lastName: player.lastName, + dateOfBirth: player.dateOfBirth, + authId: auth ? auth.id : null, + createdAt: new Date(), + updatedAt: new Date() + }; + })); + + const createdUsers = await queryInterface.select(null, 'Users'); + const userRoles = createdUsers.flatMap(user => user.roles.map(role => ({ + id: user.id, + role: role + }))); + + const rolesByName = roles.reduce((map, role) => { + map[role.name] = role; + return map; + }) + + // Create UserRoles + await queryInterface.bulkInsert('UserRoles', userRoles.map(userRole => { + return { + userId: userRole.id, + roleId: rolesByName[userRole.role].id, + createdAt: new Date(), + updatedAt: new Date() + }; + })); + + return createdUsers; +} + +export const createPlayer = async (queryInterface, roles, players) => { + + const users = await createUsers(queryInterface, roles, players); + + // Create Players + await queryInterface.bulkInsert('Players', players.map(player => { + const user = users.find(user => user.firstName === player.firstName && user.lastName === player.lastName); + return { + height: player.height ? player.height : null, + weight: player.weight ? player.weight : null, + gender: player.gender, + bats: player.bats, + throws: player.throws, + state: player.state, + userId: user ? user.id : null, + createdAt: new Date(), + updatedAt: new Date() + }; + })); + + +} diff --git a/backend/helper/user.helper.js b/backend/helper/user.helper.js new file mode 100644 index 0000000..f4dadcc --- /dev/null +++ b/backend/helper/user.helper.js @@ -0,0 +1,33 @@ +const db = require("../models/index"); + +const Op = db.Sequelize.Op; + +const { Auth: Auth, User: User, Role: Role } = db; + +const registerUser = (user) => { + return Auth.create({ + email: user.email, + password: user.password + }).then((auth) => { + return User.create({ + firstName: user.firstName, + lastName: user.lastName, + dateOfBirth: new Date(user.dateOfBirth), + authId: auth.id + }).then(createdUser => { + return Role.findAll({ + where: { + name: { + [Op.or]: user.roles + } + } + }).then(roles => { + createdUser.setRoles(roles); + + return createdUser; + }); + }); + }); +} + +module.exports = { registerUser }; diff --git a/backend/jest.setup.js b/backend/jest.setup.js index 7037f5c..4e12383 100644 --- a/backend/jest.setup.js +++ b/backend/jest.setup.js @@ -3,7 +3,7 @@ const bcrypt = require("bcryptjs"); const { beforeAll, afterAll } = require('@jest/globals'); -const { Auth: Auth, User: User, Role: Role, PitchType: PitchType } = db; +const { Auth: Auth, User: User, Player: Player, Role: Role, PitchType: PitchType } = db; const Op = db.Sequelize.Op; beforeAll(async () => { @@ -21,9 +21,17 @@ beforeAll(async () => { } } }); + const coachRole = await Role.findAll({ + where: { + name: { + [Op.eq]: 'coach' + } + } + }); await Auth.destroy({ where: {} }); await User.destroy({ where: {} }); + await Player.destroy({ where: {} }); await Auth.create({ email: 'player@example.com', password: 'hash1234' }).then(auth => { @@ -31,12 +39,33 @@ beforeAll(async () => { firstName: 'Alice', lastName: 'Player', dateOfBirth: '1990-01-01', + authId: auth.id + }); + }).then(async user => { + await user.setRoles(playerRole); + return Player.create({ + height: 172.7, + weight: 70.3, gender: 'female', - handedness: 'right', + bats: 'right', + throws: 'right', + jerseyNumber: 24, + state: 'active', + userId: user.id + }) + }); + + await Auth.create({ + email: 'coach@example.com', password: 'hash1234' + }).then(auth => { + return User.create({ + firstName: 'Bob', + lastName: 'Coach', + dateOfBirth: '1990-01-01', authId: auth.id }); }).then(user => { - return user.setRoles(playerRole); + return user.setRoles(coachRole); }); await PitchType.destroy({ where: {} }); await PitchType.bulkCreate([ diff --git a/backend/middleware/authJwt.js b/backend/middleware/authJwt.js index d6d04a0..c818fcc 100644 --- a/backend/middleware/authJwt.js +++ b/backend/middleware/authJwt.js @@ -1,7 +1,7 @@ const jwt = require("jsonwebtoken"); const config = require("../config/auth.config.js"); const db = require("../models/index"); -const User = db.user; +const User = db.User; const { TokenExpiredError } = jwt; @@ -88,7 +88,7 @@ const isCoachOrAdmin = (req, res, next) => { const authJwt = { verifyToken: verifyToken, isAdmin: isAdmin, - isModerator: isCoach, - isModeratorOrAdmin: isCoachOrAdmin + isCoach: isCoach, + isCoachOrAdmin: isCoachOrAdmin }; module.exports = authJwt; diff --git a/backend/migrations/08-create-player-and-move-data.js b/backend/migrations/08-create-player-and-move-data.js new file mode 100644 index 0000000..0168ad7 --- /dev/null +++ b/backend/migrations/08-create-player-and-move-data.js @@ -0,0 +1,71 @@ +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.createTable('Players', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + userId: { + type: Sequelize.INTEGER, + references: { + model: 'Users', + key: 'id' + }, + onUpdate: 'CASCADE', + onDelete: 'CASCADE' + }, + height: { + type: Sequelize.FLOAT + }, + weight: { + type: Sequelize.FLOAT + }, + gender: { + allowNull: false, + type: Sequelize.ENUM('male', 'female', 'other'), + }, + bats: { + type: Sequelize.ENUM('left', 'right', 'both'), + }, + throws: { + type: Sequelize.ENUM('left', 'right', 'both'), + }, + jerseyNumber: { + type: Sequelize.INTEGER, + }, + state: { + type: Sequelize.ENUM('active', 'injured', 'inactive'), + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + + // 2. Kopiere Daten von Users nach Players + await queryInterface.sequelize.query(` + INSERT INTO "Players" ("userId", "height", "weight", "gender", "bats", "throws", "createdAt", "updatedAt") + SELECT + "id" as "userId", + "height", + "weight", + "gender"::text::"enum_Players_gender", + "handedness"::text::"enum_Players_bats", + "handedness"::text::"enum_Players_throws", + "createdAt", + "updatedAt" + FROM "Users" + `); + + }, + async down(queryInterface, /*Sequelize*/) { + await queryInterface.dropTable('Players'); + } +}; diff --git a/backend/migrations/09-remove-columns-from-user.js b/backend/migrations/09-remove-columns-from-user.js new file mode 100644 index 0000000..1aa1ce9 --- /dev/null +++ b/backend/migrations/09-remove-columns-from-user.js @@ -0,0 +1,25 @@ +// Migration 2: Remove columns from Users +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.removeColumn('Users', 'height'); + await queryInterface.removeColumn('Users', 'weight'); + await queryInterface.removeColumn('Users', 'gender'); + await queryInterface.removeColumn('Users', 'handedness'); + }, + + async down(queryInterface, Sequelize) { + await queryInterface.addColumn('Users', 'height', { + type: Sequelize.FLOAT + }); + await queryInterface.addColumn('Users', 'weight', { + type: Sequelize.FLOAT + }); + await queryInterface.addColumn('Users', 'gender', { + type: Sequelize.ENUM('male', 'female', 'other') + }); + await queryInterface.addColumn('Users', 'handedness', { + type: Sequelize.ENUM('left', 'right', 'both') + }); + } +}; \ No newline at end of file diff --git a/backend/models/player.model.js b/backend/models/player.model.js new file mode 100644 index 0000000..f90a8b8 --- /dev/null +++ b/backend/models/player.model.js @@ -0,0 +1,46 @@ +const { Model } = require('sequelize'); + +module.exports = (sequelize, DataTypes) => { + class Player extends Model { + /** + * Helper method for defining associations. + * This method is not a part of the Sequelize lifecycle. + * The `models/index` file will call this method automatically. + */ + static associate(models) { + Player.belongsTo(models.User, { + foreignKey: "userId" + }); + } + } + Player.init({ + height: { + type: DataTypes.FLOAT + }, + weight: { + type: DataTypes.FLOAT + }, + gender: { + type: DataTypes.ENUM('male', 'female', 'other'), + allowNull: false + }, + bats: { + type: DataTypes.ENUM('left', 'right', 'both'), + }, + throws: { + type: DataTypes.ENUM('left', 'right', 'both'), + }, + jerseyNumber: { + type: DataTypes.INTEGER, + }, + state: { + type: DataTypes.ENUM('active', 'injured', 'inactive'), + } + }, { + sequelize, + modelName: 'Player', + tableName: "Players" + }); + + return Player; +}; diff --git a/backend/models/user.model.js b/backend/models/user.model.js index a43dfd8..16901f8 100644 --- a/backend/models/user.model.js +++ b/backend/models/user.model.js @@ -4,7 +4,7 @@ module.exports = (sequelize, DataTypes) => { class User extends Model { /** * Helper method for defining associations. - * This method is not a part of Sequelize lifecycle. + * This method is not a part of the Sequelize lifecycle. * The `models/index` file will call this method automatically. */ static associate(models) { @@ -32,25 +32,6 @@ module.exports = (sequelize, DataTypes) => { type: DataTypes.DATEONLY, allowNull: false }, - height: { - type: DataTypes.FLOAT - }, - weight: { - type: DataTypes.FLOAT - }, - gender: { - type: DataTypes.ENUM('male', 'female', 'other'), - allowNull: false - }, - handedness: { - type: DataTypes.ENUM('left', 'right', 'both'), - }, - // position: { - // type: DataTypes.ENUM - // }, - // preferredPosition: { - // type: DataTypes.ENUM - // } }, { sequelize, modelName: 'User', diff --git a/backend/package.json b/backend/package.json index 3dcd8ce..8bee971 100644 --- a/backend/package.json +++ b/backend/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "main": "server.js", "scripts": { + "prebuild": "node -p \"'export const BULLPEN_VERSION = ' + JSON.stringify(require('./package.json').version) + ';'\" > config/version.js", "test": "cross-env NODE_ENV=test jest", "pretest": "cross-env NODE_ENV=test npm run db:reset", "db:create:test": "cross-env NODE_ENV=test npx sequelize-cli db:create", @@ -13,6 +14,7 @@ "seed:dev": "NODE_ENV=development npx sequelize-cli db:seed:all --debug", "start:prod": "npm run cross-env NODE_ENV=production node server.js", "start:dev": "cross-env NODE_ENV=development nodemon server.js", + "migrate:dev": "NODE_ENV=development npx sequelize-cli db:migrate", "test:db:start": "docker-compose -f docker-compose.test.yml up -d", "test:db:stop": "docker-compose -f docker-compose.test.yml down -v", "test:run": "dotenv -e .env.test -- jest --runInBand --detectOpenHandles", diff --git a/backend/routes/player.routes.js b/backend/routes/player.routes.js new file mode 100644 index 0000000..d3fd4f7 --- /dev/null +++ b/backend/routes/player.routes.js @@ -0,0 +1,25 @@ +const {authJwt} = require("../middleware"); +const controller = require("../controllers/player.controller"); + +module.exports = function(app) { + app.use(function (req, res, next) { + res.header( + "Access-Control-Allow-Headers", + "x-access-token, Origin, Content-Type, Accept" + ); + next(); + }); + + app.post( + "/api/players", + [authJwt.verifyToken, authJwt.isCoachOrAdmin], + controller.insert); + app.get( + "/api/players", + [authJwt.verifyToken, authJwt.isCoachOrAdmin], + controller.findAll); + app.get( + "/api/players/:id", + [authJwt.verifyToken, authJwt.isCoachOrAdmin], + controller.findOne); +}; \ No newline at end of file diff --git a/backend/seeders/02-users-development.js b/backend/seeders/02-users-development.js index 70bc567..6de7b16 100644 --- a/backend/seeders/02-users-development.js +++ b/backend/seeders/02-users-development.js @@ -1,91 +1,23 @@ -const bcrypt = require("bcryptjs"); const process = require('process'); +const {createPlayer, createUsers} = require("../helper/seeder.helper"); /** @type {import('sequelize-cli').Migration} */ module.exports = { async up (queryInterface, /*Sequelize*/) { if (process.env.NODE_ENV !== 'development') return; - await queryInterface.bulkInsert('Authentications', [ - { email: 'ryan.nolan@bullpen.com', password: bcrypt.hashSync('ryan$123', 8), createdAt: new Date(), updatedAt: new Date() }, - { email: 'sandy.koufax@bullpen.com', password: bcrypt.hashSync('sandy$123', 8), createdAt: new Date(), updatedAt: new Date() }, - { email: 'pedro.martinez@bullpen.com', password: bcrypt.hashSync('pedro$123', 8), createdAt: new Date(), updatedAt: new Date() }, - { email: 'randy.johnson@bullpen.com', password: bcrypt.hashSync('randy$123', 8), createdAt: new Date(), updatedAt: new Date() }, - { email: 'sparky.anderson@bullpen.com', password: bcrypt.hashSync('sparky$123', 8), createdAt: new Date(), updatedAt: new Date() }, - ]); - - const auths = await queryInterface.select(null, 'Authentications'); - const ryanAuthId = auths.filter((auth) => auth.email === 'ryan.nolan@bullpen.com').map((auth) => auth.id).shift(); - const sandyAuthId = auths.filter((auth) => auth.email === 'sandy.koufax@bullpen.com').map((auth) => auth.id).shift(); - const pedroAuthId = auths.filter((auth) => auth.email === 'pedro.martinez@bullpen.com').map((auth) => auth.id).shift(); - const randyAuthId = auths.filter((auth) => auth.email === 'randy.johnson@bullpen.com').map((auth) => auth.id).shift(); - const sparkyAuthId = auths.filter((auth) => auth.email === 'sparky.anderson@bullpen.com').map((auth) => auth.id).shift(); - - await queryInterface.bulkInsert('Users', [{ - firstName: 'Nolan', - lastName: 'Ryan', - dateOfBirth: new Date(1947, 1, 31), - gender: 'male', - handedness: 'right', - authId: ryanAuthId, - createdAt: new Date(), - updatedAt: new Date() - }, { - firstName: 'Sandy', - lastName: 'Koufax', - dateOfBirth: new Date(1935, 12, 30), - gender: 'male', - handedness: 'right', - authId: sandyAuthId, - createdAt: new Date(), - updatedAt: new Date() - }, { - firstName: 'Pedro', - lastName: 'Martinez', - dateOfBirth: new Date(1971, 10, 25), - gender: 'male', - handedness: 'right', - authId: pedroAuthId, - createdAt: new Date(), - updatedAt: new Date() - }, { - firstName: 'randy', - lastName: 'johnson', - dateOfBirth: new Date(1963, 9, 10), - gender: 'male', - handedness: 'right', - authId: randyAuthId, - createdAt: new Date(), - updatedAt: new Date() - }, { - firstName: 'Sparky', - lastName: 'Anderson', - dateOfBirth: new Date(1934, 22, 2), - gender: 'male', - authId: sparkyAuthId, - createdAt: new Date(), - updatedAt: new Date(), - }]); - - const users = await queryInterface.select(null, 'Users'); - const ryanId = users.filter((user) => user.firstName === 'Ryan').map((user) => user.id).shift(); - const sandyId = users.filter((user) => user.firstName === 'Sandy').map((user) => user.id).shift(); - const pedroId = users.filter((user) => user.firstName === 'Pedro').map((user) => user.id).shift(); - const randyId = users.filter((user) => user.firstName === 'Randy').map((user) => user.id).shift(); - const sparkyId = users.filter((user) => user.firstName === 'Sparky').map((user) => user.id).shift(); - const roles = await queryInterface.select(null, 'Roles'); - const playerId = roles.filter((role) => role.name === 'player').map((role) => role.id).shift(); - const coachId = roles.filter((role) => role.name === 'coach').map((role) => role.id).shift(); - const adminId = roles.filter((role) => role.name === 'admin').map((role) => role.id).shift(); + const players = [ + { email: 'ryan.nolan@bullpen.com', password: 'ryan$123', firstName: 'Nolan', lastName: 'Ryan', dateOfBirth: new Date(1947, 1, 31), gender: 'male', bats: 'right', throws: 'right', state: 'active' }, + { email: 'sandy.koufax@bullpen.com', password: 'sandy$123', firstName: 'Sandy', lastName: 'Koufax', dateOfBirth: new Date(1935, 12, 30), gender: 'male', bats: 'right', throws: 'right', state: 'active' }, + { email: 'pedro.martinez@bullpen.com', password: 'pedro$123', firstName: 'Pedro', lastName: 'Martinez', dateOfBirth: new Date(1971, 10, 25), gender: 'male', bats: 'right', throws: 'right', state: 'active' }, + { email: 'randy.johnson@bullpen.com', password: 'randy$123', firstName: 'Randy', lastName: 'Johnson', dateOfBirth: new Date(1963, 9, 10), gender: 'male', bats: 'right', throws: 'right', state: 'active' }, + ]; - await queryInterface.bulkInsert('UserRoles', [ - { userId: ryanId, roleId: playerId, createdAt: new Date(), updatedAt: new Date() }, - { userId: sandyId, roleId: playerId, createdAt: new Date(), updatedAt: new Date() }, - { userId: pedroId, roleId: playerId, createdAt: new Date(), updatedAt: new Date() }, - { userId: randyId, roleId: playerId, createdAt: new Date(), updatedAt: new Date() }, - { userId: sparkyId, roleId: coachId, createdAt: new Date(), updatedAt: new Date() }, - { userId: sparkyId, roleId: adminId, createdAt: new Date(), updatedAt: new Date() }, + await createPlayer(queryInterface, roles, players); + + await createUsers(queryInterface, roles, [ + { email: 'sparky.anderson@bullpen.com', password: 'sparky$123', firstName: 'Sparky', lastName: 'Anderson', dateOfBirth: new Date(1934, 22, 2), roles: ['coach', 'admin'] }, ]); }, @@ -95,5 +27,6 @@ module.exports = { await queryInterface.dropTable('Authentications'); await queryInterface.dropTable('Users'); await queryInterface.dropTable('UserRoles'); + await queryInterface.dropTable('Players'); } }; diff --git a/backend/seeders/02-users-production.js b/backend/seeders/02-users-production.js index 63ff920..b363bf4 100644 --- a/backend/seeders/02-users-production.js +++ b/backend/seeders/02-users-production.js @@ -1,63 +1,21 @@ const bcrypt = require("bcryptjs"); const process = require('process'); +const {createPlayer, createUsers} = require("../helper/seeder.helper"); /** @type {import('sequelize-cli').Migration} */ module.exports = { async up (queryInterface, /*Sequelize*/) { if (process.env.NODE_ENV !== 'production') return; - await queryInterface.bulkInsert('Authentications', [ - { email: 'admin@example.com', password: bcrypt.hashSync('admin$123', 8), createdAt: new Date(), updatedAt: new Date() }, - { email: 'kuehl.julian@gmail.com', password: bcrypt.hashSync('julian$123', 8), createdAt: new Date(), updatedAt: new Date() }, - { email: 'cichocki.c@gmail.com', password: bcrypt.hashSync('clemens$123', 8), createdAt: new Date(), updatedAt: new Date() } - ]); - - const auths = await queryInterface.select(null, 'Authentications'); - const adminAuthId = auths.filter((auth) => auth.email === 'admin@example.com').map((auth) => auth.id).shift(); - const julianAuthId = auths.filter((auth) => auth.email === 'kuehl.julian@gmail.com').map((auth) => auth.id).shift(); - const clemensAuthId = auths.filter((auth) => auth.email === 'cichocki.c@gmail.com').map((auth) => auth.id).shift(); - - await queryInterface.bulkInsert('Users', [{ - firstName: 'Admin', - lastName: 'Bullpen', - dateOfBirth: '1970-01-01', - gender: 'other', - authId: adminAuthId, - createdAt: new Date(), - updatedAt: new Date(), - }, { - firstName: 'Julian', - lastName: 'Kühl', - dateOfBirth: '2009-08-08', - gender: 'male', - authId: julianAuthId, - createdAt: new Date(), - updatedAt: new Date(), - }, { - firstName: 'Clemens', - lastName: 'Cichocki', - dateOfBirth: '1970-01-01', - gender: 'male', - authId: clemensAuthId, - createdAt: new Date(), - updatedAt: new Date(), - }]); - - const users = await queryInterface.select(null, 'Users'); - const adminUserId = users.filter((user) => user.firstName === 'Admin').map((user) => user.id).shift(); - const julianUserId = users.filter((user) => user.firstName === 'Julian').map((user) => user.id).shift(); - const clemensUserId = users.filter((user) => user.firstName === 'Clemens').map((user) => user.id).shift(); - const roles = await queryInterface.select(null, 'Roles'); - const adminRoleId = roles.filter((role) => role.name === 'admin').map((role) => role.id).shift(); - const playerRoleId = roles.filter((role) => role.name === 'player').map((role) => role.id).shift(); - const coachRoleId = roles.filter((role) => role.name === 'coach').map((role) => role.id).shift(); + const players = [ + { email: 'kuehl.julian@gmail.com', password: 'julian$123', firstName: 'Julian', lastName: 'Kühl', dateOfBirth: new Date(2009, 8, 8), gender: 'male', jerseyNumber: 75, bats: 'right', throws: 'right', state: 'active' }, + ]; - await queryInterface.bulkInsert('UserRoles', [ - { userId: adminUserId, roleId: adminRoleId, createdAt: new Date(), updatedAt: new Date() }, - { userId: julianUserId, roleId: playerRoleId, createdAt: new Date(), updatedAt: new Date() }, - { userId: clemensUserId, roleId: coachRoleId, createdAt: new Date(), updatedAt: new Date() }, - { userId: clemensUserId, roleId: playerRoleId, createdAt: new Date(), updatedAt: new Date() }, + await createPlayer(queryInterface, roles, players); + await createUsers(queryInterface, roles, [ + { email: 'cichocki.c@gmail.com', password: 'clemens$123', firstName: 'Clemens', lastName: 'Cichocki', dateOfBirth: new Date(1970, 1, 1), roles: ['coach'] }, + { email: 'admin@example.com', password: 'admin$123', firstName: 'Admin', lastName: 'Bullpen', dateOfBirth: new Date(1970, 1, 1), roles: ['admin'] }, ]); }, @@ -67,5 +25,6 @@ module.exports = { await queryInterface.dropTable('Authentications'); await queryInterface.dropTable('Users'); await queryInterface.dropTable('UserRoles'); + await queryInterface.dropTable('Players'); } }; diff --git a/backend/test/data/player.test.data.js b/backend/test/data/player.test.data.js new file mode 100644 index 0000000..be10f0b --- /dev/null +++ b/backend/test/data/player.test.data.js @@ -0,0 +1,19 @@ +const signupPlayer = { + firstName: "Hans", + lastName: "Zimmer", + dateOfBirth: "1956-11-23", + email: "base.ball@email.com", + height: 183.3, + weight: 83.3, + gender: "male", + bats: "right", + throws: "left", + jerseyNumber: 13, + state: "inactive", + password: "base$123", + roles: ['player'] +} + +module.exports = { + signupPlayer +} diff --git a/backend/test/player.test.js b/backend/test/player.test.js new file mode 100644 index 0000000..11a862e --- /dev/null +++ b/backend/test/player.test.js @@ -0,0 +1,45 @@ +const request = require("supertest") +const { + expect, + describe, + test, +} = require('@jest/globals'); + +const app = require("../app") + +const { signupPlayer } = require("./data/player.test.data") +const {set} = require("express/lib/application"); + +describe("Test player creation, authentication and retrieval", () => { + test("should create a player", async () => { + let response = await request(app) + .post("/api/auth/login") + .send({ + email: 'coach@example.com', + password: 'hash1234' + }); + const user = response.body; + + response = await request(app) + .post("/api/players") + .set('x-access-token', user.accessToken) + .send(signupPlayer); + expect(response.header['content-type']).toBe('application/json; charset=utf-8'); + expect(response.statusCode).toBe(201); + + const player = response.body; + response = await request(app) + .get(`/api/players/${player.id}`) + .set('x-access-token', user.accessToken); + expect(response.header['content-type']).toBe('application/json; charset=utf-8'); + expect(response.statusCode).toBe(200); + expect(response.body).toEqual(player); + + response = await request(app) + .get('/api/players') + .set('x-access-token', user.accessToken); + expect(response.header['content-type']).toBe('application/json; charset=utf-8'); + expect(response.statusCode).toBe(200); + expect(response.body.filter(p => p.User.id === player.User.id).shift()).toEqual(player); + }); +});