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

v2.17.0 Release #40

Merged
merged 34 commits into from
Jan 23, 2022
Merged
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d559fc4
Updated dependencies
RaenonX Jan 14, 2022
dd5de1b
Added example for required env vars
RaenonX Jan 14, 2022
f311a23
Fixed failing tests
RaenonX Jan 16, 2022
fc4e553
Improved mongo collection typings #22
RaenonX Jan 16, 2022
dff89bf
Added basic email notification implementations #32
RaenonX Jan 16, 2022
5dad795
Added email notification on post publish/edit #32
RaenonX Jan 17, 2022
8713ba9
Fixed failing tests
RaenonX Jan 17, 2022
e6bdbb8
Refactored email files
RaenonX Jan 17, 2022
a6d57f8
Fixed failing tests
RaenonX Jan 17, 2022
a8427ab
Added email notification on tier updated #32
RaenonX Jan 17, 2022
26bb809
Added subscription management link as email footer
RaenonX Jan 17, 2022
caa1516
Added subscription update EP #36
RaenonX Jan 17, 2022
394a863
Added individual subscription management EPs
RaenonX Jan 17, 2022
e482a70
Updated GA data to use the database as cache #37
RaenonX Jan 18, 2022
81248e5
Fixed potentially erroneous async/await usage
RaenonX Jan 18, 2022
db5425f
Added subscription payload processing implementation
RaenonX Jan 18, 2022
5902bbd
Downgraded `mongodb-memory-server`
RaenonX Jan 18, 2022
445311a
Added post subscription status with refactoring RaenonX-DL/dragalia-s…
RaenonX Jan 18, 2022
a6c0797
Updated CD badge
RaenonX Jan 18, 2022
debf0c6
Fixed possible incorrect `createIndex` usage
RaenonX Jan 18, 2022
c3862f4
Added global subscription status in list response
RaenonX Jan 18, 2022
11dac62
Changed `getCollection` to `Promise`
RaenonX Jan 18, 2022
a152a69
Bumped dependencies
RaenonX Jan 18, 2022
c4cf5b3
Fixed false-positive tests
RaenonX Jan 18, 2022
f43eca8
Added subscription status in homepage response
RaenonX Jan 19, 2022
6e5fffe
Updated API definitions
RaenonX Jan 19, 2022
45ff6b2
Added `sendEmailUpdate` flag handling RaenonX-DL/dragalia-site-front#342
RaenonX Jan 20, 2022
a4197a8
Updated user settings path
RaenonX Jan 22, 2022
656d02d
Added subscription get all EP
RaenonX Jan 22, 2022
25c523c
Updated subscription update EPs to user config EPs
RaenonX Jan 23, 2022
46b8579
Added implementations for site announcement RaenonX-DL/dragalia-site-…
RaenonX Jan 23, 2022
9a211a9
Removed site announcement markdown `base64url` encoding
RaenonX Jan 23, 2022
1be9007
Updated homepage landing response
RaenonX Jan 23, 2022
7fa6133
Fixed failing tests
RaenonX Jan 23, 2022
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
Prev Previous commit
Next Next commit
Added individual subscription management EPs
Signed-off-by: RaenonX <raenonx0710@gmail.com>
  • Loading branch information
RaenonX committed Jan 17, 2022

Verified

This commit was signed with the committer’s verified signature.
snyk-bot Snyk bot
commit 394a863f3338e34162c2113a4a2394a970e735dc
8 changes: 6 additions & 2 deletions src/endpoints/lookup.ts
Original file line number Diff line number Diff line change
@@ -42,7 +42,9 @@ import {handleTierNoteUpdate} from './tier/notes/update/handler';
import {handleTierPointsGet} from './tier/points/get/handler';
import {handleTierPointsManage} from './tier/points/manage/handler';
import {handleTierPointsUpdate} from './tier/points/update/handler';
import {handlerSubscriptionUpdate} from './userControl/notifications/update/handler';
import {handleSubscriptionAdd} from './userControl/notifications/add/handler';
import {handleSubscriptionRemove} from './userControl/notifications/remove/handler';
import {handleSubscriptionUpdate} from './userControl/notifications/update/handler';


