@Test
  public void testAlertMultipleAssociations() {
    Date d = new Date();
    double lat = 10.0;
    double lon = 10.0;

    // Make a product with location and time
    ProductSummary product = new ProductSummary();
    product.setEventLatitude(new BigDecimal(lat));
    product.setEventLongitude(new BigDecimal(lon));
    product.setEventTime(d);
    product.setId(new ProductId("us", "origin", "c0001234"));
    product.setEventSource("us");
    product.setEventSourceCode("c0001234");

    // Make 3 events with similar locations and times
    Event e1 =
        createDifferentEvent(
            new BigDecimal(lat + 0.1),
            new BigDecimal(lon + 0.1),
            new Date(d.getTime() + 10),
            "us",
            "origin",
            "c0002222");

    Event e2 =
        createDifferentEvent(
            new BigDecimal(lat - 0.5),
            new BigDecimal(lon),
            new Date(d.getTime() + 50),
            "nc",
            "origin",
            "11112222");

    Event e3 =
        createDifferentEvent(
            new BigDecimal(lat + 1), new BigDecimal(lon + 1), d, "ci", "origin", "aaaa2222");

    Event e4 =
        createDifferentEvent(
            new BigDecimal(lat), new BigDecimal(lon), d, "uw", "origin", "00005555");

    Event e5 =
        createDifferentEvent(
            new BigDecimal(lat), new BigDecimal(lon), d, "us", "origin", "00005555");

    // Now add the events to a list, and find the most similar
    List<Event> events = new ArrayList<Event>();
    events.add(e1);
    events.add(e2);
    events.add(e3);
    events.add(e4);
    events.add(e5);

    // Calculate which event is most similar to the product
    DefaultAssociator associator = new DefaultAssociator();
    Event mostSimilar = associator.chooseEvent(events, product);
    Assert.assertEquals(e4, mostSimilar);
  }
  /**
   * The DefaultAssociator will filter events that are from the same source as a summary if they
   * have a different code.
   *
   * <p>This test exists to prevent a nullpointerexception regression.
   */
  @Test
  public void testChooseEventWithoutSummarySourceCode() {
    ProductSummary summary = new ProductSummary();
    List<Event> events = new LinkedList<Event>();
    DefaultAssociator associator = new DefaultAssociator();

    try {
      Event event = associator.chooseEvent(events, summary);
      Assert.assertNull("Returned event null", event);
    } catch (NullPointerException npe) {
      Assert.fail("NullPointerException thrown");
    }
  }
  /**
   * Test if the associator selects using the most important attribute first. That is, use eventId
   * before location.
   *
   * <p>This test creates 2 events, A and B, and a summary X. A and B both have eventId and location
   * information. B's location is closest to X's location, but A's eventId matches X's. The
   * associator should choose A.
   */
  @Test
  public void testAssociationOrder() {
    Date eventTime = new Date();

    // Create the first event
    ProductSummary eventSummaryA = new ProductSummary();
    eventSummaryA.setId(new ProductId("productsource", "producttype", "productcode"));
    eventSummaryA.setEventSource("source");
    eventSummaryA.setEventSourceCode("code");
    eventSummaryA.setEventLatitude(new BigDecimal("10.0"));
    eventSummaryA.setEventLongitude(new BigDecimal("10.0"));
    eventSummaryA.setEventTime(eventTime);
    Event eventA = new Event();
    eventA.addProduct(eventSummaryA);

    // Create the second event
    ProductSummary eventSummaryB = new ProductSummary();
    eventSummaryB.setId(new ProductId("productsource", "producttype", "productcode"));
    eventSummaryB.setEventSource("source2");
    eventSummaryB.setEventSourceCode("code2");
    eventSummaryB.setEventLatitude(new BigDecimal("0.0"));
    eventSummaryB.setEventLongitude(new BigDecimal("0.0"));
    eventSummaryB.setEventTime(eventTime);
    Event eventB = new Event();
    eventB.addProduct(eventSummaryB);

    // Create the test summary
    ProductSummary summaryX = new ProductSummary();
    summaryX.setId(new ProductId("productsource", "producttype", "productcode"));
    summaryX.setEventSource("source");
    summaryX.setEventSourceCode("code");
    summaryX.setEventLatitude(new BigDecimal("0.0"));
    summaryX.setEventLongitude(new BigDecimal("0.0"));
    summaryX.setEventTime(eventTime);

    // Add the events to a list
    List<Event> events = new LinkedList<Event>();
    events.add(eventA);
    events.add(eventB);

    // Test to verify event A is chosen.
    DefaultAssociator associator = new DefaultAssociator();
    Event event = associator.chooseEvent(events, summaryX);
    Assert.assertEquals("Event from same source with same code chosen", eventA, event);
  }
  /**
   * When an event source submits data using the same code, they refer to the same event.
   *
   * <p>The associator shouldn't filter an event when it uses the same source and code (although it
   * won't necessarily choose that event because it has the same source and code).
   */
  @Test
  public void testSameEventCodeFromSameSource() {
    ProductSummary summary = new ProductSummary();
    summary.setEventSource("source");
    summary.setEventSourceCode("code");

    // build event from same source, with same code
    ProductSummary differentSummary = new ProductSummary();
    differentSummary.setId(new ProductId("productsource", "producttype", "productcode"));
    differentSummary.setEventSource("source");
    differentSummary.setEventSourceCode("code");

    Event sameEvent = new Event();
    sameEvent.addProduct(differentSummary);

    List<Event> events = new LinkedList<Event>();
    events.add(sameEvent);

    // test to verify event is chosen
    DefaultAssociator associator = new DefaultAssociator();
    Event event = associator.chooseEvent(events, summary);

    Assert.assertEquals("Event from same source with same code chosen", sameEvent, event);
  }