diff --git a/README.md b/README.md index 2df2c0e..5a465b0 100644 --- a/README.md +++ b/README.md @@ -27,13 +27,14 @@ ## Запуск 1. Скомпилировать проект (включить Annotation Processor для Lombok и поставить Lombok Plugin для IDEA) -2. Запустить из IDE или с помощью java -jar app.jar +2. Запустить из IDE через MobileServicesApplication#main или после сборки из target с помощью java -jar mobile-services-1.0.jar ## Использование 1. WebUI для встроенной базы данных: http://localhost:8080/h2-console/ -1.1 JDBC Url: jdbc:h2:mem:test -1.2. User: sa -1.3. Password: +JDBC Url: jdbc:h2:mem:test +User: sa +Password: + 2. API доступно на порту 8080 | Метод | Тело запроса | Адрес | Описание | @@ -42,12 +43,19 @@ | GET | пусто |`localhost:8080/api/v1/sim-card/${номер_телефона}/status` | Статус сим-карты | | PUT | {"value": } |`localhost:8080/api/v1/sim-card/${номер_телефона}/status` | Обновить статус сим-карты | | GET | пусто |`localhost:8080/api/v1/sim-card/${номер_телефона}/minutes/total` | Количество активных минут | +| GET | пусто |`localhost:8080/api/v1/sim-card/${номер_телефона}/traffic/total` | Количество активных гигабайт | | GET | пусто |`localhost:8080/api/v1/sim-card/${номер_телефона}/minutes/packages`| Количество активных пакетов минут | -| POST |{"basePackageId": "","addition": <Количество минут>,"daysToLive": "<Время жизни (дней)>"}|`localhost:8080/api/v1/sim-card/${номер_телефона}/minutes` | Добавить пакет минут к сим-карте | +| GET | пусто |`localhost:8080/api/v1/sim-card/${номер_телефона}/traffic/packages`| Количество активных пакетов гигабайт | +| POST |{"basePackageId": "","addition": <Количество минут>,"daysToLive": "<Время жизни (дней)>"}|`localhost:8080/api/v1/sim-card/${номер_телефона}/minutes` | Добавить пакет минут к сим-карте | +| POST |{"basePackageId": "","addition": <Количество гигабайт>,"daysToLive": "<Время жизни (дней)>"}|`localhost:8080/api/v1/sim-card/${номер_телефона}/traffic` | Добавить пакет гигабайт к сим-карте | | GET | пусто |`localhost:8080/api/v1/packages-of-minutes/${id_пакета}` | Получить базовый пакет минут (обьект) | -| GET | пусто |`localhost:8080/api/v1/packages-of-minutes/` | Получить все базовые пакеты минут (обьект) | +| GET | пусто |`localhost:8080/api/v1/traffic-packages/${id_пакета}` | Получить базовый пакет траффика (обьект) | +| GET | пусто |`localhost:8080/api/v1/packages-of-minutes/` | Получить все базовые пакеты минут (список) | +| GET | пусто |`localhost:8080/api/v1/traffic-packages/` | Получить все базовые пакеты траффика (список) | | POST |{"name":"<имя_пакета>","type":""} | `localhost:8080/api/v1/packages-of-minutes/` | Сохранить в базу базовый пакет минут | -| PUT |{"value": <количество минут (отр или пол)>} |`localhost:8080/api/v1/packages-of-minutes/details/${details_id}` | Сохранить в базу базовый пакет минут | +| POST |{"name":"<имя_пакета>","type":""} | `localhost:8080/api/v1/traffic-packages/` | Сохранить в базу базовый пакет траффика | +| PUT |{"value": <количество минут (отр или пол)>} |`localhost:8080/api/v1/packages-of-minutes/details/${details_id}` | Расходовать или добавлять минуты в пакет минут | +| PUT |{"value": <количество гигабайт (отр или пол)>} |`localhost:8080/api/v1/traffic-packages/details/${details_id}` | Расходовать или добавлять гигабайты в пакет траффика | ## Контакты muchnik.ak@gmail.com \ No newline at end of file diff --git a/src/main/java/ru/muchnik/yota/mobileservices/MobileServicesApplication.java b/src/main/java/ru/muchnik/yota/mobileservices/MobileServicesApplication.java index 9c6f32a..394df08 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/MobileServicesApplication.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/MobileServicesApplication.java @@ -4,19 +4,22 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; -import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesPackageCatalog; -import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesDetails; import ru.muchnik.yota.mobileservices.model.entity.SimCard; +import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesDetails; +import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesPackageCatalog; import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficDetails; import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficPackageCatalog; -import ru.muchnik.yota.mobileservices.repository.minutes.MinutesPackageCatalogRepository; import ru.muchnik.yota.mobileservices.repository.SimCardRepository; +import ru.muchnik.yota.mobileservices.repository.minutes.MinutesPackageCatalogRepository; import ru.muchnik.yota.mobileservices.repository.traffic.TrafficPackageCatalogRepository; import java.util.Arrays; /** - * Application entry point + * Application for "YOTA" test task, see readme.md for more information + * + * @author Muchnik Andrey muchnik.ak@gmail.com + * @since 01.09.2019 */ @SpringBootApplication public class MobileServicesApplication { @@ -34,12 +37,12 @@ public CommandLineRunner runner(SimCardRepository simCardRepository, MinutesPack return args -> { MinutesPackageCatalog freeRoaming = MinutesPackageCatalog.builder() .name("FreeRoaming") - .type(MinutesPackageCatalog.MinutesPackageType.FREE_ROAMING) + .type(MinutesPackageCatalog.Type.FREE_ROAMING) .build(); MinutesPackageCatalog favoriteNumber = MinutesPackageCatalog.builder() .name("FavoriteNumber") - .type(MinutesPackageCatalog.MinutesPackageType.FAVORITE_NUMBER) + .type(MinutesPackageCatalog.Type.FAVORITE_NUMBER) .build(); MinutesDetails packageDetails = new MinutesDetails(freeRoaming, 300, 30); @@ -48,7 +51,7 @@ public CommandLineRunner runner(SimCardRepository simCardRepository, MinutesPack TrafficPackageCatalog trafficYoutube = TrafficPackageCatalog.builder() .name("Youtube") - .type(TrafficPackageCatalog.TrafficPackageType.YOUTUBE) + .type(TrafficPackageCatalog.Type.YOUTUBE) .build(); TrafficDetails trafficDetails = new TrafficDetails(trafficYoutube, 4, 2); diff --git a/src/main/java/ru/muchnik/yota/mobileservices/configuration/AspectJConfiguration.java b/src/main/java/ru/muchnik/yota/mobileservices/configuration/AspectJConfiguration.java index 8303f94..65a2d2a 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/configuration/AspectJConfiguration.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/configuration/AspectJConfiguration.java @@ -5,6 +5,7 @@ /** * Common configuration for aspectj + * * @apiNote needed to exclude autoconfiguration in test environment */ @Configuration diff --git a/src/main/java/ru/muchnik/yota/mobileservices/configuration/WebMvcConfiguration.java b/src/main/java/ru/muchnik/yota/mobileservices/configuration/WebMvcConfiguration.java index 3045c6f..fd9786e 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/configuration/WebMvcConfiguration.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/configuration/WebMvcConfiguration.java @@ -5,6 +5,7 @@ /** * Common configuration for web mvc + * * @apiNote needed to exclude autoconfiguration in test environment */ @Configuration diff --git a/src/main/java/ru/muchnik/yota/mobileservices/controller/BasePackageController.java b/src/main/java/ru/muchnik/yota/mobileservices/controller/BasePackageController.java index cd35667..f4c7529 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/controller/BasePackageController.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/controller/BasePackageController.java @@ -11,10 +11,7 @@ import ru.muchnik.yota.mobileservices.service.BaseDetailsService; import ru.muchnik.yota.mobileservices.service.BasePackageService; -import java.net.URI; -import java.util.HashMap; import java.util.List; -import java.util.Map; @RequiredArgsConstructor public abstract class BasePackageController> getPackages() { public abstract ResponseEntity savePackage(@RequestBody Type packageToSave); @PutMapping("/details/{detailsId}") - public ResponseEntity updateAmount(@PathVariable String detailsId, @RequestBody ValueDTO input) { + public ResponseEntity updatePackageAmount(@PathVariable String detailsId, @RequestBody ValueDTO input) { Integer value = input.getValue(); if (value != 0) { detailsService.updateAmount(detailsId, value); diff --git a/src/main/java/ru/muchnik/yota/mobileservices/controller/MinutesPackageController.java b/src/main/java/ru/muchnik/yota/mobileservices/controller/MinutesPackageController.java index 3356f08..8693f53 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/controller/MinutesPackageController.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/controller/MinutesPackageController.java @@ -6,8 +6,6 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import ru.muchnik.yota.mobileservices.model.dto.CreatePackageDTO; -import ru.muchnik.yota.mobileservices.model.entity.IPackageCatalog; import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesDetails; import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesPackageCatalog; import ru.muchnik.yota.mobileservices.service.minutes.MinutesDetailsService; diff --git a/src/main/java/ru/muchnik/yota/mobileservices/controller/SimCardController.java b/src/main/java/ru/muchnik/yota/mobileservices/controller/SimCardController.java index 90e64ae..25ade99 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/controller/SimCardController.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/controller/SimCardController.java @@ -9,8 +9,10 @@ import ru.muchnik.yota.mobileservices.model.dto.ValueDTO; import ru.muchnik.yota.mobileservices.model.entity.SimCard; import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesDetails; +import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficDetails; import ru.muchnik.yota.mobileservices.service.SimCardService; import ru.muchnik.yota.mobileservices.service.minutes.MinutesDetailsService; +import ru.muchnik.yota.mobileservices.service.traffic.TrafficDetailsService; import java.net.URI; import java.util.List; @@ -20,7 +22,8 @@ @RequestMapping(value = "api/v1/sim-card/", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public class SimCardController { private final SimCardService simCardService; - private final MinutesDetailsService detailsService; + private final MinutesDetailsService minutesDetailsService; + private final TrafficDetailsService trafficDetailsService; @GetMapping("{number}") public ResponseEntity getSimCard(@PathVariable String number) { @@ -34,28 +37,49 @@ public ResponseEntity> getSimCardStatus(@PathVariable String n @PutMapping("{number}/status") public ResponseEntity updateSimCardStatus(@PathVariable String number, - @RequestBody ValueDTO statusDTO) { + @RequestBody ValueDTO statusDTO) { return ResponseEntity.ok(simCardService.updateSimCardStatus(number, statusDTO.getValue())); } @GetMapping("{number}/minutes/total") public ResponseEntity> getSimCardActiveMinutesTotal(@PathVariable String number) { - int sumOfMinutesLeft = detailsService.getAllActivePackages(number).stream() + int sumOfMinutesLeft = minutesDetailsService.getAllActivePackages(number).stream() .mapToInt(MinutesDetails::getMinutesLeft) .sum(); return ResponseEntity.ok(new ValueDTO<>(sumOfMinutesLeft)); } + @GetMapping("{number}/traffic/total") + public ResponseEntity> getSimCardActiveTrafficTotal(@PathVariable String number) { + int sumOfGigabytesLeft = trafficDetailsService.getAllActivePackages(number).stream() + .mapToInt(TrafficDetails::getGigabytesLeft) + .sum(); + return ResponseEntity.ok(new ValueDTO<>(sumOfGigabytesLeft)); + } + @GetMapping("{number}/minutes/packages") - public ResponseEntity> getSimCardActivePackagesOfMinutes(@PathVariable String number) { - return ResponseEntity.ok(detailsService.getAllActivePackages(number)); + public ResponseEntity> getSimCardActiveMinutesPackages(@PathVariable String number) { + return ResponseEntity.ok(minutesDetailsService.getAllActivePackages(number)); + } + + @GetMapping("{number}/traffic/packages") + public ResponseEntity> getSimCardActiveTrafficPackages(@PathVariable String number) { + return ResponseEntity.ok(trafficDetailsService.getAllActivePackages(number)); } @PostMapping("{number}/minutes") - public ResponseEntity addPackageOfMinutesToSimCard(@PathVariable String number, - @RequestBody UpdatePackageRequestDTO requestDTO) { + public ResponseEntity addMinutesPackageToSimCard(@PathVariable String number, + @RequestBody UpdatePackageRequestDTO requestDTO) { MinutesDetails savedDetails = simCardService.addPackageOfMinutesToSimCard(number, requestDTO.getBasePackageId(), requestDTO.getAddition(), requestDTO.getDaysToLive()); - return ResponseEntity.created(URI.create("/api/v1/packages-of-addition/" + savedDetails.getId())) + return ResponseEntity.created(URI.create("/api/v1/packages-of-minutes/" + savedDetails.getId())) + .body(savedDetails); + } + + @PostMapping("{number}/traffic") + public ResponseEntity addTrafficPackageToSimCard(@PathVariable String number, + @RequestBody UpdatePackageRequestDTO requestDTO) { + TrafficDetails savedDetails = simCardService.addTrafficPackageToSimCard(number, requestDTO.getBasePackageId(), requestDTO.getAddition(), requestDTO.getDaysToLive()); + return ResponseEntity.created(URI.create("/api/v1/traffic-packages/" + savedDetails.getId())) .body(savedDetails); } } diff --git a/src/main/java/ru/muchnik/yota/mobileservices/controller/TrafficPackageController.java b/src/main/java/ru/muchnik/yota/mobileservices/controller/TrafficPackageController.java index a0094a5..03fd121 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/controller/TrafficPackageController.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/controller/TrafficPackageController.java @@ -6,7 +6,6 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import ru.muchnik.yota.mobileservices.model.dto.CreatePackageDTO; import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficDetails; import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficPackageCatalog; import ru.muchnik.yota.mobileservices.service.traffic.TrafficDetailsService; @@ -16,7 +15,7 @@ @Controller @RequestMapping(value = "api/v1/traffic-packages/", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class TrafficPackageController extends BasePackageController { +public class TrafficPackageController extends BasePackageController { public TrafficPackageController(final TrafficPackageService packageService, final TrafficDetailsService detailsService) { super(packageService, detailsService); } diff --git a/src/main/java/ru/muchnik/yota/mobileservices/controller/advice/GlobalControllerExceptionHandler.java b/src/main/java/ru/muchnik/yota/mobileservices/controller/advice/GlobalControllerExceptionHandler.java index 442033b..7a2379a 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/controller/advice/GlobalControllerExceptionHandler.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/controller/advice/GlobalControllerExceptionHandler.java @@ -76,7 +76,7 @@ public ResponseEntity handleNotFoundException(final Throwable ex) } /** - * In case of any validation exceptions, occured on any entity + * In case of any validation exceptions occurred on any entity * * @param ex throwed exception * @return business {@link ResponseEntity} diff --git a/src/main/java/ru/muchnik/yota/mobileservices/model/ErrorResponse.java b/src/main/java/ru/muchnik/yota/mobileservices/model/ErrorResponse.java index d7885bb..3d22222 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/model/ErrorResponse.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/model/ErrorResponse.java @@ -5,9 +5,10 @@ import org.springframework.http.HttpStatus; /** - * In case of exceptions that being throwed in {@link org.springframework.web.bind.annotation.RestController} - * that was catched via {@link org.springframework.web.bind.annotation.ControllerAdvice} for further response to client + * Simple model for response via {@link org.springframework.stereotype.Controller} in case of any errors. * + * @apiNote In case of exceptions that being throwed in {@link org.springframework.web.bind.annotation.RestController} + * that was catched via {@link org.springframework.web.bind.annotation.ControllerAdvice} for further response to client * @see ru.muchnik.yota.mobileservices.controller.advice.GlobalControllerExceptionHandler */ @Data diff --git a/src/main/java/ru/muchnik/yota/mobileservices/model/dto/CreatePackageDTO.java b/src/main/java/ru/muchnik/yota/mobileservices/model/dto/CreatePackageDTO.java deleted file mode 100644 index c63fbae..0000000 --- a/src/main/java/ru/muchnik/yota/mobileservices/model/dto/CreatePackageDTO.java +++ /dev/null @@ -1,18 +0,0 @@ -package ru.muchnik.yota.mobileservices.model.dto; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Simple DTO for creating package - * @see ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesPackageCatalog - * @see ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficPackageCatalog - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -public class CreatePackageDTO { - private String name; - private String type; -} diff --git a/src/main/java/ru/muchnik/yota/mobileservices/model/dto/UpdatePackageRequestDTO.java b/src/main/java/ru/muchnik/yota/mobileservices/model/dto/UpdatePackageRequestDTO.java index 0534e33..2163dee 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/model/dto/UpdatePackageRequestDTO.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/model/dto/UpdatePackageRequestDTO.java @@ -4,6 +4,9 @@ import lombok.Data; import lombok.NoArgsConstructor; +/** + * Data transfer object for update package operation + */ @Data @AllArgsConstructor @NoArgsConstructor diff --git a/src/main/java/ru/muchnik/yota/mobileservices/model/dto/ValueDTO.java b/src/main/java/ru/muchnik/yota/mobileservices/model/dto/ValueDTO.java index 45185bf..6eed40c 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/model/dto/ValueDTO.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/model/dto/ValueDTO.java @@ -5,7 +5,8 @@ import lombok.NoArgsConstructor; /** - * Simple DTO for single value-container + * Simple data transfer object for single value-container + * * @param type of value */ @Data diff --git a/src/main/java/ru/muchnik/yota/mobileservices/model/entity/IPackageCatalog.java b/src/main/java/ru/muchnik/yota/mobileservices/model/entity/IPackageCatalog.java index 9d7ee70..39351d3 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/model/entity/IPackageCatalog.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/model/entity/IPackageCatalog.java @@ -1,6 +1,6 @@ package ru.muchnik.yota.mobileservices.model.entity; -public interface IPackageCatalog { +public interface IPackageCatalog { String getId(); String getName(); diff --git a/src/main/java/ru/muchnik/yota/mobileservices/model/entity/SimCard.java b/src/main/java/ru/muchnik/yota/mobileservices/model/entity/SimCard.java index f59f544..fb15608 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/model/entity/SimCard.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/model/entity/SimCard.java @@ -37,7 +37,7 @@ public class SimCard { private boolean isActive; /** - * All {@link MinutesDetails} packages of addition that is attached to this sim card + * All {@link MinutesDetails} packages of minutes that is attached to this sim card */ @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "simCard", fetch = FetchType.LAZY) @NotNull @@ -46,7 +46,7 @@ public class SimCard { private List minutesDetails; /** - * All {@link MinutesDetails} packages of addition that is attached to this sim card + * All {@link MinutesDetails} packages of traffic that is attached to this sim card */ @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "simCard", fetch = FetchType.LAZY) @NotNull diff --git a/src/main/java/ru/muchnik/yota/mobileservices/model/entity/minutes/MinutesDetails.java b/src/main/java/ru/muchnik/yota/mobileservices/model/entity/minutes/MinutesDetails.java index f080d9b..a399f1f 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/model/entity/minutes/MinutesDetails.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/model/entity/minutes/MinutesDetails.java @@ -41,6 +41,7 @@ public class MinutesDetails implements IDetails { @PositiveOrZero private int minutesLeft; + @NotNull @Column(columnDefinition = "TIMESTAMP") private LocalDateTime activationDate; diff --git a/src/main/java/ru/muchnik/yota/mobileservices/model/entity/minutes/MinutesPackageCatalog.java b/src/main/java/ru/muchnik/yota/mobileservices/model/entity/minutes/MinutesPackageCatalog.java index a22ddc0..1882e32 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/model/entity/minutes/MinutesPackageCatalog.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/model/entity/minutes/MinutesPackageCatalog.java @@ -17,7 +17,7 @@ @AllArgsConstructor @Builder @EqualsAndHashCode(onlyExplicitlyIncluded = true) -public class MinutesPackageCatalog implements IPackageCatalog { +public class MinutesPackageCatalog implements IPackageCatalog { @Id @EqualsAndHashCode.Include @Size(max = 36) @@ -33,9 +33,9 @@ public class MinutesPackageCatalog implements IPackageCatalog { @EqualsAndHashCode.Include @Size(max = 36) private final String id = UUID.randomUUID().toString(); + /** * Reference to base package that may (in future) contains more business information */ @@ -29,6 +30,7 @@ public class TrafficDetails implements IDetails { @NotNull @JoinColumn(name = "base_package_id") private TrafficPackageCatalog basePackage; + /** * Reference to package owner sim card */ @@ -36,11 +38,14 @@ public class TrafficDetails implements IDetails { @NotNull @JoinColumn(name = "sim_card_id") private SimCard simCard; + @PositiveOrZero private int gigabytesLeft; + @NotNull @Column(columnDefinition = "TIMESTAMP") private LocalDateTime activationDate; + @NotNull @Column(columnDefinition = "TIMESTAMP") private LocalDateTime expirationDate; diff --git a/src/main/java/ru/muchnik/yota/mobileservices/model/entity/traffic/TrafficPackageCatalog.java b/src/main/java/ru/muchnik/yota/mobileservices/model/entity/traffic/TrafficPackageCatalog.java index f75d495..fc3c699 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/model/entity/traffic/TrafficPackageCatalog.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/model/entity/traffic/TrafficPackageCatalog.java @@ -17,7 +17,7 @@ @AllArgsConstructor @Builder @EqualsAndHashCode(onlyExplicitlyIncluded = true) -public class TrafficPackageCatalog implements IPackageCatalog { +public class TrafficPackageCatalog implements IPackageCatalog { @Id @EqualsAndHashCode.Include @Size(max = 36) @@ -33,9 +33,9 @@ public class TrafficPackageCatalog implements IPackageCatalog & JpaRepository> { @@ -20,10 +19,9 @@ public abstract class BaseDetailsService detailsOptional = repository.findById(id); - if (!detailsOptional.isPresent()) throw new NotFoundException("Details for package of traffic not found"); - return detailsOptional.get(); + return repository.findById(id).orElseThrow(() -> new NotFoundException("Details for package is not found!")); } + @Transactional(isolation = Isolation.READ_COMMITTED) public void updateAmount(@NonNull final String detailsId, final int addition) { Type details = getDetails(detailsId); @@ -32,6 +30,7 @@ public void updateAmount(@NonNull final String detailsId, final int addition) { amountLeft += addition; details.setAmountLeft(amountLeft); } + @Transactional(readOnly = true, isolation = Isolation.READ_COMMITTED) public List getAllActivePackages(@NonNull final String number) { return repository.findAllActive(number, LocalDateTime.now()); @@ -39,7 +38,7 @@ public List getAllActivePackages(@NonNull final String number) { private void doValidate(@NonNull final Type details, final int addition) { doValidateExpiration(details); - doValidateAdjusting(details, addition); + doValidateAddition(details, addition); } private void doValidateExpiration(@NonNull final Type details) { @@ -48,14 +47,14 @@ private void doValidateExpiration(@NonNull final Type details) { LocalDateTime expirationDate = details.getExpirationDate(); if (!activationDate.isBefore(now) || !expirationDate.isAfter(now)) { - throw new ValidationException("Package has expired!"); + throw new ValidationException("Package life time has expired!"); } } - private void doValidateAdjusting(@NonNull final Type details, final int addition) { + private void doValidateAddition(@NonNull final Type details, final int addition) { int amountLeft = details.getAmountLeft(); if (addition < 0 && amountLeft < (-addition)) { - throw new ValidationException("Amount in package of addition cannot be decremented! Left:" + amountLeft + " Decrement:" + addition); + throw new ValidationException("Amount in package cannot be decremented! Left:" + amountLeft + " Decrement by:" + addition); } } } diff --git a/src/main/java/ru/muchnik/yota/mobileservices/service/BasePackageService.java b/src/main/java/ru/muchnik/yota/mobileservices/service/BasePackageService.java index 9d727b0..df7406e 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/service/BasePackageService.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/service/BasePackageService.java @@ -9,7 +9,6 @@ import ru.muchnik.yota.mobileservices.model.exception.NotFoundException; import java.util.List; -import java.util.Optional; @RequiredArgsConstructor public abstract class BasePackageService> { @@ -17,9 +16,7 @@ public abstract class BasePackageService optionalPackage = repository.findById(id); - if (!optionalPackage.isPresent()) throw new NotFoundException("Package not found"); - return optionalPackage.get(); + return repository.findById(id).orElseThrow(() -> new NotFoundException("Package is not found!")); } @Transactional(readOnly = true, isolation = Isolation.READ_COMMITTED) diff --git a/src/main/java/ru/muchnik/yota/mobileservices/service/SimCardService.java b/src/main/java/ru/muchnik/yota/mobileservices/service/SimCardService.java index e216e5f..04e8c61 100644 --- a/src/main/java/ru/muchnik/yota/mobileservices/service/SimCardService.java +++ b/src/main/java/ru/muchnik/yota/mobileservices/service/SimCardService.java @@ -5,27 +5,26 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; +import ru.muchnik.yota.mobileservices.model.entity.SimCard; import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesDetails; import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesPackageCatalog; -import ru.muchnik.yota.mobileservices.model.entity.SimCard; +import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficDetails; +import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficPackageCatalog; import ru.muchnik.yota.mobileservices.model.exception.NotFoundException; -import ru.muchnik.yota.mobileservices.repository.minutes.MinutesDetailsRepository; import ru.muchnik.yota.mobileservices.repository.SimCardRepository; import ru.muchnik.yota.mobileservices.service.minutes.MinutesPackageService; - -import java.util.Optional; +import ru.muchnik.yota.mobileservices.service.traffic.TrafficPackageService; @Service @RequiredArgsConstructor public class SimCardService { private final SimCardRepository simCardRepository; private final MinutesPackageService minutesPackageService; + private final TrafficPackageService trafficPackageService; @Transactional(readOnly = true, isolation = Isolation.READ_COMMITTED) public SimCard getSimCard(@NonNull final String number) { - Optional optionalSimCard = simCardRepository.getByNumber(number); - if (!optionalSimCard.isPresent()) throw new NotFoundException("Sim Card not found"); - return optionalSimCard.get(); + return simCardRepository.getByNumber(number).orElseThrow(() -> new NotFoundException("Sim Card is not found!")); } @Transactional(readOnly = true, isolation = Isolation.READ_COMMITTED) @@ -41,11 +40,11 @@ public SimCard updateSimCardStatus(@NonNull final String number, final boolean s } /** - * Adds a addition package to specified sim card by number + * Adds a minutes-package to specified sim card by number * * @param number target sim card number * @param basePackageId base package id - * @param minutes addition to add + * @param minutes minutes amount to add (can be negative to decrement) * @param daysToLive days to live */ @Transactional(isolation = Isolation.READ_COMMITTED) @@ -60,4 +59,25 @@ public MinutesDetails addPackageOfMinutesToSimCard(@NonNull final String number, simCard.getMinutesDetails().add(details); return details; } + + /** + * Adds a traffic-package to specified sim card by number + * + * @param number target sim card number + * @param basePackageId base package id + * @param traffic traffic amount to add (can be negative to decrement) + * @param daysToLive days to live + */ + @Transactional(isolation = Isolation.READ_COMMITTED) + public TrafficDetails addTrafficPackageToSimCard(@NonNull final String number, + @NonNull final String basePackageId, + final int traffic, + final int daysToLive) { + final SimCard simCard = getSimCard(number); + final TrafficPackageCatalog basePackage = trafficPackageService.getPackage(basePackageId); + final TrafficDetails details = new TrafficDetails(basePackage, traffic, daysToLive); + details.setSimCard(simCard); + simCard.getTrafficDetails().add(details); + return details; + } } diff --git a/src/test/java/ru/muchnik/yota/mobileservices/controller/MinutesPackageCatalogControllerContextTest.java b/src/test/java/ru/muchnik/yota/mobileservices/controller/MinutesPackageCatalogControllerContextTest.java index bd5fcf9..9be78b0 100644 --- a/src/test/java/ru/muchnik/yota/mobileservices/controller/MinutesPackageCatalogControllerContextTest.java +++ b/src/test/java/ru/muchnik/yota/mobileservices/controller/MinutesPackageCatalogControllerContextTest.java @@ -15,7 +15,6 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesPackageCatalog; -import ru.muchnik.yota.mobileservices.service.BaseDetailsService; import ru.muchnik.yota.mobileservices.service.minutes.MinutesDetailsService; import ru.muchnik.yota.mobileservices.service.minutes.MinutesPackageService; @@ -61,7 +60,7 @@ public void getPackage() throws Exception { public void savePackage() throws Exception { MinutesPackageCatalog mp = MinutesPackageCatalog.builder() .name("name") - .type(MinutesPackageCatalog.MinutesPackageType.FAVORITE_NUMBER) + .type(MinutesPackageCatalog.Type.FAVORITE_NUMBER) .build(); when(packageService.savePackage(any())).thenReturn(mp); @@ -78,7 +77,7 @@ public void savePackage() throws Exception { verify(packageService).savePackage(captor.capture()); MinutesPackageCatalog captorValue = captor.getValue(); Assert.assertEquals("name", captorValue.getName()); - Assert.assertEquals(MinutesPackageCatalog.MinutesPackageType.FAVORITE_NUMBER, captorValue.getType()); + Assert.assertEquals(MinutesPackageCatalog.Type.FAVORITE_NUMBER, captorValue.getType()); } @Test diff --git a/src/test/java/ru/muchnik/yota/mobileservices/controller/MinutesPackageCatalogControllerTest.java b/src/test/java/ru/muchnik/yota/mobileservices/controller/MinutesPackageCatalogControllerTest.java index 6fd613e..5809d11 100644 --- a/src/test/java/ru/muchnik/yota/mobileservices/controller/MinutesPackageCatalogControllerTest.java +++ b/src/test/java/ru/muchnik/yota/mobileservices/controller/MinutesPackageCatalogControllerTest.java @@ -73,18 +73,18 @@ public void savePackage() { ResponseEntity result = controller.savePackage(MinutesPackageCatalog.builder() .name("name") - .type(MinutesPackageCatalog.MinutesPackageType.FAVORITE_NUMBER) + .type(MinutesPackageCatalog.Type.FAVORITE_NUMBER) .build()); MinutesPackageCatalog captorValue = captor.getValue(); Assert.assertEquals("name", captorValue.getName()); - Assert.assertEquals(MinutesPackageCatalog.MinutesPackageType.FAVORITE_NUMBER, captorValue.getType()); + Assert.assertEquals(MinutesPackageCatalog.Type.FAVORITE_NUMBER, captorValue.getType()); Assert.assertEquals(ResponseEntity.created(URI.create("/api/v1/packages-of-minutes/2")).body(minutesPackageCatalog), result); } @Test public void updateMinutes() { - ResponseEntity voidResponseEntity = controller.updateAmount("1", new ValueDTO<>(2)); + ResponseEntity voidResponseEntity = controller.updatePackageAmount("1", new ValueDTO<>(2)); verify(detailsService).updateAmount(eq("1"), eq(2)); Assert.assertEquals(200, voidResponseEntity.getStatusCodeValue()); @@ -92,7 +92,7 @@ public void updateMinutes() { @Test public void updateMinutesBy0() { - ResponseEntity voidResponseEntity = controller.updateAmount("1", new ValueDTO<>(0)); + ResponseEntity voidResponseEntity = controller.updatePackageAmount("1", new ValueDTO<>(0)); verifyZeroInteractions(detailsService); Assert.assertEquals(200, voidResponseEntity.getStatusCodeValue()); diff --git a/src/test/java/ru/muchnik/yota/mobileservices/controller/SimCardControllerContextTest.java b/src/test/java/ru/muchnik/yota/mobileservices/controller/SimCardControllerContextTest.java index a40bc8c..db6cefb 100644 --- a/src/test/java/ru/muchnik/yota/mobileservices/controller/SimCardControllerContextTest.java +++ b/src/test/java/ru/muchnik/yota/mobileservices/controller/SimCardControllerContextTest.java @@ -19,13 +19,15 @@ import org.springframework.test.web.servlet.MvcResult; import ru.muchnik.yota.mobileservices.model.ErrorResponse; import ru.muchnik.yota.mobileservices.model.dto.ValueDTO; -import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesPackageCatalog; -import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesDetails; import ru.muchnik.yota.mobileservices.model.entity.SimCard; +import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesDetails; +import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesPackageCatalog; +import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficDetails; +import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficPackageCatalog; import ru.muchnik.yota.mobileservices.model.exception.NotFoundException; -import ru.muchnik.yota.mobileservices.service.BaseDetailsService; import ru.muchnik.yota.mobileservices.service.SimCardService; import ru.muchnik.yota.mobileservices.service.minutes.MinutesDetailsService; +import ru.muchnik.yota.mobileservices.service.traffic.TrafficDetailsService; import java.util.ArrayList; import java.util.List; @@ -53,6 +55,9 @@ public class SimCardControllerContextTest { @MockBean private MinutesDetailsService detailsService; + @MockBean + private TrafficDetailsService trafficDetailsService; + private SimCard simCard = new SimCard(); private ObjectMapper mapper = new ObjectMapper(); @@ -124,7 +129,7 @@ public void getSimCardActiveMinutesTotal() throws Exception { ValueDTO dto = new ValueDTO<>(22); MinutesPackageCatalog pof = MinutesPackageCatalog.builder() .name("name") - .type(MinutesPackageCatalog.MinutesPackageType.FAVORITE_NUMBER) + .type(MinutesPackageCatalog.Type.FAVORITE_NUMBER) .build(); MinutesDetails details = new MinutesDetails(pof, 10, 15); MinutesDetails details2 = new MinutesDetails(pof, 12, 17); @@ -144,10 +149,34 @@ public void getSimCardActiveMinutesTotal() throws Exception { } @Test - public void getSimCardActivePackagesOfMinutes() throws Exception { + public void getSimCardActiveTrafficTotal() throws Exception { + ValueDTO dto = new ValueDTO<>(22); + TrafficPackageCatalog tpc = TrafficPackageCatalog.builder() + .name("name") + .type(TrafficPackageCatalog.Type.YOUTUBE) + .build(); + TrafficDetails details = new TrafficDetails(tpc, 10, 15); + TrafficDetails details2 = new TrafficDetails(tpc, 12, 17); + List list = new ArrayList<>(); + list.add(details); + list.add(details2); + + when(trafficDetailsService.getAllActivePackages(eq("1"))).thenReturn(list); + + mockMvc.perform(get("/api/v1/sim-card/1/traffic/total") + .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(header().string("Content-Type", MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(content().json(mapper.writeValueAsString(dto))); + } + + @Test + public void getSimCardActiveMinutesPackages() throws Exception { MinutesPackageCatalog pof = MinutesPackageCatalog.builder() .name("name") - .type(MinutesPackageCatalog.MinutesPackageType.FAVORITE_NUMBER) + .type(MinutesPackageCatalog.Type.FAVORITE_NUMBER) .build(); MinutesDetails details = new MinutesDetails(pof, 10, 15); MinutesDetails details2 = new MinutesDetails(pof, 12, 17); @@ -167,7 +196,37 @@ public void getSimCardActivePackagesOfMinutes() throws Exception { .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) .andReturn(); String content = result.getResponse().getContentAsString(); - List resultContent = mapper.readValue(content, new TypeReference>() {}); + List resultContent = mapper.readValue(content, new TypeReference>() { + }); + Assert.assertEquals(list, resultContent); + } + + @Test + public void getSimCardActiveTrafficPackages() throws Exception { + TrafficPackageCatalog pof = TrafficPackageCatalog.builder() + .name("name") + .type(TrafficPackageCatalog.Type.YOUTUBE) + .build(); + TrafficDetails details = new TrafficDetails(pof, 10, 15); + TrafficDetails details2 = new TrafficDetails(pof, 12, 17); + details.setSimCard(simCard); + details2.setSimCard(simCard); + List list = new ArrayList<>(); + list.add(details); + list.add(details2); + + when(trafficDetailsService.getAllActivePackages(eq("1"))).thenReturn(list); + + MvcResult result = mockMvc.perform(get("/api/v1/sim-card/1/traffic/packages") + .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(header().string("Content-Type", MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andReturn(); + String content = result.getResponse().getContentAsString(); + List resultContent = mapper.readValue(content, new TypeReference>() { + }); Assert.assertEquals(list, resultContent); } @@ -185,10 +244,31 @@ public void addPackageOfMinutesToSimCard() throws Exception { .andDo(print()) .andExpect(status().isCreated()) .andExpect(header().string("Content-Type", MediaType.APPLICATION_JSON_UTF8_VALUE)) - .andExpect(header().string("Location", "/api/v1/packages-of-addition/" + id)) + .andExpect(header().string("Location", "/api/v1/packages-of-minutes/" + id)) .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) .andExpect(content().json(mapper.writeValueAsString(details))); verify(simCardService).addPackageOfMinutesToSimCard(eq("1"), eq("1"), eq(15), eq(10)); } + + @Test + public void addTrafficPackageToSimCard() throws Exception { + TrafficDetails details = new TrafficDetails(); + + when(simCardService.addTrafficPackageToSimCard(eq("1"), anyString(), anyInt(), anyInt())) + .thenReturn(details); + String id = details.getId(); + + mockMvc.perform(post("/api/v1/sim-card/1/traffic") + .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE) + .content("{\"basePackageId\": 1, \"addition\": 15, \"daysToLive\": 10}")) + .andDo(print()) + .andExpect(status().isCreated()) + .andExpect(header().string("Content-Type", MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(header().string("Location", "/api/v1/traffic-packages/" + id)) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(content().json(mapper.writeValueAsString(details))); + + verify(simCardService).addTrafficPackageToSimCard(eq("1"), eq("1"), eq(15), eq(10)); + } } \ No newline at end of file diff --git a/src/test/java/ru/muchnik/yota/mobileservices/controller/SimCardControllerTest.java b/src/test/java/ru/muchnik/yota/mobileservices/controller/SimCardControllerTest.java index 6454ccd..1767a74 100644 --- a/src/test/java/ru/muchnik/yota/mobileservices/controller/SimCardControllerTest.java +++ b/src/test/java/ru/muchnik/yota/mobileservices/controller/SimCardControllerTest.java @@ -1,7 +1,6 @@ package ru.muchnik.yota.mobileservices.controller; import org.junit.Assert; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; @@ -9,15 +8,17 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import ru.muchnik.yota.mobileservices.model.dto.ValueDTO; import ru.muchnik.yota.mobileservices.model.dto.UpdatePackageRequestDTO; -import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesDetails; +import ru.muchnik.yota.mobileservices.model.dto.ValueDTO; import ru.muchnik.yota.mobileservices.model.entity.SimCard; -import ru.muchnik.yota.mobileservices.service.BaseDetailsService; +import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesDetails; +import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficDetails; import ru.muchnik.yota.mobileservices.service.SimCardService; import ru.muchnik.yota.mobileservices.service.minutes.MinutesDetailsService; +import ru.muchnik.yota.mobileservices.service.traffic.TrafficDetailsService; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import static org.mockito.ArgumentMatchers.eq; @@ -30,6 +31,8 @@ public class SimCardControllerTest { private SimCardService simCardService; @Mock private MinutesDetailsService detailsService; + @Mock + private TrafficDetailsService trafficDetailsService; @InjectMocks private SimCardController controller; @@ -41,9 +44,10 @@ public class SimCardControllerTest { @Mock private MinutesDetails details2; - @Before - public void setUp() throws Exception { - } + @Mock + private TrafficDetails trafficDetails; + @Mock + private TrafficDetails trafficDetails2; @Test public void getSimCard() { @@ -86,27 +90,67 @@ public void getSimCardActiveMinutesValue() { } @Test - public void getSimCardActiveMinutes() { + public void getSimCardActiveTrafficValue() { + List list = new ArrayList<>(); + list.add(trafficDetails); + list.add(trafficDetails2); + when(trafficDetails.getGigabytesLeft()).thenReturn(2); + when(trafficDetails2.getGigabytesLeft()).thenReturn(6); + when(trafficDetailsService.getAllActivePackages(eq("89992223344"))).thenReturn(list); + + ResponseEntity> result = controller.getSimCardActiveTrafficTotal("89992223344"); + + ResponseEntity> exp = ResponseEntity.ok(new ValueDTO<>(8)); + Assert.assertEquals(exp, result); + } + + @Test + public void getSimCardActiveMinutesPackages() { List list = new ArrayList<>(); list.add(details); list.add(details2); when(detailsService.getAllActivePackages(eq("89992223344"))).thenReturn(list); - ResponseEntity> result = controller.getSimCardActivePackagesOfMinutes("89992223344"); + ResponseEntity> result = controller.getSimCardActiveMinutesPackages("89992223344"); ResponseEntity> exp = ResponseEntity.ok(list); Assert.assertEquals(exp, result); } + @Test + public void getSimCardActiveTrafficPackages() { + List list = new ArrayList<>(); + list.add(trafficDetails); + list.add(trafficDetails2); + when(trafficDetailsService.getAllActivePackages(eq("89992223344"))).thenReturn(list); + + ResponseEntity> result = controller.getSimCardActiveTrafficPackages("89992223344"); + + ResponseEntity> exp = ResponseEntity.ok(Arrays.asList(trafficDetails, trafficDetails2)); + Assert.assertEquals(exp, result); + } + @Test public void addSimCardMinutesPackage() { when(simCardService.addPackageOfMinutesToSimCard(eq("89992223344"), eq("1"), eq(2), eq(3))) .thenReturn(details); when(details.getId()).thenReturn("1"); - ResponseEntity result = controller.addPackageOfMinutesToSimCard("89992223344", new UpdatePackageRequestDTO("1", 2, 3)); + ResponseEntity result = controller.addMinutesPackageToSimCard("89992223344", new UpdatePackageRequestDTO("1", 2, 3)); verify(simCardService).addPackageOfMinutesToSimCard(eq("89992223344"), eq("1"), eq(2), eq(3)); Assert.assertEquals(HttpStatus.CREATED, result.getStatusCode()); } + + @Test + public void addSimCardTrafficPackage() { + when(simCardService.addTrafficPackageToSimCard(eq("89992223344"), eq("1"), eq(2), eq(3))) + .thenReturn(trafficDetails); + when(trafficDetails.getId()).thenReturn("1"); + + ResponseEntity result = controller.addTrafficPackageToSimCard("89992223344", new UpdatePackageRequestDTO("1", 2, 3)); + + verify(simCardService).addTrafficPackageToSimCard(eq("89992223344"), eq("1"), eq(2), eq(3)); + Assert.assertEquals(HttpStatus.CREATED, result.getStatusCode()); + } } \ No newline at end of file diff --git a/src/test/java/ru/muchnik/yota/mobileservices/controller/TrafficPackageCatalogControllerContextTest.java b/src/test/java/ru/muchnik/yota/mobileservices/controller/TrafficPackageCatalogControllerContextTest.java index 8120669..d65a711 100644 --- a/src/test/java/ru/muchnik/yota/mobileservices/controller/TrafficPackageCatalogControllerContextTest.java +++ b/src/test/java/ru/muchnik/yota/mobileservices/controller/TrafficPackageCatalogControllerContextTest.java @@ -14,7 +14,6 @@ import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; -import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesPackageCatalog; import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficPackageCatalog; import ru.muchnik.yota.mobileservices.service.traffic.TrafficDetailsService; import ru.muchnik.yota.mobileservices.service.traffic.TrafficPackageService; @@ -61,7 +60,7 @@ public void getPackage() throws Exception { public void savePackage() throws Exception { TrafficPackageCatalog mp = TrafficPackageCatalog.builder() .name("name") - .type(TrafficPackageCatalog.TrafficPackageType.YOUTUBE) + .type(TrafficPackageCatalog.Type.YOUTUBE) .build(); when(packageService.savePackage(any())).thenReturn(mp); @@ -78,7 +77,7 @@ public void savePackage() throws Exception { verify(packageService).savePackage(captor.capture()); TrafficPackageCatalog captorValue = captor.getValue(); Assert.assertEquals("name", captorValue.getName()); - Assert.assertEquals(TrafficPackageCatalog.TrafficPackageType.YOUTUBE, captorValue.getType()); + Assert.assertEquals(TrafficPackageCatalog.Type.YOUTUBE, captorValue.getType()); } @Test diff --git a/src/test/java/ru/muchnik/yota/mobileservices/controller/TrafficPackageCatalogControllerTest.java b/src/test/java/ru/muchnik/yota/mobileservices/controller/TrafficPackageCatalogControllerTest.java index 4580c47..8c92bdd 100644 --- a/src/test/java/ru/muchnik/yota/mobileservices/controller/TrafficPackageCatalogControllerTest.java +++ b/src/test/java/ru/muchnik/yota/mobileservices/controller/TrafficPackageCatalogControllerTest.java @@ -1,7 +1,6 @@ package ru.muchnik.yota.mobileservices.controller; import org.junit.Assert; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -11,7 +10,6 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.http.ResponseEntity; import ru.muchnik.yota.mobileservices.model.dto.ValueDTO; -import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesPackageCatalog; import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficPackageCatalog; import ru.muchnik.yota.mobileservices.service.traffic.TrafficDetailsService; import ru.muchnik.yota.mobileservices.service.traffic.TrafficPackageService; @@ -70,18 +68,18 @@ public void savePackage() { ResponseEntity result = controller.savePackage(TrafficPackageCatalog.builder() .name("name") - .type(TrafficPackageCatalog.TrafficPackageType.YOUTUBE) + .type(TrafficPackageCatalog.Type.YOUTUBE) .build()); TrafficPackageCatalog captorValue = captor.getValue(); Assert.assertEquals("name", captorValue.getName()); - Assert.assertEquals(TrafficPackageCatalog.TrafficPackageType.YOUTUBE, captorValue.getType()); + Assert.assertEquals(TrafficPackageCatalog.Type.YOUTUBE, captorValue.getType()); Assert.assertEquals(ResponseEntity.created(URI.create("/api/v1/traffic-packages/2")).body(trafficPackageCatalog), result); } @Test public void updateMinutes() { - ResponseEntity voidResponseEntity = controller.updateAmount("1", new ValueDTO<>(2)); + ResponseEntity voidResponseEntity = controller.updatePackageAmount("1", new ValueDTO<>(2)); verify(detailsService).updateAmount(eq("1"), eq(2)); Assert.assertEquals(200, voidResponseEntity.getStatusCodeValue()); @@ -89,7 +87,7 @@ public void updateMinutes() { @Test public void updateMinutesBy0() { - ResponseEntity voidResponseEntity = controller.updateAmount("1", new ValueDTO<>(0)); + ResponseEntity voidResponseEntity = controller.updatePackageAmount("1", new ValueDTO<>(0)); verifyZeroInteractions(detailsService); Assert.assertEquals(200, voidResponseEntity.getStatusCodeValue()); diff --git a/src/test/java/ru/muchnik/yota/mobileservices/controller/advice/GlobalControllerExceptionHandlerContextTest.java b/src/test/java/ru/muchnik/yota/mobileservices/controller/advice/GlobalControllerExceptionHandlerContextTest.java index 1fda156..72837ca 100644 --- a/src/test/java/ru/muchnik/yota/mobileservices/controller/advice/GlobalControllerExceptionHandlerContextTest.java +++ b/src/test/java/ru/muchnik/yota/mobileservices/controller/advice/GlobalControllerExceptionHandlerContextTest.java @@ -16,7 +16,6 @@ import ru.muchnik.yota.mobileservices.model.ErrorResponse; import ru.muchnik.yota.mobileservices.model.exception.NotFoundException; import ru.muchnik.yota.mobileservices.model.exception.ValidationException; -import ru.muchnik.yota.mobileservices.service.BaseDetailsService; import ru.muchnik.yota.mobileservices.service.minutes.MinutesDetailsService; import ru.muchnik.yota.mobileservices.service.minutes.MinutesPackageService; diff --git a/src/test/java/ru/muchnik/yota/mobileservices/model/entity/traffic/TrafficDetailsTest.java b/src/test/java/ru/muchnik/yota/mobileservices/model/entity/traffic/TrafficDetailsTest.java index 1a24c31..3c3ebe6 100644 --- a/src/test/java/ru/muchnik/yota/mobileservices/model/entity/traffic/TrafficDetailsTest.java +++ b/src/test/java/ru/muchnik/yota/mobileservices/model/entity/traffic/TrafficDetailsTest.java @@ -4,8 +4,6 @@ import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.*; - public class TrafficDetailsTest { private TrafficDetails trafficDetails; diff --git a/src/test/java/ru/muchnik/yota/mobileservices/repository/MobileServicesDataJpaTest.java b/src/test/java/ru/muchnik/yota/mobileservices/repository/MobileServicesDataJpaTest.java index e444f30..98627a2 100644 --- a/src/test/java/ru/muchnik/yota/mobileservices/repository/MobileServicesDataJpaTest.java +++ b/src/test/java/ru/muchnik/yota/mobileservices/repository/MobileServicesDataJpaTest.java @@ -10,14 +10,13 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.junit4.SpringRunner; -import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesPackageCatalog; -import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesDetails; import ru.muchnik.yota.mobileservices.model.entity.SimCard; +import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesDetails; +import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesPackageCatalog; import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficDetails; import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficPackageCatalog; import ru.muchnik.yota.mobileservices.repository.minutes.MinutesDetailsRepository; import ru.muchnik.yota.mobileservices.repository.minutes.MinutesPackageCatalogRepository; -import ru.muchnik.yota.mobileservices.repository.traffic.TrafficDetailsRepository; import ru.muchnik.yota.mobileservices.repository.traffic.TrafficPackageCatalogRepository; import java.time.LocalDateTime; @@ -48,12 +47,12 @@ public class MobileServicesDataJpaTest { public void setUp() throws Exception { MinutesPackageCatalog freeRoaming = MinutesPackageCatalog.builder() .name("FreeRoaming") - .type(MinutesPackageCatalog.MinutesPackageType.FREE_ROAMING) + .type(MinutesPackageCatalog.Type.FREE_ROAMING) .build(); MinutesPackageCatalog favoriteNumber = MinutesPackageCatalog.builder() .name("FavoriteNumber") - .type(MinutesPackageCatalog.MinutesPackageType.FAVORITE_NUMBER) + .type(MinutesPackageCatalog.Type.FAVORITE_NUMBER) .build(); MinutesDetails activeFirstDetails = new MinutesDetails(freeRoaming, 300, 30); @@ -62,7 +61,7 @@ public void setUp() throws Exception { TrafficPackageCatalog trafficYoutube = TrafficPackageCatalog.builder() .name("Youtube") - .type(TrafficPackageCatalog.TrafficPackageType.YOUTUBE) + .type(TrafficPackageCatalog.Type.YOUTUBE) .build(); TrafficDetails trafficDetails = new TrafficDetails(trafficYoutube, 4, 2); diff --git a/src/test/java/ru/muchnik/yota/mobileservices/service/BaseMinutesPackageServiceTest.java b/src/test/java/ru/muchnik/yota/mobileservices/service/BaseMinutesPackageServiceTest.java index 98c4c11..9d9e4cc 100644 --- a/src/test/java/ru/muchnik/yota/mobileservices/service/BaseMinutesPackageServiceTest.java +++ b/src/test/java/ru/muchnik/yota/mobileservices/service/BaseMinutesPackageServiceTest.java @@ -48,7 +48,7 @@ public void getPackage() { } @Test - public void getPackageы() { + public void getPackages() { when(repository.findAll()).thenReturn(Arrays.asList(minutesPackageCatalog, minutesPackageCatalog2)); List result = service.getPackages(); diff --git a/src/test/java/ru/muchnik/yota/mobileservices/service/SimCardServiceTest.java b/src/test/java/ru/muchnik/yota/mobileservices/service/SimCardServiceTest.java index 781803c..62033e7 100644 --- a/src/test/java/ru/muchnik/yota/mobileservices/service/SimCardServiceTest.java +++ b/src/test/java/ru/muchnik/yota/mobileservices/service/SimCardServiceTest.java @@ -7,13 +7,16 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; -import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesPackageCatalog; -import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesDetails; import ru.muchnik.yota.mobileservices.model.entity.SimCard; +import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesDetails; +import ru.muchnik.yota.mobileservices.model.entity.minutes.MinutesPackageCatalog; +import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficDetails; +import ru.muchnik.yota.mobileservices.model.entity.traffic.TrafficPackageCatalog; import ru.muchnik.yota.mobileservices.model.exception.NotFoundException; -import ru.muchnik.yota.mobileservices.repository.minutes.MinutesDetailsRepository; import ru.muchnik.yota.mobileservices.repository.SimCardRepository; +import ru.muchnik.yota.mobileservices.repository.minutes.MinutesDetailsRepository; import ru.muchnik.yota.mobileservices.service.minutes.MinutesPackageService; +import ru.muchnik.yota.mobileservices.service.traffic.TrafficPackageService; import java.time.LocalDateTime; import java.util.ArrayList; @@ -31,6 +34,8 @@ public class SimCardServiceTest { @Mock private MinutesPackageService minutesPackageService; @Mock + private TrafficPackageService trafficPackageService; + @Mock private MinutesDetailsRepository detailsRepository; @InjectMocks @@ -42,6 +47,8 @@ public class SimCardServiceTest { @Mock private MinutesPackageCatalog basePackage; + @Mock + private TrafficPackageCatalog trafficBasePackage; @Before public void setUp() throws Exception { @@ -85,7 +92,7 @@ public void updateSimCardStatus() { Assert.assertFalse(simCard.isActive()); } - @Test (expected = NotFoundException.class) + @Test(expected = NotFoundException.class) public void updateSimCardStatusNotUpdated() { when(simCardRepository.getByNumber(eq(PHONE_NUMBER))).thenReturn(Optional.empty()); @@ -111,4 +118,24 @@ public void addMinutesPackageToSimCard() { Assert.assertTrue(resultDetails.getExpirationDate().isAfter(plusDays)); Assert.assertTrue(resultDetails.getActivationDate().compareTo(now) <= 0); } + + @Test + public void addTrafficPackageToSimCard() { + LocalDateTime plusDays = LocalDateTime.now().plusDays(3); + when(simCardRepository.getByNumber(eq(PHONE_NUMBER))).thenReturn(optionalSimCard); + when(trafficPackageService.getPackage(eq("1"))).thenReturn(trafficBasePackage); + ArrayList list = spy(new ArrayList<>()); + when(simCard.getTrafficDetails()).thenReturn(list); + + service.addTrafficPackageToSimCard(PHONE_NUMBER, "1", 2, 3); + LocalDateTime now = LocalDateTime.now(); + + verify(list).add(any(TrafficDetails.class)); + TrafficDetails resultDetails = list.get(0); + Assert.assertEquals(2, resultDetails.getGigabytesLeft()); + Assert.assertEquals(simCard, resultDetails.getSimCard()); + Assert.assertEquals(trafficBasePackage, resultDetails.getBasePackage()); + Assert.assertTrue(resultDetails.getExpirationDate().isAfter(plusDays)); + Assert.assertTrue(resultDetails.getActivationDate().compareTo(now) <= 0); + } } \ No newline at end of file