Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
1b1ad11
Testing
soujay Jan 10, 2025
72e8863
raw testing of mock data Frontend custom checks
soujay Jan 11, 2025
28d7c4d
dynamic precondition function hasCustomChecks
cquirosj Jan 11, 2025
54e0a7b
No data custom checks tests
cquirosj Jan 11, 2025
25c060d
wip Failing custom checks tests
cquirosj Jan 11, 2025
4d2e333
All custom checks are in a failed state TODOs
cquirosj Jan 11, 2025
b67139a
precondition.hasCustomChecks params rename
cquirosj Jan 11, 2025
e048aed
WIP All custom checks are in a failed state asserts
cquirosj Jan 11, 2025
045f117
Revert "WIP All custom checks are in a failed state asserts"
soujay Jan 12, 2025
b91f7c7
Revert "precondition.hasCustomChecks params rename"
soujay Jan 12, 2025
cd7ec35
Revert "All custom checks are in a failed state TODOs"
soujay Jan 12, 2025
9ec1094
Revert "wip Failing custom checks tests"
soujay Jan 12, 2025
108a218
Revert "No data custom checks tests"
soujay Jan 12, 2025
6b1ae92
Revert "dynamic precondition function hasCustomChecks"
soujay Jan 12, 2025
efbb80e
wip : add mocks for custom checks data, add test to check for "no fai…
soujay Jan 20, 2025
56379a8
add driver set up for servicecontrolwithmonitoring to fix the tests
soujay Jan 20, 2025
03a59cd
refactor files and code
soujay Jan 20, 2025
1b2b5fa
add a template for custom check items and use it for tests
soujay Jan 20, 2025
aef91cf
use mockEndpointDynamic to add customchecks url by querystring
soujay Jan 20, 2025
7f3a697
remove extra space
soujay Jan 20, 2025
c3d833f
added some console.log for testing
soujay Jan 23, 2025
df1ea7d
Update src/Frontend/test/specs/customchecks/viewing-no-data.spec.ts
soujay Jan 22, 2025
2750668
Update src/Frontend/test/specs/customchecks/viewing-no-data.spec.ts
soujay Jan 22, 2025
00a066a
add test for no custom check data scenario
soujay Jan 28, 2025
1b9c24b
set up mock data for custom check and write tests for empty and faile…
soujay Jan 28, 2025
be1a0c3
add no data and failing cutom checks
soujay Jan 29, 2025
f13e57f
fix custom check pagination test
soujay Jan 29, 2025
249bf32
generate custom check items
soujay Jan 29, 2025
2db3427
add test for custom checks to be displayed in descending order of las…
soujay Feb 3, 2025
427e9c0
Added the following tests- When a custom check fails, the custom chec…
soujay Feb 3, 2025
31481fc
test for dismissing a custom check
soujay Feb 4, 2025
03b862f
add test for dismissbutton
soujay Feb 5, 2025
2a6c65d
refactor code
soujay Feb 5, 2025
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
8 changes: 4 additions & 4 deletions src/Frontend/src/components/customchecks/CustomCheckView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,27 @@ const store = useCustomChecksStore();
<template>
<div class="row box box-warning box-no-click">
<div class="col-sm-12 no-side-padding">
<div class="custom-check-row">
<div class="custom-check-row" role="row" aria-label="custom-check-failed-row">
<div class="custom-check-row-detail">
<div class="row box-header">
<div class="col-sm-12 no-side-padding">
<p class="lead">{{ customCheck.failure_reason }}</p>
<p class="lead" role="note" aria-label="custom-check-failed-reason">{{ customCheck.failure_reason }}</p>
<div class="row">
<div class="col-sm-12 no-side-padding">
<p class="metadata">
<span class="metadata"><i aria-hidden="true" class="fa fa-check"></i> Check: {{ customCheck.custom_check_id }}</span>
<span class="metadata"><i aria-hidden="true" class="fa fa-list"></i> Category: {{ customCheck.category }}</span>
<span class="metadata"><i aria-hidden="true" class="fa pa-endpoint"></i> Endpoint: {{ customCheck.originating_endpoint.name }}</span>
<span class="metadata"><i aria-hidden="true" class="fa fa-server"></i> Host: {{ customCheck.originating_endpoint.host }}</span>
<span class="metadata"><i aria-hidden="true" class="fa fa-clock-o"></i> Last checked: <TimeSince :date-utc="customCheck.reported_at"></TimeSince></span>
<span class="metadata"><i aria-hidden="true" class="fa fa-clock-o"></i> Last checked: <TimeSince :date-utc="customCheck.reported_at" role="note" aria-label="custom-check-reported-date"></TimeSince></span>
</p>
</div>
</div>
</div>
</div>
</div>
<div>
<button type="button" class="btn btn-default" title="Dismiss this custom check so it doesn't show up as an alert" @click="store.dismissCustomCheck(customCheck.id)">Dismiss</button>
<button type="button" class="btn btn-default" title="Dismiss this custom check so it doesn't show up as an alert" role="button" aria-label="custom-check-dismiss" @click="store.dismissCustomCheck(customCheck.id)">Dismiss</button>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const serviceControlWithHeartbeats = async ({ driver }: SetupFactoryOptio
await driver.setUp(precondition.hasUpToDateServicePulse);
await driver.setUp(precondition.hasUpToDateServiceControl);
await driver.setUp(precondition.errorsDefaultHandler);
await driver.setUp(precondition.hasNoFailingCustomChecks);
await driver.setUp(precondition.hasCustomChecksEmpty);
await driver.setUp(precondition.hasEventLogItems);
await driver.setUp(precondition.hasServiceControlMainInstance(minimumSCVersionForEndpointSettings));
await driver.setUp(precondition.hasNoDisconnectedEndpoints);
Expand Down
6 changes: 3 additions & 3 deletions src/Frontend/src/views/CustomChecksView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ const { pageNumber, failingCount, failedChecks } = storeToRefs(store);
</div>

<section name="custom_checks">
<NoData v-if="failingCount === 0" message="No failed custom checks" />
<div v-else class="row">
<NoData v-if="failingCount === 0" message="No failed custom checks" role="note" aria-label="customcheck-message" />
<div v-else class="row" role="table" aria-label="custom-check-list">
<div class="col-sm-12">
<CustomCheckView v-for="item of failedChecks" :key="item.id" :custom-check="item" />
<div class="row">
<PaginationStrip :items-per-page="10" :total-count="failingCount" v-model="pageNumber" />
<PaginationStrip :items-per-page="10" :total-count="failingCount" v-model="pageNumber" role="row" aria-label="custom-check-pagination" />
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const serviceControlWithThroughput = async ({ driver }: SetupFactoryOptio
await driver.setUp(precondition.hasUpToDateServicePulse);
await driver.setUp(precondition.hasUpToDateServiceControl);
await driver.setUp(precondition.errorsDefaultHandler);
await driver.setUp(precondition.hasNoFailingCustomChecks);
await driver.setUp(precondition.hasCustomChecksEmpty);
await driver.setUp(precondition.hasEventLogItems);
await driver.setUp(precondition.hasNoHeartbeatsEndpoints);
await driver.setUp(precondition.hasServiceControlMainInstance(minimumSCVersionForThroughput));
Expand Down
3 changes: 2 additions & 1 deletion src/Frontend/test/mocks/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const driver = makeDriver();
(async () => {
await driver.setUp(precondition.serviceControlWithMonitoring);
//override the default mocked endpoints with a custom list
await driver.setUp(precondition.hasCustomChecks(3, 2));

await driver.setUp(
precondition.monitoredEndpointsNamed([
"Universe.Solarsystem.Mercury.Endpoint1",
Expand All @@ -35,7 +37,6 @@ const driver = makeDriver();
"Universe.Solarsystem.Earth.Endpoint6",
])
);

await driver.setUp(
precondition.hasFailedMessage({
withGroupId: "81dca64e-76fc-e1c3-11a2-3069f51c58c8",
Expand Down
138 changes: 138 additions & 0 deletions src/Frontend/test/preconditions/customChecks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import CustomCheck, { Status } from "@/resources/CustomCheck";
import { SetupFactoryOptions } from "../driver";
const emptyContent = JSON.stringify([]);

export const hasCustomChecksEmpty = ({ driver }: SetupFactoryOptions) => {
const serviceControlInstanceUrl = window.defaultConfig.service_control_url;
driver.mockEndpoint(`${serviceControlInstanceUrl}customchecks`, {
body: emptyContent,
headers: {
"Total-Count": "0", //count of failing custom checks
},
});
};

const generateGuid = () => {
return crypto.randomUUID();
};
const customCheckTemplate = <CustomCheck>{
id: "customchecks/6131fa95-9414-1898-9c83-c5b18587945b",
custom_check_id: "SampleCustomeCheck",
category: "SomeCategory",
status: "Pass",
failure_reason: "I don't know the reason",
reported_at: "2025-01-10T05:06:30.4074087Z",
originating_endpoint: {
name: "EndpointX",
host_id: "ff605b55-6fbb-af56-5753-73c1ff73e601",
host: "ABC",
},
};

export const hasCustomChecks =
(failingCount: number, passingCount: number) =>
({ driver }: SetupFactoryOptions) => {
const customChecksData = generateCustomChecksData(failingCount, passingCount)();

// Call getCustomChecks to mock the endpoints with the generated data
getCustomChecks(customChecksData)({ driver });
};

export const generateCustomChecksData = (failingCount: number, passingCount: number) => () => {
// Calculate total count
const totalCount = failingCount + passingCount;

// Create checks (both failing and passing)
const customChecks = Array.from({ length: totalCount }).map((_, index) => {
// Generate the date based on the index
const date = new Date();
date.setDate(date.getDate() - index); // Subtract `index` days from the current date
const reportedAt = date.toISOString(); // Convert to ISO string format

// Determine status and failure reason
const status = index < failingCount ? Status.Fail : Status.Pass;
const failureReason = status === Status.Fail ? `configured to fail on endpoint ${index}` : "";

// Generate a new GUID for the ID and host_id
const newGuid = generateGuid();
const originatingEndpointName = `endpoint ${index}`;
const originatingHost = `ABC ${index}`;
const customCategory = `Some Category ${index}`;
const customeCheckId = `SampleCustomeCheck ${index}`;

return {
...customCheckTemplate,
id: `customchecks/${newGuid}`, // New GUID for ID
category: customCategory,
custom_check_id: customeCheckId,
status, // Fail or Pass based on index
failure_reason: failureReason, // Failure reason or empty for passing
reported_at: reportedAt, // Autogenerated reported_at based on index
originating_endpoint: {
name: originatingEndpointName, // Endpoint name based on index
host_id: newGuid, // New GUID for host_id
host: originatingHost, // Host name based on index
},
};
});
return customChecks;
};

export const getCustomChecks =
(customChecks: CustomCheck[]) =>
({ driver }: SetupFactoryOptions) => {
const serviceControlInstanceUrl = window.defaultConfig.service_control_url;

const failedCustomChecks = customChecks.filter((check) => check.status === "Fail");

driver.mockEndpointDynamic(`${serviceControlInstanceUrl}customchecks`, "get", (url) => {
const status = url.searchParams.get("status");
if (status === "fail") {
return Promise.resolve({
body: failedCustomChecks,
headers: { "Total-Count": failedCustomChecks.length.toString() },
});
}

return Promise.resolve({
body: customChecks,
headers: { "Total-Count": customChecks.length.toString() },
});
});
driver.mockEndpointDynamic(`${serviceControlInstanceUrl}customchecks/:id`, "delete", (url, params) => {
const status = url.searchParams.get("status");
console.log(status + ", " + params.id);

return Promise.resolve({
body: { message: "Successfully deleted" },
status: 200,
headers: { "Content-Type": "application/json" },
});
});
};

export const updateCustomCheckItemByStatus = (data: CustomCheck[], statusToUpdate: string) => {
const itemToUpdate = data.find((item) => item.status === statusToUpdate);

if (itemToUpdate) {
if (statusToUpdate === "Pass") {
itemToUpdate.status = Status.Fail;
itemToUpdate.failure_reason = "Some reason I dont know";
} else {
itemToUpdate.status = Status.Pass;
itemToUpdate.failure_reason = "";
}
}
};
export const updateCustomCheckItemByItem = (data: CustomCheck[], itemToUpdate: CustomCheck, statusToUpdate: string) => {
const itemFound = data.find((item) => item.id === itemToUpdate.id);
if (itemFound != null) {
if (statusToUpdate === "Fail") {
itemToUpdate.status = Status.Fail;
itemToUpdate.failure_reason = "Some reason I dont know";
} else {
itemToUpdate.status = Status.Pass;
itemToUpdate.failure_reason = "";
}
}
};
11 changes: 0 additions & 11 deletions src/Frontend/test/preconditions/hasNoFailingCustomChecks.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/Frontend/test/preconditions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export { hasServiceControlMonitoringInstanceUrl } from "../preconditions/hasServ
export { hasUpToDateServiceControl } from "../preconditions/hasUpToDateServiceControl";
export { hasUpToDateServicePulse } from "../preconditions/hasUpToDateServicePulse";
export { errorsDefaultHandler } from "../preconditions/hasNoErrors";
export { hasNoFailingCustomChecks } from "../preconditions/hasNoFailingCustomChecks";
export { hasCustomChecksEmpty, hasCustomChecks, generateCustomChecksData, getCustomChecks, updateCustomCheckItemByStatus, updateCustomCheckItemByItem } from "./customChecks";
export { hasNoDisconnectedEndpoints } from "../preconditions/hasNoDisconnectedEndpoints";
export { hasNoMonitoredEndpoints, hasMonitoredEndpointsList, monitoredEndpointsNamed } from "../preconditions/hasMonitoredEndpoints";
export { hasEventLogItems } from "../preconditions/hasEventLogItems";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const serviceControlWithMonitoring = async ({ driver }: SetupFactoryOptio
await driver.setUp(precondition.errorsDefaultHandler);

//http://localhost:33333/api/customchecks
await driver.setUp(precondition.hasNoFailingCustomChecks);
await driver.setUp(precondition.hasCustomChecksEmpty);

//http://localhost:33633/monitored-endpoints/disconnected
await driver.setUp(precondition.hasNoDisconnectedEndpoints);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,85 @@
import { test, describe } from "../../drivers/vitest/driver";
import { expect } from "vitest";
import * as precondition from "../../preconditions";
import { customChecksListElement, customChecksDismissButtonList, customChecksFailedRowsList } from "./questions/failedCustomChecks";
import { waitFor } from "@testing-library/vue";
import userEvent from "@testing-library/user-event";

describe("FEATURE: Dismiss custom checks", () => {
describe("RULE: Dismiss button should be visible", () => {
test.todo("EXAMPLE: Dismiss button should be visible on each failing custom check");
test("EXAMPLE: Dismiss button is visible on each failing custom check", async ({ driver }) => {
const failingCustomCheckCount = 4;
const passingCustomCheckCount = 2;

/* SCENARIO
Given 2 failing custom checks
And the custom checks page is open
Then each should render a dismiss button
*/
await driver.setUp(precondition.serviceControlWithMonitoring);
await driver.setUp(precondition.hasCustomChecks(failingCustomCheckCount, passingCustomCheckCount));

await driver.goTo("/custom-checks");

await waitFor(async () => {
expect(await customChecksListElement()).toBeInTheDocument();
});

await waitFor(async () => {
expect(await customChecksDismissButtonList()).toHaveLength(failingCustomCheckCount); //count of dismiss button
});
});
});

describe("RULE: Dismissing a custom check should remove from the list", () => {
test.todo("EXAMPLE: The dismiss button should remove the custom check from the list when clicked");
test("EXAMPLE: The dismiss button removes the custom check from the list when clicked", async ({ driver }) => {
const failingCustomCheckCount = 4;
const passingCustomCheckCount = 2;

await driver.setUp(precondition.serviceControlWithMonitoring);
await driver.setUp(precondition.hasCustomChecks(failingCustomCheckCount, passingCustomCheckCount));

await driver.goTo("/custom-checks");

await waitFor(async () => {
expect(await customChecksListElement()).toBeInTheDocument(); //failed list is visisble
expect(await customChecksFailedRowsList()).toHaveLength(failingCustomCheckCount); //count of failed checks matches failing count set
});

let dismissButtonList = await customChecksDismissButtonList();
expect(dismissButtonList).toHaveLength(failingCustomCheckCount); //count of dismiss button matches the failed custom check count

/* SCENARIO
Given 2 failing custom checks
When the dismiss button is clicked
Then the dismissed custom check should be removed from the list
*/
//click the dismiss button
await userEvent.click(dismissButtonList[0]);

//get the new dismiss button list
dismissButtonList = await customChecksDismissButtonList();
expect(dismissButtonList).toHaveLength(failingCustomCheckCount - 1); //count of dismss button is decreased by 1
});
});
describe("RULE: Failing after a dismiss should cause the failed check to reappear", () => {
test.todo("EXAMPLE: Dismissed custom check should reappear in the list when it fails");

/* SCENARIO
Given 2 failed custom checks
And one of them is dismissed
When the dismissed custom check fails
Then the custom check should appear in the list
*/
test("EXAMPLE: Dismissed custom check should reappear in the list when it fails", async ({ driver }) => {
const failingCustomCheckCount = 4;
const passingCustomCheckCount = 0;

await driver.setUp(precondition.serviceControlWithMonitoring);

const customCheckItems = precondition.generateCustomChecksData(failingCustomCheckCount, passingCustomCheckCount)();
await driver.setUp(precondition.getCustomChecks(customCheckItems));
await driver.goTo("/custom-checks");

await waitFor(async () => {
expect(await customChecksListElement()).toBeInTheDocument(); //failed list is visisble
expect(await customChecksFailedRowsList()).toHaveLength(failingCustomCheckCount); //count of failed checks matches failing count set
});

const dismissButtonList = await customChecksDismissButtonList();
expect(dismissButtonList).toHaveLength(failingCustomCheckCount); //count of dismiss button

//click dismiss button
await userEvent.click(dismissButtonList[0]);
expect(await customChecksDismissButtonList()).toHaveLength(failingCustomCheckCount - 1); //count of dismiss button
expect(await customChecksFailedRowsList()).toHaveLength(failingCustomCheckCount - 1); //count of failed checks matches failing count set

//re-add the dismissed custom check Item
await driver.setUp(precondition.getCustomChecks(customCheckItems));
await driver.goTo("/custom-checks");
expect(await customChecksFailedRowsList()).toHaveLength(failingCustomCheckCount); //count of failed checks matches failing count set
});
});
});
Loading