Skip to content

Commit

Permalink
Merge pull request #2546 from objectcomputing/chore-replace-skillreco…
Browse files Browse the repository at this point in the history
…rd-mocking

Replace SkillRecord Mocking in tests with actual end-to-end testing
  • Loading branch information
mkimberlin authored Jul 30, 2024
2 parents eb29edd + 31953d3 commit bf48d47
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@

public interface SkillCategoryFixture extends RepositoryFixture {

default SkillCategory createDefaultSkillCategory() {
SkillCategory skillCategory = new SkillCategory("Languages", "Programming Languages");
default SkillCategory createSkillCategory(String name, String description) {
SkillCategory skillCategory = new SkillCategory(name, description);
return getSkillCategoryRepository().save(skillCategory);
}

default SkillCategory createAnotherSkillCategory() {
SkillCategory skillCategory = new SkillCategory("Libraries", "Libraries used");
return getSkillCategoryRepository().save(skillCategory);
default SkillCategory createDefaultSkillCategory() {
return createSkillCategory("Languages", "Programming Languages");
}

default SkillCategory createAnotherSkillCategory() {
return createSkillCategory("Libraries", "Libraries used");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@

public interface SkillFixture extends RepositoryFixture {

default Skill createSkill(String name, boolean isPending, String description, boolean isExtraneous) {
return getSkillRepository().save(
new Skill(name, isPending, description, isExtraneous)
);
}

default Skill createADefaultSkill() {
return getSkillRepository().save(new Skill("Limb regeneration", true,
"Regenerate a lost limb", false));
return createSkill("Limb regeneration", true, "Regenerate a lost limb", false);
}

default Skill createASecondarySkill() {
return getSkillRepository().save(new Skill("Limb restoration", true,
"Restore a lost limb", false));
return createSkill("Limb restoration", true, "Restore a lost limb", false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,111 @@

import com.objectcomputing.checkins.services.TestContainersSuite;
import com.objectcomputing.checkins.services.fixture.RoleFixture;
import com.objectcomputing.checkins.services.fixture.SkillCategoryFixture;
import com.objectcomputing.checkins.services.fixture.SkillCategorySkillFixture;
import com.objectcomputing.checkins.services.fixture.SkillFixture;
import com.objectcomputing.checkins.services.skillcategory.SkillCategory;
import com.objectcomputing.checkins.services.skills.Skill;
import io.micronaut.http.HttpHeaders;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.client.HttpClient;
import io.micronaut.http.client.annotation.Client;
import io.micronaut.http.client.exceptions.HttpClientResponseException;
import jakarta.inject.Inject;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;

import java.io.File;
import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE;
import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

class SkillRecordControllerTest extends TestContainersSuite implements RoleFixture, SkillFixture {
class SkillRecordControllerTest extends TestContainersSuite implements RoleFixture, SkillCategoryFixture, SkillCategorySkillFixture, SkillFixture {

private final Map<String, Skill> skills = new HashMap<>();

@Inject
@Client("/services/skills/records")
private HttpClient client;

@BeforeEach
void createRolesAndPermissions() {
void buildSkillHierarchy() {
createAndAssignRoles();

SkillCategory magicCategory = createSkillCategory("Magic", "Magical skills");
skills.put("conjuring", createSkill("Conjuring", false, "Conjuring skills", false));
skills.put("divination", createSkill("Divination", true, "Conjuring skills", false));
createSkillCategorySkill(magicCategory.getId(), skills.get("conjuring").getId());
createSkillCategorySkill(magicCategory.getId(), skills.get("divination").getId());

SkillCategory programmingCategory = createSkillCategory("Programming", "Programming skills");
skills.put("java", createSkill("Java", false, "Java programming skills", false));
skills.put("rust", createSkill("Rust", false, "Rust programming skills", true));
createSkillCategorySkill(programmingCategory.getId(), skills.get("java").getId());
createSkillCategorySkill(programmingCategory.getId(), skills.get("rust").getId());
}

@Test
@SuppressWarnings("resource")
void testGetSuccess() {
HttpRequest<?> request = HttpRequest
.GET("/csv")
.basicAuth(ADMIN_ROLE, ADMIN_ROLE);
HttpResponse<File> response = client.toBlocking().exchange(request, File.class);
HttpRequest<?> request = HttpRequest.GET("/csv").basicAuth(ADMIN_ROLE, ADMIN_ROLE);
HttpResponse<String> response = client.toBlocking().exchange(request, String.class);

assertEquals(HttpStatus.OK, response.getStatus());
assertTrue(response.getBody().isPresent());
String contentDisposition = response.header(HttpHeaders.CONTENT_DISPOSITION);
assertTrue(contentDisposition.startsWith("attachment; filename=skill_records"), "Unexpected content disposition: " + contentDisposition);
assertTrue(contentDisposition.endsWith(".csv"), "Unexpected content disposition: " + contentDisposition);

String body = response.body();

String[] headers = {"name", "description", "extraneous", "pending", "category_name"};
CSVFormat csvFormat = CSVFormat.DEFAULT
.builder()
.setHeader(headers)
.setQuote('"')
.setSkipHeaderRecord(true)
.build();

CSVParser parser = assertDoesNotThrow(() -> csvFormat.parse(new StringReader(body)));
List<CSVRecord> records = parser.getRecords();

assertEquals(skills.size(), records.size());

// There's no order guaranteed in the view, so to avoid flakiness we need to check for the presence of each line
List<String> lines = records.stream().map(r -> r.stream().collect(Collectors.joining(","))).toList();
List<Executable> expectations = """
Conjuring,Conjuring skills,false,false,Magic
Divination,Conjuring skills,false,true,Magic
Java,Java programming skills,false,false,Programming
Rust,Rust programming skills,true,false,Programming"""
.lines()
.map(line -> (Executable) () -> assertTrue(lines.contains(line), "Line not found: " + line))
.toList();
assertAll(expectations);
}

@Test
void testGetNotAllowed() {
HttpRequest<?> request = HttpRequest
.GET("/csv")
.basicAuth(MEMBER_ROLE, MEMBER_ROLE);
HttpRequest<?> request = HttpRequest.GET("/csv").basicAuth(MEMBER_ROLE, MEMBER_ROLE);
HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, () ->
client.toBlocking().exchange(request, File.class)
client.toBlocking().exchange(request, String.class)
);

assertEquals(HttpStatus.FORBIDDEN, responseException.getStatus());
}

}

This file was deleted.

0 comments on commit bf48d47

Please sign in to comment.