/** Test if the updating throw a {@link NullPointerException} by passing an invalid ID argument */
  @Test(expected = NullPointerException.class)
  public void testUpdateWithInvalidId() {
    controller.edit(m, Long.MAX_VALUE);
    Map<String, Object> map = m.asMap();
    Client c = (Client) map.get("client");

    c.setName("Sun");
    controller.update(c, new MapBindingResult(Collections.emptyMap(), ""));
  }
  /**
   * Test if the {@link Client} has been well updated. The following conditions are checked :<br>
   *
   * <ul>
   *   <li>The new value for the updated property can be read with the {@link ClientDAO}
   *   <li>The view is redirected to the client.html page
   * </ul>
   */
  @Test
  public void testUpdate() {
    controller.edit(m, clientId);
    Map<String, Object> map = m.asMap();
    Client c = (Client) map.get("client");

    c.setName("Sun");
    String view = controller.update(c, new MapBindingResult(Collections.emptyMap(), ""));

    assertEquals("Sun", clientDAO.findById(clientId).getName());
    assertEquals("redirect:/client.html", view);
  }
  /**
   * Test if the {@link Client} has been well created. The following conditions are checked :<br>
   *
   * <ul>
   *   <li>The created {@link Client} can be found with the {@link ClientDAO}
   *   <li>The view is redirected to the client.html page
   * </ul>
   */
  @Test
  public void testCreate() {
    controller.add(m);
    Map<String, Object> map = m.asMap();
    Client c = (Client) map.get("client");

    c.setName("company");
    String view = controller.create(c, new MapBindingResult(Collections.emptyMap(), ""));
    long id = c.getId();

    assertEquals(c, clientDAO.findById(id));
    assertEquals("redirect:/client.html", view);
  }
 /**
  * Test if the {@link Client} has been well deleted. The following conditions are checked :<br>
  *
  * <ul>
  *   <li>The deleted {@link Client} can't be found with the {@link ClientDAO}
  *   <li>The view is redirected to the client.html page
  * </ul>
  */
 @Test
 public void testDelete() {
   String view = controller.delete(clientId);
   Client client = clientDAO.findById(clientId);
   assertFalse(client.isEnabled());
   assertEquals("redirect:/client.html", view);
 }
  /**
   * Test if the model contains a <code>null</code> {@link Client} by passing an invalid ID
   * argument. The following conditions are checked :<br>
   *
   * <ul>
   *   <li>The model contains an attribute called "client"
   *   <li>This attribute has a <code>null</code> value
   * </ul>
   */
  @Test
  public void testEditWithInvalidId() {
    controller.edit(m, Long.MAX_VALUE);
    Map<String, Object> map = m.asMap();

    assertTrue(m.containsAttribute("client"));
    assertNull(map.get("client"));
  }
  /**
   * Test if the result of search is correct. The following conditions are checked :<br>
   *
   * <ul>
   *   <li>The model contains an attribute called "result"
   *   <li>This attribute is not null
   *   <li>This attribute is not empty
   *   <li>The only element in the list is the expected client
   *   <li>The view is redirected to the client/result.html page
   * </ul>
   */
  @Test
  public void testSearchExactMatch() {
    controller.searchForm(m);
    Map<String, Object> map = m.asMap();
    CompanyQueryCommand command = (CompanyQueryCommand) map.get("companyQuery");

    command.setCompanyName("client");
    command.setMatchMode(CompanyQueryCommand.EXACT_MATCH_MODE);
    ModelAndView mav = controller.search(command);

    Map<String, Object> model = mav.getModel();
    assertTrue(model.containsKey("result"));
    List<?> result = (List<?>) model.get("result");
    assertNotNull(result);
    assertEquals(1, result.size());
    assertEquals(client, result.get(0));
    assertEquals("client/result", mav.getViewName());
  }
  /**
   * Test if the model contains a {@link CompanyQueryCommand} object. The following conditions are
   * checked :<br>
   *
   * <ul>
   *   <li>The model contains an attribute called "clientQuery"
   *   <li>This attribute is not <code>null</code>
   * </ul>
   */
  @Test
  public void testSearchForm() {
    controller.searchForm(m);
    Map<String, Object> map = m.asMap();

    assertTrue(m.containsAttribute("companyQuery"));
    CompanyQueryCommand command = (CompanyQueryCommand) map.get("companyQuery");
    assertNotNull(command);
  }
  /**
   * Test if the model contains a {@link Client} object. The following conditions are checked :<br>
   *
   * <ul>
   *   <li>The model contains an attribute called "client"
   *   <li>This attribute is equal to the {@link Client} created before in setUp() method
   * </ul>
   */
  @Test
  public void testEdit() {
    controller.edit(m, clientId);
    Map<String, Object> map = m.asMap();

    assertTrue(m.containsAttribute("client"));
    Client c = (Client) map.get("client");
    assertEquals(client, c);
  }
  /**
   * Test if the model contains a {@link Client} object. The following conditions are checked :<br>
   *
   * <ul>
   *   <li>The model contains an attribute called "client"
   *   <li>This attribute is not <code>null</code>
   * </ul>
   */
  @Test
  public void testAdd() {
    controller.add(m);
    Map<String, Object> map = m.asMap();

    assertTrue(m.containsAttribute("client"));
    Client c = (Client) map.get("client");
    assertNotNull(c);
  }
  /**
   * Test if the model contains the list of all products. The following conditions are checked :<br>
   *
   * <ul>
   *   <li>The model contains an attribute called "list"
   *   <li>This list contains only one object
   *   <li>This object is equal to the {@link Client} created before in setUp() method
   * </ul>
   */
  @Test
  public void testList() {
    controller.list(m);
    Map<String, Object> map = m.asMap();

    assertTrue(m.containsAttribute("list"));
    List<?> clients = (List<?>) map.get("list");
    assertEquals(1, clients.size());
    assertEquals(client, clients.get(0));
  }
 /** Test if the deletion throw a {@link NullPointerException} by passing an invalid ID argument */
 @Test(expected = NullPointerException.class)
 public void testDeleteWithInvalidId() {
   controller.delete(Long.MAX_VALUE);
 }