Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1"""Set up testing the Contribution tool 

2 

3Here we set up the scene. 

4By means of 

5[fixtures](https://docs.pytest.org/en/latest/fixture.html) 

6we define the web-app objects 

7to be tested and the web clients to exercise functions in those objects. 

8 

9## Players 

10 

11name | role | remarks 

12--- | --- | --- 

13HaSProject | - | user that cannot login, author of legacy stuff and system objects 

14public | public | any unauthenticated user 

15auth | auth | any authenticated user without special rights 

16coord | coord | any national coordinator, from Luxemburg, but that is not relevant 

17mycoord | coord | the national coordinator of Belgium 

18expert | auth | authenticated user, expert reviewer of a test contribution 

19final | auth | authenticated user, final reviewer of a test contribution 

20editor | auth | authenticated user, added as editor of a test contribution 

21owner | auth | authenticated user from Belgium, creates and assesses a contribution 

22office | office | authenticated user of the DARIAH backoffice 

23system | system | authenticated user and system administrator 

24root | root | unique authenticated user that can assign office users and system admins 

25 

26!!! caution 

27 Although it seems that `root` and `system` are more powerful than `office`, 

28 there are things that they cannot do but `office` can. 

29 For example: **assigning** reviewers to an assessment. 

30 

31## Auxiliary 

32 

33`client` 

34: Wrap the Flask test-`client` in something more capable. 

35 

36`clean` 

37: Provides a clean slate test database. 

38 

39`starters` 

40: Provide test functions with a well-defined initial state. 

41 

42`helpers` 

43: Low-level library functions for testers. 

44 

45`subtest` 

46: Higher-level `assert` functions. 

47 

48`example` 

49: Concrete example values for testers to work with. 

50 

51`analysis` 

52: Interpret the request log after testing. 

53 

54## Test batches 

55 

56The following files can be run individually, or as part of an all-tests-run, 

57in alphabetical order of the file names. 

58 

59### Tests: app 

60 

61`test_00_app10` 

62: Checking the app urls and weird deviations from them. 

63 

64### Tests: setup 

65 

66`test_10_factory10` 

67: How the app is set up. 

68 

69`test_20_users10` 

70: Getting to know all users. 

71 

72### Tests: Contributions 

73 

74`test_30_contrib10` 

75: Getting started with contributions. 

76 

77`test_30_contrib20` 

78: Modifying contribution fields that are typed in by the user. 

79 

80`test_30_contrib30` 

81: Modifying contribution fields that have values in value tables. 

82 

83`test_30_contrib40` 

84: Checking the visibility of sensitive fields. 

85 

86`test_30_contrib50` 

87: Selecting contributions. 

88 

89### Tests: assessments 

90 

91`test_40_assess10` 

92: Starting an assessment. 

93 

94`test_40_assess20` 

95: Starting a second assessment. 

96 

97`test_40_assess30` 

98: Filling out an assessment. 

99 

100`test_40_assess30` 

101: Assigning reviewers. 

102 

103### Tests: Reviews: filling out and deciding. 

104 

105`test_50_review10` 

106: Starting reviews and filling them out. 

107 

108`test_50_review20` 

109: Checking visibility of reviews and making review decisions. 

110 Revising, resubmitting assessments and take a new review decision. 

111""" 

112 

113import pytest 

114 

115import magic # noqa 

116from control.app import appFactory 

117from clean import clean 

118from client import makeClient 

119 

120 

121DEBUG = False 

122TEST = True 

123 

124USER_LIST = """ 

125 public 

126 auth 

127 coord 

128 mycoord 

129 expert 

130 final 

131 editor 

132 owner 

133 office 

134 system 

135 root 

136""".strip().split() 

137"""The `eppn` attribute of all relevant test users in this suite. 

138 

139See the table above. 

140 

141Here we make fixtures `clientAuth`, `clientOwner` etc. for each of them. 

142These client fixtures represent a web client with the corresponding user logged in, 

143ready to interact with the server (in development mode). 

144 

145There is also a fixture `clientPublic` for the non-authenticated user. 

146 

147Finally, there is a fixture `clients` that contains fixtures for all the users. 

148""" 

