El tutorial Jobeet

11.8. Regresando al futuro en una prueba

Cuando una oferta de trabajo expira en menos de cinco días o si ya ha expirado, el usuario que la creó puede ampliar la validez de la oferta por otros 30 días a partir de la fecha actual.

Probar este requisito no es nada sencillo, ya que la fecha de expiración se establece automáticamente a dentro de 30 días cuando se crea la oferta de trabajo. Por tanto, cuando accedes a la página de una oferta de trabajo, no se visualiza el enlace para extener la validez de esa oferta. Aunque podrías modificar la fecha de expiración en la base de datos o podrías modificar la plantilla para que siempre muestre ese enlace, estas soluciones no son más que chapuzas con las que es muy fácil equivocarse. Como ya habrás adivinado, vamos a escribir algunas pruebas para que hagan este trabajo por nosotros.

En primer lugar, añade una nueva ruta para el método extend:

# apps/frontend/config/routing.yml
job:
  class:   sfPropelRouteCollection
  options:
    model:          JobeetJob
    column:         token
    object_actions: { publish: PUT, extend: PUT }
  requirements:
    token: \w+

A continuación, actualiza el código del enlace "Extend" en el elemento parcial _admin:

<!-- apps/frontend/modules/job/templates/_admin.php -->
<?php if ($job->expiresSoon()): ?>
 - <?php echo link_to('Extend', 'job_extend', $job, array('method' => 'put')) ?> for another <?php echo sfConfig::get('app_active_days') ?> days
<?php endif; ?>

Después crea la acción extend:

// apps/frontend/modules/job/actions/actions.class.php
public function executeExtend(sfWebRequest $request)
{
  $request->checkCSRFProtection();

  $job = $this->getRoute()->getObject();
  $this->forward404Unless($job->extend());

  $this->getUser()->setFlash('notice', sprintf('Your job validity has been extended until %s.', $job->getExpiresAt('m/d/Y')));

  $this->redirect($this->generateUrl('job_show_user', $job));
}

Tal y como espera la acción, el método extend() de JobeetJob devuelve el valor true si se ha ampliado la validez de la oferta de trabajo y false en cualquier otro caso:

// lib/model/JobeetJob.php
class JobeetJob extends BaseJobeetJob
{
  public function extend()
  {
    if (!$this->expiresSoon())
    {
      return false;
    }

    $this->setExpiresAt(time() + 86400 * sfConfig::get('app_active_days'));

    return $this->save();
  }

  // ...
}

Por último, añade el siguiente escenario a las pruebas:

$browser->info('  3.6 - A job validity cannot be extended before the job expires soon')->
  createJob(array('position' => 'FOO4'), true)->
  call(sprintf('/job/%s/extend', $browser->getJobByPosition('FOO4')->getToken()), 'put', array('_with_csrf' => true))->
  with('response')->begin()->
    isStatusCode(404)->
  end()
;

$browser->info('  3.7 - A job validity can be extended when the job expires soon')->
  createJob(array('position' => 'FOO5'), true)
;

$job = $browser->getJobByPosition('FOO5');
$job->setExpiresAt(time());
$job->save();

$browser->
  call(sprintf('/job/%s/extend', $job->getToken()), 'put', array('_with_csrf' => true))->
  with('response')->isRedirected()
;

$job->reload();
$browser->test()->is(
  $job->getExpiresAt('y/m/d'),
  date('y/m/d', time() + 86400 * sfConfig::get('app_active_days'))
);

Este escenario de pruebas introduce algunos elementos nuevos: * El método call() obtiene una URL utilizando un método HTTP diferente de GET o POST * Después de que la acción actualice la oferta de trabajo, recargamos el objeto local mediante $job->reload() * Al final utilizamos el objeto lime para probar de forma directa la fecha de expiración de la oferta