Skip to content

Commit

Permalink
Merge c2d374c into ee10c1d
Browse files Browse the repository at this point in the history
  • Loading branch information
bukajsytlos committed Sep 16, 2018
2 parents ee10c1d + c2d374c commit 124ad9e
Show file tree
Hide file tree
Showing 37 changed files with 871 additions and 197 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ before_install:
install:
- git clone https://github.com/FAForever/faf-stack.git faf-stack
&& pushd faf-stack
&& git checkout 2169c0c
&& git checkout 884f628
&& cp -r config.template config
&& popd
- docker-compose -f faf-stack/docker-compose.yml up -d faf-db
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ junitAddonsVersion=1.4
zohhakVersion=1.1.1
githubApiVersion=1.84
jgitVersionn=4.5.0.201609210915-r
fafCommonsVersion=09ffb08f9538f66e6e9bccabceae1e6123a3fa27
fafCommonsVersion=8dd4a6c991fd607153d8f7cd4bf43180c1f8a912
h2Version=1.4.193
jacksonDatatypeJsr310Version=2.8.11
mockitoVersion=2.19.0
Expand Down
29 changes: 29 additions & 0 deletions src/inttest/java/com/faforever/api/AbstractIntegrationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,20 @@
import com.faforever.api.config.ApplicationProfile;
import com.faforever.api.error.ErrorCode;
import com.faforever.api.utils.OAuthHelper;
import com.faforever.commons.api.dto.AbstractEntity;
import com.faforever.commons.api.dto.Avatar;
import com.faforever.commons.api.dto.AvatarAssignment;
import com.faforever.commons.api.dto.BanInfo;
import com.faforever.commons.api.dto.ModerationReport;
import com.faforever.commons.api.dto.Player;
import com.faforever.commons.api.dto.Tutorial;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.github.jasminb.jsonapi.JSONAPIDocument;
import com.github.jasminb.jsonapi.ResourceConverter;
import com.github.jasminb.jsonapi.exceptions.DocumentSerializationException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.runner.RunWith;
Expand All @@ -27,6 +37,7 @@
import org.springframework.web.context.WebApplicationContext;

import javax.transaction.Transactional;
import java.time.format.DateTimeFormatter;

import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;

