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)
Exemplo n.º 2
0
    def set_up(self):
        # Let ConsistencyTestCase set up the datastore testing stub.
        super(TestApiParticipation, self).set_up()

        application = webapp2.WSGIApplication(api_routes,
                                              config={
                                                  'webapp2_extras.sessions': {
                                                      'secret_key':
                                                      self.cookie_key
                                                  }
                                              },
                                              debug=True)
        self.testapp = webtest.TestApp(application)

        # Successful download of completion ids triggers a notification, which
        # requires a cohort name.
        Program.mock_program_config(
            self.program_label,
            {'cohorts': {
                self.cohort_label: {
                    'name': self.cohort_label
                }
            }},
        )

        with mysql_connection.connect() as sql:
            sql.reset({
                'participant':
                Participant.get_table_definition(),
                'participant_data':
                ParticipantData.get_table_definition(),
            })
    def set_up(self):
        # Let ConsistencyTestCase set up the datastore testing stub.
        super(TestApiAuthentication, self).set_up()

        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,
        )

        # Should be able to register with a legit cohort. Make sure it exists.
        Program.mock_program_config(
            self.program_label,
            {
                'name': self.program_name,
                'cohorts': {
                    self.cohort_label: {
                        'name': self.cohort_label
                    }
                }
            },
        )
Exemplo n.º 4
0
    def create_project_cohort(self, cohort_date=datetime.datetime.today()):
        program_label = 'demo-program'
        cohort_label = 'demo-cohort'
        program = Program.get_config(program_label)
        org_id = 'Org_Foo'
        liaison_id = 'User_liaison'
        project = Project.create(organization_id=org_id,
                                 program_label=program_label)
        project.put()

        one_day = datetime.timedelta(days=1)
        cohort_config = {
            'label': cohort_label,
            'name': 'Demo Cohort',
            'open_date': str(cohort_date - one_day),  # yesterday
            'close_date': str(cohort_date + one_day),  # tomorrow
        }
        program['cohorts'][cohort_label] = cohort_config
        Program.mock_program_config(
            program_label,
            {'cohorts': {
                cohort_label: cohort_config
            }},
        )

        pc = ProjectCohort.create(
            project_id=project.uid,
            organization_id=org_id,
            program_label=program_label,
            cohort_label=cohort_label,
            liaison_id=liaison_id,
        )
        pc.put()

        return pc
Exemplo n.º 5
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)
 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
Exemplo n.º 7
0
    def create_project_task(self, cohort_date=datetime.datetime.today()):
        program_label = 'demo-program'
        task_label = 'task_project_foo'
        project = Project.create(program_label=program_label,
                                 organization_id='Organization_Foo')

        task_template = {
            'label':
            task_label,
            'data_type':
            'radio',
            'select_options': [{
                'value': 'normal',
                'label': 'true names'
            }, {
                'value': 'alias',
                'label': 'aliases'
            }],
        }
        Program.mock_program_config(
            program_label,
            {'project_tasklist_template': [{
                'tasks': [task_template]
            }]})

        t = Task.create(task_label,
                        1,
                        'checkpoint_foo',
                        parent=project,
                        program_label=program_label)
        t.put()
        return t
Exemplo n.º 8
0
    def test_project_task_body(self):
        """Tasks should get dynamic properties from their definition."""
        program_label = 'demo-program'
        task_label = 'task_foo'
        project = Project.create(program_label=program_label,
                                 organization_id='Organization_Foo')

        task_template = {
            'label': task_label,
            'body': "<p>Demo body.</p>",
        }
        Program.mock_program_config(
            program_label,
            {'project_tasklist_template': [{
                'tasks': [task_template]
            }]})
        t = Task.create(task_label,
                        1,
                        'checkpoint_foo',
                        parent=project,
                        program_label=program_label)
        t_dict = t.to_client_dict()

        self.assertIsInstance(t_dict['body'], basestring)
        self.assertGreater(len(t_dict['body']), 0)
Exemplo n.º 9
0
    def test_create_select(self):
        program_label = 'demo-program'
        task_label = 'task_foo'
        project = Project.create(program_label=program_label,
                                 organization_id='Organization_Foo')

        task_template = {
            'label':
            task_label,
            'data_type':
            'radio',
            'select_options': [{
                'value': 'normal',
                'label': 'true names'
            }, {
                'value': 'alias',
                'label': 'aliases'
            }],
        }
        Program.mock_program_config(
            program_label,
            {'project_tasklist_template': [{
                'tasks': [task_template]
            }]})

        t = Task.create(task_label,
                        1,
                        'checkpoint_foo',
                        parent=project,
                        program_label=program_label)
        t_dict = t.to_client_dict()
        self.assertEqual(t_dict['select_options'],
                         task_template['select_options'])
