/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <hr>
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* This file has been modified by the OpenOLAT community. Changes are licensed
* under the Apache 2.0 license as the original file.
* <p>
*/
package org.olat.restapi;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.util.EntityUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.olat.basesecurity.GroupRoles;
import org.olat.collaboration.CollaborationTools;
import org.olat.collaboration.CollaborationToolsFactory;
import org.olat.core.CoreSpringFactory;
import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
import org.olat.core.commons.persistence.DBFactory;
import org.olat.core.id.Identity;
import org.olat.core.id.OLATResourceable;
import org.olat.core.util.FileUtils;
import org.olat.core.util.resource.OresHelper;
import org.olat.core.util.vfs.VFSContainer;
import org.olat.core.util.vfs.VFSLeaf;
import org.olat.group.BusinessGroup;
import org.olat.group.BusinessGroupService;
import org.olat.group.manager.BusinessGroupRelationDAO;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryService;
import org.olat.resource.OLATResource;
import org.olat.resource.OLATResourceManager;
import org.olat.restapi.support.vo.FileMetadataVO;
import org.olat.restapi.support.vo.FileVO;
import org.olat.test.JunitTestHelper;
import org.olat.test.OlatJerseyTestCase;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Description:<br>
*
* <P>
* Initial Date: 5 avr. 2011 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class GroupFoldersTest extends OlatJerseyTestCase {
private Identity owner1, owner2, part1, part2;
private BusinessGroup g1, g2;
private OLATResource course;
private RestConnection conn;
@Autowired
private RepositoryService repositoryService;
@Autowired
private BusinessGroupService businessGroupService;
@Autowired
private BusinessGroupRelationDAO businessGroupRelationDao;
/**
* Set up a course with learn group and group area
* EXACTLY THE SAME AS GroupMgmTest
* @see org.olat.test.OlatJerseyTestCase#setUp()
*/
@Before
@Override
public void setUp() throws Exception {
super.setUp();
conn = new RestConnection();
//create a course with learn group
owner1 = JunitTestHelper.createAndPersistIdentityAsUser("rest-one");
owner2 = JunitTestHelper.createAndPersistIdentityAsUser("rest-two");
part1 = JunitTestHelper.createAndPersistIdentityAsUser("rest-four");
part2 = JunitTestHelper.createAndPersistIdentityAsUser("rest-five");
// create course and persist as OLATResourceImpl
OLATResourceable resourceable = OresHelper.createOLATResourceableInstance("junitcourse",System.currentTimeMillis());
course = OLATResourceManager.getInstance().findOrPersistResourceable(resourceable);
RepositoryService rs = CoreSpringFactory.getImpl(RepositoryService.class);
RepositoryEntry re = rs.create("administrator", "-", "rest-re", null, course);
repositoryService.update(re);
DBFactory.getInstance().commit();
//create learn group
// 1) context one: learning groups
RepositoryEntry c1 = JunitTestHelper.createAndPersistRepositoryEntry();
// create groups without waiting list
g1 = businessGroupService.createBusinessGroup(null, "rest-g1", null, 0, 10, false, false, c1);
g2 = businessGroupService.createBusinessGroup(null, "rest-g2", null, 0, 10, false, false, c1);
DBFactory.getInstance().commitAndCloseSession();
//permission to see owners and participants
businessGroupService.updateDisplayMembers(g1, false, false, false, false, false, false, false);
businessGroupService.updateDisplayMembers(g2, true, true, false, false, false, false, false);
// members g1
businessGroupRelationDao.addRole(owner1, g1, GroupRoles.coach.name());
businessGroupRelationDao.addRole(owner2, g1, GroupRoles.coach.name());
businessGroupRelationDao.addRole(part1, g1, GroupRoles.participant.name());
businessGroupRelationDao.addRole(part2, g1, GroupRoles.participant.name());
// members g2
businessGroupRelationDao.addRole(owner1, g2, GroupRoles.coach.name());
businessGroupRelationDao.addRole(part1, g2, GroupRoles.participant.name());
//3) collaboration tools
CollaborationTools collabTools1 = CollaborationToolsFactory.getInstance().getOrCreateCollaborationTools(g1);
collabTools1.setToolEnabled(CollaborationTools.TOOL_FOLDER, true);
CollaborationTools collabTools2 = CollaborationToolsFactory.getInstance().getOrCreateCollaborationTools(g2);
collabTools2.setToolEnabled(CollaborationTools.TOOL_FOLDER, true);
DBFactory.getInstance().commitAndCloseSession(); // simulate user clicks
}
@After
public void tearDown() throws Exception {
try {
if(conn != null) {
conn.shutdown();
}
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testGetFolder() throws IOException, URISyntaxException {
assertTrue(conn.login("rest-one", "A6B7C8"));
URI request = UriBuilder.fromUri(getContextURI()).path("/groups/" + g1.getKey() + "/folder").build();
HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true);
HttpResponse response = conn.execute(method);
assertEquals(200, response.getStatusLine().getStatusCode());
InputStream body = response.getEntity().getContent();
assertNotNull(body);
}
@Test
public void testGetSubFolder() throws IOException, URISyntaxException {
//create some sub folders
CollaborationTools collabTools1 = CollaborationToolsFactory.getInstance().getOrCreateCollaborationTools(g1);
String folderRelPath = collabTools1.getFolderRelPath();
OlatRootFolderImpl folder = new OlatRootFolderImpl(folderRelPath, null);
VFSContainer newFolder1 = folder.createChildContainer("New folder 1");
if(newFolder1 == null) {
newFolder1 = (VFSContainer)folder.resolve("New folder 1");
}
assertNotNull(newFolder1);
VFSContainer newFolder11 = newFolder1.createChildContainer("New folder 1_1");
if(newFolder11 == null) {
newFolder11 = (VFSContainer)newFolder1.resolve("New folder 1_1");
}
assertNotNull(newFolder11);
assertTrue(conn.login("rest-one", "A6B7C8"));
//get root folder
URI request0 = UriBuilder.fromUri(getContextURI()).path("/groups/" + g1.getKey() + "/folder/").build();
HttpGet method0 = conn.createGet(request0, MediaType.APPLICATION_JSON, true);
HttpResponse code0 = conn.execute(method0);
assertEquals(200, code0.getStatusLine().getStatusCode());
InputStream body0 = code0.getEntity().getContent();
assertNotNull(body0);
List<FileVO> fileVos0 = parseFileArray(body0);
assertNotNull(fileVos0);
assertEquals(1, fileVos0.size());
//get sub folder
URI request1 = UriBuilder.fromUri(getContextURI()).path("/groups/" + g1.getKey() + "/folder/New_folder_1").build();
HttpGet method1 = conn.createGet(request1, MediaType.APPLICATION_JSON, true);
HttpResponse code1 = conn.execute(method1);
assertEquals(200, code1.getStatusLine().getStatusCode());
InputStream body1 = code1.getEntity().getContent();
assertNotNull(body1);
List<FileVO> fileVos1 = parseFileArray(body1);
assertNotNull(fileVos1);
assertEquals(1, fileVos1.size());
//get sub folder by link
FileVO fileVO = fileVos1.get(0);
URI fileUri = new URI(fileVO.getHref());
HttpGet brutMethod = conn.createGet(fileUri, "*/*", true);
brutMethod.addHeader("Accept", MediaType.APPLICATION_JSON);
HttpResponse codeBrut = conn.execute(brutMethod);
assertEquals(200, codeBrut.getStatusLine().getStatusCode());
EntityUtils.consume(codeBrut.getEntity());
// get sub sub folder
URI request2 = UriBuilder.fromUri(getContextURI()).path("/groups/" + g1.getKey() + "/folder/New_folder_1/New_folder_1_1").build();
HttpGet method2 = conn.createGet(request2, MediaType.APPLICATION_JSON, true);
HttpResponse code2 = conn.execute(method2);
assertEquals(200, code2.getStatusLine().getStatusCode());
InputStream body2 = code2.getEntity().getContent();
assertNotNull(body2);
EntityUtils.consume(code2.getEntity());
//get sub folder with end /
URI request3 = UriBuilder.fromUri(getContextURI()).path("/groups/" + g1.getKey() + "/folder/New_folder_1/").build();
HttpGet method3 = conn.createGet(request3, MediaType.APPLICATION_JSON, true);
HttpResponse code3 = conn.execute(method3);
assertEquals(200, code3.getStatusLine().getStatusCode());
InputStream body3 = code3.getEntity().getContent();
assertNotNull(body3);
List<FileVO> fileVos3 = parseFileArray(body3);
assertNotNull(fileVos3);
assertEquals(1, fileVos3.size());
}
@Test
public void testGetFile() throws IOException, URISyntaxException {
//create some sub folders and copy file
CollaborationTools collabTools2 = CollaborationToolsFactory.getInstance().getOrCreateCollaborationTools(g2);
String folderRelPath = collabTools2.getFolderRelPath();
OlatRootFolderImpl folder = new OlatRootFolderImpl(folderRelPath, null);
VFSContainer newFolder1 = folder.createChildContainer("New folder 2");
if(newFolder1 == null) {
newFolder1 = (VFSContainer)folder.resolve("New folder 2");
}
VFSLeaf file = (VFSLeaf)newFolder1.resolve("portrait.jpg");
if(file == null) {
file = newFolder1.createChildLeaf("portrait.jpg");
OutputStream out = file.getOutputStream(true);
InputStream in = GroupFoldersTest.class.getResourceAsStream("portrait.jpg");
FileUtils.copy(in, out);
FileUtils.closeSafely(in);
FileUtils.closeSafely(out);
}
// get the file
assertTrue(conn.login("rest-one", "A6B7C8"));
URI request = UriBuilder.fromUri(getContextURI()).path("/groups/" + g2.getKey() + "/folder/New_folder_2/portrait.jpg").build();
HttpGet method = conn.createGet(request, "*/*", true);
HttpResponse response = conn.execute(method);
assertEquals(200, response.getStatusLine().getStatusCode());
InputStream body = response.getEntity().getContent();
byte[] byteArr = IOUtils.toByteArray(body);
Assert.assertNotNull(byteArr);
Assert.assertEquals(file.getSize(), byteArr.length);
}
@Test
public void testGetFileMetadata() throws IOException, URISyntaxException {
//create some sub folders and copy file
CollaborationTools collabTools2 = CollaborationToolsFactory.getInstance().getOrCreateCollaborationTools(g2);
String folderRelPath = collabTools2.getFolderRelPath();
OlatRootFolderImpl folder = new OlatRootFolderImpl(folderRelPath, null);
VFSContainer newFolder1 = folder.createChildContainer("Metadata folder");
if(newFolder1 == null) {
newFolder1 = (VFSContainer)folder.resolve("Metadata folder");
}
VFSLeaf file = (VFSLeaf)newFolder1.resolve("portrait.jpg");
if(file == null) {
file = newFolder1.createChildLeaf("portrait.jpg");
OutputStream out = file.getOutputStream(true);
InputStream in = GroupFoldersTest.class.getResourceAsStream("portrait.jpg");
FileUtils.copy(in, out);
FileUtils.closeSafely(in);
FileUtils.closeSafely(out);
}
// get the file
assertTrue(conn.login("rest-one", "A6B7C8"));
URI request = UriBuilder.fromUri(getContextURI()).path("/groups/" + g2.getKey() + "/folder/metadata/Metadata_folder/portrait.jpg").build();
HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true);
HttpResponse response = conn.execute(method);
assertEquals(200, response.getStatusLine().getStatusCode());
FileMetadataVO fileMetadataVO = conn.parse(response, FileMetadataVO.class);
Assert.assertNotNull(fileMetadataVO);
Assert.assertEquals("portrait.jpg", fileMetadataVO.getFileName());
Assert.assertNotNull(fileMetadataVO.getSize());
Assert.assertEquals(file.getSize(), fileMetadataVO.getSize().longValue());
Assert.assertNotNull(fileMetadataVO.getHref());
Assert.assertNotNull(fileMetadataVO.getLastModified());
}
@Test
public void testCreateFolder() throws IOException, URISyntaxException {
assertTrue(conn.login("rest-one", "A6B7C8"));
URI request = UriBuilder.fromUri(getContextURI()).path("/groups/" + g1.getKey() + "/folder/New_folder_1/New_folder_1_1/New_folder_1_1_1").build();
HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
HttpResponse response = conn.execute(method);
InputStream body = response.getEntity().getContent();
assertEquals(200, response.getStatusLine().getStatusCode());
assertNotNull(body);
}
//@Test not working -> Jersey ignore the request and return 200 (why?)
public void testCreateFoldersWithSpecialCharacter() throws IOException, URISyntaxException {
assertTrue(conn.login("rest-one", "A6B7C8"));
URI request = UriBuilder.fromUri(getContextURI()).path("/groups/" + g1.getKey() + "/folder/New_folder_1/New_folder_1_1/New_folder_1 1 2").build();
HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
HttpResponse response = conn.execute(method);
assertEquals(200, response.getStatusLine().getStatusCode());
FileVO file = conn.parse(response, FileVO.class);
assertNotNull(file);
}
@Test
public void testCreateFoldersWithSpecialCharacter2() throws IOException, URISyntaxException {
assertTrue(conn.login("rest-one", "A6B7C8"));
URI request = UriBuilder.fromUri(getContextURI()).path("/groups/" + g1.getKey() + "/folder/New_folder_1/New_folder_1_1/").build();
HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
HttpEntity entity = MultipartEntityBuilder.create()
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
.addTextBody("foldername", "New folder 1 2 3")
.build();
method.setEntity(entity);
HttpResponse response = conn.execute(method);
assertEquals(200, response.getStatusLine().getStatusCode());
FileVO file = conn.parse(response, FileVO.class);
assertNotNull(file);
assertNotNull(file.getHref());
assertNotNull(file.getTitle());
assertEquals("New folder 1 2 3", file.getTitle());
}
protected <T> T parse(InputStream body, Class<T> cl) {
try {
ObjectMapper mapper = new ObjectMapper(jsonFactory);
T obj = mapper.readValue(body, cl);
return obj;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
protected List<FileVO> parseFileArray(InputStream body) {
try {
ObjectMapper mapper = new ObjectMapper(jsonFactory);
return mapper.readValue(body, new TypeReference<List<FileVO>>(){/* */});
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}