Expand All @@ -37,6 +48,8 @@
@Transactional
@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/prepDefaultUser.sql")
public abstract class AbstractIntegrationTest {
protected static final DateTimeFormatter OFFSET_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");

protected final static String AUTH_WEBSITE = "WEBSITE";
protected final static String AUTH_USER = "USER";
protected final static String AUTH_MODERATOR = "MODERATOR";
Expand All @@ -47,6 +60,7 @@ public abstract class AbstractIntegrationTest {
@Autowired
protected WebApplicationContext context;
protected ObjectMapper objectMapper;
protected ResourceConverter resourceConverter;

@Before
public void setUp() {
Expand All @@ -59,6 +73,17 @@ public void setUp() {
this.objectMapper.registerModule(new JavaTimeModule());
this.objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
this.objectMapper.setSerializationInclusion(Include.NON_EMPTY);

// maybe use reflections library to find all subtypes of AbstractEntity
resourceConverter = new ResourceConverter(
objectMapper,
ModerationReport.class,
Player.class,
Tutorial.class,
Avatar.class,
AvatarAssignment.class,
BanInfo.class
);
}

protected RequestPostProcessor getOAuthToken(String... scope) {
Expand All @@ -69,4 +94,8 @@ protected void assertApiError(MvcResult mvcResult, ErrorCode errorCode) throws E
JSONObject resonseJson = new JSONObject(mvcResult.getResponse().getContentAsString());
JSONAssert.assertEquals(String.format("{\"errors\":[{\"code\":\"%s\"}]}", errorCode.getCode()), resonseJson, false);
}

protected <T extends AbstractEntity> byte[] createJsonApiContent(T entity) throws DocumentSerializationException {
return resourceConverter.writeDocument(new JSONAPIDocument<>(entity));
}
}
170 changes: 66 additions & 104 deletions src/inttest/java/com/faforever/api/data/AvatarElideTest.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
package com.faforever.api.data;

import com.faforever.api.AbstractIntegrationTest;
import com.faforever.api.avatar.AvatarAssignmentRepository;
import com.faforever.api.avatar.AvatarRepository;
import com.faforever.api.data.domain.Avatar;
import com.faforever.api.data.domain.AvatarAssignment;
import com.faforever.api.data.domain.Player;
import com.github.jasminb.jsonapi.JSONAPIDocument;
import com.github.jasminb.jsonapi.ResourceConverter;
import com.faforever.commons.api.dto.Avatar;
import com.faforever.commons.api.dto.AvatarAssignment;
import com.faforever.commons.api.dto.Player;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.Sql.ExecutionPhase;

import java.time.OffsetDateTime;
import java.util.Optional;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
Expand All @@ -32,58 +25,45 @@
@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/prepAvatarData.sql")
@Sql(executionPhase = ExecutionPhase.AFTER_TEST_METHOD, scripts = "classpath:sql/cleanAvatarData.sql")
public class AvatarElideTest extends AbstractIntegrationTest {
@Autowired
AvatarRepository avatarRepository;
@Autowired
AvatarAssignmentRepository avatarAssignmentRepository;


@Test
public void getUnusedAvatar() throws Exception {
Avatar avatar = avatarRepository.getOne(1);

mockMvc.perform(get("/data/avatar/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.id", is(String.valueOf(avatar.getId()))))
.andExpect(jsonPath("$.data.id", is("1")))
.andExpect(jsonPath("$.data.type", is("avatar")))
.andExpect(jsonPath("$.data.attributes.tooltip", is(avatar.getTooltip())))
.andExpect(jsonPath("$.data.attributes.url", is(avatar.getUrl())))
.andExpect(jsonPath("$.data.attributes.tooltip", is("Avatar No. 1")))
.andExpect(jsonPath("$.data.attributes.url", is("http://localhost/faf/avatars/avatar1.png")))
.andExpect(jsonPath("$.data.relationships.assignments.data", hasSize(0)));
}

@Test
public void getAvatarWithPlayer() throws Exception {
Avatar avatar = avatarRepository.getOne(2);

mockMvc.perform(get("/data/avatar/2"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.id", is(String.valueOf(avatar.getId()))))
.andExpect(jsonPath("$.data.id", is("2")))
.andExpect(jsonPath("$.data.type", is("avatar")))
.andExpect(jsonPath("$.data.attributes.tooltip", is(avatar.getTooltip())))
.andExpect(jsonPath("$.data.attributes.url", is(avatar.getUrl())))
.andExpect(jsonPath("$.data.attributes.tooltip", is("Avatar No. 2")))
.andExpect(jsonPath("$.data.attributes.url", is("http://localhost/faf/avatars/avatar2.png")))
.andExpect(jsonPath("$.data.relationships.assignments.data", hasSize(2)));
}

@Test
@WithUserDetails(AUTH_MODERATOR)
public void moderatorCanAssignAvatar() throws Exception {
final ResourceConverter resourceConverter = new ResourceConverter(objectMapper, Avatar.class, Player.class, AvatarAssignment.class);
final Avatar avatar = new Avatar();
avatar.setId(1);
final Player player = new Player();
player.setId(1);
final Avatar avatar = (Avatar) new Avatar().setId("1");
final Player player = (Player) new Player().setId("1");
final AvatarAssignment avatarAssignment = new AvatarAssignment()
.setAvatar(avatar)
.setSelected(false);
mockMvc.perform(
post("/data/player/{playerId}/avatarAssignments", player.getId())
.content(resourceConverter.writeDocument(new JSONAPIDocument<>(
new AvatarAssignment()
.setAvatar(avatar)
.setSelected(null)
)
))
).andExpect(status().isCreated());
Optional<AvatarAssignment> createdAssignment = avatarAssignmentRepository.findOneByAvatarIdAndPlayerId(1, 1);
assertThat(createdAssignment.isPresent(), is(true));
assertThat(createdAssignment.get().getPlayer().getId(), is(player.getId()));
assertThat(createdAssignment.get().getAvatar().getId(), is(avatar.getId()));
.header(HttpHeaders.CONTENT_TYPE, DataController.JSON_API_MEDIA_TYPE)
.content(createJsonApiContent(avatarAssignment)))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.data.relationships.player.data.id", is(player.getId())))
.andExpect(jsonPath("$.data.relationships.avatar.data.id", is(avatar.getId())));
}

@Test
Expand All @@ -92,29 +72,24 @@ public void moderatorCanDeleteAvatarAssignment() throws Exception {
mockMvc.perform(
delete("/data/avatarAssignment/{assignmentId}", 1)
).andExpect(status().isNoContent());
final Optional<AvatarAssignment> deletedAssignment = avatarAssignmentRepository.findOneById(1);
assertThat(deletedAssignment.isPresent(), is(false));
mockMvc.perform(
get("/data/avatarAssignment/{assignmentId}", 1)
).andExpect(status().isNotFound());
}

@Test
@WithUserDetails(AUTH_USER)
public void userCannotAssignAvatar() throws Exception {
final ResourceConverter resourceConverter = new ResourceConverter(objectMapper, Avatar.class, Player.class, AvatarAssignment.class);
final Avatar avatar = new Avatar();
avatar.setId(1);
final Player player = new Player();
player.setId(1);
final Avatar avatar = (Avatar) new Avatar().setId("1");
final Player player = (Player) new Player().setId("1");
final AvatarAssignment avatarAssignment = new AvatarAssignment()
.setAvatar(avatar)
.setSelected(false);
mockMvc.perform(
post("/data/player/{playerId}/avatarAssignments", player.getId())
.content(resourceConverter.writeDocument(new JSONAPIDocument<>(
new AvatarAssignment()
.setAvatar(avatar)
.setSelected(null)
)
))
.header(HttpHeaders.CONTENT_TYPE, DataController.JSON_API_MEDIA_TYPE)
.content(createJsonApiContent(avatarAssignment))
).andExpect(status().isForbidden());
final Optional<AvatarAssignment> createdAssignment = avatarAssignmentRepository.findOneByAvatarAndPlayer(avatar, player);
assertThat(createdAssignment.isPresent(), is(false));
}

@Test
Expand All @@ -123,83 +98,70 @@ public void userCannotDeleteAvatarAssignment() throws Exception {
mockMvc.perform(
delete("/data/avatarAssignment/{assignmentId}", 1)
).andExpect(status().isForbidden());
final Optional<AvatarAssignment> stillExistingAssignment = avatarAssignmentRepository.findOneById(1);
assertThat(stillExistingAssignment.isPresent(), is(true));
mockMvc.perform(
get("/data/avatarAssignment/{assignmentId}", 1)
).andExpect(status().isOk());
}

@Test
@WithUserDetails(AUTH_MODERATOR)
public void moderatorCanUpdateAvatarAssignmentExpiration() throws Exception {
final ResourceConverter resourceConverter = new ResourceConverter(objectMapper, Avatar.class, Player.class, AvatarAssignment.class);
final OffsetDateTime now = OffsetDateTime.now();
final AvatarAssignment avatarAssignment = (AvatarAssignment) new AvatarAssignment()
.setExpiresAt(now)
.setId("1");
mockMvc.perform(
patch("/data/avatarAssignment/{assignmentId}", 1)
.content(resourceConverter.writeDocument(new JSONAPIDocument<>(
new AvatarAssignment()
.setSelected(null)
.setExpiresAt(now)
.setId(1)
)
))
).andExpect(status().isNoContent());
final Optional<AvatarAssignment> updatedAssignment = avatarAssignmentRepository.findOneById(1);
assertThat(updatedAssignment.isPresent(), is(true));
assertThat(updatedAssignment.get().getExpiresAt(), is(now));
.header(HttpHeaders.CONTENT_TYPE, DataController.JSON_API_MEDIA_TYPE)
.content(createJsonApiContent(avatarAssignment)))
.andExpect(status().isNoContent());
mockMvc.perform(
get("/data/avatarAssignment/{assignmentId}", 1))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.attributes.expiresAt", is(OFFSET_DATE_TIME_FORMATTER.format(now))));
}

@Test
@WithUserDetails(AUTH_USER)
public void userCannotUpdateAvatarAssignmentExpiration() throws Exception {
final ResourceConverter resourceConverter = new ResourceConverter(objectMapper, Avatar.class, Player.class, AvatarAssignment.class);
final OffsetDateTime now = OffsetDateTime.now();
final AvatarAssignment avatarAssignment = (AvatarAssignment) new AvatarAssignment()
.setExpiresAt(now)
.setId("1");
mockMvc.perform(
patch("/data/avatarAssignment/{assignmentId}", 1)
.content(resourceConverter.writeDocument(new JSONAPIDocument<>(
new AvatarAssignment()
.setSelected(null)
.setExpiresAt(now)
.setId(1)
)
))
).andExpect(status().isForbidden());
final Optional<AvatarAssignment> updatedAssignment = avatarAssignmentRepository.findOneById(1);
assertThat(updatedAssignment.isPresent(), is(true));
assertThat(updatedAssignment.get().getExpiresAt(), is(nullValue()));
.header(HttpHeaders.CONTENT_TYPE, DataController.JSON_API_MEDIA_TYPE)
.content(createJsonApiContent(avatarAssignment)))
.andExpect(status().isForbidden());
}

@Test
@WithUserDetails(AUTH_USER)
public void ownerCanUpdateAvatarAssignmentSelection() throws Exception {
final ResourceConverter resourceConverter = new ResourceConverter(objectMapper, Avatar.class, Player.class, AvatarAssignment.class);
final AvatarAssignment avatarAssignment = (AvatarAssignment) new AvatarAssignment()
.setSelected(true)
.setId("1");
mockMvc.perform(
patch("/data/avatarAssignment/{assignmentId}", 1)
.content(resourceConverter.writeDocument(new JSONAPIDocument<>(
new AvatarAssignment()
.setSelected(false)
.setId(1)
)
))
).andExpect(status().isNoContent());
final Optional<AvatarAssignment> updatedAssignment = avatarAssignmentRepository.findOneById(1);
assertThat(updatedAssignment.isPresent(), is(true));
assertThat(updatedAssignment.get().isSelected(), is(false));
.header(HttpHeaders.CONTENT_TYPE, DataController.JSON_API_MEDIA_TYPE)
.content(createJsonApiContent(avatarAssignment)))
.andExpect(status().isNoContent());
mockMvc.perform(
get("/data/avatarAssignment/{assignmentId}", 1))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.attributes.selected", is(true)));
}

@Test
@WithUserDetails(AUTH_MODERATOR)
public void nonOwnerCannotUpdateAvatarAssignmentSelection() throws Exception {
final ResourceConverter resourceConverter = new ResourceConverter(objectMapper, Avatar.class, Player.class, AvatarAssignment.class);
final AvatarAssignment avatarAssignment = (AvatarAssignment) new AvatarAssignment()
.setSelected(false)
.setId("1");
mockMvc.perform(
patch("/data/avatarAssignment/{assignmentId}", 1)
.content(resourceConverter.writeDocument(new JSONAPIDocument<>(
new AvatarAssignment()
.setSelected(false)
.setId(1)
)
))
).andExpect(status().isForbidden());
final Optional<AvatarAssignment> updatedAssignment = avatarAssignmentRepository.findOneById(1);
assertThat(updatedAssignment.isPresent(), is(true));
assertThat(updatedAssignment.get().isSelected(), is(true));
.header(HttpHeaders.CONTENT_TYPE, DataController.JSON_API_MEDIA_TYPE)
.content(createJsonApiContent(avatarAssignment)))
.andExpect(status().isForbidden());
}
}
Loading

0 comments on commit 124ad9e

Please sign in to comment.