Skip to content

Commit

Permalink
Merge pull request #6 from crab85193/develop
Browse files Browse the repository at this point in the history
 都道府県選択と人口データ表示機能の追加
  • Loading branch information
crab85193 authored Dec 17, 2024
2 parents 544cc24 + 7825a2e commit 79608ba
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 0 deletions.
80 changes: 80 additions & 0 deletions src/components/PopulationSelector.tsx
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;
51 changes: 51 additions & 0 deletions src/tests/PopulationSelector.test.tsx
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();
});
});

0 comments on commit 79608ba

Please sign in to comment.