Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit f434c9d1 authored by Arnau Mora's avatar Arnau Mora Committed by GitHub
Browse files

GetETag: don't ignore weakness indicator (#8)



* GetETag: don't use .let too much, add tests

* Added `weak` attribute

Signed-off-by: default avatarArnau Mora <arnyminer.z@gmail.com>

* Added tests for `weak` attribute

Signed-off-by: default avatarArnau Mora <arnyminer.z@gmail.com>

* Added tests for `weak` attribute

Signed-off-by: default avatarArnau Mora <arnyminer.z@gmail.com>

* Documented `eTag` and `weak`

Signed-off-by: default avatarArnau Mora <arnyminer.z@gmail.com>

* Refactor `weak` setting

Signed-off-by: default avatarArnau Mora <arnyminer.z@gmail.com>

* Using JUnit's `assertTrue`

Signed-off-by: default avatarArnau Mora <arnyminer.z@gmail.com>

* Use assertTrue / assertFalse

Signed-off-by: default avatarArnau Mora <arnyminer.z@gmail.com>
Co-authored-by: default avatarRicki Hirner <hirner@bitfire.at>
parent cd9390b5
Loading
Loading
Loading
Loading
+27 −9
Original line number Diff line number Diff line
@@ -13,6 +13,12 @@ import at.bitfire.dav4jvm.XmlUtils
import okhttp3.Response
import org.xmlpull.v1.XmlPullParser

/**
 * The GetETag property.
 *
 * Can also be used to parse ETags from HTTP responses – just pass the raw ETag
 * header value to the constructor and then use [eTag] and [weak].
 */
