/**
* 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 java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
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.setup.Setup;
import com.fujitsu.dc.test.unit.core.UrlUtils;
import com.fujitsu.dc.test.utils.DavResourceUtils;
import com.fujitsu.dc.test.utils.Http;
import com.fujitsu.dc.test.utils.TResponse;
import com.sun.jersey.test.framework.JerseyTest;
/**
* MKCOLのテスト.
*/
@RunWith(DcRunner.class)
@Category({Unit.class, Integration.class, Regression.class })
public class ServiceSourceTest extends JerseyTest {
String testcell = "testcell1";
String boxName = "box1";
String serviceColPath = "servicecol";
String srcPath = "servicecol/__src";
String resourcePath = "servicecol/__src/hello.js";
String jsSource = "function(request){return {status: 200,"
+ "headers: {\"Content-Type\":\"text/html\"},body: [\"hello world!\"]};}";
static final String MASTER_TOKEN = AbstractCase.MASTER_TOKEN_NAME;
/**
* コンストラクタ.
*/
public ServiceSourceTest() {
super("com.fujitsu.dc.core.rs");
}
/**
* ServiceSourceのPROPFINDで設定が取得できること.
*/
@Test
public final void ServiceSourceのPROPFINDで設定が取得できること() {
try {
// サービスコレクションの作成
Http.request("box/mkcol-service.txt")
.with("cellPath", "testcell1")
.with("path", serviceColPath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// サービスソースの取得(bodyあり)
Http.request("box/propfind-col-allprop.txt")
.with("path", srcPath)
.with("depth", "0")
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_MULTI_STATUS);
} finally {
// サービスコレクションの削除
deleteCollection(serviceColPath);
}
}
/**
* ServiceSource内のCollection作成が405になること.
*/
@Test
public final void ServiceSource内のCollection作成が405になること() {
try {
// サービスコレクションの作成
Http.request("box/mkcol-service.txt")
.with("cellPath", "testcell1")
.with("path", serviceColPath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// サービスソースコレクションに対してMKCOLを実施
Http.request("box/mkcol-normal.txt")
.with("cellPath", "testcell1")
.with("path", resourcePath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_METHOD_NOT_ALLOWED);
} finally {
// サービスコレクションの削除
deleteCollection(serviceColPath);
}
}
/**
* ServiceSourceにJavascriptファイルを登録ができること.
*/
@Test
public final void ServiceSourceにJavascriptファイルを登録ができること() {
try {
// サービスコレクションの作成
Http.request("box/mkcol-service.txt")
.with("cellPath", "testcell1")
.with("path", serviceColPath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// Javascriptソースをサービスソースに登録
Http.request("box/dav-put.txt")
.with("cellPath", "testcell1")
.with("path", resourcePath)
.with("contentType", "text/javascript")
.with("box", "box1")
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.with("source", jsSource)
.returns()
.statusCode(HttpStatus.SC_CREATED);
} finally {
// Jsソースの削除
DavResourceUtils.deleteWebDavFile("box/dav-delete.txt", Setup.TEST_CELL1, MASTER_TOKEN,
resourcePath, -1, Setup.TEST_BOX1);
// Collectionの削除
deleteCollection(serviceColPath);
}
}
/**
* ServiceSourceにJavascriptファイルを更新ができること.
*/
@Test
public final void ServiceSourceにJavascriptファイルを更新ができること() {
try {
// サービスコレクションの作成
Http.request("box/mkcol-service.txt")
.with("cellPath", "testcell1")
.with("path", serviceColPath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// Javascriptソースをサービスソースに登録
Http.request("box/dav-put.txt")
.with("cellPath", "testcell1")
.with("path", resourcePath)
.with("contentType", "text/javascript")
.with("box", "box1")
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.with("source", jsSource)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// 登録したJavascriptソースを更新
String updateSource = "function(request){return {status: 200,"
+ "headers: {\"Content-Type\":\"text/html\"},body: [\"hi world!\"]};}";
Http.request("box/dav-put.txt")
.with("cellPath", "testcell1")
.with("path", resourcePath)
.with("contentType", "text/javascript")
.with("box", "box1")
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.with("source", updateSource)
.returns()
.statusCode(HttpStatus.SC_NO_CONTENT);
// 更新したソースを取得して、変更が反映されていることを確認
TResponse response = Http.request("box/dav-get.txt")
.with("cellPath", "testcell1")
.with("path", resourcePath)
.with("box", "box1")
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_OK);
response.checkHeader(HttpHeaders.CONTENT_TYPE, "text/javascript");
assertEquals(updateSource, response.getBody().trim());
} finally {
// Jsソースの削除
DavResourceUtils.deleteWebDavFile("box/dav-delete.txt", Setup.TEST_CELL1, MASTER_TOKEN,
resourcePath, -1, Setup.TEST_BOX1);
// Collectionの削除
deleteCollection(serviceColPath);
}
}
/**
* ServiceSourceにJavascriptファイルを取得ができること.
*/
@Test
public final void ServiceSourceにJavascriptファイルを取得ができること() {
try {
// サービスコレクションの作成
Http.request("box/mkcol-service.txt")
.with("cellPath", "testcell1")
.with("path", serviceColPath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// Javascriptソースをサービスソースに登録
Http.request("box/dav-put.txt")
.with("cellPath", "testcell1")
.with("path", resourcePath)
.with("contentType", "text/javascript")
.with("box", "box1")
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.with("source", jsSource)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// Javascriptソースをサービスソースを取得
TResponse response = Http.request("box/dav-get.txt")
.with("cellPath", "testcell1")
.with("box", "box1")
.with("path", resourcePath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_OK);
response.checkHeader(HttpHeaders.CONTENT_TYPE, "text/javascript");
assertEquals(jsSource, response.getBody().trim());
} finally {
// Jsソースの削除
DavResourceUtils.deleteWebDavFile("box/dav-delete.txt", Setup.TEST_CELL1, MASTER_TOKEN,
resourcePath, -1, Setup.TEST_BOX1);
// Collectionの削除
deleteCollection(serviceColPath);
}
}
/**
* ServiceSourceの存在しないファイル取得が404になること.
*/
@Test
public final void ServiceSourceの存在しないファイル取得が404になること() {
try {
// サービスコレクションの作成
Http.request("box/mkcol-service.txt")
.with("cellPath", "testcell1")
.with("path", serviceColPath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// Javascriptソースをサービスソースを取得
Http.request("box/dav-get.txt")
.with("cellPath", "testcell1")
.with("path", resourcePath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.with("box", "box1")
.returns()
.statusCode(HttpStatus.SC_NOT_FOUND);
} finally {
// Jsソースの削除
DavResourceUtils.deleteWebDavFile("box/dav-delete.txt", Setup.TEST_CELL1, MASTER_TOKEN,
resourcePath, -1, Setup.TEST_BOX1);
// Collectionの削除
deleteCollection(serviceColPath);
}
}
/**
* ServiceSourceにJavascriptファイルを削除ができること.
*/
@Test
public final void ServiceSourceにJavascriptファイルを削除ができること() {
try {
// サービスコレクションの作成
Http.request("box/mkcol-service.txt")
.with("cellPath", "testcell1")
.with("path", serviceColPath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// Javascriptソースをサービスソースに登録
Http.request("box/dav-put.txt")
.with("cellPath", "testcell1")
.with("path", resourcePath)
.with("contentType", "text/javascript")
.with("box", "box1")
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.with("source", jsSource)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// Javascriptソースをサービスソースを削除
Http.request("box/dav-delete.txt")
.with("cellPath", "testcell1")
.with("path", resourcePath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.with("box", "box1")
.returns()
.statusCode(HttpStatus.SC_NO_CONTENT);
} finally {
// Jsソースの削除
DavResourceUtils.deleteWebDavFile("box/dav-delete.txt", Setup.TEST_CELL1, MASTER_TOKEN,
resourcePath, -1, Setup.TEST_BOX1);
// Collectionの削除
deleteCollection(serviceColPath);
}
}
/**
* ServiceSourceの存在しないファイル削除が404になること.
*/
@Test
public final void ServiceSourceの存在しないファイル削除が404になること() {
try {
// サービスコレクションの作成
Http.request("box/mkcol-service.txt")
.with("cellPath", "testcell1")
.with("path", serviceColPath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// Javascriptソースをサービスソースを削除
Http.request("box/dav-delete.txt")
.with("cellPath", "testcell1")
.with("path", resourcePath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.with("box", "box1")
.returns()
.statusCode(HttpStatus.SC_NOT_FOUND);
} finally {
// Jsソースの削除
DavResourceUtils.deleteWebDavFile("box/dav-delete.txt", Setup.TEST_CELL1, MASTER_TOKEN,
resourcePath, -1, Setup.TEST_BOX1);
// Collectionの削除
deleteCollection(serviceColPath);
}
}
/**
* ServiceSourceに登録したJavascriptファイルにPROPPATCHして設定追加できること.
*/
@Test
public final void ServiceSourceに登録したJavascriptファイルにPROPPATCHして設定追加できること() {
try {
// サービスコレクションの作成
Http.request("box/mkcol-service.txt")
.with("cellPath", "testcell1")
.with("path", serviceColPath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// Javascriptソースをサービスソースに登録
Http.request("box/dav-put.txt")
.with("cellPath", "testcell1")
.with("path", resourcePath)
.with("contentType", "text/javascript")
.with("box", "box1")
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.with("source", jsSource)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// プロパティの追加
Http.request("box/proppatch-set.txt")
.with("cell", "testcell1")
.with("box", "box1")
.with("path", resourcePath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.with("author1", "Test User1")
.with("hoge", "hoge")
.returns()
.statusCode(HttpStatus.SC_MULTI_STATUS);
// プロパティ変更の確認
TResponse tresponseWebDav = Http.request("box/propfind-col-allprop.txt")
.with("path", resourcePath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.with("depth", "0")
.returns()
.statusCode(HttpStatus.SC_MULTI_STATUS);
Element root = tresponseWebDav.bodyAsXml().getDocumentElement();
String resource = UrlUtils.box(testcell, boxName, resourcePath);
HashMap<String, String> map = new HashMap<String, String>();
map.put("Author", "Test User1");
map.put("hoge", "hoge");
checkProppatchResponse(root, resource, map);
} finally {
// Jsソースの削除
DavResourceUtils.deleteWebDavFile("box/dav-delete.txt", Setup.TEST_CELL1, MASTER_TOKEN,
resourcePath, -1, Setup.TEST_BOX1);
// Collectionの削除
deleteCollection(serviceColPath);
}
}
/**
* ServiceSourceに登録したJavascriptファイルにPROPPATCHして設定削除できること.
*/
@Test
public final void ServiceSourceに登録したJavascriptファイルにPROPPATCHして設定削除できること() {
try {
// サービスコレクションの作成
Http.request("box/mkcol-service.txt")
.with("cellPath", "testcell1")
.with("path", serviceColPath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// Javascriptソースをサービスソースに登録
Http.request("box/dav-put.txt")
.with("cellPath", "testcell1")
.with("path", resourcePath)
.with("contentType", "text/javascript")
.with("box", "box1")
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.with("source", jsSource)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// プロパティの追加
Http.request("box/proppatch-set.txt")
.with("cell", "testcell1")
.with("box", "box1")
.with("path", resourcePath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.with("author1", "Test User1")
.with("hoge", "hoge")
.returns()
.statusCode(HttpStatus.SC_MULTI_STATUS);
// プロパティの削除
Http.request("box/proppatch-remove.txt")
.with("path", resourcePath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_MULTI_STATUS);
// プロパティの削除確認
TResponse tresponseWebDav =
Http.request("box/propfind-col-allprop.txt")
.with("path", resourcePath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.with("depth", "0")
.returns()
.statusCode(HttpStatus.SC_MULTI_STATUS);
Element root = tresponseWebDav.bodyAsXml().getDocumentElement();
String resource = UrlUtils.box(testcell, boxName, resourcePath);
HashMap<String, String> map = new HashMap<String, String>();
map.put("Author", null);
map.put("hoge", null);
checkProppatchResponse(root, resource, map);
} finally {
// Jsソースの削除
DavResourceUtils.deleteWebDavFile("box/dav-delete.txt", Setup.TEST_CELL1, MASTER_TOKEN,
resourcePath, -1, Setup.TEST_BOX1);
// Collectionの削除
deleteCollection(serviceColPath);
}
}
/**
* ServiceSourceの存在しない階層パス指定で404が返却されること.
*/
@Test
public final void ServiceSourceの存在しない階層パス指定で404が返却されること() {
try {
// サービスコレクションの作成
Http.request("box/mkcol-service.txt")
.with("cellPath", "testcell1")
.with("path", serviceColPath)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_CREATED);
// Javascriptソースをサービスソースを取得
Http.request("box/dav-get.txt")
.with("cellPath", "testcell1")
.with("path", srcPath + "/test/test/test.js")
.with("box", "box1")
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_NOT_FOUND);
} finally {
// Boxの削除
deleteCollection(serviceColPath);
}
}
/**
* CollectionDELETEの実行.
*/
private void deleteCollection(final String path) {
// Boxの削除
Http.request("box/delete-col.txt")
.with("cellPath", "testcell1")
.with("path", path)
.with("token", AbstractCase.MASTER_TOKEN_NAME)
.returns()
.statusCode(HttpStatus.SC_NO_CONTENT);
}
/**
* PROPPATCHの返却値のチェック関数.
* @param doc 解析するXMLオブジェクト
* @param resorce PROPPATCHを設定したリソースパス
* @param map チェックするプロパティのKeyValue
* KeyとValueに値を入れれば値があることのチェック
* ValueをnullにするとKeyが無いことのチェック(removeの確認に使う)
*/
private void checkProppatchResponse(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);
}
}
}