Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
189 changes: 189 additions & 0 deletions __tests__/core/useRcbPlugin.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import { renderHook, fireEvent } from "@testing-library/react";
import { validateFile } from "../../src/utils/validateFile";
import { getValidator } from "../../src/utils/getValidator";
import useRcbPlugin from "../../src/core/useRcbPlugin";

const mockReplaceStyles = jest.fn();
// Mock react-chatbotify dependencies
jest.mock("react-chatbotify", () => ({
useToasts: jest.fn(() => ({ showToast: mockShowToast })),
useBotId: jest.fn(() => ({ getBotId: jest.fn().mockReturnValue("bot-id") })),
useFlow: jest.fn(() => ({ getFlow: jest.fn() })),
useStyles: jest.fn(() => ({
styles: {},
updateStyles: jest.fn(),
replaceStyles: mockReplaceStyles,
})),
}));

jest.mock("../../src/utils/validateFile", () => ({
validateFile: jest.fn(),
}));

jest.mock("../../src/utils/getValidator", () => ({
getValidator: jest.fn(),
}));

const mockedValidateFile = validateFile as jest.Mock;
const mockedGetValidator = getValidator as jest.Mock;


mockedValidateFile.mockReturnValue({
success: false,
promptContent: "Invalid file type",
});

mockedGetValidator.mockReturnValue(mockedValidateFile);

const mockShowToast = jest.fn();

describe("useRcbPlugin", () => {
beforeEach(() => {
jest.clearAllMocks(); // Clear mocks before each test
});

test("handles file upload and displays error for invalid file", () => {
const mockFile = new File(["invalid content"], "test.txt", { type: "text/plain" });

// Mock validateFile behavior
mockedValidateFile.mockReturnValue({
success: false,
promptContent: "Invalid file type",
});

// Render the hook
renderHook(() => useRcbPlugin());

// Simulate file upload event
const uploadEvent = new Event("rcb-user-upload-file");
(uploadEvent as any).data = { files: [mockFile] };

Check failure on line 59 in __tests__/core/useRcbPlugin.test.ts

View workflow job for this annotation

GitHub Actions / CI / Run Lint

Unexpected any. Specify a different type
fireEvent(window, uploadEvent);

// Debugging output
console.log("validateFile calls:", mockedValidateFile.mock.calls);
console.log("showToast calls:", mockShowToast.mock.calls);

// Assertions
expect(mockedValidateFile).toHaveBeenCalledWith(mockFile);
expect(mockShowToast).toHaveBeenCalledWith("Invalid file type", 3000);
});

test("handles file upload and does nothing for valid file", () => {
const mockFile = new File(["valid content"], "test.png", { type: "image/png" });

// Mock validateFile to return success
(validateFile as jest.Mock).mockReturnValue({
success: true,
});

// Mock getValidator to return the validateFile function
(getValidator as jest.Mock).mockReturnValue(validateFile);

renderHook(() => useRcbPlugin());

// Simulate file upload event
const uploadEvent = new Event("rcb-user-upload-file");
(uploadEvent as any).data = { files: [mockFile] }; // Attach mock data

Check failure on line 86 in __tests__/core/useRcbPlugin.test.ts

View workflow job for this annotation

GitHub Actions / CI / Run Lint

Unexpected any. Specify a different type
fireEvent(window, uploadEvent);

// Assertions
expect(validateFile).toHaveBeenCalledWith(mockFile);
expect(mockShowToast).not.toHaveBeenCalled(); // No toast for valid file
});

test("handles text input and displays error for invalid input", () => {
const mockValidator = jest.fn().mockReturnValue({
success: false,
promptContent: "Invalid input",
});

// Mock getValidator to return the text validator
mockedGetValidator.mockReturnValue(mockValidator);

renderHook(() => useRcbPlugin());

// Simulate text input event
const textEvent = new Event("rcb-user-submit-text");
(textEvent as any).data = { inputText: "invalid text" };

Check failure on line 107 in __tests__/core/useRcbPlugin.test.ts

View workflow job for this annotation

GitHub Actions / CI / Run Lint

Unexpected any. Specify a different type
fireEvent(window, textEvent);

// Assertions
expect(mockValidator).toHaveBeenCalledWith("invalid text");
expect(mockShowToast).toHaveBeenCalledWith("Invalid input", 3000);
});

test("handles text input and does nothing for valid input", () => {
const mockValidator = jest.fn().mockReturnValue({ success: true });

// Mock getValidator to return the text validator
mockedGetValidator.mockReturnValue(mockValidator);

renderHook(() => useRcbPlugin());

// Simulate text input event
const textEvent = new Event("rcb-user-submit-text");
(textEvent as any).data = { inputText: "valid input" };

Check failure on line 125 in __tests__/core/useRcbPlugin.test.ts

View workflow job for this annotation

GitHub Actions / CI / Run Lint

Unexpected any. Specify a different type
fireEvent(window, textEvent);

// Assertions
expect(mockValidator).toHaveBeenCalledWith("valid input");
expect(mockShowToast).not.toHaveBeenCalled(); // No toast for valid input
});

test("handles empty text input validation", () => {
const mockValidator = jest.fn().mockReturnValue({
success: false,
promptContent: "Input cannot be empty",
});

mockedGetValidator.mockReturnValue(mockValidator);

renderHook(() => useRcbPlugin());

const textEvent = new Event("rcb-user-submit-text");
(textEvent as any).data = { inputText: "" };

Check failure on line 144 in __tests__/core/useRcbPlugin.test.ts

View workflow job for this annotation

GitHub Actions / CI / Run Lint

Unexpected any. Specify a different type
fireEvent(window, textEvent);

// Assertions
expect(mockValidator).toHaveBeenCalledWith("");
expect(mockShowToast).toHaveBeenCalledWith("Input cannot be empty", 3000);
});

test("handles null file upload", () => {
renderHook(() => useRcbPlugin());

const uploadEvent = new Event("rcb-user-upload-file");
(uploadEvent as any).data = { files: null };

Check failure on line 156 in __tests__/core/useRcbPlugin.test.ts

View workflow job for this annotation

GitHub Actions / CI / Run Lint

Unexpected any. Specify a different type
fireEvent(window, uploadEvent);

// Assertions
expect(mockedValidateFile).not.toHaveBeenCalled();
expect(mockShowToast).not.toHaveBeenCalled();
});

test("handles empty file upload", () => {
renderHook(() => useRcbPlugin());

// Simulate empty file upload event
const uploadEvent = new Event("rcb-user-upload-file");
(uploadEvent as any).data = { files: [] };

Check failure on line 169 in __tests__/core/useRcbPlugin.test.ts

View workflow job for this annotation

GitHub Actions / CI / Run Lint

Unexpected any. Specify a different type
fireEvent(window, uploadEvent);

// Assertions
expect(mockedValidateFile).not.toHaveBeenCalled();
expect(mockShowToast).not.toHaveBeenCalled(); // No toast for empty file list
});
test("restores styles after all toasts are dismissed", () => {
renderHook(() => useRcbPlugin());

// Simulate toast dismissal event
const dismissEvent = new Event("rcb-dismiss-toast");
fireEvent(window, dismissEvent);

// Verify that styles are restored
setTimeout(() => {
expect(mockReplaceStyles).toHaveBeenCalled();
}, 0);
});

});
141 changes: 141 additions & 0 deletions __tests__/utils/getPromptStyles.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import { getPromptStyles } from "../../src/utils/getPromptStyles";
import { PluginConfig } from "../../src/types/PluginConfig";

