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

feature: Add ability for bot to send a cheatsheet for each submission #64

Merged
merged 1 commit into from
Mar 7, 2024
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
68 changes: 67 additions & 1 deletion src/commands/__test__/tarea.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { multipleBlocksOfCodeDetected } from '../../blocks/multipleBlocksOfCodeD
import { multipleGitHubLinksDetected } from '../../blocks/multipleGitHubLinksDetected';
import { IThreadResponse } from '../../api/marketplace/thread/IThreadResponse';
import { unknownCommandBlock } from '../../blocks/unknownCommandBlock';
import { assignmentCheatsheet } from '../../utils/assignmentCheatsheet';

jest.mock('../tarea/uploadTarea');
jest.mock('../../api/marketplace/user/userApi');
Expand Down Expand Up @@ -107,7 +108,72 @@ describe('tareaCommandFunction', () => {
});

expect(commandMock.say).toHaveBeenCalledWith(
`Tarea subida con éxito <@${usersInfoResponse.user.id}>!\n\nTarea:\n${fullMessage}\n\n*Para agregar correcciones responder en este hilo.*`
`Tarea subida con éxito <@${usersInfoResponse.user.id}>!\n\nTarea:\n${fullMessage}\n\nTe recomendamos leer las siguientes <${assignmentCheatsheet['1']} | notas> que pueden ayudarte a solucionar errores comunes. \n\n*Para agregar correcciones responder en este hilo (no en el mensaje original).*`
);

expect(threadApi.create).toHaveBeenCalledTimes(1);
expect(threadApi.create).toHaveBeenCalledWith({
authorId: env.BOT_ID,
text: chatPostMessageResponse.message.text,
timestamp: chatPostMessageResponse.ts,
});
});

