io.lavagna.service.StatisticsServiceTest.java Source code

Java tutorial

Introduction

Here is the source code for io.lavagna.service.StatisticsServiceTest.java

Source

/**
 * This file is part of lavagna.
 *
 * lavagna is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * lavagna is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with lavagna.  If not, see <http://www.gnu.org/licenses/>.
 */
package io.lavagna.service;

import io.lavagna.config.PersistenceAndServiceConfig;
import io.lavagna.model.Board;
import io.lavagna.model.BoardColumn;
import io.lavagna.model.BoardColumnDefinition;
import io.lavagna.model.Card;
import io.lavagna.model.CardLabel;
import io.lavagna.model.CardLabelValue;
import io.lavagna.model.ColumnDefinition;
import io.lavagna.model.LabelAndValueWithCount;
import io.lavagna.model.LabelListValue;
import io.lavagna.model.MilestoneCount;
import io.lavagna.model.Pair;
import io.lavagna.model.Project;
import io.lavagna.model.User;
import io.lavagna.service.config.TestServiceConfig;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.lang3.time.DateUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestServiceConfig.class, PersistenceAndServiceConfig.class })
public class StatisticsServiceTest {

    @Autowired
    private ProjectService projectService;

    @Autowired
    private BoardRepository boardRepository;

    @Autowired
    private BoardColumnRepository boardColumnRepository;

    @Autowired
    private CardService cardService;

    @Autowired
    private CardRepository cardRepository;

    @Autowired
    private CardLabelRepository cardLabelRepository;

    @Autowired
    private LabelService labelService;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private StatisticsService statisticsService;

    private Date today;
    private Date yesterday;
    private Date oneMonthAgo;
    private User user;
    private BoardColumn openCol;
    private Board board;
    private Card card;
    private CardLabel assigned;
    private CardLabel customLabel;
    private CardLabelValue.LabelValue labelValueToUser;

    private Date lastSnapshot;

    @Before
    public void prepare() {
        Helper.createUser(userRepository, "test", "test-user");
        user = userRepository.findUserByName("test", "test-user");
        Project p = projectService.create("test", "TEST", "desc");
        board = boardRepository.createNewBoard("test-board", "TEST-BRD", null, p.getId());
        List<BoardColumnDefinition> definitions = projectService
                .findColumnDefinitionsByProjectId(projectService.findByShortName("TEST").getId());

        for (BoardColumnDefinition def : definitions) {
            if (def.getValue() == ColumnDefinition.OPEN) {
                openCol = boardColumnRepository.addColumnToBoard("col1", def.getId(),
                        BoardColumn.BoardColumnLocation.BOARD, board.getId());
            }
        }

        today = DateUtils.truncate(new Date(), Calendar.DATE);
        yesterday = DateUtils.addDays(today, -1);
        oneMonthAgo = DateUtils.addMonths(today, -1);

        lastSnapshot = DateUtils.addYears(today, -10);

        card = cardService.createCard("card1", openCol.getId(), today, user);

        assigned = cardLabelRepository.findLabelByName(p.getId(), "ASSIGNED", CardLabel.LabelDomain.SYSTEM);
        customLabel = cardLabelRepository.addLabel(p.getId(), true, CardLabel.LabelType.USER,
                CardLabel.LabelDomain.USER, "Custom label", 0);
        labelValueToUser = new CardLabelValue.LabelValue(null, null, null, null, user.getId(), null);
    }

    private void createArchivedCard() {
        BoardColumn destination = boardColumnRepository.findDefaultColumnFor(board.getId(),
                BoardColumn.BoardColumnLocation.ARCHIVE);
        Card archivedCard = cardService.createCard("Archived card", openCol.getId(), today, user);
        cardService.moveCardToColumn(archivedCard.getId(), archivedCard.getColumnId(), destination.getId(),
                user.getId(), new Date());
    }

    private void snapshotStatistics() throws InterruptedException {
        long diffInSeconds;
        do {
            diffInSeconds = (new Date().getTime() - lastSnapshot.getTime()) / 1000;
            Thread.sleep(250);
        } while (diffInSeconds < 1);
        lastSnapshot = new Date();
        statisticsService.snapshotCardsStatus();
    }

