From d4ff2d503e778af7bc51620f68515f319d1d237f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C5=82awek=20Zatorski?= Date: Wed, 13 Nov 2024 14:52:04 +0100 Subject: [PATCH] UserAccount --- .jhipster/UserAccount.json | 26 + .yo-rc.json | 4 +- .../sasiedzi/event/domain/UserAccount.java | 113 +++++ .../repository/UserAccountRepository.java | 30 ++ ...AccountRepositoryWithBagRelationships.java | 14 + ...untRepositoryWithBagRelationshipsImpl.java | 67 +++ .../event/web/rest/UserAccountResource.java | 183 +++++++ ...0241113135042_added_entity_UserAccount.xml | 59 +++ ...2_added_entity_constraints_UserAccount.xml | 27 ++ .../liquibase/fake-data/user_account.csv | 11 + .../resources/config/liquibase/master.xml | 2 + .../webapp/app/entities/entities-menu.vue | 4 + .../webapp/app/entities/entities.component.ts | 2 + .../app/entities/event/event.service.spec.ts | 2 +- .../transaction/transaction.service.spec.ts | 2 +- .../user-account-details.component.spec.ts | 89 ++++ .../user-account-details.component.ts | 41 ++ .../user-account/user-account-details.vue | 41 ++ .../user-account-update.component.spec.ts | 138 ++++++ .../user-account-update.component.ts | 112 +++++ .../user-account/user-account-update.vue | 58 +++ .../user-account.component.spec.ts | 100 ++++ .../user-account/user-account.component.ts | 75 +++ .../user-account/user-account.service.spec.ts | 160 +++++++ .../user-account/user-account.service.ts | 85 ++++ .../entities/user-account/user-account.vue | 103 ++++ src/main/webapp/app/router/entities.ts | 28 ++ .../app/shared/model/user-account.model.ts | 15 + .../event/domain/UserAccountAsserts.java | 62 +++ .../event/domain/UserAccountTest.java | 24 + .../event/domain/UserAccountTestSamples.java | 23 + .../event/web/rest/ChargeResourceIT.java | 2 - .../event/web/rest/EventResourceIT.java | 2 + .../event/web/rest/UserAccountResourceIT.java | 450 ++++++++++++++++++ 34 files changed, 2148 insertions(+), 6 deletions(-) create mode 100644 .jhipster/UserAccount.json create mode 100644 src/main/java/com/sasiedzi/event/domain/UserAccount.java create mode 100644 src/main/java/com/sasiedzi/event/repository/UserAccountRepository.java create mode 100644 src/main/java/com/sasiedzi/event/repository/UserAccountRepositoryWithBagRelationships.java create mode 100644 src/main/java/com/sasiedzi/event/repository/UserAccountRepositoryWithBagRelationshipsImpl.java create mode 100644 src/main/java/com/sasiedzi/event/web/rest/UserAccountResource.java create mode 100644 src/main/resources/config/liquibase/changelog/20241113135042_added_entity_UserAccount.xml create mode 100644 src/main/resources/config/liquibase/changelog/20241113135042_added_entity_constraints_UserAccount.xml create mode 100644 src/main/resources/config/liquibase/fake-data/user_account.csv create mode 100644 src/main/webapp/app/entities/user-account/user-account-details.component.spec.ts create mode 100644 src/main/webapp/app/entities/user-account/user-account-details.component.ts create mode 100644 src/main/webapp/app/entities/user-account/user-account-details.vue create mode 100644 src/main/webapp/app/entities/user-account/user-account-update.component.spec.ts create mode 100644 src/main/webapp/app/entities/user-account/user-account-update.component.ts create mode 100644 src/main/webapp/app/entities/user-account/user-account-update.vue create mode 100644 src/main/webapp/app/entities/user-account/user-account.component.spec.ts create mode 100644 src/main/webapp/app/entities/user-account/user-account.component.ts create mode 100644 src/main/webapp/app/entities/user-account/user-account.service.spec.ts create mode 100644 src/main/webapp/app/entities/user-account/user-account.service.ts create mode 100644 src/main/webapp/app/entities/user-account/user-account.vue create mode 100644 src/main/webapp/app/shared/model/user-account.model.ts create mode 100644 src/test/java/com/sasiedzi/event/domain/UserAccountAsserts.java create mode 100644 src/test/java/com/sasiedzi/event/domain/UserAccountTest.java create mode 100644 src/test/java/com/sasiedzi/event/domain/UserAccountTestSamples.java create mode 100644 src/test/java/com/sasiedzi/event/web/rest/UserAccountResourceIT.java diff --git a/.jhipster/UserAccount.json b/.jhipster/UserAccount.json new file mode 100644 index 0000000..c3d89c7 --- /dev/null +++ b/.jhipster/UserAccount.json @@ -0,0 +1,26 @@ +{ + "annotations": { + "changelogDate": "20241113135042" + }, + "fields": [ + { + "fieldName": "name", + "fieldType": "String" + } + ], + "name": "UserAccount", + "pagination": "no", + "readOnly": false, + "relationships": [ + { + "otherEntityField": "login", + "otherEntityName": "user", + "otherEntityRelationshipName": "userAccount", + "relationshipName": "user", + "relationshipSide": "left", + "relationshipType": "many-to-many" + } + ], + "searchEngine": "no", + "service": "no" +} diff --git a/.yo-rc.json b/.yo-rc.json index c6fd6c0..3d3259e 100644 --- a/.yo-rc.json +++ b/.yo-rc.json @@ -15,10 +15,10 @@ "enableHibernateCache": null, "enableSwaggerCodegen": false, "enableTranslation": false, - "entities": ["Charge", "Event", "Registration", "Transaction"], + "entities": ["Charge", "Event", "Registration", "Transaction", "UserAccount"], "feignClient": null, "jhipsterVersion": "8.7.2", - "lastLiquibaseTimestamp": 1730797803000, + "lastLiquibaseTimestamp": 1731505842000, "messageBroker": false, "microfrontend": null, "microfrontends": [], diff --git a/src/main/java/com/sasiedzi/event/domain/UserAccount.java b/src/main/java/com/sasiedzi/event/domain/UserAccount.java new file mode 100644 index 0000000..00390be --- /dev/null +++ b/src/main/java/com/sasiedzi/event/domain/UserAccount.java @@ -0,0 +1,113 @@ +package com.sasiedzi.event.domain; + +import jakarta.persistence.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +/** + * A UserAccount. + */ +@Entity +@Table(name = "user_account") +@SuppressWarnings("common-java:DuplicatedBlocks") +public class UserAccount implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + @Column(name = "id") + private Long id; + + @Column(name = "name") + private String name; + + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable( + name = "rel_user_account__user", + joinColumns = @JoinColumn(name = "user_account_id"), + inverseJoinColumns = @JoinColumn(name = "user_id") + ) + private Set users = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public UserAccount id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public UserAccount name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public Set getUsers() { + return this.users; + } + + public void setUsers(Set users) { + this.users = users; + } + + public UserAccount users(Set users) { + this.setUsers(users); + return this; + } + + public UserAccount addUser(User user) { + this.users.add(user); + return this; + } + + public UserAccount removeUser(User user) { + this.users.remove(user); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof UserAccount)) { + return false; + } + return getId() != null && getId().equals(((UserAccount) o).getId()); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "UserAccount{" + + "id=" + getId() + + ", name='" + getName() + "'" + + "}"; + } +} diff --git a/src/main/java/com/sasiedzi/event/repository/UserAccountRepository.java b/src/main/java/com/sasiedzi/event/repository/UserAccountRepository.java new file mode 100644 index 0000000..14114b1 --- /dev/null +++ b/src/main/java/com/sasiedzi/event/repository/UserAccountRepository.java @@ -0,0 +1,30 @@ +package com.sasiedzi.event.repository; + +import com.sasiedzi.event.domain.UserAccount; +import java.util.List; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the UserAccount entity. + * + * When extending this class, extend UserAccountRepositoryWithBagRelationships too. + * For more information refer to https://github.com/jhipster/generator-jhipster/issues/17990. + */ +@Repository +public interface UserAccountRepository extends UserAccountRepositoryWithBagRelationships, JpaRepository { + default Optional findOneWithEagerRelationships(Long id) { + return this.fetchBagRelationships(this.findById(id)); + } + + default List findAllWithEagerRelationships() { + return this.fetchBagRelationships(this.findAll()); + } + + default Page findAllWithEagerRelationships(Pageable pageable) { + return this.fetchBagRelationships(this.findAll(pageable)); + } +} diff --git a/src/main/java/com/sasiedzi/event/repository/UserAccountRepositoryWithBagRelationships.java b/src/main/java/com/sasiedzi/event/repository/UserAccountRepositoryWithBagRelationships.java new file mode 100644 index 0000000..9c0c61b --- /dev/null +++ b/src/main/java/com/sasiedzi/event/repository/UserAccountRepositoryWithBagRelationships.java @@ -0,0 +1,14 @@ +package com.sasiedzi.event.repository; + +import com.sasiedzi.event.domain.UserAccount; +import java.util.List; +import java.util.Optional; +import org.springframework.data.domain.Page; + +public interface UserAccountRepositoryWithBagRelationships { + Optional fetchBagRelationships(Optional userAccount); + + List fetchBagRelationships(List userAccounts); + + Page fetchBagRelationships(Page userAccounts); +} diff --git a/src/main/java/com/sasiedzi/event/repository/UserAccountRepositoryWithBagRelationshipsImpl.java b/src/main/java/com/sasiedzi/event/repository/UserAccountRepositoryWithBagRelationshipsImpl.java new file mode 100644 index 0000000..6365794 --- /dev/null +++ b/src/main/java/com/sasiedzi/event/repository/UserAccountRepositoryWithBagRelationshipsImpl.java @@ -0,0 +1,67 @@ +package com.sasiedzi.event.repository; + +import com.sasiedzi.event.domain.UserAccount; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; +import java.util.stream.IntStream; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; + +/** + * Utility repository to load bag relationships based on https://vladmihalcea.com/hibernate-multiplebagfetchexception/ + */ +public class UserAccountRepositoryWithBagRelationshipsImpl implements UserAccountRepositoryWithBagRelationships { + + private static final String ID_PARAMETER = "id"; + private static final String USERACCOUNTS_PARAMETER = "userAccounts"; + + @PersistenceContext + private EntityManager entityManager; + + @Override + public Optional fetchBagRelationships(Optional userAccount) { + return userAccount.map(this::fetchUsers); + } + + @Override + public Page fetchBagRelationships(Page userAccounts) { + return new PageImpl<>( + fetchBagRelationships(userAccounts.getContent()), + userAccounts.getPageable(), + userAccounts.getTotalElements() + ); + } + + @Override + public List fetchBagRelationships(List userAccounts) { + return Optional.of(userAccounts).map(this::fetchUsers).orElse(Collections.emptyList()); + } + + UserAccount fetchUsers(UserAccount result) { + return entityManager + .createQuery( + "select userAccount from UserAccount userAccount left join fetch userAccount.users where userAccount.id = :id", + UserAccount.class + ) + .setParameter(ID_PARAMETER, result.getId()) + .getSingleResult(); + } + + List fetchUsers(List userAccounts) { + HashMap order = new HashMap<>(); + IntStream.range(0, userAccounts.size()).forEach(index -> order.put(userAccounts.get(index).getId(), index)); + List result = entityManager + .createQuery( + "select userAccount from UserAccount userAccount left join fetch userAccount.users where userAccount in :userAccounts", + UserAccount.class + ) + .setParameter(USERACCOUNTS_PARAMETER, userAccounts) + .getResultList(); + Collections.sort(result, (o1, o2) -> Integer.compare(order.get(o1.getId()), order.get(o2.getId()))); + return result; + } +} diff --git a/src/main/java/com/sasiedzi/event/web/rest/UserAccountResource.java b/src/main/java/com/sasiedzi/event/web/rest/UserAccountResource.java new file mode 100644 index 0000000..4ae9472 --- /dev/null +++ b/src/main/java/com/sasiedzi/event/web/rest/UserAccountResource.java @@ -0,0 +1,183 @@ +package com.sasiedzi.event.web.rest; + +import com.sasiedzi.event.domain.UserAccount; +import com.sasiedzi.event.repository.UserAccountRepository; +import com.sasiedzi.event.web.rest.errors.BadRequestAlertException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link com.sasiedzi.event.domain.UserAccount}. + */ +@RestController +@RequestMapping("/api/user-accounts") +@Transactional +public class UserAccountResource { + + private static final Logger LOG = LoggerFactory.getLogger(UserAccountResource.class); + + private static final String ENTITY_NAME = "userAccount"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final UserAccountRepository userAccountRepository; + + public UserAccountResource(UserAccountRepository userAccountRepository) { + this.userAccountRepository = userAccountRepository; + } + + /** + * {@code POST /user-accounts} : Create a new userAccount. + * + * @param userAccount the userAccount to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new userAccount, or with status {@code 400 (Bad Request)} if the userAccount has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("") + public ResponseEntity createUserAccount(@RequestBody UserAccount userAccount) throws URISyntaxException { + LOG.debug("REST request to save UserAccount : {}", userAccount); + if (userAccount.getId() != null) { + throw new BadRequestAlertException("A new userAccount cannot already have an ID", ENTITY_NAME, "idexists"); + } + userAccount = userAccountRepository.save(userAccount); + return ResponseEntity.created(new URI("/api/user-accounts/" + userAccount.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, userAccount.getId().toString())) + .body(userAccount); + } + + /** + * {@code PUT /user-accounts/:id} : Updates an existing userAccount. + * + * @param id the id of the userAccount to save. + * @param userAccount the userAccount to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated userAccount, + * or with status {@code 400 (Bad Request)} if the userAccount is not valid, + * or with status {@code 500 (Internal Server Error)} if the userAccount couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/{id}") + public ResponseEntity updateUserAccount( + @PathVariable(value = "id", required = false) final Long id, + @RequestBody UserAccount userAccount + ) throws URISyntaxException { + LOG.debug("REST request to update UserAccount : {}, {}", id, userAccount); + if (userAccount.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, userAccount.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!userAccountRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + userAccount = userAccountRepository.save(userAccount); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, userAccount.getId().toString())) + .body(userAccount); + } + + /** + * {@code PATCH /user-accounts/:id} : Partial updates given fields of an existing userAccount, field will ignore if it is null + * + * @param id the id of the userAccount to save. + * @param userAccount the userAccount to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated userAccount, + * or with status {@code 400 (Bad Request)} if the userAccount is not valid, + * or with status {@code 404 (Not Found)} if the userAccount is not found, + * or with status {@code 500 (Internal Server Error)} if the userAccount couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateUserAccount( + @PathVariable(value = "id", required = false) final Long id, + @RequestBody UserAccount userAccount + ) throws URISyntaxException { + LOG.debug("REST request to partial update UserAccount partially : {}, {}", id, userAccount); + if (userAccount.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, userAccount.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!userAccountRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = userAccountRepository + .findById(userAccount.getId()) + .map(existingUserAccount -> { + if (userAccount.getName() != null) { + existingUserAccount.setName(userAccount.getName()); + } + + return existingUserAccount; + }) + .map(userAccountRepository::save); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, userAccount.getId().toString()) + ); + } + + /** + * {@code GET /user-accounts} : get all the userAccounts. + * + * @param eagerload flag to eager load entities from relationships (This is applicable for many-to-many). + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of userAccounts in body. + */ + @GetMapping("") + public List getAllUserAccounts( + @RequestParam(name = "eagerload", required = false, defaultValue = "true") boolean eagerload + ) { + LOG.debug("REST request to get all UserAccounts"); + if (eagerload) { + return userAccountRepository.findAllWithEagerRelationships(); + } else { + return userAccountRepository.findAll(); + } + } + + /** + * {@code GET /user-accounts/:id} : get the "id" userAccount. + * + * @param id the id of the userAccount to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the userAccount, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/{id}") + public ResponseEntity getUserAccount(@PathVariable("id") Long id) { + LOG.debug("REST request to get UserAccount : {}", id); + Optional userAccount = userAccountRepository.findOneWithEagerRelationships(id); + return ResponseUtil.wrapOrNotFound(userAccount); + } + + /** + * {@code DELETE /user-accounts/:id} : delete the "id" userAccount. + * + * @param id the id of the userAccount to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/{id}") + public ResponseEntity deleteUserAccount(@PathVariable("id") Long id) { + LOG.debug("REST request to delete UserAccount : {}", id); + userAccountRepository.deleteById(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } +} diff --git a/src/main/resources/config/liquibase/changelog/20241113135042_added_entity_UserAccount.xml b/src/main/resources/config/liquibase/changelog/20241113135042_added_entity_UserAccount.xml new file mode 100644 index 0000000..074de61 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20241113135042_added_entity_UserAccount.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20241113135042_added_entity_constraints_UserAccount.xml b/src/main/resources/config/liquibase/changelog/20241113135042_added_entity_constraints_UserAccount.xml new file mode 100644 index 0000000..391fe61 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20241113135042_added_entity_constraints_UserAccount.xml @@ -0,0 +1,27 @@ + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/fake-data/user_account.csv b/src/main/resources/config/liquibase/fake-data/user_account.csv new file mode 100644 index 0000000..817d47f --- /dev/null +++ b/src/main/resources/config/liquibase/fake-data/user_account.csv @@ -0,0 +1,11 @@ +id;name +1;since +2;pfft what jam-packed +3;internalise +4;yum indeed for +5;minion gee +6;likewise impressive concerning +7;notwithstanding +8;furthermore +9;diligently kindly +10;buck diff --git a/src/main/resources/config/liquibase/master.xml b/src/main/resources/config/liquibase/master.xml index bb8f9ce..33047c4 100644 --- a/src/main/resources/config/liquibase/master.xml +++ b/src/main/resources/config/liquibase/master.xml @@ -15,10 +15,12 @@ + + diff --git a/src/main/webapp/app/entities/entities-menu.vue b/src/main/webapp/app/entities/entities-menu.vue index da3ac67..0b6c386 100644 --- a/src/main/webapp/app/entities/entities-menu.vue +++ b/src/main/webapp/app/entities/entities-menu.vue @@ -16,6 +16,10 @@ Transaction + + + User Account + diff --git a/src/main/webapp/app/entities/entities.component.ts b/src/main/webapp/app/entities/entities.component.ts index e9a1453..e8b84ff 100644 --- a/src/main/webapp/app/entities/entities.component.ts +++ b/src/main/webapp/app/entities/entities.component.ts @@ -4,6 +4,7 @@ import ChargeService from './charge/charge.service'; import EventService from './event/event.service'; import RegistrationService from './registration/registration.service'; import TransactionService from './transaction/transaction.service'; +import UserAccountService from './user-account/user-account.service'; import UserService from '@/entities/user/user.service'; // jhipster-needle-add-entity-service-to-entities-component-import - JHipster will import entities services here @@ -16,6 +17,7 @@ export default defineComponent({ provide('eventService', () => new EventService()); provide('registrationService', () => new RegistrationService()); provide('transactionService', () => new TransactionService()); + provide('userAccountService', () => new UserAccountService()); // jhipster-needle-add-entity-service-to-entities-component - JHipster will import entities services here }, }); diff --git a/src/main/webapp/app/entities/event/event.service.spec.ts b/src/main/webapp/app/entities/event/event.service.spec.ts index 68cc773..37e69d2 100644 --- a/src/main/webapp/app/entities/event/event.service.spec.ts +++ b/src/main/webapp/app/entities/event/event.service.spec.ts @@ -107,7 +107,7 @@ describe('Service Tests', () => { }); it('should partial update a Event', async () => { - const patchObject = { cost: 1, ...new Event() }; + const patchObject = { name: 'BBBBBB', playersLimit: 1, cost: 1, ...new Event() }; const returnedFromService = Object.assign(patchObject, elemDefault); const expected = { date: currentDate, ...returnedFromService }; diff --git a/src/main/webapp/app/entities/transaction/transaction.service.spec.ts b/src/main/webapp/app/entities/transaction/transaction.service.spec.ts index 8d5932a..ec9a0a6 100644 --- a/src/main/webapp/app/entities/transaction/transaction.service.spec.ts +++ b/src/main/webapp/app/entities/transaction/transaction.service.spec.ts @@ -100,7 +100,7 @@ describe('Service Tests', () => { }); it('should partial update a Transaction', async () => { - const patchObject = { type: 'BBBBBB', date: dayjs(currentDate).format(DATE_FORMAT), ...new Transaction() }; + const patchObject = { ...new Transaction() }; const returnedFromService = Object.assign(patchObject, elemDefault); const expected = { date: currentDate, ...returnedFromService }; diff --git a/src/main/webapp/app/entities/user-account/user-account-details.component.spec.ts b/src/main/webapp/app/entities/user-account/user-account-details.component.spec.ts new file mode 100644 index 0000000..35837c1 --- /dev/null +++ b/src/main/webapp/app/entities/user-account/user-account-details.component.spec.ts @@ -0,0 +1,89 @@ +/* tslint:disable max-line-length */ +import { vitest } from 'vitest'; +import { type MountingOptions, shallowMount } from '@vue/test-utils'; +import sinon, { type SinonStubbedInstance } from 'sinon'; +import { type RouteLocation } from 'vue-router'; + +import UserAccountDetails from './user-account-details.vue'; +import UserAccountService from './user-account.service'; +import AlertService from '@/shared/alert/alert.service'; + +type UserAccountDetailsComponentType = InstanceType; + +let route: Partial; +const routerGoMock = vitest.fn(); + +vitest.mock('vue-router', () => ({ + useRoute: () => route, + useRouter: () => ({ go: routerGoMock }), +})); + +const userAccountSample = { id: 123 }; + +describe('Component Tests', () => { + let alertService: AlertService; + + afterEach(() => { + vitest.resetAllMocks(); + }); + + describe('UserAccount Management Detail Component', () => { + let userAccountServiceStub: SinonStubbedInstance; + let mountOptions: MountingOptions['global']; + + beforeEach(() => { + route = {}; + userAccountServiceStub = sinon.createStubInstance(UserAccountService); + + alertService = new AlertService({ + bvToast: { + toast: vitest.fn(), + } as any, + }); + + mountOptions = { + stubs: { + 'font-awesome-icon': true, + 'router-link': true, + }, + provide: { + alertService, + userAccountService: () => userAccountServiceStub, + }, + }; + }); + + describe('Navigate to details', () => { + it('Should call load all on init', async () => { + // GIVEN + userAccountServiceStub.find.resolves(userAccountSample); + route = { + params: { + userAccountId: `${123}`, + }, + }; + const wrapper = shallowMount(UserAccountDetails, { global: mountOptions }); + const comp = wrapper.vm; + // WHEN + await comp.$nextTick(); + + // THEN + expect(comp.userAccount).toMatchObject(userAccountSample); + }); + }); + + describe('Previous state', () => { + it('Should go previous state', async () => { + userAccountServiceStub.find.resolves(userAccountSample); + const wrapper = shallowMount(UserAccountDetails, { global: mountOptions }); + const comp = wrapper.vm; + await comp.$nextTick(); + + comp.previousState(); + await comp.$nextTick(); + + expect(routerGoMock).toHaveBeenCalledWith(-1); + }); + }); + }); +}); diff --git a/src/main/webapp/app/entities/user-account/user-account-details.component.ts b/src/main/webapp/app/entities/user-account/user-account-details.component.ts new file mode 100644 index 0000000..68529b6 --- /dev/null +++ b/src/main/webapp/app/entities/user-account/user-account-details.component.ts @@ -0,0 +1,41 @@ +import { type Ref, defineComponent, inject, ref } from 'vue'; +import { useRoute, useRouter } from 'vue-router'; + +import UserAccountService from './user-account.service'; +import { type IUserAccount } from '@/shared/model/user-account.model'; +import { useAlertService } from '@/shared/alert/alert.service'; + +export default defineComponent({ + compatConfig: { MODE: 3 }, + name: 'UserAccountDetails', + setup() { + const userAccountService = inject('userAccountService', () => new UserAccountService()); + const alertService = inject('alertService', () => useAlertService(), true); + + const route = useRoute(); + const router = useRouter(); + + const previousState = () => router.go(-1); + const userAccount: Ref = ref({}); + + const retrieveUserAccount = async userAccountId => { + try { + const res = await userAccountService().find(userAccountId); + userAccount.value = res; + } catch (error) { + alertService.showHttpError(error.response); + } + }; + + if (route.params?.userAccountId) { + retrieveUserAccount(route.params.userAccountId); + } + + return { + alertService, + userAccount, + + previousState, + }; + }, +}); diff --git a/src/main/webapp/app/entities/user-account/user-account-details.vue b/src/main/webapp/app/entities/user-account/user-account-details.vue new file mode 100644 index 0000000..6e3c0fb --- /dev/null +++ b/src/main/webapp/app/entities/user-account/user-account-details.vue @@ -0,0 +1,41 @@ + + + diff --git a/src/main/webapp/app/entities/user-account/user-account-update.component.spec.ts b/src/main/webapp/app/entities/user-account/user-account-update.component.spec.ts new file mode 100644 index 0000000..56adc17 --- /dev/null +++ b/src/main/webapp/app/entities/user-account/user-account-update.component.spec.ts @@ -0,0 +1,138 @@ +/* tslint:disable max-line-length */ +import { vitest } from 'vitest'; +import { type MountingOptions, shallowMount } from '@vue/test-utils'; +import sinon, { type SinonStubbedInstance } from 'sinon'; +import { type RouteLocation } from 'vue-router'; + +import UserAccountUpdate from './user-account-update.vue'; +import UserAccountService from './user-account.service'; +import AlertService from '@/shared/alert/alert.service'; + +import UserService from '@/entities/user/user.service'; + +type UserAccountUpdateComponentType = InstanceType; + +let route: Partial; +const routerGoMock = vitest.fn(); + +vitest.mock('vue-router', () => ({ + useRoute: () => route, + useRouter: () => ({ go: routerGoMock }), +})); + +const userAccountSample = { id: 123 }; + +describe('Component Tests', () => { + let mountOptions: MountingOptions['global']; + let alertService: AlertService; + + describe('UserAccount Management Update Component', () => { + let comp: UserAccountUpdateComponentType; + let userAccountServiceStub: SinonStubbedInstance; + + beforeEach(() => { + route = {}; + userAccountServiceStub = sinon.createStubInstance(UserAccountService); + userAccountServiceStub.retrieve.onFirstCall().resolves(Promise.resolve([])); + + alertService = new AlertService({ + bvToast: { + toast: vitest.fn(), + } as any, + }); + + mountOptions = { + stubs: { + 'font-awesome-icon': true, + 'b-input-group': true, + 'b-input-group-prepend': true, + 'b-form-datepicker': true, + 'b-form-input': true, + }, + provide: { + alertService, + userAccountService: () => userAccountServiceStub, + + userService: () => + sinon.createStubInstance(UserService, { + retrieve: sinon.stub().resolves({}), + } as any), + }, + }; + }); + + afterEach(() => { + vitest.resetAllMocks(); + }); + + describe('save', () => { + it('Should call update service on save for existing entity', async () => { + // GIVEN + const wrapper = shallowMount(UserAccountUpdate, { global: mountOptions }); + comp = wrapper.vm; + comp.userAccount = userAccountSample; + userAccountServiceStub.update.resolves(userAccountSample); + + // WHEN + comp.save(); + await comp.$nextTick(); + + // THEN + expect(userAccountServiceStub.update.calledWith(userAccountSample)).toBeTruthy(); + expect(comp.isSaving).toEqual(false); + }); + + it('Should call create service on save for new entity', async () => { + // GIVEN + const entity = {}; + userAccountServiceStub.create.resolves(entity); + const wrapper = shallowMount(UserAccountUpdate, { global: mountOptions }); + comp = wrapper.vm; + comp.userAccount = entity; + + // WHEN + comp.save(); + await comp.$nextTick(); + + // THEN + expect(userAccountServiceStub.create.calledWith(entity)).toBeTruthy(); + expect(comp.isSaving).toEqual(false); + }); + }); + + describe('Before route enter', () => { + it('Should retrieve data', async () => { + // GIVEN + userAccountServiceStub.find.resolves(userAccountSample); + userAccountServiceStub.retrieve.resolves([userAccountSample]); + + // WHEN + route = { + params: { + userAccountId: `${userAccountSample.id}`, + }, + }; + const wrapper = shallowMount(UserAccountUpdate, { global: mountOptions }); + comp = wrapper.vm; + await comp.$nextTick(); + + // THEN + expect(comp.userAccount).toMatchObject(userAccountSample); + }); + }); + + describe('Previous state', () => { + it('Should go previous state', async () => { + userAccountServiceStub.find.resolves(userAccountSample); + const wrapper = shallowMount(UserAccountUpdate, { global: mountOptions }); + comp = wrapper.vm; + await comp.$nextTick(); + + comp.previousState(); + await comp.$nextTick(); + + expect(routerGoMock).toHaveBeenCalledWith(-1); + }); + }); + }); +}); diff --git a/src/main/webapp/app/entities/user-account/user-account-update.component.ts b/src/main/webapp/app/entities/user-account/user-account-update.component.ts new file mode 100644 index 0000000..fc7b4c1 --- /dev/null +++ b/src/main/webapp/app/entities/user-account/user-account-update.component.ts @@ -0,0 +1,112 @@ +import { type Ref, computed, defineComponent, inject, ref } from 'vue'; +import { useRoute, useRouter } from 'vue-router'; +import { useVuelidate } from '@vuelidate/core'; + +import UserAccountService from './user-account.service'; +import { useValidation } from '@/shared/composables'; +import { useAlertService } from '@/shared/alert/alert.service'; + +import UserService from '@/entities/user/user.service'; +import { type IUserAccount, UserAccount } from '@/shared/model/user-account.model'; + +export default defineComponent({ + compatConfig: { MODE: 3 }, + name: 'UserAccountUpdate', + setup() { + const userAccountService = inject('userAccountService', () => new UserAccountService()); + const alertService = inject('alertService', () => useAlertService(), true); + + const userAccount: Ref = ref(new UserAccount()); + const userService = inject('userService', () => new UserService()); + const users: Ref> = ref([]); + const isSaving = ref(false); + const currentLanguage = inject('currentLanguage', () => computed(() => navigator.language ?? 'en'), true); + + const route = useRoute(); + const router = useRouter(); + + const previousState = () => router.go(-1); + + const retrieveUserAccount = async userAccountId => { + try { + const res = await userAccountService().find(userAccountId); + userAccount.value = res; + } catch (error) { + alertService.showHttpError(error.response); + } + }; + + if (route.params?.userAccountId) { + retrieveUserAccount(route.params.userAccountId); + } + + const initRelationships = () => { + userService() + .retrieve() + .then(res => { + users.value = res.data; + }); + }; + + initRelationships(); + + const validations = useValidation(); + const validationRules = { + name: {}, + users: {}, + }; + const v$ = useVuelidate(validationRules, userAccount as any); + v$.value.$validate(); + + return { + userAccountService, + alertService, + userAccount, + previousState, + isSaving, + currentLanguage, + users, + v$, + }; + }, + created(): void { + this.userAccount.users = []; + }, + methods: { + save(): void { + this.isSaving = true; + if (this.userAccount.id) { + this.userAccountService() + .update(this.userAccount) + .then(param => { + this.isSaving = false; + this.previousState(); + this.alertService.showInfo(`A UserAccount is updated with identifier ${param.id}`); + }) + .catch(error => { + this.isSaving = false; + this.alertService.showHttpError(error.response); + }); + } else { + this.userAccountService() + .create(this.userAccount) + .then(param => { + this.isSaving = false; + this.previousState(); + this.alertService.showSuccess(`A UserAccount is created with identifier ${param.id}`); + }) + .catch(error => { + this.isSaving = false; + this.alertService.showHttpError(error.response); + }); + } + }, + + getSelected(selectedVals, option, pkField = 'id'): any { + if (selectedVals) { + return selectedVals.find(value => option[pkField] === value[pkField]) ?? option; + } + return option; + }, + }, +}); diff --git a/src/main/webapp/app/entities/user-account/user-account-update.vue b/src/main/webapp/app/entities/user-account/user-account-update.vue new file mode 100644 index 0000000..4b85e59 --- /dev/null +++ b/src/main/webapp/app/entities/user-account/user-account-update.vue @@ -0,0 +1,58 @@ + + diff --git a/src/main/webapp/app/entities/user-account/user-account.component.spec.ts b/src/main/webapp/app/entities/user-account/user-account.component.spec.ts new file mode 100644 index 0000000..8dd5bfa --- /dev/null +++ b/src/main/webapp/app/entities/user-account/user-account.component.spec.ts @@ -0,0 +1,100 @@ +/* tslint:disable max-line-length */ +import { vitest } from 'vitest'; +import { type MountingOptions, shallowMount } from '@vue/test-utils'; +import sinon, { type SinonStubbedInstance } from 'sinon'; + +import UserAccount from './user-account.vue'; +import UserAccountService from './user-account.service'; +import AlertService from '@/shared/alert/alert.service'; + +type UserAccountComponentType = InstanceType; + +const bModalStub = { + render: () => {}, + methods: { + hide: () => {}, + show: () => {}, + }, +}; + +describe('Component Tests', () => { + let alertService: AlertService; + + describe('UserAccount Management Component', () => { + let userAccountServiceStub: SinonStubbedInstance; + let mountOptions: MountingOptions['global']; + + beforeEach(() => { + userAccountServiceStub = sinon.createStubInstance(UserAccountService); + userAccountServiceStub.retrieve.resolves({ headers: {} }); + + alertService = new AlertService({ + bvToast: { + toast: vitest.fn(), + } as any, + }); + + mountOptions = { + stubs: { + bModal: bModalStub as any, + 'font-awesome-icon': true, + 'b-badge': true, + 'b-button': true, + 'router-link': true, + }, + directives: { + 'b-modal': {}, + }, + provide: { + alertService, + userAccountService: () => userAccountServiceStub, + }, + }; + }); + + describe('Mount', () => { + it('Should call load all on init', async () => { + // GIVEN + userAccountServiceStub.retrieve.resolves({ headers: {}, data: [{ id: 123 }] }); + + // WHEN + const wrapper = shallowMount(UserAccount, { global: mountOptions }); + const comp = wrapper.vm; + await comp.$nextTick(); + + // THEN + expect(userAccountServiceStub.retrieve.calledOnce).toBeTruthy(); + expect(comp.userAccounts[0]).toEqual(expect.objectContaining({ id: 123 })); + }); + }); + describe('Handles', () => { + let comp: UserAccountComponentType; + + beforeEach(async () => { + const wrapper = shallowMount(UserAccount, { global: mountOptions }); + comp = wrapper.vm; + await comp.$nextTick(); + userAccountServiceStub.retrieve.reset(); + userAccountServiceStub.retrieve.resolves({ headers: {}, data: [] }); + }); + + it('Should call delete service on confirmDelete', async () => { + // GIVEN + userAccountServiceStub.delete.resolves({}); + + // WHEN + comp.prepareRemove({ id: 123 }); + + comp.removeUserAccount(); + await comp.$nextTick(); // clear components + + // THEN + expect(userAccountServiceStub.delete.called).toBeTruthy(); + + // THEN + await comp.$nextTick(); // handle component clear watch + expect(userAccountServiceStub.retrieve.callCount).toEqual(1); + }); + }); + }); +}); diff --git a/src/main/webapp/app/entities/user-account/user-account.component.ts b/src/main/webapp/app/entities/user-account/user-account.component.ts new file mode 100644 index 0000000..b49e578 --- /dev/null +++ b/src/main/webapp/app/entities/user-account/user-account.component.ts @@ -0,0 +1,75 @@ +import { type Ref, defineComponent, inject, onMounted, ref } from 'vue'; + +import UserAccountService from './user-account.service'; +import { type IUserAccount } from '@/shared/model/user-account.model'; +import { useAlertService } from '@/shared/alert/alert.service'; + +export default defineComponent({ + compatConfig: { MODE: 3 }, + name: 'UserAccount', + setup() { + const userAccountService = inject('userAccountService', () => new UserAccountService()); + const alertService = inject('alertService', () => useAlertService(), true); + + const userAccounts: Ref = ref([]); + + const isFetching = ref(false); + + const clear = () => {}; + + const retrieveUserAccounts = async () => { + isFetching.value = true; + try { + const res = await userAccountService().retrieve(); + userAccounts.value = res.data; + } catch (err) { + alertService.showHttpError(err.response); + } finally { + isFetching.value = false; + } + }; + + const handleSyncList = () => { + retrieveUserAccounts(); + }; + + onMounted(async () => { + await retrieveUserAccounts(); + }); + + const removeId: Ref = ref(null); + const removeEntity = ref(null); + const prepareRemove = (instance: IUserAccount) => { + removeId.value = instance.id; + removeEntity.value.show(); + }; + const closeDialog = () => { + removeEntity.value.hide(); + }; + const removeUserAccount = async () => { + try { + await userAccountService().delete(removeId.value); + const message = `A UserAccount is deleted with identifier ${removeId.value}`; + alertService.showInfo(message, { variant: 'danger' }); + removeId.value = null; + retrieveUserAccounts(); + closeDialog(); + } catch (error) { + alertService.showHttpError(error.response); + } + }; + + return { + userAccounts, + handleSyncList, + isFetching, + retrieveUserAccounts, + clear, + removeId, + removeEntity, + prepareRemove, + closeDialog, + removeUserAccount, + }; + }, +}); diff --git a/src/main/webapp/app/entities/user-account/user-account.service.spec.ts b/src/main/webapp/app/entities/user-account/user-account.service.spec.ts new file mode 100644 index 0000000..900d8ef --- /dev/null +++ b/src/main/webapp/app/entities/user-account/user-account.service.spec.ts @@ -0,0 +1,160 @@ +/* tslint:disable max-line-length */ +import axios from 'axios'; +import sinon from 'sinon'; + +import UserAccountService from './user-account.service'; +import { UserAccount } from '@/shared/model/user-account.model'; + +const error = { + response: { + status: null, + data: { + type: null, + }, + }, +}; + +const axiosStub = { + get: sinon.stub(axios, 'get'), + post: sinon.stub(axios, 'post'), + put: sinon.stub(axios, 'put'), + patch: sinon.stub(axios, 'patch'), + delete: sinon.stub(axios, 'delete'), +}; + +describe('Service Tests', () => { + describe('UserAccount Service', () => { + let service: UserAccountService; + let elemDefault; + + beforeEach(() => { + service = new UserAccountService(); + elemDefault = new UserAccount(123, 'AAAAAAA'); + }); + + describe('Service methods', () => { + it('should find an element', async () => { + const returnedFromService = { ...elemDefault }; + axiosStub.get.resolves({ data: returnedFromService }); + + return service.find(123).then(res => { + expect(res).toMatchObject(elemDefault); + }); + }); + + it('should not find an element', async () => { + axiosStub.get.rejects(error); + return service + .find(123) + .then() + .catch(err => { + expect(err).toMatchObject(error); + }); + }); + + it('should create a UserAccount', async () => { + const returnedFromService = { id: 123, ...elemDefault }; + const expected = { ...returnedFromService }; + + axiosStub.post.resolves({ data: returnedFromService }); + return service.create({}).then(res => { + expect(res).toMatchObject(expected); + }); + }); + + it('should not create a UserAccount', async () => { + axiosStub.post.rejects(error); + + return service + .create({}) + .then() + .catch(err => { + expect(err).toMatchObject(error); + }); + }); + + it('should update a UserAccount', async () => { + const returnedFromService = { name: 'BBBBBB', ...elemDefault }; + + const expected = { ...returnedFromService }; + axiosStub.put.resolves({ data: returnedFromService }); + + return service.update(expected).then(res => { + expect(res).toMatchObject(expected); + }); + }); + + it('should not update a UserAccount', async () => { + axiosStub.put.rejects(error); + + return service + .update({}) + .then() + .catch(err => { + expect(err).toMatchObject(error); + }); + }); + + it('should partial update a UserAccount', async () => { + const patchObject = { name: 'BBBBBB', ...new UserAccount() }; + const returnedFromService = Object.assign(patchObject, elemDefault); + + const expected = { ...returnedFromService }; + axiosStub.patch.resolves({ data: returnedFromService }); + + return service.partialUpdate(patchObject).then(res => { + expect(res).toMatchObject(expected); + }); + }); + + it('should not partial update a UserAccount', async () => { + axiosStub.patch.rejects(error); + + return service + .partialUpdate({}) + .then() + .catch(err => { + expect(err).toMatchObject(error); + }); + }); + + it('should return a list of UserAccount', async () => { + const returnedFromService = { name: 'BBBBBB', ...elemDefault }; + const expected = { ...returnedFromService }; + axiosStub.get.resolves([returnedFromService]); + return service.retrieve().then(res => { + expect(res).toContainEqual(expected); + }); + }); + + it('should not return a list of UserAccount', async () => { + axiosStub.get.rejects(error); + + return service + .retrieve() + .then() + .catch(err => { + expect(err).toMatchObject(error); + }); + }); + + it('should delete a UserAccount', async () => { + axiosStub.delete.resolves({ ok: true }); + return service.delete(123).then(res => { + expect(res.ok).toBeTruthy(); + }); + }); + + it('should not delete a UserAccount', async () => { + axiosStub.delete.rejects(error); + + return service + .delete(123) + .then() + .catch(err => { + expect(err).toMatchObject(error); + }); + }); + }); + }); +}); diff --git a/src/main/webapp/app/entities/user-account/user-account.service.ts b/src/main/webapp/app/entities/user-account/user-account.service.ts new file mode 100644 index 0000000..5b8ffbd --- /dev/null +++ b/src/main/webapp/app/entities/user-account/user-account.service.ts @@ -0,0 +1,85 @@ +import axios from 'axios'; + +import { type IUserAccount } from '@/shared/model/user-account.model'; + +const baseApiUrl = 'api/user-accounts'; + +export default class UserAccountService { + public find(id: number): Promise { + return new Promise((resolve, reject) => { + axios + .get(`${baseApiUrl}/${id}`) + .then(res => { + resolve(res.data); + }) + .catch(err => { + reject(err); + }); + }); + } + + public retrieve(): Promise { + return new Promise((resolve, reject) => { + axios + .get(baseApiUrl) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + + public delete(id: number): Promise { + return new Promise((resolve, reject) => { + axios + .delete(`${baseApiUrl}/${id}`) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + + public create(entity: IUserAccount): Promise { + return new Promise((resolve, reject) => { + axios + .post(`${baseApiUrl}`, entity) + .then(res => { + resolve(res.data); + }) + .catch(err => { + reject(err); + }); + }); + } + + public update(entity: IUserAccount): Promise { + return new Promise((resolve, reject) => { + axios + .put(`${baseApiUrl}/${entity.id}`, entity) + .then(res => { + resolve(res.data); + }) + .catch(err => { + reject(err); + }); + }); + } + + public partialUpdate(entity: IUserAccount): Promise { + return new Promise((resolve, reject) => { + axios + .patch(`${baseApiUrl}/${entity.id}`, entity) + .then(res => { + resolve(res.data); + }) + .catch(err => { + reject(err); + }); + }); + } +} diff --git a/src/main/webapp/app/entities/user-account/user-account.vue b/src/main/webapp/app/entities/user-account/user-account.vue new file mode 100644 index 0000000..56191c0 --- /dev/null +++ b/src/main/webapp/app/entities/user-account/user-account.vue @@ -0,0 +1,103 @@ + + + diff --git a/src/main/webapp/app/router/entities.ts b/src/main/webapp/app/router/entities.ts index 3c05bfd..5695e01 100644 --- a/src/main/webapp/app/router/entities.ts +++ b/src/main/webapp/app/router/entities.ts @@ -19,6 +19,10 @@ const Transaction = () => import('@/entities/transaction/transaction.vue'); const TransactionUpdate = () => import('@/entities/transaction/transaction-update.vue'); const TransactionDetails = () => import('@/entities/transaction/transaction-details.vue'); +const UserAccount = () => import('@/entities/user-account/user-account.vue'); +const UserAccountUpdate = () => import('@/entities/user-account/user-account-update.vue'); +const UserAccountDetails = () => import('@/entities/user-account/user-account-details.vue'); + // jhipster-needle-add-entity-to-router-import - JHipster will import entities to the router here export default { @@ -121,6 +125,30 @@ export default { component: TransactionDetails, meta: { authorities: [Authority.USER] }, }, + { + path: 'user-account', + name: 'UserAccount', + component: UserAccount, + meta: { authorities: [Authority.USER] }, + }, + { + path: 'user-account/new', + name: 'UserAccountCreate', + component: UserAccountUpdate, + meta: { authorities: [Authority.USER] }, + }, + { + path: 'user-account/:userAccountId/edit', + name: 'UserAccountEdit', + component: UserAccountUpdate, + meta: { authorities: [Authority.USER] }, + }, + { + path: 'user-account/:userAccountId/view', + name: 'UserAccountView', + component: UserAccountDetails, + meta: { authorities: [Authority.USER] }, + }, // jhipster-needle-add-entity-to-router - JHipster will add entities to the router here ], }; diff --git a/src/main/webapp/app/shared/model/user-account.model.ts b/src/main/webapp/app/shared/model/user-account.model.ts new file mode 100644 index 0000000..330fffe --- /dev/null +++ b/src/main/webapp/app/shared/model/user-account.model.ts @@ -0,0 +1,15 @@ +import { type IUser } from '@/shared/model/user.model'; + +export interface IUserAccount { + id?: number; + name?: string | null; + users?: IUser[] | null; +} + +export class UserAccount implements IUserAccount { + constructor( + public id?: number, + public name?: string | null, + public users?: IUser[] | null, + ) {} +} diff --git a/src/test/java/com/sasiedzi/event/domain/UserAccountAsserts.java b/src/test/java/com/sasiedzi/event/domain/UserAccountAsserts.java new file mode 100644 index 0000000..039839c --- /dev/null +++ b/src/test/java/com/sasiedzi/event/domain/UserAccountAsserts.java @@ -0,0 +1,62 @@ +package com.sasiedzi.event.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +public class UserAccountAsserts { + + /** + * Asserts that the entity has all properties (fields/relationships) set. + * + * @param expected the expected entity + * @param actual the actual entity + */ + public static void assertUserAccountAllPropertiesEquals(UserAccount expected, UserAccount actual) { + assertUserAccountAutoGeneratedPropertiesEquals(expected, actual); + assertUserAccountAllUpdatablePropertiesEquals(expected, actual); + } + + /** + * Asserts that the entity has all updatable properties (fields/relationships) set. + * + * @param expected the expected entity + * @param actual the actual entity + */ + public static void assertUserAccountAllUpdatablePropertiesEquals(UserAccount expected, UserAccount actual) { + assertUserAccountUpdatableFieldsEquals(expected, actual); + assertUserAccountUpdatableRelationshipsEquals(expected, actual); + } + + /** + * Asserts that the entity has all the auto generated properties (fields/relationships) set. + * + * @param expected the expected entity + * @param actual the actual entity + */ + public static void assertUserAccountAutoGeneratedPropertiesEquals(UserAccount expected, UserAccount actual) { + assertThat(expected) + .as("Verify UserAccount auto generated properties") + .satisfies(e -> assertThat(e.getId()).as("check id").isEqualTo(actual.getId())); + } + + /** + * Asserts that the entity has all the updatable fields set. + * + * @param expected the expected entity + * @param actual the actual entity + */ + public static void assertUserAccountUpdatableFieldsEquals(UserAccount expected, UserAccount actual) { + assertThat(expected) + .as("Verify UserAccount relevant properties") + .satisfies(e -> assertThat(e.getName()).as("check name").isEqualTo(actual.getName())); + } + + /** + * Asserts that the entity has all the updatable relationships set. + * + * @param expected the expected entity + * @param actual the actual entity + */ + public static void assertUserAccountUpdatableRelationshipsEquals(UserAccount expected, UserAccount actual) { + // empty method + } +} diff --git a/src/test/java/com/sasiedzi/event/domain/UserAccountTest.java b/src/test/java/com/sasiedzi/event/domain/UserAccountTest.java new file mode 100644 index 0000000..1201790 --- /dev/null +++ b/src/test/java/com/sasiedzi/event/domain/UserAccountTest.java @@ -0,0 +1,24 @@ +package com.sasiedzi.event.domain; + +import static com.sasiedzi.event.domain.UserAccountTestSamples.*; +import static org.assertj.core.api.Assertions.assertThat; + +import com.sasiedzi.event.web.rest.TestUtil; +import org.junit.jupiter.api.Test; + +class UserAccountTest { + + @Test + void equalsVerifier() throws Exception { + TestUtil.equalsVerifier(UserAccount.class); + UserAccount userAccount1 = getUserAccountSample1(); + UserAccount userAccount2 = new UserAccount(); + assertThat(userAccount1).isNotEqualTo(userAccount2); + + userAccount2.setId(userAccount1.getId()); + assertThat(userAccount1).isEqualTo(userAccount2); + + userAccount2 = getUserAccountSample2(); + assertThat(userAccount1).isNotEqualTo(userAccount2); + } +} diff --git a/src/test/java/com/sasiedzi/event/domain/UserAccountTestSamples.java b/src/test/java/com/sasiedzi/event/domain/UserAccountTestSamples.java new file mode 100644 index 0000000..73a0e03 --- /dev/null +++ b/src/test/java/com/sasiedzi/event/domain/UserAccountTestSamples.java @@ -0,0 +1,23 @@ +package com.sasiedzi.event.domain; + +import java.util.Random; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicLong; + +public class UserAccountTestSamples { + + private static final Random random = new Random(); + private static final AtomicLong longCount = new AtomicLong(random.nextInt() + (2 * Integer.MAX_VALUE)); + + public static UserAccount getUserAccountSample1() { + return new UserAccount().id(1L).name("name1"); + } + + public static UserAccount getUserAccountSample2() { + return new UserAccount().id(2L).name("name2"); + } + + public static UserAccount getUserAccountRandomSampleGenerator() { + return new UserAccount().id(longCount.incrementAndGet()).name(UUID.randomUUID().toString()); + } +} diff --git a/src/test/java/com/sasiedzi/event/web/rest/ChargeResourceIT.java b/src/test/java/com/sasiedzi/event/web/rest/ChargeResourceIT.java index 9553082..7120c4b 100644 --- a/src/test/java/com/sasiedzi/event/web/rest/ChargeResourceIT.java +++ b/src/test/java/com/sasiedzi/event/web/rest/ChargeResourceIT.java @@ -358,8 +358,6 @@ class ChargeResourceIT { Charge partialUpdatedCharge = new Charge(); partialUpdatedCharge.setId(charge.getId()); - partialUpdatedCharge.amount(UPDATED_AMOUNT); - restChargeMockMvc .perform( patch(ENTITY_API_URL_ID, partialUpdatedCharge.getId()) diff --git a/src/test/java/com/sasiedzi/event/web/rest/EventResourceIT.java b/src/test/java/com/sasiedzi/event/web/rest/EventResourceIT.java index 79713e2..a93cf4f 100644 --- a/src/test/java/com/sasiedzi/event/web/rest/EventResourceIT.java +++ b/src/test/java/com/sasiedzi/event/web/rest/EventResourceIT.java @@ -328,6 +328,8 @@ class EventResourceIT { Event partialUpdatedEvent = new Event(); partialUpdatedEvent.setId(event.getId()); + partialUpdatedEvent.playersLimit(UPDATED_PLAYERS_LIMIT).cost(UPDATED_COST).comment(UPDATED_COMMENT); + restEventMockMvc .perform( patch(ENTITY_API_URL_ID, partialUpdatedEvent.getId()) diff --git a/src/test/java/com/sasiedzi/event/web/rest/UserAccountResourceIT.java b/src/test/java/com/sasiedzi/event/web/rest/UserAccountResourceIT.java new file mode 100644 index 0000000..e02d354 --- /dev/null +++ b/src/test/java/com/sasiedzi/event/web/rest/UserAccountResourceIT.java @@ -0,0 +1,450 @@ +package com.sasiedzi.event.web.rest; + +import static com.sasiedzi.event.domain.UserAccountAsserts.*; +import static com.sasiedzi.event.web.rest.TestUtil.createUpdateProxyForBean; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.mockito.Mockito.*; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.sasiedzi.event.IntegrationTest; +import com.sasiedzi.event.domain.UserAccount; +import com.sasiedzi.event.repository.UserAccountRepository; +import com.sasiedzi.event.repository.UserRepository; +import jakarta.persistence.EntityManager; +import java.util.ArrayList; +import java.util.Random; +import java.util.concurrent.atomic.AtomicLong; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +/** + * Integration tests for the {@link UserAccountResource} REST controller. + */ +@IntegrationTest +@ExtendWith(MockitoExtension.class) +@AutoConfigureMockMvc +@WithMockUser +class UserAccountResourceIT { + + private static final String DEFAULT_NAME = "AAAAAAAAAA"; + private static final String UPDATED_NAME = "BBBBBBBBBB"; + + private static final String ENTITY_API_URL = "/api/user-accounts"; + private static final String ENTITY_API_URL_ID = ENTITY_API_URL + "/{id}"; + + private static Random random = new Random(); + private static AtomicLong longCount = new AtomicLong(random.nextInt() + (2 * Integer.MAX_VALUE)); + + @Autowired + private ObjectMapper om; + + @Autowired + private UserAccountRepository userAccountRepository; + + @Autowired + private UserRepository userRepository; + + @Mock + private UserAccountRepository userAccountRepositoryMock; + + @Autowired + private EntityManager em; + + @Autowired + private MockMvc restUserAccountMockMvc; + + private UserAccount userAccount; + + private UserAccount insertedUserAccount; + + /** + * Create an entity for this test. + * + * This is a static method, as tests for other entities might also need it, + * if they test an entity which requires the current entity. + */ + public static UserAccount createEntity() { + return new UserAccount().name(DEFAULT_NAME); + } + + /** + * Create an updated entity for this test. + * + * This is a static method, as tests for other entities might also need it, + * if they test an entity which requires the current entity. + */ + public static UserAccount createUpdatedEntity() { + return new UserAccount().name(UPDATED_NAME); + } + + @BeforeEach + public void initTest() { + userAccount = createEntity(); + } + + @AfterEach + public void cleanup() { + if (insertedUserAccount != null) { + userAccountRepository.delete(insertedUserAccount); + insertedUserAccount = null; + } + userRepository.deleteAll(); + } + + @Test + @Transactional + void createUserAccount() throws Exception { + long databaseSizeBeforeCreate = getRepositoryCount(); + // Create the UserAccount + var returnedUserAccount = om.readValue( + restUserAccountMockMvc + .perform( + post(ENTITY_API_URL).with(csrf()).contentType(MediaType.APPLICATION_JSON).content(om.writeValueAsBytes(userAccount)) + ) + .andExpect(status().isCreated()) + .andReturn() + .getResponse() + .getContentAsString(), + UserAccount.class + ); + + // Validate the UserAccount in the database + assertIncrementedRepositoryCount(databaseSizeBeforeCreate); + assertUserAccountUpdatableFieldsEquals(returnedUserAccount, getPersistedUserAccount(returnedUserAccount)); + + insertedUserAccount = returnedUserAccount; + } + + @Test + @Transactional + void createUserAccountWithExistingId() throws Exception { + // Create the UserAccount with an existing ID + userAccount.setId(1L); + + long databaseSizeBeforeCreate = getRepositoryCount(); + + // An entity with an existing ID cannot be created, so this API call must fail + restUserAccountMockMvc + .perform(post(ENTITY_API_URL).with(csrf()).contentType(MediaType.APPLICATION_JSON).content(om.writeValueAsBytes(userAccount))) + .andExpect(status().isBadRequest()); + + // Validate the UserAccount in the database + assertSameRepositoryCount(databaseSizeBeforeCreate); + } + + @Test + @Transactional + void getAllUserAccounts() throws Exception { + // Initialize the database + insertedUserAccount = userAccountRepository.saveAndFlush(userAccount); + + // Get all the userAccountList + restUserAccountMockMvc + .perform(get(ENTITY_API_URL + "?sort=id,desc")) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.[*].id").value(hasItem(userAccount.getId().intValue()))) + .andExpect(jsonPath("$.[*].name").value(hasItem(DEFAULT_NAME))); + } + + @SuppressWarnings({ "unchecked" }) + void getAllUserAccountsWithEagerRelationshipsIsEnabled() throws Exception { + when(userAccountRepositoryMock.findAllWithEagerRelationships(any())).thenReturn(new PageImpl(new ArrayList<>())); + + restUserAccountMockMvc.perform(get(ENTITY_API_URL + "?eagerload=true")).andExpect(status().isOk()); + + verify(userAccountRepositoryMock, times(1)).findAllWithEagerRelationships(any()); + } + + @SuppressWarnings({ "unchecked" }) + void getAllUserAccountsWithEagerRelationshipsIsNotEnabled() throws Exception { + when(userAccountRepositoryMock.findAllWithEagerRelationships(any())).thenReturn(new PageImpl(new ArrayList<>())); + + restUserAccountMockMvc.perform(get(ENTITY_API_URL + "?eagerload=false")).andExpect(status().isOk()); + verify(userAccountRepositoryMock, times(1)).findAll(any(Pageable.class)); + } + + @Test + @Transactional + void getUserAccount() throws Exception { + // Initialize the database + insertedUserAccount = userAccountRepository.saveAndFlush(userAccount); + + // Get the userAccount + restUserAccountMockMvc + .perform(get(ENTITY_API_URL_ID, userAccount.getId())) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.id").value(userAccount.getId().intValue())) + .andExpect(jsonPath("$.name").value(DEFAULT_NAME)); + } + + @Test + @Transactional + void getNonExistingUserAccount() throws Exception { + // Get the userAccount + restUserAccountMockMvc.perform(get(ENTITY_API_URL_ID, Long.MAX_VALUE)).andExpect(status().isNotFound()); + } + + @Test + @Transactional + void putExistingUserAccount() throws Exception { + // Initialize the database + insertedUserAccount = userAccountRepository.saveAndFlush(userAccount); + + long databaseSizeBeforeUpdate = getRepositoryCount(); + + // Update the userAccount + UserAccount updatedUserAccount = userAccountRepository.findById(userAccount.getId()).orElseThrow(); + // Disconnect from session so that the updates on updatedUserAccount are not directly saved in db + em.detach(updatedUserAccount); + updatedUserAccount.name(UPDATED_NAME); + + restUserAccountMockMvc + .perform( + put(ENTITY_API_URL_ID, updatedUserAccount.getId()) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(om.writeValueAsBytes(updatedUserAccount)) + ) + .andExpect(status().isOk()); + + // Validate the UserAccount in the database + assertSameRepositoryCount(databaseSizeBeforeUpdate); + assertPersistedUserAccountToMatchAllProperties(updatedUserAccount); + } + + @Test + @Transactional + void putNonExistingUserAccount() throws Exception { + long databaseSizeBeforeUpdate = getRepositoryCount(); + userAccount.setId(longCount.incrementAndGet()); + + // If the entity doesn't have an ID, it will throw BadRequestAlertException + restUserAccountMockMvc + .perform( + put(ENTITY_API_URL_ID, userAccount.getId()) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(om.writeValueAsBytes(userAccount)) + ) + .andExpect(status().isBadRequest()); + + // Validate the UserAccount in the database + assertSameRepositoryCount(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void putWithIdMismatchUserAccount() throws Exception { + long databaseSizeBeforeUpdate = getRepositoryCount(); + userAccount.setId(longCount.incrementAndGet()); + + // If url ID doesn't match entity ID, it will throw BadRequestAlertException + restUserAccountMockMvc + .perform( + put(ENTITY_API_URL_ID, longCount.incrementAndGet()) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(om.writeValueAsBytes(userAccount)) + ) + .andExpect(status().isBadRequest()); + + // Validate the UserAccount in the database + assertSameRepositoryCount(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void putWithMissingIdPathParamUserAccount() throws Exception { + long databaseSizeBeforeUpdate = getRepositoryCount(); + userAccount.setId(longCount.incrementAndGet()); + + // If url ID doesn't match entity ID, it will throw BadRequestAlertException + restUserAccountMockMvc + .perform(put(ENTITY_API_URL).with(csrf()).contentType(MediaType.APPLICATION_JSON).content(om.writeValueAsBytes(userAccount))) + .andExpect(status().isMethodNotAllowed()); + + // Validate the UserAccount in the database + assertSameRepositoryCount(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void partialUpdateUserAccountWithPatch() throws Exception { + // Initialize the database + insertedUserAccount = userAccountRepository.saveAndFlush(userAccount); + + long databaseSizeBeforeUpdate = getRepositoryCount(); + + // Update the userAccount using partial update + UserAccount partialUpdatedUserAccount = new UserAccount(); + partialUpdatedUserAccount.setId(userAccount.getId()); + + partialUpdatedUserAccount.name(UPDATED_NAME); + + restUserAccountMockMvc + .perform( + patch(ENTITY_API_URL_ID, partialUpdatedUserAccount.getId()) + .with(csrf()) + .contentType("application/merge-patch+json") + .content(om.writeValueAsBytes(partialUpdatedUserAccount)) + ) + .andExpect(status().isOk()); + + // Validate the UserAccount in the database + + assertSameRepositoryCount(databaseSizeBeforeUpdate); + assertUserAccountUpdatableFieldsEquals( + createUpdateProxyForBean(partialUpdatedUserAccount, userAccount), + getPersistedUserAccount(userAccount) + ); + } + + @Test + @Transactional + void fullUpdateUserAccountWithPatch() throws Exception { + // Initialize the database + insertedUserAccount = userAccountRepository.saveAndFlush(userAccount); + + long databaseSizeBeforeUpdate = getRepositoryCount(); + + // Update the userAccount using partial update + UserAccount partialUpdatedUserAccount = new UserAccount(); + partialUpdatedUserAccount.setId(userAccount.getId()); + + partialUpdatedUserAccount.name(UPDATED_NAME); + + restUserAccountMockMvc + .perform( + patch(ENTITY_API_URL_ID, partialUpdatedUserAccount.getId()) + .with(csrf()) + .contentType("application/merge-patch+json") + .content(om.writeValueAsBytes(partialUpdatedUserAccount)) + ) + .andExpect(status().isOk()); + + // Validate the UserAccount in the database + + assertSameRepositoryCount(databaseSizeBeforeUpdate); + assertUserAccountUpdatableFieldsEquals(partialUpdatedUserAccount, getPersistedUserAccount(partialUpdatedUserAccount)); + } + + @Test + @Transactional + void patchNonExistingUserAccount() throws Exception { + long databaseSizeBeforeUpdate = getRepositoryCount(); + userAccount.setId(longCount.incrementAndGet()); + + // If the entity doesn't have an ID, it will throw BadRequestAlertException + restUserAccountMockMvc + .perform( + patch(ENTITY_API_URL_ID, userAccount.getId()) + .with(csrf()) + .contentType("application/merge-patch+json") + .content(om.writeValueAsBytes(userAccount)) + ) + .andExpect(status().isBadRequest()); + + // Validate the UserAccount in the database + assertSameRepositoryCount(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void patchWithIdMismatchUserAccount() throws Exception { + long databaseSizeBeforeUpdate = getRepositoryCount(); + userAccount.setId(longCount.incrementAndGet()); + + // If url ID doesn't match entity ID, it will throw BadRequestAlertException + restUserAccountMockMvc + .perform( + patch(ENTITY_API_URL_ID, longCount.incrementAndGet()) + .with(csrf()) + .contentType("application/merge-patch+json") + .content(om.writeValueAsBytes(userAccount)) + ) + .andExpect(status().isBadRequest()); + + // Validate the UserAccount in the database + assertSameRepositoryCount(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void patchWithMissingIdPathParamUserAccount() throws Exception { + long databaseSizeBeforeUpdate = getRepositoryCount(); + userAccount.setId(longCount.incrementAndGet()); + + // If url ID doesn't match entity ID, it will throw BadRequestAlertException + restUserAccountMockMvc + .perform( + patch(ENTITY_API_URL).with(csrf()).contentType("application/merge-patch+json").content(om.writeValueAsBytes(userAccount)) + ) + .andExpect(status().isMethodNotAllowed()); + + // Validate the UserAccount in the database + assertSameRepositoryCount(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void deleteUserAccount() throws Exception { + // Initialize the database + insertedUserAccount = userAccountRepository.saveAndFlush(userAccount); + + long databaseSizeBeforeDelete = getRepositoryCount(); + + // Delete the userAccount + restUserAccountMockMvc + .perform(delete(ENTITY_API_URL_ID, userAccount.getId()).with(csrf()).accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isNoContent()); + + // Validate the database contains one less item + assertDecrementedRepositoryCount(databaseSizeBeforeDelete); + } + + protected long getRepositoryCount() { + return userAccountRepository.count(); + } + + protected void assertIncrementedRepositoryCount(long countBefore) { + assertThat(countBefore + 1).isEqualTo(getRepositoryCount()); + } + + protected void assertDecrementedRepositoryCount(long countBefore) { + assertThat(countBefore - 1).isEqualTo(getRepositoryCount()); + } + + protected void assertSameRepositoryCount(long countBefore) { + assertThat(countBefore).isEqualTo(getRepositoryCount()); + } + + protected UserAccount getPersistedUserAccount(UserAccount userAccount) { + return userAccountRepository.findById(userAccount.getId()).orElseThrow(); + } + + protected void assertPersistedUserAccountToMatchAllProperties(UserAccount expectedUserAccount) { + assertUserAccountAllPropertiesEquals(expectedUserAccount, getPersistedUserAccount(expectedUserAccount)); + } + + protected void assertPersistedUserAccountToMatchUpdatableProperties(UserAccount expectedUserAccount) { + assertUserAccountAllUpdatablePropertiesEquals(expectedUserAccount, getPersistedUserAccount(expectedUserAccount)); + } +}