org.wte4j.persistence.WordTemplateRepositoryTest.java Source code

Java tutorial

Introduction

Here is the source code for org.wte4j.persistence.WordTemplateRepositoryTest.java

Source

/**
 * Copyright (C) 2015 Born Informatik AG (www.born.ch)
 *
 * 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 org.wte4j.persistence;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;

import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
import org.wte4j.EmbeddedDataBaseConfig;
import org.wte4j.FileStore;
import org.wte4j.LockingException;
import org.wte4j.MappingDetail;
import org.wte4j.Template;
import org.wte4j.TemplateQuery;
import org.wte4j.User;
import org.wte4j.WteModelService;
import org.wte4j.impl.TemplateContextFactory;
import org.wte4j.impl.WordTemplate;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { EmbeddedDataBaseConfig.class })
@TransactionConfiguration(defaultRollback = true)
@Transactional
public class WordTemplateRepositoryTest {
    private static final long LOCKED_TEMPLATE = 2;
    private static final long UNLOCKED_TEMPLATE = 1;
    @PersistenceContext
    EntityManager entityManager;
    TemplateContextFactory contextFactory = mock(TemplateContextFactory.class);
    WteModelService modelService = mock(WteModelService.class);
    WordTemplateRepository repository;

    @Before
    public void initTest() throws Exception {
        repository = new WordTemplateRepository(entityManager, contextFactory);
    }

    @Test
    @Transactional
    public void testQueryTemplates() {
        TemplateQuery query = repository.queryTemplates();
        List<Template<Object>> templates = query.list();
        assertEquals(4, templates.size());
    }

    @Test
    @Transactional
    public void testQueryWithEmptyResults() {
        TemplateQuery query = repository.queryTemplates();
        List<Template<Object>> templates = query.language("xxx").list();
        assertEquals(0, templates.size());
    }

    @Test
    @Transactional
    public void getTemplate() {
        Template<?> template = repository.getTemplate("test1", "en");
        assertNotNull(template);
    }

    @Test
    @Transactional
    public void getNonExistingTemplate() {
        Template<?> template = repository.getTemplate("XXXX", "XX");
        assertNull(template);
    }

    @Test(expected = IllegalArgumentException.class)
    @Transactional
    public void getTemplateWithWrongInputType() {
        repository.getTemplate("test1", "en", Date.class);
        fail("Exception expected");
    }

    @Test
    @Transactional
    public void locking() {
        WordTemplate<?> template = unlockedTemplate();
        User lockingUser = new User("locking", "Locking User");
        Template<?> locked = repository.lockForEdit(template, lockingUser);
        assertEquals(lockingUser, locked.getLockingUser());
        assertTrue(isVersionIncontext(locked));
    }

    @Test
    @Transactional
    public void lockingLockedTemplate() {
        WordTemplate<?> toLock = lockedTemplate();
        User second = new User("second", "Second User");
        try {
            repository.lockForEdit(toLock, second);
            fail(LockingException.class + " expected");
        } catch (LockingException e) {
            assertTrue(isVersionIncontext(toLock));
        }
    }

    @Test(expected = LockingException.class)
    @Transactional
    public void lockingTemplateParallel() {
        Template<?> template1 = unlockedTemplate();
        Template<?> template2 = unlockedTemplate();
        template1 = repository.lockForEdit(template1, new User("first", "First"));
        User second = new User("second", "Second User");
        repository.lockForEdit(template2, second);
        fail(LockingException.class + " expected");
    }

    @Test
    @Transactional
    public void lockingTwice() {
        Template<?> template = unlockedTemplate();
        User user = new User("user", "User");
        template = repository.lockForEdit(template, user);
        template = repository.lockForEdit(template, user);
        assertEquals(user, template.getLockingUser());
    }

    @Test
    @Transactional
    public void unlock() {
        WordTemplate<?> template = lockedTemplate();
        Template<?> unlocked = repository.unlock(template);
        assertNull(unlocked.getLockingUser());
        assertTrue(isVersionIncontext(unlocked));
    }

    @Test
    @Transactional
    public void persistNewTemplate() {
        WordTemplate<?> template = newTemplate();
        repository.persist(template);
        Template<?> persisted = repository.getTemplate("test3", "de");
        assertTrue(isVersionIncontext(persisted));
    }

    @Test
    @Transactional
    public void persistTemplateWithFileStore() throws Exception {
        WordTemplate<?> template = newTemplate();
        FileStore fileStore = mock(FileStore.class);
        File file = File.createTempFile("content", "docx");
        OutputStream out = FileUtils.openOutputStream(file);
        when(fileStore.getOutStream(anyString())).thenReturn(out);
        repository.setFileStore(fileStore);
        try {
            repository.persist(template);
            File epected = FileUtils.toFile(getClass().getResource("empty.docx"));
            assertTrue(FileUtils.contentEquals(epected, file));
        } finally {
            file.deleteOnExit();
        }
    }

    @Test
    @Transactional
    public void persistOfLocked() throws Exception {
        Template<?> template1 = unlockedTemplate();
        WordTemplate<?> template2 = unlockedTemplate();
        template1 = repository.lockForEdit(template1, new User("user1", "user1"));
        byte[] content = getContent("empty.docx");
        template2.getTemplateData().setContent(content, new User());
        try {
            repository.persist(template2);
            fail("Exception expected");
        } catch (LockingException e) {
            assertTrue(isVersionIncontext(template1));
        }
    }

    @Test
    @Transactional
    public void changeContent() throws Exception {
        WordTemplate<?> template = unlockedTemplate();
        byte[] content = getContent("empty.docx");
        User user = new User("new_editor", "New Editor");
        template.update(new ByteArrayInputStream(content), user);
        Template<?> peristed = repository.persist(template);
        assertTrue(isVersionIncontext(peristed));
    }

    @Test
    @Transactional
    public void updateTemplateWithFileStore() throws Exception {
        FileStore fileStore = mock(FileStore.class);
        File file = File.createTempFile("content", "docx");
        OutputStream out = FileUtils.openOutputStream(file);
        when(fileStore.getOutStream(anyString())).thenReturn(out);
        repository.setFileStore(fileStore);
        WordTemplate<?> template = unlockedTemplate();
        template.getTemplateData().setContent(getContent("empty.docx"), new User());
        try {
            repository.persist(template);
            File expected = FileUtils.toFile(getClass().getResource("empty.docx"));
            assertTrue(FileUtils.contentEquals(expected, file));
        } finally {
            file.deleteOnExit();
        }
    }

    @Test
    @Transactional
    public void deleteTemplate() {
        WordTemplate<?> template = unlockedTemplate();
        repository.delete(template);
        assertFalse(isVersionIncontext(template));
    }

    @Test
    @Transactional
    public void deleteLockedTemplate() {
        WordTemplate<?> template = lockedTemplate();
        try {
            repository.delete(template);
            fail("Exception expected. Locked templates must not be deleted");
        } catch (LockingException e) {
            assertTrue(isVersionIncontext(template));
        }
    }

    @Test
    @Transactional
    public void delteTemplateWithFileStore() throws Exception {
        FileStore fileStore = mock(FileStore.class);
        repository.setFileStore(fileStore);
        WordTemplate<?> template = unlockedTemplate();
        PersistentTemplate templateData = (PersistentTemplate) template.getTemplateData();
        repository.delete(template);
        verify(fileStore, times(1)).deleteFile(anyString());
        verify(fileStore, times(1)).deleteFile(templateData.getTemplateFileName());
        assertFalse("template must not be in persistent context", isVersionIncontext(template));
    }

    @Test
    @Transactional
    public void errorsWithFileStore() throws Exception {
        WordTemplate<?> template = unlockedTemplate();
        FileStore fileStore = mock(FileStore.class);
        repository.setFileStore(fileStore);
        EntityManager entityManager = mock(EntityManager.class);
        when(entityManager.merge(any())).thenThrow(new PersistenceException());
        repository.em = entityManager;
        try {
            repository.persist(template);
            fail("Exception expected");
        } catch (Exception e) {
            verifyZeroInteractions(fileStore);
        }
    }

    private WordTemplate<?> newTemplate() {
        try {
            PersistentTemplate templateData = new PersistentTemplate();
            templateData.setDocumentName("test3");
            templateData.setLanguage("de");
            templateData.setContent(getContent("empty.docx"));
            templateData.setCreatedAt(new Date());
            templateData.setEditedAt(new Date());
            templateData.setEditor(new User("user", "user"));

            Map<String, String> properties = new HashMap<>();
            properties.put("key", "value");
            templateData.setProperties(properties);

            MappingDetail value = new MappingDetail();
            value.setModelKey("modelKey");

            Map<String, MappingDetail> contentMaping = new HashedMap<String, MappingDetail>();
            contentMaping.put("conentKey", value);

            templateData.setContentMapping(contentMaping);

            WordTemplate<?> template = new WordTemplate<Object>(templateData, contextFactory);
            return template;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Returns a detached locked template
     */
    private WordTemplate<?> lockedTemplate() {
        PersistentTemplate template = getTemplateInContext(LOCKED_TEMPLATE);
        entityManager.detach(template);
        return new WordTemplate<Object>(template, contextFactory);
    }

    /**
     * Returns a detached unlocked template
     */
    private WordTemplate<?> unlockedTemplate() {
        PersistentTemplate template = getTemplateInContext(UNLOCKED_TEMPLATE);
        entityManager.detach(template);
        return new WordTemplate<Object>(template, contextFactory);
    }

    private byte[] getContent(String file) throws IOException {
        InputStream in = null;
        try {
            in = getClass().getResourceAsStream(file);
            return IOUtils.toByteArray(in);
        } finally {
            IOUtils.closeQuietly(in);
        }
    }

    PersistentTemplate getTemplateInContext(long id) {
        return entityManager.find(PersistentTemplate.class, id);
    }

    private boolean isVersionIncontext(Template<?> template) {
        WordTemplate<?> wordTemplate = (WordTemplate<?>) template;
        PersistentTemplate templateData = (PersistentTemplate) wordTemplate.getTemplateData();
        PersistentTemplate inContext = getTemplateInContext(templateData.getId());
        if (inContext == null) {
            return false;
        }
        return inContext.getVersion() == templateData.getVersion();
    }
}