mirror of
https://github.com/Unleash/unleash.git
synced 2025-03-18 00:19:49 +01:00
chore: remove dataUsageMultiMonthView flag (#9429)
Remove data usage multi month view flag and deprecated components and functions.
This commit is contained in:
parent
2e086161eb
commit
8629cda4d7
@ -1,26 +1,13 @@
|
||||
import { endOfMonth, format, startOfMonth } from 'date-fns';
|
||||
import {
|
||||
useInstanceTrafficMetrics,
|
||||
useTrafficSearch,
|
||||
} from 'hooks/api/getters/useInstanceTrafficMetrics/useInstanceTrafficMetrics';
|
||||
import { useTrafficSearch } from 'hooks/api/getters/useInstanceTrafficMetrics/useInstanceTrafficMetrics';
|
||||
import { useMemo } from 'react';
|
||||
import {
|
||||
calculateOverageCost,
|
||||
calculateTotalUsage,
|
||||
} from 'utils/traffic-calculations';
|
||||
import { BILLING_TRAFFIC_BUNDLE_PRICE } from './BillingPlan';
|
||||
import { useUiFlag } from 'hooks/useUiFlag';
|
||||
import { useTrafficDataEstimation } from 'hooks/useTrafficData';
|
||||
|
||||
export const useOverageCost = (includedTraffic: number) => {
|
||||
if (useUiFlag('dataUsageMultiMonthView')) {
|
||||
return useNewOverageCostCalculation(includedTraffic);
|
||||
} else {
|
||||
return useOldOverageCostCalculation(includedTraffic);
|
||||
}
|
||||
};
|
||||
|
||||
const useNewOverageCostCalculation = (includedTraffic: number) => {
|
||||
if (!includedTraffic) {
|
||||
return 0;
|
||||
}
|
||||
@ -46,34 +33,3 @@ const useNewOverageCostCalculation = (includedTraffic: number) => {
|
||||
|
||||
return overageCost;
|
||||
};
|
||||
|
||||
const useOldOverageCostCalculation = (includedTraffic: number) => {
|
||||
const {
|
||||
currentPeriod,
|
||||
toChartData,
|
||||
toTrafficUsageSum,
|
||||
endpointsInfo,
|
||||
getDayLabels,
|
||||
} = useTrafficDataEstimation();
|
||||
|
||||
const traffic = useInstanceTrafficMetrics(currentPeriod.key);
|
||||
|
||||
const overageCost = useMemo(() => {
|
||||
if (!includedTraffic) {
|
||||
return 0;
|
||||
}
|
||||
const trafficData = toChartData(
|
||||
getDayLabels(currentPeriod.dayCount),
|
||||
traffic,
|
||||
endpointsInfo,
|
||||
);
|
||||
const totalTraffic = toTrafficUsageSum(trafficData);
|
||||
return calculateOverageCost(
|
||||
totalTraffic,
|
||||
includedTraffic,
|
||||
BILLING_TRAFFIC_BUNDLE_PRICE,
|
||||
);
|
||||
}, [includedTraffic, traffic, currentPeriod, endpointsInfo]);
|
||||
|
||||
return overageCost;
|
||||
};
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { type FC, useEffect, useMemo, useState } from 'react';
|
||||
import useTheme from '@mui/material/styles/useTheme';
|
||||
import type { FC } from 'react';
|
||||
import styled from '@mui/material/styles/styled';
|
||||
import { usePageTitle } from 'hooks/usePageTitle';
|
||||
import Select from 'component/common/select';
|
||||
import { Link as RouterLink } from 'react-router-dom';
|
||||
import { Alert, Link } from '@mui/material';
|
||||
import { Alert } from '@mui/material';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import {
|
||||
@ -18,25 +16,14 @@ import {
|
||||
} from 'chart.js';
|
||||
|
||||
import { Bar } from 'react-chartjs-2';
|
||||
import { useInstanceTrafficMetrics } from 'hooks/api/getters/useInstanceTrafficMetrics/useInstanceTrafficMetrics';
|
||||
import Grid from '@mui/material/Grid';
|
||||
import { NetworkTrafficUsagePlanSummary } from './NetworkTrafficUsagePlanSummary';
|
||||
import annotationPlugin from 'chartjs-plugin-annotation';
|
||||
import {
|
||||
calculateEstimatedMonthlyCost as deprecatedCalculateEstimatedMonthlyCost,
|
||||
useTrafficDataEstimation,
|
||||
} from 'hooks/useTrafficData';
|
||||
import { customHighlightPlugin } from 'component/common/Chart/customHighlightPlugin';
|
||||
import { useTrafficLimit } from './hooks/useTrafficLimit';
|
||||
import { BILLING_TRAFFIC_BUNDLE_PRICE } from 'component/admin/billing/BillingDashboard/BillingPlan/BillingPlan';
|
||||
import { useLocationSettings } from 'hooks/useLocationSettings';
|
||||
import { PeriodSelector } from './PeriodSelector';
|
||||
import { useUiFlag } from 'hooks/useUiFlag';
|
||||
import { OverageInfo, RequestSummary } from './RequestSummary';
|
||||
import { calculateOverageCost } from 'utils/traffic-calculations';
|
||||
import { currentMonth } from './dates';
|
||||
import { type ChartDatasetType, getChartLabel } from './chart-functions';
|
||||
import { createBarChartOptions } from './bar-chart-options';
|
||||
import { getChartLabel } from './chart-functions';
|
||||
import { useTrafficStats } from './hooks/useStats';
|
||||
import { BoldText, StyledBox, TopRow } from './SharedComponents';
|
||||
import { useChartDataSelection } from './hooks/useChartDataSelection';
|
||||
@ -48,7 +35,7 @@ const TrafficInfoBoxes = styled('div')(({ theme }) => ({
|
||||
gap: theme.spacing(2, 4),
|
||||
}));
|
||||
|
||||
const NewNetworkTrafficUsage: FC = () => {
|
||||
const NetworkTrafficUsage: FC = () => {
|
||||
usePageTitle('Network - Data Usage');
|
||||
|
||||
const estimateTrafficDataCost = useUiFlag('estimateTrafficDataCost');
|
||||
@ -142,183 +129,6 @@ const NewNetworkTrafficUsage: FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const NetworkTrafficUsage: FC = () => {
|
||||
const useNewNetworkTraffic = useUiFlag('dataUsageMultiMonthView');
|
||||
return useNewNetworkTraffic ? (
|
||||
<NewNetworkTrafficUsage />
|
||||
) : (
|
||||
<OldNetworkTrafficUsage />
|
||||
);
|
||||
};
|
||||
|
||||
const OldNetworkTrafficUsage: FC = () => {
|
||||
usePageTitle('Network - Data Usage');
|
||||
const theme = useTheme();
|
||||
|
||||
const { isOss } = useUiConfig();
|
||||
|
||||
const { locationSettings } = useLocationSettings();
|
||||
const {
|
||||
record,
|
||||
period,
|
||||
setPeriod,
|
||||
selectablePeriods,
|
||||
getDayLabels,
|
||||
toChartData,
|
||||
toTrafficUsageSum,
|
||||
endpointsInfo,
|
||||
} = useTrafficDataEstimation();
|
||||
|
||||
const includedTraffic = useTrafficLimit();
|
||||
|
||||
const options = useMemo(() => {
|
||||
return createBarChartOptions(
|
||||
theme,
|
||||
(tooltipItems: any) => {
|
||||
const periodItem = record[period];
|
||||
const tooltipDate = new Date(
|
||||
periodItem.year,
|
||||
periodItem.month,
|
||||
Number.parseInt(tooltipItems[0].label),
|
||||
);
|
||||
return tooltipDate.toLocaleDateString(
|
||||
locationSettings?.locale ?? 'en-US',
|
||||
{
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
year: 'numeric',
|
||||
},
|
||||
);
|
||||
},
|
||||
includedTraffic,
|
||||
);
|
||||
}, [theme, period]);
|
||||
|
||||
const traffic = useInstanceTrafficMetrics(period);
|
||||
|
||||
const [labels, setLabels] = useState<number[]>([]);
|
||||
|
||||
const [datasets, setDatasets] = useState<ChartDatasetType[]>([]);
|
||||
|
||||
const [usageTotal, setUsageTotal] = useState<number>(0);
|
||||
|
||||
const [overageCost, setOverageCost] = useState<number>(0);
|
||||
|
||||
const [estimatedMonthlyCost, setEstimatedMonthlyCost] = useState<number>(0);
|
||||
|
||||
const data = {
|
||||
labels,
|
||||
datasets,
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setDatasets(toChartData(labels, traffic, endpointsInfo));
|
||||
}, [labels, traffic]);
|
||||
|
||||
useEffect(() => {
|
||||
if (record && period) {
|
||||
const periodData = record[period];
|
||||
setLabels(getDayLabels(periodData.dayCount));
|
||||
}
|
||||
}, [period]);
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
const usage = toTrafficUsageSum(data.datasets);
|
||||
setUsageTotal(usage);
|
||||
if (includedTraffic > 0) {
|
||||
const calculatedOverageCost = calculateOverageCost(
|
||||
usage,
|
||||
includedTraffic,
|
||||
BILLING_TRAFFIC_BUNDLE_PRICE,
|
||||
);
|
||||
setOverageCost(calculatedOverageCost);
|
||||
|
||||
setEstimatedMonthlyCost(
|
||||
deprecatedCalculateEstimatedMonthlyCost(
|
||||
period,
|
||||
data.datasets,
|
||||
includedTraffic,
|
||||
new Date(),
|
||||
BILLING_TRAFFIC_BUNDLE_PRICE,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<ConditionallyRender
|
||||
condition={isOss()}
|
||||
show={<Alert severity='warning'>Not enabled.</Alert>}
|
||||
elseShow={
|
||||
<>
|
||||
<ConditionallyRender
|
||||
condition={includedTraffic > 0 && overageCost > 0}
|
||||
show={
|
||||
<Alert severity='warning' sx={{ mb: 4 }}>
|
||||
<b>Heads up!</b> You are currently consuming
|
||||
more requests than your plan includes and will
|
||||
be billed according to our terms. Please see{' '}
|
||||
<Link
|
||||
component={RouterLink}
|
||||
to='https://www.getunleash.io/pricing'
|
||||
>
|
||||
this page
|
||||
</Link>{' '}
|
||||
for more information. In order to reduce your
|
||||
traffic consumption, you may configure an{' '}
|
||||
<Link
|
||||
component={RouterLink}
|
||||
to='https://docs.getunleash.io/reference/unleash-edge'
|
||||
>
|
||||
Unleash Edge instance
|
||||
</Link>{' '}
|
||||
in your own datacenter.
|
||||
</Alert>
|
||||
}
|
||||
/>
|
||||
<StyledBox>
|
||||
<Grid container component='header' spacing={2}>
|
||||
<Grid item xs={12} md={10}>
|
||||
<NetworkTrafficUsagePlanSummary
|
||||
usageTotal={usageTotal}
|
||||
includedTraffic={includedTraffic}
|
||||
overageCost={overageCost}
|
||||
estimatedMonthlyCost={estimatedMonthlyCost}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={2}>
|
||||
<Select
|
||||
id='dataperiod-select'
|
||||
name='dataperiod'
|
||||
options={selectablePeriods}
|
||||
value={period}
|
||||
onChange={(e) => setPeriod(e.target.value)}
|
||||
style={{
|
||||
minWidth: '100%',
|
||||
marginBottom: theme.spacing(2),
|
||||
}}
|
||||
formControlStyles={{ width: '100%' }}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12} md={2}>
|
||||
<Bar
|
||||
data={data}
|
||||
plugins={[customHighlightPlugin()]}
|
||||
options={options}
|
||||
aria-label='An instance metrics line chart with two lines: requests per second for admin API and requests per second for client API'
|
||||
/>
|
||||
</Grid>
|
||||
</StyledBox>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
// Register dependencies that we need to draw the chart.
|
||||
ChartJS.register(
|
||||
annotationPlugin,
|
||||
|
@ -2,42 +2,10 @@ import useSWR from 'swr';
|
||||
import { useMemo } from 'react';
|
||||
import { formatApiPath } from 'utils/formatPath';
|
||||
import handleErrorResponses from '../httpErrorResponseHandler';
|
||||
import type {
|
||||
TrafficUsageDataSegmentedCombinedSchema,
|
||||
TrafficUsageDataSegmentedSchema,
|
||||
} from 'openapi';
|
||||
import type { TrafficUsageDataSegmentedCombinedSchema } from 'openapi';
|
||||
import { cleanTrafficData } from 'utils/traffic-calculations';
|
||||
|
||||
export interface IInstanceTrafficMetricsResponse {
|
||||
usage: TrafficUsageDataSegmentedSchema;
|
||||
|
||||
refetch: () => void;
|
||||
|
||||
loading: boolean;
|
||||
|
||||
error?: Error;
|
||||
}
|
||||
|
||||
export const useInstanceTrafficMetrics = (
|
||||
period: string,
|
||||
): IInstanceTrafficMetricsResponse => {
|
||||
const { data, error, mutate } = useSWR(
|
||||
formatApiPath(`api/admin/metrics/traffic/${period}`),
|
||||
fetcher,
|
||||
);
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
usage: data,
|
||||
loading: !error && !data,
|
||||
refetch: () => mutate(),
|
||||
error,
|
||||
}),
|
||||
[data, error, mutate],
|
||||
);
|
||||
};
|
||||
|
||||
export type InstanceTrafficMetricsResponse2 = {
|
||||
export type InstanceTrafficMetricsResponse = {
|
||||
refetch: () => void;
|
||||
result:
|
||||
| { state: 'success'; data: TrafficUsageDataSegmentedCombinedSchema }
|
||||
@ -54,7 +22,7 @@ export const useTrafficSearch = (
|
||||
from: string;
|
||||
to: string;
|
||||
},
|
||||
): InstanceTrafficMetricsResponse2 => {
|
||||
): InstanceTrafficMetricsResponse => {
|
||||
const apiPath = `api/admin/metrics/traffic-search?grouping=${grouping}&from=${from}&to=${to}`;
|
||||
|
||||
const { data, error, mutate } = useSWR(formatApiPath(apiPath), fetcher);
|
||||
|
@ -1,228 +0,0 @@
|
||||
import type { ChartDatasetType } from 'component/admin/network/NetworkTrafficUsage/chart-functions';
|
||||
import type { IInstanceTrafficMetricsResponse } from './api/getters/useInstanceTrafficMetrics/useInstanceTrafficMetrics';
|
||||
import { useState } from 'react';
|
||||
import {
|
||||
DEFAULT_TRAFFIC_DATA_UNIT_COST,
|
||||
DEFAULT_TRAFFIC_DATA_UNIT_SIZE,
|
||||
calculateOverageCost,
|
||||
} from 'utils/traffic-calculations';
|
||||
import {
|
||||
currentMonth,
|
||||
daysInCurrentMonth,
|
||||
} from 'component/admin/network/NetworkTrafficUsage/dates';
|
||||
|
||||
export type SelectablePeriod = {
|
||||
key: string;
|
||||
dayCount: number;
|
||||
label: string;
|
||||
year: number;
|
||||
month: number;
|
||||
};
|
||||
|
||||
export type EndpointInfo = {
|
||||
label: string;
|
||||
color: string;
|
||||
order: number;
|
||||
};
|
||||
|
||||
const endpointsInfo: Record<string, EndpointInfo> = {
|
||||
'/api/admin': {
|
||||
label: 'Admin',
|
||||
color: '#6D66D9',
|
||||
order: 1,
|
||||
},
|
||||
'/api/frontend': {
|
||||
label: 'Frontend',
|
||||
color: '#A39EFF',
|
||||
order: 2,
|
||||
},
|
||||
'/api/client': {
|
||||
label: 'Server',
|
||||
color: '#D8D6FF',
|
||||
order: 3,
|
||||
},
|
||||
};
|
||||
|
||||
const padMonth = (month: number): string => month.toString().padStart(2, '0');
|
||||
|
||||
export const toSelectablePeriod = (
|
||||
date: Date,
|
||||
label?: string,
|
||||
): SelectablePeriod => {
|
||||
const year = date.getFullYear();
|
||||
const month = date.getMonth();
|
||||
const period = `${year}-${padMonth(month + 1)}`;
|
||||
const dayCount = new Date(year, month + 1, 0).getDate();
|
||||
return {
|
||||
key: period,
|
||||
year,
|
||||
month,
|
||||
dayCount,
|
||||
label:
|
||||
label ||
|
||||
date.toLocaleString('en-US', { month: 'long', year: 'numeric' }),
|
||||
};
|
||||
};
|
||||
|
||||
const currentDate = new Date(Date.now());
|
||||
const currentPeriod = toSelectablePeriod(currentDate, 'Current month');
|
||||
|
||||
const getSelectablePeriods = (): SelectablePeriod[] => {
|
||||
const selectablePeriods = [currentPeriod];
|
||||
for (
|
||||
let subtractMonthCount = 1;
|
||||
subtractMonthCount < 13;
|
||||
subtractMonthCount++
|
||||
) {
|
||||
// JavaScript wraps around the year, so we don't need to handle that.
|
||||
const date = new Date(
|
||||
currentDate.getFullYear(),
|
||||
currentDate.getMonth() - subtractMonthCount,
|
||||
1,
|
||||
);
|
||||
if (date > new Date('2024-03-31')) {
|
||||
selectablePeriods.push(toSelectablePeriod(date));
|
||||
}
|
||||
}
|
||||
return selectablePeriods;
|
||||
};
|
||||
|
||||
const toPeriodsRecord = (
|
||||
periods: SelectablePeriod[],
|
||||
): Record<string, SelectablePeriod> => {
|
||||
return periods.reduce(
|
||||
(acc, period) => {
|
||||
acc[period.key] = period;
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, SelectablePeriod>,
|
||||
);
|
||||
};
|
||||
const toChartData = (
|
||||
days: number[],
|
||||
traffic: IInstanceTrafficMetricsResponse,
|
||||
endpointsInfo: Record<string, EndpointInfo>,
|
||||
): ChartDatasetType[] => {
|
||||
if (!traffic || !traffic.usage || !traffic.usage.apiData) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const data = traffic.usage.apiData
|
||||
.filter((item) => !!endpointsInfo[item.apiPath])
|
||||
.sort(
|
||||
(item1: any, item2: any) =>
|
||||
endpointsInfo[item1.apiPath].order -
|
||||
endpointsInfo[item2.apiPath].order,
|
||||
)
|
||||
.map((item: any) => {
|
||||
const daysRec = days.reduce(
|
||||
(acc, day: number) => {
|
||||
acc[`d${day}`] = 0;
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, number>,
|
||||
);
|
||||
|
||||
for (const dayKey in item.days) {
|
||||
const day = item.days[dayKey];
|
||||
const dayNum = new Date(Date.parse(day.day)).getUTCDate();
|
||||
daysRec[`d${dayNum}`] = day.trafficTypes[0].count;
|
||||
}
|
||||
const epInfo = endpointsInfo[item.apiPath];
|
||||
|
||||
return {
|
||||
label: epInfo.label,
|
||||
data: Object.values(daysRec),
|
||||
backgroundColor: epInfo.color,
|
||||
hoverBackgroundColor: epInfo.color,
|
||||
};
|
||||
});
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
const toTrafficUsageSum = (trafficData: ChartDatasetType[]): number => {
|
||||
const data = trafficData.reduce(
|
||||
(acc: number, current: ChartDatasetType) => {
|
||||
return (
|
||||
acc +
|
||||
current.data.reduce(
|
||||
(acc_inner, current_inner) => acc_inner + current_inner,
|
||||
0,
|
||||
)
|
||||
);
|
||||
},
|
||||
0,
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
export const calculateProjectedUsage = (
|
||||
today: number,
|
||||
trafficData: ChartDatasetType[],
|
||||
daysInPeriod: number,
|
||||
) => {
|
||||
if (today < 5) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const spliceToYesterday = today - 1;
|
||||
const trafficDataUpToYesterday = trafficData.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
data: item.data.slice(0, spliceToYesterday),
|
||||
};
|
||||
});
|
||||
|
||||
const dataUsage = toTrafficUsageSum(trafficDataUpToYesterday);
|
||||
return (dataUsage / spliceToYesterday) * daysInPeriod;
|
||||
};
|
||||
|
||||
export const calculateEstimatedMonthlyCost = (
|
||||
period: string,
|
||||
trafficData: ChartDatasetType[],
|
||||
includedTraffic: number,
|
||||
currentDate: Date,
|
||||
trafficUnitCost = DEFAULT_TRAFFIC_DATA_UNIT_COST,
|
||||
trafficUnitSize = DEFAULT_TRAFFIC_DATA_UNIT_SIZE,
|
||||
) => {
|
||||
if (period !== currentMonth) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const today = currentDate.getDate();
|
||||
const projectedUsage = calculateProjectedUsage(
|
||||
today,
|
||||
trafficData,
|
||||
daysInCurrentMonth,
|
||||
);
|
||||
|
||||
return calculateOverageCost(
|
||||
projectedUsage,
|
||||
includedTraffic,
|
||||
trafficUnitCost,
|
||||
trafficUnitSize,
|
||||
);
|
||||
};
|
||||
|
||||
const getDayLabels = (dayCount: number): number[] => {
|
||||
return [...Array(dayCount).keys()].map((i) => i + 1);
|
||||
};
|
||||
|
||||
export const useTrafficDataEstimation = () => {
|
||||
const selectablePeriods = getSelectablePeriods();
|
||||
const record = toPeriodsRecord(selectablePeriods);
|
||||
const [period, setPeriod] = useState<string>(selectablePeriods[0].key);
|
||||
|
||||
return {
|
||||
record,
|
||||
period,
|
||||
setPeriod,
|
||||
selectablePeriods,
|
||||
getDayLabels,
|
||||
currentPeriod,
|
||||
toChartData,
|
||||
toTrafficUsageSum,
|
||||
endpointsInfo,
|
||||
};
|
||||
};
|
@ -90,7 +90,6 @@ export type UiFlags = {
|
||||
showUserDeviceCount?: boolean;
|
||||
flagOverviewRedesign?: boolean;
|
||||
granularAdminPermissions?: boolean;
|
||||
dataUsageMultiMonthView?: boolean;
|
||||
consumptionModel?: boolean;
|
||||
edgeObservability?: boolean;
|
||||
};
|
||||
|
@ -11,10 +11,6 @@ import type {
|
||||
TrafficUsageDataSegmentedCombinedSchema,
|
||||
TrafficUsageDataSegmentedCombinedSchemaApiDataItem,
|
||||
} from 'openapi';
|
||||
import {
|
||||
calculateEstimatedMonthlyCost as deprecatedCalculateEstimatedMonthlyCost,
|
||||
calculateProjectedUsage as deprecatedCalculateProjectedUsage,
|
||||
} from 'hooks/useTrafficData';
|
||||
|
||||
const testData4Days = [
|
||||
{
|
||||
@ -97,21 +93,13 @@ describe('traffic overage calculation', () => {
|
||||
const period = toSelectablePeriod(now);
|
||||
const testNow = new Date(now.getFullYear(), now.getMonth(), 4);
|
||||
const includedTraffic = 53_000_000;
|
||||
const result = deprecatedCalculateEstimatedMonthlyCost(
|
||||
period.key,
|
||||
testData4Days,
|
||||
includedTraffic,
|
||||
testNow,
|
||||
);
|
||||
expect(result).toBe(0);
|
||||
|
||||
const rawData = trafficData4Days(now);
|
||||
const result2 = calculateEstimatedMonthlyCost(
|
||||
const result = calculateEstimatedMonthlyCost(
|
||||
rawData,
|
||||
includedTraffic,
|
||||
testNow,
|
||||
);
|
||||
expect(result2).toBe(result);
|
||||
expect(result).toBe(0);
|
||||
});
|
||||
|
||||
it('needs 5 days or more to estimate for the month', () => {
|
||||
@ -120,27 +108,18 @@ describe('traffic overage calculation', () => {
|
||||
testData[1].data.push(23_000_000);
|
||||
testData[2].data.push(23_000_000);
|
||||
const now = new Date();
|
||||
const period = toSelectablePeriod(now);
|
||||
const testNow = new Date(now.getFullYear(), now.getMonth(), 5);
|
||||
const includedTraffic = 53_000_000;
|
||||
const result = deprecatedCalculateEstimatedMonthlyCost(
|
||||
period.key,
|
||||
testData,
|
||||
includedTraffic,
|
||||
testNow,
|
||||
);
|
||||
expect(result).toBeGreaterThan(1430);
|
||||
|
||||
const rawData = trafficData4Days(now);
|
||||
rawData[0].dataPoints.push(dataPoint(now)(5, 23_000_000));
|
||||
rawData[1].dataPoints.push(dataPoint(now)(5, 23_000_000));
|
||||
rawData[2].dataPoints.push(dataPoint(now)(5, 23_000_000));
|
||||
const result2 = calculateEstimatedMonthlyCost(
|
||||
const result = calculateEstimatedMonthlyCost(
|
||||
rawData,
|
||||
includedTraffic,
|
||||
testNow,
|
||||
);
|
||||
expect(result2).toBe(result);
|
||||
expect(result).toBeGreaterThan(1430);
|
||||
});
|
||||
|
||||
it('estimates projected data usage', () => {
|
||||
@ -151,24 +130,17 @@ describe('traffic overage calculation', () => {
|
||||
// Testing April 5th of 2024 (30 days)
|
||||
const now = new Date(2024, 3, 5);
|
||||
const period = toSelectablePeriod(now);
|
||||
const result = deprecatedCalculateProjectedUsage(
|
||||
now.getDate(),
|
||||
testData,
|
||||
period.dayCount,
|
||||
);
|
||||
// 22_500_000 * 3 * 30 = 2_025_000_000
|
||||
expect(result).toBe(2_025_000_000);
|
||||
|
||||
const rawData = trafficData4Days(now);
|
||||
rawData[0].dataPoints.push(dataPoint(now)(5, 22_500_000));
|
||||
rawData[1].dataPoints.push(dataPoint(now)(5, 22_500_000));
|
||||
rawData[2].dataPoints.push(dataPoint(now)(5, 22_500_000));
|
||||
const result2 = calculateProjectedUsage({
|
||||
const result = calculateProjectedUsage({
|
||||
dayOfMonth: now.getDate(),
|
||||
daysInMonth: period.dayCount,
|
||||
trafficData: rawData,
|
||||
});
|
||||
expect(result2).toBe(result);
|
||||
// 22_500_000 * 3 * 30 = 2_025_000_000
|
||||
expect(result).toBe(2_025_000_000);
|
||||
});
|
||||
|
||||
it('supports custom price and unit size', () => {
|
||||
@ -194,9 +166,13 @@ describe('traffic overage calculation', () => {
|
||||
const includedTraffic = 53_000_000;
|
||||
const trafficUnitSize = 500_000;
|
||||
const trafficUnitCost = 10;
|
||||
const result = deprecatedCalculateEstimatedMonthlyCost(
|
||||
period.key,
|
||||
testData,
|
||||
|
||||
const rawData = trafficData4Days(now);
|
||||
rawData[0].dataPoints.push(dataPoint(now)(5, 22_500_000));
|
||||
rawData[1].dataPoints.push(dataPoint(now)(5, 22_500_000));
|
||||
rawData[2].dataPoints.push(dataPoint(now)(5, 22_500_000));
|
||||
const result = calculateEstimatedMonthlyCost(
|
||||
rawData,
|
||||
includedTraffic,
|
||||
testNow,
|
||||
trafficUnitCost,
|
||||
@ -208,20 +184,6 @@ describe('traffic overage calculation', () => {
|
||||
const overageUnits = Math.floor(overage / trafficUnitSize);
|
||||
const total = overageUnits * trafficUnitCost;
|
||||
expect(result).toBe(total);
|
||||
|
||||
const rawData = trafficData4Days(now);
|
||||
rawData[0].dataPoints.push(dataPoint(now)(5, 22_500_000));
|
||||
rawData[1].dataPoints.push(dataPoint(now)(5, 22_500_000));
|
||||
rawData[2].dataPoints.push(dataPoint(now)(5, 22_500_000));
|
||||
const result2 = calculateEstimatedMonthlyCost(
|
||||
rawData,
|
||||
includedTraffic,
|
||||
testNow,
|
||||
trafficUnitCost,
|
||||
trafficUnitSize,
|
||||
);
|
||||
|
||||
expect(result2).toBe(result);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -24,9 +24,6 @@ export interface ITrafficDataUsageStore
|
||||
extends Store<IStatTrafficUsage, IStatTrafficUsageKey> {
|
||||
upsert(trafficDataUsage: IStatTrafficUsage): Promise<void>;
|
||||
getTrafficDataUsageForPeriod(period: string): Promise<IStatTrafficUsage[]>;
|
||||
getTrafficDataForMonthRange(
|
||||
monthsBack: number,
|
||||
): Promise<IStatMonthlyTrafficUsage[]>;
|
||||
getDailyTrafficDataUsageForPeriod(
|
||||
from: Date,
|
||||
to: Date,
|
||||
|
@ -1,4 +1,9 @@
|
||||
import { differenceInCalendarMonths, subMonths } from 'date-fns';
|
||||
import {
|
||||
differenceInCalendarMonths,
|
||||
endOfMonth,
|
||||
startOfMonth,
|
||||
subMonths,
|
||||
} from 'date-fns';
|
||||
import dbInit, { type ITestDb } from '../../../test/e2e/helpers/database-init';
|
||||
import getLogger from '../../../test/fixtures/no-logger';
|
||||
import type { ITrafficDataUsageStore, IUnleashStores } from '../../types';
|
||||
@ -234,8 +239,13 @@ test('can query for monthly aggregation of data for a specified range', async ()
|
||||
}
|
||||
|
||||
for (const monthsBack of [3, 6, 12]) {
|
||||
const to = endOfMonth(now);
|
||||
const from = subMonths(startOfMonth(now), monthsBack);
|
||||
const result =
|
||||
await trafficDataUsageStore.getTrafficDataForMonthRange(monthsBack);
|
||||
await trafficDataUsageStore.getMonthlyTrafficDataUsageForPeriod(
|
||||
from,
|
||||
to,
|
||||
);
|
||||
|
||||
// should have the current month and the preceding n months (one entry per group)
|
||||
expect(result.length).toBe((monthsBack + 1) * 2);
|
||||
|
@ -1,10 +1,4 @@
|
||||
import {
|
||||
endOfDay,
|
||||
endOfMonth,
|
||||
startOfDay,
|
||||
startOfMonth,
|
||||
subMonths,
|
||||
} from 'date-fns';
|
||||
import { endOfDay, endOfMonth, startOfDay, startOfMonth } from 'date-fns';
|
||||
import type { Db } from '../../db/db';
|
||||
import type { Logger, LogProvider } from '../../logger';
|
||||
import type {
|
||||
@ -148,13 +142,4 @@ export class TrafficDataUsageStore implements ITrafficDataUsageStore {
|
||||
endOfMonth(month),
|
||||
);
|
||||
}
|
||||
|
||||
// @deprecated: remove with flag `dataUsageMultiMonthView`
|
||||
async getTrafficDataForMonthRange(
|
||||
monthsBack: number,
|
||||
): Promise<IStatMonthlyTrafficUsage[]> {
|
||||
const to = endOfMonth(new Date());
|
||||
const from = startOfMonth(subMonths(to, monthsBack));
|
||||
return this.getMonthlyTrafficDataUsageForPeriod(from, to);
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,6 @@ export type IFlagKey =
|
||||
| 'etagVariant'
|
||||
| 'deltaApi'
|
||||
| 'uniqueSdkTracking'
|
||||
| 'dataUsageMultiMonthView'
|
||||
| 'consumptionModel'
|
||||
| 'teamsIntegrationChangeRequests'
|
||||
| 'edgeObservability'
|
||||
@ -299,10 +298,6 @@ const flags: IFlags = {
|
||||
process.env.UNLEASH_EXPERIMENTAL_UNIQUE_SDK_TRACKING,
|
||||
false,
|
||||
),
|
||||
dataUsageMultiMonthView: parseEnvVarBoolean(
|
||||
process.env.UNLEASH_EXPERIMENTAL_DATA_USAGE_MULTI_MONTH_VIEW,
|
||||
false,
|
||||
),
|
||||
consumptionModel: parseEnvVarBoolean(
|
||||
process.env.EXPERIMENTAL_CONSUMPTION_MODEL,
|
||||
false,
|
||||
|
@ -56,7 +56,6 @@ process.nextTick(async () => {
|
||||
granularAdminPermissions: true,
|
||||
deltaApi: true,
|
||||
uniqueSdkTracking: true,
|
||||
dataUsageMultiMonthView: true,
|
||||
filterExistingFlagNames: true,
|
||||
teamsIntegrationChangeRequests: true,
|
||||
simplifyDisableFeature: true,
|
||||
|
Loading…
Reference in New Issue
Block a user