CodeSVby CA Technologies

Magic Strings

< Back

Prerequisites

CodeSV supports generation of Magic Strings. Magic Strings are basically references to information/data from an incoming request that will be replaced with actual values in the response from the service.

Magic strings functionality is turned ON by default and it is possible to disable it using disableMagicStrings() in the API as seen in the example:

forGet(URL)
       .doReturn(
           okMessage()
               .withJsonBody(JSON_EXAMPLES_PORTFOLIO)
               // By default magic strings are disabled
               .disableMagicStrings()
       );

Referencing Information From Request

Magic Strings have the pattern:

${prefix.key}

It is possible to reference three different types of information from the Request. Supported prefixes are:

  • argument
  • attribute
  • metadata

In the case of HTTP protocol the arguments of the request represent query parameters, metadata represents headers and attributes are URL parameters. For clarification see the following example:

Example of Magic strings

private static final String BASE_URL = "http://www.ca.com/portfolio";
 private static final String QUERY = "?year=2016&tokenQuery=X4sPhj15WQE";

 // http://www.ca.com/portfolio/{id}?year=2016&tokenQuery=X4sPhj15WQE
 private static final String URL = BASE_URL + "/{id}" + QUERY;

 private static final String JSON_EXAMPLES_PORTFOLIO = "{"
     + "\"portfolio\": {\n"
     + "   \"id\": \"${attribute.id}\",\n"
     + "   \"year\": \"${argument.year}\",\n"
     + "   \"language\": \"${metadata.Language}\",\n"
     + "   \"productNamesList\": [\n"
     + "    \"CA Server Automation\",\n"
     + "    \"CA Service Catalog\",\n"
     + "    \"CA Service Desk Manager\",\n"
     + "    \"CA Service Management\",\n"
     + "    \"CA Service Operations Insight\",\n"
     + "    \"CA Service Virtualization\"\n"
     + "  ]\n"
     + "}}";

 @Rule
 public VirtualServerRule vs = new VirtualServerRule();

 @Test
   public void testMagicString() throws Exception {
     forGet(URL)
         .matchesHeader("Language", is("en_us"))
         .matchesQuery("tokenQuery", isEqualIgnoringCaseTo("x4sphj15wqe"))
         .matchesQuery("year", "2016")
         .doReturn(
             okMessage()
                 .withJsonBody(JSON_EXAMPLES_PORTFOLIO)
         );
 
     HttpClient client = HttpClientBuilder.create().build();
     HttpGet request = new HttpGet(BASE_URL + "/1" + QUERY);
 
     // 2 headers with the same name and different values
     request.addHeader("Language", "en_us");
     request.addHeader("Language", "en_uk");
 
     HttpResponse response = client.execute(request);
 
     BufferedReader reader = new BufferedReader(
         new InputStreamReader(response.getEntity().getContent()));
     StringBuffer result = new StringBuffer();
     String line;
     while ((line = reader.readLine()) != null) {
       result.append(line);
     }
 
     String body = result.toString().replaceAll("\\s+", "");
 
     assertEquals(200, response.getStatusLine().getStatusCode());
     assertNotNull(body);
 
     assertTrue(body.contains("\"year\":\"2016\""));
     assertFalse(body.contains("${argument.year}"));
 
     assertTrue(body.contains("\"id\":\"1\""));
     assertFalse(body.contains("${attribute.id}"));
 
     // Only the first header value will be replace
     assertTrue(body.contains("\"language\":\"en_us\""));
     assertFalse(body.contains("${metadata.Language}"));
   }

For a complete example see: MagicStringExample

Template Reference

Another functionality of magic strings is to reference custom information from a request using a template. This is useful if basic magic strings are not enough for generating a custom response. To use templates you need to specify your template, using the special string matcher matchesTemplate(String) and reference it by using the template prefix in magic strings.

Example of Using Templates

public class TemplateReferenceExample {

  private static final String BASE_URL = "http://www.ca.com/portfolio";

  private static final String TEMPLATE = "Hello, {computer}. Do you read me, {computer2}?;"
      + "Affirmative, {user}. I read you.;"
      + "Open the pod bay doors! {plead}!";

  private static final String TEXT = "Hello, HAL. Do you read me, HAL?;"
      + "Affirmative, Dave. I read you.;"
      + "Open the pod bay doors! PLEASE!";

  private static final String REFERENCE =
      "Hello, ${template.computer}. Do you read me, ${template.computer2}?;"
          + "Affirmative, ${template.user}. I read you.;"
          + "Open the pod bay doors! ${template.plead}!";

  @Rule
  public VirtualServerRule vs = new VirtualServerRule();

  @Test
  public void testTemplateMagicString() throws Exception {
    forPost(BASE_URL)
        .matchesHeader("Language", matchesTemplate("Language of Text: {language}"))
        .matchesBody(matchesTemplate(TEMPLATE))
        .doReturn(
            okMessage()
                .withStringBody(REFERENCE)
                .withHeader("Language", "${template.language}")
                // By default magic strings are disabled
                .enableMagicStrings()
        );

    HttpClient client = HttpClientBuilder.create().build();
    HttpPost request = new HttpPost(BASE_URL);

    // 2 headers with the same name and different values
    request.addHeader("Language", "Language of Text: en_us");
    request.setEntity(new StringEntity(TEXT));
    HttpResponse response;

    response = client.execute(request);
    BufferedReader rd = new BufferedReader(
        new InputStreamReader(response.getEntity().getContent()));
    StringBuffer result = new StringBuffer();
    String line;
    while ((line = rd.readLine()) != null) {
      result.append(line);
    }

    String body = result.toString();

    assertEquals(200, response.getStatusLine().getStatusCode());
    assertNotNull(body);
    assertEquals(TEXT, body);
    assertEquals("en_us", response.getFirstHeader("Language").getValue());
  }
}

For a complete example see: TemplateReferenceExample