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

1"""

2 camcops_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

28 from cardinal_pythonlib.typing_helpers import with_typehint

29 from camcops_server.cc_modules.cc_session import CamcopsSession

30 from camcops_server.cc_modules.cc_unittest import BasicDatabaseTestCase

31 from camcops_server.cc_modules.cc_view_classes import FormWizardMixin, View

32

33

34 class TestView(FormWizardMixin, View):

35 pass

36

37

38 class 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

92 class 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()