@@ -15,21 +15,21 @@ public void SetUp()
1515 [ Test ]
1616 public void UpsertEntry_DescendingSort_InsertsInCorrectPosition ( )
1717 {
18- var entry1 = new LeaderboardEntry { id = 1 , score = 100f , leaderboardSortMode = "desc" } ;
19- var entry2 = new LeaderboardEntry { id = 2 , score = 80f , leaderboardSortMode = "desc" } ;
20- var entry3 = new LeaderboardEntry { id = 3 , score = 90f , leaderboardSortMode = "desc" } ;
18+ var entry1 = new LeaderboardEntry { id = 1 , score = 100f , position = 0 , leaderboardSortMode = "desc" } ;
19+ var entry2 = new LeaderboardEntry { id = 2 , score = 80f , position = 2 , leaderboardSortMode = "desc" } ;
20+ var entry3 = new LeaderboardEntry { id = 3 , score = 90f , position = 1 , leaderboardSortMode = "desc" } ;
2121
2222 manager . UpsertEntry ( "test" , entry1 ) ;
2323 manager . UpsertEntry ( "test" , entry2 ) ;
2424 manager . UpsertEntry ( "test" , entry3 ) ;
2525
2626 var entries = manager . GetEntries ( "test" ) ;
27-
27+
2828 Assert . AreEqual ( 3 , entries . Count ) ;
2929 Assert . AreEqual ( 100f , entries [ 0 ] . score ) ;
3030 Assert . AreEqual ( 90f , entries [ 1 ] . score ) ;
3131 Assert . AreEqual ( 80f , entries [ 2 ] . score ) ;
32-
32+
3333 Assert . AreEqual ( 0 , entries [ 0 ] . position ) ;
3434 Assert . AreEqual ( 1 , entries [ 1 ] . position ) ;
3535 Assert . AreEqual ( 2 , entries [ 2 ] . position ) ;
@@ -38,21 +38,21 @@ public void UpsertEntry_DescendingSort_InsertsInCorrectPosition()
3838 [ Test ]
3939 public void UpsertEntry_AscendingSort_InsertsInCorrectPosition ( )
4040 {
41- var entry1 = new LeaderboardEntry { id = 1 , score = 100f , leaderboardSortMode = "asc" } ;
42- var entry2 = new LeaderboardEntry { id = 2 , score = 80f , leaderboardSortMode = "asc" } ;
43- var entry3 = new LeaderboardEntry { id = 3 , score = 90f , leaderboardSortMode = "asc" } ;
41+ var entry1 = new LeaderboardEntry { id = 1 , score = 100f , position = 2 , leaderboardSortMode = "asc" } ;
42+ var entry2 = new LeaderboardEntry { id = 2 , score = 80f , position = 0 , leaderboardSortMode = "asc" } ;
43+ var entry3 = new LeaderboardEntry { id = 3 , score = 90f , position = 1 , leaderboardSortMode = "asc" } ;
4444
4545 manager . UpsertEntry ( "test" , entry1 ) ;
4646 manager . UpsertEntry ( "test" , entry2 ) ;
4747 manager . UpsertEntry ( "test" , entry3 ) ;
4848
4949 var entries = manager . GetEntries ( "test" ) ;
50-
50+
5151 Assert . AreEqual ( 3 , entries . Count ) ;
5252 Assert . AreEqual ( 80f , entries [ 0 ] . score ) ;
5353 Assert . AreEqual ( 90f , entries [ 1 ] . score ) ;
5454 Assert . AreEqual ( 100f , entries [ 2 ] . score ) ;
55-
55+
5656 Assert . AreEqual ( 0 , entries [ 0 ] . position ) ;
5757 Assert . AreEqual ( 1 , entries [ 1 ] . position ) ;
5858 Assert . AreEqual ( 2 , entries [ 2 ] . position ) ;
@@ -62,39 +62,41 @@ public void UpsertEntry_AscendingSort_InsertsInCorrectPosition()
6262 public void UpsertEntry_UpdateExistingEntry_MaintainsCorrectOrder ( )
6363 {
6464 // highest score
65- var entry1 = new LeaderboardEntry { id = 1 , score = 100f , leaderboardSortMode = "desc" } ;
65+ var entry1 = new LeaderboardEntry { id = 1 , score = 100f , position = 0 , leaderboardSortMode = "desc" } ;
6666 manager . UpsertEntry ( "test" , entry1 ) ;
67-
67+
6868 // should go after entry1
69- var entry2 = new LeaderboardEntry { id = 2 , score = 80f , leaderboardSortMode = "desc" } ;
69+ var entry2 = new LeaderboardEntry { id = 2 , score = 80f , position = 1 , leaderboardSortMode = "desc" } ;
7070 manager . UpsertEntry ( "test" , entry2 ) ;
71-
71+
7272 // update entry1 to have the lowest score - should move to end
73- var updatedEntry1 = new LeaderboardEntry { id = 1 , score = 70f , leaderboardSortMode = "desc" } ;
73+ var updatedEntry1 = new LeaderboardEntry { id = 1 , score = 70f , position = 1 , leaderboardSortMode = "desc" } ;
7474 manager . UpsertEntry ( "test" , updatedEntry1 ) ;
7575
76- var entries = manager . GetEntries ( "test" ) ;
76+ var entries = manager . GetEntries ( "test" ) ;
7777 Assert . AreEqual ( 2 , entries . Count ) ;
7878
7979 Assert . AreEqual ( 2 , entries [ 0 ] . id ) ; // entry2 should be first
8080 Assert . AreEqual ( 80f , entries [ 0 ] . score ) ;
8181
82- Assert . AreEqual ( 1 , entries [ 1 ] . id ) ; // updated entry1 should be second
82+ Assert . AreEqual ( 1 , entries [ 1 ] . id ) ; // updated entry1 should be second
8383 Assert . AreEqual ( 70f , entries [ 1 ] . score ) ;
84-
85- Assert . AreEqual ( 0 , entries [ 0 ] . position ) ;
84+
85+ // Both entries have position = 1 - the cache preserves positions as received from the API
86+ // without normalizing them. This is intentional behavior.
87+ Assert . AreEqual ( 1 , entries [ 0 ] . position ) ;
8688 Assert . AreEqual ( 1 , entries [ 1 ] . position ) ;
8789 }
8890
8991 [ Test ]
9092 public void UpsertEntry_EmptyList_InsertsFirstEntry ( )
9193 {
92- var entry = new LeaderboardEntry { id = 1 , score = 100f , leaderboardSortMode = "desc" } ;
94+ var entry = new LeaderboardEntry { id = 1 , score = 100f , position = 0 , leaderboardSortMode = "desc" } ;
9395
9496 manager . UpsertEntry ( "test" , entry ) ;
9597
9698 var entries = manager . GetEntries ( "test" ) ;
97-
99+
98100 Assert . AreEqual ( 1 , entries . Count ) ;
99101 Assert . AreEqual ( 100f , entries [ 0 ] . score ) ;
100102 Assert . AreEqual ( 0 , entries [ 0 ] . position ) ;
@@ -103,17 +105,19 @@ public void UpsertEntry_EmptyList_InsertsFirstEntry()
103105 [ Test ]
104106 public void UpsertEntry_EqualScores_OrdersByCreatedAt ( )
105107 {
106- var earlierEntry = new LeaderboardEntry
107- {
108- id = 1 ,
109- score = 100f ,
108+ var earlierEntry = new LeaderboardEntry
109+ {
110+ id = 1 ,
111+ score = 100f ,
112+ position = 0 ,
110113 leaderboardSortMode = "desc" ,
111114 createdAt = "2025-09-13T10:00:00Z"
112115 } ;
113- var laterEntry = new LeaderboardEntry
114- {
115- id = 2 ,
116- score = 100f ,
116+ var laterEntry = new LeaderboardEntry
117+ {
118+ id = 2 ,
119+ score = 100f ,
120+ position = 1 ,
117121 leaderboardSortMode = "desc" ,
118122 createdAt = "2025-09-13T11:00:00Z"
119123 } ;
@@ -122,12 +126,96 @@ public void UpsertEntry_EqualScores_OrdersByCreatedAt()
122126 manager . UpsertEntry ( "test" , earlierEntry ) ;
123127
124128 var entries = manager . GetEntries ( "test" ) ;
125-
129+
126130 Assert . AreEqual ( 2 , entries . Count ) ;
127131 Assert . AreEqual ( 1 , entries [ 0 ] . id ) ; // earlier entry should be first
128132 Assert . AreEqual ( 2 , entries [ 1 ] . id ) ; // later entry should be second
129133 Assert . AreEqual ( 0 , entries [ 0 ] . position ) ;
130134 Assert . AreEqual ( 1 , entries [ 1 ] . position ) ;
131135 }
136+
137+ [ Test ]
138+ public void UpsertEntry_BumpPositions_BumpsExistingEntries ( )
139+ {
140+ var entry1 = new LeaderboardEntry { id = 1 , score = 100f , position = 0 , leaderboardSortMode = "desc" } ;
141+ var entry2 = new LeaderboardEntry { id = 2 , score = 80f , position = 1 , leaderboardSortMode = "desc" } ;
142+
143+ manager . UpsertEntry ( "test" , entry1 ) ;
144+ manager . UpsertEntry ( "test" , entry2 ) ;
145+
146+ // Insert a new entry with position 0 - should bump the others
147+ var entry3 = new LeaderboardEntry { id = 3 , score = 110f , position = 0 , leaderboardSortMode = "desc" } ;
148+ manager . UpsertEntry ( "test" , entry3 , bumpPositions : true ) ;
149+
150+ var entries = manager . GetEntries ( "test" ) ;
151+
152+ Assert . AreEqual ( 3 , entries . Count ) ;
153+ Assert . AreEqual ( 3 , entries [ 0 ] . id ) ;
154+ Assert . AreEqual ( 0 , entries [ 0 ] . position ) ; // new entry at position 0
155+
156+ Assert . AreEqual ( 1 , entries [ 1 ] . id ) ;
157+ Assert . AreEqual ( 1 , entries [ 1 ] . position ) ; // bumped from 0 to 1
158+
159+ Assert . AreEqual ( 2 , entries [ 2 ] . id ) ;
160+ Assert . AreEqual ( 2 , entries [ 2 ] . position ) ; // bumped from 1 to 2
161+ }
162+
163+ [ Test ]
164+ public void UpsertEntry_BumpPositions_OnlyBumpsAffectedEntries ( )
165+ {
166+ var entry1 = new LeaderboardEntry { id = 1 , score = 100f , position = 0 , leaderboardSortMode = "desc" } ;
167+ var entry2 = new LeaderboardEntry { id = 2 , score = 80f , position = 1 , leaderboardSortMode = "desc" } ;
168+ var entry3 = new LeaderboardEntry { id = 3 , score = 60f , position = 2 , leaderboardSortMode = "desc" } ;
169+
170+ manager . UpsertEntry ( "test" , entry1 ) ;
171+ manager . UpsertEntry ( "test" , entry2 ) ;
172+ manager . UpsertEntry ( "test" , entry3 ) ;
173+
174+ // Insert a new entry at position 1 - should only bump entries at position >= 1
175+ var entry4 = new LeaderboardEntry { id = 4 , score = 90f , position = 1 , leaderboardSortMode = "desc" } ;
176+ manager . UpsertEntry ( "test" , entry4 , bumpPositions : true ) ;
177+
178+ var entries = manager . GetEntries ( "test" ) ;
179+
180+ Assert . AreEqual ( 4 , entries . Count ) ;
181+
182+ Assert . AreEqual ( 1 , entries [ 0 ] . id ) ;
183+ Assert . AreEqual ( 0 , entries [ 0 ] . position ) ; // unchanged
184+
185+ Assert . AreEqual ( 4 , entries [ 1 ] . id ) ;
186+ Assert . AreEqual ( 1 , entries [ 1 ] . position ) ; // new entry at position 1
187+
188+ Assert . AreEqual ( 2 , entries [ 2 ] . id ) ;
189+ Assert . AreEqual ( 2 , entries [ 2 ] . position ) ; // bumped from 1 to 2
190+
191+ Assert . AreEqual ( 3 , entries [ 3 ] . id ) ;
192+ Assert . AreEqual ( 3 , entries [ 3 ] . position ) ; // bumped from 2 to 3
193+ }
194+
195+ [ Test ]
196+ public void UpsertEntry_NoBumpPositions_PreservesExistingPositions ( )
197+ {
198+ var entry1 = new LeaderboardEntry { id = 1 , score = 100f , position = 0 , leaderboardSortMode = "desc" } ;
199+ var entry2 = new LeaderboardEntry { id = 2 , score = 80f , position = 1 , leaderboardSortMode = "desc" } ;
200+
201+ manager . UpsertEntry ( "test" , entry1 ) ;
202+ manager . UpsertEntry ( "test" , entry2 ) ;
203+
204+ // Insert a new entry with position 0 without bumping
205+ var entry3 = new LeaderboardEntry { id = 3 , score = 110f , position = 0 , leaderboardSortMode = "desc" } ;
206+ manager . UpsertEntry ( "test" , entry3 , bumpPositions : false ) ;
207+
208+ var entries = manager . GetEntries ( "test" ) ;
209+
210+ Assert . AreEqual ( 3 , entries . Count ) ;
211+ Assert . AreEqual ( 3 , entries [ 0 ] . id ) ;
212+ Assert . AreEqual ( 0 , entries [ 0 ] . position ) ; // new entry at position 0
213+
214+ Assert . AreEqual ( 1 , entries [ 1 ] . id ) ;
215+ Assert . AreEqual ( 0 , entries [ 1 ] . position ) ; // unchanged - still position 0
216+
217+ Assert . AreEqual ( 2 , entries [ 2 ] . id ) ;
218+ Assert . AreEqual ( 1 , entries [ 2 ] . position ) ; // unchanged - still position 1
219+ }
132220 }
133221}
0 commit comments