Skip to content

Commit e8a27e7

Browse files
Add a form to demonstrate getDispatchedProductByDate query
1 parent 3d1ed53 commit e8a27e7

File tree

6 files changed

+112
-5
lines changed

6 files changed

+112
-5
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"autoprefixer": "^10.4.19",
5252
"postcss": "^8.4.39",
5353
"specmatic": "^2.0.1",
54-
"specmatic-beta": "github:znsio/specmatic-node-beta#2.0.3",
54+
"specmatic-beta": "github:znsio/specmatic-node-beta#2.0.4",
5555
"tailwindcss": "^3.4.3"
5656
}
5757
}

specmatic.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
sources:
22
- provider: git
33
repository: https://github.com/znsio/specmatic-order-contracts.git
4-
stub:
5-
- io/specmatic/examples/store/graphql/products_bff.graphqls
4+
consumes:
5+
- io/specmatic/examples/store/graphql/products_bff.graphqls

src/App.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import FindAvailableProductForm from './components/FindAvailableProductForm';
33
import ProductForm from './components/ProductForm';
44
import { ToastContainer, toast } from 'react-toastify';
55
import { useEffect } from 'react';
6+
import GetDispatchedProductByDateForm from './components/GetDispatchedProductByDateForm';
67

78
function App() {
89

@@ -26,6 +27,8 @@ function App() {
2627
<br/>
2728
<FindAvailableProductForm/>
2829
<br/>
30+
<GetDispatchedProductByDateForm/>
31+
<br/>
2932
<ToastContainer />
3033
</div>
3134
);

src/__test__/App.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { ApolloProvider } from "@apollo/client";
66
import client from "../apolloClient";
77
import FindAvailableProductForm from "../components/FindAvailableProductForm";
88
import { startGraphQlStub, stopGraphQlStub } from "specmatic";
9+
import GetDispatchedProductByDateForm from "../components/GetDispatchedProductByDateForm";
910

1011
global.setImmediate = global.setImmediate || ((fn, ...args) => global.setTimeout(fn, 0, ...args));
1112
let stub;
@@ -72,6 +73,21 @@ describe("App component tests", () => {
7273
expect(screen.getAllByTestId("product").length).toBeGreaterThan(0);
7374
});
7475
});
76+
77+
test("should fetch dispatched product by date", async () => {
78+
render(
79+
<ApolloProvider client={client}>
80+
<GetDispatchedProductByDateForm />
81+
</ApolloProvider>
82+
);
83+
84+
fireEvent.change(screen.getByTestId("date"), { target: { value: "2020-12-12" } });
85+
fireEvent.click(screen.getByTestId("submit"));
86+
87+
await waitFor(() => {
88+
expect(screen.getByText("12/12/2020")).toBeInTheDocument(); // Adjust the date format if needed
89+
});
90+
});
7591
});
7692

7793
afterAll(async () => {
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import React, { useEffect, useState } from 'react';
2+
import { useLazyQuery, gql } from '@apollo/client';
3+
import { toast } from 'react-toastify';
4+
import 'react-toastify/dist/ReactToastify.css';
5+
6+
const GetDispatchedProductByDateForm = () => {
7+
const [date, setDate] = useState('');
8+
const [dispatchedProduct, setDispatchedProduct] = useState(null);
9+
10+
const formatDateString = (dateString) => {
11+
return dateString.replace(/-/g, '/'); // Replace hyphens with slashes
12+
};
13+
14+
const GET_DISPATCHED_PRODUCT_BY_DATE = gql`
15+
query {
16+
getDispatchedProductByDate(date: "${formatDateString(date)}") {
17+
id
18+
dispatchDate
19+
}
20+
}
21+
`;
22+
23+
const [getDispatchedProductByDate, { loading }] = useLazyQuery(GET_DISPATCHED_PRODUCT_BY_DATE, {
24+
fetchPolicy: 'network-only',
25+
onCompleted: (data) => {
26+
setDispatchedProduct(data.getDispatchedProductByDate);
27+
},
28+
onError: () => {
29+
setDispatchedProduct(null);
30+
toast.error('Error fetching dispatched product');
31+
},
32+
});
33+
34+
const handleSubmit = async (e) => {
35+
e.preventDefault();
36+
37+
if (!Date.parse(date)) {
38+
toast.dismiss();
39+
toast.error('Please enter a valid date');
40+
return;
41+
}
42+
43+
getDispatchedProductByDate({ variables: { date } });
44+
};
45+
46+
return (
47+
<div className="max-w-md mx-auto p-8 bg-white shadow-lg rounded-lg">
48+
<h1 className="text-2xl font-bold mb-4">Get Dispatched Product by Date</h1>
49+
<form onSubmit={handleSubmit}>
50+
<div className="mb-4">
51+
<label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="date">
52+
Date
53+
</label>
54+
<input
55+
type="date"
56+
id="date"
57+
data-testid="date"
58+
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
59+
value={date}
60+
onChange={(e) => setDate(e.target.value)}
61+
/>
62+
</div>
63+
<div className="flex items-center justify-between">
64+
<button
65+
type="submit"
66+
data-testid="submit"
67+
className={`bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline ${loading && 'opacity-50 cursor-not-allowed'}`}
68+
disabled={loading}
69+
>
70+
{loading ? 'Searching...' : 'Search'}
71+
</button>
72+
</div>
73+
</form>
74+
{dispatchedProduct && (
75+
<div className="mt-8">
76+
<h2 className="text-xl font-bold mb-4">Dispatched Product</h2>
77+
<div className="p-4 border rounded-lg bg-gray-50 shadow-sm">
78+
<p><strong>ID:</strong> {dispatchedProduct.id}</p>
79+
<p><strong>Dispatch Date:</strong> {new Date(dispatchedProduct.dispatchDate).toLocaleDateString()}</p>
80+
</div>
81+
</div>
82+
)}
83+
</div>
84+
);
85+
};
86+
87+
export default GetDispatchedProductByDateForm;
88+

0 commit comments

Comments
 (0)