Skip to content

Commit

Permalink
Add tests for common/config (#23349)
Browse files Browse the repository at this point in the history
* Add tests for common/config

* Revert version dev hook
  • Loading branch information
wendevlin authored Dec 22, 2024
1 parent 0a28bbd commit 523c38a
Show file tree
Hide file tree
Showing 8 changed files with 324 additions and 14 deletions.
19 changes: 13 additions & 6 deletions src/common/config/can_show_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
138 changes: 138 additions & 0 deletions test/common/config/can_show_page.test.ts
Original file line number Diff line number Diff line change
@@ -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);
});
});
19 changes: 19 additions & 0 deletions test/common/config/components_with_service.test.ts
Original file line number Diff line number Diff line change
@@ -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([]);
});
});
13 changes: 13 additions & 0 deletions test/common/config/is_component_loaded.test.ts
Original file line number Diff line number Diff line change
@@ -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);
});
});
24 changes: 24 additions & 0 deletions test/common/config/is_pwa.test.ts
Original file line number Diff line number Diff line change
@@ -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)");
});
});
44 changes: 44 additions & 0 deletions test/common/config/is_service_loaded.test.ts
Original file line number Diff line number Diff line change
@@ -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);
});
});
23 changes: 23 additions & 0 deletions test/common/config/location_name.test.ts
Original file line number Diff line number Diff line change
@@ -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();
});
});
58 changes: 50 additions & 8 deletions test/common/config/version.test.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,83 @@
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 },

{ 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);
})
);
});

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);
});
});

0 comments on commit 523c38a

Please sign in to comment.