Skip to content

Commit d7d2afb

Browse files
committed
Added Test-cases InputValidator Plugin
1 parent 9a2b04d commit d7d2afb

29 files changed

+7811
-230
lines changed
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
import { renderHook, fireEvent } from "@testing-library/react";
2+
import { validateFile } from "../../src/utils/validateFile";
3+
import { getValidator } from "../../src/utils/getValidator";
4+
import useRcbPlugin from "../../src/core/useRcbPlugin";
5+
6+
const mockReplaceStyles = jest.fn();
7+
// Mock react-chatbotify dependencies
8+
jest.mock("react-chatbotify", () => ({
9+
useToasts: jest.fn(() => ({ showToast: mockShowToast })),
10+
useBotId: jest.fn(() => ({ getBotId: jest.fn().mockReturnValue("bot-id") })),
11+
useFlow: jest.fn(() => ({ getFlow: jest.fn() })),
12+
useStyles: jest.fn(() => ({
13+
styles: {},
14+
updateStyles: jest.fn(),
15+
replaceStyles: mockReplaceStyles,
16+
})),
17+
}));
18+
19+
jest.mock("../../src/utils/validateFile", () => ({
20+
validateFile: jest.fn(),
21+
}));
22+
23+
jest.mock("../../src/utils/getValidator", () => ({
24+
getValidator: jest.fn(),
25+
}));
26+
27+
const mockedValidateFile = validateFile as jest.Mock;
28+
const mockedGetValidator = getValidator as jest.Mock;
29+
30+
31+
mockedValidateFile.mockReturnValue({
32+
success: false,
33+
promptContent: "Invalid file type",
34+
});
35+
36+
mockedGetValidator.mockReturnValue(mockedValidateFile);
37+
38+
const mockShowToast = jest.fn();
39+
40+
describe("useRcbPlugin", () => {
41+
beforeEach(() => {
42+
jest.clearAllMocks(); // Clear mocks before each test
43+
});
44+
45+
test("handles file upload and displays error for invalid file", () => {
46+
const mockFile = new File(["invalid content"], "test.txt", { type: "text/plain" });
47+
48+
// Mock validateFile behavior
49+
mockedValidateFile.mockReturnValue({
50+
success: false,
51+
promptContent: "Invalid file type",
52+
});
53+
54+
// Render the hook
55+
renderHook(() => useRcbPlugin());
56+
57+
// Simulate file upload event
58+
const uploadEvent = new Event("rcb-user-upload-file");
59+
(uploadEvent as any).data = { files: [mockFile] };
60+
fireEvent(window, uploadEvent);
61+
62+
// Debugging output
63+
console.log("validateFile calls:", mockedValidateFile.mock.calls);
64+
console.log("showToast calls:", mockShowToast.mock.calls);
65+
66+
// Assertions
67+
expect(mockedValidateFile).toHaveBeenCalledWith(mockFile);
68+
expect(mockShowToast).toHaveBeenCalledWith("Invalid file type", 3000);
69+
});
70+
71+
test("handles file upload and does nothing for valid file", () => {
72+
const mockFile = new File(["valid content"], "test.png", { type: "image/png" });
73+
74+
// Mock validateFile to return success
75+
(validateFile as jest.Mock).mockReturnValue({
76+
success: true,
77+
});
78+
79+
// Mock getValidator to return the validateFile function
80+
(getValidator as jest.Mock).mockReturnValue(validateFile);
81+
82+
renderHook(() => useRcbPlugin());
83+
84+
// Simulate file upload event
85+
const uploadEvent = new Event("rcb-user-upload-file");
86+
(uploadEvent as any).data = { files: [mockFile] }; // Attach mock data
87+
fireEvent(window, uploadEvent);
88+
89+
// Assertions
90+
expect(validateFile).toHaveBeenCalledWith(mockFile);
91+
expect(mockShowToast).not.toHaveBeenCalled(); // No toast for valid file
92+
});
93+
94+
test("handles text input and displays error for invalid input", () => {
95+
const mockValidator = jest.fn().mockReturnValue({
96+
success: false,
97+
promptContent: "Invalid input",
98+
});
99+
100+
// Mock getValidator to return the text validator
101+
mockedGetValidator.mockReturnValue(mockValidator);
102+
103+
renderHook(() => useRcbPlugin());
104+
105+
// Simulate text input event
106+
const textEvent = new Event("rcb-user-submit-text");
107+
(textEvent as any).data = { inputText: "invalid text" };
108+
fireEvent(window, textEvent);
109+
110+
// Assertions
111+
expect(mockValidator).toHaveBeenCalledWith("invalid text");
112+
expect(mockShowToast).toHaveBeenCalledWith("Invalid input", 3000);
113+
});
114+
115+
test("handles text input and does nothing for valid input", () => {
116+
const mockValidator = jest.fn().mockReturnValue({ success: true });
117+
118+
// Mock getValidator to return the text validator
119+
mockedGetValidator.mockReturnValue(mockValidator);
120+
121+
renderHook(() => useRcbPlugin());
122+
123+
// Simulate text input event
124+
const textEvent = new Event("rcb-user-submit-text");
125+
(textEvent as any).data = { inputText: "valid input" };
126+
fireEvent(window, textEvent);
127+
128+
// Assertions
129+
expect(mockValidator).toHaveBeenCalledWith("valid input");
130+
expect(mockShowToast).not.toHaveBeenCalled(); // No toast for valid input
131+
});
132+
133+
test("handles empty text input validation", () => {
134+
const mockValidator = jest.fn().mockReturnValue({
135+
success: false,
136+
promptContent: "Input cannot be empty",
137+
});
138+
139+
mockedGetValidator.mockReturnValue(mockValidator);
140+
141+
renderHook(() => useRcbPlugin());
142+
143+
const textEvent = new Event("rcb-user-submit-text");
144+
(textEvent as any).data = { inputText: "" };
145+
fireEvent(window, textEvent);
146+
147+
// Assertions
148+
expect(mockValidator).toHaveBeenCalledWith("");
149+
expect(mockShowToast).toHaveBeenCalledWith("Input cannot be empty", 3000);
150+
});
151+
152+
test("handles null file upload", () => {
153+
renderHook(() => useRcbPlugin());
154+
155+
const uploadEvent = new Event("rcb-user-upload-file");
156+
(uploadEvent as any).data = { files: null };
157+
fireEvent(window, uploadEvent);
158+
159+
// Assertions
160+
expect(mockedValidateFile).not.toHaveBeenCalled();
161+
expect(mockShowToast).not.toHaveBeenCalled();
162+
});
163+
164+
test("handles empty file upload", () => {
165+
renderHook(() => useRcbPlugin());
166+
167+
// Simulate empty file upload event
168+
const uploadEvent = new Event("rcb-user-upload-file");
169+
(uploadEvent as any).data = { files: [] };
170+
fireEvent(window, uploadEvent);
171+
172+
// Assertions
173+
expect(mockedValidateFile).not.toHaveBeenCalled();
174+
expect(mockShowToast).not.toHaveBeenCalled(); // No toast for empty file list
175+
});
176+
test("restores styles after all toasts are dismissed", () => {
177+
renderHook(() => useRcbPlugin());
178+
179+
// Simulate toast dismissal event
180+
const dismissEvent = new Event("rcb-dismiss-toast");
181+
fireEvent(window, dismissEvent);
182+
183+
// Verify that styles are restored
184+
setTimeout(() => {
185+
expect(mockReplaceStyles).toHaveBeenCalled();
186+
}, 0);
187+
});
188+
189+
});
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import { getPromptStyles } from "../../src/utils/getPromptStyles";
2+
import { PluginConfig } from "../../src/types/PluginConfig";
3+
4+
test("applies error styles when promptType is 'error'", () => {
5+
const mockPluginConfig: PluginConfig = {
6+
promptBaseColors: {
7+
error: "red",
8+
},
9+
textAreaHighlightColors: {
10+
error: "red",
11+
},
12+
};
13+
14+
const validationResult = {
15+
success: false,
16+
promptType: "error",
17+
highlightTextArea: true,
18+
};
19+
20+
const result = getPromptStyles(validationResult, mockPluginConfig);
21+
22+
// Debugging output to verify the structure of the result
23+
console.log("Result from getPromptStyles:", result);
24+
25+
expect(result).toEqual(
26+
expect.objectContaining({
27+
toastPromptStyle: expect.objectContaining({
28+
color: "red",
29+
borderColor: "red",
30+
}),
31+
chatInputAreaStyle: expect.objectContaining({
32+
boxShadow: "red 0px 0px 5px",
33+
}),
34+
})
35+
);
36+
});
37+
38+
test("applies default styles when promptType is not provided", () => {
39+
const mockPluginConfig: PluginConfig = {
40+
promptBaseColors: {
41+
info: "blue",
42+
},
43+
};
44+
45+
const validationResult = {
46+
success: true, // No promptType provided
47+
};
48+
49+
const result = getPromptStyles(validationResult, mockPluginConfig);
50+
51+
expect(result).toEqual(
52+
expect.objectContaining({
53+
toastPromptStyle: expect.objectContaining({
54+
color: "blue",
55+
borderColor: "blue",
56+
}),
57+
})
58+
);
59+
});
60+
61+
test("applies advancedStyles when available for the promptType", () => {
62+
const mockPluginConfig: PluginConfig = {
63+
advancedStyles: {
64+
error: {
65+
toastPromptStyle: {
66+
backgroundColor: "darkred",
67+
},
68+
},
69+
},
70+
};
71+
72+
const validationResult = {
73+
success: false,
74+
promptType: "error",
75+
};
76+
77+
const result = getPromptStyles(validationResult, mockPluginConfig);
78+
79+
expect(result).toEqual(
80+
expect.objectContaining({
81+
toastPromptStyle: {
82+
backgroundColor: "darkred",
83+
},
84+
})
85+
);
86+
});
87+
88+
test("applies hovered colors when promptHoveredColors is provided", () => {
89+
const mockPluginConfig: PluginConfig = {
90+
promptHoveredColors: {
91+
success: "green",
92+
},
93+
};
94+
95+
const validationResult = {
96+
success: true,
97+
promptType: "success",
98+
};
99+
100+
const result = getPromptStyles(validationResult, mockPluginConfig);
101+
102+
expect(result).toEqual(
103+
expect.objectContaining({
104+
toastPromptHoveredStyle: {
105+
color: "green",
106+
borderColor: "green",
107+
},
108+
})
109+
);
110+
});
111+
112+
test("does not apply chat input highlight when highlightTextArea is false", () => {
113+
const mockPluginConfig: PluginConfig = {
114+
textAreaHighlightColors: {
115+
error: "red",
116+
},
117+
};
118+
119+
const validationResult = {
120+
success: false,
121+
promptType: "error",
122+
highlightTextArea: false,
123+
};
124+
125+
const result = getPromptStyles(validationResult, mockPluginConfig);
126+
127+
expect(result.chatInputAreaStyle).toBeUndefined();
128+
});
129+
test("returns an empty object when pluginConfig is empty", () => {
130+
const mockPluginConfig: PluginConfig = {};
131+
132+
const validationResult = {
133+
success: true,
134+
promptType: "success",
135+
};
136+
137+
const result = getPromptStyles(validationResult, mockPluginConfig);
138+
139+
expect(result).toEqual({});
140+
});
141+

0 commit comments

Comments
 (0)