/* * Copyright (C) 2013 RoboVM AB * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * 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/gpl-2.0.html>. */ package org.robovm.libimobiledevice; import static org.junit.Assert.*; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.Enumeration; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.junit.AfterClass; import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.robovm.libimobiledevice.AfcClient.UploadProgressCallback; import org.robovm.libimobiledevice.InstallationProxyClient.Options; import org.robovm.libimobiledevice.InstallationProxyClient.Options.PackageType; import org.robovm.libimobiledevice.InstallationProxyClient.StatusCallback; import com.dd.plist.NSArray; import com.dd.plist.NSDictionary; import com.dd.plist.NSObject; /** * Tests {@link InstallationProxyClient}. */ public class InstallationProxyClientTest { static InstallationProxyClient client; static AfcClient afcClient; @BeforeClass public static void beforeClass() { if (NativeLibrary.supportedPlatform) { String[] udids = IDevice.listUdids(); if (udids.length > 0) { String udid = udids[0]; IDevice device = new IDevice(udid); LockdowndClient lockdowndClient = new LockdowndClient(device, null, true); LockdowndServiceDescriptor instproxyService = lockdowndClient.startService(InstallationProxyClient.SERVICE_NAME); client = new InstallationProxyClient(device, instproxyService); LockdowndServiceDescriptor afcService = lockdowndClient.startService(AfcClient.SERVICE_NAME); afcClient = new AfcClient(device, afcService); } } } @AfterClass public static void cleanup() { if (client != null) { client.dispose(); client = null; } } @Before public void setUp() { Assume.assumeTrue(client != null); } @Test public void testBrowse() throws Exception { NSArray array = client.browse(); NSDictionary safari = null; for (int i = 0; i < array.count(); i++) { NSDictionary dict = (NSDictionary) array.objectAtIndex(i); NSObject v = dict.objectForKey("CFBundleIdentifier"); if (v != null && "com.apple.mobilesafari".equals(v.toString())) { safari = dict; } } assertNotNull(safari); } //removed as test until it can be rewritten to re-sign the ipa public void testUpgradeIPA() throws Exception { Path tmpDir = Files.createTempDirectory(getClass().getSimpleName()); Files.copy(getClass().getResourceAsStream("/demo.ipa"), tmpDir.resolve("demo.ipa")); afcClient.upload(tmpDir.resolve("demo.ipa").toFile(), "/TestStaging", new UploadProgressCallback() { public void progress(File path, int percentComplete) { System.out.format("[%3d%%] Uploading %s\n", percentComplete, path); } public void success() { System.out.format("[100%%] Upload done\n"); } public void error(String message) { System.out.format("Error: %s\n", message); } }); final boolean[] success = new boolean[] {false}; final CountDownLatch countDownLatch = new CountDownLatch(1); client.upgrade("/TestStaging/demo.ipa", new Options(), new StatusCallback() { @Override public void progress(String status, int percentComplete) { System.out.format("[%3d%%] %s\n", percentComplete, status); } @Override public void success() { System.out.format("[100%%] Complete\n"); success[0] = true; countDownLatch.countDown(); } @Override public void error(String message) { System.out.println("Error: "+ message); countDownLatch.countDown(); } }); countDownLatch.await(10, TimeUnit.SECONDS); assertTrue(success[0]); } //removed as test until it can be rewritten to re-sign the ipa public void testUpgradeAppBundle() throws Exception { Path tmpDir = Files.createTempDirectory(getClass().getSimpleName()); Path ipaFile = tmpDir.resolve("demo.ipa"); Files.copy(getClass().getResourceAsStream("/demo.ipa"), ipaFile); extractZip(ipaFile, tmpDir); Path appDir = tmpDir.resolve("Payload/demo.app"); afcClient.upload(appDir.toFile(), "/TestStaging", new UploadProgressCallback() { public void progress(File path, int percentComplete) { System.out.format("[%3d%%] Uploading %s\n", percentComplete, path); } public void success() { System.out.format("[100%%] Upload done\n"); } public void error(String message) { System.out.format("Error: %s\n", message); } }); final boolean[] success = new boolean[] {false}; final CountDownLatch countDownLatch = new CountDownLatch(1); client.upgrade("/TestStaging/demo.app", new Options().packageType(PackageType.Developer), new StatusCallback() { @Override public void progress(String status, int percentComplete) { System.out.format("[%3d%%] %s\n", percentComplete, status); } @Override public void success() { System.out.format("[100%%] Complete\n"); success[0] = true; countDownLatch.countDown(); } @Override public void error(String message) { System.out.println("Error: "+ message); countDownLatch.countDown(); } }); countDownLatch.await(10, TimeUnit.SECONDS); assertTrue(success[0]); } protected void extractZip(Path zipFile, Path outDir) throws IOException { try (ZipFile archive = new ZipFile(zipFile.toFile())) { Enumeration<? extends ZipEntry> entries = archive.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); Path outFile = outDir.resolve(entry.getName()); if (entry.isDirectory()) { Files.createDirectories(outFile); } else { if (!Files.exists(outFile.getParent())) { Files.createDirectories(outFile.getParent()); } try (InputStream in = archive.getInputStream(entry)) { Files.copy(in, outFile); } } } } } }