Skip to content

Commit

Permalink
Merge pull request #12 from mbgeorge48/local-storage
Browse files Browse the repository at this point in the history
Local storage
  • Loading branch information
mbgeorge48 authored Dec 23, 2023
2 parents 87a42e4 + 2132cfa commit 5527001
Show file tree
Hide file tree
Showing 16 changed files with 679 additions and 233 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ESLINT_NO_DEV_ERRORS=true
28 changes: 2 additions & 26 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,29 +1,5 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
"react-app",
"react-app/jest",
],
ignorePatterns: ["dist", ".eslintrc.cjs", "jest.config.ts"],
parser: "@typescript-eslint/parser",
plugins: ["react"],
extends: ["eslint:recommended", "plugin:react/recommended"],
rules: {
"react/react-in-jsx-scope": 0,
"react/jsx-uses-react": 0,
"react/no-unescaped-entities": 0,
"no-undef": 0,
},
overrides: [
{
files: ["**/__helpers__/**", "**/*.test.*"],
env: {
jest: true,
},
},
],
rules: { "prettier/prettier": 0 },
extends: ["universe/web", "plugin:jsx-a11y/recommended"],
};
4 changes: 4 additions & 0 deletions .github/workflows/cd-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ on:
- main
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
run:
runs-on: ubuntu-latest
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/ci-frontend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ on:
pull_request:
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
test:
runs-on: ubuntu-latest
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,10 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"eslint": "^8.56.0",
"eslint-config-universe": "^12.0.0",
"prettier": "^3.1.1"
}
}
62 changes: 62 additions & 0 deletions src/AdvancedMode.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Field, Form, Formik } from "formik";
import { useState } from "react";

import { Timer } from "./types";

interface Props {
timerData: Timer[];
}

export function AdvancedMode(props: Props) {
const [responseOk, setResponseOk] = useState<boolean>(false);
const initialValues = { url: "" };

const handleSubmit = async (values: { url: string }) => {
console.log({ values });
const response = await fetch(values.url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(props.timerData),
});
const responseSuccess = await response.ok;
setResponseOk(responseSuccess);
};

return (
<>
<p>
Experimental! Posts the form data to a URL so you can
programmatically set timers
</p>
<p>
Not aware of any endpoints that accept this data at the minute
</p>
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
{() => (
<Form className="grid">
<div className="field food-item">
<Field
className="item border"
name="url"
type="url"
placeholder="https://example.com/set-timers"
pattern="https?://.*"
size="30"
required
/>
<label htmlFor="url">
URL you'd like to POST the data to
</label>
</div>
<button type="submit" className="item">
Post!
</button>
{responseOk && <p>Success!</p>}
</Form>
)}
</Formik>
</>
);
}
42 changes: 32 additions & 10 deletions src/App.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
import { fireEvent, render, waitFor } from "@testing-library/react";
import App from "./App";
import { act, fireEvent, render, waitFor } from "@testing-library/react";

import { App } from "./App";

const mockGetItem = jest.fn();
const mockSetItem = jest.fn();
const mockRemoveItem = jest.fn();
Object.defineProperty(window, "localStorage", {
value: {
getItem: (...args: string[]) => mockGetItem(...args),
setItem: (...args: string[]) => mockSetItem(...args),
removeItem: (...args: string[]) => mockRemoveItem(...args),
},
});

describe("<App />", () => {
test("renders the basic form", () => {
Expand All @@ -22,7 +34,9 @@ describe("<App />", () => {
expect(subject.getAllByRole("textbox")).toHaveLength(1);
expect(subject.getAllByRole("spinbutton")).toHaveLength(1);

fireEvent.click(subject.getByText(/add timer/i));
await act(async () => {
fireEvent.click(subject.getByText(/add timer/i));
});

await waitFor(() => {
expect(subject.getAllByRole("textbox")).toHaveLength(2);
Expand All @@ -33,13 +47,17 @@ describe("<App />", () => {
test("removes fields when button is pressed", async () => {
const subject = render(<App />);

fireEvent.click(subject.getByText(/add timer/i));
await act(async () => {
fireEvent.click(subject.getByText(/add timer/i));
});
await waitFor(() => {
expect(subject.getAllByRole("textbox")).toHaveLength(2);
});
expect(subject.getAllByRole("spinbutton")).toHaveLength(2);

fireEvent.click(subject.getAllByText(/clear/i)[1]);
await act(async () => {
fireEvent.click(subject.getAllByText(/clear/i)[1]);
});
await waitFor(() => {
expect(subject.getAllByRole("textbox")).toHaveLength(1);
});
Expand All @@ -49,8 +67,13 @@ describe("<App />", () => {
test("renders the instructions when go is pressed", async () => {
const subject = render(<App />);

fireEvent.click(subject.getByText(/add timer/i));
fireEvent.click(subject.getByText(/add timer/i));
await act(async () => {
fireEvent.click(subject.getByText(/add timer/i));
});

await act(async () => {
fireEvent.click(subject.getByText(/add timer/i));
});
await waitFor(() => {
expect(subject.getAllByRole("textbox")).toHaveLength(3);
});
Expand All @@ -62,9 +85,8 @@ describe("<App />", () => {
fireEvent.change(timerNameFields[0], { target: { value: "Food A" } });
fireEvent.change(timerNameFields[1], { target: { value: "Food B" } });
fireEvent.change(timerNameFields[2], { target: { value: "Food C" } });
await waitFor(() => {
fireEvent.change(timerLengthFields[0], { target: { value: 10 } });
});

fireEvent.change(timerLengthFields[0], { target: { value: 10 } });
fireEvent.change(timerLengthFields[1], { target: { value: 8 } });
fireEvent.change(timerLengthFields[2], { target: { value: 5 } });

Expand Down
Loading

0 comments on commit 5527001

Please sign in to comment.