149 

150 

151USERS = set(USER_LIST) 

152 

153NAMED_USERS = USERS - {"public"} 

154"""All authenticated users.""" 

155 

156RIGHTFUL_USERS = set(""" 

157 editor 

158 owner 

159 office 

160 system 

161 root 

162""".strip().split()) 

163"""The users that have normally access to an item. """ 

164 

165 

166POWER_USERS = set(""" 

167 office 

168 system 

169 root 

170""".strip().split()) 

171"""The power users.""" 

172 

173 

174@pytest.fixture(scope="module") 

175def db(): 

176 clean() 

177 

178 

179@pytest.fixture(scope="session") 

180def app(): 

181 """Normal app for testing: development mode, test mode. 

182 

183 There is no difference between production and development, 

184 except for the existence of test users in development mode. 

185 So most tests are done in development mode, with the test users. 

186 

187 Only a few tests are in production mode, see below. 

188 """ 

189 

190 yield appFactory("development", True, DEBUG) 

191 

192 

193@pytest.fixture(scope="module") 

194def clients(app): 

195 """A dictionary of client fixtures for each user. 

196 

197 Keyed by user (eppn), the values are corresponding client fixtures. 

198 

199 This comes in handy to pass to tests that want to perform the same 

200 action on behalf of the different users. 

201 """ 

202 

203 return {user: makeClient(app, user) for user in USERS} 

204 

205 

206@pytest.fixture(scope="module") 

207def clientsNamed(app): 

208 """A dictionary of client fixtures for all authenticated users. 

209 

210 Keyed by user (eppn), the values are corresponding client fixtures. 

211 """ 

212 

213 return {user: makeClient(app, user) for user in NAMED_USERS} 

214 

215 

216@pytest.fixture(scope="module") 

217def clientsMy(app): 

218 """A dictionary of client fixtures for the owner/editor users. 

219 

220 Keyed by user (eppn), the values are corresponding client fixtures. 

221 """ 

222 

223 return {user: makeClient(app, user) for user in ("owner", "editor")} 

224 

225 

226@pytest.fixture(scope="module") 

227def clientsReviewer(app): 

228 """A dictionary of client fixtures for the reviewer users. 

229 

230 Keyed by user (eppn), the values are corresponding client fixtures. 

231 """ 

232 

233 return {user: makeClient(app, user) for user in ("expert", "final")} 

234 

235 

236@pytest.fixture(scope="module") 

237def clientsPower(app): 

238 """A dictionary of client fixtures for the power users. 

239 

240 Keyed by user (eppn), the values are corresponding client fixtures. 

241 """ 

242 

243 return {user: makeClient(app, user) for user in POWER_USERS} 

244 

245 

246@pytest.fixture(scope="module") 

247def clientPublic(app): 

248 return makeClient(app, "public") 

249 

250 

251@pytest.fixture(scope="module") 

252def clientAuth(app): 

253 return makeClient(app, "auth") 

254 

255 

256@pytest.fixture(scope="module") 

257def clientCoord(app): 

258 return makeClient(app, "coord") 

259 

260 

261@pytest.fixture(scope="module") 

262def clientExpert(app): 

263 return makeClient(app, "expert") 

264 

265 

266@pytest.fixture(scope="module") 

267def clientFinal(app): 

268 return makeClient(app, "final") 

269 

270 

271@pytest.fixture(scope="module") 

272def clientMycoord(app): 

273 return makeClient(app, "mycoord") 

274 

275 

276@pytest.fixture(scope="module") 

277def clientEditor(app): 

278 return makeClient(app, "editor") 

279 

280 

281@pytest.fixture(scope="module") 

282def clientOwner(app): 

283 return makeClient(app, "owner") 

284 

285 

286@pytest.fixture(scope="module") 

287def clientOffice(app): 

288 return makeClient(app, "office") 

289 

290 

291@pytest.fixture(scope="module") 

292def clientSystem(app): 

293 return makeClient(app, "system") 

294 

295 

296@pytest.fixture(scope="module") 

297def clientRoot(app): 

298 return makeClient(app, "root")