package com.faforever.client.patch; import com.faforever.client.i18n.I18n; import com.faforever.client.preferences.ForgedAlliancePrefs; import com.faforever.client.preferences.Preferences; import com.faforever.client.preferences.PreferencesService; import com.faforever.client.task.TaskService; import com.faforever.client.test.AbstractPlainJavaFxTest; import com.faforever.client.util.TestResources; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.mockito.Mock; import org.springframework.core.env.Environment; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; import java.util.concurrent.TimeUnit; import static com.faforever.client.patch.GitRepositoryGameUpdateService.InstallType.RETAIL; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.*; import static org.mockito.Mockito.when; public class GitCheckGameUpdateTaskTest extends AbstractPlainJavaFxTest { private static final String GIT_PATCH_URL = "git://dummy/repo.git"; private static final long TIMEOUT = 5000; private static final TimeUnit TIMEOUT_UNIT = TimeUnit.MILLISECONDS; @Rule public final TemporaryFolder reposDirectory = new TemporaryFolder(); @Rule public final TemporaryFolder fafBinDirectory = new TemporaryFolder(); @Rule public final TemporaryFolder faDirectory = new TemporaryFolder(); /** * The directory containing the cloned patch repository */ private Path binaryPatchRepoDirectory; private GitCheckGameUpdateTask instance; @Mock private TaskService taskService; @Mock private Environment environment; @Mock private GitWrapper gitWrapper; @Mock private I18n i18n; @Mock private PreferencesService preferencesService; @Mock private Preferences preferences; @Mock private ForgedAlliancePrefs forgedAlliancePrefs; @Before public void setUp() throws Exception { instance = new GitCheckGameUpdateTask(); instance.environment = environment; instance.preferencesService = preferencesService; instance.i18n = i18n; instance.gitWrapper = gitWrapper; Path reposDirectory = faDirectory.getRoot().toPath().resolve("repos"); binaryPatchRepoDirectory = reposDirectory.resolve(GitRepositoryGameUpdateService.REPO_NAME); instance.setBinaryPatchRepoDirectory(binaryPatchRepoDirectory); instance.setMigrationDataFile(binaryPatchRepoDirectory.resolve(RETAIL.migrationDataFileName)); when(preferencesService.getFafReposDirectory()).thenReturn(reposDirectory); when(preferencesService.getFafBinDirectory()).thenReturn(fafBinDirectory.getRoot().toPath()); when(preferencesService.getPreferences()).thenReturn(preferences); when(preferences.getForgedAlliance()).thenReturn(forgedAlliancePrefs); when(forgedAlliancePrefs.getPath()).thenReturn(faDirectory.getRoot().toPath()); when(environment.getProperty("patch.git.url")).thenReturn(GIT_PATCH_URL); } @Test public void testCheckForUpdatesInBackgroundRepoDirectoryMissing() throws Exception { assertTrue(Files.notExists(binaryPatchRepoDirectory)); assertThat(instance.call(), is(true)); } @Test public void testCheckForUpdatesInBackgroundRemoteHeadDifferent() throws Exception { Files.createDirectories(binaryPatchRepoDirectory); when(gitWrapper.getLocalHead(binaryPatchRepoDirectory)).thenReturn("1234"); when(gitWrapper.getRemoteHead(binaryPatchRepoDirectory)).thenReturn("5678"); assertThat(instance.call(), is(true)); } @Test public void testCheckForUpdatesInBackgroundLocalFilesMissing() throws Exception { prepareLocalPatchRepo(); when(gitWrapper.getLocalHead(binaryPatchRepoDirectory)).thenReturn("1234"); when(gitWrapper.getRemoteHead(binaryPatchRepoDirectory)).thenReturn("1234"); assertThat(instance.call(), is(true)); } private void prepareLocalPatchRepo() throws IOException { TestResources.copyResource("/patch/retail.json", binaryPatchRepoDirectory.resolve(RETAIL.migrationDataFileName)); TestResources.copyResource("/patch/bsdiff4/040943c20d9e1f7de7f496b1202a600d", binaryPatchRepoDirectory.resolve("bsdiff4/040943c20d9e1f7de7f496b1202a600d")); } @Test public void testCheckForUpdatesInBackgroundFileOutOfDate() throws Exception { prepareLocalPatchRepo(); // Copy all files to the FAF bin directory as if they were patched Path fafBinPath = fafBinDirectory.getRoot().toPath(); TestResources.copyResource("/patch/GDFBinary.dll", fafBinPath.resolve("GDFBinary.dll")); TestResources.copyResource("/patch/testFile1.txt", fafBinPath.resolve("testFile1.txt")); TestResources.copyResource("/patch/testFile2.txt", fafBinPath.resolve("fooBar.exe")); // Then modify one file Files.write(fafBinPath.resolve("testFile1.txt"), Collections.singletonList("foo")); when(gitWrapper.getLocalHead(binaryPatchRepoDirectory)).thenReturn("1234"); when(gitWrapper.getRemoteHead(binaryPatchRepoDirectory)).thenReturn("1234"); assertThat(instance.call(), is(true)); } @Test public void testCheckForUpdatesInBackgroundEverythingUpToDate() throws Exception { prepareLocalPatchRepo(); prepareFaBinaries(); GitGameUpdateTask gitGameUpdateTask = new GitGameUpdateTask(); gitGameUpdateTask.environment = environment; gitGameUpdateTask.gitWrapper = gitWrapper; gitGameUpdateTask.i18n = i18n; gitGameUpdateTask.preferencesService = preferencesService; gitGameUpdateTask.setMigrationDataFile(binaryPatchRepoDirectory.resolve(RETAIL.migrationDataFileName)); gitGameUpdateTask.setBinaryPatchRepoDirectory(binaryPatchRepoDirectory); gitGameUpdateTask.call(); when(gitWrapper.getLocalHead(binaryPatchRepoDirectory)).thenReturn("1234"); when(gitWrapper.getRemoteHead(binaryPatchRepoDirectory)).thenReturn("1234"); assertThat(instance.call(), is(false)); } private void prepareFaBinaries() throws IOException { Path faBinDirectory = faDirectory.getRoot().toPath().resolve("bin"); Files.createDirectories(faBinDirectory); TestResources.copyResource("/patch/GDFBinary.dll", faBinDirectory.resolve("GDFBinary.dll")); TestResources.copyResource("/patch/testFile1.txt", faBinDirectory.resolve("testFile1.txt")); TestResources.copyResource("/patch/testFile2.txt", faBinDirectory.resolve("testFile2.txt")); } @Test public void testCheckForUpdatesInBackgroundPatchingIsNeededBecauseRepoDirDoesntExist() throws Exception { assertThat(instance.call(), is(true)); } }