Package org.dtk.resources

Source Code of org.dtk.resources.PackagesIntegrationTest

package org.dtk.resources;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.InputStreamBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.codehaus.jackson.map.ObjectMapper;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.junit.Test;

import org.dtk.util.Options;

/**
* Test the RESTful Packages API. This API provides access to the packages
* available to the build system, allowing a user to retrieve a list of all
* packages present, retrieve details about specific packages (versions and
* modules) and create temporary packages from user applications.
*
* @author James Thomas
*/

public class PackagesIntegrationTest {

  /**
   * Service end point path.
   */ 
  final protected String packageAPIPath = "/api/packages/";

  /**
   * Test normal path through the code. Retrieve all packages
   * available and for each one, validate retrieval of package
   * versions and module details.
   *
   * @throws URISyntaxException
   * @throws IOException
   * @throws ClientProtocolException
   */
  @Test
  public void test_RetrievePackageList() throws URISyntaxException, ClientProtocolException, IOException {
    HttpResponse response = generateDefaultPackageRequest();
   
    assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
   
    // Convert resposne from JSON object to generic map structure.
    ObjectMapper om = new ObjectMapper()
    Map<String, List> packageDetails = om.readValue(response.getEntity().getContent(), Map.class);
   
    // Validate required build parameters are returned, each list should
    // be non-empty and conform the given format.
    validateNonEmptyParameterList(packageDetails.get("optimise"));
    validateNonEmptyParameterList(packageDetails.get("cdn"));
   
    // Retrieve list of available packages. For each package,
    // retrieve package versions and modules.
    List<Map<String,String>> packagesList = packageDetails.get("packages");
    assertNotNull(packagesList);
    assertTrue(packagesList.size() > 0);
   
    // Each package should contain a name and link to the versions resource
    // for that package.
    Iterator<Map<String,String>> iter = packagesList.iterator();
    while(iter.hasNext()) {
      Map<String, String> packageInfo = iter.next();
      String packageName = packageInfo.get("name"), versionsLink = packageInfo.get("link");
      assertNotNull(packageName);
      assertNotNull(versionsLink);
      validatePackageVersions(versionsLink);
    }
  }
 
  /**
   * Retrieve version information for given package. Verify response
   * corresponds to expected format. For each version, check expected
   * response is returned.
   *
   * @param packageVersionsLink - URL corresponding to a package's version resource.
   * @throws ClientProtocolException
   * @throws URISyntaxException
   * @throws IOException
   */
  public void validatePackageVersions(String packageVersionsLink) throws ClientProtocolException, URISyntaxException, IOException {
    HttpResponse response = jsonGetRequest(new URL(packageVersionsLink));
    assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
   
    ObjectMapper om = new ObjectMapper()
    List<Map<String, String>> packageVersions = om.readValue(response.getEntity().getContent(), List.class);
   
    assertNotNull(packageVersions);
    assertTrue(packageVersions.size() > 0);
   
    Iterator<Map<String, String>> iter = packageVersions.iterator();
   
    while(iter.hasNext()) {
      Map<String, String> packageVersion = iter.next();
      String versionLabel = packageVersion.get("name"), versionLink = packageVersion.get("link");
      assertNotNull(versionLabel);
      assertNotNull(versionLink);
      validatePackageVersionDetails(versionLink);
    }
  }
 
  /**
   * Retrieve details for a package version, using passed link, and
   * verify that response contains name, description and modules values.
   * The "modules" value should be a collection of lists with two string
   * elements, corresponding to module name and description.
   *
   * @param packageVersionLink - URL to retrieve package version details from.
   * @throws ClientProtocolException
   * @throws MalformedURLException
   * @throws URISyntaxException
   * @throws IOException
   */
  public void validatePackageVersionDetails(String packageVersionLink) throws ClientProtocolException, MalformedURLException, URISyntaxException, IOException {
    HttpResponse response = jsonGetRequest(new URL(packageVersionLink));
    assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
   
    // Convert JSON objet to generic map collection.
    ObjectMapper om = new ObjectMapper()
    Map<String, Object> details = om.readValue(response.getEntity().getContent(), Map.class);
   
    // Package details must contain a full name and description.
    assertNotNull(details.get("description"));
    assertNotNull(details.get("name"));
   
    // Retrieve and verify each module is an array with two elements (name and desc).
    List<List<String>> packageModules = (List<List<String>>) details.get("modules");
    assertNotNull(packageModules);
    assertTrue(packageModules.size() > 0);
   
    Iterator<List<String>> iter = packageModules.iterator();
    while(iter.hasNext()) {
      List<String> module = iter.next();
      assertEquals(2, module.size());
    }
  }
 
