diff --git a/src/Explorer/Tabs/DocumentsTabV2/DocumentsTabV2Mongo.test.tsx b/src/Explorer/Tabs/DocumentsTabV2/DocumentsTabV2Mongo.test.tsx new file mode 100644 index 000000000..107407a8f --- /dev/null +++ b/src/Explorer/Tabs/DocumentsTabV2/DocumentsTabV2Mongo.test.tsx @@ -0,0 +1,194 @@ +import { deleteDocument } from "Common/MongoProxyClient"; +import { Platform, updateConfigContext } from "ConfigContext"; +import { EditorReactProps } from "Explorer/Controls/Editor/EditorReact"; +import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter"; +import { + DELETE_BUTTON_ID, + DISCARD_BUTTON_ID, + DocumentsTabComponent, + IDocumentsTabComponentProps, + NEW_DOCUMENT_BUTTON_ID, + SAVE_BUTTON_ID, + UPDATE_BUTTON_ID, + buildQuery, +} from "Explorer/Tabs/DocumentsTabV2/DocumentsTabV2"; +import { ReactWrapper, ShallowWrapper, mount } from "enzyme"; +import * as ko from "knockout"; +import React from "react"; +import { act } from "react-dom/test-utils"; +import * as ViewModels from "../../../Contracts/ViewModels"; +import Explorer from "../../Explorer"; + +jest.requireActual("Explorer/Controls/Editor/EditorReact"); + +const PROPERTY_VALUE = "__SOME_PROPERTY_VALUE__"; + +jest.mock("Common/MongoProxyClient", () => ({ + queryDocuments: jest.fn(() => + Promise.resolve({ + continuationToken: "", + documents: [ + { + _rid: "_rid", + _self: "_self", + _etag: "etag", + _ts: 1234, + id: "id", + }, + ], + headers: {}, + }), + ), + readDocument: jest.fn(() => + Promise.resolve({ + _rid: "_rid1", + _self: "_self1", + _etag: "etag1", + property: PROPERTY_VALUE, + _ts: 5678, + id: "id1", + }), + ), + deleteDocument: jest.fn(() => Promise.resolve()), +})); + +jest.mock("Explorer/Controls/Editor/EditorReact", () => ({ + EditorReact: (props: EditorReactProps) => <>{props.content}, +})); + +jest.mock("Explorer/Controls/Dialog", () => ({ + useDialog: { + getState: jest.fn(() => ({ + showOkCancelModalDialog: (title: string, subText: string, okLabel: string, onOk: () => void) => onOk(), + })), + }, +})); + +async function waitForComponentToPaint

(wrapper: ReactWrapper

| ShallowWrapper

, amount = 0) { + let newWrapper; + await act(async () => { + await new Promise((resolve) => setTimeout(resolve, amount)); + newWrapper = wrapper.update(); + }); + return newWrapper; +} + +describe("Documents tab (Mongo API)", () => { + describe("buildQuery", () => { + it("should generate the right select query for SQL API", () => { + expect(buildQuery(true, "")).toContain("{}"); + }); + }); + + describe("Command bar buttons", () => { + const createMockProps = (): IDocumentsTabComponentProps => ({ + isPreferredApiMongoDB: true, + documentIds: [], + collection: { + id: ko.observable("foo"), + container: new Explorer(), + partitionKey: { + kind: "Hash", + paths: ["/pkey"], + version: 2, + }, + partitionKeyProperties: ["pkey"], + partitionKeyPropertyHeaders: ["/pkey"], + databaseId: "databaseId", + self: "self", + rawDataModel: undefined, + selectedSubnodeKind: undefined, + children: undefined, + isCollectionExpanded: undefined, + onDocumentDBDocumentsClick: function (): void { + throw new Error("Function not implemented."); + }, + onNewQueryClick: function (source: any, event?: MouseEvent, queryText?: string): void { + throw new Error("Function not implemented."); + }, + expandCollection: function (): void { + throw new Error("Function not implemented."); + }, + collapseCollection: function (): void { + throw new Error("Function not implemented."); + }, + getDatabase: function (): ViewModels.Database { + throw new Error("Function not implemented."); + }, + nodeKind: "nodeKind", + rid: "rid", + }, + partitionKey: undefined, + onLoadStartKey: 0, + tabTitle: "", + onExecutionErrorChange: (isExecutionError: boolean): void => { + isExecutionError; + }, + onIsExecutingChange: (isExecuting: boolean): void => { + isExecuting; + }, + isTabActive: true, + }); + + let wrapper: ReactWrapper; + + beforeEach(async () => { + updateConfigContext({ platform: Platform.Hosted }); + + const props: IDocumentsTabComponentProps = createMockProps(); + + wrapper = mount(); + wrapper = await waitForComponentToPaint(wrapper); + }); + + afterEach(() => { + wrapper.unmount(); + }); + + it("renders by default the first document", async () => { + // expect(wrapper.findWhere((node) => node.text().includes(PROPERTY_VALUE)).exists()).toBeTruthy(); + }); + + it("default buttons", async () => { + expect(useCommandBar.getState().contextButtons.find((button) => button.id === UPDATE_BUTTON_ID)).toBeDefined(); + expect(useCommandBar.getState().contextButtons.find((button) => button.id === DISCARD_BUTTON_ID)).toBeDefined(); + expect(useCommandBar.getState().contextButtons.find((button) => button.id === DELETE_BUTTON_ID)).toBeDefined(); + }); + + it("clicking on New Document should show editor with new document", () => { + act(() => { + useCommandBar + .getState() + .contextButtons.find((button) => button.id === NEW_DOCUMENT_BUTTON_ID) + .onCommandClick(undefined); + }); + expect(wrapper.findWhere((node) => node.text().includes("replace_with_new_document_id")).exists()).toBeTruthy(); + }); + + it("clicking on New Document should show Save and Discard buttons", () => { + act(() => { + useCommandBar + .getState() + .contextButtons.find((button) => button.id === NEW_DOCUMENT_BUTTON_ID) + .onCommandClick(undefined); + }); + + expect(useCommandBar.getState().contextButtons.find((button) => button.id === SAVE_BUTTON_ID)).toBeDefined(); + expect(useCommandBar.getState().contextButtons.find((button) => button.id === DISCARD_BUTTON_ID)).toBeDefined(); + }); + + it("clicking Delete Document asks for confirmation", () => { + const mockDeleteDocument = deleteDocument as jest.Mock; + mockDeleteDocument.mockClear(); + + act(() => { + useCommandBar + .getState() + .contextButtons.find((button) => button.id === DELETE_BUTTON_ID) + .onCommandClick(undefined); + }); + + expect(mockDeleteDocument).toHaveBeenCalled(); + }); + }); +});