<commit_before>package com.konkerlabs.platform.registry.test.business.services;

import com.konkerlabs.platform.registry.business.exceptions.BusinessException;
import com.konkerlabs.platform.registry.business.model.EventRule;
import com.konkerlabs.platform.registry.business.model.Tenant;
import com.konkerlabs.platform.registry.business.repositories.EventRuleRepository;
import com.konkerlabs.platform.registry.business.repositories.TenantRepository;
import com.konkerlabs.platform.registry.business.services.rules.EventRuleExecutorImpl;
import com.konkerlabs.platform.registry.business.services.rules.api.EventRuleService;
import com.konkerlabs.platform.registry.business.services.api.ServiceResponse;
import com.konkerlabs.platform.registry.test.base.BusinessLayerTestSupport;
import com.konkerlabs.platform.registry.test.base.BusinessTestConfiguration;
import com.konkerlabs.platform.registry.test.base.MongoTestConfiguration;
import com.lordofthejars.nosqlunit.annotation.UsingDataSet;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
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 java.net.URI;
import java.util.Arrays;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { MongoTestConfiguration.class, BusinessTestConfiguration.class })
public class EventRuleServiceTest extends BusinessLayerTestSupport {

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Autowired
    private EventRuleService subject;

    @Autowired
    private TenantRepository tenantRepository;
    @Autowired
    private EventRuleRepository eventRuleRepository;

    private EventRule rule;

    private String ruleId = "71fb0d48-674b-4f64-a3e5-0256ff3a63af";
    private Tenant tenant;
    private Tenant emptyTenant;

    @Before
    public void setUp() throws Exception {
        tenant = tenantRepository.findByName("Konker");
        emptyTenant = tenantRepository.findByName("EmptyTenant");

        rule = spy(EventRule.builder()
                .name("Rule name")
                .description("Description")
                .incoming(new EventRule.RuleActor(new URI("device","0000000000000004",null,null,null)))
                .outgoing(new EventRule.RuleActor(new URI("device","0000000000000005",null,null,null)))
                .transformations(Arrays.asList(new EventRule.RuleTransformation[]{
                        new EventRule.RuleTransformation(EventRuleExecutorImpl.RuleTransformationType.EXPRESSION_LANGUAGE.name())
                }))
                .active(true)
                .build());
    }
    @Test
    public void shouldRaiseAnExceptionIfTenantIsNull() throws Exception {
        thrown.expect(BusinessException.class);
        thrown.expectMessage("Tenant cannot be null");

        subject.save(null,rule);
    }
    @Test
    @UsingDataSet(locations = "/fixtures/tenants.json")
    public void shouldRaiseAnExceptionIfRecordIsNull() throws Exception {
        thrown.expect(BusinessException.class);
        thrown.expectMessage("Record cannot be null");

        subject.save(tenant,null);
    }
    @Test
    @UsingDataSet(locations = "/fixtures/tenants.json")
    public void shouldReturnResponseMessagesIfRecordIsInvalid() throws Exception {
        List<String> errorMessages = Arrays.asList(new String[] { "Some error" });
        when(rule.applyValidations()).thenReturn(errorMessages);

        ServiceResponse<EventRule> response = subject.save(tenant,rule);

        assertThat(response, notNullValue());
        assertThat(response.getStatus(), equalTo(ServiceResponse.Status.ERROR));
        assertThat(response.getResponseMessages(), equalTo(errorMessages));
    }

