de.fhg.iais.cortex.rest.resources.BinaryResourceTest.java Source code

Java tutorial

Introduction

Here is the source code for de.fhg.iais.cortex.rest.resources.BinaryResourceTest.java

Source

package de.fhg.iais.cortex.rest.resources;

/******************************************************************************
 * Copyright 2011 (c) Fraunhofer IAIS Netmedia  http://www.iais.fraunhofer.de *
 * ************************************************************************** *
 * Licensed 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.                                             *
 ******************************************************************************/

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.stub;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import junit.framework.Assert;

import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.Mockito;

import com.google.common.collect.Lists;

import de.fhg.iais.cortex.model.aip.AipObject;
import de.fhg.iais.cortex.rest.server.types.RestErrorType;
import de.fhg.iais.cortex.search.SolrFields;
import de.fhg.iais.cortex.search.types.Facet;
import de.fhg.iais.cortex.search.types.FacetValue;
import de.fhg.iais.cortex.search.types.Query;
import de.fhg.iais.cortex.search.types.SearchResults;
import de.fhg.iais.cortex.services.IAccessService;
import de.fhg.iais.cortex.services.ISearchService;
import de.fhg.iais.cortex.services.authentication.RoleProvider;
import de.fhg.iais.cortex.services.authentication.types.Role;
import de.fhg.iais.cortex.services.authentication.types.Role.Profile;
import de.fhg.iais.cortex.storage.Binary;
import de.fhg.iais.cortex.storage.exception.ItemNotFoundException;

public class BinaryResourceTest {

    private static final String INFO_OBJECT2 = "<infoobject><name>Test2</name></infoobject>";
    private static final String BLACKLIST_ID = "0001000";
    private BinaryResource binaryResource;

    private HttpHeaders headers;

    private IAccessService mockAccessService;
    private ISearchService mockSearchService;
    private RoleProvider mockRoleProvider;

