/* * Licensed to DuraSpace under one or more contributor license agreements. * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. * * DuraSpace 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.fcrepo.kernel.modeshape.utils; import static org.fcrepo.kernel.api.FedoraTypes.CONTENT_DIGEST; import static org.fcrepo.kernel.api.FedoraTypes.CONTENT_SIZE; import static org.fcrepo.kernel.api.utils.ContentDigest.DIGEST_ALGORITHM.SHA1; import static org.fcrepo.kernel.modeshape.FedoraJcrConstants.JCR_CREATEDBY; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.modeshape.jcr.api.JcrConstants.JCR_DATA; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.lang.reflect.Field; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import javax.jcr.Binary; import javax.jcr.Node; import javax.jcr.Property; import javax.jcr.PropertyIterator; import javax.jcr.RepositoryException; import javax.jcr.Value; import org.fcrepo.kernel.api.utils.ContentDigest; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; /** * Helpers to make writing unit tests easier (by providing some generic * mocks) * @author fasseg * @since May 2, 2013 */ public abstract class TestHelpers { private static final SecureRandom GARBAGE_GENERATOR = new SecureRandom( "G4RbAG3".getBytes()); public static Node getContentNodeMock(final Node mock, final int size) { return getContentNodeMock(mock, randomData(size)); } public static Node getContentNodeMock(final Node mock, final String content) { return getContentNodeMock(mock, content.getBytes()); } public static Node getContentNodeMock(final Node mock, final byte[] content) { final long size = content.length; final String digest = checksumString(content); final Value digestValue = mock(Value.class); final Value[] digestArray = {digestValue}; final String digestType = SHA1.algorithm; final Property mockFedoraSize = mock(Property.class); final Property mockProp = mock(Property.class); final Property mockDigest = mock(Property.class); final Property mockDigestType = mock(Property.class); final Property mockCreated = mock(Property.class); final Binary mockBin = mock(Binary.class); try { when(mockFedoraSize.getLong()).thenReturn(size); when(mockBin.getSize()).thenReturn(size); when(mockBin.getStream()).thenAnswer(new Answer<InputStream>() { @Override public InputStream answer(final InvocationOnMock inv) { return new ByteArrayInputStream(content); } }); when(mockProp.getBinary()).thenReturn(mockBin); when(mockDigest.getValues()).thenReturn(digestArray); when(mockDigestType.getString()).thenReturn(digestType); when(mock.hasProperty(JCR_DATA)).thenReturn(true); when(mock.hasProperty(CONTENT_SIZE)).thenReturn(true); when(mock.hasProperty(CONTENT_DIGEST)).thenReturn(true); when(mock.hasProperty(JCR_CREATEDBY)).thenReturn(true); when(mock.getProperty(JCR_DATA)).thenReturn(mockProp); when(mock.getProperty(CONTENT_SIZE)).thenReturn(mockFedoraSize); when(mock.getProperty(CONTENT_DIGEST)).thenReturn(mockDigest); when(mockDigest.isMultiple()).thenReturn(true); when(digestValue.getString()).thenReturn(digest); when(mock.getProperty(JCR_CREATEDBY)).thenReturn(mockCreated); } catch (final RepositoryException e) { } // shhh return mock; } public static String checksumString(final String content) { return checksumString(content.getBytes()); } public static String checksumString(final byte[] content) { try { final MessageDigest d = MessageDigest.getInstance(SHA1.algorithm); final byte[] digest = d.digest(content); return ContentDigest.asURI(SHA1.algorithm, digest).toString(); } catch (final NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } @SuppressWarnings("unchecked") public static PropertyIterator getPropertyIterator(final int numValues, final long size) { final PropertyIterator mock = mock(PropertyIterator.class); final Property mockProp = mock(Property.class); try { when(mockProp.isMultiple()).thenReturn(numValues > 1); if (numValues != 1) { final Value[] values = new Value[numValues]; for (int i = 0; i < numValues; i++) { final Value mockVal = mock(Value.class); final Binary mockBin = mock(Binary.class); when(mockVal.getBinary()).thenReturn(mockBin); when(mockBin.getSize()).thenReturn(size); values[i] = mockVal; } when(mockProp.getValues()).thenReturn(values); } else { final Binary mockBin = mock(Binary.class); when(mockBin.getSize()).thenReturn(size); when(mockProp.getBinary()).thenReturn(mockBin); } } catch (final RepositoryException e) { } // shhh when(mock.getSize()).thenReturn(1L); when(mock.hasNext()).thenReturn(true, false); when(mock.nextProperty()).thenReturn(mockProp).thenThrow( IndexOutOfBoundsException.class); return mock; } public static byte[] randomData(final int byteLength) { final byte[] bytes = new byte[byteLength]; GARBAGE_GENERATOR.nextBytes(bytes); return bytes; } /** * Set a field via reflection * * @param parent the owner object of the field * @param name the name of the field * @param obj the value to set */ public static void setField(final Object parent, final String name, final Object obj) { /* check the parent class too if the field could not be found */ try { final Field f = findField(parent.getClass(), name); f.setAccessible(true); f.set(parent, obj); } catch (final Exception e) { e.printStackTrace(); } } private static Field findField(final Class<?> clazz, final String name) throws NoSuchFieldException { for (final Field f : clazz.getDeclaredFields()) { if (f.getName().equals(name)) { return f; } } if (clazz.getSuperclass() == null) { throw new NoSuchFieldException("Field " + name + " could not be found"); } return findField(clazz.getSuperclass(), name); } }