/**
* 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.odatacol.batch;
import static com.fujitsu.dc.test.utils.BatchUtils.BOUNDARY;
import static com.fujitsu.dc.test.utils.BatchUtils.END_BOUNDARY;
import static com.fujitsu.dc.test.utils.BatchUtils.START_BOUNDARY;
import static com.fujitsu.dc.test.utils.BatchUtils.retrieveChangeSetResErrorBody;
import static com.fujitsu.dc.test.utils.BatchUtils.retrieveLinksPostBody;
import static com.fujitsu.dc.test.utils.BatchUtils.retrieveLinksPostResBody;
import static com.fujitsu.dc.test.utils.BatchUtils.retrievePostBody;
import static com.fujitsu.dc.test.utils.BatchUtils.retrievePostResBody;
import static org.junit.Assert.assertEquals;
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.core.MediaType;
import org.apache.http.HttpStatus;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import com.fujitsu.dc.core.DcCoreConfig;
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.AssociationEndUtils;
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.EntityTypeUtils;
import com.fujitsu.dc.test.utils.Http;
import com.fujitsu.dc.test.utils.TResponse;
import com.fujitsu.dc.test.utils.UserDataUtils;
import com.sun.jersey.test.framework.WebAppDescriptor;
/**
* UserData $batchのNavigationProperty経由登録の上限値テスト. たくさんデータを登録するので、「Integration.class, Regression.class」では動作しない。
*/
@RunWith(DcRunner.class)
@Category({Unit.class })
public class UserDataBatchWithNPLimitTest extends AbstractUserDataBatchTest {
private static final Map<String, String> INIT_PARAMS = new HashMap<String, String>();
static {
INIT_PARAMS.put("com.sun.jersey.config.property.packages", "com.fujitsu.dc.core.rs");
INIT_PARAMS.put("com.sun.jersey.spi.container.ContainerRequestFilters",
"com.fujitsu.dc.core.jersey.filter.DcCoreContainerFilter");
INIT_PARAMS.put("com.sun.jersey.spi.container.ContainerResponseFilters",
"com.fujitsu.dc.core.jersey.filter.DcCoreContainerFilter");
}
String masterToken = Setup.MASTER_TOKEN_NAME;
String cellName = "userDataBatchWithNPLimitTestCell";
String boxName = "box";
String colName = "col";
String parentEntityTypeName = "parentEntity";
String childEntityTypeName = "childEntity";
String srcEntityTypeName = "srcEntity";
String targetEntityTypeName = "targetEntity";
String parentAssociationEndName = "parentAssociation";
String childAssociationEndName = "childAssociation";
String srcAssociationEndName = "srcAssociation";
String targetAssociationEndName = "targetAssociation";
String srcId = "id";
// 登録するユーザODataの件数(N:Nの$linksで登録可能な上限値)
int maxUserDataCount = DcCoreConfig.getLinksNtoNMaxSize();
int registUserDataCount = maxUserDataCount - 10;
/**
* コンストラクタ.
*/
public UserDataBatchWithNPLimitTest() {
super(new WebAppDescriptor.Builder(UserDataBatchWithNPLimitTest.INIT_PARAMS).build());
}
/**
* ソース側のリンク数が上限に満たない場合登録できること.
* @throws ParseException リクエストボディのパースに失敗
*/
@Test
public final void ソース側のリンク数が上限に満たない場合登録できること()
throws ParseException {
try {
int index = registUserDataCount + 1;
// $batch
String path = srcEntityTypeName + "('" + srcId + "')/_" + targetEntityTypeName;
String body = START_BOUNDARY + retrievePostBody(path, String.format("id%03d", index++)) + START_BOUNDARY
+ retrievePostBody(path, String.format("id%03d", index++)) + START_BOUNDARY
+ retrievePostBody(path, String.format("id%03d", index++)) + END_BOUNDARY;
TResponse response = Http.request("box/odatacol/batch.txt").with("cell", cellName).with("box", boxName)
.with("collection", colName).with("boundary", BOUNDARY)
.with("token", DcCoreConfig.getMasterToken()).with("body", body).returns().debug()
.statusCode(HttpStatus.SC_ACCEPTED);
// レスポンスボディのチェック
index = registUserDataCount + 1;
String registeredId1 = String.format("id%03d", index++);
String registeredId2 = String.format("id%03d", index++);
String registeredId3 = String.format("id%03d", index++);
String expectedBody = START_BOUNDARY
+ retrievePostResBody(cellName, boxName, colName, targetEntityTypeName, registeredId1)
+ START_BOUNDARY
+ retrievePostResBody(cellName, boxName, colName, targetEntityTypeName, registeredId2)
+ START_BOUNDARY
+ retrievePostResBody(cellName, boxName, colName, targetEntityTypeName, registeredId3)
+ END_BOUNDARY;
checkBatchResponseBody(response, expectedBody);
// 登録済み件数が3つ増加していることのチェック
String query = String.format("?\\$top=%s&\\$inlinecount=allpages", 0);
response = Http.request("box/odatacol/list.txt").with("cell", cellName).with("box", boxName)
.with("collection", colName + "/" + srcEntityTypeName + "('" + srcId + "')")
.with("entityType", "_" + targetEntityTypeName).with("query", query)
.with("accept", MediaType.APPLICATION_JSON).with("token", masterToken).returns()
.statusCode(HttpStatus.SC_OK).debug();
// レスポンスボディの件数のチェック
JSONArray results = (JSONArray) ((JSONObject) response.bodyAsJson().get("d")).get("results");
assertEquals(0, results.size());
// __countのチェック
ODataCommon.checkResponseBodyCount(response.bodyAsJson(), registUserDataCount + 3);
} finally {
// 追加したデータの削除
for (int index = registUserDataCount + 1; index <= maxUserDataCount + 3; index++) {
deleteUserDataWithLink(srcEntityTypeName, srcId, targetEntityTypeName, index);
}
}
}
/**
* ソース側のリンク数が上限値マイナス1の場合登録できること.
* @throws ParseException リクエストボディのパースに失敗
*/
@Test
public final void ソース側のリンク数が上限値マイナス1の場合登録できること()
throws ParseException {
try {
int index = registUserDataCount + 1;
// ベースデータ追加($linksの上限値マイナス1まで登録)
for (; index <= maxUserDataCount - 1; index++) {
String id = String.format("id%03d", index);
JSONObject body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + id + "\",\"name\":\"pochi\"}");
UserDataUtils.createViaNP(masterToken, body, cellName, boxName, colName, srcEntityTypeName, srcId,
targetEntityTypeName, HttpStatus.SC_CREATED);
}
// $batch
String path = srcEntityTypeName + "('" + srcId + "')/_" + targetEntityTypeName;
String body = START_BOUNDARY + retrievePostBody(path, String.format("id%03d", index++)) + START_BOUNDARY
+ retrievePostBody(path, String.format("id%03d", index++)) + START_BOUNDARY
+ retrievePostBody(path, String.format("id%03d", index++)) + END_BOUNDARY;
TResponse response = Http.request("box/odatacol/batch.txt").with("cell", cellName).with("box", boxName)
.with("collection", colName).with("boundary", BOUNDARY)
.with("token", DcCoreConfig.getMasterToken()).with("body", body).returns().debug()
.statusCode(HttpStatus.SC_ACCEPTED);
// レスポンスボディのチェック
String registeredId = String.format("id%03d", maxUserDataCount);
String expectedBody = START_BOUNDARY
+ retrievePostResBody(cellName, boxName, colName, targetEntityTypeName, registeredId)
+ START_BOUNDARY + retrieveChangeSetResErrorBody(HttpStatus.SC_BAD_REQUEST)
+ START_BOUNDARY + retrieveChangeSetResErrorBody(HttpStatus.SC_BAD_REQUEST) + END_BOUNDARY;
checkBatchResponseBody(response, expectedBody);
// 登録済み件数が1つ増加していることのチェック
String query = String.format("?\\$top=%s&\\$inlinecount=allpages", 0);
response = Http.request("box/odatacol/list.txt").with("cell", cellName).with("box", boxName)
.with("collection", colName + "/" + srcEntityTypeName + "('" + srcId + "')")
.with("entityType", "_" + targetEntityTypeName).with("query", query)
.with("accept", MediaType.APPLICATION_JSON).with("token", masterToken).returns()
.statusCode(HttpStatus.SC_OK).debug();
// レスポンスボディの件数のチェック
JSONArray results = (JSONArray) ((JSONObject) response.bodyAsJson().get("d")).get("results");
assertEquals(0, results.size());
// __countのチェック
ODataCommon.checkResponseBodyCount(response.bodyAsJson(), maxUserDataCount);
// 1つめのリクエストで登録したデータが登録されていること
UserDataUtils.get(cellName, masterToken, boxName, colName, targetEntityTypeName, registeredId,
HttpStatus.SC_OK);
} finally {
// 追加したデータの削除
for (int index = registUserDataCount + 1; index <= maxUserDataCount + 3; index++) {
deleteUserDataWithLink(srcEntityTypeName, srcId, targetEntityTypeName, index);
}
}
}
/**
* ソース側のリンク数が上限値以上の場合400エラーとなること.
* @throws ParseException リクエストボディのパースに失敗
*/
@Test
public final void ソース側のリンク数が上限値以上の場合400エラーとなること()
throws ParseException {
try {
int index = registUserDataCount + 1;
// ベースデータ追加($linksの上限値まで登録)
for (; index <= maxUserDataCount; index++) {
String id = String.format("id%03d", index);
JSONObject body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + id + "\",\"name\":\"pochi\"}");
UserDataUtils.createViaNP(masterToken, body, cellName, boxName, colName, srcEntityTypeName, srcId,
targetEntityTypeName, HttpStatus.SC_CREATED);
}
// $batch
String path = srcEntityTypeName + "('" + srcId + "')/_" + targetEntityTypeName;
String body = START_BOUNDARY + retrievePostBody(path, String.format("id%03d", index++)) + START_BOUNDARY
+ retrievePostBody(path, String.format("id%03d", index++)) + START_BOUNDARY
+ retrievePostBody(path, String.format("id%03d", index++)) + END_BOUNDARY;
TResponse response = Http.request("box/odatacol/batch.txt").with("cell", cellName).with("box", boxName)
.with("collection", colName).with("boundary", BOUNDARY)
.with("token", DcCoreConfig.getMasterToken()).with("body", body).returns().debug()
.statusCode(HttpStatus.SC_ACCEPTED);
// レスポンスボディのチェック
String expectedBody = START_BOUNDARY + retrieveChangeSetResErrorBody(HttpStatus.SC_BAD_REQUEST)
+ START_BOUNDARY + retrieveChangeSetResErrorBody(HttpStatus.SC_BAD_REQUEST) + START_BOUNDARY
+ retrieveChangeSetResErrorBody(HttpStatus.SC_BAD_REQUEST) + END_BOUNDARY;
checkBatchResponseBody(response, expectedBody);
// 登録済み件数が増加していないことのチェック
String query = String.format("?\\$top=%s&\\$inlinecount=allpages", 0);
response = Http.request("box/odatacol/list.txt").with("cell", cellName).with("box", boxName)
.with("collection", colName + "/" + srcEntityTypeName + "('" + srcId + "')")
.with("entityType", "_" + targetEntityTypeName).with("query", query)
.with("accept", MediaType.APPLICATION_JSON).with("token", masterToken).returns()
.statusCode(HttpStatus.SC_OK).debug();
// レスポンスボディの件数のチェック
JSONArray results = (JSONArray) ((JSONObject) response.bodyAsJson().get("d")).get("results");
assertEquals(0, results.size());
// __countのチェック
ODataCommon.checkResponseBodyCount(response.bodyAsJson(), maxUserDataCount);
} finally {
// 追加したデータの削除
for (int index = registUserDataCount + 1; index <= maxUserDataCount + 3; index++) {
deleteUserDataWithLink(srcEntityTypeName, srcId, targetEntityTypeName, index);
}
}
}
/**
* ターゲット側のひとつのEntityTypeが上限値に達していても他のEntityTypeは登録できること.
* @throws ParseException リクエストボディのパースに失敗
*/
@Test
public final void ターゲット側のひとつのEntityTypeが上限値に達していても他のEntityTypeは登録できること()
throws ParseException {
String additionalEntityType = "additionalEntityType";
String additionalAssociationEnd1 = "additionalAssociation1";
String additionalAssociationEnd2 = "additionalAssociation2";
String additionalUserDataId = String.format("id%03d", 1);
try {
int index = registUserDataCount + 1;
// ベースデータ追加($linksの上限値まで登録)
for (; index <= maxUserDataCount; index++) {
String id = String.format("id%03d", index);
JSONObject body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + id + "\",\"name\":\"pochi\"}");
UserDataUtils.createViaNP(masterToken, body, cellName, boxName, colName, srcEntityTypeName, srcId,
targetEntityTypeName, HttpStatus.SC_CREATED);
}
// スキーマlink情報追加
// EntityType
EntityTypeUtils.create(cellName, masterToken, boxName, colName,
additionalEntityType, HttpStatus.SC_CREATED);
// AssociationEnd
AssociationEndUtils.create(masterToken, "*", cellName, boxName, colName, HttpStatus.SC_CREATED,
additionalAssociationEnd1, additionalEntityType);
AssociationEndUtils.create(masterToken, "*", cellName, boxName, colName, HttpStatus.SC_CREATED,
additionalAssociationEnd2, srcEntityTypeName);
// AssociationEnd - AssociationEnd $links
AssociationEndUtils.createLink(AbstractCase.MASTER_TOKEN_NAME, cellName, boxName, colName,
additionalEntityType, srcEntityTypeName, additionalAssociationEnd1, additionalAssociationEnd2,
HttpStatus.SC_NO_CONTENT);
// $batch
String path1 = srcEntityTypeName + "('" + srcId + "')/_" + targetEntityTypeName;
String path2 = srcEntityTypeName + "('" + srcId + "')/_" + additionalEntityType;
String body = START_BOUNDARY + retrievePostBody(path1, String.format("id%03d", index++))
+ START_BOUNDARY + retrievePostBody(path2, additionalUserDataId)
+ END_BOUNDARY;
TResponse response = Http.request("box/odatacol/batch.txt").with("cell", cellName).with("box", boxName)
.with("collection", colName).with("boundary", BOUNDARY)
.with("token", DcCoreConfig.getMasterToken()).with("body", body).returns().debug()
.statusCode(HttpStatus.SC_ACCEPTED);
// レスポンスボディのチェック
String expectedBody = START_BOUNDARY + retrieveChangeSetResErrorBody(HttpStatus.SC_BAD_REQUEST)
+ START_BOUNDARY
+ retrievePostResBody(cellName, boxName, colName, additionalEntityType, additionalUserDataId)
+ END_BOUNDARY;
checkBatchResponseBody(response, expectedBody);
// 登録済み件数が増加していないことのチェック
checkLinkCount(srcEntityTypeName, srcId, targetEntityTypeName, maxUserDataCount);
// 他のEntityTypeが登録できていることのチェック
checkLinkCount(srcEntityTypeName, srcId, additionalEntityType, 1);
} finally {
// 追加したデータの削除
for (int index = registUserDataCount + 1; index <= maxUserDataCount + 3; index++) {
deleteUserDataWithLink(srcEntityTypeName, srcId, targetEntityTypeName, index);
}
deleteUserDataWithLink(srcEntityTypeName, srcId, additionalEntityType, 1);
String key = "Name='" + additionalAssociationEnd1 + "',_EntityType.Name='" + additionalEntityType + "'";
String navKey = "Name='" + additionalAssociationEnd2 + "',_EntityType.Name='" + srcEntityTypeName + "'";
AssociationEndUtils.deleteLink(cellName, colName, boxName, key, navKey, -1);
AssociationEndUtils.delete(AbstractCase.MASTER_TOKEN_NAME, cellName, colName, additionalEntityType,
boxName, additionalAssociationEnd1, -1);
AssociationEndUtils.delete(AbstractCase.MASTER_TOKEN_NAME, cellName, colName, srcEntityTypeName, boxName,
additionalAssociationEnd2, -1);
EntityTypeUtils.delete(colName, masterToken, MediaType.APPLICATION_JSON, additionalEntityType, boxName,
cellName, -1);
}
}
/**
* ひとつのUserDataに対するリンクが上限値に達していても他のUserDataに対するリンクは登録できること.
* @throws ParseException リクエストボディのパースに失敗
*/
@Test
public final void ひとつのUserDataに対するリンクが上限値に達していても他のUserDataに対するリンクは登録できること()
throws ParseException {
String additionalUserDataId = String.format("id%03d", 999);
try {
int index = registUserDataCount + 1;
// ベースデータ追加($linksの上限値まで登録)
for (; index <= maxUserDataCount; index++) {
String id = String.format("id%03d", index);
JSONObject body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + id + "\",\"name\":\"pochi\"}");
UserDataUtils.createViaNP(masterToken, body, cellName, boxName, colName, srcEntityTypeName, srcId,
targetEntityTypeName, HttpStatus.SC_CREATED);
}
// ソース側ユーザOData追加
JSONObject additionalBody = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + additionalUserDataId
+ "\",\"name\":\"pochi\"}");
UserDataUtils.create(masterToken, HttpStatus.SC_CREATED, additionalBody, cellName, boxName, colName,
srcEntityTypeName);
// $batch
String path1 = srcEntityTypeName + "('" + srcId + "')/_" + targetEntityTypeName;
String path2 = srcEntityTypeName + "('" + additionalUserDataId + "')/_" + targetEntityTypeName;
String body = START_BOUNDARY + retrievePostBody(path1, String.format("id%03d", index++))
+ START_BOUNDARY + retrievePostBody(path2, additionalUserDataId)
+ END_BOUNDARY;
TResponse response = Http.request("box/odatacol/batch.txt").with("cell", cellName).with("box", boxName)
.with("collection", colName).with("boundary", BOUNDARY)
.with("token", DcCoreConfig.getMasterToken()).with("body", body).returns().debug()
.statusCode(HttpStatus.SC_ACCEPTED);
// レスポンスボディのチェック
String expectedBody = START_BOUNDARY + retrieveChangeSetResErrorBody(HttpStatus.SC_BAD_REQUEST)
+ START_BOUNDARY
+ retrievePostResBody(cellName, boxName, colName, targetEntityTypeName, additionalUserDataId)
+ END_BOUNDARY;
checkBatchResponseBody(response, expectedBody);
// 登録済み件数が増加していないことのチェック
checkLinkCount(srcEntityTypeName, srcId, targetEntityTypeName, maxUserDataCount);
// 他のEntityTypeが登録できていることのチェック
checkLinkCount(srcEntityTypeName, additionalUserDataId, targetEntityTypeName, 1);
} finally {
// 追加したデータの削除
for (int index = registUserDataCount + 1; index <= maxUserDataCount + 3; index++) {
deleteUserDataWithLink(srcEntityTypeName, srcId, targetEntityTypeName, index);
}
deleteUserDataWithLink(srcEntityTypeName, srcId, targetEntityTypeName, 999);
}
}
/**
* ソース側のひとつのEntityTypeが上限値に達していても他のEntityTypeは登録できること.
* @throws ParseException リクエストボディのパースに失敗
*/
@Test
public final void ソース側のひとつのEntityTypeが上限値に達していても他のEntityTypeは登録できること()
throws ParseException {
String additionalEntityType = "additionalEntityType";
String additionalAssociationEnd1 = "additionalAssociation1";
String additionalAssociationEnd2 = "additionalAssociation2";
String additionalUserDataId = String.format("id%03d", 999);
try {
int index = registUserDataCount + 1;
// ベースデータ追加($linksの上限値まで登録)
for (; index <= maxUserDataCount; index++) {
String id = String.format("id%03d", index);
JSONObject body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + id + "\",\"name\":\"pochi\"}");
UserDataUtils.createViaNP(masterToken, body, cellName, boxName, colName, srcEntityTypeName, srcId,
targetEntityTypeName, HttpStatus.SC_CREATED);
}
// スキーマlink情報追加
// EntityType
EntityTypeUtils.create(cellName, masterToken, boxName, colName,
additionalEntityType, HttpStatus.SC_CREATED);
// AssociationEnd
AssociationEndUtils.create(masterToken, "*", cellName, boxName, colName, HttpStatus.SC_CREATED,
additionalAssociationEnd1, additionalEntityType);
AssociationEndUtils.create(masterToken, "*", cellName, boxName, colName, HttpStatus.SC_CREATED,
additionalAssociationEnd2, targetEntityTypeName);
// AssociationEnd - AssociationEnd $links
AssociationEndUtils.createLink(AbstractCase.MASTER_TOKEN_NAME, cellName, boxName, colName,
additionalEntityType,
targetEntityTypeName, additionalAssociationEnd1, additionalAssociationEnd2,
HttpStatus.SC_NO_CONTENT);
// ソース側の追加のEntityTypeにユーザOData登録
JSONObject additionalBody = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + additionalUserDataId
+ "\",\"name\":\"pochi\"}");
UserDataUtils.create(masterToken, HttpStatus.SC_CREATED, additionalBody, cellName, boxName, colName,
additionalEntityType);
// $batch
String path1 = srcEntityTypeName + "('" + srcId + "')/_" + targetEntityTypeName;
String path2 = additionalEntityType + "('" + additionalUserDataId + "')/_" + targetEntityTypeName;
String body = START_BOUNDARY + retrievePostBody(path1, String.format("id%03d", index++))
+ START_BOUNDARY + retrievePostBody(path2, additionalUserDataId)
+ END_BOUNDARY;
TResponse response = Http.request("box/odatacol/batch.txt").with("cell", cellName).with("box", boxName)
.with("collection", colName).with("boundary", BOUNDARY)
.with("token", DcCoreConfig.getMasterToken()).with("body", body).returns().debug()
.statusCode(HttpStatus.SC_ACCEPTED);
// レスポンスボディのチェック
String expectedBody = START_BOUNDARY + retrieveChangeSetResErrorBody(HttpStatus.SC_BAD_REQUEST)
+ START_BOUNDARY
+ retrievePostResBody(cellName, boxName, colName, targetEntityTypeName, additionalUserDataId)
+ END_BOUNDARY;
checkBatchResponseBody(response, expectedBody);
// 登録済み件数が増加していないことのチェック
checkLinkCount(srcEntityTypeName, srcId, targetEntityTypeName, maxUserDataCount);
// 他のEntityTypeが登録できていることのチェック
checkLinkCount(additionalEntityType, additionalUserDataId, targetEntityTypeName, 1);
} finally {
// 追加したデータの削除
for (int index = registUserDataCount + 1; index <= maxUserDataCount + 3; index++) {
deleteUserDataWithLink(srcEntityTypeName, srcId, targetEntityTypeName, index);
}
deleteUserDataWithLink(additionalEntityType, additionalUserDataId, targetEntityTypeName, 999);
UserDataUtils.delete(masterToken, -1, cellName, boxName, colName, additionalEntityType,
additionalUserDataId);
String key = "Name='" + additionalAssociationEnd1 + "',_EntityType.Name='" + additionalEntityType + "'";
String navKey = "Name='" + additionalAssociationEnd2 + "',_EntityType.Name='" + targetEntityTypeName + "'";
AssociationEndUtils.deleteLink(cellName, colName, boxName, key, navKey, -1);
AssociationEndUtils.delete(AbstractCase.MASTER_TOKEN_NAME, cellName, colName, additionalEntityType,
boxName, additionalAssociationEnd1, -1);
AssociationEndUtils.delete(AbstractCase.MASTER_TOKEN_NAME, cellName, colName, targetEntityTypeName,
boxName, additionalAssociationEnd2, -1);
EntityTypeUtils.delete(colName, masterToken, MediaType.APPLICATION_JSON, additionalEntityType, boxName,
cellName, -1);
}
}
/**
* ONE対AST_ソース側のリンク数が上限値以上の場合でも登録できること.
* @throws ParseException リクエストボディのパースに失敗
*/
@Test
public final void ONE対AST_ソース側のリンク数が上限値以上の場合でも登録できること()
throws ParseException {
try {
int index = registUserDataCount + 1;
// ベースデータ追加($linksの上限値まで登録)
for (; index <= maxUserDataCount; index++) {
String id = String.format("id%03d", index);
JSONObject body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + id + "\",\"name\":\"pochi\"}");
UserDataUtils.createViaNP(masterToken, body, cellName, boxName, colName, parentEntityTypeName, srcId,
childEntityTypeName, HttpStatus.SC_CREATED);
}
// $batch
String path = parentEntityTypeName + "('" + srcId + "')/_" + childEntityTypeName;
String body = START_BOUNDARY + retrievePostBody(path, String.format("id%03d", index++)) + START_BOUNDARY
+ retrievePostBody(path, String.format("id%03d", index++)) + START_BOUNDARY
+ retrievePostBody(path, String.format("id%03d", index++)) + END_BOUNDARY;
TResponse response = Http.request("box/odatacol/batch.txt").with("cell", cellName).with("box", boxName)
.with("collection", colName).with("boundary", BOUNDARY)
.with("token", DcCoreConfig.getMasterToken()).with("body", body).returns().debug()
.statusCode(HttpStatus.SC_ACCEPTED);
// レスポンスボディのチェック
index = maxUserDataCount + 1;
String expectedBody = START_BOUNDARY
+ retrievePostResBody(cellName, boxName, colName, childEntityTypeName,
String.format("id%03d", index++))
+ START_BOUNDARY
+ retrievePostResBody(cellName, boxName, colName, childEntityTypeName,
String.format("id%03d", index++))
+ START_BOUNDARY
+ retrievePostResBody(cellName, boxName, colName, childEntityTypeName,
String.format("id%03d", index++))
+ END_BOUNDARY;
checkBatchResponseBody(response, expectedBody);
// 登録済み件数が増加していることのチェック
checkLinkCount(parentEntityTypeName, srcId, childEntityTypeName, maxUserDataCount + 3);
} finally {
// 追加したデータの削除
for (int index = registUserDataCount + 1; index <= maxUserDataCount + 3; index++) {
deleteUserDataWithLink(parentEntityTypeName, srcId, childEntityTypeName, index);
}
}
}
/**
* ターゲット側に存在しないEntityType名を指定した場合404エラーとなること.
* @throws ParseException リクエストボディのパースに失敗
*/
@Test
public final void ターゲット側に存在しないEntityType名を指定した場合404エラーとなること()
throws ParseException {
try {
int index = registUserDataCount + 1;
// ベースデータ追加($linksの上限値まで登録)
for (; index <= maxUserDataCount; index++) {
String id = String.format("id%03d", index);
JSONObject body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + id + "\",\"name\":\"pochi\"}");
UserDataUtils.createViaNP(masterToken, body, cellName, boxName, colName, srcEntityTypeName, srcId,
targetEntityTypeName, HttpStatus.SC_CREATED);
}
// $batch
String path1 = srcEntityTypeName + "('" + srcId + "')/_" + targetEntityTypeName;
String path2 = srcEntityTypeName + "('" + srcId + "')/_" + "dummyEntityType";
String body = START_BOUNDARY + retrievePostBody(path1, String.format("id%03d", index))
+ START_BOUNDARY + retrievePostBody(path2, String.format("id%03d", 1))
+ END_BOUNDARY;
TResponse response = Http.request("box/odatacol/batch.txt").with("cell", cellName).with("box", boxName)
.with("collection", colName).with("boundary", BOUNDARY)
.with("token", DcCoreConfig.getMasterToken()).with("body", body).returns().debug()
.statusCode(HttpStatus.SC_ACCEPTED);
// レスポンスボディのチェック
String expectedBody = START_BOUNDARY + retrieveChangeSetResErrorBody(HttpStatus.SC_BAD_REQUEST)
+ START_BOUNDARY + retrieveChangeSetResErrorBody(HttpStatus.SC_NOT_FOUND)
+ END_BOUNDARY;
checkBatchResponseBody(response, expectedBody);
} finally {
// 追加したデータの削除
for (int index = registUserDataCount + 1; index <= maxUserDataCount + 1; index++) {
deleteUserDataWithLink(srcEntityTypeName, srcId, targetEntityTypeName, index);
}
}
}
// -------------------------------
/**
* $batchでAST対ASTのUserDataの$links登録_上限値以上の$linksが存在する場合400エラーとなること.
* @throws ParseException リクエストボディのパースに失敗
*/
@Test
public final void $batchでAST対ASTのUserDataの$links登録_上限値以上の$linksが存在する場合400エラーとなること()
throws ParseException {
try {
int index = registUserDataCount + 1;
// ベースデータ追加($linksの上限値まで登録)
for (; index <= maxUserDataCount; index++) {
String id = String.format("id%03d", index);
JSONObject body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + id + "\",\"name\":\"pochi\"}");
UserDataUtils.createViaNP(masterToken, body, cellName, boxName, colName,
srcEntityTypeName, srcId, targetEntityTypeName, HttpStatus.SC_CREATED);
}
// ベースデータ追加($linksの上限値を超える分)
// target側
int linkedIndex = index;
for (; index <= maxUserDataCount + 3; index++) {
String id = String.format("id%03d", index);
JSONObject body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + id + "\",\"name\":\"pochi\"}");
UserDataUtils.create(masterToken, HttpStatus.SC_CREATED, body, cellName, boxName, colName,
targetEntityTypeName);
}
// $batch
String path = srcEntityTypeName + "('" + srcId + "')/\\$links/_" + targetEntityTypeName;
String body = "";
StringBuilder bodyBuilder = new StringBuilder();
for (; linkedIndex <= maxUserDataCount + 3; linkedIndex++) {
String linksBody = "{\"uri\":\""
+ UrlUtils.userdata(cellName, boxName, colName,
targetEntityTypeName, String.format("id%03d", linkedIndex)) + "\"}";
bodyBuilder.append(START_BOUNDARY + retrieveLinksPostBody(HttpMethod.POST, path, linksBody));
}
bodyBuilder.append(END_BOUNDARY);
body = bodyBuilder.toString();
TResponse response = Http.request("box/odatacol/batch.txt")
.with("cell", cellName)
.with("box", boxName)
.with("collection", colName)
.with("boundary", BOUNDARY)
.with("token", DcCoreConfig.getMasterToken())
.with("body", body)
.returns()
.debug()
.statusCode(HttpStatus.SC_ACCEPTED);
// レスポンスボディのチェック
String expectedBody = START_BOUNDARY + retrieveChangeSetResErrorBody(HttpStatus.SC_BAD_REQUEST)
+ START_BOUNDARY + retrieveChangeSetResErrorBody(HttpStatus.SC_BAD_REQUEST)
+ START_BOUNDARY + retrieveChangeSetResErrorBody(HttpStatus.SC_BAD_REQUEST) + END_BOUNDARY;
checkBatchResponseBody(response, expectedBody);
// 登録済み件数が増加していないことのチェック
String query = String.format("?\\$top=%s&\\$inlinecount=allpages", 0);
response = Http.request("box/odatacol/list.txt")
.with("cell", cellName)
.with("box", boxName)
.with("collection", colName + "/" + srcEntityTypeName + "('" + srcId + "')")
.with("entityType", "_" + targetEntityTypeName)
.with("query", query)
.with("accept", MediaType.APPLICATION_JSON)
.with("token", masterToken)
.returns()
.statusCode(HttpStatus.SC_OK)
.debug();
// レスポンスボディの件数のチェック
JSONArray results = (JSONArray) ((JSONObject) response.bodyAsJson().get("d")).get("results");
assertEquals(0, results.size());
// __countのチェック
ODataCommon.checkResponseBodyCount(response.bodyAsJson(), maxUserDataCount);
} finally {
// 追加したデータの削除
for (int index = registUserDataCount + 1; index <= maxUserDataCount + 3; index++) {
deleteUserDataWithLink(srcEntityTypeName, srcId, targetEntityTypeName, index);
}
}
}
/**
* $batchでONE対ASTのUserDataの$links登録_上限値以上の$linksが存在する場合登録できること.
* @throws ParseException リクエストボディのパースに失敗
*/
@Test
public final void $batchでONE対ASTのUserDataの$links登録_上限値以上の$linksが存在する場合登録できること()
throws ParseException {
try {
int index = registUserDataCount + 1;
// ベースデータ追加($linksの上限値まで登録)
for (; index <= maxUserDataCount; index++) {
String id = String.format("id%03d", index);
JSONObject body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + id + "\",\"name\":\"pochi\"}");
UserDataUtils.createViaNP(masterToken, body, cellName, boxName, colName,
parentEntityTypeName, srcId, childEntityTypeName, HttpStatus.SC_CREATED);
}
// ベースデータ追加($linksの上限値を超える分)
// target側
int linkedIndex = index;
for (; index <= maxUserDataCount + 3; index++) {
String id = String.format("id%03d", index);
JSONObject body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + id + "\",\"name\":\"pochi\"}");
UserDataUtils.create(masterToken, HttpStatus.SC_CREATED, body, cellName, boxName, colName,
childEntityTypeName);
}
// $batch
String path = parentEntityTypeName + "('" + srcId + "')/\\$links/_" + childEntityTypeName;
String body = "";
StringBuilder bodyBuilder = new StringBuilder();
for (; linkedIndex <= maxUserDataCount + 3; linkedIndex++) {
String linksBody = "{\"uri\":\""
+ UrlUtils.userdata(cellName, boxName, colName,
childEntityTypeName, String.format("id%03d", linkedIndex)) + "\"}";
bodyBuilder.append(START_BOUNDARY + retrieveLinksPostBody(HttpMethod.POST, path, linksBody));
}
bodyBuilder.append(END_BOUNDARY);
body = bodyBuilder.toString();
TResponse response = Http.request("box/odatacol/batch.txt")
.with("cell", cellName)
.with("box", boxName)
.with("collection", colName)
.with("boundary", BOUNDARY)
.with("token", DcCoreConfig.getMasterToken())
.with("body", body)
.returns()
.debug()
.statusCode(HttpStatus.SC_ACCEPTED);
// レスポンスボディのチェック
String expectedBody = START_BOUNDARY + retrieveLinksPostResBody()
+ START_BOUNDARY + retrieveLinksPostResBody()
+ START_BOUNDARY + retrieveLinksPostResBody() + END_BOUNDARY;
checkBatchResponseBody(response, expectedBody);
// 登録済み件数が増加していることのチェック
String query = String.format("?\\$top=%s&\\$inlinecount=allpages", 0);
response = Http.request("box/odatacol/list.txt")
.with("cell", cellName)
.with("box", boxName)
.with("collection", colName + "/" + parentEntityTypeName + "('" + srcId + "')")
.with("entityType", "_" + childEntityTypeName)
.with("query", query)
.with("accept", MediaType.APPLICATION_JSON)
.with("token", masterToken)
.returns()
.statusCode(HttpStatus.SC_OK)
.debug();
// レスポンスボディの件数のチェック
JSONArray results = (JSONArray) ((JSONObject) response.bodyAsJson().get("d")).get("results");
assertEquals(0, results.size());
// __countのチェック
ODataCommon.checkResponseBodyCount(response.bodyAsJson(), maxUserDataCount + 3);
} finally {
// 追加したデータの削除
for (int index = registUserDataCount + 1; index <= maxUserDataCount + 3; index++) {
deleteUserDataWithLink(parentEntityTypeName, srcId, childEntityTypeName, index);
}
}
}
/**
* 全テストの前に1度だけ実行する処理.
* @throws ParseException リクエストボディのパースに失敗
*/
@Before
public final void before() throws ParseException {
// 事前にデータを登録する
CellUtils.create(cellName, masterToken, HttpStatus.SC_CREATED);
BoxUtils.create(cellName, boxName, masterToken, HttpStatus.SC_CREATED);
DavResourceUtils.createODataCollection(masterToken, HttpStatus.SC_CREATED, cellName, boxName, colName);
// EntityType
EntityTypeUtils.create(cellName, masterToken, boxName, colName, srcEntityTypeName, HttpStatus.SC_CREATED);
EntityTypeUtils
.create(cellName, masterToken, boxName, colName, targetEntityTypeName, HttpStatus.SC_CREATED);
EntityTypeUtils.create(cellName, masterToken, boxName, colName, parentEntityTypeName, HttpStatus.SC_CREATED);
EntityTypeUtils.create(cellName, masterToken, boxName, colName, childEntityTypeName, HttpStatus.SC_CREATED);
// AssociationEnd
AssociationEndUtils.create(masterToken, "0..1", cellName, boxName, colName, HttpStatus.SC_CREATED,
parentAssociationEndName, parentEntityTypeName);
AssociationEndUtils.create(masterToken, "*", cellName, boxName, colName, HttpStatus.SC_CREATED,
childAssociationEndName, childEntityTypeName);
AssociationEndUtils.create(masterToken, "*", cellName, boxName, colName, HttpStatus.SC_CREATED,
srcAssociationEndName, srcEntityTypeName);
AssociationEndUtils.create(masterToken, "*", cellName, boxName, colName, HttpStatus.SC_CREATED,
targetAssociationEndName, targetEntityTypeName);
// AssociationEnd - AssociationEnd $links
AssociationEndUtils.createLink(AbstractCase.MASTER_TOKEN_NAME, cellName, boxName, colName,
parentEntityTypeName,
childEntityTypeName, parentAssociationEndName, childAssociationEndName, HttpStatus.SC_NO_CONTENT);
AssociationEndUtils.createLink(AbstractCase.MASTER_TOKEN_NAME, cellName, boxName, colName, srcEntityTypeName,
targetEntityTypeName, srcAssociationEndName, targetAssociationEndName, HttpStatus.SC_NO_CONTENT);
// 0..1:N関連
// src側(1)
JSONObject body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + srcId + "\",\"name\":\"pochi\"}");
UserDataUtils.create(masterToken, HttpStatus.SC_CREATED, body,
cellName, boxName, colName, parentEntityTypeName);
// target側(*)
for (int i = 1; i <= registUserDataCount; i++) {
String id = String.format("id%03d", i);
body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + id + "\",\"name\":\"pochi\"}");
UserDataUtils.createViaNP(masterToken, body, cellName, boxName, colName,
parentEntityTypeName, srcId, childEntityTypeName, HttpStatus.SC_CREATED);
}
// N:N関連
// src側(*)
body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + srcId + "\",\"name\":\"pochi\"}");
UserDataUtils.create(masterToken, HttpStatus.SC_CREATED, body,
cellName, boxName, colName, srcEntityTypeName);
// target側(*)
for (int i = 1; i <= registUserDataCount; i++) {
String id = String.format("id%03d", i);
body = (JSONObject) (new JSONParser()).parse("{\"__id\":\"" + id + "\",\"name\":\"pochi\"}");
UserDataUtils.createViaNP(masterToken, body, cellName, boxName, colName,
srcEntityTypeName, srcId, targetEntityTypeName, HttpStatus.SC_CREATED);
}
}
/**
* 全テストの後に1度だけ実行する処理.
*/
@After
public final void after() {
// Cellの再帰的削除
Setup.cellBulkDeletion(cellName);
}
private void deleteUserDataWithLink(
String srcEntityType,
String srcUserDataId,
String targetEntityType,
int index) {
String id = String.format("id%03d", index);
UserDataUtils.deleteLinks(cellName, boxName, colName,
srcEntityType, srcUserDataId, targetEntityType, id, -1);
UserDataUtils.delete(masterToken, -1, cellName, boxName, colName, targetEntityType, id);
}
private void checkLinkCount(String srcEntityType, String srcUserDataId, String targetEntityType, int expectCount) {
TResponse response;
String query = String.format("?\\$top=%s&\\$inlinecount=allpages", 0);
response = Http.request("box/odatacol/list.txt").with("cell", cellName).with("box", boxName)
.with("collection", colName + "/" + srcEntityType + "('" + srcUserDataId + "')")
.with("entityType", "_" + targetEntityType).with("query", query)
.with("accept", MediaType.APPLICATION_JSON).with("token", masterToken).returns()
.statusCode(HttpStatus.SC_OK).debug();
// __countのチェック
ODataCommon.checkResponseBodyCount(response.bodyAsJson(), expectCount);
}
}