Skip to content

Commit

Permalink
Merge pull request #27 from wajeshubham/config-import-export
Browse files Browse the repository at this point in the history
Config import export
  • Loading branch information
wajeshubham authored Feb 12, 2023
2 parents a24c758 + 9846bda commit 1188cc0
Show file tree
Hide file tree
Showing 20 changed files with 1,188 additions and 330 deletions.
11 changes: 11 additions & 0 deletions __tests__/auth.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ import Home from "@/pages";
import { render, screen, waitFor } from "@testing-library/react";
import { act } from "react-dom/test-utils";

beforeEach(() => {
// IntersectionObserver isn't available in test environment
const mockIntersectionObserver = jest.fn();
mockIntersectionObserver.mockReturnValue({
observe: () => null,
unobserve: () => null,
disconnect: () => null,
});
window.IntersectionObserver = mockIntersectionObserver;
});

beforeAll(() => {
document.createRange = () => {
const range = new Range();
Expand Down
13 changes: 13 additions & 0 deletions __tests__/components/snippng_code_area.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ import { defaultEditorConfig } from "@/lib/constants";
import { render, screen, waitFor } from "@testing-library/react";
import { act } from "react-dom/test-utils";

beforeEach(() => {
// IntersectionObserver isn't available in test environment
const mockIntersectionObserver = jest.fn();
mockIntersectionObserver.mockReturnValue({
observe: () => null,
unobserve: () => null,
disconnect: () => null,
});
window.IntersectionObserver = mockIntersectionObserver;
});

beforeAll(() => {
document.createRange = () => {
const range = new Range();
Expand Down Expand Up @@ -192,6 +203,8 @@ describe("SnippngCodeArea", () => {
<SnippngCodeArea />
</SnippngEditorContext.Provider>
);

// @ts-ignore
render(<SnippngControlHeader />);
});
const colorPicker = document.getElementById(
Expand Down
14 changes: 14 additions & 0 deletions __tests__/components/snippng_control_header.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,21 @@ beforeAll(() => {
};
});

beforeEach(() => {
// IntersectionObserver isn't available in test environment
const mockIntersectionObserver = jest.fn();
mockIntersectionObserver.mockReturnValue({
observe: () => null,
unobserve: () => null,
disconnect: () => null,
});
window.IntersectionObserver = mockIntersectionObserver;
});

describe("SnippngControlHeader", () => {
it("renders all CTA and inputs", async () => {
await act(async () => {
//@ts-ignore
render(<SnippngControlHeader />);
});
await waitFor(() => {
Expand All @@ -51,6 +63,7 @@ describe("SnippngControlHeader", () => {
},
}}
>
{/* @ts-ignore */}
<SnippngControlHeader />
</SnippngEditorContext.Provider>
);
Expand All @@ -62,6 +75,7 @@ describe("SnippngControlHeader", () => {

it("renders with TypeScript as a default language", async () => {
await act(async () => {
//@ts-ignore
render(<SnippngControlHeader />);
});
await waitFor(() => {
Expand Down
154 changes: 154 additions & 0 deletions __tests__/utils.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { DEFAULT_RANGES, DEFAULT_WIDTHS } from "@/lib/constants";
import { deepClone, validateSnippngConfig } from "@/utils";

const mockJSON = {
code: "",
snippetsName: "",
editorFontSize: 16,
editorWindowControlsType: "mac-left" as const,
fileName: "@utils/debounce.ts",
hasDropShadow: true,
lineHeight: 19,
paddingHorizontal: 70,
paddingVertical: 70,
rounded: true,
selectedLang: { label: "TypeScript", id: "typescript" },
selectedTheme: { id: "tokyoNightStorm", label: "Tokyo Night Storm" },
showFileName: true,
showLineNumbers: true,
wrapperBg: "#eee811",
gradients: ["#ba68c8", "#ffa7c4", "#e57373"],
gradientAngle: 140,
editorWidth: 450,
bgImageVisiblePatch: null,
bgBlur: 0,
};

const inValidJSON = {
invalidKey: "invalid value",
};

beforeAll(() => {
document.createRange = () => {
const range = new Range();

range.getBoundingClientRect = jest.fn();

range.getClientRects = () => {
return {
item: () => null,
length: 0,
[Symbol.iterator]: jest.fn(),
};
};

return range;
};
});

describe("Utils", () => {
it("deep clones the javascript object", async () => {
let date = new Date().toISOString();
let updatedDate = new Date().setFullYear(2002);

const objectToBeCloned = {
name: "John",
age: 20,
marks: {
science: 70,
math: 75,
},
birthDate: date,
};
const clonedObject = deepClone(objectToBeCloned);
clonedObject.name = "Updated";
clonedObject.marks.science = 10;
clonedObject.birthDate = updatedDate;

expect(objectToBeCloned.name).toBe("John");
expect(objectToBeCloned.marks.science).toBe(70);
expect(objectToBeCloned.birthDate).toBe(date);

expect(clonedObject.name).toBe("Updated");
expect(clonedObject.marks.science).toBe(10);
expect(clonedObject.birthDate).toBe(updatedDate);
});

it("validates editor config coming from uploaded JSON file", async () => {
let minValues = DEFAULT_RANGES.min;
let maxValues = DEFAULT_RANGES.max;
const mockOneResult = validateSnippngConfig({ ...mockJSON });

const mockMissingKeyResult = validateSnippngConfig({
...mockJSON,
selectedLang: undefined as any,
});

const mockInvalidKeyResult = validateSnippngConfig({
...mockJSON,
selectedLang: [] as any,
});

const mockBlueCheckResult = validateSnippngConfig({
...mockJSON,
bgBlur: 100,
});
const mockLineHeightResult = validateSnippngConfig({
...mockJSON,
lineHeight: 100,
});
const mockPadHorResult = validateSnippngConfig({
...mockJSON,
paddingHorizontal: 200,
});
const mockPadVerResult = validateSnippngConfig({
...mockJSON,
paddingVertical: 200,
});
const mockFontSizeResult = validateSnippngConfig({
...mockJSON,
editorFontSize: 54,
});
const mockGradAngResult = validateSnippngConfig({
...mockJSON,
gradientAngle: 361,
});
const mockEdWidthMinResult = validateSnippngConfig({
...mockJSON,
editorWidth: -10,
});
const mockEdWidthMaxResult = validateSnippngConfig({
...mockJSON,
editorWidth: 3000,
});
const invalidResult = validateSnippngConfig({ ...(inValidJSON as any) });
expect(mockOneResult).toBe("");
expect(mockMissingKeyResult).toBe("value.selectedLang is missing");
expect(mockInvalidKeyResult).toContain("missing");
expect(mockBlueCheckResult).toBe(
`bgBlur value must be in the range ${minValues.BLUR} to ${maxValues.BLUR}`
);
expect(mockLineHeightResult).toBe(
`lineHeight value must be in the range ${minValues.LINE_HEIGHT} to ${maxValues.LINE_HEIGHT}`
);
expect(mockPadHorResult).toBe(
`paddingHorizontal value must be in the range ${minValues.PADDING_HORIZONTAL} to ${maxValues.PADDING_HORIZONTAL}`
);
expect(mockPadVerResult).toBe(
`paddingVertical value must be in the range ${minValues.PADDING_VERTICAL} to ${maxValues.PADDING_VERTICAL}`
);
expect(mockFontSizeResult).toBe(
`editorFontSize value must be in the range ${minValues.FONT_SIZE} to ${maxValues.FONT_SIZE}`
);
expect(mockGradAngResult).toBe(
`gradientAngle value must be in the range ${minValues.GRADIENT_ANGLE} to ${maxValues.GRADIENT_ANGLE}`
);
expect(mockEdWidthMinResult).toBe(
`editorWidth value must be in the range ${DEFAULT_WIDTHS.minWidth} to ${DEFAULT_WIDTHS.maxWidth}`
);
expect(mockEdWidthMaxResult).toBe(
`editorWidth value must be in the range ${DEFAULT_WIDTHS.minWidth} to ${DEFAULT_WIDTHS.maxWidth}`
);
expect(invalidResult).toBeTruthy();
});
});
2 changes: 1 addition & 1 deletion components/ThemeToggle.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MoonIcon, SunIcon } from "@heroicons/react/24/outline";

export const ThemeToggle = () => {
const ThemeToggle = () => {
const disableTransitionsTemporarily = () => {
document.documentElement.classList.add("[&_*]:!transition-none");
window.setTimeout(() => {
Expand Down
7 changes: 3 additions & 4 deletions components/Toast.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import React, { useEffect } from "react";
import { Fragment, useState } from "react";
import { ToastInterface } from "@/types";
import { Transition } from "@headlessui/react";
import { XMarkIcon } from "@heroicons/react/20/solid";
import {
CheckCircleIcon,
InformationCircleIcon,
XCircleIcon,
} from "@heroicons/react/24/outline";
import { XMarkIcon } from "@heroicons/react/20/solid";
import { ToastInterface, ToastVariantType } from "@/types";
import React, { Fragment, useEffect, useState } from "react";

interface Props extends ToastInterface {
onClose: () => void;
Expand Down
10 changes: 8 additions & 2 deletions components/editor/SnippngCodeArea.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { useRef, useState } from "react";

import { DEFAULT_BASE_SETUP } from "@/lib/constants";
import { clsx, getEditorWrapperBg, getLanguage, getTheme } from "@/utils";
import {
clsx,
deepClone,
getEditorWrapperBg,
getLanguage,
getTheme,
} from "@/utils";

import { langs, loadLanguage } from "@uiw/codemirror-extensions-langs";
import * as themes from "@uiw/codemirror-themes-all";
Expand Down Expand Up @@ -63,7 +69,7 @@ const SnippngCodeArea = () => {
if (!user) return;
setSaving(true);
try {
const dataToBeAdded = { ...structuredClone(editorConfig) }; // deep clone the editor config to avoid mutation
const dataToBeAdded = { ...deepClone(editorConfig) }; // deep clone the editor config to avoid mutation
delete dataToBeAdded.uid; // delete existing uid if exists
const savedDoc = await addDoc(collection(db, "snippets"), {
...dataToBeAdded,
Expand Down
Loading

0 comments on commit 1188cc0

Please sign in to comment.