Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.

Commit 1ea5bd7

Browse files
streaming unit tests (#1682)
* streaming request/response unit tests * content stream tests * test send operations * pylint fixes Co-authored-by: tracyboehrer <tracyboehrer@users.noreply.github.com>
1 parent c7cef56 commit 1ea5bd7

File tree

7 files changed

+372
-4
lines changed

7 files changed

+372
-4
lines changed

libraries/botframework-streaming/botframework/streaming/receive_request.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class ReceiveRequest:
1010
def __init__(
11-
self, *, verb: str = None, path: str = None, streams: List[ContentStream]
11+
self, *, verb: str = None, path: str = None, streams: List[ContentStream] = None
1212
):
1313
self.verb = verb
1414
self.path = path

libraries/botframework-streaming/botframework/streaming/receive_response.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99

1010

1111
class ReceiveResponse:
12-
def __init__(self, status_code: int = None, streams: List[ContentStream] = None):
12+
def __init__(self, status_code: int = 0, streams: List[ContentStream] = None):
1313
self.status_code = status_code
14-
self.streams = streams
14+
self.streams = streams or []
1515

1616
def read_body_as_json(
1717
self, cls: Union[Type[Model], Type[Serializable]]

libraries/botframework-streaming/botframework/streaming/streaming_response.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Licensed under the MIT License.
33

44
import json
5+
from http import HTTPStatus
56
from uuid import UUID, uuid4
67
from typing import List, Union
78

@@ -12,7 +13,7 @@
1213

1314
class StreamingResponse:
1415
def __init__(
15-
self, *, status_code: int = None, streams: List[ResponseMessageStream] = None
16+
self, *, status_code: int = 0, streams: List[ResponseMessageStream] = None
1617
):
1718
self.status_code = status_code
1819
self.streams = streams
@@ -48,3 +49,20 @@ def create_response(status_code: int, body: object) -> "StreamingResponse":
4849
response.add_stream(body)
4950

5051
return response
52+
53+
@staticmethod
54+
def not_found(body: object = None) -> "StreamingResponse":
55+
return StreamingResponse.create_response(HTTPStatus.NOT_FOUND, body)
56+
57+
@staticmethod
58+
def forbidden(body: object = None) -> "StreamingResponse":
59+
return StreamingResponse.create_response(HTTPStatus.FORBIDDEN, body)
60+
61+
# pylint: disable=invalid-name
62+
@staticmethod
63+
def ok(body: object = None) -> "StreamingResponse":
64+
return StreamingResponse.create_response(HTTPStatus.OK, body)
65+
66+
@staticmethod
67+
def internal_server_error(body: object = None) -> "StreamingResponse":
68+
return StreamingResponse.create_response(HTTPStatus.INTERNAL_SERVER_ERROR, body)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
from uuid import uuid4
5+
6+
import aiounittest
7+
8+
from botframework.streaming.payloads import ContentStream
9+
from botframework.streaming.payloads.assemblers import PayloadStreamAssembler
10+
11+
12+
class TestResponses(aiounittest.AsyncTestCase):
13+
async def test_content_stream_ctor_none_assembler_throws(self):
14+
with self.assertRaises(TypeError):
15+
ContentStream(uuid4(), None)
16+
17+
async def test_content_stream_id(self):
18+
test_id = uuid4()
19+
test_assembler = PayloadStreamAssembler(None, test_id)
20+
sut = ContentStream(test_id, test_assembler)
21+
22+
self.assertEqual(test_id, sut.identifier)
23+
24+
async def test_content_stream_type(self):
25+
test_id = uuid4()
26+
test_assembler = PayloadStreamAssembler(None, test_id)
27+
sut = ContentStream(test_id, test_assembler)
28+
test_type = "foo/bar"
29+
30+
sut.content_type = test_type
31+
32+
self.assertEqual(test_type, sut.content_type)
33+
34+
sut.cancel()
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import json
2+
3+
import aiounittest
4+
5+
from botbuilder.schema import Activity
6+
from botframework.streaming import ReceiveRequest, StreamingRequest
7+
from botframework.streaming.payloads import ResponseMessageStream
8+
9+
10+
class TestRequests(aiounittest.AsyncTestCase):
11+
async def test_receive_request_empty_streams(self):
12+
sut = ReceiveRequest()
13+
14+
self.assertIsNotNone(sut.streams)
15+
self.assertEqual(0, len(sut.streams))
16+
17+
async def test_receive_request_null_properties(self):
18+
sut = ReceiveRequest()
19+
20+
self.assertIsNone(sut.verb)
21+
self.assertIsNone(sut.path)
22+
23+
async def test_streaming_request_null_properties(self):
24+
sut = StreamingRequest()
25+
26+
self.assertIsNone(sut.verb)
27+
self.assertIsNone(sut.path)
28+
29+
async def test_streaming_request_add_stream_null_throws(self):
30+
sut = StreamingRequest()
31+
32+
with self.assertRaises(TypeError):
33+
sut.add_stream(None)
34+
35+
async def test_streaming_request_add_stream_success(self):
36+
sut = StreamingRequest()
37+
content = "hi"
38+
39+
sut.add_stream(content)
40+
41+
self.assertIsNotNone(sut.streams)
42+
self.assertEqual(1, len(sut.streams))
43+
self.assertEqual(content, sut.streams[0].content)
44+
45+
async def test_streaming_request_add_stream_existing_list_success(self):
46+
sut = StreamingRequest()
47+
content = "hi"
48+
content_2 = "hello"
49+
50+
sut.streams = [ResponseMessageStream(content=content_2)]
51+
52+
sut.add_stream(content)
53+
54+
self.assertIsNotNone(sut.streams)
55+
self.assertEqual(2, len(sut.streams))
56+
self.assertEqual(content_2, sut.streams[0].content)
57+
self.assertEqual(content, sut.streams[1].content)
58+
59+
async def test_streaming_request_create_get_success(self):
60+
sut = StreamingRequest.create_get()
61+
62+
self.assertEqual(StreamingRequest.GET, sut.verb)
63+
self.assertIsNone(sut.path)
64+
self.assertIsNone(sut.streams)
65+
66+
async def test_streaming_request_create_post_success(self):
67+
sut = StreamingRequest.create_post()
68+
69+
self.assertEqual(StreamingRequest.POST, sut.verb)
70+
self.assertIsNone(sut.path)
71+
self.assertIsNone(sut.streams)
72+
73+
async def test_streaming_request_create_delete_success(self):
74+
sut = StreamingRequest.create_delete()
75+
76+
self.assertEqual(StreamingRequest.DELETE, sut.verb)
77+
self.assertIsNone(sut.path)
78+
self.assertIsNone(sut.streams)
79+
80+
async def test_streaming_request_create_put_success(self):
81+
sut = StreamingRequest.create_put()
82+
83+
self.assertEqual(StreamingRequest.PUT, sut.verb)
84+
self.assertIsNone(sut.path)
85+
self.assertIsNone(sut.streams)
86+
87+
async def test_streaming_request_create_with_body_success(self):
88+
content = "hi"
89+
sut = StreamingRequest.create_request(StreamingRequest.POST, "123", content)
90+
91+
self.assertEqual(StreamingRequest.POST, sut.verb)
92+
self.assertEqual("123", sut.path)
93+
self.assertIsNotNone(sut.streams)
94+
self.assertEqual(1, len(sut.streams))
95+
self.assertEqual(content, sut.streams[0].content)
96+
97+
async def test_streaming_request_set_body_string_success(self):
98+
sut = StreamingRequest()
99+
100+
sut.set_body("123")
101+
102+
self.assertIsNotNone(sut.streams)
103+
self.assertEqual(1, len(sut.streams))
104+
self.assertIsInstance(sut.streams[0].content, list)
105+
self.assertIsInstance(sut.streams[0].content[0], int)
106+
self.assertEqual("123", bytes(sut.streams[0].content).decode("utf-8-sig"))
107+
108+
async def test_streaming_request_set_body_none_does_not_throw(self):
109+
sut = StreamingRequest()
110+
111+
sut.set_body(None)
112+
113+
async def test_streaming_request_set_body_success(self):
114+
sut = StreamingRequest()
115+
activity = Activity(text="hi", type="message")
116+
117+
sut.set_body(activity)
118+
119+
self.assertIsNotNone(sut.streams)
120+
self.assertEqual(1, len(sut.streams))
121+
self.assertIsInstance(sut.streams[0].content, list)
122+
self.assertIsInstance(sut.streams[0].content[0], int)
123+
124+
assert_activity = Activity.deserialize(
125+
json.loads(bytes(sut.streams[0].content).decode("utf-8-sig"))
126+
)
127+
128+
self.assertEqual(activity.text, assert_activity.text)
129+
self.assertEqual(activity.type, assert_activity.type)
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import json
2+
from http import HTTPStatus
3+
4+
import aiounittest
5+
6+
from botbuilder.schema import Activity
7+
from botframework.streaming import ReceiveResponse, StreamingResponse
8+
from botframework.streaming.payloads import ResponseMessageStream
9+
10+
11+
class TestResponses(aiounittest.AsyncTestCase):
12+
async def test_receive_response_empty_streams(self):
13+
sut = ReceiveResponse()
14+
15+
self.assertIsNotNone(sut.streams)
16+
self.assertEqual(0, len(sut.streams))
17+
18+
async def test_receive_response_none_properties(self):
19+
sut = ReceiveResponse()
20+
21+
self.assertEqual(0, sut.status_code)
22+
23+
async def test_streaming_response_null_properties(self):
24+
sut = StreamingResponse()
25+
26+
self.assertEqual(0, sut.status_code)
27+
self.assertIsNone(sut.streams)
28+
29+
async def test_streaming_response_add_stream_none_throws(self):
30+
sut = StreamingResponse()
31+
32+
with self.assertRaises(TypeError):
33+
sut.add_stream(None)
34+
35+
async def test_streaming_response_add_stream_success(self):
36+
sut = StreamingResponse()
37+
content = "hi"
38+
39+
sut.add_stream(content)
40+
41+
self.assertIsNotNone(sut.streams)
42+
self.assertEqual(1, len(sut.streams))
43+
self.assertEqual(content, sut.streams[0].content)
44+
45+
async def test_streaming_response_add_stream_existing_list_success(self):
46+
sut = StreamingResponse()
47+
content = "hi"
48+
content_2 = "hello"
49+
50+
sut.streams = [ResponseMessageStream(content=content_2)]
51+
52+
sut.add_stream(content)
53+
54+
self.assertIsNotNone(sut.streams)
55+
self.assertEqual(2, len(sut.streams))
56+
self.assertEqual(content_2, sut.streams[0].content)
57+
self.assertEqual(content, sut.streams[1].content)
58+
59+
async def test_streaming_response_not_found_success(self):
60+
sut = StreamingResponse.not_found()
61+
62+
self.assertEqual(HTTPStatus.NOT_FOUND, sut.status_code)
63+
self.assertIsNone(sut.streams)
64+
65+
async def test_streaming_response_forbidden_success(self):
66+
sut = StreamingResponse.forbidden()
67+
68+
self.assertEqual(HTTPStatus.FORBIDDEN, sut.status_code)
69+
self.assertIsNone(sut.streams)
70+
71+
async def test_streaming_response_ok_success(self):
72+
sut = StreamingResponse.ok()
73+
74+
self.assertEqual(HTTPStatus.OK, sut.status_code)
75+
self.assertIsNone(sut.streams)
76+
77+
async def test_streaming_response_internal_server_error_success(self):
78+
sut = StreamingResponse.internal_server_error()
79+
80+
self.assertEqual(HTTPStatus.INTERNAL_SERVER_ERROR, sut.status_code)
81+
self.assertIsNone(sut.streams)
82+
83+
async def test_streaming_response_create_with_body_success(self):
84+
content = "hi"
85+
sut = StreamingResponse.create_response(HTTPStatus.OK, content)
86+
87+
self.assertEqual(HTTPStatus.OK, sut.status_code)
88+
self.assertIsNotNone(sut.streams)
89+
self.assertEqual(1, len(sut.streams))
90+
self.assertEqual(content, sut.streams[0].content)
91+
92+
async def test_streaming_response_set_body_string_success(self):
93+
sut = StreamingResponse()
94+
95+
sut.set_body("123")
96+
97+
self.assertIsNotNone(sut.streams)
98+
self.assertEqual(1, len(sut.streams))
99+
self.assertIsInstance(sut.streams[0].content, list)
100+
self.assertIsInstance(sut.streams[0].content[0], int)
101+
self.assertEqual("123", bytes(sut.streams[0].content).decode("utf-8-sig"))
102+
103+
async def test_streaming_response_set_body_none_does_not_throw(self):
104+
sut = StreamingResponse()
105+
106+
sut.set_body(None)
107+
108+
async def test_streaming_response_set_body_success(self):
109+
sut = StreamingResponse()
110+
activity = Activity(text="hi", type="message")
111+
112+
sut.set_body(activity)
113+
114+
self.assertIsNotNone(sut.streams)
115+
self.assertEqual(1, len(sut.streams))
116+
self.assertIsInstance(sut.streams[0].content, list)
117+
self.assertIsInstance(sut.streams[0].content[0], int)
118+
119+
assert_activity = Activity.deserialize(
120+
json.loads(bytes(sut.streams[0].content).decode("utf-8-sig"))
121+
)
122+
123+
self.assertEqual(activity.text, assert_activity.text)
124+
self.assertEqual(activity.type, assert_activity.type)
125+
126+
async def test_receive_base_read_body_as_string_no_content_empty_string(self):
127+
sut = ReceiveResponse()
128+
sut.streams = []
129+
130+
result = sut.read_body_as_str()
131+
132+
self.assertEqual("", result)

0 commit comments

Comments
 (0)