Ejemplo n.º 1
0
    def get(self, template, context_id):
        # Attempt to treat id as as project cohort (it might be a program, or
        # invalid).
        project_cohort = ProjectCohort.get_by_id(context_id)

        def todt(s):
            return datetime.datetime.strptime(s, config.iso_date_format)

        if project_cohort:
            # This is a "real" set of instructions with data filled in.
            organization = Organization.get_by_id(
                project_cohort.organization_id)
            liaison = User.get_by_id(organization.liaison_id)
            program = Program.get_config(project_cohort.program_label)
            cohort = program['cohorts'][project_cohort.cohort_label]
            participation_open_date = todt(cohort['open_date'])
            # See notes in program config for why we take a day off for display.
            participation_close_date = (todt(cohort['close_date']) -
                                        datetime.timedelta(1))
        else:
            # This is a generic example version of the document.
            try:
                program = Program.get_config(context_id)
            except ImportError:
                return self.http_not_found()
            organization = None
            liaison = None
            project_cohort = None
            cohort = None
            participation_open_date = None
            participation_close_date = None

        if template == 'custom_portal_technical_guide':
            # This template doesn't vary by program.
            template_filename = '{}.html'.format(template)
        else:
            template_filename = '{}_{}.html'.format(program['label'], template)

        self.write(
            template_filename,
            organization=organization,
            liaison=liaison,
            program_name=program['name'],
            cohort_name=cohort['name'] if cohort else '',
            program_description=program['description'],
            project_cohort=project_cohort,
            participation_open_date=participation_open_date,
            participation_close_date=participation_close_date,
        )
Ejemplo n.º 2
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
Ejemplo n.º 3
0
def changed_project_task(user, project, task, project_cohort_id=None):
    """If change made by an org admin, notify related account manager, or all
    the program owners. Otherwise, notify project liaison, or all the org
    admins.
    """
    t_dict = task.to_client_dict()
    program_config = Program.get_config(project.program_label)
    if project_cohort_id:
        link = '/dashboard/{pc}/tasks/{ckpt}/{task}'.format(
            pc=DatastoreModel.convert_uid(project_cohort_id),
            ckpt=DatastoreModel.convert_uid(task.checkpoint_id),
            task=task.uid
        )
    else:
        link = '/dashboard'
    params = {
        'task_id': task.uid,
        'context_id': project.uid,
        'subject': "Task updated",
        'body': u"{} updated \"{}\" in {}.".format(
            user.name, t_dict['name'], program_config['name']),
        'link': link,
        'autodismiss': True,
    }
    if user.non_admin:
        # Send to account managers (usu. set via program config ->
        # default_account_manager).
        parents = get_project_program_recipients(project)
    else:
        parents = get_project_organization_recipients(project)
    notes = [Notification.create(parent=p, **params) for p in parents]

    filtered_notes = Notification.filter_redundant(notes)
    ndb.put_multi(filtered_notes)
Ejemplo n.º 4
0
def joined_cohort(user, project_cohort):
    """Notify program and super admins."""
    # This always happens along with creating a program.
    pc = project_cohort
    program_admins = User.get(owned_programs=pc.program_label)
    super_admins = User.get(user_type='super_admin')
    organization = Organization.get_by_id(pc.organization_id)
    program_config = Program.get_config(pc.program_label)
    cohort_name = program_config['cohorts'][pc.cohort_label]['name']

    notes = []
    for admin in program_admins + super_admins:
        note = Notification.create(
            parent=admin,
            context_id=pc.uid,
            subject=u"{org} joined a cohort".format(org=organization.name),
            body=(
                u"{org} joined {cohort} in {program}. The organization is "
                "currently {status}."
            ).format(
                org=organization.name, cohort=cohort_name,
                program=program_config['name'], status=organization.status,
            ),
            link='/organizations/{}'.format(organization.short_uid),
            autodismiss=True,
        )
        notes.append(note)
    ndb.put_multi(notes)
