Skip to content

Commit

Permalink
test: add duplicate check
Browse files Browse the repository at this point in the history
  • Loading branch information
jef committed Dec 12, 2024
1 parent ddd8bc8 commit 4478d0f
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 15 deletions.
69 changes: 56 additions & 13 deletions apps/backend/src/app/modules/maps/maps.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Test, TestingModule } from '@nestjs/testing';
import { mockDeep } from 'jest-mock-extended';
import {
ConflictException,
ForbiddenException,
InternalServerErrorException,
NotFoundException
Expand All @@ -14,6 +15,8 @@ import {
} from '../../../../test/prisma-mock.const';
import { MapsService } from './maps.service';
import * as Bitflags from '@momentum/bitflags';
import { CreateMapDto } from '../../dto';
import { FileStoreService } from '../filestore/file-store.service';

describe('MapsService', () => {
let service: MapsService, db: PrismaMock;
Expand Down Expand Up @@ -45,7 +48,10 @@ describe('MapsService', () => {
it('should 500 for invalid map data', async () => {
db.mMap.findUnique.mockResolvedValueOnce('sausage' as any);

await expect(service.getMapAndCheckReadAccess({ mapID: 1, userID: 1 })).rejects.toThrow(InternalServerErrorException);
await expect(service.getMapAndCheckReadAccess({
mapID: 1,
userID: 1
})).rejects.toThrow(InternalServerErrorException);
});

it('should only allow mod and admins to access APPROVED maps when submissionOnly is true', async () => {
Expand Down Expand Up @@ -74,27 +80,27 @@ describe('MapsService', () => {
).rejects.toThrow(ForbiddenException);
}
}
})
});

it('should only non-logged in requests to access APPROVED and PUBLIC_TESTING maps', async () => {
for (const status of Enum.values(MapStatus)) {
db.mMap.findUnique.mockResolvedValueOnce({id: 1, status } as any);
it('should only non-logged in requests to access APPROVED and PUBLIC_TESTING maps', async () => {
for (const status of Enum.values(MapStatus)) {
db.mMap.findUnique.mockResolvedValueOnce({ id: 1, status } as any);

if ([MapStatus.APPROVED, MapStatus.PUBLIC_TESTING, MapStatus.FINAL_APPROVAL].includes(status)) {
expect(await service.getMapAndCheckReadAccess({ mapID: 1, })).toBeTruthy();
} else {
await expect(service.getMapAndCheckReadAccess({ mapID: 1 })).rejects.toThrow(ForbiddenException);
}
}
});
if ([MapStatus.APPROVED, MapStatus.PUBLIC_TESTING, MapStatus.FINAL_APPROVAL].includes(status)) {
expect(await service.getMapAndCheckReadAccess({ mapID: 1 })).toBeTruthy();
} else {
await expect(service.getMapAndCheckReadAccess({ mapID: 1 })).rejects.toThrow(ForbiddenException);
}
}
});

// Map of what states should PASS access checks for each MapStatus,
// otherwise should fail. Below code performs each check against each state.
const tests = {
[MapStatus.APPROVED]: 'any',
[MapStatus.PUBLIC_TESTING]: 'any',
[MapStatus.PRIVATE_TESTING]: ['admin', 'moderator', 'submitter', 'acceptedRequest', 'inCredits'],
[MapStatus.CONTENT_APPROVAL]: ['admin', 'moderator', 'submitter' ,'reviewer', 'acceptedRequest', 'inCredits'],
[MapStatus.CONTENT_APPROVAL]: ['admin', 'moderator', 'submitter', 'reviewer', 'acceptedRequest', 'inCredits'],
[MapStatus.FINAL_APPROVAL]: 'any',
[MapStatus.DISABLED]: ['admin', 'moderator']
};
Expand Down Expand Up @@ -206,4 +212,41 @@ describe('MapsService', () => {
});
}
});

describe('submitMap', () => {
it('should throw ConflictException if map with the same bspHash already exists', async () => {
const dto = {} as CreateMapDto;
const userID = 1;
const bspHash = 'existingHash';
const bspFile = { buffer: Buffer.from('dummy data') } as any;

jest.spyOn(service, 'checkCreateDto').mockResolvedValueOnce(undefined);
jest.spyOn(service, 'getBspFromTemp').mockResolvedValueOnce(bspFile);
jest
.spyOn(service, 'checkMapCompression')
.mockResolvedValueOnce(undefined);
jest.spyOn(service, 'checkMapFiles').mockImplementationOnce(() => {});
jest
.spyOn(service, 'checkSuggestionsAndZones')
.mockImplementationOnce(() => {});
jest
.spyOn(FileStoreService, 'getHashForBuffer')
.mockReturnValueOnce(bspHash);

db.mMap.findFirst.mockResolvedValueOnce({
id: 123,
name: '123',
status: 123,
images: [],
submitterID: 123,
currentVersionID: '123',
createdAt: new Date(),
updatedAt: new Date()
});

await expect(service.submitMap(dto, userID, [])).rejects.toThrow(
ConflictException
);
});
});
});
4 changes: 2 additions & 2 deletions apps/backend/src/app/modules/maps/maps.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ export class MapsService {
);
}

private async checkCreateDto(userID: number, dto: CreateMapDto) {
async checkCreateDto(userID: number, dto: CreateMapDto) {
const user = await this.db.user.findUnique({
where: { id: userID },
include: { submittedMaps: true }
Expand Down Expand Up @@ -970,7 +970,7 @@ export class MapsService {
});
}

private checkMapFiles(bspFile: File, vmfFiles: File[]) {
checkMapFiles(bspFile: File, vmfFiles: File[]) {
if (!bspFile.originalname.endsWith('.bsp'))
throw new BadRequestException('Bad BSP name');

Expand Down

0 comments on commit 4478d0f

Please sign in to comment.