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
Пример #2
0
    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)
Пример #3
0
 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')
Пример #4
0
    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)
Пример #6
0
 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
Пример #8
0
 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(),
         })
Пример #9
0
    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)
Пример #10
0
 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))
Пример #11
0
    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)
Пример #12
0
    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)
Пример #13
0
 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'])
Пример #14
0
    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
Пример #16
0
    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,
        )
Пример #17
0
 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()})
Пример #18
0
 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))
Пример #19
0
 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()})
Пример #20
0
    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)