Skip to content
This repository has been archived by the owner on Mar 23, 2022. It is now read-only.

Commit

Permalink
Merge pull request #29 from RaenonX-DL/dev
Browse files Browse the repository at this point in the history
v2.15.0 Release
  • Loading branch information
RaenonX authored Oct 4, 2021
2 parents 1ce8daa + abc5e65 commit 8ce5476
Show file tree
Hide file tree
Showing 22 changed files with 228 additions and 23 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"author": "RaenonX",
"name": "dragalia-site-back-2",
"description": "Renewed backend for Dragalia Lost info website by OM.",
"version": "2.15.0-beta.1",
"version": "2.15.0",
"engines": {
"node": "14.x",
"npm": "^7.12.0"
Expand Down
4 changes: 3 additions & 1 deletion src/base/model/seq.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ export class SequentialDocument extends Document {
throw new SeqIdSkippingError(seqId, latestSeqId + 1);
}

updateOps = {$set: {[SequenceCounterKeys.counter]: seqId}};
// Use `$max` instead of `$set` so that the sequential counter is updated
// only if the new ID is the newest
updateOps = {$max: {[SequenceCounterKeys.counter]: seqId}};
} else {
updateOps = {$inc: {[SequenceCounterKeys.counter]: increase ? 1 : 0}};
}
Expand Down
2 changes: 1 addition & 1 deletion src/endpoints/data/keyPoint/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class KeyPointInfoResponse extends ApiResponse {
info: KeyPointInfo;

/**
* Construct an unit name update endpoint API response.
* Construct a unit name update endpoint API response.
*
* @param {KeyPointInfoResponseOptions} options options to construct the response
*/
Expand Down
2 changes: 1 addition & 1 deletion src/endpoints/data/unitNameRef/get/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class UnitNameRefResponse extends ApiResponse {
data: UnitNameRefData;

/**
* Construct an unit name reference endpoint API response.
* Construct a unit name reference endpoint API response.
*
* @param {UnitNameRefResponseOptions} options options to construct the response
*/
Expand Down
4 changes: 2 additions & 2 deletions src/endpoints/data/unitNameRef/manage/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ export class UnitNameRefManageResponse extends ApiResponse {
refs: Array<UnitNameRefEntry>;

/**
* Construct an unit name managing endpoint API response.
* Construct a unit name managing endpoint API response.
*
* @param {UnitNameRefManageResponseOptions} options options to construct an unit name ref response
* @param {UnitNameRefManageResponseOptions} options options to construct a unit name ref response
*/
constructor(options: UnitNameRefManageResponseOptions) {
const responseCode = ApiResponseCode.SUCCESS;
Expand Down
4 changes: 2 additions & 2 deletions src/endpoints/data/unitNameRef/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ export class UnitNameRefEntry extends Document {
unitId: number;

/**
* Construct an unit name reference entry
* Construct a unit name reference entry
*
* @param {UnitNameRefEntryConstructParams} params parameters to construct an unit name ref entry
* @param {UnitNameRefEntryConstructParams} params parameters to construct a unit name ref entry
*/
constructor(params: UnitNameRefEntryConstructParams) {
super(params);
Expand Down
2 changes: 1 addition & 1 deletion src/endpoints/data/unitNameRef/update/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {ApiResponse} from '../../../../base/response';
*/
export class UnitNameRefUpdateResponse extends ApiResponse {
/**
* Construct an unit name update endpoint API response.
* Construct a unit name update endpoint API response.
*/
constructor() {
super(ApiResponseCode.SUCCESS);
Expand Down
2 changes: 2 additions & 0 deletions src/endpoints/lookup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {handleRoot} from './root/handler';
import {handleEmitError} from './test/handler';
import {handleTierNoteEdit} from './tier/notes/edit/handler';
import {handleTierNoteGet} from './tier/notes/get/handler';
import {handleTierNoteSingle} from './tier/notes/single/handler';
import {handleTierNoteUpdate} from './tier/notes/update/handler';
import {handleTierPointsGet} from './tier/points/get/handler';
import {handleTierPointsManage} from './tier/points/manage/handler';
Expand Down Expand Up @@ -86,6 +87,7 @@ export const handlerLookup: {[endpoint: string]: EndpointHandlers} = {
[ApiEndPoints.POST_ANALYSIS_EDIT_DRAGON]: {POST: handleEditDragonAnalysis},
[ApiEndPoints.POST_ANALYSIS_ID_CHECK]: {GET: handleAnalysisIdCheck},
[ApiEndPoints.TIER_NOTES]: {GET: handleTierNoteGet},
[ApiEndPoints.TIER_UNIT]: {GET: handleTierNoteSingle},
[ApiEndPoints.TIER_KEY_POINTS]: {GET: handleTierPointsGet},
[ApiEndPoints.DATA_UNIT_NAME_REF]: {GET: handleDataUnitNameRef},
[ApiEndPoints.DATA_KEY_POINT]: {GET: handleGetKeyPointData},
Expand Down
4 changes: 2 additions & 2 deletions src/endpoints/post/analysis/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class UnhandledUnitTypeError extends CustomError {
*/
export class UnitNotExistsError extends CustomError {
/**
* Construct an unit not exists error.
* Construct a unit not exists error.
*
* @param {number} unitId non-existent unit ID
*/
Expand All @@ -35,7 +35,7 @@ export class UnitNotExistsError extends CustomError {
*/
export class UnitTypeMismatchError extends CustomError {
/**
* Construct an unit type mismatch error.
* Construct a unit type mismatch error.
*
* @param {number} unitId unit ID that causes the error
* @param {UnitType} expectedType expected unit type
Expand Down
22 changes: 22 additions & 0 deletions src/endpoints/post/misc/controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,4 +427,26 @@ describe('Misc post controller', () => {

expect(availability).toBe(false);
});

it('returns correct ID check result across languages', async () => {
await MiscPostController.publishPost(app.mongoClient, {...payload, seqId: 1, lang: SupportedLanguages.CHT});
await MiscPostController.publishPost(app.mongoClient, {...payload, seqId: 2, lang: SupportedLanguages.CHT});
await MiscPostController.publishPost(app.mongoClient, {...payload, seqId: 1, lang: SupportedLanguages.EN});

const available = await MiscPostController.isPostIdAvailable(app.mongoClient, SupportedLanguages.CHT, 3);

expect(available).toBeTruthy();
});

it('publishes in correct ID order', async () => {
await MiscPostController.publishPost(app.mongoClient, {...payload, seqId: 1, lang: SupportedLanguages.CHT});
await MiscPostController.publishPost(app.mongoClient, {...payload, seqId: 2, lang: SupportedLanguages.CHT});
await MiscPostController.publishPost(app.mongoClient, {...payload, seqId: 1, lang: SupportedLanguages.EN});

const newPostId = await MiscPostController.publishPost(
app.mongoClient, {...payload, lang: SupportedLanguages.CHT},
);

expect(newPostId).toBe(3);
});
});
25 changes: 24 additions & 1 deletion src/endpoints/post/quest/controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {SeqIdSkippingError} from '../error';
import {QuestPostController} from './controller';
import {QuestPost, QuestPostDocument} from './model';

describe(`[Controller] ${QuestPostController.name}`, () => {

describe('Quest post controller', () => {
let app: Application;

beforeAll(async () => {
Expand Down Expand Up @@ -449,4 +450,26 @@ describe(`[Controller] ${QuestPostController.name}`, () => {

expect(availability).toBe(false);
});

it('returns correct ID check result across languages', async () => {
await QuestPostController.publishPost(app.mongoClient, {...payload, seqId: 1, lang: SupportedLanguages.CHT});
await QuestPostController.publishPost(app.mongoClient, {...payload, seqId: 2, lang: SupportedLanguages.CHT});
await QuestPostController.publishPost(app.mongoClient, {...payload, seqId: 1, lang: SupportedLanguages.EN});

const available = await QuestPostController.isPostIdAvailable(app.mongoClient, SupportedLanguages.CHT, 3);

expect(available).toBeTruthy();
});

it('publishes in correct ID order', async () => {
await QuestPostController.publishPost(app.mongoClient, {...payload, seqId: 1, lang: SupportedLanguages.CHT});
await QuestPostController.publishPost(app.mongoClient, {...payload, seqId: 2, lang: SupportedLanguages.CHT});
await QuestPostController.publishPost(app.mongoClient, {...payload, seqId: 1, lang: SupportedLanguages.EN});

const newPostId = await QuestPostController.publishPost(
app.mongoClient, {...payload, lang: SupportedLanguages.CHT},
);

expect(newPostId).toBe(3);
});
});
4 changes: 2 additions & 2 deletions src/endpoints/tier/notes/controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ describe('Tier note data controller', () => {

describe('getUnitTierNoteEdit()', () => {
it('returns `null` if no existing tier note available', async () => {
const data = await TierNoteController.getUnitTierNoteEdit(app.mongoClient, SupportedLanguages.CHT, 10950101);
const data = await TierNoteController.getUnitTierNoteSingle(app.mongoClient, SupportedLanguages.CHT, 10950101);

expect(data).toStrictEqual(null);
});
Expand All @@ -108,7 +108,7 @@ describe('Tier note data controller', () => {
].map((entry) => entry.toObject());
await UnitTierNote.getCollection(app.mongoClient).insertMany(dataArray);

const data = await TierNoteController.getUnitTierNoteEdit(app.mongoClient, SupportedLanguages.CHT, 10950101);
const data = await TierNoteController.getUnitTierNoteSingle(app.mongoClient, SupportedLanguages.CHT, 10950101);

expect(data).toStrictEqual({
points: [],
Expand Down
6 changes: 3 additions & 3 deletions src/endpoints/tier/notes/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ export class TierNoteController {
}

/**
* Get the unit tier note of a certain unit for editing.
* Get the unit tier note of a unit.
*
* @param {MongoClient} mongoClient mongo client
* @param {SupportedLanguages} lang language of the tier note
* @param {number} unitId unit ID of the tier note to be edited
* @param {number} unitId unit ID of the tier note
* @return {Promise<UnitTierNoteApi>}
*/
static async getUnitTierNoteEdit(
static async getUnitTierNoteSingle(
mongoClient: MongoClient, lang: SupportedLanguages, unitId: number,
): Promise<UnitTierNoteApi | null> {
const tierNoteDoc = await UnitTierNote.getCollection(mongoClient)
Expand Down
2 changes: 1 addition & 1 deletion src/endpoints/tier/notes/edit/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const handleTierNoteEdit = async ({
}: HandlerParams<UnitTierNoteEditPayload>): Promise<UnitTierNoteEditResponse> => {
payload = processTierNoteEditPayload(payload);

const data = await TierNoteController.getUnitTierNoteEdit(mongoClient, payload.lang, payload.unitId);
const data = await TierNoteController.getUnitTierNoteSingle(mongoClient, payload.lang, payload.unitId);

return new UnitTierNoteEditResponse({data});
};
2 changes: 1 addition & 1 deletion src/endpoints/tier/notes/edit/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {ApiResponse} from '../../../../base/response';
type UnitTierNoteEditResponseOptions = Omit<UnitTierNoteEditResponseApi, keyof BaseResponse>;

/**
* API response class for the endpoint to get the unit tier notes of an unit for edit.
* API response class for the endpoint to get the unit tier notes of a unit for edit.
*/
export class UnitTierNoteEditResponse extends ApiResponse {
data: UnitTierNote | null;
Expand Down
95 changes: 95 additions & 0 deletions src/endpoints/tier/notes/single/handler.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import {
ApiEndPoints,
ApiResponseCode,
SupportedLanguages,
UnitTierNoteSingleResponse,
} from '../../../../api-def/api';
import {Application, createApp} from '../../../../app';
import {TierNote, UnitTierNote} from '../model';


describe('Single unit tier note handler', () => {
let app: Application;

beforeAll(async () => {
app = await createApp();
});

beforeEach(async () => {
await app.reset();
});

afterAll(async () => {
await app.close();
});

it('returns null if no corresponding tier note available yet', async () => {
const response = await app.app.inject().get(ApiEndPoints.TIER_UNIT).query({
uid: '',
lang: SupportedLanguages.CHT,
unitId: 10950101,
});
expect(response.statusCode).toBe(200);

const json: UnitTierNoteSingleResponse = response.json() as UnitTierNoteSingleResponse;
expect(json.code).toBe(ApiResponseCode.SUCCESS);
expect(json.success).toBe(true);
expect(json.data).toStrictEqual(null);
});

it('returns data in specified language', async () => {
const dataArray = [
new UnitTierNote({
unitId: 10950101,
points: [],
tier: {conAi: new TierNote({ranking: 'S', note: {[SupportedLanguages.CHT]: 'A'}, isCompDependent: true})},
lastUpdateEpoch: 0,
}),
].map((entry) => entry.toObject());
await UnitTierNote.getCollection(app.mongoClient).insertMany(dataArray);

const response = await app.app.inject().get(ApiEndPoints.TIER_UNIT).query({
uid: '',
lang: SupportedLanguages.CHT,
unitId: 10950101,
});
expect(response.statusCode).toBe(200);

const json: UnitTierNoteSingleResponse = response.json() as UnitTierNoteSingleResponse;
expect(json.code).toBe(ApiResponseCode.SUCCESS);
expect(json.success).toBe(true);
expect(json.data).toStrictEqual({
points: [],
tier: {conAi: {ranking: 'S', note: 'A', isCompDependent: true}},
lastUpdateEpoch: 0,
});
});

it('returns data in alternative language if desired one does not exist', async () => {
const dataArray = [
new UnitTierNote({
unitId: 10950101,
points: [],
tier: {conAi: new TierNote({ranking: 'S', note: {[SupportedLanguages.CHT]: 'A'}, isCompDependent: true})},
lastUpdateEpoch: 0,
}),
].map((entry) => entry.toObject());
await UnitTierNote.getCollection(app.mongoClient).insertMany(dataArray);

const response = await app.app.inject().get(ApiEndPoints.TIER_UNIT).query({
uid: '',
lang: SupportedLanguages.EN,
unitId: 10950101,
});
expect(response.statusCode).toBe(200);

const json: UnitTierNoteSingleResponse = response.json() as UnitTierNoteSingleResponse;
expect(json.code).toBe(ApiResponseCode.SUCCESS);
expect(json.success).toBe(true);
expect(json.data).toStrictEqual({
points: [],
tier: {conAi: {ranking: 'S', note: 'A', isCompDependent: true}},
lastUpdateEpoch: 0,
});
});
});
17 changes: 17 additions & 0 deletions src/endpoints/tier/notes/single/handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {UnitTierNoteEditPayload} from '../../../../api-def/api';
import {processTierNoteSinglePayload} from '../../../../utils/payload/tier';
import {HandlerParams} from '../../../lookup';
import {TierNoteController} from '../controller';
import {UnitTierNoteSingleResponse} from './response';


export const handleTierNoteSingle = async ({
payload,
mongoClient,
}: HandlerParams<UnitTierNoteEditPayload>): Promise<UnitTierNoteSingleResponse> => {
payload = processTierNoteSinglePayload(payload);

const data = await TierNoteController.getUnitTierNoteSingle(mongoClient, payload.lang, payload.unitId);

return new UnitTierNoteSingleResponse({data});
};
40 changes: 40 additions & 0 deletions src/endpoints/tier/notes/single/response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {
ApiResponseCode,
BaseResponse,
UnitTierNote,
UnitTierNoteSingleResponse as UnitTierNoteSingleResponseApi,
} from '../../../../api-def/api';
import {ApiResponse} from '../../../../base/response';


type UnitTierNoteSingleResponseOptions = Omit<UnitTierNoteSingleResponseApi, keyof BaseResponse>;

/**
* API response class for the endpoint to get the unit tier notes of a unit.
*/
export class UnitTierNoteSingleResponse extends ApiResponse {
data: UnitTierNote | null;

/**
* Construct a single unit tier notes endpoint API response.
*
* @param {UnitTierNoteEditResponseOptions} options options to construct a single unit tier notes response
*/
constructor(options: UnitTierNoteSingleResponseOptions) {
const responseCode = ApiResponseCode.SUCCESS;

super(responseCode);

this.data = options.data;
}

/**
* @inheritDoc
*/
toJson(): UnitTierNoteSingleResponseApi {
return {
...super.toJson(),
data: this.data,
};
}
}
2 changes: 1 addition & 1 deletion src/endpoints/tier/notes/update/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {ApiResponse} from '../../../../base/response';


/**
* API response class for the endpoint to update the tier notes of an unit.
* API response class for the endpoint to update the tier notes of a unit.
*/
export class UnitTierNoteUpdateResponse extends ApiResponse {
/**
Expand Down
Loading

0 comments on commit 8ce5476

Please sign in to comment.