-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from crab85193/develop
都道府県選択と人口データ表示機能の追加
- Loading branch information
Showing
2 changed files
with
131 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import React, { useState } from "react"; | ||
import { fetchPopulation } from "../api/population"; // 人口データを取得するAPI | ||
import { Prefecture } from "../types/prefecture"; // 都道府県の型 | ||
import { PopulationCategory } from "../types/population"; // 人口データのカテゴリ型 | ||
|
||
interface PopulationSelectorProps { | ||
prefectures: Prefecture[]; | ||
} | ||
|
||
const PopulationSelector: React.FC<PopulationSelectorProps> = ({ | ||
prefectures, | ||
}) => { | ||
const [selectedPrefecture, setSelectedPrefecture] = useState<string | null>( | ||
null | ||
); | ||
const [populationData, setPopulationData] = useState< | ||
PopulationCategory[] | null | ||
>(null); | ||
const [loading, setLoading] = useState<boolean>(false); | ||
const [error, setError] = useState<string | null>(null); | ||
|
||
const handlePrefectureChange = async ( | ||
event: React.ChangeEvent<HTMLSelectElement> | ||
) => { | ||
const prefCode = event.target.value; | ||
setSelectedPrefecture(prefCode); | ||
setLoading(true); | ||
setError(null); | ||
|
||
try { | ||
const data = await fetchPopulation(prefCode); | ||
setPopulationData(data); | ||
} catch (error) { | ||
setError("人口データの取得に失敗しました. " + error); | ||
} finally { | ||
setLoading(false); | ||
} | ||
}; | ||
|
||
return ( | ||
<div> | ||
<h2>人口データ選択</h2> | ||
<select | ||
onChange={handlePrefectureChange} | ||
value={selectedPrefecture || ""} | ||
> | ||
<option value="">都道府県を選択</option> | ||
{prefectures.map((prefecture) => ( | ||
<option key={prefecture.prefCode} value={prefecture.prefCode}> | ||
{prefecture.prefName} | ||
</option> | ||
))} | ||
</select> | ||
|
||
{loading && <p>読み込み中...</p>} | ||
|
||
{error && <p style={{ color: "red" }}>{error}</p>} | ||
|
||
{populationData && ( | ||
<div> | ||
<h3>年別人口データ</h3> | ||
{populationData.map((category) => ( | ||
<div key={category.label}> | ||
<h4>{category.label}</h4> | ||
<ul> | ||
{category.data.map((entry) => ( | ||
<li key={entry.year}> | ||
{entry.year}: {entry.value}人 (比率: {entry.rate}%) | ||
</li> | ||
))} | ||
</ul> | ||
</div> | ||
))} | ||
</div> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export default PopulationSelector; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import React from "react"; | ||
import { render, screen, fireEvent, waitFor } from "@testing-library/react"; | ||
import PopulationSelector from "./../components/PopulationSelector"; | ||
import { fetchPopulation } from "../api/population"; | ||
import { Prefecture } from "../types/prefecture"; | ||
import { PopulationCategory } from "../types/population"; | ||
|
||
jest.mock("../api/population"); | ||
|
||
describe("PopulationSelector", () => { | ||
const mockPrefectures: Prefecture[] = [ | ||
{ prefCode: 1, prefName: "北海道" }, | ||
{ prefCode: 2, prefName: "青森県" }, | ||
]; | ||
|
||
it("都道府県を選択し、人口データが表示される", async () => { | ||
const mockPopulationData: PopulationCategory[] = [ | ||
{ | ||
label: "年少人口", | ||
data: [{ year: 1960, value: 1681479, rate: 33.37 }], | ||
}, | ||
]; | ||
|
||
(fetchPopulation as jest.Mock).mockResolvedValue(mockPopulationData); | ||
|
||
render(<PopulationSelector prefectures={mockPrefectures} />); | ||
|
||
fireEvent.change(screen.getByRole("combobox"), { target: { value: "1" } }); | ||
|
||
await waitFor(() => screen.getByText("年少人口")); | ||
|
||
expect(screen.getByText("年少人口")).toBeInTheDocument(); | ||
expect( | ||
screen.getByText("1960: 1681479人 (比率: 33.37%)") | ||
).toBeInTheDocument(); | ||
}); | ||
|
||
it("人口データの取得中にエラーメッセージが表示される", async () => { | ||
(fetchPopulation as jest.Mock).mockRejectedValue(new Error("API Error")); | ||
|
||
render(<PopulationSelector prefectures={mockPrefectures} />); | ||
|
||
fireEvent.change(screen.getByRole("combobox"), { target: { value: "1" } }); | ||
|
||
await waitFor(() => screen.getByText(/人口データの取得に失敗しました/i)); | ||
|
||
expect( | ||
screen.getByText(/人口データの取得に失敗しました/i) | ||
).toBeInTheDocument(); | ||
}); | ||
}); |