Ejemplo n.º 5
0
    def post(self, project_id, slug):
        """A project has been identified as new. Send them a welcome."""
        project = Project.get_by_id(project_id)
        program = Program.get_config(project.program_label)
        org = Organization.get_by_id(project.organization_id)

        # The Org liaison is preferred, but is not guaranteed to be set (users
        # choose their org liaison explicitly as one of the org tasks). Default
        # to the Project liaison, which is set on creation in
        # add_program.controller.js@joinProgram
        org_liaison = User.get_by_id(org.liaison_id)
        project_liaison = User.get_by_id(project.liaison_id)
        liaison = org_liaison or project_liaison

        email = Email.create(
            to_address=liaison.email,
            mandrill_template=slug,
            mandrill_template_content={
                'program_name': program['name'],
                'organization_name': org.name,
                'liaison_name': liaison.name,
                'join_date': util.datelike_to_iso_string(project.created),
            },
        )
        email.put()
    def create_pd_context(self):
        program_label = 'demo-program'
        program_config = Program.get_config(program_label)
        template = program_config['surveys'][0]['survey_tasklist_template']

        project_cohort = ProjectCohort.create(
            program_label=program_label,
            organization_id='Organization_foo',
            project_id='Project_foo',
            cohort_label='2018',
        )
        project_cohort.put()

        survey = Survey.create(
            template,
            program_label=program_label,
            organization_id='Organization_foo',
            project_cohort_id=project_cohort.uid,
            ordinal=1,
        )
        survey.put()

        participant = Participant.create(name='Pascal',
                                         organization_id='PERTS')
        participant.put()

        return (project_cohort, survey, participant)
Ejemplo n.º 7
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))
Ejemplo n.º 8
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)
Ejemplo n.º 9
0
 def test_task_creation(self):
     project = Project.create(program_label='demo-program',
                              organization_id='Organization_Foo')
     project.put()
     tasks = Task.get(ancestor=project)
     program_config = Program.get_config(project.program_label)
     template = program_config['project_tasklist_template']
     num_tasks = sum([len(checkpoint['tasks']) for checkpoint in template])
     self.assertEqual(len(tasks), num_tasks)
Ejemplo n.º 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))
Ejemplo n.º 11
0
 def test_task_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()
     tasks = Task.get(ancestor=survey)
     num_tasks = sum([len(checkpoint['tasks']) for checkpoint in template])
     self.assertEqual(len(tasks), num_tasks)
    def test_get_single_cohort(self):
        user = User.create(email="*****@*****.**", user_type='super_admin')
        user.put()

        query = '''
        query GetSingleProgramCohort(
            $program_label: String!,
            $cohort_label: String!,
        ) {
            program_cohort(
                program_label: $program_label,
                cohort_label: $cohort_label,
            ) {
                close_date
                label
                name
                open_date
                program_description
                program_label
                program_name
                registration_close_date
                registration_open_date
            }
        }
        '''

        response = self.testapp.post_json(
            '/api/graphql',
            # See http://graphql.org/learn/serving-over-http/#post-request
            {
                'query': query,
                'variables': {
                    'program_label': 'demo-program',
                    'cohort_label': '2018',
                },
            },
            headers=login_headers(user.uid),
        )

        conf = Program.get_config('demo-program')
        cohort = conf['cohorts']['2018']
        cohort['program_label'] = conf['label']
        cohort['program_name'] = conf['name']
        cohort = OrderedDict((k, cohort[k]) for k in sorted(cohort.keys()))

        self.assertEqual(
            response.body,
            json.dumps({'program_cohort': cohort}),
        )
    def test_survey_creation(self):
        """Creating a project cohort should create surveys."""

        # Hack eventual consistency for just this test because we don't
        # expect surveys to be available instantly upon creation, unlike the
        # project cohort itself.
        self.policy = datastore_stub_util.PseudoRandomHRConsistencyPolicy(
            probability=1)
        self.testbed.init_datastore_v3_stub(consistency_policy=self.policy)

        pc, user = self.test_join_cohort()

        program_label = 'demo-program'
        program = Program.get_config(program_label)

        surveys = Survey.get(project_cohort_id=pc.uid)
        self.assertEqual(len(surveys), len(program['surveys']))
    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)
