From 6c71ff5016f44e8b26d25eabc9fbd4fb571995c9 Mon Sep 17 00:00:00 2001 From: Jay Hodgson Date: Tue, 27 Feb 2024 11:47:24 -0800 Subject: [PATCH] SWC-6700 --- .../presenter/AccessRequirementPresenter.java | 41 +++++- .../AccessRequirementPresenterTest.java | 128 ++++++++++++++++++ 2 files changed, 163 insertions(+), 6 deletions(-) create mode 100644 src/test/java/org/sagebionetworks/web/unitclient/presenter/AccessRequirementPresenterTest.java diff --git a/src/main/java/org/sagebionetworks/web/client/presenter/AccessRequirementPresenter.java b/src/main/java/org/sagebionetworks/web/client/presenter/AccessRequirementPresenter.java index 5e653cc317..93b46b37ea 100644 --- a/src/main/java/org/sagebionetworks/web/client/presenter/AccessRequirementPresenter.java +++ b/src/main/java/org/sagebionetworks/web/client/presenter/AccessRequirementPresenter.java @@ -2,15 +2,19 @@ import com.google.gwt.activity.shared.AbstractActivity; import com.google.gwt.event.shared.EventBus; +import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.AcceptsOneWidget; import com.google.inject.Inject; +import org.sagebionetworks.repo.model.AccessRequirement; import org.sagebionetworks.repo.model.RestrictableObjectDescriptor; import org.sagebionetworks.repo.model.RestrictableObjectType; +import org.sagebionetworks.web.client.SynapseJavascriptClient; import org.sagebionetworks.web.client.place.AccessRequirementPlace; import org.sagebionetworks.web.client.place.AccessRequirementsPlace; import org.sagebionetworks.web.client.view.DivView; import org.sagebionetworks.web.client.view.PlaceView; import org.sagebionetworks.web.client.widget.accessrequirements.AccessRequirementWidget; +import org.sagebionetworks.web.client.widget.entity.controller.SynapseAlert; public class AccessRequirementPresenter extends AbstractActivity @@ -20,15 +24,21 @@ public class AccessRequirementPresenter private PlaceView view; private AccessRequirementWidget arWidget; private String requirementId; + private SynapseJavascriptClient jsClient; + private SynapseAlert synAlert; @Inject public AccessRequirementPresenter( PlaceView view, AccessRequirementWidget arWidget, - DivView arDiv + DivView arDiv, + SynapseJavascriptClient jsClient, + SynapseAlert synAlert ) { this.view = view; this.arWidget = arWidget; + this.jsClient = jsClient; + this.synAlert = synAlert; arDiv.addStyleName("markdown"); arDiv.add(arWidget.asWidget()); view.add(arDiv.asWidget()); @@ -44,23 +54,42 @@ public void start(AcceptsOneWidget panel, EventBus eventBus) { public void setPlace(AccessRequirementPlace place) { this.place = place; view.initHeaderAndFooter(); + synAlert.clear(); requirementId = place.getParam(AccessRequirementPlace.AR_ID_PARAM); String id = place.getParam(AccessRequirementsPlace.ID_PARAM); String typeString = place.getParam(AccessRequirementsPlace.TYPE_PARAM); // Note: configuring the Access Requirement widget without a target subject will result in notifications sent to the user will not have the context (Project/Folder/File associated with the restriction). - RestrictableObjectDescriptor targetSubject = null; - if (id != null && typeString != null) { - targetSubject = new RestrictableObjectDescriptor(); + RestrictableObjectDescriptor targetSubject = + new RestrictableObjectDescriptor(); RestrictableObjectType type = RestrictableObjectType.valueOf( typeString.toUpperCase() ); targetSubject.setType(type); targetSubject.setId(id); - } - arWidget.configure(requirementId, targetSubject); + arWidget.configure(requirementId, targetSubject); + } else { + // SWC-6700: No subject specified, pick a random one since some code assumes a subject has been specified. + jsClient.getAccessRequirement( + requirementId, + new AsyncCallback() { + @Override + public void onSuccess(AccessRequirement result) { + RestrictableObjectDescriptor firstSubject = result + .getSubjectIds() + .get(0); + arWidget.configure(requirementId, firstSubject); + } + + @Override + public void onFailure(Throwable caught) { + synAlert.handleException(caught); + } + } + ); + } } public AccessRequirementPlace getPlace() { diff --git a/src/test/java/org/sagebionetworks/web/unitclient/presenter/AccessRequirementPresenterTest.java b/src/test/java/org/sagebionetworks/web/unitclient/presenter/AccessRequirementPresenterTest.java new file mode 100644 index 0000000000..34c5a562e9 --- /dev/null +++ b/src/test/java/org/sagebionetworks/web/unitclient/presenter/AccessRequirementPresenterTest.java @@ -0,0 +1,128 @@ +package org.sagebionetworks.web.unitclient.presenter; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Widget; +import java.util.Collections; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sagebionetworks.repo.model.AccessRequirement; +import org.sagebionetworks.repo.model.RestrictableObjectDescriptor; +import org.sagebionetworks.repo.model.RestrictableObjectType; +import org.sagebionetworks.web.client.SynapseJavascriptClient; +import org.sagebionetworks.web.client.place.AccessRequirementPlace; +import org.sagebionetworks.web.client.place.AccessRequirementsPlace; +import org.sagebionetworks.web.client.presenter.AccessRequirementPresenter; +import org.sagebionetworks.web.client.view.DivView; +import org.sagebionetworks.web.client.view.PlaceView; +import org.sagebionetworks.web.client.widget.accessrequirements.AccessRequirementWidget; +import org.sagebionetworks.web.client.widget.entity.controller.SynapseAlert; +import org.sagebionetworks.web.test.helper.AsyncMockStubber; + +@RunWith(MockitoJUnitRunner.class) +public class AccessRequirementPresenterTest { + + AccessRequirementPresenter presenter; + + @Mock + PlaceView mockView; + + @Mock + AccessRequirementWidget mockArWidget; + + @Mock + DivView mockArDiv; + + @Mock + SynapseJavascriptClient mockJsClient; + + @Mock + SynapseAlert mockSynAlert; + + @Mock + AccessRequirementPlace mockPlace; + + @Mock + AccessRequirement mockAR; + + @Captor + ArgumentCaptor subjectCaptor; + + Exception caught = new Exception("this is an exception"); + + public static final String AR_ID = "1111112"; + public static final String ENTITY_ID = "syn239834"; + + @Mock + RestrictableObjectDescriptor mockSubject; + + @Before + public void setup() { + presenter = + new AccessRequirementPresenter( + mockView, + mockArWidget, + mockArDiv, + mockJsClient, + mockSynAlert + ); + when(mockPlace.getParam(AccessRequirementPlace.AR_ID_PARAM)) + .thenReturn(AR_ID); + when(mockAR.getSubjectIds()) + .thenReturn(Collections.singletonList(mockSubject)); + AsyncMockStubber + .callSuccessWith(mockAR) + .when(mockJsClient) + .getAccessRequirement(anyString(), any(AsyncCallback.class)); + } + + @Test + public void testConstruction() { + verify(mockArDiv).add(any(Widget.class)); + verify(mockView).add(any(Widget.class)); + } + + @Test + public void testParamsProvided() { + when(mockPlace.getParam(AccessRequirementsPlace.ID_PARAM)) + .thenReturn(ENTITY_ID); + when(mockPlace.getParam(AccessRequirementsPlace.TYPE_PARAM)) + .thenReturn(RestrictableObjectType.ENTITY.toString()); + + presenter.setPlace(mockPlace); + + verify(mockArWidget).configure(eq(AR_ID), subjectCaptor.capture()); + RestrictableObjectDescriptor subject = subjectCaptor.getValue(); + assertEquals(ENTITY_ID, subject.getId()); + assertEquals(RestrictableObjectType.ENTITY, subject.getType()); + } + + @Test + public void testGetAR() { + presenter.setPlace(mockPlace); + + verify(mockArWidget).configure(AR_ID, mockSubject); + } + + @Test + public void testGetARFailure() { + AsyncMockStubber + .callFailureWith(caught) + .when(mockJsClient) + .getAccessRequirement(anyString(), any(AsyncCallback.class)); + presenter.setPlace(mockPlace); + verify(mockSynAlert).clear(); + verify(mockSynAlert).handleException(caught); + } +}