def test_insert_creates_task(self): # **Don't** use .put() here, because responses are saved with a # custom transaction via insert_or_conflict() and update_or_conflict(). # Initial save should create a task. user_response_params = dict( self.response_params, type=Response.USER_LEVEL_SYMBOL, private=True, user_id='User_foo', ) r = Response.insert_or_conflict(user_response_params) expected_payload = json.dumps( r.to_dict(), default=util.json_dumps_default, ) tasks = self.taskqueue_stub.get_filtered_tasks() self.assertEqual(len(tasks), 1) self.assertEqual(tasks[0].payload, expected_payload)
def post(self): # Anyone is allowed to post responses. params = self.get_params(Response.property_types()) user = self.get_current_user() if 'user_id' not in params: params['user_id'] = user.uid required_params = ('team_id', 'parent_id', 'module_label') for k in required_params: if not params.get(k, None): return self.http_bad_request("{} required.".format(k)) # Validate the parent, if it's a cycle. parent_id = params.get('parent_id', None) parent_kind = SqlModel.get_kind(parent_id) if parent_kind == 'Cycle': cycle = SqlModel.kind_to_class(parent_kind).get_by_id(parent_id) if not cycle or not owns(user, parent_id): return self.http_forbidden("Must own the parent to respond.") # ...else this is a step label, so allow any truthy string. # Permission to create varies by type/level. params['type'] = params.get('type', Response.USER_LEVEL_SYMBOL) if params['type'] == Response.TEAM_LEVEL_SYMBOL: if not owns(user, params['team_id']): return self.http_forbidden("Must own the team to respond.") elif not owns(user, params['user_id']): return self.http_forbidden("May not create responses for others.") try: new_entity = Response.insert_or_conflict(params) except ResponseIndexConflict: return self.http_conflict( "Response for this type-user-team-parent-module combination " "exists. Send a request like `PUT /api/responses/:id`.") except JsonTextValueLengthError: return self.http_payload_too_large("Value too long.") except JsonTextDictLengthError: return self.http_payload_too_large("Body has too many keys.") self.write(new_entity)