Fakultas Ilmu Komputer UI

Commit 0c7295a1 authored by Tsamara Esperanti Erwin's avatar Tsamara Esperanti Erwin 🦄
Browse files

progress program

parent 0846d17a
...@@ -33,7 +33,7 @@ test("Test detail program renders", async () => { ...@@ -33,7 +33,7 @@ test("Test detail program renders", async () => {
await waitFor(() => getByTestId("program")); await waitFor(() => getByTestId("program"));
const program = getByTestId("program"); const program = getByTestId("program");
expect(program.textContent).toContain("Eddrick"); expect(program.textContent).toContain("Eddrick");
expect(fetch.mock.calls.length).toEqual(1); expect(fetch.mock.calls.length).toEqual(2);
}); });
test("Test mock detail program return error", async () => { test("Test mock detail program return error", async () => {
...@@ -72,7 +72,7 @@ test("Test detail program delete", async () => { ...@@ -72,7 +72,7 @@ test("Test detail program delete", async () => {
await waitFor(() => getByTestId("page")); await waitFor(() => getByTestId("page"));
const produk = getByTestId("page"); const produk = getByTestId("page");
expect(produk.textContent).toContain("dummy 2"); expect(produk.textContent).toContain("dummy 2");
expect(fetch.mock.calls.length).toEqual(1); expect(fetch.mock.calls.length).toEqual(2);
const btnDeleteModal = getByTestId("button-delete-program-modal"); const btnDeleteModal = getByTestId("button-delete-program-modal");
await act(async () => { await act(async () => {
await fireEvent.click(btnDeleteModal); await fireEvent.click(btnDeleteModal);
...@@ -81,7 +81,7 @@ test("Test detail program delete", async () => { ...@@ -81,7 +81,7 @@ test("Test detail program delete", async () => {
await act(async () => { await act(async () => {
await fireEvent.click(btnDelete); await fireEvent.click(btnDelete);
}); });
expect(fetch.mock.calls.length).toEqual(2); expect(fetch.mock.calls.length).toEqual(3);
}); });
test("Test detail produk delete error", async () => { test("Test detail produk delete error", async () => {
...@@ -110,7 +110,7 @@ test("Test detail produk delete error", async () => { ...@@ -110,7 +110,7 @@ test("Test detail produk delete error", async () => {
await waitFor(() => getByTestId("page")); await waitFor(() => getByTestId("page"));
const produk = getByTestId("page"); const produk = getByTestId("page");
expect(produk.textContent).toContain("Eddrick"); expect(produk.textContent).toContain("Eddrick");
expect(fetch.mock.calls.length).toEqual(1); expect(fetch.mock.calls.length).toEqual(2);
const btnDeleteModal = getByTestId("button-delete-program-modal"); const btnDeleteModal = getByTestId("button-delete-program-modal");
await act(async () => { await act(async () => {
await fireEvent.click(btnDeleteModal); await fireEvent.click(btnDeleteModal);
...@@ -119,8 +119,68 @@ test("Test detail produk delete error", async () => { ...@@ -119,8 +119,68 @@ test("Test detail produk delete error", async () => {
await act(async () => { await act(async () => {
await fireEvent.click(btnDelete); await fireEvent.click(btnDelete);
}); });
expect(fetch.mock.calls.length).toEqual(2); expect(fetch.mock.calls.length).toEqual(3);
expect(produk.textContent).toContain( expect(produk.textContent).toContain(
"Tidak dapat menghapus program, mohon periksa apakah ada program ini." "Tidak dapat menghapus program, mohon periksa apakah ada program ini."
); );
}); });
test("Test progress program renders", async () => {
fetch
.once(
JSON.stringify({
id: "6d7462da-6a85-4e2b-9930-69567090a5d5",
code: "3MXZ9T",
name: "dummy 2",
description: "yeyyy",
start_date_time: null,
end_date_time: null,
location: "Depok",
speaker: "Eddrick",
poster_image:
"https://industripilar-api-staging.s3.amazonaws.com/media/uploads/programs/1_txtcYocQEGtOFN33ZCTDbw.png",
})
)
.once(
JSON.stringify([{
description: "ada progress guys",
date: "2020-04-28",
image:
"https://industripilar-api-staging.s3.amazonaws.com/media/uploads/programs/1_txtcYocQEGtOFN33ZCTDbw.png",
}])
)
.once(JSON.stringify({}), { statusCode: 200 });
;
const { getByTestId } = render(
<AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
<DetailProgram />
</AuthContext.Provider>
);
await waitFor(() => getByTestId("program"));
const program = getByTestId("program");
expect(program.textContent).toContain("Eddrick");
await waitFor(() => getByTestId("progress-date"));
const progressDate = getByTestId("progress-date");
expect(progressDate.textContent).toContain("2020-04-28");
await act(async () => {
await fireEvent.click(getByTestId("button-see-proof"));
});
const close = getByTestId("button-close-proof");
expect(close.textContent).toContain("Close");
await act(async () => {
await fireEvent.click(close);
});
expect(fetch.mock.calls.length).toEqual(2);
});
test("Test mock progress program fail", async () => {
fetch.mockReject(new Error("error message"));
const { getByTestId } = render(
<AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
<DetailProgram />
</AuthContext.Provider>
);
await waitFor(() => getByTestId("progress"));
const progress = getByTestId("progress");
expect(progress.textContent).toContain("Error, progress not found");
});
...@@ -2,7 +2,8 @@ import { act, cleanup, fireEvent, render } from "@testing-library/react"; ...@@ -2,7 +2,8 @@ import { act, cleanup, fireEvent, render } from "@testing-library/react";
import AuthContext from "../../utils/contex"; import AuthContext from "../../utils/contex";
import { waitFor } from "@testing-library/dom"; import { waitFor } from "@testing-library/dom";
import React from "react"; import React from "react";
import EditProduk from "../../page/program/EditProgram"; import EditProgram from "../../page/program/EditProgram";
import FormProgress from "../../page/program/FormProgress";
beforeEach(() => { beforeEach(() => {
fetch.resetMocks(); fetch.resetMocks();
...@@ -30,7 +31,7 @@ test("Test edit program renders", async () => { ...@@ -30,7 +31,7 @@ test("Test edit program renders", async () => {
const { getByTestId } = render( const { getByTestId } = render(
<AuthContext.Provider value={{ profile: { token: "BEBAS" } }}> <AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
<EditProduk /> <EditProgram />
</AuthContext.Provider> </AuthContext.Provider>
); );
const waitProgram = getByTestId("waiting-edit-program"); const waitProgram = getByTestId("waiting-edit-program");
...@@ -44,8 +45,7 @@ test("Test edit program renders", async () => { ...@@ -44,8 +45,7 @@ test("Test edit program renders", async () => {
await act(async () => { await act(async () => {
await fireEvent.submit(getByTestId("submit-program")); await fireEvent.submit(getByTestId("submit-program"));
}); });
expect(fetch.mock.calls.length).toEqual(3);
expect(fetch.mock.calls.length).toEqual(2);
}); });
test("Test edit program renders error", async () => { test("Test edit program renders error", async () => {
...@@ -72,7 +72,7 @@ test("Test edit program renders error", async () => { ...@@ -72,7 +72,7 @@ test("Test edit program renders error", async () => {
const { getByTestId } = render( const { getByTestId } = render(
<AuthContext.Provider value={{ profile: { token: "BEBAS" } }}> <AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
<EditProduk /> <EditProgram />
</AuthContext.Provider> </AuthContext.Provider>
); );
const waitProgram = getByTestId("waiting-edit-program"); const waitProgram = getByTestId("waiting-edit-program");
...@@ -90,8 +90,99 @@ test("Test edit program renders error", async () => { ...@@ -90,8 +90,99 @@ test("Test edit program renders error", async () => {
await act(async () => { await act(async () => {
await fireEvent.submit(getByTestId("submit-program")); await fireEvent.submit(getByTestId("submit-program"));
}); });
expect(fetch.mock.calls.length).toEqual(3);
});
const produk = getByTestId("edit-program"); test("Test progress program modal", async () => {
expect(produk.textContent).toContain("Error !, Data tidak dapat disimpan"); fetch.once(
JSON.stringify({
id: "6d7462da-6a85-4e2b-9930-69567090a5d5",
code: "3MXZ9T",
name: "dummy 2",
description: "yeyyy",
start_date_time: null,
end_date_time: null,
location: "Depok",
speaker: "Eddrick",
open_donation: true,
program_minutes: null,
poster_image:
"https://industripilar-api-staging.s3.amazonaws.com/media/uploads/programs/1_txtcYocQEGtOFN33ZCTDbw.png",
link: null,
total_donation_amount: "2263691.00",
})
);
const { getByTestId } = render(
<AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
<EditProgram />
</AuthContext.Provider>
);
const waitProgram = getByTestId("waiting-edit-program");
expect(waitProgram.textContent).toContain("Fetching data..");
await waitFor(() => getByTestId("edit-program"));
const name_program = getByTestId("name-program-input");
expect(name_program.value).toEqual("dummy 2");
const modalButton = getByTestId("button-progress")
await act(async () => {
await fireEvent.click(modalButton);
});
const modal = getByTestId("modal-progress");
expect(modal.textContent).toContain("Tambah Progress");
expect(modal.textContent).toContain("Tanggal");
expect(modal.textContent).toContain("Berita");
expect(modal.textContent).toContain("Gambar");
const close = getByTestId("close-button");
await act(async () => {
await fireEvent.click(close);
});
expect(fetch.mock.calls.length).toEqual(2); expect(fetch.mock.calls.length).toEqual(2);
}); });
test("Test progress program modal submit", async () => {
fetch.once(
JSON.stringify({
id: "6d7462da-6a85-4e2b-9930-69567090a5d5",
code: "3MXZ9T",
name: "dummy 2",
description: "yeyyy",
start_date_time: null,
end_date_time: null,
location: "Depok",
speaker: "Eddrick",
open_donation: true,
program_minutes: null,
poster_image:
"https://industripilar-api-staging.s3.amazonaws.com/media/uploads/programs/1_txtcYocQEGtOFN33ZCTDbw.png",
link: null,
total_donation_amount: "2263691.00",
})
);
const { getByTestId } = render(
<AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
<FormProgress />
</AuthContext.Provider>
);
const tanggal_progress = getByTestId("tanggal-progress");
await act(async () => {
await fireEvent.input(tanggal_progress, { target: { value: "2020-05-12T19:30" } });
});
const berita_progress = getByTestId("berita-progress");
await act(async () => {
await fireEvent.input(berita_progress, { target: { value: "ini berita" } });
});
const gambar_progress = getByTestId("gambar-progress");
await act(async () => {
await fireEvent.input(gambar_progress, {
target: { value: "" },
});
});
await act(async () => {
await fireEvent.submit(getByTestId("save-button"));
});
expect(fetch.mock.calls.length).toEqual(0);
});
...@@ -150,7 +150,7 @@ const DetailDonasiBarang = ({ idDonasi }) => { ...@@ -150,7 +150,7 @@ const DetailDonasiBarang = ({ idDonasi }) => {
> >
<div> <div>
{donation.delivery_address === null ? ( {donation.delivery_address === null ? (
<div>Diantar ke masjid Al-Jabar</div> <div>Diantar ke Masjid Al-Jabar</div>
) : ( ) : (
<div>Dijemput di {donation.delivery_address}</div> <div>Dijemput di {donation.delivery_address}</div>
)} )}
......
...@@ -23,12 +23,27 @@ import { ...@@ -23,12 +23,27 @@ import {
const DetailProgram = ({ idProgram }) => { const DetailProgram = ({ idProgram }) => {
const url = `${process.env.REACT_APP_BASE_URL}/programs/${idProgram}/`; const url = `${process.env.REACT_APP_BASE_URL}/programs/${idProgram}/`;
const progressUrl = url+"progress";
const [program, error] = useFetchSingleData(url); const [program, error] = useFetchSingleData(url);
const [progress, progressError] = useFetchSingleData(progressUrl);
const [deleteProgram, errorDelete] = useDelete(url); const [deleteProgram, errorDelete] = useDelete(url);
const [openModal, setOpenModal] = useState(false); const [openModal, setOpenModal] = useState(false);
const handleClose = () => setOpenModal(false); const handleClose = () => setOpenModal(false);
const [dialogOpen, setDialogOpen] = useState(false);
let image;
const handleClickOpen = (img) => {
image = img;
setDialogOpen(true);
};
const handleClickClose = () => {
setDialogOpen(false);
};
const start_date_time = new Date(program.start_date_time).toLocaleString(); const start_date_time = new Date(program.start_date_time).toLocaleString();
const end_date_time = new Date(program.end_date_time).toLocaleString(); const end_date_time = new Date(program.end_date_time).toLocaleString();
return ( return (
<div <div
data-testid="page" data-testid="page"
...@@ -352,11 +367,90 @@ const DetailProgram = ({ idProgram }) => { ...@@ -352,11 +367,90 @@ const DetailProgram = ({ idProgram }) => {
</div> </div>
</div> </div>
</div> </div>
<div
css={css`
margin-top: 1rem;
margin-bottom: 1rem;
`}
>
<div>
<div
css={css`
margin-top: 1rem;
`}
>
<div
css={css`
margin-top: 2rem;
margin-bottom: 1rem;
font-style: normal;
font-weight: normal;
font-size: 24px;
line-height: 22px;
`}
data-testid="progress"
>
Progress Program
{progressError && <ErrorDiv>Error, progress not found.</ErrorDiv>}
{progress.length > 0 ?
<div>
{progress.map ( p =>
<div key={p.id} css={css `margin-top: 1rem; font-size: 18px`}>
<p data-testid="progress-date">{p.date}</p>
<p>{p.description}</p>
{p.image !== null &&
<Button
onClick={() => handleClickOpen(p.image)}
variant="contained"
color="primary"
size="medium"
data-testid="button-see-proof"
>
Gambar
</Button>
}
</div>
)}
</div>
:<div css={css `margin-top: 1rem ; font-size: 18px`}>Belum ada progress</div>
}
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
<Dialog
maxWidth="xl"
open={dialogOpen}
onClose={handleClickClose}
aria-labelledby="max-width-dialog-title"
>
<DialogTitle id="max-width-dialog-title">Bukti Transfer</DialogTitle>
<DialogContent>
<img
css={css`
height: 80vh;
width: 80vw;
object-fit: contain;
`}
src={image}
alt="Foto Progress"
/>
</DialogContent>
<DialogActions>
<Button
data-testid="button-close-proof"
onClick={handleClickClose}
color="primary"
>
Close
</Button>
</DialogActions>
</Dialog>
</div>
); );
}; };
......
import React from "react"; import React, {useState} from "react";
import useFetchSingleData from "../../utils/useFetchSingleData"; import useFetchSingleData from "../../utils/useFetchSingleData";
import { css } from "@emotion/core"; import { css } from "@emotion/core";
import { ErrorDiv } from "../../component/html/html"; import { ErrorDiv, RowInput } from "../../component/html/html";
import FormProgram from "./FormProgram"; import FormProgram from "./FormProgram";
import ArrowBackIcon from "@material-ui/icons/ArrowBack"; import ArrowBackIcon from "@material-ui/icons/ArrowBack";
import ErrorOutlineIcon from "@material-ui/icons/ErrorOutline"; import ErrorOutlineIcon from "@material-ui/icons/ErrorOutline";
import { navigate } from "@reach/router"; import { navigate } from "@reach/router";
import useSendData from "../../utils/useSendData"; import useSendData from "../../utils/useSendData";
import Button from "@material-ui/core/Button";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogTitle from "@material-ui/core/DialogTitle";
import FormProgress from "./FormProgress";
const EditProgram = ({ idProgram }) => { const EditProgram = ({ idProgram }) => {
const url = `${process.env.REACT_APP_BASE_URL}/programs/${idProgram}/`; const url = `${process.env.REACT_APP_BASE_URL}/programs/${idProgram}/`;
const [initialData, errorState] = useFetchSingleData(url); const [initialData, errorState] = useFetchSingleData(url);
const [send, error] = useSendData({ url, method: "PATCH", redirect: -1 }); const [send, error] = useSendData({ url, method: "PATCH", redirect: -1 });
const [dialogOpen, setDialogOpen] = useState(false);
const onSubmit = (data) => { const onSubmit = (data) => {
send(data); send(data);
}; };
const urlProgress = `${process.env.REACT_APP_BASE_URL}/programs/${idProgram}/progress`;
const [initialProgressData] = useFetchSingleData(urlProgress);
const [sendProgress] = useSendData({
url: urlProgress,
method: "POST",
redirect: "/program",
});
const onSubmitProgress = (data) => {
const formData = new FormData();
formData.append( "date", data["tanggal_progress"]);
formData.append("description", data["berita_progress"]);
if (data["gambar_progress"].length !== 0)
formData.append("image", data["gambar_progress"][0]);
sendProgress(formData);
};
if (errorState || Object.keys(initialData).length === 0) if (errorState || Object.keys(initialData).length === 0)
return ( return (
<div <div
...@@ -29,6 +53,13 @@ const EditProgram = ({ idProgram }) => { ...@@ -29,6 +53,13 @@ const EditProgram = ({ idProgram }) => {
Fetching data.. Fetching data..
</div> </div>
); );
const handleClickOpen = () => {
setDialogOpen(true);
};
const handleClose = () => {
setDialogOpen(false);
};
return ( return (
<div <div
data-testid="edit-program" data-testid="edit-program"
...@@ -84,6 +115,51 @@ const EditProgram = ({ idProgram }) => { ...@@ -84,6 +115,51 @@ const EditProgram = ({ idProgram }) => {
</div> </div>
</div> </div>
<FormProgram {...{ onSubmit, initialData }} /> <FormProgram {...{ onSubmit, initialData }} />
<RowInput>
<Button
onClick={handleClickOpen}
variant="contained"
size="medium"
data-testid="button-progress"
css={css`
text-transform: none;
width: 100%;
background: #FFFFFF;
border: 1px solid #3c8dbc;
box-sizing: border-box;
border-radius: 50px;
font-size: 14px;
line-height: 17px;
text-align: center;
letter-spacing: 0.2em;
color: #3c8dbc;
height: 2.3rem;
`}
>
Tambah Progress
</Button>
</RowInput>
<Dialog
maxWidth="xl"
open={dialogOpen}
onClose={handleClose}
aria-labelledby="max-width-dialog-title"
data-testid="modal-progress"
>
<DialogTitle id="max-width-dialog-title">Tambah Progress</DialogTitle>
<DialogContent>
<FormProgress {...{ onSubmitProgress, initialProgressData }} />
</DialogContent>
<DialogActions>
<Button
data-testid="close-button"
onClick={handleClose}
color="primary"
>
Close
</Button>
</DialogActions>
</Dialog>
</div> </div>
); );
}; };
......
...@@ -226,4 +226,4 @@ const FormProgram = ({ onSubmit, initialData = null }) => { ...@@ -226,4 +226,4 @@ const FormProgram = ({ onSubmit, initialData = null }) => {
); );
}; };
export default FormProgram; export default FormProgram;
\ No newline at end of file
import React from "react";
import {
ErrorDiv,