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 java.net.URI.create; 021import static org.fcrepo.client.ExternalContentHandling.PROXY; 022import static org.fcrepo.client.FedoraHeaderConstants.CONTENT_DISPOSITION; 023import static org.fcrepo.client.FedoraHeaderConstants.CONTENT_TYPE; 024import static org.fcrepo.client.FedoraHeaderConstants.DIGEST; 025import static org.fcrepo.client.FedoraHeaderConstants.IF_MATCH; 026import static org.fcrepo.client.FedoraHeaderConstants.IF_STATE_TOKEN; 027import static org.fcrepo.client.FedoraHeaderConstants.IF_UNMODIFIED_SINCE; 028import static org.fcrepo.client.FedoraHeaderConstants.LINK; 029import static org.fcrepo.client.FedoraHeaderConstants.PREFER; 030import static org.fcrepo.client.FedoraTypes.LDP_DIRECT_CONTAINER; 031import static org.fcrepo.client.LinkHeaderConstants.ACL_REL; 032import static org.fcrepo.client.LinkHeaderConstants.EXTERNAL_CONTENT_HANDLING; 033import static org.fcrepo.client.LinkHeaderConstants.EXTERNAL_CONTENT_REL; 034import static org.fcrepo.client.LinkHeaderConstants.TYPE_REL; 035import static org.fcrepo.client.TestUtils.baseUrl; 036import static org.junit.Assert.assertEquals; 037import static org.junit.Assert.assertNull; 038import static org.mockito.ArgumentMatchers.any; 039import static org.mockito.ArgumentMatchers.eq; 040import static org.mockito.Mockito.mock; 041import static org.mockito.Mockito.verify; 042import static org.mockito.Mockito.when; 043 044import java.io.InputStream; 045import java.net.URI; 046 047import org.apache.http.HttpEntity; 048import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; 049import org.apache.http.client.methods.HttpRequestBase; 050import org.junit.Before; 051import org.junit.Test; 052import org.junit.runner.RunWith; 053import org.mockito.ArgumentCaptor; 054import org.mockito.Captor; 055import org.mockito.Mock; 056import org.mockito.junit.MockitoJUnitRunner; 057 058/** 059 * @author bbpennel 060 */ 061@RunWith(MockitoJUnitRunner.class) 062public class PutBuilderTest { 063 064 @Mock 065 private FcrepoClient client; 066 067 @Mock 068 private FcrepoResponse fcrepoResponse; 069 070 @Captor 071 private ArgumentCaptor<HttpRequestBase> requestCaptor; 072 073 private PutBuilder testBuilder; 074 075 private URI uri; 076 077 @Before 078 public void setUp() throws Exception { 079 when(client.executeRequest(any(URI.class), any(HttpRequestBase.class))) 080 .thenReturn(fcrepoResponse); 081 082 uri = create(baseUrl); 083 testBuilder = new PutBuilder(uri, client); 084 } 085 086 @Test 087 public void testPutNoBody() throws Exception { 088 testBuilder.perform(); 089 090 verify(client).executeRequest(eq(uri), requestCaptor.capture()); 091 092 final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue(); 093 assertNull("Request body should not be set", request.getEntity()); 094 assertEquals(0, request.getAllHeaders().length); 095 } 096 097 @Test 098 public void testWithBody() throws Exception { 099 final InputStream bodyStream = mock(InputStream.class); 100 101 testBuilder.body(bodyStream, "plain/text") 102 .digestSha1("checksum") 103 .filename("file.txt") 104 .perform(); 105 106 verify(client).executeRequest(eq(uri), requestCaptor.capture()); 107 108 final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue(); 109 final HttpEntity bodyEntity = request.getEntity(); 110 assertEquals(bodyStream, bodyEntity.getContent()); 111 112 assertEquals("plain/text", request.getFirstHeader(CONTENT_TYPE).getValue()); 113 assertEquals("sha=checksum", request.getFirstHeader(DIGEST).getValue()); 114 assertEquals("attachment; filename=\"file.txt\"", request.getFirstHeader(CONTENT_DISPOSITION).getValue()); 115 } 116 117 @Test 118 public void testExternalContent() throws Exception { 119 final URI contentURI = URI.create("file:///path/to/file"); 120 testBuilder.externalContent(contentURI, "plain/text", PROXY) 121 .perform(); 122 123 verify(client).executeRequest(eq(uri), requestCaptor.capture()); 124 125 final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue(); 126 127 final FcrepoLink extLink = new FcrepoLink(request.getFirstHeader(LINK).getValue()); 128 assertEquals(EXTERNAL_CONTENT_REL, extLink.getRel()); 129 assertEquals(PROXY, extLink.getParams().get(EXTERNAL_CONTENT_HANDLING)); 130 assertEquals("plain/text", extLink.getType()); 131 } 132 133 @Test 134 public void testDisposition() throws Exception { 135 final InputStream bodyStream = mock(InputStream.class); 136 testBuilder.body(bodyStream, "plain/text").filename(null).perform(); 137 138 verify(client).executeRequest(eq(uri), requestCaptor.capture()); 139 140 final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue(); 141 final HttpEntity bodyEntity = request.getEntity(); 142 assertEquals(bodyStream, bodyEntity.getContent()); 143 assertEquals("attachment", request.getFirstHeader(CONTENT_DISPOSITION).getValue()); 144 } 145 146 @Test(expected = FcrepoOperationFailedException.class) 147 public void testPostClientError() throws Exception { 148 when(client.executeRequest(any(URI.class), any(HttpRequestBase.class))) 149 .thenThrow(new FcrepoOperationFailedException(uri, 415, "status")); 150 151 testBuilder.perform(); 152 } 153 154 @Test 155 public void testWithModificationHeaders() throws Exception { 156 final InputStream bodyStream = mock(InputStream.class); 157 158 final String etag = "123456"; 159 final String lastModified = "Mon, 19 May 2014 19:44:59 GMT"; 160 testBuilder.body(bodyStream, "plain/text") 161 .ifMatch(etag) 162 .ifUnmodifiedSince(lastModified) 163 .perform(); 164 165 verify(client).executeRequest(eq(uri), requestCaptor.capture()); 166 167 final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue(); 168 final HttpEntity bodyEntity = request.getEntity(); 169 assertEquals(bodyStream, bodyEntity.getContent()); 170 171 assertEquals("plain/text", request.getFirstHeader(CONTENT_TYPE).getValue()); 172 assertEquals(etag, request.getFirstHeader(IF_MATCH).getValue()); 173 assertEquals(lastModified, request.getFirstHeader(IF_UNMODIFIED_SINCE).getValue()); 174 } 175 176 @Test 177 public void testPreferLenient() throws Exception { 178 testBuilder.preferLenient().perform(); 179 180 verify(client).executeRequest(eq(uri), requestCaptor.capture()); 181 182 final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue(); 183 assertEquals("handling=lenient; received=\"minimal\"", request.getFirstHeader(PREFER).getValue()); 184 } 185 186 @Test 187 public void testAddInteractionModel() throws Exception { 188 testBuilder.addInteractionModel(LDP_DIRECT_CONTAINER) 189 .perform(); 190 191 verify(client).executeRequest(eq(uri), requestCaptor.capture()); 192 193 final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue(); 194 195 final FcrepoLink interLink = new FcrepoLink(request.getFirstHeader(LINK).getValue()); 196 assertEquals(TYPE_REL, interLink.getRel()); 197 assertEquals(LDP_DIRECT_CONTAINER, interLink.getUri().toString()); 198 } 199 200 @Test 201 public void testLinkAcl() throws Exception { 202 testBuilder.linkAcl("http://localhost/acl") 203 .perform(); 204 205 verify(client).executeRequest(eq(uri), requestCaptor.capture()); 206 207 final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue(); 208 209 final FcrepoLink aclLink = new FcrepoLink(request.getFirstHeader(LINK).getValue()); 210 assertEquals(ACL_REL, aclLink.getRel()); 211 assertEquals("http://localhost/acl", aclLink.getUri().toString()); 212 } 213 214 @Test 215 public void testStateToken() throws Exception { 216 final InputStream bodyStream = mock(InputStream.class); 217 final String token = "state"; 218 219 testBuilder.body(bodyStream) 220 .ifStateToken(token) 221 .perform(); 222 223 verify(client).executeRequest(eq(uri), requestCaptor.capture()); 224 225 final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue(); 226 assertEquals(token, request.getFirstHeader(IF_STATE_TOKEN).getValue()); 227 } 228 229 @Test 230 public void testAddHeader() throws Exception { 231 testBuilder.addHeader("my-header", "head-val").perform(); 232 233 verify(client).executeRequest(eq(uri), requestCaptor.capture()); 234 final HttpRequestBase request = requestCaptor.getValue(); 235 assertEquals("head-val", request.getFirstHeader("my-header").getValue()); 236 } 237 238 @Test 239 public void testAddLinkHeader() throws Exception { 240 final FcrepoLink link = FcrepoLink.fromUri("http://example.com/link").type("foo").build(); 241 testBuilder.addLinkHeader(link).perform(); 242 243 verify(client).executeRequest(eq(uri), requestCaptor.capture()); 244 final HttpRequestBase request = requestCaptor.getValue(); 245 assertEquals(link.toString(), request.getFirstHeader(LINK).getValue()); 246 } 247}