IKHSAN
ENID Baca dalam Bahasa Indonesia

homeio

Public

Forked from doctor-io/homeio

Branch
main
Latest commit
958d74616 October 2026

useCurrentWeather.test.tsx

Open raw
/* @vitest-environment jsdom */

import { renderHook, waitFor } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { useCurrentWeather } from "@/modules/system/hooks/useCurrentWeather";
import { createTestQueryClient, createWrapper } from "@/test/query-client-wrapper";

const mockUseUserLocation = vi.fn();

vi.mock("@/modules/system/hooks/useUserLocation", () => ({
  useUserLocation: () => mockUseUserLocation(),
}));

describe("useCurrentWeather", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("loads weather from Open-Meteo when browser location is available", async () => {
    mockUseUserLocation.mockReturnValue({
      location: {
        latitude: 36.8,
        longitude: 10.1,
        city: "Tunis",
        country: "Tunisia",
      },
      loading: false,
      error: null,
      permissionStatus: "granted",
      requestLocation: vi.fn(),
      setManualLocation: vi.fn(),
    });

    vi.stubGlobal(
      "fetch",
      vi.fn().mockResolvedValue({
        ok: true,
        json: async () => ({
          current: {
            temperature_2m: 21.4,
            apparent_temperature: 20.6,
            relative_humidity_2m: 67,
            wind_speed_10m: 18.5,
            weather_code: 2,
          },
          daily: {
            time: [
              "2026-02-22",
              "2026-02-23",
              "2026-02-24",
              "2026-02-25",
              "2026-02-26",
              "2026-02-27",
            ],
            weather_code: [0, 1, 2, 3, 61, 95],
            temperature_2m_max: [20, 21, 22, 23, 24, 25],
            temperature_2m_min: [11, 12, 13, 14, 15, 16],
          },
        }),
      }),
    );

    const client = createTestQueryClient();
    const { result } = renderHook(() => useCurrentWeather(), {
      wrapper: createWrapper(client),
    });

    await waitFor(() => {
      expect(result.current.isSuccess).toBe(true);
    });

    const [weatherRequestUrl, weatherRequestInit] = vi.mocked(fetch).mock.calls[0] as [
      string,
      RequestInit,
    ];
    const weatherUrl = new URL(weatherRequestUrl);

    expect(weatherUrl.origin + weatherUrl.pathname).toBe("https://api.open-meteo.com/v1/forecast");
    expect(weatherUrl.searchParams.get("latitude")).toBe("36.8");
    expect(weatherUrl.searchParams.get("longitude")).toBe("10.1");
    expect(weatherUrl.searchParams.get("timezone")).toBe("auto");
    expect(weatherUrl.searchParams.get("current")).toBe(
      "temperature_2m,apparent_temperature,relative_humidity_2m,wind_speed_10m,weather_code",
    );
    expect(weatherUrl.searchParams.get("daily")).toBe(
      "weather_code,temperature_2m_max,temperature_2m_min",
    );
    expect(weatherRequestInit).toEqual({
      cache: "no-store",
    });
    expect(vi.mocked(fetch)).toHaveBeenCalledTimes(1);
    expect(result.current.data?.source).toBe("navigator");
    expect(result.current.data?.location.label).toBe("Tunis, Tunisia");
    expect(result.current.data?.current.condition).toBe("Partly cloudy");
    expect(result.current.data?.dailyForecast).toHaveLength(5);
    expect(result.current.data?.dailyForecast[0]?.condition).toBe("Mainly clear");
  });

  it("does not fetch weather when location is unavailable", async () => {
    mockUseUserLocation.mockReturnValue({
      location: null,
      loading: false,
      error: "Location permission denied",
      permissionStatus: "denied",
      requestLocation: vi.fn(),
      setManualLocation: vi.fn(),
    });

    vi.stubGlobal("fetch", vi.fn());

    const client = createTestQueryClient();
    const { result } = renderHook(() => useCurrentWeather(), {
      wrapper: createWrapper(client),
    });

    await waitFor(() => {
      expect(result.current.fetchStatus).toBe("idle");
    });

    expect(result.current.data).toBeUndefined();
    expect(fetch).not.toHaveBeenCalled();
  });
});
bytes
3,904
lines
124
Type
tsx
Latest commit
16 October 2026