This is an automated email from the ASF dual-hosted git repository.

pvillard pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new 6a429b7cba NIFI-14332: Creating processor to list collaborators of Box 
Files
6a429b7cba is described below

commit 6a429b7cba90e28f630220a0c8f89a3b28c32941
Author: Noah Cover <[email protected]>
AuthorDate: Wed Mar 5 14:43:15 2025 -0800

    NIFI-14332: Creating processor to list collaborators of Box Files
    
    Signed-off-by: Pierre Villard <[email protected]>
    
    This closes #9774.
---
 .../processors/box/GetBoxFileCollaborators.java    | 222 +++++++++++++++++++
 .../services/org.apache.nifi.processor.Processor   |   1 +
 .../box/GetBoxFileCollaboratorsTest.java           | 237 +++++++++++++++++++++
 3 files changed, 460 insertions(+)

diff --git 
a/nifi-extension-bundles/nifi-box-bundle/nifi-box-processors/src/main/java/org/apache/nifi/processors/box/GetBoxFileCollaborators.java
 
b/nifi-extension-bundles/nifi-box-bundle/nifi-box-processors/src/main/java/org/apache/nifi/processors/box/GetBoxFileCollaborators.java
new file mode 100644
index 0000000000..26211d334a
--- /dev/null
+++ 
b/nifi-extension-bundles/nifi-box-bundle/nifi-box-processors/src/main/java/org/apache/nifi/processors/box/GetBoxFileCollaborators.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.processors.box;
+
+import com.box.sdk.BoxAPIConnection;
+import com.box.sdk.BoxAPIException;
+import com.box.sdk.BoxAPIResponseException;
+import com.box.sdk.BoxCollaboration;
+import com.box.sdk.BoxCollaborator;
+import com.box.sdk.BoxFile;
+import org.apache.nifi.annotation.behavior.InputRequirement;
+import org.apache.nifi.annotation.behavior.WritesAttribute;
+import org.apache.nifi.annotation.behavior.WritesAttributes;
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.SeeAlso;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.annotation.lifecycle.OnScheduled;
+import org.apache.nifi.box.controllerservices.BoxClientService;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.flowfile.FlowFile;
+import org.apache.nifi.processor.AbstractProcessor;
+import org.apache.nifi.processor.ProcessContext;
+import org.apache.nifi.processor.ProcessSession;
+import org.apache.nifi.processor.Relationship;
+import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.nifi.processor.util.StandardValidators;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.apache.nifi.processors.box.BoxFileAttributes.ERROR_CODE;
+import static org.apache.nifi.processors.box.BoxFileAttributes.ERROR_CODE_DESC;
+import static org.apache.nifi.processors.box.BoxFileAttributes.ERROR_MESSAGE;
+import static 
org.apache.nifi.processors.box.BoxFileAttributes.ERROR_MESSAGE_DESC;
+import static org.apache.nifi.processors.box.BoxFileAttributes.ID;
+import static org.apache.nifi.processors.box.BoxFileAttributes.ID_DESC;
+
+@InputRequirement(InputRequirement.Requirement.INPUT_REQUIRED)
+@Tags({"box", "storage", "collaboration", "permissions", "sharing"})
+@CapabilityDescription("Retrieves all collaborators on a Box file and adds the 
collaboration information to the FlowFile's attributes.")
+@SeeAlso({FetchBoxFile.class, ListBoxFile.class})
+@WritesAttributes({
+        @WritesAttribute(attribute = ID, description = ID_DESC),
+        @WritesAttribute(attribute = "box.collaborations.<status>.users.ids", 
description = "Comma-separated list of user collaborator IDs by status"),
+        @WritesAttribute(attribute = "box.collaborations.<status>.groups.ids", 
description = "Comma-separated list of group collaborator IDs by status"),
+        @WritesAttribute(attribute = 
"box.collaborations.<status>.users.emails", description = "Comma-separated list 
of user collaborator emails by status"),
+        @WritesAttribute(attribute = 
"box.collaborations.<status>.groups.emails", description = "Comma-separated 
list of group collaborator emails by status"),
+        @WritesAttribute(attribute = "box.collaborations.count", description = 
"Total number of collaborations on the file"),
+        @WritesAttribute(attribute = ERROR_CODE, description = 
ERROR_CODE_DESC),
+        @WritesAttribute(attribute = ERROR_MESSAGE, description = 
ERROR_MESSAGE_DESC)
+})
+public class GetBoxFileCollaborators extends AbstractProcessor {
+
+    public static final PropertyDescriptor FILE_ID = new 
PropertyDescriptor.Builder()
+            .name("File ID")
+            .description("The ID of the Box file to retrieve collaborators 
for")
+            .required(true)
+            .defaultValue("${box.id}")
+            
.expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            .build();
+
+    public static final Relationship REL_SUCCESS = new Relationship.Builder()
+            .name("success")
+            .description("FlowFiles that have been successfully processed will 
be routed to this relationship")
+            .build();
+
+    public static final Relationship REL_FAILURE = new Relationship.Builder()
+            .name("failure")
+            .description("FlowFiles that encounter errors during processing 
will be routed to this relationship")
+            .build();
+
+    public static final Relationship REL_NOT_FOUND = new Relationship.Builder()
+            .name("not.found")
+            .description("FlowFiles for which the specified Box file was not 
found")
+            .build();
+
+    public static final Set<Relationship> RELATIONSHIPS = Set.of(
+            REL_SUCCESS,
+            REL_FAILURE,
+            REL_NOT_FOUND
+    );
+
+    private static final List<PropertyDescriptor> PROPERTY_DESCRIPTORS = 
List.of(
+            BoxClientService.BOX_CLIENT_SERVICE,
+            FILE_ID
+    );
+
+    private volatile BoxAPIConnection boxAPIConnection;
+
+    @Override
+    protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
+        return PROPERTY_DESCRIPTORS;
+    }
+
+    @Override
+    public Set<Relationship> getRelationships() {
+        return RELATIONSHIPS;
+    }
+
+    @OnScheduled
+    public void onScheduled(final ProcessContext context) {
+        BoxClientService boxClientService = 
context.getProperty(BoxClientService.BOX_CLIENT_SERVICE).asControllerService(BoxClientService.class);
+        boxAPIConnection = boxClientService.getBoxApiConnection();
+    }
+
+    @Override
+    public void onTrigger(final ProcessContext context, final ProcessSession 
session) throws ProcessException {
+        FlowFile flowFile = session.get();
+        if (flowFile == null) {
+            return;
+        }
+
+        final String fileId = 
context.getProperty(FILE_ID).evaluateAttributeExpressions(flowFile).getValue();
+        try {
+            flowFile = fetchCollaborations(fileId, session, flowFile);
+            session.transfer(flowFile, REL_SUCCESS);
+        } catch (final BoxAPIResponseException e) {
+            flowFile = session.putAttribute(flowFile, ERROR_MESSAGE, 
e.getMessage());
+            flowFile = session.putAttribute(flowFile, ERROR_CODE, 
String.valueOf(e.getResponseCode()));
+
+            if (e.getResponseCode() == 404) {
+                getLogger().warn("Box file with ID {} was not found.", fileId);
+                session.transfer(flowFile, REL_NOT_FOUND);
+            } else {
+                getLogger().error("Failed to retrieve Box file collaborations 
for file [{}]", fileId, e);
+                session.transfer(flowFile, REL_FAILURE);
+            }
+        } catch (final BoxAPIException e) {
+            flowFile = session.putAttribute(flowFile, ERROR_MESSAGE, 
e.getMessage());
+            flowFile = session.putAttribute(flowFile, ERROR_CODE, 
String.valueOf(e.getResponseCode()));
+            flowFile = session.penalize(flowFile);
+            session.transfer(flowFile, REL_FAILURE);
+        }
+    }
+
+    /**
+     * Creates a BoxFile instance for a given file ID.
+     *
+     * @param fileId the ID of the file
+     * @return BoxFile instance
+     */
+    protected BoxFile getBoxFile(final String fileId) {
+        return new BoxFile(boxAPIConnection, fileId);
+    }
+
+    private FlowFile fetchCollaborations(final String fileId,
+                                         final ProcessSession session,
+                                         final FlowFile flowFile) {
+        final BoxFile boxFile = getBoxFile(fileId);
+        final Iterable<BoxCollaboration.Info> collaborations = 
boxFile.getAllFileCollaborations();
+
+        final List<String> statusTypes = List.of(
+                "accepted.users", "accepted.groups",
+                "pending.users", "pending.groups",
+                "rejected.users", "rejected.groups"
+        );
+
+        final Map<String, List<String>> collabIdMap = statusTypes.stream()
+                .collect(Collectors.toMap(key -> key, key -> new 
ArrayList<>()));
+
+        final Map<String, List<String>> collabEmailMap = statusTypes.stream()
+                .collect(Collectors.toMap(key -> key, key -> new 
ArrayList<>()));
+
+        int count = 0;
+        for (final BoxCollaboration.Info collabInfo : collaborations) {
+            count++;
+
+            boolean isUser = 
collabInfo.getAccessibleBy().getType().equals(BoxCollaborator.CollaboratorType.USER);
+            final String collabId = collabInfo.getAccessibleBy().getID();
+            final String status = 
collabInfo.getStatus().toString().toLowerCase();
+            final String type = isUser ? "users" : "groups";
+            final String key = status + "." + type;
+
+            collabIdMap.get(key).add(collabId);
+
+            final String email = collabInfo.getAccessibleBy().getLogin();
+            if (email != null) {
+                collabEmailMap.get(key).add(email);
+            }
+        }
+
+        final Map<String, String> attributes = new HashMap<>();
+        attributes.put(ID, fileId);
+        attributes.put("box.collaborations.count", String.valueOf(count));
+
+        collabIdMap.forEach((key, value) ->
+                addAttributeIfNotEmpty(attributes, "box.collaborations." + key 
+ ".ids", value));
+
+        collabEmailMap.forEach((key, value) ->
+                addAttributeIfNotEmpty(attributes, "box.collaborations." + key 
+ ".emails", value));
+
+        return session.putAllAttributes(flowFile, attributes);
+    }
+
+    private void addAttributeIfNotEmpty(final Map<String, String> attributes,
+                                        final String key,
+                                        final List<String> values) {
+        if (values != null && !values.isEmpty()) {
+            attributes.put(key, String.join(",", values));
+        }
+    }
+}
\ No newline at end of file
diff --git 
a/nifi-extension-bundles/nifi-box-bundle/nifi-box-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor
 
b/nifi-extension-bundles/nifi-box-bundle/nifi-box-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor
index 23954f2a85..bf46003c94 100644
--- 
a/nifi-extension-bundles/nifi-box-bundle/nifi-box-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor
+++ 
b/nifi-extension-bundles/nifi-box-bundle/nifi-box-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor
@@ -12,6 +12,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+org.apache.nifi.processors.box.GetBoxFileCollaborators
 org.apache.nifi.processors.box.ListBoxFile
 org.apache.nifi.processors.box.FetchBoxFile
 org.apache.nifi.processors.box.FetchBoxFileInfo
diff --git 
a/nifi-extension-bundles/nifi-box-bundle/nifi-box-processors/src/test/java/org/apache/nifi/processors/box/GetBoxFileCollaboratorsTest.java
 
b/nifi-extension-bundles/nifi-box-bundle/nifi-box-processors/src/test/java/org/apache/nifi/processors/box/GetBoxFileCollaboratorsTest.java
new file mode 100644
index 0000000000..0e374ca33d
--- /dev/null
+++ 
b/nifi-extension-bundles/nifi-box-bundle/nifi-box-processors/src/test/java/org/apache/nifi/processors/box/GetBoxFileCollaboratorsTest.java
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.processors.box;
+
+import com.box.sdk.BoxAPIException;
+import com.box.sdk.BoxAPIResponseException;
+import com.box.sdk.BoxCollaboration;
+import com.box.sdk.BoxCollaborator;
+import com.box.sdk.BoxFile;
+import com.box.sdk.BoxGroup;
+import com.box.sdk.BoxResourceIterable;
+import com.box.sdk.BoxUser;
+import org.apache.nifi.util.MockFlowFile;
+import org.apache.nifi.util.TestRunners;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+public class GetBoxFileCollaboratorsTest extends AbstractBoxFileTest {
+    private static final String TEST_USER_ID_1 = "user1";
+    private static final String TEST_USER_ID_2 = "user2";
+    private static final String TEST_USER_ID_3 = "user3";
+    private static final String TEST_GROUP_ID_1 = "group1";
+    private static final String TEST_GROUP_ID_2 = "group2";
+    private static final String TEST_USER_EMAIL_1 = "[email protected]";
+    private static final String TEST_USER_EMAIL_2 = "[email protected]";
+    private static final String TEST_USER_EMAIL_3 = "[email protected]";
+    private static final String TEST_GROUP_EMAIL_1 = "[email protected]";
+    private static final String TEST_GROUP_EMAIL_2 = "[email protected]";
+
+    @Mock
+    BoxFile mockBoxFile;
+
+    @Mock
+    BoxCollaboration.Info mockCollabInfo1;
+
+    @Mock
+    BoxCollaboration.Info mockCollabInfo2;
+
+    @Mock
+    BoxCollaboration.Info mockCollabInfo3;
+
+    @Mock
+    BoxCollaboration.Info mockCollabInfo4;
+
+    @Mock
+    BoxCollaboration.Info mockCollabInfo5;
+
+    @Mock
+    BoxUser.Info mockUserInfo1;
+
+    @Mock
+    BoxUser.Info mockUserInfo2;
+
+    @Mock
+    BoxUser.Info mockUserInfo3;
+
+    @Mock
+    BoxGroup.Info mockGroupInfo1;
+
+    @Mock
+    BoxGroup.Info mockGroupInfo2;
+
+    @Mock
+    BoxResourceIterable<BoxCollaboration.Info> mockCollabIterable;
+
+    @Override
+    @BeforeEach
+    void setUp() throws Exception {
+        final GetBoxFileCollaborators testSubject = new 
GetBoxFileCollaborators() {
+            @Override
+            protected BoxFile getBoxFile(String fileId) {
+                return mockBoxFile;
+            }
+        };
+
+        testRunner = TestRunners.newTestRunner(testSubject);
+        super.setUp();
+    }
+
+    @Test
+    void testGetCollaborationsFromFlowFileAttribute() {
+        testRunner.setProperty(GetBoxFileCollaborators.FILE_ID, "${box.id}");
+        final MockFlowFile inputFlowFile = new MockFlowFile(0);
+        final Map<String, String> attributes = new HashMap<>();
+        attributes.put(BoxFileAttributes.ID, TEST_FILE_ID);
+        inputFlowFile.putAttributes(attributes);
+
+        setupMockCollaborations();
+
+        testRunner.enqueue(inputFlowFile);
+        testRunner.run();
+
+        
testRunner.assertAllFlowFilesTransferred(GetBoxFileCollaborators.REL_SUCCESS, 
1);
+        final List<MockFlowFile> flowFiles = 
testRunner.getFlowFilesForRelationship(GetBoxFileCollaborators.REL_SUCCESS);
+        final MockFlowFile flowFilesFirst = flowFiles.getFirst();
+
+        flowFilesFirst.assertAttributeEquals("box.collaborations.count", "5");
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.accepted.users.ids", 
TEST_USER_ID_1 + "," + TEST_USER_ID_2);
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.accepted.groups.ids", 
TEST_GROUP_ID_1);
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.pending.users.ids", 
TEST_USER_ID_3);
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.pending.groups.ids", 
TEST_GROUP_ID_2);
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.accepted.users.emails",
 TEST_USER_EMAIL_1 + "," + TEST_USER_EMAIL_2);
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.accepted.groups.emails",
 TEST_GROUP_EMAIL_1);
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.pending.users.emails", 
TEST_USER_EMAIL_3);
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.pending.groups.emails",
 TEST_GROUP_EMAIL_2);
+    }
+
+    @Test
+    void testGetCollaborationsFromProperty() {
+        testRunner.setProperty(GetBoxFileCollaborators.FILE_ID, TEST_FILE_ID);
+
+        setupMockCollaborations();
+
+        final MockFlowFile inputFlowFile = new MockFlowFile(0);
+        testRunner.enqueue(inputFlowFile);
+        testRunner.run();
+
+        
testRunner.assertAllFlowFilesTransferred(GetBoxFileCollaborators.REL_SUCCESS, 
1);
+        final List<MockFlowFile> flowFiles = 
testRunner.getFlowFilesForRelationship(GetBoxFileCollaborators.REL_SUCCESS);
+        final MockFlowFile flowFilesFirst = flowFiles.getFirst();
+
+        flowFilesFirst.assertAttributeEquals("box.collaborations.count", "5");
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.accepted.users.ids", 
TEST_USER_ID_1 + "," + TEST_USER_ID_2);
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.accepted.groups.ids", 
TEST_GROUP_ID_1);
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.pending.users.ids", 
TEST_USER_ID_3);
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.pending.groups.ids", 
TEST_GROUP_ID_2);
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.accepted.users.emails",
 TEST_USER_EMAIL_1 + "," + TEST_USER_EMAIL_2);
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.accepted.groups.emails",
 TEST_GROUP_EMAIL_1);
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.pending.users.emails", 
TEST_USER_EMAIL_3);
+        
flowFilesFirst.assertAttributeEquals("box.collaborations.pending.groups.emails",
 TEST_GROUP_EMAIL_2);