type HttpMethods = 'GET' | 'POST' | 'HEAD';
@@ -98,7 +100,9 @@ export const handlerLookup: {[endpoint: string]: EndpointHandlers} = {
[ApiEndPoints.MANAGE_TIER_NOTE]: {GET: handleTierNoteEdit, POST: handleTierNoteUpdate},
[ApiEndPoints.MANAGE_TIER_POINTS]: {GET: handleTierPointsManage, POST: handleTierPointsUpdate},
[ApiEndPoints.PRESET_ATK_SKILL_INPUT]: {GET: handleGetAtkSkillPreset, POST: handleSetAtkSkillPreset},
[ApiEndPoints.USER_SUBSCRIPTIONS]: {POST: handlerSubscriptionUpdate},
[ApiEndPoints.USER_SUBSCRIPTIONS_UPDATE]: {POST: handleSubscriptionUpdate},
[ApiEndPoints.USER_SUBSCRIPTIONS_ADD]: {POST: handleSubscriptionAdd},
[ApiEndPoints.USER_SUBSCRIPTIONS_REMOVE]: {POST: handleSubscriptionRemove},
};

export const handleResponse = async <T extends RequestPayloadBase>(
84 changes: 84 additions & 0 deletions src/endpoints/userControl/notifications/add/handler.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import {ObjectId} from 'mongodb';

import {
ApiEndPoints,
ApiResponseCode,
PostType,
SubscriptionAddResponse,
SupportedLanguages,
} from '../../../../api-def/api';
import {Application, createApp} from '../../../../app';
import {
SubscriptionRecord,
SubscriptionRecordDocument,
SubscriptionRecordDocumentKey,
} from '../../../../thirdparty/mail/data/subscription/model';


describe('Subscription add handler', () => {
let app: Application;

const uid = new ObjectId();

const subRecs: SubscriptionRecordDocument[] = [
{
[SubscriptionRecordDocumentKey.key]: {type: 'const', name: 'ALL_QUEST'},
[SubscriptionRecordDocumentKey.uid]: uid,
},
{
[SubscriptionRecordDocumentKey.key]: {type: 'post', postType: PostType.QUEST, id: 8},
[SubscriptionRecordDocumentKey.uid]: uid,
},
];

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

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

await SubscriptionRecord.getCollection(app.mongoClient).insertMany(subRecs);
});

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

it('adds a subscription', async () => {
const response = await app.app.inject().post(ApiEndPoints.USER_SUBSCRIPTIONS_ADD).payload({
uid,
lang: SupportedLanguages.CHT,
subKeyBase64: Buffer.from(JSON.stringify({
[SubscriptionRecordDocumentKey.key]: {type: 'post', postType: PostType.QUEST, id: 7},
[SubscriptionRecordDocumentKey.uid]: uid,
})).toString('base64url'),
});
expect(response.statusCode).toBe(200);

const json: SubscriptionAddResponse = response.json() as SubscriptionAddResponse;
expect(json.code).toBe(ApiResponseCode.SUCCESS);
expect(json.success).toBe(true);

const docCount = await SubscriptionRecord.getCollection(app.mongoClient).countDocuments();

expect(docCount).toBe(3);
});

it('does not return 500 if already subscribed', async () => {
const response = await app.app.inject().post(ApiEndPoints.USER_SUBSCRIPTIONS_ADD).payload({
uid,
lang: SupportedLanguages.CHT,
subKeyBase64: Buffer.from(JSON.stringify(subRecs[0][SubscriptionRecordDocumentKey.key])).toString('base64url'),
});
expect(response.statusCode).toBe(200);

const json: SubscriptionAddResponse = response.json() as SubscriptionAddResponse;
expect(json.code).toBe(ApiResponseCode.SUCCESS);
expect(json.success).toBe(true);

const docs = await SubscriptionRecord.getCollection(app.mongoClient).find().toArray();

expect(docs).toStrictEqual(subRecs);
});
});
14 changes: 14 additions & 0 deletions src/endpoints/userControl/notifications/add/handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {SubscriptionAddPayload} from '../../../../api-def/api';
import {SubscriptionRecordController} from '../../../../thirdparty/mail/data/subscription/controller';
import {HandlerParams} from '../../../lookup';
import {SubscriptionAddResponse} from './response';


export const handleSubscriptionAdd = async ({
payload,
mongoClient,
}: HandlerParams<SubscriptionAddPayload>): Promise<SubscriptionAddResponse> => {
await SubscriptionRecordController.addSubscription(mongoClient, payload);

return new SubscriptionAddResponse();
};
17 changes: 17 additions & 0 deletions src/endpoints/userControl/notifications/add/response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {ApiResponseCode} from '../../../../api-def/api';
import {ApiResponse} from '../../../../base/response';


