Package org.zanata.file

Source Code of org.zanata.file.DocumentUploadUtilTest

/*
* Copyright 2013, Red Hat, Inc. and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.zanata.file;

import static com.google.common.base.Charsets.UTF_8;
import static javax.ws.rs.core.Response.Status.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.sameInstance;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.fail;
import static org.zanata.file.DocumentUploadUtil.getInputStream;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.SQLException;

import org.apache.commons.io.IOUtils;
import org.hibernate.Session;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.zanata.common.EntityStatus;
import org.zanata.exception.ChunkUploadException;
import org.zanata.model.HDocumentUpload;
import org.zanata.model.HDocumentUploadPart;
import org.zanata.rest.DocumentFileUploadForm;
import org.zanata.service.TranslationFileService;

import com.google.common.base.Optional;
import com.google.common.io.Files;

@Test(groups = { "unit-tests" })
public class DocumentUploadUtilTest extends DocumentUploadTest {

    private static final String HASH_OF_ABCDEFGHI =
            "d41d8cd98f00b204e9800998ecf8427e";
    @Mock
    Session session;
    @Mock
    TranslationFileService translationFileService;
    @Mock
    UploadPartPersistService uploadPartPersistService;

    @Mock
    Blob partBlob0;
    @Mock
    Blob partBlob1;

    @Captor
    private ArgumentCaptor<InputStream> persistedInputStreamCaptor;

    private DocumentUploadUtil util;

    @BeforeMethod
    public void beforeEachMethod() {
        MockitoAnnotations.initMocks(this);
        seam.reset();
        seam.ignoreNonResolvable().use("identity", identity)
                .use("session", session).use("documentDAO", documentDAO)
                .use("documentUploadDAO", documentUploadDAO)
                .use("projectIterationDAO", projectIterationDAO)
                .use("translationFileServiceImpl", translationFileService)
                .use("uploadPartPersistService", uploadPartPersistService)
                .allowCycles();

        util = seam.autowire(DocumentUploadUtil.class);
    }

    public void notValidIfNotLoggedIn() {
        conf = defaultUpload().build();
        mockNotLoggedIn();
        try {
            util.failIfUploadNotValid(conf.id, conf.uploadForm);
            fail("Should throw exception if user is not logged in");
        } catch (ChunkUploadException e) {
            assertThat(e.getStatusCode(), is(UNAUTHORIZED));
            assertThat(e.getMessage(),
                    is("Valid combination of username and api-key for this "
                            + "server were not included in the request."));
        }
    }

    public void notValidIfNoFileContent() {
        conf = defaultUpload().fileStream(null).build();
        mockLoggedIn();
        try {
            util.failIfUploadNotValid(conf.id, conf.uploadForm);
            fail("Should throw exception if there is no file content");
        } catch (ChunkUploadException e) {
            assertThat(e.getStatusCode(), is(PRECONDITION_FAILED));
            assertThat(
                    e.getMessage(),
                    is("Required form parameter 'file' containing file content "
                            + "was not found."));
        }
    }

    public void notValidIfNoFileType() {
        conf = defaultUpload().fileType(null).build();
        mockLoggedIn();
        try {
            util.failIfUploadNotValid(conf.id, conf.uploadForm);
            fail("Should throw exception if file type is not set.");
        } catch (ChunkUploadException e) {
            assertThat(e.getStatusCode(), is(PRECONDITION_FAILED));
            assertThat(e.getMessage(),
                    is("Required form parameter 'type' was not found."));
        }
    }

    public void notValidIfNoContentHash() {
        conf = defaultUpload().hash(null).build();
        mockLoggedIn();
        try {
            util.failIfHashNotPresent(conf.uploadForm);
            fail("Should throw exception if hash is not set.");
        } catch (ChunkUploadException e) {
            assertThat(e.getStatusCode(), is(PRECONDITION_FAILED));
            assertThat(e.getMessage(),
                    is("Required form parameter 'hash' was not found."));
        }
    }

    public void notValidIfVersionDoesNotExist() {
        conf = defaultUpload().build();
        mockLoggedIn();
        mockVersionDoesNotExist();
        try {
            util.failIfUploadNotValid(conf.id, conf.uploadForm);
            fail("Should throw exception if project-version does not exist.");
        } catch (ChunkUploadException e) {
            assertThat(e.getStatusCode(), is(NOT_FOUND));
            assertThat(e.getMessage(),
                    is("The specified project-version \"myproject:myversion\" "
                            + "does not exist on this server."));
        }
    }

    public void notValidIfProjectIsReadOnly() {
        notValidIfProjectStatusIs(EntityStatus.READONLY);
    }

    public void notValidIfProjectIsObsolete() {
        notValidIfProjectStatusIs(EntityStatus.OBSOLETE);
    }

    private void notValidIfProjectStatusIs(EntityStatus nonActiveStatus) {
        conf = defaultUpload().projectStatus(nonActiveStatus).build();
        mockLoggedIn();
        mockProjectAndVersionStatus();
        try {
            util.failIfUploadNotValid(conf.id, conf.uploadForm);
            fail("Should throw exception if project is read only or obsolete.");
        } catch (ChunkUploadException e) {
            assertThat(e.getStatusCode(), is(FORBIDDEN));
            assertThat(
                    e.getMessage(),
                    is("The project \"myproject\" is not active. Document upload "
                            + "is not allowed."));
        }
    }

    public void notValidIfVersionIsReadOnly() {
        notValidIfVersionStatusIs(EntityStatus.READONLY);
    }

    public void notValidIfVersionIsObsolete() {
        notValidIfVersionStatusIs(EntityStatus.OBSOLETE);
    }

    private void notValidIfVersionStatusIs(EntityStatus nonActiveStatus) {
        conf = defaultUpload().versionStatus(nonActiveStatus).build();
        mockLoggedIn();
        mockProjectAndVersionStatus();
        try {
            util.failIfUploadNotValid(conf.id, conf.uploadForm);
            fail("Should throw exception if version is read only or obsolete.");
        } catch (ChunkUploadException e) {
            assertThat(e.getStatusCode(), is(FORBIDDEN));
            assertThat(e.getMessage(),
                    is("The project-version \"myproject:myversion\" is not "
                            + "active. Document upload is not allowed."));
        }
    }

    public void notValidIfFileTypeInvalid() {
        conf = defaultUpload().fileType("invalid").build();
        mockLoggedIn();
        mockProjectAndVersionStatus();
        try {
            util.failIfUploadNotValid(conf.id, conf.uploadForm);
            fail("Should throw exception if file type is not valid.");
        } catch (ChunkUploadException e) {
            assertThat(e.getStatusCode(), is(PRECONDITION_FAILED));
            assertThat(e.getMessage(),
                    is("Value 'invalid' is not a recognized document type."));
        }
    }

    public void subsequentPartNoUploadId() {
        conf = defaultUpload().first(false).uploadId(null).build();
        mockLoggedIn();
        mockProjectAndVersionStatus();
        try {
            util.failIfUploadNotValid(conf.id, conf.uploadForm);
            fail("Should throw exception if this is not the first part but no uploadId is supplied");
        } catch (ChunkUploadException e) {
            assertThat(e.getStatusCode(), is(PRECONDITION_FAILED));
            assertThat(
                    e.getMessage(),
                    is("Form parameter 'uploadId' must be provided when this is "
                            + "not the first part."));

        }
    }

    public void subsequentPartUploadNotPresent() {
        conf = defaultUpload().first(false).uploadId(5L).build();
        mockLoggedIn();
        mockProjectAndVersionStatus();
        Mockito.when(documentUploadDAO.findById(conf.uploadId))
                .thenReturn(null);

        try {
            util.failIfUploadNotValid(conf.id, conf.uploadForm);
        } catch (ChunkUploadException e) {
            assertThat(e.getStatusCode(), is(PRECONDITION_FAILED));
            assertThat(e.getMessage(),
                    is("No incomplete uploads found for uploadId '5'."));
        }
    }

    public void subsequentPartUploadMismatchedDocId() {
        conf =
                defaultUpload().first(false).uploadId(5L)
                        .docId("mismatched-id").build();
        mockLoggedIn();
        mockProjectAndVersionStatus();

        HDocumentUpload upload = new HDocumentUpload();
        upload.setDocId("correct-id");
        when(documentUploadDAO.findById(conf.uploadId)).thenReturn(upload);

        try {
            util.failIfUploadNotValid(conf.id, conf.uploadForm);
        } catch (ChunkUploadException e) {
            assertThat(e.getStatusCode(), is(PRECONDITION_FAILED));
            assertThat(
                    e.getMessage(),
                    is("Supplied uploadId '5' in request is not valid for document 'mismatched-id'."));
        }
    }

    public void returnFormStreamWhenFileIsAbsent() throws FileNotFoundException {
        InputStream streamFromForm =
                new ByteArrayInputStream("test".getBytes());
        conf = defaultUpload().fileStream(streamFromForm).build();
        InputStream returnedStream =
                getInputStream(Optional.<File> absent(), conf.uploadForm);

        assertThat(returnedStream, is(sameInstance(streamFromForm)));
    }

    public void returnFileStreamWhenFileIsPresent() throws IOException {
        File f = null;
        try {
            f = File.createTempFile("test", "test");
            Files.write("text in file", f, UTF_8);
            Optional<File> presentFile = Optional.of(f);
            InputStream streamFromForm =
                    new ByteArrayInputStream("test".getBytes());
            conf = defaultUpload().fileStream(streamFromForm).build();

            InputStream returnedStream =
                    getInputStream(presentFile, conf.uploadForm);

            assertThat(IOUtils.toString(returnedStream, "utf-8"),
                    is("text in file"));
        } finally {
            if (f != null) {
                f.delete();
            }
        }
    }

    public void canCombineUploadPartsInOrder() throws SQLException, IOException {
        HDocumentUpload upload = mockTwoPartUploadUsingHash(HASH_OF_ABCDEFGHI);

        InputStream finalPartStream =
                new ByteArrayInputStream("ghi".getBytes());
        File persistedFile = new File("test");

        DocumentFileUploadForm uploadForm = new DocumentFileUploadForm();
        uploadForm.setFileStream(finalPartStream);

        when(
                translationFileService
                        .persistToTempFile(persistedInputStreamCaptor.capture()))
                .thenReturn(persistedFile);

        File returnedFile =
                util.combineToTempFileAndDeleteUploadRecord(upload,
                        uploadForm);

        assertThat(returnedFile, is(sameInstance(persistedFile)));
        String persistedContents =
                IOUtils.toString(persistedInputStreamCaptor.getValue(), "utf-8");
        assertThat(persistedContents, is("abcdefghi"));
        verify(session).delete(upload);
    }

    public void combineFailsOnHashMismatch() throws SQLException {
        HDocumentUpload upload = mockTwoPartUploadUsingHash("incorrect hash");
        InputStream finalPartStream =
                new ByteArrayInputStream("ghi".getBytes());

        DocumentFileUploadForm uploadForm = new DocumentFileUploadForm();
        uploadForm.setFileStream(finalPartStream);

        try {
            util.combineToTempFileAndDeleteUploadRecord(upload, uploadForm);
        } catch (ChunkUploadException e) {
            assertThat(e.getStatusCode(), is(CONFLICT));
            assertThat(
                    e.getMessage(),
                    is("MD5 hash \"incorrect hash\" sent with request does " +
                          "not match server-generated hash. Aborted upload " +
                          "operation."));
        }
    }

    public void combineSetsHashWhenNoHashProvided() throws SQLException {
        HDocumentUpload upload = mockTwoPartUploadUsingHash("");
        InputStream finalPartStream =
                new ByteArrayInputStream("ghi".getBytes());

        DocumentFileUploadForm uploadForm = new DocumentFileUploadForm();
        uploadForm.setFileStream(finalPartStream);

        util.combineToTempFileAndDeleteUploadRecord(upload, uploadForm);
        assertThat(uploadForm.getHash(), is(HASH_OF_ABCDEFGHI));
    }

    private HDocumentUpload mockTwoPartUploadUsingHash(String hash)
            throws SQLException {
        HDocumentUpload upload = new HDocumentUpload();
        upload.setContentHash(hash);

        HDocumentUploadPart part0 = new HDocumentUploadPart();
        when(partBlob0.getBinaryStream()).thenReturn(
                new ByteArrayInputStream("abc".getBytes()));
        part0.setContent(partBlob0);
        upload.getParts().add(part0);

        HDocumentUploadPart part1 = new HDocumentUploadPart();
        when(partBlob1.getBinaryStream()).thenReturn(
                new ByteArrayInputStream("def".getBytes()));
        part1.setContent(partBlob1);
        upload.getParts().add(part1);
        return upload;
    }

    // TODO damason: test mismatched hash when persisting temp file
}
TOP

Related Classes of org.zanata.file.DocumentUploadUtilTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.