+    }
+
+    @Test
+    void testApiErrorHandling() {
+        testRunner.setProperty(GetBoxFileCollaborators.FILE_ID, TEST_FILE_ID);
+
+        final BoxAPIResponseException mockException = new 
BoxAPIResponseException("API Error", 404, "Box File Not Found", null);
+        when(mockBoxFile.getAllFileCollaborations()).thenThrow(mockException);
+
+        final MockFlowFile inputFlowFile = new MockFlowFile(0);
+        testRunner.enqueue(inputFlowFile);
+        testRunner.run();
+
+        
testRunner.assertAllFlowFilesTransferred(GetBoxFileCollaborators.REL_NOT_FOUND, 
1);
+        final List<MockFlowFile> flowFiles = 
testRunner.getFlowFilesForRelationship(GetBoxFileCollaborators.REL_NOT_FOUND);
+        final MockFlowFile flowFilesFirst = flowFiles.getFirst();
+        flowFilesFirst.assertAttributeEquals(BoxFileAttributes.ERROR_CODE, 
"404");
+        flowFilesFirst.assertAttributeEquals(BoxFileAttributes.ERROR_MESSAGE, 
"API Error [404]");
+    }
+
+    @Test
+    void testBoxApiExceptionHandling() {
+        testRunner.setProperty(GetBoxFileCollaborators.FILE_ID, TEST_FILE_ID);
+
+        final BoxAPIException mockException = new BoxAPIException("General API 
Error:", 500, "Unexpected Error");
+        when(mockBoxFile.getAllFileCollaborations()).thenThrow(mockException);
+
+        final MockFlowFile inputFlowFile = new MockFlowFile(0);
+        testRunner.enqueue(inputFlowFile);
+        testRunner.run();
+
+        
testRunner.assertAllFlowFilesTransferred(GetBoxFileCollaborators.REL_FAILURE, 
1);
+        final List<MockFlowFile> flowFiles = 
testRunner.getFlowFilesForRelationship(GetBoxFileCollaborators.REL_FAILURE);
+        final MockFlowFile flowFilesFirst = flowFiles.getFirst();
+
+        flowFilesFirst.assertAttributeEquals(BoxFileAttributes.ERROR_CODE, 
"500");
+        flowFilesFirst.assertAttributeEquals(BoxFileAttributes.ERROR_MESSAGE, 
"General API Error:\nUnexpected Error");
+    }
+
+    private void setupMockCollaborations() {
+        setupCollaborator(mockCollabInfo1, mockUserInfo1, 
BoxCollaborator.CollaboratorType.USER, TEST_USER_ID_1, 
BoxCollaboration.Status.ACCEPTED);
+        setupCollaborator(mockCollabInfo2, mockUserInfo2, 
BoxCollaborator.CollaboratorType.USER, TEST_USER_ID_2, 
BoxCollaboration.Status.ACCEPTED);
+        setupCollaborator(mockCollabInfo3, mockGroupInfo1, 
BoxCollaborator.CollaboratorType.GROUP, TEST_GROUP_ID_1, 
BoxCollaboration.Status.ACCEPTED);
+        setupCollaborator(mockCollabInfo4, mockUserInfo3, 
BoxCollaborator.CollaboratorType.USER, TEST_USER_ID_3, 
BoxCollaboration.Status.PENDING);
+        setupCollaborator(mockCollabInfo5, mockGroupInfo2, 
BoxCollaborator.CollaboratorType.GROUP, TEST_GROUP_ID_2, 
BoxCollaboration.Status.PENDING);
+
+        when(mockCollabIterable.iterator()).thenReturn(
+                List.of(mockCollabInfo1, mockCollabInfo2, mockCollabInfo3, 
mockCollabInfo4, mockCollabInfo5).iterator()
+        );
+
+        
when(mockBoxFile.getAllFileCollaborations()).thenReturn(mockCollabIterable);
+    }
+
+    private void setupCollaborator(final BoxCollaboration.Info collabInfo,
+                                   final BoxCollaborator.Info collaboratorInfo,
+                                   final BoxCollaborator.CollaboratorType type,
+                                   final String id,
+                                   final BoxCollaboration.Status status) {
+        when(collabInfo.getAccessibleBy()).thenReturn(collaboratorInfo);
+        when(collaboratorInfo.getType()).thenReturn(type);
+        when(collaboratorInfo.getID()).thenReturn(id);
+        when(collabInfo.getStatus()).thenReturn(status);
+
+        final Map<String, String> userEmails = Map.of(
+                TEST_USER_ID_1, TEST_USER_EMAIL_1,
+                TEST_USER_ID_2, TEST_USER_EMAIL_2,
+                TEST_USER_ID_3, TEST_USER_EMAIL_3
+        );
+
+        Map<String, String> groupEmails = Map.of(
+                TEST_GROUP_ID_1, TEST_GROUP_EMAIL_1,
+                TEST_GROUP_ID_2, TEST_GROUP_EMAIL_2
+        );
+        String email = null;
+        if (type.equals(BoxCollaborator.CollaboratorType.USER)) {
+            email = userEmails.getOrDefault(id, null);
+        } else if (type.equals(BoxCollaborator.CollaboratorType.GROUP)) {
+            email = groupEmails.getOrDefault(id, null);
+        }
+
+        when(collaboratorInfo.getLogin()).thenReturn(email);
+    }
+}
\ No newline at end of file

Reply via email to