Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accumulate Time Lost from comments sent through LOVE #275

Merged
merged 11 commits into from
Aug 23, 2024
Merged

Conversation

Vebop
Copy link
Contributor

@Vebop Vebop commented Aug 14, 2024

Added update_time_loss() to request jira ticket by ID, and updates the existing time_lost value adding what was given in the form to the original value from the ticket.
Called this function from jira_comment() only if 'time_lost' is provided in the request_data.

Updated test_jira_comment() to patch this new function.
Added test_update_time_loss.

@Vebop Vebop marked this pull request as ready for review August 21, 2024 00:16
Comment on lines 319 to 333
def test_update_time_loss(self):
"""Test call to update_time_loss and verify field was updated"""
# patch both requests.get, requests.put
mock_jira_patcher = patch("requests.get")
mock_jira_client = mock_jira_patcher.start()
response = requests.Response()
response.status_code = 200
response.json = lambda: {"customfield_10106": 13.6}
mock_jira_client.return_value = response

mock_jira_patcher = patch("requests.put")
mock_jira_client = mock_jira_patcher.start()
response = requests.Response()
response.status_code = 200
mock_jira_client.return_value = response

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace with patch decorators to simplify. No need to create response twice, me thinks.

@patch("requests.get")
@patch("requests.post")
def test_update_time_loss(self, mock_get, mock_post):
"""Test call to update_time_loss and verify field was updated"""
# patch both requests.get, requests.put
response = requests.Response()
response.status_code = 200
mock_get.return_value = response

    response.json = lambda: {"customfield_10106": 13.6}
    mock_post.return_value = response

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered that and saw the pattern in this file was to use the decorators for patching environment variables and the implemented way for requests. I wasn't familiar with any best practices that designate one way or the other. However I do like this way so I'll update it.

Copy link
Contributor

@sebastian-aranda sebastian-aranda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job @Vebop ! This looks good, but I left several comments for the sake of explicity, hope you can take a look 🙏

@@ -505,6 +505,57 @@ def jira_ticket(request_data):
)


def update_time_loss(jira_id: int, add_time_loss: float = 0.0) -> Response:
"""Connect to the Rubin Observatory JIRA Cloud REST API to
update a jira ticket's specific field
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should specify here that were are updating the specific time_lost field.

manager/manager/utils.py Outdated Show resolved Hide resolved
)
response = requests.get(get_url, headers=headers)
existent_time_loss = (
response.json().get("customfield_10106", 0.0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be too much to ask, as I should have done it before 😅 ... but for the sake of having better maintainable software I'll ask anyways... Could you move this constant: customfield_10106 to a variable (see begining of the utils.py file)? Also, if you could move the other customfield_ constants it would be awesome 🙏.

"customfield_10106": float(existent_time_loss + add_time_loss),
},
}
put_url = f"https://{os.environ.get('JIRA_API_HOSTNAME')}/rest/api/latest/issue/{jira_id}/"
Copy link
Contributor

@sebastian-aranda sebastian-aranda Aug 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the difference between get_url and put_url is only a / at the end for the later one. Is this necessary? I'm asking basically if we could use the same url for both purposes.

put_url = f"https://{os.environ.get('JIRA_API_HOSTNAME')}/rest/api/latest/issue/{jira_id}/"
response = requests.put(put_url, json=jira_payload, headers=headers)

if response.status_code == 200 or response.status_code == 204:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In which case we would be receiving a status_code = 204?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good question that made me realize the response is only ever 204 for success, not 200. When the update is sent successfully we receive a 204 No Content.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, good to know! Just sharing a nice resource here in case you find it usfeul 🤭: https://http.cat/

manager/manager/utils.py Outdated Show resolved Hide resolved
manager/manager/utils.py Outdated Show resolved Hide resolved
Comment on lines 319 to 320
@patch("requests.get")
@patch("requests.put")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not an obligation, but for the sake of standardization could you use the format as on the test_add_comment function (without fixtures)? Again, not an obligation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, just saw @pothiers review... One sec, I'm looking at the comments.

Copy link
Contributor

@sebastian-aranda sebastian-aranda Aug 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, so this is one of those things that can be or cannot be jaja. I think is up to the developer, but the thing is (IIRC) this would be the first place on this repo that uses this fixtures format. Again, not an obligation, up to you 😉. But, we should standardize this at some point and add some details to the README.md to point into a standard direction.

Comment on lines 348 to 350
mock_timeloss_patcher = patch("manager.utils.update_time_loss")
mock_timeloss_client = mock_timeloss_patcher.start()
mock_timeloss_client.return_value = response
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a comment before in regards of returning a 400 response in the case the update_time_loss fails (on the jira_comment function). If you are willing to add that suggestion, that should be tested here (ensuring we get the bad response arranged by the update_time_loss function, in this case mocked up).

@@ -311,6 +316,27 @@ def test_needed_parameters(self):

mock_jira_patcher.stop()

@patch("requests.get")
@patch("requests.put")
def test_update_time_loss(self, mock_get, mock_put):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps you could also test when the update_time_loss fails and returns a 400 status code, ensuring we return the arranged ack (e.g. "Jira time_lost field could not be updated" in case you accept my other suggestion too).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I learned that when we use requests.Response() as our patch in the unit tests, that this is not the same as rest_framework.response.Response (that we set in utils.py). So when we start to mock one of these, we cannot then check what the 'ack' would have been, since we are patching that object.

@Vebop Vebop requested a review from sebastian-aranda August 22, 2024 23:29
Copy link
Contributor

@sebastian-aranda sebastian-aranda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! thanks for the great work here @Vebop 💪.

@Vebop Vebop merged commit ee8cac7 into develop Aug 23, 2024
2 checks passed
@Vebop Vebop deleted the tickets/DM-45776 branch August 23, 2024 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants