streams: Add endpoint "GET /streams/{stream_id}" to get stream by id.

Fixes #22082.
This commit is contained in:
Sahil Batra 2022-05-18 17:24:35 +05:30 committed by Tim Abbott
parent 1c0ece73f2
commit ce34b585a5
8 changed files with 118 additions and 3 deletions

View File

@ -20,6 +20,11 @@ format used by the Zulip server that they are interacting with.
## Changes in Zulip 6.0
**Feature level 132**
* [`GET /streams/{stream_id}`](/api/get-stream-by-id):
Added new endpoint to get a stream by ID.
**Feature level 131**
* [`GET /user_groups`](/api/get-user-groups),[`POST

View File

@ -31,6 +31,7 @@
* [Get all subscribers](/api/get-subscribers)
* [Update subscription settings](/api/update-subscription-settings)
* [Get all streams](/api/get-streams)
* [Get a stream by ID](/api/get-stream-by-id)
* [Get stream ID](/api/get-stream-id)
* [Create a stream](/api/create-stream)
* [Update a stream](/api/update-stream)

View File

@ -33,7 +33,7 @@ DESKTOP_WARNING_VERSION = "5.4.3"
# Changes should be accompanied by documentation explaining what the
# new level means in templates/zerver/api/changelog.md, as well as
# "**Changes**" entries in the endpoint's documentation in `zulip.yaml`.
API_FEATURE_LEVEL = 131
API_FEATURE_LEVEL = 132
# Bump the minor PROVISION_VERSION to indicate that folks should provision
# only when going from an old version of the code to a newer version. Bump

View File

@ -13428,6 +13428,67 @@ paths:
`include_all_active` parameter (i.e. because they are not an organization
administrator):
/streams/{stream_id}:
get:
operationId: get-stream-by-id
summary: Get a stream by ID
tags: ["streams"]
description: |
Fetch details for the stream with the ID `stream_id`.
`GET {{ api_url }}/v1/streams/{stream_id}`
**Changes**: New in Zulip 6.0 (feature level 132).
parameters:
- $ref: "#/components/parameters/StreamIdInPath"
responses:
"200":
description: Success.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/JsonSuccessBase"
- $ref: "#/components/schemas/SuccessDescription"
- additionalProperties: false
properties:
result: {}
msg: {}
stream:
$ref: "#/components/schemas/BasicStream"
example:
{
"msg": "",
"result": "success",
"stream":
{
"description": "A Scandinavian country",
"first_message_id": 1,
"history_public_to_subscribers": True,
"invite_only": False,
"is_announcement_only": False,
"is_web_public": False,
"message_retention_days": null,
"name": "Denmark",
"rendered_description": "<p>A Scandinavian country</p>",
"stream_id": 7,
"stream_post_policy": 1,
},
}
"400":
description: Bad request.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/CodedError"
- example:
{
"code": "BAD_REQUEST",
"msg": "Invalid stream id",
"result": "error",
}
description: |
An example JSON response for when the stream ID is not valid.
delete:
operationId: archive-stream
summary: Archive a stream

View File

@ -1983,7 +1983,7 @@ class RestAPITest(ZulipTestCase):
result = self.client_options("/json/streams/15")
self.assertEqual(result.status_code, 204)
self.assertEqual(str(result["Allow"]), "DELETE, PATCH")
self.assertEqual(str(result["Allow"]), "DELETE, GET, HEAD, PATCH")
def test_http_accept_redirect(self) -> None:
result = self.client_get("/json/users", HTTP_ACCEPT="text/html")

View File

@ -5457,6 +5457,40 @@ class GetStreamsTest(ZulipTestCase):
]
self.assertEqual(sorted(s["name"] for s in json["streams"]), sorted(all_streams))
def test_get_single_stream_api(self) -> None:
self.login("hamlet")
realm = get_realm("zulip")
denmark_stream = get_stream("Denmark", realm)
result = self.client_get(f"/json/streams/{denmark_stream.id}")
self.assert_json_success(result)
json = result.json()
self.assertEqual(json["stream"]["name"], "Denmark")
self.assertEqual(json["stream"]["stream_id"], denmark_stream.id)
result = self.client_get("/json/streams/9999")
self.assert_json_error(result, "Invalid stream id")
private_stream = self.make_stream("private_stream", invite_only=True)
self.subscribe(self.example_user("cordelia"), "private_stream")
# Non-admins cannot access unsubscribed private streams.
result = self.client_get(f"/json/streams/{private_stream.id}")
self.assert_json_error(result, "Invalid stream id")
self.login("iago")
result = self.client_get(f"/json/streams/{private_stream.id}")
self.assert_json_success(result)
json = result.json()
self.assertEqual(json["stream"]["name"], "private_stream")
self.assertEqual(json["stream"]["stream_id"], private_stream.id)
self.login("cordelia")
result = self.client_get(f"/json/streams/{private_stream.id}")
self.assert_json_success(result)
json = result.json()
self.assertEqual(json["stream"]["name"], "private_stream")
self.assertEqual(json["stream"]["stream_id"], private_stream.id)
class StreamIdTest(ZulipTestCase):
def test_get_stream_id(self) -> None:

View File

@ -754,6 +754,16 @@ def get_streams_backend(
return json_success(request, data={"streams": streams})
@has_request_variables
def get_stream_backend(
request: HttpRequest,
user_profile: UserProfile,
stream_id: int,
) -> HttpResponse:
(stream, sub) = access_stream_by_id(user_profile, stream_id, allow_realm_admin=True)
return json_success(request, data={"stream": stream.to_dict()})
@has_request_variables
def get_topics_backend(
request: HttpRequest,

View File

@ -145,6 +145,7 @@ from zerver.views.streams import (
create_default_stream_group,
deactivate_stream_backend,
delete_in_topic,
get_stream_backend,
get_streams_backend,
get_subscribers_backend,
get_topics_backend,
@ -443,7 +444,10 @@ v1_api_and_json_patterns = [
# GET returns "stream info" (undefined currently?), HEAD returns whether stream exists (200 or 404)
rest_path("streams/<int:stream_id>/members", GET=get_subscribers_backend),
rest_path(
"streams/<int:stream_id>", PATCH=update_stream_backend, DELETE=deactivate_stream_backend
"streams/<int:stream_id>",
GET=get_stream_backend,
PATCH=update_stream_backend,
DELETE=deactivate_stream_backend,
),
# Delete topic in stream
rest_path("streams/<int:stream_id>/delete_topic", POST=delete_in_topic),