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

Added notification items #221

Merged
merged 5 commits into from
Nov 10, 2021
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
4 changes: 3 additions & 1 deletion src/__tests__/unit/report.controller.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import {ReportController} from '../../controllers';
import {ReferenceType, ReportType} from '../../enums';
import {Report} from '../../models';
import {ReportRepository} from '../../repositories';
import {NotificationService} from '../../services';
import {givenReport} from '../helpers';

describe('ReportController', () => {
let reportRepository: StubbedInstanceWithSinonAccessor<ReportRepository>;
let notificationService: NotificationService;
let controller: ReportController;
let aReportWithId: Report;
let aListOfReports: Report[];
Expand Down Expand Up @@ -81,6 +83,6 @@ describe('ReportController', () => {
}),
] as Report[];

controller = new ReportController(reportRepository);
controller = new ReportController(reportRepository, notificationService);
}
});
11 changes: 11 additions & 0 deletions src/controllers/report.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ import {ReportRepository} from '../repositories';
import {intercept} from '@loopback/context';
import {PaginationInterceptor} from '../interceptors';
import {ReportInterceptor} from '../interceptors/report.interceptor';
import {service} from '@loopback/core';
import {NotificationService} from '../services';

export class ReportController {
constructor(
@repository(ReportRepository)
public reportRepository: ReportRepository,
@service(NotificationService)
public notificationService: NotificationService,
) {}

@intercept(PaginationInterceptor.BINDING_KEY)
Expand Down Expand Up @@ -95,6 +99,13 @@ export class ReportController {
report: Partial<Report>,
): Promise<void> {
await this.reportRepository.updateById(id, report);

try {
await this.notificationService.sendReportResponseToUser(id);
await this.notificationService.sendReportResponseToReporters(id);
} catch {
// ignore
}
}

@intercept(ReportInterceptor.BINDING_KEY)
Expand Down
41 changes: 34 additions & 7 deletions src/controllers/user-report.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@ import {
requestBody,
HttpErrors,
} from '@loopback/rest';
import {ReferenceType, ReportStatusType, ReportType} from '../enums';
import {
PlatformType,
ReferenceType,
ReportStatusType,
ReportType,
} from '../enums';
import {ReportInterceptor} from '../interceptors';
import {Report, ReportDetail} from '../models';
import {
ReportRepository,
PostRepository,
CommentRepository,
UserRepository,
UserSocialMediaRepository,
} from '../repositories';
import {NotificationService} from '../services';

Expand All @@ -29,6 +35,8 @@ export class UserReportController {
protected commentRepository: CommentRepository,
@repository(UserRepository)
protected userRepository: UserRepository,
@repository(UserSocialMediaRepository)
protected userSocialMediaRepository: UserSocialMediaRepository,
@service(NotificationService)
protected notificationService: NotificationService,
) {}
Expand Down Expand Up @@ -57,7 +65,6 @@ export class UserReportController {
})
reportDetail: ReportDetail,
): Promise<Report> {
// TODO: Added notification service when report a post or a user
return this.getReport(id, reportDetail);
}

Expand Down Expand Up @@ -107,13 +114,33 @@ export class UserReportController {
include: ['user'],
});

if (foundPost.createdBy === id) {
throw new HttpErrors.UnprocessableEntity(
'You cannot report your own post',
if (foundPost.platform === PlatformType.MYRIAD) {
if (foundPost.createdBy === id) {
throw new HttpErrors.UnprocessableEntity(
'You cannot report your own post',
);
}

return foundPost;
} else {
const userSocialMedia = await this.userSocialMediaRepository.findOne({
where: {
peopleId: foundPost.peopleId,
},
});

if (!userSocialMedia) {
throw new HttpErrors.UnprocessableEntity(
'You cannot report this post, because this post does not belong to any user!',
);
}

foundPost.user = await this.userRepository.findById(
userSocialMedia.userId,
);
}

return foundPost;
return foundPost;
}
}

