def test_local_doesnt_exist(self): """ MyObject.objects.get(cdms_pk=..) when local obj does not exist, should hit the cdms api, create a local obj and return it. """ modified_on = (timezone.now() + datetime.timedelta(days=1)).replace(microsecond=0) self.mocked_cdms_api.get.side_effect = mocked_cdms_get( get_data={ 'ModifiedOn': modified_on, 'Name': 'new name', 'DateTimeField': None, 'IntField': None, 'FKField': None } ) SimpleObj.objects.skip_cdms().all().delete() self.assertEqual(SimpleObj.objects.skip_cdms().count(), 0) obj = SimpleObj.objects.get(cdms_pk='cdms-pk') self.assertEqual(SimpleObj.objects.skip_cdms().count(), 1) self.assertEqual(obj.cdms_pk, 'cdms-pk') self.assertEqual(obj.name, 'new name') self.assertEqual(obj.modified, modified_on) self.assertAPIGetCalled( SimpleObj, kwargs={'guid': 'cdms-pk'} ) self.assertAPINotCalled(['list', 'update', 'delete', 'create']) # reload obj and check obj = SimpleObj.objects.skip_cdms().get(pk=obj.pk) self.assertEqual(obj.cdms_pk, 'cdms-pk') self.assertEqual(obj.name, 'new name') self.assertEqual(obj.modified, modified_on)
def __call__(self, result, mocked_cdms_api, *args, **kwargs): # mocking the modified value so that the tests don't depend on the automatic 'now' datetime value # and therefore we can catch all hidden problems. self.mocked_modified = (timezone.now() + datetime.timedelta(minutes=1)).replace(microsecond=0) mocked_cdms_api.create.side_effect = mocked_cdms_create() mocked_cdms_api.get.side_effect = mocked_cdms_get(get_data={ 'ModifiedOn': self.mocked_modified }) mocked_cdms_api.update.side_effect = mocked_cdms_update() self.mocked_cdms_api = mocked_cdms_api super(BaseMockedCDMSApiTestCase, self).__call__(result, *args, **kwargs)
def test_with_cdms_more_up_to_date(self): """ If the cdms obj includes more recent changes: - get obj from local db - get cdms_obj from cdms - update obj from cdms_obj - create a revision """ modified_on = self.obj.modified + datetime.timedelta(seconds=1) self.mocked_cdms_api.get.side_effect = mocked_cdms_get( get_data={ 'ModifiedOn': modified_on, 'Name': 'new name', 'DateTimeField': '/Date(1451606400000)/', 'IntField': 10, 'FKField': None } ) obj = SimpleObj.objects.get(pk=self.obj.pk) self.assertEqual(obj.name, 'new name') self.assertEqual(obj.dt_field, datetime.datetime(2016, 1, 1).replace(tzinfo=datetime.timezone.utc)) self.assertEqual(obj.int_field, 10) self.assertEqual(obj.modified, modified_on) self.assertEqual(obj.created, self.obj.created) self.assertAPIGetCalled( SimpleObj, kwargs={'guid': self.obj.cdms_pk} ) self.assertAPINotCalled(['list', 'update', 'delete', 'create']) # reload obj and check obj = SimpleObj.objects.skip_cdms().get(pk=obj.pk) self.assertEqual(obj.cdms_pk, 'cdms-pk') self.assertEqual(obj.name, 'new name') self.assertEqual(obj.modified, modified_on) # check versions self.assertEqual(Version.objects.count(), 1) self.assertEqual(Revision.objects.count(), 1) version_list = reversion.get_for_object(obj) self.assertEqual(len(version_list), 1) version = version_list[0] self.assertIsCDMSRefreshRevision(version.revision) version_data = version.field_dict self.assertEqual(version_data['cdms_pk'], obj.cdms_pk) self.assertEqual(version_data['modified'], obj.modified) self.assertEqual(version_data['created'], obj.created)
def test_local_doesnt_exist(self): """ MyObject.objects.get(cdms_pk=..) when local obj does not exist, should hit the cdms api, create a local obj and return it. The operation should create a revision. """ modified_on = (timezone.now() + datetime.timedelta(days=1)).replace(microsecond=0) self.mocked_cdms_api.get.side_effect = mocked_cdms_get( get_data={ 'ModifiedOn': modified_on, 'Name': 'new name', 'DateTimeField': None, 'IntField': None, 'FKField': None } ) SimpleObj.objects.skip_cdms().all().delete() self.assertEqual(SimpleObj.objects.skip_cdms().count(), 0) obj = SimpleObj.objects.get(cdms_pk='cdms-pk') self.assertEqual(SimpleObj.objects.skip_cdms().count(), 1) self.assertEqual(obj.cdms_pk, 'cdms-pk') self.assertEqual(obj.name, 'new name') self.assertEqual(obj.modified, modified_on) self.assertAPIGetCalled( SimpleObj, kwargs={'guid': 'cdms-pk'} ) self.assertAPINotCalled(['list', 'update', 'delete', 'create']) # reload obj and check obj = SimpleObj.objects.skip_cdms().get(pk=obj.pk) self.assertEqual(obj.cdms_pk, 'cdms-pk') self.assertEqual(obj.name, 'new name') self.assertEqual(obj.modified, modified_on) # check versions self.assertEqual(Version.objects.count(), 1) self.assertEqual(Revision.objects.count(), 1) version_list_obj = reversion.get_for_object(obj) self.assertEqual(len(version_list_obj), 1) version = version_list_obj[0] self.assertIsCDMSRefreshRevision(version.revision) version_data = version.field_dict self.assertEqual(version_data['cdms_pk'], obj.cdms_pk) self.assertEqual(version_data['modified'], obj.modified) self.assertEqual(version_data['created'], obj.created)
def test_with_objs_in_sync(self): """ If the cdms obj and local obj are in sync: - get obj from local db - get cdms_obj from cdms - no local changes happen """ self.mocked_cdms_api.get.side_effect = mocked_cdms_get( get_data={ 'ModifiedOn': self.obj.modified } ) obj = SimpleObj.objects.get(pk=self.obj.pk) self.assertEqual(obj.modified, self.obj.modified) self.assertAPIGetCalled( SimpleObj, kwargs={'guid': self.obj.cdms_pk} ) self.assertAPINotCalled(['list', 'update', 'delete', 'create'])
def test_with_local_more_up_to_date(self): """ If the local obj is more up to date, it means that the last syncronisation didn't work as it should have, so we raise ObjectsNotInSyncException. """ modified_on = self.obj.modified - datetime.timedelta(seconds=0.001) self.mocked_cdms_api.get.side_effect = mocked_cdms_get( get_data={ 'ModifiedOn': modified_on } ) self.assertRaises( ObjectsNotInSyncException, SimpleObj.objects.get, pk=self.obj.pk ) self.assertAPIGetCalled( SimpleObj, kwargs={'guid': self.obj.cdms_pk} ) self.assertAPINotCalled(['list', 'update', 'delete', 'create'])
def __call__(self, result, mocked_cdms_api, *args, **kwargs): mocked_cdms_api.create.side_effect = mocked_cdms_create() mocked_cdms_api.get.side_effect = mocked_cdms_get() self.mocked_cdms_api = mocked_cdms_api super(BaseMockedCDMSApiTestCase, self).__call__(result, *args, **kwargs)
def test_save(self): """ obj.save() should - get the related cdms obj - update the cdms obj - save local obj This also checks that after the operation, the local_obj.modified has the same value as the cdms modified one, NOT the automatic django value. This is important for the syncronisation. """ # mock get call self.mocked_cdms_api.get.side_effect = mocked_cdms_get( get_data={ 'ModifiedOn': timezone.now() + datetime.timedelta(hours=1) } ) modified_on = (timezone.now() + datetime.timedelta(days=1)).replace(microsecond=0) self.mocked_cdms_api.update.side_effect = mocked_cdms_update( update_data={ 'ModifiedOn': modified_on } ) # create without cdms and then save obj = SimpleObj.objects.skip_cdms().create( cdms_pk='cdms-pk', name='old name' ) # save self.assertEqual(SimpleObj.objects.skip_cdms().count(), 1) obj.name = 'simple obj' obj.save() self.assertEqual(SimpleObj.objects.skip_cdms().count(), 1) self.assertEqual(obj.modified, modified_on) # check cdms get called self.assertAPIGetCalled( SimpleObj, kwargs={'guid': 'cdms-pk'} ) # check cdms update called self.assertAPIUpdateCalled( SimpleObj, kwargs={ 'guid': 'cdms-pk', 'data': { 'Name': 'simple obj', 'DateTimeField': None, 'IntField': None, 'SimpleId': 'cdms-pk', 'FKField': None } } ) self.assertAPINotCalled(['list', 'create', 'delete']) # reload obj and check, 'modified' should be == cdms modified obj = SimpleObj.objects.skip_cdms().get(pk=obj.pk) self.assertEqual(obj.name, 'simple obj') self.assertEqual(obj.modified, modified_on)