gt:         Owner owner = this.component.getOwner(this.entity);
context: /*
   * See the NOTICE file distributed with this work for additional
   * information regarding copyright ownership.
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU Affero General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU Affero General Public License for more details.
   *
   * You should have received a copy of the GNU Affero General Public License
   * along with this program.  If not, see http://www.gnu.org/licenses/
   */
  package org.phenotips.data.permissions.internal;
  
  import org.phenotips.data.Patient;
  import org.phenotips.data.permissions.AccessLevel;
  import org.phenotips.data.permissions.Collaborator;
  import org.phenotips.data.permissions.Owner;
  import org.phenotips.data.permissions.internal.access.EditAccessLevel;
  import org.phenotips.data.permissions.internal.access.ManageAccessLevel;
  import org.phenotips.data.permissions.internal.access.NoAccessLevel;
  import org.phenotips.data.permissions.internal.access.OwnerAccessLevel;
  import org.phenotips.data.permissions.internal.access.ViewAccessLevel;
  import org.phenotips.entities.PrimaryEntity;
  
  import org.xwiki.component.manager.ComponentLookupException;
  import org.xwiki.component.manager.ComponentManager;
  import org.xwiki.component.util.DefaultParameterizedType;
  import org.xwiki.model.reference.DocumentReference;
  import org.xwiki.model.reference.DocumentReferenceResolver;
  import org.xwiki.model.reference.EntityReference;
  import org.xwiki.model.reference.EntityReferenceSerializer;
  import org.xwiki.security.authorization.AuthorizationManager;
  import org.xwiki.security.authorization.Right;
  import org.xwiki.test.mockito.MockitoComponentMockingRule;
  
  import java.lang.reflect.ParameterizedType;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.List;
  
  import javax.inject.Provider;
  
  import org.apache.commons.lang3.StringUtils;
  import org.junit.Assert;
  import org.junit.Before;
  import org.junit.Rule;
  import org.junit.Test;
  import org.mockito.Mock;
  import org.mockito.MockitoAnnotations;
  import org.slf4j.Logger;
  
  import com.xpn.xwiki.XWiki;
  import com.xpn.xwiki.XWikiContext;
  import com.xpn.xwiki.XWikiException;
  import com.xpn.xwiki.doc.XWikiDocument;
  import com.xpn.xwiki.objects.BaseObject;
  import com.xpn.xwiki.user.api.XWikiGroupService;
  
  import static org.mockito.Matchers.any;
  import static org.mockito.Matchers.anyBoolean;
  import static org.mockito.Matchers.anyString;
  import static org.mockito.Matchers.eq;
  import static org.mockito.Mockito.doThrow;
  import static org.mockito.Mockito.mock;
  import static org.mockito.Mockito.never;
  import static org.mockito.Mockito.times;
  import static org.mockito.Mockito.verify;
  import static org.mockito.Mockito.verifyZeroInteractions;
  import static org.mockito.Mockito.when;
  
  /**
   * Tests for the default {@link EntityAccessManager} implementation, {@link DefaultEntityAccessManager}.
   *
   * @version $Id$
   */
  public class DefaultEntityAccessManagerTest
  {
      private static final String WIKI_NAME = "xwiki";
  
      private static final String DATA = "data";
  
      private static final String SPACE_NAME = "XWiki";
  
      private static final String GROUP_SPACE_NAME = "Groups";
  
      private static final String PHENOTIPS = "PhenoTips";
  
      private static final String OWNER_NAME = "padams";
  
      private static final String COLLABORATOR_NAME = "hmccoy";
  
      private static final String OTHER_USER_NAME = "cxavier";
  
      private static final String OWNER_TITLE = "Owner";
  
      private static final String VISIBILITY_TITLE = "Visibility";
  
      private static final String COLLABORATOR_TITLE = "Collaborator";
  
      private static final String COLLABORATORS_LABEL = "collaborators";
  
      private static final String COLLABORATOR_LABEL = "collaborator";
  
      private static final String ACCESS_LABEL = "access";
  
      private static final String OWNER_LABEL = "owner";
  
      private static final String EDIT_LABEL = "edit";
  
      private static final String VIEW_LABEL = "view";
  
      private static final String UNKNOWN_LABEL = "unknown";
  
      private static final String MANAGE_LABEL = "manage";
  
      private static final String NONE_LABEL = "none";
  
      private static final String OWNER_STR = "xwiki:XWiki.padams";
  
      private static final String COLLABORATOR_STR = "xwiki:XWiki.hmccoy";
  
      private static final String OTHER_USER_STR = "xwiki:XWiki.cxavier";
  
      private static final String GROUP_STR = "xwiki:Groups.collaborators";
  
      private static final String PATIENT_ID = "P0000001";
  
      private static final AccessLevel EDIT_ACCESS = new EditAccessLevel();
  
      private static final AccessLevel VIEW_ACCESS = new ViewAccessLevel();
  
      private static final AccessLevel MANAGE_ACCESS = new ManageAccessLevel();
  
      private static final AccessLevel OWNER_ACCESS = new OwnerAccessLevel();
  
      private static final AccessLevel NO_ACCESS = new NoAccessLevel();
  
      /** The patient used for tests. */
      private static final DocumentReference PATIENT_REFERENCE = new DocumentReference(WIKI_NAME, DATA, PATIENT_ID);
  
      /** The user used as the owner of the patient. */
      private static final DocumentReference OWNER = new DocumentReference(WIKI_NAME, SPACE_NAME, OWNER_NAME);
  
      /** The user used as a collaborator. */
      private static final DocumentReference COLLABORATOR = new DocumentReference(WIKI_NAME, SPACE_NAME,
          COLLABORATOR_NAME);
  
      /** The user used as a non-collaborator. */
      private static final DocumentReference OTHER_USER = new DocumentReference(WIKI_NAME, SPACE_NAME, OTHER_USER_NAME);
  
      /** Group used as collaborator. */
      private static final DocumentReference GROUP =
          new DocumentReference(WIKI_NAME, GROUP_SPACE_NAME, COLLABORATORS_LABEL);
  
      private static final DocumentReference OWNER_CLASS = new DocumentReference(WIKI_NAME, PHENOTIPS, OWNER_TITLE);
  
      private static final DocumentReference VISIBILITY_CLASS = new DocumentReference(WIKI_NAME, PHENOTIPS,
          VISIBILITY_TITLE);
  
      private static final DocumentReference COLLABORATOR_CLASS = new DocumentReference(WIKI_NAME, PHENOTIPS,
          COLLABORATOR_TITLE);
  
      @Rule
      public MockitoComponentMockingRule<EntityAccessManager> mocker =
          new MockitoComponentMockingRule<>(DefaultEntityAccessManager.class);
  
      @Mock
      private Patient entity;
  
      @Mock
      private XWikiDocument entityDoc;
  
      @Mock
      private BaseObject ownerObject;
  
      @Mock
      private XWikiGroupService groupService;
  
      @Mock
      private BaseObject visibilityObject;
  
      @Mock
      private BaseObject collaboratorObject1;
  
      @Mock
      private BaseObject collaboratorObject2;
  
      @Mock
      private BaseObject collaboratorObject3;
  
      @Mock
      private XWikiContext context;
  
      @Mock
      private XWiki xwiki;
  
      private ParameterizedType entityResolverType = new DefaultParameterizedType(null, DocumentReferenceResolver.class,
          EntityReference.class);
  
      private ParameterizedType stringResolverType = new DefaultParameterizedType(null, DocumentReferenceResolver.class,
          String.class);
  
      private ParameterizedType stringSerializerType = new DefaultParameterizedType(null,
          EntityReferenceSerializer.class, String.class);
  
      private DocumentReferenceResolver<EntityReference> partialEntityResolver;
  
      private ComponentManager componentManager;
  
      private EntityAccessManager component;
  
      private AuthorizationManager rights;
  
      private EntityAccessHelper helper;
  
      private AccessLevel noAccess;
  
      private Logger logger;
  
      @Before
      public void setUp() throws Exception
      {
          MockitoAnnotations.initMocks(this);
  
          final Provider<XWikiContext> xcontextProvider = this.mocker.getInstance(XWikiContext.TYPE_PROVIDER);
          when(xcontextProvider.get()).thenReturn(this.context);
          when(this.context.getWiki()).thenReturn(this.xwiki);
  
          this.partialEntityResolver = this.mocker.getInstance(this.entityResolverType, "currentmixed");
          this.componentManager = this.mocker.getInstance(ComponentManager.class, "context");
          this.noAccess = this.mocker.getInstance(AccessLevel.class, NONE_LABEL);
          this.rights = this.mocker.getInstance(AuthorizationManager.class);
          this.helper = this.mocker.getInstance(EntityAccessHelper.class);
  
          this.component = this.mocker.getComponentUnderTest();
          this.logger = this.mocker.getMockedLogger();
  
          when(this.entity.getDocumentReference()).thenReturn(PATIENT_REFERENCE);
          when(this.entity.getXDocument()).thenReturn(this.entityDoc);
          when(this.entityDoc.getXObject(OWNER_CLASS)).thenReturn(this.ownerObject);
          when(this.entityDoc.getXObject(OWNER_CLASS, true, this.context)).thenReturn(this.ownerObject);
          when(this.ownerObject.getStringValue(OWNER_LABEL)).thenReturn(OWNER_STR);
          when(this.entityDoc.getXObject(VISIBILITY_CLASS)).thenReturn(this.visibilityObject);
          when(this.entityDoc.getXObject(VISIBILITY_CLASS, true, this.context)).thenReturn(this.visibilityObject);
  
          when(this.partialEntityResolver.resolve(Owner.CLASS_REFERENCE, PATIENT_REFERENCE)).thenReturn(
              OWNER_CLASS);
          when(this.helper.getStringProperty(this.entity.getXDocument(), OWNER_CLASS, OWNER_LABEL)).thenReturn(OWNER_STR);
  
          final DocumentReferenceResolver<String> stringEntityResolver =
              this.mocker.getInstance(this.stringResolverType, "currentmixed");
          when(stringEntityResolver.resolve(OWNER_STR, PATIENT_REFERENCE)).thenReturn(OWNER);
          when(this.partialEntityResolver.resolve(OWNER)).thenReturn(OWNER);
  
          final EntityReferenceSerializer<String> stringEntitySerializer =
              this.mocker.getInstance(this.stringSerializerType);
          when(stringEntitySerializer.serialize(OWNER)).thenReturn(OWNER_STR);
  
          when(this.componentManager.getInstance(AccessLevel.class, EDIT_LABEL)).thenReturn(EDIT_ACCESS);
          when(this.componentManager.getInstance(AccessLevel.class, VIEW_LABEL)).thenReturn(VIEW_ACCESS);
          when(this.componentManager.getInstance(AccessLevel.class, MANAGE_LABEL)).thenReturn(MANAGE_ACCESS);
          when(this.componentManager.getInstance(AccessLevel.class, OWNER_LABEL)).thenReturn(OWNER_ACCESS);
          when(this.componentManager.getInstance(AccessLevel.class, NONE_LABEL)).thenReturn(NO_ACCESS);
  
          when(this.partialEntityResolver.resolve(Collaborator.CLASS_REFERENCE, PATIENT_REFERENCE)).thenReturn(
              COLLABORATOR_CLASS);
          when(stringEntityResolver.resolve(OWNER_STR)).thenReturn(OWNER);
          when(stringEntityResolver.resolve(COLLABORATOR_STR, PATIENT_REFERENCE)).thenReturn(COLLABORATOR);
          when(stringEntityResolver.resolve(OTHER_USER_STR, PATIENT_REFERENCE)).thenReturn(OTHER_USER);
          when(stringEntityResolver.resolve(GROUP_STR, PATIENT_REFERENCE)).thenReturn(GROUP);
  
          when(this.partialEntityResolver.resolve(COLLABORATOR)).thenReturn(COLLABORATOR);
  
          when(stringEntitySerializer.serialize(COLLABORATOR)).thenReturn(COLLABORATOR_STR);
          when(stringEntitySerializer.serialize(OTHER_USER)).thenReturn(OTHER_USER_STR);
      }
  
      /** Basic tests for {@link EntityAccessManager#getOwner(PrimaryEntity)}. */
      @Test
      public void getOwner()
      {
          final Owner owner = this.component.getOwner(this.entity);
          Assert.assertNotNull(owner);
          Assert.assertSame(OWNER, owner.getUser());
      }
  
      /** {@link EntityAccessManager#getOwner(PrimaryEntity)} returns a null user when the owner isn't specified. */
      @Test
      public void getOwnerWithMissingOwnerAndReferrer()
      {
          when(this.helper.getStringProperty(this.entity.getXDocument(), OWNER_CLASS, OWNER_LABEL)).thenReturn(null);
          when(this.ownerObject.getStringValue(OWNER_LABEL)).thenReturn(null);
  