mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-29 06:15:29 -04:00
test: add e2e tests for note permissions
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
cbfab3ca62
commit
825b3b72ff
1 changed files with 243 additions and 20 deletions
|
@ -8,14 +8,16 @@ import { join } from 'path';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
|
|
||||||
import { NotInDBError } from '../../src/errors/errors';
|
import { NotInDBError } from '../../src/errors/errors';
|
||||||
|
import { Group } from '../../src/groups/group.entity';
|
||||||
import { User } from '../../src/users/user.entity';
|
import { User } from '../../src/users/user.entity';
|
||||||
import { TestSetup, TestSetupBuilder } from '../test-setup';
|
import { TestSetup, TestSetupBuilder } from '../test-setup';
|
||||||
|
|
||||||
describe('Notes', () => {
|
describe('Notes', () => {
|
||||||
let testSetup: TestSetup;
|
let testSetup: TestSetup;
|
||||||
|
|
||||||
let user: User;
|
let user1: User;
|
||||||
let user2: User;
|
let user2: User;
|
||||||
|
let group1: Group;
|
||||||
let content: string;
|
let content: string;
|
||||||
let forbiddenNoteId: string;
|
let forbiddenNoteId: string;
|
||||||
let uploadPath: string;
|
let uploadPath: string;
|
||||||
|
@ -35,11 +37,15 @@ describe('Notes', () => {
|
||||||
const password1 = 'AHardcodedStrongP@ssword123';
|
const password1 = 'AHardcodedStrongP@ssword123';
|
||||||
const username2 = 'hardcoded2';
|
const username2 = 'hardcoded2';
|
||||||
const password2 = 'AHardcodedStrongP@ssword12';
|
const password2 = 'AHardcodedStrongP@ssword12';
|
||||||
|
const groupname1 = 'groupname1';
|
||||||
|
|
||||||
user = await testSetup.userService.createUser(username1, 'Testy');
|
user1 = await testSetup.userService.createUser(username1, 'Testy');
|
||||||
await testSetup.identityService.createLocalIdentity(user, password1);
|
await testSetup.identityService.createLocalIdentity(user1, password1);
|
||||||
user2 = await testSetup.userService.createUser(username2, 'Max Mustermann');
|
user2 = await testSetup.userService.createUser(username2, 'Max Mustermann');
|
||||||
await testSetup.identityService.createLocalIdentity(user2, password2);
|
await testSetup.identityService.createLocalIdentity(user2, password2);
|
||||||
|
|
||||||
|
group1 = await testSetup.groupService.createGroup(groupname1, 'Group 1');
|
||||||
|
|
||||||
content = 'This is a test note.';
|
content = 'This is a test note.';
|
||||||
testImage = await fs.readFile('test/public-api/fixtures/test.png');
|
testImage = await fs.readFile('test/public-api/fixtures/test.png');
|
||||||
|
|
||||||
|
@ -75,7 +81,7 @@ describe('Notes', () => {
|
||||||
describe('GET /notes/{note}', () => {
|
describe('GET /notes/{note}', () => {
|
||||||
it('works with an existing note', async () => {
|
it('works with an existing note', async () => {
|
||||||
// check if we can succefully get a note that exists
|
// check if we can succefully get a note that exists
|
||||||
await testSetup.notesService.createNote(content, user, 'test1');
|
await testSetup.notesService.createNote(content, user1, 'test1');
|
||||||
const response = await agent
|
const response = await agent
|
||||||
.get('/api/private/notes/test1')
|
.get('/api/private/notes/test1')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
|
@ -147,10 +153,10 @@ describe('Notes', () => {
|
||||||
const noteId = 'test3';
|
const noteId = 'test3';
|
||||||
const note = await testSetup.notesService.createNote(
|
const note = await testSetup.notesService.createNote(
|
||||||
content,
|
content,
|
||||||
user,
|
user1,
|
||||||
noteId,
|
noteId,
|
||||||
);
|
);
|
||||||
await testSetup.mediaService.saveFile(testImage, user, note);
|
await testSetup.mediaService.saveFile(testImage, user1, note);
|
||||||
await agent
|
await agent
|
||||||
.delete(`/api/private/notes/${noteId}`)
|
.delete(`/api/private/notes/${noteId}`)
|
||||||
.set('Content-Type', 'application/json')
|
.set('Content-Type', 'application/json')
|
||||||
|
@ -164,7 +170,7 @@ describe('Notes', () => {
|
||||||
new NotInDBError(`Note with id/alias '${noteId}' not found.`),
|
new NotInDBError(`Note with id/alias '${noteId}' not found.`),
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
await testSetup.mediaService.listUploadsByUser(user),
|
await testSetup.mediaService.listUploadsByUser(user1),
|
||||||
).toHaveLength(0);
|
).toHaveLength(0);
|
||||||
await fs.rmdir(uploadPath);
|
await fs.rmdir(uploadPath);
|
||||||
});
|
});
|
||||||
|
@ -172,12 +178,12 @@ describe('Notes', () => {
|
||||||
const noteId = 'test3a';
|
const noteId = 'test3a';
|
||||||
const note = await testSetup.notesService.createNote(
|
const note = await testSetup.notesService.createNote(
|
||||||
content,
|
content,
|
||||||
user,
|
user1,
|
||||||
noteId,
|
noteId,
|
||||||
);
|
);
|
||||||
const upload = await testSetup.mediaService.saveFile(
|
const upload = await testSetup.mediaService.saveFile(
|
||||||
testImage,
|
testImage,
|
||||||
user,
|
user1,
|
||||||
note,
|
note,
|
||||||
);
|
);
|
||||||
await agent
|
await agent
|
||||||
|
@ -193,7 +199,7 @@ describe('Notes', () => {
|
||||||
new NotInDBError(`Note with id/alias '${noteId}' not found.`),
|
new NotInDBError(`Note with id/alias '${noteId}' not found.`),
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
await testSetup.mediaService.listUploadsByUser(user),
|
await testSetup.mediaService.listUploadsByUser(user1),
|
||||||
).toHaveLength(1);
|
).toHaveLength(1);
|
||||||
// Remove /upload/ from path as we just need the filename.
|
// Remove /upload/ from path as we just need the filename.
|
||||||
const fileName = upload.fileUrl.replace('/uploads/', '');
|
const fileName = upload.fileUrl.replace('/uploads/', '');
|
||||||
|
@ -213,7 +219,7 @@ describe('Notes', () => {
|
||||||
describe('GET /notes/{note}/metadata', () => {
|
describe('GET /notes/{note}/metadata', () => {
|
||||||
it('returns complete metadata object', async () => {
|
it('returns complete metadata object', async () => {
|
||||||
const noteAlias = 'metadata_test_note';
|
const noteAlias = 'metadata_test_note';
|
||||||
await testSetup.notesService.createNote(content, user, noteAlias);
|
await testSetup.notesService.createNote(content, user1, noteAlias);
|
||||||
const metadata = await agent
|
const metadata = await agent
|
||||||
.get(`/api/private/notes/${noteAlias}/metadata`)
|
.get(`/api/private/notes/${noteAlias}/metadata`)
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
|
@ -255,7 +261,7 @@ describe('Notes', () => {
|
||||||
// create a note
|
// create a note
|
||||||
const note = await testSetup.notesService.createNote(
|
const note = await testSetup.notesService.createNote(
|
||||||
content,
|
content,
|
||||||
user,
|
user1,
|
||||||
noteAlias,
|
noteAlias,
|
||||||
);
|
);
|
||||||
// save the creation time
|
// save the creation time
|
||||||
|
@ -277,10 +283,10 @@ describe('Notes', () => {
|
||||||
|
|
||||||
describe('GET /notes/{note}/revisions', () => {
|
describe('GET /notes/{note}/revisions', () => {
|
||||||
it('works with existing alias', async () => {
|
it('works with existing alias', async () => {
|
||||||
await testSetup.notesService.createNote(content, user, 'test4');
|
await testSetup.notesService.createNote(content, user1, 'test4');
|
||||||
// create a second note to check for a regression, where typeorm always returned
|
// create a second note to check for a regression, where typeorm always returned
|
||||||
// all revisions in the database
|
// all revisions in the database
|
||||||
await testSetup.notesService.createNote(content, user, 'test4a');
|
await testSetup.notesService.createNote(content, user1, 'test4a');
|
||||||
const response = await agent
|
const response = await agent
|
||||||
.get('/api/private/notes/test4/revisions')
|
.get('/api/private/notes/test4/revisions')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
|
@ -308,7 +314,7 @@ describe('Notes', () => {
|
||||||
const noteId = 'test8';
|
const noteId = 'test8';
|
||||||
const note = await testSetup.notesService.createNote(
|
const note = await testSetup.notesService.createNote(
|
||||||
content,
|
content,
|
||||||
user,
|
user1,
|
||||||
noteId,
|
noteId,
|
||||||
);
|
);
|
||||||
await testSetup.notesService.updateNote(note, 'update');
|
await testSetup.notesService.updateNote(note, 'update');
|
||||||
|
@ -345,7 +351,7 @@ describe('Notes', () => {
|
||||||
it('works with an existing alias', async () => {
|
it('works with an existing alias', async () => {
|
||||||
const note = await testSetup.notesService.createNote(
|
const note = await testSetup.notesService.createNote(
|
||||||
content,
|
content,
|
||||||
user,
|
user1,
|
||||||
'test5',
|
'test5',
|
||||||
);
|
);
|
||||||
const revision = await testSetup.revisionsService.getLatestRevision(note);
|
const revision = await testSetup.revisionsService.getLatestRevision(note);
|
||||||
|
@ -375,12 +381,12 @@ describe('Notes', () => {
|
||||||
const extraAlias = 'test7';
|
const extraAlias = 'test7';
|
||||||
const note1 = await testSetup.notesService.createNote(
|
const note1 = await testSetup.notesService.createNote(
|
||||||
content,
|
content,
|
||||||
user,
|
user1,
|
||||||
alias,
|
alias,
|
||||||
);
|
);
|
||||||
const note2 = await testSetup.notesService.createNote(
|
const note2 = await testSetup.notesService.createNote(
|
||||||
content,
|
content,
|
||||||
user,
|
user1,
|
||||||
extraAlias,
|
extraAlias,
|
||||||
);
|
);
|
||||||
const response = await agent
|
const response = await agent
|
||||||
|
@ -392,12 +398,12 @@ describe('Notes', () => {
|
||||||
const testImage = await fs.readFile('test/private-api/fixtures/test.png');
|
const testImage = await fs.readFile('test/private-api/fixtures/test.png');
|
||||||
const upload0 = await testSetup.mediaService.saveFile(
|
const upload0 = await testSetup.mediaService.saveFile(
|
||||||
testImage,
|
testImage,
|
||||||
user,
|
user1,
|
||||||
note1,
|
note1,
|
||||||
);
|
);
|
||||||
const upload1 = await testSetup.mediaService.saveFile(
|
const upload1 = await testSetup.mediaService.saveFile(
|
||||||
testImage,
|
testImage,
|
||||||
user,
|
user1,
|
||||||
note2,
|
note2,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -440,4 +446,221 @@ describe('Notes', () => {
|
||||||
.expect(403);
|
.expect(403);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('permissions', () => {
|
||||||
|
const user1NoteAlias = 'user1NoteAlias';
|
||||||
|
const user2NoteAlias = 'user2NoteAlias';
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await testSetup.notesService.createNote(
|
||||||
|
'This is a test note.',
|
||||||
|
user1,
|
||||||
|
user1NoteAlias,
|
||||||
|
);
|
||||||
|
await testSetup.notesService.createNote(
|
||||||
|
'This is a test note.',
|
||||||
|
user2,
|
||||||
|
user2NoteAlias,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('users', () => {
|
||||||
|
describe('PUT /notes/{note}/metadata/permissions/users/{userName}', () => {
|
||||||
|
it('fails, when note does not exist', async () => {
|
||||||
|
await agent
|
||||||
|
.put(
|
||||||
|
`/api/private/notes/notExisting/metadata/permissions/users/${user1.username}`,
|
||||||
|
)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(404);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails, when user is not the owner', async () => {
|
||||||
|
await agent
|
||||||
|
.put(
|
||||||
|
`/api/private/notes/${user2NoteAlias}/metadata/permissions/users/${user1.username}`,
|
||||||
|
)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(403);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("doesn't do anything if the user is the owner", async () => {
|
||||||
|
const note = await testSetup.notesService.getNoteByIdOrAlias(
|
||||||
|
user1NoteAlias,
|
||||||
|
);
|
||||||
|
await testSetup.permissionsService.removeUserPermission(note, user2);
|
||||||
|
|
||||||
|
const response = await agent
|
||||||
|
.put(
|
||||||
|
`/api/private/notes/${user1NoteAlias}/metadata/permissions/users/${user1.username}`,
|
||||||
|
)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(200)
|
||||||
|
.send({ canEdit: true });
|
||||||
|
expect(response.body.sharedToUsers).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each([true, false])('works with edit set to %s', async (canEdit) => {
|
||||||
|
const response = await agent
|
||||||
|
.put(
|
||||||
|
`/api/private/notes/${user1NoteAlias}/metadata/permissions/users/${user2.username}`,
|
||||||
|
)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(200)
|
||||||
|
.send({ canEdit: canEdit });
|
||||||
|
expect(response.body.sharedToUsers[0].canEdit).toBe(canEdit);
|
||||||
|
expect(response.body.sharedToUsers[0].username).toBe(user2.username);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('DELETE /notes/{note}/metadata/permissions/users/{userName}', () => {
|
||||||
|
it('fails, when note does not exist', async () => {
|
||||||
|
await agent
|
||||||
|
.delete(
|
||||||
|
`/api/private/notes/notExisting/metadata/permissions/users/${user1.username}`,
|
||||||
|
)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(404);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails, when user is not the owner', async () => {
|
||||||
|
await agent
|
||||||
|
.delete(
|
||||||
|
`/api/private/notes/${user2NoteAlias}/metadata/permissions/users/${user1.username}`,
|
||||||
|
)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(403);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works', async () => {
|
||||||
|
const note = await testSetup.notesService.getNoteByIdOrAlias(
|
||||||
|
user1NoteAlias,
|
||||||
|
);
|
||||||
|
await testSetup.permissionsService.setUserPermission(
|
||||||
|
note,
|
||||||
|
user2,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
const response = await agent
|
||||||
|
.delete(
|
||||||
|
`/api/private/notes/${user1NoteAlias}/metadata/permissions/users/${user2.username}`,
|
||||||
|
)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(200)
|
||||||
|
.send({ canEdit: true });
|
||||||
|
expect(response.body.sharedToUsers).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('groups', () => {
|
||||||
|
describe('PUT /notes/{note}/metadata/permissions/groups/{groupName}', () => {
|
||||||
|
it('fails, when note does not exist', async () => {
|
||||||
|
await agent
|
||||||
|
.put(
|
||||||
|
`/api/private/notes/notExisting/metadata/permissions/groups/${user1.username}`,
|
||||||
|
)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(404);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails, when user is not the owner', async () => {
|
||||||
|
await agent
|
||||||
|
.put(
|
||||||
|
`/api/private/notes/${user2NoteAlias}/metadata/permissions/groups/${group1.name}`,
|
||||||
|
)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(403);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each([true, false])('works with edit set to %s', async (canEdit) => {
|
||||||
|
const response = await agent
|
||||||
|
.put(
|
||||||
|
`/api/private/notes/${user1NoteAlias}/metadata/permissions/groups/${group1.name}`,
|
||||||
|
)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(200)
|
||||||
|
.send({ canEdit: canEdit });
|
||||||
|
expect(response.body.sharedToGroups[2].canEdit).toBe(canEdit);
|
||||||
|
expect(response.body.sharedToGroups[2].groupName).toBe(group1.name);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('DELETE /notes/{note}/metadata/permissions/groups/{groupName}', () => {
|
||||||
|
it('fails, when note does not exist', async () => {
|
||||||
|
await agent
|
||||||
|
.delete(
|
||||||
|
`/api/private/notes/notExisting/metadata/permissions/groups/${group1.name}`,
|
||||||
|
)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(404);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails, when user is not the owner', async () => {
|
||||||
|
await agent
|
||||||
|
.delete(
|
||||||
|
`/api/private/notes/${user2NoteAlias}/metadata/permissions/groups/${group1.name}`,
|
||||||
|
)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(403);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works', async () => {
|
||||||
|
const note = await testSetup.notesService.getNoteByIdOrAlias(
|
||||||
|
user1NoteAlias,
|
||||||
|
);
|
||||||
|
await testSetup.permissionsService.setGroupPermission(
|
||||||
|
note,
|
||||||
|
group1,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
const response = await agent
|
||||||
|
.delete(
|
||||||
|
`/api/private/notes/${user1NoteAlias}/metadata/permissions/groups/${group1.name}`,
|
||||||
|
)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(200)
|
||||||
|
.send({ canEdit: true });
|
||||||
|
expect(response.body.sharedToGroups).toHaveLength(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('owner', () => {
|
||||||
|
describe('PUT /notes/{note}/metadata/permissions/owner', () => {
|
||||||
|
it('fails, when note does not exist', async () => {
|
||||||
|
await agent
|
||||||
|
.put(`/api/private/notes/notExisting/metadata/permissions/owner`)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(404);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails, when user is not the owner', async () => {
|
||||||
|
await agent
|
||||||
|
.put(
|
||||||
|
`/api/private/notes/${user2NoteAlias}/metadata/permissions/owner`,
|
||||||
|
)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(403);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works', async () => {
|
||||||
|
const alias = 'noteForNewOwner';
|
||||||
|
await testSetup.notesService.createNote(
|
||||||
|
"I'll get a new owner!",
|
||||||
|
user1,
|
||||||
|
alias,
|
||||||
|
);
|
||||||
|
const response = await agent
|
||||||
|
.put(`/api/private/notes/${alias}/metadata/permissions/owner`)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(200)
|
||||||
|
.send({ newOwner: user2.username });
|
||||||
|
expect(response.body.metadata.permissions.owner).toBe(user2.username);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue