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
Update email_address to be fetched from new API #1450
base: main
Are you sure you want to change the base?
Conversation
82035d7
to
b5d4657
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rsashank Thanks for the updates here 👍
I tested this and it appears to manually work against the community server, but as noted inline this will not work as expected for older servers, or likely where the incoming email is not configured on newer servers.
To isolate the API-specific logic, one option would be to have stream_email_address
handle the logic across server versions. That could then be tested separately, and the existing UI tests could remain very similar.
4bf3497
to
e2856b6
Compare
@zulipbot add "PR needs review" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rsashank This looks to have a good flow, but I think we should take the opportunity to move the logic that varies with server version in the model.
It would also be good to see independent tests for the model methods.
When you update the suggested additional model method to call the _fetch
, that would be a good time to include what is currently in the first commit - and using NotRequired
would be a good change at that point too.
zulipterminal/model.py
Outdated
def stream_email_address(self, stream_id: int) -> str: | ||
""" | ||
Return a string containing the email address of a stream. | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's name this more explicitly with a _fetch
prefix, to indicate this makes an API call to the server. The leading underscore will mean that we don't expect it to be called/used outside of the model.
My suggestion would be to add a separate model function which wraps the logic for determining if the data is present in the stream/subscription, and fetches it otherwise using the wrapped .call_endpoint
method. You might consider the movement of the existing code in the popup into this new method to be a preliminary refactor; then once you have added the _fetch
commit, you can update this other method to call it.
The docstring doesn't add much, compared to the method name and signature (ie. parameter & return value)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review! I've updated the PR accordingly.
I'm still unsure about the docstrings though.
e2856b6
to
b8244ce
Compare
e5ccdce
to
1c5106c
Compare
1c5106c
to
590d2b1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rsashank This looks close to ready - most of my feedback should be clear to address, but let me know if not :)
if response.get("result") == "success": | ||
email_address = response.get("email", "") | ||
return str(email_address) | ||
return "invalid" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this arbitrary string isn't likely to be mistaken for an email address, it would be clearer to have this return something like None
instead.
This likely simplifies the rest of the code here too.
if stream_email == "invalid" or stream_email is None: | ||
stream_email = "" | ||
return stream_email |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly here, the empty string is a special marker string being returned, to indicate that we couldn't get the email address, but we can just use None
again.
# This field was removed from the subscription data in Zulip 7.5 / ZFL226 | ||
# Using the new /streams/{stream_id}/email_address endpoint | ||
# if field isn't present in subscription data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's good to see this updated comment, but note that this detail is now described in the model, so we don't need it here :)
At this position in the code, all we care about is 'what is the stream email address for this stream', and rely upon the model to do the right thing, as best it can.
@@ -1398,9 +1398,11 @@ def test_stream_info_content__email_copy_text( | |||
general_stream: Dict[str, Any], | |||
stream_email_present: bool, | |||
expected_copy_text: str, | |||
mocker: MockerFixture, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no additional use of mocker
here, so this is unnecessary?
return str(email_address) | ||
return "invalid" | ||
|
||
def stream_copy_text(self, stream_id: int) -> str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is certainly about a stream
, but it's specifically returning an email address for the stream, so I'd be confused reading this (or where it's used) why it was named with a copy_text
suffix.
So, let's use a more descriptive name for this method :)
Attempts to retrieve stream email from stream_dict, fetching | ||
from method if unavailable. (Retains handling across server versions). | ||
""" | ||
stream = self.stream_dict[stream_id] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a PR open to support fixing this problem more broadly, but in general we should check that a stream_id is in the dict until we have a clearer solution. See similar functions where we use a RuntimeError for now.
assert result == return_value | ||
|
||
@pytest.mark.parametrize( | ||
"stream, fetched, response, return_value", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests generally look good, but it's useful to use expected_
before parameters that are only used in asserts (and place them at the end).
Similarly, while the parameters are somewhat descriptive, more detail is generally better, eg.
- is it all the stream data? part of it?
- what is the response from?
if not stream_email_present: | ||
del general_stream["email_address"] | ||
self.controller.model.stream_copy_text.return_value = "" | ||
|
||
model = self.controller.model | ||
stream_id = general_stream["stream_id"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be simplified further? The code doesn't access as much of the model data directly now.
Did you understand what I meant here? I missed following up on this. Reading this again, I think my original idea was to add the model methods in two stages: firstly to wrap the direct data access (pure refactor) and secondly update that method and add the new one (so only in the model) to try and fetch the data instead - combined with the This isn't critical, so focus on the other points first, but consider how the code changes would read differently in two commits as above. |
What does this PR do, and why?
Added helper function to send request and get stream email_address, and called the helper function when user is viewing Stream Information.
External discussion & connections
topic
https://chat.zulip.org/#narrow/stream/206-zulip-terminal/topic/Stream.20Information.20ZT.20CrashHow did you test this?
Self-review checklist for each commit
Visual changes