Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/572 integrate seedlot creation #579

Merged
Show file tree
Hide file tree
Changes from 14 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ca.bc.gov.backendstartapi.dto;

import io.swagger.v3.oas.annotations.media.Schema;

/**
* This general record is used for simple data object with only a code and description to be
* consumed by endpoints.
*/
@Schema(description = """
A DTO for seedlot sources.
""")
public record SeedlotSourceDto(
@Schema(description = "The Code that represent a data object", example = "1") String code,
@Schema(description = "The description/value of the data object", example = "Squirrel cache")
String description,
@Schema(description = "Indicate whether this option is default", example = "True")
Boolean isDefault) {}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ca.bc.gov.backendstartapi.endpoint;

import ca.bc.gov.backendstartapi.dto.CodeDescriptionDto;
import ca.bc.gov.backendstartapi.dto.SeedlotSourceDto;
import ca.bc.gov.backendstartapi.entity.SeedlotSourceEntity;
import ca.bc.gov.backendstartapi.service.SeedlotSourceService;
import io.swagger.v3.oas.annotations.Operation;
Expand Down Expand Up @@ -63,14 +63,21 @@ public class SeedlotSourceEndpoint {
@Schema(
type = "string",
description = "Name of a seedlot source",
example = "Custom Lot"))
example = "Custom Lot")),
@SchemaProperty(
name = "isDefault",
schema =
@Schema(
type = "boolean",
description = "Indicates if this option is default",
example = "true"))
})),
@ApiResponse(
responseCode = "401",
description = "Access token is missing or invalid",
content = @Content(schema = @Schema(implementation = Void.class)))
})
public List<CodeDescriptionDto> getAllSeedlotSource() {
public List<SeedlotSourceDto> getAllSeedlotSource() {
return seedlotSourceService.getAllSeedlotSource();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,19 @@ public class SeedlotSourceEntity extends CodeDescriptionEntity {
@Column(name = "seedlot_source_code", length = 3)
private String seedlotSourceCode;

@Column(name = "default_source_ind", nullable = true)
private Boolean isDefault;

/**
* Constructor for SeedlotSourceEntity.
*/
public SeedlotSourceEntity(
String seedlotSourceCode, String description, EffectiveDateRange effectiveDateRange) {
String seedlotSourceCode,
String description,
EffectiveDateRange effectiveDateRange,
Boolean isDefault) {
super(description, effectiveDateRange);
this.seedlotSourceCode = seedlotSourceCode;
this.isDefault = isDefault;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ca.bc.gov.backendstartapi.service;

import ca.bc.gov.backendstartapi.dto.CodeDescriptionDto;
import ca.bc.gov.backendstartapi.dto.SeedlotSourceDto;
import ca.bc.gov.backendstartapi.repository.SeedlotSourceRepository;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -18,15 +18,18 @@ public SeedlotSourceService(SeedlotSourceRepository seedlotSourceRepository) {
}

/** Fetch all valid seedlot source from the repository. */
public List<CodeDescriptionDto> getAllSeedlotSource() {
public List<SeedlotSourceDto> getAllSeedlotSource() {
log.info("Fetching all seedlot source");
List<CodeDescriptionDto> resultList = new ArrayList<>();
List<SeedlotSourceDto> resultList = new ArrayList<>();
seedlotSourceRepository.findAll().stream()
.filter(method -> method.isValid())
.forEach(
method -> {
CodeDescriptionDto methodToAdd =
new CodeDescriptionDto(method.getSeedlotSourceCode(), method.getDescription());
SeedlotSourceDto methodToAdd =
new SeedlotSourceDto(
method.getSeedlotSourceCode(),
method.getDescription(),
method.getIsDefault());
resultList.add(methodToAdd);
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
alter table
spar.seedlot_source_list
add
default_source_ind boolean default null;

alter table
spar.seedlot_source_list
add
constraint only_one_default_source unique (default_source_ind);

update
spar.seedlot_source_list
set
description = 'Custom Seedlot'
where
seedlot_source_code = 'CUS';

update
spar.seedlot_source_list
set
default_source_ind = true
where
seedlot_source_code = 'TPT';
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import ca.bc.gov.backendstartapi.dto.CodeDescriptionDto;
import ca.bc.gov.backendstartapi.dto.SeedlotSourceDto;
import ca.bc.gov.backendstartapi.service.SeedlotSourceService;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
Expand Down Expand Up @@ -37,9 +37,9 @@ class SeedlotSourceEndpointTest {
@WithMockUser(roles = "user_read")
void getAllSeedlotSource() throws Exception {

CodeDescriptionDto firstMethod = new CodeDescriptionDto("CUS", "Custom Lot");
CodeDescriptionDto secondMethod = new CodeDescriptionDto("TPT", "Tested Parent Trees");
CodeDescriptionDto thirdMethod = new CodeDescriptionDto("UPT", "Untested Parent Trees");
SeedlotSourceDto firstMethod = new SeedlotSourceDto("CUS", "Custom Lot", null);
SeedlotSourceDto secondMethod = new SeedlotSourceDto("TPT", "Tested Parent Trees", true);
SeedlotSourceDto thirdMethod = new SeedlotSourceDto("UPT", "Untested Parent Trees", null);

when(seedlotSourceService.getAllSeedlotSource())
.thenReturn(List.of(firstMethod, secondMethod, thirdMethod));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ protected Seedlot createSeedlot(String id) {
new GeneticWorthEntity("AD", "Animal browse resistance (deer)", effectiveDateRange);
geneticWorthRepository.saveAndFlush(geneticWorth);


var seedlotSource = new SeedlotSourceEntity("CUS", "Custom Lot", effectiveDateRange);
var seedlotSource = new SeedlotSourceEntity("CUS", "Custom Lot", effectiveDateRange, null);
seedlotSourceRepository.saveAndFlush(seedlotSource);

var seedlot = new Seedlot(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void createSeedlotTest_happyPath_shouldSucceed() {
when(seedlotStatusRepository.findById("PND")).thenReturn(Optional.of(statusEntity));

SeedlotSourceEntity sourceEntity =
new SeedlotSourceEntity("TPT", "Tested Parent Trees", DATE_RANGE);
new SeedlotSourceEntity("TPT", "Tested Parent Trees", DATE_RANGE, null);
when(seedlotSourceRepository.findById("TPT")).thenReturn(Optional.of(sourceEntity));

Seedlot seedlot = new Seedlot("63000");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.mockito.Mockito.when;

import ca.bc.gov.backendstartapi.dto.CodeDescriptionDto;
import ca.bc.gov.backendstartapi.dto.SeedlotSourceDto;
import ca.bc.gov.backendstartapi.entity.SeedlotSourceEntity;
import ca.bc.gov.backendstartapi.entity.embeddable.EffectiveDateRange;
import ca.bc.gov.backendstartapi.repository.SeedlotSourceRepository;
Expand Down Expand Up @@ -39,15 +40,15 @@ void getAllSeedlotSourceServiceTest() {
var expiredDateRange = new EffectiveDateRange(effectiveDate, expiredDate);

SeedlotSourceEntity firstEntity =
new SeedlotSourceEntity("CUS", "Custom Lot", effectiveDateRange);
new SeedlotSourceEntity("CUS", "Custom Lot", effectiveDateRange, null);
seedlotSourceRepository.saveAndFlush(firstEntity);
SeedlotSourceEntity secondEntity =
new SeedlotSourceEntity("TPT", "Tested Parent Trees", effectiveDateRange);
new SeedlotSourceEntity("TPT", "Tested Parent Trees", effectiveDateRange, true);
seedlotSourceRepository.saveAndFlush(secondEntity);

// This entity should not appear in the result list
SeedlotSourceEntity expiredEntity =
new SeedlotSourceEntity("V", "V for Vendetta", expiredDateRange);
new SeedlotSourceEntity("V", "V for Vendetta", expiredDateRange, null);
seedlotSourceRepository.saveAndFlush(expiredEntity);

List<SeedlotSourceEntity> testEntityList =
Expand All @@ -74,7 +75,7 @@ void getAllSeedlotSourceServiceTest() {
}
};

List<CodeDescriptionDto> resultList = seedlotSourceService.getAllSeedlotSource();
List<SeedlotSourceDto> resultList = seedlotSourceService.getAllSeedlotSource();

Assertions.assertEquals(testEntityList.size() - 1, resultList.size());
Assertions.assertEquals(testDtoList.size(), resultList.size());
Expand Down
54 changes: 36 additions & 18 deletions frontend/cypress/e2e/smoke-test/create-a-class-seedlot.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,29 @@ describe('Create A Class Seedlot', () => {
cy.login();
cy.visit('/seedlots');
cy.url().should('contains', '/seedlots');

cy.intercept(
{
method: 'GET',
url: '**/api/forest-clients/**'
},
{
statusCode: 200
}
).as('verifyLocationCode');

cy.intercept(
{
method: 'POST',
url: '**/api/seedlots'
},
{
statusCode: 200,
craigyu marked this conversation as resolved.
Show resolved Hide resolved
body: {
seedlotNumber: '654321'
}
}
).as('submitSeedlot');
});

it('should register a Class A Seedlot', () => {
Expand Down Expand Up @@ -55,33 +78,33 @@ describe('Create A Class Seedlot', () => {
.scrollIntoView()
.click();
// Check checkbox behavior when Tested parent tree selected
cy.get('#tested-radio')
cy.get('#seedlot-source-radio-btn-tpt')
.should('be.checked');
cy.get('#untested-radio')
cy.get('#seedlot-source-radio-btn-upt')
.should('not.be.checked');
cy.get('#custom-radio')
cy.get('#seedlot-source-radio-btn-cus')
.should('not.be.checked');
// Check checkbox behavior when Custom seedlot selected
cy.get('#custom-radio')
cy.get('#seedlot-source-radio-btn-cus')
.siblings('.bx--radio-button__label')
.find('.bx--radio-button__appearance')
.click();
cy.get('#tested-radio')
cy.get('#seedlot-source-radio-btn-tpt')
.should('not.be.checked');
cy.get('#untested-radio')
cy.get('#seedlot-source-radio-btn-upt')
.should('not.be.checked');
cy.get('#custom-radio')
cy.get('#seedlot-source-radio-btn-cus')
.should('be.checked');
// Check checkbox behavior when Untested parent tree selected
cy.get('#untested-radio')
cy.get('#seedlot-source-radio-btn-upt')
.siblings('.bx--radio-button__label')
.find('.bx--radio-button__appearance')
.click();
cy.get('#tested-radio')
cy.get('#seedlot-source-radio-btn-tpt')
.should('not.be.checked');
cy.get('#untested-radio')
cy.get('#seedlot-source-radio-btn-upt')
.should('be.checked');
cy.get('#custom-radio')
cy.get('#seedlot-source-radio-btn-cus')
.should('not.be.checked');
// To be registered? should be checked by default
cy.get('#registered-tree-seed-center')
Expand All @@ -93,13 +116,8 @@ describe('Create A Class Seedlot', () => {
cy.get('.save-button')
.find('button')
.click();
// To-do Validate seedlot id
cy.get('.scf-info-container')
.find('h2')
.contains(/^Your A class seedlot [0-9]/);
cy.contains('button', "Go back to seedlot's main screen")
.click();
cy.get('.bx--data-table-content').contains(data.seedlotInformation.species);
cy.url().should('contains', '/creation-success');
cy.get('h1').contains('654321');
});
});

Expand Down
21 changes: 21 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"react-hash-string": "^1.0.0",
"react-router-dom": "^6.3.0",
"react-test-renderer": "^18.2.0",
"react-toastify": "^9.1.3",
"sass": "1.64.2",
"ts-jest": "^29.1.0",
"typescript": "^5.1.3",
Expand Down
Loading
Loading