Skip to content

Commit

Permalink
Merge pull request #15 from Caryzxy/main
Browse files Browse the repository at this point in the history
The fully functional PR for #Issue 9
  • Loading branch information
Caryzxy authored Feb 28, 2025
2 parents 53ca2ed + 7773df0 commit d8e4df3
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 1 deletion.
9 changes: 9 additions & 0 deletions install/data/categories.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,14 @@
"color": "#ffffff",
"icon" : "fa-question",
"order": 3
},
{
"name": "Questions",
"description": "Post any question you have!",
"descriptionParsed": "<p>Post any question you have!</p>\n",
"bgColor": "#e95c5a",
"color": "#ffffff",
"icon" : "fa-question",
"order": 5
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
{./name}
{{{ else }}}
<a class="text-reset" href="{{{ if ./link }}}{./link}{{{ else }}}{config.relative_path}/category/{./slug}{{{ end }}}" itemprop="url">{../name}</a>
{{{ end }}}
{{{ end }}}
38 changes: 38 additions & 0 deletions src/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,42 @@ async function createGlobalModeratorsGroup() {
await groups.show('Global Moderators');
}

async function createStudents() {
const groups = require('./groups');
const exists = await groups.exists('Students');
if (exists) {
winston.info('Students group found, skipping creation!');
} else {
await groups.create({
name: 'Students',
userTitle: 'Student',
description: 'Cute students here',
hidden: 0,
private: 0,
disableJoinRequests: 0,
});
}
await groups.show('Students');
}

async function createInstructors() {
const groups = require('./groups');
const exists = await groups.exists('Instructors');
if (exists) {
winston.info('Instructors group found, skipping creation!');
} else {
await groups.create({
name: 'Instructors',
userTitle: 'Instructor',
description: 'Cool instructors are here',
hidden: 0,
private: 0,
disableJoinRequests: 0,
});
}
await groups.show('Instructors');
}

async function giveGlobalPrivileges() {
const privileges = require('./privileges');
const defaultPrivileges = [
Expand Down Expand Up @@ -584,6 +620,8 @@ install.setup = async function () {
await createDefaultUserGroups();
const adminInfo = await createAdministrator();
await createGlobalModeratorsGroup();
await createStudents();
await createInstructors();
await giveGlobalPrivileges();
await createMenuItems();
await createWelcomePost();
Expand Down
30 changes: 30 additions & 0 deletions src/posts/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const topics = require('../topics');
const categories = require('../categories');
const groups = require('../groups');
const privileges = require('../privileges');
const notifications = require('../notifications');

module.exports = function (Posts) {
Posts.create = async function (data) {
Expand Down Expand Up @@ -71,9 +72,38 @@ module.exports = function (Posts) {
Posts.uploads.sync(postData.pid),
]);

// 🔹 Check if the posting user is in a specific group
const postingGroup = 'Students'; // Change this to the correct group name
const notifyGroup = 'Instructors'; // Change this to the target group
const targetCategoryId = 5; // Change to the category ID you want
const belongsToPostingGroup = await groups.isMember(uid, postingGroup);

result = await plugins.hooks.fire('filter:post.get', { post: postData, uid: data.uid });
result.post.isMain = isMain;
plugins.hooks.fire('action:post.save', { post: _.clone(result.post) });

if (belongsToPostingGroup && postData.cid === targetCategoryId) {
console.log(`User in ${postingGroup} posted in category ${targetCategoryId}, notifying ${notifyGroup}`);

// 🔹 Get all members of the notify group using `getMembers`
const notifyUids = await groups.getMembers(notifyGroup, 0, -1);

if (notifyUids.length === 0) {
console.log(`No users found in group ${notifyGroup}, skipping notifications.`);
return;
}

// 🔹 Create the notification
const notification = await notifications.create({
type: 'custom-notification',
bodyShort: `A new post was made in category Question!`,
nid: `post:${postData.pid}`,
path: `/post/${postData.pid}`,
from: postData.uid,
});
// 🔹 Push the notification to all users in notifyGroup
await notifications.push(notification, notifyUids);
}
return result.post;
};

Expand Down
123 changes: 123 additions & 0 deletions test/posts.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const file = require('../src/file');
const helpers = require('./helpers');
const utils = require('../src/utils');
const request = require('../src/request');
const notifications = require('../src/notifications');

describe('Post\'s', () => {
let voterUid;
Expand Down Expand Up @@ -1202,6 +1203,128 @@ describe('Post\'s', () => {
});
});

describe('Posts & Notifications', () => {
let studentUid;

Check failure on line 1207 in test/posts.js

View workflow job for this annotation

GitHub Actions / test

Expected indentation of 1 tab but found 4 spaces
let instructorUid;

Check failure on line 1208 in test/posts.js

View workflow job for this annotation

GitHub Actions / test

Expected indentation of 1 tab but found 4 spaces
let receiverUid;

Check failure on line 1209 in test/posts.js

View workflow job for this annotation

GitHub Actions / test

Expected indentation of 1 tab but found 4 spaces
const studentGroup = "students"; // Students group

Check failure on line 1210 in test/posts.js

View workflow job for this annotation

GitHub Actions / test

Expected indentation of 1 tab but found 4 spaces

Check failure on line 1210 in test/posts.js

View workflow job for this annotation

GitHub Actions / test

Strings must use singlequote
const instructorGroup = "instructors"; // Instructors group

Check failure on line 1211 in test/posts.js

View workflow job for this annotation

GitHub Actions / test

Expected indentation of 1 tab but found 4 spaces

Check failure on line 1211 in test/posts.js

View workflow job for this annotation

GitHub Actions / test

Strings must use singlequote
const notifyGroup = "notify-group"; // The group that should receive notifications

Check failure on line 1212 in test/posts.js

View workflow job for this annotation

GitHub Actions / test

Expected indentation of 1 tab but found 4 spaces
const targetCategoryId = 1; // The category ID that triggers notifications
const testCategoryId = 1; // New test category

before(async () => {
// Create a student user who will post
studentUid = await user.create({
username: 'studentUser',
email: 'student@test.com',
});

// Create an instructor user
instructorUid = await user.create({
username: 'instructorUser',
email: 'instructor@test.com',
});

// Create a user who should receive notifications
receiverUid = await user.create({
username: 'receiverUser',
email: 'receiver@test.com',
});

// Add student to `students` group
await groups.join(studentGroup, studentUid);

// Add instructor to `instructors` group
await groups.join(instructorGroup, instructorUid);

// Add receiver to `notifyGroup`
await groups.join(notifyGroup, receiverUid);

// Create a test category with `cid = 5`
await categories.create({
cid: testCategoryId,
name: "Test Category",
description: "This is a test category.",
});
});

it('should create a post successfully in cid = 5', async () => {
const { postData } = await topics.post({
uid: studentUid,
cid: testCategoryId, // Posting in category 5
title: 'Test Post in Category 5',
content: 'This is a test post in category 5.',
});

assert(postData, "Post was not created in category 5");
console.log("✅ Post creation in category 5 test passed.");
});

it('should notify the correct group when a student posts in target category', async () => {
// Simulate a post by a student in `targetCategoryId`
const { postData } = await topics.post({
uid: studentUid,
cid: targetCategoryId,
title: 'Student Test Notification Post',
content: 'This post should trigger a notification.',
});

assert(postData, "Post was not created");

// Create the notification
const notification = await notifications.create({
type: 'notificationType_new-topic-in-category',
bodyShort: `New post in category ${targetCategoryId}!`,
nid: `post:${postData.pid}`,
path: `/post/${postData.pid}`,
from: studentUid,
});

// Send notification to all in `notifyGroup`
await notifications.push(notification, [receiverUid]);

// Fetch notifications for the receiver
const userNotifications = await notifications.getMultiple([`post:${postData.pid}`]);
const foundNotification = userNotifications.find(n => n.nid === `post:${postData.pid}`);

assert(foundNotification, "Receiver did not get the expected notification");
console.log("✅ Notification test passed: Receiver received the notification.");
});

it('should notify when an instructor posts in cid = 5', async () => {
// Simulate a post by an instructor in `cid = 5`
const { postData } = await topics.post({
uid: instructorUid,
cid: testCategoryId, // Posting in category 5
title: 'Instructor Test Post',
content: 'This post should also trigger a notification.',
});

assert(postData, "Instructor post was not created in category 5");

// Create the notification
const notification = await notifications.create({
type: 'notificationType_new-topic-in-category',
bodyShort: `Instructor posted in category ${testCategoryId}!`,
nid: `post:${postData.pid}`,
path: `/post/${postData.pid}`,
from: instructorUid,
});

// Send notification to all in `notifyGroup`
await notifications.push(notification, [receiverUid]);

// Fetch notifications for the receiver
const userNotifications = await notifications.getMultiple([`post:${postData.pid}`]);
const foundNotification = userNotifications.find(n => n.nid === `post:${postData.pid}`);

assert(foundNotification, "Receiver did not get the expected notification for instructor post");
console.log("✅ Notification test passed: Receiver received notification for instructor post.");
});


});
describe('Posts\'', async () => {
let files;

Expand Down

0 comments on commit d8e4df3

Please sign in to comment.