    @Test
    public void shouldRaiseAnExceptionIfTenantDoesNotExist() throws Exception {
        thrown.expect(BusinessException.class);
        thrown.expectMessage("Tenant does not exist");

        subject.save(Tenant.builder().id("unknown_id").name("name").build(),rule);
    }
    @Test
    @UsingDataSet(locations = "/fixtures/tenants.json")
    public void shouldPersistIfRuleIsValid() throws Exception {

        ServiceResponse<EventRule> response = subject.save(tenant,rule);

        assertThat(response, notNullValue());
        assertThat(response.getStatus(), equalTo(ServiceResponse.Status.OK));
        assertThat(eventRuleRepository.findByIncomingURI(rule.getIncoming().getUri()), notNullValue());
        assertThat(response.getResult().getIncoming().getUri(),equalTo(rule.getIncoming().getUri()));
    }
    //TODO Verify this constraint for effectiveness
//    @Test
//    @UsingDataSet(locations = "/fixtures/tenants.json")
//    public void shouldReturnAValidationMessageIfIncomingAndOutgoingChannelsAreTheSame() throws Exception {
//        String channel = "channel";
//
//        rule.getIncoming().getData().put("channel",channel);
//        rule.getOutgoing().getData().put("channel",channel);
//
//        List<String> errorMessages = Arrays.asList(new String[] { "Incoming and outgoing device channels cannot be the same" });
//        ServiceResponse response = subject.save(tenant,rule);
//
//        assertThat(response, notNullValue());
//        assertThat(response.getStatus(), equalTo(ServiceResponse.Status.ERROR));
//        assertThat(response.getResponseMessages(), equalTo(errorMessages));
//    }
    @Test
    @UsingDataSet(locations = {"/fixtures/tenants.json","/fixtures/event-rules.json"})
    public void shouldReturnAllRegisteredRulesWithinATenant() throws Exception {
        List<EventRule> allRules = subject.getAll(tenant);

        assertThat(allRules, notNullValue());
        assertThat(allRules, hasSize(6));
        assertThat(allRules.get(0).getId(), equalTo("71fb0d48-674b-4f64-a3e5-0256ff3a63af"));
        assertThat(allRules.get(1).getId(), equalTo("71fb0d48-674b-4f64-a3e5-0256ff3a63ab"));
        assertThat(allRules.get(2).getId(), equalTo("71fb0d48-674b-4f64-a3e5-0256ff3a63ac"));
        assertThat(allRules.get(3).getId(), equalTo("71fb0d48-674b-4f64-a3e5-0256ff3a63ad"));
        assertThat(allRules.get(4).getId(), equalTo("71fb0d48-674b-4f64-a3e5-0256ff3a63ae"));
        assertThat(allRules.get(5).getId(), equalTo("71fb0d48-674b-4f64-a3e5-0256ff3a63ba"));

        allRules = subject.getAll(emptyTenant);
        assertThat(allRules, notNullValue());
        assertThat(allRules, empty());<commit_msg>Rule executor engine improvements.<commit_after>package com.konkerlabs.platform.registry.test.business.services;

import com.konkerlabs.platform.registry.business.exceptions.BusinessException;
import com.konkerlabs.platform.registry.business.model.EventRule;
import com.konkerlabs.platform.registry.business.model.Tenant;
import com.konkerlabs.platform.registry.business.repositories.EventRuleRepository;
import com.konkerlabs.platform.registry.business.repositories.TenantRepository;
import com.konkerlabs.platform.registry.business.services.rules.EventRuleExecutorImpl;
import com.konkerlabs.platform.registry.business.services.rules.api.EventRuleService;
import com.konkerlabs.platform.registry.business.services.api.ServiceResponse;
import com.konkerlabs.platform.registry.test.base.BusinessLayerTestSupport;
import com.konkerlabs.platform.registry.test.base.BusinessTestConfiguration;
import com.konkerlabs.platform.registry.test.base.MongoTestConfiguration;
import com.lordofthejars.nosqlunit.annotation.UsingDataSet;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
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 java.net.URI;
import java.util.Arrays;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { MongoTestConfiguration.class, BusinessTestConfiguration.class })
public class EventRuleServiceTest extends BusinessLayerTestSupport {

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Autowired
    private EventRuleService subject;

    @Autowired
    private TenantRepository tenantRepository;
    @Autowired
    private EventRuleRepository eventRuleRepository;

    private EventRule rule;

    private String ruleId = "71fb0d48-674b-4f64-a3e5-0256ff3a63af";
    private Tenant tenant;
    private Tenant emptyTenant;