/**
* Subscription add response class.
*
* This always returns `ApiResponseCode.SUCCESS` if used.
*/
export class SubscriptionAddResponse extends ApiResponse {
/**
* Construct a user subscription add response class.
*/
constructor() {
super(ApiResponseCode.SUCCESS);
}
}
81 changes: 81 additions & 0 deletions src/endpoints/userControl/notifications/remove/handler.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import {ObjectId} from 'mongodb';

import {
ApiEndPoints,
ApiResponseCode,
PostType,
SubscriptionRemoveResponse,
SupportedLanguages,
} from '../../../../api-def/api';
import {Application, createApp} from '../../../../app';
import {
SubscriptionRecord,
SubscriptionRecordDocument,
SubscriptionRecordDocumentKey,
} from '../../../../thirdparty/mail/data/subscription/model';


describe('Subscription remove handler', () => {
let app: Application;

const uid = new ObjectId();

const subRecs: SubscriptionRecordDocument[] = [
{
[SubscriptionRecordDocumentKey.key]: {type: 'const', name: 'ALL_QUEST'},
[SubscriptionRecordDocumentKey.uid]: uid,
},
{
[SubscriptionRecordDocumentKey.key]: {type: 'post', postType: PostType.QUEST, id: 8},
[SubscriptionRecordDocumentKey.uid]: uid,
},
];

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

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

await SubscriptionRecord.getCollection(app.mongoClient).insertMany(subRecs);
});

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

it('removes existing subscription', async () => {
const response = await app.app.inject().post(ApiEndPoints.USER_SUBSCRIPTIONS_REMOVE).payload({
uid,
lang: SupportedLanguages.CHT,
subKeyBase64: Buffer.from(JSON.stringify(subRecs[0][SubscriptionRecordDocumentKey.key])).toString('base64url'),
});
expect(response.statusCode).toBe(200);

const json: SubscriptionRemoveResponse = response.json() as SubscriptionRemoveResponse;
expect(json.code).toBe(ApiResponseCode.SUCCESS);
expect(json.success).toBe(true);

const doc = await SubscriptionRecord.getCollection(app.mongoClient).findOne();

expect(doc).toStrictEqual(subRecs[1]);
});

it('does not return 500 even if the subscription does not exist', async () => {
const response = await app.app.inject().post(ApiEndPoints.USER_SUBSCRIPTIONS_REMOVE).payload({
uid,
lang: SupportedLanguages.CHT,
subKeyBase64: Buffer.from('[]').toString('base64url'),
});
expect(response.statusCode).toBe(200);

const json: SubscriptionRemoveResponse = response.json() as SubscriptionRemoveResponse;
expect(json.code).toBe(ApiResponseCode.SUCCESS);
expect(json.success).toBe(true);

const docCount = await SubscriptionRecord.getCollection(app.mongoClient).countDocuments();

expect(docCount).toStrictEqual(2);
});
});
14 changes: 14 additions & 0 deletions src/endpoints/userControl/notifications/remove/handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {SubscriptionRemovePayload} from '../../../../api-def/api';
import {SubscriptionRecordController} from '../../../../thirdparty/mail/data/subscription/controller';
import {HandlerParams} from '../../../lookup';
import {SubscriptionRemoveResponse} from './response';


export const handleSubscriptionRemove = async ({
payload,
mongoClient,
}: HandlerParams<SubscriptionRemovePayload>): Promise<SubscriptionRemoveResponse> => {
await SubscriptionRecordController.removeSubscription(mongoClient, payload);

return new SubscriptionRemoveResponse();
};
17 changes: 17 additions & 0 deletions src/endpoints/userControl/notifications/remove/response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {ApiResponseCode} from '../../../../api-def/api';
import {ApiResponse} from '../../../../base/response';


/**
* Subscription remove response class.
*
* This always returns `ApiResponseCode.SUCCESS` if used.
*/
export class SubscriptionRemoveResponse extends ApiResponse {
/**
* Construct a user subscription remove response class.
*/
constructor() {
super(ApiResponseCode.SUCCESS);
}
}
28 changes: 13 additions & 15 deletions src/endpoints/userControl/notifications/update/handler.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {ObjectId} from 'mongodb';

