Skip to content

Commit 790052c

Browse files
committed
test to ensure only creator can see and edit the entries
1 parent 10be8ec commit 790052c

File tree

2 files changed

+244
-0
lines changed

2 files changed

+244
-0
lines changed

tests/admin.spec.ts

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,163 @@
11
import { test, expect } from '@playwright/test'
2+
import { testUser } from './helpers'
23

34
test.describe.configure({ mode: 'serial' })
45

6+
test.describe('entry access control', () => {
7+
const baseUrl = 'http://localhost:8000'
8+
let createdEntryId: string
9+
10+
test('admin can create an entry', async () => {
11+
// Set user as admin
12+
await fetch(`${baseUrl}/mock/user?type=admin`)
13+
14+
const payload = {
15+
data: {
16+
'1': 'Admin User',
17+
'2': testUser,
18+
'3': 'Test Project',
19+
'4': 'bilateral',
20+
'6': 'university',
21+
'8': 'Afghanistan',
22+
'9': 'partner',
23+
'10': 'agreementNotDone',
24+
'11': ['education'],
25+
'12': 'mediumDuration',
26+
'13': 'noExternalFunding',
27+
'16': 'mediumBudget',
28+
'17': 'noTransferPersonalData',
29+
'20': 'Kardan University',
30+
'23': 'noTransferMilitaryKnowledge',
31+
'24': 'noSuccessfulCollaboration',
32+
'25': 'likelyNoEthicalIssues',
33+
faculty: 'H40',
34+
unit: 'H528',
35+
tuhatProjectExists: 'tuhatOptionNegative',
36+
},
37+
sessionToken: 'test-session-token',
38+
tuhatData: {},
39+
}
40+
41+
const response = await fetch(`${baseUrl}/api/entries/1`, {
42+
method: 'POST',
43+
headers: { 'Content-Type': 'application/json' },
44+
body: JSON.stringify(payload),
45+
})
46+
47+
expect(response.status).toBe(201)
48+
const entry = await response.json()
49+
createdEntryId = entry.id
50+
expect(createdEntryId).toBeDefined()
51+
})
52+
53+
test('normal user cannot access entry created by admin', async () => {
54+
// Change user to normal
55+
await fetch(`${baseUrl}/mock/user?type=normal`)
56+
57+
const response = await fetch(`${baseUrl}/api/entries/${createdEntryId}`, {
58+
method: 'GET',
59+
headers: { 'Content-Type': 'application/json' },
60+
})
61+
62+
expect(response.status).toBe(401)
63+
const data = await response.json()
64+
expect(data.error).toContain('Unauthorized')
65+
})
66+
67+
test('normal user cannot edit entry created by admin', async () => {
68+
// Ensure user is still normal
69+
await fetch(`${baseUrl}/mock/user?type=normal`)
70+
71+
const payload = {
72+
data: {
73+
'1': 'Modified by Normal User',
74+
'2': testUser,
75+
'3': 'Modified Project',
76+
'4': 'bilateral',
77+
'6': 'university',
78+
'8': 'Sweden',
79+
'9': 'partner',
80+
'10': 'agreementDone',
81+
'11': ['education', 'research'],
82+
'12': 'mediumDuration',
83+
'13': 'noExternalFunding',
84+
'16': 'mediumBudget',
85+
'17': 'noTransferPersonalData',
86+
'20': 'Kardan University',
87+
'23': 'noTransferMilitaryKnowledge',
88+
'24': 'successfulCollaboration',
89+
'25': 'likelyNoEthicalIssues',
90+
faculty: 'H40',
91+
unit: 'H528',
92+
tuhatProjectExists: 'tuhatOptionNegative',
93+
},
94+
tuhatData: {},
95+
}
96+
97+
const response = await fetch(`${baseUrl}/api/entries/${createdEntryId}`, {
98+
method: 'PUT',
99+
headers: { 'Content-Type': 'application/json' },
100+
body: JSON.stringify(payload),
101+
})
102+
103+
expect(response.status).toBe(401)
104+
const data = await response.json()
105+
expect(data.error).toContain('Unauthorized')
106+
})
107+
108+
test('admin creator can still access and edit their entry', async () => {
109+
// Change back to admin
110+
await fetch(`${baseUrl}/mock/user?type=admin`)
111+
112+
// Test GET
113+
const getResponse = await fetch(`${baseUrl}/api/entries/${createdEntryId}`, {
114+
method: 'GET',
115+
headers: { 'Content-Type': 'application/json' },
116+
})
117+
118+
expect(getResponse.status).toBe(200)
119+
const entry = await getResponse.json()
120+
expect(entry.id).toBe(createdEntryId)
121+
122+
// Test PUT
123+
const payload = {
124+
data: {
125+
'1': 'Admin Modified',
126+
'2': testUser,
127+
'3': 'Admin Modified Project',
128+
'4': 'bilateral',
129+
'6': 'university',
130+
'8': 'Denmark',
131+
'9': 'coordinator',
132+
'10': 'agreementDone',
133+
'11': ['education', 'research'],
134+
'12': 'longDuration',
135+
'13': 'externalFunding',
136+
'16': 'largeBudget',
137+
'17': 'noTransferPersonalData',
138+
'20': 'Ahlobait University',
139+
'23': 'noTransferMilitaryKnowledge',
140+
'24': 'successfulCollaboration',
141+
'25': 'likelyNoEthicalIssues',
142+
faculty: 'H40',
143+
unit: 'H528',
144+
tuhatProjectExists: 'tuhatOptionNegative',
145+
},
146+
tuhatData: {},
147+
}
148+
149+
const putResponse = await fetch(`${baseUrl}/api/entries/${createdEntryId}`, {
150+
method: 'PUT',
151+
headers: { 'Content-Type': 'application/json' },
152+
body: JSON.stringify(payload),
153+
})
154+
155+
expect(putResponse.status).toBe(200)
156+
const updatedEntry = await putResponse.json()
157+
expect(updatedEntry.id).toBe(createdEntryId)
158+
})
159+
})
160+
5161
test.describe('admin endpoints access control', () => {
6162
const baseUrl = 'http://localhost:8000'
7163

tests/api.spec.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,4 +297,92 @@ test.describe('api', () => {
297297
expect(updatedEntry.data.updatedData[0].country[0].code).toBe('AF')
298298
expect(updatedEntry.data.updatedData[1].country[0].code).toBe('SE')
299299
})
300+
301+
test('only creator can view and edit an entry', async () => {
302+
let mockUserResponse = await fetch(`${baseUrl}/api/mock/user?type=admin`)
303+
304+
const initialPayload = {
305+
data: {
306+
'1': 'Admin Creator',
307+
'2': testUser,
308+
'3': 'Admin Project',
309+
'4': 'bilateral',
310+
'6': 'university',
311+
'8': 'Afghanistan',
312+
'9': 'partner',
313+
'10': 'agreementNotDone',
314+
'11': ['education'],
315+
'12': 'mediumDuration',
316+
'13': 'noExternalFunding',
317+
'16': 'mediumBudget',
318+
'17': 'noTransferPersonalData',
319+
'20': 'Kardan University',
320+
'23': 'noTransferMilitaryKnowledge',
321+
'24': 'noSuccessfulCollaboration',
322+
'25': 'likelyNoEthicalIssues',
323+
faculty: 'H40',
324+
unit: 'H528',
325+
tuhatProjectExists: 'tuhatOptionNegative',
326+
},
327+
sessionToken: 'access-control-test-session',
328+
tuhatData: {},
329+
}
330+
331+
const createResponse = await fetch(`${baseUrl}/api/entries/1`, {
332+
method: 'POST',
333+
headers: { 'Content-Type': 'application/json' },
334+
body: JSON.stringify(initialPayload),
335+
})
336+
337+
expect(createResponse.status).toBe(201)
338+
const createdEntry = await createResponse.json()
339+
const entryId = createdEntry.id
340+
mockUserResponse = await fetch(`${baseUrl}/api/mock/user?type=normal`)
341+
expect(mockUserResponse.status).toBe(200)
342+
343+
const getResponse = await fetch(`${baseUrl}/api/entries/${entryId}`, {
344+
method: 'GET',
345+
headers: { 'Content-Type': 'application/json' },
346+
})
347+
348+
expect(getResponse.status).toBe(401)
349+
const getError = await getResponse.json()
350+
expect(getError.error).toContain('Unauthorized')
351+
352+
const updatePayload = {
353+
data: {
354+
'1': 'Unauthorized Edit',
355+
'2': testUser,
356+
'3': 'Should Not Work',
357+
'4': 'bilateral',
358+
'6': 'university',
359+
'8': 'Sweden',
360+
'9': 'partner',
361+
'10': 'agreementDone',
362+
'11': ['education', 'research'],
363+
'12': 'mediumDuration',
364+
'13': 'noExternalFunding',
365+
'16': 'mediumBudget',
366+
'17': 'noTransferPersonalData',
367+
'20': 'Kardan University',
368+
'23': 'noTransferMilitaryKnowledge',
369+
'24': 'successfulCollaboration',
370+
'25': 'likelyNoEthicalIssues',
371+
faculty: 'H40',
372+
unit: 'H528',
373+
tuhatProjectExists: 'tuhatOptionNegative',
374+
},
375+
tuhatData: {},
376+
}
377+
378+
const putResponse = await fetch(`${baseUrl}/api/entries/${entryId}`, {
379+
method: 'PUT',
380+
headers: { 'Content-Type': 'application/json' },
381+
body: JSON.stringify(updatePayload),
382+
})
383+
384+
expect(putResponse.status).toBe(401)
385+
const putError = await putResponse.json()
386+
expect(putError.error).toContain('Unauthorized')
387+
})
300388
})

0 commit comments

Comments
 (0)