Openstatus
www.openstatus.dev
1import { beforeEach, describe, expect, test } from "bun:test";
2import type { z } from "zod";
3import type { monitorRegionSchema } from "../src/schema/constants";
4import { updateRegion } from "./region-migration";
5
6// Import the types we need
7
8describe("updateRegion", () => {
9 let regions: z.infer<typeof monitorRegionSchema>[];
10
11 beforeEach(() => {
12 // Reset regions array before each test
13 regions = ["ams", "hkg", "fra", "lax"];
14 });
15
16 describe("when old region exists in array", () => {
17 test("should replace old region with 'sin' when new region does not exist in array", () => {
18 updateRegion("hkg", "sin", regions);
19
20 expect(regions).toEqual(["ams", "sin", "fra", "lax"]);
21 expect(regions).toHaveLength(4);
22 });
23
24 test("should remove old region when new region already exists in array", () => {
25 updateRegion("hkg", "ams", regions);
26
27 expect(regions).toEqual(["ams", "fra", "lax"]);
28 expect(regions).toHaveLength(3);
29 });
30
31 test("should handle replacing first element", () => {
32 updateRegion("ams", "sin", regions);
33
34 expect(regions).toEqual(["sin", "hkg", "fra", "lax"]);
35 });
36
37 test("should handle replacing last element", () => {
38 updateRegion("lax", "sin", regions);
39
40 expect(regions).toEqual(["ams", "hkg", "fra", "sin"]);
41 });
42
43 test("should handle case where old and new region are the same", () => {
44 updateRegion("hkg", "hkg", regions);
45
46 // Since hkg exists, it should be removed (newRegionIndex !== -1)
47 expect(regions).toEqual(["ams", "fra", "lax"]);
48 expect(regions).toHaveLength(3);
49 });
50 });
51
52 describe("when old region does not exist in array", () => {
53 test("should not modify the array when old region is not found", () => {
54 const originalRegions = [...regions];
55 updateRegion("sin", "syd", regions);
56
57 expect(regions).toEqual(originalRegions);
58 expect(regions).toHaveLength(4);
59 });
60 });
61
62 describe("edge cases", () => {
63 test("should handle empty regions array", () => {
64 const emptyRegions: z.infer<typeof monitorRegionSchema>[] = [];
65 updateRegion("hkg", "sin", emptyRegions);
66
67 expect(emptyRegions).toEqual([]);
68 expect(emptyRegions).toHaveLength(0);
69 });
70
71 test("should handle single element array - replace scenario", () => {
72 const singleRegion: z.infer<typeof monitorRegionSchema>[] = ["hkg"];
73 updateRegion("hkg", "sin", singleRegion);
74
75 expect(singleRegion).toEqual(["sin"]);
76 });
77
78 test("should handle single element array - remove scenario", () => {
79 const singleRegion: z.infer<typeof monitorRegionSchema>[] = ["hkg"];
80 updateRegion("hkg", "hkg", singleRegion);
81
82 expect(singleRegion).toEqual([]);
83 });
84
85 test("should handle array with duplicate regions", () => {
86 const duplicateRegions: z.infer<typeof monitorRegionSchema>[] = [
87 "ams",
88 "hkg",
89 "ams",
90 "fra",
91 ];
92 updateRegion("hkg", "sin", duplicateRegions);
93
94 // Should only replace the first occurrence of hkg
95 expect(duplicateRegions).toEqual(["ams", "sin", "ams", "fra"]);
96 });
97
98 test("should handle multiple occurrences of old region", () => {
99 const multipleOldRegions: z.infer<typeof monitorRegionSchema>[] = [
100 "hkg",
101 "ams",
102 "hkg",
103 "fra",
104 ];
105 updateRegion("hkg", "sin", multipleOldRegions);
106
107 // Should only replace the first occurrence
108 expect(multipleOldRegions).toEqual(["sin", "ams", "hkg", "fra"]);
109 });
110
111 describe("function mutates original array", () => {
112 test("should modify the original regions array reference", () => {
113 const originalReference = regions;
114 updateRegion("hkg", "sin", regions);
115
116 // Should be the same reference (mutated)
117 expect(regions).toBe(originalReference);
118 expect(regions).toEqual(["ams", "sin", "fra", "lax"]);
119 });
120 });
121
122 describe("full migrations", () => {
123 test("should modify the original regions array reference", () => {
124 const newRegions = [
125 "ams",
126 "arn",
127 "atl",
128 "bog",
129 "bom",
130 "bos",
131 "cdg",
132 "den",
133 "dfw",
134 "ewr",
135 "eze",
136 "fra",
137 "gdl",
138 "gig",
139 "gru",
140 "hkg",
141 "iad",
142 "jnb",
143 "lax",
144 "lhr",
145 "mad",
146 "mia",
147 "nrt",
148 "ord",
149 "otp",
150 "phx",
151 "qro",
152 "sin",
153 "scl",
154 "sjc",
155 "sea",
156 "sin",
157 "syd",
158 "waw",
159 "yul",
160 "yyz",
161 ] as z.infer<typeof monitorRegionSchema>[];
162 // Asia Pacific
163 updateRegion("hkg", "sin", newRegions);
164
165 // North America
166 updateRegion("atl", "dfw", newRegions);
167 updateRegion("mia", "dfw", newRegions);
168 updateRegion("gdl", "dfw", newRegions);
169 updateRegion("qro", "dfw", newRegions);
170 updateRegion("bos", "ewr", newRegions);
171 updateRegion("phx", "lax", newRegions);
172 updateRegion("sea", "sjc", newRegions);
173 updateRegion("yul", "yyz", newRegions);
174
175 // Europe
176 updateRegion("waw", "ams", newRegions);
177 updateRegion("mad", "cdg", newRegions);
178 updateRegion("otp", "fra", newRegions);
179
180 // South America
181 updateRegion("bog", "gru", newRegions);
182 updateRegion("gig", "gru", newRegions);
183 updateRegion("scl", "gru", newRegions);
184 updateRegion("eze", "gru", newRegions);
185
186 // Should be the same reference (mutated)
187
188 expect(newRegions).toEqual([
189 "ams",
190 "arn",
191 "bom",
192 "cdg",
193 "den",
194 "dfw",
195 "ewr",
196 "fra",
197 "gru",
198 "iad",
199 "jnb",
200 "lax",
201 "lhr",
202 "nrt",
203 "ord",
204 "sin",
205 "sjc",
206 "sin",
207 "syd",
208 "yyz",
209 ]);
210 });
211 });
212 });
213});