Coverage for test\test_dependencies.py: 98%

1 from nexios import get_application

2 import pytest

3 from nexios.http import Request, Response

4 from nexios.testing import Client

5 from nexios import Depend

6 from typing import Optional

7 from pydantic import BaseModel

8

9

10@pytest.fixture

11 async def di_client():

12 app = get_application()

13 async with Client(app) as client:

14 yield client, app

15

16

17# Test basic dependency injection

18 async def test_basic_di(di_client):

19 client, app = di_client

20

21 async def get_message():

22 return "Hello from DI"

23

24 @app.get("/di/basic")

25 async def basic_di_route(

26 req: Request, res: Response, msg: str = Depend(get_message)

27 ):

28 return res.text(msg)

29

30 response = await client.get("/di/basic")

31 assert response.status_code == 200

32 assert response.text == "Hello from DI"

33

34

35# Test dependency with request access

36 async def test_request_dependency(di_client):

37 client, app = di_client

38

39 async def get_user_agent(req: Request):

40 return req.headers.get("user-agent", "unknown")

41

42 @app.get("/di/user-agent")

43 async def user_agent_route(

44 req: Request, res: Response, ua: str = Depend(get_user_agent)

45 ):

46 return res.text(ua)

47

48 response = await client.get("/di/user-agent", headers={"User-Agent": "test-agent"})

49 assert response.status_code == 200

50 assert response.text == "test-agent"

51

52

53# Test nested dependencies

54 async def test_nested_dependencies(di_client):

55 client, app = di_client

56

57 async def get_config():

58 return {"env": "test"}

59

60 async def get_service(config: dict = Depend(get_config)):

61 return f"Service in {config['env']} environment"

62

63 @app.get("/di/nested")

64 async def nested_route(

65 req: Request, res: Response, service: str = Depend(get_service)

66 ):

67 return res.text(service)

68

69 response = await client.get("/di/nested")

70 assert response.status_code == 200

71 assert response.text == "Service in test environment"

72

73

74# Test dependency with pydantic model

75 async def test_pydantic_dependency(di_client):

76 client, app = di_client

77

78 class QueryParams(BaseModel):

79 page: int = 1

80 limit: int = 10

81

82 async def get_params(req: Request) -> QueryParams:

83 return QueryParams(**req.query_params)

84

85 @app.get("/di/pydantic")

86 async def pydantic_route(

87 req: Request, res: Response, params: QueryParams = Depend(get_params)

88 ):

89 return res.json({"page": params.page, "limit": params.limit})

90

91 response = await client.get("/di/pydantic?page=2&limit=20")

92 assert response.status_code == 200

93 assert response.json() == {"page": 2, "limit": 20}

94

95

96# Test optional dependencies

97 async def test_optional_dependency(di_client):

98 client, app = di_client

99

100 async def optional_header(req: Request):

101 if "x-optional" in req.headers:

102 return req.headers["x-optional"]

103 return None

104

105 @app.get("/di/optional")

106 async def optional_route(

107 req: Request, res: Response, header: Optional[str] = Depend(optional_header)

108 ):

109 return res.text(header or "not-provided")

110

111 # Test with header

112 response = await client.get("/di/optional", headers={"x-optional": "provided"})

113 assert response.status_code == 200

114 assert response.text == "provided"

115

116 # Test without header

117 response = await client.get("/di/optional")

118 assert response.status_code == 200

119 assert response.text == "not-provided"

120

121

122# Test dependency error handling

123 async def test_dependency_error(di_client):

124 client, app = di_client

125

126 async def failing_dependency():

127 raise ValueError("Dependency failed")

128

129 @app.get("/di/error")

130 async def error_route(

131 req: Request, res: Response, dep: str = Depend(failing_dependency)

132 ):

133 return res.text("should-not-reach-here")

134

135 response = await client.get("/di/error")

136 assert response.status_code == 500

137 assert "Dependency failed" in response.text

138

139

140# Test sync dependencies

141 async def test_sync_dependency(di_client):

142 client, app = di_client

143

144 def sync_dependency():

145 return "sync-result"

146

147 @app.get("/di/sync")

148 async def sync_route(

149 req: Request, res: Response, result: str = Depend(sync_dependency)

150 ):

151 return res.text(result)

152

153 response = await client.get("/di/sync")

154 assert response.status_code == 200

155 assert response.text == "sync-result"

156

157

158# Test dependency with route parameters

159 async def test_route_param_dependency(di_client):

160 client, app = di_client

161

162 async def get_id_param(req: Request):

163 return req.path_params["id"]

164

165 @app.get("/di/param/{id}")

166 async def param_route(req: Request, res: Response, id: str = Depend(get_id_param)):

167 return res.text(id)

168

169 response = await client.get("/di/param/123")

170 assert response.status_code == 200

171 assert response.text == "123"