/* * Copyright 2013 Hewlett-Packard Development Company, L.P * * 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.hp.alm.ali.idea.services; import com.hp.alm.ali.Handler; import com.hp.alm.ali.Isolated; import com.hp.alm.ali.ServerVersion; import com.hp.alm.ali.idea.IntellijTest; import com.hp.alm.ali.idea.RestInvocations; import com.hp.alm.ali.idea.entity.EntityListener; import com.hp.alm.ali.idea.entity.EntityRef; import com.hp.alm.ali.idea.model.Entity; import com.hp.alm.ali.idea.model.parser.EntityList; import com.hp.alm.ali.idea.rest.RestService; import com.hp.alm.ali.idea.rest.ServerType; import com.intellij.openapi.application.ApplicationManager; import org.jdom.Element; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; @Isolated // Current release manipulation introduces various side-effects, better avoid the headache. public class SprintServiceTest extends IntellijTest { private SprintService sprintService; private MetadataService metadataService; private MetadataSimpleService metadataSimpleService; public SprintServiceTest() { super(ServerVersion.AGM); } @Before public void preClean() throws Throwable { sprintService = getComponent(SprintService.class); metadataService = getComponent(MetadataService.class); metadataSimpleService = getComponent(MetadataSimpleService.class); } @Test public void testGetState() throws Throwable { selectTestRelease(); Element state = sprintService.getState(); Assert.assertEquals("SprintService", state.getName()); Assert.assertEquals("1001", state.getAttributeValue("release-id")); Assert.assertEquals("Test Release", state.getAttributeValue("release-name")); Assert.assertEquals("1002", state.getAttributeValue("release-cycle-id")); Assert.assertEquals("Sprint 2", state.getAttributeValue("release-cycle-name")); Assert.assertEquals("101", state.getAttributeValue("team-id")); Assert.assertEquals("The Team", state.getAttributeValue("team-name")); } @Test public void testGetState_None() throws Throwable { Element state = sprintService.getState(); Assert.assertEquals("SprintService", state.getName()); Assert.assertNull(state.getAttributeValue("release-id")); Assert.assertNull(state.getAttributeValue("release-name")); Assert.assertNull(state.getAttributeValue("release-cycle-id")); Assert.assertNull(state.getAttributeValue("release-cycle-name")); Assert.assertNull(state.getAttributeValue("team-id")); Assert.assertNull(state.getAttributeValue("team-name")); } @Test public void testLoadState() throws Throwable { sprintTeamRequests_TestRelease(handler); WaitForEventsListener listener = new WaitForEventsListener(sprintService); Element state = new Element("SprintService"); state.setAttribute("release-id", "1001"); state.setAttribute("release-name", "Test Release"); state.setAttribute("release-cycle-id", "1001"); state.setAttribute("release-cycle-name", "Sprint 1"); state.setAttribute("team-id", "101"); state.setAttribute("team-name", "The Team"); sprintService.loadState(state); handler.consume(); listener.waitForEvents(1001, 1001, 101); Assert.assertEquals(1001, sprintService.getRelease().getId()); Assert.assertEquals(1001, sprintService.getSprint().getId()); Assert.assertEquals(101, sprintService.getTeam().getId()); } @Test public void testLoadState_None() throws Throwable { selectTestRelease(); WaitForEventsListener listener = new WaitForEventsListener(sprintService); Element state = new Element("SprintService"); sprintService.loadState(state); listener.waitForEvents(null, null, null); Assert.assertNull(sprintService.getRelease()); Assert.assertNull(sprintService.getSprint()); Assert.assertNull(sprintService.getTeam()); } @Test public void testConnectedTo() throws Throwable { selectTestRelease(); RestInvocations.getAuthenticationInfo(handler); releaseSprintTeamRequests_TestRelease(handler); // re-connecting triggers data reload getComponent(RestService.class).setServerType(ServerType.AGM); handler.consume(); } @Test public void testSelectRelease() throws Throwable { WaitForEventsListener listener = new WaitForEventsListener(sprintService); sprintTeamRequests_TestRelease(handler); // sprint and team are retrieved and selected sprintService.selectRelease(new Entity("release", 1001)); listener.waitForEvents(1001, 1002, 101); } @Test public void testSelectRelease_None() throws Throwable { selectTestRelease(); WaitForEventsListener listener = new WaitForEventsListener(sprintService); // sprint and team are cleared too sprintService.selectRelease(null); listener.waitForEvents(null, null, null); } @Test public void testSelectSprint() throws Throwable { selectTestRelease(); WaitForEventsListener listener = new WaitForEventsListener(sprintService, false, true, false); sprintService.selectSprint(new Entity("release-cycle", 1001)); listener.waitForEvents(null, 1001, null); } @Test public void testSelectTeam() throws Throwable { selectTestRelease(); WaitForEventsListener listener = new WaitForEventsListener(sprintService, false, false, true); sprintService.selectTeam(new Entity("team", 102)); listener.waitForEvents(null, null, 102); } @Test public void testGetReleases() throws Throwable { sprintService.resetValues(); releaseSprintTeamRequests_TestRelease(handler); for(int i = 0; i < 3; i++) { handler.async(); ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { @Override public void run() { final EntityList releases = sprintService.getReleases(); handler.done(new Runnable() { @Override public void run() { Assert.assertEquals(2, releases.size()); Assert.assertEquals(1001, releases.get(0).getId()); Assert.assertEquals(1000, releases.get(1).getId()); } }); } }); } handler.consume(); } @Test public void testGetSprints() throws Throwable { selectTestRelease(); sprintService.resetValues(); sprintRequests_TestRelease(handler); for(int i = 0; i < 3; i++) { handler.async(); ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { @Override public void run() { final EntityList sprints = sprintService.getSprints(); handler.done(new Runnable() { @Override public void run() { Assert.assertEquals(2, sprints.size()); Assert.assertEquals(1001, sprints.get(0).getId()); Assert.assertEquals(1002, sprints.get(1).getId()); } }); } }); } handler.consume(); } @Test public void testGetTeams() throws Throwable { selectTestRelease(); sprintService.resetValues(); teamRequests_TestRelease(handler); for(int i = 0; i < 3; i++) { handler.async(); ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { @Override public void run() { final EntityList teams = sprintService.getTeams(); handler.done(new Runnable() { @Override public void run() { Assert.assertEquals(2, teams.size()); Assert.assertEquals(101, teams.get(0).getId()); Assert.assertEquals(102, teams.get(1).getId()); } }); } }); } handler.consume(); } @Test public void testGetRelease() throws Throwable { selectTestRelease(); Assert.assertEquals(1001, sprintService.getRelease().getId()); } @Test public void testGetSprint() throws Throwable { selectTestRelease(); Assert.assertEquals(1002, sprintService.getSprint().getId()); } @Test public void testGetTeam() throws Throwable { selectTestRelease(); Assert.assertEquals(101, sprintService.getTeam().getId()); } @Test public void testGetCurrentSprint() throws Throwable { selectTestRelease(); Assert.assertEquals(1002, sprintService.getCurrentSprint().getId()); } @Test public void testGetCurrentSprint_notLoaded() throws Throwable { sprintService.resetValues(); Assert.assertNull(sprintService.getCurrentSprint()); } @Test public void testGetCurrentSprint_notMatching() throws Throwable { Assert.assertNull(sprintService.getCurrentSprint()); } @Test public void testIsCurrentSprint() throws Throwable { Entity sprint = new Entity("release-cycle", 1); sprint.setProperty("tense", "PAST"); Assert.assertFalse(SprintService.isCurrentSprint(sprint)); sprint.setProperty("tense", "CURRENT"); Assert.assertTrue(SprintService.isCurrentSprint(sprint)); sprint.setProperty("tense", "FUTURE"); Assert.assertFalse(SprintService.isCurrentSprint(sprint)); } @Test public void testDistance() throws Throwable { Entity sprint = new Entity("release-cycle", 1); // invalid value Assert.assertEquals(Long.MAX_VALUE, SprintService.distance(new Date().getTime(), sprint)); sprint.setProperty("start-date", "2013-05-02"); sprint.setProperty("end-date", "2013-05-09"); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); // future sprint Assert.assertEquals(1000, SprintService.distance(format.parse("2013-05-01 23:59:59").getTime(), sprint)); // past sprint Assert.assertEquals(1000, SprintService.distance(format.parse("2013-05-10 00:00:01").getTime(), sprint)); // current sprint Assert.assertEquals(0, SprintService.distance(format.parse("2013-05-07 13:12:11").getTime(), sprint)); } @Test public void testLookup() throws Throwable { selectTestRelease(); Assert.assertEquals("Test Release", sprintService.lookup(new EntityRef("release", 1001)).getPropertyValue("name")); Assert.assertEquals("Sprint 2", sprintService.lookup(new EntityRef("release-cycle", 1002)).getPropertyValue("name")); Assert.assertEquals("The Others", sprintService.lookup(new EntityRef("team", 102)).getPropertyValue("name")); Assert.assertNull(sprintService.lookup(new EntityRef("defect", 1))); sprintService.resetValues(); Assert.assertNull(sprintService.lookup(new EntityRef("release", 1001))); Assert.assertNull(sprintService.lookup(new EntityRef("release-cycle", 1002))); Assert.assertNull(sprintService.lookup(new EntityRef("team", 102))); Assert.assertNull(sprintService.lookup(new EntityRef("defect", 1))); } @Test public void testRespondsToCacheRequests() throws Throwable { selectTestRelease(); handler.async(); getComponent(EntityService.class).requestCachedEntity(new EntityRef("release-cycle", 1002), Arrays.asList("name"), new EntityListener() { @Override public void entityLoaded(final Entity entity, Event event) { handler.done(new Runnable() { @Override public void run() { Assert.assertEquals("Sprint 2", entity.getPropertyValue("name")); } }); } @Override public void entityNotFound(EntityRef ref, boolean removed) { handler.fail("not found in cache"); } }); } private void releaseSprintTeamRequests_TestRelease(Handler handler) { sprintTeamRequests_TestRelease(handler); handler.addRequest(false, "GET", "/qcbin/rest/domains/domain/projects/project/releases?fields=id,name,start-date,end-date,product-group-id&query={product-group-id[1000]}&order-by={}", 200) .content("sprintServiceTest_releases.xml"); } private void sprintTeamRequests_TestRelease(Handler handler) { sprintRequests_TestRelease(handler); teamRequests_TestRelease(handler); } private void sprintRequests_TestRelease(Handler handler) { handler.addRequest(false, "GET", "/qcbin/rest/domains/domain/projects/project/release-cycles?fields=id,name,tense,start-date,end-date&query={parent-id[1001]}&order-by={start-date[ASC]}", 200) .content("sprintServiceTest_sprints.xml"); } private void teamRequests_TestRelease(Handler handler) { handler.addRequest(false, "GET", "/qcbin/rest/domains/domain/projects/project/teams?fields=id,name&query={release.id[1001]}&order-by={name[ASC]}", 200) .content("sprintServiceTest_teams.xml"); } private void selectTestRelease() throws Throwable { if(sprintService.getRelease() != null) { return; } releaseSprintTeamRequests_TestRelease(handler); WaitForEventsListener listener = new WaitForEventsListener(sprintService); sprintService.connectedTo(ServerType.AGM); handler.consume(); listener.waitForEvents(1001, 1002, 101); metadataService.connectedTo(ServerType.NONE); metadataSimpleService.connectedTo(ServerType.NONE); Assert.assertEquals("1001", sprintService.getState().getAttributeValue("release-id")); } public static class WaitForEventsListener implements SprintService.Listener { private Semaphore semaphore; private Entity team; private Entity release; private Entity sprint; private SprintService sprintService; private boolean releaseEvent; private boolean sprintEvent; private boolean teamEvent; private StringBuffer fail; public WaitForEventsListener(SprintService sprintService) { this(sprintService, true, true, true); } public WaitForEventsListener(SprintService sprintService, boolean releaseEvent, boolean sprintEvent, boolean teamEvent) { this.semaphore = new Semaphore(0); this.sprintService = sprintService; this.releaseEvent = initSemaphore(releaseEvent); this.sprintEvent = initSemaphore(sprintEvent); this.teamEvent = initSemaphore(teamEvent); this.fail = new StringBuffer(); sprintService.addListener(this); } private boolean initSemaphore(boolean enabled) { if(!enabled) { semaphore.release(1); } return enabled; } @Override public void onReleaseSelected(Entity release) { if(!releaseEvent) { fail.append("unexpected onRelease event: " + release + "; "); } else { releaseEvent = false; this.release = release; semaphore.release(1); } } @Override public void onSprintSelected(Entity sprint) { if(!sprintEvent) { fail.append("unexpected onSprint event: " + sprint + "; "); } else { sprintEvent = false; this.sprint = sprint; semaphore.release(1); } } @Override public void onTeamSelected(Entity team) { if(!teamEvent) { fail.append("unexpected onTeam event: " + team + "; "); } else { teamEvent = false; this.team = team; semaphore.release(1); } } public void waitForEvents(Integer releaseId, Integer sprintId, Integer teamId) throws InterruptedException { Assert.assertTrue(semaphore.tryAcquire(3, 2000000, TimeUnit.MILLISECONDS)); sprintService.removeListener(this); if(fail.length() > 0) { Assert.fail(fail.toString()); } compare(release, releaseId); compare(sprint, sprintId); compare(team, teamId); } private void compare(Entity entity, Integer id) { if(id == null) { Assert.assertNull(entity); } else { Assert.assertEquals(id.intValue(), entity.getId()); } } } }