diff --git a/src/common/config/can_show_page.ts b/src/common/config/can_show_page.ts index 48ceec7b65..a7bec75622 100644 --- a/src/common/config/can_show_page.ts +++ b/src/common/config/can_show_page.ts @@ -8,20 +8,27 @@ export const canShowPage = (hass: HomeAssistant, page: PageNavigation) => !hideAdvancedPage(hass, page) && isNotLoadedIntegration(hass, page); -const isLoadedIntegration = (hass: HomeAssistant, page: PageNavigation) => +export const isLoadedIntegration = ( + hass: HomeAssistant, + page: PageNavigation +) => !page.component || ensureArray(page.component).some((integration) => isComponentLoaded(hass, integration) ); -const isNotLoadedIntegration = (hass: HomeAssistant, page: PageNavigation) => +export const isNotLoadedIntegration = ( + hass: HomeAssistant, + page: PageNavigation +) => !page.not_component || !ensureArray(page.not_component).some((integration) => isComponentLoaded(hass, integration) ); -const isCore = (page: PageNavigation) => page.core; -const isAdvancedPage = (page: PageNavigation) => page.advancedOnly; -const userWantsAdvanced = (hass: HomeAssistant) => hass.userData?.showAdvanced; -const hideAdvancedPage = (hass: HomeAssistant, page: PageNavigation) => +export const isCore = (page: PageNavigation) => page.core; +export const isAdvancedPage = (page: PageNavigation) => page.advancedOnly; +export const userWantsAdvanced = (hass: HomeAssistant) => + hass.userData?.showAdvanced; +export const hideAdvancedPage = (hass: HomeAssistant, page: PageNavigation) => isAdvancedPage(page) && !userWantsAdvanced(hass); diff --git a/test/common/config/can_show_page.test.ts b/test/common/config/can_show_page.test.ts new file mode 100644 index 0000000000..fc444e8ce2 --- /dev/null +++ b/test/common/config/can_show_page.test.ts @@ -0,0 +1,138 @@ +import { describe, it, expect } from "vitest"; +import { + canShowPage, + isLoadedIntegration, + isNotLoadedIntegration, + isCore, + isAdvancedPage, + userWantsAdvanced, + hideAdvancedPage, +} from "../../../src/common/config/can_show_page"; +import type { PageNavigation } from "../../../src/layouts/hass-tabs-subpage"; +import type { HomeAssistant } from "../../../src/types"; + +describe("canShowPage", () => { + it("should return true if the page can be shown", () => { + const hass = { + config: { components: ["test_component"] }, + userData: { showAdvanced: true }, + } as unknown as HomeAssistant; + const page = { + component: "test_component", + core: true, + advancedOnly: false, + } as unknown as PageNavigation; + expect(canShowPage(hass, page)).toBe(true); + }); + + it("should return false if the page cannot be shown", () => { + const hass = { + config: { components: ["test_component"] }, + userData: { showAdvanced: false }, + } as unknown as HomeAssistant; + const page = { + component: "other_component", + core: false, + advancedOnly: true, + } as unknown as PageNavigation; + expect(canShowPage(hass, page)).toBe(false); + }); +}); + +describe("isLoadedIntegration", () => { + it("should return true if the integration is loaded", () => { + const hass = { + config: { components: ["test_component"] }, + } as unknown as HomeAssistant; + const page = { component: "test_component" } as unknown as PageNavigation; + expect(isLoadedIntegration(hass, page)).toBe(true); + }); + + it("should return false if the integration is not loaded", () => { + const hass = { + config: { components: ["test_component"] }, + } as unknown as HomeAssistant; + const page = { component: "other_component" } as unknown as PageNavigation; + expect(isLoadedIntegration(hass, page)).toBe(false); + }); +}); + +describe("isNotLoadedIntegration", () => { + it("should return true if the integration is not loaded", () => { + const hass = { + config: { components: ["test_component"] }, + } as unknown as HomeAssistant; + const page = { + not_component: "other_component", + } as unknown as PageNavigation; + expect(isNotLoadedIntegration(hass, page)).toBe(true); + }); + + it("should return false if the integration is loaded", () => { + const hass = { + config: { components: ["test_component"] }, + } as unknown as HomeAssistant; + const page = { + not_component: "test_component", + } as unknown as PageNavigation; + expect(isNotLoadedIntegration(hass, page)).toBe(false); + }); +}); + +describe("isCore", () => { + it("should return true if the page is core", () => { + const page = { core: true } as unknown as PageNavigation; + expect(isCore(page)).toBe(true); + }); + + it("should return false if the page is not core", () => { + const page = { core: false } as unknown as PageNavigation; + expect(isCore(page)).toBe(false); + }); +}); + +describe("isAdvancedPage", () => { + it("should return true if the page is advanced", () => { + const page = { advancedOnly: true } as unknown as PageNavigation; + expect(isAdvancedPage(page)).toBe(true); + }); + + it("should return false if the page is not advanced", () => { + const page = { advancedOnly: false } as unknown as PageNavigation; + expect(isAdvancedPage(page)).toBe(false); + }); +}); + +describe("userWantsAdvanced", () => { + it("should return true if the user wants advanced pages", () => { + const hass = { + userData: { showAdvanced: true }, + } as unknown as HomeAssistant; + expect(userWantsAdvanced(hass)).toBe(true); + }); + + it("should return false if the user does not want advanced pages", () => { + const hass = { + userData: { showAdvanced: false }, + } as unknown as HomeAssistant; + expect(userWantsAdvanced(hass)).toBe(false); + }); +}); + +describe("hideAdvancedPage", () => { + it("should return true if the advanced page should be hidden", () => { + const hass = { + userData: { showAdvanced: false }, + } as unknown as HomeAssistant; + const page = { advancedOnly: true } as unknown as PageNavigation; + expect(hideAdvancedPage(hass, page)).toBe(true); + }); + + it("should return false if the advanced page should not be hidden", () => { + const hass = { + userData: { showAdvanced: true }, + } as unknown as HomeAssistant; + const page = { advancedOnly: true } as unknown as PageNavigation; + expect(hideAdvancedPage(hass, page)).toBe(false); + }); +}); diff --git a/test/common/config/components_with_service.test.ts b/test/common/config/components_with_service.test.ts new file mode 100644 index 0000000000..ab4016d648 --- /dev/null +++ b/test/common/config/components_with_service.test.ts @@ -0,0 +1,19 @@ +import { describe, it, expect } from "vitest"; +import { componentsWithService } from "../../../src/common/config/components_with_service"; +import type { HomeAssistant } from "../../../src/types"; + +describe("componentsWithService", () => { + it("should return an array of domains with the service", () => { + const hass = { + services: { + domain1: { test_service: {} }, + domain2: { other_service: {} }, + }, + } as unknown as HomeAssistant; + expect(componentsWithService(hass, "test_service")).toEqual(["domain1"]); + expect(componentsWithService(hass, "other_service")).toEqual(["domain2"]); + + // empty if service is not found + expect(componentsWithService(hass, "another_service")).toEqual([]); + }); +}); diff --git a/test/common/config/is_component_loaded.test.ts b/test/common/config/is_component_loaded.test.ts new file mode 100644 index 0000000000..59d9508dcb --- /dev/null +++ b/test/common/config/is_component_loaded.test.ts @@ -0,0 +1,13 @@ +import { describe, it, expect } from "vitest"; +import { isComponentLoaded } from "../../../src/common/config/is_component_loaded"; +import type { HomeAssistant } from "../../../src/types"; + +describe("isComponentLoaded", () => { + it("should return if the component is loaded", () => { + const hass = { + config: { components: ["test_component"] }, + } as unknown as HomeAssistant; + expect(isComponentLoaded(hass, "test_component")).toBe(true); + expect(isComponentLoaded(hass, "other_component")).toBe(false); + }); +}); diff --git a/test/common/config/is_pwa.test.ts b/test/common/config/is_pwa.test.ts new file mode 100644 index 0000000000..b9fd70f778 --- /dev/null +++ b/test/common/config/is_pwa.test.ts @@ -0,0 +1,24 @@ +import { describe, it, expect, vi, afterEach } from "vitest"; +import isPwa from "../../../src/common/config/is_pwa"; + +describe("isPwa", () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + it("should return true if the display mode is standalone", () => { + const mockMatchMedia = vi.fn(() => ({ matches: true })) as any; + window.matchMedia = mockMatchMedia; + + expect(isPwa()).toBe(true); + expect(mockMatchMedia).toHaveBeenCalledWith("(display-mode: standalone)"); + }); + + it("should return false if the display mode is not standalone", () => { + const mockMatchMedia = vi.fn(() => ({ matches: false })) as any; + window.matchMedia = mockMatchMedia; + expect(isPwa()).toBe(false); + + expect(mockMatchMedia).toHaveBeenCalledWith("(display-mode: standalone)"); + }); +}); diff --git a/test/common/config/is_service_loaded.test.ts b/test/common/config/is_service_loaded.test.ts new file mode 100644 index 0000000000..4cd6a39c54 --- /dev/null +++ b/test/common/config/is_service_loaded.test.ts @@ -0,0 +1,44 @@ +import { describe, it, expect } from "vitest"; +import { isServiceLoaded } from "../../../src/common/config/is_service_loaded"; +import type { HomeAssistant } from "../../../src/types"; + +describe("isServiceLoaded", () => { + it("should return true if the service is loaded", () => { + const hass = { + services: { + light: { + turn_on: {}, + }, + }, + } as unknown as HomeAssistant; + expect(isServiceLoaded(hass, "light", "turn_on")).toBe(true); + }); + + it("should return false if the service is not loaded", () => { + const hass: HomeAssistant = { + services: { + light: { + turn_on: {}, + }, + }, + } as unknown as HomeAssistant; + expect(isServiceLoaded(hass, "light", "turn_off")).toBe(false); + }); + + it("should return false if the domain is not loaded", () => { + const hass: HomeAssistant = { + services: { + light: { + turn_on: {}, + }, + }, + } as unknown as HomeAssistant; + expect(isServiceLoaded(hass, "switch", "turn_on")).toBe(false); + }); + + it("should handle null hass", () => { + expect( + isServiceLoaded(null as unknown as HomeAssistant, "light", "turn_on") + ).toBe(null); + }); +}); diff --git a/test/common/config/location_name.test.ts b/test/common/config/location_name.test.ts new file mode 100644 index 0000000000..e865b9d674 --- /dev/null +++ b/test/common/config/location_name.test.ts @@ -0,0 +1,23 @@ +import { describe, it, expect } from "vitest"; +import computeLocationName from "../../../src/common/config/location_name"; +import type { HomeAssistant } from "../../../src/types"; + +describe("computeLocationName", () => { + it("should return the correct location name", () => { + const hass = { + config: { location_name: "Home" }, + } as unknown as HomeAssistant; + expect(computeLocationName(hass)).toBe("Home"); + }); + + it("should return undefined if the location name is not set", () => { + const hass = { config: {} } as unknown as HomeAssistant; + expect(computeLocationName(hass)).toBeUndefined(); + }); + + it("should return undefined if hass is not provided", () => { + expect( + computeLocationName(undefined as unknown as HomeAssistant) + ).toBeUndefined(); + }); +}); diff --git a/test/common/config/version.test.ts b/test/common/config/version.test.ts index 029abf6f9c..8b4e7fc493 100644 --- a/test/common/config/version.test.ts +++ b/test/common/config/version.test.ts @@ -1,13 +1,16 @@ -import { assert, describe, it } from "vitest"; -import { atLeastVersion } from "../../../src/common/config/version"; +import { afterAll, beforeAll, describe, expect, it } from "vitest"; +import { + atLeastVersion, + isDevVersion, +} from "../../../src/common/config/version"; const testTruthyData = [ { version: "2021.1.1", major: 2021, minor: 1, patch: 1 }, { version: "2021.1.1", major: 2021, minor: 1 }, { version: "2021.1.1", major: 2020, minor: 12, patch: 1 }, { version: "2021.1.1", major: 2020, minor: 12 }, - { version: "2021.1.1", major: 2021, minor: 2, patch: 0 }, - { version: "2021.1.1", major: 2021, minor: 2 }, + { version: "2021.2.0", major: 2021, minor: 2, patch: 0 }, + { version: "2021.2.1", major: 2021, minor: 2 }, { version: "2021.2.4", major: 0, minor: 113, patch: 0 }, { version: "2021.2.4", major: 0, minor: 113 }, @@ -15,19 +18,21 @@ const testTruthyData = [ { version: "0.114.0", major: 0, minor: 113, patch: 0 }, { version: "0.114.0", major: 0, minor: 113 }, - { version: "2021.2.0dev.2323", major: 2021, minor: 2, patch: 0 }, + { version: "2021.2.0dev.2323", major: 2021, minor: 1, patch: 0 }, { version: "2021.2.0dev.2323", major: 2021, minor: 2 }, ]; const testFalsyData = [ - { version: "0.114.0", major: 0, minor: 113 }, + { version: "0.114.0", major: 0, minor: 115 }, { version: "2021.2.0dev.2323", major: 2021, minor: 2, patch: 0 }, ]; describe("atLeastVersion - Truthy", () => { testTruthyData.forEach((test) => it(`'${test.version}' >= ${test.major},${test.minor},${test.patch}`, () => { - assert.isTrue(atLeastVersion("2021.1.1", 2021, 1)); + expect( + atLeastVersion(test.version, test.major, test.minor, test.patch) + ).toBe(true); }) ); }); @@ -35,7 +40,44 @@ describe("atLeastVersion - Truthy", () => { describe("atLeastVersion - Falsy", () => { testFalsyData.forEach((test) => it(`'${test.version}' >= ${test.major},${test.minor},${test.patch}`, () => { - assert.isTrue(atLeastVersion("2021.1.1", 2021, 1)); + expect( + atLeastVersion(test.version, test.major, test.minor, test.patch) + ).toBe(false); }) ); }); + +describe("atLeastVersion - DEMO", () => { + beforeAll(() => { + // eslint-disable-next-line no-global-assign + __DEMO__ = true; + }); + afterAll(() => { + // eslint-disable-next-line no-global-assign + __DEMO__ = false; + }); + + testFalsyData.forEach((test) => + it(`'${test.version}' >= ${test.major},${test.minor},${test.patch}`, () => { + expect(atLeastVersion("2021.1.1", 2021, 1)).toBe(true); + }) + ); +}); + +describe("isDevVersion", () => { + it("should return false for demo version", () => { + // eslint-disable-next-line no-global-assign + __DEMO__ = true; + expect(isDevVersion("2021.1.1dev.123")).toBe(false); + // eslint-disable-next-line no-global-assign + __DEMO__ = false; + }); + + it("should return true for dev version", () => { + expect(isDevVersion("2021.1.1dev.1231")).toBe(true); + }); + + it("should return false for non-dev version", () => { + expect(isDevVersion("2021.1.1")).toBe(false); + }); +});