it("should not send a cheatsheet as part of the response if the lesson doesn't have one", async () => {
const typeCodeText = 'console.log("Hello World!!!")';
const fullMessage =
'Hola, aca dejo la tarea\n\n```console.log("Hello World!!!")```';

commandMock.command = {
text: fullMessage,
channel_name: 'clase-3',
user_id: 'mockId',
};

const submissionResponseMock = {
completed: false,
delivery: typeCodeText,
fkStudentId: 1,
fkTaskId: 3,
id: 1,
isActive: true,
viewer: undefined,
} as unknown as ISubmissionResponse;

commandMock.client.users.info.mockResolvedValueOnce(
// @ts-ignore
usersInfoResponse
);

uploadTareaMock.mockResolvedValueOnce(submissionResponseMock);

commandMock.say.mockResolvedValueOnce({
ok: true,
ts: chatPostMessageResponse.ts,
message: {
text: chatPostMessageResponse.message.text,
},
});

threadApiCreateMock.mockResolvedValue({} as unknown as IThreadResponse);

await tareaCommandFunction(
// @ts-ignore
commandMock
);

expect(uploadTareaMock).toBeCalledTimes(1);
expect(uploadTareaMock).toHaveBeenCalledWith({
classNumber: '3',
delivery: typeCodeText,
slackId: usersInfoResponse.user.id,
firstName: usersInfoResponse.user.profile.first_name,
lastName: usersInfoResponse.user.profile.last_name,
email: usersInfoResponse.user.profile.email,
});

expect(commandMock.say).toHaveBeenCalledWith(
`Tarea subida con éxito <@${usersInfoResponse.user.id}>!\n\nTarea:\n${fullMessage}\n\n*Para agregar correcciones responder en este hilo (no en el mensaje original).*`
);

expect(threadApi.create).toHaveBeenCalledTimes(1);
Expand Down
60 changes: 14 additions & 46 deletions src/commands/tarea/tarea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { multipleBlocksOfCodeDetected } from '../../blocks/multipleBlocksOfCodeD
import { multipleSubmissionFormatsDetected } from '../../blocks/multipleSubmissionsDetected';
import { wrongFormatSubmission } from '../../blocks/wrongFormatSubmission';
import { multipleGitHubLinksDetected } from '../../blocks/multipleGitHubLinksDetected';
import { assignmentCheatsheet } from '../../utils/assignmentCheatsheet';

dotenv.config();

Expand All @@ -46,37 +47,26 @@ export const tareaCommandFunction = async ({
respond,
client,
}: Command): Promise<void> => {
console.log('HERE START TAREA COMMAND FUNCTION');
console.log('command: ', command);
console.log('client: ', client);

await ack();

try {
console.log('HERE ENTERS IN TRY BLOCK');
const { user } = (await client.users.info({
user: command.user_id,
})) as IUserClient;

console.log('user: ', user);
console.log('client.users.info property "user": ', command.user_id);

if (!user) {
throw new Error('Slack-api Error: User not found');
}

const classNumber = validateChannelName(command.channel_name);

console.log('classNumber: ', classNumber);

if (!classNumber) {
await respond(unknownCommandBlock());
return;
}

const submissionHasValidFormat = validateSubmissionFormat(command.text);

console.log('submissionHasValidFormat: ', submissionHasValidFormat);

if (!submissionHasValidFormat) {
await respond(wrongFormatSubmission());
return;
Expand All @@ -86,8 +76,6 @@ export const tareaCommandFunction = async ({
command.text
);

console.log('submissionHasSingleFormat: ', submissionHasSingleFormat);

if (!submissionHasSingleFormat) {
await respond(multipleSubmissionFormatsDetected());
return;
Expand All @@ -97,11 +85,6 @@ export const tareaCommandFunction = async ({
command.text
);

console.log(
'validateIsNotMultipleSubmissions: ',
validateIsNotMultipleSubmissions
);

if (!validateIsNotMultipleSubmissions && command.text.includes('```')) {
await respond(multipleBlocksOfCodeDetected());
return;
Expand All @@ -120,17 +103,13 @@ export const tareaCommandFunction = async ({
delivery: command.text,
});

console.log('validSubmissionFormat: ', validSubmissionFormat);

if (!validSubmissionFormat) {
await respond(wrongFormatBlock());
return;
}

const onlySubmissionContent = extractOnlySubmission(command.text);

console.log('onlySubmissionContent: ', onlySubmissionContent);

if (command.text && validSubmissionFormat) {
const tarea = await uploadTarea({
classNumber,
Expand All @@ -141,22 +120,18 @@ export const tareaCommandFunction = async ({
email: user.profile.email as string,
});

console.log('tarea: ', tarea);
console.log('uploadTarea property "classNumber": ', classNumber);
console.log('uploadTarea property "slackId": ', user.id);
console.log('uploadTarea property "delivery": ', onlySubmissionContent);
console.log(
'uploadTarea property "firstName": ',
user.profile.first_name
);
console.log('uploadTarea property "lastName": ', user.profile.last_name);
console.log('uploadTarea property "email": ', user.profile.email);

const messageResponse = await say(
`Tarea subida con éxito <@${
user.id
}>!\n\nTarea:\n${command.text.trim()}\n\n*Para agregar correcciones responder en este hilo.*`
);
const cheatsheet =
assignmentCheatsheet[classNumber as keyof typeof assignmentCheatsheet];

const submissionResponse = cheatsheet
? `Tarea subida con éxito <@${
user.id
}>!\n\nTarea:\n${command.text.trim()}\n\nTe recomendamos leer las siguientes <${cheatsheet} | notas> que pueden ayudarte a solucionar errores comunes. \n\n*Para agregar correcciones responder en este hilo (no en el mensaje original).*`
: `Tarea subida con éxito <@${
user.id
}>!\n\nTarea:\n${command.text.trim()}\n\n*Para agregar correcciones responder en este hilo (no en el mensaje original).*`;

const messageResponse = await say(submissionResponse);

console.log('messageResponse: ', messageResponse);

Expand All @@ -168,13 +143,6 @@ export const tareaCommandFunction = async ({
taskId: tarea.taskId,
};

console.log('thread: ', thread);
console.log('thread property "authorId": ', process.env.BOT_ID!);
console.log('thread property "studentId": ', tarea.studentId);
console.log('thread property "text": ', messageResponse.message?.text);
console.log('thread property "timestamp": ', messageResponse.ts);
console.log('thread property "taskId": ', tarea.taskId);

await threadApi.create(thread);
}
} catch (error) {
Expand Down
98 changes: 96 additions & 2 deletions src/events/reaction/__test__/handleRobotFaceReaction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
import { ISubmissionResponse } from '../../../api/marketplace/submission/ISubmissionResponse';
import threadApi from '../../../api/marketplace/thread/threadApi';
import env from '../../../config/env.config';
import { assignmentCheatsheet } from '../../../utils/assignmentCheatsheet';

jest.mock('../../../commands/tarea/uploadTarea');
jest.mock('../../../api/marketplace/user/userApi');
Expand Down Expand Up @@ -113,7 +114,7 @@ describe('handleRobotFaceReaction', () => {
expect(clientMock.chat.postMessage).toBeCalledTimes(2);
expect(clientMock.chat.postMessage).toHaveBeenNthCalledWith(1, {
channel: messageAuthorEvent.item.channel,
text: `Tarea subida con éxito <@${messageAuthorEvent.item_user}>! \n\nAcá está el <${chatGetPermalinkResponse.permalink}|Link> al mensaje original.\n\n*Para agregar correcciones responder en este hilo (no en el mensaje original).*`,
text: `Tarea subida con éxito <@${messageAuthorEvent.item_user}>! \n\nAcá está el <${chatGetPermalinkResponse.permalink}|Link> al mensaje original. Te recomendamos leer las siguientes <${assignmentCheatsheet['1']} | notas> que pueden ayudarte a solucionar errores comunes. \n\n*Para agregar correcciones responder en este hilo (no en el mensaje original).*`,
});
expect(clientMock.chat.postMessage).toHaveBeenNthCalledWith(2, {
channel: messageAuthorEvent.item.channel,
Expand Down Expand Up @@ -214,7 +215,7 @@ describe('handleRobotFaceReaction', () => {
expect(clientMock.chat.postMessage).toBeCalledTimes(2);
expect(clientMock.chat.postMessage).toHaveBeenNthCalledWith(1, {
channel: randomUserEvent.item.channel,
text: `Tarea subida con éxito <@${randomUserEvent.item_user}>! \n\nAcá está el <${chatGetPermalinkResponse.permalink}|Link> al mensaje original.\n\n*Para agregar correcciones responder en este hilo (no en el mensaje original).*`,
text: `Tarea subida con éxito <@${messageAuthorEvent.item_user}>! \n\nAcá está el <${chatGetPermalinkResponse.permalink}|Link> al mensaje original. Te recomendamos leer las siguientes <${assignmentCheatsheet['1']} | notas> que pueden ayudarte a solucionar errores comunes. \n\n*Para agregar correcciones responder en este hilo (no en el mensaje original).*`,
});
expect(clientMock.chat.postMessage).toHaveBeenNthCalledWith(2, {
channel: randomUserEvent.item.channel,
Expand Down Expand Up @@ -274,6 +275,99 @@ describe('handleRobotFaceReaction', () => {
expect(clientMock.reactions.add).toBeCalledTimes(0);
expect(loggerMock.error).toBeCalledTimes(0);
});

it("should not send a cheatsheet as part of the response if the lesson doesn't have one", async () => {
const typeCodeText = 'console.log("Hello World!!!")';

const submissionResponseMock = {
completed: false,
delivery: typeCodeText,
studentId: 1,
taskId: 3,
id: 1,
isActive: true,
viewer: undefined,
} as ISubmissionResponse;

clientMock.conversations.history.mockResolvedValueOnce(
// @ts-ignore
conversationsHistoryResponse
);

clientMock.users.info.mockResolvedValueOnce(
// @ts-ignore
usersInfoResponse
);

clientMock.conversations.info.mockResolvedValueOnce(
// @ts-ignore
{
channel: {
...conversationsInfoResponse,
name: 'clase-3',
name_normalized: 'clase-3',
},
}
);

uploadTareaMock.mockResolvedValueOnce(submissionResponseMock);

clientMock.chat.getPermalink.mockResolvedValueOnce(
// @ts-ignore
chatGetPermalinkResponse
);

clientMock.chat.postMessage.mockResolvedValueOnce(
// @ts-ignore
chatPostMessageResponse
);

await handleRobotFaceReaction({
client: clientMock,
// @ts-ignore
event: messageAuthorEvent,
logger: loggerMock,
});

expect(uploadTareaMock).toBeCalledTimes(1);
expect(uploadTareaMock).toHaveBeenCalledWith({
classNumber: '3',
delivery: typeCodeText,
slackId: messageAuthorEvent.item_user,
firstName: usersInfoResponse.user.profile.first_name,
lastName: usersInfoResponse.user.profile.last_name,
email: usersInfoResponse.user.profile.email,
});

expect(clientMock.chat.postMessage).toBeCalledTimes(2);
expect(clientMock.chat.postMessage).toHaveBeenNthCalledWith(1, {
channel: messageAuthorEvent.item.channel,
text: `Tarea subida con éxito <@${messageAuthorEvent.item_user}>! \n\nAcá está el <${chatGetPermalinkResponse.permalink}|Link> al mensaje original.\n\n*Para agregar correcciones responder en este hilo (no en el mensaje original).*`,
});
expect(clientMock.chat.postMessage).toHaveBeenNthCalledWith(2, {
channel: messageAuthorEvent.item.channel,
text: 'Si querés agregar una corrección a esta tarea hacelo como una respuesta al mensaje que mandó el bot.',
thread_ts: messageAuthorEvent.item.ts,
});

expect(threadApi.create).toHaveBeenCalledTimes(1);
expect(threadApi.create).toHaveBeenCalledWith({
authorId: env.BOT_ID,
studentId: submissionResponseMock.studentId,
taskId: submissionResponseMock.taskId,
text: chatPostMessageResponse.message.text,
timestamp: chatPostMessageResponse.ts,
});

expect(clientMock.reactions.add).toBeCalledTimes(1);
expect(clientMock.reactions.add).toBeCalledWith({
channel: messageAuthorEvent.item.channel,
name: 'white_check_mark',
timestamp: messageAuthorEvent.item.ts,
});

expect(loggerMock.error).toBeCalledTimes(0);
});
});

describe('Submission types', () => {
Expand Down
Loading
Loading