Commit 909fb7d2 authored by Tim Coates (CPVV)'s avatar Tim Coates (CPVV)

Add basic unit tests

parent 88bb6fc1
......@@ -23,6 +23,8 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok'
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation group: 'com.google.guava', name: 'guava', version: '29.0-jre'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
......
package au.com.tpic.avatar.services;
import au.com.tpic.avatar.configuration.AvatarServiceProperites;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
......@@ -26,22 +28,24 @@ public class AvatarService {
public AvatarService(AvatarServiceProperites properites) throws IOException {
Stream<Path> avatars = Files.walk(properites.getDirectory());
this.fileList = new HashMap<>();
avatars.filter(this::correctFormat).forEach(path -> this.fileList.put(getHash(path), path));
avatars.filter(this::correctFormat).forEach(path -> this.fileList.put(getFileHash(path), path));
}
public byte[] getAvatar(String hash, String size) throws IOException {
public ResponseEntity<byte[]> getAvatar(String request, String size) throws IOException {
try {
hash = hash.toLowerCase();
String hash = getRequestHash(request);
MediaType format = getRequestFormat(request);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedImage image = (fileList.containsKey(hash)) ? readImageToSize(fileList.get(hash), Integer.parseInt(size)) : generateIdenticons(hash, Integer.parseInt(size));
ImageIO.write(image, "jpg", baos);
return baos.toByteArray();
ImageIO.write(image, format.getSubtype(), baos);
return ResponseEntity.ok().contentType(format).body(baos.toByteArray());
} catch (Exception ignored) {
return getClass().getClassLoader().getResourceAsStream("default.jpg").readAllBytes();
byte[] body = getClass().getClassLoader().getResourceAsStream("default.jpg").readAllBytes();
return ResponseEntity.ok().contentType(MediaType.IMAGE_JPEG).body(body);
}
}
public static BufferedImage generateIdenticons(String text, int size) {
private static BufferedImage generateIdenticons(String text, int size) {
int width = 5, height = 5;
byte[] hash = text.getBytes();
......@@ -50,7 +54,7 @@ public class AvatarService {
WritableRaster raster = identicon.getRaster();
int[] background = new int[]{255, 255, 255};
int[] foreground = new int[]{hash[0] & 255, hash[3] & 255, hash[6] & 255};
int[] foreground = new int[]{hash[0] & 255, hash[hash.length / 3] & 255, hash[hash.length / 2] & 255};
for (int x = 0; x < width; x++) {
//Enforce horizontal symmetry
......@@ -86,7 +90,7 @@ public class AvatarService {
return outputImage;
}
private String getHash(Path path) {
private String getFileHash(Path path) {
String filename = com.google.common.io.Files.getNameWithoutExtension(path.getFileName().toString());
return DigestUtils.md5DigestAsHex(filename.getBytes());
}
......@@ -97,5 +101,17 @@ public class AvatarService {
return accepted.contains(extension.toLowerCase());
}
private String getRequestHash(String request) {
return request.toLowerCase().split("\\.")[0];
}
private MediaType getRequestFormat(String request) {
try {
String format = request.toLowerCase().split("\\.")[1];
return MediaType.valueOf("image/" + format);
} catch (Exception ignored) {
return MediaType.IMAGE_JPEG;
}
}
}
......@@ -2,7 +2,7 @@ package au.com.tpic.avatar.web;
import au.com.tpic.avatar.services.AvatarService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
......@@ -14,13 +14,13 @@ public class AvatarController {
@Autowired
private AvatarService service;
@GetMapping(produces = MediaType.IMAGE_JPEG_VALUE)
public byte[] getDefaultAvatar(@RequestParam(value = "s", required = false, defaultValue = "200") String size) throws IOException {
@GetMapping
public ResponseEntity<byte[]> getDefaultAvatar(@RequestParam(value = "s", required = false, defaultValue = "200") String size) throws IOException {
return service.getAvatar(null, size);
}
@GetMapping(value = "{hash}", produces = MediaType.IMAGE_JPEG_VALUE)
public byte[] getAvatar(@PathVariable String hash, @RequestParam(value = "s", required = false, defaultValue = "200") String size) throws IOException {
return service.getAvatar(hash, size);
@GetMapping(value = "{request}")
public ResponseEntity<byte[]> getAvatar(@PathVariable String request, @RequestParam(value = "s", required = false, defaultValue = "200") String size) throws IOException {
return service.getAvatar(request, size);
}
}
package au.com.tpic.avatar.services;
import au.com.tpic.avatar.configuration.AvatarServiceProperites;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import java.io.IOException;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat;
class AvatarServiceTest {
private final AvatarService avatarService;
public AvatarServiceTest() throws IOException {
AvatarServiceProperites properties = new AvatarServiceProperites();
properties.setDirectory(Path.of("build", "tmp"));
this.avatarService = new AvatarService(properties);
}
@Test
void getDefaultAvatar() throws IOException {
byte[] expectedBody = getClass().getResourceAsStream("/default.jpg").readAllBytes();
ResponseEntity<byte[]> expectedResponse = ResponseEntity.ok().contentType(MediaType.IMAGE_JPEG).body(expectedBody);
assertThat(avatarService.getAvatar(null, "200")).isEqualTo(expectedResponse);
}
@Test
void getIdenticonAvatar() throws IOException {
byte[] expectedBody = getClass().getResourceAsStream("/B725DDDD5F2F979522DCC55A05E.jpg").readAllBytes();
ResponseEntity<byte[]> expectedResponse = ResponseEntity.ok().contentType(MediaType.IMAGE_JPEG).body(expectedBody);
assertThat(avatarService.getAvatar("B725DDDD5F2F979522DCC55A05E", "200")).isEqualTo(expectedResponse);
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment