Package org.waveprotocol.box.server.robots.operations

Source Code of org.waveprotocol.box.server.robots.operations.DocumentModifyServiceTest

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.
*/

package org.waveprotocol.box.server.robots.operations;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.wave.api.Element;
import com.google.wave.api.ElementType;
import com.google.wave.api.Gadget;
import com.google.wave.api.InvalidRequestException;
import com.google.wave.api.OperationRequest;
import com.google.wave.api.OperationType;
import com.google.wave.api.Range;
import com.google.wave.api.JsonRpcConstant.ParamsProperty;
import com.google.wave.api.OperationRequest.Parameter;
import com.google.wave.api.data.ApiView;
import com.google.wave.api.data.ApiView.ElementInfo;
import com.google.wave.api.impl.DocumentModifyAction;
import com.google.wave.api.impl.DocumentModifyAction.BundledAnnotation;
import com.google.wave.api.impl.DocumentModifyAction.ModifyHow;
import com.google.wave.api.impl.DocumentModifyQuery;

import org.waveprotocol.box.server.robots.RobotsTestBase;
import org.waveprotocol.box.server.robots.testing.OperationServiceHelper;
import org.waveprotocol.wave.model.conversation.ObservableConversationBlip;
import org.waveprotocol.wave.model.document.Document;
import org.waveprotocol.wave.model.document.util.LineContainers;
import org.waveprotocol.wave.model.document.util.XmlStringBuilder;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
* Unit tests for {@link DocumentModifyService}.
*
* @author ljvderijk@google.com (Lennard de Rijk)
*/
public class DocumentModifyServiceTest extends RobotsTestBase {

  private static final String NO_ANNOTATION_KEY = null;
  private static final List<String> NO_VALUES = Collections.<String> emptyList();
  private static final List<BundledAnnotation> NO_BUNDLED_ANNOTATIONS = Collections.emptyList();
  private static final List<Element> NO_ELEMENTS = Collections.emptyList();
  private static final String ANNOTATION_VALUE = "annotationValue";
  private static final String ANNOTATION_KEY = "annotationKey";
  private static final String INITIAL_CONTENT = "Hello world!";
  private static final int CONTENT_START_TEXT = 1;
  private static final int CONTENT_START_XML = 3;

  private DocumentModifyService service;
  private OperationServiceHelper helper;
  private String rootBlipId;

  @Override
  protected void setUp() throws Exception {
    service = DocumentModifyService.create();
    helper = new OperationServiceHelper(WAVELET_NAME, ALEX);

    ObservableConversationBlip rootBlip = getRootBlip();
    rootBlipId = rootBlip.getId();
    LineContainers.appendToLastLine(
        rootBlip.getContent(), XmlStringBuilder.createText(INITIAL_CONTENT));
  }

  public void testFailOnMultipleWhereParams() throws Exception {
    OperationRequest operation =
        operationRequest(OperationType.DOCUMENT_MODIFY, rootBlipId,
            Parameter.of(ParamsProperty.MODIFY_ACTION, new DocumentModifyAction()),
            Parameter.of(ParamsProperty.RANGE, new Range(0, 1)),
            Parameter.of(ParamsProperty.INDEX, 0));

    try {
      service.execute(operation, helper.getContext(), ALEX);
      fail("Expected InvalidRequestException");
    } catch (InvalidRequestException e) {
      // expected
    }
  }

  public void testAnnotate() throws Exception {
    OperationRequest operation =
        operationRequest(OperationType.DOCUMENT_MODIFY, rootBlipId,
            Parameter.of(ParamsProperty.MODIFY_ACTION, new DocumentModifyAction(ModifyHow.ANNOTATE,
                Collections.singletonList(ANNOTATION_VALUE), ANNOTATION_KEY, NO_ELEMENTS,
                NO_BUNDLED_ANNOTATIONS, false)),
            Parameter.of(ParamsProperty.INDEX, CONTENT_START_TEXT));

    service.execute(operation, helper.getContext(), ALEX);

    String annotation = getRootBlip().getContent().getAnnotation(CONTENT_START_XML, ANNOTATION_KEY);
    assertEquals("Expected the text to be annotated", ANNOTATION_VALUE, annotation);
    assertNull("Expected this text not to be annotated",
        getRootBlip().getContent().getAnnotation(CONTENT_START_XML + 1, ANNOTATION_KEY));
  }

