def create_checkpoints(self): """Checkpoints should gain additional properties as client dicts.""" config = { 'project_tasklist_template': [ { 'name': "Project Foo", 'label': 'demo_project__foo', 'body': "foo", 'tasks': [], }, { 'name': "Project Bar", 'label': 'demo_project__bar', 'body': "bar", 'tasks': [], }, ], } Program.mock_program_config('demo-program', config) checkpoints = ( Checkpoint.create( parent_id='Project_foo', ordinal=1, program_label='demo-program', **config['project_tasklist_template'][0] ), Checkpoint.create( parent_id='Project_bar', ordinal=2, program_label='demo-program', **config['project_tasklist_template'][1] ), ) Checkpoint.put_multi(checkpoints) return checkpoints
def test_select_checkpoints_with_offset(self): """Can use queries like "LIMIT 20,10" to get "pages" of records.""" # Create two checkpoints. program_label = 'demo-program' Program.mock_program_config( program_label, { 'project_tasklist_template': [ { 'name': 'Foo', 'label': 'checkpoint_foo', 'tasks': [] }, { 'name': 'Bar', 'label': 'checkpoint_bar', 'tasks': [] }, ] }) project = Project.create(program_label=program_label, organization_id='Organization_Foo') project.put() # Select each of the two checkpoints in different queries with one-row # pages. r1 = Checkpoint.get(program_label=program_label, n=1, offset=0) r2 = Checkpoint.get(program_label=program_label, n=1, offset=1) self.assertNotEqual(r1[0].uid, r2[0].uid)
def test_update_checkpoint(self): project = Project.create(program_label='demo-program', organization_id='Organization_Foo') project.put() checkpoint = Checkpoint.get(parent_id=project.uid)[0] checkpoint.name = 'foo' checkpoint.put() fetched = Checkpoint.get_by_id(checkpoint.uid) self.assertEqual(fetched.name, 'foo')
def test_update_checkpoint_waiting(self): user = User.create(email='*****@*****.**', user_type='super_admin') user.put() org = Organization.create(name='Foo Org') org.put() # Work with the first checkpoint (generally there's only one anyway). c = org.tasklist.checkpoints[0] # Our org tasklist doesn't change much; break down its structure. tasks = [t for t in org.tasklist.tasks if t.checkpoint_id == c.uid] invite_task, liaison_task, approve_task = tasks # Marking the first two complete should change the checkpoint to # waiting, since the last is for super admins only. for task in (invite_task, liaison_task): task.status = 'complete' self.testapp.put_json( '/api/tasks/{}'.format(task.uid), task.to_client_dict(), headers=login_headers(user.uid), ) fetched_c = Checkpoint.get_by_id(c.uid) self.assertEqual(fetched_c.status, 'waiting')
def set_up(self): """Clear relevant tables from testing SQL database.""" # Let ConsistencyTestCase set up the datastore testing stub. super(TestGraphQLProjectCohort, self).set_up() with mysql_connection.connect() as sql: sql.reset({ 'checkpoint': Checkpoint.get_table_definition(), }) Program.mock_program_config( self.program_label, { 'name': self.program_name, 'default_portal_type': 'name_or_id', 'description': self.program_description, 'cohorts': { self.cohort_label: self.cohort } }) application = webapp2.WSGIApplication(api_routes, config={ 'webapp2_extras.sessions': { 'secret_key': self.cookie_key } }, debug=True) self.testapp = webtest.TestApp(application)
def test_checkpoint_creation(self): project = Project.create(program_label='demo-program', organization_id='Organization_Foo') project.put() checkpoints = Checkpoint.get(parent_id=project.uid) program_config = Program.get_config(project.program_label) template = program_config['project_tasklist_template'] self.assertEqual(len(checkpoints), len(template))
def test_update_checkpoint(self): """Can't change a checkpoint to an invalid status, based on tasks.""" # One checkpoint with one tasks. orig_config = organization_tasks.tasklist_template tasklist_tmpl = [ { 'name': "Checkpoint Foo", 'label': 'checkpoint label foo', 'tasks': [{ 'label': 'foo', 'non_admin_may_edit': True }, { 'label': 'bar', 'non_admin_may_edit': True }] }, ] organization_tasks.tasklist_template = tasklist_tmpl user = User.create(email='*****@*****.**', user_type='user') org = Organization.create(name='org', tasklist_template=tasklist_tmpl, liaison_id=user.uid) user.owned_organizations = [org.uid] org.put() user.put() # Make one task complete, the other stays incomplete by default. org.tasklist.tasks[0].status = 'complete' org.tasklist.tasks[0].put() # This is an unsaved, in-memory dict, and thus doesn't contain defaults # set in the table definition. ckpt = org.tasklist.checkpoints[0] # Fetch the checkpoint by id to pick up those defaults. ckpt = Checkpoint.get_by_id(ckpt.uid) # The derived checkpoint status is 'incomplete'. Setting it this way # should work. response = self.testapp.put_json( '/api/checkpoints/{}'.format(ckpt.uid), ckpt.to_client_dict(), headers=login_headers(user.uid), ) # Shouldn't be able to set the checkpoint to any other value. ckpt.status = 'foo' response = self.testapp.put_json( '/api/checkpoints/{}'.format(ckpt.uid), ckpt.to_client_dict(), headers=login_headers(user.uid), status=500, ) organization_tasks.tasklist_template = orig_config
def set_up(self): """Clear relevant tables from testing SQL database.""" # Let ConsistencyTestCase set up the datastore testing stub. super(TestSqlModel, self).set_up() with mysql_connection.connect() as sql: sql.reset({ 'checkpoint': Checkpoint.get_table_definition(), 'participant_data': ParticipantData.get_table_definition(), })
def test_fetch_checkpoints(self): """Tests method to pull checkpoints for an organization tasklist.""" org = Organization.create() org.put() # Tasks are automatically created from template on org.put() checkpoints = Checkpoint.get(parent_id=org.uid, order='ordinal') self.assertNotEqual(len(checkpoints), 0) self.assertEqual(DatastoreModel.get_kind(checkpoints[0].uid), 'Checkpoint') # Check that the checkpoints are being ordered properly. for i, c in enumerate(checkpoints): self.assertEqual(c.ordinal, i + 1)
def test_checkpoint_creation(self): program_label = 'demo-program' program_config = Program.get_config(program_label) template = program_config['surveys'][0]['survey_tasklist_template'] survey = Survey.create( template, program_label=program_label, organization_id='Organization_Foo', ordinal=1, ) survey.put() checkpoints = Checkpoint.get(parent_id=survey.uid) self.assertEqual(len(checkpoints), len(template))
def set_up(self): """Clear relevant tables from testing SQL database.""" super(TestTaskReminder, self).set_up() with mysql_connection.connect() as sql: sql.reset({'checkpoint': Checkpoint.get_table_definition()}) application = webapp2.WSGIApplication(api_routes, config={ 'webapp2_extras.sessions': { 'secret_key': self.cookie_key } }, debug=True) self.testapp = webtest.TestApp(application)
def set_up(self): # Let ConsistencyTestCase set up the datastore testing stub. super(TestApiTask, self).set_up() with mysql_connection.connect() as sql: sql.reset({'checkpoint': Checkpoint.get_table_definition()}) application = webapp2.WSGIApplication(api_routes, config={ 'webapp2_extras.sessions': { 'secret_key': self.cookie_key } }, debug=True) self.testapp = webtest.TestApp(application)
def test_checkpoint_client_dict(self): """Checkpoints should gain additional properties as client dicts.""" checkpoint_template = { 'name': "Project Foo", 'label': 'demo_project__foo', 'body': "foo", 'tasks': [], } config = {'project_tasklist_template': [checkpoint_template]} Program.mock_program_config('demo-program', config) checkpoint = Checkpoint.create(parent_id='Project_foo', ordinal=1, program_label='demo-program', **checkpoint_template) self.assertIsNone(getattr(checkpoint, 'body', None)) self.assertIsNotNone(checkpoint.to_client_dict()['body'])
def create_with_project_cohort(self): checkpoint_template = { 'name': "Survey Foo", 'label': 'demo_survey__foo', 'body': "foo", 'tasks': [], } config = { 'surveys': [ { 'name': "Student Module", 'survey_tasklist_template': [checkpoint_template], }, ], } Program.mock_program_config(self.program_label, config) org = Organization.create(name='Foo Org') org.put() project = Project.create( program_label=self.program_label, organization_id=org.uid, ) project.put() pc = ProjectCohort.create( program_label=self.program_label, organization_id=org.uid, project_id=project.uid, ) pc.put() checkpoint = Checkpoint.create(parent_id='Survey_foo', ordinal=1, program_label=self.program_label, organization_id=org.uid, project_id=project.uid, project_cohort_id=pc.uid, status='incomplete', **checkpoint_template) checkpoint.put() pc.update_cached_properties() return org, project, pc, checkpoint
def tasklist_query_expected(self, liaison, org, project, pc, surveys): org.tasklist.open() project.tasklist.open() for s in surveys: s.tasklist.open() unexpected_props = ('survey_ids', ) pc_items = [(k, v) for k, v in pc.to_client_dict().items() if k not in unexpected_props] # Assemble the result we expect, being careful to put everything in an # explicit order, since that's how the client will see it. expected = { "project_cohort": OrderedDict(pc_items + [ ('surveys', [s.to_client_dict() for s in surveys]), ('checkpoints', [ OrderedDict( list(c.to_client_dict().items()) + [ ('tasks', [ t.to_client_dict() for t in Task.get( ancestor=DatastoreModel.id_to_key( c.parent_id), checkpoint_id=c.uid, order='ordinal', ) ]), ]) for c in Checkpoint.for_tasklist(pc) ]), ("liaison", liaison.to_client_dict()), ("organization", OrderedDict( list(org.to_client_dict().items()) + [ ("liaison", liaison.to_client_dict()), ("users", [ liaison.to_client_dict(), ]), ])), ("program_cohort", self.cohort), ("project", project.to_client_dict()), ]), } return graphql_queries.single_tasklist, expected
def set_up(self): # Let ConsistencyTestCase set up the datastore testing stub. super(TestApiPermissions, self).set_up() with mysql_connection.connect() as sql: sql.reset({'checkpoint': Checkpoint.get_table_definition()}) application = webapp2.WSGIApplication(api_routes, config={ 'webapp2_extras.sessions': { 'secret_key': self.cookie_key } }, debug=True) self.testapp = webtest.TestApp(application) # Tone down the intense number of hashing rounds for passwords so our # unit tests are fast. User.password_hashing_context.update( sha512_crypt__default_rounds=1000, sha256_crypt__default_rounds=1000, )
def set_up(self): """Clear relevant tables from testing SQL database.""" super(TestTask, self).set_up() with mysql_connection.connect() as sql: sql.reset({'checkpoint': Checkpoint.get_table_definition()})
def test_get_checkpoint_by_id(self): project = Project.create(program_label='demo-program', organization_id='Organization_Foo') project.put() checkpoints = Checkpoint.get(parent_id=project.uid) self.assertIsNotNone(Checkpoint.get_by_id(checkpoints[0].uid))
def set_up(self): """Clear relevant tables from testing SQL database.""" # Let ConsistencyTestCase set up the datastore testing stub. super(TestProject, self).set_up() with mysql_connection.connect() as sql: sql.reset({'checkpoint': Checkpoint.get_table_definition()})
def get(self): program_label = 'cg17' cohort = Program.get_current_cohort(program_label) url = '{protocol}://{domain}/api/scripts/cg'.format( protocol='http' if util.is_localhost() else 'https', domain=('localhost:9080' if util.is_localhost() else os.environ['RSERVE_DOMAIN']), ) # Look up all the valid project cohorts pc_ids = [ pc_key.id() for pc_key in ProjectCohort.get( program_label=program_label, cohort_label=cohort['label'], status='open', keys_only=True, n=float('inf'), ) ] # To match up the right report tasks, we'll need tasks and checkpoints. checkpoints = [ c for c in Checkpoint.get( label='cg17_survey__monitor_1', cohort_label=cohort['label'], n=float('inf'), ) if c.project_cohort_id in pc_ids ] checkpoint_ids = [c.uid for c in checkpoints] tasks = [ t for t in Task.get( label='cg17_survey__report_1', n=float('inf'), ) if t.checkpoint_id in checkpoint_ids ] # Alternate way to get tasks, via surveys, which may or may not be # more efficient. My current assumption is, for large result sets, # SQL-back checkpoints are faster. # # survey_keys = [s.key for s in Survey.get( # program_label=program_label, # cohort_label=cohort['label'], # n=float('inf'), # ) if s.project_cohort_id in pc_ids] # tasks = [t for t in Task.get( # label='cg17_survey__report_1', # n=float('inf'), # ) if t.key.parent() in survey_keys] payload = { 'reporting_units': [ self.build_reporting_unit(uid, checkpoints, tasks) for uid in pc_ids ], } secrets = ('neptune_sql_credentials', 'big_pipe_credentials', 'qualtrics_credentials') for s in secrets: payload[s] = SecretValue.get(s, None) result = urlfetch.fetch(url=url, payload=json.dumps(payload), method=urlfetch.POST, headers={ 'Authorization': 'Bearer ' + rserve_jwt(), 'Content-Type': 'application/json', }) if not result or result.status_code >= 300: logging.error("Non-successful response from RServe: {} {}".format( result.status_code, result.content)) else: logging.info("response status: {}".format(result.status_code)) try: json.loads(result.content) # ok, it's valid # logging.info(util.truncate_json(result.content)) logging.info(result.content) except: # just log as text logging.info(result.content)