    private void verifyResults(Map<Long, Map<ColumnDefinition, Long>> results, int resultsSize, Date date,
            ColumnDefinition def, long expectedValue) {
        Assert.assertEquals(resultsSize, results.size());
        long dateTime = DateUtils.truncate(date, Calendar.DATE).getTime();
        if (!results.containsKey(dateTime)) {
            Assert.fail();
        }

        Map<ColumnDefinition, Long> day = results.get(dateTime);
        if (!day.containsKey(def)) {
            Assert.fail();
        }

        Assert.assertEquals(expectedValue, day.get(def).longValue());
    }

    @Test
    public void getCardsStatusByBoardTest() throws InterruptedException {
        Map<Long, Map<ColumnDefinition, Long>> results = statisticsService.getCardsStatusByBoard(board.getId(),
                oneMonthAgo);

        Assert.assertEquals(0, results.size());

        snapshotStatistics();

        results = statisticsService.getCardsStatusByBoard(board.getId(), oneMonthAgo);

        verifyResults(results, 1, today, ColumnDefinition.OPEN, 1);
    }

    @Test
    public void getCardsStatusByProjectTest() throws InterruptedException {
        Map<Long, Map<ColumnDefinition, Long>> results = statisticsService
                .getCardsStatusByProject(board.getProjectId(), oneMonthAgo);

        Assert.assertEquals(0, results.size());

        snapshotStatistics();

        results = statisticsService.getCardsStatusByProject(board.getProjectId(), oneMonthAgo);

        verifyResults(results, 1, today, ColumnDefinition.OPEN, 1);
    }

    @Test
    public void getCardsStatusByBoardOnDoubleSnapshotTest() throws InterruptedException {
        Map<Long, Map<ColumnDefinition, Long>> results = statisticsService.getCardsStatusByBoard(board.getId(),
                oneMonthAgo);

        Assert.assertEquals(0, results.size());

        snapshotStatistics();

        snapshotStatistics();

        results = statisticsService.getCardsStatusByBoard(board.getId(), oneMonthAgo);

        verifyResults(results, 1, today, ColumnDefinition.OPEN, 1);
    }

    @Test
    public void getCardsStatusByBoardOnDoubleCreateTest() throws InterruptedException {
        Map<Long, Map<ColumnDefinition, Long>> results = statisticsService.getCardsStatusByBoard(board.getId(),
                oneMonthAgo);

        Assert.assertEquals(0, results.size());

        snapshotStatistics();

        cardService.createCard("card2", openCol.getId(), today, user);

        snapshotStatistics();

        results = statisticsService.getCardsStatusByBoard(board.getId(), oneMonthAgo);

        verifyResults(results, 1, today, ColumnDefinition.OPEN, 2);
    }

    @Test
    public void getActiveUsersOnBoardTest() {
        Integer activeUsers = statisticsService.getActiveUsersOnBoard(board.getId(), oneMonthAgo);

        Assert.assertEquals(1, activeUsers.intValue());
    }

    @Test
    public void getActiveUsersOnProjectTest() {
        Integer activeUsers = statisticsService.getActiveUsersOnProject(board.getProjectId(), oneMonthAgo);

        Assert.assertEquals(1, activeUsers.intValue());
    }

    @Test
    public void getAverageUsersPerCardOnBoardTest() {
        double averageUsers = statisticsService.getAverageUsersPerCardOnBoard(board.getId());
        Assert.assertEquals(0, averageUsers, Double.MIN_VALUE);

        labelService.addLabelValueToCard(assigned.getId(), card.getId(), labelValueToUser, user, new Date());

        averageUsers = statisticsService.getAverageUsersPerCardOnBoard(board.getId());
        Assert.assertEquals(1, averageUsers, Double.MIN_VALUE);

        createArchivedCard();

        averageUsers = statisticsService.getAverageUsersPerCardOnBoard(board.getId());
        Assert.assertEquals(1, averageUsers, Double.MIN_VALUE);
    }

    @Test
    public void getAverageUsersPerCardOnProjectTest() {
        double averageUsers = statisticsService.getAverageUsersPerCardOnProject(board.getProjectId());
        Assert.assertEquals(0, averageUsers, Double.MIN_VALUE);

        labelService.addLabelValueToCard(assigned.getId(), card.getId(), labelValueToUser, user, new Date());

        averageUsers = statisticsService.getAverageUsersPerCardOnProject(board.getProjectId());
        Assert.assertEquals(1, averageUsers, Double.MIN_VALUE);

        createArchivedCard();

        averageUsers = statisticsService.getAverageUsersPerCardOnProject(board.getProjectId());
        Assert.assertEquals(1, averageUsers, Double.MIN_VALUE);
    }