class GetETag(
    rawETag: String?
): Property {
@@ -25,22 +31,34 @@ class GetETag(
            response.header("ETag")?.let { GetETag(it) }
    }

    /**
     * The parsed eTag value. May be null if the tag is weak.
     */
    val eTag: String?

    /**
     * If the tag is weak. May be null if the tag passed is null.
     */
    val weak: Boolean?

    init {
        /* entity-tag = [ weak ] opaque-tag
           weak       = "W/"
           opaque-tag = quoted-string
        */
        var tag: String? = rawETag
        tag?.let {
        if (tag != null) {
            // remove trailing "W/"
            if (it.startsWith("W/") && it.length >= 3)
            // entity tag is weak (doesn't matter for us)
                tag = it.substring(2)

            tag?.let { tag = QuotedStringUtils.decodeQuotedString(it) }
        }
            if (tag.startsWith("W/") && tag.length >= 3) {
                // entity tag is weak
                tag = tag.substring(2)
                weak = true
            } else
                weak = false

            tag = QuotedStringUtils.decodeQuotedString(tag)
        } else
            weak = null

        eTag = tag
    }
+15 −5
Original line number Diff line number Diff line
@@ -104,19 +104,25 @@ class DavCollectionTest {
                url.resolve("/dav/test.doc") -> {
                    assertTrue(response.isSuccess())
                    assertEquals(Response.HrefRelation.MEMBER, relation)
                    assertEquals("00001-abcd1", response[GetETag::class.java]?.eTag)
                    val eTag = response[GetETag::class.java]
                    assertEquals("00001-abcd1", eTag?.eTag)
                    assertTrue(eTag?.weak == false)
                    nrCalled++
                }
                url.resolve("/dav/vcard.vcf") -> {
                    assertTrue(response.isSuccess())
                    assertEquals(Response.HrefRelation.MEMBER, relation)
                    assertEquals("00002-abcd1", response[GetETag::class.java]?.eTag)
                    val eTag = response[GetETag::class.java]
                    assertEquals("00002-abcd1", eTag?.eTag)
                    assertTrue(eTag?.weak == false)
                    nrCalled++
                }
                url.resolve("/dav/calendar.ics") -> {
                    assertTrue(response.isSuccess())
                    assertEquals(Response.HrefRelation.MEMBER, relation)
                    assertEquals("00003-abcd1", response[GetETag::class.java]?.eTag)
                    val eTag = response[GetETag::class.java]
                    assertEquals("00003-abcd1", eTag?.eTag)
                    assertTrue(eTag?.weak == false)
                    nrCalled++
                }
            }
@@ -174,13 +180,17 @@ class DavCollectionTest {
                url.resolve("/dav/test.doc") -> {
                    assertTrue(response.isSuccess())
                    assertEquals(Response.HrefRelation.MEMBER, relation)
                    assertEquals("00001-abcd1", response[GetETag::class.java]?.eTag)
                    val eTag = response[GetETag::class.java]
                    assertEquals("00001-abcd1", eTag?.eTag)
                    assertTrue(eTag?.weak == false)
                    nrCalled++
                }
                url.resolve("/dav/vcard.vcf") -> {
                    assertTrue(response.isSuccess())
                    assertEquals(Response.HrefRelation.MEMBER, relation)
                    assertEquals("00002-abcd1", response[GetETag::class.java]?.eTag)
                    val eTag = response[GetETag::class.java]
                    assertEquals("00002-abcd1", eTag?.eTag)
                    assertTrue(eTag?.weak == false)
                    nrCalled++
                }
                url.resolve("/dav/removed.txt") -> {
+13 −6
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ import okhttp3.OkHttpClient
import okhttp3.Protocol
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.ResponseBody.Companion.asResponseBody
import okhttp3.ResponseBody.Companion.toResponseBody
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
@@ -244,7 +243,9 @@ class DavResourceTest {
            called = true
            assertEquals(sampleText, response.body!!.string())

            assertEquals("My Weak ETag", GetETag.fromResponse(response)?.eTag)
            val eTag = GetETag.fromResponse(response)
            assertEquals("My Weak ETag", eTag!!.eTag)
            assertTrue(eTag.weak!!)
            assertEquals("application/x-test-result".toMediaType(), GetContentType(response.body!!.contentType()!!).type)
        }
        assertTrue(called)
@@ -267,7 +268,9 @@ class DavResourceTest {
        dav.get("*/*", null) { response ->
            called = true
            assertEquals(sampleText, response.body!!.string())
            assertEquals("StrongETag", GetETag(response.header("ETag")).eTag)
            val eTag = GetETag(response.header("ETag"))
            assertEquals("StrongETag", eTag.eTag)
            assertFalse(eTag.weak!!)
        }
        assertTrue(called)

@@ -799,7 +802,9 @@ class DavResourceTest {
        var called = false
        dav.put(sampleText.toRequestBody("text/plain".toMediaType())) { response ->
            called = true
            assertEquals("Weak PUT ETag", GetETag.fromResponse(response)!!.eTag)
            val eTag = GetETag.fromResponse(response)!!
            assertEquals("Weak PUT ETag", eTag.eTag)
            assertTrue(eTag.weak!!)
            assertEquals(response.request.url, dav.location)
        }
        assertTrue(called)
@@ -820,7 +825,9 @@ class DavResourceTest {
        dav.put(sampleText.toRequestBody("text/plain".toMediaType()), ifNoneMatch = true) { response ->
            called = true
            assertEquals(url.resolve("/target"), response.request.url)
            assertNull("Weak PUT ETag", GetETag.fromResponse(response)?.eTag)
            val eTag = GetETag.fromResponse(response)
            assertNull("Weak PUT ETag", eTag?.eTag)
            assertNull(eTag?.weak)
        }
        assertTrue(called)

@@ -838,7 +845,7 @@ class DavResourceTest {
                called = true
            }
            fail("Expected PreconditionFailedException")
        } catch(e: PreconditionFailedException) {}
        } catch(_: PreconditionFailedException) {}
        assertFalse(called)
        rq = mockServer.takeRequest()
        assertEquals("\"ExistingETag\"", rq.getHeader("If-Match"))
+48 −0
Original line number Diff line number Diff line
package at.bitfire.dav4jvm.property

import org.junit.Assert.*
import org.junit.Test

class GetETagTest: PropertyTest() {

    @Test
    fun testGetETag_NoText() {
        val results = parseProperty("<getetag xmlns=\"DAV:\"><invalid/></getetag>")
        val getETag = results.first() as GetETag
        assertNull(getETag.eTag)
        assertNull(getETag.weak)
    }

    @Test
    fun testGetETag_Strong() {
        val results = parseProperty("<getetag xmlns=\"DAV:\">\"Correct strong ETag\"</getetag>")
        val getETag = results.first() as GetETag
        assertEquals("Correct strong ETag", getETag.eTag)
        assertFalse(getETag.weak!!)
    }

    @Test
    fun testGetETag_Strong_NoQuotes() {
        val results = parseProperty("<getetag xmlns=\"DAV:\">Strong ETag without quotes</getetag>")
        val getETag = results.first() as GetETag
        assertEquals("Strong ETag without quotes", getETag.eTag)
        assertFalse(getETag.weak!!)
    }

    @Test
    fun testGetETag_Weak() {
        val results = parseProperty("<getetag xmlns=\"DAV:\">W/\"Correct weak ETag\"</getetag>")
        val getETag = results.first() as GetETag
        assertEquals("Correct weak ETag", getETag.eTag)
        assertTrue(getETag.weak!!)
    }

    @Test
    fun testGetETag_Weak_NoQuotes() {
        val results = parseProperty("<getetag xmlns=\"DAV:\">W/Weak ETag without quotes</getetag>")
        val getETag = results.first() as GetETag
        assertEquals("Weak ETag without quotes", getETag.eTag)
        assertTrue(getETag.weak!!)
    }

}
 No newline at end of file