Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 134 additions & 0 deletions src/screens/SelectLineScreen.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -618,3 +618,137 @@ describe('SelectLineScreenPresets - ループデータ生成', () => {
expect(getAllByTestId('preset-card').length).toBe(1);
});
});

describe('SelectLineScreen - 路線切り替え時の前回データクリア', () => {
beforeEach(() => {
jest.clearAllMocks();
});
Comment on lines +623 to +625
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

jest.clearAllMocks()afterEach で呼んでください

ガイドラインに合わせて beforeEach ではなく afterEach に移してください。

修正案
-  beforeEach(() => {
+  afterEach(() => {
     jest.clearAllMocks();
   });
As per coding guidelines "**/*.test.{ts,tsx}: Call `jest.clearAllMocks()` in `afterEach` hook".
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
beforeEach(() => {
jest.clearAllMocks();
});
afterEach(() => {
jest.clearAllMocks();
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/screens/SelectLineScreen.test.tsx` around lines 623 - 625, Move the
jest.clearAllMocks() call out of the beforeEach hook and place it in an
afterEach hook; specifically remove the existing beforeEach(() => {
jest.clearAllMocks(); }) and add afterEach(() => { jest.clearAllMocks(); }) so
tests in SelectLineScreen.test.tsx follow the guideline to clear mocks after
each test.


it('路線選択時に前回の列車種別データ(fetchedTrainTypes, trainType, pendingTrainType)がクリアされる', () => {
const mockSetNavigationState = jest.fn();
// 大江戸線を選択した後の状態を再現
const staleNavigationState = {
headerState: 'CURRENT',
leftStations: [],
trainType: { id: 10, groupId: 500, name: '都営大江戸線' },
pendingTrainType: { id: 10, groupId: 500, name: '都営大江戸線' },
autoModeEnabled: true,
stationForHeader: null,
arrived: false,
approaching: false,
isLEDTheme: false,
fetchedTrainTypes: [{ id: 10, groupId: 500, name: '都営大江戸線' }],
headerTransitionDelay: false,
targetAutoModeStation: null,
firstStop: true,
presetsFetched: false,
presetRoutes: [],
};

(useAtom as jest.Mock).mockReturnValue([
staleNavigationState,
mockSetNavigationState,
]);

// handleLineSelected で fetch 前に行われるリセットをシミュレート
mockSetNavigationState((prev: typeof staleNavigationState) => ({
...prev,
fetchedTrainTypes: [],
trainType: null,
pendingTrainType: null,
}));

const updateFunction = mockSetNavigationState.mock.calls[0][0];
const updatedState = updateFunction(staleNavigationState);

expect(updatedState.fetchedTrainTypes).toEqual([]);
expect(updatedState.trainType).toBeNull();
expect(updatedState.pendingTrainType).toBeNull();
});

it('路線選択時に前回のpending駅データがクリアされる', () => {
const mockSetStationState = jest.fn();
// 大江戸線を選択した後の状態を再現
const staleStationState = {
station: { id: 1, name: '大門' },
stations: [],
pendingStation: { id: 2, name: '六本木' },
pendingStations: [
{ id: 2, name: '六本木' },
{ id: 3, name: '新宿西口' },
],
selectedDirection: 'INBOUND',
wantedDestination: null,
selectedBound: { id: 4, name: '光が丘' },
stationsCache: [],
};

(useAtom as jest.Mock).mockReturnValue([
staleStationState,
mockSetStationState,
]);

// handleLineSelected で fetch 前に行われるリセットをシミュレート
mockSetStationState((prev: typeof staleStationState) => ({
...prev,
pendingStation: null,
pendingStations: [],
selectedDirection: null,
wantedDestination: null,
selectedBound: null,
}));

const updateFunction = mockSetStationState.mock.calls[0][0];
const updatedState = updateFunction(staleStationState);

expect(updatedState.pendingStation).toBeNull();
expect(updatedState.pendingStations).toEqual([]);
expect(updatedState.selectedDirection).toBeNull();
expect(updatedState.wantedDestination).toBeNull();
expect(updatedState.selectedBound).toBeNull();
// 現在の最寄り駅は変更されないことを確認
expect(updatedState.station).toEqual({ id: 1, name: '大門' });
});

it('リセット後に新しい路線データで上書きされる', () => {
const mockSetStationState = jest.fn();
// リセット済みの状態
const resetState = {
station: { id: 1, name: '大門' },
stations: [],
pendingStation: null,
pendingStations: [],
selectedDirection: null,
wantedDestination: null,
selectedBound: null,
stationsCache: [],
};

(useAtom as jest.Mock).mockReturnValue([resetState, mockSetStationState]);

// fetch 完了後に行われる状態更新をシミュレート
const newPendingStation = {
id: 5,
name: '大門',
line: { id: 200, name: '都営浅草線' },
};
const newPendingStations = [
{ id: 5, name: '大門' },
{ id: 6, name: '新橋' },
];
mockSetStationState((prev: typeof resetState) => ({
...prev,
pendingStation: newPendingStation,
pendingStations: newPendingStations,
}));

const updateFunction = mockSetStationState.mock.calls[0][0];
const updatedState = updateFunction(resetState);

expect(updatedState.pendingStation).toEqual(newPendingStation);
expect(updatedState.pendingStations).toEqual(newPendingStations);
// リセット済みのフィールドは null/空のまま(fetch 結果では上書きされない)
expect(updatedState.selectedDirection).toBeNull();
expect(updatedState.selectedBound).toBeNull();
});
Comment on lines +627 to +753
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

実装コードを実行していないため、テストが実質的に自己検証になっています

mockSetNavigationState/StationState に渡す更新関数をテスト側で作って直接評価しているので、実装側がリセット処理を行っていなくてもテストが通ります。SelectLineScreen の実処理(例: ルート選択イベントやハンドラ)を発火させ、そこで渡された更新関数の結果を検証する形にしてください。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/screens/SelectLineScreen.test.tsx` around lines 627 - 753, The tests
currently construct and invoke the state updater themselves, so they pass even
if SelectLineScreen's handler doesn't reset state; instead render/mount
SelectLineScreen and trigger the actual line-selection action (call the handler
via user event e.g., fireEvent.press on the line item or invoke the component
prop that calls handleLineSelected) so the component supplies the updater to
mockSetNavigationState/mockSetStationState; then grab the updater passed by the
component (mockSetNavigationState.mock.calls[0][0] or
mockSetStationState.mock.calls[0][0]) and apply it to the stale state to assert
fetchedTrainTypes/trainType/pendingTrainType and
pendingStation/pendingStations/selectedDirection/wantedDestination/selectedBound
were cleared before fetch and that subsequent fetch updates (simulate fetch
completion) overwrite only intended fields; ensure you no longer call mockSet...
with an inline updater in the test itself but simulate the UI event that
triggers SelectLineScreen.handleLineSelected.

});