    // Average cards per user

    @Test
    public void getAverageCardsPerUserOnBoardTest() {
        double averageUsers = statisticsService.getAverageCardsPerUserOnBoard(board.getId());
        Assert.assertEquals(0, averageUsers, Double.MIN_VALUE);

        labelService.addLabelValueToCard(assigned.getId(), card.getId(), labelValueToUser, user, new Date());

        averageUsers = statisticsService.getAverageCardsPerUserOnBoard(board.getId());
        Assert.assertEquals(1, averageUsers, Double.MIN_VALUE);

        createArchivedCard();

        averageUsers = statisticsService.getAverageCardsPerUserOnBoard(board.getId());
        Assert.assertEquals(1, averageUsers, Double.MIN_VALUE);
    }

    @Test
    public void getAverageCardsPerUserOnProjectTest() {
        double averageUsers = statisticsService.getAverageCardsPerUserOnProject(board.getProjectId());
        Assert.assertEquals(0, averageUsers, Double.MIN_VALUE);

        labelService.addLabelValueToCard(assigned.getId(), card.getId(), labelValueToUser, user, new Date());

        averageUsers = statisticsService.getAverageCardsPerUserOnProject(board.getProjectId());
        Assert.assertEquals(1, averageUsers, Double.MIN_VALUE);

        createArchivedCard();

        averageUsers = statisticsService.getAverageCardsPerUserOnProject(board.getProjectId());
        Assert.assertEquals(1, averageUsers, Double.MIN_VALUE);
    }

    // Cards by label

    @Test
    public void getCardsByLabelOnBoardTest() {
        List<LabelAndValueWithCount> labels = statisticsService.getCardsByLabelOnBoard(board.getId());
        Assert.assertEquals(0, labels.size());

        labelService.addLabelValueToCard(customLabel.getId(), card.getId(), labelValueToUser, user, new Date());

        labels = statisticsService.getCardsByLabelOnBoard(board.getId());
        Assert.assertEquals(1, labels.size());
    }

    @Test
    public void getCardsByLabelOnProjectTest() {
        List<LabelAndValueWithCount> labels = statisticsService.getCardsByLabelOnProject(board.getProjectId());
        Assert.assertEquals(0, labels.size());

        labelService.addLabelValueToCard(customLabel.getId(), card.getId(), labelValueToUser, user, new Date());

        labels = statisticsService.getCardsByLabelOnProject(board.getProjectId());
        Assert.assertEquals(1, labels.size());
    }

    // Created / closed cards

    @Test
    public void getCreatedAndClosedCardsByBoardTest() {
        Map<Long, Pair<Long, Long>> events = statisticsService.getCreatedAndClosedCardsByBoard(board.getId(),
                oneMonthAgo);
        Assert.assertEquals(1, events.size());
        Assert.assertEquals(1, events.get(today.getTime()).getFirst().longValue());
        Assert.assertEquals(0, events.get(today.getTime()).getSecond().longValue());

        cardService.createCard("card2", openCol.getId(), yesterday, user);
        cardService.createCard("card3", openCol.getId(), yesterday, user);

        BoardColumn destination = boardColumnRepository.findDefaultColumnFor(board.getId(),
                BoardColumn.BoardColumnLocation.ARCHIVE);
        cardService.moveCardToColumn(card.getId(), card.getColumnId(), destination.getId(), user.getId(),
                yesterday);

        events = statisticsService.getCreatedAndClosedCardsByBoard(board.getId(), oneMonthAgo);

        Assert.assertEquals(2, events.size());
        Assert.assertEquals(1l, events.get(today.getTime()).getFirst().longValue());
        Assert.assertEquals(0l, events.get(today.getTime()).getSecond().longValue());
        Assert.assertEquals(2l, events.get(yesterday.getTime()).getFirst().longValue());
        Assert.assertEquals(1l, events.get(yesterday.getTime()).getSecond().longValue());
    }

