/**
   * Simulates the process when an object's relation change (the child object). The child object is
   * not an entry object The change connects it to another object, which have this relation as an
   * inverse view relation. While this does put the child in a record, this is not reflected in the
   * database, as we do not check what the relation points to.
   *
   * @throws Exception
   */
  @Test
  public void testObjectRelationsChangedChildChanged() throws Exception {
    final String pid = "doms:test1";
    final String child = "doms:test2";
    final int key = 1;

    TestHelpers.addEntry(pid, fcmock, child);

    Date now = new Date();
    final Record recordToLookup = new Record(child, VIEW_ANGLE, COLLECTION);

    final Record recordBefore =
        new Record(
            pid, VIEW_ANGLE, COLLECTION, null, new Date(1), null, null, TestHelpers.asSet(pid));

    when(dbSession.getPersistentRecord(eq(recordToLookup))).thenReturn(recordBefore);
    when(dbSession.getRecordsContainingThisPid(pid)).thenReturn(TestHelpers.asSet(recordBefore));
    when(dbSession.getRecordsContainingThisPid(child))
        .thenReturn(TestHelpers.emptySet(Record.class));

    store.objectRelationsChanged(child, now, key);

    InOrder mocks = inOrder(dbSession, fcmock);

    mocks.verify(dbSession).beginTransaction();

    // Datastream RELSEXT changed
    mocks.verify(fcmock).isCurrentlyContentModel(child);
    mocks.verify(fcmock).getCollections(child, now);
    mocks.verify(fcmock).getState(child, now);

    // backend.reconnectObjects
    mocks.verify(fcmock).getEntryAngles(child, now);

    // Check for any old records which should be unlinked. There are none
    mocks
        .verify(dbSession)
        .getRecordsNotInTheseCollectionsAndViewAngles(
            child, TestHelpers.emptySet(String.class), TestHelpers.asSet(COLLECTION));
    // Find all the records affected by this change
    mocks.verify(dbSession).getRecordsContainingThisPid(child);

    // UpdateDAtes
    mocks.verify(dbSession).updateDates(child, now);
    // LatestKey
    mocks.verify(dbSession).setLatestKey(key);

    verifyNoMoreInteractions(dbSession, fcmock);
  }
  /**
   * Simulates the process when we receive a object changed state to active from the worklog
   *
   * @throws Exception
   */
  @Test
  public void testObjectPublished() throws Exception {
    Date now = new Date();
    final String pid = "doms:test1";
    int key = 1;

    final Record keyedRecord = new Record(pid, VIEW_ANGLE, COLLECTION);
    final Record newRecord =
        new Record(pid, VIEW_ANGLE, COLLECTION, null, now, null, null, TestHelpers.asSet(pid));
    TestHelpers.addEntry("doms:test1", fcmock);

    when(dbSession.getPersistentRecord(eq(keyedRecord))).thenReturn(newRecord);
    when(dbSession.getRecordsContainingThisPid(pid)).thenReturn(TestHelpers.asSet(newRecord));
    store.objectStateChanged("doms:test1", now, "A", 1);

    InOrder mocks = inOrder(dbSession, fcmock);
    // ObjectStateChanged
    mocks.verify(dbSession).beginTransaction();
    mocks.verify(fcmock).getCollections(pid, now);

    // ModifyStates
    mocks.verify(dbSession).getAllRecordsWithThisEntryPid(pid);
    mocks.verify(fcmock).getEntryAngles(pid, now);
    mocks.verify(dbSession).getPersistentRecord(keyedRecord);
    mocks.verify(dbSession).saveRecord(newRecord);
    // UpdateDAtes
    mocks.verify(dbSession).updateDates(pid, now);
    // LatestKey
    mocks.verify(dbSession).setLatestKey(key);

    verifyNoMoreInteractions(dbSession, fcmock);
  }
  /**
   * Simulates the process when we receive an object purged or object changed state to deleted from
   * the worklog
   *
   * @throws Exception
   */
  @Test
  public void testObjectDeletedBasic() throws Exception {
    Date now = new Date();
    final String pid = "doms:test1";
    int key = 1;

    final Record newRecord =
        new Record(pid, VIEW_ANGLE, COLLECTION, null, now, null, null, TestHelpers.asSet(pid));

    when(dbSession.getPersistentRecord(eq(new Record(pid, VIEW_ANGLE, COLLECTION))))
        .thenReturn(newRecord);
    when(dbSession.getRecordsContainingThisPid(pid)).thenReturn(TestHelpers.asSet(newRecord));
    store.objectDeleted(pid, now, ++key);

    InOrder mocks = inOrder(dbSession, fcmock);
    // ObjectDeleted
    mocks.verify(dbSession).beginTransaction();
    // ModifyStates
    mocks.verify(dbSession).getRecordsContainingThisPid(pid);
    mocks.verify(dbSession).saveRecord(newRecord);
    // UpdateDAtes
    mocks.verify(dbSession).updateDates(pid, now);
    // LatestKey
    mocks.verify(dbSession).setLatestKey(key);

    verifyNoMoreInteractions(dbSession, fcmock);
  }
  /**
   * Simulates the process when an object's relations change, but this does not change the view
   * bundle, ie. when a non-view relation change
   *
   * @throws Exception
   */
  @Test
  public void testObjectRelationsChangedSameBundle() throws Exception {
    final String pid = "doms:test1";
    final int key = 1;

    final String child = "doms:test2";
    TestHelpers.addEntry(pid, fcmock, child);
    Date now = new Date();
    final Record keyedRecord = new Record(pid, VIEW_ANGLE, COLLECTION);
    final Record newRecord =
        new Record(
            pid, VIEW_ANGLE, COLLECTION, null, now, null, null, TestHelpers.asSet(pid, child));
    when(dbSession.getPersistentRecord(eq(keyedRecord))).thenReturn(newRecord);
    when(dbSession.getRecordsContainingThisPid(pid)).thenReturn(TestHelpers.asSet(newRecord));

    store.objectRelationsChanged(pid, now, key);

    InOrder mocks = inOrder(dbSession, fcmock);

    mocks.verify(dbSession).beginTransaction();

    mocks.verify(fcmock).isCurrentlyContentModel(pid);
    mocks.verify(fcmock).getCollections(pid, now);
    mocks.verify(fcmock).getState(pid, now);

    mocks.verify(fcmock).getEntryAngles(pid, now);
    mocks.verify(dbSession).getPersistentRecord(keyedRecord);

    mocks
        .verify(dbSession)
        .getRecordsNotInTheseCollectionsAndViewAngles(
            pid, TestHelpers.asSet(VIEW_ANGLE), TestHelpers.asSet(COLLECTION));
    mocks.verify(dbSession).getRecordsContainingThisPid(pid);

    mocks.verify(fcmock).calcViewBundle(pid, VIEW_ANGLE, now);

    // UpdateDAtes
    mocks.verify(dbSession).updateDates(pid, now);
    // LatestKey
    mocks.verify(dbSession).setLatestKey(key);

    verifyNoMoreInteractions(dbSession, fcmock);
  }