  /**
   * Retrieve an invalid package version. API should
   * respond with a standard 404. Generate random
   * package name to access.
   *
   * @throws IOException
   * @throws URISyntaxException
   * @throws ClientProtocolException
   */
  @Test
  public void test_RetrieveVersionsForInvalidPackage() throws ClientProtocolException, URISyntaxException, IOException {
    // Generate random package name to retrieve.
    String randomPackageName = RandomStringUtils.randomAlphabetic(32);
    URL invalidPackageResource = new URL(Options.getTestAPILocation(packageAPIPath) + randomPackageName);
    HttpResponse response = jsonGetRequest(invalidPackageResource);
    assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusLine().getStatusCode())
  }
 
  /**
   * Test the retrieval of package details for a valid package but
   * with an invalid version. Use the first package returned from
   * the global resource list with a pseudo-random version identifier.
   * Service should response with a HTTP 404.
   *
   * @throws ClientProtocolException
   * @throws MalformedURLException
   * @throws URISyntaxException
   * @throws IOException
   */
  @Test
  public void test_RetrieveDetailsForValidPackageAndInvalidVersion() throws ClientProtocolException, MalformedURLException, URISyntaxException, IOException {
    // Retrieve actual list of packages and pick first one found.
    HttpResponse response = generateDefaultPackageRequest();
    assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
   
    // Convert response from JSON object to generic map structure.
    ObjectMapper om = new ObjectMapper()
    Map<String, List> packageDetails = om.readValue(response.getEntity().getContent(), Map.class);
   
    // Retrieve list of available packages and just pick first one.
    String packageVersionsLink = ((Map<String, String>) packageDetails.get("packages").get(0)).get("link");
   
    // Generate random package version to retrieve.
    String randomPackageName = RandomStringUtils.randomAlphabetic(32);
    URL invalidPackageResource = new URL(packageVersionsLink + "/" + randomPackageName);
    response = jsonGetRequest(invalidPackageResource);
   
    // API should return a standard HTTP 404 code.
    assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusLine().getStatusCode())
  }
 
  /**
   * Test retrieval of package details for an invalid package. Service should
   * respond with a standard HTTP 404.
   *
   * @throws ClientProtocolException
   * @throws URISyntaxException
   * @throws IOException
   */
  @Test
  public void test_RetrieveInvalidPackageAndInvalidVersionDetails() throws ClientProtocolException, URISyntaxException, IOException {
    // Generate random package name to retrieve.
    String randomChars = RandomStringUtils.randomAlphabetic(32);
    URL invalidPackageResource = new URL(Options.getTestAPILocation(packageAPIPath) + randomChars + "/" + randomChars);
    HttpResponse response = jsonGetRequest(invalidPackageResource);
    assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusLine().getStatusCode())
  }
 
  /**
   * Test the creation of a new package, from a compressed user application.
   * Create the POST request, containing multipart form fields, and check response
   * contains a package identifier for the temporary package along with module dependencies.
   *
   * @throws URISyntaxException
   * @throws IOException
   * @throws ClientProtocolException
   */
  @Test
  public void test_CreateNewPackage() throws URISyntaxException, ClientProtocolException, IOException {
    // Create HTTP Post request to base package URL
    URL url = new URL(Options.getTestAPILocation(packageAPIPath));
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost(url.toURI());
   
    // We want to upload our sample application, containing custom module
    // definitions and DTK dependencies.
    MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
   
    InputStream is = getClass().getClassLoader().getResourceAsStream("user_app.zip");   
    InputStreamBody bin = new InputStreamBody(is, "application/zip", "user_app.zip");
    reqEntity.addPart("user_app", bin);
   
    httpPost.setEntity(reqEntity);
    HttpResponse response = httpclient.execute(httpPost);
   
    // HTTP 201, resource was created.
    assertEquals(HttpStatus.SC_CREATED, response.getStatusLine().getStatusCode());
   
    // Check for HTML encompassed JSON response.
    String httpEncodedJson = IOUtils.toString(response.getEntity().getContent());
   
    // Extract JSON from textarea tag in returned HTML.
    Document doc = Jsoup.parse(httpEncodedJson);
    Elements textareas = doc.getElementsByTag("textarea");
    String jsonContent = textareas.get(0).text();
   
    // Convert JSON objet to generic map collection.
    ObjectMapper om = new ObjectMapper()
    Map<String, Object> details = om.readValue(jsonContent, Map.class);
   
    // Extract response values for standard Dojo modules within user application,
    // user defined custom modules and reference id for new package. Confirm they
    // match our expected values.
    List<String> dojoModules = (List<String>) details.get("requiredDojoModules");
    Collections.sort(dojoModules);
    assertEquals(Arrays.asList("dijit.form.Button", "dojo.cache", "dojox.form.BusyButton"),
      dojoModules);
   
    // Make sure list elements are in the same order
    List<String> availableModules = (List<String>) details.get("availableModules");
    Collections.sort(availableModules);
   
    assertEquals(Arrays.asList("user_app.module_a", "user_app.module_b", "user_app.module_c", "user_app.util.util"),
      availableModules);
   
    List<Map<String, String>> packages = (List<Map<String, String>>) details.get("packages");
   
    assertEquals(packages.size(), 1);
    Map<String, String> tempPackage = packages.get(0);   
    assertNotNull(tempPackage.get("name"));
    assertNotNull(tempPackage.get("version"));
  }
 
  /**
   * Test a new package creation request with the missing body
   * parameter containing the actual user application zip. Service
   * should response with a status code 400. 
   *
   * @throws URISyntaxException
   * @throws IOException
   * @throws ClientProtocolException
   *
   */
  @Test
  public void test_CreateNewPackageMissingResource() throws URISyntaxException, ClientProtocolException, IOException {
    // Create HTTP Post request to base package URL
    URL url = new URL(Options.getTestAPILocation(packageAPIPath));
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost(url.toURI());
   
    // We want to upload our sample application, containing custom module
    // definitions and DTK dependencies.
    MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
   
    httpPost.setEntity(reqEntity);
    HttpResponse response = httpclient.execute(httpPost);
   
    // HTTP 400, invalid request.
    assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusLine().getStatusCode());
  }
 
  /**
   * Validate a parameter list. The parameter list should be non-empty
   * and contain map collections, which contain non-null values for the
   * keys "value" and "label".
   *
   * @param parameterList - Collection of parameters object, containing
   * value and label atrributes.
   */
  protected void validateNonEmptyParameterList (List<Map<String, String>> parameterList) {
    // Check list has at least one member.
    assertNotNull(parameterList);
    assertTrue(parameterList.size() > 0);
    // Check all members for non-null value and label attributes
    Iterator<Map<String, String>> iter = parameterList.iterator();
   
    while(iter.hasNext()) {
      Map<String, String> parameter = iter.next();
      assertNotNull(parameter.get("value"));
      assertNotNull(parameter.get("label"))
    }
  }
 
  /**
   * Generate the default package request for all package and
   * compiler details.
   *
   * @return HTTP response for request
   * @throws ClientProtocolException
   * @throws MalformedURLException
   * @throws URISyntaxException
   * @throws IOException
   */
  protected HttpResponse generateDefaultPackageRequest() throws ClientProtocolException, MalformedURLException, URISyntaxException, IOException {
    return jsonGetRequest(new URL(Options.getTestAPILocation(packageAPIPath)));
  }
 
  /**
   * Generate a HTTP GET request for JSON content to the
   * specified URL.
   *
   * @param resourceLocation - URL for request.
   * @return HTTP response for request
   * @throws URISyntaxException
   * @throws ClientProtocolException
   * @throws IOException
   */
  protected HttpResponse jsonGetRequest(URL resourceLocation) throws URISyntaxException, ClientProtocolException, IOException {
    // Set up HTTP client connection....
    HttpClient httpClient = new DefaultHttpClient();
    HttpGet httpGet = new HttpGet(resourceLocation.toURI());
   
    // Content type headers
    httpGet.setHeader("Content-Type", "application/json");
    httpGet.setHeader("Accept", "application/json");
   
    return httpClient.execute(httpGet);
  }
}
TOP

Related Classes of org.dtk.resources.PackagesIntegrationTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.