    @Test
    public void getCreatedAndClosedCardsByProjectTest() {
        Map<Long, Pair<Long, Long>> events = statisticsService
                .getCreatedAndClosedCardsByProject(board.getProjectId(), oneMonthAgo);
        Assert.assertEquals(1, events.size());
        Assert.assertEquals(1, events.get(today.getTime()).getFirst().longValue());
        Assert.assertEquals(0, events.get(today.getTime()).getSecond().longValue());

        cardService.createCard("card2", openCol.getId(), yesterday, user);
        cardService.createCard("card3", openCol.getId(), yesterday, user);

        BoardColumn destination = boardColumnRepository.findDefaultColumnFor(board.getId(),
                BoardColumn.BoardColumnLocation.ARCHIVE);
        cardService.moveCardToColumn(card.getId(), card.getColumnId(), destination.getId(), user.getId(),
                yesterday);

        events = statisticsService.getCreatedAndClosedCardsByProject(board.getProjectId(), oneMonthAgo);

        Assert.assertEquals(2, events.size());
        Assert.assertEquals(1l, events.get(today.getTime()).getFirst().longValue());
        Assert.assertEquals(0l, events.get(today.getTime()).getSecond().longValue());
        Assert.assertEquals(2l, events.get(yesterday.getTime()).getFirst().longValue());
        Assert.assertEquals(1l, events.get(yesterday.getTime()).getSecond().longValue());
    }

    // Most active card

    @Test
    public void getMostActiveCardByBoardTest() {
        Card resultCard = statisticsService.getMostActiveCardByBoard(board.getId(), oneMonthAgo);
        Assert.assertEquals(card.getId(), resultCard.getId());
    }

    @Test
    public void getTodayMostActiveCardByBoardTest() {
        Card resultCard = statisticsService.getMostActiveCardByBoard(board.getId(), today);
        Assert.assertEquals(card.getId(), resultCard.getId());
    }

    @Test
    public void getTomorrowMostActiveCardByBoardTest() {
        Card resultCard = statisticsService.getMostActiveCardByBoard(board.getId(), DateUtils.addDays(today, 1));
        Assert.assertNull(resultCard);
    }

    @Test
    public void getMostActiveCardByProjectTest() {
        Card resultCard = statisticsService.getMostActiveCardByProject(board.getProjectId(), oneMonthAgo);
        Assert.assertEquals(card.getId(), resultCard.getId());
    }

    @Test
    public void getTodayMostActiveCardByProjectTest() {
        Card resultCard = statisticsService.getMostActiveCardByProject(board.getProjectId(), today);
        Assert.assertEquals(card.getId(), resultCard.getId());
    }

    @Test
    public void getTomorrowMostActiveCardByProjectTest() {
        Card resultCard = statisticsService.getMostActiveCardByProject(board.getProjectId(),
                DateUtils.addDays(today, 1));
        Assert.assertNull(resultCard);
    }

    // Milestones

    @Test
    public void getCreatedAndClosedCardsByMilestoneTest() {
        Card card2 = cardService.createCard("card2", openCol.getId(), yesterday, user);

        CardLabel milestoneLabel = cardLabelRepository.findLabelByName(board.getProjectId(), "MILESTONE",
                CardLabel.LabelDomain.SYSTEM);

        LabelListValue milestone = cardLabelRepository.addLabelListValue(milestoneLabel.getId(), "Dummy milestone");

        Map<Long, Pair<Long, Long>> results = statisticsService.getAssignedAndClosedCardsByMilestone(milestone,
                oneMonthAgo);
        Assert.assertEquals(results.size(), 0);

        labelService.addLabelValueToCard(milestoneLabel.getId(), card2.getId(),
                new CardLabelValue.LabelValue(null, null, null, null, null, milestone.getId()), user, new Date());

        results = statisticsService.getAssignedAndClosedCardsByMilestone(milestone, oneMonthAgo);
        Assert.assertEquals(results.size(), 1);
    }

    @Test
    public void testFindCardsByMilestoneOnEmptyProject() {
        Project p = projectService.create("test", "TEST2", "desc");
        List<MilestoneCount> res = statisticsService.findCardsCountByMilestone(p.getId());
        Assert.assertEquals(0, res.size());
    }

