feat: test integration connection (#669)

* feat: add test integration for pi-hole

* refactor: test integration for pi-hole

* fix: multiple secrets of same type could be used for integration creation

* fix: remove integration test connection test and add mock for test-connection function

* fix: add missing onUpdateFn to mysql integration secrets

* fix: format issues

* feat: add home assistant test connection

* fix: deepsource issues

* test: add system integration tests for test connection

* fix: add before all for pulling home assistant image

* test: add unit tests for handleTestConnectionResponseAsync

* test: add unit test for testConnectionAsync

* test: add mroe tests to integration-test-connection

* fix: deepsource issues

* fix: deepsource issue

* chore: address pull request feedback
This commit is contained in:
Meier Lukas
2024-06-22 21:02:04 +02:00
committed by GitHub
parent 92afd82d22
commit f92aeba403
30 changed files with 1138 additions and 550 deletions

View File

@@ -5,13 +5,9 @@ import { Integration } from "../base/integration";
import { entityStateSchema } from "./homeassistant-types";
export class HomeAssistantIntegration extends Integration {
async getEntityStateAsync(entityId: string) {
public async getEntityStateAsync(entityId: string) {
try {
const response = await fetch(appendPath(this.integration.url, `/states/${entityId}`), {
headers: {
Authorization: `Bearer ${this.getSecretValue("apiKey")}`,
},
});
const response = await this.getAsync(`/api/states/${entityId}`);
const body = (await response.json()) as unknown;
if (!response.ok) {
logger.warn(`Response did not indicate success`);
@@ -29,17 +25,12 @@ export class HomeAssistantIntegration extends Integration {
}
}
async triggerAutomationAsync(entityId: string) {
public async triggerAutomationAsync(entityId: string) {
try {
const response = await fetch(appendPath(this.integration.url, "/services/automation/trigger"), {
headers: {
Authorization: `Bearer ${this.getSecretValue("apiKey")}`,
},
body: JSON.stringify({
entity_id: entityId,
}),
method: "POST",
const response = await this.postAsync("/api/services/automation/trigger", {
entity_id: entityId,
});
return response.ok;
} catch (err) {
logger.error(`Failed to fetch from '${this.integration.url}': ${err as string}`);
@@ -53,21 +44,61 @@ export class HomeAssistantIntegration extends Integration {
* @param entityId - The ID of the entity to toggle.
* @returns A boolean indicating whether the toggle action was successful.
*/
async triggerToggleAsync(entityId: string) {
public async triggerToggleAsync(entityId: string) {
try {
const response = await fetch(appendPath(this.integration.url, "/services/homeassistant/toggle"), {
headers: {
Authorization: `Bearer ${this.getSecretValue("apiKey")}`,
},
body: JSON.stringify({
entity_id: entityId,
}),
method: "POST",
const response = await this.postAsync("/api/services/homeassistant/toggle", {
entity_id: entityId,
});
return response.ok;
} catch (err) {
logger.error(`Failed to fetch from '${this.integration.url}': ${err as string}`);
return false;
}
}
public async testConnectionAsync(): Promise<void> {
await super.handleTestConnectionResponseAsync({
queryFunctionAsync: async () => {
return await this.getAsync("/api/config");
},
});
}
/**
* Makes a GET request to the Home Assistant API.
* It includes the authorization header with the API key.
* @param path full path to the API endpoint
* @returns the response from the API
*/
private async getAsync(path: `/api/${string}`) {
return await fetch(appendPath(this.integration.url, path), {
headers: this.getAuthHeaders(),
});
}
/**
* Makes a POST request to the Home Assistant API.
* It includes the authorization header with the API key.
* @param path full path to the API endpoint
* @param body the body of the request
* @returns the response from the API
*/
private async postAsync(path: `/api/${string}`, body: Record<string, string>) {
return await fetch(appendPath(this.integration.url, path), {
headers: this.getAuthHeaders(),
body: JSON.stringify(body),
method: "POST",
});
}
/**
* Returns the headers required for authorization.
* @returns the authorization headers
*/
private getAuthHeaders() {
return {
Authorization: `Bearer ${this.getSecretValue("apiKey")}`,
};
}
}