Usage.utils.test.ts251 lines · main
1import { describe, expect, it } from 'vitest'
2
3import { dailyUsageToDataPoints } from './Usage.utils'
4import { PricingMetric } from '@/data/analytics/org-daily-stats-query'
5import type { OrgDailyUsageResponse } from '@/data/analytics/org-daily-stats-query'
6
7describe('dailyUsageToDataPoints', () => {
8 it('returns empty array when dailyUsage is undefined', () => {
9 const result = dailyUsageToDataPoints(undefined, () => true)
10 expect(result).toEqual([])
11 })
12
13 it('returns empty array when usages array is empty', () => {
14 const dailyUsage: OrgDailyUsageResponse = {
15 usages: [],
16 }
17 const result = dailyUsageToDataPoints(dailyUsage, () => true)
18 expect(result).toEqual([])
19 })
20
21 it('transforms single usage entry correctly', () => {
22 const dailyUsage: OrgDailyUsageResponse = {
23 usages: [
24 {
25 date: '2025-10-01',
26 metric: PricingMetric.EGRESS,
27 usage: 15,
28 usage_original: 15 * 1e9,
29 breakdown: null,
30 },
31 ],
32 }
33
34 const result = dailyUsageToDataPoints(dailyUsage, () => true)
35
36 expect(result).toHaveLength(1)
37 expect(result[0]).toEqual({
38 period_start: '2025-10-01',
39 periodStartFormatted: '01 Oct',
40 egress: 15 * 1e9,
41 })
42 })
43
44 it('groups multiple metrics by date correctly', () => {
45 const dailyUsage: OrgDailyUsageResponse = {
46 usages: [
47 {
48 date: '2025-10-01',
49 metric: PricingMetric.EGRESS,
50 usage: 1000000,
51 usage_original: 1000000,
52 breakdown: null,
53 },
54 {
55 date: '2025-10-01',
56 metric: PricingMetric.DATABASE_SIZE,
57 usage: 5000000,
58 usage_original: 5000000,
59 breakdown: null,
60 },
61 ],
62 }
63
64 const result = dailyUsageToDataPoints(dailyUsage, () => true)
65
66 expect(result).toHaveLength(1)
67 expect(result[0]).toEqual({
68 period_start: '2025-10-01',
69 periodStartFormatted: '01 Oct',
70 egress: 1000000,
71 database_size: 5000000,
72 })
73 })
74
75 it('creates separate data points for different dates', () => {
76 const dailyUsage: OrgDailyUsageResponse = {
77 usages: [
78 {
79 date: '2025-10-01',
80 metric: PricingMetric.EGRESS,
81 usage: 1000000,
82 usage_original: 1000000,
83 breakdown: null,
84 },
85 {
86 date: '2025-10-02',
87 metric: PricingMetric.EGRESS,
88 usage: 2000000,
89 usage_original: 2000000,
90 breakdown: null,
91 },
92 ],
93 }
94
95 const result = dailyUsageToDataPoints(dailyUsage, () => true)
96
97 expect(result).toHaveLength(2)
98 expect(result[0]).toEqual({
99 period_start: '2025-10-01',
100 periodStartFormatted: '01 Oct',
101 egress: 1000000,
102 })
103 expect(result[1]).toEqual({
104 period_start: '2025-10-02',
105 periodStartFormatted: '02 Oct',
106 egress: 2000000,
107 })
108 })
109
110 it('includes breakdown data when present', () => {
111 const dailyUsage: OrgDailyUsageResponse = {
112 usages: [
113 {
114 date: '2025-10-01',
115 metric: PricingMetric.EGRESS,
116 usage: 1000000,
117 usage_original: 1000000,
118 breakdown: {
119 egress_rest: 400000,
120 egress_realtime: 300000,
121 egress_storage: 200000,
122 egress_supavisor: 100000,
123 egress_function: 0,
124 egress_graphql: 0,
125 egress_logdrain: 0,
126 },
127 },
128 ],
129 }
130
131 const result = dailyUsageToDataPoints(dailyUsage, () => true)
132
133 expect(result).toHaveLength(1)
134 expect(result[0]).toEqual({
135 period_start: '2025-10-01',
136 periodStartFormatted: '01 Oct',
137 egress: 1000000,
138 egress_rest: 400000,
139 egress_realtime: 300000,
140 egress_storage: 200000,
141 egress_supavisor: 100000,
142 egress_function: 0,
143 egress_graphql: 0,
144 egress_logdrain: 0,
145 })
146 })
147
148 it('handles complex scenario with multiple dates, metrics, and breakdowns', () => {
149 const dailyUsage: OrgDailyUsageResponse = {
150 usages: [
151 {
152 date: '2025-10-01',
153 metric: PricingMetric.EGRESS,
154 usage: 1000000,
155 usage_original: 1000000,
156 breakdown: {
157 egress_rest: 600000,
158 egress_realtime: 400000,
159 egress_storage: 0,
160 egress_supavisor: 0,
161 egress_function: 0,
162 egress_graphql: 0,
163 egress_logdrain: 0,
164 },
165 },
166 {
167 date: '2025-10-01',
168 metric: PricingMetric.DATABASE_SIZE,
169 usage: 5000000,
170 usage_original: 5000000,
171 breakdown: null,
172 },
173 {
174 date: '2025-10-02',
175 metric: PricingMetric.EGRESS,
176 usage: 1500000,
177 usage_original: 1500000,
178 breakdown: {
179 egress_rest: 900000,
180 egress_realtime: 600000,
181 egress_storage: 0,
182 egress_supavisor: 0,
183 egress_function: 0,
184 egress_graphql: 0,
185 egress_logdrain: 0,
186 },
187 },
188 {
189 date: '2025-10-02',
190 metric: PricingMetric.STORAGE_SIZE,
191 usage: 2000000,
192 usage_original: 2000000,
193 breakdown: null,
194 },
195 ],
196 }
197
198 const result = dailyUsageToDataPoints(dailyUsage, () => true)
199
200 expect(result).toHaveLength(2)
201 expect(result[0]).toEqual({
202 period_start: '2025-10-01',
203 periodStartFormatted: '01 Oct',
204 egress: 1000000,
205 egress_rest: 600000,
206 egress_realtime: 400000,
207 egress_storage: 0,
208 egress_supavisor: 0,
209 egress_function: 0,
210 egress_graphql: 0,
211 egress_logdrain: 0,
212 database_size: 5000000,
213 })
214 expect(result[1]).toEqual({
215 period_start: '2025-10-02',
216 periodStartFormatted: '02 Oct',
217 egress: 1500000,
218 egress_rest: 900000,
219 egress_realtime: 600000,
220 egress_storage: 0,
221 egress_supavisor: 0,
222 egress_function: 0,
223 egress_graphql: 0,
224 egress_logdrain: 0,
225 storage_size: 2000000,
226 })
227 })
228
229 it('handles zero usage values', () => {
230 const dailyUsage: OrgDailyUsageResponse = {
231 usages: [
232 {
233 date: '2025-10-01',
234 metric: PricingMetric.EGRESS,
235 usage: 0,
236 usage_original: 0,
237 breakdown: null,
238 },
239 ],
240 }
241
242 const result = dailyUsageToDataPoints(dailyUsage, () => true)
243
244 expect(result).toHaveLength(1)
245 expect(result[0]).toEqual({
246 period_start: '2025-10-01',
247 periodStartFormatted: '01 Oct',
248 egress: 0,
249 })
250 })
251})