    @Test
    public void testFindCardsByMilestoneOnMultipleProjects() {
        cardService.createCard("card1", openCol.getId(), new Date(), user);
        cardService.createCard("card2", openCol.getId(), new Date(), user);
        Project p = projectService.create("test", "TEST2", "desc");

        Assert.assertEquals(0, statisticsService.findCardsCountByMilestone(p.getId()).size());
        Assert.assertEquals(1, statisticsService.findCardsCountByMilestone(board.getProjectId()).size());
    }

    @Test
    public void testFindCardsByMilestone() {
        cardService.createCard("card1", openCol.getId(), new Date(), user);
        cardService.createCard("card2", openCol.getId(), new Date(), user);
        cardService.createCard("card3", openCol.getId(), new Date(), user);

        List<MilestoneCount> res = statisticsService.findCardsCountByMilestone(board.getProjectId());
        Assert.assertEquals(1, res.size());
    }

    @Test
    public void testFindCardsByMilestoneOnTrashedCards() {
        cardService.createCard("card1", openCol.getId(), new Date(), user);
        cardService.createCard("card2", openCol.getId(), new Date(), user);

        Card card3 = cardService.createCard("card3", openCol.getId(), new Date(), user);
        List<Integer> trashedCardIds = new ArrayList<>();
        trashedCardIds.add(card3.getId());
        BoardColumn trashColumn = boardColumnRepository.findDefaultColumnFor(openCol.getBoardId(),
                BoardColumn.BoardColumnLocation.TRASH);
        cardService.moveCardsToColumn(trashedCardIds, openCol.getId(), trashColumn.getId(), user.getId(),
                BoardColumn.BoardColumnLocation.MAPPING.get(BoardColumn.BoardColumnLocation.TRASH), new Date());

        Card card4 = cardService.createCard("card4", openCol.getId(), new Date(), user);
        List<Integer> archivedCardIds = new ArrayList<>();
        archivedCardIds.add(card4.getId());
        BoardColumn archiveColumn = boardColumnRepository.findDefaultColumnFor(openCol.getBoardId(),
                BoardColumn.BoardColumnLocation.ARCHIVE);
        cardService.moveCardsToColumn(archivedCardIds, openCol.getId(), archiveColumn.getId(), user.getId(),
                BoardColumn.BoardColumnLocation.MAPPING.get(BoardColumn.BoardColumnLocation.ARCHIVE), new Date());

        // Double check that everything is in the right place
        Assert.assertEquals(3, cardRepository.findAllByColumnId(openCol.getId()).size());
        Assert.assertEquals(1, cardRepository.findAllByColumnId(trashColumn.getId()).size());
        Assert.assertEquals(1, cardRepository.findAllByColumnId(archiveColumn.getId()).size());

        List<MilestoneCount> res = statisticsService.findCardsCountByMilestone(board.getProjectId());

        Assert.assertEquals(2, res.size());
    }

    private void checkMilestone(List<MilestoneCount> result, Integer milestoneId, int count) {
        for (MilestoneCount mc : result) {
            if (Objects.equals(mc.getMilestoneId(), milestoneId)) {
                Assert.assertEquals(count, mc.getCount());
                return;
            }
        }
        Assert.fail();
    }

    @Test
    public void testFindCardsByMilestoneWithLabels() {
        cardService.createCard("card1", openCol.getId(), new Date(), user);
        cardService.createCard("card2", openCol.getId(), new Date(), user);
        Card c3 = cardService.createCard("card3", openCol.getId(), new Date(), user);

        LabelListValue llv = null;
        for (CardLabel cardLabel : cardLabelRepository.findLabelsByProject(board.getProjectId())) {
            if (cardLabel.getDomain() == CardLabel.LabelDomain.SYSTEM && cardLabel.getName().equals("MILESTONE")) {
                llv = cardLabelRepository.addLabelListValue(cardLabel.getId(), "v1.0");
                cardLabelRepository.addLabelValueToCard(cardLabel, c3.getId(),
                        new CardLabelValue.LabelValue(null, null, null, null, null, llv.getId()));
                break;
            }
        }
        List<MilestoneCount> res = statisticsService.findCardsCountByMilestone(board.getProjectId());
        Assert.assertEquals(2, res.size());

        checkMilestone(res, null, 3);
        checkMilestone(res, llv.getId(), 1);
    }
}