Refactor project validation, add test
authorDavid ‘Bombe’ Roden <bombe@freenetproject.org>
Sun, 18 Sep 2016 17:47:16 +0000 (19:47 +0200)
committerDavid ‘Bombe’ Roden <bombe@freenetproject.org>
Sun, 18 Sep 2016 17:47:16 +0000 (19:47 +0200)
src/main/java/de/todesbaum/jsite/application/ProjectInserter.java
src/main/java/de/todesbaum/jsite/application/validation/CheckReport.java [new file with mode: 0644]
src/main/java/de/todesbaum/jsite/application/validation/Issue.java [new file with mode: 0644]
src/main/java/de/todesbaum/jsite/application/validation/ProjectValidator.java [new file with mode: 0644]
src/main/java/de/todesbaum/jsite/main/Main.java
src/test/java/de/todesbaum/jsite/application/validation/ProjectValidatorTest.java [new file with mode: 0644]

index c7dad3b..e43c8b1 100644 (file)
@@ -23,17 +23,9 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -227,92 +219,6 @@ public class ProjectInserter implements FileScannerListener, Runnable {
        }
 
        /**
-        * Validates the given project. The project will be checked for any invalid
-        * conditions, such as invalid insert or request keys, missing path names,
-        * missing default file, and so on.
-        *
-        * @param project
-        *            The project to check
-        * @return The encountered warnings and errors
-        */
-       public static CheckReport validateProject(Project project) {
-               CheckReport checkReport = new CheckReport();
-               if ((project.getLocalPath() == null) || (project.getLocalPath().trim().length() == 0)) {
-                       checkReport.addIssue("error.no-local-path", true);
-               }
-               if ((project.getPath() == null) || (project.getPath().trim().length() == 0)) {
-                       checkReport.addIssue("error.no-path", true);
-               }
-               if ((project.getIndexFile() == null) || (project.getIndexFile().length() == 0)) {
-                       checkReport.addIssue("warning.empty-index", false);
-               } else {
-                       File indexFile = new File(project.getLocalPath(), project.getIndexFile());
-                       if (!indexFile.exists()) {
-                               checkReport.addIssue("error.index-missing", true);
-                       }
-               }
-               String indexFile = project.getIndexFile();
-               boolean hasIndexFile = (indexFile != null) && (indexFile.length() > 0);
-               List<String> allowedIndexContentTypes = Arrays.asList("text/html", "application/xhtml+xml");
-               if (hasIndexFile && !allowedIndexContentTypes.contains(project.getFileOption(indexFile).getMimeType())) {
-                       checkReport.addIssue("warning.index-not-html", false);
-               }
-               Map<String, FileOption> fileOptions = project.getFileOptions();
-               Set<Entry<String, FileOption>> fileOptionEntries = fileOptions.entrySet();
-               boolean insert = fileOptionEntries.isEmpty();
-               for (Entry<String, FileOption> fileOptionEntry : fileOptionEntries) {
-                       String fileName = fileOptionEntry.getKey();
-                       FileOption fileOption = fileOptionEntry.getValue();
-                       insert |= fileOption.isInsert() || fileOption.isInsertRedirect();
-                       if (fileName.equals(project.getIndexFile()) && !fileOption.isInsert() && !fileOption.isInsertRedirect()) {
-                               checkReport.addIssue("error.index-not-inserted", true);
-                       }
-                       if (!fileOption.isInsert() && fileOption.isInsertRedirect() && ((fileOption.getCustomKey().length() == 0) || "CHK@".equals(fileOption.getCustomKey()))) {
-                               checkReport.addIssue("error.no-custom-key", true, fileName);
-                       }
-               }
-               if (!insert) {
-                       checkReport.addIssue("error.no-files-to-insert", true);
-               }
-               Set<String> fileNames = new HashSet<String>();
-               for (Entry<String, FileOption> fileOptionEntry : fileOptionEntries) {
-                       FileOption fileOption = fileOptionEntry.getValue();
-                       if (!fileOption.isInsert() && !fileOption.isInsertRedirect()) {
-                               logger.log(Level.FINEST, "Ignoring {0}.", fileOptionEntry.getKey());
-                               continue;
-                       }
-                       String fileName = fileOption.getChangedName().orElse(fileOptionEntry.getKey());
-                       logger.log(Level.FINEST, "Adding “{0}” for {1}.", new Object[] { fileName, fileOptionEntry.getKey() });
-                       if (!fileNames.add(fileName)) {
-                               checkReport.addIssue("error.duplicate-file", true, fileName);
-                       }
-               }
-               long totalSize = 0;
-               final CountDownLatch completionLatch = new CountDownLatch(1);
-               FileScanner fileScanner = new FileScanner(project, (error, files) -> completionLatch.countDown());
-               fileScanner.startInBackground();
-               while (completionLatch.getCount() > 0) {
-                       try {
-                               completionLatch.await();
-                       } catch (InterruptedException ie1) {
-                               /* TODO: logging */
-                       }
-               }
-               for (ScannedFile scannedFile : fileScanner.getFiles()) {
-                       String fileName = scannedFile.getFilename();
-                       FileOption fileOption = project.getFileOption(fileName);
-                       if ((fileOption != null) && !fileOption.isInsert()) {
-                               continue;
-                       }
-                       totalSize += new File(project.getLocalPath(), fileName).length();
-               }
-               if (totalSize > 2 * 1024 * 1024) {
-                       checkReport.addIssue("warning.site-larger-than-2-mib", false);
-               }
-               return checkReport;
-       }
-
-       /**
         * {@inheritDoc}
         */
        @Override
