1
+ /**
2
+ * @jest -environment ./test/fastify-test-env.ts
3
+ */
4
+
1
5
import { faker } from "@faker-js/faker/." ;
2
6
import { CertificationAuthorityContestationDecision } from "@prisma/client" ;
7
+ import { addDays , subDays } from "date-fns" ;
3
8
import { prismaClient } from "../../../../prisma/client" ;
9
+ import { authorizationHeaderForUser } from "../../../../test/helpers/authorization-helper" ;
4
10
import { createCandidacyHelper } from "../../../../test/helpers/entities/create-candidacy-helper" ;
11
+ import { injectGraphql } from "../../../../test/helpers/graphql-helper" ;
5
12
import { clearDatabase } from "../../../../test/jestClearDatabaseBeforeEachTestFile" ;
6
13
import { createCandidacyContestationCaducite } from "./createCandidacyContestationCaducite" ;
7
14
15
+ const VALID_CONTESTATION_REASON = "Valid contestation reason" ;
16
+ const FUTURE_DATE = addDays ( new Date ( ) , 30 ) ;
17
+ const PAST_DATE = subDays ( new Date ( ) , 1 ) ;
18
+
19
+ const createContestationMutation = async ( {
20
+ keycloakId,
21
+ candidacyId,
22
+ contestationReason,
23
+ readyForJuryEstimatedAt,
24
+ } : {
25
+ keycloakId : string ;
26
+ candidacyId : string ;
27
+ contestationReason : string ;
28
+ readyForJuryEstimatedAt : Date ;
29
+ } ) =>
30
+ await injectGraphql ( {
31
+ fastify : ( global as any ) . fastify ,
32
+ authorization : authorizationHeaderForUser ( {
33
+ role : "candidate" ,
34
+ keycloakId,
35
+ } ) ,
36
+ payload : {
37
+ requestType : "mutation" ,
38
+ endpoint : "candidacy_contestation_caducite_create_contestation" ,
39
+ arguments : {
40
+ candidacyId,
41
+ contestationReason,
42
+ readyForJuryEstimatedAt,
43
+ } ,
44
+ returnFields : "{id,contestationReason}" ,
45
+ } ,
46
+ } ) ;
47
+
8
48
describe ( "createCandidacyContestationCaducite" , ( ) => {
9
49
beforeEach ( async ( ) => {
10
50
await clearDatabase ( ) ;
@@ -13,13 +53,11 @@ describe("createCandidacyContestationCaducite", () => {
13
53
describe ( "Input validation" , ( ) => {
14
54
test ( "should fail when contestationReason is empty" , async ( ) => {
15
55
const candidacy = await createCandidacyHelper ( ) ;
16
- const futureDate = new Date ( ) ;
17
- futureDate . setDate ( futureDate . getDate ( ) + 30 ) ;
18
56
19
57
const createContestationPromise = createCandidacyContestationCaducite ( {
20
58
candidacyId : candidacy . id ,
21
59
contestationReason : "" ,
22
- readyForJuryEstimatedAt : futureDate ,
60
+ readyForJuryEstimatedAt : FUTURE_DATE ,
23
61
} ) ;
24
62
25
63
await expect ( createContestationPromise ) . rejects . toThrow (
@@ -29,13 +67,11 @@ describe("createCandidacyContestationCaducite", () => {
29
67
30
68
test ( "should fail when readyForJuryEstimatedAt is in the past" , async ( ) => {
31
69
const candidacy = await createCandidacyHelper ( ) ;
32
- const pastDate = new Date ( ) ;
33
- pastDate . setDate ( pastDate . getDate ( ) - 1 ) ;
34
70
35
71
const createContestationPromise = createCandidacyContestationCaducite ( {
36
72
candidacyId : candidacy . id ,
37
- contestationReason : "Valid reason" ,
38
- readyForJuryEstimatedAt : pastDate ,
73
+ contestationReason : VALID_CONTESTATION_REASON ,
74
+ readyForJuryEstimatedAt : PAST_DATE ,
39
75
} ) ;
40
76
41
77
await expect ( createContestationPromise ) . rejects . toThrow (
@@ -46,13 +82,10 @@ describe("createCandidacyContestationCaducite", () => {
46
82
47
83
describe ( "Candidacy validation" , ( ) => {
48
84
test ( "should fail when candidacy does not exist" , async ( ) => {
49
- const futureDate = new Date ( ) ;
50
- futureDate . setDate ( futureDate . getDate ( ) + 30 ) ;
51
-
52
85
const createContestationPromise = createCandidacyContestationCaducite ( {
53
86
candidacyId : faker . string . uuid ( ) ,
54
- contestationReason : "Valid reason" ,
55
- readyForJuryEstimatedAt : futureDate ,
87
+ contestationReason : VALID_CONTESTATION_REASON ,
88
+ readyForJuryEstimatedAt : FUTURE_DATE ,
56
89
} ) ;
57
90
58
91
await expect ( createContestationPromise ) . rejects . toThrow (
@@ -62,22 +95,20 @@ describe("createCandidacyContestationCaducite", () => {
62
95
63
96
test ( "should fail when a contestation is pending" , async ( ) => {
64
97
const candidacy = await createCandidacyHelper ( ) ;
65
- const futureDate = new Date ( ) ;
66
- futureDate . setDate ( futureDate . getDate ( ) + 30 ) ;
67
98
68
99
await prismaClient . candidacyContestationCaducite . create ( {
69
100
data : {
70
101
candidacyId : candidacy . id ,
71
- contestationReason : "Initial contestation" ,
102
+ contestationReason : VALID_CONTESTATION_REASON ,
72
103
certificationAuthorityContestationDecision :
73
104
CertificationAuthorityContestationDecision . DECISION_PENDING ,
74
105
} ,
75
106
} ) ;
76
107
77
108
const createContestationPromise = createCandidacyContestationCaducite ( {
78
109
candidacyId : candidacy . id ,
79
- contestationReason : "Another contestation" ,
80
- readyForJuryEstimatedAt : futureDate ,
110
+ contestationReason : VALID_CONTESTATION_REASON ,
111
+ readyForJuryEstimatedAt : FUTURE_DATE ,
81
112
} ) ;
82
113
83
114
await expect ( createContestationPromise ) . rejects . toThrow (
@@ -87,22 +118,20 @@ describe("createCandidacyContestationCaducite", () => {
87
118
88
119
test ( "should fail when caducity has been confirmed" , async ( ) => {
89
120
const candidacy = await createCandidacyHelper ( ) ;
90
- const futureDate = new Date ( ) ;
91
- futureDate . setDate ( futureDate . getDate ( ) + 30 ) ;
92
121
93
122
await prismaClient . candidacyContestationCaducite . create ( {
94
123
data : {
95
124
candidacyId : candidacy . id ,
96
- contestationReason : "Initial contestation" ,
125
+ contestationReason : VALID_CONTESTATION_REASON ,
97
126
certificationAuthorityContestationDecision :
98
127
CertificationAuthorityContestationDecision . CADUCITE_CONFIRMED ,
99
128
} ,
100
129
} ) ;
101
130
102
131
const createContestationPromise = createCandidacyContestationCaducite ( {
103
132
candidacyId : candidacy . id ,
104
- contestationReason : "Another contestation" ,
105
- readyForJuryEstimatedAt : futureDate ,
133
+ contestationReason : VALID_CONTESTATION_REASON ,
134
+ readyForJuryEstimatedAt : FUTURE_DATE ,
106
135
} ) ;
107
136
108
137
await expect ( createContestationPromise ) . rejects . toThrow (
@@ -114,52 +143,85 @@ describe("createCandidacyContestationCaducite", () => {
114
143
describe ( "Successful creation" , ( ) => {
115
144
test ( "should successfully create a contestation and update readyForJuryEstimatedAt" , async ( ) => {
116
145
const candidacy = await createCandidacyHelper ( ) ;
117
- const futureDate = new Date ( ) ;
118
- futureDate . setDate ( futureDate . getDate ( ) + 30 ) ;
119
146
120
147
const result = await createCandidacyContestationCaducite ( {
121
148
candidacyId : candidacy . id ,
122
- contestationReason : "Valid contestation reason" ,
123
- readyForJuryEstimatedAt : futureDate ,
149
+ contestationReason : VALID_CONTESTATION_REASON ,
150
+ readyForJuryEstimatedAt : FUTURE_DATE ,
124
151
} ) ;
125
152
126
153
expect ( result ) . toMatchObject ( {
127
154
candidacyId : candidacy . id ,
128
- contestationReason : "Valid contestation reason" ,
155
+ contestationReason : VALID_CONTESTATION_REASON ,
129
156
} ) ;
130
157
131
158
const updatedCandidacy = await prismaClient . candidacy . findUnique ( {
132
159
where : { id : candidacy . id } ,
133
160
} ) ;
134
161
expect ( updatedCandidacy ?. readyForJuryEstimatedAt ?. getTime ( ) ) . toBe (
135
- futureDate . getTime ( ) ,
162
+ FUTURE_DATE . getTime ( ) ,
136
163
) ;
137
164
} ) ;
138
165
139
166
test ( "should allow new contestation when previous one was invalidated" , async ( ) => {
140
167
const candidacy = await createCandidacyHelper ( ) ;
141
- const futureDate = new Date ( ) ;
142
- futureDate . setDate ( futureDate . getDate ( ) + 30 ) ;
143
168
144
169
await prismaClient . candidacyContestationCaducite . create ( {
145
170
data : {
146
171
candidacyId : candidacy . id ,
147
- contestationReason : "Initial contestation" ,
172
+ contestationReason : VALID_CONTESTATION_REASON ,
148
173
certificationAuthorityContestationDecision :
149
174
CertificationAuthorityContestationDecision . CADUCITE_INVALIDATED ,
150
175
} ,
151
176
} ) ;
152
177
153
178
const result = await createCandidacyContestationCaducite ( {
154
179
candidacyId : candidacy . id ,
155
- contestationReason : "New valid contestation" ,
156
- readyForJuryEstimatedAt : futureDate ,
180
+ contestationReason : VALID_CONTESTATION_REASON ,
181
+ readyForJuryEstimatedAt : FUTURE_DATE ,
157
182
} ) ;
158
183
159
184
expect ( result ) . toMatchObject ( {
160
185
candidacyId : candidacy . id ,
161
- contestationReason : "New valid contestation" ,
186
+ contestationReason : VALID_CONTESTATION_REASON ,
187
+ } ) ;
188
+ } ) ;
189
+ } ) ;
190
+
191
+ describe ( "Security" , ( ) => {
192
+ test ( "should allow candidate to create contestation for their own candidacy" , async ( ) => {
193
+ const candidacy = await createCandidacyHelper ( ) ;
194
+
195
+ const resp = await createContestationMutation ( {
196
+ keycloakId : candidacy . candidate ?. keycloakId ?? "" ,
197
+ candidacyId : candidacy . id ,
198
+ contestationReason : VALID_CONTESTATION_REASON ,
199
+ readyForJuryEstimatedAt : FUTURE_DATE ,
200
+ } ) ;
201
+
202
+ expect ( resp . statusCode ) . toEqual ( 200 ) ;
203
+ expect (
204
+ resp . json ( ) . data . candidacy_contestation_caducite_create_contestation ,
205
+ ) . toMatchObject ( {
206
+ contestationReason : VALID_CONTESTATION_REASON ,
207
+ } ) ;
208
+ } ) ;
209
+
210
+ test ( "should not allow candidate to create contestation for another candidacy" , async ( ) => {
211
+ const candidacy = await createCandidacyHelper ( ) ;
212
+ const otherCandidacy = await createCandidacyHelper ( ) ;
213
+
214
+ const resp = await createContestationMutation ( {
215
+ keycloakId : candidacy . candidate ?. keycloakId ?? "" ,
216
+ candidacyId : otherCandidacy . id ,
217
+ contestationReason : VALID_CONTESTATION_REASON ,
218
+ readyForJuryEstimatedAt : FUTURE_DATE ,
162
219
} ) ;
220
+
221
+ expect ( resp . statusCode ) . toEqual ( 200 ) ;
222
+ expect ( resp . json ( ) . errors ?. [ 0 ] . message ) . toEqual (
223
+ "Vous n'êtes pas autorisé à accéder à cette candidature" ,
224
+ ) ;
163
225
} ) ;
164
226
} ) ;
165
227
} ) ;
0 commit comments