/* * Copyright (C) 2011 Laurent Caillette * * This program 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 3 of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.novelang.novella; import java.io.File; import java.util.List; import com.google.common.collect.Lists; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import static org.junit.Assert.assertSame; import static org.novelang.ResourcesForTests.Images; import static org.novelang.ResourcesForTests.initialize; import static org.novelang.parser.NodeKind.*; import static org.novelang.parser.antlr.TreeFixture.tree; import org.novelang.common.Problem; import org.novelang.common.ProblemCollector; import org.novelang.common.SyntacticTree; import org.novelang.common.filefixture.Relativizer; import org.novelang.common.filefixture.ResourceInstaller; import org.novelang.common.filefixture.ResourceSchema; import org.novelang.logger.Logger; import org.novelang.logger.LoggerFactory; import org.novelang.parser.antlr.TreeFixture; import org.novelang.testing.junit.MethodSupport; /** * Tests for {@link ImageFixer} * * @author Laurent Caillette */ public class ImageFixerTest { @Test public void noChange() { final ImageFixer pathRelocator = new ImageFixer( parentDirectory, parentDirectory, null ) ; final SyntacticTree tree = tree( NOVELLA, tree( PARAGRAPH_REGULAR ) ) ; TreeFixture.assertEqualsNoSeparators( tree, pathRelocator.relocateResources( tree ) ) ; } @Test public void replaceRasterImageInTree() { final ListProblemCollector problemCollector = new ListProblemCollector() ; final ImageFixer pathRelocator = new ImageFixer( parentDirectory, parentDirectory, problemCollector ) ; final SyntacticTree treeToAbsolutize = tree( NOVELLA, tree( PARAGRAPH_REGULAR, tree( RASTER_IMAGE, tree( RESOURCE_LOCATION, RESOURCE_UNDER_PARENT ) ) ) ) ; final String expectedAbsoluteResourceLocation = RESOURCE_UNDER_PARENT; final SyntacticTree expectedTree = tree( NOVELLA, tree( PARAGRAPH_REGULAR, tree( RASTER_IMAGE, tree( RESOURCE_LOCATION, expectedAbsoluteResourceLocation ), tree( _IMAGE_WIDTH, RASTER_IMAGE_WIDTH ), tree( _IMAGE_HEIGHT, RASTER_IMAGE_HEIGHT ) ) ) ) ; final SyntacticTree resultTree = pathRelocator.relocateResources( treeToAbsolutize ); Assert.assertFalse( "" + problemCollector, problemCollector.hasProblem() ) ; TreeFixture.assertEqualsNoSeparators( expectedTree, resultTree ) ; } /** * In addition to tree content, this test verifies that SVG document is parsed * (which includes some entity loading). */ @Test public void replaceVectorImageInTree() { final ListProblemCollector problemCollector = new ListProblemCollector() ; final ImageFixer imageFixer = new ImageFixer( grandChildDirectory, grandChildDirectory, problemCollector ) ; final SyntacticTree treeToAbsolutize = tree( NOVELLA, tree( PARAGRAPH_REGULAR, tree( VECTOR_IMAGE, tree( RESOURCE_LOCATION, RESOURCE_UNDER_GRANDCHILD_RELATIVE_TO_ITSELF ) ) ) ) ; final String expectedAbsoluteResourceLocation = RESOURCE_UNDER_GRANDCHILD_ABSOLUTE_TO_ITSELF ; final SyntacticTree expectedTree = tree( NOVELLA, tree( PARAGRAPH_REGULAR, tree( VECTOR_IMAGE, tree( RESOURCE_LOCATION, expectedAbsoluteResourceLocation ), tree( _IMAGE_WIDTH, VECTOR_IMAGE_WIDTH ), tree( _IMAGE_HEIGHT, VECTOR_IMAGE_HEIGHT ) ) ) ) ; final SyntacticTree resultTree = imageFixer.relocateResources( treeToAbsolutize ); Assert.assertFalse( "" + problemCollector, problemCollector.hasProblem() ) ; TreeFixture.assertEqualsNoSeparators( expectedTree, resultTree ) ; } @Test public void reportProblem() { final ListProblemCollector problemCollector = new ListProblemCollector() ; final ImageFixer pathRelocator = new ImageFixer( parentDirectory, parentDirectory, problemCollector ) ; final SyntacticTree treeToAbsolutize = tree( NOVELLA, tree( PARAGRAPH_REGULAR, tree( RASTER_IMAGE, tree( RESOURCE_LOCATION, "./doesnotexist" ) ) ) ) ; pathRelocator.relocateResources( treeToAbsolutize ) ; assertSame( 1, problemCollector.getProblems().length ) ; } @Test( expected = ImageFixerException.class ) public void detectUnauthorizedAccessToUpperDirectory() throws ImageFixerException { justRelocate( childDirectory, childDirectory, ( ".." + RESOURCE_UNDER_PARENT ) // This one exists above, but should be forbidden! ) ; } @Test( expected = ImageFixerException.class ) public void detectNonExistingResource() throws ImageFixerException { justRelocate( parentDirectory, parentDirectory, "doesnotexist" ) ; } @Test public void absoluteFromBaseToBase() throws ImageFixerException { check( RESOURCE_UNDER_PARENT, parentDirectory, parentDirectory, RESOURCE_UNDER_PARENT ) ; } @Test public void relativeFromBaseToBase() throws ImageFixerException { check( RESOURCE_UNDER_PARENT, parentDirectory, parentDirectory, "." + RESOURCE_UNDER_PARENT ) ; } @Test public void absoluteFromChildToChild() throws ImageFixerException { check( RESOURCE_UNDER_CHILD, parentDirectory, childDirectory, RESOURCE_UNDER_CHILD ) ; } @Test public void relativeFromChildToChild() throws ImageFixerException { check( RESOURCE_UNDER_CHILD, parentDirectory, childDirectory, RESOURCE_UNDER_CHILD_RELATIVE_TO_ITSELF ) ; } @Test public void absoluteFromChildToGrandchild() throws ImageFixerException { check( RESOURCE_UNDER_GRANDCHILD, parentDirectory, childDirectory, RESOURCE_UNDER_GRANDCHILD ) ; } @Test public void relativeFromChildToGrandchild() throws ImageFixerException { check( RESOURCE_UNDER_GRANDCHILD, parentDirectory, childDirectory, RESOURCE_UNDER_GRANDCHILD ) ; } @Test public void relativeFromChildToParent() throws ImageFixerException { check( RESOURCE_UNDER_PARENT, parentDirectory, childDirectory, ".." + RESOURCE_UNDER_PARENT ) ; } @Test public void absoluteFromChildToParent() throws ImageFixerException { check( RESOURCE_UNDER_PARENT, parentDirectory, childDirectory, RESOURCE_UNDER_PARENT ) ; } // ======= // Fixture // ======= private static final Logger LOGGER = LoggerFactory.getLogger( ImageFixerTest.class ) ; private static final String RESOURCE_UNDER_PARENT ; private static final String RESOURCE_UNDER_CHILD ; private static final String RESOURCE_UNDER_GRANDCHILD ; static { initialize() ; final Relativizer relativizer = ResourceSchema.relativizer( Images.dir ) ; RESOURCE_UNDER_PARENT = relativizer.apply( Images.RED_PNG ) ; RESOURCE_UNDER_CHILD = relativizer.apply( Images.Child.BLUE_GIF ) ; RESOURCE_UNDER_GRANDCHILD = relativizer.apply( Images.Child.Grandchild.YELLOW_SVG ) ; } private static final String RESOURCE_UNDER_CHILD_RELATIVE_TO_ITSELF = "./" + Images.Child.BLUE_GIF.getName() ; private static final String RESOURCE_UNDER_GRANDCHILD_RELATIVE_TO_ITSELF = "./" + Images.Child.Grandchild.YELLOW_SVG.getName() ; private static final String RESOURCE_UNDER_GRANDCHILD_ABSOLUTE_TO_ITSELF = "/" + Images.Child.Grandchild.YELLOW_SVG.getName() ; private static final String RASTER_IMAGE_WIDTH = Images.RASTER_IMAGE_WIDTH ; private static final String RASTER_IMAGE_HEIGHT = Images.RASTER_IMAGE_HEIGHT ; private static final String VECTOR_IMAGE_WIDTH = Images.VECTOR_IMAGE_WIDTH ; private static final String VECTOR_IMAGE_HEIGHT = Images.VECTOR_IMAGE_HEIGHT ; private File parentDirectory ; private File childDirectory ; private File grandChildDirectory ; @Rule public final MethodSupport methodSupport = new MethodSupport() { @Override protected void beforeStatementEvaluation() throws Exception { parentDirectory = getDirectory() ; final ResourceInstaller filer = new ResourceInstaller( parentDirectory ) ; filer.copyContent( Images.dir ) ; childDirectory = filer.createFileObject( Images.dir, Images.Child.dir ); grandChildDirectory = filer.createFileObject( Images.dir, Images.Child.Grandchild.dir ) ; } }; private void check( final String expectedRelativeResourceName, final File baseDirectory, final File referrerDirectory, final String resourceNameRelativeToReferrer ) throws ImageFixerException { final ListProblemCollector problemCollector = new ListProblemCollector() ; final ImageFixer pathRelocator = new ImageFixer( baseDirectory, referrerDirectory, problemCollector ) ; final String actualRelativeResourceName = pathRelocator.relocate( resourceNameRelativeToReferrer ) ; LOGGER.info( "Checking...\n baseDirectory='", baseDirectory, "'\n referrerDirectory='", referrerDirectory, "'\n resourceNameRelativeToReferrer='", resourceNameRelativeToReferrer, "'\n expectedRelativeResourceName=''", expectedRelativeResourceName, "'" ) ; Assert.assertEquals( expectedRelativeResourceName, actualRelativeResourceName ) ; Assert.assertEquals( 0, problemCollector.getProblems().length ) ; } private void justRelocate( final File baseDirectory, final File referrerDirectory, final String resourceNameRelativeToReferrer ) throws ImageFixerException { final ListProblemCollector problemCollector = new ListProblemCollector() ; final ImageFixer pathRelocator = new ImageFixer( baseDirectory, referrerDirectory, problemCollector ) ; pathRelocator.relocate( resourceNameRelativeToReferrer ) ; } private class ListProblemCollector implements ProblemCollector { private final List< Problem > problems = Lists.newArrayList() ; @Override public void collect( final Problem problem ) { problems.add( problem ) ; } public Problem[] getProblems() { return problems.toArray( new Problem[ problems.size() ] ) ; } public boolean hasProblem() { return ! problems.isEmpty() ; } @Override public String toString() { return problems.toString() ; } } }