    @Before
    public void setUp() throws Exception {
        createMocks();

        this.binaryResource = new BinaryResource(this.mockAccessService, this.mockSearchService,
                this.mockRoleProvider, BLACKLIST_ID);
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testSecurityCheck() {
        HttpHeaders headers = mock(HttpHeaders.class);
        HttpServletRequest request = mock(HttpServletRequest.class);

        Role roleRestricted = new Role();
        roleRestricted.setProfile(Profile.RESTRICTED_READ);

        Role roleRead = new Role();
        roleRead.setProfile(Profile.READ);

        Role roleFull = new Role();
        roleFull.setProfile(Profile.FULL);

        this.mockRoleProvider = mock(RoleProvider.class);

        //        AipObject aip = mock(AipObject.class);
        //        stub(aip.isNewFormat()).toReturn(true).toReturn(true).toReturn(false).toReturn(false);
        //        stub(aip.getObjectForPathOrNull(NewSchemaPaths.PATH_PROVIDER_ID.path(), String.class))
        //            .toReturn(BLACKLIST_ID)
        //            .toReturn("0002000")
        //            .toReturn(BLACKLIST_ID)
        //            .toReturn("0002000");
        //
        //        stub(this.mockAccessService.getAip(Matchers.anyString())).toReturn(aip);

        Facet providerBlacklistIdFacet = new Facet(SolrFields.PROVIDER_ID);
        providerBlacklistIdFacet.addFacetValue(new FacetValue(BLACKLIST_ID, 1));

        SearchResults resultBlacklistId = new SearchResults();
        resultBlacklistId.setFacets(new Facet[] { providerBlacklistIdFacet });

        Facet providerOtherIdFacet = new Facet(SolrFields.PROVIDER_ID);
        providerOtherIdFacet.addFacetValue(new FacetValue("0002000", 1));

        SearchResults resultOtherId = new SearchResults();
        resultOtherId.setFacets(new Facet[] { providerOtherIdFacet });

        Mockito.when(this.mockSearchService.searchFaceted(Matchers.any(Query.class))).thenReturn(resultBlacklistId)
                .thenReturn(resultOtherId).thenReturn(resultBlacklistId).thenReturn(resultOtherId);

        this.binaryResource = new BinaryResource(this.mockAccessService, this.mockSearchService,
                this.mockRoleProvider, BLACKLIST_ID);

        // Check access for blacklisted providers and security level lesser than FULL
        stub(this.mockRoleProvider.get()).toReturn(roleRestricted).toReturn(roleRead);

        Response response = this.binaryResource.getBinary(headers, "1", "test.txt", request);
        Assert.assertTrue(response.getStatus() == 403);

        response = this.binaryResource.getBinary(headers, "1", "test.txt", request);
        Assert.assertTrue(response.getStatus() == 200);

        response = this.binaryResource.getBinary(headers, "1", "test.txt", request);
        Assert.assertTrue(response.getStatus() == 200);

        response = this.binaryResource.getBinary(headers, "1", "test.txt", request);
        Assert.assertTrue(response.getStatus() == 200);

        // Check blacklisted provider but full security level
        stub(this.mockRoleProvider.get()).toReturn(roleFull);

        //        stub(aip.isNewFormat()).toReturn(true).toReturn(true).toReturn(false).toReturn(false);
        //        stub(aip.getObjectForPathOrNull(NewSchemaPaths.PATH_PROVIDER_ID.path(), String.class))
        //            .toReturn(BLACKLIST_ID)
        //            .toReturn("0002000")
        //            .toReturn(BLACKLIST_ID)
        //            .toReturn("0002000");
        Mockito.when(this.mockSearchService.searchFaceted(Matchers.any(Query.class))).thenReturn(resultBlacklistId)
                .thenReturn(resultOtherId).thenReturn(resultBlacklistId).thenReturn(resultOtherId);

        response = this.binaryResource.getBinary(headers, "1", "test.txt", request);
        Assert.assertTrue(response.getStatus() == 200);

        response = this.binaryResource.getBinary(headers, "1", "test.txt", request);
        Assert.assertTrue(response.getStatus() == 200);

        response = this.binaryResource.getBinary(headers, "1", "test.txt", request);
        Assert.assertTrue(response.getStatus() == 200);

        response = this.binaryResource.getBinary(headers, "1", "test.txt", request);
        Assert.assertTrue(response.getStatus() == 200);
    }

    @Test
    public void testGetBinaryExceptions() throws IOException {
        HttpServletRequest request = mock(HttpServletRequest.class);

        stub(this.headers.getRequestHeader("Range")).toReturn(Lists.asList("bytes=499-0", new String[] {}))
                .toReturn(Lists.asList("bytes=0-499", new String[] {}))
                .toReturn(Lists.asList("btyes=", new String[] {})).toReturn(null);
        stub(this.headers.getRequestHeader("If-Range")).toReturn(Lists.asList("", new String[] { "", "", "" }));

        Mockito.when(this.mockSearchService.searchFaceted(Matchers.any(Query.class)))
                .thenReturn(new SearchResults());
        Mockito.when(this.mockRoleProvider.get()).thenReturn(new Role());

        Response response = this.binaryResource.getBinary(this.headers, "1", "test.txt", request);

        Assert.assertTrue(response.getStatus() == 416);

        response = this.binaryResource.getBinary(this.headers, "1", "test.txt", request);

        Assert.assertTrue(response.getStatus() == 416);

        response = this.binaryResource.getBinary(this.headers, "1", "test.txt", request);

        Assert.assertTrue(response.getStatus() == 416);

        response = this.binaryResource.getBinary(this.headers, "1", "test.txt", request);

        Assert.assertTrue(response.getStatus() == 200);
        Assert.assertEquals("TestBinary", IOUtils.toString((ByteArrayInputStream) response.getEntity()));

        response = this.binaryResource.getBinary(this.headers, "3", "fail.xml", request); //NOSONAR

        RestErrorType expectedError = new RestErrorType("IndexOutOfBoundsException", null, "");
        RestErrorType actualError = (RestErrorType) response.getEntity();

        Assert.assertEquals(500, response.getStatus());
        Assert.assertEquals(expectedError, actualError);
    }

    // Enable again when byte range requests are back in the game
    @Ignore
    @Test
    public void testGetBinary() throws IOException {
        HttpServletRequest request = mock(HttpServletRequest.class);

        stub(this.headers.getRequestHeader("Range")).toReturn(Lists.asList("bytes=0-4", new String[] {}))
                .toReturn(Lists.asList("bytes=5-9", new String[] {}));

        Mockito.when(this.mockSearchService.searchFaceted(Matchers.any(Query.class)))
                .thenReturn(new SearchResults());
        Mockito.when(this.mockRoleProvider.get()).thenReturn(new Role());

        Response binary = this.binaryResource.getBinary(this.headers, "1", "test.txt", request);
        String result = IOUtils.toString((InputStream) binary.getEntity());
        assertEquals("TestB", result);

        binary = this.binaryResource.getBinary(this.headers, "3", "test.txt", request);
        result = IOUtils.toString((InputStream) binary.getEntity());
        assertEquals("inary", result);

        stub(this.headers.getRequestHeader("If-Range"))
                .toReturn(Lists.asList("\"c5e62cce0a4240bbb04b5062cb4ad8d2\"", new String[] { "", "", "" }));

        binary = this.binaryResource.getBinary(this.headers, "4", "test.txt", request);
        result = IOUtils.toString((InputStream) binary.getEntity());
        assertEquals("inary", result);

        binary = this.binaryResource.getBinary(this.headers, "4", "test.txt", request);
        assertEquals(416, binary.getStatus());

        stub(this.headers.getRequestHeader("If-Range"))
                .toReturn(Lists.asList("\"UnknownTag\"", new String[] { "", "", "" }));

        binary = this.binaryResource.getBinary(this.headers, "4", "test.txt", request);
        assertEquals(Status.PRECONDITION_FAILED.getStatusCode(), binary.getStatus());
    }

    @Test
    public void testGetNotExistingBinary() {
        HttpServletRequest request = mock(HttpServletRequest.class);

        Mockito.when(this.mockSearchService.searchFaceted(Matchers.any(Query.class)))
                .thenReturn(new SearchResults());
        Mockito.when(this.mockRoleProvider.get()).thenReturn(new Role());

        Response response = this.binaryResource.getBinary(this.headers, "2", "fail.xml", request);

        RestErrorType expectedError = new RestErrorType("ItemNotFoundException",
                "Item: 2 / fail.xml not found: Binary not found", "");
        RestErrorType actualError = (RestErrorType) response.getEntity();

        Assert.assertEquals(404, response.getStatus());
        Assert.assertEquals(expectedError, actualError);

    }

    private void createMocks() {
        this.headers = mock(HttpHeaders.class);
        this.mockAccessService = mock(IAccessService.class);
        stub(this.mockAccessService.getBinary("1", "test.txt")).toReturn(
                new Binary(new ByteArrayInputStream("TestBinary".getBytes()), "TestBinary".getBytes().length));
        stub(this.mockAccessService.getBinary("3", "test.txt")).toReturn(
                new Binary(new ByteArrayInputStream("TestBinary".getBytes()), "TestBinary".getBytes().length));
        stub(this.mockAccessService.getBinary("4", "test.txt")).toReturn(
                new Binary(new ByteArrayInputStream("TestBinary".getBytes()), "TestBinary".getBytes().length));
        stub(this.mockAccessService.getBinary("2", "fail.xml"))
                .toThrow(new ItemNotFoundException("Item: 2 / fail.xml not found: Binary not found"));
        stub(this.mockAccessService.getBinary("3", "fail.xml")).toThrow(new IndexOutOfBoundsException());

        stub(this.mockAccessService.getAip(Matchers.anyString())).toReturn(new AipObject());

        this.mockRoleProvider = mock(RoleProvider.class);
        this.mockSearchService = mock(ISearchService.class);

    }
}