blob: b41a130ed931f880dac8f5943ad00d450aa747a5 [file] [log] [blame]
#!/usr/bin/env python
#
# Copyright 2007 Google 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.
#
"""Tests for devappserver2.admin.datastore_viewer."""
import datetime
import os
import unittest
import google
import mox
import webapp2
from google.appengine.api import apiproxy_stub_map
from google.appengine.api import datastore
from google.appengine.api import datastore_types
from google.appengine.datastore import datastore_pb
from google.appengine.datastore import datastore_stub_util
from google.appengine.tools.devappserver2 import api_server
from google.appengine.tools.devappserver2.admin import admin_request_handler
from google.appengine.tools.devappserver2.admin import datastore_viewer
class PropertyNameToValuesTest(unittest.TestCase):
"""Tests for datastore_viewer._property_name_to_value(s)."""
def setUp(self):
self.app_id = 'myapp'
self.entity1 = datastore.Entity('Kind1', id=123, _app=self.app_id)
self.entity1['cat'] = 5
self.entity1['dog'] = 10
self.entity2 = datastore.Entity('Kind1', id=124, _app=self.app_id)
self.entity2['dog'] = 15
self.entity2['mouse'] = 'happy'
def test_property_name_to_values(self):
self.assertEqual({'cat': [5],
'dog': mox.SameElementsAs([10, 15]),
'mouse': ['happy']},
datastore_viewer._property_name_to_values([self.entity1,
self.entity2]))
def test_property_name_to_value(self):
self.assertEqual({'cat': 5,
'dog': mox.Func(lambda v: v in [10, 15]),
'mouse': 'happy'},
datastore_viewer._property_name_to_value([self.entity1,
self.entity2]))
class GetWriteOpsTest(unittest.TestCase):
"""Tests for DatastoreRequestHandler._get_write_ops."""
def setUp(self):
self.app_id = 'myapp'
os.environ['APPLICATION_ID'] = self.app_id
# Use a consistent replication strategy so the puts done in the test code
# are seen immediately by the queries under test.
consistent_policy = datastore_stub_util.MasterSlaveConsistencyPolicy()
api_server.test_setup_stubs(
app_id=self.app_id,
application_root=None, # Needed to allow index updates.
datastore_consistency=consistent_policy)
def test_no_properties(self):
entity = datastore.Entity('Yar', id=123, _app=self.app_id) # 2 writes.
self.assertEquals(
2, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
def test_indexed_properties_no_composite_indexes(self):
entity = datastore.Entity('Yar', id=123, _app=self.app_id) # 2 writes.
entity['p1'] = None # 2 writes.
entity['p2'] = None # 2 writes.
entity['p3'] = [1, 2, 3] # 6 writes.
self.assertEquals(
12, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
def test_unindexed_properties_no_composite_indexes(self):
entity = datastore.Entity('Yar', id=123, _app=self.app_id) # 2 writes.
entity['u1'] = None # 0 writes.
entity['u2'] = None # 0 writes.
entity['u3'] = [1, 2, 3] # 0 writes.
entity.set_unindexed_properties(('u1', 'u2', 'u3'))
# unindexed properties have no impact on cost
self.assertEquals(
2, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
def test_composite_index(self):
ci = datastore_pb.CompositeIndex()
ci.set_app_id(datastore_types.ResolveAppId(None))
ci.set_id(0)
ci.set_state(ci.WRITE_ONLY)
index = ci.mutable_definition()
index.set_ancestor(0)
index.set_entity_type('Yar')
prop = index.add_property()
prop.set_name('this')
prop.set_direction(prop.ASCENDING)
prop = index.add_property()
prop.set_name('that')
prop.set_direction(prop.DESCENDING)
stub = apiproxy_stub_map.apiproxy.GetStub('datastore_v3')
stub.CreateIndex(ci)
self.assertEquals(1, len(datastore.GetIndexes()))
# no properties, no composite indices.
entity = datastore.Entity('Yar', id=123, _app=self.app_id) # 2 writes.
# We only have the 2 built-in index writes because the entity doesn't have
# property values for any of the index properties.
self.assertEquals(
2, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
entity['this'] = 4
# Unindexed property so no additional writes
entity.set_unindexed_properties(('this',))
self.assertEquals(
2, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
entity['that'] = 4
# Unindexed property so no additional writes
entity.set_unindexed_properties(('this', 'that'))
self.assertEquals(
2, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
# no indexed property value on 'that'
entity.set_unindexed_properties(('that',))
# 2 writes for the entity.
# 2 writes for the single indexed property.
self.assertEquals(
4, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
# indexed property value on both 'this' and 'that'
entity.set_unindexed_properties(())
# 2 writes for the entity
# 4 writes for the indexed properties
# 1 writes for the composite index
self.assertEquals(
7, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
# now run tests with null property values
entity = datastore.Entity('Yar', id=123, _app=self.app_id) # 2 writes.
entity['this'] = None
# 2 for the entity
# 2 for the single indexed property
self.assertEquals(
4, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
entity['that'] = None
# 2 for the entity
# 4 for the indexed properties
# 1 for the composite index
self.assertEquals(
7, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
# now run tests with a repeated property
entity = datastore.Entity('Yar', id=123, _app=self.app_id) # 2 writes.
entity['this'] = [1, 2, 3]
# 2 for the entity
# 6 for the indexed properties
self.assertEquals(
8, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
entity['that'] = None
# 2 for the entity
# 8 for the indexed properties
# 3 for the Composite index
self.assertEquals(
13, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
entity['that'] = [4, 5]
# 2 for the entity
# 10 for the indexed properties
# 6 for the Composite index
self.assertEquals(
18, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
def test_composite_index_no_properties(self):
ci = datastore_pb.CompositeIndex()
ci.set_app_id(datastore_types.ResolveAppId(None))
ci.set_id(0)
ci.set_state(ci.WRITE_ONLY)
index = ci.mutable_definition()
index.set_ancestor(0)
index.set_entity_type('Yar')
stub = apiproxy_stub_map.apiproxy.GetStub('datastore_v3')
stub.CreateIndex(ci)
self.assertEquals(1, len(datastore.GetIndexes()))
# no properties, and composite index with no properties.
entity = datastore.Entity('Yar', id=123, _app=self.app_id) # 2 writes.
# We have the 2 built-in index writes, and one for the entity key in the
# composite index despite the fact that there are no proerties defined in
# the index.
self.assertEquals(
3, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
# now with a repeated property
entity = datastore.Entity('Yar', id=123, _app=self.app_id) # 2 writes.
entity['this'] = [1, 2, 3]
# 2 for the entity
# 6 for the indexed properties
# 1 for the composite index
self.assertEquals(
9, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
def test_composite_ancestor_index(self):
ci = datastore_pb.CompositeIndex()
ci.set_app_id(datastore_types.ResolveAppId(None))
ci.set_id(0)
ci.set_state(ci.WRITE_ONLY)
index = ci.mutable_definition()
index.set_ancestor(1)
index.set_entity_type('Yar')
prop = index.add_property()
prop.set_name('this')
prop.set_direction(prop.ASCENDING)
prop = index.add_property()
prop.set_name('that')
prop.set_direction(prop.DESCENDING)
stub = apiproxy_stub_map.apiproxy.GetStub('datastore_v3')
stub.CreateIndex(ci)
self.assertEquals(1, len(datastore.GetIndexes()))
entity = datastore.Entity('Yar', id=123, _app=self.app_id) # 2 writes.
entity['this'] = 4
entity['that'] = 4
# 2 for the entity
# 4 for the indexed properties
# 1 for the composite index
self.assertEquals(
7, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
# Now use the same entity but give it an ancestor
parent_entity = datastore.Entity('parent', id=123, _app=self.app_id)
entity = datastore.Entity(
'Yar',
parent=parent_entity.key(),
id=123,
_app=self.app_id) # 2 writes.
entity['this'] = 4
entity['that'] = 4
# 2 writes for the entity.
# 4 writes for the indexed properties.
# 2 writes for the composite indices.
self.assertEquals(
8, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
# Now use the same entity but give it 2 ancestors.
grandparent_entity = datastore.Entity(
'grandparent', id=123, _app=self.app_id)
parent_entity = datastore.Entity(
'parent', parent=grandparent_entity.key(), id=123, _app=self.app_id)
entity = datastore.Entity(
'Yar',
parent=parent_entity.key(),
id=123,
_app=self.app_id) # 2 writes.
entity['this'] = 4
entity['that'] = 4
# 2 writes for the entity.
# 4 writes for the indexed properties.
# 3 writes for the composite indices.
self.assertEquals(
9, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
# Now try it with a multi-value prop
entity['this'] = [None, None, None]
# 2 writes for the entity.
# 8 writes for the indexed properties.
# 9 writes for the composite indices.
self.assertEquals(
19, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
# Now try it with 2 multi-value props.
entity['that'] = [None, None]
# 2 writes for the entity.
# 10 writes for the indexed properties.
# 18 writes for the composite indices.
self.assertEquals(
30, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
def test_composite_ancestor_index_no_properties(self):
ci = datastore_pb.CompositeIndex()
ci.set_app_id(datastore_types.ResolveAppId(None))
ci.set_id(0)
ci.set_state(ci.WRITE_ONLY)
index = ci.mutable_definition()
index.set_ancestor(1)
index.set_entity_type('Yar')
stub = apiproxy_stub_map.apiproxy.GetStub('datastore_v3')
stub.CreateIndex(ci)
self.assertEquals(1, len(datastore.GetIndexes()))
entity = datastore.Entity('Yar', id=123, _app=self.app_id) # 2 writes.
entity['this'] = [None, None]
# 2 writes for the entity.
# 4 writes for the indexed properties.
# 1 writes for the composite index.
self.assertEquals(
7, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
# Now use the same entity but give it an ancestor
parent_entity = datastore.Entity('parent', id=123, _app=self.app_id)
entity = datastore.Entity(
'Yar',
parent=parent_entity.key(),
id=123,
_app=self.app_id) # 2 writes.
entity['this'] = [None, None]
# 2 writes for the entity.
# 4 writes for the indexed properties.
# 2 writes for the composite indices.
self.assertEquals(
8, datastore_viewer.DatastoreRequestHandler._get_write_ops(entity))
class GetEntitiesTest(unittest.TestCase):
"""Tests for DatastoreRequestHandler._get_entities."""
def setUp(self):
self.app_id = 'myapp'
os.environ['APPLICATION_ID'] = self.app_id
# Use a consistent replication strategy so the puts done in the test code
# are seen immediately by the queries under test.
consistent_policy = datastore_stub_util.MasterSlaveConsistencyPolicy()
api_server.test_setup_stubs(
app_id=self.app_id,
datastore_consistency=consistent_policy)
self.entity1 = datastore.Entity('Kind1', id=123, _app=self.app_id)
self.entity1['intprop'] = 1
self.entity1['listprop'] = [7, 8, 9]
datastore.Put(self.entity1)
self.entity2 = datastore.Entity('Kind1', id=124, _app=self.app_id)
self.entity2['stringprop'] = 'value2'
self.entity2['listprop'] = [4, 5, 6]
datastore.Put(self.entity2)
self.entity3 = datastore.Entity('Kind1', id=125, _app=self.app_id)
self.entity3['intprop'] = 3
self.entity3['stringprop'] = 'value3'
self.entity3['listprop'] = [1, 2, 3]
datastore.Put(self.entity3)
self.entity4 = datastore.Entity('Kind1', id=126, _app=self.app_id)
self.entity4['intprop'] = 4
self.entity4['stringprop'] = 'value4'
self.entity4['listprop'] = [10, 11, 12]
datastore.Put(self.entity4)
def test_ascending_int_order(self):
entities, total = datastore_viewer._get_entities(kind='Kind1',
namespace='',
order='intprop',
start=0,
count=100)
self.assertEqual([self.entity1, self.entity3, self.entity4], entities)
self.assertEqual(3, total)
def test_decending_string_order(self):
entities, total = datastore_viewer._get_entities(kind='Kind1',
namespace='',
order='-stringprop',
start=0,
count=100)
self.assertEqual([self.entity4, self.entity3, self.entity2], entities)
self.assertEqual(3, total)
def test_start_and_count(self):
entities, total = datastore_viewer._get_entities(kind='Kind1',
namespace='',
order='listprop',
start=1,
count=2)
self.assertEqual([self.entity2, self.entity1], entities)
self.assertEqual(4, total)
class GetEntityTemplateDataTest(unittest.TestCase):
def setUp(self):
self.app_id = 'myapp'
os.environ['APPLICATION_ID'] = self.app_id
# Use a consistent replication strategy so the puts done in the test code
# are seen immediately by the queries under test.
consistent_policy = datastore_stub_util.MasterSlaveConsistencyPolicy()
api_server.test_setup_stubs(
app_id=self.app_id,
datastore_consistency=consistent_policy)
self.entity1 = datastore.Entity('Kind1', id=123, _app=self.app_id)
self.entity1['intprop'] = 1
self.entity1['listprop'] = [7, 8, 9]
datastore.Put(self.entity1)
self.entity2 = datastore.Entity('Kind1', id=124, _app=self.app_id)
self.entity2['stringprop'] = 'value2'
self.entity2['listprop'] = [4, 5, 6]
datastore.Put(self.entity2)
self.entity3 = datastore.Entity('Kind1', id=125, _app=self.app_id)
self.entity3['intprop'] = 3
self.entity3['listprop'] = [1, 2, 3]
datastore.Put(self.entity3)
self.entity4 = datastore.Entity('Kind1', id=126, _app=self.app_id)
self.entity4['intprop'] = 4
self.entity4['stringprop'] = 'value4'
self.entity4['listprop'] = [10, 11]
datastore.Put(self.entity4)
def test(self):
headers, entities, total_entities = (
datastore_viewer.DatastoreRequestHandler._get_entity_template_data(
request_uri='http://next/',
kind='Kind1',
namespace='',
order='intprop',
start=1))
self.assertEqual(
[{'name': 'intprop'}, {'name': 'listprop'}, {'name': 'stringprop'}],
headers)
self.assertEqual(
[{'attributes': [{'name': u'intprop',
'short_value': '3',
'value': '3'},
{'name': u'listprop',
'short_value': mox.Regex(r'\[1L?, 2L?, 3L?\]'),
'value': mox.Regex(r'\[1L?, 2L?, 3L?\]')},
{'name': u'stringprop',
'short_value': '',
'value': ''}],
'edit_uri': '/datastore/edit/{0}?next=http%3A//next/'.format(
self.entity3.key()),
'key': datastore_types.Key.from_path(u'Kind1', 125, _app=u'myapp'),
'key_id': 125,
'key_name': None,
'shortened_key': 'agVteWFw...',
'write_ops': 10},
{'attributes': [{'name': u'intprop',
'short_value': '4',
'value': '4'},
{'name': u'listprop',
'short_value': mox.Regex(r'\[10L?, 11L?\]'),
'value': mox.Regex(r'\[10L?, 11L?\]')},
{'name': u'stringprop',
'short_value': u'value4',
'value': u'value4'}],
'edit_uri': '/datastore/edit/{0}?next=http%3A//next/'.format(
self.entity4.key()),
'key': datastore_types.Key.from_path(u'Kind1', 126, _app=u'myapp'),
'key_id': 126,
'key_name': None,
'shortened_key': 'agVteWFw...',
'write_ops': 10}],
entities)
self.assertEqual(3, total_entities)
class DatastoreRequestHandlerGetTest(unittest.TestCase):
"""Tests for DatastoreRequestHandler.get."""
def setUp(self):
self.app_id = 'myapp'
os.environ['APPLICATION_ID'] = self.app_id
api_server.test_setup_stubs(app_id=self.app_id)
self.mox = mox.Mox()
self.mox.StubOutWithMock(admin_request_handler.AdminRequestHandler,
'render')
def tearDown(self):
self.mox.UnsetStubs()
def test_empty_request_and_empty_datastore(self):
request = webapp2.Request.blank('/datastore')
response = webapp2.Response()
handler = datastore_viewer.DatastoreRequestHandler(request, response)
handler.render('datastore_viewer.html',
{'entities': [],
'headers': [],
'kind': None,
'kinds': [],
'message': None,
'namespace': '',
'num_pages': 0,
'order': None,
'paging_base_url': '/datastore?',
'order_base_url': '/datastore?',
'page': 1,
'select_namespace_url': '/datastore?namespace=',
'show_namespace': False,
'start': 0,
'total_entities': 0})
self.mox.ReplayAll()
handler.get()
self.mox.VerifyAll()
def test_empty_request_and_populated_datastore(self):
entity = datastore.Entity('Kind1', id=123, _app=self.app_id)
entity['intprop'] = 1
entity['listprop'] = [7, 8, 9]
datastore.Put(entity)
request = webapp2.Request.blank('/datastore')
response = webapp2.Response()
handler = datastore_viewer.DatastoreRequestHandler(request, response)
self.mox.ReplayAll()
handler.get()
self.mox.VerifyAll()
self.assertEqual(302, response.status_int)
self.assertEqual('http://localhost/datastore?kind=Kind1',
response.location)
def test_kind_request_and_populated_datastore(self):
entity = datastore.Entity('Kind1', id=123, _app=self.app_id)
entity['intprop'] = 1
entity['listprop'] = [7, 8, 9]
datastore.Put(entity)
request = webapp2.Request.blank('/datastore?kind=Kind1')
response = webapp2.Response()
handler = datastore_viewer.DatastoreRequestHandler(request, response)
handler.render(
'datastore_viewer.html',
{'entities': mox.IgnoreArg(), # Tested with _get_entity_template_data.
'headers': mox.IgnoreArg(), # Tested with _get_entity_template_data.
'kind': 'Kind1',
'kinds': ['Kind1'],
'message': None,
'namespace': '',
'num_pages': 1,
'order': None,
'order_base_url': '/datastore?kind=Kind1',
'page': 1,
'paging_base_url': '/datastore?kind=Kind1',
'select_namespace_url': '/datastore?kind=Kind1&namespace=',
'show_namespace': False,
'start': 0,
'total_entities': 1})
self.mox.ReplayAll()
handler.get()
self.mox.VerifyAll()
def test_order_request(self):
entity = datastore.Entity('Kind1', id=123, _app=self.app_id)
entity['intprop'] = 1
entity['listprop'] = [7, 8, 9]
datastore.Put(entity)
request = webapp2.Request.blank(
'/datastore?kind=Kind1&order=intprop')
response = webapp2.Response()
handler = datastore_viewer.DatastoreRequestHandler(request, response)
handler.render(
'datastore_viewer.html',
{'entities': mox.IgnoreArg(), # Tested with _get_entity_template_data.
'headers': mox.IgnoreArg(), # Tested with _get_entity_template_data.
'kind': 'Kind1',
'kinds': ['Kind1'],
'message': None,
'namespace': '',
'num_pages': 1,
'order': 'intprop',
'order_base_url': '/datastore?kind=Kind1',
'page': 1,
'paging_base_url': '/datastore?kind=Kind1&order=intprop',
'select_namespace_url':
'/datastore?kind=Kind1&namespace=&order=intprop',
'show_namespace': False,
'start': 0,
'total_entities': 1})
self.mox.ReplayAll()
handler.get()
self.mox.VerifyAll()
def test_namespace_request(self):
entity = datastore.Entity('Kind1',
id=123,
_app=self.app_id,
_namespace='google')
entity['intprop'] = 1
entity['listprop'] = [7, 8, 9]
datastore.Put(entity)
request = webapp2.Request.blank(
'/datastore?kind=Kind1&namespace=google')
response = webapp2.Response()
handler = datastore_viewer.DatastoreRequestHandler(request, response)
handler.render(
'datastore_viewer.html',
{'entities': mox.IgnoreArg(), # Tested with _get_entity_template_data.
'headers': mox.IgnoreArg(), # Tested with _get_entity_template_data.
'kind': 'Kind1',
'kinds': ['Kind1'],
'message': None,
'namespace': 'google',
'num_pages': 1,
'order': None,
'order_base_url': '/datastore?kind=Kind1&namespace=google',
'page': 1,
'paging_base_url': '/datastore?kind=Kind1&namespace=google',
'select_namespace_url':
'/datastore?kind=Kind1&namespace=google',
'show_namespace': True,
'start': 0,
'total_entities': 1})
self.mox.ReplayAll()
handler.get()
self.mox.VerifyAll()
def test_page_request(self):
for i in range(1000):
entity = datastore.Entity('Kind1', id=i+1, _app=self.app_id)
entity['intprop'] = i
datastore.Put(entity)
request = webapp2.Request.blank(
'/datastore?kind=Kind1&page=3')
response = webapp2.Response()
handler = datastore_viewer.DatastoreRequestHandler(request, response)
handler.render(
'datastore_viewer.html',
{'entities': mox.IgnoreArg(), # Tested with _get_entity_template_data.
'headers': mox.IgnoreArg(), # Tested with _get_entity_template_data.
'kind': 'Kind1',
'kinds': ['Kind1'],
'message': None,
'namespace': '',
'num_pages': 50,
'order': None,
'order_base_url': '/datastore?kind=Kind1&page=3',
'page': 3,
'paging_base_url': '/datastore?kind=Kind1',
'select_namespace_url':
'/datastore?kind=Kind1&namespace=&page=3',
'show_namespace': False,
'start': 40,
'total_entities': 1000})
self.mox.ReplayAll()
handler.get()
self.mox.VerifyAll()
class DatastoreEditRequestHandlerTest(unittest.TestCase):
"""Tests for DatastoreEditRequestHandler."""
def setUp(self):
self.app_id = 'myapp'
os.environ['APPLICATION_ID'] = self.app_id
# Use a consistent replication strategy so that the test can use queries
# to verify that an entity was written.
consistent_policy = datastore_stub_util.MasterSlaveConsistencyPolicy()
api_server.test_setup_stubs(
app_id=self.app_id,
datastore_consistency=consistent_policy)
self.mox = mox.Mox()
self.mox.StubOutWithMock(admin_request_handler.AdminRequestHandler,
'render')
self.entity1 = datastore.Entity('Kind1', id=123, _app=self.app_id)
self.entity1['intprop'] = 1
self.entity1['listprop'] = [7, 8, 9]
self.entity1['dateprop'] = datastore_types._OverflowDateTime(2**60)
datastore.Put(self.entity1)
self.entity2 = datastore.Entity('Kind1', id=124, _app=self.app_id)
self.entity2['stringprop'] = 'value2'
self.entity2['listprop'] = [4, 5, 6]
datastore.Put(self.entity2)
self.entity3 = datastore.Entity('Kind1', id=125, _app=self.app_id)
self.entity3['intprop'] = 3
self.entity3['listprop'] = [1, 2, 3]
datastore.Put(self.entity3)
self.entity4 = datastore.Entity('Kind1', id=126, _app=self.app_id)
self.entity4['intprop'] = 4
self.entity4['stringprop'] = 'value4'
self.entity4['listprop'] = [10, 11]
datastore.Put(self.entity4)
def tearDown(self):
self.mox.UnsetStubs()
def test_get_no_entity_key_string(self):
request = webapp2.Request.blank(
'/datastore/edit?kind=Kind1&next=http://next/')
response = webapp2.Response()
handler = datastore_viewer.DatastoreEditRequestHandler(request, response)
handler.render(
'datastore_edit.html',
{'fields': [('dateprop',
'overflowdatetime',
mox.Regex('^<input class="overflowdatetime".*'
'value="".*$')),
('intprop',
'int',
mox.Regex('^<input class="int".*value="".*$')),
('listprop', 'list', ''),
('stringprop',
'string',
mox.Regex('^<input class="string".*$'))],
'key': None,
'key_id': None,
'key_name': None,
'kind': 'Kind1',
'namespace': '',
'next': 'http://next/',
'parent_key': None,
'parent_key_string': None})
self.mox.ReplayAll()
handler.get()
self.mox.VerifyAll()
def test_get_no_entity_key_string_and_no_entities_in_namespace(self):
request = webapp2.Request.blank(
'/datastore/edit?kind=Kind1&namespace=cat&next=http://next/')
response = webapp2.Response()
handler = datastore_viewer.DatastoreEditRequestHandler(request, response)
self.mox.ReplayAll()
handler.get()
self.mox.VerifyAll()
self.assertEqual(302, response.status_int)
self.assertRegexpMatches(
response.location,
r'/datastore\?kind=Kind1&message=Cannot+.*&namespace=cat')
def test_get_entity_string(self):
request = webapp2.Request.blank(
'/datastore/edit/%s?next=http://next/' % self.entity1.key())
response = webapp2.Response()
handler = datastore_viewer.DatastoreEditRequestHandler(request, response)
handler.render(
'datastore_edit.html',
{'fields': [('dateprop',
'overflowdatetime',
mox.Regex('^<input class="overflowdatetime".*'
'value="1152921504606846976".*$')),
('intprop',
'int',
mox.Regex('^<input class="int".*value="1".*$')),
('listprop', 'list', mox.Regex(r'\[7L?, 8L?, 9L?\]'))],
'key': str(self.entity1.key()),
'key_id': 123,
'key_name': None,
'kind': 'Kind1',
'namespace': '',
'next': 'http://next/',
'parent_key': None,
'parent_key_string': None})
self.mox.ReplayAll()
handler.get(str(self.entity1.key()))
self.mox.VerifyAll()
def test_post_no_entity_key_string(self):
request = webapp2.Request.blank(
'/datastore/edit',
POST={'kind': 'Kind1',
'overflowdatetime|dateprop': '2009-12-24 23:59:59',
'int|intprop': '123',
'string|stringprop': 'Hello',
'next': 'http://redirect/'})
response = webapp2.Response()
handler = datastore_viewer.DatastoreEditRequestHandler(request, response)
self.mox.ReplayAll()
handler.post()
self.mox.VerifyAll()
self.assertEqual(302, response.status_int)
self.assertEqual('http://redirect/', response.location)
# Check that the entity was added.
query = datastore.Query('Kind1')
query.update({'dateprop': datetime.datetime(2009, 12, 24, 23, 59, 59),
'intprop': 123,
'stringprop': 'Hello'})
self.assertEquals(1, query.Count())
def test_post_entity_key_string(self):
request = webapp2.Request.blank(
'/datastore/edit/%s' % self.entity4.key(),
POST={'overflowdatetime|dateprop': str(2**60),
'int|intprop': '123',
'string|stringprop': '',
'next': 'http://redirect/'})
response = webapp2.Response()
handler = datastore_viewer.DatastoreEditRequestHandler(request, response)
self.mox.ReplayAll()
handler.post(str(self.entity4.key()))
self.mox.VerifyAll()
self.assertEqual(302, response.status_int)
self.assertEqual('http://redirect/', response.location)
# Check that the entity was updated.
entity = datastore.Get(self.entity4.key())
self.assertEqual(2**60, entity['dateprop'])
self.assertEqual(123, entity['intprop'])
self.assertEqual([10, 11], entity['listprop'])
self.assertNotIn('stringprop', entity)
if __name__ == '__main__':
unittest.main()