Merge branch 'master' of ssh://dev.hostsharing.net:29418/hsadmin/hsadmin-ng

This commit is contained in:
Michael Hierweck 2019-04-27 15:46:55 +02:00
commit 2fdb914f6d
46 changed files with 811 additions and 195 deletions

View File

@ -42,9 +42,6 @@ public class HsadminNgApp {
@PostConstruct
public void initApplication() {
// TODO: remove this hack once proper user roles are implemented
SecurityUtils.addUserRole(null, null, Role.HOSTMASTER);
Collection<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
log.error("You have misconfigured your application! It should not run " +
@ -54,6 +51,14 @@ public class HsadminNgApp {
log.error("You have misconfigured your application! It should not " +
"run with both the 'dev' and 'cloud' profiles at the same time.");
}
// TODO: remove this hack once proper user roles are implemented
if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
// For some strange reasons, HsadminNgApp is created in locally running tests,
// but not on Jenkins, therefore the login user had no rights and many tests
// failed.
SecurityUtils.addUserRole(null, null, Role.HOSTMASTER);
}
}
/**

View File

@ -22,7 +22,7 @@ public class Asset implements Serializable {
private static final long serialVersionUID = 1L;
public static final String ENTITY_NAME = "asset";
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
@ -59,6 +59,11 @@ public class Asset implements Serializable {
return id;
}
public Asset id(Long id) {
this.id = id;
return this;
}
public void setId(Long id) {
this.id = id;
}

View File

@ -1,6 +1,8 @@
package org.hostsharing.hsadminng.security;
import org.hostsharing.hsadminng.service.accessfilter.Role;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
@ -14,6 +16,8 @@ import java.util.Optional;
*/
public final class SecurityUtils {
private static final Logger log = LoggerFactory.getLogger(SecurityUtils.class);
private static List<UserRoleAssignment> userRoleAssignments = new ArrayList<>();
private SecurityUtils() {
@ -86,16 +90,18 @@ public final class SecurityUtils {
? ura.role
: Role.ANYBODY).
reduce(Role.ANYBODY, (r1, r2) -> r1.covers(r2) ? r1 : r2);
log.debug("getLoginUserRoleFor({}, {}) returned {}", onDtoClass, onId, highestRole);
return highestRole;
}
private static boolean matches(Class<?> onDtoClass, Long onId, UserRoleAssignment ura) {
final boolean matches = (ura.onClass == null || onDtoClass == ura.onClass) && (ura.onId == null || ura.onId.equals(onId));
final boolean matches = (ura.onClass == null || onDtoClass == ura.onClass) && (ura.onId == null || ura.onId.equals(onId));
return matches;
}
// TODO: depends on https://plan.hostsharing.net/project/hsadmin/us/67?milestone=34
public static void addUserRole(final Class<?> onClass, final Long onId, final Role role) {
log.info("addUserRole({}, {}, {})", onClass, onId, role);
userRoleAssignments.add(new UserRoleAssignment(onClass, onId, role));
}

View File

@ -4,6 +4,7 @@ import org.hostsharing.hsadminng.domain.Asset;
import org.hostsharing.hsadminng.repository.AssetRepository;
import org.hostsharing.hsadminng.service.dto.AssetDTO;
import org.hostsharing.hsadminng.service.mapper.AssetMapper;
import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
@ -11,6 +12,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import java.util.Optional;
/**
@ -18,16 +20,19 @@ import java.util.Optional;
*/
@Service
@Transactional
public class AssetService {
public class AssetService implements IdToDtoResolver<AssetDTO> {
private final Logger log = LoggerFactory.getLogger(AssetService.class);
private final EntityManager em;
private final AssetRepository assetRepository;
private final AssetMapper assetMapper;
private final AssetValidator assetValidator;
public AssetService(AssetRepository assetRepository, AssetMapper assetMapper, AssetValidator assetValidator ) {
public AssetService(final EntityManager em, final AssetRepository assetRepository, final AssetMapper assetMapper, final AssetValidator assetValidator) {
this.em = em;
this.assetRepository = assetRepository;
this.assetMapper = assetMapper;
this.assetValidator = assetValidator;
@ -44,6 +49,8 @@ public class AssetService {
assetValidator.validate(assetDTO);
Asset asset = assetMapper.toEntity(assetDTO);
asset = assetRepository.save(asset);
em.flush();
em.refresh(asset);
return assetMapper.toDto(asset);
}
@ -81,6 +88,7 @@ public class AssetService {
*/
public void delete(Long id) {
log.debug("Request to delete Asset : {}", id);
assetRepository.deleteById(id);
throw new BadRequestAlertException("Asset transactions are immutable", Asset.ENTITY_NAME, "assetTransactionImmutable");
}
}

View File

@ -12,6 +12,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import java.util.Optional;
/**
@ -23,15 +24,19 @@ public class MembershipService implements IdToDtoResolver<MembershipDTO> {
private final Logger log = LoggerFactory.getLogger(MembershipService.class);
private final EntityManager em;
private final MembershipValidator membershipValidator;
private final MembershipRepository membershipRepository;
private final MembershipMapper membershipMapper;
public MembershipService(final MembershipValidator membershipValidator,
public MembershipService(final EntityManager em,
final MembershipValidator membershipValidator,
final MembershipRepository membershipRepository,
final MembershipMapper membershipMapper) {
this.em = em;
this.membershipValidator = membershipValidator;
this.membershipRepository = membershipRepository;
this.membershipMapper = membershipMapper;
@ -50,6 +55,8 @@ public class MembershipService implements IdToDtoResolver<MembershipDTO> {
Membership membership = membershipMapper.toEntity(membershipDTO);
membership = membershipRepository.save(membership);
em.flush();
em.refresh(membership);
return membershipMapper.toDto(membership);
}

View File

@ -12,6 +12,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import java.util.Optional;
/**
@ -23,13 +24,16 @@ public class ShareService implements IdToDtoResolver<ShareDTO> {
private final Logger log = LoggerFactory.getLogger(ShareService.class);
private final EntityManager em;
private final ShareRepository shareRepository;
private final ShareMapper shareMapper;
private final ShareValidator shareValidator;
public ShareService(ShareRepository shareRepository, ShareMapper shareMapper, ShareValidator shareValidator) {
public ShareService(final EntityManager em, final ShareRepository shareRepository, final ShareMapper shareMapper, final ShareValidator shareValidator) {
this.em = em;
this.shareRepository = shareRepository;
this.shareMapper = shareMapper;
this.shareValidator = shareValidator;
@ -48,6 +52,8 @@ public class ShareService implements IdToDtoResolver<ShareDTO> {
Share share = shareMapper.toEntity(shareDTO);
share = shareRepository.save(share);
em.flush();
em.refresh(share);
return shareMapper.toDto(share);
}

View File

@ -1,6 +1,11 @@
package org.hostsharing.hsadminng.service.dto;
import org.hostsharing.hsadminng.domain.enumeration.AssetAction;
import org.hostsharing.hsadminng.service.AssetService;
import org.hostsharing.hsadminng.service.MembershipService;
import org.hostsharing.hsadminng.service.accessfilter.*;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.context.ApplicationContext;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@ -12,29 +17,40 @@ import java.util.Objects;
/**
* A DTO for the Asset entity.
*/
public class AssetDTO implements Serializable {
public class AssetDTO implements Serializable, AccessMappings {
@SelfId(resolver = AssetService.class)
@AccessFor(read = Role.ANY_CUSTOMER_USER)
private Long id;
@NotNull
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private LocalDate documentDate;
@NotNull
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private LocalDate valueDate;
@NotNull
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private AssetAction action;
@NotNull
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private BigDecimal amount;
@Size(max = 160)
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = Role.SUPPORTER)
private String remark;
@ParentId(resolver = MembershipService.class)
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private Long membershipId;
private String membershipDisplayReference;
// TODO: these init/update rights actually mean "ignore", we might want to express this in a better way
// background: there is no converter for any display label in DTOs to entity field values anyway
@AccessFor(init=Role.ANYBODY, update = Role.ANYBODY, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private String membershipDisplayLabel;
public Long getId() {
return id;
@ -92,12 +108,12 @@ public class AssetDTO implements Serializable {
this.membershipId = membershipId;
}
public String getMembershipDisplayReference() {
return membershipDisplayReference;
public String getMembershipDisplayLabel() {
return membershipDisplayLabel;
}
public void setMembershipDisplayReference(String membershipDisplayReference) {
this.membershipDisplayReference = membershipDisplayReference;
public void setMembershipDisplayLabel(String membershipDisplayLabel) {
this.membershipDisplayLabel = membershipDisplayLabel;
}
@Override
@ -131,7 +147,23 @@ public class AssetDTO implements Serializable {
", amount=" + getAmount() +
", remark='" + getRemark() + "'" +
", membership=" + getMembershipId() +
", membership='" + getMembershipDisplayReference() + "'" +
", membership='" + getMembershipDisplayLabel() + "'" +
"}";
}
@JsonComponent
public static class AssetJsonSerializer extends JsonSerializerWithAccessFilter<AssetDTO> {
public AssetJsonSerializer(final ApplicationContext ctx) {
super(ctx);
}
}
@JsonComponent
public static class AssetJsonDeserializer extends JsonDeserializerWithAccessFilter<AssetDTO> {
public AssetJsonDeserializer(final ApplicationContext ctx) {
super(ctx);
}
}
}

View File

@ -85,6 +85,9 @@ public class CustomerDTO extends FluentBuilder<CustomerDTO> implements AccessMap
@AccessFor(init = Role.ADMIN, update = Role.SUPPORTER, read = Role.SUPPORTER)
private String remark;
@AccessFor(init=Role.ANYBODY, update=Role.ANYBODY, read = Role.ANY_CUSTOMER_USER)
private String displayLabel;
public Long getId() {
return id;
}
@ -213,6 +216,14 @@ public class CustomerDTO extends FluentBuilder<CustomerDTO> implements AccessMap
this.remark = remark;
}
public String getDisplayLabel() {
return displayLabel;
}
public void setDisplayLabel(final String displayLabel) {
this.displayLabel = displayLabel;
}
@Override
public boolean equals(Object o) {
if (this == o) {

View File

@ -2,10 +2,9 @@ package org.hostsharing.hsadminng.service.dto;
import org.hostsharing.hsadminng.service.CustomerService;
import org.hostsharing.hsadminng.service.MembershipService;
import org.hostsharing.hsadminng.service.accessfilter.AccessFor;
import org.hostsharing.hsadminng.service.accessfilter.ParentId;
import org.hostsharing.hsadminng.service.accessfilter.Role;
import org.hostsharing.hsadminng.service.accessfilter.SelfId;
import org.hostsharing.hsadminng.service.accessfilter.*;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.context.ApplicationContext;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@ -16,7 +15,7 @@ import java.util.Objects;
/**
* A DTO for the Membership entity.
*/
public class MembershipDTO extends FluentBuilder<MembershipDTO> implements Serializable {
public class MembershipDTO extends FluentBuilder<MembershipDTO> implements Serializable, AccessMappings {
@SelfId(resolver = MembershipService.class)
@AccessFor(read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
@ -26,18 +25,18 @@ public class MembershipDTO extends FluentBuilder<MembershipDTO> implements Seria
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private LocalDate admissionDocumentDate;
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private LocalDate cancellationDocumentDate;
@NotNull
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private LocalDate memberFromDate;
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private LocalDate memberUntilDate;
@Size(max = 160)
@AccessFor(init = Role.ADMIN, read = Role.SUPPORTER)
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = Role.SUPPORTER)
private String remark;
@ParentId(resolver = CustomerService.class)
@ -47,6 +46,12 @@ public class MembershipDTO extends FluentBuilder<MembershipDTO> implements Seria
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private String customerPrefix;
@AccessFor(init = Role.ANYBODY, update = Role.ANYBODY, read = Role.FINANCIAL_CONTACT)
private String displayLabel;
@AccessFor(init = Role.ANYBODY, update = Role.ANYBODY, read = Role.FINANCIAL_CONTACT)
private String customerDisplayLabel;
public Long getId() {
return id;
}
@ -111,6 +116,22 @@ public class MembershipDTO extends FluentBuilder<MembershipDTO> implements Seria
this.customerPrefix = customerPrefix;
}
public String getDisplayLabel() {
return displayLabel;
}
public void setDisplayLabel(final String displayLabel) {
this.displayLabel = displayLabel;
}
public String getCustomerDisplayLabel() {
return customerDisplayLabel;
}
public void setCustomerDisplayLabel(final String customerDisplayLabel) {
this.customerDisplayLabel = customerDisplayLabel;
}
@Override
public boolean equals(Object o) {
if (this == o) {
@ -145,4 +166,20 @@ public class MembershipDTO extends FluentBuilder<MembershipDTO> implements Seria
", customer='" + getCustomerPrefix() + "'" +
"}";
}
@JsonComponent
public static class MembershipJsonSerializer extends JsonSerializerWithAccessFilter<MembershipDTO> {
public MembershipJsonSerializer(final ApplicationContext ctx) {
super(ctx);
}
}
@JsonComponent
public static class MembershipJsonDeserializer extends JsonDeserializerWithAccessFilter<MembershipDTO> {
public MembershipJsonDeserializer(final ApplicationContext ctx) {
super(ctx);
}
}
}

View File

@ -48,7 +48,7 @@ public class ShareDTO implements Serializable {
private Long membershipId;
@AccessFor(read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private String membershipDisplayReference;
private String membershipDisplayLabel;
public Long getId() {
return id;
@ -106,12 +106,12 @@ public class ShareDTO implements Serializable {
this.membershipId = membershipId;
}
public String getMembershipDisplayReference() {
return membershipDisplayReference;
public String getMembershipDisplayLabel() {
return membershipDisplayLabel;
}
public void setMembershipDisplayReference(String membershipDisplayReference) {
this.membershipDisplayReference = membershipDisplayReference;
public void setMembershipDisplayLabel(String membershipDisplayLabel) {
this.membershipDisplayLabel = membershipDisplayLabel;
}
@Override
@ -145,7 +145,7 @@ public class ShareDTO implements Serializable {
", quantity=" + getQuantity() +
", remark='" + getRemark() + "'" +
", membership=" + getMembershipId() +
", membership='" + getMembershipDisplayReference() + "'" +
", membership='" + getMembershipDisplayLabel() + "'" +
"}";
}
}

View File

@ -2,8 +2,10 @@ package org.hostsharing.hsadminng.service.mapper;
import org.hostsharing.hsadminng.domain.Asset;
import org.hostsharing.hsadminng.service.dto.AssetDTO;
import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
/**
* Mapper for the entity Asset and its DTO AssetDTO.
@ -12,9 +14,14 @@ import org.mapstruct.Mapping;
public interface AssetMapper extends EntityMapper<AssetDTO, Asset> {
@Mapping(source = "membership.id", target = "membershipId")
@Mapping(source = "membership.admissionDocumentDate", target = "membershipDisplayReference")
@Mapping(target = "membershipDisplayLabel", ignore = true)
AssetDTO toDto(Asset asset);
@AfterMapping
default void setMembershipDisplayLabel(final @MappingTarget AssetDTO dto, final Asset entity) {
dto.setMembershipDisplayLabel(MembershipMapper.displayLabel(entity.getMembership()));
}
@Mapping(source = "membershipId", target = "membership")
Asset toEntity(AssetDTO assetDTO);

View File

@ -1,9 +1,11 @@
package org.hostsharing.hsadminng.service.mapper;
import org.hostsharing.hsadminng.domain.*;
import org.hostsharing.hsadminng.domain.Customer;
import org.hostsharing.hsadminng.service.dto.CustomerDTO;
import org.mapstruct.*;
import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
/**
* Mapper for the entity Customer and its DTO CustomerDTO.
@ -11,6 +13,18 @@ import org.mapstruct.*;
@Mapper(componentModel = "spring", uses = {})
public interface CustomerMapper extends EntityMapper<CustomerDTO, Customer> {
static String displayLabel(Customer customer) {
return customer.getName()
+ " [" + customer.getReference() + ":" + customer.getPrefix() +"]";
}
@Mapping(target = "displayLabel", ignore = true)
CustomerDTO toDto(Customer customer);
@AfterMapping
default void setDisplayLabel(final @MappingTarget CustomerDTO dto, final Customer entity) {
dto.setDisplayLabel(displayLabel(entity));
}
@Mapping(target = "memberships", ignore = true)
@Mapping(target = "sepamandates", ignore = true)

View File

@ -1,9 +1,14 @@
package org.hostsharing.hsadminng.service.mapper;
import org.hostsharing.hsadminng.domain.*;
import org.hostsharing.hsadminng.domain.Customer;
import org.hostsharing.hsadminng.domain.Membership;
import org.hostsharing.hsadminng.service.dto.MembershipDTO;
import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.*;
import java.util.Objects;
/**
* Mapper for the entity Membership and its DTO MembershipDTO.
@ -11,10 +16,27 @@ import org.mapstruct.*;
@Mapper(componentModel = "spring", uses = {CustomerMapper.class})
public interface MembershipMapper extends EntityMapper<MembershipDTO, Membership> {
static String displayLabel(final Membership entity) {
final Customer customer = entity.getCustomer();
return CustomerMapper.displayLabel(customer) + " "
+ Objects.toString(entity.getMemberFromDate(), "") + " - "
+ Objects.toString(entity.getMemberUntilDate(), "...");
}
@Mapping(source = "customer.id", target = "customerId")
@Mapping(source = "customer.prefix", target = "customerPrefix")
@Mapping(target = "displayLabel", ignore = true)
@Mapping(target = "customerDisplayLabel", ignore = true)
MembershipDTO toDto(Membership membership);
// TODO BLOG HOWTO: multi-field display reference for selection lists
// also change the filed in the option list in *-update.html
@AfterMapping
default void setMembershipDisplayLabel(final @MappingTarget MembershipDTO dto, final Membership entity) {
dto.setDisplayLabel(displayLabel(entity));
dto.setCustomerDisplayLabel(CustomerMapper.displayLabel(entity.getCustomer()));
}
@Mapping(target = "shares", ignore = true)
@Mapping(target = "assets", ignore = true)
@Mapping(source = "customerId", target = "customer")

View File

@ -2,8 +2,10 @@ package org.hostsharing.hsadminng.service.mapper;
import org.hostsharing.hsadminng.domain.Share;
import org.hostsharing.hsadminng.service.dto.ShareDTO;
import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
/**
* Mapper for the entity Share and its DTO ShareDTO.
@ -12,9 +14,14 @@ import org.mapstruct.Mapping;
public interface ShareMapper extends EntityMapper<ShareDTO, Share> {
@Mapping(source = "membership.id", target = "membershipId")
@Mapping(source = "membership.admissionDocumentDate", target = "membershipDisplayReference")
@Mapping(target = "membershipDisplayLabel", ignore = true)
ShareDTO toDto(Share share);
@AfterMapping
default void setMembershipDisplayLabel(final @MappingTarget ShareDTO dto, final Share entity) {
dto.setMembershipDisplayLabel(MembershipMapper.displayLabel(entity.getMembership()));
}
@Mapping(source = "membershipId", target = "membership")
Share toEntity(ShareDTO shareDTO);

View File

@ -131,7 +131,7 @@ public class CustomerResource {
@DeleteMapping("/customers/{id}")
public ResponseEntity<Void> deleteCustomer(@PathVariable Long id) {
log.debug("REST request to delete Customer : {}", id);
customerService.delete(id);
return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert(ENTITY_NAME, id.toString())).build();
// TODO mhoennig: Rather completely remove the endpoint?
throw new BadRequestAlertException("Customres can't be deleted", ENTITY_NAME, "customerNotDeletable");
}
}

View File

@ -1,25 +1,24 @@
package org.hostsharing.hsadminng.web.rest;
import io.github.jhipster.web.util.ResponseUtil;
import org.hostsharing.hsadminng.service.MembershipQueryService;
import org.hostsharing.hsadminng.service.MembershipService;
import org.hostsharing.hsadminng.service.dto.MembershipCriteria;
import org.hostsharing.hsadminng.service.dto.MembershipDTO;
import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException;
import org.hostsharing.hsadminng.web.rest.util.HeaderUtil;
import org.hostsharing.hsadminng.web.rest.util.PaginationUtil;
import org.hostsharing.hsadminng.service.dto.MembershipDTO;
import org.hostsharing.hsadminng.service.dto.MembershipCriteria;
import org.hostsharing.hsadminng.service.MembershipQueryService;
import io.github.jhipster.web.util.ResponseUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Optional;
@ -132,7 +131,7 @@ public class MembershipResource {
@DeleteMapping("/memberships/{id}")
public ResponseEntity<Void> deleteMembership(@PathVariable Long id) {
log.debug("REST request to delete Membership : {}", id);
membershipService.delete(id);
return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert(ENTITY_NAME, id.toString())).build();
// TODO mhoennig: Rather completely remove the endpoint?
throw new BadRequestAlertException("Memberships can't be deleted", ENTITY_NAME, "membershipNotDeletable");
}
}

View File

@ -37,7 +37,10 @@ spring:
indent-output: true
datasource:
type: com.zaxxer.hikari.HikariDataSource
# H2 in memory:
url: jdbc:h2:mem:hsadminng;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
# H2 in file:
# url: jdbc:h2:~/.hsadminng.h2db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
username: hsadminNg
password:
hikari:

View File

@ -26,6 +26,7 @@
<appender-ref ref="ASYNC"/>
</root>
-->
<logger name="org.hostsharing.hsadminng" level="INFO"/>
<logger name="javax.activation" level="WARN"/>
<logger name="javax.mail" level="WARN"/>

View File

@ -1,7 +1,7 @@
<div class="row justify-content-center">
<div class="col-8">
<div *ngIf="asset">
<h2><span jhiTranslate="hsadminNgApp.asset.detail.title">Asset</span> {{asset.id}}</h2>
<h2><span jhiTranslate="hsadminNgApp.asset.detail.title">Asset</span>: #{{asset.id}} - {{asset.membershipDisplayLabel}}</h2>
<hr>
<jhi-alert-error></jhi-alert-error>
<dl class="row-md jh-entity-details">
@ -28,7 +28,7 @@
<dt><span jhiTranslate="hsadminNgApp.asset.membership">Membership</span></dt>
<dd>
<div *ngIf="asset.membershipId">
<a [routerLink]="['/membership', asset.membershipId, 'view']">{{asset.membershipDisplayReference}}</a>
<a [routerLink]="['/membership', asset.membershipId, 'view']">{{asset.membershipDisplayLabel}}</a>
</div>
</dd>
</dl>

View File

@ -89,7 +89,7 @@
<label class="form-control-label" jhiTranslate="hsadminNgApp.asset.membership" for="field_membership">Membership</label>
<select class="form-control" id="field_membership" name="membership" [(ngModel)]="asset.membershipId" required>
<option *ngIf="!editForm.value.membership" [ngValue]="null" selected></option>
<option [ngValue]="membershipOption.id" *ngFor="let membershipOption of memberships; trackBy: trackMembershipById">{{membershipOption.admissionDocumentDate}}</option>
<option [ngValue]="membershipOption.id" *ngFor="let membershipOption of memberships; trackBy: trackMembershipById">{{membershipOption.displayLabel}}</option>
</select>
</div>
<div [hidden]="!(editForm.controls.membership?.dirty && editForm.controls.membership?.invalid)">

View File

@ -19,8 +19,7 @@
<th jhiSortBy="valueDate"><span jhiTranslate="hsadminNgApp.asset.valueDate">Value Date</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="action"><span jhiTranslate="hsadminNgApp.asset.action">Action</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="amount"><span jhiTranslate="hsadminNgApp.asset.amount">Amount</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="remark"><span jhiTranslate="hsadminNgApp.asset.remark">Remark</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="membershipDisplayReference"><span jhiTranslate="hsadminNgApp.asset.membership">Membership</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="membershipDisplayLabel"><span jhiTranslate="hsadminNgApp.asset.membership">Membership</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th></th>
</tr>
</thead>
@ -31,10 +30,9 @@
<td>{{asset.valueDate | date:'mediumDate'}}</td>
<td jhiTranslate="{{'hsadminNgApp.AssetAction.' + asset.action}}">{{asset.action}}</td>
<td>{{asset.amount}}</td>
<td>{{asset.remark}}</td>
<td>
<div *ngIf="asset.membershipId">
<a [routerLink]="['../membership', asset.membershipId , 'view' ]" >{{asset.membershipDisplayReference}}</a>
<a [routerLink]="['../membership', asset.membershipId , 'view' ]" >{{asset.membershipDisplayLabel}}</a>
</div>
</td>
<td class="text-right">

View File

@ -1,7 +1,7 @@
<div class="row justify-content-center">
<div class="col-8">
<div *ngIf="customer">
<h2><span jhiTranslate="hsadminNgApp.customer.detail.title">Customer</span> {{customer.id}}</h2>
<h2><span jhiTranslate="hsadminNgApp.customer.detail.title">Customer</span>: {{customer.displayLabel}}</h2>
<hr>
<jhi-alert-error></jhi-alert-error>
<dl class="row-md jh-entity-details">

View File

@ -18,18 +18,7 @@
<th jhiSortBy="reference"><span jhiTranslate="hsadminNgApp.customer.reference">Reference</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="prefix"><span jhiTranslate="hsadminNgApp.customer.prefix">Prefix</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="name"><span jhiTranslate="hsadminNgApp.customer.name">Name</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="kind"><span jhiTranslate="hsadminNgApp.customer.kind">Kind</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="birthDate"><span jhiTranslate="hsadminNgApp.customer.birthDate">Birth Date</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="birthPlace"><span jhiTranslate="hsadminNgApp.customer.birthPlace">Birth Place</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="registrationCourt"><span jhiTranslate="hsadminNgApp.customer.registrationCourt">Registration Court</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="registrationNumber"><span jhiTranslate="hsadminNgApp.customer.registrationNumber">Registration Number</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="vatRegion"><span jhiTranslate="hsadminNgApp.customer.vatRegion">Vat Region</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="vatNumber"><span jhiTranslate="hsadminNgApp.customer.vatNumber">Vat Number</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="contractualSalutation"><span jhiTranslate="hsadminNgApp.customer.contractualSalutation">Contractual Salutation</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="contractualAddress"><span jhiTranslate="hsadminNgApp.customer.contractualAddress">Contractual Address</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="billingSalutation"><span jhiTranslate="hsadminNgApp.customer.billingSalutation">Billing Salutation</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="billingAddress"><span jhiTranslate="hsadminNgApp.customer.billingAddress">Billing Address</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="remark"><span jhiTranslate="hsadminNgApp.customer.remark">Remark</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="kind"><span jhiTranslate="hsadminNgApp.customer.kind">Kind</span> <fa-icon [icon]="'sort'"></fa-icon></thn></th>
<th></th>
</tr>
</thead>
@ -40,17 +29,6 @@
<td>{{customer.prefix}}</td>
<td>{{customer.name}}</td>
<td jhiTranslate="{{'hsadminNgApp.CustomerKind.' + customer.kind}}">{{customer.kind}}</td>
<td>{{customer.birthDate | date:'mediumDate'}}</td>
<td>{{customer.birthPlace}}</td>
<td>{{customer.registrationCourt}}</td>
<td>{{customer.registrationNumber}}</td>
<td jhiTranslate="{{'hsadminNgApp.VatRegion.' + customer.vatRegion}}">{{customer.vatRegion}}</td>
<td>{{customer.vatNumber}}</td>
<td>{{customer.contractualSalutation}}</td>
<td>{{customer.contractualAddress}}</td>
<td>{{customer.billingSalutation}}</td>
<td>{{customer.billingAddress}}</td>
<td>{{customer.remark}}</td>
<td class="text-right">
<div class="btn-group flex-btn-group-container">
<button type="submit"

View File

@ -1,7 +1,7 @@
<div class="row justify-content-center">
<div class="col-8">
<div *ngIf="membership">
<h2><span jhiTranslate="hsadminNgApp.membership.detail.title">Membership</span> {{membership.id}}</h2>
<h2><span jhiTranslate="hsadminNgApp.membership.detail.title">Membership</span>: {{membership.displayLabel}}</h2>
<hr>
<jhi-alert-error></jhi-alert-error>
<dl class="row-md jh-entity-details">
@ -28,7 +28,7 @@
<dt><span jhiTranslate="hsadminNgApp.membership.customer">Customer</span></dt>
<dd>
<div *ngIf="membership.customerId">
<a [routerLink]="['/customer', membership.customerId, 'view']">{{membership.customerPrefix}}</a>
<a [routerLink]="['/customer', membership.customerId, 'view']">{{membership.customerDisplayLabel}}</a>
</div>
</dd>
</dl>

View File

@ -77,7 +77,7 @@
<label class="form-control-label" jhiTranslate="hsadminNgApp.membership.customer" for="field_customer">Customer</label>
<select class="form-control" id="field_customer" name="customer" [(ngModel)]="membership.customerId" required>
<option *ngIf="!editForm.value.customer" [ngValue]="null" selected></option>
<option [ngValue]="customerOption.id" *ngFor="let customerOption of customers; trackBy: trackCustomerById">{{customerOption.prefix}}</option>
<option [ngValue]="customerOption.id" *ngFor="let customerOption of customers; trackBy: trackCustomerById">{{customerOption.displayLabel}}</option>
</select>
</div>
<div [hidden]="!(editForm.controls.customer?.dirty && editForm.controls.customer?.invalid)">

View File

@ -19,7 +19,6 @@
<th jhiSortBy="cancellationDocumentDate"><span jhiTranslate="hsadminNgApp.membership.cancellationDocumentDate">Cancellation Document Date</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="memberFromDate"><span jhiTranslate="hsadminNgApp.membership.memberFromDate">Member From Date</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="memberUntilDate"><span jhiTranslate="hsadminNgApp.membership.memberUntilDate">Member Until Date</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="remark"><span jhiTranslate="hsadminNgApp.membership.remark">Remark</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="customerPrefix"><span jhiTranslate="hsadminNgApp.membership.customer">Customer</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th></th>
</tr>
@ -28,13 +27,12 @@
<tr *ngFor="let membership of memberships ;trackBy: trackId">
<td><a [routerLink]="['/membership', membership.id, 'view' ]">{{membership.id}}</a></td>
<td>{{membership.admissionDocumentDate | date:'mediumDate'}}</td>
<td>{{membership.cancellationDocumentDate | date:'mediumDate'}}</td>
<td>{{membership.cancellationDocumentDate | date:'mediumDsate'}}</td>
<td>{{membership.memberFromDate | date:'mediumDate'}}</td>
<td>{{membership.memberUntilDate | date:'mediumDate'}}</td>
<td>{{membership.remark}}</td>
<td>
<div *ngIf="membership.customerId">
<a [routerLink]="['../customer', membership.customerId , 'view' ]" >{{membership.customerPrefix}}</a>
<a [routerLink]="['../customer', membership.customerId , 'view' ]" >{{membership.customerDisplayLabel}}</a>
</div>
</td>
<td class="text-right">

View File

@ -1,7 +1,7 @@
<div class="row justify-content-center">
<div class="col-8">
<div *ngIf="share">
<h2><span jhiTranslate="hsadminNgApp.share.detail.title">Share</span> {{share.id}}</h2>
<h2><span jhiTranslate="hsadminNgApp.share.detail.title">Share</span>: #{{share.id}} - {{share.membershipDisplayLabel}}</h2>
<hr>
<jhi-alert-error></jhi-alert-error>
<dl class="row-md jh-entity-details">
@ -28,7 +28,7 @@
<dt><span jhiTranslate="hsadminNgApp.share.membership">Membership</span></dt>
<dd>
<div *ngIf="share.membershipId">
<a [routerLink]="['/membership', share.membershipId, 'view']">{{share.membershipDisplayReference}}</a>
<a [routerLink]="['/membership', share.membershipId, 'view']">{{share.membershipDisplayLabel}}</a>
</div>
</dd>
</dl>

View File

@ -85,7 +85,7 @@
<label class="form-control-label" jhiTranslate="hsadminNgApp.share.membership" for="field_membership">Membership</label>
<select class="form-control" id="field_membership" name="membership" [(ngModel)]="share.membershipId" required>
<option *ngIf="!editForm.value.membership" [ngValue]="null" selected></option>
<option [ngValue]="membershipOption.id" *ngFor="let membershipOption of memberships; trackBy: trackMembershipById">{{membershipOption.admissionDocumentDate}}</option>
<option [ngValue]="membershipOption.id" *ngFor="let membershipOption of memberships; trackBy: trackMembershipById">{{membershipOption.displayLabel}}</option>
</select>
</div>
<div [hidden]="!(editForm.controls.membership?.dirty && editForm.controls.membership?.invalid)">

View File

@ -19,8 +19,7 @@
<th jhiSortBy="valueDate"><span jhiTranslate="hsadminNgApp.share.valueDate">Value Date</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="action"><span jhiTranslate="hsadminNgApp.share.action">Action</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="quantity"><span jhiTranslate="hsadminNgApp.share.quantity">Quantity</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="remark"><span jhiTranslate="hsadminNgApp.share.remark">Remark</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="membershipDisplayReference"><span jhiTranslate="hsadminNgApp.share.membership">Membership</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="membershipDisplayLabel"><span jhiTranslate="hsadminNgApp.share.membership">Membership</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th></th>
</tr>
</thead>
@ -31,10 +30,9 @@
<td>{{share.valueDate | date:'mediumDate'}}</td>
<td jhiTranslate="{{'hsadminNgApp.ShareAction.' + share.action}}">{{share.action}}</td>
<td>{{share.quantity}}</td>
<td>{{share.remark}}</td>
<td>
<div *ngIf="share.membershipId">
<a [routerLink]="['../membership', share.membershipId , 'view' ]" >{{share.membershipDisplayReference}}</a>
<a [routerLink]="['../membership', share.membershipId , 'view' ]" >{{share.membershipDisplayLabel}}</a>
</div>
</td>
<td class="text-right">

View File

@ -16,8 +16,8 @@ export interface IAsset {
action?: AssetAction;
amount?: number;
remark?: string;
membershipDisplayReference?: string;
membershipId?: number;
membershipDisplayLabel?: string;
}
export class Asset implements IAsset {
@ -28,7 +28,7 @@ export class Asset implements IAsset {
public action?: AssetAction,
public amount?: number,
public remark?: string,
public membershipDisplayReference?: string,
public membershipId?: number
public membershipId?: number,
public membershipDisplayLabel?: string
) {}
}

View File

@ -32,6 +32,7 @@ export interface ICustomer {
remark?: string;
memberships?: IMembership[];
sepamandates?: ISepaMandate[];
displayLabel?: string;
}
export class Customer implements ICustomer {
@ -53,6 +54,7 @@ export class Customer implements ICustomer {
public billingAddress?: string,
public remark?: string,
public memberships?: IMembership[],
public sepamandates?: ISepaMandate[]
public sepamandates?: ISepaMandate[],
public displayLabel?: string
) {}
}

View File

@ -13,6 +13,8 @@ export interface IMembership {
assets?: IAsset[];
customerPrefix?: string;
customerId?: number;
customerDisplayLabel?: string;
displayLabel?: string;
}
export class Membership implements IMembership {
@ -26,6 +28,8 @@ export class Membership implements IMembership {
public shares?: IShare[],
public assets?: IAsset[],
public customerPrefix?: string,
public customerId?: number
public customerId?: number,
public customerDisplayLabel?: string,
public displayLabel?: string
) {}
}

View File

@ -12,7 +12,7 @@ export interface IShare {
action?: ShareAction;
quantity?: number;
remark?: string;
membershipDisplayReference?: string;
membershipDisplayLabel?: string;
membershipId?: number;
}
@ -24,7 +24,7 @@ export class Share implements IShare {
public action?: ShareAction,
public quantity?: number,
public remark?: string,
public membershipDisplayReference?: string,
public membershipDisplayLabel?: string,
public membershipId?: number
) {}
}

View File

@ -5,6 +5,7 @@
"shareCancellationNegativeQuantity": "Kündigungen von Geschäftsanteilen erfordern eine negative Stückzahl",
"shareTransactionImmutable": "Transaktionen mit Geschäftsanteilen sind unveränderlich",
"membershipNotDeletable": "Mitgliedschaft kann nicht gelöscht werden, setze stattdessen das 'untilDate'",
"customerNotDeletable": "Kunden können nicht explizit gelöscht werden'",
"untilDateMustBeAfterSinceDate": "Mitgliedshafts-Austrittsdatum muss nach dem Beitrittsdatum liegen",
"anotherUncancelledMembershipExists": "Nur eine einzige ungekündigte Mitgliedschaft pro Kunde ist zulässig",
"initializationProhibited": "Initialisierung des Feldes unzulässig",

View File

@ -5,6 +5,7 @@
"shareCancellationNegativeQuantity": "Share cancellations require a negative quantity",
"shareTransactionImmutable": "Share transactions are immutable",
"membershipNotDeletable": "Membership cannot be deleted, instead set 'untilDate'",
"customerNotDeletable": "Customer cannot be deleted explicitly'",
"untilDateMustBeAfterSinceDate": "Membership until date must be after since date",
"anotherUncancelledMembershipExists": "Only a single uncancelled membership allowed per customer",
"initializationProhibited": "Initialization of the field prohibited",

View File

@ -0,0 +1,167 @@
package org.hostsharing.hsadminng.service;
import org.apache.commons.lang3.RandomUtils;
import org.hostsharing.hsadminng.domain.Asset;
import org.hostsharing.hsadminng.domain.enumeration.AssetAction;
import org.hostsharing.hsadminng.repository.AssetRepository;
import org.hostsharing.hsadminng.service.dto.AssetDTO;
import org.hostsharing.hsadminng.service.mapper.AssetMapper;
import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import javax.persistence.EntityManager;
import java.math.BigDecimal;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowableOfType;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.*;
// HINT: In IntelliJ IDEA such unit test classes can be created with Shift-Ctrl-T.
// Do not forget to amend the class name (.e.g. ...UnitTest / ...IntTest)!
public class AssetServiceUnitTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock
private EntityManager em;
@Mock
private AssetRepository assetRepository;
@Mock
private AssetValidator assetValidator; // needed for @InjectMocks assetService
@Mock
private AssetMapper assetMapper;
@InjectMocks
private AssetService assetService;
// HINT: Click outside of any test method (e.g. here) and use Ctrl-Shift-F10
// to run all tests from this test class. Use Ctrl-F5 to run the last execution again;
// 'execution' here can also apply to running the application, whatever ran last.
// HINT: In IntelliJ IDEA such test methods can be created with Alt-Insert.
@Test
public void deleteIsRejectedForAssetTransactions() {
// when
final Throwable throwException = catchThrowableOfType(() -> assetService.delete(RandomUtils.nextLong()), BadRequestAlertException.class);
// then
// HINT: When using auto-import for assertions (e.g. via Alt-Enter in IntelliJ IDEA),
// beware to use the correct candidate from org.assertj.core.api.Assertions.
assertThat(throwException).isEqualToComparingFieldByField(
new BadRequestAlertException("Asset transactions are immutable", "asset", "assetTransactionImmutable"));
}
@Test
public void saveShouldPersistValidTransactions() {
// given
final AssetDTO givenAssetDTO = givenAssetDTO(null, AssetAction.PAYMENT, anyPositiveAmout());
// HINT: given(...)...will...() can't be used for void methods, in that case use Mockito's do...() methods
doNothing().when(assetValidator).validate(givenAssetDTO);
// when
final AssetDTO returnedAssetDto = assetService.save(givenAssetDTO);
// then
verify(em).flush();
verify(em).refresh(any(Asset.class));
assertThat(returnedAssetDto).isEqualToIgnoringGivenFields(givenAssetDTO, "id");
}
@Test
public void saveShouldNotPersistInvalidTransactions() {
// given
final AssetDTO givenAssetDTO = givenAssetDTO(null, AssetAction.PAYMENT, anyNegativeAmount());
doThrow(new BadRequestAlertException("Some Dummy Test Violation", "asset", "assetInvalidTestDummy")).when(assetValidator).validate(givenAssetDTO);
// when
final Throwable throwException = catchThrowableOfType(() -> assetService.save(givenAssetDTO), BadRequestAlertException.class);
// then
assertThat(throwException).isEqualToComparingFieldByField(
new BadRequestAlertException("Some Dummy Test Violation", "asset", "assetInvalidTestDummy"));
}
@Test
public void saveShouldUpdateValidTransactions() {
// given
final AssetDTO givenAssetDTO = givenAssetDTO(anyNonNullId(), AssetAction.PAYMENT, anyPositiveAmout());
doNothing().when(assetValidator).validate(givenAssetDTO);
// when
final AssetDTO returnedAssetDto = assetService.save(givenAssetDTO);
// then
verify(em).flush();
verify(em).refresh(any(Asset.class));
assertThat(returnedAssetDto).isEqualToIgnoringGivenFields(givenAssetDTO, "id");
}
@Test
public void saveShouldNotUpdateInvalidTransactions() {
// given
final AssetDTO givenAssetDTO = givenAssetDTO(anyNonNullId(), AssetAction.PAYMENT, anyNegativeAmount());
// HINT: given(...) can't be used for void methods, in that case use Mockito's do...() methods
doThrow(new BadRequestAlertException("Some Dummy Test Violation", "asset", "assetInvalidTestDummy")).when(assetValidator).validate(givenAssetDTO);
// when
final Throwable throwException = catchThrowableOfType(() -> assetService.save(givenAssetDTO), BadRequestAlertException.class);
// then
assertThat(throwException).isEqualToComparingFieldByField(
new BadRequestAlertException("Some Dummy Test Violation", "asset", "assetInvalidTestDummy"));
}
// --- only test fixture code below ---
private long anyNonNullId() {
return RandomUtils.nextInt();
}
// HINT: This rather complicated setup indicates that the method AssetService::save breaks the single responsibility principle.
private AssetDTO givenAssetDTO(final Long id, final AssetAction givenAction, final BigDecimal givenQuantity) {
final AssetDTO givenAssetDTO = createAssetDTO(id, givenAction, givenQuantity);
// dto -> entity
final Asset givenAssetEntity = Mockito.mock(Asset.class);
given(assetMapper.toEntity(same(givenAssetDTO))).willReturn(givenAssetEntity);
// assetRepository.save(entity);
final Asset persistedAssetEntity = Mockito.mock(Asset.class);
given(assetRepository.save(same(givenAssetEntity))).willReturn(persistedAssetEntity);
// entity -> dto
AssetDTO persistedAssetDTO = createAssetDTO(id == null ? RandomUtils.nextLong() : id, givenAction, givenQuantity);
given(assetMapper.toDto(same(persistedAssetEntity))).willReturn(persistedAssetDTO);
return givenAssetDTO;
}
private AssetDTO createAssetDTO(Long id, AssetAction givenAction, BigDecimal givenAmount) {
final AssetDTO givenAssetDTO = new AssetDTO();
givenAssetDTO.setId(id);
givenAssetDTO.setAction(givenAction);
givenAssetDTO.setAmount(givenAmount);
return givenAssetDTO;
}
private BigDecimal anyPositiveAmout() {
return BigDecimal.valueOf(RandomUtils.nextInt()).add(new BigDecimal("0.1"));
}
private BigDecimal anyNegativeAmount() {
return anyPositiveAmout().negate();
}
}

View File

@ -15,12 +15,13 @@ import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import javax.persistence.EntityManager;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowableOfType;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.*;
// HINT: In IntelliJ IDEA such unit test classes can be created with Shift-Ctrl-T.
@ -30,6 +31,9 @@ public class ShareServiceUnitTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock
private EntityManager em;
@Mock
private ShareRepository shareRepository;
@ -70,6 +74,8 @@ public class ShareServiceUnitTest {
final ShareDTO returnedShareDto = shareService.save(givenShareDTO);
// then
verify(em).flush();
verify(em).refresh(any(Share.class));
assertThat(returnedShareDto).isEqualToIgnoringGivenFields(givenShareDTO, "id");
}
@ -97,6 +103,8 @@ public class ShareServiceUnitTest {
final ShareDTO returnedShareDto = shareService.save(givenShareDTO);
// then
verify(em).flush();
verify(em).refresh(any(Share.class));
assertThat(returnedShareDto).isEqualToIgnoringGivenFields(givenShareDTO, "id");
}

View File

@ -1,11 +1,14 @@
package org.hostsharing.hsadminng.service.accessfilter;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import java.util.List;
public class JSonBuilder {
private StringBuilder json = new StringBuilder();
@SafeVarargs
public static String asJSon(final ImmutablePair<String, Object>... properties) {
final StringBuilder json = new StringBuilder();
@ -14,15 +17,8 @@ public class JSonBuilder {
json.append(": ");
if (prop.right instanceof Number) {
json.append(prop.right);
} else if (prop.right instanceof List) {
json.append("[");
for ( int n = 0; n < ((List<Integer>)prop.right).size(); ++n ) {
if ( n > 0 ) {
json.append(",");
}
json.append(((List<Integer>)prop.right).get(n));
}
json.append("]");
} else if (prop.right instanceof List) {
json.append(toJSonArray(prop.right));
} else {
json.append(inQuotes(prop.right));
}
@ -31,6 +27,50 @@ public class JSonBuilder {
return "{\n" + json.substring(0, json.length() - 2) + "\n}";
}
public JSonBuilder withFieldValue(String name, String value) {
json.append(inQuotes(name) + ":" + (value != null ? inQuotes(value) : "null") + ",");
return this;
}
public JSonBuilder withFieldValue(String name, Number value) {
json.append(inQuotes(name) + ":" + (value != null ? value : "null") + ",");
return this;
}
public JSonBuilder toJSonNullFieldDefinition(String name) {
json.append(inQuotes(name) + ":null,");
return this;
}
public JSonBuilder withFieldValueIfPresent(String name, String value) {
json.append(value != null ? inQuotes(name) + ":" + inQuotes(value) + "," : "");
return this;
}
public JSonBuilder withFieldValueIfPresent(String name, Number value) {
json.append(value != null ? inQuotes(name) + ":" + value + "," : "");
return this;
}
@Override
public String toString() {
return "{" + StringUtils.removeEnd(json.toString(), ",") + "}";
}
@SuppressWarnings("unchecked")
// currently just for the case of date values represented as arrays of integer
private static String toJSonArray(final Object value) {
final StringBuilder jsonArray = new StringBuilder("[");
for (int n = 0; n < ((List<Integer>) value).size(); ++n) {
if (n > 0) {
jsonArray.append(",");
}
jsonArray.append(((List<Integer>) value).get(n));
}
return jsonArray.toString() + "]";
}
private static String inQuotes(Object value) {
return value != null ? "\"" + value.toString() + "\"" : "null";
}

View File

@ -20,7 +20,7 @@ public class MockSecurityContext {
public static void givenUserHavingRole(final Class<?> onClass, final Long onId, final Role role) {
if ((onClass == null || onId == null) && !role.isIndependent()) {
throw new IllegalArgumentException("dependent roles like " + role + " missing DtoClass and ID");
throw new IllegalArgumentException("dependent role " + role + " needs DtoClass and ID");
}
SecurityUtils.addUserRole(onClass, onId, role);
}

View File

@ -0,0 +1,214 @@
package org.hostsharing.hsadminng.service.dto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.RandomUtils;
import org.hostsharing.hsadminng.domain.Asset;
import org.hostsharing.hsadminng.domain.Customer;
import org.hostsharing.hsadminng.domain.Membership;
import org.hostsharing.hsadminng.domain.enumeration.AssetAction;
import org.hostsharing.hsadminng.repository.AssetRepository;
import org.hostsharing.hsadminng.repository.CustomerRepository;
import org.hostsharing.hsadminng.repository.MembershipRepository;
import org.hostsharing.hsadminng.service.AssetService;
import org.hostsharing.hsadminng.service.AssetValidator;
import org.hostsharing.hsadminng.service.MembershipValidator;
import org.hostsharing.hsadminng.service.accessfilter.JSonBuilder;
import org.hostsharing.hsadminng.service.accessfilter.Role;
import org.hostsharing.hsadminng.service.mapper.AssetMapper;
import org.hostsharing.hsadminng.service.mapper.AssetMapperImpl;
import org.hostsharing.hsadminng.service.mapper.CustomerMapperImpl;
import org.hostsharing.hsadminng.service.mapper.MembershipMapperImpl;
import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.json.JsonTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import javax.persistence.EntityManager;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenAuthenticatedUser;
import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenUserHavingRole;
import static org.junit.Assert.assertEquals;
import static org.mockito.BDDMockito.given;
@JsonTest
@SpringBootTest(classes = {
AssetMapperImpl.class,
AssetDTO.AssetJsonSerializer.class,
AssetDTO.AssetJsonDeserializer.class,
MembershipMapperImpl.class,
CustomerMapperImpl.class
})
@RunWith(SpringRunner.class)
public class AssetDTOUnitTest {
private static final Long SOME_CUSTOMER_ID = RandomUtils.nextLong(100, 199);
private static final Integer SOME_CUSTOMER_REFERENCE = 10001;
private static final String SOME_CUSTOMER_PREFIX = "abc";
private static final String SOME_CUSTOMER_NAME = "Some Customer Name";
private static final Customer SOME_CUSTOMER = new Customer().id(SOME_CUSTOMER_ID).reference(SOME_CUSTOMER_REFERENCE).prefix(SOME_CUSTOMER_PREFIX).name(SOME_CUSTOMER_NAME);
private static final Long SOME_MEMBERSHIP_ID = RandomUtils.nextLong(200, 299);
private static final LocalDate SOME_MEMBER_FROM_DATE = LocalDate.parse("2000-12-06") ;
private static final Membership SOME_MEMBERSHIP = new Membership().id(SOME_MEMBERSHIP_ID).customer(SOME_CUSTOMER).memberFromDate(SOME_MEMBER_FROM_DATE);
public static final String SOME_MEMBERSHIP_DISPLAY_LABEL = "Some Customer Name [10001:abc] 2000-12-06 - ...";
private static final Long SOME_ASSET_ID = RandomUtils.nextLong(300, 399);
private static final Asset SOME_ASSET = new Asset().id(SOME_ASSET_ID).membership(SOME_MEMBERSHIP);
@Rule
public MockitoRule mockito = MockitoJUnit.rule();
@Autowired
private ObjectMapper objectMapper;
@Autowired
private AssetMapper assetMapper;
@MockBean
private AssetRepository assetRepository;
@MockBean
private AssetValidator assetValidator;
@MockBean
private CustomerRepository customerRepository;
@MockBean
private MembershipRepository membershipRepository;
@MockBean
private MembershipValidator membershipValidator;
@MockBean
private AssetService assetService;
@MockBean
private EntityManager em;
@Before
public void init() {
given(customerRepository.findById(SOME_CUSTOMER_ID)).willReturn(Optional.of(SOME_CUSTOMER));
given(membershipRepository.findById(SOME_MEMBERSHIP_ID)).willReturn(Optional.of(SOME_MEMBERSHIP));
given(assetRepository.findById(SOME_ASSET_ID)).willReturn((Optional.of(SOME_ASSET)));
}
@Test
public void shouldSerializePartiallyForFinancialCustomerContact() throws JsonProcessingException {
// given
givenAuthenticatedUser();
givenUserHavingRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.FINANCIAL_CONTACT);
final AssetDTO given = createSomeAssetDTO(SOME_ASSET_ID);
// when
final String actual = objectMapper.writeValueAsString(given);
// then
given.setRemark(null);
assertEquals(createExpectedJSon(given), actual);
}
@Test
public void shouldSerializeCompletelyForSupporter() throws JsonProcessingException {
// given
givenAuthenticatedUser();
givenUserHavingRole(Role.SUPPORTER);
final AssetDTO given = createSomeAssetDTO(SOME_ASSET_ID);
// when
final String actual = objectMapper.writeValueAsString(given);
// then
assertEquals(createExpectedJSon(given), actual);
}
@Test
public void shouldNotDeserializeForContractualCustomerContact() {
// given
givenAuthenticatedUser();
givenUserHavingRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.CONTRACTUAL_CONTACT);
final String json = new JSonBuilder()
.withFieldValue("id", SOME_ASSET_ID)
.withFieldValue("remark", "Updated Remark")
.toString();
// when
final Throwable actual = catchThrowable(() -> objectMapper.readValue(json, AssetDTO.class));
// then
assertThat(actual).isInstanceOfSatisfying(BadRequestAlertException.class, bre ->
assertThat(bre.getMessage()).isEqualTo("Update of field AssetDTO.remark prohibited for current user role CONTRACTUAL_CONTACT")
);
}
@Test
public void shouldDeserializeForAdminIfRemarkIsChanged() throws IOException {
// given
givenAuthenticatedUser();
givenUserHavingRole(Role.ADMIN);
final String json = new JSonBuilder()
.withFieldValue("id", SOME_ASSET_ID)
.withFieldValue("remark", "Updated Remark")
.toString();
// when
final AssetDTO actual = objectMapper.readValue(json, AssetDTO.class);
// then
final AssetDTO expected = new AssetDTO();
expected.setId(SOME_ASSET_ID);
expected.setMembershipId(SOME_MEMBERSHIP_ID);
expected.setRemark("Updated Remark");
expected.setMembershipDisplayLabel(SOME_MEMBERSHIP_DISPLAY_LABEL);
assertThat(actual).isEqualToIgnoringGivenFields(expected, "displayLabel");
}
// --- only test fixture below ---
private String createExpectedJSon(AssetDTO dto) {
return new JSonBuilder()
.withFieldValueIfPresent("id", dto.getId())
.withFieldValueIfPresent("documentDate", dto.getDocumentDate().toString())
.withFieldValueIfPresent("valueDate", dto.getValueDate().toString())
.withFieldValueIfPresent("action", dto.getAction().name())
.withFieldValueIfPresent("amount", dto.getAmount().doubleValue())
.withFieldValueIfPresent("remark", dto.getRemark())
.withFieldValueIfPresent("membershipId", dto.getMembershipId())
.withFieldValue("membershipDisplayLabel", dto.getMembershipDisplayLabel())
.toString();
}
private AssetDTO createSomeAssetDTO(final long id) {
final AssetDTO given = new AssetDTO();
given.setId(id);
given.setAction(AssetAction.PAYMENT);
given.setAmount(new BigDecimal("512.01"));
given.setDocumentDate(LocalDate.parse("2019-04-27"));
given.setValueDate(LocalDate.parse("2019-04-28"));
given.setMembershipId(SOME_MEMBERSHIP_ID);
given.setRemark("Some Remark");
given.setMembershipDisplayLabel("Display Label for Membership #" + SOME_MEMBERSHIP_ID);
return given;
}
}

View File

@ -7,6 +7,7 @@ import org.hostsharing.hsadminng.domain.enumeration.CustomerKind;
import org.hostsharing.hsadminng.domain.enumeration.VatRegion;
import org.hostsharing.hsadminng.repository.CustomerRepository;
import org.hostsharing.hsadminng.service.CustomerService;
import org.hostsharing.hsadminng.service.accessfilter.JSonBuilder;
import org.hostsharing.hsadminng.service.accessfilter.Role;
import org.hostsharing.hsadminng.service.mapper.CustomerMapper;
import org.hostsharing.hsadminng.service.mapper.CustomerMapperImpl;
@ -78,12 +79,12 @@ public class CustomerDTOUnitTest {
String actual = objectMapper.writeValueAsString(given);
// then
final String expectedJSon = "{" +
toJSonFieldDefinition("id", given.getId()) + "," +
toJSonFieldDefinition("reference", given.getReference()) + "," +
toJSonFieldDefinition("prefix", given.getPrefix()) + "," +
toJSonFieldDefinition("name", given.getName()) +
"}";
final String expectedJSon = new JSonBuilder()
.withFieldValue("id", given.getId())
.withFieldValue("reference", given.getReference())
.withFieldValue("prefix", given.getPrefix())
.withFieldValue("name", given.getName())
.withFieldValue("displayLabel", given.getDisplayLabel()).toString();
assertEquals(expectedJSon, actual);
}
@ -118,56 +119,30 @@ public class CustomerDTOUnitTest {
expected.setId(1234L);
expected.setContractualSalutation("Hallo Updated");
expected.setBillingSalutation("Moin Updated");
assertThat(actual).isEqualToComparingFieldByField(expected);
assertThat(actual).isEqualToIgnoringGivenFields(expected, "displayLabel");
}
// --- only test fixture below ---
private String createExpectedJSon(CustomerDTO dto) {
String json = // the fields in alphanumeric order:
toJSonFieldDefinitionIfPresent("id", dto.getId()) +
toJSonFieldDefinitionIfPresent("reference", dto.getReference()) +
toJSonFieldDefinitionIfPresent("prefix", dto.getPrefix()) +
toJSonFieldDefinitionIfPresent("name", dto.getName()) +
toJSonFieldDefinitionIfPresent("kind", "LEGAL") +
toJSonNullFieldDefinition("birthDate") +
toJSonNullFieldDefinition("birthPlace") +
toJSonFieldDefinitionIfPresent("registrationCourt", "Registergericht") +
toJSonFieldDefinitionIfPresent("registrationNumber", "Registernummer") +
toJSonFieldDefinitionIfPresent("vatRegion", "DOMESTIC") +
toJSonFieldDefinitionIfPresent("vatNumber", "DE1234") +
toJSonFieldDefinitionIfPresent("contractualSalutation", dto.getContractualSalutation()) +
toJSonFieldDefinitionIfPresent("contractualAddress", dto.getContractualAddress()) +
toJSonFieldDefinitionIfPresent("billingSalutation", dto.getBillingSalutation()) +
toJSonFieldDefinitionIfPresent("billingAddress", dto.getBillingAddress()) +
toJSonFieldDefinitionIfPresent("remark", dto.getRemark());
return "{" + json.substring(0, json.length() - 1) + "}";
}
private String toJSonFieldDefinition(String name, String value) {
return inQuotes(name) + ":" + (value != null ? inQuotes(value) : "null");
}
private String toJSonFieldDefinition(String name, Number value) {
return inQuotes(name) + ":" + (value != null ? value : "null");
}
private String toJSonNullFieldDefinition(String name) {
return inQuotes(name) + ":null,";
}
private String toJSonFieldDefinitionIfPresent(String name, String value) {
return value != null ? inQuotes(name) + ":" + inQuotes(value) + "," : "";
}
private String toJSonFieldDefinitionIfPresent(String name, Number value) {
return value != null ? inQuotes(name) + ":" + value + "," : "";
}
private String inQuotes(Object value) {
return "\"" + value.toString() + "\"";
return new JSonBuilder()
.withFieldValueIfPresent("id", dto.getId())
.withFieldValueIfPresent("reference", dto.getReference())
.withFieldValueIfPresent("prefix", dto.getPrefix())
.withFieldValueIfPresent("name", dto.getName())
.withFieldValueIfPresent("kind", "LEGAL")
.toJSonNullFieldDefinition("birthDate")
.toJSonNullFieldDefinition("birthPlace")
.withFieldValueIfPresent("registrationCourt", "Registergericht")
.withFieldValueIfPresent("registrationNumber", "Registernummer")
.withFieldValueIfPresent("vatRegion", "DOMESTIC")
.withFieldValueIfPresent("vatNumber", "DE1234")
.withFieldValueIfPresent("contractualSalutation", dto.getContractualSalutation())
.withFieldValueIfPresent("contractualAddress", dto.getContractualAddress())
.withFieldValueIfPresent("billingSalutation", dto.getBillingSalutation())
.withFieldValueIfPresent("billingAddress", dto.getBillingAddress())
.withFieldValueIfPresent("remark", dto.getRemark())
.withFieldValueIfPresent("displayLabel", dto.getDisplayLabel()).toString();
}
private CustomerDTO createSomeCustomerDTO(final long id) {
@ -186,6 +161,7 @@ public class CustomerDTOUnitTest {
given.setBillingAddress("Noch eine Adresse");
given.setBillingSalutation("Moin");
given.setRemark("Eine Bemerkung");
given.setDisplayLabel("Display Label");
return given;
}
}

View File

@ -154,7 +154,7 @@ public class ShareDTOUnitTest {
givenDTO.setAction(ShareAction.SUBSCRIPTION);
givenDTO.setQuantity(3);
givenDTO.setDocumentDate(LocalDate.parse("2019-04-22"));
givenDTO.setMembershipDisplayReference("2019-04-21"); // TODO: why is this not a LocalDate?
givenDTO.setMembershipDisplayLabel("2019-04-21"); // TODO: why is this not a LocalDate?
givenDTO.setValueDate(LocalDate.parse("2019-04-30"));
givenDTO.setRemark("Some Remark");
return givenDTO;

View File

@ -7,6 +7,8 @@ import org.hostsharing.hsadminng.domain.enumeration.AssetAction;
import org.hostsharing.hsadminng.repository.AssetRepository;
import org.hostsharing.hsadminng.service.AssetQueryService;
import org.hostsharing.hsadminng.service.AssetService;
import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext;
import org.hostsharing.hsadminng.service.accessfilter.Role;
import org.hostsharing.hsadminng.service.dto.AssetDTO;
import org.hostsharing.hsadminng.service.mapper.AssetMapper;
import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator;
@ -27,6 +29,7 @@ import org.springframework.validation.Validator;
import javax.persistence.EntityManager;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.List;
@ -54,8 +57,8 @@ public class AssetResourceIntTest {
private static final AssetAction DEFAULT_ACTION = AssetAction.PAYMENT;
private static final AssetAction UPDATED_ACTION = AssetAction.HANDOVER;
private static final BigDecimal DEFAULT_AMOUNT = new BigDecimal(1);
private static final BigDecimal UPDATED_AMOUNT = new BigDecimal(2);
private static final BigDecimal DEFAULT_AMOUNT = new BigDecimal("1");
private static final BigDecimal UPDATED_AMOUNT = new BigDecimal("2");
private static final String DEFAULT_REMARK = "AAAAAAAAAA";
private static final String UPDATED_REMARK = "BBBBBBBBBB";
@ -93,6 +96,9 @@ public class AssetResourceIntTest {
@Before
public void setup() {
MockSecurityContext.givenAuthenticatedUser();
MockSecurityContext.givenUserHavingRole(Role.ADMIN);
MockitoAnnotations.initMocks(this);
final AssetResource assetResource = new AssetResource(assetService, assetQueryService);
this.restAssetMockMvc = MockMvcBuilders.standaloneSetup(assetResource)
@ -168,16 +174,16 @@ public class AssetResourceIntTest {
assertThat(testAsset.getDocumentDate()).isEqualTo(DEFAULT_DOCUMENT_DATE);
assertThat(testAsset.getValueDate()).isEqualTo(DEFAULT_VALUE_DATE);
assertThat(testAsset.getAction()).isEqualTo(DEFAULT_ACTION);
assertThat(testAsset.getAmount()).isEqualTo(DEFAULT_AMOUNT);
assertThat(testAsset.getAmount()).isEqualTo(DEFAULT_AMOUNT.setScale(2, RoundingMode.HALF_DOWN));
assertThat(testAsset.getRemark()).isEqualTo(DEFAULT_REMARK);
}
@Test
@Transactional
public void createAssetWithExistingId() throws Exception {
public void createAssetWithIdForNonExistingEntity() throws Exception {
int databaseSizeBeforeCreate = assetRepository.findAll().size();
// Create the Asset with an existing ID
// Create the Asset with an ID
asset.setId(1L);
AssetDTO assetDTO = assetMapper.toDto(asset);
@ -192,6 +198,27 @@ public class AssetResourceIntTest {
assertThat(assetList).hasSize(databaseSizeBeforeCreate);
}
@Test
@Transactional
public void createAssetWithExistingExistingEntity() throws Exception {
// Initialize the database
assetRepository.saveAndFlush(asset);
int databaseSizeBeforeCreate = assetRepository.findAll().size();
// Create the Asset with the ID of an existing ID
AssetDTO assetDTO = assetMapper.toDto(asset);
// An entity with an existing ID cannot be created, so this API call must fail
restAssetMockMvc.perform(post("/api/assets")
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(TestUtil.convertObjectToJsonBytes(assetDTO)))
.andExpect(status().isBadRequest());
// Validate the Asset in the database
List<Asset> assetList = assetRepository.findAll();
assertThat(assetList).hasSize(databaseSizeBeforeCreate);
}
@Test
@Transactional
public void checkDocumentDateIsRequired() throws Exception {
@ -283,7 +310,7 @@ public class AssetResourceIntTest {
.andExpect(jsonPath("$.[*].valueDate").value(hasItem(DEFAULT_VALUE_DATE.toString())))
.andExpect(jsonPath("$.[*].action").value(hasItem(DEFAULT_ACTION.toString())))
.andExpect(jsonPath("$.[*].amount").value(hasItem(DEFAULT_AMOUNT.intValue())))
.andExpect(jsonPath("$.[*].remark").value(hasItem(DEFAULT_REMARK.toString())));
.andExpect(jsonPath("$.[*].remark").value(hasItem(DEFAULT_REMARK)));
}
@Test
@ -301,7 +328,7 @@ public class AssetResourceIntTest {
.andExpect(jsonPath("$.valueDate").value(DEFAULT_VALUE_DATE.toString()))
.andExpect(jsonPath("$.action").value(DEFAULT_ACTION.toString()))
.andExpect(jsonPath("$.amount").value(DEFAULT_AMOUNT.intValue()))
.andExpect(jsonPath("$.remark").value(DEFAULT_REMARK.toString()));
.andExpect(jsonPath("$.remark").value(DEFAULT_REMARK));
}
@Test

View File

@ -9,6 +9,7 @@ import org.hostsharing.hsadminng.domain.enumeration.VatRegion;
import org.hostsharing.hsadminng.repository.CustomerRepository;
import org.hostsharing.hsadminng.service.CustomerQueryService;
import org.hostsharing.hsadminng.service.CustomerService;
import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext;
import org.hostsharing.hsadminng.service.accessfilter.Role;
import org.hostsharing.hsadminng.service.dto.CustomerDTO;
import org.hostsharing.hsadminng.service.mapper.CustomerMapper;
@ -136,6 +137,9 @@ public class CustomerResourceIntTest {
@Before
public void setup() {
MockSecurityContext.givenAuthenticatedUser();
MockSecurityContext.givenUserHavingRole(Role.ADMIN);
MockitoAnnotations.initMocks(this);
givenAuthenticatedUser();
@ -261,7 +265,7 @@ public class CustomerResourceIntTest {
public void createCustomerWithNonExistingIdIsRejected() throws Exception {
int databaseSizeBeforeCreate = customerRepository.findAll().size();
// Create the Customer with an existing ID
// Create the Customer with an ID for which no entity exists
customer.setId(1L);
CustomerDTO customerDTO = customerMapper.toDto(customer);
@ -430,20 +434,20 @@ public class CustomerResourceIntTest {
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$.id").value(customer.getId().intValue()))
.andExpect(jsonPath("$.reference").value(DEFAULT_REFERENCE))
.andExpect(jsonPath("$.prefix").value(DEFAULT_PREFIX.toString()))
.andExpect(jsonPath("$.name").value(DEFAULT_NAME.toString()))
.andExpect(jsonPath("$.prefix").value(DEFAULT_PREFIX))
.andExpect(jsonPath("$.name").value(DEFAULT_NAME))
.andExpect(jsonPath("$.kind").value(DEFAULT_KIND.toString()))
.andExpect(jsonPath("$.birthDate").value(DEFAULT_BIRTH_DATE.toString()))
.andExpect(jsonPath("$.birthPlace").value(DEFAULT_BIRTH_PLACE.toString()))
.andExpect(jsonPath("$.registrationCourt").value(DEFAULT_REGISTRATION_COURT.toString()))
.andExpect(jsonPath("$.registrationNumber").value(DEFAULT_REGISTRATION_NUMBER.toString()))
.andExpect(jsonPath("$.birthPlace").value(DEFAULT_BIRTH_PLACE))
.andExpect(jsonPath("$.registrationCourt").value(DEFAULT_REGISTRATION_COURT))
.andExpect(jsonPath("$.registrationNumber").value(DEFAULT_REGISTRATION_NUMBER))
.andExpect(jsonPath("$.vatRegion").value(DEFAULT_VAT_REGION.toString()))
.andExpect(jsonPath("$.vatNumber").value(DEFAULT_VAT_NUMBER.toString()))
.andExpect(jsonPath("$.contractualSalutation").value(DEFAULT_CONTRACTUAL_SALUTATION.toString()))
.andExpect(jsonPath("$.contractualAddress").value(DEFAULT_CONTRACTUAL_ADDRESS.toString()))
.andExpect(jsonPath("$.billingSalutation").value(DEFAULT_BILLING_SALUTATION.toString()))
.andExpect(jsonPath("$.billingAddress").value(DEFAULT_BILLING_ADDRESS.toString()))
.andExpect(jsonPath("$.remark").value(DEFAULT_REMARK.toString()));
.andExpect(jsonPath("$.vatNumber").value(DEFAULT_VAT_NUMBER))
.andExpect(jsonPath("$.contractualSalutation").value(DEFAULT_CONTRACTUAL_SALUTATION))
.andExpect(jsonPath("$.contractualAddress").value(DEFAULT_CONTRACTUAL_ADDRESS))
.andExpect(jsonPath("$.billingSalutation").value(DEFAULT_BILLING_SALUTATION))
.andExpect(jsonPath("$.billingAddress").value(DEFAULT_BILLING_ADDRESS))
.andExpect(jsonPath("$.remark").value(DEFAULT_REMARK));
}
@Test
@ -1265,11 +1269,11 @@ public class CustomerResourceIntTest {
// Delete the customer
restCustomerMockMvc.perform(delete("/api/customers/{id}", customer.getId())
.accept(TestUtil.APPLICATION_JSON_UTF8))
.andExpect(status().isOk());
.andExpect(status().isBadRequest());
// Validate the database is empty
// Validate the database is unchanged
List<Customer> customerList = customerRepository.findAll();
assertThat(customerList).hasSize(databaseSizeBeforeDelete - 1);
assertThat(customerList).hasSize(databaseSizeBeforeDelete);
}
@Test

View File

@ -8,6 +8,8 @@ import org.hostsharing.hsadminng.domain.Share;
import org.hostsharing.hsadminng.repository.MembershipRepository;
import org.hostsharing.hsadminng.service.MembershipQueryService;
import org.hostsharing.hsadminng.service.MembershipService;
import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext;
import org.hostsharing.hsadminng.service.accessfilter.Role;
import org.hostsharing.hsadminng.service.dto.MembershipDTO;
import org.hostsharing.hsadminng.service.mapper.MembershipMapper;
import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator;
@ -97,6 +99,9 @@ public class MembershipResourceIntTest {
@Before
public void setup() {
MockSecurityContext.givenAuthenticatedUser();
MockSecurityContext.givenUserHavingRole(Role.ADMIN);
MockitoAnnotations.initMocks(this);
final MembershipResource membershipResource = new MembershipResource(membershipService, membershipQueryService);
this.restMembershipMockMvc = MockMvcBuilders.standaloneSetup(membershipResource)
@ -177,10 +182,32 @@ public class MembershipResourceIntTest {
@Test
@Transactional
public void createMembershipWithExistingId() throws Exception {
public void createCustomerWithExistingIdIsRejected() throws Exception {
// Initialize the database
final long existingCustomerId = membershipRepository.saveAndFlush(membership).getId();
int databaseSizeBeforeCreate = membershipRepository.findAll().size();
// Create the Membership with an existing ID
// Create the Customer with an existing ID
membership.setId(existingCustomerId);
MembershipDTO membershipDTO = membershipMapper.toDto(membership);
// An entity with an existing ID cannot be created, so this API call must fail
restMembershipMockMvc.perform(post("/api/memberships")
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(TestUtil.convertObjectToJsonBytes(membershipDTO)))
.andExpect(status().isBadRequest());
// Validate the Customer in the database
List<Membership> membershipList = membershipRepository.findAll();
assertThat(membershipList).hasSize(databaseSizeBeforeCreate);
}
@Test
@Transactional
public void createCustomerWithNonExistingIdIsRejected() throws Exception {
int databaseSizeBeforeCreate = membershipRepository.findAll().size();
// Create the Membership with an ID for which no entity exists
membership.setId(1L);
MembershipDTO membershipDTO = membershipMapper.toDto(membership);
@ -248,7 +275,7 @@ public class MembershipResourceIntTest {
.andExpect(jsonPath("$.[*].cancellationDocumentDate").value(hasItem(DEFAULT_CANCELLATION_DOCUMENT_DATE.toString())))
.andExpect(jsonPath("$.[*].memberFromDate").value(hasItem(DEFAULT_MEMBER_FROM_DATE.toString())))
.andExpect(jsonPath("$.[*].memberUntilDate").value(hasItem(DEFAULT_MEMBER_UNTIL_DATE.toString())))
.andExpect(jsonPath("$.[*].remark").value(hasItem(DEFAULT_REMARK.toString())));
.andExpect(jsonPath("$.[*].remark").value(hasItem(DEFAULT_REMARK)));
}
@Test
@ -266,7 +293,7 @@ public class MembershipResourceIntTest {
.andExpect(jsonPath("$.cancellationDocumentDate").value(DEFAULT_CANCELLATION_DOCUMENT_DATE.toString()))
.andExpect(jsonPath("$.memberFromDate").value(DEFAULT_MEMBER_FROM_DATE.toString()))
.andExpect(jsonPath("$.memberUntilDate").value(DEFAULT_MEMBER_UNTIL_DATE.toString()))
.andExpect(jsonPath("$.remark").value(DEFAULT_REMARK.toString()));
.andExpect(jsonPath("$.remark").value(DEFAULT_REMARK));
}
@Test
@ -682,9 +709,7 @@ public class MembershipResourceIntTest {
// Disconnect from session so that the updates on updatedMembership are not directly saved in db
em.detach(updatedMembership);
updatedMembership
.admissionDocumentDate(UPDATED_ADMISSION_DOCUMENT_DATE)
.cancellationDocumentDate(UPDATED_CANCELLATION_DOCUMENT_DATE)
.memberFromDate(UPDATED_MEMBER_FROM_DATE)
.memberUntilDate(UPDATED_MEMBER_UNTIL_DATE)
.remark(UPDATED_REMARK);
MembershipDTO membershipDTO = membershipMapper.toDto(updatedMembership);
@ -698,9 +723,9 @@ public class MembershipResourceIntTest {
List<Membership> membershipList = membershipRepository.findAll();
assertThat(membershipList).hasSize(databaseSizeBeforeUpdate);
Membership testMembership = membershipList.get(membershipList.size() - 1);
assertThat(testMembership.getAdmissionDocumentDate()).isEqualTo(UPDATED_ADMISSION_DOCUMENT_DATE);
assertThat(testMembership.getAdmissionDocumentDate()).isEqualTo(DEFAULT_ADMISSION_DOCUMENT_DATE);
assertThat(testMembership.getCancellationDocumentDate()).isEqualTo(UPDATED_CANCELLATION_DOCUMENT_DATE);
assertThat(testMembership.getMemberFromDate()).isEqualTo(UPDATED_MEMBER_FROM_DATE);
assertThat(testMembership.getMemberFromDate()).isEqualTo(DEFAULT_MEMBER_FROM_DATE);
assertThat(testMembership.getMemberUntilDate()).isEqualTo(UPDATED_MEMBER_UNTIL_DATE);
assertThat(testMembership.getRemark()).isEqualTo(UPDATED_REMARK);
}

View File

@ -7,6 +7,8 @@ import org.hostsharing.hsadminng.domain.enumeration.ShareAction;
import org.hostsharing.hsadminng.repository.ShareRepository;
import org.hostsharing.hsadminng.service.ShareQueryService;
import org.hostsharing.hsadminng.service.ShareService;
import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext;
import org.hostsharing.hsadminng.service.accessfilter.Role;
import org.hostsharing.hsadminng.service.dto.ShareDTO;
import org.hostsharing.hsadminng.service.mapper.ShareMapper;
import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator;
@ -92,6 +94,9 @@ public class ShareResourceIntTest {
@Before
public void setup() {
MockSecurityContext.givenAuthenticatedUser();
MockSecurityContext.givenUserHavingRole(Role.ADMIN);
MockitoAnnotations.initMocks(this);
final ShareResource shareResource = new ShareResource(shareService, shareQueryService);
this.restShareMockMvc = MockMvcBuilders.standaloneSetup(shareResource)