  public void testClearAnnotatation() throws Exception {
    Document doc = getRootBlip().getContent();
    doc.setAnnotation(CONTENT_START_XML, CONTENT_START_XML + 1, ANNOTATION_KEY, ANNOTATION_VALUE);

    String annotation = getRootBlip().getContent().getAnnotation(CONTENT_START_XML, ANNOTATION_KEY);
    assertEquals("Expected the text to be annotated", ANNOTATION_VALUE, annotation);

    OperationRequest operation =
      operationRequest(OperationType.DOCUMENT_MODIFY, rootBlipId,
            Parameter.of(ParamsProperty.MODIFY_ACTION,
                new DocumentModifyAction(ModifyHow.CLEAR_ANNOTATION, NO_VALUES, ANNOTATION_KEY,
                    NO_ELEMENTS, NO_BUNDLED_ANNOTATIONS, false)),
            Parameter.of(ParamsProperty.INDEX, CONTENT_START_TEXT));

    service.execute(operation, helper.getContext(), ALEX);

    assertNull("Expected this text not to be annotated",
        getRootBlip().getContent().getAnnotation(CONTENT_START_XML, ANNOTATION_KEY));
  }
 
  public void testInsertGadget() throws Exception {
    String gadgetUrl = "http://wave-api.appspot.com/public/gadgets/areyouin/gadget.xml";
    List<Element> elementsIn = Lists.newArrayListWithCapacity(1);
    Map<String,String> properties = Maps.newHashMap();
    properties.put("url", gadgetUrl);
    properties.put("author", ALEX.getAddress());
    elementsIn.add(new Gadget(properties));

    OperationRequest operation =
      operationRequest(OperationType.DOCUMENT_MODIFY, rootBlipId,
            Parameter.of(ParamsProperty.MODIFY_ACTION,
                new DocumentModifyAction(ModifyHow.INSERT, NO_VALUES, NO_ANNOTATION_KEY,
                    elementsIn, NO_BUNDLED_ANNOTATIONS, false)),
            Parameter.of(ParamsProperty.INDEX, CONTENT_START_TEXT));

    service.execute(operation, helper.getContext(), ALEX);
   
    Gadget gadget = null;
    List<ElementInfo> elementsOut = getApiView().getElements();
    int size = 0;
    for (ElementInfo elementOut : elementsOut) {
      if (!elementOut.element.isGadget()) {
        continue;
      } else {
        size++;
        gadget = (Gadget)elementOut.element;
      }
    }
    assertEquals(1, size);
    assertEquals(gadgetUrl, gadget.getUrl());
    assertEquals(ALEX.getAddress(), gadget.getAuthor());
  }
 
  public void testUpdateGadget() throws Exception {
    String propertyName = "propertyName";
    String propertyValue = "propertyValue";

    String propertyNameToDelete = "propertyNameToDelete";
    String propertyValueToDelete = "propertyValueToDelete";

    String gadgetUrl = "http://wave-api.appspot.com/public/gadgets/areyouin/gadget.xml";
    String gadgetXml =
        "<gadget author=\"" + ALEX.getAddress() + "\" prefs=\"\" state=\"\" title=\"\" "
        + "url=\"" + gadgetUrl + "\">"
        + "<state name=\"author\" value=\"" + ALEX.getAddress()+ "\"/>"
        + "<state name=\"url\" " + "value=\"" + gadgetUrl + "\"/>"
        + "<state name=\"" + propertyName + "\" value=\"" + propertyValue + "\"/>"
        + "<state name=\"" + propertyNameToDelete + "\" value=\"" + propertyValueToDelete + "\"/>"
        + "</gadget>";

    ObservableConversationBlip rootBlip = getRootBlip();
    rootBlipId = rootBlip.getId();
    LineContainers.appendToLastLine(rootBlip.getContent(),
        XmlStringBuilder.createFromXmlString(gadgetXml));

    List<Element> updatedElementsIn = Lists.newArrayListWithCapacity(1);
    Map<String, String> newProperties = Maps.newHashMap();

    String updatedPropertyValue = "updatedPropertyValue";
    newProperties.put(propertyName, updatedPropertyValue);
    String newPropertyName = "newPropertyName";
    String newPropertyValue = "newPropertyValue";
    newProperties.put(newPropertyName, newPropertyValue);
    newProperties.put(propertyNameToDelete, null);
    updatedElementsIn.add(new Gadget(newProperties));

    OperationRequest updateOperation =
        operationRequest(OperationType.DOCUMENT_MODIFY, rootBlipId,
            Parameter.of(ParamsProperty.MODIFY_ACTION,
                new DocumentModifyAction(ModifyHow.UPDATE_ELEMENT,
                NO_VALUES, NO_ANNOTATION_KEY, updatedElementsIn, NO_BUNDLED_ANNOTATIONS, false)),
            Parameter.of(ParamsProperty.MODIFY_QUERY, new DocumentModifyQuery(ElementType.GADGET,
                ImmutableMap.of("url", gadgetUrl), 1)));

    service.execute(updateOperation, helper.getContext(), ALEX);

    Gadget gadget = null;
    List<ElementInfo> elementsOut = getApiView().getElements();
    for (ElementInfo elementOut : elementsOut) {
      if (elementOut.element.isGadget()) {
        gadget = (Gadget) elementOut.element;
      }
    }
    assertEquals(gadgetUrl, gadget.getUrl());
    assertEquals(ALEX.getAddress(), gadget.getAuthor());
    assertEquals(updatedPropertyValue, gadget.getProperty(propertyName));
    assertNotNull(gadget.getProperty(newPropertyName));
    assertEquals(newPropertyValue, gadget.getProperty(newPropertyName));
    assertNull(gadget.getProperty(propertyNameToDelete));
  }

