com.netflix.genie.web.resources.handlers.GenieResourceHttpRequestHandlerUnitTests.java Source code

Java tutorial

Introduction

Here is the source code for com.netflix.genie.web.resources.handlers.GenieResourceHttpRequestHandlerUnitTests.java

Source

/*
 *
 *  Copyright 2016 Netflix, Inc.
 *
 *     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.
 *
 */
package com.netflix.genie.web.resources.handlers;

import com.google.common.collect.Lists;
import com.netflix.genie.core.jobs.JobConstants;
import com.netflix.genie.test.categories.UnitTest;
import com.netflix.genie.web.resources.writers.DirectoryWriter;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.mockito.Mockito;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.UUID;

/**
 * Unit tests for the GenieResourceHttpRequestHandler class.
 *
 * @author tgianos
 * @since 3.0.0
 */
@Category(UnitTest.class)
public class GenieResourceHttpRequestHandlerUnitTests {

    private DirectoryWriter directoryWriter;
    private GenieResourceHttpRequestHandler handler;
    private Resource location;

    /**
     * Setup for the tests.
     */
    @Before
    public void setup() {
        this.directoryWriter = Mockito.mock(DirectoryWriter.class);
        this.handler = new GenieResourceHttpRequestHandler(this.directoryWriter);
        this.location = Mockito.mock(Resource.class);

        final List<Resource> locations = Lists.newArrayList(this.location);
        this.handler.setLocations(locations);
    }

    /**
     * Make sure we can't handle any requests for resources without a resource location to look in.
     *
     * @throws ServletException on error
     * @throws IOException      on error
     */
    @Test(expected = IllegalStateException.class)
    public void cantHandleRequestWithOutAnyLocations() throws ServletException, IOException {
        this.handler.setLocations(Lists.newArrayList());
        this.handler.handleRequest(Mockito.mock(HttpServletRequest.class), Mockito.mock(HttpServletResponse.class));
    }

    /**
     * Make sure we can't handle any requests for resources with more than one resource available.
     *
     * @throws ServletException on error
     * @throws IOException      on error
     */
    @Test(expected = IllegalStateException.class)
    public void cantHandleRequestWithTooManyLocations() throws ServletException, IOException {
        this.handler.setLocations(Lists.newArrayList(Mockito.mock(Resource.class), Mockito.mock(Resource.class)));
        this.handler.handleRequest(Mockito.mock(HttpServletRequest.class), Mockito.mock(HttpServletResponse.class));
    }

    /**
     * Make sure we can't handle the HTTP request for a resource if we don't have the proper attribute in the request.
     *
     * @throws ServletException on error
     * @throws IOException      on error
     */
    @Test(expected = IllegalStateException.class)
    public void cantHandleRequestWithoutHandlerMappingAttribute() throws ServletException, IOException {
        final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
        final HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
        Mockito.when(request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).thenReturn(null);
        this.handler.handleRequest(request, response);
    }

    /**
     * Make sure if the resource doesn't exist we return a 404.
     *
     * @throws ServletException On any error
     * @throws IOException      On any error
     */
    @Test
    public void cantHandleRequestIfResourceDoesntExist() throws ServletException, IOException {
        final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
        final HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
        final String path = UUID.randomUUID().toString();
        Mockito.when(request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).thenReturn(path);
        final Resource resource = Mockito.mock(Resource.class);
        Mockito.when(this.location.createRelative(Mockito.eq(path))).thenReturn(resource);
        Mockito.when(resource.exists()).thenReturn(false);

        this.handler.handleRequest(request, response);

        Mockito.verify(response, Mockito.times(1)).sendError(HttpStatus.NOT_FOUND.value());
    }

    /**
     * Make sure if the resource isn't a directory it's sent to super.
     * <p>
     * Note: This doesn't actually test returning a file as we leverage Spring's implementation
     * which we assume is working.
     *
     * @throws ServletException On any error
     * @throws IOException      On any error
     */
    @Test
    public void canHandleRequestForFile() throws ServletException, IOException {
        final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
        final HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
        final String path = UUID.randomUUID().toString();
        Mockito.when(request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).thenReturn(path);
        final Resource resource = Mockito.mock(Resource.class);
        Mockito.when(this.location.createRelative(Mockito.eq(path))).thenReturn(resource);
        Mockito.when(resource.exists()).thenReturn(true);
        final File file = Mockito.mock(File.class);
        Mockito.when(resource.getFile()).thenReturn(file);
        Mockito.when(file.isDirectory()).thenReturn(false);

        this.handler.handleRequest(request, response);

        Mockito.verify(response, Mockito.times(1)).sendError(HttpStatus.NOT_FOUND.value());
    }