    @Before
    public void setUp() throws Exception {
        tenant = tenantRepository.findByName("Konker");
        emptyTenant = tenantRepository.findByName("EmptyTenant");

        rule = spy(EventRule.builder()
                .name("Rule name")
                .description("Description")
                .incoming(new EventRule.RuleActor(new URI("device","0000000000000004",null,null,null)))
                .outgoing(new EventRule.RuleActor(new URI("device","0000000000000005",null,null,null)))
                .transformations(Arrays.asList(new EventRule.RuleTransformation[]{
                        new EventRule.RuleTransformation(EventRuleExecutorImpl.RuleTransformationType.EXPRESSION_LANGUAGE.name())
                }))
                .active(true)
                .build());
    }
    @Test
    public void shouldRaiseAnExceptionIfTenantIsNull() throws Exception {
        thrown.expect(BusinessException.class);
        thrown.expectMessage("Tenant cannot be null");

        subject.save(null,rule);
    }
    @Test
    @UsingDataSet(locations = "/fixtures/tenants.json")
    public void shouldRaiseAnExceptionIfRecordIsNull() throws Exception {
        thrown.expect(BusinessException.class);
        thrown.expectMessage("Record cannot be null");

        subject.save(tenant,null);
    }
    @Test
    @UsingDataSet(locations = "/fixtures/tenants.json")
    public void shouldReturnResponseMessagesIfRecordIsInvalid() throws Exception {
        List<String> errorMessages = Arrays.asList(new String[] { "Some error" });
        when(rule.applyValidations()).thenReturn(errorMessages);

        ServiceResponse<EventRule> response = subject.save(tenant,rule);

        assertThat(response, notNullValue());
        assertThat(response.getStatus(), equalTo(ServiceResponse.Status.ERROR));
        assertThat(response.getResponseMessages(), equalTo(errorMessages));
    }

    @Test
    public void shouldRaiseAnExceptionIfTenantDoesNotExist() throws Exception {
        thrown.expect(BusinessException.class);
        thrown.expectMessage("Tenant does not exist");

        subject.save(Tenant.builder().id("unknown_id").name("name").build(),rule);
    }
    @Test
    @UsingDataSet(locations = "/fixtures/tenants.json")
    public void shouldPersistIfRuleIsValid() throws Exception {

        ServiceResponse<EventRule> response = subject.save(tenant,rule);

        assertThat(response, notNullValue());
        assertThat(response.getStatus(), equalTo(ServiceResponse.Status.OK));
        assertThat(eventRuleRepository.findByIncomingURI(rule.getIncoming().getUri()), notNullValue());
        assertThat(response.getResult().getIncoming().getUri(),equalTo(rule.getIncoming().getUri()));
    }
    //TODO Verify this constraint for effectiveness
//    @Test
//    @UsingDataSet(locations = "/fixtures/tenants.json")
//    public void shouldReturnAValidationMessageIfIncomingAndOutgoingChannelsAreTheSame() throws Exception {
//        String channel = "channel";
//
//        rule.getIncoming().getData().put("channel",channel);
//        rule.getOutgoing().getData().put("channel",channel);
//
//        List<String> errorMessages = Arrays.asList(new String[] { "Incoming and outgoing device channels cannot be the same" });
//        ServiceResponse response = subject.save(tenant,rule);
//
//        assertThat(response, notNullValue());
//        assertThat(response.getStatus(), equalTo(ServiceResponse.Status.ERROR));
//        assertThat(response.getResponseMessages(), equalTo(errorMessages));
//    }
    @Test
    @UsingDataSet(locations = {"/fixtures/tenants.json","/fixtures/event-rules.json"})
    public void shouldReturnAllRegisteredRulesWithinATenant() throws Exception {
        List<EventRule> allRules = subject.getAll(tenant);

        assertThat(allRules, notNullValue());
        assertThat(allRules, hasSize(8));
        assertThat(allRules.get(0).getId(), equalTo("71fb0d48-674b-4f64-a3e5-0256ff3a63af"));
        assertThat(allRules.get(1).getId(), equalTo("71fb0d48-674b-4f64-a3e5-0256ff3a63ab"));
        assertThat(allRules.get(2).getId(), equalTo("71fb0d48-674b-4f64-a3e5-0256ff3a63ac"));
        assertThat(allRules.get(3).getId(), equalTo("71fb0d48-674b-4f64-a3e5-0256ff3a63ad"));
        assertThat(allRules.get(4).getId(), equalTo("71fb0d48-674b-4f64-a3e5-0256ff3a63ae"));
        assertThat(allRules.get(5).getId(), equalTo("71fb0d48-674b-4f64-a3e5-0256ff3a63ba"));
        assertThat(allRules.get(6).getId(), equalTo("71fb0d48-674b-4f64-a3e5-0256ff3a63bb"));
        assertThat(allRules.get(7).getId(), equalTo("71fb0d48-674b-4f64-a3e5-0256ff3a63bc"));

        allRules = subject.getAll(emptyTenant);
        assertThat(allRules, notNullValue());
        assertThat(allRules, empty());
{'fraction_non_alphanumeric': 0.11990111248454882, 'fraction_numerical': 0.029520831818512325, 'mean_word_length': 4.2476154139641356, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4633328', 'n_tokens_mistral': 4135, 'n_tokens_neox': 3990, 'n_words': 572}