  public void testDelete() throws Exception {
    OperationRequest operation =
      operationRequest(OperationType.DOCUMENT_MODIFY, rootBlipId,
            Parameter.of(ParamsProperty.MODIFY_ACTION,
                new DocumentModifyAction(ModifyHow.DELETE, NO_VALUES, NO_ANNOTATION_KEY,
                    NO_ELEMENTS, NO_BUNDLED_ANNOTATIONS, false)),
            Parameter.of(ParamsProperty.INDEX, CONTENT_START_TEXT));

    service.execute(operation, helper.getContext(), ALEX);

    // Cut off the /n
    String after = getApiView().apiContents().substring(1);
    assertEquals("First character should be deleted", INITIAL_CONTENT.substring(1), after);
  }

  public void testInsert() throws Exception {
    String toInsert = "insertedText";

    // Insert a new piece of annotated text before the current text.
    OperationRequest operation =
        operationRequest(OperationType.DOCUMENT_MODIFY, rootBlipId,
            Parameter.of(ParamsProperty.MODIFY_ACTION,
                new DocumentModifyAction(ModifyHow.INSERT, Collections.singletonList(toInsert),
                    NO_ANNOTATION_KEY, NO_ELEMENTS,
                    BundledAnnotation.listOf(ANNOTATION_KEY, ANNOTATION_VALUE), false)),
            Parameter.of(ParamsProperty.INDEX, CONTENT_START_TEXT));

    service.execute(operation, helper.getContext(), ALEX);

    // Cut off the /n
    String result = getApiView().apiContents().substring(1);
    assertEquals(
        "The result should start with the inserted text", toInsert + INITIAL_CONTENT, result);

    String annotation = getRootBlip().getContent().getAnnotation(CONTENT_START_XML, ANNOTATION_KEY);
    assertEquals("Expected the text to be annotated", ANNOTATION_VALUE, annotation);
  }

  public void testInsertAfter() throws Exception {
    String toInsert = "insertedText";
    OperationRequest operation =
        operationRequest(OperationType.DOCUMENT_MODIFY, rootBlipId,
            Parameter.of(ParamsProperty.MODIFY_ACTION,
                new DocumentModifyAction(ModifyHow.INSERT_AFTER,
                    Collections.singletonList(toInsert), NO_ANNOTATION_KEY, NO_ELEMENTS,
                    NO_BUNDLED_ANNOTATIONS, false)),
            Parameter.of(ParamsProperty.INDEX, CONTENT_START_TEXT));

    service.execute(operation, helper.getContext(), ALEX);

    // Cut off the /n
    String after = getApiView().apiContents().substring(1);
    assertEquals("Content should be insterted after the first character",
        INITIAL_CONTENT.charAt(0) + toInsert + INITIAL_CONTENT.substring(1), after);
  }

  public void testReplace() throws Exception {
    String replacement = "replacedText";
    OperationRequest operation =
        operationRequest(OperationType.DOCUMENT_MODIFY, rootBlipId,
            Parameter.of(ParamsProperty.MODIFY_ACTION,
                new DocumentModifyAction(ModifyHow.REPLACE, Collections.singletonList(replacement),
                    NO_ANNOTATION_KEY, NO_ELEMENTS, NO_BUNDLED_ANNOTATIONS, false)),
            Parameter.of(ParamsProperty.RANGE,
                new Range(CONTENT_START_TEXT, CONTENT_START_TEXT + INITIAL_CONTENT.length())));

    service.execute(operation, helper.getContext(), ALEX);

    // Cut off the /n
    String after = getApiView().apiContents().substring(1);
    assertEquals("The entire text should be replaced", replacement, after);
  }

  private ApiView getApiView() throws InvalidRequestException {
    ApiView view = new ApiView(
        getRootBlip().getContent(), helper.getContext().openWavelet(WAVE_ID, WAVELET_ID, ALEX));
    return view;
  }

  private ObservableConversationBlip getRootBlip() throws InvalidRequestException {
    ObservableConversationBlip rootBlip =
        helper.getContext().openConversation(WAVE_ID, WAVELET_ID, ALEX).getRoot().getRootThread()
            .getFirstBlip();
    return rootBlip;
  }
}
TOP

Related Classes of org.waveprotocol.box.server.robots.operations.DocumentModifyServiceTest

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.