def test_delete_code_allowed(self): code = 'trout viper' path = '/api/codes/{}'.format(code.replace(' ', '-')) pc = ProjectCohort.create( code=code, organization_id='triton', program_label='triton', ) pc.put() pc.key.get() # simulate consistency, code fetches are eventual token = jwt_helper.encode({ 'user_id': 'User_foo', 'email': '*****@*****.**', 'allowed_endpoints': ['DELETE //neptune{}'.format(path)], }) self.testapp.delete( path, headers={'Authorization': 'Bearer ' + token}, status=204, ) # Project cohort AND Unique should be gone self.assertIsNone(pc.key.get()) unique_key = ndb.Key('Unique', ProjectCohort.uniqueness_key(code)) self.assertIsNone(unique_key.get())
def delete_for_program(entity): """Permanently delete anything in the datastore from a program. Works with Projects, ProjectCohorts, and Surveys. Also requires a param set in mapreduce.yaml: `program_label`. """ params = context.get().mapreduce_spec.mapper.params if getattr(entity, 'program_label', None) != params['program_label']: return # If this is a project cohort, delete the Unique entity that serves as an # index of participation codes. key_name = ProjectCohort.uniqueness_key(getattr(entity, 'code', '')) unique_entity = ndb.Key('Unique', key_name).get() if unique_entity: yield op.db.Delete(unique_entity) # Some entities have tasks in their entity group. There's no convenient # way to query tasks directly, so delete them while we're handling their # parent. # Bypass DatastoreModel to make sure we get soft-deleted entities. for task in Task.query(ancestor=entity.key).iter(): yield op.db.Delete(task) yield op.db.Delete(entity)