@@ -435,139 +341,4 @@ public class ProjectInserter implements FileScannerListener, Runnable {
                }
        }
 
-       /**
-        * Container class that collects all warnings and errors that occured during
-        * {@link ProjectInserter#validateProject(Project) project validation}.
-        *
-        * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
-        */
-       public static class CheckReport implements Iterable<Issue> {
-
-               /** The issures that occured. */
-               private final List<Issue> issues = new ArrayList<Issue>();
-
-               /**
-                * Adds an issue.
-                *
-                * @param issue
-                *            The issue to add
-                */
-               public void addIssue(Issue issue) {
-                       issues.add(issue);
-               }
-
-               /**
-                * Creates an {@link Issue} from the given error key and fatality flag
-                * and {@link #addIssue(Issue) adds} it.
-                *
-                * @param errorKey
-                *            The error key
-                * @param fatal
-                *            {@code true} if the error is fatal, {@code false} if only
-                *            a warning should be generated
-                * @param parameters
-                *            Any additional parameters
-                */
-               public void addIssue(String errorKey, boolean fatal, String... parameters) {
-                       addIssue(new Issue(errorKey, fatal, parameters));
-               }
-
-               /**
-                * {@inheritDoc}
-                */
-               @Override
-               public Iterator<Issue> iterator() {
-                       return issues.iterator();
-               }
-
-               /**
-                * Returns whether this check report does not contain any errors.
-                *
-                * @return {@code true} if this check report does not contain any
-                *         errors, {@code false} if this check report does contain
-                *         errors
-                */
-               public boolean isEmpty() {
-                       return issues.isEmpty();
-               }
-
-               /**
-                * Returns the number of issues in this check report.
-                *
-                * @return The number of issues
-                */
-               public int size() {
-                       return issues.size();
-               }
-
-       }
-
-       /**
-        * Container class for a single issue. An issue contains an error key
-        * that describes the error, and a fatality flag that determines whether
-        * the insert has to be aborted (if the flag is {@code true}) or if it
-        * can still be performed and only a warning should be generated (if the
-        * flag is {@code false}).
-        *
-        * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’
-        *         Roden</a>
-        */
-       public static class Issue {
-
-               /** The error key. */
-               private final String errorKey;
-
-               /** The fatality flag. */
-               private final boolean fatal;
-
-               /** Additional parameters. */
-               private String[] parameters;
-
-               /**
-                * Creates a new issue.
-                *
-                * @param errorKey
-                *            The error key
-                * @param fatal
-                *            The fatality flag
-                * @param parameters
-                *            Any additional parameters
-                */
-               protected Issue(String errorKey, boolean fatal, String... parameters) {
-                       this.errorKey = errorKey;
-                       this.fatal = fatal;
-                       this.parameters = parameters;
-               }
-
-               /**
-                * Returns the key of the encountered error.
-                *
-                * @return The error key
-                */
-               public String getErrorKey() {
-                       return errorKey;
-               }
-
-               /**
-                * Returns whether the issue is fatal and the insert has to be
-                * aborted. Otherwise only a warning should be shown.
-                *
-                * @return {@code true} if the insert needs to be aborted, {@code
-                *         false} otherwise
-                */
-               public boolean isFatal() {
-                       return fatal;
-               }
-
-               /**
-                * Returns any additional parameters.
-                *
-                * @return The additional parameters
-                */
-               public String[] getParameters() {
-                       return parameters;
-               }
-
-       }
-
 }
