diff --git a/cypress/fixtures/diplomatic.json b/cypress/fixtures/diplomatic.json index a0a4f300..0c42eec5 100644 --- a/cypress/fixtures/diplomatic.json +++ b/cypress/fixtures/diplomatic.json @@ -47,6 +47,12 @@ "result": "Denmark", "description": "05" }, + { + "country": "malaysia", + "region": "98", + "result": "Senegal", + "description": "98" + }, { "country": "montenegro", "region": "11", diff --git a/cypress/fixtures/diplomaticsFlags.json b/cypress/fixtures/diplomaticsFlags.json index 2e942c15..9275aa9d 100644 --- a/cypress/fixtures/diplomaticsFlags.json +++ b/cypress/fixtures/diplomaticsFlags.json @@ -35,6 +35,10 @@ "country": "lithuania", "imageUrl": "Lithuanian_diplomatic_license_plate" }, + { + "country": "malaysia", + "imageUrl": "Vehicle_registration_plates_of_Malaysia" + }, { "country": "montenegro", "imageUrl": "Montenegro_diplomatic_license_plate" diff --git a/cypress/fixtures/flags/diplomatic.json b/cypress/fixtures/flags/diplomatic.json index 4c9df6bc..1e7da347 100644 --- a/cypress/fixtures/flags/diplomatic.json +++ b/cypress/fixtures/flags/diplomatic.json @@ -9,6 +9,7 @@ "๐Ÿ‡ฎ๐Ÿ‡นโ€ƒItaly", "๐Ÿ‡ฐ๐Ÿ‡ฌโ€ƒKyrgyzstan", "๐Ÿ‡ฑ๐Ÿ‡นโ€ƒLithuania", + "๐Ÿ‡ฒ๐Ÿ‡พโ€ƒMalaysia", "๐Ÿ‡ฒ๐Ÿ‡ชโ€ƒMontenegro", "๐Ÿ‡ณ๐Ÿ‡ดโ€ƒNorway", "๐Ÿ‡ต๐Ÿ‡ฑโ€ƒPoland", diff --git a/cypress/fixtures/flags/private.json b/cypress/fixtures/flags/private.json index 87d953df..023f8d0c 100644 --- a/cypress/fixtures/flags/private.json +++ b/cypress/fixtures/flags/private.json @@ -20,6 +20,7 @@ "๐Ÿ‡ฝ๐Ÿ‡ฐโ€ƒKosovo", "๐Ÿ‡ฐ๐Ÿ‡ฌโ€ƒKyrgyzstan", "๐Ÿ‡ฑ๐Ÿ‡นโ€ƒLithuania", + "๐Ÿ‡ฒ๐Ÿ‡พโ€ƒMalaysia", "๐Ÿ‡ฒ๐Ÿ‡ฉโ€ƒMoldova", "๐Ÿ‡ฒ๐Ÿ‡ชโ€ƒMontenegro", "๐Ÿ‡ณ๐Ÿ‡ดโ€ƒNorway", diff --git a/cypress/fixtures/regions.json b/cypress/fixtures/regions.json index e84c310c..4086db2d 100644 --- a/cypress/fixtures/regions.json +++ b/cypress/fixtures/regions.json @@ -113,6 +113,12 @@ "result": "Klaipฤ—da County", "description": "L" }, + { + "country": "malaysia", + "region": "A", + "result": "Perak", + "description": "A" + }, { "country": "moldova", "region": "BE", diff --git a/cypress/fixtures/regionsFlags.json b/cypress/fixtures/regionsFlags.json index f14977a7..6e86bb8b 100644 --- a/cypress/fixtures/regionsFlags.json +++ b/cypress/fixtures/regionsFlags.json @@ -1,139 +1,143 @@ [ - { - "country": "armenia", - "imageUrl": "armenia" - }, - { - "country": "austria", - "imageUrl": "Austrian" - }, - { - "country": "azerbaijan", - "imageUrl": "Azerbaijan" - }, - { - "country": "belarus", - "imageUrl": "Belarus" - }, - { - "country": "british", - "imageUrl": "GB-license-plate-infographics-en.jpg" - }, - { - "country": "bulgaria", - "imageUrl": "Bulgaria" - }, - { - "country": "croatia", - "imageUrl": "Delnice_HR" - }, - { - "country": "czech", - "imageUrl": "license-plate-infographics-en.jpg" - }, - { - "country": "estonia", - "imageUrl": "Estonian" - }, - { - "country": "france", - "imageUrl": "France" - }, - { - "country": "germany", - "imageUrl": "germany" - }, - { - "country": "greece", - "imageUrl": "Greek" - }, - { - "country": "hungary", - "imageUrl": "Hungarian" - }, - { - "country": "ireland", - "imageUrl": "Ireland" - }, - { - "country": "italian", - "imageUrl": "Italy" - }, - { - "country": "kazakhstan", - "imageUrl": "Kazakhstan" - }, - { - "country": "kosovo", - "imageUrl": "Kosovo" - }, - { - "country": "kyrgyzstan", - "imageUrl": "KG" - }, - { - "country": "lithuania", - "imageUrl": "Lithuania" - }, - { - "country": "moldova", - "imageUrl": "Moldova" - }, - { - "country": "montenegro", - "imageUrl": "Montenegro" - }, - { - "country": "norway", - "imageUrl": "Skilt_elbil" - }, - { - "country": "macedonia", - "imageUrl": "North_Macedonia" - }, - { - "country": "poland", - "imageUrl": "poland" - }, - { - "country": "romania", - "imageUrl": "Romanian" - }, - { - "country": "russia", - "imageUrl": "Russian" - }, - { - "country": "serbia", - "imageUrl": "Serbia" - }, - { - "country": "slovakia", - "imageUrl": "Slovak" - }, - { - "country": "slovenia", - "imageUrl": "Tablica_KR_-_Kranj" - }, - { - "country": "sweden", - "imageUrl": "Sweden" - }, - { - "country": "switzerland", - "imageUrl": "switzerland" - }, - { - "country": "turkey", - "imageUrl": "Turkey" - }, - { - "country": "ukraine", - "imageUrl": "Ukraine" - }, - { - "country": "uzbekistan", - "imageUrl": "Uzbekistan" - } - ] + { + "country": "armenia", + "imageUrl": "armenia" + }, + { + "country": "austria", + "imageUrl": "Austrian" + }, + { + "country": "azerbaijan", + "imageUrl": "Azerbaijan" + }, + { + "country": "belarus", + "imageUrl": "Belarus" + }, + { + "country": "british", + "imageUrl": "GB-license-plate-infographics-en.jpg" + }, + { + "country": "bulgaria", + "imageUrl": "Bulgaria" + }, + { + "country": "croatia", + "imageUrl": "Delnice_HR" + }, + { + "country": "czech", + "imageUrl": "license-plate-infographics-en.jpg" + }, + { + "country": "estonia", + "imageUrl": "Estonian" + }, + { + "country": "france", + "imageUrl": "France" + }, + { + "country": "germany", + "imageUrl": "germany" + }, + { + "country": "greece", + "imageUrl": "Greek" + }, + { + "country": "hungary", + "imageUrl": "Hungarian" + }, + { + "country": "ireland", + "imageUrl": "Ireland" + }, + { + "country": "italian", + "imageUrl": "Italy" + }, + { + "country": "kazakhstan", + "imageUrl": "Kazakhstan" + }, + { + "country": "kosovo", + "imageUrl": "Kosovo" + }, + { + "country": "kyrgyzstan", + "imageUrl": "KG" + }, + { + "country": "lithuania", + "imageUrl": "Lithuania" + }, + { + "country": "malaysia", + "imageUrl": "Vehicle_registration_plates_of_Malaysia" + }, + { + "country": "moldova", + "imageUrl": "Moldova" + }, + { + "country": "montenegro", + "imageUrl": "Montenegro" + }, + { + "country": "norway", + "imageUrl": "Skilt_elbil" + }, + { + "country": "macedonia", + "imageUrl": "North_Macedonia" + }, + { + "country": "poland", + "imageUrl": "poland" + }, + { + "country": "romania", + "imageUrl": "Romanian" + }, + { + "country": "russia", + "imageUrl": "Russian" + }, + { + "country": "serbia", + "imageUrl": "Serbia" + }, + { + "country": "slovakia", + "imageUrl": "Slovak" + }, + { + "country": "slovenia", + "imageUrl": "Tablica_KR_-_Kranj" + }, + { + "country": "sweden", + "imageUrl": "Sweden" + }, + { + "country": "switzerland", + "imageUrl": "switzerland" + }, + { + "country": "turkey", + "imageUrl": "Turkey" + }, + { + "country": "ukraine", + "imageUrl": "Ukraine" + }, + { + "country": "uzbekistan", + "imageUrl": "Uzbekistan" + } +] \ No newline at end of file diff --git a/frontend/src/App.js b/frontend/src/App.js index a62189be..7a50257d 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -35,6 +35,7 @@ function App() { "kosovo": "https://upload.wikimedia.org/wikipedia/en/thumb/a/a9/Kosovo_car_registration_plate_labels.svg/320px-Kosovo_car_registration_plate_labels.svg.png", "kyrgyzstan": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a1/Plak_shakhsi-KG.png/800px-Plak_shakhsi-KG.png", "lithuania": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f5/Lithuanian_license_plate.svg/1280px-Lithuanian_license_plate.svg.png", + "malaysia": "https://en.m.wikipedia.org/wiki/Vehicle_registration_plates_of_Malaysia#/media/File%3AMalaysia_penang_license_plate_front.JPG", "moldova": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/af/Moldova_MD_license_plate_ABC012_2015.svg/1024px-Moldova_MD_license_plate_ABC012_2015.svg.png", "montenegro": "https://upload.wikimedia.org/wikipedia/commons/f/f6/License_plate_Montenegro.jpg", "norway": "https://upload.wikimedia.org/wikipedia/commons/3/33/Skilt_elbil.jpg", @@ -63,6 +64,7 @@ let diplomaticImages = { "italian": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Targa_automobilistica_Italia_1985_CD%E2%80%A20213%E2%80%A2XG_Corpo_Diplomatico_Citt%C3%A0_del_Vaticano.jpg/1024px-Targa_automobilistica_Italia_1985_CD%E2%80%A20213%E2%80%A2XG_Corpo_Diplomatico_Citt%C3%A0_del_Vaticano.jpg", "kyrgyzstan": "https://upload.wikimedia.org/wikipedia/commons/3/38/Kyrgyzstan_diplomatic_technical_staff_license_plate.png", "lithuania": "https://upload.wikimedia.org/wikipedia/commons/8/8e/Lithuanian_diplomatic_license_plate.JPG?20120714185557", + "malaysia": "https://en.wikipedia.org/wiki/Vehicle_registration_plates_of_Malaysia#/media/File:Diplomat_Plate_Number.jpg", "montenegro": "https://upload.wikimedia.org/wikipedia/commons/0/08/Montenegro_diplomatic_license_plate_%28Norway%29.jpg", "norway": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ed/Norway_diplomatic_license_plate_CD_48160_2014_Oslo.jpg/1280px-Norway_diplomatic_license_plate_CD_48160_2014_Oslo.jpg", "portugal": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4c/Portugal_diplomatic_license_plate_200-CD530.jpg/800px-Portugal_diplomatic_license_plate_200-CD530.jpg", @@ -396,47 +398,48 @@ return ( />
- -
-
+ +
+
@@ -480,6 +483,7 @@ return ( + diff --git a/src/main/java/com/regions/simpleregions/controller/MalaysiaController.java b/src/main/java/com/regions/simpleregions/controller/MalaysiaController.java new file mode 100644 index 00000000..dc0d124c --- /dev/null +++ b/src/main/java/com/regions/simpleregions/controller/MalaysiaController.java @@ -0,0 +1,47 @@ +package com.regions.simpleregions.controller; + +import com.regions.simpleregions.entity.MalaysiaEntity; +import com.regions.simpleregions.exception.DescriptionNotFoundException; +import com.regions.simpleregions.exception.RegionNotFoundException; +import com.regions.simpleregions.service.MalaysiaService; +import lombok.Data; +import lombok.extern.log4j.Log4j2; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +@CrossOrigin("http://localhost:3000/") +@Log4j2 +@Data +@RestController +@RequestMapping("/api/v1/malaysia/plates") +public class MalaysiaController { + + private final MalaysiaService malaysiaService; + + @GetMapping("/region/{region}") + public ResponseEntity getMalaysiaPlatesByRegion(@Valid final @PathVariable("region") String region) { + try { + return ResponseEntity.ok(malaysiaService.getMalaysiaPlatesByRegion(region)); + } catch (final RegionNotFoundException | RuntimeException exception) { + log.debug("RegionNotFoundException", exception.getMessage()); + return ResponseEntity.badRequest().body(exception.getMessage()); + } + } + + @GetMapping("/description/{description}") + public ResponseEntity getMalaysiaPlatesByDescription(@Valid final @PathVariable("description") String description) { + try { + return ResponseEntity.ok(malaysiaService.getMalaysiaPlatesByDescription(description)); + } catch (final DescriptionNotFoundException | RuntimeException exception) { + log.debug("DescriptionNotFoundException", exception.getMessage()); + return ResponseEntity.badRequest().body(exception.getMessage()); + } + } + + @GetMapping("/all") + public ResponseEntity> getAllMalaysiaRegions() { + return ResponseEntity.ok(malaysiaService.getAllRegions()); + } +} diff --git a/src/main/java/com/regions/simpleregions/controller/MalaysiaDiplomaticController.java b/src/main/java/com/regions/simpleregions/controller/MalaysiaDiplomaticController.java new file mode 100644 index 00000000..844d766e --- /dev/null +++ b/src/main/java/com/regions/simpleregions/controller/MalaysiaDiplomaticController.java @@ -0,0 +1,48 @@ +package com.regions.simpleregions.controller; + + +import com.regions.simpleregions.entity.MalaysiaDiplomaticEntity; +import com.regions.simpleregions.exception.DescriptionNotFoundException; +import com.regions.simpleregions.exception.RegionNotFoundException; +import com.regions.simpleregions.service.MalaysiaDiplomaticService; +import lombok.Data; +import lombok.extern.log4j.Log4j2; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +@CrossOrigin("http://localhost:3000/") +@Log4j2 +@Data +@RestController +@RequestMapping("/api/v1/malaysia/diplomatic/plates") +public class MalaysiaDiplomaticController { + + private final MalaysiaDiplomaticService malaysiaDiplomaticService; + + @GetMapping("/region/{region}") + public ResponseEntity getMalaysiaDiplomaticPlatesByRegion(@Valid final @PathVariable("region") String region) { + try { + return ResponseEntity.ok(malaysiaDiplomaticService.getMalaysiaDiplomaticPlatesByRegion(region)); + } catch (final RegionNotFoundException | RuntimeException exception) { + log.debug("RegionNotFoundException", exception.getMessage()); + return ResponseEntity.badRequest().body(exception.getMessage()); + } + } + + @GetMapping("/description/{description}") + public ResponseEntity getMalaysiaDiplomaticPlatesByDescription(@Valid final @PathVariable("description") String description) { + try { + return ResponseEntity.ok(malaysiaDiplomaticService.getMalaysiaDiplomaticPlatesByDescription(description)); + } catch (final DescriptionNotFoundException | RuntimeException exception) { + log.debug("DescriptionNotFoundException", exception.getMessage()); + return ResponseEntity.badRequest().body(exception.getMessage()); + } + } + + @GetMapping("/all") + public ResponseEntity> getAllMalaysiaDiplomaticRegions() { + return ResponseEntity.ok(malaysiaDiplomaticService.getAllMalaysiaDiplomaticRegions()); + } +} diff --git a/src/main/java/com/regions/simpleregions/entity/MalaysiaDiplomaticEntity.java b/src/main/java/com/regions/simpleregions/entity/MalaysiaDiplomaticEntity.java new file mode 100644 index 00000000..3568c36a --- /dev/null +++ b/src/main/java/com/regions/simpleregions/entity/MalaysiaDiplomaticEntity.java @@ -0,0 +1,28 @@ +package com.regions.simpleregions.entity; + +import lombok.Data; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Size; + +@Data +@Entity +public class MalaysiaDiplomaticEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + @Size(min = 2, max = 4, message = "Min 2, Max 4") + @NotEmpty(message = "Field is mandatory") + @NotBlank(message = "Field is mandatory") + private String region; + + @Column(nullable = false) + @Size(min = 2, max = 30, message = "Min 2, Max 30") + @NotEmpty(message = "Field is mandatory") + @NotBlank(message = "Field is mandatory") + private String description; +} diff --git a/src/main/java/com/regions/simpleregions/entity/MalaysiaEntity.java b/src/main/java/com/regions/simpleregions/entity/MalaysiaEntity.java new file mode 100644 index 00000000..ade09f84 --- /dev/null +++ b/src/main/java/com/regions/simpleregions/entity/MalaysiaEntity.java @@ -0,0 +1,29 @@ +package com.regions.simpleregions.entity; + +import lombok.Data; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Size; + +@Data +@Entity +public class MalaysiaEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + @Size(min = 2, max = 4, message = "Min 2, Max 4") + @NotEmpty(message = "Field is mandatory") + @NotBlank(message = "Field is mandatory") + private String region; + + @Column(nullable = false) + @Size(min = 2, max = 30, message = "Min 2, Max 30") + @NotEmpty(message = "Field is mandatory") + @NotBlank(message = "Field is mandatory") + private String description; +} diff --git a/src/main/java/com/regions/simpleregions/model/MalaysiaDiplomaticModel.java b/src/main/java/com/regions/simpleregions/model/MalaysiaDiplomaticModel.java new file mode 100644 index 00000000..7fdc8c6c --- /dev/null +++ b/src/main/java/com/regions/simpleregions/model/MalaysiaDiplomaticModel.java @@ -0,0 +1,30 @@ +package com.regions.simpleregions.model; + +import com.regions.simpleregions.entity.MalaysiaDiplomaticEntity; +import lombok.Data; + +import java.util.Optional; + +@Data +public class MalaysiaDiplomaticModel { + + private String description; + + private String region; + + public static MalaysiaDiplomaticModel toModelByRegion(Optional entity) { + MalaysiaDiplomaticModel model = new MalaysiaDiplomaticModel(); + model.setDescription(entity.get().getDescription()); + model.setRegion(entity.get().getRegion()); + + return model; + } + + public static MalaysiaDiplomaticModel toModelByDescription(MalaysiaDiplomaticEntity entity) { + MalaysiaDiplomaticModel model = new MalaysiaDiplomaticModel(); + model.setDescription(entity.getDescription()); + model.setRegion(entity.getRegion()); + + return model; + } +} diff --git a/src/main/java/com/regions/simpleregions/model/MalaysiaModel.java b/src/main/java/com/regions/simpleregions/model/MalaysiaModel.java new file mode 100644 index 00000000..3e0e0db4 --- /dev/null +++ b/src/main/java/com/regions/simpleregions/model/MalaysiaModel.java @@ -0,0 +1,30 @@ +package com.regions.simpleregions.model; + +import com.regions.simpleregions.entity.MalaysiaEntity; +import lombok.Data; + +import java.util.Optional; + +@Data +public class MalaysiaModel { + + private String description; + + private String region; + + public static MalaysiaModel toModelByRegion(Optional entity) { + MalaysiaModel model = new MalaysiaModel(); + model.setDescription(entity.get().getDescription()); + model.setRegion(entity.get().getRegion()); + + return model; + } + + public static MalaysiaModel toModelByDescription(MalaysiaEntity entity) { + MalaysiaModel model = new MalaysiaModel(); + model.setDescription(entity.getDescription()); + model.setRegion(entity.getRegion()); + + return model; + } +} diff --git a/src/main/java/com/regions/simpleregions/respository/MalaysiaDiplomaticRepository.java b/src/main/java/com/regions/simpleregions/respository/MalaysiaDiplomaticRepository.java new file mode 100644 index 00000000..fd426221 --- /dev/null +++ b/src/main/java/com/regions/simpleregions/respository/MalaysiaDiplomaticRepository.java @@ -0,0 +1,17 @@ +package com.regions.simpleregions.respository; + +import com.regions.simpleregions.entity.MalaysiaDiplomaticEntity; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; +import org.springframework.web.bind.annotation.PathVariable; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface MalaysiaDiplomaticRepository extends CrudRepository { + Optional findByRegion(@PathVariable String region); + @Query("select malaysia from MalaysiaDiplomaticEntity malaysia WHERE malaysia.description LIKE CONCAT('%',:description,'%') order by malaysia.description asc ") + List findByDescription(@PathVariable String description); +} diff --git a/src/main/java/com/regions/simpleregions/respository/MalaysiaRepository.java b/src/main/java/com/regions/simpleregions/respository/MalaysiaRepository.java new file mode 100644 index 00000000..f168cba5 --- /dev/null +++ b/src/main/java/com/regions/simpleregions/respository/MalaysiaRepository.java @@ -0,0 +1,19 @@ +package com.regions.simpleregions.respository; + +import com.regions.simpleregions.entity.MalaysiaEntity; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; +import org.springframework.web.bind.annotation.PathVariable; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface MalaysiaRepository extends CrudRepository { + + Optional findByRegion(@PathVariable String region); + + @Query("select malaysia from MalaysiaEntity malaysia WHERE malaysia.description LIKE CONCAT('%',:description,'%') order by malaysia.description asc ") + List findByDescription(@PathVariable String description); +} diff --git a/src/main/java/com/regions/simpleregions/service/MalaysiaDiplomaticService.java b/src/main/java/com/regions/simpleregions/service/MalaysiaDiplomaticService.java new file mode 100644 index 00000000..443eff1c --- /dev/null +++ b/src/main/java/com/regions/simpleregions/service/MalaysiaDiplomaticService.java @@ -0,0 +1,60 @@ +package com.regions.simpleregions.service; + +import com.regions.simpleregions.entity.MalaysiaDiplomaticEntity; +import com.regions.simpleregions.exception.DescriptionNotFoundException; +import com.regions.simpleregions.exception.RegionNotFoundException; +import com.regions.simpleregions.model.MalaysiaDiplomaticModel; +import com.regions.simpleregions.respository.MalaysiaDiplomaticRepository; +import lombok.Data; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Log4j2 +@Data +@Service +public class MalaysiaDiplomaticService { + + private final MalaysiaDiplomaticRepository malaysiaDiplomaticRepository; + + @Value("${notification.region.message}") + private String regionNotFound; + + @Value("${notification.description.message}") + private String descriptionNotFound; + + @Cacheable(value = "montenegro_diplomatic_region", key = "#region") + public MalaysiaDiplomaticModel getMalaysiaDiplomaticPlatesByRegion(final String region) throws RegionNotFoundException { + log.info("Start method getMontenegroDiplomaticPlatesByRegion"); + Optional malaysiaRegion = malaysiaDiplomaticRepository.findByRegion(region); + + Optional.ofNullable(malaysiaRegion.stream().parallel().filter(malaysiaDiplomaticEntity -> malaysiaDiplomaticEntity.getRegion().equalsIgnoreCase(region)) + .findFirst() + .orElseThrow(() -> new RegionNotFoundException(String.format(regionNotFound, region)))); + + return MalaysiaDiplomaticModel.toModelByRegion(malaysiaRegion); + } + + @Cacheable(value = "montenegro_diplomatic_description", key = "#description") + public List getMalaysiaDiplomaticPlatesByDescription(final String description) throws DescriptionNotFoundException { + log.info("Start method getMontenegroDiplomaticPlatesByDescription"); + List malaysiaEntityList = malaysiaDiplomaticRepository.findByDescription(description); + + malaysiaEntityList.stream().parallel().map(montenegroEntity -> montenegroEntity + .getDescription() + .equalsIgnoreCase(description)) + .findAny() + .orElseThrow(() -> new DescriptionNotFoundException(String.format(descriptionNotFound, description))); + + return malaysiaEntityList.stream().map(MalaysiaDiplomaticModel::toModelByDescription).toList(); + } + + public Iterable getAllMalaysiaDiplomaticRegions() { + log.info("Start method getAllMontenegroDiplomaticRegions"); + return malaysiaDiplomaticRepository.findAll(); + } +} diff --git a/src/main/java/com/regions/simpleregions/service/MalaysiaService.java b/src/main/java/com/regions/simpleregions/service/MalaysiaService.java new file mode 100644 index 00000000..66d15b92 --- /dev/null +++ b/src/main/java/com/regions/simpleregions/service/MalaysiaService.java @@ -0,0 +1,57 @@ +package com.regions.simpleregions.service; + +import com.regions.simpleregions.entity.MalaysiaEntity; +import com.regions.simpleregions.exception.DescriptionNotFoundException; +import com.regions.simpleregions.exception.RegionNotFoundException; +import com.regions.simpleregions.model.MalaysiaModel; +import com.regions.simpleregions.respository.MalaysiaRepository; +import lombok.Data; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Log4j2 +@Data +@Service +public class MalaysiaService { + + private final MalaysiaRepository malaysiaRepository; + + @Value("${notification.region.message}") + private String regionNotFound; + + @Value("${notification.description.message}") + private String descriptionNotFound; + + @Cacheable(value = "moldova_region", key = "#region") + public MalaysiaModel getMalaysiaPlatesByRegion(final String region) throws RegionNotFoundException { + log.info("Start method getMoldovaPlatesByRegion"); + Optional malaysiaRegion = malaysiaRepository.findByRegion(region); + + Optional.ofNullable(malaysiaRegion.stream().parallel().filter(malaysiaEntity -> malaysiaEntity.getRegion().equalsIgnoreCase(region)).findFirst().orElseThrow(() -> + + new RegionNotFoundException(String.format(regionNotFound, region)))); + + return MalaysiaModel.toModelByRegion(malaysiaRegion); + } + + @Cacheable(value = "moldova_description", key = "#description") + public List getMalaysiaPlatesByDescription(final String description) throws DescriptionNotFoundException { + log.info("Start method getMoldovaPlatesByDescription"); + List malaysiaEntityList = malaysiaRepository.findByDescription(description); + + malaysiaEntityList.stream().parallel().map(malaysiaEntity -> malaysiaEntity.getDescription().equalsIgnoreCase(description)).findAny().orElseThrow(() -> + new DescriptionNotFoundException(String.format(descriptionNotFound, description))); + + return malaysiaEntityList.stream().map(MalaysiaModel::toModelByDescription).toList(); + } + + public Iterable getAllRegions() { + log.info("Start method getAllRegions"); + return malaysiaRepository.findAll(); + } +} diff --git a/src/main/resources/sql/countries/malaysia.sql b/src/main/resources/sql/countries/malaysia.sql new file mode 100644 index 00000000..532e5a27 --- /dev/null +++ b/src/main/resources/sql/countries/malaysia.sql @@ -0,0 +1,29 @@ +DROP TABLE IF EXISTS `malaysia_entity`; + +CREATE TABLE `malaysia_entity` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `description` varchar(255) DEFAULT NULL, + `region` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +LOCK TABLES `malaysia_entity` WRITE; +/*!40000 ALTER TABLE `moldova_entity` DISABLE KEYS */; +INSERT INTO `malaysia_entity` (description, region) VALUES +('Perak','A'), +('Selangor','B'), +('Pahang','C'), +('Kelantan','D'), +('Putrajaya','F'), +('Johor','J'), +('Kedah','K'), +('Malacca','M'), +('Negeri Sembilan','N'), +('Penang','P'), +('Perlis','R'), +('Terengganu','T'), +('Kuala Lumpur','V'), +('Kuala Lumpur','W'); +UNLOCK TABLES; + +ALTER TABLE malaysia_entity ADD INDEX malaysia_index (description, region); diff --git a/src/main/resources/sql/diplomatic/malaysia_diplomatic.sql b/src/main/resources/sql/diplomatic/malaysia_diplomatic.sql new file mode 100644 index 00000000..3c200fd2 --- /dev/null +++ b/src/main/resources/sql/diplomatic/malaysia_diplomatic.sql @@ -0,0 +1,113 @@ +DROP TABLE IF EXISTS `malaysia_diplomatic_entity`; +CREATE TABLE `malaysia_diplomatic_entity` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `description` varchar(255) DEFAULT NULL, + `region` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +LOCK TABLES `malaysia_diplomatic_entity` WRITE; +INSERT INTO `malaysia_diplomatic_entity` (description, region) VALUES +('Sri Lanka','10'), +('Thailand','11'), +('Switzerland','12'), +('Libya','14'), +('Australia','15'), +('United States','16'), +('Pakistan','17'), +('Germany','18'), +('Bangladesh','19'), +('Syria','21'), +('Canada','22'), +('Netherlands','23'), +('Russia','24'), +('Belgium','25'), +('Philippines','26'), +('Romania','27'), +('Indonesia','29'), +('Poland','30'), +('Eswatini','31'), +('Egypt','31'), +('Sweden','32'), +('Cambodia','34'), +('New Zealand','35'), +('South Korea','36'), +('Austria','37'), +('United Kingdom','38'), +('Singapore','39'), +('India','40'), +('Myanmar','41'), +('Vietnam','42'), +('Denmark','43'), +('Iraq','44'), +('Seychelles','45'), +('Japan','46'), +('France','47'), +('Saudi Arabia','48'), +('China','49'), +('Czech Republic','50'), +('Turkey','51'), +('Slovakia','52'), +('Finland','53'), +('Kuwait','54'), +('Brazil','55'), +('Timor-Leste','56'), +('Iran','57'), +('Brunei','58'), +('Oman','59'), +('Norway','60'), +('Palestine','61'), +('Argentina','62'), +('Ukraine','63'), +('Spain','64'), +('Fiji','65'), +('Morocco','66'), +('Mauritius','67'), +('Chile','68'), +('Sudan','69'), +('Nigeria','70'), +('Mexico','71'), +('Laos','72'), +('Venezuela','73'), +('Zimbabwe','74'), +('Hungary','75'), +('Peru','76'), +('Algeria','77'), +('Albania','78'), +('South Africa','79'), +('Bosnia and Herzegovina','80'), +('Ecuador','81'), +('Uruguay','82'), +('Ireland','83'), +('Colombia','84'), +('United Arab Emirates','85'), +('Croatia','86'), +('Afghanistan','87'), +('Namibia','88'), +('Uzbekistan','89'), +('Luxembourg','90'), +('Kenya','91'), +('Guinea','92'), +('Kazakhstan','93'), +('Ghana','94'), +('Kyrgyzstan','95'), +('Jordan','96'), +('Cuba','97'), +('Senegal','98'), +('Yemen','99'), +('European Union','100'), +('Nepal','101'), +('Papua New Guinea','102'), +('Lebanon','103'), +('Qatar','104'), +('Maldives','105'), +('Azerbaijan','107'), +('Zambia','109'), +('Vatican City','110'), +('Somalia','111'), +('Georgia','114'), +('Gambia','115'), +('Tajikistan','117'); +UNLOCK TABLES; + +ALTER TABLE malaysia_diplomatic_entity ADD INDEX malaysia_diplomatic_index (description, region); \ No newline at end of file diff --git a/src/test/java/com/regions/simpleregions/countries/SimpleIntegrationMalaysiaTest.java b/src/test/java/com/regions/simpleregions/countries/SimpleIntegrationMalaysiaTest.java new file mode 100644 index 00000000..54ba3460 --- /dev/null +++ b/src/test/java/com/regions/simpleregions/countries/SimpleIntegrationMalaysiaTest.java @@ -0,0 +1,134 @@ +package com.regions.simpleregions.countries; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@AutoConfigureMockMvc +class SimpleIntegrationMalaysiaTest { + @Autowired + private MockMvc mockMvc; + + @Value("${notification.description.message}") + private String descriptionNotFound; + + @Value("${notification.region.message}") + private String regionNotFound; + + private final String PATH = "/api/v1/malaysia/plates"; + + @Value("${http.auth-token-header-name}") + private String headerName; + + @Value("${http.auth-token}") + private String authToken; + + @Test + void getRegionHandle_whenGetMalaysiaPlatesByRegion_thenStatus200() throws Exception { + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/region/R") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.region").isNotEmpty()) + .andExpect(jsonPath("$.region", equalTo("R"))) + .andExpect(jsonPath("$.description").isNotEmpty()) + .andExpect(jsonPath("$.description", equalTo("Perlis"))); + } + + @Test + void getRegionHandle_whenGetMalaysiaPlatesByDescription_thenStatus200() throws Exception { + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/description/Perlis") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[*]").isNotEmpty()) + .andExpect(jsonPath("$[*].region").isNotEmpty()) + .andExpect(jsonPath("$[*].description").isNotEmpty()) + .andExpect(jsonPath("$[*]", hasSize(1))); + } + + @Test + void getRegionHandle_whenGetMalaysiaPlatesByDescriptionContains_thenStatus200() throws Exception { + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/description/Per") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].region", equalTo("A"))) + .andExpect(jsonPath("$[0].description", equalTo("Perak"))); + } + + @Test + void getRegionHandle_whenGetAllMalaysiaRegions_thenStatus200() throws Exception { + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/all") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[*]").isNotEmpty()) + .andExpect(jsonPath("$[*]", hasSize(14))); + } + + @Test + void getRegionHandle_whenGetMalaysiaPlatesWithoutDescription_thenStatus404() throws Exception { + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/description/") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isNotFound()); + } + + @Test + void getRegionHandle_whenGetMalaysiaPlatesWithoutRegion_thenStatus404() throws Exception { + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/region/") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isNotFound()); + } + + @Test + void getRegionHandle_whenExceptionMalaysiaPlatesByRegion_thenStatus400() throws Exception { + String region = "I"; + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/region/" + region) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isBadRequest()) + .andExpect(MockMvcResultMatchers.content().string(String.format(regionNotFound, region))); + } + + @Test + void getRegionHandle_whenExceptionMalaysiaPlatesByDescription_thenStatus400() throws Exception { + String description = "WWWWWWW"; + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/description/" + description) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isBadRequest()) + .andExpect(MockMvcResultMatchers.content().string(String.format(descriptionNotFound, description))); + } + + @Test + void getRegionHandle_whenGetMalaysiaWithoutApiKey_thenStatus200() throws Exception { + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/region/") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isForbidden()); + } +} diff --git a/src/test/java/com/regions/simpleregions/diplomatic/SimpleIntegrationMalaysiaDiplomaticTest.java b/src/test/java/com/regions/simpleregions/diplomatic/SimpleIntegrationMalaysiaDiplomaticTest.java new file mode 100644 index 00000000..24385f26 --- /dev/null +++ b/src/test/java/com/regions/simpleregions/diplomatic/SimpleIntegrationMalaysiaDiplomaticTest.java @@ -0,0 +1,135 @@ +package com.regions.simpleregions.diplomatic; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@AutoConfigureMockMvc +class SimpleIntegrationMalaysiaDiplomaticTest { + @Autowired + private MockMvc mockMvc; + + @Value("${notification.description.message}") + private String descriptionNotFound; + + @Value("${notification.region.message}") + private String regionNotFound; + + private final String PATH = "/api/v1/malaysia/diplomatic/plates"; + + @Value("${http.auth-token-header-name}") + private String headerName; + + @Value("${http.auth-token}") + private String authToken; + + @Test + void getRegionHandle_whenGetMalaysia_thenStatus200() throws Exception { + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/region/98") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.region").isNotEmpty()) + .andExpect(jsonPath("$.region", equalTo("98"))) + .andExpect(jsonPath("$.description").isNotEmpty()) + .andExpect(jsonPath("$.description", equalTo("Senegal"))); + } + + @Test + void getRegionHandle_whenGetMalaysiaPlatesByDescription_thenStatus200() throws Exception { + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/description/Senegal") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[*]").isNotEmpty()) + .andExpect(jsonPath("$[*].region").isNotEmpty()) + .andExpect(jsonPath("$[*].description").isNotEmpty()) + .andExpect(jsonPath("$[*]", hasSize(1))); + } + + @Test + void getRegionHandle_whenGetMalaysiaPlatesByDescriptionContains_thenStatus200() throws Exception { + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/description/Sen") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].region", equalTo("98"))) + .andExpect(jsonPath("$[0].description", equalTo("Senegal"))); + } + + @Test + void getRegionHandle_whenGetAllMalaysiaPlatesRegions_thenStatus200() throws Exception { + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/all") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[*]").isNotEmpty()) + .andExpect(jsonPath("$[*]", hasSize(100))); + } + + @Test + void getRegionHandle_whenGetMalaysiaPlatesWithoutDescription_thenStatus404() throws Exception { + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/description/") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isNotFound()); + } + + @Test + void getRegionHandle_whenGetMalaysiaPlatesWithoutRegion_thenStatus404() throws Exception { + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/region/") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isNotFound()); + } + + @Test + void getRegionHandle_whenExceptionMalaysiaPlatesByRegion_thenStatus400() throws Exception { + String region = "600"; + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/region/" + region) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isBadRequest()) + .andExpect(MockMvcResultMatchers.content().string(String.format(regionNotFound, region))); + + } + + @Test + void getRegionHandle_whenExceptionMalaysiaPlatesByDescription_thenStatus400() throws Exception { + String description = "WWWWWWW"; + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/description/" + description) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON).header(headerName, authToken)) + .andExpect(status().isBadRequest()) + .andExpect(MockMvcResultMatchers.content().string(String.format(descriptionNotFound, description))); + } + + @Test + void getRegionHandle_whenGetMalaysiaWithoutApiKey_thenStatus200() throws Exception { + mockMvc.perform(MockMvcRequestBuilders + .get(PATH + "/region/") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isForbidden()); + } +}