Exemplo n.º 10
0
    def test_initial_values(self):
        """Adopt initial values if specified, overriding defaults."""
        # Background
        program_label = 'demo-program'
        task_label_default = 'task_default'
        task_label_init = 'task_init'

        # One task with default values, one with a non-default initial value.
        task_template_default = {
            'label': task_label_default,
            # default value of disabled is False
        }
        task_template_initial_values = {
            'label': task_label_init,
            'initial_values': {
                'disabled': True
            },  # override default
        }
        Program.mock_program_config(
            program_label, {
                'project_tasklist_template': [{
                    'tasks': [
                        task_template_default,
                        task_template_initial_values,
                    ]
                }]
            })

        # Creating the project will generate a tasklist with the above tasks.
        project = Project.create(program_label=program_label,
                                 organization_id='Organization_Foo')

        self.assertFalse(project.tasklist.tasks[0].disabled)
        self.assertTrue(project.tasklist.tasks[1].disabled)
Exemplo n.º 11
0
    def set_up(self):
        """Clear relevant tables from testing SQL database."""
        # Let ConsistencyTestCase set up the datastore testing stub.
        super(TestProjectCohort, self).set_up()

        Program.mock_program_config(self.program_label, {
            'default_portal_type': 'name_or_id',
        })
Exemplo n.º 12
0
    def test_join_org(self):
        """Joining an org makes task reminders for all contained tasklists."""
        program_label = 'demo-program'
        cohort_label = 'demo-cohort'

        # Guarantee the dates will work by mocking the cohort config.
        cohort_config = {
            'label': cohort_label,
            'name': 'Demo Cohort',
            'open_date': str(datetime.date.today()),
            'close_date': str(datetime.date.today()),
        }
        Program.mock_program_config(
            program_label,
            {'cohorts': {
                cohort_label: cohort_config
            }},
        )

        program = Program.get_config(program_label)
        tasklist_template = program['surveys'][0]['survey_tasklist_template']

        owner = User.create(email='*****@*****.**', user_type='user')
        org = Organization.create(name="Foo Org", liaison_id=owner.uid)
        owner.owned_organizations = [org.uid]
        project = Project.create(program_label=program_label,
                                 organization_id=org.uid)
        survey = Survey.create(tasklist_template,
                               project_id=project.uid,
                               organization_id=org.uid,
                               program_label=program_label,
                               ordinal=1,
                               cohort_label=cohort_label)
        owner.put()
        org.put()
        project.put()
        survey.put()

        # The assumption here is the org and its contents are long-standing,
        # so force consistency with all.
        org.key.get()
        project.key.get()
        survey.key.get()

        joiner = User.create(email='*****@*****.**', user_type='user')
        joiner.put()

        self.testapp.post_json(
            '/api/users/{}/organizations'.format(joiner.uid),
            org.to_client_dict(),
            headers=login_headers(owner.uid),
        )

        # One TaskReminder for each of: org tasklist, project tasklist, survey
        # tasklist.
        self.assertEqual(len(TaskReminder.get(ancestor=joiner)), 3)

        return (org, project, survey, owner, joiner)
Exemplo n.º 13
0
    def test_queue_org_welcome_back(self):
        Program.mock_program_config('p1', {'project_tasklist_template': []})

        # Case 1: New PC, returning.
        returning_pc1 = ProjectCohort.create(
            program_label='p1',
            organization_id='Organization_returning',
            project_id='Project_returning',
            cohort_label='2020',
        )
        returning_pc1.put()
        returning_pc2 = ProjectCohort.create(
            program_label='p1',
            organization_id='Organization_returning',
            project_id='Project_returning',
            cohort_label='2019',
            created=datetime.datetime.now() - datetime.timedelta(days=365))
        returning_pc2.put()

        # Case 2: New PC, but not returning.
        new_pc = ProjectCohort.create(
            program_label='p1',
            organization_id='Organization_new',
            project_id='Project_new',
        )
        new_pc.put()

        # Case 3: Old PC (not created in the day).
        old_pc = ProjectCohort.create(
            program_label='p1',
            organization_id='Organization_old',
            project_id='Project_old',
            created=datetime.datetime.now() - datetime.timedelta(hours=48),
        )
        old_pc.put()

        # Some tasks are created on put. We're not interested in these.
        creation_tasks = self.taskqueue_stub.get_filtered_tasks()

        templates = [
            self.create_mandrill_template('p1-{}'.format(
                auto_prompt.ORG_WELCOME_BACK_SUFFIX)),
        ]

        auto_prompt.queue_org_welcome_back(templates)

        tasks = self.taskqueue_stub.get_filtered_tasks()
        num_new_tasks = len(tasks) - len(creation_tasks)

        # Only the returning pc should have a task queued.
        self.assertEqual(num_new_tasks, 1)

        expected_url = '/task/email_project/Project_returning/p1-org-welcome-back'
        self.assertIn(expected_url, [t.url for t in tasks])

        Program.reset_mocks()
