mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-06 13:58:05 +03:00
beatoraja submit-course tests
This commit is contained in:
@@ -178,7 +178,7 @@ t.test("#KtchiPBScoreToBeatorajaFormat", (t) => {
|
||||
await db.scores.remove({ scoreID: "mock_lampPB" });
|
||||
|
||||
t.rejects(() => KtchiPBScoreToBeatorajaFormat(pbScore, gazerChart, 2), {
|
||||
message: /User's PB on.*has no lampPB/u,
|
||||
message: /User 1's PB on.*has no lampPB/u,
|
||||
} as any);
|
||||
|
||||
t.end();
|
||||
|
||||
@@ -199,4 +199,277 @@ t.test("POST /ir/beatoraja/submit-score", (t) => {
|
||||
t.end();
|
||||
});
|
||||
|
||||
const courseScore = {
|
||||
course: {
|
||||
name: "GENOSIDE 2018 段位認定 発狂皆伝",
|
||||
charts: [
|
||||
{
|
||||
md5: "cfad3baadce9e02c45021963453d7c94",
|
||||
},
|
||||
{
|
||||
md5: "77d23be22b2370925c573d922276bce0",
|
||||
},
|
||||
{
|
||||
md5: "188a99f74ab71804f2e360dcf484545c",
|
||||
},
|
||||
{
|
||||
md5: "c46a81cb184f5a804c119930d6eba748",
|
||||
},
|
||||
],
|
||||
constraint: ["MIRROR", "GAUGE_LR2", "LN"],
|
||||
trophy: [{}, {}],
|
||||
lntype: 0,
|
||||
},
|
||||
score: {
|
||||
sha256: "",
|
||||
lntype: 0,
|
||||
player: "unknown",
|
||||
clear: "Clear",
|
||||
date: 0,
|
||||
epg: 1334,
|
||||
lpg: 788,
|
||||
egr: 1634,
|
||||
lgr: 382,
|
||||
egd: 239,
|
||||
lgd: 142,
|
||||
ebd: 34,
|
||||
lbd: 8,
|
||||
epr: 0,
|
||||
lpr: 93,
|
||||
ems: 63,
|
||||
lms: 74,
|
||||
maxcombo: 225,
|
||||
notes: 6005,
|
||||
passnotes: 4654,
|
||||
minbp: 1623,
|
||||
option: 0,
|
||||
assist: 0,
|
||||
gauge: 0,
|
||||
deviceType: "BM_CONTROLLER",
|
||||
judgeAlgorithm: "Combo",
|
||||
rule: "Beatoraja_7",
|
||||
exscore: 6260,
|
||||
},
|
||||
};
|
||||
|
||||
t.test("POST /ir/beatoraja/submit-course", (t) => {
|
||||
t.beforeEach(ResetDBState);
|
||||
|
||||
t.test("Should accept a valid clear", async (t) => {
|
||||
const res = await mockApi
|
||||
.post("/ir/beatoraja/submit-course")
|
||||
.set("X-KtchiIR-Version", "2.0.0")
|
||||
.set("Authorization", "Bearer token")
|
||||
.send(courseScore);
|
||||
|
||||
t.equal(res.status, 200);
|
||||
t.equal(res.body.success, true);
|
||||
t.equal(res.body.description, "Successfully updated class.");
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test("Should silently reject a fail", async (t) => {
|
||||
const res = await mockApi
|
||||
.post("/ir/beatoraja/submit-course")
|
||||
.set("X-KtchiIR-Version", "2.0.0")
|
||||
.set("Authorization", "Bearer token")
|
||||
.send(deepmerge(courseScore, { score: { clear: "Failed" } }));
|
||||
|
||||
t.equal(res.status, 200);
|
||||
t.equal(res.body.success, true);
|
||||
t.equal(res.body.description, "Class not updated.");
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test("Should reject scores with no charts", async (t) => {
|
||||
const res = await mockApi
|
||||
.post("/ir/beatoraja/submit-course")
|
||||
.set("X-KtchiIR-Version", "2.0.0")
|
||||
.set("Authorization", "Bearer token")
|
||||
.send(deepmerge(courseScore, { course: { charts: [] } }, { arrayMerge: (d, s) => s }));
|
||||
|
||||
t.equal(res.status, 400);
|
||||
t.equal(res.body.success, false);
|
||||
t.equal(res.body.description, "Invalid Course Submission.");
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test("Should reject scores with invalid chart documents", async (t) => {
|
||||
const res = await mockApi
|
||||
.post("/ir/beatoraja/submit-course")
|
||||
.set("X-KtchiIR-Version", "2.0.0")
|
||||
.set("Authorization", "Bearer token")
|
||||
.send(deepmerge(courseScore, { course: { charts: [1, 2, 3, 4] } }));
|
||||
|
||||
t.equal(res.status, 400);
|
||||
t.equal(res.body.success, false);
|
||||
t.equal(res.body.description, "Invalid Course Submission.");
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test("Should reject scores with too many chart documents", async (t) => {
|
||||
const res = await mockApi
|
||||
.post("/ir/beatoraja/submit-course")
|
||||
.set("X-KtchiIR-Version", "2.0.0")
|
||||
.set("Authorization", "Bearer token")
|
||||
.send(
|
||||
deepmerge(courseScore, {
|
||||
course: { charts: [{ md5: "a" }, { md5: "a" }, { md5: "a" }, { md5: "a" }] },
|
||||
})
|
||||
);
|
||||
|
||||
t.equal(res.status, 400);
|
||||
t.equal(res.body.success, false);
|
||||
t.equal(res.body.description, "Invalid Course Submission.");
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test("Should reject scores not on LN mode", async (t) => {
|
||||
const res = await mockApi
|
||||
.post("/ir/beatoraja/submit-course")
|
||||
.set("X-KtchiIR-Version", "2.0.0")
|
||||
.set("Authorization", "Bearer token")
|
||||
.send(
|
||||
deepmerge(courseScore, {
|
||||
score: {
|
||||
lntype: 1,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
t.equal(res.status, 400);
|
||||
t.equal(res.body.success, false);
|
||||
t.equal(res.body.description, "LN mode is the only supported mode for dans.");
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test("Should reject too few constraints", async (t) => {
|
||||
const res = await mockApi
|
||||
.post("/ir/beatoraja/submit-course")
|
||||
.set("X-KtchiIR-Version", "2.0.0")
|
||||
.set("Authorization", "Bearer token")
|
||||
.send(
|
||||
deepmerge(
|
||||
courseScore,
|
||||
{
|
||||
course: {
|
||||
constraint: ["GAUGE_LR2"],
|
||||
},
|
||||
},
|
||||
{ arrayMerge: (d, s) => s }
|
||||
)
|
||||
);
|
||||
|
||||
t.equal(res.status, 400);
|
||||
t.equal(res.body.success, false);
|
||||
t.equal(res.body.description, "Invalid Constraints.");
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test("Should reject non-array constraints", async (t) => {
|
||||
const res = await mockApi
|
||||
.post("/ir/beatoraja/submit-course")
|
||||
.set("X-KtchiIR-Version", "2.0.0")
|
||||
.set("Authorization", "Bearer token")
|
||||
.send(
|
||||
deepmerge(
|
||||
courseScore,
|
||||
{
|
||||
course: {
|
||||
constraint: "foo",
|
||||
},
|
||||
},
|
||||
{ arrayMerge: (d, s) => s }
|
||||
)
|
||||
);
|
||||
|
||||
t.equal(res.status, 400);
|
||||
t.equal(res.body.success, false);
|
||||
t.equal(res.body.description, "Invalid Constraints.");
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test("Should reject too many constraints", async (t) => {
|
||||
const res = await mockApi
|
||||
.post("/ir/beatoraja/submit-course")
|
||||
.set("X-KtchiIR-Version", "2.0.0")
|
||||
.set("Authorization", "Bearer token")
|
||||
.send(
|
||||
deepmerge(
|
||||
courseScore,
|
||||
{
|
||||
course: {
|
||||
constraint: ["a", "b", "c", "d"],
|
||||
},
|
||||
},
|
||||
{ arrayMerge: (d, s) => s }
|
||||
)
|
||||
);
|
||||
|
||||
t.equal(res.status, 400);
|
||||
t.equal(res.body.success, false);
|
||||
t.equal(res.body.description, "Invalid Constraints.");
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test("Should reject invalid constraints", async (t) => {
|
||||
const res = await mockApi
|
||||
.post("/ir/beatoraja/submit-course")
|
||||
.set("X-KtchiIR-Version", "2.0.0")
|
||||
.set("Authorization", "Bearer token")
|
||||
.send(
|
||||
deepmerge(
|
||||
courseScore,
|
||||
{
|
||||
course: {
|
||||
constraint: ["foo", "bar"],
|
||||
},
|
||||
},
|
||||
{ arrayMerge: (d, s) => s }
|
||||
)
|
||||
);
|
||||
|
||||
t.equal(res.status, 400);
|
||||
t.equal(res.body.success, false);
|
||||
t.equal(res.body.description, "Invalid Constraints.");
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test("Should reject invalid constraints for 3", async (t) => {
|
||||
const res = await mockApi
|
||||
.post("/ir/beatoraja/submit-course")
|
||||
.set("X-KtchiIR-Version", "2.0.0")
|
||||
.set("Authorization", "Bearer token")
|
||||
.send(
|
||||
deepmerge(
|
||||
courseScore,
|
||||
{
|
||||
course: {
|
||||
constraint: ["GAUGE_LR2", "MIRROR", "CHEAT_MODE"],
|
||||
},
|
||||
},
|
||||
{ arrayMerge: (d, s) => s }
|
||||
)
|
||||
);
|
||||
|
||||
t.equal(res.status, 400);
|
||||
t.equal(res.body.success, false);
|
||||
t.equal(res.body.description, "Invalid Constraints.");
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.teardown(CloseAllConnections);
|
||||
|
||||
@@ -141,7 +141,12 @@ router.post("/submit-score", async (req, res) => {
|
||||
router.post("/submit-course", async (req, res) => {
|
||||
const charts = req.body.course?.charts;
|
||||
|
||||
if (!charts || !Array.isArray(charts) || charts.length !== 4) {
|
||||
if (
|
||||
!charts ||
|
||||
!Array.isArray(charts) ||
|
||||
charts.length !== 4 ||
|
||||
!charts.every((e) => e && typeof e === "object" && typeof e.md5 === "string")
|
||||
) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
description: `Invalid Course Submission.`,
|
||||
@@ -166,8 +171,8 @@ router.post("/submit-course", async (req, res) => {
|
||||
|
||||
// Constraints are a bit complicated.
|
||||
// We only want to accept dans with the following
|
||||
// beatoraja constraints - ["MIRROR","LR2_GAUGE"] or
|
||||
// ["MIRROR", "LR2_GAUGE", "LN"].
|
||||
// beatoraja constraints - ["MIRROR","GAUGE_LR2"] or
|
||||
// ["MIRROR", "GAUGE_LR2", "LN"].
|
||||
const constraint = req.body.course.constraint;
|
||||
|
||||
if (
|
||||
@@ -177,16 +182,16 @@ router.post("/submit-course", async (req, res) => {
|
||||
) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
description: `Invalid constraints.`,
|
||||
description: `Invalid Constraints.`,
|
||||
});
|
||||
}
|
||||
|
||||
// If there are two constraints, check that they are
|
||||
// MIRROR and LR2_GAUGE.
|
||||
if (!constraint.includes("MIRROR") || !constraint.includes("LR2_GAUGE")) {
|
||||
// MIRROR and GAUGE_LR2.
|
||||
if (!constraint.includes("MIRROR") || !constraint.includes("GAUGE_LR2")) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
description: `Invalid constraints.`,
|
||||
description: `Invalid Constraints.`,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -202,7 +207,7 @@ router.post("/submit-course", async (req, res) => {
|
||||
}
|
||||
|
||||
// Combine the md5s into one string in their order.
|
||||
const combinedMD5s = charts.map((e) => e.md5).join();
|
||||
const combinedMD5s = charts.map((e) => e.md5).join("");
|
||||
|
||||
const course = await db["bms-course-lookup"].findOne({
|
||||
md5sums: combinedMD5s,
|
||||
@@ -225,10 +230,10 @@ router.post("/submit-course", async (req, res) => {
|
||||
course.value
|
||||
);
|
||||
|
||||
if (result) {
|
||||
if (result === false) {
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
description: "Successfully updated class.",
|
||||
description: "Class not updated.",
|
||||
body: {
|
||||
set: course.set,
|
||||
value: course.value,
|
||||
@@ -238,7 +243,7 @@ router.post("/submit-course", async (req, res) => {
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
description: "Class not updated.",
|
||||
description: "Successfully updated class.",
|
||||
body: {
|
||||
set: course.set,
|
||||
value: course.value,
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
[
|
||||
{
|
||||
"title": "GENOSIDE 2018 段位認定 Overjoy",
|
||||
"md5sums": "cfad3baadce9e02c45021963453d7c9477d23be22b2370925c573d922276bce0188a99f74ab71804f2e360dcf484545cc46a81cb184f5a804c119930d6eba748",
|
||||
"set": "genocideDan",
|
||||
"playtype": "7K",
|
||||
"value": 22
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user