def testUpdateEntityAndGeometry(self):
    layer = model.Layer(name='a', world='earth')
    layer_id = layer.put().id()
    schema1 = model.Schema(layer=layer, name='abc')
    schema1.put()
    template1 = model.Template(schema=schema1, name='def', text='',
                               parent=schema1)
    template1.put()
    schema2 = model.Schema(layer=layer, name='abc2')
    schema2.put()
    template2 = model.Template(schema=schema2, name='def2', text='',
                               parent=schema2)
    template2_id = template2.put().id()
    old_entity = model.Entity(layer=layer, name='old', template=template1,
                              field_q='w')
    entity_id = old_entity.put().id()
    old_point = model.Point(location=db.GeoPt(6, 5), parent=old_entity)
    old_entity.geometries = [old_point.put().id()]
    old_entity.put()

    fields = {'name': 'ghi', 'view_location': db.GeoPt(1, 2),
              'template': template2, 'field_x': 'y'}
    geometries = [
        {'type': model.Point, 'fields': {'location': db.GeoPt(3, 4)}},
        {'type': model.LineString, 'fields': {
            'points': [db.GeoPt(5, 6), db.GeoPt(7, 8)]
        }}
    ]

    entity._UpdateEntityAndGeometry(entity_id, fields, geometries, True)
    result = model.Entity.get_by_id(entity_id)
    self.assertEqual(result.layer.key().id(), layer_id)
    self.assertEqual(result.name, 'ghi')
    self.assertEqual(result.view_location, db.GeoPt(1, 2))
    self.assertEqual(result.template.key().id(), template2_id)
    self.assertEqual(result.field_x, 'y')
    self.assertFalse(hasattr(result, 'field_q'))
    self.assertEqual(len(result.geometries), 2)
    point = model.Geometry.get_by_id(result.geometries[0], parent=result)
    line_string = model.Geometry.get_by_id(result.geometries[1], parent=result)
    self.assertEqual(point.location, db.GeoPt(3, 4))
    self.assertEqual(line_string.points, [db.GeoPt(5, 6), db.GeoPt(7, 8)])
    self.assertEqual(result.location, db.GeoPt(3, 4))
  def testUpdate(self):
    self.mox.StubOutWithMock(util, 'GetInstance')
    self.mox.StubOutWithMock(entity, '_ValidateEntityArguments')
    self.mox.StubOutWithMock(entity, '_UpdateEntityAndGeometry')
    self.mox.StubOutWithMock(model, 'Entity', use_mock_anything=True)
    handler = entity.EntityHandler()
    request = {'a': 'b', 'c': 'd', 'entity_id': '123'}
    handler.request = self.mox.CreateMockAnything()
    handler.request.get = request.get
    handler.request.arguments = request.keys
    fields = {'x': 'y'}
    mock_entity = self.mox.CreateMockAnything()
    dummy_layer = object()
    dummy_geometries = object()

    # Success.
    util.GetInstance(model.Entity, '123', dummy_layer).AndReturn(mock_entity)
    entity._ValidateEntityArguments(dummy_layer, request, True).AndReturn((
        fields, dummy_geometries))
    mock_entity.ClearCache()
    entity._UpdateEntityAndGeometry(123, fields, dummy_geometries, True)
    model.Entity.get_by_id(123).AndReturn(mock_entity)
    mock_entity.GenerateKML()

    # Failure during validation.
    util.GetInstance(model.Entity, '123', dummy_layer).AndReturn(mock_entity)
    entity._ValidateEntityArguments(dummy_layer, request, True).AndRaise(
        util.BadRequest)

    # Failure during geometry switch.
    util.GetInstance(model.Entity, '123', dummy_layer).AndReturn(mock_entity)
    entity._ValidateEntityArguments(dummy_layer, request, True).AndReturn((
        fields, dummy_geometries))
    mock_entity.ClearCache()
    entity._UpdateEntityAndGeometry(
        123, fields, dummy_geometries, True).AndRaise(db.BadValueError)

    self.mox.ReplayAll()
    handler.Update(dummy_layer)
    self.assertRaises(util.BadRequest, handler.Update, dummy_layer)
    self.assertRaises(util.BadRequest, handler.Update, dummy_layer)