import {insertMockUser} from '../../../../../test/data/user';
import {
ApiEndPoints,
ApiResponseCode,
@@ -18,10 +17,10 @@ import {
} from '../../../../thirdparty/mail/data/subscription/model';


describe('Tier note updating handler', () => {
describe('Subscription batch update handler', () => {
let app: Application;

const uidAdmin = new ObjectId();
const uid = new ObjectId();

const subKeys: SubscriptionKey[] = [
{type: 'const', name: 'ALL_QUEST'},
@@ -35,16 +34,15 @@ describe('Tier note updating handler', () => {

beforeEach(async () => {
await app.reset();
await insertMockUser(app.mongoClient, {id: uidAdmin, isAdmin: true});
});

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

it('adds new subscriptions of a user if not existed before', async () => {
const response = await app.app.inject().post(ApiEndPoints.USER_SUBSCRIPTIONS).payload({
uid: uidAdmin,
const response = await app.app.inject().post(ApiEndPoints.USER_SUBSCRIPTIONS_UPDATE).payload({
uid,
lang: SupportedLanguages.CHT,
subKeysBase64,
});
@@ -65,24 +63,24 @@ describe('Tier note updating handler', () => {

expect(docs).toStrictEqual(subKeys.map((key) => ({
[SubscriptionRecordDocumentKey.key]: key,
[SubscriptionRecordDocumentKey.uid]: uidAdmin,
[SubscriptionRecordDocumentKey.uid]: uid,
})));
});

it('updates the subscriptions of a user', async () => {
await SubscriptionRecord.getCollection(app.mongoClient).insertMany([
{
[SubscriptionRecordDocumentKey.key]: {type: 'const', name: 'ALL_QUEST'},
[SubscriptionRecordDocumentKey.uid]: uidAdmin,
[SubscriptionRecordDocumentKey.uid]: uid,
},
{
[SubscriptionRecordDocumentKey.key]: {type: 'post', postType: PostType.QUEST, id: 8},
[SubscriptionRecordDocumentKey.uid]: uidAdmin,
[SubscriptionRecordDocumentKey.uid]: uid,
},
]);

const response = await app.app.inject().post(ApiEndPoints.USER_SUBSCRIPTIONS).payload({
uid: uidAdmin,
const response = await app.app.inject().post(ApiEndPoints.USER_SUBSCRIPTIONS_UPDATE).payload({
uid,
lang: SupportedLanguages.CHT,
subKeysBase64,
});
@@ -103,18 +101,18 @@ describe('Tier note updating handler', () => {

expect(docs).toStrictEqual(subKeys.map((key) => ({
[SubscriptionRecordDocumentKey.key]: key,
[SubscriptionRecordDocumentKey.uid]: uidAdmin,
[SubscriptionRecordDocumentKey.uid]: uid,
})));
});

it('completely removes the subscriptions of a user', async () => {
await SubscriptionRecord.getCollection(app.mongoClient).insertMany(subKeys.map((key) => ({
[SubscriptionRecordDocumentKey.key]: key,
[SubscriptionRecordDocumentKey.uid]: uidAdmin,
[SubscriptionRecordDocumentKey.uid]: uid,
})));

const response = await app.app.inject().post(ApiEndPoints.USER_SUBSCRIPTIONS).payload({
uid: uidAdmin,
const response = await app.app.inject().post(ApiEndPoints.USER_SUBSCRIPTIONS_UPDATE).payload({
uid,
lang: SupportedLanguages.CHT,
subKeysBase64: Buffer.from('[]', 'base64url').toString(),
});
2 changes: 1 addition & 1 deletion src/endpoints/userControl/notifications/update/handler.ts
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ import {HandlerParams} from '../../../lookup';
import {SubscriptionUpdateResponse} from './response';


export const handlerSubscriptionUpdate = async ({
export const handleSubscriptionUpdate = async ({
payload,
mongoClient,
}: HandlerParams<SubscriptionUpdatePayload>): Promise<SubscriptionUpdateResponse> => {
2 changes: 1 addition & 1 deletion src/endpoints/userControl/notifications/update/response.ts
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ import {ApiResponse} from '../../../../base/response';
*/
export class SubscriptionUpdateResponse extends ApiResponse {
/**
* Construct a user subscription update response class..
* Construct a user subscription update response class.
*/
constructor() {
super(ApiResponseCode.SUCCESS);
Loading