Skip to content

Commit 5cc7e8a

Browse files
Adding fields for veto system (#896)
Closes #894 Co-authored-by: Brutus5000 <[email protected]>
1 parent d1e53e6 commit 5cc7e8a

File tree

5 files changed

+197
-7
lines changed

5 files changed

+197
-7
lines changed

configuration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
| DATABASE_ADDRESS | | | `127.0.0.1` |
1818
| DATABASE_NAME | | | `faf` |
1919
| DATABASE_PASSWORD | | | `banana` |
20-
| DATABASE_SCHEMA_VERSION | `124` | | |
20+
| DATABASE_SCHEMA_VERSION | `135` | | |
2121
| DATABASE_USERNAME | | | `faf-java-api` |
2222
| EMAIL_FROM_ADDRESS | | | `[email protected]` |
2323
| EMAIL_FROM_NAME | | | `FAForever` |
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
package com.faforever.api.data;
2+
3+
import com.faforever.api.AbstractIntegrationTest;
4+
import com.faforever.api.data.domain.GroupPermission;
5+
import com.faforever.api.security.OAuthScope;
6+
import org.junit.jupiter.api.Test;
7+
import org.springframework.http.HttpHeaders;
8+
import org.springframework.test.context.jdbc.Sql;
9+
import org.springframework.test.context.jdbc.Sql.ExecutionPhase;
10+
11+
import static com.faforever.api.data.JsonApiMediaType.JSON_API_MEDIA_TYPE;
12+
import static org.hamcrest.Matchers.hasSize;
13+
import static org.hamcrest.Matchers.is;
14+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
15+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
16+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
17+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
18+
19+
@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/truncateTables.sql")
20+
@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/prepDefaultData.sql")
21+
@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/prepMatchmakerQueueMapPoolData.sql")
22+
public class MatchmakerQueueMapPoolElideTest extends AbstractIntegrationTest {
23+
24+
private static <T> String genUpdateRequestForField(String fieldName, T fieldValue) {
25+
if (fieldValue instanceof String) {
26+
fieldValue = (T) ("\"" + fieldValue + "\"");
27+
}
28+
29+
return """
30+
{
31+
"data": {
32+
"type": "matchmakerQueueMapPool",
33+
"id": "101",
34+
"attributes": {
35+
"%s": %s
36+
}
37+
}
38+
}
39+
""".formatted(fieldName, fieldValue);
40+
}
41+
42+
@Test
43+
public void canReadMatchmakerQueueMapPoolWithoutScopeAndRole() throws Exception {
44+
mockMvc.perform(get("/data/matchmakerQueueMapPool")
45+
.with(getOAuthTokenWithActiveUser(NO_SCOPE, NO_AUTHORITIES)))
46+
.andExpect(status().isOk())
47+
.andExpect(jsonPath("$.data", hasSize(5)));
48+
}
49+
50+
@Test
51+
public void canReadMatchmakerQueueMapPoolParamsWithoutScopeAndRole() throws Exception {
52+
mockMvc.perform(get("/data/matchmakerQueueMapPool/101")
53+
.with(getOAuthTokenWithActiveUser(NO_SCOPE, NO_AUTHORITIES)))
54+
.andExpect(status().isOk())
55+
.andExpect(jsonPath("$.data.id", is("101")))
56+
.andExpect(jsonPath("$.data.type", is("matchmakerQueueMapPool")))
57+
.andExpect(jsonPath("$.data.attributes.maxRating", is(800.0)))
58+
.andExpect(jsonPath("$.data.attributes.minRating", is(300.0)))
59+
.andExpect(jsonPath("$.data.attributes.vetoTokensPerPlayer", is(1)))
60+
.andExpect(jsonPath("$.data.attributes.minimumMapsAfterVeto", is(1.5)))
61+
.andExpect(jsonPath("$.data.attributes.maxTokensPerMap", is(1)))
62+
.andExpect(jsonPath("$.data.relationships.mapPool.data.id", is("2")))
63+
.andExpect(jsonPath("$.data.relationships.matchmakerQueue.data.id", is("1")));
64+
}
65+
66+
@Test
67+
public void cannotUpdateMatchmakerQueueMapPoolMinRatingWithoutScopeAndRole() throws Exception {
68+
mockMvc.perform(patch("/data/matchmakerQueueMapPool/101")
69+
.with(getOAuthTokenWithActiveUser(NO_SCOPE, NO_AUTHORITIES))
70+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
71+
.content(genUpdateRequestForField("minRating", 1000)))
72+
.andExpect(status().isForbidden());
73+
}
74+
75+
@Test
76+
public void cannotUpdateMatchmakerQueueMapPoolMaxRatingWithoutScopeAndRole() throws Exception {
77+
mockMvc.perform(patch("/data/matchmakerQueueMapPool/101")
78+
.with(getOAuthTokenWithActiveUser(NO_SCOPE, NO_AUTHORITIES))
79+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
80+
.content(genUpdateRequestForField("maxRating", 1000)))
81+
.andExpect(status().isForbidden());
82+
}
83+
84+
@Test
85+
public void cannotUpdateMatchmakerQueueMapPoolVetoTokensPerPlayerWithoutScopeAndRole() throws Exception {
86+
mockMvc.perform(patch("/data/matchmakerQueueMapPool/101")
87+
.with(getOAuthTokenWithActiveUser(NO_SCOPE, NO_AUTHORITIES))
88+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
89+
.content(genUpdateRequestForField("vetoTokensPerPlayer", 1)))
90+
.andExpect(status().isForbidden());
91+
}
92+
93+
@Test
94+
public void cannotUpdateMatchmakerQueueMapPoolMaxTokensPerMapWithoutScopeAndRole() throws Exception {
95+
mockMvc.perform(patch("/data/matchmakerQueueMapPool/101")
96+
.with(getOAuthTokenWithActiveUser(NO_SCOPE, NO_AUTHORITIES))
97+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
98+
.content(genUpdateRequestForField("maxTokensPerMap", 2)))
99+
.andExpect(status().isForbidden());
100+
}
101+
102+
@Test
103+
public void cannotUpdateMatchmakerQueueMapPoolMinimumMapsAfterVetoWithoutScopeAndRole() throws Exception {
104+
mockMvc.perform(patch("/data/matchmakerQueueMapPool/101")
105+
.with(getOAuthTokenWithActiveUser(NO_SCOPE, NO_AUTHORITIES))
106+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
107+
.content(genUpdateRequestForField("minimumMapsAfterVeto", 3.1)))
108+
.andExpect(status().isForbidden());
109+
}
110+
111+
@Test
112+
public void canUpdateMatchmakerQueueMapPoolMinRatingWithScopeAndRole() throws Exception {
113+
mockMvc.perform(patch("/data/matchmakerQueueMapPool/101")
114+
.with(getOAuthTokenWithActiveUser(OAuthScope._ADMINISTRATIVE_ACTION, GroupPermission.ROLE_WRITE_MATCHMAKER_MAP))
115+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
116+
.content(genUpdateRequestForField("minRating", 1000)))
117+
.andExpect(status().isNoContent());
118+
}
119+
120+
@Test
121+
public void canUpdateMatchmakerQueueMapPoolMaxRatingWithScopeAndRole() throws Exception {
122+
mockMvc.perform(patch("/data/matchmakerQueueMapPool/101")
123+
.with(getOAuthTokenWithActiveUser(OAuthScope._ADMINISTRATIVE_ACTION, GroupPermission.ROLE_WRITE_MATCHMAKER_MAP))
124+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
125+
.content(genUpdateRequestForField("maxRating", 1000)))
126+
.andExpect(status().isNoContent());
127+
}
128+
129+
@Test
130+
public void canUpdateMatchmakerQueueMapPoolVetoTokensPerPlayerWithScopeAndRole() throws Exception {
131+
mockMvc.perform(patch("/data/matchmakerQueueMapPool/101")
132+
.with(getOAuthTokenWithActiveUser(OAuthScope._ADMINISTRATIVE_ACTION, GroupPermission.ROLE_WRITE_MATCHMAKER_MAP))
133+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
134+
.content(genUpdateRequestForField("vetoTokensPerPlayer", 1)))
135+
.andExpect(status().isNoContent());
136+
}
137+
138+
@Test
139+
public void canUpdateMatchmakerQueueMapPoolMaxTokensPerMapWithScopeAndRole() throws Exception {
140+
mockMvc.perform(patch("/data/matchmakerQueueMapPool/101")
141+
.with(getOAuthTokenWithActiveUser(OAuthScope._ADMINISTRATIVE_ACTION, GroupPermission.ROLE_WRITE_MATCHMAKER_MAP))
142+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
143+
.content(genUpdateRequestForField("maxTokensPerMap", 2)))
144+
.andExpect(status().isNoContent());
145+
}
146+
147+
@Test
148+
public void canUpdateMatchmakerQueueMapPoolMinimumMapsAfterVetoWithScopeAndRole() throws Exception {
149+
mockMvc.perform(patch("/data/matchmakerQueueMapPool/101")
150+
.with(getOAuthTokenWithActiveUser(OAuthScope._ADMINISTRATIVE_ACTION, GroupPermission.ROLE_WRITE_MATCHMAKER_MAP))
151+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
152+
.content(genUpdateRequestForField("minimumMapsAfterVeto", 3.1)))
153+
.andExpect(status().isNoContent());
154+
}
155+
}

src/inttest/resources/sql/prepMapData.sql

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ INSERT INTO map_pool (id, name) VALUES
1313
(4, 'Ladder 1v1 1300-1800'),
1414
(5, 'Ladder 1v1 1800+');
1515

16-
INSERT INTO matchmaker_queue_map_pool (matchmaker_queue_id, map_pool_id, min_rating, max_rating) VALUES
17-
(1, 1, null, 300),
18-
(1, 2, 300, 800),
19-
(1, 3, 800, 1300),
20-
(1, 4, 1300, 1800),
21-
(1, 5, 1800, null);
16+
INSERT INTO matchmaker_queue_map_pool (matchmaker_queue_id, map_pool_id, min_rating, max_rating, veto_tokens_per_player, max_tokens_per_map, minimum_maps_after_veto) VALUES
17+
(1, 1, null, 300,1,1,1),
18+
(1, 2, 300, 800,1,1,1),
19+
(1, 3, 800, 1300,1,1,1),
20+
(1, 4, 1300, 1800,1,1,1),
21+
(1, 5, 1800, null,1,1,1);
2222

2323
INSERT INTO map_pool_map_version (id, map_pool_id, map_version_id, map_params, weight) VALUES
2424
(1, 1, 1, null, 1),
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
INSERT INTO map_pool (id, name) VALUES
2+
(1, 'Ladder 1v1 <300'),
3+
(2, 'Ladder 1v1 300-800'),
4+
(3, 'Ladder 1v1 800-1300'),
5+
(4, 'Ladder 1v1 1300-1800'),
6+
(5, 'Ladder 1v1 1800+');
7+
8+
INSERT INTO matchmaker_queue_map_pool (id, matchmaker_queue_id, map_pool_id, min_rating, max_rating, veto_tokens_per_player, max_tokens_per_map, minimum_maps_after_veto) VALUES
9+
(100, 1, 1, null, 300,1,1,1),
10+
(101, 1, 2, 300, 800,1,1,1.5),
11+
(102, 1, 3, 800, 1300,1,1,1),
12+
(103, 1, 4, 1300, 1800,1,1,1),
13+
(104, 1, 5, 1800, null,1,1,1);

src/main/java/com/faforever/api/data/domain/MatchmakerQueueMapPool.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ public class MatchmakerQueueMapPool extends AbstractEntity<MatchmakerQueueMapPoo
3030
private Double minRating;
3131
private Double maxRating;
3232
private MapPool mapPool;
33+
// Veto system fields
34+
private Integer vetoTokensPerPlayer;
35+
private Integer maxTokensPerMap;
36+
private Float minimumMapsAfterVeto;
3337

3438
@ManyToOne(fetch = FetchType.LAZY)
3539
@JoinColumn(name = "matchmaker_queue_id")
@@ -57,4 +61,22 @@ public Double getMaxRating() {
5761
public MapPool getMapPool() {
5862
return mapPool;
5963
}
64+
65+
@Column(name = "veto_tokens_per_player")
66+
@UpdatePermission(expression = WriteMatchmakerMapCheck.EXPRESSION)
67+
public Integer getVetoTokensPerPlayer() {
68+
return vetoTokensPerPlayer;
69+
}
70+
71+
@Column(name = "max_tokens_per_map")
72+
@UpdatePermission(expression = WriteMatchmakerMapCheck.EXPRESSION)
73+
public Integer getMaxTokensPerMap() {
74+
return maxTokensPerMap;
75+
}
76+
77+
@Column(name = "minimum_maps_after_veto")
78+
@UpdatePermission(expression = WriteMatchmakerMapCheck.EXPRESSION)
79+
public Float getMinimumMapsAfterVeto() {
80+
return minimumMapsAfterVeto;
81+
}
6082
}

0 commit comments

Comments
 (0)