Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions api-project-platform/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Spring Boot Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

<!-- Spring Boot Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down Expand Up @@ -77,6 +87,10 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.opendevstack.apiservice.projectplatform.facade.impl;

import lombok.extern.slf4j.Slf4j;
import org.opendevstack.apiservice.externalservice.projectsinfoservice.exception.ProjectsInfoServiceException;
import org.opendevstack.apiservice.externalservice.projectsinfoservice.model.Platforms;
import org.opendevstack.apiservice.externalservice.projectsinfoservice.service.ProjectsInfoService;
Expand All @@ -10,6 +11,7 @@
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class ProjectsFacadeImpl implements ProjectsFacade {

private final ProjectsInfoService projectsInfoService;
Expand All @@ -30,4 +32,5 @@ public ProjectPlatforms getProjectPlatforms(String projectKey) throws ProjectPla
throw new ProjectPlatformsException("Failed to retrieve project platforms", e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ public ProjectPlatforms toApiModel(Platforms externalPlatforms) {
ProjectPlatforms apiPlatforms = new ProjectPlatforms();

// Map sections
if (externalPlatforms.getSections() != null) {
if (externalPlatforms.sections() != null) {
apiPlatforms.setSections(
externalPlatforms.getSections().stream()
externalPlatforms.sections().stream()
.map(this::toApiSection)
.collect(Collectors.toList())
);
Expand All @@ -55,13 +55,13 @@ private Section toApiSection(PlatformSection externalSection) {
}

Section apiSection = new Section();
apiSection.setSection(externalSection.getSection());
apiSection.setTooltip(externalSection.getTooltip());
apiSection.setSection(externalSection.section());
apiSection.setTooltip(externalSection.tooltip());

// Map links
if (externalSection.getLinks() != null) {
if (externalSection.links() != null) {
apiSection.setLinks(
externalSection.getLinks().stream()
externalSection.links().stream()
.map(this::toApiLink)
.collect(Collectors.toList())
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,127 +1,82 @@
package org.opendevstack.apiservice.projectplatform.facade.impl;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.opendevstack.apiservice.externalservice.projectsinfoservice.exception.ProjectsInfoServiceException;
import org.opendevstack.apiservice.externalservice.projectsinfoservice.model.PlatformSection;
import org.opendevstack.apiservice.externalservice.projectsinfoservice.model.Platforms;
import org.opendevstack.apiservice.externalservice.projectsinfoservice.service.ProjectsInfoService;
import org.opendevstack.apiservice.projectplatform.exception.ProjectPlatformsException;
import org.opendevstack.apiservice.projectplatform.mapper.ProjectPlatformsMapper;
import org.opendevstack.apiservice.projectplatform.model.Link;
import org.opendevstack.apiservice.projectplatform.model.ProjectPlatforms;
import org.opendevstack.apiservice.projectplatform.model.Section;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class ProjectsFacadeImplTest {

@Mock
private ProjectsInfoService projectsInfoService;

@Mock
private ProjectPlatformsMapper mapper;

private ProjectsFacadeImpl facade;
private ProjectsFacadeImpl sut;

@BeforeEach
void setUp() {
facade = new ProjectsFacadeImpl(projectsInfoService, mapper);
}

@Test
void givenAnyProjectKey_whenGetProjectPlatforms_thenGetMockProjectPlatforms() throws ProjectsInfoServiceException, ProjectPlatformsException {
// Arrange
String projectKey = "DEVSTACK";
void setup() {
projectsInfoService = mock(ProjectsInfoService.class);
mapper = mock(ProjectPlatformsMapper.class);

// Create external service response
Platforms externalPlatforms = new Platforms();
sut = new ProjectsFacadeImpl(projectsInfoService, mapper);

// Create expected API response
ProjectPlatforms expectedPlatforms = createExpectedProjectPlatforms();
// Reset security context before each test
SecurityContextHolder.clearContext();
}

// Mock behavior
when(projectsInfoService.getProjectPlatforms(projectKey)).thenReturn(externalPlatforms);
when(mapper.toApiModel(externalPlatforms)).thenReturn(expectedPlatforms);

// Act
ProjectPlatforms result = facade.getProjectPlatforms(projectKey);

// Assert
assertNotNull(result, "Result should not be null");

List<Section> sections = result.getSections();
assertNotNull(sections, "Sections should not be null");
assertEquals(3, sections.size(), "There should be 3 sections");

// Validate first section
Section appPlatformSection = sections.get(0);
assertEquals("Project Shortcuts - Application Platform", appPlatformSection.getSection());
assertEquals(4, appPlatformSection.getLinks().size());
assertTrue(appPlatformSection.getLinks().stream().anyMatch(link -> link.getLabel().equals("JIRA")));
assertTrue(appPlatformSection.getLinks().stream().allMatch(link -> link.getUrl().equals("https://www.google.com")));

// Validate second section
Section dataPlatformSection = sections.get(1);
assertEquals("Project Shortcuts - Data Platform", dataPlatformSection.getSection());
assertEquals(2, dataPlatformSection.getLinks().size());

// Validate third section
Section servicesSection = sections.get(2);
assertEquals("Services", servicesSection.getSection());
assertEquals(3, servicesSection.getLinks().size());

// Verify interactions
verify(projectsInfoService, times(1)).getProjectPlatforms(projectKey);
verify(mapper, times(1)).toApiModel(externalPlatforms);
@AfterEach
void cleanup() {
SecurityContextHolder.clearContext();
}

@Test
void givenProjectsInfoServiceThrowsException_whenGetProjectPlatforms_thenRuntimeExceptionIsThrown() throws ProjectsInfoServiceException {
// Arrange
String projectKey = "DEVSTACK";
when(projectsInfoService.getProjectPlatforms(projectKey))
.thenThrow(new ProjectsInfoServiceException("Service error"));
void getProjectPlatforms_whenGetProjectPlatforms_thenReturnMappedApiModel() throws Exception {
//given
String projectKey = "PROJ";

// Act & Assert
ProjectPlatformsException exception = assertThrows(ProjectPlatformsException.class, () -> facade.getProjectPlatforms(projectKey));
List<PlatformSection> sections = List.of();
Platforms externalPlatforms = new Platforms(sections);
when(projectsInfoService.getProjectPlatforms(projectKey)).thenReturn(externalPlatforms);

assertEquals("Failed to retrieve project platforms", exception.getMessage());
verify(projectsInfoService, times(1)).getProjectPlatforms(projectKey);
verify(mapper, never()).toApiModel(any());
}
ProjectPlatforms mapped = new ProjectPlatforms();
when(mapper.toApiModel(externalPlatforms)).thenReturn(mapped);

private ProjectPlatforms createExpectedProjectPlatforms() {
ProjectPlatforms platforms = new ProjectPlatforms();
//when
ProjectPlatforms result = sut.getProjectPlatforms(projectKey);

// Set sections
Section appPlatformSection = new Section("Project Shortcuts - Application Platform", "tooltip", List.of(
new Link("JIRA", "https://www.google.com", "tooltip", "type", "abbreviation", false),
new Link("Bitbucket", "https://www.google.com", "tooltip", "type", "abbreviation", false),
new Link("Confluence", "https://www.google.com", "tooltip", "type", "abbreviation", false),
new Link("Jenkins", "https://www.google.com", "tooltip", "type", "abbreviation", false)
));
//then
verify(projectsInfoService).getProjectPlatforms(projectKey);
verify(mapper).toApiModel(externalPlatforms);

Section dataPlatformSection = new Section("Project Shortcuts - Data Platform", "tooltip", List.of(
new Link("EKG", "https://www.google.com", "tooltip", "type", "abbreviation", false),
new Link("EDGC", "https://www.google.com", "tooltip", "type", "abbreviation", false)
));
assertThat(result).isSameAs(mapped);
}

Section servicesSection = new Section("Services", "tooltip", List.of(
new Link("Service Onboarding", "https://www.google.com", "tooltip", "type", "abbreviation", false),
new Link("Documentation", "https://www.google.com", "tooltip", "type", "abbreviation", false),
new Link("Service Training", "https://www.google.com", "tooltip", "type", "abbreviation", false)
));
@Test
void getProjectPlatforms_whenInfoServiceThrowsException_thenWrapInProjectPlatformsException() throws Exception {
//given
String projectKey = "PROJ";

platforms.setSections(List.of(appPlatformSection, dataPlatformSection, servicesSection));
when(projectsInfoService.getProjectPlatforms(projectKey))
.thenThrow(new ProjectsInfoServiceException("boom"));

return platforms;
//when/then
assertThatThrownBy(() -> sut.getProjectPlatforms(projectKey))
.isInstanceOf(ProjectPlatformsException.class)
.hasMessageContaining("Failed to retrieve project platforms");
}
}

}
Loading