|
@@ -70,7 +70,7 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
BlobContainerClient containerClient = mock(BlobContainerClient.class);
|
|
BlobContainerClient containerClient = mock(BlobContainerClient.class);
|
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
|
containerClient,
|
|
containerClient,
|
|
|
- "reports",
|
|
|
|
|
|
|
+ "report",
|
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
|
FIXED_CLOCK);
|
|
FIXED_CLOCK);
|
|
|
|
|
|
|
@@ -79,7 +79,7 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
Duration.ofMinutes(15));
|
|
Duration.ofMinutes(15));
|
|
|
|
|
|
|
|
assertThat(downloadUrl).isEqualTo(URI.create(
|
|
assertThat(downloadUrl).isEqualTo(URI.create(
|
|
|
- "https://dcjxbtest.blob.core.chinacloudapi.cn/reports/exam-sprint-outlook-report-report-123.pdf"));
|
|
|
|
|
|
|
+ "https://dcjxbtest.blob.core.chinacloudapi.cn/report/report-123/exam-sprint-outlook-report-report-123.pdf"));
|
|
|
verifyNoInteractions(containerClient);
|
|
verifyNoInteractions(containerClient);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -88,7 +88,7 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
BlobContainerClient containerClient = mock(BlobContainerClient.class);
|
|
BlobContainerClient containerClient = mock(BlobContainerClient.class);
|
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
|
containerClient,
|
|
containerClient,
|
|
|
- "/reports/",
|
|
|
|
|
|
|
+ "/report/",
|
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn/",
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn/",
|
|
|
FIXED_CLOCK);
|
|
FIXED_CLOCK);
|
|
|
|
|
|
|
@@ -97,26 +97,26 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
Duration.ofMinutes(15));
|
|
Duration.ofMinutes(15));
|
|
|
|
|
|
|
|
assertThat(downloadUrl).isEqualTo(URI.create(
|
|
assertThat(downloadUrl).isEqualTo(URI.create(
|
|
|
- "https://dcjxbtest.blob.core.chinacloudapi.cn/reports/file.pdf"));
|
|
|
|
|
|
|
+ "https://dcjxbtest.blob.core.chinacloudapi.cn/report/report-123/file.pdf"));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
@Test
|
|
|
- void generateDownloadUrlEncodesFileNameWithoutReportScopedPath() {
|
|
|
|
|
|
|
+ void generateDownloadUrlEncodesReportScopedFileNameWithoutReportTypePath() {
|
|
|
BlobContainerClient containerClient = mock(BlobContainerClient.class);
|
|
BlobContainerClient containerClient = mock(BlobContainerClient.class);
|
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
|
containerClient,
|
|
containerClient,
|
|
|
- "reports",
|
|
|
|
|
|
|
+ "report",
|
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
|
FIXED_CLOCK);
|
|
FIXED_CLOCK);
|
|
|
|
|
|
|
|
URI downloadUrl = storage.generateDownloadUrl(
|
|
URI downloadUrl = storage.generateDownloadUrl(
|
|
|
- "John Doe-报告 #1?.pdf",
|
|
|
|
|
|
|
+ "report-123/John Doe-报告 #1?.pdf",
|
|
|
Duration.ofMinutes(15));
|
|
Duration.ofMinutes(15));
|
|
|
|
|
|
|
|
assertThat(downloadUrl.toString()).isEqualTo(
|
|
assertThat(downloadUrl.toString()).isEqualTo(
|
|
|
- "https://dcjxbtest.blob.core.chinacloudapi.cn/reports/John%20Doe-报告%20%231%3F.pdf");
|
|
|
|
|
|
|
+ "https://dcjxbtest.blob.core.chinacloudapi.cn/report/report-123/John%20Doe-报告%20%231%3F.pdf");
|
|
|
assertThat(downloadUrl.getRawPath()).isEqualTo(
|
|
assertThat(downloadUrl.getRawPath()).isEqualTo(
|
|
|
- "/reports/John%20Doe-报告%20%231%3F.pdf");
|
|
|
|
|
|
|
+ "/report/report-123/John%20Doe-报告%20%231%3F.pdf");
|
|
|
assertThat(downloadUrl.getRawQuery()).isNull();
|
|
assertThat(downloadUrl.getRawQuery()).isNull();
|
|
|
assertThat(downloadUrl.getRawFragment()).isNull();
|
|
assertThat(downloadUrl.getRawFragment()).isNull();
|
|
|
}
|
|
}
|
|
@@ -126,7 +126,7 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
BlobContainerClient containerClient = mock(BlobContainerClient.class);
|
|
BlobContainerClient containerClient = mock(BlobContainerClient.class);
|
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
|
containerClient,
|
|
containerClient,
|
|
|
- "reports",
|
|
|
|
|
|
|
+ "report",
|
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
|
FIXED_CLOCK);
|
|
FIXED_CLOCK);
|
|
|
|
|
|
|
@@ -140,7 +140,7 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
BlobContainerClient containerClient = mock(BlobContainerClient.class);
|
|
BlobContainerClient containerClient = mock(BlobContainerClient.class);
|
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
|
containerClient,
|
|
containerClient,
|
|
|
- "reports",
|
|
|
|
|
|
|
+ "report",
|
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
|
FIXED_CLOCK);
|
|
FIXED_CLOCK);
|
|
|
|
|
|
|
@@ -155,7 +155,7 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
|
|
|
|
|
assertThatThrownBy(() -> new AzureBlobExamSprintReportStorage(
|
|
assertThatThrownBy(() -> new AzureBlobExamSprintReportStorage(
|
|
|
containerClient,
|
|
containerClient,
|
|
|
- "reports",
|
|
|
|
|
|
|
+ "report",
|
|
|
"///",
|
|
"///",
|
|
|
FIXED_CLOCK))
|
|
FIXED_CLOCK))
|
|
|
.isInstanceOf(IllegalStateException.class)
|
|
.isInstanceOf(IllegalStateException.class)
|
|
@@ -168,7 +168,7 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
|
|
|
|
|
assertThatThrownBy(() -> new AzureBlobExamSprintReportStorage(
|
|
assertThatThrownBy(() -> new AzureBlobExamSprintReportStorage(
|
|
|
containerClient,
|
|
containerClient,
|
|
|
- "reports",
|
|
|
|
|
|
|
+ "report",
|
|
|
" / ",
|
|
" / ",
|
|
|
FIXED_CLOCK))
|
|
FIXED_CLOCK))
|
|
|
.isInstanceOf(IllegalStateException.class)
|
|
.isInstanceOf(IllegalStateException.class)
|
|
@@ -176,13 +176,13 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
@Test
|
|
|
- void uploadUsesFileNameAsBlobNameAndSendsHeadersAndMetadataInUploadRequest() {
|
|
|
|
|
|
|
+ void uploadUsesReportIdAndFileNameAsBlobNameAndSendsHeadersAndMetadataInUploadRequest() {
|
|
|
BlobContainerClient containerClient = mock(BlobContainerClient.class);
|
|
BlobContainerClient containerClient = mock(BlobContainerClient.class);
|
|
|
BlobClient blobClient = mock(BlobClient.class);
|
|
BlobClient blobClient = mock(BlobClient.class);
|
|
|
when(containerClient.getBlobClient(anyString())).thenReturn(blobClient);
|
|
when(containerClient.getBlobClient(anyString())).thenReturn(blobClient);
|
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
|
containerClient,
|
|
containerClient,
|
|
|
- "reports",
|
|
|
|
|
|
|
+ "report",
|
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
|
FIXED_CLOCK);
|
|
FIXED_CLOCK);
|
|
|
|
|
|
|
@@ -193,9 +193,9 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
new byte[]{1, 2, 3},
|
|
new byte[]{1, 2, 3},
|
|
|
Instant.parse("2026-01-10T00:00:00Z"));
|
|
Instant.parse("2026-01-10T00:00:00Z"));
|
|
|
|
|
|
|
|
- assertThat(storedFile.storageObjectKey()).isEqualTo("file.pdf");
|
|
|
|
|
|
|
+ assertThat(storedFile.storageObjectKey()).isEqualTo("report-123/file.pdf");
|
|
|
assertThat(storedFile.fileName()).isEqualTo("file.pdf");
|
|
assertThat(storedFile.fileName()).isEqualTo("file.pdf");
|
|
|
- verify(containerClient).getBlobClient("file.pdf");
|
|
|
|
|
|
|
+ verify(containerClient).getBlobClient("report-123/file.pdf");
|
|
|
verify(blobClient).uploadWithResponse(argThat(options ->
|
|
verify(blobClient).uploadWithResponse(argThat(options ->
|
|
|
options.getLength() == 3
|
|
options.getLength() == 3
|
|
|
&& options.getHeaders() != null
|
|
&& options.getHeaders() != null
|
|
@@ -216,7 +216,7 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
.thenReturn(successfulUploadResponse());
|
|
.thenReturn(successfulUploadResponse());
|
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
|
containerClient,
|
|
containerClient,
|
|
|
- "reports",
|
|
|
|
|
|
|
+ "report",
|
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
|
FIXED_CLOCK);
|
|
FIXED_CLOCK);
|
|
|
|
|
|
|
@@ -234,8 +234,8 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
.contains("exam_sprint_report_azure_storage_upload_completed")
|
|
.contains("exam_sprint_report_azure_storage_upload_completed")
|
|
|
.contains("reportId=report-123")
|
|
.contains("reportId=report-123")
|
|
|
.contains("reportType=OUTLOOK")
|
|
.contains("reportType=OUTLOOK")
|
|
|
- .contains("storageObjectKey=file.pdf")
|
|
|
|
|
- .contains("blobName=file.pdf")
|
|
|
|
|
|
|
+ .contains("storageObjectKey=report-123/file.pdf")
|
|
|
|
|
+ .contains("blobName=report-123/file.pdf")
|
|
|
.contains("fileName=file.pdf")
|
|
.contains("fileName=file.pdf")
|
|
|
.contains("pdfByteLength=3")
|
|
.contains("pdfByteLength=3")
|
|
|
.contains("durationMs=")
|
|
.contains("durationMs=")
|
|
@@ -258,7 +258,7 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
.thenThrow(blobStorageException());
|
|
.thenThrow(blobStorageException());
|
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
|
containerClient,
|
|
containerClient,
|
|
|
- "reports",
|
|
|
|
|
|
|
+ "report",
|
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
|
FIXED_CLOCK);
|
|
FIXED_CLOCK);
|
|
|
|
|
|
|
@@ -274,8 +274,8 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
.contains("exam_sprint_report_azure_storage_upload_failed")
|
|
.contains("exam_sprint_report_azure_storage_upload_failed")
|
|
|
.contains("reportId=report-123")
|
|
.contains("reportId=report-123")
|
|
|
.contains("reportType=OUTLOOK")
|
|
.contains("reportType=OUTLOOK")
|
|
|
- .contains("storageObjectKey=file.pdf")
|
|
|
|
|
- .contains("blobName=file.pdf")
|
|
|
|
|
|
|
+ .contains("storageObjectKey=report-123/file.pdf")
|
|
|
|
|
+ .contains("blobName=report-123/file.pdf")
|
|
|
.contains("fileName=file.pdf")
|
|
.contains("fileName=file.pdf")
|
|
|
.contains("pdfByteLength=3")
|
|
.contains("pdfByteLength=3")
|
|
|
.contains("durationMs=")
|
|
.contains("durationMs=")
|
|
@@ -290,13 +290,13 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
@Test
|
|
|
- void uploadUsesDisplayFileNameAsTheStorageObjectKey() {
|
|
|
|
|
|
|
+ void uploadUsesReportIdAndDisplayFileNameAsTheStorageObjectKey() {
|
|
|
BlobContainerClient containerClient = mock(BlobContainerClient.class);
|
|
BlobContainerClient containerClient = mock(BlobContainerClient.class);
|
|
|
BlobClient blobClient = mock(BlobClient.class);
|
|
BlobClient blobClient = mock(BlobClient.class);
|
|
|
when(containerClient.getBlobClient(anyString())).thenReturn(blobClient);
|
|
when(containerClient.getBlobClient(anyString())).thenReturn(blobClient);
|
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
|
|
|
containerClient,
|
|
containerClient,
|
|
|
- "reports",
|
|
|
|
|
|
|
+ "report",
|
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
"https://dcjxbtest.blob.core.chinacloudapi.cn",
|
|
|
FIXED_CLOCK);
|
|
FIXED_CLOCK);
|
|
|
|
|
|
|
@@ -313,8 +313,9 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
new byte[]{2},
|
|
new byte[]{2},
|
|
|
Instant.parse("2026-01-10T00:00:00Z"));
|
|
Instant.parse("2026-01-10T00:00:00Z"));
|
|
|
|
|
|
|
|
- assertThat(firstStoredFile.storageObjectKey()).isEqualTo("same-display-name.pdf");
|
|
|
|
|
- assertThat(secondStoredFile.storageObjectKey()).isEqualTo("same-display-name.pdf");
|
|
|
|
|
|
|
+ assertThat(firstStoredFile.storageObjectKey()).isEqualTo("report-123/same-display-name.pdf");
|
|
|
|
|
+ assertThat(secondStoredFile.storageObjectKey()).isEqualTo("report-456/same-display-name.pdf");
|
|
|
|
|
+ assertThat(firstStoredFile.storageObjectKey()).isNotEqualTo(secondStoredFile.storageObjectKey());
|
|
|
assertThat(firstStoredFile.fileName()).isEqualTo("same-display-name.pdf");
|
|
assertThat(firstStoredFile.fileName()).isEqualTo("same-display-name.pdf");
|
|
|
assertThat(secondStoredFile.fileName()).isEqualTo("same-display-name.pdf");
|
|
assertThat(secondStoredFile.fileName()).isEqualTo("same-display-name.pdf");
|
|
|
}
|
|
}
|
|
@@ -330,7 +331,7 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
true,
|
|
true,
|
|
|
null);
|
|
null);
|
|
|
return new SimpleResponse<>(
|
|
return new SimpleResponse<>(
|
|
|
- new HttpRequest(HttpMethod.PUT, "https://example.test/reports/file.pdf"),
|
|
|
|
|
|
|
+ new HttpRequest(HttpMethod.PUT, "https://example.test/report/report-123/file.pdf"),
|
|
|
201,
|
|
201,
|
|
|
headers,
|
|
headers,
|
|
|
blockBlobItem);
|
|
blockBlobItem);
|
|
@@ -345,7 +346,7 @@ class AzureBlobExamSprintReportStorageTest {
|
|
|
.set("x-ms-error-code", "ServerBusy"));
|
|
.set("x-ms-error-code", "ServerBusy"));
|
|
|
when(response.getHeaderValue(HttpHeaderName.X_MS_REQUEST_ID)).thenReturn("azure-request-failed");
|
|
when(response.getHeaderValue(HttpHeaderName.X_MS_REQUEST_ID)).thenReturn("azure-request-failed");
|
|
|
when(response.getHeaderValue(HttpHeaderName.X_MS_CLIENT_REQUEST_ID)).thenReturn("client-request-failed");
|
|
when(response.getHeaderValue(HttpHeaderName.X_MS_CLIENT_REQUEST_ID)).thenReturn("client-request-failed");
|
|
|
- when(response.getRequest()).thenReturn(new HttpRequest(HttpMethod.PUT, new URL("https://example.test/reports/file.pdf")));
|
|
|
|
|
|
|
+ when(response.getRequest()).thenReturn(new HttpRequest(HttpMethod.PUT, new URL("https://example.test/report/report-123/file.pdf")));
|
|
|
return new BlobStorageException("ServerBusy", response, null);
|
|
return new BlobStorageException("ServerBusy", response, null);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|