/* * Catroid: An on-device visual programming system for Android devices * Copyright (C) 2010-2016 The Catrobat Team * (<http://developer.catrobat.org/credits>) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * An additional term exception under section 7 of the GNU Affero * General Public License, version 3, is available at * http://developer.catrobat.org/license_additional_term * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.catrobat.catroid.test.io; import android.test.InstrumentationTestCase; import org.catrobat.catroid.ProjectManager; import org.catrobat.catroid.common.Constants; import org.catrobat.catroid.common.FileChecksumContainer; import org.catrobat.catroid.common.LookData; import org.catrobat.catroid.common.SoundInfo; import org.catrobat.catroid.content.Project; import org.catrobat.catroid.content.Script; import org.catrobat.catroid.content.SingleSprite; import org.catrobat.catroid.content.Sprite; import org.catrobat.catroid.content.StartScript; import org.catrobat.catroid.content.WhenScript; import org.catrobat.catroid.content.bricks.Brick; import org.catrobat.catroid.content.bricks.ChangeXByNBrick; import org.catrobat.catroid.content.bricks.ChangeYByNBrick; import org.catrobat.catroid.content.bricks.ComeToFrontBrick; import org.catrobat.catroid.content.bricks.GoNStepsBackBrick; import org.catrobat.catroid.content.bricks.HideBrick; import org.catrobat.catroid.content.bricks.PlaceAtBrick; import org.catrobat.catroid.content.bricks.PlaySoundBrick; import org.catrobat.catroid.content.bricks.SetLookBrick; import org.catrobat.catroid.content.bricks.SetSizeToBrick; import org.catrobat.catroid.content.bricks.SetXBrick; import org.catrobat.catroid.content.bricks.SetYBrick; import org.catrobat.catroid.content.bricks.ShowBrick; import org.catrobat.catroid.content.bricks.WaitBrick; import org.catrobat.catroid.content.bricks.WhenStartedBrick; import org.catrobat.catroid.exceptions.ProjectException; import org.catrobat.catroid.io.StorageHandler; import org.catrobat.catroid.test.utils.TestUtils; import org.catrobat.catroid.utils.Utils; import java.io.File; import java.io.IOException; import java.util.ArrayList; public class MediaPathTest extends InstrumentationTestCase { private static final int IMAGE_FILE_ID = org.catrobat.catroid.test.R.raw.icon; private static final int SOUND_FILE_ID = org.catrobat.catroid.test.R.raw.testsound; private static final int BIGBLUE_ID = org.catrobat.catroid.test.R.raw.bigblue; private Project project; private File testImage; private File bigBlue; private File testSound; private File testImageCopy; private File testImageCopy2; private File testSoundCopy; private File bigBlue2; private File bigBlue3; private String imageName = "testImage.png"; private String soundName = "testSound.mp3"; private String projectName = "testProject7"; private String sceneName; private String bigBlueName = "bigblue.png"; @Override protected void setUp() throws Exception { TestUtils.clearProject(projectName); TestUtils.clearProject("mockProject"); project = new Project(getInstrumentation().getTargetContext(), projectName); sceneName = project.getDefaultScene().getName(); StorageHandler.getInstance().saveProject(project); ProjectManager.getInstance().setProject(project); ProjectManager.getInstance().setFileChecksumContainer(new FileChecksumContainer()); Project mockProject = new Project(getInstrumentation().getTargetContext(), "mockProject"); StorageHandler.getInstance().saveProject(mockProject); testImage = TestUtils.saveFileToProject(mockProject.getName(), mockProject.getDefaultScene().getName(), imageName, IMAGE_FILE_ID, getInstrumentation() .getContext(), TestUtils.TYPE_IMAGE_FILE); bigBlue = TestUtils.saveFileToProject(mockProject.getName(), mockProject.getDefaultScene().getName(), bigBlueName, BIGBLUE_ID, getInstrumentation() .getContext(), TestUtils.TYPE_IMAGE_FILE); testSound = TestUtils.saveFileToProject(mockProject.getName(), mockProject.getDefaultScene().getName(), soundName, SOUND_FILE_ID, getInstrumentation() .getContext(), TestUtils.TYPE_SOUND_FILE); //copy files with the Storagehandler copy function testImageCopy = StorageHandler.getInstance().copyImage(projectName, sceneName, testImage.getAbsolutePath(), null); testImageCopy2 = StorageHandler.getInstance().copyImage(projectName, sceneName, testImage.getAbsolutePath(), null); testSoundCopy = StorageHandler.getInstance().copySoundFile(testSound.getAbsolutePath()); } @Override protected void tearDown() throws Exception { TestUtils.clearProject(projectName); TestUtils.clearProject("mockProject"); super.tearDown(); } public void testPathsInProjectFile() throws IOException { fillProjectWithAllBricksAndMediaFiles(); String project = TestUtils.getProjectfileAsString(projectName); assertFalse("project contains DEFAULT_ROOT", project.contains(Constants.DEFAULT_ROOT)); assertFalse("project contains IMAGE_DIRECTORY", project.contains(Constants.IMAGE_DIRECTORY)); assertFalse("project contains SOUND_DIRECTORY", project.contains(Constants.SOUND_DIRECTORY)); assertFalse("project contains sdcard/", project.contains("sdcard/")); } public void testFilenameChecksum() throws IOException { fillProjectWithAllBricksAndMediaFiles(); String project = TestUtils.getProjectfileAsString(projectName); String checksumImage = Utils.md5Checksum(testImageCopy); String checksumSound = Utils.md5Checksum(testSoundCopy); String unexpectedImagenameTags = ">" + imageName + "<"; String unexpectedSoundnameTags = ">" + soundName + "<"; assertFalse("the imagename has no checksum", project.contains(unexpectedImagenameTags)); assertFalse("the soundname has no checksum", project.contains(unexpectedSoundnameTags)); String expectedImagename = checksumImage + "_" + imageName; String expectedSoundname = checksumSound + "_" + soundName; assertTrue("expected image name not in project", project.contains(expectedImagename)); assertTrue("expected sound name not in project", project.contains(expectedSoundname)); String expectedImagenameTags = ">" + checksumImage + "_" + imageName + "<"; String expectedSoundnameTags = ">" + checksumSound + "_" + soundName + "<"; assertTrue("unexpected imagename", project.contains(expectedImagenameTags)); assertTrue("unexpected soundname", project.contains(expectedSoundnameTags)); assertEquals("the copy does not equal the original image", Utils.md5Checksum(testImage), Utils.md5Checksum(testImageCopy)); assertEquals("the copy does not equal the original image", Utils.md5Checksum(testImage), Utils.md5Checksum(testImageCopy2)); assertEquals("the copy does not equal the original image", Utils.md5Checksum(testSound), Utils.md5Checksum(testSoundCopy)); //check if copy doesn't save more instances of the same file: File directory = new File(Constants.DEFAULT_ROOT + "/" + projectName + "/" + this.project.getDefaultScene().getName() + "/" + Constants.IMAGE_DIRECTORY); File[] filesImage = directory.listFiles(); //nomedia file is also in images folder assertEquals("Wrong amount of files in folder", 2, filesImage.length); } public void testCopyLargeImage() throws IOException, InterruptedException { StorageHandler storage = StorageHandler.getInstance(); bigBlue2 = storage.copyImage(projectName, sceneName, bigBlue.getAbsolutePath(), null); bigBlue3 = storage.copyImage(projectName, sceneName, bigBlue.getAbsolutePath(), null); fillProjectWithAllBricksAndMediaFiles(); File directory = new File(Constants.DEFAULT_ROOT + "/" + projectName + "/" + project.getDefaultScene().getName() + "/" + Constants.IMAGE_DIRECTORY); File[] filesImage = directory.listFiles(); //nomedia file is also in images folder assertEquals("Wrong amount of files in folder", 3, filesImage.length); assertNotSame("The image was not downsized", Utils.md5Checksum(bigBlue), Utils.md5Checksum(bigBlue2)); assertEquals("The copies are not the same", bigBlue2.hashCode(), bigBlue3.hashCode()); } public void testIncrementUsage() { FileChecksumContainer container = ProjectManager.getInstance().getFileChecksumContainer(); Sprite testSprite = new SingleSprite("testSprite"); ArrayList<LookData> lookDataList = new ArrayList<LookData>(); LookData lookData = new LookData(); lookData.setLookName("testLook"); lookData.setLookFilename(Utils.md5Checksum(testImage) + "_" + testImage.getName()); lookDataList.add(lookData); testSprite.setLookDataList(lookDataList); project.getDefaultScene().addSprite(testSprite); project.getDefaultScene().addSprite(testSprite.clone()); assertEquals("Usage counter has not been incremented!", 3, container.getUsage(Utils.md5Checksum(testImage))); } public void testDecrementUsage() { StorageHandler storageHandler = StorageHandler.getInstance(); storageHandler.deleteFile(testImageCopy.getAbsolutePath(), false); FileChecksumContainer container = ProjectManager.getInstance().getFileChecksumContainer(); assertTrue("checksum not in project although file should exist", container.containsChecksum(Utils.md5Checksum(testImageCopy))); storageHandler.deleteFile(testImageCopy2.getAbsolutePath(), false); assertFalse("checksum in project although file should not exist", container.containsChecksum(Utils.md5Checksum(testImageCopy2))); File directory = new File(Constants.DEFAULT_ROOT + "/" + projectName + "/" + project.getDefaultScene().getName() + "/" + Constants.IMAGE_DIRECTORY); File[] filesImage = directory.listFiles(); //nomedia file is also in images folder assertEquals("Wrong amount of files in folder - delete unsuccessfull", 1, filesImage.length); storageHandler.deleteFile(testImageCopy.getAbsolutePath(), false); //there a FileNotFoundException is thrown and caught (this is expected behavior) } public void testContainerOnLoadProject() throws IOException { fillProjectWithAllBricksAndMediaFiles(); ProjectManager projectManager = ProjectManager.getInstance(); String checksumImage = Utils.md5Checksum(testImage); String checksumSound = Utils.md5Checksum(testSound); projectManager.setFileChecksumContainer(null); //hack to delete the filechecksumcontainer and see if a new one is created on load try { ProjectManager.getInstance().loadProject(projectName, getInstrumentation().getTargetContext()); assertTrue("Load project worked correctly", true); } catch (ProjectException projectException) { fail("Project is not loaded successfully"); } assertTrue("does not contain checksum", projectManager.getFileChecksumContainer().containsChecksum(checksumImage)); assertTrue("does not contain checksum", projectManager.getFileChecksumContainer().containsChecksum(checksumSound)); assertFalse("returns true even when the checksum is for sure not added", projectManager .getFileChecksumContainer().containsChecksum(checksumImage + "5")); assertEquals("The path to the file is not found or wrong", testImageCopy.getAbsolutePath(), projectManager .getFileChecksumContainer().getPath(checksumImage)); assertEquals("The path to the file is not found or wrong", testSoundCopy.getAbsolutePath(), projectManager .getFileChecksumContainer().getPath(checksumSound)); } public void testFileChecksumContainerNotInProjectFile() throws IOException { fillProjectWithAllBricksAndMediaFiles(); String projectString = TestUtils.getProjectfileAsString(projectName); assertFalse("FileChecksumcontainer is in the project", projectString.contains("FileChecksumContainer")); try { ProjectManager.getInstance().loadProject(projectName, getInstrumentation().getTargetContext()); assertTrue("Load project worked correctly", true); } catch (ProjectException projectException) { fail("Project is not loaded successfully"); } projectString = TestUtils.getProjectfileAsString(projectName); assertFalse("FileChecksumcontainer is in the project", projectString.contains("FileChecksumContainer")); } public void testLookDataListAndSoundInfoListInProjectFile() throws IOException { fillProjectWithAllBricksAndMediaFiles(); String projectString = TestUtils.getProjectfileAsString(projectName); assertTrue("LookDataList not in project", projectString.contains("lookList")); assertTrue("SoundList not in project", projectString.contains("soundList")); try { ProjectManager.getInstance().loadProject(projectName, getInstrumentation().getTargetContext()); } catch (ProjectException projectException) { fail("Project is not loaded successfully"); } projectString = TestUtils.getProjectfileAsString(projectName); assertTrue("LookDataList not in project", projectString.contains("lookList")); assertTrue("SoundList not in project", projectString.contains("soundList")); } private void fillProjectWithAllBricksAndMediaFiles() throws IOException { Sprite sprite = new SingleSprite("testSprite"); Script script = new StartScript(); Script whenScript = new WhenScript(); sprite.addScript(script); sprite.addScript(whenScript); project.getDefaultScene().addSprite(sprite); SetLookBrick lookBrick2 = new SetLookBrick(); LookData lookData = new LookData(); lookData.setLookFilename(testImageCopy2.getName()); lookData.setLookName("testImageCopy2"); lookBrick2.setLook(lookData); sprite.getLookDataList().add(lookData); ArrayList<Brick> brickList1 = new ArrayList<Brick>(); ArrayList<Brick> brickList2 = new ArrayList<Brick>(); brickList1.add(new ChangeXByNBrick(4)); brickList1.add(new ChangeYByNBrick(5)); brickList1.add(new ComeToFrontBrick()); brickList1.add(new GoNStepsBackBrick(5)); brickList1.add(new HideBrick()); brickList1.add(new WhenStartedBrick(script)); brickList1.add(lookBrick2); SetLookBrick lookBrick = new SetLookBrick(); lookData = new LookData(); lookData.setLookFilename(testImageCopy.getName()); lookData.setLookName("testImageCopy"); lookBrick.setLook(lookData); sprite.getLookDataList().add(lookData); PlaySoundBrick soundBrick = new PlaySoundBrick(); SoundInfo soundInfo = new SoundInfo(); soundInfo.setSoundFileName(testSoundCopy.getName()); soundInfo.setTitle("title"); soundBrick.setSoundInfo(soundInfo); sprite.getSoundList().add(soundInfo); brickList2.add(new PlaceAtBrick(50, 50)); brickList2.add(soundBrick); brickList2.add(new SetSizeToBrick(50)); brickList2.add(lookBrick); brickList2.add(new SetXBrick(50)); brickList2.add(new SetYBrick(50)); brickList2.add(new ShowBrick()); brickList2.add(new WaitBrick(1000)); for (Brick brick : brickList1) { script.addBrick(brick); } for (Brick brick : brickList2) { whenScript.addBrick(brick); } StorageHandler.getInstance().saveProject(project); } }