Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalized Map Versioning #1032

Merged
merged 7 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Closes #<!--(issue number here)-->

### Checks

- [ ] __!! DONT IGNORE ME !! I have ran `nx run db:create-migration <name>` and committed the migration if I've made DB schema changes__
- [ ] I have included/updated tests where applicable (see [Testing](https://github.com/momentum-mod/website/wiki/Testing))
- [ ] I have ran `nx run db:create-migration` and committed the migration if I've made DB schema changes
- [ ] I have followed [semantic commit messages](https://gist.github.com/joshbuchea/6f47e86d2510bce28f8e7f42ae84c716) e.g. `feat: Add foo`, `chore: Update bar`, etc...
- [ ] My branch has a clear history of changes that can be easy to follow when being reviewed commit-by-commit
- [ ] My branch is functionally complete; the only changes to be done will be those potentially requested in code review
Expand Down
209 changes: 105 additions & 104 deletions apps/backend-e2e/src/admin.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -931,6 +931,7 @@ describe('Admin', () => {
describe('PATCH', () => {
const bspBuffer = readFileSync(path.join(FILES_PATH, 'map.bsp'));
const vmfBuffer = readFileSync(path.join(FILES_PATH, 'map.vmf'));
const bspHash = createSha1Hash(bspBuffer);

let mod,
modToken,
Expand All @@ -953,6 +954,26 @@ describe('Admin', () => {
createMapData = {
name: 'surf_map',
submitter: { connect: { id: u1.id } },
versions: {
createMany: {
data: [
{
versionNum: 1,
bspHash: createSha1Hash(
'apple banana cat dog elephant fox grape hat igloo joker'
),
zones: BabyZonesStub as unknown as JsonValue, // TODO: #855
submitterID: u1.id
},
{
versionNum: 2,
bspHash,
zones: BabyZonesStub as unknown as JsonValue, // TODO: #855
submitterID: u1.id
}
]
}
},
submission: {
create: {
type: MapSubmissionType.ORIGINAL,
Expand All @@ -970,16 +991,7 @@ describe('Admin', () => {
tier: 1,
type: LeaderboardType.IN_SUBMISSION
}
],
versions: {
create: {
versionNum: 1,
hash: createSha1Hash(
'apple banana cat dog elephant fox grape hat igloo joker'
),
zones: BabyZonesStub as unknown as JsonValue // TODO: #855
}
}
]
}
}
};
Expand Down Expand Up @@ -1177,6 +1189,8 @@ describe('Admin', () => {
`${MapStatus.CONTENT_APPROVAL},${MapStatus.FINAL_APPROVAL },${Role.ADMIN}`,
`${MapStatus.CONTENT_APPROVAL},${MapStatus.DISABLED },${Role.MODERATOR}`,
`${MapStatus.CONTENT_APPROVAL},${MapStatus.DISABLED },${Role.ADMIN}`,
`${MapStatus.PUBLIC_TESTING },${MapStatus.FINAL_APPROVAL },${Role.MODERATOR}`,
`${MapStatus.PUBLIC_TESTING },${MapStatus.FINAL_APPROVAL },${Role.ADMIN}`,
`${MapStatus.PUBLIC_TESTING },${MapStatus.CONTENT_APPROVAL},${Role.MODERATOR}`,
`${MapStatus.PUBLIC_TESTING },${MapStatus.CONTENT_APPROVAL},${Role.ADMIN}`,
`${MapStatus.PUBLIC_TESTING },${MapStatus.DISABLED },${Role.MODERATOR}`,
Expand Down Expand Up @@ -1211,30 +1225,26 @@ describe('Admin', () => {

const map = await db.createMap({
...createMapData,
submission: {
versions: {
create: {
...createMapData.submission.create,
versions: {
create: {
zones: BabyZonesStub,
versionNum: 1,
hash: createSha1Hash(bspBuffer)
}
}
zones: BabyZonesStub as unknown as JsonValue, // TODO: #855
versionNum: 1,
bspHash: createSha1Hash(bspBuffer),
submitterID: u1.id
}
},
status: s1
});

await prisma.mapSubmission.update({
where: { mapID: map.id },
data: { currentVersionID: map.submission.versions[0].id }
await prisma.mMap.update({
where: { id: map.id },
data: { currentVersionID: map.versions[0].id }
});

// Annoying to have to do this for every test but FA -> Approved
// will throw otherwise.
await fileStore.add(
`submissions/${map.submission.versions[0].id}.bsp`,
`submissions/${map.versions[0].id}.bsp`,
bspBuffer
);

Expand Down Expand Up @@ -1281,44 +1291,41 @@ describe('Admin', () => {

const map = await db.createMap({
...createMapData,
submission: {
versions: {
create: {
...createMapData.submission.create,
versions: {
create: {
zones: BabyZonesStub,
versionNum: 1,
hash: createSha1Hash(bspBuffer)
}
}
zones: BabyZonesStub as unknown as JsonValue, // TODO: #855
versionNum: 1,
bspHash: createSha1Hash(bspBuffer),
submitterID: u1.id
}
},
status: MapStatus.DISABLED
});

await prisma.mapSubmission.update({
where: { mapID: map.id },
await prisma.mMap.update({
where: { id: map.id },
data: {
currentVersionID: map.submission.versions[0].id,
dates: [
{
status: MapStatus.APPROVED,
date: new Date(Date.now() - 2000)
},
{
status: MapStatus.DISABLED,
date: new Date(Date.now() - 1000)
currentVersionID: map.versions[0].id,
submission: {
update: {
dates: [
{
status: MapStatus.APPROVED,
date: new Date(Date.now() - 2000)
},
{
status: MapStatus.DISABLED,
date: new Date(Date.now() - 1000)
}
]
}
]
}
}
});

// Annoying to have to do this for every test but FA -> Approved
// will throw otherwise.
await fileStore.add(
`submissions/${map.submission.versions[0].id}.bsp`,
bspBuffer
);
await fileStore.add(`submissions/${map.versions[0].id}.bsp`, bspBuffer);

await req.patch({
url: `admin/maps/${map.id}`,
Expand Down Expand Up @@ -1349,16 +1356,17 @@ describe('Admin', () => {

const map = await db.createMap({
...createMapData,
versions: {
create: {
versionNum: 1,
bspHash: createSha1Hash(bspBuffer),
zones: BabyZonesStub as unknown as JsonValue, // TODO: #855
submitterID: u1.id
}
},
submission: {
create: {
...createMapData.submission.create,
versions: {
create: {
versionNum: 1,
hash: createSha1Hash(bspBuffer),
zones: BabyZonesStub
}
},
placeholders: [
{
type: MapCreditType.CONTRIBUTOR,
Expand All @@ -1371,15 +1379,12 @@ describe('Admin', () => {
status: MapStatus.FINAL_APPROVAL
});

await prisma.mapSubmission.update({
where: { mapID: map.id },
data: { currentVersionID: map.submission.versions[0].id }
await prisma.mMap.update({
where: { id: map.id },
data: { currentVersionID: map.versions[0].id }
});

await fileStore.add(
`submissions/${map.submission.versions[0].id}.bsp`,
bspBuffer
);
await fileStore.add(`submissions/${map.versions[0].id}.bsp`, bspBuffer);

await req.patch({
url: `admin/maps/${map.id}`,
Expand Down Expand Up @@ -1444,34 +1449,36 @@ describe('Admin', () => {
beforeEach(async () => {
map = await db.createMap({
...createMapData,
submission: {
create: {
...createMapData.submission.create,
versions: {
create: {
versions: {
createMany: {
data: [
{
versionNum: 1,
hash: createSha1Hash(bspBuffer),
zones: ZonesStub,
hasVmf: true
bspHash,
zones: ZonesStub as any,
hasVmf: true,
submitterID: u1.id
},
{
versionNum: 2,
bspHash,
zones: ZonesStub as any,
hasVmf: true,
submitterID: u1.id
}
}
]
}
},
status: MapStatus.FINAL_APPROVAL
});

const vmfZip = new Zip();
vmfZip.addFile('map.vmf', vmfBuffer);

await fileStore.add(
`submissions/${map.submission.versions[0].id}_VMFs.zip`,
vmfZip.toBuffer()
);

await fileStore.add(
`submissions/${map.submission.versions[0].id}.bsp`,
bspBuffer
);
for (const i of [0, 1]) {
const id = map.versions[i].id;
await fileStore.add(`maps/${id}_VMFs.zip`, vmfZip.toBuffer());
await fileStore.add(`maps/${id}.bsp`, bspBuffer);
}

await prisma.leaderboard.createMany({
data: ZonesStubLeaderboards.map((lb) => ({
Expand All @@ -1483,7 +1490,7 @@ describe('Admin', () => {
});
});

it('should copy latest submission version files to maps/ after map status changed from FA to approved', async () => {
it('should delete old version files after map status changed from FA to approved', async () => {
const bspHash = createSha1Hash(bspBuffer);
const vmfHash = createSha1Hash(vmfBuffer);

Expand All @@ -1495,33 +1502,26 @@ describe('Admin', () => {
});

const updatedMap = await prisma.mMap.findUnique({
where: { id: map.id }
where: { id: map.id },
include: { currentVersion: true, versions: true }
});

expect(updatedMap).toMatchObject({
status: MapStatus.APPROVED,
hash: bspHash,
hasVmf: true
currentVersion: { bspHash, versionNum: 2 }
});

expect(
await fileStore.exists(
`submissions/${map.submission.versions[0].id}.bsp`
)
).toBeFalsy();
expect(
await fileStore.exists(
`submissions/${map.submission.versions[0].id}_VMFs.zip`
)
).toBeFalsy();

expect(
createSha1Hash(await fileStore.get(`maps/${map.name}.bsp`))
).toBe(bspHash);
const id1 = map.versions[0].id;
const id2 = map.versions[1].id;
expect(await fileStore.exists(`maps/${id1}.bsp`)).toBeFalsy();
expect(await fileStore.exists(`maps/${id1}_VMFs.zip`)).toBeFalsy();

expect(createSha1Hash(await fileStore.get(`maps/${id2}.bsp`))).toBe(
bspHash
);
expect(
createSha1Hash(
new Zip(await fileStore.get(`maps/${map.name}_VMFs.zip`))
new Zip(await fileStore.get(`maps/${id2}_VMFs.zip`))
.getEntry('map.vmf')
.getData()
)
Expand Down Expand Up @@ -1925,12 +1925,13 @@ describe('Admin', () => {
token: adminToken
});

const updated = await prisma.mMap.findFirst({ where: { id: map.id } });
expect(updated).toMatchObject({
status: MapStatus.DISABLED,
hash: null
const updated = await prisma.mMap.findFirst({
where: { id: map.id },
include: { versions: true }
});

expect(updated.status).toBe(MapStatus.DISABLED);
expect(updated.versions.at(-1).bspHash).toBeNull();
expect(await fileStore.exists(`maps/${fileName}.bsp`)).toBeFalsy();

// We used to delete these, check we don't anymore
Expand Down
11 changes: 10 additions & 1 deletion apps/backend-e2e/src/maps-2.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import {
import { MapListVersionDto } from '../../backend/src/app/dto/map/map-list-version.dto';
import path from 'node:path';
import { LeaderboardStatsDto } from '../../backend/src/app/dto/run/leaderboard-stats.dto';
import { JsonValue } from 'type-fest';

describe('Maps Part 2', () => {
let app,
Expand Down Expand Up @@ -759,7 +760,15 @@ describe('Maps Part 2', () => {
async () =>
([token, map] = await Promise.all([
db.loginNewUser(),
db.createMap({ zones: ZonesStub })
db.createMap({
versions: {
create: {
zones: ZonesStub as unknown as JsonValue, // TODO: #855
versionNum: 1,
submitter: db.getNewUserCreateData()
}
}
})
]))
);

Expand Down
Loading
Loading