diff --git a/src/main/java/de/todesbaum/jsite/application/validation/CheckReport.java b/src/main/java/de/todesbaum/jsite/application/validation/CheckReport.java
new file mode 100644 (file)
index 0000000..7a10c36
--- /dev/null
@@ -0,0 +1,37 @@
+package de.todesbaum.jsite.application.validation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import de.todesbaum.jsite.application.Project;
+
+/**
+ * Container class that collects all warnings and errors that occured during
+ * {@link ProjectValidator#validateProject(Project) project validation}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class CheckReport implements Iterable<Issue> {
+
+       private final List<Issue> issues = new ArrayList<>();
+
+       void addIssue(String errorKey, boolean fatal, String... parameters) {
+               issues.add(new Issue(errorKey, fatal, parameters));
+       }
+
+       public Collection<Issue> getIssues() {
+               return issues;
+       }
+
+       @Override
+       public Iterator<Issue> iterator() {
+               return issues.iterator();
+       }
+
+       public boolean isEmpty() {
+               return issues.isEmpty();
+       }
+
+}
diff --git a/src/main/java/de/todesbaum/jsite/application/validation/Issue.java b/src/main/java/de/todesbaum/jsite/application/validation/Issue.java
new file mode 100644 (file)
index 0000000..451aabc
--- /dev/null
@@ -0,0 +1,64 @@
+package de.todesbaum.jsite.application.validation;
+
+import static java.lang.String.format;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Container class for a single issue. An issue contains an error key that describes the error,
+ * and a fatality flag that determines whether the insert has to be aborted (if the flag is
+ * {@code true}) or if it can still be performed and only a warning should be generated (if the
+ * flag is {@code false}).
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class Issue {
+
+       private final String errorKey;
+       private final boolean fatal;
+       private final String[] parameters;
+
+       Issue(String errorKey, boolean fatal, String... parameters) {
+               this.errorKey = errorKey;
+               this.fatal = fatal;
+               this.parameters = parameters;
+       }
+
+       public String getErrorKey() {
+               return errorKey;
+       }
+
+       public boolean isFatal() {
+               return fatal;
+       }
+
+       public String[] getParameters() {
+               return parameters;
+       }
+
+       @Override
+       public boolean equals(Object o) {
+               if (this == o) {
+                       return true;
+               }
+               if (o == null || getClass() != o.getClass()) {
+                       return false;
+               }
+               Issue issue = (Issue) o;
+               return fatal == issue.fatal &&
+                               Objects.equals(errorKey, issue.errorKey) &&
+                               Arrays.equals(parameters, issue.parameters);
+       }
+
+       @Override
+       public int hashCode() {
+               return Objects.hash(errorKey, fatal, parameters);
+       }
+
+       @Override
+       public String toString() {
+               return format("Issue{errorKey=\"%s\", fatal=%s, parameters=%s}", errorKey, fatal, Arrays.toString(parameters));
+       }
+
+}
diff --git a/src/main/java/de/todesbaum/jsite/application/validation/ProjectValidator.java b/src/main/java/de/todesbaum/jsite/application/validation/ProjectValidator.java
new file mode 100644 (file)
index 0000000..2e03e6c
--- /dev/null
@@ -0,0 +1,107 @@
+package de.todesbaum.jsite.application.validation;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import de.todesbaum.jsite.application.FileOption;
+import de.todesbaum.jsite.application.Project;
+import de.todesbaum.jsite.gui.FileScanner;
+import de.todesbaum.jsite.gui.ScannedFile;
+
+/**
+ * Validates a project and returns a number of {@link Issue}s in a {@link CheckReport}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class ProjectValidator {
+
+       private static final Logger logger = Logger.getLogger(ProjectValidator.class.getName());
+
+       public static CheckReport validateProject(Project project) {
+               CheckReport checkReport = new CheckReport();
+               if ((project.getLocalPath() == null) || (project.getLocalPath().trim().length() == 0)) {
+                       checkReport.addIssue("error.no-local-path", true);
+                       return checkReport;
+               }
+               if ((project.getPath() == null) || (project.getPath().trim().length() == 0)) {
+                       checkReport.addIssue("error.no-path", true);
+               }
+               if ((project.getIndexFile() == null) || (project.getIndexFile().length() == 0)) {
+                       checkReport.addIssue("warning.empty-index", false);
+               } else {
+                       File indexFile = new File(project.getLocalPath(), project.getIndexFile());
+                       if (!indexFile.exists()) {
+                               checkReport.addIssue("error.index-missing", true);
+                       }
+               }
+               String indexFile = project.getIndexFile();
+               boolean hasIndexFile = (indexFile != null) && (indexFile.length() > 0);
+               List<String> allowedIndexContentTypes = Arrays.asList("text/html", "application/xhtml+xml");
+               if (hasIndexFile && !allowedIndexContentTypes.contains(project.getFileOption(indexFile).getMimeType())) {
+                       checkReport.addIssue("warning.index-not-html", false);
+               }
+               Map<String, FileOption> fileOptions = project.getFileOptions();
+               Set<Entry<String, FileOption>> fileOptionEntries = fileOptions.entrySet();
+               boolean insert = fileOptionEntries.isEmpty();
+               for (Entry<String, FileOption> fileOptionEntry : fileOptionEntries) {
+                       String fileName = fileOptionEntry.getKey();
+                       FileOption fileOption = fileOptionEntry.getValue();
+                       insert |= fileOption.isInsert() || fileOption.isInsertRedirect();
+                       if (fileName.equals(project.getIndexFile()) && !fileOption.isInsert() && !fileOption.isInsertRedirect()) {
+                               checkReport.addIssue("error.index-not-inserted", true);
+                       }
+                       if (!fileOption.isInsert() && fileOption.isInsertRedirect() && ((fileOption.getCustomKey().length() == 0) || "CHK@".equals(
+                                       fileOption.getCustomKey()))) {
+                               checkReport.addIssue("error.no-custom-key", true, fileName);
+                       }
+               }
+               if (!insert) {
+                       checkReport.addIssue("error.no-files-to-insert", true);
+               }
+               Set<String> fileNames = new HashSet<>();
+               for (Entry<String, FileOption> fileOptionEntry : fileOptionEntries) {
+                       FileOption fileOption = fileOptionEntry.getValue();
+                       if (!fileOption.isInsert() && !fileOption.isInsertRedirect()) {
+                               logger.log(Level.FINEST, "Ignoring {0}.", fileOptionEntry.getKey());
+                               continue;
+                       }
+                       String fileName = fileOption.getChangedName().orElse(fileOptionEntry.getKey());
+                       logger.log(Level.FINEST, "Adding “{0}” for {1}.", new Object[] { fileName, fileOptionEntry.getKey() });
+                       if (!fileNames.add(fileName)) {
+                               checkReport.addIssue("error.duplicate-file", true, fileName);
+                       }
+               }
+               long totalSize = 0;
+               final CountDownLatch completionLatch = new CountDownLatch(1);
+               FileScanner fileScanner = new FileScanner(project, (error, files) -> completionLatch.countDown());
+               fileScanner.startInBackground();
+               while (completionLatch.getCount() > 0) {
+                       try {
+                               completionLatch.await();
+                       } catch (InterruptedException ie1) {
+                               /* TODO: logging */
+                       }
+               }
+               for (ScannedFile scannedFile : fileScanner.getFiles()) {
+                       String fileName = scannedFile.getFilename();
+                       FileOption fileOption = project.getFileOption(fileName);
+                       if ((fileOption != null) && !fileOption.isInsert()) {
+                               continue;
+                       }
+                       totalSize += new File(project.getLocalPath(), fileName).length();
+               }
+               if (totalSize > 2 * 1024 * 1024) {
+                       checkReport.addIssue("warning.site-larger-than-2-mib", false);
+               }
+               return checkReport;
+       }
+
+}
index 8a0b898..a8d70e7 100644 (file)
@@ -47,15 +47,16 @@ import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
 
 import net.pterodactylus.util.image.IconLoader;
+
 import de.todesbaum.jsite.application.Freenet7Interface;
 import de.todesbaum.jsite.application.Node;
 import de.todesbaum.jsite.application.Project;
-import de.todesbaum.jsite.application.ProjectInserter;
-import de.todesbaum.jsite.application.ProjectInserter.CheckReport;
-import de.todesbaum.jsite.application.ProjectInserter.Issue;
 import de.todesbaum.jsite.application.UpdateChecker;
 import de.todesbaum.jsite.application.UpdateListener;
 import de.todesbaum.jsite.application.WebOfTrustInterface;
+import de.todesbaum.jsite.application.validation.CheckReport;
+import de.todesbaum.jsite.application.validation.Issue;
+import de.todesbaum.jsite.application.validation.ProjectValidator;
 import de.todesbaum.jsite.gui.NodeManagerListener;
 import de.todesbaum.jsite.gui.NodeManagerPage;
 import de.todesbaum.jsite.gui.PreferencesPage;
@@ -561,7 +562,7 @@ public class Main implements ActionListener, ListSelectionListener, WizardListen
                                JOptionPane.showMessageDialog(wizard, I18n.getMessage("jsite.error.no-node-selected"), null, JOptionPane.ERROR_MESSAGE);
                                return;
                        }
-                       CheckReport checkReport = ProjectInserter.validateProject(project);
+                       CheckReport checkReport = ProjectValidator.validateProject(project);
                        for (Issue issue : checkReport) {
                                if (issue.isFatal()) {
                                        JOptionPane.showMessageDialog(wizard, MessageFormat.format(I18n.getMessage("jsite." + issue.getErrorKey()), (Object[]) issue.getParameters()), null, JOptionPane.ERROR_MESSAGE);
diff --git a/src/test/java/de/todesbaum/jsite/application/validation/ProjectValidatorTest.java b/src/test/java/de/todesbaum/jsite/application/validation/ProjectValidatorTest.java
new file mode 100644 (file)
index 0000000..545ab45
--- /dev/null
@@ -0,0 +1,172 @@
+package de.todesbaum.jsite.application.validation;
+
+import static de.todesbaum.jsite.application.validation.ProjectValidator.validateProject;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.not;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.StandardOpenOption;
+
+import de.todesbaum.jsite.application.Project;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * Unit test for {@link ProjectValidator}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class ProjectValidatorTest {
+
+       @Rule
+       public final TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+       private Project project = new Project();
+
+       @Before
+       public void setupProject() throws Exception {
+               project.setLocalPath(temporaryFolder.getRoot().getPath());
+               project.setPath("temp");
+               project.setIndexFile("index.html");
+               temporaryFolder.newFile("index.html").createNewFile();
+       }
+
+       @Test
+       public void completelyValidProjectDoesNotGenerateAnyIssues() {
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), empty());
+       }
+
+       @Test
+       public void missingLocalPathResultsInError() {
+               project.setLocalPath(null);
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("error.no-local-path", true)));
+       }
+
+       @Test
+       public void emptyLocalPathResultsInError() {
+               project.setLocalPath("   ");
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("error.no-local-path", true)));
+       }
+
+       @Test
+       public void missingPathResultsInError() {
+               project.setPath(null);
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("error.no-path", true)));
+       }
+
+       @Test
+       public void emptyPathResultsInError() {
+               project.setPath("   ");
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("error.no-path", true)));
+       }
+
+       @Test
+       public void missingIndexFileResultsInWarning() {
+               project.setIndexFile(null);
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("warning.empty-index", false)));
+       }
+
+       @Test
+       public void emptyIndexFileResultsInWarning() {
+               project.setIndexFile("");
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("warning.empty-index", false)));
+       }
+
+       @Test
+       public void settingIndexFileWithoutExistingFileResultsInWarning() {
+               project.setIndexFile("test.html");
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("error.index-missing", true)));
+       }
+
+       @Test
+       public void usingNonHtmlMimeTypeForIndexFileResultsInWarning() {
+               project.getFileOption("index.html").setMimeType("text/plain");
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("warning.index-not-html", false)));
+       }
+
+       @Test
+       public void notInsertingTheIndexFileAnyFileResultsInError() {
+               project.getFileOption("index.html").setInsert(false);
+               project.getFileOption("index.html").setInsertRedirect(false);
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("error.index-not-inserted", true)));
+       }
+
+       @Test
+       public void insertingARedirectWithRedirectUrlResultsInError() {
+               project.getFileOption("index.html").setInsert(false);
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("error.no-custom-key", true, "index.html")));
+       }
+
+       @Test
+       public void insertingARedirectEmptyKeyUrlResultsInError() {
+               project.getFileOption("index.html").setInsert(false);
+               project.getFileOption("index.html").setCustomKey(null);
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("error.no-custom-key", true, "index.html")));
+       }
+
+       @Test
+       public void insertingARedirectToCHKUrlResultsInError() {
+               project.getFileOption("index.html").setInsert(false);
+               project.getFileOption("index.html").setCustomKey("CHK@");
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("error.no-custom-key", true, "index.html")));
+       }
+
+       @Test
+       public void notInsertingAnyFileResultsInError() {
+               project.getFileOption("index.html").setInsert(false);
+               project.getFileOption("index.html").setInsertRedirect(false);
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("error.no-files-to-insert", true)));
+       }
+
+       @Test
+       public void filesWithDuplicateTargetNamesResultInAnError() {
+               project.getFileOption("second.html").setChangedName("index.html");
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("error.duplicate-file", true, "index.html")));
+       }
+
+       @Test
+       public void filesWithLessThenOrEqualTo2MegabytesDoNotResultInWarning() throws Exception {
+               File largeFile = new File(temporaryFolder.getRoot(), "large.html");
+               Files.write(largeFile.toPath(), new byte[2 * 1048576], StandardOpenOption.CREATE_NEW);
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), not(hasItem(new Issue("warning.site-larger-than-2-mib", false))));
+       }
+
+       @Test
+       public void filesWithSizeOfMoreThan2MegabytesDoNotResultInWarning() throws Exception {
+               File largeFile = new File(temporaryFolder.getRoot(), "large.html");
+               Files.write(largeFile.toPath(), new byte[2 * 1048576 + 1], StandardOpenOption.CREATE_NEW);
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), hasItem(new Issue("warning.site-larger-than-2-mib", false)));
+       }
+
+       @Test
+       public void filesAreCorrectlyIgnoreForSizeCheckIfNotInserted() throws Exception {
+               File largeFile = new File(temporaryFolder.getRoot(), "large.html");
+               Files.write(largeFile.toPath(), new byte[2 * 1048576 + 1], StandardOpenOption.CREATE_NEW);
+               project.getFileOption("large.html").setInsert(false);
+               CheckReport checkReport = validateProject(project);
+               assertThat(checkReport.getIssues(), not(hasItem(new Issue("warning.site-larger-than-2-mib", false))));
+       }
+
+}