From a7b830215836c44d40e9a30b8c0ca6f9fb0ffe8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=8C=E1=85=A9=E1=86=BC?= =?UTF-8?q?=E1=84=8B=E1=85=AF=E1=86=AB=20Jongwon?= Date: Tue, 22 Aug 2023 03:13:03 +0900 Subject: [PATCH 01/12] =?UTF-8?q?[REFACTOR]=20#41:=20spring=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=EC=97=90=EC=84=9C=20=EC=9D=91=EB=8B=B5=EB=B0=9B?= =?UTF-8?q?=EB=8A=94=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20python=EC=BD=94=EB=93=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend-recommend/recommend.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/backend-recommend/recommend.py b/backend-recommend/recommend.py index 10e63cf..0460a72 100644 --- a/backend-recommend/recommend.py +++ b/backend-recommend/recommend.py @@ -25,7 +25,7 @@ def recByApriori(body): optionList = body['options'] for i in range(len(optionList)): - input.append(optionList[i]['subOptionId']) + input.append(str(optionList[i])) input = set(input) dataset = [] @@ -65,6 +65,9 @@ def recByApriori(body): response = [] for item in top_items: consequent = item[0] - response.append({"salesOptions": ",".join(consequent)}) + subResponse = [] + for option in consequent: + subResponse.append(int(option)) + response.append(subResponse) return jsonify(response) \ No newline at end of file From 123c2e94e24dada230faffa45c082adfcea7a763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=8C=E1=85=A9=E1=86=BC?= =?UTF-8?q?=E1=84=8B=E1=85=AF=E1=86=AB=20Jongwon?= Date: Tue, 22 Aug 2023 03:14:15 +0900 Subject: [PATCH 02/12] =?UTF-8?q?[CHORE]=20#41:=20=ED=8C=8C=EC=9D=B4?= =?UTF-8?q?=EC=8D=AC=20=EC=84=9C=EB=B2=84=20=EB=B3=B4=EC=95=88=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20yml=ED=8C=8C=EC=9D=BC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/.gitignore | 3 ++- backend/src/test/resources/application.yml | 19 ------------------- 2 files changed, 2 insertions(+), 20 deletions(-) delete mode 100644 backend/src/test/resources/application.yml diff --git a/backend/.gitignore b/backend/.gitignore index 6c3f256..f2a5319 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -37,4 +37,5 @@ out/ .vscode/ ### yml files ### -src/main/resources/application.yml \ No newline at end of file +src/main/resources/application.yml +src/test/resources/application.yml \ No newline at end of file diff --git a/backend/src/test/resources/application.yml b/backend/src/test/resources/application.yml deleted file mode 100644 index a3374c9..0000000 --- a/backend/src/test/resources/application.yml +++ /dev/null @@ -1,19 +0,0 @@ -spring: - config: - activate: - on-profile: test - h2: - console: - enabled: true - datasource: - url: jdbc:h2:mem:test;MODE=MySQL; - username: sa - password: - driver-class-name: org.h2.Driver - sql: - init: - mode: always - schema-locations: classpath:schema-h2.sql - -python: - url: http://localhost:5001/test From bbb19cf18e35e5979015184359fcd45bf498d7b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=8C=E1=85=A9=E1=86=BC?= =?UTF-8?q?=E1=84=8B=E1=85=AF=E1=86=AB=20Jongwon?= Date: Tue, 22 Aug 2023 03:14:38 +0900 Subject: [PATCH 03/12] =?UTF-8?q?[ADD]=20#41:=20=EC=9C=A0=EC=82=AC?= =?UTF-8?q?=EA=B2=AC=EC=A0=81=20=EC=9A=94=EC=95=BD=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=A0=9C=EA=B3=B5=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A5=BC=20=EC=9C=84=ED=95=9C=20sql=EB=AC=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/resources/insert/insert-sales-h2.sql | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 backend/src/test/resources/insert/insert-sales-h2.sql diff --git a/backend/src/test/resources/insert/insert-sales-h2.sql b/backend/src/test/resources/insert/insert-sales-h2.sql new file mode 100644 index 0000000..1246a45 --- /dev/null +++ b/backend/src/test/resources/insert/insert-sales-h2.sql @@ -0,0 +1,163 @@ +SET REFERENTIAL_INTEGRITY FALSE; + +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (129, 1, 155, '69,70'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (130, 1, 165, '69,70'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (131, 1, 152, '69,70'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (132, 1, 139, '69,70'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (133, 1, 135, '69,70'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (134, 1, 164, '69,70'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (135, 1, 153, '69,70'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (136, 1, 143, '69,70'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (137, 1, 162, '69,71'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (138, 1, 148, '69,71'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (139, 1, 138, '69,71'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (140, 1, 159, '69,71'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (141, 1, 156, '69,71'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (142, 1, 150, '69,71'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (143, 1, 154, '69,71'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (144, 1, 145, '69,71'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (145, 1, 144, '69,72'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (146, 1, 157, '69,72'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (147, 1, 150, '69,72'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (148, 1, 162, '69,72'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (149, 1, 145, '69,72'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (150, 1, 155, '69,72'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (151, 1, 162, '69,72'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (152, 1, 158, '69,72'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (153, 1, 149, '69,73'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (154, 1, 145, '69,73'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (155, 1, 150, '69,73'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (156, 1, 164, '69,73'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (157, 1, 163, '69,73'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (158, 1, 152, '69,73'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (159, 1, 143, '69,73'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (160, 1, 142, '69,73'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (161, 1, 140, '69,74'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (162, 1, 138, '69,74'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (163, 1, 151, '69,74'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (164, 1, 159, '69,74'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (165, 1, 144, '69,74'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (166, 1, 139, '69,74'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (167, 1, 144, '69,74'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (168, 1, 149, '69,74'); + +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (384, 1, 129); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (385, 3, 129); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (386, 5, 129); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (387, 1, 130); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (388, 3, 130); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (389, 6, 130); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (390, 1, 131); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (391, 4, 131); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (392, 5, 131); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (393, 1, 132); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (394, 4, 132); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (395, 6, 132); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (396, 2, 133); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (397, 3, 133); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (398, 5, 133); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (399, 2, 134); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (400, 3, 134); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (401, 6, 134); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (402, 2, 135); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (403, 4, 135); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (404, 5, 135); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (405, 2, 136); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (406, 4, 136); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (407, 6, 136); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (408, 1, 137); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (409, 3, 137); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (410, 5, 137); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (411, 1, 138); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (412, 3, 138); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (413, 6, 138); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (414, 1, 139); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (415, 4, 139); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (416, 5, 139); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (417, 1, 140); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (418, 4, 140); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (419, 6, 140); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (420, 2, 141); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (421, 3, 141); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (422, 5, 141); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (423, 2, 142); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (424, 3, 142); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (425, 6, 142); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (426, 2, 143); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (427, 4, 143); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (428, 5, 143); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (429, 2, 144); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (430, 4, 144); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (431, 6, 144); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (432, 1, 145); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (433, 3, 145); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (434, 5, 145); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (435, 1, 146); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (436, 3, 146); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (437, 6, 146); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (438, 1, 147); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (439, 4, 147); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (440, 5, 147); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (441, 1, 148); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (442, 4, 148); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (443, 6, 148); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (444, 2, 149); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (445, 3, 149); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (446, 5, 149); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (447, 2, 150); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (448, 3, 150); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (449, 6, 150); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (450, 2, 151); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (451, 4, 151); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (452, 5, 151); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (453, 2, 152); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (454, 4, 152); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (455, 6, 152); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (456, 1, 153); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (457, 3, 153); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (458, 5, 153); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (459, 1, 154); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (460, 3, 154); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (461, 6, 154); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (462, 1, 155); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (463, 4, 155); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (464, 5, 155); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (465, 1, 156); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (466, 4, 156); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (467, 6, 156); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (468, 2, 157); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (469, 3, 157); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (470, 5, 157); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (471, 2, 158); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (472, 3, 158); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (473, 6, 158); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (474, 2, 159); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (475, 4, 159); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (476, 5, 159); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (477, 2, 160); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (478, 4, 160); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (479, 6, 160); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (480, 1, 161); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (481, 3, 161); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (482, 5, 161); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (483, 1, 162); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (484, 3, 162); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (485, 6, 162); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (486, 1, 163); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (487, 4, 163); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (488, 5, 163); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (489, 1, 164); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (490, 4, 164); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (491, 6, 164); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (492, 2, 165); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (493, 3, 165); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (494, 5, 165); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (495, 2, 166); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (496, 3, 166); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (497, 6, 166); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (498, 2, 167); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (499, 4, 167); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (500, 5, 167); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (501, 2, 168); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (502, 4, 168); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (503, 6, 168); From 40feb60e0b95ebf35d95c3706dd856d8942c547a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=8C=E1=85=A9=E1=86=BC?= =?UTF-8?q?=E1=84=8B=E1=85=AF=E1=86=AB=20Jongwon?= Date: Tue, 22 Aug 2023 03:15:33 +0900 Subject: [PATCH 04/12] =?UTF-8?q?[FEAT]=20#41:=20=EC=9C=A0=EC=82=AC?= =?UTF-8?q?=EA=B2=AC=EC=A0=81=20=EC=9A=94=EC=95=BD=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=A0=9C=EA=B3=B5=20API=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=EB=90=98=EB=8A=94=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EA=B5=AC=ED=98=84=20=EC=88=98=EC=A0=95=20=EB=B0=8F?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../autoever2/cartag/exception/ErrorCode.java | 8 +++++--- .../exception/GlobalExceptionHandler.java | 20 +++++++++++++++++++ .../exception/InvalidDataException.java | 11 ++++++++++ .../cartag/exception/ServerException.java | 19 ++++++++++++++++++ 4 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 backend/src/main/java/autoever2/cartag/exception/InvalidDataException.java create mode 100644 backend/src/main/java/autoever2/cartag/exception/ServerException.java diff --git a/backend/src/main/java/autoever2/cartag/exception/ErrorCode.java b/backend/src/main/java/autoever2/cartag/exception/ErrorCode.java index d86cdb0..3432fdd 100644 --- a/backend/src/main/java/autoever2/cartag/exception/ErrorCode.java +++ b/backend/src/main/java/autoever2/cartag/exception/ErrorCode.java @@ -7,9 +7,11 @@ @Getter @RequiredArgsConstructor public enum ErrorCode { - INVALID_PARAMETER(HttpStatus.BAD_REQUEST, "Invalid parameter included"), - RESOURCE_NOT_FOUND(HttpStatus.NOT_FOUND, "Resource not exists"), - INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "Unknown error"); + INVALID_PARAMETER(HttpStatus.BAD_REQUEST, "잘못된 파라미터 형식입니다."), + INVALID_OPTIONS_REQUEST(HttpStatus.BAD_REQUEST, "잘못된 옵션으로 접근하였습니다."), + DATA_NOT_EXISTS(HttpStatus.NOT_FOUND, "데이터가 존재하지 않습니다."), + INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "서버오류입니다. 관리자에게 문의하세요."), + PARSE_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "데이터 파싱에 실패했습니다."); private final HttpStatus httpStatus; private final String message; diff --git a/backend/src/main/java/autoever2/cartag/exception/GlobalExceptionHandler.java b/backend/src/main/java/autoever2/cartag/exception/GlobalExceptionHandler.java index 5868423..85a1962 100644 --- a/backend/src/main/java/autoever2/cartag/exception/GlobalExceptionHandler.java +++ b/backend/src/main/java/autoever2/cartag/exception/GlobalExceptionHandler.java @@ -1,10 +1,12 @@ package autoever2.cartag.exception; +import lombok.extern.log4j.Log4j2; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice +@Log4j2 public class GlobalExceptionHandler { @ExceptionHandler(EmptyDataException.class) @@ -15,4 +17,22 @@ public ResponseEntity handleEmptyDataException(EmptyDataException .message(errorCode.getMessage()) .build()); } + + @ExceptionHandler(InvalidDataException.class) + public ResponseEntity handleInvalidDataException(InvalidDataException e) { + ErrorCode errorCode = e.getErrorCode(); + return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.builder() + .code(errorCode.toString()) + .message(errorCode.getMessage()) + .build()); + } + + @ExceptionHandler(ServerException.class) + public ResponseEntity handleServerException(ServerException e) { + ErrorCode errorCode = e.getErrorCode(); + log.error("Server Error: " + errorCode.getMessage()); + return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.builder() + .code(errorCode.toString()) + .build()); + } } diff --git a/backend/src/main/java/autoever2/cartag/exception/InvalidDataException.java b/backend/src/main/java/autoever2/cartag/exception/InvalidDataException.java new file mode 100644 index 0000000..997122d --- /dev/null +++ b/backend/src/main/java/autoever2/cartag/exception/InvalidDataException.java @@ -0,0 +1,11 @@ +package autoever2.cartag.exception; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public class InvalidDataException extends RuntimeException { + + private final ErrorCode errorCode; +} diff --git a/backend/src/main/java/autoever2/cartag/exception/ServerException.java b/backend/src/main/java/autoever2/cartag/exception/ServerException.java new file mode 100644 index 0000000..f7d5cd1 --- /dev/null +++ b/backend/src/main/java/autoever2/cartag/exception/ServerException.java @@ -0,0 +1,19 @@ +package autoever2.cartag.exception; + +import lombok.Getter; + +@Getter +public class ServerException extends RuntimeException { + private final ErrorCode errorCode; + private final String message; + + public ServerException(ErrorCode errorCode) { + this.errorCode = errorCode; + this.message = null; + } + + public ServerException(ErrorCode errorCode, String cause) { + this.errorCode = errorCode; + this.message = cause; + } +} From 53f1f10a7f62338c6e4f279a932c99d6aa09479b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=8C=E1=85=A9=E1=86=BC?= =?UTF-8?q?=E1=84=8B=E1=85=AF=E1=86=AB=20Jongwon?= Date: Tue, 22 Aug 2023 03:16:52 +0900 Subject: [PATCH 05/12] =?UTF-8?q?[TEST]=20#41:=20=EC=9C=A0=EC=82=AC?= =?UTF-8?q?=EA=B2=AC=EC=A0=81=20=EC=9A=94=EC=95=BD=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=A0=9C=EA=B3=B5=20API=20=EA=B4=80=EB=A0=A8=20Rep?= =?UTF-8?q?ository=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=B0=8F=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC=20=EB=B3=80=EA=B2=BD=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../autoever2/cartag/service/CarService.java | 14 ++-- .../cartag/service/ColorService.java | 7 +- .../cartag/service/ModelService.java | 4 +- .../cartag/service/OptionService.java | 2 +- .../repository/QuoteRepositoryTest.java | 68 +++++++++++++++++++ .../cartag/service/CarServiceTest.java | 2 +- .../cartag/service/ColorServiceTest.java | 6 +- 7 files changed, 85 insertions(+), 18 deletions(-) create mode 100644 backend/src/test/java/autoever2/cartag/repository/QuoteRepositoryTest.java diff --git a/backend/src/main/java/autoever2/cartag/service/CarService.java b/backend/src/main/java/autoever2/cartag/service/CarService.java index 9584a26..fc942e0 100644 --- a/backend/src/main/java/autoever2/cartag/service/CarService.java +++ b/backend/src/main/java/autoever2/cartag/service/CarService.java @@ -5,8 +5,8 @@ import autoever2.cartag.domain.color.OuterColorDto; import autoever2.cartag.domain.model.ModelDefaultDto; import autoever2.cartag.domain.option.QuoteSubOptionDto; -import autoever2.cartag.domain.share.QuoteIdList; -import autoever2.cartag.domain.share.QuoteInfoDto; +import autoever2.cartag.domain.quote.QuoteDataDto; +import autoever2.cartag.domain.quote.QuoteInfoDto; import autoever2.cartag.exception.EmptyDataException; import autoever2.cartag.exception.ErrorCode; import autoever2.cartag.repository.CarRepository; @@ -41,7 +41,7 @@ public List getAllCarTypes() { public List findCarByCarType(int carType) { List carInfos = carRepository.findCarByCarType(carType); if (carInfos.isEmpty()) { - throw new EmptyDataException(ErrorCode.RESOURCE_NOT_FOUND); + throw new EmptyDataException(ErrorCode.DATA_NOT_EXISTS); } return carInfos.stream() @@ -54,12 +54,12 @@ public CarDefaultDto findCarDefaultDtoByCarId(int carId) { List innerColorList = colorRepository.findInnerColorCarByCarId(carId); List modelList = modelRepository.findModelDefaultDtoByCarId(carId); if (outerColorList.isEmpty() || innerColorList.isEmpty() || modelList.isEmpty()) { - throw new EmptyDataException(ErrorCode.RESOURCE_NOT_FOUND); + throw new EmptyDataException(ErrorCode.DATA_NOT_EXISTS); } int colorId = outerColorList.get(0).getColorId(); Optional colorCarOuterImage = colorRepository.findOuterColorImagesByColorId(colorId); if (colorCarOuterImage.isEmpty()) { - throw new EmptyDataException(ErrorCode.RESOURCE_NOT_FOUND); + throw new EmptyDataException(ErrorCode.DATA_NOT_EXISTS); } String value = colorCarOuterImage.get(); String outerImageUrl = value.substring(0, value.indexOf("*")) + 1 + value.substring(value.indexOf("*") + 1, value.length()); @@ -94,7 +94,7 @@ public List findAllBoughInfos() { .collect(Collectors.toList()); } - public QuoteInfoDto findShareInfoDto(QuoteIdList idList) { + public QuoteInfoDto findShareInfoDto(QuoteDataDto idList) { int carId = idList.getCarId(); int powerTrainId = idList.getPowerTrainId(); int bodyTypeId = idList.getBodyTypeId(); @@ -114,7 +114,7 @@ public QuoteInfoDto findShareInfoDto(QuoteIdList idList) { optionInfos.add(optionInfo.get()); continue; } - throw new EmptyDataException(ErrorCode.RESOURCE_NOT_FOUND); + throw new EmptyDataException(ErrorCode.DATA_NOT_EXISTS); } OuterColorDto outerColorDto = outerColorInfo.get(); String imageUrl = changeUrl(outerColorDto.getColorCarImage(), 1); diff --git a/backend/src/main/java/autoever2/cartag/service/ColorService.java b/backend/src/main/java/autoever2/cartag/service/ColorService.java index 0e4d343..b508afe 100644 --- a/backend/src/main/java/autoever2/cartag/service/ColorService.java +++ b/backend/src/main/java/autoever2/cartag/service/ColorService.java @@ -10,7 +10,6 @@ import autoever2.cartag.repository.ColorRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest; import java.util.ArrayList; import java.util.List; @@ -30,7 +29,7 @@ public class ColorService { public List changeImageToImages(int colorId) { Optional images = colorRepository.findOuterColorImagesByColorId(colorId); if (images.isEmpty()) { - throw new EmptyDataException(ErrorCode.RESOURCE_NOT_FOUND); + throw new EmptyDataException(ErrorCode.DATA_NOT_EXISTS); } List outerColorCarImages = new ArrayList<>(); String value = images.get(); @@ -44,7 +43,7 @@ public List changeImageToImages(int colorId) { public List findOuterColorByCarId(int carId) { List outerColors = colorRepository.findOuterColorCarByCarId(carId); if (outerColors.isEmpty()) { - throw new EmptyDataException(ErrorCode.RESOURCE_NOT_FOUND); + throw new EmptyDataException(ErrorCode.DATA_NOT_EXISTS); } Optional totalCount = carRepository.findCarBoughtCountByCarId(carId); return outerColors.stream() @@ -56,7 +55,7 @@ public List findOuterColorByCarId(int carId) { public List findInnerColorByCarId(int carId) { List innerColors = colorRepository.findInnerColorCarByCarId(carId); if (innerColors.isEmpty()) { - throw new EmptyDataException(ErrorCode.RESOURCE_NOT_FOUND); + throw new EmptyDataException(ErrorCode.DATA_NOT_EXISTS); } Optional totalCount = carRepository.findCarBoughtCountByCarId(carId); return innerColors.stream() diff --git a/backend/src/main/java/autoever2/cartag/service/ModelService.java b/backend/src/main/java/autoever2/cartag/service/ModelService.java index d2aca4d..bc6bf3b 100644 --- a/backend/src/main/java/autoever2/cartag/service/ModelService.java +++ b/backend/src/main/java/autoever2/cartag/service/ModelService.java @@ -21,7 +21,7 @@ public class ModelService { public List getModelTypeData(int carId) { List modelData = modelRepository.findAllModelTypeData(carId); if (modelData.isEmpty()) { - throw new EmptyDataException(ErrorCode.RESOURCE_NOT_FOUND); + throw new EmptyDataException(ErrorCode.DATA_NOT_EXISTS); } Long carBoughtCount = carRepository.findCarBoughtCountByCarId(carId).orElse(0L); List powerTrainData = modelData.stream().filter(modelShortMappedDto -> modelShortMappedDto.getModelTypeId() == 1).collect(Collectors.toList()); @@ -114,7 +114,7 @@ private Double calculateHmgString(String input) { //TODO: RuntimeException 처리 public ModelDetailMappedDto getModelDetail(int modelId) { - return modelRepository.findModelDetailData(modelId).orElseThrow(() -> new EmptyDataException(ErrorCode.RESOURCE_NOT_FOUND)); + return modelRepository.findModelDetailData(modelId).orElseThrow(() -> new EmptyDataException(ErrorCode.DATA_NOT_EXISTS)); } //TODO: RuntimeException 처리 diff --git a/backend/src/main/java/autoever2/cartag/service/OptionService.java b/backend/src/main/java/autoever2/cartag/service/OptionService.java index 9b3240a..11d5520 100644 --- a/backend/src/main/java/autoever2/cartag/service/OptionService.java +++ b/backend/src/main/java/autoever2/cartag/service/OptionService.java @@ -57,7 +57,7 @@ public List getDefaultOptionList(int carId) { //TODO: RuntimeException 처리 public OptionDetailDto getOptionDetailData(int carId, int optionId, boolean isDefault) { - OptionDetailMappedDto detail = optionRepository.findOptionDetail(carId, optionId, isDefault).orElseThrow(() -> new EmptyDataException(ErrorCode.RESOURCE_NOT_FOUND)); + OptionDetailMappedDto detail = optionRepository.findOptionDetail(carId, optionId, isDefault).orElseThrow(() -> new EmptyDataException(ErrorCode.DATA_NOT_EXISTS)); List packageSubOptions = optionRepository.findPackageSubOptions(optionId); diff --git a/backend/src/test/java/autoever2/cartag/repository/QuoteRepositoryTest.java b/backend/src/test/java/autoever2/cartag/repository/QuoteRepositoryTest.java new file mode 100644 index 0000000..e2e4ae9 --- /dev/null +++ b/backend/src/test/java/autoever2/cartag/repository/QuoteRepositoryTest.java @@ -0,0 +1,68 @@ +package autoever2.cartag.repository; + +import autoever2.cartag.domain.quote.HistorySearchDto; +import autoever2.cartag.domain.quote.HistoryShortDto; +import org.assertj.core.api.SoftAssertions; +import org.assertj.core.api.junit.jupiter.InjectSoftAssertions; +import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.jdbc.Sql; + +import javax.sql.DataSource; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ActiveProfiles("test") +@JdbcTest +@Sql({"classpath:insert/insert-sales-h2.sql"}) +@ExtendWith(SoftAssertionsExtension.class) +class QuoteRepositoryTest { + + @InjectSoftAssertions + SoftAssertions softAssertions; + + private final QuoteRepository quoteRepository; + + @Autowired + public QuoteRepositoryTest(DataSource dataSource) { + quoteRepository = new QuoteRepository(dataSource); + } + + @Test + void findShortData() { + HistorySearchDto search1 = HistorySearchDto.builder() + .carId(1) + .powerTrainId(1) + .bodyTypeId(3) + .operationId(5) + .optionIds(List.of(69, 70)) + .build(); + HistorySearchDto search2 = HistorySearchDto.builder() + .carId(1) + .powerTrainId(1) + .bodyTypeId(3) + .operationId(5) + .optionIds(List.of(69, 74)) + .build(); + + HistoryShortDto expected1 = HistoryShortDto.builder() + .historyId(129L) + .soldCount(155) + .build(); + HistoryShortDto expected2 = HistoryShortDto.builder() + .historyId(161L) + .soldCount(140) + .build(); + + assertTrue(quoteRepository.findShortData(search1).isPresent()); + assertTrue(quoteRepository.findShortData(search2).isPresent()); + softAssertions.assertThat(quoteRepository.findShortData(search1).get()).usingRecursiveComparison().isEqualTo(expected1); + softAssertions.assertThat(quoteRepository.findShortData(search2).get()).usingRecursiveComparison().isEqualTo(expected2); + } +} \ No newline at end of file diff --git a/backend/src/test/java/autoever2/cartag/service/CarServiceTest.java b/backend/src/test/java/autoever2/cartag/service/CarServiceTest.java index a070cb4..a9342b9 100644 --- a/backend/src/test/java/autoever2/cartag/service/CarServiceTest.java +++ b/backend/src/test/java/autoever2/cartag/service/CarServiceTest.java @@ -120,7 +120,7 @@ void getCarType() { when(carRepository.findCarByCarType(carType)).thenReturn(carInfoDtoList); when(optionRepository.findDefaultOptionByCarId(carId)).thenReturn(trimDefaultOptionDtoList); - when(carRepository.findCarByCarType(2)).thenThrow(new EmptyDataException(ErrorCode.RESOURCE_NOT_FOUND)); + when(carRepository.findCarByCarType(2)).thenThrow(new EmptyDataException(ErrorCode.DATA_NOT_EXISTS)); List carByCarType = carService.findCarByCarType(carType); diff --git a/backend/src/test/java/autoever2/cartag/service/ColorServiceTest.java b/backend/src/test/java/autoever2/cartag/service/ColorServiceTest.java index 3135bf6..95dd477 100644 --- a/backend/src/test/java/autoever2/cartag/service/ColorServiceTest.java +++ b/backend/src/test/java/autoever2/cartag/service/ColorServiceTest.java @@ -138,9 +138,9 @@ void getModelTypeData() { when(colorRepository.findOuterColorCarByCarId(carId)).thenReturn(outerColors); when(colorRepository.findOuterColorImagesByColorId(colorId)).thenReturn(Optional.of("red_image_*.jpg")); when(carRepository.findCarBoughtCountByCarId(carId)).thenReturn(Optional.of(10000L)); - when(colorRepository.findOuterColorImagesByColorId(2)).thenThrow(new EmptyDataException(ErrorCode.RESOURCE_NOT_FOUND)); - when(colorRepository.findOuterColorCarByCarId(2)).thenThrow(new EmptyDataException(ErrorCode.RESOURCE_NOT_FOUND)); - when(colorRepository.findInnerColorCarByCarId(2)).thenThrow(new EmptyDataException(ErrorCode.RESOURCE_NOT_FOUND)); + when(colorRepository.findOuterColorImagesByColorId(2)).thenThrow(new EmptyDataException(ErrorCode.DATA_NOT_EXISTS)); + when(colorRepository.findOuterColorCarByCarId(2)).thenThrow(new EmptyDataException(ErrorCode.DATA_NOT_EXISTS)); + when(colorRepository.findInnerColorCarByCarId(2)).thenThrow(new EmptyDataException(ErrorCode.DATA_NOT_EXISTS)); //when From f116241beca967462b2ec9ec1e15123d51c44576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=8C=E1=85=A9=E1=86=BC?= =?UTF-8?q?=E1=84=8B=E1=85=AF=E1=86=AB=20Jongwon?= Date: Tue, 22 Aug 2023 03:25:14 +0900 Subject: [PATCH 06/12] =?UTF-8?q?[CHORE]=20#41:=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BB=A4=EB=B2=84=EB=A6=AC=EC=A7=80=20CI=20workflo?= =?UTF-8?q?w=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f6a4478..bb5eb7c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,8 +1,9 @@ name: test coverage + on: pull_request: - branches: + branches: - 'dev' paths: - '**.java' @@ -12,6 +13,7 @@ permissions: pull-requests: write env: + APPLICATION: ${{ secrets.APPLICATION_TEST }} wd: ./backend jobs: @@ -20,12 +22,20 @@ jobs: steps: - uses: actions/checkout@v3 + - name: Set up JDK 11 uses: actions/setup-java@v3 with: java-version: '11' distribution: 'temurin' + - name: Copy application.yml + working-directory: ${{ env.wd }} + run: | + mkdir src/test/resources + touch ./src/test/resources/application.yml + echo "${{ secrets.APPLICATION_TEST }}" > ./src/test/resources/application.yml + - name: Setup Gradle uses: gradle/gradle-build-action@v2 From 178ca83aa5cf7ffc599df126f6b823f3111acfb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=8C=E1=85=A9=E1=86=BC?= =?UTF-8?q?=E1=84=8B=E1=85=AF=E1=86=AB=20Jongwon?= Date: Tue, 22 Aug 2023 14:10:48 +0900 Subject: [PATCH 07/12] =?UTF-8?q?[TEST]=20#41:=20=EC=9C=A0=EC=82=AC?= =?UTF-8?q?=EA=B2=AC=EC=A0=81=20=EC=9A=94=EC=95=BD=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=A0=9C=EA=B3=B5=20API=20=EA=B4=80=EB=A0=A8=20Ser?= =?UTF-8?q?vice,=20Controller=ED=85=8C=EC=8A=A4=ED=8A=B8.=20=ED=86=B5?= =?UTF-8?q?=ED=95=A9=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=8A=94=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=EB=A1=9C=20=EC=A3=BC=EC=84=9D=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/OptionControllerTest.java | 4 - .../controller/QuoteControllerTest.java | 83 +++++++++++ .../cartag/integration/QuoteTest.java | 80 +++++++++++ .../cartag/service/QuoteServiceTest.java | 132 ++++++++++++++++++ .../test/resources/insert/insert-sales-h2.sql | 14 ++ 5 files changed, 309 insertions(+), 4 deletions(-) create mode 100644 backend/src/test/java/autoever2/cartag/controller/QuoteControllerTest.java create mode 100644 backend/src/test/java/autoever2/cartag/integration/QuoteTest.java create mode 100644 backend/src/test/java/autoever2/cartag/service/QuoteServiceTest.java diff --git a/backend/src/test/java/autoever2/cartag/controller/OptionControllerTest.java b/backend/src/test/java/autoever2/cartag/controller/OptionControllerTest.java index 43ad7c8..3fa8cb8 100644 --- a/backend/src/test/java/autoever2/cartag/controller/OptionControllerTest.java +++ b/backend/src/test/java/autoever2/cartag/controller/OptionControllerTest.java @@ -2,9 +2,6 @@ import autoever2.cartag.domain.option.*; import autoever2.cartag.service.OptionService; -import io.swagger.v3.oas.annotations.media.ArraySchema; -import io.swagger.v3.oas.annotations.media.Schema; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -15,7 +12,6 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import static org.mockito.BDDMockito.given; diff --git a/backend/src/test/java/autoever2/cartag/controller/QuoteControllerTest.java b/backend/src/test/java/autoever2/cartag/controller/QuoteControllerTest.java new file mode 100644 index 0000000..540a1f1 --- /dev/null +++ b/backend/src/test/java/autoever2/cartag/controller/QuoteControllerTest.java @@ -0,0 +1,83 @@ +package autoever2.cartag.controller; + +import autoever2.cartag.domain.quote.HistoryShortDto; +import autoever2.cartag.domain.quote.QuoteDataDto; +import autoever2.cartag.service.CarService; +import autoever2.cartag.service.QuoteService; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(QuoteController.class) +public class QuoteControllerTest { + + @Autowired + MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @MockBean + private QuoteService quoteService; + + @MockBean + private CarService carService; + + @Test + @DisplayName("유사견적 간략 데이터 제공 API 테스트") + void getRecommendedList() throws Exception { + //given + QuoteDataDto quoteDataDto = QuoteDataDto.builder() + .carId(1) + .powerTrainId(1) + .bodyTypeId(3) + .operationId(5) + .optionIdList(List.of(69)) + .build(); + + List expected = new ArrayList<>(); + expected.add(HistoryShortDto.builder() + .historyId(129L) + .soldCount(155) + .build()); + expected.add(HistoryShortDto.builder() + .historyId(161L) + .soldCount(140) + .build()); + expected.add(HistoryShortDto.builder() + .historyId(137L) + .soldCount(162) + .build()); + expected.add(HistoryShortDto.builder() + .historyId(169L) + .soldCount(140) + .build()); + + String content = objectMapper.writeValueAsString(quoteDataDto); + given(quoteService.findTopHistory(quoteDataDto)).willReturn(expected); + //when + ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders.post("/api/quote/list").content(content) + .contentType(MediaType.APPLICATION_JSON)); + + //then + resultActions.andExpect(status().isOk()) + .andExpect(jsonPath("$[0].historyId").value(129)) + .andExpect(jsonPath("$[1].soldCount").value(140)) + .andExpect(jsonPath("$[2].soldCount").value(162)) + .andExpect(jsonPath("$[3].historyId").value(169)); + } +} diff --git a/backend/src/test/java/autoever2/cartag/integration/QuoteTest.java b/backend/src/test/java/autoever2/cartag/integration/QuoteTest.java new file mode 100644 index 0000000..6740c4b --- /dev/null +++ b/backend/src/test/java/autoever2/cartag/integration/QuoteTest.java @@ -0,0 +1,80 @@ +package autoever2.cartag.integration; + +import autoever2.cartag.controller.QuoteController; +import autoever2.cartag.domain.quote.HistoryShortDto; +import autoever2.cartag.domain.quote.QuoteDataDto; +import autoever2.cartag.recommend.RecommendConnector; +import org.assertj.core.api.SoftAssertions; +import org.assertj.core.api.junit.jupiter.InjectSoftAssertions; +import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.BDDMockito.given; + +@SpringBootTest +@Transactional +@ActiveProfiles("test") +@Sql({"classpath:insert/insert-sales-h2.sql"}) +@ExtendWith({SoftAssertionsExtension.class}) +public class QuoteTest { + + @InjectSoftAssertions + private SoftAssertions softAssertions; + + @Autowired + QuoteController quoteController; + @Autowired + private RecommendConnector connector; + +// @Test +// @DisplayName("유사견적 간략정보 호출 API 통합테스트") +// void historyIntegrationTest() { +// QuoteDataDto quoteDataDto = QuoteDataDto.builder() +// .carId(1) +// .powerTrainId(1) +// .bodyTypeId(3) +// .operationId(5) +// .optionIdList(List.of(69)) +// .build(); +// +// List expected = new ArrayList<>(); +// expected.add(HistoryShortDto.builder() +// .historyId(129L) +// .soldCount(155) +// .build()); +// expected.add(HistoryShortDto.builder() +// .historyId(161L) +// .soldCount(140) +// .build()); +// expected.add(HistoryShortDto.builder() +// .historyId(137L) +// .soldCount(162) +// .build()); +// expected.add(HistoryShortDto.builder() +// .historyId(169L) +// .soldCount(140) +// .build()); +// +// List> response = new ArrayList<>(); +// response.add(List.of(70)); +// response.add(List.of(74)); +// response.add(List.of(71)); +// response.add(List.of(84)); +// given(connector.request(quoteDataDto)).willReturn(response); +// +// List result = quoteController.getRecommendedList(quoteDataDto); +// +// softAssertions.assertThat(result).usingRecursiveComparison().isEqualTo(expected); +// } +} diff --git a/backend/src/test/java/autoever2/cartag/service/QuoteServiceTest.java b/backend/src/test/java/autoever2/cartag/service/QuoteServiceTest.java new file mode 100644 index 0000000..433b65d --- /dev/null +++ b/backend/src/test/java/autoever2/cartag/service/QuoteServiceTest.java @@ -0,0 +1,132 @@ +package autoever2.cartag.service; + +import autoever2.cartag.domain.quote.HistorySearchDto; +import autoever2.cartag.domain.quote.HistoryShortDto; +import autoever2.cartag.domain.quote.QuoteDataDto; +import autoever2.cartag.recommend.RecommendConnector; +import autoever2.cartag.repository.OptionRepository; +import autoever2.cartag.repository.QuoteRepository; +import org.assertj.core.api.SoftAssertions; +import org.assertj.core.api.junit.jupiter.InjectSoftAssertions; +import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static org.mockito.Mockito.when; + +@ExtendWith({MockitoExtension.class, SoftAssertionsExtension.class}) +class QuoteServiceTest { + + @InjectSoftAssertions + private SoftAssertions softAssertions; + + @InjectMocks + private QuoteService quoteService; + + @Mock + private OptionRepository optionRepository; + + @Mock + private QuoteRepository quoteRepository; + + @Mock + private RecommendConnector recommendConnector; + + @Test + void findTopHistory() { + //given + QuoteDataDto quoteDataDto = QuoteDataDto.builder() + .carId(1) + .powerTrainId(1) + .bodyTypeId(3) + .operationId(5) + .optionIdList(List.of(69)) + .build(); + + List> response = new ArrayList<>(); + response.add(List.of(70)); + response.add(List.of(74)); + response.add(List.of(71)); + response.add(List.of(84)); + + List expected = new ArrayList<>(); + expected.add(HistoryShortDto.builder() + .historyId(129L) + .soldCount(155) + .build()); + expected.add(HistoryShortDto.builder() + .historyId(161L) + .soldCount(140) + .build()); + expected.add(HistoryShortDto.builder() + .historyId(137L) + .soldCount(162) + .build()); + expected.add(HistoryShortDto.builder() + .historyId(169L) + .soldCount(140) + .build()); + + + when(optionRepository.countExistOptions(quoteDataDto.getCarId(), quoteDataDto.getOptionIdList())).thenReturn(1L); + when(recommendConnector.request(quoteDataDto)).thenReturn(response); + + when(quoteRepository.findShortData(HistorySearchDto.builder() + .carId(1) + .powerTrainId(1) + .bodyTypeId(3) + .operationId(5) + .optionIds(List.of(69, 70)) + .build())) + .thenReturn(Optional.of(HistoryShortDto.builder() + .historyId(129L) + .soldCount(155) + .build())); + when(quoteRepository.findShortData(HistorySearchDto.builder() + .carId(1) + .powerTrainId(1) + .bodyTypeId(3) + .operationId(5) + .optionIds(List.of(69, 74)) + .build())) + .thenReturn(Optional.of(HistoryShortDto.builder() + .historyId(161L) + .soldCount(140) + .build())); + when(quoteRepository.findShortData(HistorySearchDto.builder() + .carId(1) + .powerTrainId(1) + .bodyTypeId(3) + .operationId(5) + .optionIds(List.of(69, 71)) + .build())) + .thenReturn(Optional.of(HistoryShortDto.builder() + .historyId(137L) + .soldCount(162) + .build())); + when(quoteRepository.findShortData(HistorySearchDto.builder() + .carId(1) + .powerTrainId(1) + .bodyTypeId(3) + .operationId(5) + .optionIds(List.of(69, 84)) + .build())) + .thenReturn(Optional.of(HistoryShortDto.builder() + .historyId(169L) + .soldCount(140) + .build())); + + //when + List result = quoteService.findTopHistory(quoteDataDto); + + //then + softAssertions.assertThat(result).usingRecursiveComparison().isEqualTo(expected); + } +} \ No newline at end of file diff --git a/backend/src/test/resources/insert/insert-sales-h2.sql b/backend/src/test/resources/insert/insert-sales-h2.sql index 1246a45..d889878 100644 --- a/backend/src/test/resources/insert/insert-sales-h2.sql +++ b/backend/src/test/resources/insert/insert-sales-h2.sql @@ -1,5 +1,8 @@ SET REFERENTIAL_INTEGRITY FALSE; +INSERT INTO SubOptionData (sub_option_data_id, car_id, option_id, option_bought_count, option_price) VALUES (1, 1, 69, 48015, 1090000); +INSERT INTO SubOptionData (sub_option_data_id, car_id, option_id, option_bought_count, option_price) VALUES (2, 1, 70, 121380, 790000); + INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (129, 1, 155, '69,70'); INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (130, 1, 165, '69,70'); INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (131, 1, 152, '69,70'); @@ -40,6 +43,14 @@ INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUE INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (166, 1, 139, '69,74'); INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (167, 1, 144, '69,74'); INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (168, 1, 149, '69,74'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (169, 1, 140, '69,84'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (170, 1, 150, '69,84'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (171, 1, 152, '69,84'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (172, 1, 143, '69,84'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (173, 1, 162, '69,84'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (174, 1, 151, '69,84'); +INSERT INTO SalesHistory (history_id, car_id, sold_count, sold_options_id) VALUES (175, 1, 149, '69,84'); + INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (384, 1, 129); INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (385, 3, 129); @@ -161,3 +172,6 @@ INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) V INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (501, 2, 168); INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (502, 4, 168); INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (503, 6, 168); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (504, 1, 169); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (505, 3, 169); +INSERT INTO HistoryModelMapper (history_model_mapper_id, model_id, history_id) VALUES (506, 5, 169); From 0c749ce226c205ef26e83ee3183000f448bb12ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=8C=E1=85=A9=E1=86=BC?= =?UTF-8?q?=E1=84=8B=E1=85=AF=E1=86=AB=20Jongwon?= Date: Tue, 22 Aug 2023 14:11:41 +0900 Subject: [PATCH 08/12] =?UTF-8?q?[CHORE]=20#41:=20Jacoco=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=20gradle=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/build.gradle | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/backend/build.gradle b/backend/build.gradle index a4e0ea3..c4038a2 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -41,37 +41,24 @@ tasks.named('test') { } jacoco { - toolVersion = '0.8.9' -} - -test { - useJUnitPlatform() - finalizedBy jacocoTestReport + toolVersion = '0.8.9' } jacocoTestReport { - dependsOn test - reports { - xml.required = true - } - finalizedBy 'jacocoTestCoverageVerification' + dependsOn test + reports { + xml.required = true + html.required = true + csv.required = false + } } -jacocoTestCoverageVerification { - violationRules { - rule { - limit { - counter = 'LINE' - value = 'COVEREDRATIO' - minimum = 0.8 - } - limit { - counter = 'METHOD' - value = 'COVEREDRATIO' - minimum = 0.8 - } - } - } +tasks.register('testCoverage', Test) { + group 'verification' + description 'Runs the tests with covarage (Create JaCoCo report)' + + dependsOn test, jacocoTestReport + tasks['jacocoTestReport'].mustRunAfter(tasks['test']) } jar { From 3a2ccdc9201c90196484092554a8ea882f708540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=8C=E1=85=A9=E1=86=BC?= =?UTF-8?q?=E1=84=8B=E1=85=AF=E1=86=AB=20Jongwon?= Date: Tue, 22 Aug 2023 14:12:04 +0900 Subject: [PATCH 09/12] =?UTF-8?q?[FEAT]=20#41:=20=EC=9C=A0=EC=82=AC?= =?UTF-8?q?=EA=B2=AC=EC=A0=81=20=EC=9A=94=EC=95=BD=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EC=A0=9C=EA=B3=B5=20API=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cartag/controller/CarController.java | 24 ------ .../cartag/controller/QuoteController.java | 55 +++++++++++++ .../controller/RecommendController.java | 21 ----- .../cartag/domain/quote/HistorySearchDto.java | 57 +++++++++++++ .../cartag/domain/quote/HistoryShortDto.java | 31 +++++++ .../cartag/domain/quote/QuoteDataDto.java | 41 ++++++++++ .../domain/{share => quote}/QuoteInfoDto.java | 2 +- .../cartag/domain/share/QuoteIdList.java | 17 ---- .../cartag/recommend/RecommendConnector.java | 81 +++++++++++++++++++ .../cartag/repository/OptionRepository.java | 12 +++ .../cartag/repository/QuoteRepository.java | 46 +++++++++++ .../cartag/service/QuoteService.java | 51 ++++++++++++ .../cartag/service/RecommendService.java | 59 -------------- 13 files changed, 375 insertions(+), 122 deletions(-) create mode 100644 backend/src/main/java/autoever2/cartag/controller/QuoteController.java delete mode 100644 backend/src/main/java/autoever2/cartag/controller/RecommendController.java create mode 100644 backend/src/main/java/autoever2/cartag/domain/quote/HistorySearchDto.java create mode 100644 backend/src/main/java/autoever2/cartag/domain/quote/HistoryShortDto.java create mode 100644 backend/src/main/java/autoever2/cartag/domain/quote/QuoteDataDto.java rename backend/src/main/java/autoever2/cartag/domain/{share => quote}/QuoteInfoDto.java (99%) delete mode 100644 backend/src/main/java/autoever2/cartag/domain/share/QuoteIdList.java create mode 100644 backend/src/main/java/autoever2/cartag/recommend/RecommendConnector.java create mode 100644 backend/src/main/java/autoever2/cartag/repository/QuoteRepository.java create mode 100644 backend/src/main/java/autoever2/cartag/service/QuoteService.java delete mode 100644 backend/src/main/java/autoever2/cartag/service/RecommendService.java diff --git a/backend/src/main/java/autoever2/cartag/controller/CarController.java b/backend/src/main/java/autoever2/cartag/controller/CarController.java index 4538b1a..503cd12 100644 --- a/backend/src/main/java/autoever2/cartag/controller/CarController.java +++ b/backend/src/main/java/autoever2/cartag/controller/CarController.java @@ -1,10 +1,7 @@ package autoever2.cartag.controller; -import autoever2.cartag.domain.car.BoughtCarDto; import autoever2.cartag.domain.car.CarDefaultDto; import autoever2.cartag.domain.car.CarDto; -import autoever2.cartag.domain.share.QuoteIdList; -import autoever2.cartag.domain.share.QuoteInfoDto; import autoever2.cartag.domain.car.CarTypeDto; import autoever2.cartag.service.CarService; import io.swagger.v3.oas.annotations.Operation; @@ -15,7 +12,6 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -56,24 +52,4 @@ public List carTrimInfo(@Parameter(description = "선택한 car_type") @ public CarDefaultDto carDefaultDto(@Parameter(description = "선택한 car_id") @RequestParam("carid") int carId) { return service.findCarDefaultDtoByCarId(carId); } - - @Operation(summary = "차량 구매 정보 반환 api", description = "차량 구매 정보 조회 method") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = BoughtCarDto.class))), - }) - @GetMapping("bought/infos") - public List boughtCarDtos() { - return service.findAllBoughInfos(); - } - - @Operation(summary = "차량 공유하기를 위한 api", description = "차량 공유를 위한 정보 반환") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = QuoteInfoDto.class))), - }) - @PostMapping("/infos/shares") - public QuoteInfoDto boughtCarDtos(@Parameter(description = "선택한 id 리스트") @RequestBody QuoteIdList idList) { - return service.findShareInfoDto(idList); - } - - } diff --git a/backend/src/main/java/autoever2/cartag/controller/QuoteController.java b/backend/src/main/java/autoever2/cartag/controller/QuoteController.java new file mode 100644 index 0000000..2018a58 --- /dev/null +++ b/backend/src/main/java/autoever2/cartag/controller/QuoteController.java @@ -0,0 +1,55 @@ +package autoever2.cartag.controller; + +import autoever2.cartag.domain.car.BoughtCarDto; +import autoever2.cartag.domain.quote.HistoryShortDto; +import autoever2.cartag.domain.quote.QuoteDataDto; +import autoever2.cartag.domain.quote.QuoteInfoDto; +import autoever2.cartag.service.CarService; +import autoever2.cartag.service.QuoteService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/quote") +@RequiredArgsConstructor +public class QuoteController { + + private final CarService carService; + private final QuoteService quoteService; + + @Operation(summary = "추천 견적 그래프 제공 API", description = "유사견적(최대 4개)와 판매횟수 제공") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = HistoryShortDto.class))) + }) + @PostMapping("/list") + public List getRecommendedList(@RequestBody QuoteDataDto quoteDataDto) { + List result = quoteService.findTopHistory(quoteDataDto); + return result; + } + + @Operation(summary = "차량 구매 정보 반환 api", description = "차량 구매 정보 조회 method") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = BoughtCarDto.class))), + }) + @GetMapping("bought/infos") + public List boughtCarDtos() { + return carService.findAllBoughInfos(); + } + + @Operation(summary = "차량 공유하기를 위한 api", description = "차량 공유를 위한 정보 반환") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = QuoteInfoDto.class))), + }) + @PostMapping("/infos/shares") + public QuoteInfoDto boughtCarDtos(@Parameter(description = "선택한 id 리스트") @RequestBody QuoteDataDto idList) { + return carService.findShareInfoDto(idList); + } +} diff --git a/backend/src/main/java/autoever2/cartag/controller/RecommendController.java b/backend/src/main/java/autoever2/cartag/controller/RecommendController.java deleted file mode 100644 index 3d56738..0000000 --- a/backend/src/main/java/autoever2/cartag/controller/RecommendController.java +++ /dev/null @@ -1,21 +0,0 @@ -package autoever2.cartag.controller; - -import autoever2.cartag.service.RecommendService; -import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/api/recommend") -@RequiredArgsConstructor -public class RecommendController { - - private final RecommendService recommendService; - - @PostMapping("/list") - public ResponseEntity getRecommendedList() { - return ResponseEntity.ok(recommendService.getList()); - } -} diff --git a/backend/src/main/java/autoever2/cartag/domain/quote/HistorySearchDto.java b/backend/src/main/java/autoever2/cartag/domain/quote/HistorySearchDto.java new file mode 100644 index 0000000..42da0ec --- /dev/null +++ b/backend/src/main/java/autoever2/cartag/domain/quote/HistorySearchDto.java @@ -0,0 +1,57 @@ +package autoever2.cartag.domain.quote; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@NoArgsConstructor +@Getter +public class HistorySearchDto { + + private int carId; + private int powerTrainId; + private int bodyTypeId; + private int operationId; + private List optionIds; + + @Builder + public HistorySearchDto(int carId, int powerTrainId, int bodyTypeId, int operationId, List optionIds) { + this.carId = carId; + this.powerTrainId = powerTrainId; + this.bodyTypeId = bodyTypeId; + this.operationId = operationId; + this.optionIds = new ArrayList<>(); + + this.optionIds.addAll(optionIds); + } + + public void addAllOption(List optionId) { + optionIds.addAll(optionId); + } + + public String getOptionIds() { + if(optionIds.isEmpty()) { + return ""; + } + + StringBuilder stringBuilder = new StringBuilder(); + for(int index = 0; index < optionIds.size() - 1; index++) { + stringBuilder.append(optionIds.get(index)).append(","); + } + stringBuilder.append(optionIds.get(optionIds.size()-1)); + + return stringBuilder.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + HistorySearchDto that = (HistorySearchDto) o; + return carId == that.carId && powerTrainId == that.powerTrainId && bodyTypeId == that.bodyTypeId && operationId == that.operationId && Objects.equals(optionIds, that.optionIds); + } +} diff --git a/backend/src/main/java/autoever2/cartag/domain/quote/HistoryShortDto.java b/backend/src/main/java/autoever2/cartag/domain/quote/HistoryShortDto.java new file mode 100644 index 0000000..7ad1535 --- /dev/null +++ b/backend/src/main/java/autoever2/cartag/domain/quote/HistoryShortDto.java @@ -0,0 +1,31 @@ +package autoever2.cartag.domain.quote; + +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.List; + +@Schema(description = "실제 판매견적 간략 데이터") +@Getter +@Setter +@NoArgsConstructor +public class HistoryShortDto { + + @Schema(description = "견적의 ID, 또는 내 견적의 ID") + private Long historyId; + @Schema(description = "견적의 판매 횟수") + private int soldCount; + @ArraySchema(schema = @Schema(implementation = HistoryShortDto.class, description = "유사견적 상위 4개 반환")) + List histories; + + @Builder + public HistoryShortDto(Long historyId, int soldCount, List histories) { + this.historyId = historyId; + this.soldCount = soldCount; + this.histories = histories; + } +} diff --git a/backend/src/main/java/autoever2/cartag/domain/quote/QuoteDataDto.java b/backend/src/main/java/autoever2/cartag/domain/quote/QuoteDataDto.java new file mode 100644 index 0000000..03b287a --- /dev/null +++ b/backend/src/main/java/autoever2/cartag/domain/quote/QuoteDataDto.java @@ -0,0 +1,41 @@ +package autoever2.cartag.domain.quote; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Getter @Setter +@NoArgsConstructor +public class QuoteDataDto { + private int carId; + private int powerTrainId; + private int bodyTypeId; + private int operationId; + private int outerColorId; + private int innerColorId; + private List optionIdList = new ArrayList<>(); + + @Builder + public QuoteDataDto(int carId, int powerTrainId, int bodyTypeId, int operationId, int outerColorId, int innerColorId, List optionIdList) { + this.carId = carId; + this.powerTrainId = powerTrainId; + this.bodyTypeId = bodyTypeId; + this.operationId = operationId; + this.outerColorId = outerColorId; + this.innerColorId = innerColorId; + this.optionIdList = optionIdList; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + QuoteDataDto that = (QuoteDataDto) o; + return carId == that.carId && powerTrainId == that.powerTrainId && bodyTypeId == that.bodyTypeId && operationId == that.operationId && outerColorId == that.outerColorId && innerColorId == that.innerColorId && Objects.equals(optionIdList, that.optionIdList); + } +} diff --git a/backend/src/main/java/autoever2/cartag/domain/share/QuoteInfoDto.java b/backend/src/main/java/autoever2/cartag/domain/quote/QuoteInfoDto.java similarity index 99% rename from backend/src/main/java/autoever2/cartag/domain/share/QuoteInfoDto.java rename to backend/src/main/java/autoever2/cartag/domain/quote/QuoteInfoDto.java index 4f3770f..d269b78 100644 --- a/backend/src/main/java/autoever2/cartag/domain/share/QuoteInfoDto.java +++ b/backend/src/main/java/autoever2/cartag/domain/quote/QuoteInfoDto.java @@ -1,4 +1,4 @@ -package autoever2.cartag.domain.share; +package autoever2.cartag.domain.quote; import autoever2.cartag.domain.car.TrimInfoDto; import autoever2.cartag.domain.color.InnerColorDto; diff --git a/backend/src/main/java/autoever2/cartag/domain/share/QuoteIdList.java b/backend/src/main/java/autoever2/cartag/domain/share/QuoteIdList.java deleted file mode 100644 index d84336a..0000000 --- a/backend/src/main/java/autoever2/cartag/domain/share/QuoteIdList.java +++ /dev/null @@ -1,17 +0,0 @@ -package autoever2.cartag.domain.share; - -import lombok.Getter; -import lombok.Setter; - -import java.util.ArrayList; -import java.util.List; -@Getter @Setter -public class QuoteIdList { - private int carId; - private int powerTrainId; - private int bodyTypeId; - private int operationId; - private int outerColorId; - private int innerColorId; - private List optionIdList = new ArrayList<>(); -} diff --git a/backend/src/main/java/autoever2/cartag/recommend/RecommendConnector.java b/backend/src/main/java/autoever2/cartag/recommend/RecommendConnector.java new file mode 100644 index 0000000..c14d001 --- /dev/null +++ b/backend/src/main/java/autoever2/cartag/recommend/RecommendConnector.java @@ -0,0 +1,81 @@ +package autoever2.cartag.recommend; + +import autoever2.cartag.domain.quote.QuoteDataDto; +import autoever2.cartag.exception.ErrorCode; +import autoever2.cartag.exception.ServerException; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.ArrayList; +import java.util.List; + +@Component +public class RecommendConnector { + + @Value("${python.url}") + private String requestURL; + + public List> request(QuoteDataDto quoteDataDto) { + + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(requestURL)) + .header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(getJsonFromEstimate(quoteDataDto))).build(); + + HttpResponse response = null; + try { + response = client.send(request, HttpResponse.BodyHandlers.ofString()); + } catch (InterruptedException e) { + throw new ServerException(ErrorCode.INTERNAL_SERVER_ERROR, e.getMessage()); + } catch (IOException e) { + throw new ServerException(ErrorCode.INTERNAL_SERVER_ERROR, e.getMessage()); + } + + return parseResponse(response.body()); + } + + + public String getJsonFromEstimate(QuoteDataDto quoteDataDto) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("carId", quoteDataDto.getCarId()); + jsonObject.put("powerTrain", quoteDataDto.getPowerTrainId()); + jsonObject.put("bodyType", quoteDataDto.getBodyTypeId()); + jsonObject.put("operation", quoteDataDto.getOperationId()); + jsonObject.put("options", quoteDataDto.getOptionIdList()); + + return jsonObject.toJSONString(); + } + + private List> parseResponse(String responseBody) { + JSONParser parser = new JSONParser(); + JSONArray resultArray = null; + try { + resultArray = (JSONArray) parser.parse(responseBody); + } catch (ParseException e) { + throw new ServerException(ErrorCode.PARSE_ERROR, e.getMessage()); + } + + List> result = new ArrayList<>(); + for (Object o : resultArray) { + JSONArray optionArray = (JSONArray) o; + List options = new ArrayList<>(); + + for (Object option : optionArray) { + options.add(Math.toIntExact((Long) option)); + } + + result.add(options); + } + return result; + } +} diff --git a/backend/src/main/java/autoever2/cartag/repository/OptionRepository.java b/backend/src/main/java/autoever2/cartag/repository/OptionRepository.java index 079a4ab..a241cc8 100644 --- a/backend/src/main/java/autoever2/cartag/repository/OptionRepository.java +++ b/backend/src/main/java/autoever2/cartag/repository/OptionRepository.java @@ -150,4 +150,16 @@ private RowMapper shareSubOptionRowMapper() { return BeanPropertyRowMapper.newInstance(QuoteSubOptionDto.class); } + public Long countExistOptions(int carId, List optionIds) { + String sql = "select count(*) as totalCount " + + "from SubOptionData " + + "where car_id = :carId and option_id IN (:optionIds)"; + + SqlParameterSource param = new MapSqlParameterSource() + .addValue("carId", carId) + .addValue("optionIds", optionIds); + + return template.queryForObject(sql, param, Long.class); + } + } diff --git a/backend/src/main/java/autoever2/cartag/repository/QuoteRepository.java b/backend/src/main/java/autoever2/cartag/repository/QuoteRepository.java new file mode 100644 index 0000000..27f1a0a --- /dev/null +++ b/backend/src/main/java/autoever2/cartag/repository/QuoteRepository.java @@ -0,0 +1,46 @@ +package autoever2.cartag.repository; + +import autoever2.cartag.domain.quote.HistorySearchDto; +import autoever2.cartag.domain.quote.HistoryShortDto; +import org.springframework.dao.support.DataAccessUtils; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.namedparam.SqlParameterSource; +import org.springframework.stereotype.Repository; + +import javax.sql.DataSource; +import java.util.Optional; + +@Repository +public class QuoteRepository { + + private final NamedParameterJdbcTemplate template; + + public QuoteRepository(DataSource dataSource) { + this.template = new NamedParameterJdbcTemplate(dataSource); + } + + public Optional findShortData(HistorySearchDto historySearchDto) { + String sql = "select sh.history_id, sh.sold_count, sh.sold_options_id " + + "from SalesHistory sh " + + "inner join HistoryModelMapper hm " + + "on hm.history_id = sh.history_id " + + "where sh.car_id = :carId and sh.sold_options_id = :optionIds and hm.model_id in (:powerTrainId, :bodyTypeId, :operationId) " + + "group by sh.history_id having count(hm.model_id) = 3"; + + SqlParameterSource param = new MapSqlParameterSource() + .addValue("carId", historySearchDto.getCarId()) + .addValue("optionIds", historySearchDto.getOptionIds()) + .addValue("powerTrainId", historySearchDto.getPowerTrainId()) + .addValue("bodyTypeId", historySearchDto.getBodyTypeId()) + .addValue("operationId", historySearchDto.getOperationId()); + + return Optional.ofNullable(DataAccessUtils.singleResult(template.query(sql, param, historyShortRowMapper()))); + } + + private RowMapper historyShortRowMapper() { + return BeanPropertyRowMapper.newInstance(HistoryShortDto.class); + } +} diff --git a/backend/src/main/java/autoever2/cartag/service/QuoteService.java b/backend/src/main/java/autoever2/cartag/service/QuoteService.java new file mode 100644 index 0000000..585fe5e --- /dev/null +++ b/backend/src/main/java/autoever2/cartag/service/QuoteService.java @@ -0,0 +1,51 @@ +package autoever2.cartag.service; + +import autoever2.cartag.domain.quote.HistorySearchDto; +import autoever2.cartag.domain.quote.HistoryShortDto; +import autoever2.cartag.domain.quote.QuoteDataDto; +import autoever2.cartag.exception.ErrorCode; +import autoever2.cartag.exception.InvalidDataException; +import autoever2.cartag.recommend.RecommendConnector; +import autoever2.cartag.repository.OptionRepository; +import autoever2.cartag.repository.QuoteRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class QuoteService { + + private final OptionRepository optionRepository; + private final QuoteRepository quoteRepository; + private final RecommendConnector recommendConnector; + + public List findTopHistory(QuoteDataDto quoteDataDto) { + + List optionIds = quoteDataDto.getOptionIdList(); + if(optionIds.size() != optionRepository.countExistOptions(quoteDataDto.getCarId(), optionIds)) { + throw new InvalidDataException(ErrorCode.INVALID_OPTIONS_REQUEST); + } + + List> result = recommendConnector.request(quoteDataDto); + + List historyList = result.stream().map(options -> { + HistorySearchDto historyData = HistorySearchDto.builder() + .carId(quoteDataDto.getCarId()) + .powerTrainId(quoteDataDto.getPowerTrainId()) + .bodyTypeId(quoteDataDto.getBodyTypeId()) + .operationId(quoteDataDto.getOperationId()) + .optionIds(optionIds) + .build(); + historyData.addAllOption(options); + + return historyData; + }).collect(Collectors.toList()); + + return historyList.stream().map(historySearchDto -> + quoteRepository.findShortData(historySearchDto).orElse(null) + ).collect(Collectors.toList()); + } +} diff --git a/backend/src/main/java/autoever2/cartag/service/RecommendService.java b/backend/src/main/java/autoever2/cartag/service/RecommendService.java deleted file mode 100644 index 3860e10..0000000 --- a/backend/src/main/java/autoever2/cartag/service/RecommendService.java +++ /dev/null @@ -1,59 +0,0 @@ -package autoever2.cartag.service; - -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.PropertySource; -import org.springframework.stereotype.Service; - -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; - -@Service -public class RecommendService { - - @Value("${python.url}") - private String requestURL; - - //TODO: 응답 존재 안할 시 예외처리 - public String getList() { - HttpClient client = HttpClient.newHttpClient(); - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(requestURL)) - .header("Content-Type", "application/json") - .POST(HttpRequest.BodyPublishers.ofString(getJsonFromEstimate())).build(); - - try { - HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); - String body = response.body(); - return body; - } catch (Exception e) { - e.getMessage(); - } - - return null; - } - - public String getJsonFromEstimate() { - JSONObject jsonObject = new JSONObject(); - jsonObject.put("carId", 1); - jsonObject.put("powerTrain", 1); - jsonObject.put("bodyType", 3); - jsonObject.put("operation", 5); - - JSONArray jsonArray = new JSONArray(); - JSONObject subOption = new JSONObject(); - subOption.put("subOptionId", "69"); - jsonArray.add(subOption); - subOption = new JSONObject(); - subOption.put("subOptionId", "70"); - jsonArray.add(subOption); - - jsonObject.put("options", jsonArray); - - - return jsonObject.toJSONString(); - } -} From 10c10e220f5967607ba1a66516db45503fb94863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=8C=E1=85=A9=E1=86=BC?= =?UTF-8?q?=E1=84=8B=E1=85=AF=E1=86=AB=20Jongwon?= Date: Tue, 22 Aug 2023 14:57:45 +0900 Subject: [PATCH 10/12] =?UTF-8?q?[BUG=20FIX]=20#41:=20dev=20merge=20?= =?UTF-8?q?=EC=B6=A9=EB=8F=8C=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=AF=B8=ED=86=B5=EA=B3=BC=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cartag/repository/OptionRepository.java | 1 - .../cartag/controller/CarControllerTest.java | 117 +----------------- .../controller/ModelControllerTest.java | 2 - .../controller/QuoteControllerTest.java | 108 ++++++++++++++++ .../autoever2/cartag/integration/CarTest.java | 12 -- .../cartag/integration/ModelTest.java | 3 + .../repository/OptionRepositoryTest.java | 9 ++ .../cartag/service/CarServiceTest.java | 6 +- 8 files changed, 127 insertions(+), 131 deletions(-) diff --git a/backend/src/main/java/autoever2/cartag/repository/OptionRepository.java b/backend/src/main/java/autoever2/cartag/repository/OptionRepository.java index a241cc8..d4db237 100644 --- a/backend/src/main/java/autoever2/cartag/repository/OptionRepository.java +++ b/backend/src/main/java/autoever2/cartag/repository/OptionRepository.java @@ -161,5 +161,4 @@ public Long countExistOptions(int carId, List optionIds) { return template.queryForObject(sql, param, Long.class); } - } diff --git a/backend/src/test/java/autoever2/cartag/controller/CarControllerTest.java b/backend/src/test/java/autoever2/cartag/controller/CarControllerTest.java index c79e94d..7ea364e 100644 --- a/backend/src/test/java/autoever2/cartag/controller/CarControllerTest.java +++ b/backend/src/test/java/autoever2/cartag/controller/CarControllerTest.java @@ -4,11 +4,10 @@ import autoever2.cartag.domain.car.CarTypeDto; import autoever2.cartag.domain.car.TrimDefaultOptionDto; import autoever2.cartag.domain.option.QuoteSubOptionDto; -import autoever2.cartag.domain.share.QuoteIdList; -import autoever2.cartag.domain.share.QuoteInfoDto; +import autoever2.cartag.domain.quote.QuoteDataDto; +import autoever2.cartag.domain.quote.QuoteInfoDto; import autoever2.cartag.service.CarService; -import org.json.JSONArray; -import org.json.JSONObject; +import autoever2.cartag.service.QuoteService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -20,10 +19,8 @@ import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import java.awt.image.AreaAveragingScaleFilter; import java.util.ArrayList; import java.util.List; -import java.util.Stack; import static org.mockito.BDDMockito.given; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -31,6 +28,7 @@ @WebMvcTest(CarController.class) class CarControllerTest { + @Autowired MockMvc mockMvc; @@ -39,8 +37,6 @@ class CarControllerTest { private List carDtoList; private List defaultOptions; - private List quoteSubOptionDtoList; - private QuoteInfoDto quoteInfoDto; @BeforeEach void setup() { @@ -112,70 +108,6 @@ void setup() { .build() ); - quoteSubOptionDtoList = new ArrayList<>(); - - quoteSubOptionDtoList.add(QuoteSubOptionDto - .builder() - .optionId(69) - .optionPrice(123400L) - .optionTitle("상세품목") - .optionImage("image_1.jpg") - .optionName("3열 열선시트") - .build()); - - quoteSubOptionDtoList.add(QuoteSubOptionDto - .builder() - .optionId(70) - .optionPrice(100L) - .optionTitle("휠") - .optionImage("iamge_2.jpg") - .optionName("20인치 다크 스퍼터링") - .build()); - - quoteSubOptionDtoList.add(QuoteSubOptionDto - .builder() - .optionId(71) - .optionPrice(8977L) - .optionTitle("악세사리") - .optionImage("image_3.jpg") - .optionName("후진가이드램프") - .build()); - - quoteInfoDto = QuoteInfoDto - .builder() - .carId(1) - .trim("Le Blanc") - .carDefaultPrice(40000000) - .powerTrainId(1) - .powerTrainTitle("파워트레인") - .powerTrainImage("image_1.jpg") - .powerTrainName("디젤2.2") - .powerTrainPrice(0L) - .bodyTypeId(5) - .bodyTypeTitle("바디타입") - .bodyTypeImage("image_2.jpg") - .bodyTypeName("7인승") - .bodyTypePrice(1500L) - .operationTitle("구동방식") - .operationId(3) - .operationImage("image_3.jpg") - .operationName("2WD") - .operationPrice(8900L) - .colorOuterTitle("외장색상") - .colorOuterId(4) - .colorOuterImage("red_1.jpg") - .colorOuterPrice(1500L) - .colorOuterImageName("퍼플 펄") - .colorCarOuterImage("outer_red.jpg") - .colorInnerTitle("내장색상") - .colorInnerId(1) - .colorInnerImage("blue_1.jpg") - .colorInnerPrice(1220L) - .colorInnerImageName("퀄팅 천연(파랑)") - .colorCarInnerImage("inner_red.jpg") - .optionList(quoteSubOptionDtoList) - .build(); - } @Test @@ -225,45 +157,4 @@ void getCarTypeList() throws Exception { .andExpect(jsonPath("$[1].carTypeImage").value("/cartype/santafe.png")) .andExpect(jsonPath("$[2].carTypeName").value("디 올 뉴 코나 Hybrid")); } - - @Test - @DisplayName("id에 따른 공유 데이터 반환") - void getShareInfo() throws Exception { - ArrayList optionIds = new ArrayList<>(); - optionIds.add(69); - optionIds.add(70); - optionIds.add(71); - QuoteIdList quoteIdList = QuoteIdList - .builder() - .carId(1) - .powerTrainId(1) - .operationId(3) - .bodyTypeId(5) - .innerColorId(1) - .outerColorId(4) - .optionIdList(optionIds) - .build(); - - given(service.findShareInfoDto(quoteIdList)).willReturn(quoteInfoDto); - - ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders.post("/api/cars/infos/shares") - .content("{\n" + - " \"carId\": 1,\n" + - " \"powerTrainId\": 1,\n" + - " \"bodyTypeId\": 5,\n" + - " \"operationId\": 3,\n" + - " \"outerColorId\": 4,\n" + - " \"innerColorId\": 1,\n" + - " \"optionIdList\": [69, 70, 71]\n" + - "}").contentType(MediaType.APPLICATION_JSON)); - resultActions.andExpect(status().isOk()) - .andExpect(jsonPath("$.carDefaultPrice").value(40000000)) - .andExpect(jsonPath("$.trim").value("Le Blanc")) - .andExpect(jsonPath("$.powerTrainImage").value("image_1.jpg")) - .andExpect(jsonPath("$.bodyTypeName").value("7인승")) - .andExpect(jsonPath("$.operationTitle").value("구동방식")) - .andExpect(jsonPath("$.colorOuterPrice").value(1500L)) - .andExpect(jsonPath("$.colorCarInnerImage").value("inner_red.jpg")) - .andExpect(jsonPath("$.optionList.size()").value(3)); - } } \ No newline at end of file diff --git a/backend/src/test/java/autoever2/cartag/controller/ModelControllerTest.java b/backend/src/test/java/autoever2/cartag/controller/ModelControllerTest.java index 6d24ebf..da67b29 100644 --- a/backend/src/test/java/autoever2/cartag/controller/ModelControllerTest.java +++ b/backend/src/test/java/autoever2/cartag/controller/ModelControllerTest.java @@ -3,9 +3,7 @@ import autoever2.cartag.domain.model.ModelDetailMappedDto; import autoever2.cartag.domain.model.ModelEfficiencyDataDto; import autoever2.cartag.domain.model.ModelShortDataDto; -import autoever2.cartag.domain.model.PowerTrainMappedDto; import autoever2.cartag.service.ModelService; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/backend/src/test/java/autoever2/cartag/controller/QuoteControllerTest.java b/backend/src/test/java/autoever2/cartag/controller/QuoteControllerTest.java index 540a1f1..7c3c285 100644 --- a/backend/src/test/java/autoever2/cartag/controller/QuoteControllerTest.java +++ b/backend/src/test/java/autoever2/cartag/controller/QuoteControllerTest.java @@ -1,7 +1,9 @@ package autoever2.cartag.controller; +import autoever2.cartag.domain.option.QuoteSubOptionDto; import autoever2.cartag.domain.quote.HistoryShortDto; import autoever2.cartag.domain.quote.QuoteDataDto; +import autoever2.cartag.domain.quote.QuoteInfoDto; import autoever2.cartag.service.CarService; import autoever2.cartag.service.QuoteService; import com.fasterxml.jackson.databind.ObjectMapper; @@ -80,4 +82,110 @@ void getRecommendedList() throws Exception { .andExpect(jsonPath("$[2].soldCount").value(162)) .andExpect(jsonPath("$[3].historyId").value(169)); } + @Test + @DisplayName("id에 따른 공유 데이터 반환") + void getShareInfo() throws Exception { + + List quoteSubOptionDtoList = new ArrayList<>(); + + quoteSubOptionDtoList.add(QuoteSubOptionDto + .builder() + .optionId(69) + .optionPrice(123400L) + .optionTitle("상세품목") + .optionImage("image_1.jpg") + .optionName("3열 열선시트") + .build()); + + quoteSubOptionDtoList.add(QuoteSubOptionDto + .builder() + .optionId(70) + .optionPrice(100L) + .optionTitle("휠") + .optionImage("iamge_2.jpg") + .optionName("20인치 다크 스퍼터링") + .build()); + + quoteSubOptionDtoList.add(QuoteSubOptionDto + .builder() + .optionId(71) + .optionPrice(8977L) + .optionTitle("악세사리") + .optionImage("image_3.jpg") + .optionName("후진가이드램프") + .build()); + + ArrayList optionIds = new ArrayList<>(); + optionIds.add(69); + optionIds.add(70); + optionIds.add(71); + QuoteDataDto quoteIdList = QuoteDataDto + .builder() + .carId(1) + .powerTrainId(1) + .operationId(3) + .bodyTypeId(5) + .innerColorId(1) + .outerColorId(4) + .optionIdList(optionIds) + .build(); + + QuoteInfoDto quoteInfoDto = QuoteInfoDto + .builder() + .carId(1) + .trim("Le Blanc") + .carDefaultPrice(40000000) + .powerTrainId(1) + .powerTrainTitle("파워트레인") + .powerTrainImage("image_1.jpg") + .powerTrainName("디젤2.2") + .powerTrainPrice(0L) + .bodyTypeId(5) + .bodyTypeTitle("바디타입") + .bodyTypeImage("image_2.jpg") + .bodyTypeName("7인승") + .bodyTypePrice(1500L) + .operationTitle("구동방식") + .operationId(3) + .operationImage("image_3.jpg") + .operationName("2WD") + .operationPrice(8900L) + .colorOuterTitle("외장색상") + .colorOuterId(4) + .colorOuterImage("red_1.jpg") + .colorOuterPrice(1500L) + .colorOuterImageName("퍼플 펄") + .colorCarOuterImage("outer_red.jpg") + .colorInnerTitle("내장색상") + .colorInnerId(1) + .colorInnerImage("blue_1.jpg") + .colorInnerPrice(1220L) + .colorInnerImageName("퀄팅 천연(파랑)") + .colorCarInnerImage("inner_red.jpg") + .optionList(quoteSubOptionDtoList) + .build(); + + + given(carService.findShareInfoDto(quoteIdList)).willReturn(quoteInfoDto); + + ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders.post("/api/quote/infos/shares") + .content("{\n" + + " \"carId\": 1,\n" + + " \"powerTrainId\": 1,\n" + + " \"bodyTypeId\": 5,\n" + + " \"operationId\": 3,\n" + + " \"outerColorId\": 4,\n" + + " \"innerColorId\": 1,\n" + + " \"optionIdList\": [69, 70, 71]\n" + + "}").contentType(MediaType.APPLICATION_JSON)); + resultActions.andExpect(status().isOk()) + .andExpect(jsonPath("$.carDefaultPrice").value(40000000)) + .andExpect(jsonPath("$.trim").value("Le Blanc")) + .andExpect(jsonPath("$.powerTrainImage").value("image_1.jpg")) + .andExpect(jsonPath("$.bodyTypeName").value("7인승")) + .andExpect(jsonPath("$.operationTitle").value("구동방식")) + .andExpect(jsonPath("$.colorOuterPrice").value(1500L)) + .andExpect(jsonPath("$.colorCarInnerImage").value("inner_red.jpg")) + .andExpect(jsonPath("$.optionList.size()").value(3)); + } } diff --git a/backend/src/test/java/autoever2/cartag/integration/CarTest.java b/backend/src/test/java/autoever2/cartag/integration/CarTest.java index b44d145..70d1116 100644 --- a/backend/src/test/java/autoever2/cartag/integration/CarTest.java +++ b/backend/src/test/java/autoever2/cartag/integration/CarTest.java @@ -1,19 +1,9 @@ package autoever2.cartag.integration; import autoever2.cartag.controller.CarController; -import autoever2.cartag.domain.car.CarDefaultDto; import autoever2.cartag.domain.car.CarDto; import autoever2.cartag.domain.car.CarTypeDto; -import autoever2.cartag.domain.share.QuoteIdList; -import autoever2.cartag.domain.share.QuoteInfoDto; import autoever2.cartag.exception.EmptyDataException; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -21,8 +11,6 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.jdbc.Sql; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; import java.util.ArrayList; import java.util.List; diff --git a/backend/src/test/java/autoever2/cartag/integration/ModelTest.java b/backend/src/test/java/autoever2/cartag/integration/ModelTest.java index 9eccd3e..313e187 100644 --- a/backend/src/test/java/autoever2/cartag/integration/ModelTest.java +++ b/backend/src/test/java/autoever2/cartag/integration/ModelTest.java @@ -41,6 +41,9 @@ void getModelList() { PowerTrainDataDto hmgData = trimModels.get(0).getHmgData(); assertEquals("45.0/1750~2750", hmgData.getMaxKgfm()); + assertEquals("202/3800", hmgData.getMaxPs()); + assertEquals(1.0, hmgData.getRatioKgfm()); + assertEquals(1.0, hmgData.getRatioPs()); assertEquals(1.0, hmgData.getRatioKgfm()); } diff --git a/backend/src/test/java/autoever2/cartag/repository/OptionRepositoryTest.java b/backend/src/test/java/autoever2/cartag/repository/OptionRepositoryTest.java index 9080aca..5883f4e 100644 --- a/backend/src/test/java/autoever2/cartag/repository/OptionRepositoryTest.java +++ b/backend/src/test/java/autoever2/cartag/repository/OptionRepositoryTest.java @@ -247,4 +247,13 @@ void getOptionInfo(){ Optional subOptionInfoV2 = optionRepository.findSubOptionByOptionId(100); assertTrue(subOptionInfoV2.isEmpty()); } + + @Test + @DisplayName("옵션이 실제로 존재하는지 검증") + void countExistOptions() { + int carId = 1; + List optionIds = List.of(69); + + assertEquals(1, optionRepository.countExistOptions(carId, optionIds)); + } } \ No newline at end of file diff --git a/backend/src/test/java/autoever2/cartag/service/CarServiceTest.java b/backend/src/test/java/autoever2/cartag/service/CarServiceTest.java index 2ba0636..7ee721d 100644 --- a/backend/src/test/java/autoever2/cartag/service/CarServiceTest.java +++ b/backend/src/test/java/autoever2/cartag/service/CarServiceTest.java @@ -5,8 +5,8 @@ import autoever2.cartag.domain.color.OuterColorDto; import autoever2.cartag.domain.model.ModelDefaultDto; import autoever2.cartag.domain.option.QuoteSubOptionDto; -import autoever2.cartag.domain.share.QuoteIdList; -import autoever2.cartag.domain.share.QuoteInfoDto; +import autoever2.cartag.domain.quote.QuoteDataDto; +import autoever2.cartag.domain.quote.QuoteInfoDto; import autoever2.cartag.exception.EmptyDataException; import autoever2.cartag.exception.ErrorCode; import autoever2.cartag.repository.CarRepository; @@ -236,7 +236,7 @@ void integrateAllInfo() { when(optionRepository.findSubOptionByOptionId(1)).thenReturn(Optional.of(subOption)); - QuoteInfoDto shareInfoDto = carService.findShareInfoDto(QuoteIdList.builder() + QuoteInfoDto shareInfoDto = carService.findShareInfoDto(QuoteDataDto.builder() .carId(1) .powerTrainId(1) .bodyTypeId(3) From eb45840ce67f3035e6aa9581a2c241874741065f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=8C=E1=85=A9=E1=86=BC?= =?UTF-8?q?=E1=84=8B=E1=85=AF=E1=86=AB=20Jongwon?= Date: Tue, 22 Aug 2023 14:58:35 +0900 Subject: [PATCH 11/12] =?UTF-8?q?[STYLE]=20#41:=20=EC=BB=A8=ED=8A=B8?= =?UTF-8?q?=EB=A1=A4=EB=9F=AC=EB=AA=85=20=EC=A4=91=EB=B3=B5=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/autoever2/cartag/controller/ModelController.java | 4 ++-- .../java/autoever2/cartag/controller/QuoteController.java | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/autoever2/cartag/controller/ModelController.java b/backend/src/main/java/autoever2/cartag/controller/ModelController.java index ce55de9..0a9fcac 100644 --- a/backend/src/main/java/autoever2/cartag/controller/ModelController.java +++ b/backend/src/main/java/autoever2/cartag/controller/ModelController.java @@ -3,7 +3,6 @@ import autoever2.cartag.domain.model.ModelDetailMappedDto; import autoever2.cartag.domain.model.ModelEfficiencyDataDto; import autoever2.cartag.domain.model.ModelShortDataDto; -import autoever2.cartag.domain.model.PowerTrainMappedDto; import autoever2.cartag.service.ModelService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -37,7 +36,8 @@ public class ModelController { }) @GetMapping("/list") public List getTrimModelType(@Parameter(description = "선택한 차량 트림ID") @RequestParam("carid") int carId) { - return modelTypeService.getModelTypeData(carId); + List result = modelTypeService.getModelTypeData(carId); + return result; } @Operation(summary = "모델타입 상세 데이터 조회", description = "모델명과 설명, 이미지 반환하는 api") diff --git a/backend/src/main/java/autoever2/cartag/controller/QuoteController.java b/backend/src/main/java/autoever2/cartag/controller/QuoteController.java index 2018a58..8ab4177 100644 --- a/backend/src/main/java/autoever2/cartag/controller/QuoteController.java +++ b/backend/src/main/java/autoever2/cartag/controller/QuoteController.java @@ -40,7 +40,7 @@ public List getRecommendedList(@RequestBody QuoteDataDto quoteD @ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = BoughtCarDto.class))), }) @GetMapping("bought/infos") - public List boughtCarDtos() { + public List getAllHistorySum() { return carService.findAllBoughInfos(); } @@ -49,7 +49,8 @@ public List boughtCarDtos() { @ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = QuoteInfoDto.class))), }) @PostMapping("/infos/shares") - public QuoteInfoDto boughtCarDtos(@Parameter(description = "선택한 id 리스트") @RequestBody QuoteDataDto idList) { - return carService.findShareInfoDto(idList); + public QuoteInfoDto getQuoteDetail(@Parameter(description = "선택한 id 리스트") @RequestBody QuoteDataDto idList) { + QuoteInfoDto data = carService.findShareInfoDto(idList); + return data; } } From eb37c55cafe857b28876b65098de86a4f0c97b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=A2=85=EC=9B=90=20Jongwon?= Date: Tue, 22 Aug 2023 15:04:22 +0900 Subject: [PATCH 12/12] Update test.yml --- .github/workflows/test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 69a992f..b77c14a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,7 +32,6 @@ jobs: - name: Copy application.yml working-directory: ${{ env.wd }} run: | - mkdir src/test/resources touch ./src/test/resources/application.yml echo "${{ secrets.APPLICATION_TEST }}" > ./src/test/resources/application.yml