| // Copyright 2014 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package webdav | |
| import ( | |
| "reflect" | |
| "strings" | |
| "testing" | |
| ) | |
| func TestParseIfHeader(t *testing.T) { | |
| // The "section x.y.z" test cases come from section x.y.z of the spec at | |
| // http://www.webdav.org/specs/rfc4918.html | |
| testCases := []struct { | |
| desc string | |
| input string | |
| want ifHeader | |
| }{{ | |
| "bad: empty", | |
| ``, | |
| ifHeader{}, | |
| }, { | |
| "bad: no parens", | |
| `foobar`, | |
| ifHeader{}, | |
| }, { | |
| "bad: empty list #1", | |
| `()`, | |
| ifHeader{}, | |
| }, { | |
| "bad: empty list #2", | |
| `(a) (b c) () (d)`, | |
| ifHeader{}, | |
| }, { | |
| "bad: no list after resource #1", | |
| `<foo>`, | |
| ifHeader{}, | |
| }, { | |
| "bad: no list after resource #2", | |
| `<foo> <bar> (a)`, | |
| ifHeader{}, | |
| }, { | |
| "bad: no list after resource #3", | |
| `<foo> (a) (b) <bar>`, | |
| ifHeader{}, | |
| }, { | |
| "bad: no-tag-list followed by tagged-list", | |
| `(a) (b) <foo> (c)`, | |
| ifHeader{}, | |
| }, { | |
| "bad: unfinished list", | |
| `(a`, | |
| ifHeader{}, | |
| }, { | |
| "bad: unfinished ETag", | |
| `([b`, | |
| ifHeader{}, | |
| }, { | |
| "bad: unfinished Notted list", | |
| `(Not a`, | |
| ifHeader{}, | |
| }, { | |
| "bad: double Not", | |
| `(Not Not a)`, | |
| ifHeader{}, | |
| }, { | |
| "good: one list with a Token", | |
| `(a)`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| conditions: []Condition{{ | |
| Token: `a`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "good: one list with an ETag", | |
| `([a])`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| conditions: []Condition{{ | |
| ETag: `a`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "good: one list with three Nots", | |
| `(Not a Not b Not [d])`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| conditions: []Condition{{ | |
| Not: true, | |
| Token: `a`, | |
| }, { | |
| Not: true, | |
| Token: `b`, | |
| }, { | |
| Not: true, | |
| ETag: `d`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "good: two lists", | |
| `(a) (b)`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| conditions: []Condition{{ | |
| Token: `a`, | |
| }}, | |
| }, { | |
| conditions: []Condition{{ | |
| Token: `b`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "good: two Notted lists", | |
| `(Not a) (Not b)`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| conditions: []Condition{{ | |
| Not: true, | |
| Token: `a`, | |
| }}, | |
| }, { | |
| conditions: []Condition{{ | |
| Not: true, | |
| Token: `b`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "section 7.5.1", | |
| `<http://www.example.com/users/f/fielding/index.html> | |
| (<urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6>)`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| resourceTag: `http://www.example.com/users/f/fielding/index.html`, | |
| conditions: []Condition{{ | |
| Token: `urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "section 7.5.2 #1", | |
| `(<urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf>)`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| conditions: []Condition{{ | |
| Token: `urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "section 7.5.2 #2", | |
| `<http://example.com/locked/> | |
| (<urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf>)`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| resourceTag: `http://example.com/locked/`, | |
| conditions: []Condition{{ | |
| Token: `urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "section 7.5.2 #3", | |
| `<http://example.com/locked/member> | |
| (<urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf>)`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| resourceTag: `http://example.com/locked/member`, | |
| conditions: []Condition{{ | |
| Token: `urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "section 9.9.6", | |
| `(<urn:uuid:fe184f2e-6eec-41d0-c765-01adc56e6bb4>) | |
| (<urn:uuid:e454f3f3-acdc-452a-56c7-00a5c91e4b77>)`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| conditions: []Condition{{ | |
| Token: `urn:uuid:fe184f2e-6eec-41d0-c765-01adc56e6bb4`, | |
| }}, | |
| }, { | |
| conditions: []Condition{{ | |
| Token: `urn:uuid:e454f3f3-acdc-452a-56c7-00a5c91e4b77`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "section 9.10.8", | |
| `(<urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4>)`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| conditions: []Condition{{ | |
| Token: `urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "section 10.4.6", | |
| `(<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2> | |
| ["I am an ETag"]) | |
| (["I am another ETag"])`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| conditions: []Condition{{ | |
| Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, | |
| }, { | |
| ETag: `"I am an ETag"`, | |
| }}, | |
| }, { | |
| conditions: []Condition{{ | |
| ETag: `"I am another ETag"`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "section 10.4.7", | |
| `(Not <urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2> | |
| <urn:uuid:58f202ac-22cf-11d1-b12d-002035b29092>)`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| conditions: []Condition{{ | |
| Not: true, | |
| Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, | |
| }, { | |
| Token: `urn:uuid:58f202ac-22cf-11d1-b12d-002035b29092`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "section 10.4.8", | |
| `(<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>) | |
| (Not <DAV:no-lock>)`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| conditions: []Condition{{ | |
| Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, | |
| }}, | |
| }, { | |
| conditions: []Condition{{ | |
| Not: true, | |
| Token: `DAV:no-lock`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "section 10.4.9", | |
| `</resource1> | |
| (<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2> | |
| [W/"A weak ETag"]) (["strong ETag"])`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| resourceTag: `/resource1`, | |
| conditions: []Condition{{ | |
| Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, | |
| }, { | |
| ETag: `W/"A weak ETag"`, | |
| }}, | |
| }, { | |
| resourceTag: `/resource1`, | |
| conditions: []Condition{{ | |
| ETag: `"strong ETag"`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "section 10.4.10", | |
| `<http://www.example.com/specs/> | |
| (<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>)`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| resourceTag: `http://www.example.com/specs/`, | |
| conditions: []Condition{{ | |
| Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "section 10.4.11 #1", | |
| `</specs/rfc2518.doc> (["4217"])`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| resourceTag: `/specs/rfc2518.doc`, | |
| conditions: []Condition{{ | |
| ETag: `"4217"`, | |
| }}, | |
| }}, | |
| }, | |
| }, { | |
| "section 10.4.11 #2", | |
| `</specs/rfc2518.doc> (Not ["4217"])`, | |
| ifHeader{ | |
| lists: []ifList{{ | |
| resourceTag: `/specs/rfc2518.doc`, | |
| conditions: []Condition{{ | |
| Not: true, | |
| ETag: `"4217"`, | |
| }}, | |
| }}, | |
| }, | |
| }} | |
| for _, tc := range testCases { | |
| got, ok := parseIfHeader(strings.Replace(tc.input, "\n", "", -1)) | |
| if gotEmpty := reflect.DeepEqual(got, ifHeader{}); gotEmpty == ok { | |
| t.Errorf("%s: should be different: empty header == %t, ok == %t", tc.desc, gotEmpty, ok) | |
| continue | |
| } | |
| if !reflect.DeepEqual(got, tc.want) { | |
| t.Errorf("%s:\ngot %v\nwant %v", tc.desc, got, tc.want) | |
| continue | |
| } | |
| } | |
| } |