All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.chutneytesting.scenario.infra.raw.DatabaseTestCaseRepository Maven / Gradle / Ivy

The newest version!
/*
 * SPDX-FileCopyrightText: 2017-2024 Enedis
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 */

package com.chutneytesting.scenario.infra.raw;

import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.Long.valueOf;
import static java.util.Optional.empty;
import static java.util.Optional.ofNullable;
import static org.apache.commons.lang3.StringUtils.isNumeric;

import com.chutneytesting.campaign.infra.CampaignScenarioJpaRepository;
import com.chutneytesting.campaign.infra.jpa.CampaignScenarioEntity;
import com.chutneytesting.execution.infra.storage.DatabaseExecutionJpaRepository;
import com.chutneytesting.execution.infra.storage.jpa.ScenarioExecutionEntity;
import com.chutneytesting.scenario.domain.gwt.GwtTestCase;
import com.chutneytesting.scenario.infra.jpa.ScenarioEntity;
import com.chutneytesting.server.core.domain.scenario.AggregatedRepository;
import com.chutneytesting.server.core.domain.scenario.ScenarioNotFoundException;
import com.chutneytesting.server.core.domain.scenario.ScenarioNotParsableException;
import com.chutneytesting.server.core.domain.scenario.TestCase;
import com.chutneytesting.server.core.domain.scenario.TestCaseMetadata;
import jakarta.persistence.EntityManager;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
@Transactional(readOnly = true)
public class DatabaseTestCaseRepository implements AggregatedRepository {

    private final ScenarioJpaRepository scenarioJpaRepository;
    private final DatabaseExecutionJpaRepository scenarioExecutionsJpaRepository;
    private final CampaignScenarioJpaRepository campaignScenarioJpaRepository;
    private final EntityManager entityManager;
    private final Pattern pattern = Pattern.compile("\"([^\"]*)\"");


    public DatabaseTestCaseRepository(
        ScenarioJpaRepository jpa,
        DatabaseExecutionJpaRepository scenarioExecutionsJpaRepository,
        CampaignScenarioJpaRepository campaignScenarioJpaRepository, EntityManager entityManager) {
        this.scenarioJpaRepository = jpa;
        this.scenarioExecutionsJpaRepository = scenarioExecutionsJpaRepository;
        this.campaignScenarioJpaRepository = campaignScenarioJpaRepository;
        this.entityManager = entityManager;
    }

    @Override
    @Transactional
    public String save(GwtTestCase testCase) {
        if (testCaseDoesNotExist(testCase.id())) {
            saveScenarioWithExplicitId(testCase);
            return testCase.id();
        }
        try {
            return scenarioJpaRepository.save(ScenarioEntity.fromGwtTestCase(testCase)).getId().toString();
        } catch (ObjectOptimisticLockingFailureException e) {
            throw new ScenarioNotFoundException(testCase.id(), testCase.metadata().version());
        }
    }

    @Override
    public Optional findById(String scenarioId) {
        if (checkIdInput(scenarioId)) {
            return empty();
        }
        Optional scenarioDao = scenarioJpaRepository.findByIdAndActivated(valueOf(scenarioId), true)
            .filter(ScenarioEntity::isActivated);
        return scenarioDao.map(ScenarioEntity::toGwtTestCase);
    }

    @Override
    public Optional findExecutableById(String id) {
        return findById(id).map(TestCase.class::cast);
    }

    @Override
    public Optional findMetadataById(String testCaseId) {
        if (checkIdInput(testCaseId)) {
            return empty();
        }
        return scenarioJpaRepository.findMetaDataByIdAndActivated(valueOf(testCaseId), true).map(ScenarioEntity::toTestCaseMetadata);
    }

    @Override
    public List findAll() {
        return scenarioJpaRepository.findMetaDataByActivatedTrue().stream()
            .map(ScenarioEntity::toTestCaseMetadata)
            .toList();
    }

    @Override
    public List findAllByDatasetId(String datasetId) {
        return scenarioJpaRepository.findByActivatedTrueAndDefaultDataset(datasetId).stream()
            .map(ScenarioEntity::toTestCaseMetadata)
            .toList();
    }