if (referenceType === ReferenceType.COMMENT) {
Expand Down
6 changes: 6 additions & 0 deletions src/interceptors/initial-creation.interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@ export class InitialCreationInterceptor implements Provider<Interceptor> {
}

case ControllerType.TRANSACTION: {
if (invocationCtx.args[0].from === invocationCtx.args[0].to) {
throw new HttpErrors.UnprocessableEntity(
'From and to address cannot be the same!',
);
}

await this.currencyRepository.findById(
invocationCtx.args[0].currencyId,
);
Expand Down
81 changes: 41 additions & 40 deletions src/services/notification.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
Comment,
MentionUser,
Notification,
Report,
Transaction,
User,
UserSocialMedia,
Expand Down Expand Up @@ -138,44 +137,49 @@ export class NotificationService {
notification.referenceId = comment.id;
notification.message = 'commented: ' + comment.text;

if (comment.type === ReferenceType.COMMENT) {
notification.additionalReferenceId =
await this.getCommentAdditionalReferenceIds(comment.id ?? '');
}

// FCM messages
const title = 'New Comment';
const body = fromUser.name + ' ' + notification.message;

let toUser: User = new User();

const post = await this.postRepository.findById(comment.postId);

// Notification comment to comment
if (comment.type === ReferenceType.COMMENT) {
const toComment = await this.commentRepository.findById(
comment.referenceId,
);

if (toComment.userId === comment.userId) return false;

const notificationSetting =
await this.notificationSettingRepository.findOne({
where: {userId: toComment.userId},
});

// TODO: fixed notification setting
if (notificationSetting && !notificationSetting.comments) return false;

notification.additionalReferenceId =
await this.getCommentAdditionalReferenceIds(comment.id ?? '');

toUser = await this.userRepository.findById(toComment.userId);
notification.to = toUser.id;

await this.notificationRepository.create(notification);
await this.fcmService.sendNotification(toUser.fcmTokens, title, body);

return true;
} else {
notification.additionalReferenceId = [{postId: post.id}];
}

const post = await this.postRepository.findById(comment.postId);

// Notification comment to post
let toUsers: string[] = [];
if (post.platform === PlatformType.MYRIAD) {
toUser = await this.userRepository.findById(post.createdBy);

if (toUser.id === comment.userId) return false;

toUsers.push(toUser.id);
} else {
const userSocialMedia = await this.userSocialMediaRepository.findOne({
Expand All @@ -187,14 +191,14 @@ export class NotificationService {
toUsers.push(toUser.id);
}

toUsers = [...toUsers, ...post.importers, post.createdBy];
toUsers = [...toUsers, ...post.importers].filter(
userId => userId !== comment.userId,
);
}

if (toUsers.length === 0) return false;
if (!toUser) return false;

notification.additionalReferenceId = [{postId: comment.postId}];

const notificationSetting =
await this.notificationSettingRepository.findOne({
where: {userId: toUser.id},
Expand Down Expand Up @@ -237,11 +241,10 @@ export class NotificationService {
return true;
}

async sendReportResponseToReporters(
reportId: string,
type: ReferenceType,
referenceId: string,
): Promise<boolean> {
async sendReportResponseToReporters(reportId: string): Promise<boolean> {
const {referenceType, referenceId} = await this.reportRepository.findById(
reportId,
);
const reporters = await this.userReportReportRepository.find({
where: {reportId: reportId},
});
Expand All @@ -258,7 +261,7 @@ export class NotificationService {
notification.from = getHexPublicKey(pair);
notification.message = 'approved your report';

switch (type) {
switch (referenceType) {
case ReferenceType.USER: {
notification.type = NotificationType.USER_BANNED;
notification.referenceId = referenceId;
Expand Down Expand Up @@ -320,8 +323,9 @@ export class NotificationService {
return true;
}

async sendReportResponseToUser(report: Report): Promise<boolean> {
const {referenceId, referenceType, status} = report;
async sendReportResponseToUser(reportId: string): Promise<boolean> {
const {referenceId, referenceType, status} =
await this.reportRepository.findById(reportId);

if (status !== ReportStatusType.REMOVED) return false;

Expand Down Expand Up @@ -555,32 +559,29 @@ export class NotificationService {
const body = fromUser.name + ' ' + notification.message;
const toUsers = await this.userRepository.find({
where: {
or: mentions.map(mention => {
return {
id: mention.id,
};
}),
or: mentions
.filter(mention => mention.id !== from)
.map(mention => {
return {
id: mention.id,
};
}),
},
});

if (toUsers.length === 0) return false;

const notifications = toUsers
.filter(async user => {
try {
const notificationSetting =
await this.notificationSettingRepository.findOne({
where: {
userId: user.id,
},
});

if (notificationSetting && !notificationSetting.mentions)
return false;
return true;
} catch {
// ignore
}
const notificationSetting =
await this.notificationSettingRepository.findOne({
where: {
userId: user.id,
},
});

if (notificationSetting && !notificationSetting.mentions) return false;
return true;
})
.map(toUser => {
const updatedNotification = {
Expand Down