Exemplo n.º 14
0
    def test_override_portal_message(self):
        label = 'override-program'
        config = {'override_portal_message': 'Override message.'}
        Program.mock_program_config(label, config)

        pc = ProjectCohort.create(program_label=label)
        self.assertEqual(
            pc.to_client_dict()['portal_message'],
            config['override_portal_message'],
        )
Exemplo n.º 15
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'])
    def set_up(self):
        # Let ConsistencyTestCase set up the datastore testing stub.
        super(TestGraphQLProgramCohort, self).set_up()

        application = webapp2.WSGIApplication(
            api_routes,
            config={
                'webapp2_extras.sessions': {
                    'secret_key': self.cookie_key
                }
            },
            debug=True
        )
        self.testapp = webtest.TestApp(application)

        Program.mock_program_config('demo-program', {'cohorts': self.cohorts})
Exemplo n.º 17
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 test_join_cohort(self, cohort_date=datetime.date.today()):
        """Allowed for org admin owner of project."""

        # Existing things to relate to.
        program_label = 'demo-program'
        cohort_label = 'demo-cohort'
        program = Program.get_config(program_label)
        org_id = 'Org_Foo'
        user = User.create(email="*****@*****.**",
                           owned_organizations=[org_id])
        project = Project.create(organization_id=org_id,
                                 program_label=program_label)
        user.put()
        project.put()

        # Guarantee the dates will work by mocking the cohort config.
        one_day = datetime.timedelta(days=1)
        cohort_config = {
            'label': cohort_label,
            'name': 'Demo Cohort',
            'open_date': str(cohort_date - one_day),  # yesterday
            'close_date': str(cohort_date + one_day),  # tomorrow
        }
        program['cohorts'][cohort_label] = cohort_config
        Program.mock_program_config(
            program_label,
            {'cohorts': {cohort_label: cohort_config}},
        )

        # Create the project cohort through the api. Any response other than
        # 200 will fail the test.
        response = self.testapp.post_json(
            '/api/project_cohorts',
            {
                'project_id': project.uid,
                'organization_id': org_id,
                'program_label': program_label,
                'cohort_label': cohort_label,
                'liaison_id': user.uid,
            },
            headers=login_headers(user.uid)
        )
        response_dict = json.loads(response.body)

        return (ProjectCohort.get_by_id(response_dict['uid']), user)
Exemplo n.º 19
0
    def set_up(self):
        """Clear relevant tables from testing SQL database."""
        # Let ConsistencyTestCase set up the datastore testing stub.
        super(TestGraphQL, self).set_up()

        Program.mock_program_config(self.program_label, {
            'default_portal_type': 'name_or_id',
        })

        application = webapp2.WSGIApplication(api_routes,
                                              config={
                                                  'webapp2_extras.sessions': {
                                                      'secret_key':
                                                      self.cookie_key
                                                  }
                                              },
                                              debug=True)
        self.testapp = webtest.TestApp(application)
    def test_dashboard_unlisted(self):
        """Some programs support other apps and aren't meant to be queried."""
        # See #1015
        Program.mock_program_config('ep19', {'listed': False})

        user = User.create(email='*****@*****.**', user_type='super_admin')
        user.put()

        pc = ProjectCohort.create(
            program_label='ep19',
            organization_id='Org_foo',
        )
        pc.put()

        response = self.testapp.get('/api/dashboard?program_label=ep19',
                                    headers=login_headers(user.uid))

        self.assertEqual(response.body, '[]')
