@Test
  public void testActivityHierarchy() throws Exception {
    AssetEntry parentAssetEntry = SocialActivityTestUtil.addAssetEntry(creatorUser, group);

    SocialActivityHierarchyEntryThreadLocal.push(
        parentAssetEntry.getClassNameId(), parentAssetEntry.getClassPK());

    SocialActivityTestUtil.addActivity(creatorUser, group, assetEntry, 1);

    List<SocialActivity> activities =
        SocialActivityLocalServiceUtil.getGroupActivities(
            group.getGroupId(), QueryUtil.ALL_POS, QueryUtil.ALL_POS);

    Assert.assertEquals(1, activities.size());

    SocialActivity activity = activities.get(0);

    Assert.assertEquals(parentAssetEntry.getClassNameId(), activity.getParentClassNameId());
    Assert.assertEquals(parentAssetEntry.getClassPK(), activity.getParentClassPK());

    SocialActivityTestUtil.addActivity(
        creatorUser, group, assetEntry, SocialActivityConstants.TYPE_DELETE);

    Assert.assertEquals(
        1, SocialActivityLocalServiceUtil.getGroupActivitiesCount(group.getGroupId()));
  }
  @After
  public void tearDown() throws Exception {
    SocialActivityHierarchyEntryThreadLocal.clear();

    if (_actorUser != null) {
      UserLocalServiceUtil.deleteUser(_actorUser);

      _actorUser = null;
    }

    if (_assetEntry != null) {
      AssetEntryLocalServiceUtil.deleteEntry(_assetEntry);

      _assetEntry = null;
    }

    if (_creatorUser != null) {
      UserLocalServiceUtil.deleteUser(_creatorUser);

      _creatorUser = null;
    }

    if (_group != null) {
      GroupLocalServiceUtil.deleteGroup(_group);

      _group = null;
    }
  }
  @Before
  public void setUp() throws Exception {
    group = GroupTestUtil.addGroup();

    actorUser = UserTestUtil.addUser("actor", group.getGroupId());
    creatorUser = UserTestUtil.addUser("creator", group.getGroupId());

    assetEntry = SocialActivityTestUtil.addAssetEntry(creatorUser, group, null);

    SocialActivityHierarchyEntryThreadLocal.clear();
  }
 @After
 public void tearDown() throws Exception {
   SocialActivityHierarchyEntryThreadLocal.clear();
 }
  /**
   * Records an activity with the given time in the database.
   *
   * <p>This method records a social activity done on an asset, identified by its class name and
   * class primary key, in the database. Additional information (such as the original message ID for
   * a reply to a forum post) is passed in via the <code>extraData</code> in JSON format. For
   * activities affecting another user, a mirror activity is generated that describes the action
   * from the user's point of view. The target user's ID is passed in via the <code>receiverUserId
   * </code>.
   *
   * <p>Example for a mirrored activity:<br>
   * When a user replies to a message boards post, the reply action is stored in the database with
   * the <code>receiverUserId</code> being the ID of the author of the original message. The <code>
   * extraData</code> contains the ID of the original message in JSON format. A mirror activity is
   * generated with the values of the <code>userId</code> and the <code>receiverUserId</code>
   * swapped. This mirror activity basically describes a "replied to" event.
   *
   * <p>Mirror activities are most often used in relation to friend requests and activities.
   *
   * @param userId the primary key of the acting user
   * @param groupId the primary key of the group
   * @param createDate the activity's date
   * @param className the target asset's class name
   * @param classPK the primary key of the target asset
   * @param type the activity's type
   * @param extraData any extra data regarding the activity
   * @param receiverUserId the primary key of the receiving user
   * @throws PortalException if the user or group could not be found
   */
  @Override
  public void addActivity(
      long userId,
      long groupId,
      Date createDate,
      String className,
      long classPK,
      int type,
      String extraData,
      long receiverUserId)
      throws PortalException {

    if (ExportImportThreadLocal.isImportInProcess()) {
      return;
    }

    User user = userPersistence.findByPrimaryKey(userId);
    long classNameId = classNameLocalService.getClassNameId(className);

    if (groupId > 0) {
      Group group = groupLocalService.getGroup(groupId);

      if (group.isLayout()) {
        Layout layout = layoutLocalService.getLayout(group.getClassPK());

        groupId = layout.getGroupId();
      }
    }

    final SocialActivity activity = socialActivityPersistence.create(0);

    activity.setGroupId(groupId);
    activity.setCompanyId(user.getCompanyId());
    activity.setUserId(user.getUserId());
    activity.setCreateDate(createDate.getTime());
    activity.setMirrorActivityId(0);
    activity.setClassNameId(classNameId);
    activity.setClassPK(classPK);

    SocialActivityHierarchyEntry activityHierarchyEntry =
        SocialActivityHierarchyEntryThreadLocal.peek();

    if (activityHierarchyEntry != null) {
      activity.setParentClassNameId(activityHierarchyEntry.getClassNameId());
      activity.setParentClassPK(activityHierarchyEntry.getClassPK());
    }

    activity.setType(type);
    activity.setExtraData(extraData);
    activity.setReceiverUserId(receiverUserId);

    AssetEntry assetEntry = assetEntryPersistence.fetchByC_C(classNameId, classPK);

    activity.setAssetEntry(assetEntry);

    SocialActivity mirrorActivity = null;

    if ((receiverUserId > 0) && (userId != receiverUserId)) {
      mirrorActivity = socialActivityPersistence.create(0);

      mirrorActivity.setGroupId(groupId);
      mirrorActivity.setCompanyId(user.getCompanyId());
      mirrorActivity.setUserId(receiverUserId);
      mirrorActivity.setCreateDate(createDate.getTime());
      mirrorActivity.setClassNameId(classNameId);
      mirrorActivity.setClassPK(classPK);

      if (activityHierarchyEntry != null) {
        mirrorActivity.setParentClassNameId(activityHierarchyEntry.getClassNameId());
        mirrorActivity.setParentClassPK(activityHierarchyEntry.getClassPK());
      }

      mirrorActivity.setType(type);
      mirrorActivity.setExtraData(extraData);
      mirrorActivity.setReceiverUserId(user.getUserId());
      mirrorActivity.setAssetEntry(assetEntry);
    }

    final SocialActivity finalMirrorActivity = mirrorActivity;

    Callable<Void> callable =
        new Callable<Void>() {

          @Override
          public Void call() throws Exception {
            socialActivityLocalService.addActivity(activity, finalMirrorActivity);

            return null;
          }
        };

    TransactionCommitCallbackUtil.registerCallback(callable);
  }