<commit_before>/**
 * @module controllers/game
 */

const Game = require('../models/game');
const User = require('../models/user');
const has = require('has');

/**
 * Internal helper method for validating that a chosen name is unique.
 * @param {String} newName - the requested Game name field value
 */
function validateNameUnique(newName) {
  return Game.where('name', newName).count('name')
    .then(count => (count === 0));
}

/**
 * Get all Games in the database
 * @param  {Express.Request}   req  - the request object
 * @param  {Express.Response}  res  - the response object
 */
function getGames(req, res) {
  return Game.fetchAll()
  .then(collection => res.json(collection.serialize()))
  .catch(
    /* istanbul ignore next */
    (err) => {
      console.error(err);
      res.status(500).json({
        error: 'UnknownError',
        request: req.body,
      });
    }
  );
}

/**
 * Get the Game matching the 'id' param of the request from the database.
 * @param {Express.Request} req   - the request object
 * @param {Express.Response} res  - the response object
 */
function getGameById(req, res) {
  return Game.where('id', req.params.id).fetch()
  .then((game) => {
    if (game) {
      res.status(200).json(game.serialize());
    } else {
      res.status(404).json({
        error: 'Game with the associated ID was not found',
        request: req.params,
      });
    }
  })
  .catch(
    /* istanbul ignore next */
    (err) => {
      console.error(err);
      res.status(500).json({
        error: 'UnknownError',
        request: req.params,
      });
    }
  );
}

/**
 * Pre-req: verifyProfessor middleware
 * Controller to update an existing Game
 * @param {Express.Request} req  - the request object
 * @param {Express.Response} res - the response object
 */
