/* * Copyright (c) 2009 Lockheed Martin Corporation * * 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 org.eurekastreams.server.service.restlets; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.UUID; import net.sf.json.JSONObject; import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.integration.junit4.JUnit4Mockery; import org.jmock.lib.legacy.ClassImposteriser; import org.junit.Before; import org.junit.Test; import org.restlet.Context; import org.restlet.data.MediaType; import org.restlet.data.Request; import org.restlet.data.Response; import org.restlet.data.Status; import org.restlet.resource.Representation; import org.restlet.resource.ResourceException; import org.restlet.resource.Variant; import org.eurekastreams.server.domain.Job; import org.eurekastreams.server.domain.Person; import org.eurekastreams.server.persistence.JobMapper; /** * Test class for JobEntryResource. */ public class JobEntryResourceTest { /** * Subject under test. */ private JobsEntryResource sut; /** * Context for building mock objects. */ private final Mockery context = new JUnit4Mockery() { { setImposteriser(ClassImposteriser.INSTANCE); } }; /** * Mocked restlet context. */ private Context restContext = context.mock(Context.class); /** * Mocked request. */ private Request request = context.mock(Request.class); /** * Mocked response. */ private Response response = context.mock(Response.class); /** * Mocked ResponseAdapter. */ private ResponseAdapter adaptedResponse = context.mock(ResponseAdapter.class); /** * Mocked job mapper. */ private JobMapper jobMapper = context.mock(JobMapper.class); /** * UUID to represent a Person. Arbitrary. */ private String uuid = UUID.randomUUID().toString(); /** * A job id for testing. Arbitrary. */ private static final Long JOB_ID = 235L; /** * The starting date for the job. */ private static Date dateFrom; /** * The ending date for the job. */ private static Date dateTo; /** * Company name value for tests. */ private static final String COMPANY_NAME = "company name"; /** * Industry for tests. */ private static final String INDUSTRY = "industry"; /** * Job title for tests. */ private static final String TITLE = "engineer"; /** * Job description for tests. */ private static final String DESCRIPTION = "this that and the other thing"; /** * Job from month for tests. */ private static final String FROM_MONTH = "01"; /** * Job from year for tests. */ private static final String FROM_YEAR = "2008"; /** * Job to year for tests. */ private static final String TO_YEAR_PRESENT = ""; /** * Job to year for tests. */ private static final String TO_YEAR = "2009"; /** * Job to month for tests. */ private static final String TO_MONTH_PRESENT = ""; /** * Job to month for tests. */ private static final String TO_MONTH = "03"; /** * Set up the SUT. * * @throws ParseException * should not occur. */ @Before public void setup() throws ParseException { final Map<String, Object> attributes = new HashMap<String, Object>(); attributes.put("uuid", uuid); attributes.put("jobId", JOB_ID.toString()); final DateFormat df = new SimpleDateFormat("MM/yyyy"); dateFrom = df.parse(FROM_MONTH + "/" + FROM_YEAR); dateTo = df.parse(TO_MONTH + "/" + TO_YEAR); context.checking(new Expectations() { { allowing(request).getAttributes(); will(returnValue(attributes)); } }); sut = new JobsEntryResource(); sut.init(restContext, request, response); sut.setJobMapper(jobMapper); sut.setAdaptedResponse(adaptedResponse); } /** * Test the GET call. * * @throws ResourceException * not expected * @throws IOException * not expected * @throws ParseException * not expected */ @Test public void represent() throws ResourceException, IOException, ParseException { DateFormat df = new SimpleDateFormat("dd/MM/yyyy"); final Variant variant = context.mock(Variant.class); final Job job = context.mock(Job.class); final Date fullDateFrom = df.parse("0/01/2008"); final Date fullDateTo = df.parse("0/01/2009"); context.checking(new Expectations() { { oneOf(jobMapper).findById(JOB_ID); will(returnValue(job)); oneOf(job).getId(); will(returnValue(JOB_ID)); oneOf(job).getCompanyName(); will(returnValue(COMPANY_NAME)); oneOf(job).getIndustry(); will(returnValue(INDUSTRY)); oneOf(job).getTitle(); will(returnValue(TITLE)); oneOf(job).getDateFrom(); will(returnValue(fullDateFrom)); oneOf(job).getDateTo(); will(returnValue(fullDateTo)); oneOf(job).getDescription(); will(returnValue(DESCRIPTION)); } }); Representation actual = sut.represent(variant); assertEquals("MediaType doesn't match", MediaType.APPLICATION_JSON, actual.getMediaType()); JSONObject json = JSONObject.fromObject(actual.getText()); String actualCompanyName = (String) json.get(JobsEntryResource.COMPANY_NAME_KEY); assertTrue("Got a wrong job", actualCompanyName.equals(COMPANY_NAME)); context.assertIsSatisfied(); } /** * Test the PUT functionality. * * @throws ResourceException * not expected * @throws IOException * not expected * @throws ParseException * not expected */ @Test public void storeRepresentation() throws ResourceException, IOException, ParseException { Representation entity = setupPUTExpectations(false); context.checking(new Expectations() { { oneOf(jobMapper).flush(uuid); } }); sut.storeRepresentation(entity); context.assertIsSatisfied(); } /** * Test the PUT functionality when the client does not provide a closing date. * * @throws ResourceException * not expected * @throws IOException * not expected * @throws ParseException * not expected */ @Test public void storeRepresentationForPresentJob() throws ResourceException, IOException, ParseException { Representation entity = setupPUTExpectations(true); context.checking(new Expectations() { { oneOf(jobMapper).flush(uuid); } }); sut.storeRepresentation(entity); context.assertIsSatisfied(); } /** * Set up the expectations common to the two PUT tests. * * @param present * toggle to switch the expectations for testing a job that is current. * @return a representation to pass to the storeRepresentation method * @throws IOException * not expected */ private Representation setupPUTExpectations(final boolean present) throws IOException { final Job job = context.mock(Job.class); final Person owner = context.mock(Person.class); final Representation entity = context.mock(Representation.class); final String json = buildJSONString(present); context.checking(new Expectations() { { oneOf(jobMapper).findById(JOB_ID); will(returnValue(job)); oneOf(entity).getText(); will(returnValue(json)); oneOf(job).getOwner(); will(returnValue(owner)); oneOf(job).setCompanyName(COMPANY_NAME); oneOf(job).setIndustry(INDUSTRY); oneOf(job).setTitle(TITLE); oneOf(job).setDateFrom(dateFrom); oneOf(job).setDateTo((present ? null : dateTo)); oneOf(job).setDescription(DESCRIPTION); oneOf(job).getId(); will(returnValue(JOB_ID)); oneOf(job).getCompanyName(); will(returnValue(COMPANY_NAME)); oneOf(job).getIndustry(); will(returnValue(INDUSTRY)); oneOf(job).getTitle(); will(returnValue(TITLE)); oneOf(job).getDateFrom(); will(returnValue(dateFrom)); oneOf(job).getDateTo(); will(returnValue((present ? null : dateTo))); oneOf(job).getDescription(); will(returnValue(DESCRIPTION)); oneOf(adaptedResponse).setEntity(json, MediaType.APPLICATION_JSON); } }); return entity; } /** * Build up the JSON string that the storeRepresentation method will interpret. * * @param presentJob * toggle to change the json to a job that is current for testing. * @return a JSON string representing the input data */ private String buildJSONString(final boolean presentJob) { JSONObject jsonJob = new JSONObject(); jsonJob.put(JobsResource.JOB_ID_KEY, JOB_ID); jsonJob.put(JobsResource.COMPANY_NAME_KEY, COMPANY_NAME); jsonJob.put(JobsResource.INDUSTRY_KEY, INDUSTRY); jsonJob.put(JobsResource.TITLE_KEY, TITLE); jsonJob.put(JobsResource.DATE_FROM_YEAR_KEY, FROM_YEAR); jsonJob.put(JobsResource.DATE_FROM_MONTH_KEY, FROM_MONTH); jsonJob.put(JobsResource.DATE_TO_YEAR_KEY, presentJob ? TO_YEAR_PRESENT : TO_YEAR); jsonJob.put(JobsResource.DATE_TO_MONTH_KEY, presentJob ? TO_MONTH_PRESENT : TO_MONTH); jsonJob.put(JobsResource.DESCRIPTION_KEY, DESCRIPTION); return jsonJob.toString(); } /** * Test the PUT functionality when the provided job id does not correspond to a job in the db. Should throw a * ResourceException with a 404. * * @throws ResourceException * not expected * @throws IOException * not expected * @throws ParseException * not expected */ @Test public void storeRepresentationWithBadId() throws ResourceException, IOException, ParseException { final Representation entity = context.mock(Representation.class); context.checking(new Expectations() { { oneOf(jobMapper).findById(JOB_ID); will(returnValue(null)); } }); try { sut.storeRepresentation(entity); fail("Should have thrown exception"); } catch (ResourceException ex) { assertEquals(Status.CLIENT_ERROR_NOT_FOUND, ex.getStatus()); } context.assertIsSatisfied(); } /** * Test the DELETE functionality. * */ @Test public void removeRepresentations() { context.checking(new Expectations() { { oneOf(jobMapper).delete(JOB_ID); oneOf(jobMapper).flush(uuid); } }); sut.removeRepresentations(); context.assertIsSatisfied(); } }