/** * Copyright (c) 2012, Thilo Planz. All rights reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package v7db.files.buckets; import java.io.ByteArrayInputStream; import java.io.IOException; import javax.servlet.http.HttpServletResponse; import jmockmongo.MockMongoTestCaseSupport; import org.apache.commons.codec.digest.DigestUtils; import org.bson.BasicBSONObject; import org.xml.sax.SAXException; import v7db.files.UnitTestSupport; import v7db.files.mongodb.MongoContentStorage; import v7db.files.spi.ContentSHA; import com.meterware.httpunit.GetMethodWebRequest; import com.meterware.httpunit.HttpException; import com.meterware.httpunit.HttpNotFoundException; import com.meterware.httpunit.PostMethodWebRequest; import com.meterware.httpunit.PutMethodWebRequest; import com.meterware.httpunit.WebRequest; import com.meterware.httpunit.WebResponse; import com.meterware.servletunit.ServletRunner; import com.meterware.servletunit.ServletUnitClient; public class BucketsServletTest extends MockMongoTestCaseSupport { private ServletRunner sr; public static class TestBucketsServlet extends BucketsServlet { private static final long serialVersionUID = 1L; public TestBucketsServlet() { super(UnitTestSupport.getDefaultProperties()); } } @Override protected void setUp() throws Exception { super.setUp(); sr = new ServletRunner(); sr.registerServlet("myServlet/*", TestBucketsServlet.class.getName()); } private BasicBSONObject prepareBucket(String bucketId, String GET, String POST, String PUT) { BasicBSONObject o = new BasicBSONObject("_id", bucketId).append("GET", GET).append("POST", POST).append("PUT", PUT); prepareMockData("test.v7files.buckets", o); return o; } public void testEchoPutGET() throws IOException, SAXException { ServletUnitClient sc = sr.newClient(); { WebRequest request = new GetMethodWebRequest( "http://test/myServlet/1"); request.setParameter("sha", "1234"); try { sc.getResponse(request); fail("bucket not found => 404"); } catch (HttpNotFoundException e) { assertEquals("Bucket '1' not found", e.getResponseMessage()); } } prepareBucket("1", "EchoPut", null, null); { WebRequest request = new GetMethodWebRequest( "http://test/myServlet/1"); request.setParameter("sha", "1234"); try { sc.getResponse(request); fail("bucket not found => 404"); } catch (HttpNotFoundException e) { assertEquals( "Bucket '1' does not have a file matching digest '1234'", e.getResponseMessage()); } } MongoContentStorage storage = new MongoContentStorage(getMongo().getDB( "test")); ContentSHA sha = storage.storeContent(new ByteArrayInputStream("test" .getBytes())); { WebRequest request = new GetMethodWebRequest( "http://test/myServlet/1"); request.setParameter("sha", sha.getDigest()); request.setParameter("filename", "a.txt"); WebResponse response = sc.getResponse(request); assertEquals("test", response.getText()); assertEquals(sha.getDigest(), response.getHeaderField("ETag")); assertEquals(4, response.getContentLength()); assertEquals("attachment; filename=\"a.txt\"", response .getHeaderField("Content-Disposition")); } { WebRequest request = new GetMethodWebRequest( "http://test/myServlet/1"); request.setParameter("sha", sha.getDigest()); request.setHeaderField("If-None-Match", sha.getDigest()); WebResponse response = sc.getResponse(request); assertEquals(HttpServletResponse.SC_NOT_MODIFIED, response .getResponseCode()); } } public void testEchoPutPUT() throws IOException, SAXException { ServletUnitClient sc = sr.newClient(); { WebRequest request = new PutMethodWebRequest( "http://test/myServlet/1", new ByteArrayInputStream( "testPUT".getBytes()), "text/plain"); try { sc.getResponse(request); fail("bucket not found => 404"); } catch (HttpNotFoundException e) { assertEquals("Bucket '1' not found", e.getResponseMessage()); } } prepareBucket("1", "EchoPut", null, null); { WebRequest request = new PutMethodWebRequest( "http://test/myServlet/1", new ByteArrayInputStream( "testPUT".getBytes()), "text/plain"); request.setParameter("sha", "1234"); try { sc.getResponse(request); fail("uploads not allowed => 405"); } catch (HttpException e) { assertEquals(HttpServletResponse.SC_METHOD_NOT_ALLOWED, e .getResponseCode()); } } prepareBucket("2", "EchoPut", null, "EchoPut"); { WebRequest request = new PutMethodWebRequest( "http://test/myServlet/2", new ByteArrayInputStream( "testPUT".getBytes()), "text/plain"); WebResponse response = sc.getResponse(request); assertEquals(DigestUtils.shaHex("testPUT".getBytes()), response .getText()); assertMockMongoContainsDocument("test.v7files.content", DigestUtils .sha("testPUT".getBytes())); WebRequest get = new GetMethodWebRequest("http://test/myServlet/2"); get.setParameter("sha", response.getText()); assertEquals("testPUT", sc.getResponse(get).getText()); } } public void testFormPostGET() throws IOException, SAXException { BasicBSONObject bucket = prepareBucket("1", "FormPost", null, null); MongoContentStorage storage = new MongoContentStorage(getMongo().getDB( "test")); ContentSHA sha = storage.storeContent(new ByteArrayInputStream("test" .getBytes())); ServletUnitClient sc = sr.newClient(); { WebRequest request = new GetMethodWebRequest( "http://test/myServlet/1"); request.setParameter("sha", sha.getDigest()); try { sc.getResponse(request); fail("bucket not found => 404"); } catch (HttpNotFoundException e) { assertEquals(String.format( "Bucket '1' does not have a file matching digest '%s'", sha.getDigest()), e.getResponseMessage()); } } bucket.append("FormPost", new BasicBSONObject("data", new BasicBSONObject("files", new BasicBSONObject("file", new BasicBSONObject("filename", "a.txt").append("sha", sha.getSHA()))))); { WebRequest request = new GetMethodWebRequest( "http://test/myServlet/1"); request.setParameter("sha", sha.getDigest()); WebResponse response = sc.getResponse(request); assertEquals("test", response.getText()); assertEquals(sha.getDigest(), response.getHeaderField("ETag")); assertEquals(4, response.getContentLength()); assertEquals("attachment; filename=\"a.txt\"", response .getHeaderField("Content-Disposition")); } { WebRequest request = new GetMethodWebRequest( "http://test/myServlet/1"); request.setParameter("sha", sha.getDigest()); request.setParameter("filename", "x.txt"); WebResponse response = sc.getResponse(request); assertEquals("test", response.getText()); assertEquals(sha.getDigest(), response.getHeaderField("ETag")); assertEquals(4, response.getContentLength()); assertEquals("attachment; filename=\"x.txt\"", response .getHeaderField("Content-Disposition")); } { WebRequest request = new GetMethodWebRequest( "http://test/myServlet/1"); request.setParameter("sha", sha.getDigest()); request.setHeaderField("If-None-Match", sha.getDigest()); WebResponse response = sc.getResponse(request); assertEquals(HttpServletResponse.SC_NOT_MODIFIED, response .getResponseCode()); } } public void testFormPostPOST() throws IOException, SAXException { ServletUnitClient sc = sr.newClient(); { PostMethodWebRequest request = new PostMethodWebRequest( "http://test/myServlet/1"); try { sc.getResponse(request); fail("bucket not found => 404"); } catch (HttpNotFoundException e) { assertEquals("Bucket '1' not found", e.getResponseMessage()); } } prepareBucket("1", "FormPost", null, null); { PostMethodWebRequest request = new PostMethodWebRequest( "http://test/myServlet/1"); try { sc.getResponse(request); fail("uploads not allowed => 405"); } catch (HttpException e) { assertEquals(HttpServletResponse.SC_METHOD_NOT_ALLOWED, e .getResponseCode()); } } // // TODO: an actual POST, see // http://stackoverflow.com/questions/10891247/file-upload-post-request-with-servletunit } }