Ejemplo n.º 15
0
    def test_put_clears_dashboard_queries(self):
        org_id = 'Organization_Foo'
        program_label = 'demo-program'
        pc = ProjectCohort.create(
            program_label='demo-program',
            organization_id=org_id,
            project_id='Project_Foo',
            cohort_label='2018',
        )
        pc.put()
        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=org_id,
            project_cohort_id=pc.uid,
            ordinal=1,
        )
        survey.put()

        org_key = util.cached_query_key(
            'SuperDashboard',
            organization_id=pc.organization_id,
        )
        program_cohort_key = util.cached_query_key(
            'SuperDashboard',
            program_label=pc.program_label,
            cohort_label=pc.cohort_label,
        )

        memcache.set(org_key, {'foo': 1})
        memcache.set(program_cohort_key, {'foo': 1})

        # Re-fetch the org so it doesn't have an associated tasklist, which
        # saves checkpoints. This should clear memcache without relying on those
        # checkpoints.
        survey = survey.key.get()
        survey.status = 'ready'
        survey.put()

        self.assertIsNone(memcache.get(org_key))
        self.assertIsNone(memcache.get(program_cohort_key))
    def test_get_all_for_program(self):
        user = User.create(email="*****@*****.**", user_type='super_admin')
        user.put()

        query = '''
        query GetProgramCohorts($program_label: String!) {
            program_cohorts(program_label: $program_label) {
                label
            }
        }
        '''

        response = self.testapp.post_json(
            '/api/graphql',
            {'query': query, 'variables': {'program_label': 'demo-program'}},
            headers=login_headers(user.uid),
        )
        received = json.loads(response.body)

        for l in Program.get_config('demo-program')['cohorts'].keys():
            self.assertIn({'label': l}, received['program_cohorts'])
Ejemplo n.º 17
0
def downloaded_identifiers(user, project_cohort_id):
    supers = User.get(user_type='super_admin')
    notes = []

    project_cohort = ProjectCohort.get_by_id(project_cohort_id)
    organization = Organization.get_by_id(project_cohort.organization_id)
    program = Program.get_config(project_cohort.program_label)
    cohort_name = program['cohorts'][project_cohort.cohort_label]['name']

    for sup in supers:
        note = Notification.create(
            parent=sup,
            context_id=project_cohort_id,
            subject="IDs Downloaded",
            body=u"{} ({}) downloaded IDs for {}: {} {}.".format(
                user.name, user.email, organization.name, program['name'],
                cohort_name),
            link='/dashboard/{}'.format(project_cohort.short_uid),
            autodismiss=True,
        )
        notes.append(note)
    ndb.put_multi(notes)
    def create_project_cohort(self, cohort_date=datetime.datetime.today()):
        program = Program.get_config(self.program_label)
        liaison = User.create(email='*****@*****.**')
        org = Organization.create(name="Org Foo", liaison_id=liaison.uid)
        liaison.owned_organizations.append(org.uid)
        project = Project.create(organization_id=org.uid,
                                 program_label=self.program_label)
        liaison.put()
        org.put()
        project.put()

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

        surveys = Survey.create_for_project_cohort(program['surveys'], pc)
        ndb.put_multi(surveys)

        return liaison, org, project, pc, surveys
Ejemplo n.º 19
0
 def test_default_portal_type(self):
     """Portal type should be based on program config"""
     program = Program.get_config(self.program_label)
     pc = ProjectCohort.create(program_label=self.program_label, )
     self.assertEqual(pc.portal_type, program['default_portal_type'])