def test_post_empty_report(self): """RServe posts "empty" reports to note why it hasn't produced a visible report. Test that the API accepts these for each kind of parent. """ rserve_user = User.create( id='rserve', email='*****@*****.**', user_type='super_admin', ) rserve_user.put() org = Organization.create(name='Organization', captain_id='User_cap', program_id=self.program.uid) org.put() team = Team.create( name='Team Foo', captain_id='User_cap', organization_ids=[org.uid], program_id=self.program.uid, ) team.put() classroom = Classroom.create(name='Class foo', team_id=team.uid, code='trout viper', contact_id='User_contact') classroom.put() url = '/api/reports' report_date = datetime.date.today().strftime('%Y-%m-%d') self.testapp.post_json( url, dict(self.empty_report_params(report_date, org.uid), organization_id=org.uid), headers=self.login_headers(rserve_user), ) self.testapp.post_json( url, dict(self.empty_report_params(report_date, team.uid), team_id=team.uid), headers=self.login_headers(rserve_user), ) self.testapp.post_json( url, dict(self.empty_report_params(report_date, classroom.uid), team_id=team.uid, classroom_id=classroom.uid), headers=self.login_headers(rserve_user), ) reports = Report.get() self.assertEqual(len(reports), 3) self.assertEqual(all(r.template == 'empty' for r in reports), True)
def get(self, parent_type, rel_id, filename): # Always require a jwt that specifies this path/report. This allows # shareable, expiring links. if not self.get_current_user().super_admin: params = self.get_params({'token': str}) token = params.get('token', None) payload, error = jwt_helper.decode(token) if error == jwt_helper.EXPIRED: return self.http_forbidden("This link has expired.") elif not payload or error: return self.http_bad_request("Missing or invalid token.") allowed_endpoints = payload.get('allowed_endpoints', []) if self.get_endpoint_str() not in allowed_endpoints: return self.http_forbidden("Token does not allow endpoint.") if parent_type == 'organizations': parent_id = Organization.get_long_uid(rel_id), elif parent_type == 'teams': parent_id = Team.get_long_uid(rel_id), elif parent_type == 'classrooms': parent_id = Classroom.get_long_uid(rel_id), else: raise Exception("Unrecognized parent type: {}".format(parent_type)) results = Report.get(parent_id=parent_id, filename=filename) if len(results) == 0: return self.http_not_found() report = results[0] # We intentionally don't check permissions or ownership any further # here, because reports are shared by link, and we already checked for # a jwt in the query string. self.response.headers.update({ 'Content-Disposition': 'inline; filename={}'.format(report.filename), # Unicode not allowed in headers. 'Content-Type': str(report.content_type), }) try: with gcs.open(report.gcs_path, 'r') as gcs_file: self.response.write(gcs_file.read()) except gcs.NotFoundError: logging.error("Couldn't find a gcs file for report {}".format( report.to_dict())) self.http_not_found()
def get_report_parents(program, week, should_force): # Look up teams and classrooms relevant to the requested script. orgs = Organization.get(program_id=program.uid, n=float('inf')) teams = Team.get(program_id=program.uid, n=float('inf')) classrooms = Classroom.get_by_program(program.uid) if should_force: # Don't skip any, re-request them all. skip_parent_ids = [] else: # Find all the reports for the current period that have already # been generated and don't re-request them. existing_reports = Report.get(issue_date=week, n=float('inf')) skip_parent_ids = [r.parent_id for r in existing_reports] return ( [o for o in orgs if o.uid not in skip_parent_ids], [t for t in teams if t.uid not in skip_parent_ids], [c for c in classrooms if c.uid not in skip_parent_ids], )