forked from monkeytypegame/monkeytype
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'monkeytypegame:master' into master
- Loading branch information
Showing
78 changed files
with
1,232 additions
and
562 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import request from "supertest"; | ||
import app from "../../../src/app"; | ||
import * as PsaDal from "../../../src/dal/psa"; | ||
import * as Prometheus from "../../../src/utils/prometheus"; | ||
import { ObjectId } from "mongodb"; | ||
const mockApp = request(app); | ||
|
||
describe("Psa Controller", () => { | ||
describe("get psa", () => { | ||
const getPsaMock = vi.spyOn(PsaDal, "get"); | ||
const recordClientVersionMock = vi.spyOn(Prometheus, "recordClientVersion"); | ||
|
||
afterEach(() => { | ||
getPsaMock.mockReset(); | ||
recordClientVersionMock.mockReset(); | ||
}); | ||
|
||
it("get psas without authorization", async () => { | ||
//GIVEN | ||
const psaOne: PsaDal.DBPSA = { | ||
_id: new ObjectId(), | ||
message: "test2", | ||
date: 1000, | ||
level: 1, | ||
sticky: true, | ||
}; | ||
const psaTwo: PsaDal.DBPSA = { | ||
_id: new ObjectId(), | ||
message: "test2", | ||
date: 2000, | ||
level: 2, | ||
sticky: false, | ||
}; | ||
getPsaMock.mockResolvedValue([psaOne, psaTwo]); | ||
|
||
//WHEN | ||
const { body } = await mockApp.get("/psas").expect(200); | ||
|
||
//THEN | ||
expect(body).toEqual({ | ||
message: "PSAs retrieved", | ||
data: [ | ||
{ | ||
_id: psaOne._id.toHexString(), | ||
date: 1000, | ||
level: 1, | ||
message: "test2", | ||
sticky: true, | ||
}, | ||
{ | ||
_id: psaTwo._id.toHexString(), | ||
date: 2000, | ||
level: 2, | ||
message: "test2", | ||
sticky: false, | ||
}, | ||
], | ||
}); | ||
|
||
expect(recordClientVersionMock).toHaveBeenCalledWith("unknown"); | ||
}); | ||
it("get psas with authorization", async () => { | ||
await mockApp | ||
.get("/psas") | ||
.set("authorization", `Uid 123456789`) | ||
.expect(200); | ||
}); | ||
|
||
it("get psas records x-client-version", async () => { | ||
await mockApp.get("/psas").set("x-client-version", "1.0").expect(200); | ||
|
||
expect(recordClientVersionMock).toHaveBeenCalledWith("1.0"); | ||
}); | ||
it("get psas records client-version", async () => { | ||
await mockApp.get("/psas").set("client-version", "2.0").expect(200); | ||
|
||
expect(recordClientVersionMock).toHaveBeenCalledWith("2.0"); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import request from "supertest"; | ||
import app from "../../../src/app"; | ||
import * as PublicDal from "../../../src/dal/public"; | ||
const mockApp = request(app); | ||
|
||
describe("PublicController", () => { | ||
describe("get speed histogram", () => { | ||
const getSpeedHistogramMock = vi.spyOn(PublicDal, "getSpeedHistogram"); | ||
|
||
afterEach(() => { | ||
getSpeedHistogramMock.mockReset(); | ||
}); | ||
|
||
it("gets for english time 60", async () => { | ||
//GIVEN | ||
getSpeedHistogramMock.mockResolvedValue({ "0": 1, "10": 2 }); | ||
|
||
//WHEN | ||
const { body } = await mockApp | ||
.get("/public/speedHistogram") | ||
.query({ language: "english", mode: "time", mode2: "60" }); | ||
//.expect(200); | ||
console.log(body); | ||
|
||
//THEN | ||
expect(body).toEqual({ | ||
message: "Public speed histogram retrieved", | ||
data: { "0": 1, "10": 2 }, | ||
}); | ||
|
||
expect(getSpeedHistogramMock).toHaveBeenCalledWith( | ||
"english", | ||
"time", | ||
"60" | ||
); | ||
}); | ||
|
||
it("gets for mode", async () => { | ||
for (const mode of ["time", "words", "quote", "zen", "custom"]) { | ||
const response = await mockApp | ||
.get("/public/speedHistogram") | ||
.query({ language: "english", mode, mode2: "custom" }); | ||
expect(response.status, "for mode " + mode).toEqual(200); | ||
} | ||
}); | ||
|
||
it("gets for mode2", async () => { | ||
for (const mode2 of [ | ||
"10", | ||
"25", | ||
"50", | ||
"100", | ||
"15", | ||
"30", | ||
"60", | ||
"120", | ||
"zen", | ||
"custom", | ||
]) { | ||
const response = await mockApp | ||
.get("/public/speedHistogram") | ||
.query({ language: "english", mode: "words", mode2 }); | ||
|
||
expect(response.status, "for mode2 " + mode2).toEqual(200); | ||
} | ||
}); | ||
it("fails for missing query", async () => { | ||
const { body } = await mockApp.get("/public/speedHistogram").expect(422); | ||
|
||
expect(body).toEqual({ | ||
message: "Invalid query schema", | ||
validationErrors: [ | ||
'"language" Required', | ||
'"mode" Required', | ||
'"mode2" Needs to be either a number, "zen" or "custom."', | ||
], | ||
}); | ||
}); | ||
it("fails for invalid query", async () => { | ||
const { body } = await mockApp | ||
.get("/public/speedHistogram") | ||
.query({ | ||
language: "en?gli.sh", | ||
mode: "unknownMode", | ||
mode2: "unknownMode2", | ||
}) | ||
.expect(422); | ||
|
||
expect(body).toEqual({ | ||
message: "Invalid query schema", | ||
validationErrors: [ | ||
'"language" Invalid', | ||
`"mode" Invalid enum value. Expected 'time' | 'words' | 'quote' | 'custom' | 'zen', received 'unknownMode'`, | ||
'"mode2" Needs to be either a number, "zen" or "custom."', | ||
], | ||
}); | ||
}); | ||
it("fails for unknown query", async () => { | ||
const { body } = await mockApp | ||
.get("/public/speedHistogram") | ||
.query({ | ||
language: "english", | ||
mode: "time", | ||
mode2: "60", | ||
extra: "value", | ||
}) | ||
.expect(422); | ||
|
||
expect(body).toEqual({ | ||
message: "Invalid query schema", | ||
validationErrors: ["Unrecognized key(s) in object: 'extra'"], | ||
}); | ||
}); | ||
}); | ||
describe("get typing stats", () => { | ||
const getTypingStatsMock = vi.spyOn(PublicDal, "getTypingStats"); | ||
|
||
afterEach(() => { | ||
getTypingStatsMock.mockReset(); | ||
}); | ||
|
||
it("gets without authentication", async () => { | ||
//GIVEN | ||
getTypingStatsMock.mockResolvedValue({ | ||
testsCompleted: 23, | ||
testsStarted: 42, | ||
timeTyping: 1000, | ||
} as any); | ||
|
||
//WHEN | ||
const { body } = await mockApp.get("/public/typingStats").expect(200); | ||
|
||
//THEN | ||
expect(body).toEqual({ | ||
message: "Public typing stats retrieved", | ||
data: { | ||
testsCompleted: 23, | ||
testsStarted: 42, | ||
timeTyping: 1000, | ||
}, | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,11 @@ | ||
import { GetPsaResponse } from "@monkeytype/contracts/psas"; | ||
import * as PsaDAL from "../../dal/psa"; | ||
import { MonkeyResponse } from "../../utils/monkey-response"; | ||
import { MonkeyResponse2 } from "../../utils/monkey-response"; | ||
import { replaceObjectIds } from "../../utils/misc"; | ||
|
||
export async function getPsas(): Promise<MonkeyResponse> { | ||
export async function getPsas( | ||
_req: MonkeyTypes.Request2 | ||
): Promise<GetPsaResponse> { | ||
const data = await PsaDAL.get(); | ||
return new MonkeyResponse("PSAs retrieved", data); | ||
return new MonkeyResponse2("PSAs retrieved", replaceObjectIds(data)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,22 @@ | ||
import { | ||
GetSpeedHistogramQuery, | ||
GetSpeedHistogramResponse, | ||
GetTypingStatsResponse, | ||
} from "@monkeytype/contracts/public"; | ||
import * as PublicDAL from "../../dal/public"; | ||
import { MonkeyResponse } from "../../utils/monkey-response"; | ||
import { MonkeyResponse2 } from "../../utils/monkey-response"; | ||
|
||
export async function getPublicSpeedHistogram( | ||
req: MonkeyTypes.Request | ||
): Promise<MonkeyResponse> { | ||
export async function getSpeedHistogram( | ||
req: MonkeyTypes.Request2<GetSpeedHistogramQuery> | ||
): Promise<GetSpeedHistogramResponse> { | ||
const { language, mode, mode2 } = req.query; | ||
const data = await PublicDAL.getSpeedHistogram( | ||
language as string, | ||
mode as string, | ||
mode2 as string | ||
); | ||
return new MonkeyResponse("Public speed histogram retrieved", data); | ||
const data = await PublicDAL.getSpeedHistogram(language, mode, mode2); | ||
return new MonkeyResponse2("Public speed histogram retrieved", data); | ||
} | ||
|
||
export async function getPublicTypingStats( | ||
_req: MonkeyTypes.Request | ||
): Promise<MonkeyResponse> { | ||
export async function getTypingStats( | ||
_req: MonkeyTypes.Request2 | ||
): Promise<GetTypingStatsResponse> { | ||
const data = await PublicDAL.getTypingStats(); | ||
return new MonkeyResponse("Public typing stats retrieved", data); | ||
return new MonkeyResponse2("Public typing stats retrieved", data); | ||
} |
Oops, something went wrong.