/** * 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.cell.ctl; import java.util.ArrayList; import org.apache.http.HttpStatus; import org.json.simple.JSONObject; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; 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.ODataCommon; import com.fujitsu.dc.test.setup.Setup; import com.fujitsu.dc.test.unit.core.UrlUtils; import com.fujitsu.dc.test.utils.BoxUtils; import com.fujitsu.dc.test.utils.Http; import com.fujitsu.dc.test.utils.RelationUtils; import com.fujitsu.dc.test.utils.TResponse; /** * BoxとRelationの$linksのテスト. */ @RunWith(DcRunner.class) @Category({Unit.class, Integration.class, Regression.class }) public class BoxRelationLinkTest extends ODataCommon { private static final String CELL_NAME = "testcell1"; private static final String ENTITY_SET_BOX = "Box"; private static final String ENTITY_SET_RELATION = "Relation"; private static final String NAV_PROP_BOX = "_Box"; private static final String NAV_PROP_RELATION = "_Relation"; static final String TOKEN = AbstractCase.MASTER_TOKEN_NAME; /** * コンストラクタ. テスト対象のパッケージをsuperに渡す必要がある */ public BoxRelationLinkTest() { super("com.fujitsu.dc.core.rs"); } /** * BoxとRelationのlinkを一覧取得できること. */ @Test public final void BoxとRelationのlinkを一覧取得できること() { String relationName = "relation_BoxRelationLinkTest"; String boxName = "box_BoxRelationLinkTest"; TResponse resBox = null; TResponse resRelation = null; try { // Box作成 resBox = BoxUtils.create(CELL_NAME, boxName, TOKEN); // Boxと紐付いたRelation登録 resRelation = createRelation(relationName, boxName); // Boxに紐付くRelationのlink一覧取得 TResponse res = Http.request("links-request-no-navkey.txt") .with("method", "GET") .with("token", TOKEN) .with("cellPath", CELL_NAME) .with("entitySet", ENTITY_SET_BOX) .with("key", "Name='" + boxName + "'") .with("navProp", NAV_PROP_RELATION) .returns() .debug() .statusCode(HttpStatus.SC_OK); // レスポンスヘッダのチェック checkCommonResponseHeader(res); // レスポンスボディのチェック ArrayList<String> uri = new ArrayList<String>(); uri.add(resRelation.getLocationHeader()); checkLinResponseBody(res.bodyAsJson(), uri); } finally { // Relation削除 deleteOdataResource(resRelation.getLocationHeader()); // Box削除 deleteOdataResource(resBox.getLocationHeader()); } } /** * Boxと紐付くRelationが存在しない場合Relationのlinkを一覧取得し200が返却されること. */ @Test public final void Boxと紐付くRelationが存在しない場合Relationのlinkを一覧取得し200が返却されること() { String relationName = "relation_BoxRelationLinkTest"; String boxName = "box_BoxRelationLinkTest"; TResponse resBox = null; TResponse resRelation = null; try { // Box作成 resBox = BoxUtils.create(CELL_NAME, boxName, TOKEN); // Boxと紐付かないRelation登録 resRelation = createRelation(relationName, null); // Boxに紐付くRelationのlink一覧取得 TResponse res = Http.request("links-request-no-navkey.txt") .with("method", "GET") .with("token", TOKEN) .with("cellPath", CELL_NAME) .with("entitySet", ENTITY_SET_BOX) .with("key", "Name='" + boxName + "'") .with("navProp", NAV_PROP_RELATION) .returns() .debug() .statusCode(HttpStatus.SC_OK); // レスポンスヘッダのチェック checkCommonResponseHeader(res); // レスポンスボディのチェック ArrayList<String> uri = new ArrayList<String>(); checkLinResponseBody(res.bodyAsJson(), uri); } finally { // Relation削除 deleteOdataResource(resRelation.getLocationHeader()); // Box削除 deleteOdataResource(resBox.getLocationHeader()); } } /** * RelationとBoxのlinkを一覧取得できること. */ @Test public final void RelationとBoxのlinkを一覧取得できること() { String relationName = "relation_BoxRelationLinkTest"; String boxName = "box1"; TResponse resRelation = null; try { // Boxと紐付いたRelation登録 resRelation = createRelation(relationName, boxName); // Relationに紐付くBoxのlink一覧取得 TResponse res = Http.request("links-request-no-navkey.txt") .with("method", "GET") .with("token", TOKEN) .with("cellPath", CELL_NAME) .with("entitySet", ENTITY_SET_RELATION) .with("key", "Name='" + relationName + "',_Box.Name='" + boxName + "'") .with("navProp", NAV_PROP_BOX) .returns() .debug() .statusCode(HttpStatus.SC_OK); // レスポンスヘッダのチェック checkCommonResponseHeader(res); // レスポンスボディのチェック ArrayList<String> uri = new ArrayList<String>(); uri.add(UrlUtils.cellCtl(CELL_NAME, ENTITY_SET_BOX, boxName)); checkLinResponseBody(res.bodyAsJson(), uri); } finally { // Relation削除 deleteOdataResource(resRelation.getLocationHeader()); } } /** * BoxとIdなしRelationのlinkを更新するとresponseが400であること. */ @Test public final void BoxとIdなしRelationのlinkを更新するとresponseが400であること() { String relationName = "relation_BoxRelationLinkTest"; String boxName = "box_BoxRelationLinkTest"; String linkPath = "__ctl/" + ENTITY_SET_BOX + "\\('" + boxName + "'\\)/\\$links/" + NAV_PROP_RELATION; String relationUri = UrlUtils.cellCtlWithoutSingleQuote(CELL_NAME, ENTITY_SET_RELATION, relationName); TResponse resBox = null; TResponse resRelation = null; try { // Box作成 resBox = BoxUtils.create(CELL_NAME, boxName, TOKEN); // Boxと紐付いたRelation登録 resRelation = createRelation(relationName, boxName); // Boxに紐付くRelationのlink一覧取得 Http.request("link-update-with-body.txt") .with("token", TOKEN) .with("cellPath", CELL_NAME) .with("linkPath", linkPath) .with("body", "\\{\\\"uri\\\":\\\"" + relationUri + "\\\"") .with("navProp", NAV_PROP_RELATION) .returns() .debug() .statusCode(HttpStatus.SC_BAD_REQUEST); } finally { // Relation削除 deleteOdataResource(resRelation.getLocationHeader()); // Box削除 deleteOdataResource(resBox.getLocationHeader()); } } /** * BoxとIdありRelationのlinkを更新するとresponseが501であること. */ @Test public final void BoxとIdありRelationのlinkを更新するとresponseが501であること() { String relationName = "relation_BoxRelationLinkTest"; String boxName = "box_BoxRelationLinkTest"; String linkPath = "__ctl/" + ENTITY_SET_BOX + "\\('" + boxName + "'\\)/\\$links/" + NAV_PROP_RELATION + "\\('" + relationName + "'\\)"; String relationUri = UrlUtils.cellCtlWithoutSingleQuote(CELL_NAME, ENTITY_SET_RELATION, relationName); TResponse resBox = null; TResponse resRelation = null; try { // Box作成 resBox = BoxUtils.create(CELL_NAME, boxName, TOKEN); // Boxと紐付いたRelation登録 resRelation = createRelation(relationName, boxName); // Boxに紐付くRelationのlink一覧取得 Http.request("link-update-with-body.txt") .with("token", TOKEN) .with("cellPath", CELL_NAME) .with("linkPath", linkPath) .with("body", "\\{\\\"uri\\\":\\\"" + relationUri + "\\\"") .with("navProp", NAV_PROP_RELATION) .returns() .debug() .statusCode(HttpStatus.SC_NOT_IMPLEMENTED); } finally { // Relation削除 deleteOdataResource(resRelation.getLocationHeader()); // Box削除 deleteOdataResource(resBox.getLocationHeader()); } } /** * Relationと紐付くBoxが存在しない場合Boxのlinkを一覧取得し200が返却されること. */ @Test public final void Relationと紐付くBoxが存在しない場合Boxのlinkを一覧取得し200が返却されること() { String relationName = "relation_BoxRelationLinkTest"; String boxName = null; TResponse resRelation = null; try { // Boxと紐付かないRelation登録 resRelation = createRelation(relationName, boxName); // Relationに紐付くBoxのlink一覧取得 TResponse res = Http.request("links-request-no-navkey.txt") .with("method", "GET") .with("token", TOKEN) .with("cellPath", CELL_NAME) .with("entitySet", ENTITY_SET_RELATION) .with("key", "Name='" + relationName + "'") .with("navProp", NAV_PROP_BOX) .returns() .debug() .statusCode(HttpStatus.SC_OK); // レスポンスヘッダのチェック checkCommonResponseHeader(res); // レスポンスボディのチェック ArrayList<String> uri = new ArrayList<String>(); checkLinResponseBody(res.bodyAsJson(), uri); } finally { // Relation削除 deleteOdataResource(resRelation.getLocationHeader()); } } /** * RelationとIdなしBoxのlinkを更新するとresponseが400であること. */ @Test public final void RelationとIdなしBoxのlinkを更新するとresponseが400であること() { String relationName = "relation_BoxRelationLinkTest"; String boxName = "box_BoxRelationLinkTest"; String linkPath = "__ctl/" + ENTITY_SET_RELATION + "\\('" + relationName + "'\\)/\\$links/" + NAV_PROP_BOX; String boxUri = UrlUtils.cellCtlWithoutSingleQuote(CELL_NAME, ENTITY_SET_BOX, boxName); TResponse resBox = null; TResponse resRelation = null; try { // Box作成 resBox = BoxUtils.create(CELL_NAME, boxName, TOKEN); // Boxと紐付いたRelation登録 resRelation = createRelation(relationName, boxName); // Boxに紐付くRelationのlink一覧取得 Http.request("link-update-with-body.txt") .with("token", TOKEN) .with("cellPath", CELL_NAME) .with("linkPath", linkPath) .with("body", "\\{\\\"uri\\\":\\\"" + boxUri + "\\\"") .with("navProp", NAV_PROP_RELATION) .returns() .debug() .statusCode(HttpStatus.SC_BAD_REQUEST); } finally { // Relation削除 deleteOdataResource(resRelation.getLocationHeader()); // Box削除 deleteOdataResource(resBox.getLocationHeader()); } } /** * RelationとIdありBoxのlinkを更新するとresponseが501であること. */ @Test public final void RelationとIdありBoxのlinkを更新するとresponseが501であること() { String relationName = "relation_BoxRelationLinkTest"; String boxName = "box_BoxRelationLinkTest"; String linkPath = "__ctl/" + ENTITY_SET_RELATION + "\\('" + relationName + "'\\)/\\$links/" + NAV_PROP_BOX + "\\('" + boxName + "'\\)"; String boxUri = UrlUtils.cellCtlWithoutSingleQuote(CELL_NAME, ENTITY_SET_BOX, boxName); TResponse resBox = null; TResponse resRelation = null; try { // Box作成 resBox = BoxUtils.create(CELL_NAME, boxName, TOKEN); // Boxと紐付いたRelation登録 resRelation = createRelation(relationName, boxName); // Boxに紐付くRelationのlink一覧取得 Http.request("link-update-with-body.txt") .with("token", TOKEN) .with("cellPath", CELL_NAME) .with("linkPath", linkPath) .with("body", "\\{\\\"uri\\\":\\\"" + boxUri + "\\\"") .with("navProp", NAV_PROP_RELATION) .returns() .debug() .statusCode(HttpStatus.SC_NOT_IMPLEMENTED); } finally { // Relation削除 deleteOdataResource(resRelation.getLocationHeader()); // Box削除 deleteOdataResource(resBox.getLocationHeader()); } } /** * BoxとRelationのLink削除時に単一キーの同名Relationが存在すると409になること. */ @Test @SuppressWarnings("unchecked") public final void BoxとRelationのLink削除時に単一キーの同名Relationが存在すると409になること() { final String boxName = "relationLinkBox"; final String relationName = "boxLinkRelation"; try { // Boxの作成 BoxUtils.create(CELL_NAME, boxName, TOKEN, HttpStatus.SC_CREATED); // 上のBoxと結びつくRelation作成 JSONObject body = new JSONObject(); body.put("Name", relationName); body.put("_Box.Name", boxName); RelationUtils.create(CELL_NAME, TOKEN, body, HttpStatus.SC_CREATED); // 上のBoxと結びつかないRelation作成 body.remove("_Box.Name"); RelationUtils.create(CELL_NAME, TOKEN, body, HttpStatus.SC_CREATED); String relationKeyName = "_Box.Name='" + boxName + "',Name='" + relationName + "'"; // BoxとRelationのLink削除(単一キーのRelationが存在するため削除できない(409)) deleteBoxRelationLink(boxName, relationKeyName, HttpStatus.SC_CONFLICT); // RelationとBoxのLink削除(逆向きでも同様に409) deleteRelationBoxLink(relationKeyName, boxName, HttpStatus.SC_CONFLICT); // Relationの削除 RelationUtils.delete(CELL_NAME, TOKEN, relationName, null, HttpStatus.SC_NO_CONTENT); // BoxとRelationのLink削除(単一キーのRelationが存在しないので削除できる) deleteBoxRelationLink(boxName, relationKeyName, HttpStatus.SC_NO_CONTENT); // 結びつくRelationの削除 RelationUtils.delete(CELL_NAME, TOKEN, relationName, null, HttpStatus.SC_NO_CONTENT); // Boxの削除 BoxUtils.delete(CELL_NAME, TOKEN, boxName, HttpStatus.SC_NO_CONTENT); } finally { // 結びつくRelationの削除 RelationUtils.delete(CELL_NAME, TOKEN, relationName, boxName, -1); RelationUtils.delete(CELL_NAME, TOKEN, relationName, null, -1); // Boxの削除 BoxUtils.delete(CELL_NAME, TOKEN, boxName, -1); } } /** * BoxとRelationのLink作成時に複合キーの同名Relationが存在すると409になること. */ @Test @SuppressWarnings("unchecked") public final void BoxとRelationのLink作成時に複合キーの同名Relationが存在すると409になること() { final String boxName = "relationLinkBox"; final String relationName = "boxLinkRelation"; try { // Boxの作成 BoxUtils.create(CELL_NAME, boxName, TOKEN, HttpStatus.SC_CREATED); // 上のBoxと結びつくRelation作成 JSONObject body = new JSONObject(); body.put("Name", relationName); body.put("_Box.Name", boxName); RelationUtils.create(CELL_NAME, TOKEN, body, HttpStatus.SC_CREATED); // 上のBoxと結びつかないRelation作成 body.remove("_Box.Name"); RelationUtils.create(CELL_NAME, TOKEN, body, HttpStatus.SC_CREATED); String relationKeyName = "_Box.Name='" + boxName + "',Name='" + relationName + "'"; // BoxとRelationのLink作成(複合キーの同一Relationが存在するため作成できない(409)) createBoxRelationLink(boxName, relationName, HttpStatus.SC_CONFLICT); // RelationとBoxのLink作成(逆向きでも同様に409) createRelationBoxLink(relationName, boxName, HttpStatus.SC_CONFLICT); // Relationの削除 RelationUtils.delete(CELL_NAME, TOKEN, relationName, null, HttpStatus.SC_NO_CONTENT); // BoxとRelationのLink削除(単一キーのRelationが存在しないので削除できる) deleteBoxRelationLink(boxName, relationKeyName, HttpStatus.SC_NO_CONTENT); // 結びつくRelationの削除 RelationUtils.delete(CELL_NAME, TOKEN, relationName, null, HttpStatus.SC_NO_CONTENT); // Boxの削除 BoxUtils.delete(CELL_NAME, TOKEN, boxName, HttpStatus.SC_NO_CONTENT); } finally { // 結びつくRelationの削除 RelationUtils.delete(CELL_NAME, TOKEN, relationName, boxName, -1); RelationUtils.delete(CELL_NAME, TOKEN, relationName, null, -1); // Boxの削除 BoxUtils.delete(CELL_NAME, TOKEN, boxName, -1); } } /** * BoxとRelationのlink作成時URLのNP名とボディのエンティティ名が異なる場合400になること. */ @Test public final void BoxとRelationのlink作成時URLのNP名とボディのエンティティ名が異なる場合400になること() { String targetUri = UrlUtils.cellRoot(Setup.TEST_CELL1) + "__ctl/Relation(Name='" + Setup.CELL_RELATION + "',_Box.Name=null)"; // Box-Relationの$link Http.request("links-request-with-body.txt") .with("method", "POST") .with("token", AbstractCase.MASTER_TOKEN_NAME) .with("cellPath", Setup.TEST_CELL1) .with("entitySet", "Box") .with("key", "'" + Setup.TEST_BOX1 + "'") .with("navProp", "_Role") .with("uri", targetUri) .returns() .statusCode(HttpStatus.SC_BAD_REQUEST); } private void deleteBoxRelationLink(final String boxName, final String linkRoleKey, final int status) { Http.request("links-request.txt") .with("method", "DELETE") .with("token", AbstractCase.MASTER_TOKEN_NAME) .with("cellPath", CELL_NAME) .with("entitySet", ENTITY_SET_BOX) .with("key", "'" + boxName + "'") .with("navProp", NAV_PROP_RELATION) .with("navKey", linkRoleKey) .returns() .debug() .statusCode(status); } private void deleteRelationBoxLink(final String roleName, final String linkBoxKey, final int status) { Http.request("links-request.txt") .with("method", "DELETE") .with("token", AbstractCase.MASTER_TOKEN_NAME) .with("cellPath", CELL_NAME) .with("entitySet", ENTITY_SET_RELATION) .with("key", roleName) .with("navProp", NAV_PROP_BOX) .with("navKey", "'" + linkBoxKey + "'") .returns() .debug() .statusCode(status); } private void createBoxRelationLink(final String boxName, final String relationName, final int expectedStatus) { String url = UrlUtils.cellCtl(CELL_NAME, ENTITY_SET_RELATION, relationName); Http.request("links-request-with-body.txt") .with("method", "POST") .with("token", AbstractCase.MASTER_TOKEN_NAME) .with("cellPath", CELL_NAME) .with("entitySet", ENTITY_SET_BOX) .with("key", "'" + boxName + "'") .with("navProp", NAV_PROP_RELATION) .with("uri", url) .returns() .debug() .statusCode(expectedStatus); } private void createRelationBoxLink(final String relationName, final String boxName, final int expectedStatus) { String url = UrlUtils.cellCtl(CELL_NAME, ENTITY_SET_BOX, boxName); Http.request("links-request-with-body.txt") .with("method", "POST") .with("token", AbstractCase.MASTER_TOKEN_NAME) .with("cellPath", CELL_NAME) .with("entitySet", ENTITY_SET_RELATION) .with("key", "'" + relationName + "'") .with("navProp", NAV_PROP_BOX) .with("uri", url) .returns() .debug() .statusCode(expectedStatus); } /** * Relation作成. * @param relationName relationName * @param boxName boxName(指定しない場合はnull) * @return レスポンス */ @SuppressWarnings("unchecked") private TResponse createRelation(String relationName, String boxName) { JSONObject bodyJson = new JSONObject(); bodyJson.put("Name", relationName); if (boxName != null) { bodyJson.put("_Box.Name", boxName); } return RelationUtils.create(CELL_NAME, TOKEN, bodyJson, HttpStatus.SC_CREATED); } }