split user into user and player and enhanced player with attributes bats, throws, jerseyNumber and state
This commit is contained in:
parent
a18bbff1e2
commit
7465e9500c
|
|
@ -14,6 +14,7 @@ app.use(express.urlencoded({ extended: true }));
|
||||||
require('./routes/info.routes')(app);
|
require('./routes/info.routes')(app);
|
||||||
require('./routes/auth.routes')(app);
|
require('./routes/auth.routes')(app);
|
||||||
require('./routes/user.routes')(app);
|
require('./routes/user.routes')(app);
|
||||||
|
require('./routes/player.routes')(app);
|
||||||
require('./routes/pitchType.routes')(app);
|
require('./routes/pitchType.routes')(app);
|
||||||
require('./routes/bullpenSession.routes')(app);
|
require('./routes/bullpenSession.routes')(app);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,48 @@
|
||||||
const db = require("../models/index");
|
const db = require("../models/index");
|
||||||
const config = require("../config/auth.config");
|
const config = require("../config/auth.config");
|
||||||
const { Auth: Auth, User: User, Role: Role, RefreshToken: RefreshToken } = db;
|
const { Auth: Auth, User: User, RefreshToken: RefreshToken } = db;
|
||||||
|
|
||||||
const Op = db.Sequelize.Op;
|
|
||||||
|
|
||||||
const jwt = require("jsonwebtoken");
|
const jwt = require("jsonwebtoken");
|
||||||
|
const {registerUser} = require("../helper/user.helper");
|
||||||
|
|
||||||
exports.register = (req, res) => {
|
exports.register = (req, res) => {
|
||||||
// Save User to Database
|
// Ensure at least one role ist set
|
||||||
Auth.create({
|
req.body.roles = req.body.roles?.length ? req.body.roles : ['player'];
|
||||||
email: req.body.email,
|
|
||||||
password: req.body.password
|
try {
|
||||||
}).then((auth) => {
|
registerUser(req.body);
|
||||||
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!" });
|
res.send({ message: "User registered successfully!" });
|
||||||
});
|
} catch (err) {
|
||||||
});
|
|
||||||
}).catch(err => {
|
|
||||||
res.status(500).send({ message: err.message });
|
res.status(500).send({ message: err.message });
|
||||||
});
|
}
|
||||||
}).catch(err => {
|
// // Save User to Database
|
||||||
res.status(500).send({ message: err.message });
|
// 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) => {
|
exports.login = async (req, res) => {
|
||||||
|
|
@ -94,10 +97,6 @@ exports.login = async (req, res) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// exports.logout = (req, res) => {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
exports.refreshToken = async (req, res) => {
|
exports.refreshToken = async (req, res) => {
|
||||||
const { refreshToken: requestToken } = req.body;
|
const { refreshToken: requestToken } = req.body;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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}.`});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -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()
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 };
|
||||||
|
|
@ -3,7 +3,7 @@ const bcrypt = require("bcryptjs");
|
||||||
|
|
||||||
const { beforeAll, afterAll } = require('@jest/globals');
|
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;
|
const Op = db.Sequelize.Op;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
|
|
@ -21,9 +21,17 @@ beforeAll(async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const coachRole = await Role.findAll({
|
||||||
|
where: {
|
||||||
|
name: {
|
||||||
|
[Op.eq]: 'coach'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
await Auth.destroy({ where: {} });
|
await Auth.destroy({ where: {} });
|
||||||
await User.destroy({ where: {} });
|
await User.destroy({ where: {} });
|
||||||
|
await Player.destroy({ where: {} });
|
||||||
await Auth.create({
|
await Auth.create({
|
||||||
email: 'player@example.com', password: 'hash1234'
|
email: 'player@example.com', password: 'hash1234'
|
||||||
}).then(auth => {
|
}).then(auth => {
|
||||||
|
|
@ -31,12 +39,33 @@ beforeAll(async () => {
|
||||||
firstName: 'Alice',
|
firstName: 'Alice',
|
||||||
lastName: 'Player',
|
lastName: 'Player',
|
||||||
dateOfBirth: '1990-01-01',
|
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',
|
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
|
authId: auth.id
|
||||||
});
|
});
|
||||||
}).then(user => {
|
}).then(user => {
|
||||||
return user.setRoles(playerRole);
|
return user.setRoles(coachRole);
|
||||||
});
|
});
|
||||||
await PitchType.destroy({ where: {} });
|
await PitchType.destroy({ where: {} });
|
||||||
await PitchType.bulkCreate([
|
await PitchType.bulkCreate([
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const jwt = require("jsonwebtoken");
|
const jwt = require("jsonwebtoken");
|
||||||
const config = require("../config/auth.config.js");
|
const config = require("../config/auth.config.js");
|
||||||
const db = require("../models/index");
|
const db = require("../models/index");
|
||||||
const User = db.user;
|
const User = db.User;
|
||||||
|
|
||||||
const { TokenExpiredError } = jwt;
|
const { TokenExpiredError } = jwt;
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ const isCoachOrAdmin = (req, res, next) => {
|
||||||
const authJwt = {
|
const authJwt = {
|
||||||
verifyToken: verifyToken,
|
verifyToken: verifyToken,
|
||||||
isAdmin: isAdmin,
|
isAdmin: isAdmin,
|
||||||
isModerator: isCoach,
|
isCoach: isCoach,
|
||||||
isModeratorOrAdmin: isCoachOrAdmin
|
isCoachOrAdmin: isCoachOrAdmin
|
||||||
};
|
};
|
||||||
module.exports = authJwt;
|
module.exports = authJwt;
|
||||||
|
|
|
||||||
|
|
@ -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');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -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')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
@ -4,7 +4,7 @@ module.exports = (sequelize, DataTypes) => {
|
||||||
class User extends Model {
|
class User extends Model {
|
||||||
/**
|
/**
|
||||||
* Helper method for defining associations.
|
* 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.
|
* The `models/index` file will call this method automatically.
|
||||||
*/
|
*/
|
||||||
static associate(models) {
|
static associate(models) {
|
||||||
|
|
@ -32,25 +32,6 @@ module.exports = (sequelize, DataTypes) => {
|
||||||
type: DataTypes.DATEONLY,
|
type: DataTypes.DATEONLY,
|
||||||
allowNull: false
|
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,
|
sequelize,
|
||||||
modelName: 'User',
|
modelName: 'User',
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"prebuild": "node -p \"'export const BULLPEN_VERSION = ' + JSON.stringify(require('./package.json').version) + ';'\" > config/version.js",
|
||||||
"test": "cross-env NODE_ENV=test jest",
|
"test": "cross-env NODE_ENV=test jest",
|
||||||
"pretest": "cross-env NODE_ENV=test npm run db:reset",
|
"pretest": "cross-env NODE_ENV=test npm run db:reset",
|
||||||
"db:create:test": "cross-env NODE_ENV=test npx sequelize-cli db:create",
|
"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",
|
"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:prod": "npm run cross-env NODE_ENV=production node server.js",
|
||||||
"start:dev": "cross-env NODE_ENV=development nodemon 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:start": "docker-compose -f docker-compose.test.yml up -d",
|
||||||
"test:db:stop": "docker-compose -f docker-compose.test.yml down -v",
|
"test:db:stop": "docker-compose -f docker-compose.test.yml down -v",
|
||||||
"test:run": "dotenv -e .env.test -- jest --runInBand --detectOpenHandles",
|
"test:run": "dotenv -e .env.test -- jest --runInBand --detectOpenHandles",
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
};
|
||||||
|
|
@ -1,91 +1,23 @@
|
||||||
const bcrypt = require("bcryptjs");
|
|
||||||
const process = require('process');
|
const process = require('process');
|
||||||
|
const {createPlayer, createUsers} = require("../helper/seeder.helper");
|
||||||
|
|
||||||
/** @type {import('sequelize-cli').Migration} */
|
/** @type {import('sequelize-cli').Migration} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
async up (queryInterface, /*Sequelize*/) {
|
async up (queryInterface, /*Sequelize*/) {
|
||||||
if (process.env.NODE_ENV !== 'development') return;
|
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 roles = await queryInterface.select(null, 'Roles');
|
||||||
const playerId = roles.filter((role) => role.name === 'player').map((role) => role.id).shift();
|
const players = [
|
||||||
const coachId = roles.filter((role) => role.name === 'coach').map((role) => role.id).shift();
|
{ 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' },
|
||||||
const adminId = roles.filter((role) => role.name === 'admin').map((role) => role.id).shift();
|
{ 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', [
|
await createPlayer(queryInterface, roles, players);
|
||||||
{ userId: ryanId, roleId: playerId, createdAt: new Date(), updatedAt: new Date() },
|
|
||||||
{ userId: sandyId, roleId: playerId, createdAt: new Date(), updatedAt: new Date() },
|
await createUsers(queryInterface, roles, [
|
||||||
{ userId: pedroId, roleId: playerId, createdAt: new Date(), updatedAt: new Date() },
|
{ email: 'sparky.anderson@bullpen.com', password: 'sparky$123', firstName: 'Sparky', lastName: 'Anderson', dateOfBirth: new Date(1934, 22, 2), roles: ['coach', 'admin'] },
|
||||||
{ 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() },
|
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -95,5 +27,6 @@ module.exports = {
|
||||||
await queryInterface.dropTable('Authentications');
|
await queryInterface.dropTable('Authentications');
|
||||||
await queryInterface.dropTable('Users');
|
await queryInterface.dropTable('Users');
|
||||||
await queryInterface.dropTable('UserRoles');
|
await queryInterface.dropTable('UserRoles');
|
||||||
|
await queryInterface.dropTable('Players');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,63 +1,21 @@
|
||||||
const bcrypt = require("bcryptjs");
|
const bcrypt = require("bcryptjs");
|
||||||
const process = require('process');
|
const process = require('process');
|
||||||
|
const {createPlayer, createUsers} = require("../helper/seeder.helper");
|
||||||
|
|
||||||
/** @type {import('sequelize-cli').Migration} */
|
/** @type {import('sequelize-cli').Migration} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
async up (queryInterface, /*Sequelize*/) {
|
async up (queryInterface, /*Sequelize*/) {
|
||||||
if (process.env.NODE_ENV !== 'production') return;
|
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 roles = await queryInterface.select(null, 'Roles');
|
||||||
const adminRoleId = roles.filter((role) => role.name === 'admin').map((role) => role.id).shift();
|
const players = [
|
||||||
const playerRoleId = roles.filter((role) => role.name === 'player').map((role) => role.id).shift();
|
{ 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' },
|
||||||
const coachRoleId = roles.filter((role) => role.name === 'coach').map((role) => role.id).shift();
|
];
|
||||||
|
|
||||||
await queryInterface.bulkInsert('UserRoles', [
|
await createPlayer(queryInterface, roles, players);
|
||||||
{ userId: adminUserId, roleId: adminRoleId, createdAt: new Date(), updatedAt: new Date() },
|
await createUsers(queryInterface, roles, [
|
||||||
{ userId: julianUserId, roleId: playerRoleId, createdAt: new Date(), updatedAt: new Date() },
|
{ email: 'cichocki.c@gmail.com', password: 'clemens$123', firstName: 'Clemens', lastName: 'Cichocki', dateOfBirth: new Date(1970, 1, 1), roles: ['coach'] },
|
||||||
{ userId: clemensUserId, roleId: coachRoleId, createdAt: new Date(), updatedAt: new Date() },
|
{ email: 'admin@example.com', password: 'admin$123', firstName: 'Admin', lastName: 'Bullpen', dateOfBirth: new Date(1970, 1, 1), roles: ['admin'] },
|
||||||
{ userId: clemensUserId, roleId: playerRoleId, createdAt: new Date(), updatedAt: new Date() },
|
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -67,5 +25,6 @@ module.exports = {
|
||||||
await queryInterface.dropTable('Authentications');
|
await queryInterface.dropTable('Authentications');
|
||||||
await queryInterface.dropTable('Users');
|
await queryInterface.dropTable('Users');
|
||||||
await queryInterface.dropTable('UserRoles');
|
await queryInterface.dropTable('UserRoles');
|
||||||
|
await queryInterface.dropTable('Players');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue