@Override
  public void distributeIssueChangeEvent(DefaultIssue issue, @Nullable String severity, @Nullable String type, @Nullable String transition,
    BranchDto branch, String projectKey) {
    Issue changedIssue = new Issue(issue.key(), branch.getKey());

    Boolean resolved = isResolved(transition);

    if (severity == null && type == null && resolved == null) {
      return;
    }

    IssueChangedEvent event = new IssueChangedEvent(projectKey, new Issue[]{changedIssue},
      resolved, severity, type);

    persistEvent(event, branch.getProjectUuid());
  }
@Test
  public void distributeIssueChangeEvent_whenBulkIssueChange_shouldDistributesEvents() {
    RuleDto rule = db.rules().insert();

    ProjectData projectData1 = db.components().insertPublicProject();
    ProjectDto project1 = projectData1.getProjectDto();
    BranchDto branch1 = projectData1.getMainBranchDto();
    ComponentDto componentDto1 = projectData1.getMainBranchComponent();
    IssueDto issue1 = db.issues().insert(rule, branch1, componentDto1, i -> i.setSeverity(MAJOR.name()).setType(RuleType.BUG));

    ProjectData projectData2 = db.components().insertPublicProject();
    ProjectDto project2 = projectData2.getProjectDto();
    BranchDto branch2 = projectData2.getMainBranchDto();
    ComponentDto componentDto2 = projectData2.getMainBranchComponent();
    IssueDto issue2 = db.issues().insert(rule, branch2, componentDto2, i -> i.setSeverity(MAJOR.name()).setType(RuleType.BUG));

    ProjectData projectData3 = db.components().insertPublicProject();
    ProjectDto project3 = projectData3.getProjectDto();
    BranchDto branch3 = projectData3.getMainBranchDto();
    ComponentDto componentDto3 = projectData3.getMainBranchComponent();
    IssueDto issue3 = db.issues().insert(rule, branch3, componentDto3, i -> i.setSeverity(MAJOR.name()).setType(RuleType.BUG));

    DefaultIssue defaultIssue1 = issue1.toDefaultIssue().setCurrentChangeWithoutAddChange(new FieldDiffs()
      .setDiff("resolution", null, null)
      .setDiff("severity", MAJOR.name(), CRITICAL.name())
      .setDiff("type", RuleType.BUG.name(), CODE_SMELL.name()));
    DefaultIssue defaultIssue2 = issue2.toDefaultIssue().setCurrentChangeWithoutAddChange(new FieldDiffs()
      .setDiff("resolution", "OPEN", "FALSE-POSITIVE")
      .setDiff("severity", MAJOR.name(), CRITICAL.name())
      .setDiff("type", RuleType.BUG.name(), CODE_SMELL.name()));

    Set<DefaultIssue> issues = Set.of(defaultIssue1, defaultIssue2, issue3.toDefaultIssue());
    Map<String, ComponentDto> projectsByUuid = new HashMap<>();
    projectsByUuid.put(componentDto1.branchUuid(), componentDto1);
    projectsByUuid.put(componentDto2.branchUuid(), componentDto2);
    projectsByUuid.put(componentDto3.branchUuid(), componentDto3);
    Map<String, BranchDto> branchesByProjectUuid = new HashMap<>();
    branchesByProjectUuid.put(componentDto1.branchUuid(), branch1);
    branchesByProjectUuid.put(componentDto2.branchUuid(), branch2);
    branchesByProjectUuid.put(componentDto3.branchUuid(), branch3);

    underTest.distributeIssueChangeEvent(issues, projectsByUuid, branchesByProjectUuid);

    Deque<PushEventDto> issueChangedEvents = db.getDbClient().pushEventDao()
      .selectChunkByProjectUuids(db.getSession(), Set.of(project1.getUuid(), project2.getUuid()),
        1l, null, 3);

    assertThat(issueChangedEvents).hasSize(2);

    assertThat(issueChangedEvents)
      .extracting(PushEventDto::getName, PushEventDto::getProjectUuid)
      .containsExactlyInAnyOrder(
        tuple("IssueChanged", project1.getUuid()),
        tuple("IssueChanged", project2.getUuid()));

    Optional<PushEventDto> project1Event = issueChangedEvents.stream().filter(e -> e.getProjectUuid().equals(project1.getUuid())).findFirst();
    Optional<PushEventDto> project2Event = issueChangedEvents.stream().filter(e -> e.getProjectUuid().equals(project2.getUuid())).findFirst();

    assertThat(project1Event).isPresent();
    assertThat(project2Event).isPresent();

    String firstPayload = new String(project1Event.get().getPayload(), StandardCharsets.UTF_8);
    assertThat(firstPayload)
      .contains("\"userSeverity\":\"" + CRITICAL.name() + "\"",
        "\"userType\":\"" + CODE_SMELL.name() + "\"",
        "\"resolved\":" + false);

    String secondPayload = new String(project2Event.get().getPayload(), StandardCharsets.UTF_8);
    assertThat(secondPayload)
      .contains("\"userSeverity\":\"" + CRITICAL.name() + "\"",
        "\"userType\":\"" + CODE_SMELL.name() + "\"",
        "\"resolved\":" + true);
  }