diff --git a/docs/sequencingModule.drawio.png b/docs/sequencingModule.drawio.png index 935d0f7b..f48018a6 100644 Binary files a/docs/sequencingModule.drawio.png and b/docs/sequencingModule.drawio.png differ diff --git a/src/main/java/ca/gc/aafc/seqdb/api/dto/SequenceManagedAttributeDto.java b/src/main/java/ca/gc/aafc/seqdb/api/dto/SequenceManagedAttributeDto.java new file mode 100644 index 00000000..6d4f83ca --- /dev/null +++ b/src/main/java/ca/gc/aafc/seqdb/api/dto/SequenceManagedAttributeDto.java @@ -0,0 +1,41 @@ +package ca.gc.aafc.seqdb.api.dto; + +import ca.gc.aafc.dina.dto.RelatedEntity; +import ca.gc.aafc.dina.i18n.MultilingualDescription; +import ca.gc.aafc.dina.vocabulary.TypedVocabularyElement; +import ca.gc.aafc.seqdb.api.entities.SequenceManagedAttribute; + +import io.crnk.core.resource.annotations.JsonApiId; +import io.crnk.core.resource.annotations.JsonApiResource; +import lombok.Data; + +import java.time.OffsetDateTime; +import java.util.UUID; + +import org.javers.core.metamodel.annotation.Id; +import org.javers.core.metamodel.annotation.PropertyName; +import org.javers.core.metamodel.annotation.TypeName; + +@RelatedEntity(SequenceManagedAttribute.class) +@Data +@JsonApiResource(type = SequenceManagedAttributeDto.TYPENAME) +@TypeName(SequenceManagedAttributeDto.TYPENAME) +public class SequenceManagedAttributeDto { + public static final String TYPENAME = "managed-attribute"; + + @JsonApiId + @Id + @PropertyName("id") + private UUID uuid; + private String name; + private String key; + private TypedVocabularyElement.VocabularyElementType vocabularyElementType; + private String unit; + private SequenceManagedAttribute.ManagedAttributeComponent managedAttributeComponent; + private String[] acceptedValues; + private OffsetDateTime createdOn; + private String createdBy; + private String group; + private MultilingualDescription multilingualDescription; + +} diff --git a/src/main/java/ca/gc/aafc/seqdb/api/entities/SequenceManagedAttribute.java b/src/main/java/ca/gc/aafc/seqdb/api/entities/SequenceManagedAttribute.java new file mode 100644 index 00000000..8db2517b --- /dev/null +++ b/src/main/java/ca/gc/aafc/seqdb/api/entities/SequenceManagedAttribute.java @@ -0,0 +1,118 @@ +package ca.gc.aafc.seqdb.api.entities; + +import java.time.OffsetDateTime; +import java.util.UUID; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.Getter; + +import org.hibernate.annotations.Generated; +import org.hibernate.annotations.GenerationTime; +import org.hibernate.annotations.NaturalId; +import org.hibernate.annotations.NaturalIdCache; +import org.hibernate.annotations.Type; + +import ca.gc.aafc.dina.entity.DinaEntityIdentifiableByName; +import ca.gc.aafc.dina.entity.ManagedAttribute; +import ca.gc.aafc.dina.i18n.MultilingualDescription; +import ca.gc.aafc.dina.i18n.MultilingualTitle; + +@Entity(name = "managed_attribute") +@Getter +@Setter +@Builder +@AllArgsConstructor +@RequiredArgsConstructor +@NaturalIdCache +public class SequenceManagedAttribute implements ManagedAttribute, DinaEntityIdentifiableByName { + + public enum ManagedAttributeComponent { + GENERIC_MOLECULAR_ANALYSIS; + + public static ManagedAttributeComponent fromString(String s) { + for (ManagedAttributeComponent source : ManagedAttributeComponent.values()) { + if (source.name().equalsIgnoreCase(s)) { + return source; + } + } + return null; + } + } + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @NaturalId + @NotNull + @Column(name = "uuid", unique = true) + private UUID uuid; + + @Column(name = "created_on", insertable = false, updatable = false) + @Generated(value = GenerationTime.INSERT) + private OffsetDateTime createdOn; + + @NotBlank + @Column(name = "created_by", updatable = false) + private String createdBy; + + @NotBlank + private String name; + + @Type(type = "jsonb") + @Column(name = "multilingual_description") + @Valid + private MultilingualDescription multilingualDescription; + + @NotBlank + @Column(name = "_group") + @Size(max = 50) + private String group; + + @NotBlank + @Size(max = 50) + @Column(updatable = false) + private String key; + + @NotNull + @Type(type = "pgsql_enum") + @Enumerated(EnumType.STRING) + @Column(name = "type") + private VocabularyElementType vocabularyElementType; + + @NotNull + @Enumerated(EnumType.STRING) + @Column(name = "component") + private ManagedAttributeComponent managedAttributeComponent; + + @Type(type = "string-array") + @Column(name = "accepted_values", columnDefinition = "text[]") + private String[] acceptedValues; + + @Size(max = 50) + private String unit; + + @Override + public String getTerm() { + return null; + } + + @Override + public MultilingualTitle getMultilingualTitle() { + return null; + } + +} diff --git a/src/main/java/ca/gc/aafc/seqdb/api/repository/SequenceManagedAttributeRepository.java b/src/main/java/ca/gc/aafc/seqdb/api/repository/SequenceManagedAttributeRepository.java new file mode 100644 index 00000000..9ee6309d --- /dev/null +++ b/src/main/java/ca/gc/aafc/seqdb/api/repository/SequenceManagedAttributeRepository.java @@ -0,0 +1,88 @@ +package ca.gc.aafc.seqdb.api.repository; + +import org.springframework.boot.info.BuildProperties; +import org.springframework.stereotype.Repository; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import ca.gc.aafc.dina.mapper.DinaMapper; +import ca.gc.aafc.dina.repository.DinaRepository; +import ca.gc.aafc.dina.repository.external.ExternalResourceProvider; +import ca.gc.aafc.dina.security.DinaAuthenticatedUser; +import ca.gc.aafc.dina.security.TextHtmlSanitizer; +import ca.gc.aafc.dina.service.AuditService; +import ca.gc.aafc.seqdb.api.dto.SequenceManagedAttributeDto; +import ca.gc.aafc.seqdb.api.entities.SequenceManagedAttribute; +import ca.gc.aafc.seqdb.api.security.SuperUserInGroupCUDAuthorizationService; +import ca.gc.aafc.seqdb.api.service.SequenceManagedAttributeService; + +import io.crnk.core.exception.ResourceNotFoundException; +import io.crnk.core.queryspec.QuerySpec; +import java.io.Serializable; +import java.util.Optional; +import java.util.regex.Pattern; +import lombok.NonNull; + +@Repository +public class SequenceManagedAttributeRepository extends DinaRepository { + + private final SequenceManagedAttributeService dinaService; + private Optional dinaAuthenticatedUser; + + public static final Pattern KEY_LOOKUP_PATTERN = Pattern.compile("(.*)\\.(.*)"); + + public SequenceManagedAttributeRepository( + @NonNull SequenceManagedAttributeService service, + @NonNull SuperUserInGroupCUDAuthorizationService authService, + ExternalResourceProvider externalResourceProvider, + @NonNull AuditService auditService, + @NonNull BuildProperties buildProperties, + Optional dinaAuthenticatedUser, + ObjectMapper objectMapper + ) { + super( + service, authService, + Optional.of(auditService), + new DinaMapper<>(SequenceManagedAttributeDto.class), + SequenceManagedAttributeDto.class, + SequenceManagedAttribute.class, + null, + externalResourceProvider, + buildProperties, objectMapper); + this.dinaService = service; + this.dinaAuthenticatedUser = dinaAuthenticatedUser; + } + + @Override + public S create(S resource) { + dinaAuthenticatedUser.ifPresent( + authenticatedUser -> resource.setCreatedBy(authenticatedUser.getUsername())); + return super.create(resource); + } + + @Override + public SequenceManagedAttributeDto findOne(Serializable id, QuerySpec querySpec) { + + // Allow lookup by component type + key. + // e.g. collecting_event.attribute_name + var matcher = KEY_LOOKUP_PATTERN.matcher(id.toString()); + if (matcher.groupCount() == 2) { + if (matcher.find()) { + SequenceManagedAttribute.ManagedAttributeComponent component = SequenceManagedAttribute.ManagedAttributeComponent + .fromString(matcher.group(1)); + String attributeKey = matcher.group(2); + + SequenceManagedAttribute managedAttribute = + dinaService.findOneByKeyAndComponent(attributeKey, component); + + if (managedAttribute != null) { + return getMappingLayer().toDtoSimpleMapping(managedAttribute); + } else { + throw new ResourceNotFoundException("Managed Attribute not found: " + TextHtmlSanitizer.sanitizeText(id.toString())); + } + } + } + + return super.findOne(id, querySpec); + } +} diff --git a/src/main/java/ca/gc/aafc/seqdb/api/security/SuperUserInGroupCUDAuthorizationService.java b/src/main/java/ca/gc/aafc/seqdb/api/security/SuperUserInGroupCUDAuthorizationService.java new file mode 100644 index 00000000..e46af135 --- /dev/null +++ b/src/main/java/ca/gc/aafc/seqdb/api/security/SuperUserInGroupCUDAuthorizationService.java @@ -0,0 +1,39 @@ +package ca.gc.aafc.seqdb.api.security; + +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Service; + +import ca.gc.aafc.dina.security.auth.PermissionAuthorizationService; + +/** + * Authorization service that will authorize SUPER_USER (and DINA_ADMIN) for the group of the entity. + * The currentUser must be at least SUPER_USER on the group defined on the entity. + */ +@Service +public class SuperUserInGroupCUDAuthorizationService extends PermissionAuthorizationService { + + @Override + @PreAuthorize("hasMinimumGroupAndRolePermissions(@currentUser, 'SUPER_USER', #entity)") + public void authorizeCreate(Object entity) { + } + + @Override + @PreAuthorize("hasMinimumGroupAndRolePermissions(@currentUser, 'SUPER_USER', #entity)") + public void authorizeUpdate(Object entity) { + } + + @Override + @PreAuthorize("hasMinimumGroupAndRolePermissions(@currentUser, 'SUPER_USER', #entity)") + public void authorizeDelete(Object entity) { + } + + // Do nothing for now + @Override + public void authorizeRead(Object entity) { + } + + @Override + public String getName() { + return "SuperUserInGroupCUDAuthorizationService"; + } +} diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/SequenceManagedAttributeService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/SequenceManagedAttributeService.java new file mode 100644 index 00000000..0e5b4931 --- /dev/null +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/SequenceManagedAttributeService.java @@ -0,0 +1,69 @@ +package ca.gc.aafc.seqdb.api.service; + +import liquibase.repackaged.org.apache.commons.lang3.StringUtils; +import lombok.NonNull; + +import org.apache.commons.lang3.tuple.Pair; +import org.springframework.stereotype.Service; +import org.springframework.validation.SmartValidator; + +import ca.gc.aafc.dina.jpa.BaseDAO; +import ca.gc.aafc.dina.service.ManagedAttributeService; +import ca.gc.aafc.dina.service.PostgresJsonbService; +import ca.gc.aafc.dina.util.UUIDHelper; +import ca.gc.aafc.seqdb.api.entities.SequenceManagedAttribute; + +@Service +public class SequenceManagedAttributeService extends ManagedAttributeService { + + public static final String MANAGED_ATTRIBUTES_COL_NAME = "managed_attributes"; + + public static final String GENERIC_MOLECULAR_ANALYSIS_TABLE_NAME = "generic_molecular_analysis"; + + private static final String COMPONENT_FIELD_NAME = "managedAttributeComponent"; + + private final PostgresJsonbService jsonbService; + + public SequenceManagedAttributeService( + @NonNull BaseDAO baseDAO, + @NonNull SmartValidator sv, + @NonNull PostgresJsonbService postgresJsonbService) { + super(baseDAO, sv, SequenceManagedAttribute.class); + this.jsonbService = postgresJsonbService; + } + + @Override + protected void preCreate(SequenceManagedAttribute entity) { + entity.setUuid(UUIDHelper.generateUUIDv7()); + entity.setGroup(standardizeGroupName(entity)); + super.preCreate(entity); + } + + @Override + protected void preDelete(SequenceManagedAttribute entity) { + switch (entity.getManagedAttributeComponent()) { + case GENERIC_MOLECULAR_ANALYSIS: + checkKeysFor(entity.getKey(), GENERIC_MOLECULAR_ANALYSIS_TABLE_NAME); + break; + default: + throw new IllegalStateException( + "Unexpected managed attribute component of: " + entity.getManagedAttributeComponent()); + } + } + + public SequenceManagedAttribute findOneByKeyAndComponent(String key, + SequenceManagedAttribute.ManagedAttributeComponent component) { + if (StringUtils.isBlank(key) || component == null) { + return null; + } + return findOneByKeyAnd(key, Pair.of(COMPONENT_FIELD_NAME, component)); + } + + private void checkKeysFor(String key, String tableName) { + Integer countFirstLevelKeys = jsonbService.countFirstLevelKeys( + tableName, SequenceManagedAttributeService.MANAGED_ATTRIBUTES_COL_NAME, key); + if (countFirstLevelKeys > 0) { + throw new IllegalStateException("Managed attribute key: " + key + ", is currently in use."); + } + } +} diff --git a/src/main/resources/db/changelog/db.changelog-master.xml b/src/main/resources/db/changelog/db.changelog-master.xml index 97de9032..4d9d25cc 100644 --- a/src/main/resources/db/changelog/db.changelog-master.xml +++ b/src/main/resources/db/changelog/db.changelog-master.xml @@ -59,4 +59,5 @@ + diff --git a/src/main/resources/db/changelog/migrations/55-Add_managed_attribute.xml b/src/main/resources/db/changelog/migrations/55-Add_managed_attribute.xml new file mode 100644 index 00000000..0eeb27f3 --- /dev/null +++ b/src/main/resources/db/changelog/migrations/55-Add_managed_attribute.xml @@ -0,0 +1,51 @@ + + + + + + CREATE TYPE managed_attribute_type AS ENUM ( + 'INTEGER', + 'STRING', + 'DATE', + 'BOOL', + 'DECIMAL' + ); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/java/ca/gc/aafc/seqdb/api/BaseIntegrationTest.java b/src/test/java/ca/gc/aafc/seqdb/api/BaseIntegrationTest.java index c676b83a..e7dbd329 100644 --- a/src/test/java/ca/gc/aafc/seqdb/api/BaseIntegrationTest.java +++ b/src/test/java/ca/gc/aafc/seqdb/api/BaseIntegrationTest.java @@ -29,7 +29,7 @@ public abstract class BaseIntegrationTest { @PersistenceContext protected EntityManager entityManager; - @Inject - protected DatabaseSupportService service; +// @Inject +// protected DatabaseSupportService service; } diff --git a/src/test/java/ca/gc/aafc/seqdb/api/SequenceModuleBaseIT.java b/src/test/java/ca/gc/aafc/seqdb/api/SequenceModuleBaseIT.java index cc735c59..4166e806 100644 --- a/src/test/java/ca/gc/aafc/seqdb/api/SequenceModuleBaseIT.java +++ b/src/test/java/ca/gc/aafc/seqdb/api/SequenceModuleBaseIT.java @@ -12,6 +12,7 @@ import ca.gc.aafc.seqdb.api.service.PcrBatchItemService; import ca.gc.aafc.seqdb.api.service.PcrBatchService; import ca.gc.aafc.seqdb.api.service.SeqSubmissionService; +import ca.gc.aafc.seqdb.api.service.SequenceManagedAttributeService; import ca.gc.aafc.seqdb.api.service.SequencingFacilityService; public class SequenceModuleBaseIT extends BaseIntegrationTest { @@ -49,4 +50,7 @@ public class SequenceModuleBaseIT extends BaseIntegrationTest { @Inject protected MetagenomicsBatchItemService metagenomicsBatchItemService; + @Inject + protected SequenceManagedAttributeService managedAttributeService; + } diff --git a/src/test/java/ca/gc/aafc/seqdb/api/repository/SequenceManagedAttributeRepositoryIT.java b/src/test/java/ca/gc/aafc/seqdb/api/repository/SequenceManagedAttributeRepositoryIT.java new file mode 100644 index 00000000..04cc5f02 --- /dev/null +++ b/src/test/java/ca/gc/aafc/seqdb/api/repository/SequenceManagedAttributeRepositoryIT.java @@ -0,0 +1,54 @@ +package ca.gc.aafc.seqdb.api.repository; + +import io.crnk.core.queryspec.QuerySpec; +import java.util.UUID; +import javax.inject.Inject; + +import org.junit.jupiter.api.Test; + +import ca.gc.aafc.dina.testsupport.security.WithMockKeycloakUser; +import ca.gc.aafc.dina.vocabulary.TypedVocabularyElement; +import ca.gc.aafc.seqdb.api.dto.SequenceManagedAttributeDto; +import ca.gc.aafc.seqdb.api.entities.SequenceManagedAttribute; + +import ca.gc.aafc.seqdb.api.testsupport.fixtures.SequenceManagedAttributeTestFixture; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class SequenceManagedAttributeRepositoryIT extends BaseRepositoryTestV2 { + + @Inject + private SequenceManagedAttributeRepository repo; + + @Test + @WithMockKeycloakUser(groupRole = "dina-group:SUPER_USER") + void create_recordCreated() { + String expectedName = "dina attribute #12"; + String expectedValue = "dina value"; + String expectedCreatedBy = "dina"; + String expectedGroup = "dina-group"; + + SequenceManagedAttributeDto dto = SequenceManagedAttributeTestFixture.newManagedAttribute(); + dto.setName(expectedName); + dto.setVocabularyElementType(TypedVocabularyElement.VocabularyElementType.INTEGER); + dto.setAcceptedValues(new String[]{expectedValue}); + dto.setManagedAttributeComponent(SequenceManagedAttribute.ManagedAttributeComponent.GENERIC_MOLECULAR_ANALYSIS); + dto.setCreatedBy(expectedCreatedBy); + dto.setGroup(expectedGroup); + + UUID uuid = repo.create(dto).getUuid(); + SequenceManagedAttributeDto result = repo.findOne(uuid, new QuerySpec( + SequenceManagedAttributeDto.class)); + assertEquals(uuid, result.getUuid()); + assertEquals(expectedName, result.getName()); + assertEquals("dina_attribute_12", result.getKey()); + assertEquals(expectedValue, result.getAcceptedValues()[0]); + assertNotNull(result.getCreatedBy()); + assertEquals(expectedGroup, result.getGroup()); + assertEquals(TypedVocabularyElement.VocabularyElementType.INTEGER, result.getVocabularyElementType()); + assertEquals( + SequenceManagedAttribute.ManagedAttributeComponent.GENERIC_MOLECULAR_ANALYSIS, + result.getManagedAttributeComponent()); + } +} diff --git a/src/test/java/ca/gc/aafc/seqdb/api/service/SequenceManagedAttributeServiceIT.java b/src/test/java/ca/gc/aafc/seqdb/api/service/SequenceManagedAttributeServiceIT.java new file mode 100644 index 00000000..53372067 --- /dev/null +++ b/src/test/java/ca/gc/aafc/seqdb/api/service/SequenceManagedAttributeServiceIT.java @@ -0,0 +1,38 @@ +package ca.gc.aafc.seqdb.api.service; + +import org.junit.jupiter.api.Test; + +import ca.gc.aafc.seqdb.api.SequenceModuleBaseIT; +import ca.gc.aafc.seqdb.api.entities.SequenceManagedAttribute; +import ca.gc.aafc.seqdb.api.testsupport.factories.SequenceManagedAttributeFactory; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class SequenceManagedAttributeServiceIT extends SequenceModuleBaseIT { + + private static final String GROUP = "grp"; + + @Test + void delete_WhenNotInUse_DeleteAccepted() { + SequenceManagedAttribute attribute = newAttribute(SequenceManagedAttribute.ManagedAttributeComponent.GENERIC_MOLECULAR_ANALYSIS); + managedAttributeService.create(attribute); + + assertNotNull( + managedAttributeService.findOne(attribute.getUuid(), SequenceManagedAttribute.class)); + + // To enable when usage is implemented +// managedAttributeService.delete(attribute); +// +// Assertions.assertNull( +// managedAttributeService.findOne(attribute.getUuid(), CollectionManagedAttribute.class)); + } + + private static SequenceManagedAttribute newAttribute(SequenceManagedAttribute.ManagedAttributeComponent component) { + return SequenceManagedAttributeFactory.newManagedAttribute() + .createdBy("SequenceManagedAttributeServiceIT") + .managedAttributeComponent(component) + .group(GROUP) + .acceptedValues(null) + .build(); + } +} diff --git a/src/test/java/ca/gc/aafc/seqdb/api/testsupport/factories/SequenceManagedAttributeFactory.java b/src/test/java/ca/gc/aafc/seqdb/api/testsupport/factories/SequenceManagedAttributeFactory.java new file mode 100644 index 00000000..fb40a1a9 --- /dev/null +++ b/src/test/java/ca/gc/aafc/seqdb/api/testsupport/factories/SequenceManagedAttributeFactory.java @@ -0,0 +1,26 @@ +package ca.gc.aafc.seqdb.api.testsupport.factories; + +import java.util.UUID; + +import org.apache.commons.lang3.RandomStringUtils; + +import ca.gc.aafc.dina.vocabulary.TypedVocabularyElement; +import ca.gc.aafc.seqdb.api.entities.SequenceManagedAttribute; +import ca.gc.aafc.seqdb.api.testsupport.fixtures.MultilingualTestFixture; + +public class SequenceManagedAttributeFactory { + + public static SequenceManagedAttribute.SequenceManagedAttributeBuilder newManagedAttribute() { + return SequenceManagedAttribute + .builder() + .uuid(UUID.randomUUID()) + .name(RandomStringUtils.randomAlphabetic(5)) + .group(RandomStringUtils.randomAlphabetic(5)) + .createdBy(RandomStringUtils.randomAlphabetic(5)) + .vocabularyElementType(TypedVocabularyElement.VocabularyElementType.STRING) + .acceptedValues(new String[]{"value"}) + .managedAttributeComponent(SequenceManagedAttribute.ManagedAttributeComponent.GENERIC_MOLECULAR_ANALYSIS) + .multilingualDescription(MultilingualTestFixture.newMultilingualDescription()); + } + +} diff --git a/src/test/java/ca/gc/aafc/seqdb/api/testsupport/fixtures/MultilingualTestFixture.java b/src/test/java/ca/gc/aafc/seqdb/api/testsupport/fixtures/MultilingualTestFixture.java new file mode 100644 index 00000000..542b08b1 --- /dev/null +++ b/src/test/java/ca/gc/aafc/seqdb/api/testsupport/fixtures/MultilingualTestFixture.java @@ -0,0 +1,26 @@ +package ca.gc.aafc.seqdb.api.testsupport.fixtures; + +import java.util.List; + +import org.apache.commons.lang3.RandomStringUtils; + +import ca.gc.aafc.dina.i18n.MultilingualDescription; +import ca.gc.aafc.dina.i18n.MultilingualTitle; + +public class MultilingualTestFixture { + + public static MultilingualDescription newMultilingualDescription() { + return MultilingualDescription.builder() + .descriptions(List.of(MultilingualDescription + .MultilingualPair.of("en", RandomStringUtils.randomAlphabetic(4)))) + .build(); + } + + public static MultilingualTitle newMultilingualTitle() { + return MultilingualTitle.builder() + .titles(List.of(MultilingualTitle + .MultilingualTitlePair.of("en", RandomStringUtils.randomAlphabetic(4)))) + .build(); + } + +} diff --git a/src/test/java/ca/gc/aafc/seqdb/api/testsupport/fixtures/SequenceManagedAttributeTestFixture.java b/src/test/java/ca/gc/aafc/seqdb/api/testsupport/fixtures/SequenceManagedAttributeTestFixture.java new file mode 100644 index 00000000..46e1a8f1 --- /dev/null +++ b/src/test/java/ca/gc/aafc/seqdb/api/testsupport/fixtures/SequenceManagedAttributeTestFixture.java @@ -0,0 +1,26 @@ +package ca.gc.aafc.seqdb.api.testsupport.fixtures; + +import org.apache.commons.lang3.RandomStringUtils; + +import ca.gc.aafc.dina.vocabulary.TypedVocabularyElement; +import ca.gc.aafc.seqdb.api.dto.SequenceManagedAttributeDto; +import ca.gc.aafc.seqdb.api.entities.SequenceManagedAttribute; + +public class SequenceManagedAttributeTestFixture { + + public static final String GROUP = "dina"; + + public static SequenceManagedAttributeDto newManagedAttribute() { + SequenceManagedAttributeDto collectionManagedAttributeDto = new SequenceManagedAttributeDto(); + collectionManagedAttributeDto.setName(RandomStringUtils.randomAlphabetic(5)); + collectionManagedAttributeDto.setGroup(GROUP); + collectionManagedAttributeDto.setVocabularyElementType( + TypedVocabularyElement.VocabularyElementType.INTEGER); + collectionManagedAttributeDto.setAcceptedValues(new String[]{"1", "2"}); + collectionManagedAttributeDto.setUnit("cm"); + collectionManagedAttributeDto.setManagedAttributeComponent(SequenceManagedAttribute.ManagedAttributeComponent.GENERIC_MOLECULAR_ANALYSIS); + collectionManagedAttributeDto.setCreatedBy("created by"); + collectionManagedAttributeDto.setMultilingualDescription(MultilingualTestFixture.newMultilingualDescription()); + return collectionManagedAttributeDto; + } +}