├── .env.default ├── .gitignore ├── .travis.yml ├── README.md ├── docker-compose.yml ├── eatgo-admin-api ├── build.gradle └── src │ ├── main │ ├── java │ │ └── kr │ │ │ └── co │ │ │ └── fastcampus │ │ │ └── eatgo │ │ │ ├── EatgoAdminApiApplication.java │ │ │ ├── application │ │ │ ├── CategoryService.java │ │ │ ├── MenuItemService.java │ │ │ ├── RegionService.java │ │ │ ├── RestaurantService.java │ │ │ ├── ReviewService.java │ │ │ └── UserService.java │ │ │ └── interfaces │ │ │ ├── CategoryController.java │ │ │ ├── MenuItemController.java │ │ │ ├── RegionController.java │ │ │ ├── RestaurantController.java │ │ │ ├── RestaurantErrorAdvice.java │ │ │ ├── ReviewController.java │ │ │ ├── UserController.java │ │ │ └── WelcomeController.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── kr │ └── co │ └── fastcampus │ └── eatgo │ ├── EatgoAdminApiApplicationTests.java │ ├── application │ ├── CategoryServiceTests.java │ ├── MenuItemServiceTests.java │ ├── RegionServiceTests.java │ ├── RestaurantServiceTests.java │ ├── ReviewServiceTests.java │ └── UserServiceTests.java │ └── interfaces │ ├── CategoryControllerTests.java │ ├── MenuItemControllerTests.java │ ├── RegionControllerTests.java │ ├── RestaurantControllerTests.java │ ├── ReviewControllerTests.java │ └── UserControllerTests.java ├── eatgo-admin-web ├── .browserslistrc ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── .nvmrc ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── App.vue │ ├── components │ │ └── GlobalNavigator.vue │ ├── main.js │ ├── router.js │ ├── store │ │ ├── actions.js │ │ ├── http.js │ │ ├── index.js │ │ └── mutations.js │ └── views │ │ ├── CategoryList.vue │ │ ├── CategoryNew.vue │ │ ├── Home.vue │ │ ├── Login.vue │ │ ├── MenuItems.vue │ │ ├── RegionList.vue │ │ ├── RegionNew.vue │ │ ├── RestaurantEdit.vue │ │ ├── RestaurantList.vue │ │ ├── RestaurantNew.vue │ │ ├── ReviewList.vue │ │ └── UserList.vue └── vue.config.js ├── eatgo-common ├── build.gradle └── src │ ├── main │ └── java │ │ └── kr │ │ └── co │ │ └── fastcampus │ │ └── eatgo │ │ ├── domain │ │ ├── Category.java │ │ ├── CategoryRepository.java │ │ ├── MenuItem.java │ │ ├── MenuItemRepository.java │ │ ├── Region.java │ │ ├── RegionRepository.java │ │ ├── Reservation.java │ │ ├── ReservationRepository.java │ │ ├── Restaurant.java │ │ ├── RestaurantNotFoundException.java │ │ ├── RestaurantRepository.java │ │ ├── Review.java │ │ ├── ReviewRepository.java │ │ ├── User.java │ │ └── UserRepository.java │ │ └── utils │ │ └── JwtUtil.java │ └── test │ └── java │ └── kr │ └── co │ └── fastcampus │ └── eatgo │ ├── domain │ ├── CategoryTests.java │ ├── RegionTests.java │ ├── RestaurantTests.java │ └── UserTests.java │ └── utils │ └── JwtUtilTests.java ├── eatgo-customer-api ├── build.gradle └── src │ ├── main │ ├── java │ │ └── kr │ │ │ └── co │ │ │ └── fastcampus │ │ │ └── eatgo │ │ │ ├── EatgoCustomerApiApplication.java │ │ │ ├── SecurityJavaConfig.java │ │ │ ├── application │ │ │ ├── CategoryService.java │ │ │ ├── EmailExistedException.java │ │ │ ├── RegionService.java │ │ │ ├── ReservationService.java │ │ │ ├── RestaurantService.java │ │ │ ├── ReviewService.java │ │ │ └── UserService.java │ │ │ ├── filters │ │ │ └── JwtAuthenticationFilter.java │ │ │ └── interfaces │ │ │ ├── CategoryController.java │ │ │ ├── RegionController.java │ │ │ ├── ReservationController.java │ │ │ ├── RestaurantController.java │ │ │ ├── RestaurantErrorAdvice.java │ │ │ ├── ReviewController.java │ │ │ ├── UserController.java │ │ │ └── WelcomeController.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── kr │ └── co │ └── fastcampus │ └── eatgo │ ├── EatgoCustomerApiApplicationTests.java │ ├── application │ ├── CategoryServiceTests.java │ ├── RegionServiceTests.java │ ├── ReservationServiceTests.java │ ├── RestaurantServiceTests.java │ ├── ReviewServiceTests.java │ └── UserServiceTests.java │ └── interfaces │ ├── CategoryControllerTests.java │ ├── RegionControllerTests.java │ ├── ReservationControllerTests.java │ ├── RestaurantControllerTest.java │ ├── ReviewControllerTests.java │ ├── UserControllerTests.java │ └── WelcomeControllerTests.java ├── eatgo-customer-web ├── .browserslistrc ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── .nvmrc ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── App.vue │ ├── components │ │ └── GlobalNavigator.vue │ ├── main.js │ ├── router.js │ ├── store │ │ ├── actions.js │ │ ├── http.js │ │ ├── index.js │ │ └── mutations.js │ └── views │ │ ├── Home.vue │ │ ├── Login.vue │ │ ├── RestaurantDetail.vue │ │ └── RestaurantList.vue └── vue.config.js ├── eatgo-login-api ├── build.gradle └── src │ ├── main │ ├── java │ │ └── kr │ │ │ └── co │ │ │ └── fastcampus │ │ │ └── eatgo │ │ │ ├── EatgoLoginApiApplication.java │ │ │ ├── SecurityJavaConfig.java │ │ │ ├── application │ │ │ ├── EmailNotExistedException.java │ │ │ ├── PasswordWrongException.java │ │ │ └── UserService.java │ │ │ └── interfaces │ │ │ ├── SessionController.java │ │ │ ├── SessionErrorAdvice.java │ │ │ ├── SessionRequestDto.java │ │ │ └── SessionResponseDto.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── kr │ └── co │ └── fastcampus │ └── eatgo │ ├── EatgoLoginApiApplicationTests.java │ ├── application │ └── UserServiceTests.java │ └── interfaces │ └── SessionControllerTests.java ├── eatgo-restaurant-api ├── build.gradle └── src │ ├── main │ ├── java │ │ └── kr │ │ │ └── co │ │ │ └── fastcampus │ │ │ └── eatgo │ │ │ ├── EatgoRestaurantApiApplication.java │ │ │ ├── SecurityJavaConfig.java │ │ │ ├── application │ │ │ └── ReservationService.java │ │ │ ├── filters │ │ │ └── JwtAuthenticationFilter.java │ │ │ └── interfaces │ │ │ └── ReservationController.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── kr │ └── co │ └── fastcampus │ └── eatgo │ ├── EatgoRestaurantApiApplicationTests.java │ ├── application │ └── ReservationServiceTests.java │ └── interfaces │ └── ReservationControllerTests.java ├── eatgo-restaurant-web ├── .browserslistrc ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── .nvmrc ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── App.vue │ ├── components │ │ └── GlobalNavigator.vue │ ├── main.js │ ├── router.js │ ├── store │ │ ├── actions.js │ │ ├── http.js │ │ ├── index.js │ │ └── mutations.js │ └── views │ │ ├── Home.vue │ │ ├── Login.vue │ │ └── ReservationList.vue └── vue.config.js ├── eatgo-web ├── .gitignore ├── .nvmrc ├── index.html ├── package-lock.json ├── package.json └── src │ └── index.js ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── run.sh └── settings.gradle /.env.default: -------------------------------------------------------------------------------- 1 | MYSQL_ROOT_PASSWORD=password 2 | MYSQL_USER=root 3 | MYSQL_PASSWORD=password 4 | MYSQL_DATABASE=eatgo 5 | MYSQL_HOST=mysql 6 | 7 | SPRING_PROFILES_ACTIVE=mysql 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | 6 | ### STS ### 7 | .apt_generated 8 | .classpath 9 | .factorypath 10 | .project 11 | .settings 12 | .springBeans 13 | .sts4-cache 14 | 15 | ### IntelliJ IDEA ### 16 | .idea 17 | *.iws 18 | *.iml 19 | *.ipr 20 | out/ 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | 29 | ### VS Code ### 30 | .vscode/ 31 | 32 | 33 | ### .env 34 | /.env 35 | 36 | ### data 37 | /data 38 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - openjdk8 4 | 5 | script: 6 | - ./gradlew check 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EatGo 2 | 3 | [![Build Status](https://travis-ci.org/ahastudio/fastcampus-eatgo.svg?branch=master)](https://travis-ci.org/ahastudio/fastcampus-eatgo) 4 | 5 | “Fast Campus 올인원 패키지: Java 웹 개발 마스터” 실전 프로젝트. 6 | 7 | ## Test all 8 | 9 | ```bash 10 | SPRING_PROFILES_ACTIVE=test ./gradlew cleanTest test 11 | ``` 12 | 13 | ## Build JAR 14 | 15 | ```bash 16 | ./gradlew bootJar 17 | ``` 18 | 19 | ## Install dependencies for web 20 | 21 | ```bash 22 | bash -c "cd eatgo-admin-web && npm install" 23 | bash -c "cd eatgo-customer-web && npm install" 24 | bash -c "cd eatgo-restaurant-web && npm install" 25 | ``` 26 | 27 | ## Run with Docker 28 | 29 | ```bash 30 | # Docker용 환경 설정 파일을 복사합니다. 31 | # .env 파일은 필요에 따라 수정해서 사용하시면 됩니다. 32 | cp .env.default .env 33 | 34 | # 컨테이너를 모두 실행합니다. 35 | docker-compose up 36 | ``` 37 | 38 | 웹 프론트엔드 확인: 39 | 40 | - Admin: 41 | - Customer: 42 | - Restaurant: 43 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mysql: 4 | image: mariadb:10.4.7 5 | env_file: .env 6 | volumes: 7 | - ./data/mariadb:/var/lib/mysql 8 | ports: 9 | - 13306:3306 10 | command: | 11 | --character-set-server=utf8mb4 12 | --collation-server=utf8mb4_unicode_ci 13 | healthcheck: 14 | test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"] 15 | timeout: 10s 16 | retries: 10 17 | login-api: 18 | image: openjdk:8 19 | env_file: .env 20 | volumes: 21 | - ./run.sh:/home/eatgo/run.sh 22 | - ./eatgo-login-api/build/libs:/home/eatgo/libs 23 | ports: 24 | - 8001:8080 25 | depends_on: 26 | - mysql 27 | command: bash -c "cd /home/eatgo && sh run.sh" 28 | admin-api: 29 | image: openjdk:8 30 | env_file: .env 31 | volumes: 32 | - ./run.sh:/home/eatgo/run.sh 33 | - ./eatgo-admin-api/build/libs:/home/eatgo/libs 34 | ports: 35 | - 8002:8080 36 | depends_on: 37 | - mysql 38 | command: bash -c "cd /home/eatgo && sh run.sh" 39 | customer-api: 40 | image: openjdk:8 41 | env_file: .env 42 | volumes: 43 | - ./run.sh:/home/eatgo/run.sh 44 | - ./eatgo-customer-api/build/libs:/home/eatgo/libs 45 | ports: 46 | - 8003:8080 47 | depends_on: 48 | - mysql 49 | command: bash -c "cd /home/eatgo && sh run.sh" 50 | restaurant-api: 51 | image: openjdk:8 52 | env_file: .env 53 | volumes: 54 | - ./run.sh:/home/eatgo/run.sh 55 | - ./eatgo-restaurant-api/build/libs:/home/eatgo/libs 56 | ports: 57 | - 8004:8080 58 | depends_on: 59 | - mysql 60 | command: bash -c "cd /home/eatgo && sh run.sh" 61 | admin-web: 62 | image: node:10.16.3 63 | volumes: 64 | - ./eatgo-admin-web:/home/eatgo 65 | ports: 66 | - 8082:3000 67 | environment: 68 | - VUE_APP_API_BASE_URL=http://localhost:8002 69 | - VUE_APP_LOGIN_API_BASE_URL=http://localhost:8001 70 | command: bash -c "cd /home/eatgo && npm run serve" 71 | healthcheck: 72 | test: curl -sS http://localhost:8080 || exit 1 73 | timeout: 10s 74 | retries: 10 75 | customer-web: 76 | image: node:10.16.3 77 | volumes: 78 | - ./eatgo-customer-web:/home/eatgo 79 | ports: 80 | - 8083:3000 81 | environment: 82 | - VUE_APP_API_BASE_URL=http://localhost:8003 83 | - VUE_APP_LOGIN_API_BASE_URL=http://localhost:8001 84 | command: bash -c "cd /home/eatgo && npm run serve" 85 | healthcheck: 86 | test: curl -sS http://localhost:8080 || exit 1 87 | timeout: 10s 88 | retries: 10 89 | restaurant-web: 90 | image: node:10.16.3 91 | volumes: 92 | - ./eatgo-restaurant-web:/home/eatgo 93 | ports: 94 | - 8084:3000 95 | environment: 96 | - VUE_APP_API_BASE_URL=http://localhost:8004 97 | - VUE_APP_LOGIN_API_BASE_URL=http://localhost:8001 98 | command: bash -c "cd /home/eatgo && npm run serve" 99 | healthcheck: 100 | test: curl -sS http://localhost:8080 || exit 1 101 | timeout: 10s 102 | retries: 10 103 | -------------------------------------------------------------------------------- /eatgo-admin-api/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.2.1.RELEASE' 3 | id 'io.spring.dependency-management' version '1.0.8.RELEASE' 4 | id 'java' 5 | } 6 | 7 | group = 'kr.co.fastcampus' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '1.8' 10 | 11 | configurations { 12 | developmentOnly 13 | runtimeClasspath { 14 | extendsFrom developmentOnly 15 | } 16 | compileOnly { 17 | extendsFrom annotationProcessor 18 | } 19 | } 20 | 21 | repositories { 22 | mavenCentral() 23 | } 24 | 25 | dependencies { 26 | implementation project(':eatgo-common') 27 | 28 | implementation 'org.springframework.boot:spring-boot-starter-web' 29 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 30 | 31 | implementation 'com.h2database:h2' 32 | implementation 'mysql:mysql-connector-java' 33 | 34 | compileOnly 'org.projectlombok:lombok' 35 | 36 | developmentOnly 'org.springframework.boot:spring-boot-devtools' 37 | 38 | annotationProcessor 'org.projectlombok:lombok' 39 | 40 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 41 | } 42 | 43 | test { 44 | useJUnitPlatform() 45 | } 46 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/EatgoAdminApiApplication.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class EatgoAdminApiApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(EatgoAdminApiApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/application/CategoryService.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Category; 4 | import kr.co.fastcampus.eatgo.domain.CategoryRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.transaction.Transactional; 9 | import java.util.List; 10 | 11 | @Service 12 | @Transactional 13 | public class CategoryService { 14 | 15 | private CategoryRepository categoryRepository; 16 | 17 | @Autowired 18 | public CategoryService(CategoryRepository categoryRepository) { 19 | this.categoryRepository = categoryRepository; 20 | } 21 | 22 | public List getCategories() { 23 | List categories = categoryRepository.findAll(); 24 | 25 | return categories; 26 | } 27 | 28 | public Category addCategory(String name) { 29 | Category category = Category.builder().name(name).build(); 30 | 31 | categoryRepository.save(category); 32 | 33 | return category; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/application/MenuItemService.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.MenuItem; 4 | import kr.co.fastcampus.eatgo.domain.MenuItemRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.transaction.Transactional; 9 | import java.util.List; 10 | 11 | @Service 12 | @Transactional 13 | public class MenuItemService { 14 | 15 | private MenuItemRepository menuItemRepository; 16 | 17 | @Autowired 18 | public MenuItemService(MenuItemRepository menuItemRepository) { 19 | this.menuItemRepository = menuItemRepository; 20 | } 21 | 22 | public List getMenuItems(Long restaurantId) { 23 | return menuItemRepository.findAllByRestaurantId(restaurantId); 24 | } 25 | 26 | public void bulkUpdate(Long restaurantId, List menuItems) { 27 | for (MenuItem menuItem : menuItems) { 28 | update(restaurantId, menuItem); 29 | } 30 | } 31 | 32 | private void update(Long restaurantId, MenuItem menuItem) { 33 | if (menuItem.isDestroy()) { 34 | menuItemRepository.deleteById(menuItem.getId()); 35 | return; 36 | } 37 | 38 | menuItem.setRestaurantId(restaurantId); 39 | menuItemRepository.save(menuItem); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/application/RegionService.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Region; 4 | import kr.co.fastcampus.eatgo.domain.RegionRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.transaction.Transactional; 9 | import java.util.List; 10 | 11 | @Service 12 | @Transactional 13 | public class RegionService { 14 | 15 | private RegionRepository regionRepository; 16 | 17 | @Autowired 18 | public RegionService(RegionRepository regionRepository) { 19 | this.regionRepository = regionRepository; 20 | } 21 | 22 | public List getRegions() { 23 | List regions = regionRepository.findAll(); 24 | 25 | return regions; 26 | } 27 | 28 | public Region addRegion(String name) { 29 | Region region = Region.builder().name(name).build(); 30 | 31 | regionRepository.save(region); 32 | 33 | return region; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/application/RestaurantService.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Restaurant; 4 | import kr.co.fastcampus.eatgo.domain.RestaurantNotFoundException; 5 | import kr.co.fastcampus.eatgo.domain.RestaurantRepository; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import javax.transaction.Transactional; 10 | import java.util.List; 11 | 12 | @Service 13 | @Transactional 14 | public class RestaurantService { 15 | 16 | private RestaurantRepository restaurantRepository; 17 | 18 | @Autowired 19 | public RestaurantService(RestaurantRepository restaurantRepository) { 20 | this.restaurantRepository = restaurantRepository; 21 | } 22 | 23 | public List getRestaurants() { 24 | List restaurants = restaurantRepository.findAll(); 25 | 26 | return restaurants; 27 | } 28 | 29 | public Restaurant getRestaurant(Long id) { 30 | Restaurant restaurant = restaurantRepository.findById(id) 31 | .orElseThrow(() -> new RestaurantNotFoundException(id)); 32 | 33 | return restaurant; 34 | } 35 | 36 | public Restaurant addRestaurant(Restaurant restaurant) { 37 | return restaurantRepository.save(restaurant); 38 | } 39 | 40 | @Transactional 41 | public Restaurant updateRestaurant(Long id, Long categoryId, 42 | String name, String address) { 43 | Restaurant restaurant = restaurantRepository.findById(id).orElse(null); 44 | 45 | restaurant.updateInformation(categoryId, name, address); 46 | 47 | return restaurant; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/application/ReviewService.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Review; 4 | import kr.co.fastcampus.eatgo.domain.ReviewRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.transaction.Transactional; 9 | import java.util.List; 10 | 11 | @Service 12 | @Transactional 13 | public class ReviewService { 14 | 15 | private ReviewRepository reviewRepository; 16 | 17 | @Autowired 18 | public ReviewService(ReviewRepository reviewRepository) { 19 | this.reviewRepository = reviewRepository; 20 | } 21 | 22 | public List getReviews() { 23 | return reviewRepository.findAll(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/application/UserService.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.User; 4 | import kr.co.fastcampus.eatgo.domain.UserRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.transaction.Transactional; 9 | import java.util.List; 10 | 11 | @Service 12 | @Transactional 13 | public class UserService { 14 | 15 | private UserRepository userRepositoy; 16 | 17 | @Autowired 18 | public UserService(UserRepository userRepositoy) { 19 | this.userRepositoy = userRepositoy; 20 | } 21 | 22 | public List getUsers() { 23 | List users = userRepositoy.findAll(); 24 | 25 | return users; 26 | } 27 | 28 | public User addUser(String email, String name) { 29 | User user = User.builder() 30 | .email(email) 31 | .name(name) 32 | .level(1L) 33 | .build(); 34 | 35 | return userRepositoy.save(user); 36 | } 37 | 38 | public User updateUser(Long id, String email, String name, Long level) { 39 | // TODO: restaurantService의 예외 처리 참고. 40 | User user = userRepositoy.findById(id).orElse(null); 41 | 42 | user.setEmail(email); 43 | user.setName(name); 44 | user.setLevel(level); 45 | 46 | return user; 47 | } 48 | 49 | public User deactiveUser(Long id) { 50 | // TODO: restaurantService의 예외 처리 참고. 51 | User user = userRepositoy.findById(id).orElse(null); 52 | 53 | user.deativate(); 54 | 55 | return user; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/CategoryController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.CategoryService; 4 | import kr.co.fastcampus.eatgo.domain.Category; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | import java.net.URI; 10 | import java.net.URISyntaxException; 11 | import java.util.List; 12 | 13 | @CrossOrigin 14 | @RestController 15 | public class CategoryController { 16 | 17 | @Autowired 18 | private CategoryService categoryService; 19 | 20 | @GetMapping("/categories") 21 | public List list() { 22 | List regions = categoryService.getCategories(); 23 | 24 | return regions; 25 | } 26 | 27 | @PostMapping("/categories") 28 | public ResponseEntity create( 29 | @RequestBody Category resource 30 | ) throws URISyntaxException { 31 | String name = resource.getName(); 32 | 33 | Category category = categoryService.addCategory(name); 34 | 35 | String url = "/categories/" + category.getId(); 36 | return ResponseEntity.created(new URI(url)).body("{}"); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/MenuItemController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.MenuItemService; 4 | import kr.co.fastcampus.eatgo.domain.MenuItem; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | import java.util.List; 9 | 10 | @CrossOrigin 11 | @RestController 12 | public class MenuItemController { 13 | 14 | @Autowired 15 | private MenuItemService menuItemService; 16 | 17 | @GetMapping("/restaurants/{restaurantId}/menuitems") 18 | public List list(@PathVariable Long restaurantId) { 19 | List menuItems = menuItemService.getMenuItems(restaurantId); 20 | 21 | return menuItems; 22 | } 23 | 24 | @PatchMapping("/restaurants/{restaurantId}/menuitems") 25 | public String bulkUpate( 26 | @PathVariable("restaurantId") Long restaurantId, 27 | @RequestBody List menuItems 28 | ) { 29 | menuItemService.bulkUpdate(restaurantId, menuItems); 30 | 31 | return ""; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/RegionController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.RegionService; 4 | import kr.co.fastcampus.eatgo.domain.Region; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | import java.net.URI; 10 | import java.net.URISyntaxException; 11 | import java.util.List; 12 | 13 | @CrossOrigin 14 | @RestController 15 | public class RegionController { 16 | 17 | @Autowired 18 | private RegionService regionService; 19 | 20 | @GetMapping("/regions") 21 | public List list() { 22 | List regions = regionService.getRegions(); 23 | 24 | return regions; 25 | } 26 | 27 | @PostMapping("/regions") 28 | public ResponseEntity create( 29 | @RequestBody Region resource 30 | ) throws URISyntaxException { 31 | String name = resource.getName(); 32 | 33 | Region region = regionService.addRegion(name); 34 | 35 | String url = "/regions/" + region.getId(); 36 | return ResponseEntity.created(new URI(url)).body("{}"); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/RestaurantController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.RestaurantService; 4 | import kr.co.fastcampus.eatgo.domain.Restaurant; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | import javax.validation.Valid; 10 | import java.net.URI; 11 | import java.net.URISyntaxException; 12 | import java.util.List; 13 | 14 | @CrossOrigin 15 | @RestController 16 | public class RestaurantController { 17 | 18 | @Autowired 19 | private RestaurantService restaurantService; 20 | 21 | @GetMapping("/restaurants") 22 | public List list() { 23 | List restaurants = restaurantService.getRestaurants(); 24 | 25 | return restaurants; 26 | } 27 | 28 | @GetMapping("/restaurants/{id}") 29 | public Restaurant detail(@PathVariable("id") Long id) { 30 | Restaurant restaurant = restaurantService.getRestaurant(id); 31 | 32 | return restaurant; 33 | } 34 | 35 | @PostMapping("/restaurants") 36 | public ResponseEntity create(@Valid @RequestBody Restaurant resource) 37 | throws URISyntaxException { 38 | Restaurant restaurant = restaurantService.addRestaurant( 39 | Restaurant.builder() 40 | .categoryId(resource.getCategoryId()) 41 | .name(resource.getName()) 42 | .address(resource.getAddress()) 43 | .build()); 44 | 45 | URI location = new URI("/restaurants/" + restaurant.getId()); 46 | return ResponseEntity.created(location).body("{}"); 47 | } 48 | 49 | @PatchMapping("/restaurants/{id}") 50 | public String update(@PathVariable("id") Long id, 51 | @Valid @RequestBody Restaurant resource) { 52 | Long categoryId = resource.getCategoryId(); 53 | String name = resource.getName(); 54 | String address = resource.getAddress(); 55 | 56 | restaurantService.updateRestaurant(id, categoryId, name, address); 57 | 58 | return "{}"; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/RestaurantErrorAdvice.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.domain.RestaurantNotFoundException; 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.web.bind.annotation.ControllerAdvice; 6 | import org.springframework.web.bind.annotation.ExceptionHandler; 7 | import org.springframework.web.bind.annotation.ResponseBody; 8 | import org.springframework.web.bind.annotation.ResponseStatus; 9 | 10 | @ControllerAdvice 11 | public class RestaurantErrorAdvice { 12 | 13 | @ResponseBody 14 | @ResponseStatus(HttpStatus.NOT_FOUND) 15 | @ExceptionHandler(RestaurantNotFoundException.class) 16 | public String handleNotFound() { 17 | return "{}"; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/ReviewController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.ReviewService; 4 | import kr.co.fastcampus.eatgo.domain.Review; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.CrossOrigin; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import java.util.List; 11 | 12 | @CrossOrigin 13 | @RestController 14 | public class ReviewController { 15 | 16 | @Autowired 17 | private ReviewService reviewService; 18 | 19 | @GetMapping("/reviews") 20 | public List list() { 21 | List reviews = reviewService.getReviews(); 22 | 23 | return reviews; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/UserController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.UserService; 4 | import kr.co.fastcampus.eatgo.domain.User; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | import java.net.URI; 10 | import java.net.URISyntaxException; 11 | import java.util.List; 12 | 13 | @CrossOrigin 14 | @RestController 15 | public class UserController { 16 | 17 | @Autowired 18 | private UserService userService; 19 | 20 | @GetMapping("/users") 21 | public List list() { 22 | List users = userService.getUsers(); 23 | 24 | return users; 25 | } 26 | 27 | @PostMapping("/users") 28 | public ResponseEntity create( 29 | @RequestBody User resource 30 | ) throws URISyntaxException { 31 | String email = resource.getEmail(); 32 | String name = resource.getName(); 33 | 34 | User user = userService.addUser(email, name); 35 | 36 | String url = "/users/" + user.getId(); 37 | 38 | return ResponseEntity.created(new URI(url)).body("{}"); 39 | } 40 | 41 | @PatchMapping("/users/{id}") 42 | public String update( 43 | @PathVariable("id") Long id, 44 | @RequestBody User resource 45 | ) { 46 | String email = resource.getEmail(); 47 | String name = resource.getName(); 48 | Long level = resource.getLevel(); 49 | 50 | userService.updateUser(id, email, name, level); 51 | 52 | return "{}"; 53 | } 54 | 55 | @DeleteMapping("/users/{id}") 56 | public String delete(@PathVariable("id") Long id) { 57 | userService.deactiveUser(id); 58 | 59 | return "{}"; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/WelcomeController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class WelcomeController { 8 | 9 | @GetMapping("/") 10 | public String hello() { 11 | return "Hello, world!!!"; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:h2:~/data/eatgo 4 | jpa: 5 | hibernate: 6 | ddl-auto: update 7 | 8 | --- 9 | 10 | spring: 11 | profiles: test 12 | datasource: 13 | url: jdbc:h2:mem:test 14 | 15 | --- 16 | 17 | spring: 18 | profiles: mysql 19 | datasource: 20 | url: jdbc:mysql://${MYSQL_HOST}:3306/${MYSQL_DATABASE} 21 | username: ${MYSQL_USER} 22 | password: ${MYSQL_PASSWORD} 23 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/test/java/kr/co/fastcampus/eatgo/EatgoAdminApiApplicationTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | public class EatgoAdminApiApplicationTests { 8 | 9 | @Test 10 | public void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/test/java/kr/co/fastcampus/eatgo/application/CategoryServiceTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Category; 4 | import kr.co.fastcampus.eatgo.domain.CategoryRepository; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | import org.mockito.InjectMocks; 8 | import org.mockito.Mock; 9 | import org.mockito.MockitoAnnotations; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import static org.assertj.core.api.Assertions.assertThat; 15 | import static org.mockito.ArgumentMatchers.any; 16 | import static org.mockito.BDDMockito.given; 17 | import static org.mockito.Mockito.verify; 18 | 19 | public class CategoryServiceTests { 20 | 21 | @InjectMocks 22 | private CategoryService categoryService; 23 | 24 | @Mock 25 | private CategoryRepository categoryRepository; 26 | 27 | @BeforeEach 28 | public void setUp() { 29 | MockitoAnnotations.initMocks(this); 30 | } 31 | 32 | @Test 33 | public void getRegions() { 34 | List mockCategory = new ArrayList<>(); 35 | mockCategory.add(Category.builder().name("Korean Food").build()); 36 | 37 | given(categoryRepository.findAll()).willReturn(mockCategory); 38 | 39 | List categories = categoryService.getCategories(); 40 | 41 | Category category = categories.get(0); 42 | assertThat(category.getName()).isEqualTo("Korean Food"); 43 | } 44 | 45 | @Test 46 | public void addCategory() { 47 | Category category = categoryService.addCategory("Korean Food"); 48 | 49 | verify(categoryRepository).save(any()); 50 | 51 | assertThat(category.getName()).isEqualTo("Korean Food"); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/test/java/kr/co/fastcampus/eatgo/application/MenuItemServiceTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.MenuItem; 4 | import kr.co.fastcampus.eatgo.domain.MenuItemRepository; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | import org.mockito.InjectMocks; 8 | import org.mockito.Mock; 9 | import org.mockito.MockitoAnnotations; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import static org.assertj.core.api.Assertions.assertThat; 15 | import static org.mockito.ArgumentMatchers.any; 16 | import static org.mockito.ArgumentMatchers.eq; 17 | import static org.mockito.BDDMockito.given; 18 | import static org.mockito.Mockito.times; 19 | import static org.mockito.Mockito.verify; 20 | 21 | public class MenuItemServiceTests { 22 | 23 | @InjectMocks 24 | private MenuItemService menuItemService; 25 | 26 | @Mock 27 | private MenuItemRepository menuItemRepository; 28 | 29 | @BeforeEach 30 | public void setUp() { 31 | MockitoAnnotations.initMocks(this); 32 | } 33 | 34 | @Test 35 | public void getMenuItems() { 36 | List mockMenuItems = new ArrayList<>(); 37 | mockMenuItems.add(MenuItem.builder().name("Kimchi").build()); 38 | 39 | given(menuItemRepository.findAllByRestaurantId(1004L)) 40 | .willReturn(mockMenuItems); 41 | 42 | List menuItems = menuItemService.getMenuItems(1004L); 43 | 44 | MenuItem menuItem = menuItems.get(0); 45 | 46 | assertThat(menuItem.getName()).isEqualTo("Kimchi"); 47 | } 48 | 49 | @Test 50 | public void bulkUpdate() { 51 | List menuItems = new ArrayList(); 52 | 53 | menuItems.add(MenuItem.builder().name("Kimchi").build()); 54 | menuItems.add(MenuItem.builder().id(12L).name("Gukbob").build()); 55 | menuItems.add(MenuItem.builder().id(1004L).destroy(true).build()); 56 | 57 | menuItemService.bulkUpdate(1L, menuItems); 58 | 59 | verify(menuItemRepository, times(2)).save(any()); 60 | verify(menuItemRepository, times(1)).deleteById(eq(1004L)); 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /eatgo-admin-api/src/test/java/kr/co/fastcampus/eatgo/application/RegionServiceTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Region; 4 | import kr.co.fastcampus.eatgo.domain.RegionRepository; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | import org.mockito.InjectMocks; 8 | import org.mockito.Mock; 9 | import org.mockito.MockitoAnnotations; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import static org.assertj.core.api.Assertions.assertThat; 15 | import static org.mockito.ArgumentMatchers.any; 16 | import static org.mockito.BDDMockito.given; 17 | import static org.mockito.Mockito.verify; 18 | 19 | public class RegionServiceTests { 20 | 21 | @InjectMocks 22 | private RegionService regionService; 23 | 24 | @Mock 25 | private RegionRepository regionRepository; 26 | 27 | @BeforeEach 28 | public void setUp() { 29 | MockitoAnnotations.initMocks(this); 30 | } 31 | 32 | @Test 33 | public void getRegions() { 34 | List mockRegions = new ArrayList<>(); 35 | mockRegions.add(Region.builder().name("Seoul").build()); 36 | 37 | given(regionRepository.findAll()).willReturn(mockRegions); 38 | 39 | List regions = regionService.getRegions(); 40 | 41 | Region region = regions.get(0); 42 | assertThat(region.getName()).isEqualTo("Seoul"); 43 | } 44 | 45 | @Test 46 | public void addRegion() { 47 | Region region = regionService.addRegion("Seoul"); 48 | 49 | verify(regionRepository).save(any()); 50 | 51 | assertThat(region.getName()).isEqualTo("Seoul"); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/test/java/kr/co/fastcampus/eatgo/application/RestaurantServiceTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Restaurant; 4 | import kr.co.fastcampus.eatgo.domain.RestaurantNotFoundException; 5 | import kr.co.fastcampus.eatgo.domain.RestaurantRepository; 6 | import org.junit.jupiter.api.BeforeEach; 7 | import org.junit.jupiter.api.Test; 8 | import org.mockito.InjectMocks; 9 | import org.mockito.Mock; 10 | import org.mockito.MockitoAnnotations; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | import java.util.Optional; 15 | 16 | import static org.assertj.core.api.Assertions.assertThat; 17 | import static org.assertj.core.api.Assertions.assertThatThrownBy; 18 | import static org.mockito.ArgumentMatchers.any; 19 | import static org.mockito.BDDMockito.given; 20 | 21 | public class RestaurantServiceTests { 22 | 23 | @InjectMocks 24 | private RestaurantService restaurantService; 25 | 26 | @Mock 27 | private RestaurantRepository restaurantRepository; 28 | 29 | @BeforeEach 30 | public void setUp() { 31 | MockitoAnnotations.initMocks(this); 32 | 33 | mockRestaurantRepository(); 34 | } 35 | 36 | private void mockRestaurantRepository() { 37 | List restaurants = new ArrayList<>(); 38 | Restaurant restaurant = Restaurant.builder() 39 | .id(1004L) 40 | .categoryId(1L) 41 | .address("Seoul") 42 | .name("Bob zip") 43 | .build(); 44 | restaurants.add(restaurant); 45 | 46 | given(restaurantRepository.findAll()).willReturn(restaurants); 47 | 48 | given(restaurantRepository.findById(1004L)) 49 | .willReturn(Optional.of(restaurant)); 50 | } 51 | 52 | @Test 53 | public void getRestaurants() { 54 | List restaurants = restaurantService.getRestaurants(); 55 | 56 | Restaurant restaurant = restaurants.get(0); 57 | 58 | assertThat(restaurant.getId()).isEqualTo(1004L); 59 | } 60 | 61 | @Test 62 | public void getRestaurantWithExisted() { 63 | Restaurant restaurant = restaurantService.getRestaurant(1004L); 64 | 65 | assertThat(restaurant.getId()).isEqualTo(1004L); 66 | } 67 | 68 | @Test 69 | public void getRestaurantWithNotExisted() { 70 | assertThatThrownBy(() -> { 71 | restaurantService.getRestaurant(404L); 72 | }).isInstanceOf(RestaurantNotFoundException.class); 73 | } 74 | 75 | @Test 76 | public void addRestaurant() { 77 | given(restaurantRepository.save(any())).will(invocation -> { 78 | Restaurant restaurant = invocation.getArgument(0); 79 | restaurant.setId(1234L); 80 | return restaurant; 81 | }); 82 | 83 | Restaurant restaurant = Restaurant.builder() 84 | .name("BeRyong") 85 | .address("Busan") 86 | .build(); 87 | 88 | Restaurant created = restaurantService.addRestaurant(restaurant); 89 | 90 | assertThat(created.getId()).isEqualTo(1234L); 91 | } 92 | 93 | @Test 94 | public void updateRestaurant() { 95 | Restaurant restaurant = Restaurant.builder() 96 | .id(1004L) 97 | .name("Bob zip") 98 | .address("Seoul") 99 | .build(); 100 | 101 | given(restaurantRepository.findById(1004L)) 102 | .willReturn(Optional.of(restaurant)); 103 | 104 | restaurantService.updateRestaurant(1004L, 1L, "Sool zip", "Busan"); 105 | 106 | assertThat(restaurant.getName()).isEqualTo("Sool zip"); 107 | assertThat(restaurant.getAddress()).isEqualTo("Busan"); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/test/java/kr/co/fastcampus/eatgo/application/ReviewServiceTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Review; 4 | import kr.co.fastcampus.eatgo.domain.ReviewRepository; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | import org.mockito.InjectMocks; 8 | import org.mockito.Mock; 9 | import org.mockito.MockitoAnnotations; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import static org.assertj.core.api.Assertions.assertThat; 15 | import static org.mockito.BDDMockito.given; 16 | 17 | public class ReviewServiceTests { 18 | 19 | @InjectMocks 20 | private ReviewService reviewService; 21 | 22 | @Mock 23 | private ReviewRepository reviewRepository; 24 | 25 | @BeforeEach 26 | public void setUp() { 27 | MockitoAnnotations.initMocks(this); 28 | } 29 | 30 | @Test 31 | public void getReviews() { 32 | List mockReviews = new ArrayList<>(); 33 | mockReviews.add(Review.builder().description("Cool!").build()); 34 | 35 | given(reviewRepository.findAll()).willReturn(mockReviews); 36 | 37 | List reviews = reviewService.getReviews(); 38 | 39 | Review review = reviews.get(0); 40 | 41 | assertThat(review.getDescription()).isEqualTo("Cool!"); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/test/java/kr/co/fastcampus/eatgo/application/UserServiceTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.User; 4 | import kr.co.fastcampus.eatgo.domain.UserRepository; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | import org.mockito.InjectMocks; 8 | import org.mockito.Mock; 9 | import org.mockito.MockitoAnnotations; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | import java.util.Optional; 14 | 15 | import static org.assertj.core.api.Assertions.assertThat; 16 | import static org.mockito.ArgumentMatchers.any; 17 | import static org.mockito.ArgumentMatchers.eq; 18 | import static org.mockito.BDDMockito.given; 19 | import static org.mockito.Mockito.verify; 20 | 21 | public class UserServiceTests { 22 | 23 | @InjectMocks 24 | private UserService userService; 25 | 26 | @Mock 27 | private UserRepository userRepositoy; 28 | 29 | @BeforeEach 30 | public void setUp() { 31 | MockitoAnnotations.initMocks(this); 32 | } 33 | 34 | @Test 35 | public void getUsers() { 36 | List mockUsers = new ArrayList<>(); 37 | mockUsers.add(User.builder() 38 | .email("tester@example.com") 39 | .name("테스터") 40 | .level(1L) 41 | .build()); 42 | 43 | given(userRepositoy.findAll()).willReturn(mockUsers); 44 | 45 | List users = userService.getUsers(); 46 | 47 | User user = users.get(0); 48 | 49 | assertThat(user.getName()).isEqualTo("테스터"); 50 | } 51 | 52 | @Test 53 | public void addUser() { 54 | String email = "admin@exmaple.com"; 55 | String name = "Administrator"; 56 | 57 | User mockUser = User.builder().email(email).name(name).build(); 58 | 59 | given(userRepositoy.save(any())).willReturn(mockUser); 60 | 61 | User user = userService.addUser(email, name); 62 | 63 | assertThat(user.getName()).isEqualTo(name); 64 | } 65 | 66 | @Test 67 | public void updateUser() { 68 | Long id = 1004L; 69 | String email = "admin@exmaple.com"; 70 | String name = "Superman"; 71 | Long level = 100L; 72 | 73 | User mockUser = User.builder().id(id) 74 | .email(email) 75 | .name("Administrator") 76 | .level(1L) 77 | .build(); 78 | 79 | given(userRepositoy.findById(id)).willReturn(Optional.of(mockUser)); 80 | 81 | User user = userService.updateUser(id, email, name, level); 82 | 83 | verify(userRepositoy).findById(eq(id)); 84 | 85 | assertThat(user.getName()).isEqualTo("Superman"); 86 | assertThat(user.isAdmin()).isTrue(); 87 | } 88 | 89 | @Test 90 | public void deactiveUser() { 91 | Long id = 1004L; 92 | 93 | User mockUser = User.builder() 94 | .id(id) 95 | .email("admin@exmaple.com") 96 | .name("Administrator") 97 | .level(100L) 98 | .build(); 99 | 100 | given(userRepositoy.findById(id)).willReturn(Optional.of(mockUser)); 101 | 102 | User user = userService.deactiveUser(1004L); 103 | 104 | verify(userRepositoy).findById(1004L); 105 | 106 | assertThat(user.isAdmin()).isFalse(); 107 | assertThat(user.isActive()).isFalse(); 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/test/java/kr/co/fastcampus/eatgo/interfaces/CategoryControllerTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.CategoryService; 4 | import kr.co.fastcampus.eatgo.domain.Category; 5 | import kr.co.fastcampus.eatgo.domain.Region; 6 | import org.junit.jupiter.api.Test; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 9 | import org.springframework.boot.test.mock.mockito.MockBean; 10 | import org.springframework.http.MediaType; 11 | import org.springframework.test.web.servlet.MockMvc; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | import static org.hamcrest.core.StringContains.containsString; 17 | import static org.mockito.BDDMockito.given; 18 | import static org.mockito.Mockito.verify; 19 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 20 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 21 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 22 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 23 | 24 | @WebMvcTest(CategoryController.class) 25 | public class CategoryControllerTests { 26 | 27 | @Autowired 28 | private MockMvc mvc; 29 | 30 | @MockBean 31 | private CategoryService categoryService; 32 | 33 | @Test 34 | public void list() throws Exception { 35 | List categories = new ArrayList<>(); 36 | categories.add(Category.builder().name("Korean Food").build()); 37 | 38 | given(categoryService.getCategories()).willReturn(categories); 39 | 40 | mvc.perform(get("/categories")) 41 | .andExpect(status().isOk()) 42 | .andExpect(content().string(containsString("Korean Food"))); 43 | } 44 | 45 | @Test 46 | public void create() throws Exception { 47 | Category category = Category.builder().name("Korean Food").build(); 48 | 49 | given(categoryService.addCategory("Korean Food")).willReturn(category); 50 | 51 | mvc.perform(post("/categories") 52 | .contentType(MediaType.APPLICATION_JSON) 53 | .content("{\"name\":\"Korean Food\"}")) 54 | .andExpect(status().isCreated()) 55 | .andExpect(content().string("{}")); 56 | 57 | verify(categoryService).addCategory("Korean Food"); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/test/java/kr/co/fastcampus/eatgo/interfaces/MenuItemControllerTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.MenuItemService; 4 | import kr.co.fastcampus.eatgo.domain.MenuItem; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 8 | import org.springframework.boot.test.mock.mockito.MockBean; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.test.web.servlet.MockMvc; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | import static org.hamcrest.core.StringContains.containsString; 16 | import static org.mockito.ArgumentMatchers.any; 17 | import static org.mockito.ArgumentMatchers.eq; 18 | import static org.mockito.BDDMockito.given; 19 | import static org.mockito.Mockito.verify; 20 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 21 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; 22 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 23 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 24 | 25 | @WebMvcTest(MenuItemController.class) 26 | public class MenuItemControllerTests { 27 | 28 | @Autowired 29 | private MockMvc mvc; 30 | 31 | @MockBean 32 | private MenuItemService menuItemService; 33 | 34 | @Test 35 | public void list() throws Exception { 36 | List menuItems = new ArrayList<>(); 37 | menuItems.add(MenuItem.builder().name("Kimchi").build()); 38 | 39 | given(menuItemService.getMenuItems(1L)).willReturn(menuItems); 40 | 41 | mvc.perform(get("/restaurants/1/menuitems")) 42 | .andExpect(status().isOk()) 43 | .andExpect(content().string(containsString("Kimchi"))); 44 | } 45 | 46 | @Test 47 | public void bulkUpdate() throws Exception { 48 | mvc.perform(patch("/restaurants/12/menuitems") 49 | .contentType(MediaType.APPLICATION_JSON) 50 | .content("[]")) 51 | .andExpect(status().isOk()); 52 | 53 | verify(menuItemService).bulkUpdate(eq(12L), any()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/test/java/kr/co/fastcampus/eatgo/interfaces/RegionControllerTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.RegionService; 4 | import kr.co.fastcampus.eatgo.domain.Region; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 8 | import org.springframework.boot.test.mock.mockito.MockBean; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.test.web.servlet.MockMvc; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | import static org.hamcrest.core.StringContains.containsString; 16 | import static org.mockito.BDDMockito.given; 17 | import static org.mockito.Mockito.verify; 18 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 19 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 20 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 21 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 22 | 23 | @WebMvcTest(RegionController.class) 24 | public class RegionControllerTests { 25 | 26 | @Autowired 27 | private MockMvc mvc; 28 | 29 | @MockBean 30 | private RegionService regionService; 31 | 32 | @Test 33 | public void list() throws Exception { 34 | List regions = new ArrayList<>(); 35 | regions.add(Region.builder().name("Seoul").build()); 36 | 37 | given(regionService.getRegions()).willReturn(regions); 38 | 39 | mvc.perform(get("/regions")) 40 | .andExpect(status().isOk()) 41 | .andExpect(content().string(containsString("Seoul"))); 42 | } 43 | 44 | @Test 45 | public void create() throws Exception { 46 | Region region = Region.builder().name("Seoul").build(); 47 | 48 | given(regionService.addRegion("Seoul")).willReturn(region); 49 | 50 | mvc.perform(post("/regions") 51 | .contentType(MediaType.APPLICATION_JSON) 52 | .content("{\"name\":\"Seoul\"}")) 53 | .andExpect(status().isCreated()) 54 | .andExpect(content().string("{}")); 55 | 56 | verify(regionService).addRegion("Seoul"); 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /eatgo-admin-api/src/test/java/kr/co/fastcampus/eatgo/interfaces/ReviewControllerTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.ReviewService; 4 | import kr.co.fastcampus.eatgo.domain.Review; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 8 | import org.springframework.boot.test.mock.mockito.MockBean; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.test.web.servlet.MockMvc; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | import static org.hamcrest.Matchers.containsString; 16 | import static org.mockito.ArgumentMatchers.any; 17 | import static org.mockito.ArgumentMatchers.eq; 18 | import static org.mockito.BDDMockito.given; 19 | import static org.mockito.Mockito.never; 20 | import static org.mockito.Mockito.verify; 21 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 22 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 23 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; 24 | 25 | @WebMvcTest(ReviewController.class) 26 | public class ReviewControllerTests { 27 | 28 | @Autowired 29 | MockMvc mvc; 30 | 31 | @MockBean 32 | private ReviewService reviewService; 33 | 34 | @Test 35 | public void list() throws Exception { 36 | List reviews = new ArrayList<>(); 37 | reviews.add(Review.builder().description("Cool!").build()); 38 | 39 | given(reviewService.getReviews()).willReturn(reviews); 40 | 41 | mvc.perform(get("/reviews")) 42 | .andExpect(status().isOk()) 43 | .andExpect(content().string(containsString("Cool!"))); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /eatgo-admin-api/src/test/java/kr/co/fastcampus/eatgo/interfaces/UserControllerTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.UserService; 4 | import kr.co.fastcampus.eatgo.domain.User; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 8 | import org.springframework.boot.test.mock.mockito.MockBean; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.test.web.servlet.MockMvc; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | import static org.hamcrest.core.StringContains.containsString; 16 | import static org.mockito.ArgumentMatchers.eq; 17 | import static org.mockito.BDDMockito.given; 18 | import static org.mockito.Mockito.verify; 19 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; 20 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 21 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 22 | 23 | @WebMvcTest(UserController.class) 24 | public class UserControllerTests { 25 | 26 | @Autowired 27 | private MockMvc mvc; 28 | 29 | @MockBean 30 | private UserService userService; 31 | 32 | @Test 33 | public void list() throws Exception { 34 | List users = new ArrayList<>(); 35 | users.add(User.builder() 36 | .email("tester@example.com") 37 | .name("Tester") 38 | .level(1L) 39 | .build()); 40 | 41 | given(userService.getUsers()).willReturn(users); 42 | 43 | mvc.perform(get("/users")) 44 | .andExpect(status().isOk()) 45 | .andExpect(content().string(containsString("Tester"))); 46 | } 47 | 48 | @Test 49 | public void create() throws Exception { 50 | String email = "admin@exmaple.com"; 51 | String name = "Administrator"; 52 | 53 | User user = User.builder().email(email).name(name).build(); 54 | 55 | given(userService.addUser(email, name)).willReturn(user); 56 | 57 | mvc.perform(post("/users") 58 | .contentType(MediaType.APPLICATION_JSON) 59 | .content("{\"email\":\"admin@exmaple.com\",\"name\":\"Administrator\"}")) 60 | .andExpect(status().isCreated()); 61 | 62 | verify(userService).addUser(email, name); 63 | } 64 | 65 | @Test 66 | public void update() throws Exception { 67 | mvc.perform(patch("/users/1004") 68 | .contentType(MediaType.APPLICATION_JSON) 69 | .content("{\"email\":\"admin@exmaple.com\"," + 70 | "\"name\":\"Administrator\",\"level\":100}")) 71 | .andExpect(status().isOk()); 72 | 73 | Long id = 1004L; 74 | String email = "admin@exmaple.com"; 75 | String name = "Administrator"; 76 | Long level = 100L; 77 | 78 | verify(userService).updateUser(eq(id), eq(email), eq(name), eq(level)); 79 | } 80 | 81 | @Test 82 | public void deactivate() throws Exception { 83 | mvc.perform(delete("/users/1004")) 84 | .andExpect(status().isOk()); 85 | 86 | verify(userService).deactiveUser(1004L); 87 | } 88 | 89 | } -------------------------------------------------------------------------------- /eatgo-admin-web/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /eatgo-admin-web/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue}] 2 | indent_style = space 3 | indent_size = 2 4 | end_of_line = lf 5 | trim_trailing_whitespace = true 6 | insert_final_newline = true 7 | max_line_length = 100 8 | -------------------------------------------------------------------------------- /eatgo-admin-web/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true, 5 | }, 6 | extends: [ 7 | 'plugin:vue/essential', 8 | '@vue/airbnb', 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint', 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /eatgo-admin-web/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /eatgo-admin-web/.nvmrc: -------------------------------------------------------------------------------- 1 | v10.16.3 2 | -------------------------------------------------------------------------------- /eatgo-admin-web/README.md: -------------------------------------------------------------------------------- 1 | # EatGo Admin Web 2 | 3 | ## Project setup 4 | 5 | ```bash 6 | npm install 7 | ``` 8 | 9 | ### Compiles and hot-reloads for development 10 | 11 | ```bash 12 | npm run serve 13 | ``` 14 | 15 | ### Compiles and minifies for production 16 | 17 | ```bash 18 | npm run build 19 | ``` 20 | 21 | ### Run your tests 22 | 23 | ```bash 24 | npm run test 25 | ``` 26 | 27 | ### Lints and fixes files 28 | 29 | ```bash 30 | npm run lint 31 | ``` 32 | 33 | ### Customize configuration 34 | 35 | See [Configuration Reference](https://cli.vuejs.org/config/). 36 | -------------------------------------------------------------------------------- /eatgo-admin-web/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app', 4 | ], 5 | }; 6 | -------------------------------------------------------------------------------- /eatgo-admin-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eatgo-admin-web", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.19.0", 12 | "core-js": "^2.6.5", 13 | "vue": "^2.6.10", 14 | "vue-router": "^3.0.3", 15 | "vuex": "^3.1.1" 16 | }, 17 | "devDependencies": { 18 | "@vue/cli-plugin-babel": "^3.11.0", 19 | "@vue/cli-plugin-eslint": "^3.11.0", 20 | "@vue/cli-service": "^3.11.0", 21 | "@vue/eslint-config-airbnb": "^4.0.0", 22 | "babel-eslint": "^10.0.1", 23 | "eslint": "^5.16.0", 24 | "eslint-plugin-vue": "^5.0.0", 25 | "vue-template-compiler": "^2.6.10" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /eatgo-admin-web/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {}, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /eatgo-admin-web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahastudio/fastcampus-eatgo/21bc7212e120d217bed5d0f995925d0789033900/eatgo-admin-web/public/favicon.ico -------------------------------------------------------------------------------- /eatgo-admin-web/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | EatGo Admin 9 | 14 | 15 | 16 |
17 |
18 |
19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 27 | 28 | 33 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/components/GlobalNavigator.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 57 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import App from './App.vue'; 3 | import router from './router'; 4 | import store from './store'; 5 | 6 | Vue.config.productionTip = false; 7 | 8 | store.dispatch('setAccessToken', { 9 | accessToken: localStorage.getItem('accessToken') || '', 10 | }); 11 | 12 | new Vue({ 13 | router, 14 | render: h => h(App), 15 | }).$mount('#app'); 16 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Router from 'vue-router'; 3 | 4 | import Home from './views/Home.vue'; 5 | import RestaurantList from './views/RestaurantList.vue'; 6 | import RestaurantNew from './views/RestaurantNew.vue'; 7 | import RestaurantEdit from './views/RestaurantEdit.vue'; 8 | import MenuItems from './views/MenuItems.vue'; 9 | import CategoryList from './views/CategoryList.vue'; 10 | import CategoryNew from './views/CategoryNew.vue'; 11 | import RegionList from './views/RegionList.vue'; 12 | import RegionNew from './views/RegionNew.vue'; 13 | import UserList from './views/UserList.vue'; 14 | import ReviewList from './views/ReviewList.vue'; 15 | import Login from './views/Login.vue'; 16 | 17 | import store from './store'; 18 | 19 | Vue.use(Router); 20 | 21 | const authenticated = (_to, _from, next) => { 22 | if (!store.state.accessToken) { 23 | next('/login'); 24 | return; 25 | } 26 | 27 | next(); 28 | }; 29 | 30 | export default new Router({ 31 | mode: 'history', 32 | base: process.env.BASE_URL, 33 | routes: [ 34 | { 35 | path: '/', 36 | name: 'home', 37 | component: Home, 38 | beforeEnter: authenticated, 39 | }, 40 | { 41 | path: '/restaurants', 42 | name: 'restaurant-list', 43 | component: RestaurantList, 44 | beforeEnter: authenticated, 45 | }, 46 | { 47 | path: '/restaurants/new', 48 | name: 'restaurant-new', 49 | component: RestaurantNew, 50 | beforeEnter: authenticated, 51 | }, 52 | { 53 | path: '/restaurants/:restaurantId', 54 | name: 'restaurant-edit', 55 | component: RestaurantEdit, 56 | beforeEnter: authenticated, 57 | }, 58 | { 59 | path: '/restaurants/:restaurantId/menuitems', 60 | name: 'menu-items', 61 | component: MenuItems, 62 | beforeEnter: authenticated, 63 | }, 64 | { 65 | path: '/categories', 66 | name: 'category-list', 67 | component: CategoryList, 68 | beforeEnter: authenticated, 69 | }, 70 | { 71 | path: '/categories/new', 72 | name: 'category-new', 73 | component: CategoryNew, 74 | beforeEnter: authenticated, 75 | }, 76 | { 77 | path: '/regions', 78 | name: 'region-list', 79 | component: RegionList, 80 | beforeEnter: authenticated, 81 | }, 82 | { 83 | path: '/regions/new', 84 | name: 'region-new', 85 | component: RegionNew, 86 | beforeEnter: authenticated, 87 | }, 88 | { 89 | path: '/users', 90 | name: 'user-list', 91 | component: UserList, 92 | beforeEnter: authenticated, 93 | }, 94 | { 95 | path: '/reviews', 96 | name: 'review-list', 97 | component: ReviewList, 98 | beforeEnter: authenticated, 99 | }, 100 | { 101 | path: '/login', 102 | name: 'login', 103 | component: Login, 104 | }, 105 | ], 106 | }); 107 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/store/http.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const LOGIN_API_BASE_URL = process.env.VUE_APP_LOGIN_API_BASE_URL; 4 | const API_BASE_URL = process.env.VUE_APP_API_BASE_URL; 5 | 6 | let http = axios.create({ 7 | baseURL: API_BASE_URL || 'http://localhost:8080', 8 | }); 9 | 10 | export const useAccessToken = (accessToken) => { 11 | http = axios.create({ 12 | baseURL: process.env.VUE_APP_API_BASE_URL || 'http://localhost:8080', 13 | headers: { 14 | authorization: `Bearer ${accessToken}`, 15 | }, 16 | }); 17 | }; 18 | 19 | export const get = async (path) => { 20 | const { data } = await http.get(path); 21 | return data; 22 | }; 23 | 24 | export const post = async (path, payload) => { 25 | const { data } = await http.post(path, payload); 26 | return data; 27 | }; 28 | 29 | export const patch = async (path, payload) => { 30 | const { data } = await http.patch(path, payload); 31 | return data; 32 | }; 33 | 34 | export const loginPost = async (path, payload) => { 35 | const url = `${LOGIN_API_BASE_URL || 'http://localhost:8080'}${path}`; 36 | const { data } = await axios.post(url, payload); 37 | return data; 38 | }; 39 | 40 | export default { 41 | }; 42 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuex from 'vuex'; 3 | 4 | import mutations from './mutations'; 5 | import actions from './actions'; 6 | 7 | Vue.use(Vuex); 8 | 9 | const state = { 10 | accessToken: '', 11 | restaurants: [], 12 | restaurant: {}, 13 | menuItems: [], 14 | categories: [], 15 | category: {}, 16 | regions: [], 17 | region: {}, 18 | reviews: [], 19 | users: [], 20 | }; 21 | 22 | export default new Vuex.Store({ 23 | state, 24 | mutations, 25 | actions, 26 | }); 27 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/store/mutations.js: -------------------------------------------------------------------------------- 1 | export default { 2 | setAccessToken(state, accessToken) { 3 | state.accessToken = accessToken; 4 | }, 5 | setRestaurants(state, restaurants) { 6 | state.restaurants = restaurants; 7 | }, 8 | setRestaurant(state, restaurant) { 9 | state.restaurant = restaurant; 10 | }, 11 | setMenuItems(state, menuItems) { 12 | state.menuItems = menuItems; 13 | }, 14 | setCategories(state, categories) { 15 | state.categories = categories; 16 | }, 17 | setCategory(state, category) { 18 | state.category = category; 19 | }, 20 | setRegions(state, regions) { 21 | state.regions = regions; 22 | }, 23 | setRegion(state, region) { 24 | state.region = region; 25 | }, 26 | setReviews(state, reviews) { 27 | state.reviews = reviews; 28 | }, 29 | setUsers(state, users) { 30 | state.users = users; 31 | }, 32 | }; 33 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/views/CategoryList.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 35 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/views/CategoryNew.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 46 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/views/Login.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 45 | 46 | 51 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/views/MenuItems.vue: -------------------------------------------------------------------------------- 1 | 56 | 57 | 80 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/views/RegionList.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 35 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/views/RegionNew.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 46 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/views/RestaurantEdit.vue: -------------------------------------------------------------------------------- 1 | 66 | 67 | 91 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/views/RestaurantList.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 57 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/views/RestaurantNew.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 72 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/views/ReviewList.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 37 | -------------------------------------------------------------------------------- /eatgo-admin-web/src/views/UserList.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 47 | -------------------------------------------------------------------------------- /eatgo-admin-web/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devServer: { 3 | port: 3000, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /eatgo-common/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.2.1.RELEASE' 3 | id 'io.spring.dependency-management' version '1.0.8.RELEASE' 4 | id 'java' 5 | } 6 | 7 | group = 'kr.co.fastcampus' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '1.8' 10 | 11 | configurations { 12 | developmentOnly 13 | runtimeClasspath { 14 | extendsFrom developmentOnly 15 | } 16 | compileOnly { 17 | extendsFrom annotationProcessor 18 | } 19 | } 20 | 21 | repositories { 22 | mavenCentral() 23 | } 24 | 25 | dependencies { 26 | implementation 'org.springframework.boot:spring-boot-starter-web' 27 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 28 | implementation 'com.h2database:h2' 29 | 30 | implementation 'io.jsonwebtoken:jjwt-api:0.10.7' 31 | 32 | runtime 'io.jsonwebtoken:jjwt-impl:0.10.7' 33 | runtime 'io.jsonwebtoken:jjwt-jackson:0.10.7' 34 | 35 | compileOnly 'org.projectlombok:lombok' 36 | 37 | developmentOnly 'org.springframework.boot:spring-boot-devtools' 38 | 39 | annotationProcessor 'org.projectlombok:lombok' 40 | 41 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 42 | } 43 | 44 | jar { 45 | enabled = true 46 | } 47 | 48 | bootJar { 49 | enabled = false 50 | } 51 | 52 | test { 53 | useJUnitPlatform() 54 | } 55 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/Category.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.persistence.Entity; 9 | import javax.persistence.GeneratedValue; 10 | import javax.persistence.Id; 11 | 12 | @Entity 13 | @Getter 14 | @Builder 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class Category { 18 | 19 | @Id 20 | @GeneratedValue 21 | private Long id; 22 | 23 | private String name; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/CategoryRepository.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.List; 6 | 7 | public interface CategoryRepository extends CrudRepository { 8 | 9 | List findAll(); 10 | 11 | Category save(Category category); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/MenuItem.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import lombok.*; 5 | 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.Id; 9 | import javax.persistence.Transient; 10 | 11 | @Entity 12 | @Getter 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class MenuItem { 17 | 18 | @Id 19 | @GeneratedValue 20 | private Long id; 21 | 22 | @Setter 23 | private Long restaurantId; 24 | 25 | private String name; 26 | 27 | @Transient 28 | @JsonInclude(JsonInclude.Include.NON_DEFAULT) 29 | private boolean destroy; 30 | } 31 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/MenuItemRepository.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.List; 6 | 7 | public interface MenuItemRepository extends CrudRepository { 8 | List findAllByRestaurantId(Long restaurantId); 9 | 10 | void deleteById(Long id); 11 | } 12 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/Region.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.persistence.Entity; 9 | import javax.persistence.GeneratedValue; 10 | import javax.persistence.Id; 11 | 12 | @Entity 13 | @Getter 14 | @Builder 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class Region { 18 | 19 | @Id 20 | @GeneratedValue 21 | private Long id; 22 | 23 | private String name; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/RegionRepository.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.List; 6 | 7 | public interface RegionRepository extends CrudRepository { 8 | 9 | List findAll(); 10 | 11 | Region save(Region region); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/Reservation.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import lombok.*; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.Id; 8 | import javax.validation.constraints.Min; 9 | import javax.validation.constraints.NotEmpty; 10 | import javax.validation.constraints.NotNull; 11 | 12 | @Entity 13 | @Getter 14 | @Builder 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class Reservation { 18 | 19 | @Id 20 | @GeneratedValue 21 | private Long id; 22 | 23 | private Long restaurantId; 24 | 25 | private Long userId; 26 | 27 | @Setter 28 | private String name; 29 | 30 | @Setter 31 | @NotEmpty 32 | private String date; 33 | 34 | @Setter 35 | @NotEmpty 36 | private String time; 37 | 38 | @Setter 39 | @NotNull 40 | private Integer partySize; 41 | } 42 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/ReservationRepository.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.List; 6 | 7 | public interface ReservationRepository 8 | extends CrudRepository { 9 | 10 | List findAllByRestaurantId(Long restaurantId); 11 | 12 | Reservation save(Reservation reservation); 13 | } 14 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/Restaurant.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | 4 | import com.fasterxml.jackson.annotation.JsonInclude; 5 | import lombok.*; 6 | 7 | import javax.persistence.Entity; 8 | import javax.persistence.GeneratedValue; 9 | import javax.persistence.Id; 10 | import javax.persistence.Transient; 11 | import javax.validation.constraints.NotEmpty; 12 | import javax.validation.constraints.NotNull; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | @Entity 17 | @Getter 18 | @Builder 19 | @NoArgsConstructor 20 | @AllArgsConstructor 21 | public class Restaurant { 22 | 23 | @Id 24 | @GeneratedValue 25 | @Setter 26 | private Long id; 27 | 28 | @NotNull 29 | private Long categoryId; 30 | 31 | @NotEmpty 32 | private String name; 33 | 34 | @NotEmpty 35 | private String address; 36 | 37 | @Transient 38 | @JsonInclude(JsonInclude.Include.NON_NULL) 39 | private List menuItems; 40 | 41 | @Transient 42 | @JsonInclude(JsonInclude.Include.NON_NULL) 43 | private List reviews; 44 | 45 | public String getInformation() { 46 | return name + " in " + address; 47 | } 48 | 49 | public void updateInformation(Long categoryId, 50 | String name, String address) { 51 | this.categoryId = categoryId; 52 | this.name = name; 53 | this.address = address; 54 | } 55 | 56 | public void setMenuItems(List menuItems) { 57 | this.menuItems = new ArrayList<>(menuItems); 58 | } 59 | 60 | public void setReviews(List reviews) { 61 | this.reviews = new ArrayList<>(reviews); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/RestaurantNotFoundException.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | public class RestaurantNotFoundException extends RuntimeException { 4 | 5 | public RestaurantNotFoundException(Long id) { 6 | super("Could not find restaurant " + id); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/RestaurantRepository.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.List; 6 | import java.util.Optional; 7 | 8 | public interface RestaurantRepository extends CrudRepository { 9 | List findAll(); 10 | 11 | List findAllByAddressContainingAndCategoryId( 12 | String region, Long categoryId); 13 | 14 | Optional findById(Long id); 15 | 16 | Restaurant save(Restaurant restaurant); 17 | } 18 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/Review.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import lombok.*; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.Id; 8 | import javax.validation.constraints.NotEmpty; 9 | import javax.validation.constraints.NotNull; 10 | 11 | @Entity 12 | @Getter 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class Review { 17 | 18 | @Id 19 | @GeneratedValue 20 | private Long id; 21 | 22 | @Setter 23 | private Long restaurantId; 24 | 25 | private String name; 26 | 27 | @NotNull 28 | private Integer score; 29 | 30 | @NotEmpty 31 | private String description; 32 | } 33 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/ReviewRepository.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.List; 6 | 7 | public interface ReviewRepository extends CrudRepository { 8 | 9 | List findAll(); 10 | 11 | List findAllByRestaurantId(Long restaurantId); 12 | 13 | Review save(Review review); 14 | } 15 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/User.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import lombok.*; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.Id; 8 | import javax.validation.constraints.NotEmpty; 9 | import javax.validation.constraints.NotNull; 10 | 11 | @Entity 12 | @Getter 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class User { 17 | 18 | @Id 19 | @GeneratedValue 20 | private Long id; 21 | 22 | @Setter 23 | @NotEmpty 24 | private String email; 25 | 26 | @Setter 27 | @NotEmpty 28 | private String name; 29 | 30 | @Setter 31 | @NotNull 32 | private Long level; 33 | 34 | private String password; 35 | 36 | private Long restaurantId; 37 | 38 | public boolean isAdmin() { 39 | return level >= 100; 40 | } 41 | 42 | public boolean isActive() { 43 | return level > 0; 44 | } 45 | 46 | public void deativate() { 47 | level = 0L; 48 | } 49 | 50 | public void setRestaurantId(Long restaurantId) { 51 | this.level = 50L; 52 | this.restaurantId = restaurantId; 53 | } 54 | 55 | public boolean isRestaurantOwner() { 56 | return level == 50L; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/domain/UserRepository.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.List; 6 | import java.util.Optional; 7 | 8 | public interface UserRepository extends CrudRepository { 9 | 10 | List findAll(); 11 | 12 | Optional findById(Long id); 13 | 14 | Optional findByEmail(String email); 15 | } 16 | -------------------------------------------------------------------------------- /eatgo-common/src/main/java/kr/co/fastcampus/eatgo/utils/JwtUtil.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.utils; 2 | 3 | import io.jsonwebtoken.Claims; 4 | import io.jsonwebtoken.JwtBuilder; 5 | import io.jsonwebtoken.Jwts; 6 | import io.jsonwebtoken.SignatureAlgorithm; 7 | import io.jsonwebtoken.security.Keys; 8 | 9 | import java.security.Key; 10 | 11 | public class JwtUtil { 12 | 13 | private Key key; 14 | 15 | public JwtUtil(String secret) { 16 | this.key = Keys.hmacShaKeyFor(secret.getBytes()); 17 | } 18 | 19 | public String createToken(Long userId, String name, Long restaurantId) { 20 | JwtBuilder builder = Jwts.builder() 21 | .claim("userId", userId) 22 | .claim("name", name); 23 | if (restaurantId != null) { 24 | builder = builder.claim("restaurantId", restaurantId); 25 | } 26 | return builder 27 | .signWith(key, SignatureAlgorithm.HS256) 28 | .compact(); 29 | } 30 | 31 | public Claims getClaims(String token) { 32 | return Jwts.parser() 33 | .setSigningKey(key) 34 | .parseClaimsJws(token) 35 | .getBody(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /eatgo-common/src/test/java/kr/co/fastcampus/eatgo/domain/CategoryTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | public class CategoryTests { 8 | 9 | @Test 10 | public void creation() { 11 | Category category = Category.builder().name("Korean Food").build(); 12 | 13 | assertThat(category.getName()).isEqualTo("Korean Food"); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /eatgo-common/src/test/java/kr/co/fastcampus/eatgo/domain/RegionTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | public class RegionTests { 8 | 9 | @Test 10 | public void creation() { 11 | Region region = Region.builder().name("서울").build(); 12 | 13 | assertThat(region.getName()).isEqualTo("서울"); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /eatgo-common/src/test/java/kr/co/fastcampus/eatgo/domain/RestaurantTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | public class RestaurantTests { 8 | 9 | @Test 10 | public void creation() { 11 | Restaurant restaurant = Restaurant.builder() 12 | .id(1004L) 13 | .name("Bob zip") 14 | .address("Seoul") 15 | .build(); 16 | 17 | assertThat(restaurant.getId()).isEqualTo(1004L); 18 | assertThat(restaurant.getName()).isEqualTo("Bob zip"); 19 | assertThat(restaurant.getAddress()).isEqualTo("Seoul"); 20 | } 21 | 22 | @Test 23 | public void information() { 24 | Restaurant restaurant = Restaurant.builder() 25 | .id(1004L) 26 | .name("Bob zip") 27 | .address("Seoul") 28 | .build(); 29 | 30 | assertThat(restaurant.getInformation()).isEqualTo("Bob zip in Seoul"); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /eatgo-common/src/test/java/kr/co/fastcampus/eatgo/domain/UserTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.domain; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | public class UserTests { 8 | 9 | @Test 10 | public void creation() { 11 | User user = User.builder() 12 | .email("tester@example.com") 13 | .name("테스터") 14 | .level(100L) 15 | .build(); 16 | 17 | assertThat(user.getName()).isEqualTo("테스터"); 18 | assertThat(user.isAdmin()).isTrue(); 19 | assertThat(user.isActive()).isTrue(); 20 | 21 | user.deativate(); 22 | 23 | assertThat(user.isActive()).isFalse(); 24 | } 25 | 26 | @Test 27 | public void restaurantOwner() { 28 | User user = User.builder().level(1L).build(); 29 | 30 | assertThat(user.isRestaurantOwner()).isFalse(); 31 | 32 | user.setRestaurantId(1004L); 33 | 34 | assertThat(user.isRestaurantOwner()).isTrue(); 35 | assertThat(user.getRestaurantId()).isEqualTo(1004L); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /eatgo-common/src/test/java/kr/co/fastcampus/eatgo/utils/JwtUtilTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.utils; 2 | 3 | import io.jsonwebtoken.Claims; 4 | import org.junit.jupiter.api.BeforeEach; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | public class JwtUtilTests { 10 | 11 | private static final String SECRET = "12345678901234567890123456789012"; 12 | 13 | private JwtUtil jwtUtil; 14 | 15 | @BeforeEach 16 | public void setUp() { 17 | jwtUtil = new JwtUtil(SECRET); 18 | } 19 | 20 | @Test 21 | public void createToken() { 22 | String token = jwtUtil.createToken(1004L, "John", null); 23 | 24 | assertThat(token).contains("."); 25 | } 26 | 27 | @Test 28 | public void getCalims() { 29 | String token = "eyJhbGciOiJIUzI1NiJ9." + 30 | "eyJ1c2VySWQiOjEwMDQsIm5hbWUiOiJKb2huIn0." + 31 | "8hm6ZOJykSINHxL-rf0yV882fApL3hyQ9-WGlJUyo2A"; 32 | 33 | Claims claims = jwtUtil.getClaims(token); 34 | 35 | assertThat(claims.get("userId", Long.class)).isEqualTo(1004L); 36 | assertThat(claims.get("name")).isEqualTo("John"); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /eatgo-customer-api/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.2.1.RELEASE' 3 | id 'io.spring.dependency-management' version '1.0.8.RELEASE' 4 | id 'java' 5 | } 6 | 7 | group = 'kr.co.fastcampus' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '1.8' 10 | 11 | configurations { 12 | developmentOnly 13 | runtimeClasspath { 14 | extendsFrom developmentOnly 15 | } 16 | compileOnly { 17 | extendsFrom annotationProcessor 18 | } 19 | } 20 | 21 | repositories { 22 | mavenCentral() 23 | } 24 | 25 | dependencies { 26 | implementation project(':eatgo-common') 27 | 28 | implementation 'org.springframework.boot:spring-boot-starter-web' 29 | implementation 'org.springframework.boot:spring-boot-starter-security' 30 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 31 | 32 | implementation 'com.h2database:h2' 33 | implementation 'mysql:mysql-connector-java' 34 | 35 | compileOnly 'org.projectlombok:lombok' 36 | 37 | developmentOnly 'org.springframework.boot:spring-boot-devtools' 38 | 39 | annotationProcessor 'org.projectlombok:lombok' 40 | 41 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 42 | } 43 | 44 | test { 45 | useJUnitPlatform() 46 | } 47 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/EatgoCustomerApiApplication.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class EatgoCustomerApiApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(EatgoCustomerApiApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/SecurityJavaConfig.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo; 2 | 3 | import kr.co.fastcampus.eatgo.filters.JwtAuthenticationFilter; 4 | import kr.co.fastcampus.eatgo.utils.JwtUtil; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 10 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 11 | import org.springframework.security.config.http.SessionCreationPolicy; 12 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 13 | import org.springframework.security.crypto.password.PasswordEncoder; 14 | 15 | import javax.servlet.Filter; 16 | 17 | @Configuration 18 | @EnableWebSecurity 19 | public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { 20 | 21 | @Value("${jwt.secret}") 22 | private String secret; 23 | 24 | @Override 25 | protected void configure(HttpSecurity http) throws Exception { 26 | Filter filter = new JwtAuthenticationFilter( 27 | authenticationManager(), jwtUtil()); 28 | 29 | http 30 | .cors().disable() 31 | .csrf().disable() 32 | .formLogin().disable() 33 | .headers().frameOptions().disable() 34 | .and() 35 | .addFilter(filter) 36 | .sessionManagement() 37 | .sessionCreationPolicy(SessionCreationPolicy.STATELESS); 38 | } 39 | 40 | @Bean 41 | public PasswordEncoder passwordEncoder() { 42 | return new BCryptPasswordEncoder(); 43 | } 44 | 45 | @Bean 46 | public JwtUtil jwtUtil() { 47 | return new JwtUtil(secret); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/application/CategoryService.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Category; 4 | import kr.co.fastcampus.eatgo.domain.CategoryRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.util.List; 9 | 10 | @Service 11 | public class CategoryService { 12 | 13 | private CategoryRepository categoryRepository; 14 | 15 | @Autowired 16 | public CategoryService(CategoryRepository categoryRepository) { 17 | this.categoryRepository = categoryRepository; 18 | } 19 | 20 | public List getCategories() { 21 | List categories = categoryRepository.findAll(); 22 | 23 | return categories; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/application/EmailExistedException.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | public class EmailExistedException extends RuntimeException { 4 | 5 | EmailExistedException(String email) { 6 | super("Email is already registered: " + email); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/application/RegionService.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Region; 4 | import kr.co.fastcampus.eatgo.domain.RegionRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.util.List; 9 | 10 | @Service 11 | public class RegionService { 12 | 13 | private RegionRepository regionRepository; 14 | 15 | @Autowired 16 | public RegionService(RegionRepository regionRepository) { 17 | this.regionRepository = regionRepository; 18 | } 19 | 20 | public List getRegions() { 21 | List regions = regionRepository.findAll(); 22 | 23 | return regions; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/application/ReservationService.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Reservation; 4 | import kr.co.fastcampus.eatgo.domain.ReservationRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.transaction.Transactional; 9 | 10 | @Service 11 | @Transactional 12 | public class ReservationService { 13 | 14 | private ReservationRepository reservationRepository; 15 | 16 | @Autowired 17 | public ReservationService(ReservationRepository reservationRepository) { 18 | this.reservationRepository = reservationRepository; 19 | } 20 | 21 | public Reservation addReservation(Long restaurantId, Long userId, String name, 22 | String date, String time, Integer partySize) { 23 | Reservation reservation = Reservation.builder() 24 | .restaurantId(restaurantId) 25 | .userId(userId) 26 | .name(name) 27 | .date(date) 28 | .time(time) 29 | .partySize(partySize) 30 | .build(); 31 | 32 | return reservationRepository.save(reservation); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/application/RestaurantService.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.*; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.stereotype.Service; 6 | 7 | import javax.transaction.Transactional; 8 | import java.util.List; 9 | 10 | @Service 11 | @Transactional 12 | public class RestaurantService { 13 | 14 | private RestaurantRepository restaurantRepository; 15 | private MenuItemRepository menuItemRepository; 16 | private ReviewRepository reviewRepository; 17 | 18 | @Autowired 19 | public RestaurantService(RestaurantRepository restaurantRepository, 20 | MenuItemRepository menuItemRepository, 21 | ReviewRepository reviewRepository) { 22 | this.restaurantRepository = restaurantRepository; 23 | this.menuItemRepository = menuItemRepository; 24 | this.reviewRepository = reviewRepository; 25 | } 26 | 27 | public List getRestaurants(String region, long categoryId) { 28 | List restaurants = 29 | restaurantRepository.findAllByAddressContainingAndCategoryId( 30 | region, categoryId); 31 | 32 | return restaurants; 33 | } 34 | 35 | public Restaurant getRestaurant(Long id) { 36 | Restaurant restaurant = restaurantRepository.findById(id) 37 | .orElseThrow(() -> new RestaurantNotFoundException(id)); 38 | 39 | List menuItems = menuItemRepository.findAllByRestaurantId(id); 40 | restaurant.setMenuItems(menuItems); 41 | 42 | List reviews = reviewRepository.findAllByRestaurantId(id); 43 | restaurant.setReviews(reviews); 44 | 45 | return restaurant; 46 | } 47 | 48 | public Restaurant addRestaurant(Restaurant restaurant) { 49 | return restaurantRepository.save(restaurant); 50 | } 51 | 52 | public Restaurant updateRestaurant(Long id, Long categoryId, 53 | String name, String address) { 54 | Restaurant restaurant = restaurantRepository.findById(id).orElse(null); 55 | 56 | restaurant.updateInformation(categoryId, name, address); 57 | 58 | return restaurant; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/application/ReviewService.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Review; 4 | import kr.co.fastcampus.eatgo.domain.ReviewRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | @Service 9 | public class ReviewService { 10 | 11 | private ReviewRepository reviewRepository; 12 | 13 | @Autowired 14 | public ReviewService(ReviewRepository reviewRepository) { 15 | this.reviewRepository = reviewRepository; 16 | } 17 | 18 | public Review addReview(Long restaurantId, String name, Integer score, 19 | String description) { 20 | Review review = Review.builder() 21 | .restaurantId(restaurantId) 22 | .name(name) 23 | .score(score) 24 | .description(description) 25 | .build(); 26 | 27 | return reviewRepository.save(review); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/application/UserService.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.User; 4 | import kr.co.fastcampus.eatgo.domain.UserRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 7 | import org.springframework.security.crypto.password.PasswordEncoder; 8 | import org.springframework.stereotype.Service; 9 | 10 | import javax.transaction.Transactional; 11 | import java.util.Optional; 12 | 13 | @Service 14 | @Transactional 15 | public class UserService { 16 | 17 | UserRepository userRepostory; 18 | 19 | PasswordEncoder passwordEncoder; 20 | 21 | @Autowired 22 | public UserService(UserRepository userRepostory, 23 | PasswordEncoder passwordEncoder) { 24 | this.userRepostory = userRepostory; 25 | this.passwordEncoder = passwordEncoder; 26 | } 27 | 28 | public User registerUser(String email, String name, String password) { 29 | Optional existed = userRepostory.findByEmail(email); 30 | if (existed.isPresent()) { 31 | throw new EmailExistedException(email); 32 | } 33 | 34 | String encodedPassword = passwordEncoder.encode(password); 35 | 36 | User user = User.builder() 37 | .email(email) 38 | .name(name) 39 | .password(encodedPassword) 40 | .level(1L) 41 | .build(); 42 | 43 | return userRepostory.save(user); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/filters/JwtAuthenticationFilter.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.filters; 2 | 3 | import io.jsonwebtoken.Claims; 4 | import kr.co.fastcampus.eatgo.utils.JwtUtil; 5 | import org.springframework.security.authentication.AuthenticationManager; 6 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 7 | import org.springframework.security.core.Authentication; 8 | import org.springframework.security.core.context.SecurityContext; 9 | import org.springframework.security.core.context.SecurityContextHolder; 10 | import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; 11 | 12 | import javax.servlet.FilterChain; 13 | import javax.servlet.ServletException; 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpServletResponse; 16 | import java.io.IOException; 17 | 18 | public class JwtAuthenticationFilter extends BasicAuthenticationFilter { 19 | 20 | private JwtUtil jwtUtil; 21 | 22 | public JwtAuthenticationFilter( 23 | AuthenticationManager authenticationManager, JwtUtil jwtUtil) { 24 | super(authenticationManager); 25 | this.jwtUtil = jwtUtil; 26 | } 27 | 28 | @Override 29 | protected void doFilterInternal( 30 | HttpServletRequest request, 31 | HttpServletResponse response, 32 | FilterChain chain 33 | ) throws IOException, ServletException { 34 | Authentication authentication = getAuthentication(request); 35 | 36 | if (authentication != null) { 37 | SecurityContext context = SecurityContextHolder.getContext(); 38 | context.setAuthentication(authentication); 39 | } 40 | 41 | chain.doFilter(request, response); 42 | } 43 | 44 | private Authentication getAuthentication(HttpServletRequest request) { 45 | String token = request.getHeader("Authorization"); 46 | if (token == null) { 47 | return null; 48 | } 49 | 50 | Claims claims = jwtUtil.getClaims(token.substring("Bearer ".length())); 51 | 52 | Authentication authentication = 53 | new UsernamePasswordAuthenticationToken(claims, null); 54 | return authentication; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/CategoryController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.CategoryService; 4 | import kr.co.fastcampus.eatgo.domain.Category; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.CrossOrigin; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import java.util.List; 11 | 12 | @CrossOrigin 13 | @RestController 14 | public class CategoryController { 15 | 16 | @Autowired 17 | private CategoryService categoryService; 18 | 19 | @GetMapping("/categories") 20 | public List list() { 21 | List regions = categoryService.getCategories(); 22 | 23 | return regions; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/RegionController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.RegionService; 4 | import kr.co.fastcampus.eatgo.domain.Region; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.CrossOrigin; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import java.util.List; 11 | 12 | @CrossOrigin 13 | @RestController 14 | public class RegionController { 15 | 16 | @Autowired 17 | private RegionService regionService; 18 | 19 | @GetMapping("/regions") 20 | public List list() { 21 | List regions = regionService.getRegions(); 22 | 23 | return regions; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/ReservationController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import io.jsonwebtoken.Claims; 4 | import kr.co.fastcampus.eatgo.application.ReservationService; 5 | import kr.co.fastcampus.eatgo.domain.Reservation; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.security.core.Authentication; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import javax.validation.Valid; 12 | import java.net.URI; 13 | import java.net.URISyntaxException; 14 | 15 | @CrossOrigin 16 | @RestController 17 | public class ReservationController { 18 | 19 | @Autowired 20 | private ReservationService reservationService; 21 | 22 | @PostMapping("/restaurants/{restaurantId}/reservations") 23 | public ResponseEntity creaate( 24 | Authentication authentication, 25 | @PathVariable Long restaurantId, 26 | @Valid @RequestBody Reservation resource 27 | ) throws URISyntaxException { 28 | Claims claims = (Claims) authentication.getPrincipal(); 29 | 30 | Long userId = claims.get("userId", Long.class); 31 | String name = claims.get("name", String.class); 32 | 33 | String date = resource.getDate(); 34 | String time = resource.getTime(); 35 | Integer partySize = resource.getPartySize(); 36 | 37 | Reservation reservation = reservationService.addReservation( 38 | restaurantId, userId, name, date, time, partySize); 39 | 40 | String url = "/restaurants/" + restaurantId + 41 | "/reservations/" + reservation.getId(); 42 | return ResponseEntity.created(new URI(url)).body("{}"); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/RestaurantController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.RestaurantService; 4 | import kr.co.fastcampus.eatgo.domain.Restaurant; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | import java.util.List; 9 | 10 | @CrossOrigin 11 | @RestController 12 | public class RestaurantController { 13 | 14 | @Autowired 15 | private RestaurantService restaurantService; 16 | 17 | @GetMapping("/restaurants") 18 | public List list( 19 | @RequestParam("region") String region, 20 | @RequestParam("category") Long categoryId 21 | ) { 22 | List restaurants = 23 | restaurantService.getRestaurants(region, categoryId); 24 | 25 | return restaurants; 26 | } 27 | 28 | @GetMapping("/restaurants/{id}") 29 | public Restaurant detail(@PathVariable("id") Long id) { 30 | Restaurant restaurant = restaurantService.getRestaurant(id); 31 | 32 | return restaurant; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/RestaurantErrorAdvice.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.domain.RestaurantNotFoundException; 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.web.bind.annotation.ControllerAdvice; 6 | import org.springframework.web.bind.annotation.ExceptionHandler; 7 | import org.springframework.web.bind.annotation.ResponseBody; 8 | import org.springframework.web.bind.annotation.ResponseStatus; 9 | 10 | @ControllerAdvice 11 | public class RestaurantErrorAdvice { 12 | 13 | @ResponseBody 14 | @ResponseStatus(HttpStatus.NOT_FOUND) 15 | @ExceptionHandler(RestaurantNotFoundException.class) 16 | public String handleNotFound() { 17 | return "{}"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/ReviewController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import io.jsonwebtoken.Claims; 4 | import kr.co.fastcampus.eatgo.application.ReviewService; 5 | import kr.co.fastcampus.eatgo.domain.Review; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.security.core.Authentication; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import javax.validation.Valid; 12 | import java.net.URI; 13 | import java.net.URISyntaxException; 14 | 15 | @CrossOrigin 16 | @RestController 17 | public class ReviewController { 18 | 19 | @Autowired 20 | private ReviewService reviewService; 21 | 22 | @PostMapping("/restaurants/{restaurantId}/reviews") 23 | public ResponseEntity create( 24 | Authentication authentication, 25 | @PathVariable("restaurantId") Long restaurantId, 26 | @Valid @RequestBody Review resource 27 | ) throws URISyntaxException { 28 | Claims claims = (Claims) authentication.getPrincipal(); 29 | 30 | String name = claims.get("name", String.class); 31 | Integer score = resource.getScore(); 32 | String description = resource.getDescription(); 33 | 34 | Review review = reviewService.addReview( 35 | restaurantId, name, score, description); 36 | 37 | String url = "/restaurants/" + restaurantId + 38 | "/reviews/" + review.getId(); 39 | return ResponseEntity.created(new URI(url)).body("{}"); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/UserController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.UserService; 4 | import kr.co.fastcampus.eatgo.domain.User; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.CrossOrigin; 8 | import org.springframework.web.bind.annotation.PostMapping; 9 | import org.springframework.web.bind.annotation.RequestBody; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import java.net.URI; 13 | import java.net.URISyntaxException; 14 | 15 | @CrossOrigin 16 | @RestController 17 | public class UserController { 18 | 19 | @Autowired 20 | private UserService userService; 21 | 22 | @PostMapping("/users") 23 | public ResponseEntity create( 24 | @RequestBody User resource 25 | ) throws URISyntaxException { 26 | String email = resource.getEmail(); 27 | String name = resource.getName(); 28 | String password = resource.getPassword(); 29 | 30 | User user = userService.registerUser(email, name, password); 31 | 32 | String url = "/users/" + user.getId(); 33 | return ResponseEntity.created(new URI(url)).body("{}"); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/WelcomeController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class WelcomeController { 8 | 9 | @GetMapping("/") 10 | public String hello() { 11 | return "Hello, world!"; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:h2:~/data/eatgo 4 | jpa: 5 | hibernate: 6 | ddl-auto: update 7 | 8 | jwt: 9 | secret: 12345678901234567890123456789012 10 | 11 | --- 12 | 13 | spring: 14 | profiles: test 15 | datasource: 16 | url: jdbc:h2:mem:test 17 | 18 | --- 19 | 20 | spring: 21 | profiles: mysql 22 | datasource: 23 | url: jdbc:mysql://${MYSQL_HOST}:3306/${MYSQL_DATABASE} 24 | username: ${MYSQL_USER} 25 | password: ${MYSQL_PASSWORD} 26 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/test/java/kr/co/fastcampus/eatgo/EatgoCustomerApiApplicationTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | public class EatgoCustomerApiApplicationTests { 8 | 9 | @Test 10 | public void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/test/java/kr/co/fastcampus/eatgo/application/CategoryServiceTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Category; 4 | import kr.co.fastcampus.eatgo.domain.CategoryRepository; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | import org.mockito.InjectMocks; 8 | import org.mockito.Mock; 9 | import org.mockito.MockitoAnnotations; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import static org.assertj.core.api.Assertions.assertThat; 15 | import static org.mockito.BDDMockito.given; 16 | 17 | public class CategoryServiceTests { 18 | 19 | @InjectMocks 20 | private CategoryService categoryService; 21 | 22 | @Mock 23 | private CategoryRepository categoryRepository; 24 | 25 | @BeforeEach 26 | public void setUp() { 27 | MockitoAnnotations.initMocks(this); 28 | } 29 | 30 | @Test 31 | public void getRegions() { 32 | List mockCategory = new ArrayList<>(); 33 | mockCategory.add(Category.builder().name("Korean Food").build()); 34 | 35 | given(categoryRepository.findAll()).willReturn(mockCategory); 36 | 37 | List categories = categoryService.getCategories(); 38 | 39 | Category category = categories.get(0); 40 | assertThat(category.getName()).isEqualTo("Korean Food"); 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /eatgo-customer-api/src/test/java/kr/co/fastcampus/eatgo/application/RegionServiceTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Region; 4 | import kr.co.fastcampus.eatgo.domain.RegionRepository; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | import org.mockito.InjectMocks; 8 | import org.mockito.Mock; 9 | import org.mockito.MockitoAnnotations; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import static org.assertj.core.api.Assertions.assertThat; 15 | import static org.mockito.BDDMockito.given; 16 | 17 | public class RegionServiceTests { 18 | 19 | @InjectMocks 20 | private RegionService regionService; 21 | 22 | @Mock 23 | private RegionRepository regionRepository; 24 | 25 | @BeforeEach 26 | public void setUp() { 27 | MockitoAnnotations.initMocks(this); 28 | } 29 | 30 | @Test 31 | public void getRegions() { 32 | List mockRegions = new ArrayList<>(); 33 | mockRegions.add(Region.builder().name("Seoul").build()); 34 | 35 | given(regionRepository.findAll()).willReturn(mockRegions); 36 | 37 | List regions = regionService.getRegions(); 38 | 39 | Region region = regions.get(0); 40 | assertThat(region.getName()).isEqualTo("Seoul"); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/test/java/kr/co/fastcampus/eatgo/application/ReservationServiceTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Reservation; 4 | import kr.co.fastcampus.eatgo.domain.ReservationRepository; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | import org.mockito.InjectMocks; 8 | import org.mockito.Mock; 9 | import org.mockito.MockitoAnnotations; 10 | 11 | import static org.assertj.core.api.Assertions.assertThat; 12 | import static org.mockito.ArgumentMatchers.any; 13 | import static org.mockito.BDDMockito.given; 14 | import static org.mockito.Mockito.verify; 15 | 16 | public class ReservationServiceTests { 17 | 18 | @InjectMocks 19 | private ReservationService reservationService; 20 | 21 | @Mock 22 | private ReservationRepository reservationRepository; 23 | 24 | @BeforeEach 25 | public void setUp() { 26 | MockitoAnnotations.initMocks(this); 27 | } 28 | 29 | @Test 30 | public void addReservation() { 31 | Long restaurantId = 369L; 32 | Long userId = 1004L; 33 | String name = "John"; 34 | String date = "2019-12-24"; 35 | String time = "20:00"; 36 | Integer partySize = 20; 37 | 38 | given(reservationRepository.save(any())).will(invocation -> { 39 | Reservation reservation = invocation.getArgument(0); 40 | return reservation; 41 | }); 42 | 43 | Reservation reservation = reservationService.addReservation( 44 | restaurantId, userId, name, date, time, partySize); 45 | 46 | assertThat(reservation.getName()).isEqualTo(name); 47 | 48 | verify(reservationRepository).save(any(Reservation.class)); 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /eatgo-customer-api/src/test/java/kr/co/fastcampus/eatgo/application/ReviewServiceTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.ReviewRepository; 4 | import org.junit.jupiter.api.BeforeEach; 5 | import org.junit.jupiter.api.Test; 6 | import org.mockito.InjectMocks; 7 | import org.mockito.Mock; 8 | import org.mockito.MockitoAnnotations; 9 | 10 | import static org.mockito.ArgumentMatchers.any; 11 | import static org.mockito.Mockito.verify; 12 | 13 | public class ReviewServiceTests { 14 | 15 | @InjectMocks 16 | private ReviewService reviewService; 17 | 18 | @Mock 19 | private ReviewRepository reviewRepository; 20 | 21 | @BeforeEach 22 | public void setUp() { 23 | MockitoAnnotations.initMocks(this); 24 | } 25 | 26 | @Test 27 | public void addReview() { 28 | reviewService.addReview(1004L, "JOKER", 3, "Mat-it-da"); 29 | 30 | verify(reviewRepository).save(any()); 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /eatgo-customer-api/src/test/java/kr/co/fastcampus/eatgo/application/UserServiceTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.User; 4 | import kr.co.fastcampus.eatgo.domain.UserRepository; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | import org.mockito.InjectMocks; 8 | import org.mockito.Mock; 9 | import org.mockito.MockitoAnnotations; 10 | import org.springframework.security.crypto.password.PasswordEncoder; 11 | 12 | import java.util.Optional; 13 | 14 | import static org.assertj.core.api.Assertions.assertThatThrownBy; 15 | import static org.mockito.ArgumentMatchers.any; 16 | import static org.mockito.BDDMockito.given; 17 | import static org.mockito.Mockito.never; 18 | import static org.mockito.Mockito.verify; 19 | 20 | public class UserServiceTests { 21 | 22 | @InjectMocks 23 | private UserService userService; 24 | 25 | @Mock 26 | private UserRepository userRepostory; 27 | 28 | @Mock 29 | private PasswordEncoder passwordEncoder; 30 | 31 | @BeforeEach 32 | public void setUp() { 33 | MockitoAnnotations.initMocks(this); 34 | } 35 | 36 | @Test 37 | public void registerUser() { 38 | String email = "tester@example.com"; 39 | String name = "Tester"; 40 | String password = "test"; 41 | 42 | userService.registerUser(email, name, password); 43 | 44 | verify(userRepostory).save(any()); 45 | } 46 | 47 | @Test 48 | public void registerUserWithExistedEmail() { 49 | String email = "tester@example.com"; 50 | String name = "Tester"; 51 | String password = "test"; 52 | 53 | User user = User.builder().build(); 54 | given(userRepostory.findByEmail(email)).willReturn(Optional.of(user)); 55 | 56 | assertThatThrownBy(() -> { 57 | userService.registerUser(email, name, password); 58 | }).isInstanceOf(EmailExistedException.class); 59 | 60 | verify(userRepostory, never()).save(any()); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/test/java/kr/co/fastcampus/eatgo/interfaces/CategoryControllerTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.CategoryService; 4 | import kr.co.fastcampus.eatgo.domain.Category; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 8 | import org.springframework.boot.test.mock.mockito.MockBean; 9 | import org.springframework.test.web.servlet.MockMvc; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import static org.hamcrest.core.StringContains.containsString; 15 | import static org.mockito.BDDMockito.given; 16 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 17 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 18 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 19 | 20 | @WebMvcTest(CategoryController.class) 21 | public class CategoryControllerTests { 22 | 23 | @Autowired 24 | private MockMvc mvc; 25 | 26 | @MockBean 27 | private CategoryService categoryService; 28 | 29 | @Test 30 | public void list() throws Exception { 31 | List categories = new ArrayList<>(); 32 | categories.add(Category.builder().name("Korean Food").build()); 33 | 34 | given(categoryService.getCategories()).willReturn(categories); 35 | 36 | mvc.perform(get("/categories")) 37 | .andExpect(status().isOk()) 38 | .andExpect(content().string(containsString("Korean Food"))); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/test/java/kr/co/fastcampus/eatgo/interfaces/RegionControllerTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.RegionService; 4 | import kr.co.fastcampus.eatgo.domain.Region; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 8 | import org.springframework.boot.test.mock.mockito.MockBean; 9 | import org.springframework.test.web.servlet.MockMvc; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import static org.hamcrest.core.StringContains.containsString; 15 | import static org.mockito.BDDMockito.given; 16 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 17 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 18 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 19 | 20 | @WebMvcTest(RegionController.class) 21 | public class RegionControllerTests { 22 | 23 | @Autowired 24 | private MockMvc mvc; 25 | 26 | @MockBean 27 | private RegionService regionService; 28 | 29 | @Test 30 | public void list() throws Exception { 31 | List regions = new ArrayList<>(); 32 | regions.add(Region.builder().name("Seoul").build()); 33 | 34 | given(regionService.getRegions()).willReturn(regions); 35 | 36 | mvc.perform(get("/regions")) 37 | .andExpect(status().isOk()) 38 | .andExpect(content().string(containsString("Seoul"))); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/test/java/kr/co/fastcampus/eatgo/interfaces/ReservationControllerTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.ReservationService; 4 | import kr.co.fastcampus.eatgo.domain.Reservation; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 8 | import org.springframework.boot.test.mock.mockito.MockBean; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.test.web.servlet.MockMvc; 11 | 12 | import static org.mockito.ArgumentMatchers.any; 13 | import static org.mockito.BDDMockito.given; 14 | import static org.mockito.Mockito.verify; 15 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 16 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 17 | 18 | @WebMvcTest(ReservationController.class) 19 | public class ReservationControllerTests { 20 | 21 | @Autowired 22 | private MockMvc mvc; 23 | 24 | @MockBean 25 | private ReservationService reservationService; 26 | 27 | @Test 28 | public void create() throws Exception { 29 | String token = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEwMDQsIm5hbWUiOiJKb2huIn0.8hm6ZOJykSINHxL-rf0yV882fApL3hyQ9-WGlJUyo2A"; 30 | 31 | Reservation mockReservation = Reservation.builder().id(12L).build(); 32 | 33 | given(reservationService 34 | .addReservation(any(), any(), any(), any(), any(), any()) 35 | ).willReturn(mockReservation); 36 | 37 | mvc.perform(post("/restaurants/369/reservations") 38 | .header("Authorization", "Bearer " + token) 39 | .contentType(MediaType.APPLICATION_JSON) 40 | .content("{\"date\":\"2019-12-24\",\"time\":\"20:00\"," + 41 | "\"partySize\":20}")) 42 | .andExpect(status().isCreated()); 43 | 44 | Long userId = 1004L; 45 | String name = "John"; 46 | String date = "2019-12-24"; 47 | String time = "20:00"; 48 | Integer partySize = 20; 49 | 50 | verify(reservationService) 51 | .addReservation(369L, userId, name, date, time, partySize); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/test/java/kr/co/fastcampus/eatgo/interfaces/RestaurantControllerTest.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.RestaurantService; 4 | import kr.co.fastcampus.eatgo.domain.MenuItem; 5 | import kr.co.fastcampus.eatgo.domain.Restaurant; 6 | import kr.co.fastcampus.eatgo.domain.RestaurantNotFoundException; 7 | import kr.co.fastcampus.eatgo.domain.Review; 8 | import org.junit.jupiter.api.Test; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 11 | import org.springframework.boot.test.mock.mockito.MockBean; 12 | import org.springframework.test.web.servlet.MockMvc; 13 | 14 | import java.util.ArrayList; 15 | import java.util.Arrays; 16 | import java.util.List; 17 | 18 | import static org.hamcrest.core.StringContains.containsString; 19 | import static org.mockito.BDDMockito.given; 20 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 21 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 22 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 23 | 24 | @WebMvcTest(RestaurantController.class) 25 | public class RestaurantControllerTest { 26 | 27 | @Autowired 28 | private MockMvc mvc; 29 | 30 | @MockBean 31 | private RestaurantService restaurantService; 32 | 33 | @Test 34 | public void list() throws Exception { 35 | List restaurants = new ArrayList<>(); 36 | restaurants.add(Restaurant.builder() 37 | .id(1004L) 38 | .categoryId(1L) 39 | .name("JOKER House") 40 | .address("Seoul") 41 | .build()); 42 | 43 | given(restaurantService.getRestaurants("Seoul", 1L)) 44 | .willReturn(restaurants); 45 | 46 | mvc.perform(get("/restaurants?region=Seoul&category=1")) 47 | .andExpect(status().isOk()) 48 | .andExpect(content().string( 49 | containsString("\"id\":1004") 50 | )) 51 | .andExpect(content().string( 52 | containsString("\"name\":\"JOKER House\"") 53 | )); 54 | } 55 | 56 | @Test 57 | public void detailWithExisted() throws Exception { 58 | Restaurant restaurant = Restaurant.builder() 59 | .id(1004L) 60 | .name("JOKER House") 61 | .address("Seoul") 62 | .build(); 63 | MenuItem menuItem = MenuItem.builder() 64 | .name("Kimchi") 65 | .build(); 66 | restaurant.setMenuItems(Arrays.asList(menuItem)); 67 | Review review = Review.builder() 68 | .name("JOKER") 69 | .score(5) 70 | .description("Great!") 71 | .build(); 72 | restaurant.setReviews(Arrays.asList(review)); 73 | 74 | given(restaurantService.getRestaurant(1004L)).willReturn(restaurant); 75 | 76 | mvc.perform(get("/restaurants/1004")) 77 | .andExpect(status().isOk()) 78 | .andExpect(content().string( 79 | containsString("\"id\":1004") 80 | )) 81 | .andExpect(content().string( 82 | containsString("\"name\":\"JOKER House\"") 83 | )) 84 | .andExpect(content().string( 85 | containsString("Kimchi") 86 | )) 87 | .andExpect(content().string( 88 | containsString("Great!") 89 | )); 90 | } 91 | 92 | @Test 93 | public void detailWithNotExisted() throws Exception { 94 | given(restaurantService.getRestaurant(404L)) 95 | .willThrow(new RestaurantNotFoundException(404L)); 96 | 97 | mvc.perform(get("/restaurants/404")) 98 | .andExpect(status().isNotFound()) 99 | .andExpect(content().string("{}")); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/test/java/kr/co/fastcampus/eatgo/interfaces/ReviewControllerTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.ReviewService; 4 | import kr.co.fastcampus.eatgo.domain.Review; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 8 | import org.springframework.boot.test.mock.mockito.MockBean; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.test.web.servlet.MockMvc; 11 | 12 | import static org.mockito.ArgumentMatchers.any; 13 | import static org.mockito.BDDMockito.given; 14 | import static org.mockito.Mockito.never; 15 | import static org.mockito.Mockito.verify; 16 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 17 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; 18 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 19 | 20 | @WebMvcTest(ReviewController.class) 21 | public class ReviewControllerTests { 22 | 23 | @Autowired 24 | private MockMvc mvc; 25 | 26 | @MockBean 27 | private ReviewService reviewService; 28 | 29 | @Test 30 | public void createWithValidAttriutes() throws Exception { 31 | String token = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEwMDQsIm5hbWUiOiJKb2huIn0.8hm6ZOJykSINHxL-rf0yV882fApL3hyQ9-WGlJUyo2A"; 32 | 33 | given(reviewService.addReview(1L, "John", 3, "Mat-it-da")).willReturn( 34 | Review.builder().id(1004L).build()); 35 | 36 | mvc.perform(post("/restaurants/1/reviews") 37 | .header("Authorization", "Bearer " + token) 38 | .contentType(MediaType.APPLICATION_JSON) 39 | .content("{\"score\":3,\"description\":\"Mat-it-da\"}")) 40 | .andExpect(status().isCreated()) 41 | .andExpect(header().string("location", "/restaurants/1/reviews/1004")); 42 | 43 | verify(reviewService).addReview(1L, "John", 3, "Mat-it-da"); 44 | } 45 | 46 | @Test 47 | public void createWithInvalidAttriutes() throws Exception { 48 | mvc.perform(post("/restaurants/1/reviews") 49 | .contentType(MediaType.APPLICATION_JSON) 50 | .content("{}")) 51 | .andExpect(status().isBadRequest()); 52 | 53 | verify(reviewService, never()).addReview(any(), any(), any(), any()); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/test/java/kr/co/fastcampus/eatgo/interfaces/UserControllerTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.UserService; 4 | import kr.co.fastcampus.eatgo.domain.User; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 8 | import org.springframework.boot.test.mock.mockito.MockBean; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.test.web.servlet.MockMvc; 11 | 12 | import static org.mockito.BDDMockito.given; 13 | import static org.mockito.Mockito.verify; 14 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 15 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; 16 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 17 | 18 | @WebMvcTest(UserController.class) 19 | public class UserControllerTests { 20 | 21 | @Autowired 22 | MockMvc mvc; 23 | 24 | @MockBean 25 | private UserService userService; 26 | 27 | @Test 28 | public void create() throws Exception { 29 | User mockUser = User.builder() 30 | .id(1004L) 31 | .email("tester@example.com") 32 | .name("Tester") 33 | .password("test") 34 | .build(); 35 | 36 | given(userService.registerUser("tester@example.com", "Tester", "test")) 37 | .willReturn(mockUser); 38 | 39 | mvc.perform(post("/users") 40 | .contentType(MediaType.APPLICATION_JSON) 41 | .content("{\"email\":\"tester@example.com\"," + 42 | "\"name\":\"Tester\",\"password\":\"test\"}")) 43 | .andExpect(status().isCreated()) 44 | .andExpect(header().string("location", "/users/1004")); 45 | 46 | verify(userService) 47 | .registerUser("tester@example.com", "Tester", "test"); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /eatgo-customer-api/src/test/java/kr/co/fastcampus/eatgo/interfaces/WelcomeControllerTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 6 | import org.springframework.test.web.servlet.MockMvc; 7 | 8 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 9 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 10 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 11 | 12 | @WebMvcTest(WelcomeController.class) 13 | public class WelcomeControllerTests { 14 | 15 | @Autowired 16 | MockMvc mvc; 17 | 18 | @Test 19 | public void hello() throws Exception { 20 | mvc.perform(get("/")) 21 | .andExpect(status().isOk()) 22 | .andExpect(content().string("Hello, world!")); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /eatgo-customer-web/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /eatgo-customer-web/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue}] 2 | indent_style = space 3 | indent_size = 2 4 | end_of_line = lf 5 | trim_trailing_whitespace = true 6 | insert_final_newline = true 7 | max_line_length = 100 8 | -------------------------------------------------------------------------------- /eatgo-customer-web/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true, 5 | }, 6 | extends: [ 7 | 'plugin:vue/essential', 8 | '@vue/airbnb', 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint', 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /eatgo-customer-web/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /eatgo-customer-web/.nvmrc: -------------------------------------------------------------------------------- 1 | v10.16.3 2 | -------------------------------------------------------------------------------- /eatgo-customer-web/README.md: -------------------------------------------------------------------------------- 1 | # EatGo Customer Web 2 | 3 | ## Project setup 4 | 5 | ```bash 6 | npm install 7 | ``` 8 | 9 | ### Compiles and hot-reloads for development 10 | 11 | ```bash 12 | npm run serve 13 | ``` 14 | 15 | ### Compiles and minifies for production 16 | 17 | ```bash 18 | npm run build 19 | ``` 20 | 21 | ### Run your tests 22 | 23 | ```bash 24 | npm run test 25 | ``` 26 | 27 | ### Lints and fixes files 28 | 29 | ```bash 30 | npm run lint 31 | ``` 32 | 33 | ### Customize configuration 34 | 35 | See [Configuration Reference](https://cli.vuejs.org/config/). 36 | -------------------------------------------------------------------------------- /eatgo-customer-web/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app', 4 | ], 5 | }; 6 | -------------------------------------------------------------------------------- /eatgo-customer-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eatgo-customer-web", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.19.0", 12 | "core-js": "^2.6.5", 13 | "moment": "^2.24.0", 14 | "vue": "^2.6.10", 15 | "vue-router": "^3.0.3", 16 | "vuex": "^3.1.1" 17 | }, 18 | "devDependencies": { 19 | "@vue/cli-plugin-babel": "^3.11.0", 20 | "@vue/cli-plugin-eslint": "^3.11.0", 21 | "@vue/cli-service": "^3.11.0", 22 | "@vue/eslint-config-airbnb": "^4.0.0", 23 | "babel-eslint": "^10.0.1", 24 | "eslint": "^5.16.0", 25 | "eslint-plugin-vue": "^5.0.0", 26 | "vue-template-compiler": "^2.6.10" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /eatgo-customer-web/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {}, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /eatgo-customer-web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahastudio/fastcampus-eatgo/21bc7212e120d217bed5d0f995925d0789033900/eatgo-customer-web/public/favicon.ico -------------------------------------------------------------------------------- /eatgo-customer-web/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | EatGo 9 | 14 | 15 | 16 |
17 |
18 |
19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /eatgo-customer-web/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 27 | 28 | 33 | -------------------------------------------------------------------------------- /eatgo-customer-web/src/components/GlobalNavigator.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 30 | 31 | 49 | -------------------------------------------------------------------------------- /eatgo-customer-web/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import App from './App.vue'; 3 | import router from './router'; 4 | import store from './store'; 5 | 6 | Vue.config.productionTip = false; 7 | 8 | store.dispatch('setAccessToken', { 9 | accessToken: localStorage.getItem('accessToken') || '', 10 | }); 11 | 12 | new Vue({ 13 | router, 14 | render: h => h(App), 15 | }).$mount('#app'); 16 | -------------------------------------------------------------------------------- /eatgo-customer-web/src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Router from 'vue-router'; 3 | 4 | import Home from './views/Home.vue'; 5 | import RestaurantList from './views/RestaurantList.vue'; 6 | import RestaurantDetail from './views/RestaurantDetail.vue'; 7 | import Login from './views/Login.vue'; 8 | 9 | import store from './store'; 10 | 11 | Vue.use(Router); 12 | 13 | const authenticated = (_to, _from, next) => { 14 | if (!store.state.accessToken) { 15 | next('/login'); 16 | return; 17 | } 18 | 19 | next(); 20 | }; 21 | 22 | export default new Router({ 23 | mode: 'history', 24 | base: process.env.BASE_URL, 25 | routes: [ 26 | { 27 | path: '/', 28 | name: 'home', 29 | component: Home, 30 | beforeEnter: authenticated, 31 | }, 32 | { 33 | path: '/restaurants', 34 | name: 'restaurant-list', 35 | component: RestaurantList, 36 | beforeEnter: authenticated, 37 | }, 38 | { 39 | path: '/restaurants/:restaurantId', 40 | name: 'restaurant-detail', 41 | component: RestaurantDetail, 42 | beforeEnter: authenticated, 43 | }, 44 | { 45 | path: '/login', 46 | name: 'login', 47 | component: Login, 48 | }, 49 | ], 50 | }); 51 | -------------------------------------------------------------------------------- /eatgo-customer-web/src/store/actions.js: -------------------------------------------------------------------------------- 1 | import * as moment from 'moment'; 2 | 3 | import { 4 | useAccessToken, 5 | get, post, 6 | loginPost, 7 | } from './http'; 8 | 9 | export default { 10 | setAccessToken({ commit }, { accessToken }) { 11 | commit('setAccessToken', accessToken); 12 | 13 | useAccessToken(accessToken); 14 | 15 | localStorage.setItem('accessToken', accessToken); 16 | }, 17 | clearAccessToken({ commit }) { 18 | commit('setAccessToken', ''); 19 | 20 | useAccessToken(''); 21 | 22 | localStorage.removeItem('accessToken'); 23 | }, 24 | async createSession({ commit }, { email, password, success }) { 25 | const { accessToken } = await loginPost('/session', { email, password }); 26 | commit('setAccessToken', accessToken); 27 | 28 | useAccessToken(accessToken); 29 | localStorage.setItem('accessToken', accessToken); 30 | 31 | success(); 32 | }, 33 | async loadCategories({ commit }) { 34 | const categories = await get('/categories'); 35 | commit('setCategories', categories); 36 | }, 37 | async loadRestaurants({ commit }, { region, category }) { 38 | const restaurants = await get('/restaurants', { region, category }); 39 | commit('setRestaurants', restaurants); 40 | }, 41 | async loadRestaurant({ commit }, restaurantId) { 42 | const restaurant = await get(`/restaurants/${restaurantId}`); 43 | commit('setRestaurant', restaurant); 44 | }, 45 | resetReview({ commit }) { 46 | commit('setReview', { 47 | score: 3, 48 | description: '', 49 | }); 50 | }, 51 | async createReview({ state, dispatch }, restaurantId) { 52 | const { review } = state; 53 | try { 54 | await post(`/restaurants/${restaurantId}/reviews`, review); 55 | dispatch('resetReview'); 56 | dispatch('loadRestaurant', restaurantId); 57 | } catch (e) { 58 | // TODO: Show error message 59 | } 60 | }, 61 | resetReservation({ commit }) { 62 | const time = moment().add(1.5, 'hour'); 63 | commit('setReservation', { 64 | date: time.format('YYYY-MM-DD'), 65 | time: time.format('HH:00'), 66 | partySize: 1, 67 | }); 68 | }, 69 | async createReservation({ state, dispatch }, restaurantId) { 70 | const { reservation } = state; 71 | try { 72 | await post(`/restaurants/${restaurantId}/reservations`, reservation); 73 | dispatch('resetReservation'); 74 | } catch (e) { 75 | // TODO: Show error message 76 | } 77 | }, 78 | }; 79 | -------------------------------------------------------------------------------- /eatgo-customer-web/src/store/http.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const LOGIN_API_BASE_URL = process.env.VUE_APP_LOGIN_API_BASE_URL; 4 | const API_BASE_URL = process.env.VUE_APP_API_BASE_URL; 5 | 6 | let http = axios.create({ 7 | baseURL: API_BASE_URL || 'http://localhost:8080', 8 | }); 9 | 10 | export const useAccessToken = (accessToken) => { 11 | http = axios.create({ 12 | baseURL: process.env.VUE_APP_API_BASE_URL || 'http://localhost:8080', 13 | headers: { 14 | authorization: `Bearer ${accessToken}`, 15 | }, 16 | }); 17 | }; 18 | 19 | export const get = async (path, params) => { 20 | const { data } = await http.get(path, { params }); 21 | return data; 22 | }; 23 | 24 | export const post = async (path, payload) => { 25 | const { data } = await http.post(path, payload); 26 | return data; 27 | }; 28 | 29 | export const loginPost = async (path, payload) => { 30 | const url = `${LOGIN_API_BASE_URL || 'http://localhost:8080'}${path}`; 31 | const { data } = await axios.post(url, payload); 32 | return data; 33 | }; 34 | 35 | export default { 36 | }; 37 | -------------------------------------------------------------------------------- /eatgo-customer-web/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuex from 'vuex'; 3 | 4 | import mutations from './mutations'; 5 | import actions from './actions'; 6 | 7 | Vue.use(Vuex); 8 | 9 | const state = { 10 | accessToken: '', 11 | categories: [], 12 | restaurants: [], 13 | restaurant: {}, 14 | review: {}, 15 | reservation: {}, 16 | }; 17 | 18 | export default new Vuex.Store({ 19 | state, 20 | mutations, 21 | actions, 22 | }); 23 | -------------------------------------------------------------------------------- /eatgo-customer-web/src/store/mutations.js: -------------------------------------------------------------------------------- 1 | export default { 2 | setAccessToken(state, accessToken) { 3 | state.accessToken = accessToken; 4 | }, 5 | setCategories(state, categories) { 6 | state.categories = categories; 7 | }, 8 | setRestaurants(state, restaurants) { 9 | state.restaurants = restaurants; 10 | }, 11 | setRestaurant(state, restaurant) { 12 | state.restaurant = restaurant; 13 | }, 14 | setReview(state, review) { 15 | state.review = review; 16 | }, 17 | setReservation(state, reservation) { 18 | state.reservation = reservation; 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /eatgo-customer-web/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 33 | 34 | 66 | -------------------------------------------------------------------------------- /eatgo-customer-web/src/views/Login.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 45 | -------------------------------------------------------------------------------- /eatgo-customer-web/src/views/RestaurantDetail.vue: -------------------------------------------------------------------------------- 1 | 51 | 52 | 78 | 79 | 126 | -------------------------------------------------------------------------------- /eatgo-customer-web/src/views/RestaurantList.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 33 | 34 | 59 | -------------------------------------------------------------------------------- /eatgo-customer-web/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devServer: { 3 | port: 3000, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /eatgo-login-api/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.2.1.RELEASE' 3 | id 'io.spring.dependency-management' version '1.0.8.RELEASE' 4 | id 'java' 5 | } 6 | 7 | group = 'kr.co.fastcampus' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '1.8' 10 | 11 | configurations { 12 | developmentOnly 13 | runtimeClasspath { 14 | extendsFrom developmentOnly 15 | } 16 | compileOnly { 17 | extendsFrom annotationProcessor 18 | } 19 | } 20 | 21 | repositories { 22 | mavenCentral() 23 | } 24 | 25 | dependencies { 26 | implementation project(':eatgo-common') 27 | 28 | implementation 'org.springframework.boot:spring-boot-starter-web' 29 | implementation 'org.springframework.boot:spring-boot-starter-security' 30 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 31 | 32 | implementation 'com.h2database:h2' 33 | implementation 'mysql:mysql-connector-java' 34 | 35 | compileOnly 'org.projectlombok:lombok' 36 | 37 | developmentOnly 'org.springframework.boot:spring-boot-devtools' 38 | 39 | annotationProcessor 'org.projectlombok:lombok' 40 | 41 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 42 | } 43 | 44 | test { 45 | useJUnitPlatform() 46 | } 47 | -------------------------------------------------------------------------------- /eatgo-login-api/src/main/java/kr/co/fastcampus/eatgo/EatgoLoginApiApplication.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class EatgoLoginApiApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(EatgoLoginApiApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /eatgo-login-api/src/main/java/kr/co/fastcampus/eatgo/SecurityJavaConfig.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo; 2 | 3 | import kr.co.fastcampus.eatgo.utils.JwtUtil; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 8 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 10 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 11 | import org.springframework.security.crypto.password.PasswordEncoder; 12 | 13 | @Configuration 14 | @EnableWebSecurity 15 | public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { 16 | 17 | @Value("${jwt.secret}") 18 | private String secret; 19 | 20 | @Override 21 | protected void configure(HttpSecurity http) throws Exception { 22 | http 23 | .cors().disable() 24 | .csrf().disable() 25 | .formLogin().disable() 26 | .headers().frameOptions().disable(); 27 | } 28 | 29 | @Bean 30 | public PasswordEncoder passwordEncoder() { 31 | return new BCryptPasswordEncoder(); 32 | } 33 | 34 | @Bean 35 | public JwtUtil jwtUtil() { 36 | return new JwtUtil(secret); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /eatgo-login-api/src/main/java/kr/co/fastcampus/eatgo/application/EmailNotExistedException.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | public class EmailNotExistedException extends RuntimeException { 4 | 5 | EmailNotExistedException(String email) { 6 | super("Email is not registered: " + email); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /eatgo-login-api/src/main/java/kr/co/fastcampus/eatgo/application/PasswordWrongException.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | public class PasswordWrongException extends RuntimeException { 4 | 5 | PasswordWrongException() { 6 | super("Password is wrong"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /eatgo-login-api/src/main/java/kr/co/fastcampus/eatgo/application/UserService.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.User; 4 | import kr.co.fastcampus.eatgo.domain.UserRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.security.crypto.password.PasswordEncoder; 7 | import org.springframework.stereotype.Service; 8 | 9 | import javax.transaction.Transactional; 10 | import java.util.Optional; 11 | 12 | @Service 13 | @Transactional 14 | public class UserService { 15 | 16 | UserRepository userRepostory; 17 | 18 | PasswordEncoder passwordEncoder; 19 | 20 | @Autowired 21 | public UserService(UserRepository userRepostory, 22 | PasswordEncoder passwordEncoder) { 23 | this.userRepostory = userRepostory; 24 | this.passwordEncoder = passwordEncoder; 25 | } 26 | 27 | public User authenticate(String email, String password) { 28 | User user = userRepostory.findByEmail(email) 29 | .orElseThrow(() -> new EmailNotExistedException(email)); 30 | 31 | if (!passwordEncoder.matches(password, user.getPassword())) { 32 | throw new PasswordWrongException(); 33 | } 34 | 35 | return user; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /eatgo-login-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/SessionController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.UserService; 4 | import kr.co.fastcampus.eatgo.domain.User; 5 | import kr.co.fastcampus.eatgo.utils.JwtUtil; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.web.bind.annotation.CrossOrigin; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | import java.net.URI; 14 | import java.net.URISyntaxException; 15 | 16 | @CrossOrigin 17 | @RestController 18 | public class SessionController { 19 | 20 | @Autowired 21 | private JwtUtil jwtUtil; 22 | 23 | @Autowired 24 | private UserService userService; 25 | 26 | @PostMapping("/session") 27 | public ResponseEntity create( 28 | @RequestBody SessionRequestDto resource 29 | ) throws URISyntaxException { 30 | String email = resource.getEmail(); 31 | String password = resource.getPassword(); 32 | 33 | User user = userService.authenticate(email, password); 34 | 35 | String accessToken = jwtUtil.createToken( 36 | user.getId(), 37 | user.getName(), 38 | user.isRestaurantOwner() ? user.getRestaurantId() : null); 39 | 40 | String url = "/session"; 41 | return ResponseEntity.created(new URI(url)).body( 42 | SessionResponseDto.builder() 43 | .accessToken(accessToken) 44 | .build()); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /eatgo-login-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/SessionErrorAdvice.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.EmailNotExistedException; 4 | import kr.co.fastcampus.eatgo.application.PasswordWrongException; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.web.bind.annotation.ControllerAdvice; 7 | import org.springframework.web.bind.annotation.ExceptionHandler; 8 | import org.springframework.web.bind.annotation.ResponseBody; 9 | import org.springframework.web.bind.annotation.ResponseStatus; 10 | 11 | @ControllerAdvice 12 | public class SessionErrorAdvice { 13 | 14 | @ResponseBody 15 | @ResponseStatus(HttpStatus.BAD_REQUEST) 16 | @ExceptionHandler(EmailNotExistedException.class) 17 | public String handleEmailNotExisted() { 18 | return "{}"; 19 | } 20 | 21 | @ResponseBody 22 | @ResponseStatus(HttpStatus.BAD_REQUEST) 23 | @ExceptionHandler(PasswordWrongException.class) 24 | public String handlePasswordWrong() { 25 | return "{}"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /eatgo-login-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/SessionRequestDto.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class SessionRequestDto { 7 | 8 | private String email; 9 | 10 | private String password; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /eatgo-login-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/SessionResponseDto.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | 6 | @Data 7 | @Builder 8 | public class SessionResponseDto { 9 | 10 | private String accessToken; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /eatgo-login-api/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:h2:~/data/eatgo 4 | jpa: 5 | hibernate: 6 | ddl-auto: update 7 | 8 | jwt: 9 | secret: 12345678901234567890123456789012 10 | 11 | --- 12 | 13 | spring: 14 | profiles: test 15 | datasource: 16 | url: jdbc:h2:mem:test 17 | 18 | --- 19 | 20 | spring: 21 | profiles: mysql 22 | datasource: 23 | url: jdbc:mysql://${MYSQL_HOST}:3306/${MYSQL_DATABASE} 24 | username: ${MYSQL_USER} 25 | password: ${MYSQL_PASSWORD} 26 | -------------------------------------------------------------------------------- /eatgo-login-api/src/test/java/kr/co/fastcampus/eatgo/EatgoLoginApiApplicationTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | public class EatgoLoginApiApplicationTests { 8 | 9 | @Test 10 | public void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /eatgo-login-api/src/test/java/kr/co/fastcampus/eatgo/application/UserServiceTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.User; 4 | import kr.co.fastcampus.eatgo.domain.UserRepository; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | import org.mockito.InjectMocks; 8 | import org.mockito.Mock; 9 | import org.mockito.MockitoAnnotations; 10 | import org.springframework.security.crypto.password.PasswordEncoder; 11 | 12 | import java.util.Optional; 13 | 14 | import static org.assertj.core.api.Assertions.assertThat; 15 | import static org.assertj.core.api.Assertions.assertThatThrownBy; 16 | import static org.mockito.ArgumentMatchers.any; 17 | import static org.mockito.BDDMockito.given; 18 | 19 | public class UserServiceTests { 20 | 21 | @InjectMocks 22 | private UserService userService; 23 | 24 | @Mock 25 | private UserRepository userRepostory; 26 | 27 | @Mock 28 | private PasswordEncoder passwordEncoder; 29 | 30 | @BeforeEach 31 | public void setUp() { 32 | MockitoAnnotations.initMocks(this); 33 | } 34 | 35 | @Test 36 | public void authenticateWithValidAttributes() { 37 | String email = "tester@example.com"; 38 | String password = "test"; 39 | 40 | User mockUser = User.builder().email(email).build(); 41 | 42 | given(userRepostory.findByEmail(email)) 43 | .willReturn(Optional.of(mockUser)); 44 | 45 | given(passwordEncoder.matches(any(), any())).willReturn(true); 46 | 47 | User user = userService.authenticate(email, password); 48 | 49 | assertThat(user.getEmail()).isEqualTo(email); 50 | } 51 | 52 | @Test 53 | public void authenticateWithNotExistedEmail() { 54 | String email = "x@example.com"; 55 | String password = "test"; 56 | 57 | given(userRepostory.findByEmail(email)) 58 | .willReturn(Optional.empty()); 59 | 60 | assertThatThrownBy(() -> { 61 | userService.authenticate(email, password); 62 | }).isInstanceOf(EmailNotExistedException.class); 63 | } 64 | 65 | @Test 66 | public void authenticateWithWrongPassword() { 67 | String email = "tester@example.com"; 68 | String password = "x"; 69 | 70 | User mockUser = User.builder().email(email).build(); 71 | 72 | given(userRepostory.findByEmail(email)) 73 | .willReturn(Optional.of(mockUser)); 74 | 75 | given(passwordEncoder.matches(any(), any())).willReturn(false); 76 | 77 | assertThatThrownBy(() -> { 78 | userService.authenticate(email, password); 79 | }).isInstanceOf(PasswordWrongException.class); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /eatgo-restaurant-api/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.2.1.RELEASE' 3 | id 'io.spring.dependency-management' version '1.0.8.RELEASE' 4 | id 'java' 5 | } 6 | 7 | group = 'kr.co.fastcampus' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '1.8' 10 | 11 | configurations { 12 | developmentOnly 13 | runtimeClasspath { 14 | extendsFrom developmentOnly 15 | } 16 | compileOnly { 17 | extendsFrom annotationProcessor 18 | } 19 | } 20 | 21 | repositories { 22 | mavenCentral() 23 | } 24 | 25 | dependencies { 26 | implementation project(':eatgo-common') 27 | 28 | implementation 'org.springframework.boot:spring-boot-starter-web' 29 | implementation 'org.springframework.boot:spring-boot-starter-security' 30 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 31 | 32 | implementation 'com.h2database:h2' 33 | implementation 'mysql:mysql-connector-java' 34 | 35 | compileOnly 'org.projectlombok:lombok' 36 | 37 | developmentOnly 'org.springframework.boot:spring-boot-devtools' 38 | 39 | annotationProcessor 'org.projectlombok:lombok' 40 | 41 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 42 | } 43 | 44 | test { 45 | useJUnitPlatform() 46 | } 47 | -------------------------------------------------------------------------------- /eatgo-restaurant-api/src/main/java/kr/co/fastcampus/eatgo/EatgoRestaurantApiApplication.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class EatgoRestaurantApiApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(EatgoRestaurantApiApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /eatgo-restaurant-api/src/main/java/kr/co/fastcampus/eatgo/SecurityJavaConfig.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo; 2 | 3 | import kr.co.fastcampus.eatgo.filters.JwtAuthenticationFilter; 4 | import kr.co.fastcampus.eatgo.utils.JwtUtil; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 10 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 11 | import org.springframework.security.config.http.SessionCreationPolicy; 12 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 13 | import org.springframework.security.crypto.password.PasswordEncoder; 14 | 15 | import javax.servlet.Filter; 16 | 17 | @Configuration 18 | @EnableWebSecurity 19 | public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { 20 | 21 | @Value("${jwt.secret}") 22 | private String secret; 23 | 24 | @Override 25 | protected void configure(HttpSecurity http) throws Exception { 26 | Filter filter = new JwtAuthenticationFilter( 27 | authenticationManager(), jwtUtil()); 28 | 29 | http 30 | .cors().disable() 31 | .csrf().disable() 32 | .formLogin().disable() 33 | .headers().frameOptions().disable() 34 | .and() 35 | .addFilter(filter) 36 | .sessionManagement() 37 | .sessionCreationPolicy(SessionCreationPolicy.STATELESS); 38 | } 39 | 40 | @Bean 41 | public PasswordEncoder passwordEncoder() { 42 | return new BCryptPasswordEncoder(); 43 | } 44 | 45 | @Bean 46 | public JwtUtil jwtUtil() { 47 | return new JwtUtil(secret); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /eatgo-restaurant-api/src/main/java/kr/co/fastcampus/eatgo/application/ReservationService.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Reservation; 4 | import kr.co.fastcampus.eatgo.domain.ReservationRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.transaction.Transactional; 9 | import java.util.List; 10 | 11 | @Service 12 | @Transactional 13 | public class ReservationService { 14 | 15 | private ReservationRepository reservationRepository; 16 | 17 | @Autowired 18 | public ReservationService(ReservationRepository reservationRepository) { 19 | this.reservationRepository = reservationRepository; 20 | } 21 | 22 | public List getReservations(Long restaurantId) { 23 | return reservationRepository.findAllByRestaurantId(restaurantId); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /eatgo-restaurant-api/src/main/java/kr/co/fastcampus/eatgo/filters/JwtAuthenticationFilter.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.filters; 2 | 3 | import io.jsonwebtoken.Claims; 4 | import kr.co.fastcampus.eatgo.utils.JwtUtil; 5 | import org.springframework.security.authentication.AuthenticationManager; 6 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 7 | import org.springframework.security.core.Authentication; 8 | import org.springframework.security.core.context.SecurityContext; 9 | import org.springframework.security.core.context.SecurityContextHolder; 10 | import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; 11 | 12 | import javax.servlet.FilterChain; 13 | import javax.servlet.ServletException; 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpServletResponse; 16 | import java.io.IOException; 17 | 18 | public class JwtAuthenticationFilter extends BasicAuthenticationFilter { 19 | 20 | private JwtUtil jwtUtil; 21 | 22 | public JwtAuthenticationFilter( 23 | AuthenticationManager authenticationManager, JwtUtil jwtUtil) { 24 | super(authenticationManager); 25 | this.jwtUtil = jwtUtil; 26 | } 27 | 28 | @Override 29 | protected void doFilterInternal( 30 | HttpServletRequest request, 31 | HttpServletResponse response, 32 | FilterChain chain 33 | ) throws IOException, ServletException { 34 | Authentication authentication = getAuthentication(request); 35 | 36 | if (authentication != null) { 37 | SecurityContext context = SecurityContextHolder.getContext(); 38 | context.setAuthentication(authentication); 39 | } 40 | 41 | chain.doFilter(request, response); 42 | } 43 | 44 | private Authentication getAuthentication(HttpServletRequest request) { 45 | String token = request.getHeader("Authorization"); 46 | if (token == null) { 47 | return null; 48 | } 49 | 50 | Claims claims = jwtUtil.getClaims(token.substring("Bearer ".length())); 51 | 52 | Authentication authentication = 53 | new UsernamePasswordAuthenticationToken(claims, null); 54 | return authentication; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /eatgo-restaurant-api/src/main/java/kr/co/fastcampus/eatgo/interfaces/ReservationController.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import io.jsonwebtoken.Claims; 4 | import kr.co.fastcampus.eatgo.application.ReservationService; 5 | import kr.co.fastcampus.eatgo.domain.Reservation; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.security.core.Authentication; 8 | import org.springframework.web.bind.annotation.CrossOrigin; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import java.util.List; 13 | 14 | @CrossOrigin 15 | @RestController 16 | public class ReservationController { 17 | 18 | @Autowired 19 | private ReservationService reservationService; 20 | 21 | @GetMapping("/reservations") 22 | public List list( 23 | Authentication authentication 24 | ) { 25 | Claims claims = (Claims) authentication.getPrincipal(); 26 | 27 | Long restaurantId = claims.get("restaurantId", Long.class); 28 | 29 | List reservations = 30 | reservationService.getReservations(restaurantId); 31 | 32 | return reservations; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /eatgo-restaurant-api/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:h2:~/data/eatgo 4 | jpa: 5 | hibernate: 6 | ddl-auto: update 7 | 8 | jwt: 9 | secret: 12345678901234567890123456789012 10 | 11 | --- 12 | 13 | spring: 14 | profiles: test 15 | datasource: 16 | url: jdbc:h2:mem:test 17 | 18 | --- 19 | 20 | spring: 21 | profiles: mysql 22 | datasource: 23 | url: jdbc:mysql://${MYSQL_HOST}:3306/${MYSQL_DATABASE} 24 | username: ${MYSQL_USER} 25 | password: ${MYSQL_PASSWORD} 26 | -------------------------------------------------------------------------------- /eatgo-restaurant-api/src/test/java/kr/co/fastcampus/eatgo/EatgoRestaurantApiApplicationTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | public class EatgoRestaurantApiApplicationTests { 8 | 9 | @Test 10 | public void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /eatgo-restaurant-api/src/test/java/kr/co/fastcampus/eatgo/application/ReservationServiceTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.application; 2 | 3 | import kr.co.fastcampus.eatgo.domain.Reservation; 4 | import kr.co.fastcampus.eatgo.domain.ReservationRepository; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | import org.mockito.InjectMocks; 8 | import org.mockito.Mock; 9 | import org.mockito.MockitoAnnotations; 10 | 11 | import java.util.List; 12 | 13 | import static org.mockito.Mockito.verify; 14 | 15 | public class ReservationServiceTests { 16 | 17 | @InjectMocks 18 | private ReservationService reservationService; 19 | 20 | @Mock 21 | private ReservationRepository reservationRepository; 22 | 23 | @BeforeEach 24 | public void setUp() { 25 | MockitoAnnotations.initMocks(this); 26 | } 27 | 28 | @Test 29 | public void getReservations() { 30 | Long restaurantId = 1004L; 31 | 32 | List reservations = 33 | reservationService.getReservations(restaurantId); 34 | 35 | verify(reservationRepository).findAllByRestaurantId(restaurantId); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /eatgo-restaurant-api/src/test/java/kr/co/fastcampus/eatgo/interfaces/ReservationControllerTests.java: -------------------------------------------------------------------------------- 1 | package kr.co.fastcampus.eatgo.interfaces; 2 | 3 | import kr.co.fastcampus.eatgo.application.ReservationService; 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 7 | import org.springframework.boot.test.mock.mockito.MockBean; 8 | import org.springframework.test.web.servlet.MockMvc; 9 | 10 | import static org.mockito.Mockito.verify; 11 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 12 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 13 | 14 | @WebMvcTest(ReservationController.class) 15 | public class ReservationControllerTests { 16 | 17 | @Autowired 18 | private MockMvc mvc; 19 | 20 | @MockBean 21 | private ReservationService reservationService; 22 | 23 | @Test 24 | public void list() throws Exception { 25 | String token = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjIwMjAsIm5hbWUiOiJPd25lciIsInJlc3RhdXJhbnRJZCI6MTAwNH0.a5n4PWJ2-3yVyMaLGG0HSPXtH_mgpOvofpQ1OFkgDOQ"; 26 | 27 | mvc.perform(get("/reservations") 28 | .header("Authorization", "Bearer " + token)) 29 | .andExpect(status().isOk()); 30 | 31 | verify(reservationService).getReservations(1004L); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue}] 2 | indent_style = space 3 | indent_size = 2 4 | end_of_line = lf 5 | trim_trailing_whitespace = true 6 | insert_final_newline = true 7 | max_line_length = 100 8 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true, 5 | }, 6 | extends: [ 7 | 'plugin:vue/essential', 8 | '@vue/airbnb', 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint', 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/.nvmrc: -------------------------------------------------------------------------------- 1 | v10.16.3 2 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/README.md: -------------------------------------------------------------------------------- 1 | # EatGo Restaurant Web 2 | 3 | ## Project setup 4 | 5 | ```bash 6 | npm install 7 | ``` 8 | 9 | ### Compiles and hot-reloads for development 10 | 11 | ```bash 12 | npm run serve 13 | ``` 14 | 15 | ### Compiles and minifies for production 16 | 17 | ```bash 18 | npm run build 19 | ``` 20 | 21 | ### Run your tests 22 | 23 | ```bash 24 | npm run test 25 | ``` 26 | 27 | ### Lints and fixes files 28 | 29 | ```bash 30 | npm run lint 31 | ``` 32 | 33 | ### Customize configuration 34 | 35 | See [Configuration Reference](https://cli.vuejs.org/config/). 36 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app', 4 | ], 5 | }; 6 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eatgo-restaurant-web", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.19.0", 12 | "core-js": "^2.6.5", 13 | "vue": "^2.6.10", 14 | "vue-router": "^3.0.3", 15 | "vuex": "^3.1.1" 16 | }, 17 | "devDependencies": { 18 | "@vue/cli-plugin-babel": "^3.11.0", 19 | "@vue/cli-plugin-eslint": "^3.11.0", 20 | "@vue/cli-service": "^3.11.0", 21 | "@vue/eslint-config-airbnb": "^4.0.0", 22 | "babel-eslint": "^10.0.1", 23 | "eslint": "^5.16.0", 24 | "eslint-plugin-vue": "^5.0.0", 25 | "vue-template-compiler": "^2.6.10" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {}, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahastudio/fastcampus-eatgo/21bc7212e120d217bed5d0f995925d0789033900/eatgo-restaurant-web/public/favicon.ico -------------------------------------------------------------------------------- /eatgo-restaurant-web/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | EatGo for Restaurant 9 | 14 | 15 | 16 |
17 |
18 |
19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 27 | 28 | 33 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/src/components/GlobalNavigator.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 42 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import App from './App.vue'; 3 | import router from './router'; 4 | import store from './store'; 5 | 6 | Vue.config.productionTip = false; 7 | 8 | store.dispatch('setAccessToken', { 9 | accessToken: localStorage.getItem('accessToken') || '', 10 | }); 11 | 12 | new Vue({ 13 | router, 14 | render: h => h(App), 15 | }).$mount('#app'); 16 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Router from 'vue-router'; 3 | 4 | import Home from './views/Home.vue'; 5 | import ReservationList from './views/ReservationList.vue'; 6 | import Login from './views/Login.vue'; 7 | 8 | import store from './store'; 9 | 10 | Vue.use(Router); 11 | 12 | const authenticated = (_to, _from, next) => { 13 | if (!store.state.accessToken) { 14 | next('/login'); 15 | return; 16 | } 17 | 18 | next(); 19 | }; 20 | 21 | export default new Router({ 22 | mode: 'history', 23 | base: process.env.BASE_URL, 24 | routes: [ 25 | { 26 | path: '/', 27 | name: 'home', 28 | component: Home, 29 | beforeEnter: authenticated, 30 | }, 31 | { 32 | path: '/reservations', 33 | name: 'reservation-list', 34 | component: ReservationList, 35 | beforeEnter: authenticated, 36 | }, 37 | { 38 | path: '/login', 39 | name: 'login', 40 | component: Login, 41 | }, 42 | ], 43 | }); 44 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/src/store/actions.js: -------------------------------------------------------------------------------- 1 | import { useAccessToken, get, loginPost } from './http'; 2 | 3 | export default { 4 | setAccessToken({ commit }, { accessToken }) { 5 | commit('setAccessToken', accessToken); 6 | 7 | useAccessToken(accessToken); 8 | 9 | localStorage.setItem('accessToken', accessToken); 10 | }, 11 | clearAccessToken({ commit }) { 12 | commit('setAccessToken', ''); 13 | 14 | useAccessToken(''); 15 | 16 | localStorage.removeItem('accessToken'); 17 | }, 18 | async createSession({ commit }, { email, password, success }) { 19 | const { accessToken } = await loginPost('/session', { email, password }); 20 | commit('setAccessToken', accessToken); 21 | 22 | useAccessToken(accessToken); 23 | localStorage.setItem('accessToken', accessToken); 24 | 25 | success(); 26 | }, 27 | async loadReservations({ commit }) { 28 | const reservations = await get('/reservations'); 29 | commit('setReservations', reservations); 30 | }, 31 | }; 32 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/src/store/http.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const LOGIN_API_BASE_URL = process.env.VUE_APP_LOGIN_API_BASE_URL; 4 | const API_BASE_URL = process.env.VUE_APP_API_BASE_URL; 5 | 6 | let http = axios.create({ 7 | baseURL: API_BASE_URL || 'http://localhost:8080', 8 | }); 9 | 10 | export const useAccessToken = (accessToken) => { 11 | http = axios.create({ 12 | baseURL: process.env.VUE_APP_API_BASE_URL || 'http://localhost:8080', 13 | headers: { 14 | authorization: `Bearer ${accessToken}`, 15 | }, 16 | }); 17 | }; 18 | 19 | export const get = async (path) => { 20 | const { data } = await http.get(path); 21 | return data; 22 | }; 23 | 24 | export const loginPost = async (path, payload) => { 25 | const url = `${LOGIN_API_BASE_URL || 'http://localhost:8080'}${path}`; 26 | const { data } = await axios.post(url, payload); 27 | return data; 28 | }; 29 | 30 | export default { 31 | }; 32 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuex from 'vuex'; 3 | 4 | import mutations from './mutations'; 5 | import actions from './actions'; 6 | 7 | Vue.use(Vuex); 8 | 9 | const state = { 10 | accessToken: '', 11 | reservations: [], 12 | }; 13 | 14 | export default new Vuex.Store({ 15 | state, 16 | mutations, 17 | actions, 18 | }); 19 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/src/store/mutations.js: -------------------------------------------------------------------------------- 1 | export default { 2 | setAccessToken(state, accessToken) { 3 | state.accessToken = accessToken; 4 | }, 5 | setReservations(state, reservations) { 6 | state.reservations = reservations; 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/src/views/Login.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 45 | 46 | 51 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/src/views/ReservationList.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 41 | -------------------------------------------------------------------------------- /eatgo-restaurant-web/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devServer: { 3 | port: 3000, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /eatgo-web/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /eatgo-web/.nvmrc: -------------------------------------------------------------------------------- 1 | v10.16.3 2 | -------------------------------------------------------------------------------- /eatgo-web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | EatGo 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /eatgo-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eatgo-web", 3 | "version": "1.0.0", 4 | "description": "EatGo Web Project", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --port 3000", 8 | "test": "jest" 9 | }, 10 | "author": "Ashal aka JOKER", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "webpack": "^4.41.2", 14 | "webpack-cli": "^3.3.10", 15 | "webpack-dev-server": "^3.9.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /eatgo-web/src/index.js: -------------------------------------------------------------------------------- 1 | (async () => { 2 | const url = 'http://localhost:8080/restaurants'; 3 | const response = await fetch(url); 4 | const restaurants = await response.json(); 5 | 6 | const element = document.getElementById('app'); 7 | element.innerHTML = ` 8 | ${restaurants.map(restaurant => ` 9 |

10 | ${restaurant.id} 11 | ${restaurant.name} 12 | ${restaurant.address} 13 |

14 | `).join('')} 15 | `; 16 | })(); 17 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahastudio/fastcampus-eatgo/21bc7212e120d217bed5d0f995925d0789033900/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Aug 21 01:11:17 KST 2019 2 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 3 | distributionBase=GRADLE_USER_HOME 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS="-Xmx64m" 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | until java -jar libs/*.jar 2 | do 3 | printf "******************************************************************" 4 | sleep 5 5 | done 6 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | } 5 | } 6 | rootProject.name = 'eatgo' 7 | 8 | include 'eatgo-common' 9 | include 'eatgo-admin-api' 10 | include 'eatgo-customer-api' 11 | include 'eatgo-customer-api' 12 | include 'eatgo-login-api' 13 | include 'eatgo-restaurant-api' 14 | 15 | --------------------------------------------------------------------------------