[Query Copilot V2] Unit tests for V2 Copilot (#1580)

* Add tests for V2 of copilot and fix query parameter feature flag

* Fix merge changes
This commit is contained in:
v-darkora 2023-08-21 16:29:00 +02:00 committed by GitHub
parent ebd40cb9b0
commit 19100ec437
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 886 additions and 377 deletions

View File

@ -1,10 +1,26 @@
import { Text } from "@fluentui/react";
import { shallow } from "enzyme"; import { shallow } from "enzyme";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import React from "react"; import React from "react";
import { SampleBubble } from "./SampleBubble"; import { SampleBubble } from "./SampleBubble";
describe("Sample Bubble snapshot test", () => { describe("Sample Bubble snapshot test", () => {
it("should render ", () => { it("should render", () => {
const wrapper = shallow(<SampleBubble />); const wrapper = shallow(<SampleBubble />);
const sampleInputs = wrapper.find(Text);
expect(sampleInputs.length).toEqual(2);
expect(useQueryCopilot.getState().userPrompt).toEqual("");
expect(wrapper).toMatchSnapshot();
});
it("should render and be clicked", () => {
const wrapper = shallow(<SampleBubble />);
const firstSampleInput = wrapper.find(Text).first();
firstSampleInput.simulate("click", {}, "");
expect(useQueryCopilot.getState().userPrompt).toEqual(expect.any(String));
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
}); });

View File

@ -1,6 +1,54 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Sample Bubble snapshot test should render 1`] = ` exports[`Sample Bubble snapshot test should render 1`] = `
<Stack
horizontalAlign="end"
style={
Object {
"alignItems": "center",
"display": "flex",
"margin": "10px",
"padding": "10px",
}
}
verticalAlign="end"
>
<Text
key="0"
onClick={[Function]}
style={
Object {
"border": "1.5px solid #B0BEFF",
"borderRadius": "4px",
"cursor": "pointer",
"marginBottom": "5px",
"padding": "2px",
"width": "100%",
}
}
>
Write a query to return last 10 records in the database
</Text>
<Text
key="1"
onClick={[Function]}
style={
Object {
"border": "1.5px solid #B0BEFF",
"borderRadius": "4px",
"cursor": "pointer",
"marginBottom": "5px",
"padding": "2px",
"width": "100%",
}
}
>
Write a query to return all records in this table created in the last thirty days which also have the record owner as "Contoso"
</Text>
</Stack>
`;
exports[`Sample Bubble snapshot test should render and be clicked 1`] = `
<Stack <Stack
horizontalAlign="end" horizontalAlign="end"
style={ style={

View File

@ -1,10 +1,84 @@
import { IconButton, Image, TextField } from "@fluentui/react";
import { shallow } from "enzyme"; import { shallow } from "enzyme";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import React from "react"; import React from "react";
import { Footer } from "./Footer"; import { Footer } from "./Footer";
describe("Footer snapshot test", () => { describe("Footer snapshot test", () => {
it("should render ", () => { const initialStoreState = useQueryCopilot.getState();
beforeEach(() => {
useQueryCopilot.setState(initialStoreState, true);
});
it("should open sample prompts on button click", () => {
const wrapper = shallow(<Footer />); const wrapper = shallow(<Footer />);
const samplePromptsImage = wrapper.find(Image).first();
samplePromptsImage.simulate("click", {});
expect(useQueryCopilot.getState().isSamplePromptsOpen).toBeTruthy();
expect(wrapper).toMatchSnapshot();
});
it("should update user input", () => {
const wrapper = shallow(<Footer />);
const newInput = "some new input";
const textInput = wrapper.find(TextField).first();
textInput.simulate("change", {}, newInput);
expect(useQueryCopilot.getState().userPrompt).toEqual(newInput);
expect(wrapper).toMatchSnapshot();
});
it("should pass text with enter key", () => {
const testMessage = "test message";
useQueryCopilot.getState().setUserPrompt(testMessage);
const wrapper = shallow(<Footer />);
const textInput = wrapper.find(TextField).first();
// eslint-disable-next-line @typescript-eslint/no-empty-function
textInput.simulate("keydown", { key: "Enter", shiftKey: false, preventDefault: () => {} });
expect(useQueryCopilot.getState().chatMessages).toEqual([testMessage]);
expect(useQueryCopilot.getState().userPrompt).toEqual("");
expect(wrapper).toMatchSnapshot();
});
it("should not pass text with non enter key", () => {
const wrapper = shallow(<Footer />);
const textInput = wrapper.find(TextField).first();
// eslint-disable-next-line @typescript-eslint/no-empty-function
textInput.simulate("keydown", { key: "K", shiftKey: false, preventDefault: () => {} });
expect(useQueryCopilot.getState().chatMessages).toEqual([]);
expect(useQueryCopilot.getState().userPrompt).toEqual("");
expect(wrapper).toMatchSnapshot();
});
it("should not pass if no text", () => {
const wrapper = shallow(<Footer />);
const textInput = wrapper.find(TextField).first();
// eslint-disable-next-line @typescript-eslint/no-empty-function
textInput.simulate("keydown", { key: "Enter", shiftKey: false, preventDefault: () => {} });
expect(useQueryCopilot.getState().chatMessages).toEqual([]);
expect(useQueryCopilot.getState().userPrompt).toEqual("");
expect(wrapper).toMatchSnapshot();
});
it("should pass text with icon button", () => {
const testMessage = "test message";
useQueryCopilot.getState().setUserPrompt(testMessage);
const wrapper = shallow(<Footer />);
const iconButton = wrapper.find(IconButton).first();
iconButton.simulate("click", {});
expect(useQueryCopilot.getState().chatMessages).toEqual([testMessage]);
expect(useQueryCopilot.getState().userPrompt).toEqual("");
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
}); });

View File

@ -1,6 +1,421 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Footer snapshot test should render 1`] = ` exports[`Footer snapshot test should not pass if no text 1`] = `
<Stack
horizontal={true}
horizontalAlign="end"
style={
Object {
"alignItems": "center",
"background": "white",
"borderRadius": "20px",
"display": "flex",
"margin": "5px",
"padding": "5px",
}
}
verticalAlign="end"
>
<Stack>
<Image
onClick={[Function]}
src=""
styles={
Object {
"label": Object {
"fontWeight": 400,
"paddingLeft": 8,
"textAlign": "left",
},
"root": Object {
"border": "5px",
"selectors": Object {
":hover": Object {
"outline": "1px dashed #605e5c",
},
},
},
}
}
/>
<SamplePrompts
sampleProps={
Object {
"isSamplePromptsOpen": false,
"setIsSamplePromptsOpen": [Function],
"setTextBox": [Function],
}
}
/>
</Stack>
<StyledTextFieldBase
multiline={true}
onChange={[Function]}
onKeyDown={[Function]}
placeholder="Write your own prompt or ask a question"
resizable={false}
styles={
Object {
"fieldGroup": Object {
"border": "none",
},
"root": Object {
"border": "none",
"borderRadius": "20px",
"height": "80px",
"marginLeft": "10px",
"outline": "none",
"padding": "8px",
"width": "100%",
},
}
}
value=""
/>
<CustomizedIconButton
iconProps={
Object {
"iconName": "Send",
}
}
onClick={[Function]}
/>
</Stack>
`;
exports[`Footer snapshot test should not pass text with non enter key 1`] = `
<Stack
horizontal={true}
horizontalAlign="end"
style={
Object {
"alignItems": "center",
"background": "white",
"borderRadius": "20px",
"display": "flex",
"margin": "5px",
"padding": "5px",
}
}
verticalAlign="end"
>
<Stack>
<Image
onClick={[Function]}
src=""
styles={
Object {
"label": Object {
"fontWeight": 400,
"paddingLeft": 8,
"textAlign": "left",
},
"root": Object {
"border": "5px",
"selectors": Object {
":hover": Object {
"outline": "1px dashed #605e5c",
},
},
},
}
}
/>
<SamplePrompts
sampleProps={
Object {
"isSamplePromptsOpen": false,
"setIsSamplePromptsOpen": [Function],
"setTextBox": [Function],
}
}
/>
</Stack>
<StyledTextFieldBase
multiline={true}
onChange={[Function]}
onKeyDown={[Function]}
placeholder="Write your own prompt or ask a question"
resizable={false}
styles={
Object {
"fieldGroup": Object {
"border": "none",
},
"root": Object {
"border": "none",
"borderRadius": "20px",
"height": "80px",
"marginLeft": "10px",
"outline": "none",
"padding": "8px",
"width": "100%",
},
}
}
value=""
/>
<CustomizedIconButton
iconProps={
Object {
"iconName": "Send",
}
}
onClick={[Function]}
/>
</Stack>
`;
exports[`Footer snapshot test should open sample prompts on button click 1`] = `
<Stack
horizontal={true}
horizontalAlign="end"
style={
Object {
"alignItems": "center",
"background": "white",
"borderRadius": "20px",
"display": "flex",
"margin": "5px",
"padding": "5px",
}
}
verticalAlign="end"
>
<Stack>
<Image
onClick={[Function]}
src=""
styles={
Object {
"label": Object {
"fontWeight": 400,
"paddingLeft": 8,
"textAlign": "left",
},
"root": Object {
"border": "5px",
"selectors": Object {
":hover": Object {
"outline": "1px dashed #605e5c",
},
},
},
}
}
/>
<SamplePrompts
sampleProps={
Object {
"isSamplePromptsOpen": false,
"setIsSamplePromptsOpen": [Function],
"setTextBox": [Function],
}
}
/>
</Stack>
<StyledTextFieldBase
multiline={true}
onChange={[Function]}
onKeyDown={[Function]}
placeholder="Write your own prompt or ask a question"
resizable={false}
styles={
Object {
"fieldGroup": Object {
"border": "none",
},
"root": Object {
"border": "none",
"borderRadius": "20px",
"height": "80px",
"marginLeft": "10px",
"outline": "none",
"padding": "8px",
"width": "100%",
},
}
}
value=""
/>
<CustomizedIconButton
iconProps={
Object {
"iconName": "Send",
}
}
onClick={[Function]}
/>
</Stack>
`;
exports[`Footer snapshot test should pass text with enter key 1`] = `
<Stack
horizontal={true}
horizontalAlign="end"
style={
Object {
"alignItems": "center",
"background": "white",
"borderRadius": "20px",
"display": "flex",
"margin": "5px",
"padding": "5px",
}
}
verticalAlign="end"
>
<Stack>
<Image
onClick={[Function]}
src=""
styles={
Object {
"label": Object {
"fontWeight": 400,
"paddingLeft": 8,
"textAlign": "left",
},
"root": Object {
"border": "5px",
"selectors": Object {
":hover": Object {
"outline": "1px dashed #605e5c",
},
},
},
}
}
/>
<SamplePrompts
sampleProps={
Object {
"isSamplePromptsOpen": false,
"setIsSamplePromptsOpen": [Function],
"setTextBox": [Function],
}
}
/>
</Stack>
<StyledTextFieldBase
multiline={true}
onChange={[Function]}
onKeyDown={[Function]}
placeholder="Write your own prompt or ask a question"
resizable={false}
styles={
Object {
"fieldGroup": Object {
"border": "none",
},
"root": Object {
"border": "none",
"borderRadius": "20px",
"height": "80px",
"marginLeft": "10px",
"outline": "none",
"padding": "8px",
"width": "100%",
},
}
}
value="test message"
/>
<CustomizedIconButton
iconProps={
Object {
"iconName": "Send",
}
}
onClick={[Function]}
/>
</Stack>
`;
exports[`Footer snapshot test should pass text with icon button 1`] = `
<Stack
horizontal={true}
horizontalAlign="end"
style={
Object {
"alignItems": "center",
"background": "white",
"borderRadius": "20px",
"display": "flex",
"margin": "5px",
"padding": "5px",
}
}
verticalAlign="end"
>
<Stack>
<Image
onClick={[Function]}
src=""
styles={
Object {
"label": Object {
"fontWeight": 400,
"paddingLeft": 8,
"textAlign": "left",
},
"root": Object {
"border": "5px",
"selectors": Object {
":hover": Object {
"outline": "1px dashed #605e5c",
},
},
},
}
}
/>
<SamplePrompts
sampleProps={
Object {
"isSamplePromptsOpen": false,
"setIsSamplePromptsOpen": [Function],
"setTextBox": [Function],
}
}
/>
</Stack>
<StyledTextFieldBase
multiline={true}
onChange={[Function]}
onKeyDown={[Function]}
placeholder="Write your own prompt or ask a question"
resizable={false}
styles={
Object {
"fieldGroup": Object {
"border": "none",
},
"root": Object {
"border": "none",
"borderRadius": "20px",
"height": "80px",
"marginLeft": "10px",
"outline": "none",
"padding": "8px",
"width": "100%",
},
}
}
value="test message"
/>
<CustomizedIconButton
iconProps={
Object {
"iconName": "Send",
}
}
onClick={[Function]}
/>
</Stack>
`;
exports[`Footer snapshot test should update user input 1`] = `
<Stack <Stack
horizontal={true} horizontal={true}
horizontalAlign="end" horizontalAlign="end"

View File

@ -1,10 +1,17 @@
import { IconButton } from "@fluentui/react";
import { shallow } from "enzyme"; import { shallow } from "enzyme";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import React from "react"; import React from "react";
import { Header } from "./Header"; import { Header } from "./Header";
describe("Header snapshot test", () => { describe("Header snapshot test", () => {
it("should render ", () => { it("should close on button click ", () => {
const wrapper = shallow(<Header />); const wrapper = shallow(<Header />);
const iconButton = wrapper.find(IconButton).first();
iconButton.simulate("click", {});
expect(useQueryCopilot.getState().showCopilotSidebar).toBeFalsy();
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
}); });

View File

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Header snapshot test should render 1`] = ` exports[`Header snapshot test should close on button click 1`] = `
<Stack <Stack
horizontal={true} horizontal={true}
style={ style={

View File

@ -1,10 +1,32 @@
import { PrimaryButton } from "@fluentui/react";
import { shallow } from "enzyme"; import { shallow } from "enzyme";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import { withHooks } from "jest-react-hooks-shallow";
import React from "react"; import React from "react";
import { WelcomeSidebarModal } from "./WelcomeSidebarModal"; import { WelcomeSidebarModal } from "./WelcomeSidebarModal";
describe("WelcomeSidebarModal snapshot test", () => { describe("Welcome Sidebar Modal snapshot test", () => {
it("should render ", () => { it("should close on button click ", () => {
const wrapper = shallow(<WelcomeSidebarModal />); withHooks(() => {
expect(wrapper).toMatchSnapshot(); const wrapper = shallow(<WelcomeSidebarModal />);
const spy = jest.spyOn(localStorage, "setItem");
spy.mockClear();
const button = wrapper.find(PrimaryButton).first();
button.simulate("click", {});
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenLastCalledWith("showWelcomeSidebar", "false");
expect(useQueryCopilot.getState().showWelcomeSidebar).toBeFalsy();
expect(wrapper).toMatchSnapshot();
});
});
it("should not reneder with local storage key", () => {
withHooks(() => {
window.localStorage.setItem("showWelcomeSidebar", "false");
const wrapper = shallow(<WelcomeSidebarModal />);
expect(wrapper).toMatchSnapshot();
});
}); });
}); });

View File

@ -7,9 +7,9 @@ import CopilotSidebarWelcomeIllustration from "../../../../../images/CopilotSide
import Thumb from "../../../../../images/CopilotThumb.svg"; import Thumb from "../../../../../images/CopilotThumb.svg";
export const WelcomeSidebarModal: React.FC = (): JSX.Element => { export const WelcomeSidebarModal: React.FC = (): JSX.Element => {
const { setShowWelcomeSidebar } = useQueryCopilot(); const { showWelcomeSidebar, setShowWelcomeSidebar } = useQueryCopilot();
const hideModal = () => { const hideModal = (): void => {
setShowWelcomeSidebar(false); setShowWelcomeSidebar(false);
window.localStorage.setItem("showWelcomeSidebar", "false"); window.localStorage.setItem("showWelcomeSidebar", "false");
}; };
@ -20,108 +20,111 @@ export const WelcomeSidebarModal: React.FC = (): JSX.Element => {
}, []); }, []);
return ( return (
<Stack showWelcomeSidebar && (
style={{ <Stack
width: "100%",
height: "100%",
overflow: "auto",
backgroundColor: "#FAFAFA",
}}
>
<div
style={{ style={{
margin: "20px 10px", width: "100%",
padding: "20px", height: "100%",
maxHeight: "100%", overflow: "auto",
boxSizing: "border-box", backgroundColor: "#FAFAFA",
borderRadius: "20px", flex: "1 0 100%",
backgroundColor: "white",
}} }}
> >
<Stack horizontalAlign="center" verticalAlign="center"> <div
<Image src={CopilotSidebarWelcomeIllustration} /> style={{
</Stack> margin: "20px 10px",
padding: "20px",
maxHeight: "100%",
boxSizing: "border-box",
borderRadius: "20px",
backgroundColor: "white",
}}
>
<Stack horizontalAlign="center" verticalAlign="center">
<Image src={CopilotSidebarWelcomeIllustration} />
</Stack>
<Stack> <Stack>
<Stack.Item align="center" style={{ marginBottom: "10px" }}> <Stack.Item align="center" style={{ marginBottom: "10px" }}>
<Text className="title bold">Welcome to Copilot in CosmosDB</Text> <Text className="title bold">Welcome to Copilot in CosmosDB</Text>
</Stack.Item> </Stack.Item>
<Stack.Item style={{ marginBottom: "15px" }}> <Stack.Item style={{ marginBottom: "15px" }}>
<Stack> <Stack>
<Stack horizontal> <Stack horizontal>
<Stack.Item align="start"> <Stack.Item align="start">
<Image src={Flash} /> <Image src={Flash} />
</Stack.Item> </Stack.Item>
<Stack.Item align="center" style={{ marginLeft: "10px" }}> <Stack.Item align="center" style={{ marginLeft: "10px" }}>
<Text style={{ fontWeight: 600 }}> <Text style={{ fontWeight: 600 }}>
Let copilot do the work for you Let copilot do the work for you
<br />
</Text>
</Stack.Item>
</Stack>
<Stack.Item style={{ textAlign: "start", marginLeft: "25px" }}>
<Text>
Ask Copilot to generate a query by describing the query in your words.
<br /> <br />
<Link href="http://aka.ms/cdb-copilot-learn-more">Learn more</Link>
</Text> </Text>
</Stack.Item> </Stack.Item>
</Stack> </Stack>
<Stack.Item style={{ textAlign: "start", marginLeft: "25px" }}> </Stack.Item>
<Text> <Stack.Item style={{ marginBottom: "15px" }}>
Ask Copilot to generate a query by describing the query in your words. <Stack>
<br /> <Stack horizontal>
<Link href="http://aka.ms/cdb-copilot-learn-more">Learn more</Link> <Stack.Item align="start">
</Text> <Image src={Thumb} />
</Stack.Item> </Stack.Item>
</Stack> <Stack.Item align="center" style={{ marginLeft: "10px" }}>
</Stack.Item> <Text style={{ fontWeight: 600 }}>
<Stack.Item style={{ marginBottom: "15px" }}> Use your judgement
<Stack> <br />
<Stack horizontal> </Text>
<Stack.Item align="start"> </Stack.Item>
<Image src={Thumb} /> </Stack>
</Stack.Item> <Stack.Item style={{ textAlign: "start", marginLeft: "25px" }}>
<Stack.Item align="center" style={{ marginLeft: "10px" }}> <Text>
<Text style={{ fontWeight: 600 }}> AI-generated content can have mistakes. Make sure its accurate and appropriate before using it.
Use your judgement
<br /> <br />
<Link href="http://aka.ms/cdb-copilot-preview-terms">Read preview terms</Link>
</Text> </Text>
</Stack.Item> </Stack.Item>
</Stack> </Stack>
<Stack.Item style={{ textAlign: "start", marginLeft: "25px" }}> </Stack.Item>
<Text> <Stack.Item style={{ marginBottom: "15px" }}>
AI-generated content can have mistakes. Make sure its accurate and appropriate before using it. <Stack>
<br /> <Stack horizontal>
<Link href="http://aka.ms/cdb-copilot-preview-terms">Read preview terms</Link> <Stack.Item align="start">
</Text> <Image src={Database} />
</Stack.Item> </Stack.Item>
</Stack> <Stack.Item align="center" style={{ marginLeft: "10px" }}>
</Stack.Item> <Text style={{ fontWeight: 600 }}>
<Stack.Item style={{ marginBottom: "15px" }}> Copilot currently works only a sample database
<Stack> <br />
<Stack horizontal> </Text>
<Stack.Item align="start"> </Stack.Item>
<Image src={Database} /> </Stack>
</Stack.Item> <Stack.Item style={{ textAlign: "start", marginLeft: "25px" }}>
<Stack.Item align="center" style={{ marginLeft: "10px" }}> <Text>
<Text style={{ fontWeight: 600 }}> Copilot is setup on a sample database we have configured for you at no cost
Copilot currently works only a sample database
<br /> <br />
<Link href="http://aka.ms/cdb-copilot-learn-more">Learn more</Link>
</Text> </Text>
</Stack.Item> </Stack.Item>
</Stack> </Stack>
<Stack.Item style={{ textAlign: "start", marginLeft: "25px" }}> </Stack.Item>
<Text> </Stack>
Copilot is setup on a sample database we have configured for you at no cost
<br />
<Link href="http://aka.ms/cdb-copilot-learn-more">Learn more</Link>
</Text>
</Stack.Item>
</Stack>
</Stack.Item>
</Stack>
<Stack> <Stack>
<Stack.Item align="center"> <Stack.Item align="center">
<PrimaryButton style={{ width: "224px", height: "32px" }} onClick={hideModal}> <PrimaryButton style={{ width: "224px", height: "32px" }} onClick={hideModal}>
Get Started Get Started
</PrimaryButton> </PrimaryButton>
</Stack.Item> </Stack.Item>
</Stack> </Stack>
</div> </div>
</Stack> </Stack>
)
); );
}; };

View File

@ -1,243 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`WelcomeSidebarModal snapshot test should render 1`] = ` exports[`Welcome Sidebar Modal snapshot test should close on button click 1`] = `""`;
<Stack
style={ exports[`Welcome Sidebar Modal snapshot test should not reneder with local storage key 1`] = `""`;
Object {
"backgroundColor": "#FAFAFA",
"height": "100%",
"overflow": "auto",
"width": "100%",
}
}
>
<div
style={
Object {
"backgroundColor": "white",
"borderRadius": "20px",
"boxSizing": "border-box",
"margin": "20px 10px",
"maxHeight": "100%",
"padding": "20px",
}
}
>
<Stack
horizontalAlign="center"
verticalAlign="center"
>
<Image
src=""
/>
</Stack>
<Stack>
<StackItem
align="center"
style={
Object {
"marginBottom": "10px",
}
}
>
<Text
className="title bold"
>
Welcome to Copilot in CosmosDB
</Text>
</StackItem>
<StackItem
style={
Object {
"marginBottom": "15px",
}
}
>
<Stack>
<Stack
horizontal={true}
>
<StackItem
align="start"
>
<Image
src=""
/>
</StackItem>
<StackItem
align="center"
style={
Object {
"marginLeft": "10px",
}
}
>
<Text
style={
Object {
"fontWeight": 600,
}
}
>
Let copilot do the work for you
<br />
</Text>
</StackItem>
</Stack>
<StackItem
style={
Object {
"marginLeft": "25px",
"textAlign": "start",
}
}
>
<Text>
Ask Copilot to generate a query by describing the query in your words.
<br />
<StyledLinkBase
href="http://aka.ms/cdb-copilot-learn-more"
>
Learn more
</StyledLinkBase>
</Text>
</StackItem>
</Stack>
</StackItem>
<StackItem
style={
Object {
"marginBottom": "15px",
}
}
>
<Stack>
<Stack
horizontal={true}
>
<StackItem
align="start"
>
<Image
src=""
/>
</StackItem>
<StackItem
align="center"
style={
Object {
"marginLeft": "10px",
}
}
>
<Text
style={
Object {
"fontWeight": 600,
}
}
>
Use your judgement
<br />
</Text>
</StackItem>
</Stack>
<StackItem
style={
Object {
"marginLeft": "25px",
"textAlign": "start",
}
}
>
<Text>
AI-generated content can have mistakes. Make sure its accurate and appropriate before using it.
<br />
<StyledLinkBase
href="http://aka.ms/cdb-copilot-preview-terms"
>
Read preview terms
</StyledLinkBase>
</Text>
</StackItem>
</Stack>
</StackItem>
<StackItem
style={
Object {
"marginBottom": "15px",
}
}
>
<Stack>
<Stack
horizontal={true}
>
<StackItem
align="start"
>
<Image
src=""
/>
</StackItem>
<StackItem
align="center"
style={
Object {
"marginLeft": "10px",
}
}
>
<Text
style={
Object {
"fontWeight": 600,
}
}
>
Copilot currently works only a sample database
<br />
</Text>
</StackItem>
</Stack>
<StackItem
style={
Object {
"marginLeft": "25px",
"textAlign": "start",
}
}
>
<Text>
Copilot is setup on a sample database we have configured for you at no cost
<br />
<StyledLinkBase
href="http://aka.ms/cdb-copilot-learn-more"
>
Learn more
</StyledLinkBase>
</Text>
</StackItem>
</Stack>
</StackItem>
</Stack>
<Stack>
<StackItem
align="center"
>
<CustomizedPrimaryButton
onClick={[Function]}
style={
Object {
"height": "32px",
"width": "224px",
}
}
>
Get Started
</CustomizedPrimaryButton>
</StackItem>
</Stack>
</div>
</Stack>
`;

View File

@ -1,10 +1,54 @@
import { Stack } from "@fluentui/react";
import { SampleBubble } from "Explorer/QueryCopilot/V2/Bubbles/Sample/SampleBubble";
import { shallow } from "enzyme"; import { shallow } from "enzyme";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import { withHooks } from "jest-react-hooks-shallow";
import React from "react"; import React from "react";
import { QueryCopilotSidebar } from "./QueryCopilotSidebar"; import { QueryCopilotSidebar } from "./QueryCopilotSidebar";
describe("QueryCopilotSidebar snapshot test", () => { describe("Query Copilot Sidebar snapshot test", () => {
it("should render ", () => { const initialState = useQueryCopilot.getState();
beforeEach(() => {
useQueryCopilot.setState(initialState, true);
});
it("should render and set copilot used flag ", () => {
withHooks(() => {
useQueryCopilot.getState().setShowCopilotSidebar(true);
const wrapper = shallow(<QueryCopilotSidebar />);
expect(useQueryCopilot.getState().wasCopilotUsed).toBeTruthy();
expect(wrapper).toMatchSnapshot();
});
});
it("should render and not set copilot used flag ", () => {
withHooks(() => {
const wrapper = shallow(<QueryCopilotSidebar />);
expect(useQueryCopilot.getState().wasCopilotUsed).toBeFalsy();
expect(wrapper).toMatchSnapshot();
});
});
it("should render with chat messages", () => {
const message = "some test message";
useQueryCopilot.getState().setChatMessages([message]);
const wrapper = shallow(<QueryCopilotSidebar />); const wrapper = shallow(<QueryCopilotSidebar />);
const messageContainer = wrapper.find(Stack).findWhere((x) => x.text() === message);
expect(messageContainer).toBeDefined();
expect(wrapper).toMatchSnapshot();
});
it("should render samples without messages", () => {
const wrapper = shallow(<QueryCopilotSidebar />);
const sampleBubble = wrapper.find(SampleBubble);
expect(sampleBubble).toBeDefined();
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
}); });

View File

@ -9,7 +9,7 @@ import React from "react";
import { WelcomeSidebarModal } from "../Modal/WelcomeSidebarModal"; import { WelcomeSidebarModal } from "../Modal/WelcomeSidebarModal";
export const QueryCopilotSidebar: React.FC = (): JSX.Element => { export const QueryCopilotSidebar: React.FC = (): JSX.Element => {
const { setWasCopilotUsed, showCopilotSidebar, chatMessages, showWelcomeSidebar } = useQueryCopilot(); const { setWasCopilotUsed, showCopilotSidebar, chatMessages } = useQueryCopilot();
React.useEffect(() => { React.useEffect(() => {
if (showCopilotSidebar) { if (showCopilotSidebar) {
@ -18,44 +18,39 @@ export const QueryCopilotSidebar: React.FC = (): JSX.Element => {
}, []); }, []);
return ( return (
<Stack style={{ width: "100%", height: "100%", backgroundColor: "#FAFAFA", overflow: "auto" }}> <Stack style={{ width: "100%", height: "100%", backgroundColor: "#FAFAFA" }}>
<Header /> <Header />
{showWelcomeSidebar ? ( <WelcomeSidebarModal />
<WelcomeSidebarModal /> <Stack
) : ( style={{
<> flexGrow: 1,
display: "flex",
flexDirection: "column",
overflowY: "auto",
}}
>
<WelcomeBubble />
{chatMessages.map((message, index) => (
<Stack <Stack
key={index}
horizontalAlign="center"
tokens={{ padding: 8, childrenGap: 8 }}
style={{ style={{
flexGrow: 1, backgroundColor: "#E0E7FF",
display: "flex", borderRadius: "8px",
flexDirection: "column", margin: "5px 10px",
overflowY: "auto", textAlign: "start",
}} }}
> >
<WelcomeBubble /> {message}
{chatMessages.map((message, index) => (
<Stack
key={index}
horizontalAlign="center"
tokens={{ padding: 8, childrenGap: 8 }}
style={{
backgroundColor: "#E0E7FF",
borderRadius: "8px",
margin: "5px 10px",
textAlign: "start",
}}
>
{message}
</Stack>
))}
<RetrievingBubble />
{chatMessages.length === 0 && <SampleBubble />}
</Stack> </Stack>
<Footer /> ))}
</>
)} <RetrievingBubble />
{chatMessages.length === 0 && <SampleBubble />}
</Stack>
<Footer />
</Stack> </Stack>
); );
}; };

View File

@ -1,17 +1,140 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`QueryCopilotSidebar snapshot test should render 1`] = ` exports[`Query Copilot Sidebar snapshot test should render and not set copilot used flag 1`] = `
<Stack <Stack
style={ style={
Object { Object {
"backgroundColor": "#FAFAFA", "backgroundColor": "#FAFAFA",
"height": "100%", "height": "100%",
"overflow": "auto",
"width": "100%", "width": "100%",
} }
} }
> >
<Header /> <Header />
<WelcomeSidebarModal /> <WelcomeSidebarModal />
<Stack
style={
Object {
"display": "flex",
"flexDirection": "column",
"flexGrow": 1,
"overflowY": "auto",
}
}
>
<WelcomeBubble />
<RetrievingBubble />
<SampleBubble />
</Stack>
<Footer />
</Stack>
`;
exports[`Query Copilot Sidebar snapshot test should render and set copilot used flag 1`] = `
<Stack
style={
Object {
"backgroundColor": "#FAFAFA",
"height": "100%",
"width": "100%",
}
}
>
<Header />
<WelcomeSidebarModal />
<Stack
style={
Object {
"display": "flex",
"flexDirection": "column",
"flexGrow": 1,
"overflowY": "auto",
}
}
>
<WelcomeBubble />
<RetrievingBubble />
<SampleBubble />
</Stack>
<Footer />
</Stack>
`;
exports[`Query Copilot Sidebar snapshot test should render samples without messages 1`] = `
<Stack
style={
Object {
"backgroundColor": "#FAFAFA",
"height": "100%",
"width": "100%",
}
}
>
<Header />
<WelcomeSidebarModal />
<Stack
style={
Object {
"display": "flex",
"flexDirection": "column",
"flexGrow": 1,
"overflowY": "auto",
}
}
>
<WelcomeBubble />
<RetrievingBubble />
<SampleBubble />
</Stack>
<Footer />
</Stack>
`;
exports[`Query Copilot Sidebar snapshot test should render with chat messages 1`] = `
<Stack
style={
Object {
"backgroundColor": "#FAFAFA",
"height": "100%",
"width": "100%",
}
}
>
<Header />
<WelcomeSidebarModal />
<Stack
style={
Object {
"display": "flex",
"flexDirection": "column",
"flexGrow": 1,
"overflowY": "auto",
}
}
>
<WelcomeBubble />
<Stack
horizontalAlign="center"
key="0"
style={
Object {
"backgroundColor": "#E0E7FF",
"borderRadius": "8px",
"margin": "5px 10px",
"textAlign": "start",
}
}
tokens={
Object {
"childrenGap": 8,
"padding": 8,
}
}
>
some test message
</Stack>
<RetrievingBubble />
</Stack>
<Footer />
</Stack> </Stack>
`; `;

View File

@ -111,7 +111,7 @@ export function extractFeatures(given = new URLSearchParams(window.location.sear
enablePriorityBasedThrottling: "true" === get("enableprioritybasedthrottling"), enablePriorityBasedThrottling: "true" === get("enableprioritybasedthrottling"),
enableNPSSurvey: "true" === get("enablenpssurvey"), enableNPSSurvey: "true" === get("enablenpssurvey"),
enableCopilot: "true" === get("enablecopilot"), enableCopilot: "true" === get("enablecopilot"),
copilotVersion: get("copilotVersion") ? get("copilotVersion") : "v1.0", copilotVersion: get("copilotversion") ?? "v1.0",
enableCopilotPhoenixGateaway: "true" === get("enablecopilotphoenixgateaway"), enableCopilotPhoenixGateaway: "true" === get("enablecopilotphoenixgateaway"),
enableCopilotFullSchema: "true" === get("enablecopilotfullschema"), enableCopilotFullSchema: "true" === get("enablecopilotfullschema"),
}; };