Coverage for cc_modules/tests/cc_view_classes_tests.py: 18%

92 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2025-01-31 07:07 +0000

1""" 

2camcops_server/cc_modules/tests/cc_view_classes_tests.py 

3 

4=============================================================================== 

5 

6 Copyright (C) 2012, University of Cambridge, Department of Psychiatry. 

7 Created by Rudolf Cardinal (rnc1001@cam.ac.uk). 

8 

9 This file is part of CamCOPS. 

10 

11 CamCOPS is free software: you can redistribute it and/or modify 

12 it under the terms of the GNU General Public License as published by 

13 the Free Software Foundation, either version 3 of the License, or 

14 (at your option) any later version. 

15 

16 CamCOPS is distributed in the hope that it will be useful, 

17 but WITHOUT ANY WARRANTY; without even the implied warranty of 

18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

19 GNU General Public License for more details. 

20 

21 You should have received a copy of the GNU General Public License 

22 along with CamCOPS. If not, see <https://www.gnu.org/licenses/>. 

23 

24=============================================================================== 

25 

26""" 

27 

28from cardinal_pythonlib.typing_helpers import with_typehint 

29from camcops_server.cc_modules.cc_session import CamcopsSession 

30from camcops_server.cc_modules.cc_unittest import BasicDatabaseTestCase 

31from camcops_server.cc_modules.cc_view_classes import FormWizardMixin, View 

32 

33 

34class TestView(FormWizardMixin, View): 

35 pass 

36 

37 

38class TestStateMixin(with_typehint(BasicDatabaseTestCase)): 

39 """ 

40 For testing FormWizardMixin state. 

41 """ 

42 

43 def assert_state_is_finished(self) -> None: 

44 """ 

45 Asserts that the state has been marked as "finished", i.e. with the 

46 finish flag set to true and only selected other parameters present. 

47 """ 

48 state = self.req.camcops_session.form_state 

49 self.assertIsNotNone(state, msg="state is None (incorrect)") 

50 self.assertTrue( 

51 state[FormWizardMixin.PARAM_FINISHED], 

52 msg=f"PARAM_FINISHED is " 

53 f"{state[FormWizardMixin.PARAM_FINISHED]!r} (should be True)", 

54 ) 

55 expected_finished_params = { 

56 FormWizardMixin.PARAM_FINISHED, 

57 FormWizardMixin.PARAM_ROUTE_NAME, 

58 FormWizardMixin.PARAM_STEP, 

59 } 

60 state_params = set(state.keys()) 

61 wrong_params = state_params - expected_finished_params 

62 missing_params = expected_finished_params - state_params 

63 self.assertFalse( 

64 bool(wrong_params), 

65 msg=f"Inappropriate parameters: {wrong_params!r}", 

66 ) 

67 self.assertFalse( 

68 bool(missing_params), msg=f"Missing parameters: {missing_params!r}" 

69 ) 

70 

71 def assert_state_is_clean(self) -> None: 

72 """ 

73 Asserts that the state is None or contains only certain permitted 

74 parameters. 

75 """ 

76 state = self.req.camcops_session.form_state 

77 permissible_params = { 

78 FormWizardMixin.PARAM_FINISHED, 

79 FormWizardMixin.PARAM_ROUTE_NAME, 

80 FormWizardMixin.PARAM_STEP, 

81 } 

82 state_is_none = bool(state is None) 

83 state_params = set(state.keys()) 

84 wrong_params = state_params - permissible_params 

85 state_contains_only_permissible_params = not wrong_params 

86 self.assertTrue( 

87 state_is_none or state_contains_only_permissible_params, 

88 msg=f"State contains inappropriate parameters {wrong_params!r}", 

89 ) 

90 

91 

92class FormWizardMixinTests(TestStateMixin, BasicDatabaseTestCase): 

93 def setUp(self) -> None: 

94 super().setUp() 

95 

96 self.req.matched_route.name = "test_route" 

97 

98 def test_route_name_is_saved_in_existing_session(self) -> None: 

99 self.req.camcops_session.form_state = { 

100 FormWizardMixin.PARAM_STEP: "some-previous-step", 

101 FormWizardMixin.PARAM_ROUTE_NAME: "some_previous_route_name", 

102 } 

103 self.req.dbsession.add(self.req.camcops_session) 

104 self.req.dbsession.commit() 

105 

106 TestView(self.req) 

107 

108 self.assertEqual( 

109 self.req.camcops_session.form_state[ 

110 FormWizardMixin.PARAM_ROUTE_NAME 

111 ], 

112 "test_route", 

113 ) 

114 

115 self.req.dbsession.flush() 

116 session_id = self.req.camcops_session.id 

117 self.assertIsNotNone(session_id) 

118 

119 self.req.dbsession.commit() 

120 

121 session = ( 

122 self.req.dbsession.query(CamcopsSession) 

123 .filter(CamcopsSession.id == session_id) 

124 .one() 

125 ) 

126 

127 self.assertEqual( 

128 session.form_state[FormWizardMixin.PARAM_ROUTE_NAME], "test_route" 

129 ) 

130 

131 def test_step_is_saved_in_new_session(self) -> None: 

132 view = TestView(self.req) 

133 view.step = "test" 

134 self.assertEqual( 

135 self.req.camcops_session.form_state[FormWizardMixin.PARAM_STEP], 

136 "test", 

137 ) 

138 

139 self.req.dbsession.flush() 

140 session_id = self.req.camcops_session.id 

141 self.assertIsNotNone(session_id) 

142 

143 self.req.dbsession.commit() 

144 

145 session = ( 

146 self.req.dbsession.query(CamcopsSession) 

147 .filter(CamcopsSession.id == session_id) 

148 .one() 

149 ) 

150 

151 self.assertEqual( 

152 session.form_state[FormWizardMixin.PARAM_STEP], "test" 

153 ) 

154 

155 def test_route_name_is_saved_in_new_session(self) -> None: 

156 TestView(self.req) 

157 

158 self.assertEqual( 

159 self.req.camcops_session.form_state[ 

160 FormWizardMixin.PARAM_ROUTE_NAME 

161 ], 

162 "test_route", 

163 ) 

164 

165 self.req.dbsession.flush() 

166 session_id = self.req.camcops_session.id 

167 self.assertIsNotNone(session_id) 

168 

169 self.req.dbsession.commit() 

170 

171 session = ( 

172 self.req.dbsession.query(CamcopsSession) 

173 .filter(CamcopsSession.id == session_id) 

174 .one() 

175 ) 

176 

177 self.assertEqual( 

178 session.form_state[FormWizardMixin.PARAM_ROUTE_NAME], "test_route" 

179 ) 

180 

181 def test_step_is_updated_for_same_route(self) -> None: 

182 self.req.camcops_session.form_state = { 

183 FormWizardMixin.PARAM_STEP: "previous_step", 

184 FormWizardMixin.PARAM_ROUTE_NAME: "test_route", 

185 } 

186 self.req.dbsession.add(self.req.camcops_session) 

187 self.req.dbsession.commit() 

188 

189 view = TestView(self.req) 

190 view.step = "next_step" 

191 self.assertEqual( 

192 self.req.camcops_session.form_state[FormWizardMixin.PARAM_STEP], 

193 "next_step", 

194 ) 

195 

196 self.req.dbsession.flush() 

197 session_id = self.req.camcops_session.id 

198 self.assertIsNotNone(session_id) 

199 

200 self.req.dbsession.commit() 

201 

202 session = ( 

203 self.req.dbsession.query(CamcopsSession) 

204 .filter(CamcopsSession.id == session_id) 

205 .one() 

206 ) 

207 

208 self.assertEqual( 

209 session.form_state[FormWizardMixin.PARAM_STEP], "next_step" 

210 ) 

211 

212 def test_arbitrary_field_is_saved_in_new_session(self) -> None: 

213 view = TestView(self.req) 

214 view.state["test_field"] = "test_value" 

215 

216 self.assertEqual( 

217 self.req.camcops_session.form_state["test_field"], "test_value" 

218 ) 

219 

220 self.req.dbsession.flush() 

221 session_id = self.req.camcops_session.id 

222 self.assertIsNotNone(session_id) 

223 

224 self.req.dbsession.commit() 

225 

226 session = ( 

227 self.req.dbsession.query(CamcopsSession) 

228 .filter(CamcopsSession.id == session_id) 

229 .one() 

230 ) 

231 

232 self.assertEqual(session.form_state["test_field"], "test_value") 

233 

234 def test_finish_and_finished(self) -> None: 

235 self.req.camcops_session.form_state = { 

236 FormWizardMixin.PARAM_STEP: "previous_step", 

237 FormWizardMixin.PARAM_ROUTE_NAME: "test_route", 

238 } 

239 self.req.dbsession.add(self.req.camcops_session) 

240 self.req.dbsession.commit() 

241 

242 view = TestView(self.req) 

243 self.assertFalse(view.finished()) 

244 

245 view.finish() 

246 

247 self.assertTrue(view.finished()) 

248 self.assert_state_is_finished()