Fakultas Ilmu Komputer UI

Commit e78125b8 authored by Wan Muhammad Rayhan Arwindra's avatar Wan Muhammad Rayhan Arwindra 🤸🏽
Browse files

Merge branch 'pbi_3_batch_transaksi' into 'staging'

Pbi 3 batch transaksi

See merge request !84
parents 451b1568 12034fa9
Pipeline #58538 passed with stages
in 17 minutes and 19 seconds
......@@ -4568,6 +4568,11 @@
}
}
},
"classnames": {
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
},
"clean-stack": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
......@@ -5460,6 +5465,19 @@
"integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
"dev": true
},
"deep-equal": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
"integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
"requires": {
"is-arguments": "^1.0.4",
"is-date-object": "^1.0.1",
"is-regex": "^1.0.4",
"object-is": "^1.0.1",
"object-keys": "^1.1.1",
"regexp.prototype.flags": "^1.2.0"
}
},
"deep-equal-ident": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/deep-equal-ident/-/deep-equal-ident-1.1.1.tgz",
......@@ -11099,6 +11117,11 @@
"integrity": "sha512-+D4s2HCnxPd5PjjI0STKwncjXTUKKqm74MDMz9OPXavjsGmjkvwgLtA5yoxJUdmpj52+2u+RrXgPipahKczMKg==",
"dev": true
},
"node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
},
"node-forge": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
......@@ -11385,16 +11408,6 @@
"is-wsl": "^2.1.1"
}
},
"open": {
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/open/-/open-7.3.0.tgz",
"integrity": "sha512-mgLwQIx2F/ye9SmbrUkurZCnkoXyXyu9EbHtJZrICjVAJfyMArdHp3KkixGdZx1ZHFPNIwl0DDM1dFFqXbTLZw==",
"dev": true,
"requires": {
"is-docker": "^2.0.0",
"is-wsl": "^2.1.1"
}
},
"optionator": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
......@@ -15079,3 +15092,4 @@
}
}
}
import { cleanup, render } from "@testing-library/react";
import AuthContext from "../../utils/contex";
import React from "react";
import DetailBatch from "../../page/batch/DetailBatch";
import { waitFor } from "@testing-library/dom";
beforeEach(() => {
fetch.resetMocks();
});
afterEach(cleanup);
test("Test detail loaded batch", async () => {
fetch.mockResponseOnce(
JSON.stringify({
id: "8e9a8f94-cb5c-4b2d-b4f1-81ccfb9f1b0a",
batch_name: "Batch 1",
start_: "2020-04-28",
updated_at: "2020-04-28",
amount: "10000.00"
})
);
const { getByTestId } = render(
<AuthContext.Provider value={{ profile: { token: "tester" } }}>
<DetailBatch batchId={"8e9a8f94-cb5c-4b2d-b4f1-81ccfb9f1b0a"} />
</AuthContext.Provider>
);
const wait = getByTestId("waiting-detail-batch");
expect(wait.textContent).toContain("Fetching data..");
await waitFor(() => getByTestId("page-detail-batch"));
const data = getByTestId("page-detail-batch");
expect(data.textContent).toContain("BATCH");
});
import { act, cleanup, fireEvent, render } from "@testing-library/react";
import AuthContext from "../../utils/contex";
import { waitFor } from "@testing-library/dom";
import React from "react";
import EditBatch from "../../page/batch/EditBatch";
beforeEach(() => {
fetch.resetMocks();
});
afterEach(cleanup);
test("Test edit batch renders", async () => {
fetch
.once(
JSON.stringify({
id: "8e9a8f94-cb5c-4b2d-b4f1-81ccfb9f1b0a",
batch_name: "a",
start_date: "2020-04-28",
end_date: "2020-04-28",
shipping_cost: "10000.00"
})
)
.once(
JSON.stringify({
count: 1,
next: null,
previous: null,
results: [
{
id: "e9a8f94-cb5c-4b2d-b4f1-81ccfb9f1b0a",
batch_name: "Batch 1",
start_date: "2020-04-28",
end_date: "2020-04-28",
shipping_cost: "10000.00"
},
],
})
)
.once(
JSON.stringify({
count: 1,
next: null,
previous: null,
results: [
{
id: "e9a8f94-cb5c-4b2d-b4f1-81ccfb9f1b0a",
batch_name: "Batch 1",
start_date: "2020-04-28",
end_date: "2020-04-28",
shipping_cost: "10000.00"
},
],
})
)
.once(JSON.stringify({}), { statusCode: 200 });
const { getByTestId } = render(
<AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
<EditBatch />
</AuthContext.Provider>
);
const waitBatch = getByTestId("waiting-edit-batch");
expect(waitBatch.textContent).toContain("Fetching data..");
await waitFor(() => getByTestId("edit-batch"));
const name_batch = getByTestId("name-batch-input");
expect(name_batch.value).toEqual("a");
await act(async () => {
await fireEvent.input(name_batch, { target: { value: "test" } });
});
await act(async () => {
await fireEvent.submit(getByTestId("submit-batch"));
});
expect(fetch.mock.calls.length).toEqual(2);
});
test("Test edit batch renders error", async () => {
fetch
.once(
JSON.stringify({
id: "e9a8f94-cb5c-4b2d-b4f1-81ccfb9f1b0a",
batch_name: "a",
start_date: "2020-04-28",
end_date: "2020-04-28",
shipping_cost: "10000.00"
})
)
.once(
JSON.stringify({
count: 1,
next: null,
previous: null,
results: [
{
id: "e9a8f94-cb5c-4b2d-b4f1-81ccfb9f1b0a",
batch_name: "a",
start_date: "2020-04-28",
end_date: "2020-04-28",
shipping_cost: "10000.00"
},
],
})
)
.once(
JSON.stringify({
count: 1,
next: null,
previous: null,
results: [
{
id: "e9a8f94-cb5c-4b2d-b4f1-81ccfb9f1b0a",
batch_name: "a",
start_date: "2020-04-28",
end_date: "2020-04-28",
shipping_cost: "10000.00"
},
],
})
)
.once(JSON.stringify({}), { status: 400 });
const { getByTestId } = render(
<AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
<EditBatch />
</AuthContext.Provider>
);
const waitProduk = getByTestId("waiting-edit-batch");
expect(waitProduk.textContent).toContain("Fetching data..");
await waitFor(() => getByTestId("edit-batch"));
const name_batch = getByTestId("name-batch-input");
expect(name_batch.value).toEqual("a");
await act(async () => {
await fireEvent.submit(getByTestId("submit-batch"));
});
expect(fetch.mock.calls.length).toEqual(2);
});
......@@ -51,6 +51,7 @@ test(" Test List transaksi", async () => {
created_at: "2020-04-18T10:59:42.074386+07:00",
updated_at: "2020-04-18T11:00:18.150633+07:00",
subtotal: "370000.00",
batch: "Batch 1"
},
],
})
......@@ -65,6 +66,7 @@ test(" Test List transaksi", async () => {
expect(data.textContent).toContain("whtestest");
expect(data.textContent).toContain("Rp370.000");
expect(data.textContent).toContain("18 April 2020 10:59");
expect(data.textContent).toContain("Batch 1");
expect(fetch.mock.calls.length).toEqual(1);
});
......@@ -112,6 +114,7 @@ test(" Test List transaksi filter", async () => {
created_at: "2020-04-18T10:59:42.074386+07:00",
updated_at: "2020-04-18T11:00:18.150633+07:00",
subtotal: "370000.00",
batch: "Batch 2",
},
],
})
......@@ -158,6 +161,7 @@ test(" Test List transaksi filter", async () => {
created_at: "2020-04-18T10:59:42.074386+07:00",
updated_at: "2020-04-18T11:00:18.150633+07:00",
subtotal: "370000.00",
batch: "Batch 1",
},
],
})
......@@ -172,6 +176,8 @@ test(" Test List transaksi filter", async () => {
expect(data.textContent).toContain("whtestest");
expect(data.textContent).toContain("Rp370.000");
expect(data.textContent).toContain("18 April 2020 10:59");
expect(data.textContent).toContain("Batch 2");
expect(data.textContent)
expect(fetch.mock.calls.length).toEqual(1);
await act(async () => {
await fireEvent.click(getByTestId("filter-button"));
......@@ -180,8 +186,12 @@ test(" Test List transaksi filter", async () => {
await fireEvent.input(
getByLabelText("Status transaksi", { target: { value: "002" } })
);
await fireEvent.input(
getByLabelText("Batch", {target: { value:"Batch 1"}})
)
await fireEvent.click(getByTestId("submit-filter"));
});
expect(data.textContent).toContain("filterwhtest");
expect(data.textContent).toContain("Batch 1");
expect(fetch.mock.calls.length).toEqual(2);
});
......@@ -21,6 +21,21 @@ const FormDownload = ({ url }) => {
display: flex;
`}
>
<div
css={css`
margin-right:15px;
`}
>
<label
htmlFor="batch"
css={css`
font-weight: bold;
`}
>
Batch{" "}
</label>
<input name="batch" type="text" ref={register} />
</div>
{error && <ErrorDiv>Mohon maaf ada sesuatu yang salah</ErrorDiv>}
<div>
<label
......@@ -44,6 +59,7 @@ const FormDownload = ({ url }) => {
</label>
<input name="before" type="date" ref={register} />
</div>
<Button
type="submit"
variant="contained"
......
......@@ -32,7 +32,7 @@ const Sidebar = () => {
>
<div
css={css`
margin-top: 12vh;
margin-top: 8vh;
`}
/>
<Logo />
......@@ -66,6 +66,7 @@ const Sidebar = () => {
text-align: center;
height: 2.5rem;
color: #3C8DBC;
margin-bottom: 2rem
`}
>
<StyledA
......
......@@ -135,6 +135,7 @@ const TableComponent = ({
.filter(([, val]) => val !== "")
.map(([key, val]) => `${key}=${val}`)
.join("&");
console.log(filter);
setFilter(filter);
})}
css={css`
......@@ -145,6 +146,7 @@ const TableComponent = ({
>
{filter.map((field) => {
if (Array.isArray(field)) {
if (field[2] === "date"){
return (
<RowInput key={field[0]}>
<LabelInput htmlFor={field[0]}>{field[1]}</LabelInput>
......@@ -156,6 +158,20 @@ const TableComponent = ({
/>
</RowInput>
);
}else{
return (
<RowInput key={field[0]}>
<LabelInput htmlFor={field[0]}>{field[1]}</LabelInput>
<InputForm
id={field[0]}
type="text"
name={field[0]}
ref={registerFilter}
/>
</RowInput>
);
}
} else if (typeof field === "object") {
const k = Object.keys(field);
return (
......
......@@ -11,6 +11,13 @@ export const stringToDate = (date) => {
);
};
export const stringToDateNoTime = (date) => {
const dateFormat = new Date(date);
return (
<Moment format={"DD MMMM YYYY"} tz="Asia/Jakarta" date={dateFormat} />
);
};
export const stringToCurrency = (currency) => (
<NumberFormat
value={currency}
......
import React from "react";
import useFetchSingleData from "../../utils/useFetchSingleData";
import { css } from "@emotion/core";
import ArrowBackIcon from "@material-ui/icons/ArrowBack";
import { navigate } from "@reach/router";
import { stringToCurrency, stringToDateNoTime } from "../../component/TableUtils";
import { ErrorDiv } from "../../component/html/html";
import LinkYellow from "../../component/LinkYellow";
const DetailBatch = ({ batchId }) => {
const url = `${process.env.REACT_APP_BASE_URL}/batch/${batchId}/`;
// const url = `http://localhost:8000/batch/${batchId}/`; // for local testing purposes
const [batch, error] = useFetchSingleData(url);
if (Object.keys(batch).length === 0)
return (
<div
data-testid="waiting-detail-batch"
css={css`
display: flex;
margin: 2rem 3rem 3rem 3rem;
flex-direction: column;
font-size: 25px;
`}
>
{error && <ErrorDiv>Something error</ErrorDiv>}
Fetching data..
</div>
);
return (
<div
data-testid="page-detail-batch"
css={css`
display: flex;
margin: 2rem 3rem 3rem 3rem;
flex-direction: column;
justify-content: space-around;
height: 75vh;
`}
>
{error && <ErrorDiv>Something error</ErrorDiv>}
<div>
<button
css={css`
align-self: start;
background-color: Transparent;
background-repeat: no-repeat;
border: none;
cursor: pointer;
overflow: hidden;
outline: none;
display: inline-block;
vertical-align: middle;
`}
onClick={() => navigate(-1)}
>
<ArrowBackIcon fontSize="large" />
</button>
<div
css={css`
display: inline-block;
font-size: 2rem;
vertical-align: middle;
`}
>
DETAIL BATCH
</div>
</div>
<div css={css`
font-size: 1.5rem;
display: flex;
align-content: space-between;
`}>
<div css={css`display: flex;`}>
<div css={css`margin-right: 1rem;`}>
Nama Batch:
</div>
<div>{batch.batch_name}</div>
</div>
</div>
<div css={css`font-size: 1.2rem;display: flex;`}>
<div css={css`margin-right: 0.5rem;`}>
Start date:{" "}
</div>
<div>{stringToDateNoTime(batch.start_date)}</div>
</div>
<div css={css`font-size: 1.2rem;display: flex;`}>
<div css={css`margin-right: 0.5rem;`}>
End date:{" "}
</div>
<div>{stringToDateNoTime(batch.end_date)}</div>
</div>
<div css={css`font-size: 1.2rem;display: flex;`}>
<div css={css`margin-right: 0.5rem;`}>
Shipping cost:{" "}
</div>
<div>{stringToCurrency(batch.shipping_cost)}</div>
</div>
<div className="container-fluid row">
<div className="col-12">
<div css={css`flex-grow: 1;`}>
<LinkYellow css={css`border: 3px solid #3c8dbc;`} to="ubah">
UBAH
</LinkYellow>
</div>
</div>
</div>
{/* {editing ?
<>
<ButtonRed
data-testid="button-edit-batch-cancel"
onClick={() => handleEditStart()}
>
CANCEL
</ButtonRed>
<ButtonSubmit
data-testid="button-edit-batch-apply"
onClick={() => handleEditApply()}
>
APPLY
</ButtonSubmit>
</> :
<ButtonSubmit
data-testid="button-edit-batch-start"
onClick={() => handleEditStart()}
>
EDIT
</ButtonSubmit>
} */}
</div>
)
}
export default DetailBatch;
import React from "react";
import { css } from "@emotion/core";
import FormBatch from "./FormBatch";
import ArrowBackIcon from "@material-ui/icons/ArrowBack";
import ErrorOutlineIcon from "@material-ui/icons/ErrorOutline";
import useFetchSingleData from "../../utils/useFetchSingleData";
import useSendData from "../../utils/useSendData";
import { navigate } from "@reach/router";
import {ErrorDiv } from "../../component/html/html";
const EditBatch = ({ batchId }) => {
const url = `${process.env.REACT_APP_BASE_URL}/batch/${batchId}/`;
// const url = `http://localhost:8000/batch/${batchId}/`; // for local testing purposes
const [initialData, errorState] = useFetchSingleData(url);
const [send, error] = useSendData({ url, method: "PATCH", redirect: -1 });
const onSubmit = (data) => {
const formData = new FormData();
formData.append("batch_name", data["batch_name"]);
formData.append("start_date", data["start_date"]);
formData.append("end_date", data["end_date"]);
formData.append("shipping_cost", data["shipping_cost"])
send(formData);
};
if (errorState || Object.keys(initialData).length === 0)
return (
<div
data-testid="waiting-edit-batch"
css={css`
display: flex;
margin: 2rem 3rem 3rem 3rem;
flex-direction: column;
font-size: 25px;
`}
>
Fetching data..
</div>
);
return (
<div
data-testid="edit-batch"
css={css`
display: flex;
margin: 2rem 3rem 3rem 3rem;
flex-direction: column;
`}
>
{error && <ErrorDiv>Error !, Data tidak dapat disimpan</ErrorDiv>}
<div
css={css`
display: flex;
flex-direction: row;
`}
>
<button
data-testid="back"
css={css`
background-color: Transparent;
background-repeat: no-repeat;
border: none;
cursor: pointer;
overflow: hidden;
outline: none;
`}
onClick={() => navigate(-1)}
>
<ArrowBackIcon fontSize="large" />
</button>
<div
css={css`
font-size: 36px;