/* Copyright (c) 2012 LinkedIn Corp. 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.linkedin.restli.example.impl; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.testng.Assert; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.linkedin.restli.client.util.PatchGenerator; import com.linkedin.restli.common.HttpStatus; import com.linkedin.restli.common.PatchRequest; import com.linkedin.restli.example.EXIF; import com.linkedin.restli.example.LatLong; import com.linkedin.restli.example.Photo; import com.linkedin.restli.example.PhotoFormats; import com.linkedin.restli.internal.server.model.ResourceModel; import com.linkedin.restli.internal.server.model.RestLiAnnotationReader; import com.linkedin.restli.server.CreateResponse; import com.linkedin.restli.server.PagingContext; import com.linkedin.restli.server.UpdateResponse; import com.linkedin.restli.server.mock.SimpleBeanProvider; import com.linkedin.restli.server.resources.InjectResourceFactory; public class TestPhotoResource { private PhotoResource _res; private static Map<String, ResourceModel> buildResourceModels(Class<?>... rootResourceClasses) { final Map<String, ResourceModel> map = new HashMap<String, ResourceModel>(); for (Class<?> rootResourceClass : rootResourceClasses) { final ResourceModel model = RestLiAnnotationReader.processResource(rootResourceClass); map.put("/" + model.getName(), model); } return map; } private Long createPhoto() { // create a new photo and confirm photo ID return createPhoto("Test Photo"); } private Long createPhoto(String title) { return createPhoto(title, PhotoFormats.PNG); } private Long createPhoto(String title, PhotoFormats format) { final LatLong l = new LatLong().setLatitude(7.0f).setLongitude(27.0f); final EXIF e = new EXIF().setIsFlash(true).setLocation(l); final Photo p = new Photo().setTitle(title).setFormat(format).setExif(e); final CreateResponse cResp = _res.create(p); Assert.assertTrue(cResp.hasId()); return (Long) cResp.getId(); } // function annotated with @BeforeMethod will run once before each test starts @BeforeMethod public void initResource() { // the photo resource requires dependency injection to work // we use InjectResourceFactory from pegasus to manually inject the dependency SimpleBeanProvider beanProvider = new SimpleBeanProvider(); final PhotoDatabase photoDb = new PhotoDatabaseImpl(10); beanProvider.add("photoDb", photoDb); beanProvider.add("albumDb", new AlbumDatabaseImpl(10)); beanProvider.add("albumEntryDb", new AlbumEntryDatabaseImpl(photoDb, 3)); final InjectResourceFactory factory = new InjectResourceFactory(beanProvider); final Map<String, ResourceModel> pathRootResourceMap = buildResourceModels(PhotoResource.class); factory.setRootResources(pathRootResourceMap); _res = factory.create(PhotoResource.class); Assert.assertNotNull(_res); Assert.assertNotNull(_res.getDb()); } @Test public void testResourceGet() { // because the test function will take arbitrary order // always create a photo and operate on that photo for a test function final Long id = createPhoto(); // validate all data are correct final Photo p = _res.get(id); Assert.assertNotNull(p); Assert.assertEquals(p.getId(), id); Assert.assertTrue(p.hasExif()); final EXIF e = p.getExif(); Assert.assertTrue(e.hasLocation()); final LatLong l = e.getLocation(); Assert.assertEquals(l.getLatitude(), 7.0f); Assert.assertEquals(l.getLongitude(), 27.0f); } @Test public void testBatchGet() { final String[] titles = {"1","2","3"}; final long[] ids = new long[titles.length]; for (int i = 0; i < titles.length; i++) ids[i] = createPhoto(titles[i]); // validate all data are correct Set<Long> batchIds = new HashSet<Long>(); batchIds.add(ids[1]); batchIds.add(ids[2]); Map<Long, Photo> batchPhotos = _res.batchGet(batchIds); Assert.assertEquals(batchPhotos.size(), 2); for (int i = 1; i < titles.length; i++) // go through {1,2} { final Photo p = batchPhotos.get(ids[i]); Assert.assertNotNull(p); Assert.assertEquals(p.getTitle(), titles[i]); Assert.assertEquals(p.getId().longValue(), ids[i]); Assert.assertTrue(p.hasExif()); final EXIF e = p.getExif(); Assert.assertTrue(e.hasLocation()); final LatLong l = e.getLocation(); Assert.assertEquals(l.getLatitude(), 7.0f); Assert.assertEquals(l.getLongitude(), 27.0f); } } @Test public void testResourceUpdate() { final Long id = createPhoto(); final LatLong l1 = new LatLong().setLongitude(-27.0f); final EXIF e1 = new EXIF().setLocation(l1); final Photo p1 = new Photo().setExif(e1); final UpdateResponse uResp = _res.update(id, p1); Assert.assertEquals(uResp.getStatus(), HttpStatus.S_204_NO_CONTENT); // validate data is changed to correct value final Photo p2 = _res.get(id); Assert.assertNotNull(p2.hasExif()); final EXIF e2 = p2.getExif(); Assert.assertNotNull(e2.hasLocation()); final LatLong l2 = e2.getLocation(); Assert.assertEquals(l2.getLongitude(), -27.0f); } @Test public void testResourceDelete() { final Long id = createPhoto(); // validate response status code final UpdateResponse uResp = _res.delete(id); Assert.assertEquals(uResp.getStatus(), HttpStatus.S_204_NO_CONTENT); } @Test public void testResourcePartialUpdate() { final Long id = createPhoto("PartialTestPhoto"); final String newTitle = "The New Title"; final Photo p = new Photo().setTitle(newTitle); final PatchRequest<Photo> patch = PatchGenerator.diffEmpty(p); final UpdateResponse uResp = _res.update(id, patch); final Photo updatedPhoto = _res.get(id); Assert.assertEquals(updatedPhoto.getTitle(), newTitle); Assert.assertEquals(uResp.getStatus(), HttpStatus.S_202_ACCEPTED); } @Test public void testResourceFind() { _res.purge(); createPhoto("InEdible"); createPhoto("InEdible"); createPhoto("InEdible", PhotoFormats.BMP); final PagingContext pc = new PagingContext(0, 4); final PagingContext pc2 = new PagingContext(0, 2); final List<Photo> foundByTitle = _res.find(pc, "InEdible", null); Assert.assertEquals(foundByTitle.size(), 3); final List<Photo> foundByFormat = _res.find(pc, null, PhotoFormats.BMP); Assert.assertEquals(foundByFormat.size(), 1); final List<Photo> foundByTitleAndFormat = _res.find(pc, "InEdible", PhotoFormats.PNG); Assert.assertEquals(foundByTitleAndFormat.size(), 2); final List<Photo> foundTwo = _res.find(pc2, null, null); Assert.assertEquals(foundTwo.size(), 2); // testResourcePurge() assumes there is at least one photo createPhoto(); } @Test public void testResourcePurge() { // photo database is initialized to have 1 photo // at any time of the test, that initial photo should present for purge Assert.assertTrue(_res.purge() > 0); } }