/** * personium.io * Copyright 2014 FUJITSU LIMITED * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.fujitsu.dc.test.jersey.box; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.http.HttpHeaders; import org.apache.http.HttpStatus; import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.fujitsu.dc.core.DcCoreException; import com.fujitsu.dc.core.model.Box; import com.fujitsu.dc.test.categories.Integration; import com.fujitsu.dc.test.categories.Regression; import com.fujitsu.dc.test.categories.Unit; import com.fujitsu.dc.test.jersey.AbstractCase; import com.fujitsu.dc.test.jersey.DcRunner; import com.fujitsu.dc.test.jersey.box.odatacol.schema.complextype.ComplexTypeUtils; import com.fujitsu.dc.test.jersey.box.odatacol.schema.complextypeproperty.ComplexTypePropertyUtils; import com.fujitsu.dc.test.setup.Setup; import com.fujitsu.dc.test.unit.core.UrlUtils; import com.fujitsu.dc.test.utils.AccountUtils; import com.fujitsu.dc.test.utils.BoxUtils; import com.fujitsu.dc.test.utils.CellUtils; import com.fujitsu.dc.test.utils.DavResourceUtils; import com.fujitsu.dc.test.utils.Http; import com.fujitsu.dc.test.utils.ResourceUtils; import com.fujitsu.dc.test.utils.RoleUtils; import com.fujitsu.dc.test.utils.TResponse; import com.fujitsu.dc.test.utils.TestMethodUtils; import com.sun.jersey.test.framework.JerseyTest; /** * MKCOLのテスト. */ @RunWith(DcRunner.class) @Category({Unit.class, Integration.class, Regression.class }) public class CollectionTest extends JerseyTest { /** * コンストラクタ. */ public CollectionTest() { super("com.fujitsu.dc.core.rs"); } static final String ACL_AUTH_TEST_SETTING_FILE = "box/acl-authtest.txt"; static final String ACL_AUTH_PROPPATCH_TEST_SETTING_FILE = "box/acl-authtestProppatch.txt"; static final String TOKEN = AbstractCase.MASTER_TOKEN_NAME; static final String ACL_SETTING_TEST = "box/acl-setting.txt"; /** * MKCOL-Normalのテスト. */ @Test public final void MKCOL_Normalのテスト() { String path = "davcol1"; try { // コレクションの作成 Http.request("box/mkcol-normal.txt") .with("cellPath", "testcell1") .with("path", path) .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // コレクションの取得(bodyあり) TResponse tresponseAll = Http.request("box/propfind-col-allprop.txt") .with("path", path) .with("depth", "0") .with("token", TOKEN) .returns(); tresponseAll.statusCode(HttpStatus.SC_MULTI_STATUS); // コレクションの取得(bodyなし) TResponse tresponse = Http.request("box/propfind-col-body-0.txt") .with("path", path) .with("depth", "0") .with("token", TOKEN) .returns(); tresponse.statusCode(HttpStatus.SC_MULTI_STATUS); // bodyの全文比較 assertEquals(tresponse.getBody(), tresponseAll.getBody()); // BodyXMLからの要素取得 String status1 = getXmlNodeValue(tresponse.bodyAsXml(), "status"); assertEquals("HTTP/1.1 200 OK", status1); // webDAVの仕様とのマッチ assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "response")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "href")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "propstat")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "prop")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "creationdate")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "getlastmodified")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "resourcetype")); } finally { // コレクションの削除 deleteTest(path, -1); // コレクションの取得(削除の確認) Http.request("box/propfind-col-allprop.txt") .with("path", path) .with("depth", "0") .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_NOT_FOUND); } } /** * MKCOL_Body異常系のテスト. */ @Test public final void MKCOL_Body異常系のテスト() { String path = "davcol3"; StringBuilder sb; sb = new StringBuilder(); sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); sb.append("<D:mkcol xmlns:D=\"DAV:\" xmlns:dc=\"urn:x-dc1:xmlns\">"); sb.append("<D:sets><D:prop><D:resourcetype><D:collection/></D:resourcetype></D:prop></D:sets>"); sb.append("</D:mkcol>"); // Http http = Http.request("box/mkcol-custom.txt").with("path", path).with("token", TOKEN); try { // XML不正 String code = DcCoreException.Dav.XML_ERROR.getCode(); String message = DcCoreException.Dav.XML_ERROR.getMessage(); sb = new StringBuilder(); sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); sb.append("<D:mkcol xmlns:D=\"DAV:\" xmlns:dc=\"urn:x-dc1:xmlns\">"); sb.append("<D:set<D:prop><D:resourcetype2><D:collection/></D:resourcetype2></D:prop></D:set>"); sb.append("</D:mkcol>"); Http.request("box/mkcol-custom.txt") .with("path", path) .with("token", TOKEN) .with("body", sb.toString()) .returns() .statusCode(HttpStatus.SC_BAD_REQUEST) .checkErrorResponse(code, message); // set 要素無し sb = new StringBuilder(); sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); sb.append("<D:mkcol xmlns:D=\"DAV:\" xmlns:dc=\"urn:x-dc1:xmlns\">"); sb.append("</D:mkcol>"); Http.request("box/mkcol-custom.txt") .with("path", path) .with("token", TOKEN) .with("body", sb.toString()) .returns() .statusCode(HttpStatus.SC_FORBIDDEN); // set 要素名ミス sb = new StringBuilder(); sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); sb.append("<D:mkcol xmlns:D=\"DAV:\" xmlns:dc=\"urn:x-dc1:xmlns\">"); sb.append("<D:sets><D:prop><D:resourcetype><D:collection/></D:resourcetype></D:prop></D:sets>"); sb.append("</D:mkcol>"); Http.request("box/mkcol-custom.txt") .with("path", path) .with("token", TOKEN) .with("body", sb.toString()) .returns() .statusCode(HttpStatus.SC_FORBIDDEN); // props 要素名ミス sb = new StringBuilder(); sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); sb.append("<D:mkcol xmlns:D=\"DAV:\" xmlns:dc=\"urn:x-dc1:xmlns\">"); sb.append("<D:set><D:props><D:resourcetype><D:collection/></D:resourcetype></D:props></D:set>"); sb.append("</D:mkcol>"); Http.request("box/mkcol-custom.txt") .with("path", path) .with("token", TOKEN) .with("body", sb.toString()) .returns() .statusCode(HttpStatus.SC_FORBIDDEN); // resourcetype 要素名ミス sb = new StringBuilder(); sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); sb.append("<D:mkcol xmlns:D=\"DAV:\" xmlns:dc=\"urn:x-dc1:xmlns\">"); sb.append("<D:set><D:prop><D:resourcetype2><D:collection/></D:resourcetype2></D:prop></D:set>"); sb.append("</D:mkcol>"); Http.request("box/mkcol-custom.txt") .with("path", path) .with("token", TOKEN) .with("body", sb.toString()) .returns() .statusCode(HttpStatus.SC_FORBIDDEN); // resourcetype が不正 sb = new StringBuilder(); sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); sb.append("<D:mkcol xmlns:D=\"DAV:\" xmlns:dc=\"urn:x-dc1:xmlns\">"); sb.append("<D:set><D:prop><D:resourcetype><D:collection2/></D:resourcetype></D:prop></D:set>"); sb.append("</D:mkcol>"); Http.request("box/mkcol-custom.txt") .with("path", path) .with("token", TOKEN) .with("body", sb.toString()) .returns() .statusCode(HttpStatus.SC_FORBIDDEN); } catch (Exception e) { e.printStackTrace(); } finally { // コレクションの削除 deleteTest(path, -1); } } /** * mkcolのテスト. */ @Test public final void MKCOL_Body無しのテスト() { String path = "davcol2"; try { // コレクションの作成 Http.request("box/mkcol-0.txt") .with("path", path) .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // コレクションの取得(bodyなし) TResponse tresponse = Http.request("box/propfind-col-body-0.txt") .with("path", path) .with("depth", "0") .with("token", TOKEN) .returns(); tresponse.statusCode(HttpStatus.SC_MULTI_STATUS); // コレクションの取得(bodyあり) TResponse tresponseAll = Http.request("box/propfind-col-allprop.txt") .with("path", path) .with("depth", "0") .with("token", TOKEN) .returns(); tresponseAll.statusCode(HttpStatus.SC_MULTI_STATUS); // コレクションpropfindの比較 assertEquals(tresponse.getBody(), tresponseAll.getBody()); // BodyXMLからの要素取得 String status1 = getXmlNodeValue(tresponse.bodyAsXml(), "status"); assertEquals("HTTP/1.1 200 OK", status1); // webDAVの仕様とのマッチ assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "response")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "href")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "propstat")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "prop")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "creationdate")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "getlastmodified")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "resourcetype")); } finally { // コレクションの削除 deleteTest(path, -1); // コレクションの取得(削除の確認) Http.request("box/propfind-col-allprop.txt") .with("path", path) .with("depth", "0") .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_NOT_FOUND); } } /** * mkcolのテスト. */ @Test public final void MKCOL_Body無しContentLength無しのテスト() { String path = "davcol2"; try { // コレクションの作成 Http.request("box/mkcol-0-non-content-length.txt") .with("path", path) .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // コレクションの取得(bodyなし) TResponse tresponse = Http.request("box/propfind-col-body-0.txt") .with("path", path) .with("depth", "0") .with("token", TOKEN) .returns(); tresponse.statusCode(HttpStatus.SC_MULTI_STATUS); // コレクションの取得(bodyあり) TResponse tresponseAll = Http.request("box/propfind-col-allprop.txt") .with("path", path) .with("depth", "0") .with("token", TOKEN) .returns(); tresponseAll.statusCode(HttpStatus.SC_MULTI_STATUS); // コレクションpropfindの比較 assertEquals(tresponse.getBody(), tresponseAll.getBody()); // BodyXMLからの要素取得 String status1 = getXmlNodeValue(tresponse.bodyAsXml(), "status"); assertEquals("HTTP/1.1 200 OK", status1); // webDAVの仕様とのマッチ assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "response")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "href")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "propstat")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "prop")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "creationdate")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "getlastmodified")); assertNotNull(getXmlNodeValue(tresponse.bodyAsXml(), "resourcetype")); } finally { // コレクションの削除 deleteTest(path, -1); // コレクションの取得(削除の確認) Http.request("box/propfind-col-allprop.txt") .with("path", path) .with("depth", "0") .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_NOT_FOUND); } } /** * ODataのコレクション作成テスト. */ @Test public final void ODataのコレクション作成テスト() { String path = "odatacol"; try { // コレクションの作成 Http.request("box/mkcol-odata.txt") .with("cellPath", "testcell1") .with("boxPath", "box1") .with("path", path) .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // コレクションの取得(bodyあり) TResponse tresponseAll = Http.request("box/propfind-col-allprop.txt") .with("path", path) .with("depth", "0") .with("token", TOKEN) .returns(); tresponseAll.statusCode(HttpStatus.SC_MULTI_STATUS); // dc:odata の存在チェック serviceColTypeTest(tresponseAll.bodyAsXml(), "dc:odata"); } finally { // Boxの削除 deleteTest(path, -1); } } /** * Serviceのコレクション作成テスト. */ @Test public final void Serviceのコレクション作成テスト() { String path = "servicecol"; try { // コレクションの作成 Http.request("box/mkcol-service.txt") .with("cellPath", "testcell1") .with("path", path) .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // コレクションの取得(bodyあり) TResponse tresponseAll = Http.request("box/propfind-col-allprop.txt") .with("path", path) .with("depth", "0") .with("token", TOKEN) .returns(); tresponseAll.statusCode(HttpStatus.SC_MULTI_STATUS); // dc:service の存在チェック serviceColTypeTest(tresponseAll.bodyAsXml(), "dc:service"); } finally { // コレクションの削除 deleteTest(path, -1); } } /** * Serviceのコレクション削除時に__srcの削除が行われることの確認. */ @Test public final void Serviceのコレクション削除時に__srcの削除が行われることの確認() { String path = "servicecol02"; try { // コレクションの作成 Http.request("box/mkcol-service.txt") .with("cellPath", Setup.TEST_CELL1) .with("path", path) .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // コレクションの削除 deleteTest(path, HttpStatus.SC_NO_CONTENT); // servicecol02 の存在チェック ResourceUtils.accessResource(path, TOKEN, HttpStatus.SC_NOT_FOUND, Setup.TEST_BOX1, Setup.TEST_CELL1); // __src の存在チェック ResourceUtils.accessResource(path + "/__src", TOKEN, HttpStatus.SC_NOT_FOUND, Setup.TEST_BOX1, Setup.TEST_CELL1); } finally { // Boxの削除 deleteTest(path, -1); } } /** * 階層コレクション作成テスト. 階層の内容↓ box1 ┗davcol1 ┗davcol2 ┗davcol5 ┗odatacol1 ┗davcol3 => 登録できない ┗servicecol1 ┗ davcol4 => * 登録できない */ @Test public final void 階層コレクション作成テスト() { try { // 基底Davコレクションの作成 Http.request("box/mkcol-normal.txt") .with("cellPath", "testcell1") .with("path", "davcol1") .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // コレクションの作成 Davコレクション配下にDavコレクションを作成出来る事を確認 Http.request("box/mkcol-normal.txt") .with("cellPath", "testcell1") .with("path", "davcol1/davcol2") .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // コレクションの作成 Davコレクション配下にDavコレクションを作成出来る事を確認 Http.request("box/mkcol-normal.txt") .with("cellPath", "testcell1") .with("path", "davcol1/davcol2/davcol5") .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // コレクションの作成 Davコレクション配下にODataコレクションを作成出来る事を確認 Http.request("box/mkcol-odata.txt") .with("cellPath", "testcell1") .with("boxPath", "box1") .with("path", "davcol1/odatacol1") .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // コレクションの作成 Davコレクション配下にServiceコレクションを作成出来る事を確認 Http.request("box/mkcol-service.txt") .with("cellPath", "testcell1") .with("path", "davcol1/servicecol1") .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // コレクションの作成 ODataコレクション配下にコレクションを作成出来ない事を確認 // TODO レスポンスコードが404で正しいかどうかは、将来再検討 Http.request("box/mkcol-normal.txt") .with("cellPath", "testcell1") .with("path", "davcol1/odatacol1/davcol3") .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_NOT_FOUND); // コレクションの作成 Serviceコレクション配下にコレクションを作成出来ない事を確認 // TODO レスポンスコードが404で正しいかどうかは、将来再検討 Http.request("box/mkcol-normal.txt") .with("cellPath", "testcell1") .with("path", "davcol1/servicecol1/davcol4") .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_METHOD_NOT_ALLOWED); // コレクションの取得(depth1のテスト) TResponse tresponseWebDav = Http.request("box/propfind-col-allprop.txt") .with("path", "davcol1") .with("depth", "1") .with("token", TOKEN) .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); // davcol1配下のXML構成確認テスト String testcell = "testcell1"; String boxName = "box1"; String baseCell = "davcol1"; Element root = tresponseWebDav.bodyAsXml().getDocumentElement(); NodeList resourcetypeList = root.getElementsByTagName("response"); // responseの要素数が4 assertEquals(4, resourcetypeList.getLength()); // 各要素のhref・statusの確認 depthTest(resourcetypeList, UrlUtils.box(testcell, boxName, baseCell), "HTTP/1.1 200 OK"); depthTest(resourcetypeList, UrlUtils.box(testcell, boxName, baseCell, "servicecol1"), "HTTP/1.1 200 OK"); depthTest(resourcetypeList, UrlUtils.box(testcell, boxName, baseCell, "odatacol1"), "HTTP/1.1 200 OK"); depthTest(resourcetypeList, UrlUtils.box(testcell, boxName, baseCell, "davcol2"), "HTTP/1.1 200 OK"); // davcol5が取得出来ていない事を確認 assertEquals(-1, tresponseWebDav.getBody().indexOf(UrlUtils.box(testcell, boxName, baseCell, "davcol2", "davcol5"))); } finally { // Boxの削除 deleteTest("davcol1/servicecol1", -1); deleteTest("davcol1/odatacol1", -1); deleteTest("davcol1/davcol2/davcol5", -1); deleteTest("davcol1/davcol2", -1); deleteTest("davcol1", -1); } } /** * DavCol削除時の子供データチェックテスト. 階層の内容↓ box1 ┗davcol1 ┗davcol2 ┗davFile.txt */ @Test public final void DavCol削除時の子供データチェックテスト() { String davCol1 = "davcol1"; String davCol2 = "davcol2"; String davFileName = "davFile.txt"; try { // 基底Davコレクションの作成 DavResourceUtils.createWebDavCollection(TOKEN, HttpStatus.SC_CREATED, davCol1); // コレクションの作成 Davコレクション配下にDavコレクションを作成出来る事を確認 DavResourceUtils.createWebDavCollection(TOKEN, HttpStatus.SC_CREATED, davCol1 + "/" + davCol2); // Davファイルの作成 DavResourceUtils.createWebDavFile(Setup.TEST_CELL1, TOKEN, "box/dav-put.txt", "hoge", Setup.TEST_BOX1, davCol1 + "/" + davCol2 + "/" + davFileName, HttpStatus.SC_CREATED); // コレクションの削除→子供(DavFile)があるため削除出来ない deleteTest(davCol1 + "/" + davCol2, HttpStatus.SC_CONFLICT); // コレクションの削除→子供(davcol2)があるため削除出来ない deleteTest(davCol1, HttpStatus.SC_CONFLICT); // Davファイルの削除 DavResourceUtils.deleteWebDavFile("box/dav-delete.txt", Setup.TEST_CELL1, TOKEN, davCol1 + "/" + davCol2 + "/" + davFileName, HttpStatus.SC_NO_CONTENT, Setup.TEST_BOX1); // コレクションの削除→子供(DavFile)が無くなったため削除出来る deleteTest(davCol1 + "/" + davCol2, HttpStatus.SC_NO_CONTENT); // コレクションの削除→子供(davcol2)が無いため削除出来る deleteTest(davCol1, HttpStatus.SC_NO_CONTENT); } finally { // コレクションの削除 DavResourceUtils.deleteWebDavFile("box/dav-delete.txt", Setup.TEST_CELL1, TOKEN, davCol1 + "/" + davCol2 + "/" + davFileName, -1, Setup.TEST_BOX1); deleteTest(davCol1 + "/" + davCol2, -1); deleteTest(davCol1, -1); } } /** * Box削除時の子供Collectionチェックテスト. 階層の内容↓ deleteBox ┗davcol1 */ @Test public final void Box削除時の子供Collectionチェックテスト() { String boxName = "deleteBox"; String davCol1 = "davcol1"; try { // 基底Boxの作成 BoxUtils.create(Setup.TEST_CELL1, boxName, TOKEN, HttpStatus.SC_CREATED); // コレクションの作成 DavResourceUtils.createWebDavCollection("box/mkcol.txt", Setup.TEST_CELL1, boxName + "/" + davCol1, TOKEN, HttpStatus.SC_CREATED); // Boxの削除→子供(davcol1)があるため削除出来ない BoxUtils.delete(Setup.TEST_CELL1, TOKEN, boxName, HttpStatus.SC_CONFLICT); // コレクションの削除 DavResourceUtils.deleteCollection(Setup.TEST_CELL1, boxName, davCol1, TOKEN, HttpStatus.SC_NO_CONTENT); // コレクションの削除→子供(davcol1)が無いため削除出来る BoxUtils.delete(Setup.TEST_CELL1, TOKEN, boxName, HttpStatus.SC_NO_CONTENT); } finally { // コレクションの削除 DavResourceUtils.deleteCollection(Setup.TEST_CELL1, boxName, davCol1, TOKEN, -1); BoxUtils.delete(Setup.TEST_CELL1, TOKEN, boxName, -1); } } /** * Box削除時の子供WebDavFileチェックテスト. 階層の内容↓ deleteBox deleteFile */ @Test public final void Box削除時の子供WebDavFileチェックテスト() { String boxName = "deleteBox"; String davFileNmae = "deleteFile"; try { // 基底Boxの作成 BoxUtils.create(Setup.TEST_CELL1, boxName, TOKEN, HttpStatus.SC_CREATED); // Box直下にWebDavファイルを作成 DavResourceUtils.createWebDavFile(Setup.TEST_CELL1, TOKEN, "box/dav-put.txt", "hoge", boxName, davFileNmae, HttpStatus.SC_CREATED); // Boxの削除→子供(deleteFile)があるため削除出来ない BoxUtils.delete(Setup.TEST_CELL1, TOKEN, boxName, HttpStatus.SC_CONFLICT); // WebDavファイルの削除 DavResourceUtils.deleteWebDavFile(Setup.TEST_CELL1, TOKEN, boxName, davFileNmae); // Boxの削除→子供(deleteFile)が無いため削除出来る BoxUtils.delete(Setup.TEST_CELL1, TOKEN, boxName, HttpStatus.SC_NO_CONTENT); } finally { // WebDavファイルの削除 DavResourceUtils.deleteWebDavFile(Setup.TEST_CELL1, TOKEN, boxName, davFileNmae); // Boxの削除 BoxUtils.delete(Setup.TEST_CELL1, TOKEN, boxName, -1); } } /** * Odata削除時の子供データチェックテスト. 階層の内容↓ deleteOdata ┗deleteEntType */ @Test public final void Odata削除時の子供データチェックテスト() { String odataName = "deleteOdata"; String entityType = "deleteEntType"; String accept = "application/xml"; try { // Odataコレクションの作成 DavResourceUtils.createODataCollection(TOKEN, HttpStatus.SC_CREATED, Setup.TEST_CELL1, Setup.TEST_BOX1, odataName); // EntityTypeの作成 Http.request("box/entitySet-post.txt") .with("cellPath", Setup.TEST_CELL1) .with("boxPath", Setup.TEST_BOX1) .with("odataSvcPath", odataName) .with("token", "Bearer " + TOKEN) .with("accept", accept) .with("Name", entityType) .returns() .statusCode(HttpStatus.SC_CREATED); // Odataの削除→子供(deleteEntType)があるため削除出来ない TResponse response = deleteTest(odataName, HttpStatus.SC_FORBIDDEN); String code = DcCoreException.Dav.HAS_CHILDREN.getCode(); String message = DcCoreException.Dav.HAS_CHILDREN.getMessage(); response.checkErrorResponse(code, message); // EntityTypeの削除 entityTypeDelete(odataName, TOKEN, accept, entityType, Setup.TEST_CELL1, HttpStatus.SC_NO_CONTENT); // Odataの削除→子供(deleteEntType)が無いため削除出来る deleteTest(odataName, HttpStatus.SC_NO_CONTENT); } finally { // EntityTypeの削除 entityTypeDelete(odataName, TOKEN, accept, entityType, Setup.TEST_CELL1, -1); // Odataの削除 deleteTest(odataName, -1); } } /** * Odata削除時の子供データチェックテスト. 階層の内容↓ deleteOdata deleteComplexType deleteComplexTypeProperty */ @Test public final void Odata削除時のComplex子供データチェックテスト() { String odataName = "deleteOdata"; String complexTypeName = "deleteComplexType"; String complexTypePropertyName = "deleteComplexTypeProperty"; try { // Odataコレクションの作成 DavResourceUtils.createODataCollection(TOKEN, HttpStatus.SC_CREATED, Setup.TEST_CELL1, Setup.TEST_BOX1, odataName); // ComplexTypeの作成 ComplexTypeUtils.create(Setup.TEST_CELL1, Setup.TEST_BOX1, odataName, complexTypeName, HttpStatus.SC_CREATED); // Odataの削除→子供(ComplexType)があるため削除出来ない TResponse response = deleteTest(odataName, HttpStatus.SC_FORBIDDEN); String code = DcCoreException.Dav.HAS_CHILDREN.getCode(); String message = DcCoreException.Dav.HAS_CHILDREN.getMessage(); response.checkErrorResponse(code, message); // ComplexTypePropertyの作成 ComplexTypePropertyUtils.create(Setup.TEST_CELL1, Setup.TEST_BOX1, odataName, complexTypePropertyName, complexTypeName, "Edm.String", HttpStatus.SC_CREATED); // Odataの削除→子供(ComplexType + ComplexTypeProeprty)があるため削除出来ない response = deleteTest(odataName, HttpStatus.SC_FORBIDDEN); code = DcCoreException.Dav.HAS_CHILDREN.getCode(); message = DcCoreException.Dav.HAS_CHILDREN.getMessage(); response.checkErrorResponse(code, message); // ComplexTypePropertyの削除 ComplexTypePropertyUtils.delete(Setup.TEST_CELL1, Setup.TEST_BOX1, odataName, complexTypePropertyName, complexTypeName, HttpStatus.SC_NO_CONTENT); // ComplexTypeの削除 ComplexTypeUtils.delete(AbstractCase.MASTER_TOKEN_NAME, Setup.TEST_CELL1, Setup.TEST_BOX1, odataName, complexTypeName, HttpStatus.SC_NO_CONTENT); // Odataの削除→子供(ComplexType + ComplexTypeProeprty)が無いため削除出来る deleteTest(odataName, HttpStatus.SC_NO_CONTENT); } finally { // ComplexTypePropertyの削除 ComplexTypePropertyUtils.delete(Setup.TEST_CELL1, Setup.TEST_BOX1, odataName, complexTypePropertyName, complexTypeName, -1); // ComplexTypeの削除 ComplexTypeUtils.delete(AbstractCase.MASTER_TOKEN_NAME, Setup.TEST_CELL1, Setup.TEST_BOX1, odataName, complexTypeName, -1); // Odataの削除 deleteTest(odataName, -1); } } /** * Serviceコレクション削除時の子供データチェックテスト. 階層の内容↓ deleteService ┗__src ┗davFile.txt */ @Test public final void Serviceコレクション削除時の子供データチェックテスト() { String sriveceName = "deleteService"; String src = "__src"; String davFileName = "davFile.js"; try { // serviceコレクションの作成 DavResourceUtils.createServiceCollection(TOKEN, HttpStatus.SC_CREATED, sriveceName); // ファイルの作成 DavResourceUtils.createWebDavFile(Setup.TEST_CELL1, TOKEN, "box/dav-put.txt", "hoge", Setup.TEST_BOX1, sriveceName + "/" + src + "/" + davFileName, HttpStatus.SC_CREATED); // serviceコレクションの削除→子供(__src/davFile.js)があるため削除出来ない TResponse response = deleteTest(sriveceName, HttpStatus.SC_FORBIDDEN); String code = DcCoreException.Dav.HAS_CHILDREN.getCode(); String message = DcCoreException.Dav.HAS_CHILDREN.getMessage(); response.checkErrorResponse(code, message); // ファイルの削除 DavResourceUtils.deleteWebDavFile("box/dav-delete.txt", Setup.TEST_CELL1, TOKEN, sriveceName + "/" + src + "/" + davFileName, HttpStatus.SC_NO_CONTENT, Setup.TEST_BOX1); // serviceの削除→子供(__src/davFile.js)が無いため削除出来る deleteTest(sriveceName, HttpStatus.SC_NO_CONTENT); } finally { // ファイルの削除 DavResourceUtils.deleteWebDavFile("box/dav-delete.txt", Setup.TEST_CELL1, TOKEN, sriveceName + "/" + src + "/" + davFileName, -1, Setup.TEST_BOX1); // serviceコレクションの削除 deleteTest(sriveceName, -1); } } /** * DELETEの実行. * @return DELETEの実行結果 */ private TResponse deleteTest(final String path, int code) { // コレクションの削除 return Http.request("box/delete-col.txt") .with("cellPath", "testcell1") .with("path", path) .with("token", TOKEN) .returns() .statusCode(code); } /** * resourcetypeのタグ内テスト. テスト内容 ・resourcetypeタグの要素数=1 ・resourcetypeタグ内のタグ数=1 ・collectionタグ・serviceTypeタグの存在チェック */ private void serviceColTypeTest(final Document doc, final String serviceType) { Element root = doc.getDocumentElement(); NodeList resourcetypeList = root.getElementsByTagName("resourcetype"); assertEquals(1, resourcetypeList.getLength()); Element resourcetype = (Element) resourcetypeList.item(0); NodeList children = resourcetype.getChildNodes(); String dc = null; String collection = null; int elementCounut = 0; for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (child instanceof Element) { elementCounut++; Element childElement = (Element) child; if (childElement.getTagName().equals(serviceType)) { dc = childElement.getTagName(); } else if (childElement.getTagName().equals("collection")) { collection = childElement.getTagName(); } } } assertEquals(2, elementCounut); assertNotNull(dc); assertNotNull(collection); } /** * depth:1でのPROPFINDのレスポンスbodyテスト. */ private void depthTest(final NodeList nodeList, final String resorce, final String statusLine) { String statusResult = ""; Element resourcetype = null; for (int c = 0; c < nodeList.getLength(); c++) { resourcetype = (Element) nodeList.item(c); NodeList hrefchildren = resourcetype.getElementsByTagName("href"); assertNotNull(hrefchildren); assertEquals(1, hrefchildren.getLength()); String hrefResult = (hrefchildren.item(0)).getFirstChild().getNodeValue(); if (hrefResult.equals(resorce)) { NodeList statuschild = resourcetype.getElementsByTagName("status"); assertNotNull(statuschild); assertEquals(1, statuschild.getLength()); statusResult = (statuschild.item(0)).getFirstChild().getNodeValue(); break; } } assertEquals(statusResult, statusLine); } /** * Depthの異常値テスト. */ @Test public final void Depthの異常値のテスト() { String path = "depthcol"; try { // コレクションの作成 Http.request("box/mkcol-normal.txt") .with("cellPath", "testcell1") .with("path", path) .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // コレクションの取得(depth:infinity) Http.request("box/propfind-col-allprop.txt") .with("path", path) .with("depth", "infinity") .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_FORBIDDEN); // コレクションの取得(depth:error) Http.request("box/propfind-col-allprop.txt") .with("path", path) .with("depth", "error") .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_BAD_REQUEST); // コレクションの取得(depth:null) Http.request("box/propfind-col-allprop-depth-null.txt") .with("path", path) .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_BAD_REQUEST); } finally { deleteTest(path, -1); } } /** * PROPPATCHのテスト. プロパティ設定=>更新=>削除 */ @Test public final void PROPPATCHのテスト() { String path = "patchcol"; String testcell = "testcell1"; String boxName = "box1"; try { TResponse tresponseWebDav = null; // DAVコレクションの作成 tresponseWebDav = Http.request("box/mkcol-normal.txt") .with("cellPath", "testcell1") .with("path", path) .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); String etag1 = tresponseWebDav.getHeader(HttpHeaders.ETAG); assertNotNull(etag1); // PROPPATCH設定実行 tresponseWebDav = Http.request("box/proppatch-set.txt").with("cell", testcell).with("box", boxName) .with("path", path).with("token", TOKEN) .with("author1", "Test User1") .with("hoge", "hoge") .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); String etag2 = tresponseWebDav.getHeader(HttpHeaders.ETAG); assertNotNull(etag2); assertFalse(etag1.equals(etag2)); // プロパティ変更の確認 tresponseWebDav = Http.request("box/propfind-col-allprop.txt").with("path", path).with("token", TOKEN) .with("depth", "0") .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); Element root = tresponseWebDav.bodyAsXml().getDocumentElement(); String resorce = UrlUtils.box(testcell, boxName, path); HashMap<String, String> map = new HashMap<String, String>(); // TODO 名前空間のテストを実施する。 map.put("Author", "Test User1"); map.put("hoge", "hoge"); proppatchResponseTest(root, resorce, map); // プロパティの変更 tresponseWebDav = Http.request("box/proppatch-set.txt").with("cell", testcell).with("box", boxName) .with("path", path).with("token", TOKEN) .with("author1", "Author1 update") .with("hoge", "fuga") .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); // プロパティの変更確認 tresponseWebDav = Http.request("box/propfind-col-allprop.txt").with("path", path).with("token", TOKEN) .with("depth", "0") .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); Element root2 = tresponseWebDav.bodyAsXml().getDocumentElement(); HashMap<String, String> map2 = new HashMap<String, String>(); map.put("Author", "Author1 update"); map.put("hoge", "fuga"); proppatchResponseTest(root2, resorce, map2); // プロパティの削除 tresponseWebDav = Http.request("box/proppatch-remove.txt").with("path", path).with("token", TOKEN) .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); // プロパティの削除確認 tresponseWebDav = Http.request("box/propfind-col-allprop.txt").with("path", path).with("token", TOKEN) .with("depth", "0") .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); Element root3 = tresponseWebDav.bodyAsXml().getDocumentElement(); HashMap<String, String> map3 = new HashMap<String, String>(); map.put("Author", null); map.put("hoge", null); proppatchResponseTest(root3, resorce, map3); // set、remove同時実行の実験 // TODO SETとREMOVEが同時に行われるレスポンスはsetとremoveの内容が同じPROPSTATで返ってきているがわけるべき // TODO SETのレスポンス内のプロパティに設定値が入っているのはまずそう。 <key>value</key> => <key/> tresponseWebDav = Http.request("box/proppatch.txt").with("cell", Setup.TEST_CELL1) .with("box", Setup.TEST_BOX1).with("path", path).with("token", "Bearer " + TOKEN) .with("author1", "Author1 update").with("hoge", "fuga") .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); tresponseWebDav = Http.request("box/propfind-col-allprop.txt").with("path", path).with("token", TOKEN) .with("depth", "0") .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); } finally { deleteTest(path, -1); } } /** * PROPPATCH階層設定のテスト. プロパティ設定=>更新=>削除 */ @Test public final void PROPPATCH階層設定のテスト() { String path = "patchclasscol"; String testcell = "testcell1"; String boxName = "box1"; try { TResponse tresponseWebDav = null; // DAVコレクションの作成 Http.request("box/mkcol-normal.txt") .with("cellPath", "testcell1") .with("path", path) .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // PROPPATCH設定実行 tresponseWebDav = Http.request("box/proppatch-class.txt").with("path", path).with("token", TOKEN) .with("cellPath", "testcell1") .with("name1", "Test User1") .with("src1", "hoge") .with("name2", "Test User2") .with("src2", "fuga") .with("name3", "Test User3") .with("src3", "boy") .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); // プロパティ変更の確認 tresponseWebDav = Http.request("box/propfind-col-allprop.txt").with("path", path).with("token", TOKEN) .with("depth", "0") .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); Element root = tresponseWebDav.bodyAsXml().getDocumentElement(); String resorce = UrlUtils.box(testcell, boxName, path); ArrayList<String> list = new ArrayList<String>(); // TODO 名前空間のテストを実施する。 list.add("name"); list.add("Test User1"); list.add("src"); list.add("hoge"); list.add("name"); list.add("Test User2"); list.add("src"); list.add("fuga"); list.add("name"); list.add("Test User3"); list.add("src"); list.add("boy"); proppatchClassResponseTest(root, resorce, "service", list); // プロパティの変更 tresponseWebDav = Http.request("box/proppatch-class.txt").with("path", path).with("token", TOKEN) .with("cellPath", "testcell1") .with("name1", "Test User13") .with("src1", "hoge3") .with("name2", "Test User23") .with("src2", "3fuga") .with("name3", "3Test User3") .with("src3", "3boy") .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); // プロパティの変更確認 tresponseWebDav = Http.request("box/propfind-col-allprop.txt").with("path", path).with("token", TOKEN) .with("depth", "0") .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); Element root2 = tresponseWebDav.bodyAsXml().getDocumentElement(); ArrayList<String> list2 = new ArrayList<String>(); list2.add("name"); list2.add("Test User13"); list2.add("src"); list2.add("hoge3"); list2.add("name"); list2.add("Test User23"); list2.add("src"); list2.add("3fuga"); list2.add("name"); list2.add("3Test User3"); list2.add("src"); list2.add("3boy"); proppatchClassResponseTest(root2, resorce, "service", list2); // プロパティの削除 tresponseWebDav = Http.request("box/proppatch-remove.txt").with("path", path).with("token", TOKEN) .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); } finally { deleteTest(path, -1); } } /** * WebDAV_ACLのテスト. */ @Test public final void WebDAV_ACLのテスト() { String path = "aclcol1"; String testcell = "testcell1"; String boxName = "box1"; try { // コレクションの作成 Http.request("box/mkcol-normal.txt") .with("cellPath", "testcell1") .with("path", path) .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // ACLの設定 Http.request("box/acl.txt") .with("colname", path) .with("token", TOKEN) .with("roleBaseUrl", UrlUtils.roleResource(testcell, null, "")) .with("level", "") .returns() .statusCode(HttpStatus.SC_OK); // ACLの確認 TResponse tresponseWebDav = Http.request("box/propfind-col-allprop.txt") .with("path", path) .with("depth", "1") .with("token", TOKEN) .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); // PROPFOINDレスポンスボディの確認 String resorce = UrlUtils.box(testcell, boxName, path); Element root2 = tresponseWebDav.bodyAsXml().getDocumentElement(); List<Map<String, List<String>>> list = new ArrayList<Map<String, List<String>>>(); Map<String, List<String>> map = new HashMap<String, List<String>>(); List<String> rolList = new ArrayList<String>(); rolList.add("read"); rolList.add("write"); map.put(UrlUtils.aclRelativePath(Box.DEFAULT_BOX_NAME, "role1"), rolList); list.add(map); List<String> rolList2 = new ArrayList<String>(); Map<String, List<String>> map2 = new HashMap<String, List<String>>(); rolList2.add("read"); map2.put(UrlUtils.aclRelativePath(Box.DEFAULT_BOX_NAME, "role2"), rolList2); list.add(map2); TestMethodUtils.aclResponseTest(root2, resorce, list, 1, UrlUtils.roleResource(testcell, boxName, ""), null); } finally { deleteTest(path, -1); } } /** * WebDAV_ACLのPricipalフルパスのテスト. */ @Test public final void WebDAV_ACLのPricipalフルパスのテスト() { String path = "aclcol1"; String testcell = "testcell1"; String boxName = "box1"; try { // コレクションの作成 DavResourceUtils.createWebDavCollection("box/mkcol-normal.txt", testcell, path, TOKEN, HttpStatus.SC_CREATED); // ACLの設定 DavResourceUtils.setACLwithRoleBaseUrl(testcell, TOKEN, HttpStatus.SC_OK, boxName, path, "box/acl-setting-baseurl.txt", UrlUtils.roleResource(testcell, null, "role1"), "<D:read/>", ""); // ACLの確認 TResponse tresponseWebDav = DavResourceUtils.propfind("box/propfind-col-allprop.txt", TOKEN, HttpStatus.SC_MULTI_STATUS, path); // PROPFOINDレスポンスボディの確認 String resorce = UrlUtils.box(testcell, boxName, path); Element root2 = tresponseWebDav.bodyAsXml().getDocumentElement(); List<Map<String, List<String>>> list = new ArrayList<Map<String, List<String>>>(); Map<String, List<String>> map = new HashMap<String, List<String>>(); List<String> rolList = new ArrayList<String>(); rolList.add("read"); map.put(UrlUtils.aclRelativePath(Box.DEFAULT_BOX_NAME, "role1"), rolList); list.add(map); TestMethodUtils.aclResponseTest(root2, resorce, list, 1, UrlUtils.roleResource(testcell, boxName, ""), null); } finally { deleteTest(path, -1); } } /** * Service_ACLのテスト. */ @Test public final void Service_ACLのテスト() { String path = "aclcol1"; String testcell = "testcell1"; String boxName = "box1"; try { // コレクションの作成 Http.request("box/mkcol-service.txt") .with("cellPath", "testcell1") .with("path", path) .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // ACLの設定 Http.request("box/acl-service.txt") .with("colname", path) .with("token", TOKEN) .with("roleBaseUrl", UrlUtils.roleResource(testcell, null, "")) .with("level", "") .returns() .statusCode(HttpStatus.SC_OK); // ACLの確認 TResponse tresponseWebDav = Http.request("box/propfind-col-allprop.txt") .with("path", path) .with("depth", "1") .with("token", TOKEN) .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); // PROPFOINDレスポンスボディの確認 String resorce = UrlUtils.box(testcell, boxName, path); Element root2 = tresponseWebDav.bodyAsXml().getDocumentElement(); List<Map<String, List<String>>> list = new ArrayList<Map<String, List<String>>>(); Map<String, List<String>> map = new HashMap<String, List<String>>(); List<String> rolList = new ArrayList<String>(); rolList.add("exec"); map.put(UrlUtils.aclRelativePath(Box.DEFAULT_BOX_NAME, "role1"), rolList); list.add(map); TestMethodUtils.aclResponseTest(root2, resorce, list, 2, UrlUtils.roleResource(testcell, boxName, ""), null); } finally { deleteTest(path, -1); } } /** * OData_ACLのテスト. */ @Test public final void OData_ACLのテスト() { String path = "aclcol1"; String testcell = "testcell1"; String boxName = "box1"; try { // コレクションの作成 Http.request("box/mkcol-odata.txt") .with("cellPath", "testcell1") .with("boxPath", "box1") .with("path", path) .with("token", TOKEN) .returns() .statusCode(HttpStatus.SC_CREATED); // ACLの設定 Http.request("box/acl.txt") .with("colname", path) .with("token", TOKEN) .with("roleBaseUrl", UrlUtils.roleResource(testcell, null, "")) .with("level", "") .returns() .statusCode(HttpStatus.SC_OK); // ACLの確認 TResponse tresponseWebDav = Http.request("box/propfind-col-allprop.txt") .with("path", path) .with("depth", "1") .with("token", TOKEN) .returns(); tresponseWebDav.statusCode(HttpStatus.SC_MULTI_STATUS); // PROPFOINDレスポンスボディの確認 String resorce = UrlUtils.box(testcell, boxName, path); Element root2 = tresponseWebDav.bodyAsXml().getDocumentElement(); List<Map<String, List<String>>> list = new ArrayList<Map<String, List<String>>>(); Map<String, List<String>> map = new HashMap<String, List<String>>(); List<String> rolList = new ArrayList<String>(); rolList.add("read"); rolList.add("write"); map.put(UrlUtils.aclRelativePath(Box.DEFAULT_BOX_NAME, "role1"), rolList); list.add(map); List<String> rolList2 = new ArrayList<String>(); Map<String, List<String>> map2 = new HashMap<String, List<String>>(); rolList2.add("read"); map2.put(UrlUtils.aclRelativePath(Box.DEFAULT_BOX_NAME, "role2"), rolList2); list.add(map2); TestMethodUtils.aclResponseTest(root2, resorce, list, 1, UrlUtils.roleResource(testcell, boxName, ""), null); } finally { deleteTest(path, -1); } } /** * ROLEが存在しない場合でのACLのテスト. */ @Test public final void ROLEが存在しない場合でのACLのテスト() { String path = "setodata"; String testcell = "testcell1"; // ACLの設定 Http.request("box/acl-role-not-found.txt") .with("colname", path) .with("token", TOKEN) .with("roleBaseUrl", UrlUtils.roleResource(testcell, null, "")) .with("level", "") .returns() .statusCode(HttpStatus.SC_BAD_REQUEST); } /** * xml:baseに存在しないCellを指定した場合でのACLのテスト. */ @Test public final void xml_baseに存在しないCellを指定した場合でのACLのテスト() { // ACLの設定 Http.request("box/acl-setting-single-collection.txt") .with("cell", Setup.TEST_CELL1) .with("box", Setup.TEST_BOX1) .with("col", Setup.TEST_ODATA) .with("token", AbstractCase.MASTER_TOKEN_NAME) .with("roleBaseUrl", UrlUtils.roleResource("notExistsCell", null, "role1")) .returns() .statusCode(HttpStatus.SC_BAD_REQUEST); } /** * xml_baseに存在しないBoxを指定した場合でのACLのテスト. */ @Test public final void xml_baseに存在しないBoxを指定した場合でのACLのテスト() { // ACLの設定 Http.request("box/acl-setting-single-collection.txt") .with("cell", Setup.TEST_CELL1) .with("box", Setup.TEST_BOX1) .with("col", Setup.TEST_ODATA) .with("token", AbstractCase.MASTER_TOKEN_NAME) .with("roleBaseUrl", UrlUtils.roleResource(Setup.TEST_CELL1, "notExistsBox", "role1")) .with("level", "") .returns() .statusCode(HttpStatus.SC_BAD_REQUEST); } /** * xml_baseに存在しないCollectionを指定した場合でのACLのテスト. */ @Test public final void xml_baseに存在しないCollectionを指定した場合でのACLのテスト() { // ACLの設定 Http.request("box/acl-setting-href-with-baseurl.txt") .with("cell", Setup.TEST_CELL1) .with("box", Setup.TEST_BOX1) .with("col", Setup.TEST_ODATA) .with("role", "notExistsCol/../__/role1") .with("token", AbstractCase.MASTER_TOKEN_NAME) .with("roleBaseUrl", UrlUtils.roleResource(Setup.TEST_CELL1, null, "")) .with("level", "") .returns() .statusCode(HttpStatus.SC_BAD_REQUEST); } /** * Roleに紐付いていないBox名を指定した場合でのACLのテスト. */ @Test public final void Roleに紐付いていないBox名を指定した場合でのACLのテスト() { String testBox = "testBox01"; String testRole = "testRole01"; try { // Boxの作成 BoxUtils.create(Setup.TEST_CELL1, testBox, TOKEN); // Boxに紐付かないRoleの作成 RoleUtils.create(Setup.TEST_CELL1, TOKEN, null, testRole, HttpStatus.SC_CREATED); // ACLの設定 Http.request("box/acl-setting-single-collection.txt") .with("cell", Setup.TEST_CELL1) .with("box", Setup.TEST_BOX1) .with("col", Setup.TEST_ODATA) .with("token", AbstractCase.MASTER_TOKEN_NAME) .with("roleBaseUrl", UrlUtils.roleResource(Setup.TEST_CELL1, testBox, testRole)) .with("level", "") .returns() .statusCode(HttpStatus.SC_BAD_REQUEST); } finally { // Roleの削除 RoleUtils.delete(Setup.TEST_CELL1, TOKEN, null, testRole); // Box1の削除 BoxUtils.delete(Setup.TEST_CELL1, TOKEN, testBox); } } /** * BOX_ACLのテスト. */ @Test public final void Box_ACLのテスト() { String path = "box1"; String testcell = "testcell1"; try { // ACLの設定 Http.request("box/acl.txt") .with("colname", "") .with("token", TOKEN) .with("roleBaseUrl", UrlUtils.roleResource(testcell, null, "")) .with("level", "") .returns() .statusCode(HttpStatus.SC_OK); // ACLの確認 TResponse tresponseWebDav = CellUtils.propfind(testcell + "/" + path, TOKEN, "0", HttpStatus.SC_MULTI_STATUS); // PROPFOINDレスポンスボディの確認 String resorce = UrlUtils.boxRoot(testcell, path); Element root2 = tresponseWebDav.bodyAsXml().getDocumentElement(); List<Map<String, List<String>>> list = new ArrayList<Map<String, List<String>>>(); Map<String, List<String>> map = new HashMap<String, List<String>>(); List<String> rolList = new ArrayList<String>(); rolList.add("read"); rolList.add("write"); map.put(UrlUtils.aclRelativePath(Box.DEFAULT_BOX_NAME, "role1"), rolList); list.add(map); List<String> rolList2 = new ArrayList<String>(); Map<String, List<String>> map2 = new HashMap<String, List<String>>(); rolList2.add("read"); map2.put(UrlUtils.aclRelativePath(Box.DEFAULT_BOX_NAME, "role2"), rolList2); list.add(map2); TestMethodUtils.aclResponseTest(root2, resorce, list, 1, UrlUtils.roleResource(testcell, path, ""), null); } finally { // ACLの設定を下に戻す DavResourceUtils.setACL(testcell, AbstractCase.MASTER_TOKEN_NAME, HttpStatus.SC_OK, "", ACL_AUTH_TEST_SETTING_FILE, Setup.TEST_BOX1, ""); } } /** * BOX_ACL異常系_大文字やハイフンを含むRole名をACL登録できることの確認. */ @Test public final void BOX_ACL異常系_大文字やハイフンを含むRole名をACL登録できることの確認() { String path = "box1"; String testcell = "testcell1"; String token = AbstractCase.MASTER_TOKEN_NAME; String[] roles = {"RoleName", "role-name" }; try { for (String role : roles) { try { // 前準備 // 名前に大文字を含むロール登録 RoleUtils.create(testcell, token, path, role, HttpStatus.SC_CREATED); // ACLの設定 DavResourceUtils.setACLwithBox(testcell, token, HttpStatus.SC_OK, path, "", "box/acl-setting.txt", role, path, "<D:write/>", ""); // ACLの確認 TResponse tresponseWebDav = CellUtils.propfind(testcell + "/" + path, TOKEN, "0", HttpStatus.SC_MULTI_STATUS); // PROPFOINDレスポンスボディの確認 String resorce = UrlUtils.boxRoot(testcell, path); Element root = tresponseWebDav.bodyAsXml().getDocumentElement(); List<Map<String, List<String>>> list = new ArrayList<Map<String, List<String>>>(); Map<String, List<String>> map = new HashMap<String, List<String>>(); List<String> rolList = new ArrayList<String>(); rolList.add("write"); map.put(role, rolList); list.add(map); TestMethodUtils.aclResponseTest(root, resorce, list, 1, UrlUtils.roleResource(testcell, path, ""), null); } finally { // Role削除 RoleUtils.delete(testcell, token, path, role); } } } finally { // ACL設定を元に戻す DavResourceUtils.setACL(testcell, AbstractCase.MASTER_TOKEN_NAME, HttpStatus.SC_OK, "", ACL_AUTH_TEST_SETTING_FILE, Setup.TEST_BOX1, ""); } } /** * PropFindとPropPatchの権限テスト. */ @Test public final void PropFindとPropPatchの権限テスト() { final String accountRead = "accountRead"; final String accountReadAcl = "accountReadAcl"; final String testCol = "testCol"; try { // Accountを作成する AccountUtils.create(AbstractCase.MASTER_TOKEN_NAME, Setup.TEST_CELL1, accountRead, accountRead, HttpStatus.SC_CREATED); AccountUtils.create(AbstractCase.MASTER_TOKEN_NAME, Setup.TEST_CELL1, accountReadAcl, accountReadAcl, HttpStatus.SC_CREATED); // ロール追加(Read) RoleUtils.create(Setup.TEST_CELL1, AbstractCase.MASTER_TOKEN_NAME, null, "roleRead", HttpStatus.SC_CREATED); // ロール追加(Read-Acl) RoleUtils.create(Setup.TEST_CELL1, AbstractCase.MASTER_TOKEN_NAME, null, "roleReadAcl", HttpStatus.SC_CREATED); // ロール結びつけ(BOXに結びつかないロールとアカウント結びつけ) ResourceUtils.linkAccountRole(Setup.TEST_CELL1, AbstractCase.MASTER_TOKEN_NAME, accountRead, null, "roleRead", HttpStatus.SC_NO_CONTENT); // ロール結びつけ(BOXに結びつかないロールとアカウント結びつけ) ResourceUtils.linkAccountRole(Setup.TEST_CELL1, AbstractCase.MASTER_TOKEN_NAME, accountReadAcl, null, "roleReadAcl", HttpStatus.SC_NO_CONTENT); // コレクション作成 DavResourceUtils.createODataCollection(AbstractCase.MASTER_TOKEN_NAME, HttpStatus.SC_CREATED, Setup.TEST_CELL1, Setup.TEST_BOX1, testCol); // ACL設定 DavResourceUtils.setACL(Setup.TEST_CELL1, AbstractCase.MASTER_TOKEN_NAME, HttpStatus.SC_OK, testCol, ACL_AUTH_PROPPATCH_TEST_SETTING_FILE, Setup.TEST_BOX1, ""); // 読み込みのみ String readToken = ResourceUtils.getMyCellLocalToken(Setup.TEST_CELL1, accountRead, accountRead); // 読み込みとACL読み込み String readAclToken = ResourceUtils.getMyCellLocalToken(Setup.TEST_CELL1, accountReadAcl, accountReadAcl); // PropFind TResponse res = DavResourceUtils.propfind("box/propfind-col-allprop.txt", readToken, HttpStatus.SC_MULTI_STATUS, testCol); // PROPFIND(XML形式)のACL部分のみ文字列操作で抽出する // ACLタグが存在しない事を確認する NodeList list = res.bodyAsXml().getElementsByTagNameNS("DAV:", "acl"); assertTrue(res.getBody(), list.getLength() == 0); TResponse res2 = DavResourceUtils.propfind("box/propfind-col-allprop.txt", readAclToken, HttpStatus.SC_MULTI_STATUS, testCol); // PROPFIND(XML形式)のACL部分のみ文字列操作で抽出する // ACLタグが存在することを確認する NodeList list2 = res2.bodyAsXml().getElementsByTagNameNS("DAV:", "acl"); assertTrue(res2.getBody(), list2.getLength() > 0); } finally { // コレクションの削除 DavResourceUtils.deleteCollection(Setup.TEST_CELL1, Setup.TEST_BOX1, testCol, AbstractCase.MASTER_TOKEN_NAME, -1); // 結びつけの解除 ResourceUtils.linkAccountRollDelete(Setup.TEST_CELL1, AbstractCase.MASTER_TOKEN_NAME, accountReadAcl, null, "roleReadAcl"); ResourceUtils.linkAccountRollDelete(Setup.TEST_CELL1, AbstractCase.MASTER_TOKEN_NAME, accountRead, null, "roleRead"); // Roleの削除 RoleUtils.delete(Setup.TEST_CELL1, AbstractCase.MASTER_TOKEN_NAME, null, "roleRead"); RoleUtils.delete(Setup.TEST_CELL1, AbstractCase.MASTER_TOKEN_NAME, null, "roleReadAcl"); // Accountの削除 AccountUtils.delete(Setup.TEST_CELL1, AbstractCase.MASTER_TOKEN_NAME, accountReadAcl, HttpStatus.SC_NO_CONTENT); AccountUtils.delete(Setup.TEST_CELL1, AbstractCase.MASTER_TOKEN_NAME, accountRead, HttpStatus.SC_NO_CONTENT); } } /** * ContentLengthが未設定の場合のPROPFIND確認テスト. */ @Test public final void ContentLengthが未設定の場合のPROPFIND確認テスト() { TResponse tresponse = Http.request("box/propfind-non-content-length.txt") .with("path", Setup.TEST_ODATA) .with("depth", "0") .with("token", TOKEN) .returns(); tresponse.statusCode(HttpStatus.SC_MULTI_STATUS); } /** * bodyのpropfindタグが不正の場合にPROPFINDで400になる確認. */ @Test public final void bodyのpropfindタグが不正の場合にPROPFINDで400になる確認() { // 正 propfind // 誤 propfinds String body = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<D:propfinds xmlns:D=\"DAV:\"><D:allprop/></D:propfinds>"; TResponse tresponse = Http.request("box/propfind-body.txt") .with("path", Setup.TEST_ODATA) .with("depth", "0") .with("token", TOKEN) .with("body", body) .returns(); tresponse.statusCode(HttpStatus.SC_BAD_REQUEST); } /** * bodyのallpropタグが不正の場合にPROPFINDで400になる確認. TODO V1.1 PROPFINDの正式実装後有効化する */ @Test @Ignore public final void bodyのallpropタグが不正の場合にPROPFINDで400になる確認() { String body = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<D:propfind xmlns:D=\"DAV:\"><D:allprope/></D:propfind>"; TResponse tresponse = Http.request("box/propfind-body.txt") .with("path", Setup.TEST_ODATA) .with("depth", "0") .with("token", TOKEN) .with("body", body) .returns(); tresponse.statusCode(HttpStatus.SC_BAD_REQUEST); } /** * 存在しないパスにPUTで409が返る事を確認する. */ @Test public final void 存在しないパスにPUTで409が返る事を確認する() { String davFileName = "davFile.txt"; // 存在しないWebDavコレクションへのDavファイルの作成 // testcell1/box1/hogecol/davFile.txt DavResourceUtils.createWebDavFile(Setup.TEST_CELL1, TOKEN, "box/dav-put.txt", "hoge", Setup.TEST_BOX1, "hogecol" + "/" + davFileName, HttpStatus.SC_CONFLICT); } /** * 存在しないパスにMKCOLで409が返る事を確認する. */ @Test public final void 存在しないパスにMKCOLで409が返る事を確認する() { String colName = "colHoge/colhuga"; // 存在しないパスへのOdataコレクションの作成 // testcell1/box1/colHoge/colhuga DavResourceUtils.createODataCollection(TOKEN, HttpStatus.SC_CONFLICT, Setup.TEST_CELL1, Setup.TEST_BOX1, colName); } /** * 存在しない階層パスにPUTで409が返る事を確認する. */ @Test public final void 存在しない階層パスにPUTで409が返る事を確認する() { String davFileName = "davFile.txt"; // 存在しないWebDavコレクションへのDavファイルの作成 // testcell1/box1/hogecol/davFile.txt DavResourceUtils.createWebDavFile(Setup.TEST_CELL1, TOKEN, "box/dav-put.txt", "hoge", Setup.TEST_BOX1, "hogecol" + "/" + "hugacol/" + davFileName, HttpStatus.SC_CONFLICT); } /** * XMLから指定したタグ名の要素を返す. * @param doc ドキュメント * @param tagName タグ名 * @return result 要素の値 */ private String getXmlNodeValue(final Document doc, final String tagName) { return DavResourceUtils.getXmlNodeValue(doc, tagName); } /** * PROPPATCHの返却値のチェック関数. * @param doc 解析するXMLオブジェクト * @param resorce PROPPATCHを設定したリソースパス * @param map チェックするプロパティのKeyValue KeyとValueに値を入れれば値があることのチェック ValueをnullにするとKeyが無いことのチェック(removeの確認に使う) */ private void proppatchResponseTest(Element doc, String resorce, Map<String, String> map) { NodeList response = doc.getElementsByTagName("response"); assertEquals(1, response.getLength()); Element node = (Element) response.item(0); assertEquals( resorce, node.getElementsByTagName("href").item(0).getFirstChild().getNodeValue()); assertEquals( "HTTP/1.1 200 OK", node.getElementsByTagName("status").item(0).getFirstChild().getNodeValue()); for (Iterator<String> it = map.keySet().iterator(); it.hasNext();) { Object key = it.next(); Object value = map.get(key); String textContext = null; NodeList tmp = node.getElementsByTagName("prop").item(0).getChildNodes(); for (int i = 0; i < tmp.getLength(); i++) { Node child = tmp.item(i); if (child instanceof Element) { Element childElement = (Element) child; if (childElement.getLocalName().equals(key)) { textContext = childElement.getTextContent(); break; } } } assertEquals(value, textContext); } } /** * PROPPATCH階層型の返却値のチェック関数. * @param doc 解析するXMLオブジェクト * @param resorce PROPPATCHを設定したリソースパス * @param lapName propタグ内でプロパティをラップしているタグ名 * @param map チェックするプロパティのKeyValue KeyとValueに値を入れれば値があることのチェック ValueをnullにするとKeyが無いことのチェック(removeの確認に使う) */ private void proppatchClassResponseTest(Element doc, String resorce, String lapName, ArrayList<String> list) { NodeList response = doc.getElementsByTagName("response"); assertEquals(1, response.getLength()); Element node = (Element) response.item(0); assertEquals( resorce, node.getElementsByTagName("href").item(0).getFirstChild().getNodeValue()); assertEquals( "HTTP/1.1 200 OK", node.getElementsByTagName("status").item(0).getFirstChild().getNodeValue()); String lapNameFlg = null; NodeList tmp = node.getElementsByTagName("prop").item(0).getChildNodes(); for (int i = 0; i < tmp.getLength(); i++) { Node child = tmp.item(i); if (child instanceof Element) { // プロパティをラップしているタグ名判断 Element childElement = (Element) child; if (childElement.getLocalName().equals(lapName)) { lapNameFlg = "true"; // Pathタグの内のプロパティ判断 NodeList pTmp = childElement.getChildNodes(); for (int ii = 0; ii < pTmp.getLength(); ii++) { Node pChild = pTmp.item(ii); if (pChild instanceof Element) { Element pChildElement = (Element) pChild; NamedNodeMap attrs = pChildElement.getAttributes(); if (attrs != null) { String falg = null; for (Iterator<String> it = list.listIterator(); it.hasNext();) { Object key = it.next(); Object value = it.next(); Node attr = (Node) attrs.getNamedItem((String) key); if (attr != null && attr.getNodeValue().equals(value)) { falg = "true"; } } assertNotNull(falg); } } } } } } // プロパティをラップしているタグ名判断 assertNotNull(lapNameFlg); } /** * entityTypeの削除. * @param odataName * @param token * @param accept * @return */ private TResponse entityTypeDelete(final String odataName, final String token, final String accept, final String entSetName, final String cellPath, final int code) { TResponse tresponse = Http.request("box/entitySet-delete.txt") .with("cellPath", cellPath) .with("boxPath", "box1") .with("odataSvcPath", odataName) .with("token", token) .with("accept", accept) .with("Name", entSetName) .returns() .statusCode(code); return tresponse; } }