Exemplo n.º 21
0
    def test_queue_org_welcome(self):
        Program.mock_program_config('p1', {'project_tasklist_template': []})
        Program.mock_program_config('p2', {'project_tasklist_template': []})
        old_project = Project.create(
            program_label='p1',
            organization_id='Organization_foo',
            created=datetime.datetime.now() - datetime.timedelta(hours=48),
        )
        old_project.put()
        new_project = Project.create(
            program_label='p1',
            organization_id='Organization_foo',
        )
        new_project.put()
        other_project = Project.create(
            program_label='p2',  # no matching template
            organization_id='Organization_foo',
        )
        other_project.put()

        templates = [
            self.create_mandrill_template('p1-{}'.format(
                auto_prompt.ORG_WELCOME_SUFFIX)),
            self.create_mandrill_template('foo-template'),
        ]

        auto_prompt.queue_org_welcome(templates)

        tasks = self.taskqueue_stub.get_filtered_tasks()

        # Only the recently created project, which also has a org welcome
        # template, should be queued. The old project, and the project on the
        # other program, should not be welcomed.
        self.assertEqual(len(tasks), 1)

        expected_url = '/task/email_project/{}/p1-org-welcome'.format(
            new_project.uid)
        self.assertIn(expected_url, [t.url for t in tasks])

        Program.reset_mocks()
    def test_custom_sender(self):
        # Mock a program that defines a special contact email address.
        program_label = 'ep'
        sender = '*****@*****.**'
        Program.mock_program_config(
            program_label,
            {
                'name': 'Engagement Project',
                'contact_email_address': sender,
            },
        )

        email_addr = '*****@*****.**'

        response = self.testapp.post_json(
            '/api/register',
            {
                'domain': 'https://copilot.perts.net',
                'platform': 'triton',
                'email': email_addr,
                'program_label': program_label,
            },
            status=204,
        )

        # Email was created with from/reply properties.
        emails = Email.get(to_address=email_addr)
        email = emails[0]
        self.assertEqual(
            email.mandrill_template_content['contact_email_address'],
            sender,
        )
        self.assertEqual(email.from_address, sender)
        self.assertEqual(email.reply_to, sender)
        # Should be hard-coded in api_helper
        self.assertEqual(email.from_name, 'Copilot')
Exemplo n.º 23
0
    def test_checklist_nudge(self):
        month_from_now = util.datelike_to_iso_string(datetime.date.today() +
                                                     datetime.timedelta(
                                                         days=30))

        Program.mock_program_config(
            'p1',
            {
                'cohorts': {
                    '2019': {
                        'label': '2019',
                        'open_date': '2019-06-01'
                    },
                    '2020': {
                        'label': '2020',
                        'open_date': month_from_now
                    },
                },
                'project_tasklist_template': []
            },
        )
        Program.mock_program_config(
            'p2',
            {
                'cohorts': {},
                'project_tasklist_template': []
            },
        )

        templates = [
            self.create_mandrill_template('p1-{}'.format(
                auto_prompt.CHECKLIST_NUDGE_SUFFIX)),
        ]

        # Case 1: 2020 PCs gets prompt
        current_pc1 = ProjectCohort.create(
            program_label='p1',
            organization_id='Organization_foo',
            project_id='Project_current1',
            cohort_label='2020',
        )
        current_pc1.put()
        current_pc2 = ProjectCohort.create(
            program_label='p1',
            organization_id='Organization_bar',
            project_id='Project_current2',
            cohort_label='2020',
        )
        current_pc2.put()

        # Case 2: 2019 PC does not
        old_pc = ProjectCohort.create(
            program_label='p1',
            cohort_label='2019',
            project_id='Project_old',
        )
        old_pc.put()

        # Case 3: PC in other program does not
        other_pc = ProjectCohort.create(
            program_label='p2',
            cohort_label='2020',
            project_id='Project_other',
        )
        other_pc.put()

        # Some tasks are created on put. We're not interested in these.
        creation_tasks = self.taskqueue_stub.get_filtered_tasks()

        auto_prompt.queue_checklist_nudge(templates)

        tasks = self.taskqueue_stub.get_filtered_tasks()
        num_new_tasks = len(tasks) - len(creation_tasks)

        # Only the 2 2020 pcs in the right program should have a task queued.
        self.assertEqual(num_new_tasks, 2)

        expected_url1 = '/task/email_project/Project_current1/p1-checklist-nudge'
        self.assertIn(expected_url1, [t.url for t in tasks])
        expected_url2 = '/task/email_project/Project_current2/p1-checklist-nudge'
        self.assertIn(expected_url2, [t.url for t in tasks])

        Program.reset_mocks()