|
6 | 6 | import com.faforever.client.test.PlatformTest; |
7 | 7 | import org.junit.jupiter.api.BeforeEach; |
8 | 8 | import org.junit.jupiter.api.Test; |
| 9 | +import org.junit.jupiter.api.extension.ExtendWith; |
9 | 10 | import org.junit.jupiter.api.io.TempDir; |
| 11 | +import org.mockito.ArgumentCaptor; |
| 12 | +import org.mockito.Captor; |
10 | 13 | import org.mockito.Mock; |
11 | 14 | import org.mockito.Spy; |
| 15 | +import org.mockito.junit.jupiter.MockitoExtension; |
| 16 | +import org.springframework.http.MediaType; |
| 17 | +import org.springframework.web.reactive.function.BodyInserter; |
| 18 | +import org.springframework.web.reactive.function.client.WebClient; |
12 | 19 | import reactor.core.publisher.Mono; |
13 | 20 |
|
| 21 | +import java.net.URI; |
14 | 22 | import java.nio.file.Files; |
15 | 23 | import java.nio.file.Path; |
| 24 | +import java.util.UUID; |
16 | 25 |
|
17 | | -import static org.hamcrest.MatcherAssert.assertThat; |
18 | | -import static org.hamcrest.collection.IsArrayWithSize.emptyArray; |
| 26 | +import static com.faforever.client.mod.ModUploadTask.MOD_UPLOAD_COMPLETE_API_POST; |
| 27 | +import static com.faforever.client.mod.ModUploadTask.MOD_UPLOAD_START_API_GET; |
19 | 28 | import static org.junit.jupiter.api.Assertions.assertThrows; |
20 | 29 | import static org.mockito.ArgumentMatchers.any; |
| 30 | +import static org.mockito.ArgumentMatchers.eq; |
21 | 31 | import static org.mockito.Mockito.lenient; |
22 | 32 | import static org.mockito.Mockito.verify; |
| 33 | +import static org.mockito.Mockito.when; |
23 | 34 |
|
24 | | -public class ModUploadTaskTest extends PlatformTest { |
| 35 | +@ExtendWith(MockitoExtension.class) |
| 36 | +class ModUploadTaskTest extends PlatformTest { |
25 | 37 |
|
26 | 38 | @TempDir |
27 | | - public Path tempDirectory; |
| 39 | + Path tempDirectory; |
28 | 40 |
|
29 | | - private ModUploadTask instance; |
| 41 | + @Mock |
| 42 | + FafApiAccessor fafApiAccessor; |
30 | 43 |
|
31 | 44 | @Mock |
32 | | - private FafApiAccessor fafApiAccessor; |
| 45 | + WebClient defaultWebClient; |
| 46 | + |
33 | 47 | @Mock |
34 | | - private I18n i18n; |
| 48 | + I18n i18n; |
| 49 | + |
35 | 50 | @Spy |
36 | | - private DataPrefs dataPrefs; |
| 51 | + DataPrefs dataPrefs; |
| 52 | + |
| 53 | + @Captor |
| 54 | + ArgumentCaptor<ModUploadMetadata> metadataCaptor; |
| 55 | + |
| 56 | + ModUploadTask underTest; |
| 57 | + |
| 58 | + UUID requestId; |
| 59 | + URI signedUri; |
| 60 | + |
| 61 | + @Mock |
| 62 | + WebClient.RequestBodyUriSpec requestBodySpec; |
| 63 | + @Mock |
| 64 | + WebClient.RequestHeadersSpec<?> headersSpec; |
| 65 | + @Mock |
| 66 | + WebClient.ResponseSpec responseSpec; |
37 | 67 |
|
38 | 68 | @BeforeEach |
39 | | - public void setUp() throws Exception { |
40 | | - instance = new ModUploadTask(fafApiAccessor, i18n, dataPrefs); |
41 | | - dataPrefs.setBaseDataDirectory(tempDirectory); |
| 69 | + void setUp() throws Exception { |
| 70 | + underTest = new ModUploadTask(fafApiAccessor, i18n, dataPrefs, defaultWebClient); |
42 | 71 |
|
| 72 | + dataPrefs.setBaseDataDirectory(tempDirectory); |
43 | 73 | Files.createDirectories(dataPrefs.getCacheDirectory()); |
| 74 | + |
44 | 75 | lenient().when(i18n.get(any())).thenReturn(""); |
45 | | - lenient().when(fafApiAccessor.uploadFile(any(), any(), any(), any())).thenReturn(Mono.empty()); |
| 76 | + |
| 77 | + requestId = UUID.randomUUID(); |
| 78 | + signedUri = new URI("https://example.com/upload"); |
46 | 79 | } |
47 | 80 |
|
48 | 81 | @Test |
49 | | - public void testModPathNull() throws Exception { |
50 | | - assertThrows(NullPointerException.class, () -> instance.call()); |
| 82 | + void testModPathNull() { |
| 83 | + assertThrows(NullPointerException.class, () -> underTest.call()); |
51 | 84 | } |
52 | 85 |
|
53 | 86 | @Test |
54 | | - public void testProgressListenerNull() throws Exception { |
55 | | - instance.setModPath(Path.of(".")); |
56 | | - assertThrows(NullPointerException.class, () -> instance.call()); |
| 87 | + void testProgressListenerNull() { |
| 88 | + underTest.setModPath(Path.of(".")); |
| 89 | + assertThrows(NullPointerException.class, () -> underTest.call()); |
57 | 90 | } |
58 | 91 |
|
59 | 92 | @Test |
60 | | - public void testCall() throws Exception { |
61 | | - instance.setModPath(Files.createDirectories(tempDirectory.resolve("test-mod"))); |
| 93 | + void testCall() throws Exception { |
| 94 | + stubWebClient(); |
| 95 | + |
| 96 | + when(responseSpec.bodyToMono(Void.class)).thenReturn(Mono.empty()); |
| 97 | + when(fafApiAccessor.postJson(eq(MOD_UPLOAD_COMPLETE_API_POST), metadataCaptor.capture())).thenReturn(Mono.empty()); |
| 98 | + |
| 99 | + Path modFolder = Files.createDirectory(tempDirectory.resolve("my-mod")); |
| 100 | + Files.writeString(modFolder.resolve("hello.txt"), "world"); |
| 101 | + |
| 102 | + underTest.setModPath(modFolder); |
| 103 | + underTest.call(); |
| 104 | + |
| 105 | + verify(fafApiAccessor).getApiObject(MOD_UPLOAD_START_API_GET, UploadUrlResponse.class); |
| 106 | + verify(defaultWebClient).put(); |
| 107 | + verify(fafApiAccessor).postJson(eq(MOD_UPLOAD_COMPLETE_API_POST), metadataCaptor.capture()); |
| 108 | + |
| 109 | + assert metadataCaptor.getValue().requestId().equals(requestId); |
| 110 | + assert Files.list(dataPrefs.getCacheDirectory()).toList().isEmpty(); |
| 111 | + } |
62 | 112 |
|
63 | | - instance.call(); |
| 113 | + @Test |
| 114 | + void testCallUploadFails() throws Exception { |
| 115 | + stubWebClient(); |
| 116 | + |
| 117 | + when(responseSpec.bodyToMono(Void.class)).thenReturn(Mono.error(new IllegalStateException("Simulated S3 failure"))); |
| 118 | + |
| 119 | + Path modFolder = Files.createDirectory(tempDirectory.resolve("my-mod")); |
| 120 | + Files.writeString(modFolder.resolve("hello.txt"), "world"); |
| 121 | + |
| 122 | + underTest.setModPath(modFolder); |
| 123 | + |
| 124 | + assertThrows(IllegalStateException.class, () -> underTest.call()); |
| 125 | + } |
64 | 126 |
|
65 | | - verify(fafApiAccessor).uploadFile(any(), any(), any(), any()); |
| 127 | + void stubWebClient() { |
| 128 | + when(fafApiAccessor.getApiObject(MOD_UPLOAD_START_API_GET, UploadUrlResponse.class)).thenReturn( |
| 129 | + Mono.just(new UploadUrlResponse(signedUri, requestId))); |
66 | 130 |
|
67 | | - assertThat(Files.list(dataPrefs.getCacheDirectory()).toArray(), emptyArray()); |
| 131 | + when(defaultWebClient.put()).thenReturn(requestBodySpec); |
| 132 | + when(requestBodySpec.uri(signedUri)).thenReturn(requestBodySpec); |
| 133 | + when(requestBodySpec.accept(MediaType.APPLICATION_JSON)).thenReturn(requestBodySpec); |
| 134 | + when(requestBodySpec.contentType(MediaType.valueOf("application/zip"))).thenReturn(requestBodySpec); |
| 135 | + when(requestBodySpec.body(any(BodyInserter.class))).thenReturn(headersSpec); |
| 136 | + when(headersSpec.retrieve()).thenReturn(responseSpec); |
| 137 | + when(responseSpec.onStatus(any(), any())).thenReturn(responseSpec); |
68 | 138 | } |
69 | 139 | } |
0 commit comments