def testCreate(self):
    self.mox.StubOutWithMock(entity, '_ValidateEntityArguments')
    self.mox.StubOutWithMock(entity, '_CreateEntityAndGeometry')
    self.mox.StubOutWithMock(model, 'Entity', use_mock_anything=True)
    handler = entity.EntityHandler()
    request = {'a': 'b', 'c': 'd', 'e': 'f'}
    handler.request = self.mox.CreateMockAnything()
    handler.request.get = request.get
    handler.request.arguments = request.keys
    handler.response = self.mox.CreateMockAnything()
    handler.response.out = self.mox.CreateMockAnything()
    mock_entity = self.mox.CreateMockAnything()
    mock_layer = self.mox.CreateMockAnything()
    dummy_fields = object()
    dummy_geometries = object()
    dummy_id = object()

    # Success.
    entity._ValidateEntityArguments(mock_layer, request, False).AndReturn((
        dummy_fields, dummy_geometries))
    mock_layer.ClearCache()
    entity._CreateEntityAndGeometry(
        mock_layer, dummy_fields, dummy_geometries).AndReturn(dummy_id)
    handler.response.out.write(dummy_id)
    model.Entity.get_by_id(dummy_id).AndReturn(mock_entity)
    mock_entity.GenerateKML()

    # Failure during validation.
    entity._ValidateEntityArguments(mock_layer, request, False).AndRaise(
        util.BadRequest)

    # Failure during creation.
    entity._ValidateEntityArguments(mock_layer, request, False).AndReturn((
        dummy_fields, dummy_geometries))
    mock_layer.ClearCache()
    entity._CreateEntityAndGeometry(
        mock_layer, dummy_fields, dummy_geometries).AndRaise(util.BadRequest)

    self.mox.ReplayAll()
    handler.Create(mock_layer)
    self.assertRaises(util.BadRequest, handler.Create, mock_layer)
    self.assertRaises(util.BadRequest, handler.Create, mock_layer)
  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)
  def testValidateEntityArguments(self):
    layer = model.Layer(name='a', world='earth')
    layer.put()
    folder = model.Folder(layer=layer, name='abc')
    folder_id = folder.put().id()
    style = model.Style(layer=layer, name='def')
    style_id = style.put().id()
    region = model.Region(layer=layer, north=4.0, south=3.0, east=2.0, west=1.0)
    region_id = region.put().id()
    schema = model.Schema(layer=layer, name='ghi')
    schema_id = schema.put().id()
    template = model.Template(schema=schema, name='jkl', text='', parent=schema)
    template_id = template.put().id()

    # Success, full.
    fields, geometries = entity._ValidateEntityArguments(layer, {
        'name': 'abc',
        'snippet': 'def',
        'folder': str(folder_id),
        'folder_index': '123',
        'schema': str(schema_id),
        'template': str(template_id),
        'style': str(style_id),
        'region': str(region_id),
        'view_latitude': '4.5',
        'view_longitude': '5.6',
        'view_altitude': '6.7',
        'view_heading': '7.8',
        'view_tilt': '8.9',
        'view_roll': '12.34',
        'view_range': '9.0',
        'view_is_camera': 'yes',
        'priority': '42.13',
        'geometries': '[{"type":"Point","fields":{"location":[1.23,4.56]}}]'
    }, False)
    self.assertEqual(fields['folder'].key().id(), folder_id)
    del fields['folder']
    self.assertEqual(fields['template'].key().id(), template_id)
    del fields['template']
    self.assertEqual(fields['style'].key().id(), style_id)
    del fields['style']
    self.assertEqual(fields['region'].key().id(), region_id)
    del fields['region']
    self.assertEqual(fields, {
        'name': 'abc',
        'snippet': 'def',
        'folder_index': 123,
        'view_location': db.GeoPt(4.5, 5.6),
        'view_altitude': 6.7,
        'view_heading': 7.8,
        'view_tilt': 8.9,
        'view_roll': 12.34,
        'view_range': 9.0,
        'view_is_camera': True,
        'priority': 42.13
    })
    self.assertEqual(geometries, [
        {'type': model.Point, 'fields': {
            'location': db.GeoPt(1.23, 4.56), 'extrude': False,
            'altitude_mode': None, 'altitude': None,
        }}
    ])

    # Success, partial.
    fields, geometries = entity._ValidateEntityArguments(layer, {
        'name': 'abc',
        'folder': str(folder_id),
        'view_latitude': '4.5',
        'view_longitude': '5.6',
        'view_is_camera': '',
        'geometries': '[{"type":"LineString","fields":{"points":[[1.2, 3.4]]}}]'
    }, False)
    self.assertEqual(fields['folder'].key().id(), folder_id)
    del fields['folder']
    self.assertEqual(fields, {
        'name': 'abc',
        'view_location': db.GeoPt(4.5, 5.6),
        'view_is_camera': None
    })
    self.assertEqual(geometries, [
        {'type': model.LineString, 'fields': {
            'points': [db.GeoPt(1.2, 3.4)],
            'altitudes': [],
            'altitude_mode': None,
            'extrude': False,
            'tessellate': False
        }}
    ])

    # Success, no-op.
    fields, geometries = entity._ValidateEntityArguments(layer, {}, True)
    self.assertEqual(fields, {})
    self.assertEqual(geometries, [])

    # Failure, empty name.
    self.assertRaises(util.BadRequest, entity._ValidateEntityArguments, layer, {
        'name': '',
        'geometries': '[{"type":"Point","fields":{"location":[1.23,4.56]}}]'
    }, False)

    # Failure, no geometries.
    self.assertRaises(util.BadRequest, entity._ValidateEntityArguments, layer, {
        'name': 'abc',
        'geometries': '[]'
    }, False)

    # Invalid value.
    self.assertRaises(util.BadRequest, entity._ValidateEntityArguments, layer, {
        'name': 'abc',
        'view_range': 'xyz',
        'geometries': '[{"type":"Point","fields":{"location":[1.23,4.56]}}]'
    }, False)

    # Invalid JSON.
    self.assertRaises(util.BadRequest, entity._ValidateEntityArguments, layer, {
        'name': 'abc',
        'view_range': 'xyz',
        'geometries': '[{"type":"Point",fields":{"location":[1.23,4.56]}}]'
    }, False)