Package com.getperka.flatpack.demo.client

Source Code of com.getperka.flatpack.demo.client.ClientSmokeTest

/*
* #%L
* FlatPack Demonstration Client
* %%
* Copyright (C) 2012 Perka Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package com.getperka.flatpack.demo.client;

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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import javax.ws.rs.core.UriBuilder;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import com.getperka.flatpack.Configuration;
import com.getperka.flatpack.FlatPack;
import com.getperka.flatpack.FlatPackEntity;
import com.getperka.flatpack.client.StatusCodeException;
import com.getperka.flatpack.demo.server.DemoServer;

/**
* Contains a variety of smoke tests to demonstrate various facets of the FlatPack stack.
*/
public class ClientSmokeTest {

  private static final int PORT = 8111;

  /**
   * Spin up an instance of the demo server.
   */
  @BeforeClass
  public static void beforeClass() {
    assertTrue(new DemoServer().start(PORT));
  }

  private ClientApi api;
  private Random random;

  /**
   * Creates an instance of the ClientApi.
   */
  @Before
  public void before() throws IOException {
    random = new Random(0);

    Configuration config = new Configuration()
        .addTypeSource(ClientTypeSource.get());
    api = new ClientApi(FlatPack.create(config));
    api.setServerBase(UriBuilder.fromUri("http://localhost").port(PORT).build());
    api.setVerbose(true);
    assertEquals(204, api.resetPost().execute().getResponseCode());
  }

  /**
   * Demonstrates ConstraintViolation handling. ConstraintViolations are returned as a simple
   * {@code string:string} map in the FlatPackEntity's {@code error} block. The goal is to provide
   * enough context for user interfaces to present the error message in a useful way, without
   * assuming that the client is a Java app.
   */
  @Test
  public void testConstraintViolation() throws IOException {
    Product p = makeProduct();
    p.setPrice(BigDecimal.valueOf(-1));

    FlatPackEntity<?> entity = null;
    try {
      api.productsPut(Collections.singletonList(p))
          .queryParameter("isAdmin", "true")
          .execute();
      fail("Should have seen StatusCodeException");
    } catch (StatusCodeException e) {
      // The 400 status code is returned by the service method.
      assertEquals(400, e.getStatusCode());
      /*
       * If the server returned a valid flatpack-encoded response, it can be retrieved from the
       * StatusCodeException. Otherwise, this method will return null.
       */
      entity = e.getEntity();
    }

    // Pull out the error messages
    Map<String, String> errors = entity.getExtraErrors();
    assertNotNull(errors);
    assertEquals(1, errors.size());
    Map.Entry<String, String> entry = errors.entrySet().iterator().next();
    assertEquals("price", entry.getKey());
    assertEquals("must be greater than or equal to 0", entry.getValue());
  }

  /**
   * Demonstrates how generated client API will present a non-FlatPack resource (as an
   * HttpUrlConnection).
   */
  @Test
  public void testNonFlatpackEndpoint() throws IOException {
    // The query parameters are added as a builder-style pattern
    HttpURLConnection conn = api.helloGet().withName("ClientSmokeTest").execute();
    assertEquals(200, conn.getResponseCode());
    BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),
        Charset.forName("UTF8")));
    assertEquals("Hello ClientSmokeTest!", reader.readLine());
  }

  /**
   * Demonstrates the use of roles to restrict property setters.
   */
  @Test
  public void testRolePropertyAccess() throws IOException {
    // Create a Product
    Product p = new Product();
    UUID uuid = p.getUuid();
    p.setName("Product");
    p.setNotes("Some notes");
    p.setPrice(BigDecimal.valueOf(42));
    api.productsPut(Collections.singletonList(p))
        .queryParameter("isAdmin", "true")
        .execute();

    // Try to update it with a non-admin request
    p = new Product();
    p.setUuid(uuid);
    p.setPrice(BigDecimal.valueOf(1));
    api.productsPut(Collections.singletonList(p)).execute();

    // Verify that nothing changed, as nobody
    List<Product> products = api.productsGet().execute().getValue();
    assertEquals(1, products.size());
    p = products.get(0);
    // Same UUID
    assertEquals(uuid, p.getUuid());
    // Unchanged price
    assertEquals(BigDecimal.valueOf(42), p.getPrice());
    // Can't see the notes
    assertNull(p.getNotes());

    // Now try the update again, as an admin
    p = new Product();
    p.setUuid(uuid);
    p.setPrice(BigDecimal.valueOf(99));
    api.productsPut(Collections.singletonList(p))
        .queryParameter("isAdmin", "true")
        .execute();

    // Verify the changes, as nobody
    products = api.productsGet().execute().getValue();
    assertEquals(1, products.size());
    p = products.get(0);
    // Same UUID
    assertEquals(uuid, p.getUuid());
    // Unchanged price
    assertEquals(BigDecimal.valueOf(99), p.getPrice());
  }

  /**
   * Demonstrates a couple of round-trips to the server.
   */
  @Test
  public void testSimpleGetAndPut() throws IOException {
    List<Product> products = api.productsGet().execute().getValue();
    assertEquals(0, products.size());

    // A server error would be reported as a StatusCodeException, a subclass of IOException
    api.productsPut(Arrays.asList(makeProduct(), makeProduct()))
        .queryParameter("isAdmin", "true")
        .execute();

    /*
     * The object returned from productsGet() is an endpoint-specific interface that may contain
     * additional fluid setters for declared query parameters. It also provides access to some
     * request internals, including the FlatPackEntity that will be sent as part of the request.
     * This allows callers to further customize outgoing requests, in the above case to add the
     * isAdmin query parameter that interacts with the DummyAuthenticator. The call to execute()
     * triggers payload serialization and execution of the HTTP request. This returns a
     * FlatPackEntity describing the response, and getValue() returns the primary value object
     * contained in the payload.
     */
    FlatPackEntity<List<Product>> entity = api.productsGet().execute();
    assertTrue(entity.getExtraErrors().toString(), entity.getExtraErrors().isEmpty());
    assertTrue(entity.getExtraWarnings().toString(), entity.getExtraWarnings().isEmpty());
    products = entity.getValue();
    assertEquals(2, products.size());
    assertEquals(BigDecimal.valueOf(360), products.get(0).getPrice());
    assertEquals(BigDecimal.valueOf(948), products.get(1).getPrice());
    assertTrue(products.get(0).wasPersistent());
    assertTrue(products.get(1).wasPersistent());

    // Try to update one of the objects
    Product p = products.get(0);
    p.setPrice(BigDecimal.valueOf(99));
    assertEquals(Collections.singleton("price"), p.dirtyPropertyNames());
    api.productsPut(Collections.singletonList(p)).queryParameter("isAdmin", "true").execute();

    // Re-fetch and verify update
    products = api.productsGet().execute().getValue();
    assertEquals(99, products.get(0).getPrice().intValue());
    assertTrue(products.get(0).dirtyPropertyNames().isEmpty());
  }

  private Product makeProduct() {
    Product p = new Product();
    p.setName("ClientSmokeTest");
    p.setPrice(BigDecimal.valueOf(random.nextInt(1000)));
    return p;
  }
}
TOP

Related Classes of com.getperka.flatpack.demo.client.ClientSmokeTest

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.