fix: show accurate removal dialog for expired licenses (#22018)

## Summary

The license removal confirmation dialog always showed:

> Removing this license will disable all Premium features. You add a new
license at any time.

This is misleading when the license being removed is already expired —
an expired license isn't providing any features, so removing it won't
disable anything.

## Changes

- Extracted `isExpired` variable in `LicenseCard` (reusing the existing
expiry check)
- Made the dialog description conditional:
- **Expired license**: "This license has already expired and is not
providing any features. Removing it will not affect your current
entitlements."
- **Active license**: "Removing this license will disable all Premium
features. You can add a new license at any time."
- Also fixed a minor typo in the active license message ("You add" →
"You can add")
- Added two new tests covering both dialog variants

## Testing

All 5 `LicenseCard` tests pass, including the 2 new ones:
- `shows expired removal message for expired licenses`
- `shows disabling features warning for active licenses`

---------

Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com>
This commit is contained in:
blinkagent[bot]
2026-02-16 07:34:51 +00:00
committed by GitHub
co-authored by blink-so[bot]
parent 4b3889e4f9
commit 2ed9e7fa6d
2 changed files with 49 additions and 2 deletions
@@ -1,6 +1,7 @@
import { MockLicenseResponse } from "testHelpers/entities";
import { render } from "testHelpers/renderHelpers";
import { screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { LicenseCard } from "./LicenseCard";
describe("LicenseCard", () => {
@@ -40,6 +41,44 @@ describe("LicenseCard", () => {
await screen.findByText("Enterprise");
});
it("shows expired removal message for expired licenses", async () => {
const user = userEvent.setup();
render(
<LicenseCard
license={MockLicenseResponse[3]}
userLimitActual={1}
userLimitLimit={10}
onRemove={() => null}
isRemoving={false}
/>,
);
const removeButton = await screen.findByRole("button", { name: /remove/i });
await user.click(removeButton);
await screen.findByText(/This license has already expired/);
});
it("shows disabling features warning for active licenses", async () => {
const user = userEvent.setup();
render(
<LicenseCard
license={MockLicenseResponse[0]}
userLimitActual={1}
userLimitLimit={10}
onRemove={() => null}
isRemoving={false}
/>,
);
const removeButton = await screen.findByRole("button", { name: /remove/i });
await user.click(removeButton);
await screen.findByText(
/Removing this license will disable all Premium features/,
);
});
it("renders license's user_limit when it is available instead of using the default", async () => {
const licenseUserLimit = 3;
const license = {
@@ -29,6 +29,10 @@ export const LicenseCard: FC<LicenseCardProps> = ({
const currentUserLimit = license.claims.features.user_limit || userLimitLimit;
const isExpired = dayjs
.unix(license.claims.license_expires)
.isBefore(dayjs());
const licenseType = license.claims.trial
? "Trial"
: license.claims.feature_set?.toLowerCase() === "premium"
@@ -57,7 +61,11 @@ export const LicenseCard: FC<LicenseCardProps> = ({
title="Confirm License Removal"
confirmLoading={isRemoving}
confirmText="Remove"
description="Removing this license will disable all Premium features. You add a new license at any time."
description={
isExpired
? "This license has already expired and is not providing any features. Removing it will not affect your current entitlements."
: "Removing this license will disable all Premium features. You can add a new license at any time."
}
/>
<Stack
direction="row"
@@ -94,7 +102,7 @@ export const LicenseCard: FC<LicenseCardProps> = ({
</Stack>
)}
<Stack direction="column" spacing={0} alignItems="center">
{dayjs(license.claims.license_expires * 1000).isBefore(dayjs()) ? (
{isExpired ? (
<Pill css={styles.expiredBadge} type="error">
Expired
</Pill>