    /**
     * Make sure if the resource is a directory as HTML it's handled properly.
     *
     * @throws Exception On any error
     */
    @Test
    public void canHandleRequestForDirectoryHtml() throws Exception {
        final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
        final HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
        final String path = UUID.randomUUID().toString();
        Mockito.when(request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).thenReturn(path);
        Mockito.when(request.getHeader(HttpHeaders.ACCEPT)).thenReturn(MediaType.TEXT_HTML_VALUE);
        final String forwardedUrl = UUID.randomUUID().toString();
        Mockito.when(request.getHeader(JobConstants.GENIE_FORWARDED_FROM_HEADER)).thenReturn(forwardedUrl);
        final Resource resource = Mockito.mock(Resource.class);
        Mockito.when(this.location.createRelative(Mockito.eq(path))).thenReturn(resource);
        Mockito.when(resource.exists()).thenReturn(true);
        final File file = Mockito.mock(File.class);
        Mockito.when(resource.getFile()).thenReturn(file);
        Mockito.when(file.isDirectory()).thenReturn(true);

        final String html = UUID.randomUUID().toString();

        Mockito.when(this.directoryWriter.toHtml(Mockito.eq(file), Mockito.eq(forwardedUrl), Mockito.eq(false)))
                .thenReturn(html);

        final ServletOutputStream os = Mockito.mock(ServletOutputStream.class);
        Mockito.when(response.getOutputStream()).thenReturn(os);

        this.handler.handleRequest(request, response);

        Mockito.verify(response, Mockito.times(1)).setContentType(MediaType.TEXT_HTML_VALUE);
        Mockito.verify(response, Mockito.times(1)).getOutputStream();
        Mockito.verify(this.directoryWriter, Mockito.times(1)).toHtml(Mockito.eq(file), Mockito.eq(forwardedUrl),
                Mockito.eq(false));
        Mockito.verify(os, Mockito.times(1)).write(html.getBytes(Charset.forName("UTF-8")));
    }

    /**
     * Make sure if the resource is a directory as JSON it's handled properly.
     *
     * @throws Exception On any error
     */
    @Test
    public void canHandleRequestForDirectoryJson() throws Exception {
        final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
        final HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
        final String path = UUID.randomUUID().toString();
        Mockito.when(request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).thenReturn(path);
        Mockito.when(request.getHeader(HttpHeaders.ACCEPT)).thenReturn(null);
        final String requestUrl = UUID.randomUUID().toString();
        Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer(requestUrl));
        final Resource resource = Mockito.mock(Resource.class);
        Mockito.when(this.location.createRelative(Mockito.eq(path))).thenReturn(resource);
        Mockito.when(resource.exists()).thenReturn(true);
        final File file = Mockito.mock(File.class);
        Mockito.when(resource.getFile()).thenReturn(file);
        Mockito.when(file.isDirectory()).thenReturn(true);

        final String html = UUID.randomUUID().toString();

        Mockito.when(this.directoryWriter.toJson(Mockito.eq(file), Mockito.eq(requestUrl), Mockito.eq(false)))
                .thenReturn(html);

        final ServletOutputStream os = Mockito.mock(ServletOutputStream.class);
        Mockito.when(response.getOutputStream()).thenReturn(os);

        this.handler.handleRequest(request, response);

        Mockito.verify(response, Mockito.times(1)).setContentType(MediaType.APPLICATION_JSON_VALUE);
        Mockito.verify(response, Mockito.times(1)).getOutputStream();
        Mockito.verify(this.directoryWriter, Mockito.times(1)).toJson(Mockito.eq(file), Mockito.eq(requestUrl),
                Mockito.eq(false));
        Mockito.verify(os, Mockito.times(1)).write(html.getBytes(Charset.forName("UTF-8")));
    }

    /**
     * Make sure if the resource is a directory it's handled properly until exception thrown.
     *
     * @throws Exception On any error
     */
    @Test(expected = ServletException.class)
    public void cantHandleRequestForDirectoryWhenException() throws Exception {
        final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
        final HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
        final String path = UUID.randomUUID().toString();
        Mockito.when(request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).thenReturn(path);
        Mockito.when(request.getAttribute(GenieResourceHttpRequestHandler.GENIE_JOB_IS_ROOT_DIRECTORY))
                .thenReturn(false);
        final String requestUrl = UUID.randomUUID().toString();
        Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer(requestUrl));
        final Resource resource = Mockito.mock(Resource.class);
        Mockito.when(this.location.createRelative(Mockito.eq(path))).thenReturn(resource);
        Mockito.when(resource.exists()).thenReturn(true);
        final File file = Mockito.mock(File.class);
        Mockito.when(resource.getFile()).thenReturn(file);
        Mockito.when(file.isDirectory()).thenReturn(true);

        Mockito.when(this.directoryWriter.toHtml(Mockito.eq(file), Mockito.eq(requestUrl), Mockito.eq(true)))
                .thenThrow(new Exception());

        final ServletOutputStream os = Mockito.mock(ServletOutputStream.class);
        Mockito.when(response.getOutputStream()).thenReturn(os);

        this.handler.handleRequest(request, response);
    }

    /**
     * Make sure we can use the overridden set headers method properly for large file sizes.
     *
     * @throws IOException on error
     */
    @Test
    public void canSetHeaders() throws IOException {
        final HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
        final Resource resource = Mockito.mock(Resource.class);
        final MediaType mediaType = MediaType.APPLICATION_OCTET_STREAM;

        final long justRight = (long) Integer.MAX_VALUE;
        final long tooLong = (long) Integer.MAX_VALUE + 1;
        Mockito.when(resource.contentLength()).thenReturn(justRight).thenReturn(tooLong);

        this.handler.setHeaders(response, resource, mediaType);
        this.handler.setHeaders(response, resource, null);

        Mockito.verify(response, Mockito.times(1)).setContentLengthLong(justRight);
        Mockito.verify(response, Mockito.times(1)).setContentLengthLong(tooLong);
        Mockito.verify(response, Mockito.times(1)).setContentType(Mockito.anyString());
    }
}