001/*
002 * Licensed to DuraSpace under one or more contributor license agreements.
003 * See the NOTICE file distributed with this work for additional information
004 * regarding copyright ownership.
005 *
006 * DuraSpace licenses this file to you under the Apache License,
007 * Version 2.0 (the "License"); you may not use this file except in
008 * compliance with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.fcrepo.client;
019
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertNull;
022import static org.junit.Assert.assertTrue;
023import static org.fcrepo.client.LinkHeaderConstants.DESCRIBEDBY_REL;
024import static org.fcrepo.client.LinkHeaderConstants.MEMENTO_ORIGINAL_REL;
025import static org.fcrepo.client.LinkHeaderConstants.MEMENTO_TIME_MAP_REL;
026
027import java.net.URI;
028import java.util.List;
029
030import org.junit.Test;
031import org.junit.runner.RunWith;
032import org.mockito.junit.MockitoJUnitRunner;
033
034/**
035 * @author acoburn
036 */
037@RunWith(MockitoJUnitRunner.class)
038public class FcrepoLinkTest {
039
040    private static final String TEST_URI = "http://localhost/rest/a/b/c";
041
042    private static final String MULTI_LINK_HEADER =
043            "<http://a.example.org/>; rel=\"original\", " +
044            "<http://arxiv.example.net/timemap/http://a.example.org/>" +
045            "; rel=\"timemap\"; type=\"application/link-format\"" +
046            "; from=\"Tue, 15 Sep 2000 11:28:26 GMT\"" +
047            "; until=\"Wed, 20 Jan 2010 09:34:33 GMT\"";
048
049    @Test
050    public void testLink() {
051        final String header = String.format("<%s>; rel=\"%s\"", TEST_URI, DESCRIBEDBY_REL);
052        final FcrepoLink link = new FcrepoLink(header);
053        assertEquals(URI.create(TEST_URI), link.getUri());
054        assertEquals(TEST_URI, link.getUri().toString());
055        assertEquals(DESCRIBEDBY_REL, link.getRel());
056    }
057
058    @Test
059    public void testLinkNoQuotes() {
060        final String header = String.format("<%s>; rel=%s", TEST_URI, DESCRIBEDBY_REL);
061        final FcrepoLink link = new FcrepoLink(header);
062        assertEquals(URI.create(TEST_URI), link.getUri());
063        assertEquals(TEST_URI, link.getUri().toString());
064        assertEquals(DESCRIBEDBY_REL, link.getRel());
065    }
066
067    @Test(expected = IllegalArgumentException.class)
068    public void testLinkNoBrackets() {
069        final String header = String.format("%s; rel=%s", TEST_URI, DESCRIBEDBY_REL);
070        new FcrepoLink(header);
071    }
072
073    @Test(expected = IllegalArgumentException.class)
074    public void testLinkBadBrackets1() {
075        final String header = String.format("<%s; rel=%s", TEST_URI, DESCRIBEDBY_REL);
076        new FcrepoLink(header);
077    }
078
079    @Test(expected = IllegalArgumentException.class)
080    public void testLinkBadBrackets2() {
081        final String header = String.format("%s>; rel=%s", TEST_URI, DESCRIBEDBY_REL);
082        new FcrepoLink(header);
083    }
084
085    @Test(expected = IllegalArgumentException.class)
086    public void testLinkBadQuotes() {
087        final String header = String.format("<%s>; rel=\"%s", TEST_URI, DESCRIBEDBY_REL);
088        new FcrepoLink(header);
089    }
090
091    @Test(expected = IllegalArgumentException.class)
092    public void testNullLink() {
093        new FcrepoLink(null);
094    }
095
096    @Test(expected = IllegalArgumentException.class)
097    public void testEmptyLink() {
098        new FcrepoLink(" ");
099    }
100
101    @Test
102    public void testMultipleSegments() {
103        final FcrepoLink link = new FcrepoLink("<a>; rel=foo; bar=bar");
104        assertEquals(URI.create("a"), link.getUri());
105        assertEquals("foo", link.getRel());
106        assertEquals("bar", link.getParam("bar"));
107    }
108
109    @Test
110    public void testMultipleMeta() {
111        final FcrepoLink link = new FcrepoLink("<a>; rel=foo=bar");
112        assertEquals(URI.create("a"), link.getUri());
113        // = is an allowable character for the parameter value
114        assertEquals("foo=bar", link.getRel());
115    }
116
117    @Test
118    public void testArbitraryParameter() {
119        final FcrepoLink link = new FcrepoLink("<a>; foo=bar");
120        assertEquals(URI.create("a"), link.getUri());
121        assertNull(link.getRel());
122    }
123
124    @Test
125    public void testQuotedParamWithDelimiters() {
126        final FcrepoLink link = new FcrepoLink("<a>; foo=\"a,b;c=d\"");
127        assertEquals(URI.create("a"), link.getUri());
128        assertEquals("a,b;c=d", link.getParam("foo"));
129    }
130
131    @Test(expected = IllegalArgumentException.class)
132    public void testUnquotedParamWithDelimiters() {
133        new FcrepoLink("<a>; foo=a;b");
134    }
135
136    @Test
137    public void testNoParameters() {
138        final FcrepoLink link = new FcrepoLink("<a>");
139        assertEquals(URI.create("a"), link.getUri());
140        assertNull(link.getRel());
141        assertNull(link.getType());
142    }
143
144    @Test
145    public void testFromUriString() {
146        final FcrepoLink link = FcrepoLink.fromUri("http://example.com/").build();
147        assertEquals(URI.create("http://example.com/"), link.getUri());
148    }
149
150    @Test(expected = IllegalArgumentException.class)
151    public void testFromUriStringNull() {
152        FcrepoLink.fromUri((String) null).build();
153    }
154
155    @Test
156    public void testFromUri() {
157        final FcrepoLink link = FcrepoLink.fromUri(URI.create("http://example.com/")).build();
158        assertEquals(URI.create("http://example.com/"), link.getUri());
159    }
160
161    @Test(expected = IllegalArgumentException.class)
162    public void testFromUriNull() {
163        FcrepoLink.fromUri((URI) null).build();
164    }
165
166    @Test
167    public void testBuilder() {
168        final FcrepoLink link = new FcrepoLink.Builder()
169                .uri(TEST_URI)
170                .rel("bar")
171                .type("foo")
172                .param("special", "val")
173                .build();
174
175        assertEquals(URI.create(TEST_URI), link.getUri());
176        assertEquals("bar", link.getRel());
177        assertEquals("foo", link.getType());
178        assertEquals("val", link.getParam("special"));
179    }
180
181    @Test
182    public void testToStringNoParams() {
183        final String header = String.format("<%s>", TEST_URI);
184        final FcrepoLink link = new FcrepoLink(header);
185        assertEquals(header, link.toString());
186    }
187
188    @Test
189    public void testToStringWithParam() {
190        final String header = String.format("<%s>; rel=\"%s\"", TEST_URI, DESCRIBEDBY_REL);
191        final FcrepoLink link = new FcrepoLink(header);
192        assertEquals(header, link.toString());
193    }
194
195    @Test
196    public void testToStringMultipleParams() {
197        final FcrepoLink link = new FcrepoLink.Builder()
198                .uri(TEST_URI)
199                .rel("bar")
200                .type("foo")
201                .param("special", "val")
202                .build();
203
204        final String header = link.toString();
205        assertTrue("Stringified link did not contain URI", header.contains(TEST_URI));
206        assertTrue("Stringified link did not contain rel", header.contains("; rel=\"bar\""));
207        assertTrue("Stringified link did not contain type", header.contains("; type=\"foo\""));
208        assertTrue("Stringified link did not contain param", header.contains("; special=\"val\""));
209    }
210
211    @Test
212    public void testValueOf() {
213        final String header = String.format("<%s>; rel=\"%s\"", TEST_URI, DESCRIBEDBY_REL);
214
215        final FcrepoLink link = FcrepoLink.valueOf(header);
216
217        assertEquals(TEST_URI, link.getUri().toString());
218        assertEquals(DESCRIBEDBY_REL, link.getRel());
219    }
220
221    @Test(expected = IllegalArgumentException.class)
222    public void testValueOfWithComma() {
223        FcrepoLink.valueOf(MULTI_LINK_HEADER);
224    }
225
226    @Test
227    public void testFromHeaderSingleLink() {
228        final String header = String.format("<%s>; rel=\"%s\"", TEST_URI, DESCRIBEDBY_REL);
229
230        final List<FcrepoLink> links = FcrepoLink.fromHeader(header);
231        assertEquals("Incorrect number of links returned", 1, links.size());
232
233        assertEquals(TEST_URI, links.get(0).getUri().toString());
234        assertEquals(DESCRIBEDBY_REL, links.get(0).getRel());
235    }
236
237    @Test
238    public void testFromHeaderMultipleLinks() {
239        final List<FcrepoLink> links = FcrepoLink.fromHeader(MULTI_LINK_HEADER);
240        assertEquals("Incorrect number of links returned", 2, links.size());
241
242        final FcrepoLink link1 = links.get(0);
243        assertEquals("http://a.example.org/", link1.getUri().toString());
244        assertEquals(MEMENTO_ORIGINAL_REL, link1.getRel());
245
246        final FcrepoLink link2 = links.get(1);
247        assertEquals("http://arxiv.example.net/timemap/http://a.example.org/", link2.getUri().toString());
248        assertEquals(MEMENTO_TIME_MAP_REL, link2.getRel());
249        assertEquals("application/link-format", link2.getType());
250        assertEquals("Tue, 15 Sep 2000 11:28:26 GMT", link2.getParam("from"));
251    }
252
253    @Test
254    public void testFromHeaderUriContainsComma() throws Exception {
255        final String header = String.format("<a,b>; rel=\"%s\"", DESCRIBEDBY_REL);
256
257        final List<FcrepoLink> links = FcrepoLink.fromHeader(header);
258        assertEquals("Incorrect number of links returned", 1, links.size());
259
260        assertEquals("a,b", links.get(0).getUri().toString());
261        assertEquals(DESCRIBEDBY_REL, links.get(0).getRel());
262    }
263
264    @Test
265    public void testFromHeaderParamContainsComma() throws Exception {
266        final String header = "<a>; param=\"value,with,commas\"";
267
268        final List<FcrepoLink> links = FcrepoLink.fromHeader(header);
269        assertEquals("Incorrect number of links returned", 1, links.size());
270
271        assertEquals("a", links.get(0).getUri().toString());
272        assertEquals("value,with,commas", links.get(0).getParam("param"));
273    }
274
275    @Test(expected = IllegalArgumentException.class)
276    public void testFromHeaderUnterminatedUri() {
277        final String header = String.format("<a; rel=\"%s\"", DESCRIBEDBY_REL);
278        FcrepoLink.fromHeader(header);
279    }
280
281    @Test(expected = IllegalArgumentException.class)
282    public void testFromHeaderUnterminatedQuotes() {
283        final String header = String.format("<a>; rel=\"%s, <b>", DESCRIBEDBY_REL);
284        FcrepoLink.fromHeader(header);
285    }
286}