@@ -4,10 +4,14 @@ import assertions.assertSuccess
44import database.entity.Area
55import io.ktor.client.statement.bodyAsChannel
66import io.ktor.client.statement.readRawBytes
7+ import io.ktor.http.HttpHeaders
8+ import io.ktor.http.etag
79import io.ktor.http.isSuccess
10+ import io.ktor.http.lastModified
811import io.ktor.utils.io.readBuffer
912import java.awt.image.BufferedImage
1013import java.io.File
14+ import java.security.MessageDigest
1115import javax.imageio.ImageIO
1216import kotlin.test.Test
1317import kotlin.test.assertEquals
@@ -17,27 +21,32 @@ import kotlinx.io.copyTo
1721import server.DataProvider
1822import server.base.ApplicationTestBase
1923import server.base.StubApplicationTestBuilder
24+ import server.response.FileSource
25+ import server.response.FileUUID
26+ import storage.FileType
27+ import storage.HashUtils
28+ import storage.MessageDigestAlgorithm
2029import storage.Storage
2130
2231class TestFileDownloading : ApplicationTestBase () {
2332 private suspend inline fun StubApplicationTestBuilder.provideImageFile (
2433 imageFile : String = "/images/alcoi.jpg",
25- block : (imageUUID: String ) -> Unit
34+ block : (imageUUID: String , imageFile: File ) -> Unit
2635 ) {
2736 val areaId = DataProvider .provideSampleArea(this , imageFile = imageFile)
2837
29- var image : String ? = null
38+ var imageFile : File ? = null
3039
3140 get(" /area/$areaId " ).apply {
3241 assertSuccess<Area > { data ->
3342 assertNotNull(data)
34- image = data.image.toRelativeString( Storage . ImagesDir )
43+ imageFile = data.image
3544 }
3645 }
3746
38- assertNotNull(image )
47+ assertNotNull(imageFile )
3948
40- block(image )
49+ block(imageFile.toRelativeString( Storage . ImagesDir ), imageFile )
4150 }
4251
4352 private fun downloadResized (
@@ -46,7 +55,7 @@ class TestFileDownloading : ApplicationTestBase() {
4655 fetch : (BufferedImage ) -> Int ,
4756 imageFile : String = "/images/alcoi.jpg"
4857 ) = test {
49- provideImageFile(imageFile) { image ->
58+ provideImageFile(imageFile) { image, _ ->
5059 val tempFile = File .createTempFile(" eaic" , null )
5160 val response = get(" /download/$image ?$argument =$value " )
5261 assertTrue(
@@ -69,14 +78,29 @@ class TestFileDownloading : ApplicationTestBase() {
6978
7079 @Test
7180 fun `test downloading files` () = test {
72- provideImageFile { image ->
81+ provideImageFile { image, imageFile ->
7382 get(" /download/$image " ).apply {
74- headers[" Content-Type" ].let { contentType ->
75- assertEquals(
76- " image/jpeg" ,
77- contentType,
78- " Content-Type header is not JPEG. Got: $contentType "
83+ headers[HttpHeaders .ContentType ].let { contentType ->
84+ assertEquals(" image/jpeg" , contentType, " Content-Type header is not JPEG. Got: $contentType " )
85+ }
86+ assertEquals(image, headers[HttpHeaders .FileUUID ], " File UUID header is not correct" )
87+ assertEquals(
88+ FileType .IMAGE .headerValue,
89+ headers[HttpHeaders .FileSource ],
90+ " File source header is not correct."
91+ )
92+ etag().let {
93+ val hash = HashUtils .getCheckSumFromFile(
94+ MessageDigest .getInstance(MessageDigestAlgorithm .SHA_256 ),
95+ imageFile
7996 )
97+ assertEquals(" \" $hash \" " , it, " ETag header is not correct" )
98+ }
99+ lastModified()?.time.let {
100+ // Value may be truncated to seconds and converted again to ms, so we need to truncate it
101+ val fileLastModified = imageFile.lastModified() / 1000 * 1000
102+ val headerLastModified = it?.div(1000 )?.times(1000 )
103+ assertEquals(fileLastModified, headerLastModified, " Last-Modified header is not correct" )
80104 }
81105 readRawBytes()
82106 }
0 commit comments