test("applies error styles when promptType is 'error'", () => {
const mockPluginConfig: PluginConfig = {
promptBaseColors: {
error: "red",
},
textAreaHighlightColors: {
error: "red",
},
};

const validationResult = {
success: false,
promptType: "error",
highlightTextArea: true,
};

const result = getPromptStyles(validationResult, mockPluginConfig);

// Debugging output to verify the structure of the result
console.log("Result from getPromptStyles:", result);

expect(result).toEqual(
expect.objectContaining({
toastPromptStyle: expect.objectContaining({
color: "red",
borderColor: "red",
}),
chatInputAreaStyle: expect.objectContaining({
boxShadow: "red 0px 0px 5px",
}),
})
);
});

test("applies default styles when promptType is not provided", () => {
const mockPluginConfig: PluginConfig = {
promptBaseColors: {
info: "blue",
},
};

const validationResult = {
success: true, // No promptType provided
};

const result = getPromptStyles(validationResult, mockPluginConfig);

expect(result).toEqual(
expect.objectContaining({
toastPromptStyle: expect.objectContaining({
color: "blue",
borderColor: "blue",
}),
})
);
});

test("applies advancedStyles when available for the promptType", () => {
const mockPluginConfig: PluginConfig = {
advancedStyles: {
error: {
toastPromptStyle: {
backgroundColor: "darkred",
},
},
},
};

const validationResult = {
success: false,
promptType: "error",
};

const result = getPromptStyles(validationResult, mockPluginConfig);

expect(result).toEqual(
expect.objectContaining({
toastPromptStyle: {
backgroundColor: "darkred",
},
})
);
});

test("applies hovered colors when promptHoveredColors is provided", () => {
const mockPluginConfig: PluginConfig = {
promptHoveredColors: {
success: "green",
},
};

const validationResult = {
success: true,
promptType: "success",
};

const result = getPromptStyles(validationResult, mockPluginConfig);

expect(result).toEqual(
expect.objectContaining({
toastPromptHoveredStyle: {
color: "green",
borderColor: "green",
},
})
);
});

test("does not apply chat input highlight when highlightTextArea is false", () => {
const mockPluginConfig: PluginConfig = {
textAreaHighlightColors: {
error: "red",
},
};

const validationResult = {
success: false,
promptType: "error",
highlightTextArea: false,
};

const result = getPromptStyles(validationResult, mockPluginConfig);

expect(result.chatInputAreaStyle).toBeUndefined();
});
test("returns an empty object when pluginConfig is empty", () => {
const mockPluginConfig: PluginConfig = {};

const validationResult = {
success: true,
promptType: "success",
};

const result = getPromptStyles(validationResult, mockPluginConfig);

expect(result).toEqual({});
});

Loading