Coverage for tests / test_tutorial / test_server_sent_events / test_tutorial004.py: 100%

34 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-04-06 01:24 +0000

1import importlib 1abcd

2 

3import pytest 1abcd

4from fastapi.testclient import TestClient 1abcd

5from inline_snapshot import snapshot 1abcd

6 

7 

8@pytest.fixture( 1abcd

9 name="client", 

10 params=[ 

11 pytest.param("tutorial004_py310"), 

12 ], 

13) 

14def get_client(request: pytest.FixtureRequest): 1abcd

15 mod = importlib.import_module(f"docs_src.server_sent_events.{request.param}") 1qrstuvwxyzABCD

16 client = TestClient(mod.app) 1qrstuvwxyzABCD

17 return client 1qrstuvwxyzABCD

18 

19 

20def test_stream_all_items(client: TestClient): 1abcd

21 response = client.get("/items/stream") 1efgh

22 assert response.status_code == 200, response.text 1efgh

23 

24 data_lines = [ 1efgh

25 line for line in response.text.strip().split("\n") if line.startswith("data: ") 

26 ] 

27 assert len(data_lines) == 3 1efgh

28 

29 id_lines = [ 1efgh

30 line for line in response.text.strip().split("\n") if line.startswith("id: ") 

31 ] 

32 assert id_lines == ["id: 0", "id: 1", "id: 2"] 1efgh

33 

34 

35def test_resume_from_last_event_id(client: TestClient): 1abcd

36 response = client.get( 1ijkl

37 "/items/stream", 

38 headers={"last-event-id": "0"}, 

39 ) 

40 assert response.status_code == 200, response.text 1ijkl

41 

42 data_lines = [ 1ijkl

43 line for line in response.text.strip().split("\n") if line.startswith("data: ") 

44 ] 

45 assert len(data_lines) == 2 1ijkl

46 

47 id_lines = [ 1ijkl

48 line for line in response.text.strip().split("\n") if line.startswith("id: ") 

49 ] 

50 assert id_lines == ["id: 1", "id: 2"] 1ijkl

51 

52 

53def test_resume_from_last_item(client: TestClient): 1abcd

54 response = client.get( 1mnop

55 "/items/stream", 

56 headers={"last-event-id": "1"}, 

57 ) 

58 assert response.status_code == 200, response.text 1mnop

59 

60 data_lines = [ 1mnop

61 line for line in response.text.strip().split("\n") if line.startswith("data: ") 

62 ] 

63 assert len(data_lines) == 1 1mnop

64 

65 id_lines = [ 1mnop

66 line for line in response.text.strip().split("\n") if line.startswith("id: ") 

67 ] 

68 assert id_lines == ["id: 2"] 1mnop

69 

70 

71def test_openapi_schema(client: TestClient): 1abcd

72 response = client.get("/openapi.json") 1EFGH

73 assert response.status_code == 200, response.text 1EFGH

74 assert response.json() == snapshot( 1EFGH

75 { 

76 "openapi": "3.1.0", 

77 "info": {"title": "FastAPI", "version": "0.1.0"}, 

78 "paths": { 

79 "/items/stream": { 

80 "get": { 

81 "summary": "Stream Items", 

82 "operationId": "stream_items_items_stream_get", 

83 "parameters": [ 

84 { 

85 "name": "last-event-id", 

86 "in": "header", 

87 "required": False, 

88 "schema": { 

89 "anyOf": [{"type": "integer"}, {"type": "null"}], 

90 "title": "Last-Event-Id", 

91 }, 

92 } 

93 ], 

94 "responses": { 

95 "200": { 

96 "description": "Successful Response", 

97 "content": { 

98 "text/event-stream": { 

99 "itemSchema": { 

100 "type": "object", 

101 "properties": { 

102 "data": {"type": "string"}, 

103 "event": {"type": "string"}, 

104 "id": {"type": "string"}, 

105 "retry": { 

106 "type": "integer", 

107 "minimum": 0, 

108 }, 

109 }, 

110 } 

111 } 

112 }, 

113 }, 

114 "422": { 

115 "description": "Validation Error", 

116 "content": { 

117 "application/json": { 

118 "schema": { 

119 "$ref": "#/components/schemas/HTTPValidationError" 

120 } 

121 } 

122 }, 

123 }, 

124 }, 

125 } 

126 } 

127 }, 

128 "components": { 

129 "schemas": { 

130 "HTTPValidationError": { 

131 "properties": { 

132 "detail": { 

133 "items": { 

134 "$ref": "#/components/schemas/ValidationError" 

135 }, 

136 "type": "array", 

137 "title": "Detail", 

138 } 

139 }, 

140 "type": "object", 

141 "title": "HTTPValidationError", 

142 }, 

143 "ValidationError": { 

144 "properties": { 

145 "loc": { 

146 "items": { 

147 "anyOf": [{"type": "string"}, {"type": "integer"}] 

148 }, 

149 "type": "array", 

150 "title": "Location", 

151 }, 

152 "msg": {"type": "string", "title": "Message"}, 

153 "type": {"type": "string", "title": "Error Type"}, 

154 "input": {"title": "Input"}, 

155 "ctx": {"type": "object", "title": "Context"}, 

156 }, 

157 "type": "object", 

158 "required": ["loc", "msg", "type"], 

159 "title": "ValidationError", 

160 }, 

161 } 

162 }, 

163 } 

164 )