diff --git a/surge/projects.py b/surge/projects.py index f215201..dffda26 100644 --- a/surge/projects.py +++ b/surge/projects.py @@ -23,7 +23,7 @@ class Project(APIResource): def __init__(self, **kwargs): super().__init__() - self.__dict__.update(kwargs) + self._update(**kwargs) if self.id is None: raise SurgeMissingIDError @@ -31,6 +31,10 @@ def __init__(self, **kwargs): if not (hasattr(self, "name") and self.name): raise SurgeMissingAttributeError + + def _update(self, **kwargs): + self.__dict__.update(kwargs) + if hasattr(self, "created_at") and self.created_at: # Convert timestamp str into datetime self.created_at = dateutil.parser.parse(self.created_at) @@ -39,6 +43,7 @@ def __init__(self, **kwargs): if hasattr(self, "questions"): self.questions = self._convert_questions_to_objects(self.questions) + def __str__(self): return f'' @@ -360,9 +365,9 @@ def update( description: str = None, params: dict = {}, api_key: str = None, - ): + ) -> 'Project': """ - Update an existing project + Update an existing project, and updates the project object in-place Arguments: name (str): Name of the project. @@ -375,7 +380,7 @@ def update( num_workers_per_task (int, optional): How many workers work on each task (i.e., how many responses per task). Returns: - project: new Project object + project: updated Project object """ params = {**params} @@ -397,7 +402,8 @@ def update( endpoint = f"{PROJECTS_ENDPOINT}/{self.id}" response_json = self.put(endpoint, params, api_key=api_key) - return Project(**response_json) + self._update(**response_json) + return self def workable_by_surger(self, surger_id, api_key: str = None): """ diff --git a/tests/test_projects.py b/tests/test_projects.py index 6919256..c07231e 100644 --- a/tests/test_projects.py +++ b/tests/test_projects.py @@ -459,3 +459,57 @@ def test_update_with_fields_template(): {"fields_text": "ABC"}, api_key=None, ) + + +def test_update_modifies_project_in_place(): + """Test that update() modifies the project object in-place based on PUT response.""" + project = Project( + id="UPDATE_IN_PLACE", + name="Original Name", + status="draft", + payment_per_response=0.10 + ) + + # Store original object id to verify same instance is returned + original_object_id = id(project) + + # Mock the PUT response with updated attributes + put_response = { + "id": "UPDATE_IN_PLACE", + "name": "Updated Name", + "status": "launched", + "payment_per_response": 0.25, + "description": "New description added", + "instructions": "Updated instructions" + } + + with patch.object(Project, "put") as mock_put: + mock_put.return_value = put_response + + # Verify initial state + assert project.name == "Original Name" + assert project.status == "draft" + assert project.payment_per_response == 0.10 + assert not hasattr(project, "description") + assert not hasattr(project, "instructions") + + # Call update + updated_project = project.update(name="Updated Name") + + # Verify the same object instance is returned + assert updated_project is project + assert id(updated_project) == original_object_id + + # Verify project attributes were updated in-place from PUT response + assert project.name == "Updated Name" + assert project.status == "launched" + assert project.payment_per_response == 0.25 + assert project.description == "New description added" + assert project.instructions == "Updated instructions" + + # Verify PUT was called correctly + mock_put.assert_called_once_with( + f"{PROJECTS_ENDPOINT}/{project.id}", + {"name": "Updated Name"}, + api_key=None, + )