function updateGame(req, res) {
  const gameId = req.params.id;
  const user = req.user;
  const updatedFields = req.body;

  function validateUpdateRequests() {
    if (Object.getOwnPropertyNames(updatedFields).length === 0) {
      res.status(204).send();
      return false;
    }

    if (has(updatedFields, 'id')) {
      res.status(400).json({
        error: 'You may not alter the read-only "id" field',
        request: updatedFields,
      });
      return false;
    }

    if (has(updatedFields, 'max_round')) {
      if (updatedFields.max_round < 0) {
        res.status(400).json({
          error: 'The "max_round" field may not be a negative integer.',
          request: updatedFields,
        });
        return false;
      }
    }

    if (has(updatedFields, 'current_round')) {
      if (updatedFields.current_round < 0) {
        res.status(400).json({
          error: 'The "current_round" field may not be a negative integer.',
          request: updatedFields,
        });
        return false;
      }
    }

    if (has(updatedFields, 'round_phase')) {
      if (updatedFields.round_phase < 0) {
        res.status(400).json({
          error: 'The "round_phase" field may not be a negative integer.',
          request: updatedFields,
        });
        return false;
      }
    }

    if (has(updatedFields, 'created_at')) {
      res.status(400).json({
        error: 'You may not alter the read-only "created_at" field',
        request: updatedFields,
      });
      return false;
    }

    if (has(updatedFields, 'name')) {
      // Don't allow empty or all whitespace names
      if (updatedFields.name.replace(/\s/g, '') === '') {
        res.status(400).json({
          error: '"name" field cannot be an empty string.',
          request: updatedFields,
        });
        return null;
      }
      const namePromise = validateNameUnique(updatedFields.name).then((isValid) => {
        if (!isValid) {
          throw new Error('Game with Name exists');
        }
      })
      .catch((err) => {
        if (err.message === 'Game with Name exists') {
          res.status(400).json({
            error: 'There is already a Game with that name. Please choose a unique name.',
            request: updatedFields,
          });
          return false;
        }
        console.error(err);
        res.status(500).json({
          error: 'UnknownError',
          request: updatedFields,
        });
        return false;
      });
      return Promise.resolve(namePromise);
    }

    if (has(updatedFields, 'storyteller_id')) {
      // New storyteller must be is_admin or in Professors role.
      const storytellerId = updatedFields.storyteller_id;
      const existingUserQuery = User.where('id', storytellerId);<commit_msg>Return 'false' if name is updated to all-whitespace.<commit_after>/**
 * @module controllers/game
 */

const Game = require('../models/game');
const User = require('../models/user');
const has = require('has');

/**
 * Internal helper method for validating that a chosen name is unique.
 * @param {String} newName - the requested Game name field value
 */
function validateNameUnique(newName) {
  return Game.where('name', newName).count('name')
    .then(count => (count === 0));
}

/**
 * Get all Games in the database
 * @param  {Express.Request}   req  - the request object
 * @param  {Express.Response}  res  - the response object
 */
function getGames(req, res) {
  return Game.fetchAll()
  .then(collection => res.json(collection.serialize()))
  .catch(
    /* istanbul ignore next */
    (err) => {
      console.error(err);
      res.status(500).json({
        error: 'UnknownError',
        request: req.body,
      });
    }
  );
}

/**
 * Get the Game matching the 'id' param of the request from the database.
 * @param {Express.Request} req   - the request object
 * @param {Express.Response} res  - the response object
 */
function getGameById(req, res) {
  return Game.where('id', req.params.id).fetch()
  .then((game) => {
    if (game) {
      res.status(200).json(game.serialize());
    } else {
      res.status(404).json({
        error: 'Game with the associated ID was not found',
        request: req.params,
      });
    }
  })
  .catch(
    /* istanbul ignore next */
    (err) => {
      console.error(err);
      res.status(500).json({
        error: 'UnknownError',
        request: req.params,
      });
    }
  );
}

/**
 * Pre-req: verifyProfessor middleware
 * Controller to update an existing Game
 * @param {Express.Request} req  - the request object
 * @param {Express.Response} res - the response object
 */
function updateGame(req, res) {
  const gameId = req.params.id;
  const user = req.user;
  const updatedFields = req.body;

  function validateUpdateRequests() {
    if (Object.getOwnPropertyNames(updatedFields).length === 0) {
      res.status(204).send();
      return false;
    }

    if (has(updatedFields, 'id')) {
      res.status(400).json({
        error: 'You may not alter the read-only "id" field',
        request: updatedFields,
      });
      return false;
    }

    if (has(updatedFields, 'max_round')) {
      if (updatedFields.max_round < 0) {
        res.status(400).json({
          error: 'The "max_round" field may not be a negative integer.',
          request: updatedFields,
        });
        return false;
      }
    }

    if (has(updatedFields, 'current_round')) {
      if (updatedFields.current_round < 0) {
        res.status(400).json({
          error: 'The "current_round" field may not be a negative integer.',
          request: updatedFields,
        });
        return false;
      }
    }

    if (has(updatedFields, 'round_phase')) {
      if (updatedFields.round_phase < 0) {
        res.status(400).json({
          error: 'The "round_phase" field may not be a negative integer.',
          request: updatedFields,
        });
        return false;
      }
    }

    if (has(updatedFields, 'created_at')) {
      res.status(400).json({
        error: 'You may not alter the read-only "created_at" field',
        request: updatedFields,
      });
      return false;
    }

    if (has(updatedFields, 'name')) {
      // Don't allow empty or all whitespace names
      if (updatedFields.name.replace(/\s/g, '') === '') {
        res.status(400).json({
          error: '"name" field cannot be an empty string.',
          request: updatedFields,
        });
        return false;
      }
      const namePromise = validateNameUnique(updatedFields.name).then((isValid) => {
        if (!isValid) {
          throw new Error('Game with Name exists');
        }
      })
      .catch((err) => {
        if (err.message === 'Game with Name exists') {
          res.status(400).json({
            error: 'There is already a Game with that name. Please choose a unique name.',
            request: updatedFields,
          });
          return false;
        }
        console.error(err);
        res.status(500).json({
          error: 'UnknownError',
          request: updatedFields,
        });
        return false;
      });
      return Promise.resolve(namePromise);
    }

    if (has(updatedFields, 'storyteller_id')) {
      // New storyteller must be is_admin or in Professors role.
      const storytellerId = updatedFields.storyteller_id;
      const existingUserQuery = User.where('id', storytellerId);
{'fraction_non_alphanumeric': 0.13790093825005456, 'fraction_numerical': 0.009600698232598735, 'mean_word_length': 2.302233429394813, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2722882', 'n_tokens_mistral': 2746, 'n_tokens_neox': 2665, 'n_words': 736}