    @Override
    @Transactional
    public void removeById(String scenarioId) {
        if (checkIdInput(scenarioId)) {
            return;
        }
        scenarioJpaRepository.findByIdAndActivated(valueOf(scenarioId), true)
            .ifPresent(scenarioJpa -> {
                List allExecutions = scenarioExecutionsJpaRepository.findAllByScenarioId(scenarioId);
                allExecutions.forEach(e -> {
                    e.forCampaignExecution(null);
                    scenarioExecutionsJpaRepository.save(e);
                });

                List allCampaignScenarioEntities = campaignScenarioJpaRepository.findAllByScenarioId(scenarioId);
                campaignScenarioJpaRepository.deleteAll(allCampaignScenarioEntities);

                scenarioJpa.deactivate();
                scenarioJpaRepository.save(scenarioJpa);
            });
    }

    @Override
    public Optional lastVersion(String scenarioId) {
        if (checkIdInput(scenarioId)) {
            return empty();
        }
        try {
            return scenarioJpaRepository.lastVersion(valueOf(scenarioId));
        } catch (IncorrectResultSizeDataAccessException e) {
            return empty();
        }
    }

    @Override
    public List search(String textFilter) {
        if (!textFilter.isEmpty()) {
            List words = getWordsToSearchWithQuotes(escapeSql(textFilter));
            Specification scenarioDaoSpecification = buildLikeSpecificationOnContent(words)
                .and(ScenarioJpaRepository.activatedScenarioSpecification());

            CriteriaBuilder builder = entityManager.getCriteriaBuilder();
            CriteriaQuery query = builder.createQuery(ScenarioEntity.class);
            Root root = query.from(ScenarioEntity.class);
            query.select(builder.construct(ScenarioEntity.class, root.get("id"), root.get("title"), root.get("description"), root.get("tags"), root.get("creationDate"), root.get("activated"), root.get("userId"), root.get("updateDate"), root.get("version"), root.get("defaultDataset")));
            query = query.where(scenarioDaoSpecification.toPredicate(root, query, builder));

            return entityManager.createQuery(query).getResultList().stream().map(ScenarioEntity::toTestCaseMetadata).toList();
        } else {
            return findAll();
        }
    }

    private boolean testCaseDoesNotExist(String id) {
        try {
            return Long.parseLong(id) >= 0 && findById(id).isEmpty();
        } catch (NumberFormatException e) {
            throw new ScenarioNotParsableException("Cannot parse id", e);
        }
    }

    List getWordsToSearchWithQuotes(String input) {
        List words = new ArrayList<>();
        Matcher matcher = pattern.matcher(input);

        while (matcher.find()) {
            String word = matcher.group(1);
            if (!word.isEmpty()) {
                words.add(word);
            }
        }
        words.addAll(Arrays.stream(input.replaceAll(pattern.pattern(), "").split("\\s")).filter(value -> !value.isEmpty()).toList());
        return words;
    }

    private void saveScenarioWithExplicitId(GwtTestCase testCase) {
        ScenarioEntity scenarioEntity = ScenarioEntity.fromGwtTestCase(testCase);
        scenarioJpaRepository.saveWithExplicitId(
            scenarioEntity.getId(),
            scenarioEntity.getTitle(),
            scenarioEntity.getDescription(),
            scenarioEntity.getContent(),
            scenarioEntity.getTags(),
            scenarioEntity.getCreationDate(),
            scenarioEntity.isActivated(),
            scenarioEntity.getUserId(),
            scenarioEntity.getUpdateDate(),
            scenarioEntity.getVersion(),
            scenarioEntity.getDefaultDataset()
        );
    }

    private static String escapeSql(String str) {
        if (str == null) {
            return null;
        }
        return str.replace("'", "''");
    }

    private Specification buildLikeSpecificationOnContent(List words) {
        Specification scenarioDaoSpecification = null;
        for (String word : words) {
            Specification wordSpecification = ScenarioJpaRepository.contentContains(word);
            scenarioDaoSpecification = ofNullable(scenarioDaoSpecification)
                .map(s -> s.or(wordSpecification))
                .orElse(wordSpecification);
        }
        return scenarioDaoSpecification;
    }

    private boolean checkIdInput(String scenarioId) {
        return isNullOrEmpty(scenarioId) || !isNumeric(scenarioId);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy