From c824e656c461a8166f2102e3ac036b9f40982803 Mon Sep 17 00:00:00 2001 From: SeungHyun Hong Date: Tue, 7 May 2024 17:42:22 +0900 Subject: [PATCH 1/5] :clown_face: Update Mock json data --- .../Mocks/CreditsResponse.json | 5 +- .../Mocks/HomeProductResponse.json | 273 ++++++++--------- .../Mocks/NoticeDetailResponse.json | 6 +- .../Mocks/NoticeListResponse.json | 20 +- .../Mocks/ProductInfoPriceResponse.json | 103 +++---- .../Mocks/ProductInfoProductResponse.json | 20 +- .../Mocks/SearchProductResponse.json | 282 ++++++------------ .../xcschemes/PyeonHaeng-iOS.xcscheme | 3 +- 8 files changed, 280 insertions(+), 432 deletions(-) diff --git a/APIService/Sources/CreditsAPISupport/Mocks/CreditsResponse.json b/APIService/Sources/CreditsAPISupport/Mocks/CreditsResponse.json index 99ac366..a0b0575 100644 --- a/APIService/Sources/CreditsAPISupport/Mocks/CreditsResponse.json +++ b/APIService/Sources/CreditsAPISupport/Mocks/CreditsResponse.json @@ -1,5 +1,6 @@ { + "id": 1, "title": "만든 사람들", - "body": "편행을 함께 만든 사람들을 소개합니다.\r\n\r\n기획/디자인\r\n- 박상훈, 홍승현\r\n\r\n개발\r\n- 홍승현과 아이들\r\n\r\n다국어 지원\r\n- 영어\r\n- 일본어", - "date": "2024-03-20T01:07:55Z" + "content": "편행을 함께 만든 사람들을 소개합니다.\r\n\r\n기획/디자인\r\n- 박상훈, 홍승현\r\n\r\n개발\r\n- 홍승현과 아이들\r\n\r\n다국어 지원\r\n- 영어\r\n- 일본어", + "createdAt": "2024-03-20T01:07:55Z" } diff --git a/APIService/Sources/HomeAPISupport/Mocks/HomeProductResponse.json b/APIService/Sources/HomeAPISupport/Mocks/HomeProductResponse.json index d1c592d..f2e88bd 100644 --- a/APIService/Sources/HomeAPISupport/Mocks/HomeProductResponse.json +++ b/APIService/Sources/HomeAPISupport/Mocks/HomeProductResponse.json @@ -1,206 +1,195 @@ { - "count": 20, - "has_more": false, + "count": 1633, + "hasMore": true, "results": [ { - "name": "미성)콴타브레이크", - "img": "https://image.woodongs.com/imgsvr/item/GD_6291003632815_001.jpg", - "price": 800, + "id": 135280, + "name": "코카)코카콜라제로500ml", + "price": 2300, + "promotion": "BUY_ONE_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://www.7-eleven.co.kr/upload/product/8801094/082604.1.jpg" + }, + { + "id": 140045, + "name": "PPG화이트초코", + "price": 1800, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81337 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8809399462800_001.jpg" }, { - "name": "녹차녹차돌자반55G", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809186873710_001.jpg", - "price": 3300, + "id": 140046, + "name": "콩두부부침210G", + "price": 4000, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81338 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8801114111154_155.jpg" }, { - "name": "파래파래돌자반55G", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809186873703_001.jpg", - "price": 3300, + "id": 140047, + "name": "콩두부찌개210G", + "price": 4000, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81339 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8801114111161_163.jpg" }, { - "name": "CJ)워터젤리복숭아130G", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801007038032_035.jpg", - "price": 1900, + "id": 140048, + "name": "좋은울날대4P", + "price": 2800, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81340 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8801166094054_001.jpg" }, { - "name": "CJ)워터젤리오렌지130G", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801007026275_278.jpg", - "price": 1900, + "id": 140049, + "name": "네)물티슈80P캡", + "price": 5500, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81341 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8809848531903_001.jpg" }, { - "name": "CJ)워터젤리포도130G", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801007067285_002.jpg", - "price": 1900, + "id": 140050, + "name": "치즈아몬드볼", + "price": 2500, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81342 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8809318029534_003.jpg" }, { - "name": "안동간고등어100G(순살/냉동)", - "img": "None", - "price": 5000, + "id": 140051, + "name": "까눌레젤리40G", + "price": 3000, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81343 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_4902750385108_002.jpg" }, { - "name": "노가리먹태1입", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809677723586_002.jpg", - "price": 6900, + "id": 140052, + "name": "아삭한샐러드", + "price": 2900, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81344 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_2800100227547_002.jpg" }, { - "name": "먹태랑오징어30G", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809193858434_002.jpg", - "price": 6900, + "id": 140053, + "name": "와일드샐러드", + "price": 2900, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81345 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_2800100227554_002.jpg" }, { - "name": "먹태를찍먹30G", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809193858250_004.jpg", - "price": 6900, + "id": 140054, + "name": "칼집찰현미500G", + "price": 4500, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81346 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8804246034339_002.jpg" }, { - "name": "복태구이(40G/1미)", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809465730147_001.jpg", - "price": 8500, + "id": 140055, + "name": "칼집현미500G", + "price": 4500, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81347 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8804246034322_002.jpg" }, { - "name": "미닛메이드)레몬에이드제로350ML", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801094326203_001.jpg", - "price": 1900, + "id": 140056, + "name": "녹차돌자반55G", + "price": 3900, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81348 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8809186873710_001.jpg" }, { - "name": "현대)미에로화이바스파클링제로", - "img": "https://image.woodongs.com/imgsvr/item/GD_8806004000587_002.jpg", - "price": 2200, + "id": 140057, + "name": "파래돌자반55G", + "price": 3900, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81349 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8809186873703_001.jpg" }, { - "name": "빙그레)닥터캡슐베리믹스130ML", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801104669283_001.jpg", - "price": 2200, + "id": 140058, + "name": "오렌지소다600", + "price": 2100, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81350 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8806002023397_002.jpg" }, { - "name": "빙그레)닥터캡슐복분자130ML", - "img": "None", - "price": 2200, + "id": 140059, + "name": "자두자몽소다", + "price": 2100, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81351 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8806002023410_002.jpg" }, { - "name": "빙그레)닥터캡슐사과130ML", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801104665421_001.jpg", - "price": 2200, + "id": 140060, + "name": "간고등어(순살)", + "price": 5000, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81352 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": null }, { - "name": "빙그레)닥터캡슐프로텍트130ML", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801104302739_004.jpg", - "price": 2200, + "id": 140061, + "name": "노가리먹태1입", + "price": 6900, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81353 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8809677723586_002.jpg" }, { - "name": "Y(P)명품갈비탕600G(냉장)", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809396242689_001.JPG", - "price": 15900, + "id": 140062, + "name": "미니붕어빵(팥)", + "price": 600, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81354 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_2800100228940_001.jpg" }, { - "name": "Y(P)명품염소전골500G(냉장)", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809396242733_001.jpg", - "price": 15900, + "id": 140063, + "name": "먹태랑오징어", + "price": 7900, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81355 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8809193858434_002.jpg" }, { - "name": "꿀에빠진도라지말랭이15G", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809742173049_001.jpg", - "price": 2500, + "id": 140064, + "name": "먹태를찍먹30G", + "price": 7900, + "promotion": "BUY_ONE_GET_ONE_FREE", "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81356 + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8809193858250_004.jpg" } ] } diff --git a/APIService/Sources/NoticeAPISupport/Mocks/NoticeDetailResponse.json b/APIService/Sources/NoticeAPISupport/Mocks/NoticeDetailResponse.json index ff3aefb..3959b62 100644 --- a/APIService/Sources/NoticeAPISupport/Mocks/NoticeDetailResponse.json +++ b/APIService/Sources/NoticeAPISupport/Mocks/NoticeDetailResponse.json @@ -1,6 +1,6 @@ { + "id": 1, "title": "test test", - "body": "안녕하세요 편행팀입니다~\n새로워진 2024년을 맞아 편행이 새단장으로 여러분을 찾아왔습니다. 앞으로도 우리 자주 만나요!\n\n[업데이트 정보]\n- 새로운 버전(v.2.0.0)으로 리뉴얼 되었습니다.\n- 새로워진 편행 2.0에서 더욱 더 합리적인 소비 생활 되세요!\n- 앱 디자인 및 전반적인 UX를 개선해서 사용하기 편하게 했어요!\n- 합리적인 소비를 도와드리고자 행사 상품 가격의 변동 정보를 그래프로 보여드려요!\n\n- 기타 자잘한 버그들을 수정했습니다.\n- 단말 안정화 적용\n- 화면 및 네트워크 최적화\n\n- 2023년 3월 편의점 행사정보가 업데이트 되었습니다.\n\n[새로운 기능]\n- 지도 기능이 추가되었습니다.\n- 카테고리가 추가되었습니다.\n\n[주의사항]\n- 본 어플리케이션에서 표시된 정보는 실제 행사정보와 차이가 있을수 있습니다.\n- 행사는 편의점 브랜드 및 재고상태에 따라 다르게 적용될 수 있습니다.", - "date": "2024-02-25T19:41:11Z", - "id": 1 + "content": "안녕하세요 편행팀입니다~\n새로워진 2024년을 맞아 편행이 새단장으로 여러분을 찾아왔습니다. 앞으로도 우리 자주 만나요!\n\n[업데이트 정보]\n- 새로운 버전(v.2.0.0)으로 리뉴얼 되었습니다.\n- 새로워진 편행 2.0에서 더욱 더 합리적인 소비 생활 되세요!\n- 앱 디자인 및 전반적인 UX를 개선해서 사용하기 편하게 했어요!\n- 합리적인 소비를 도와드리고자 행사 상품 가격의 변동 정보를 그래프로 보여드려요!\n\n- 기타 자잘한 버그들을 수정했습니다.\n- 단말 안정화 적용\n- 화면 및 네트워크 최적화\n\n- 2023년 3월 편의점 행사정보가 업데이트 되었습니다.\n\n[새로운 기능]\n- 지도 기능이 추가되었습니다.\n- 카테고리가 추가되었습니다.\n\n[주의사항]\n- 본 어플리케이션에서 표시된 정보는 실제 행사정보와 차이가 있을수 있습니다.\n- 행사는 편의점 브랜드 및 재고상태에 따라 다르게 적용될 수 있습니다.", + "createdAt": "2024-02-25T19:41:11Z" } diff --git a/APIService/Sources/NoticeAPISupport/Mocks/NoticeListResponse.json b/APIService/Sources/NoticeAPISupport/Mocks/NoticeListResponse.json index 8decbf9..4f6091f 100644 --- a/APIService/Sources/NoticeAPISupport/Mocks/NoticeListResponse.json +++ b/APIService/Sources/NoticeAPISupport/Mocks/NoticeListResponse.json @@ -1,18 +1,18 @@ { - "count": 2, - "has_more": false, + "count": 1, + "hasMore": false, "results": [ { - "title": "test test", - "body": null, - "date": "2024-02-25T19:41:11Z", - "id": 1 + "id": 2, + "title": "test title", + "content": "test content", + "createdAt": "2024-05-02T13:23:02Z" }, { - "title": "테스트 제목", - "body": null, - "date": "2024-02-26T20:35:48Z", - "id": 2 + "id": 1, + "title": "test title", + "content": "test content", + "createdAt": "2024-05-02T13:23:02Z" } ] } diff --git a/APIService/Sources/ProductInfoAPISupport/Mocks/ProductInfoPriceResponse.json b/APIService/Sources/ProductInfoAPISupport/Mocks/ProductInfoPriceResponse.json index 549c6e4..4d9022b 100644 --- a/APIService/Sources/ProductInfoAPISupport/Mocks/ProductInfoPriceResponse.json +++ b/APIService/Sources/ProductInfoAPISupport/Mocks/ProductInfoPriceResponse.json @@ -1,65 +1,38 @@ -{ - "count": 6, - "results": [ - { - "name": "힛더티)슈퍼말차초코콘150ML", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809490180818_002.jpg", - "price": 2400, - "store": "GS25", - "tag": "2+1", - "proinfo": 0, - "date": "2023-06-01T00:00:00Z", - "id": 33580 - }, - { - "name": "힛더티)슈퍼말차초코콘150ML", - "img": "http://gs25appimg.gsretail.com/imgsvr/item/GD_8809490180818_001.jpg", - "price": 2100, - "store": "GS25", - "tag": "2+1", - "proinfo": 0, - "date": "2023-05-01T00:00:00Z", - "id": 28766 - }, - { - "name": "힛더티)슈퍼말차초코콘150ML", - "img": "http://gs25appimg.gsretail.com/imgsvr/item/GD_8809490180818_001.jpg", - "price": 2500, - "store": "GS25", - "tag": "2+1", - "proinfo": 0, - "date": "2023-03-01T00:00:00Z", - "id": 17993 - }, - { - "name": "힛더티)슈퍼말차초코콘150ML", - "img": "http://gs25appimg.gsretail.com/imgsvr/item/GD_8809490180818_001.jpg", - "price": 2600, - "store": "GS25", - "tag": "2+1", - "proinfo": 0, - "date": "2023-02-01T00:00:00Z", - "id": 13602 - }, - { - "name": "힛더티)슈퍼말차초코콘150ML", - "img": "http://gs25appimg.gsretail.com/imgsvr/item/GD_8809490180818_001.jpg", - "price": 3000, - "store": "GS25", - "tag": "2+1", - "proinfo": 0, - "date": "2023-01-01T00:00:00Z", - "id": 9644 - }, - { - "name": "힛더티)슈퍼말차초코콘150ML", - "img": "http://gs25appimg.gsretail.com/imgsvr/item/GD_8809490180818_001.jpg", - "price": 2900, - "store": "GS25", - "tag": "2+1", - "proinfo": 0, - "date": "2022-11-01T00:00:00Z", - "id": 2792 - } - ] -} +[ + { + "id": 135280, + "name": "코카)코카콜라제로500ml", + "price": 2300, + "promotion": "BUY_ONE_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://www.7-eleven.co.kr/upload/product/8801094/082604.1.jpg" + }, + { + "id": 76877, + "name": "코카)코카콜라제로500ml", + "price": 2300, + "promotion": "BUY_TWO_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2024-02-01T00:00:00Z", + "imageUrl": "https://www.7-eleven.co.kr/upload/product/8801094/082604.1.jpg" + }, + { + "id": 44143, + "name": "코카)코카콜라제로500ml", + "price": 2300, + "promotion": "BUY_ONE_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2023-08-01T00:00:00Z", + "imageUrl": "https://www.7-eleven.co.kr/upload/product/8801094/082604.1.jpg" + }, + { + "id": 5044, + "name": "코카)코카콜라제로500ml", + "price": 2200, + "promotion": "BUY_TWO_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2022-11-01T00:00:00Z", + "imageUrl": "https://www.7-eleven.co.kr/upload/product/8801094/082604.1.jpg" + } +] diff --git a/APIService/Sources/ProductInfoAPISupport/Mocks/ProductInfoProductResponse.json b/APIService/Sources/ProductInfoAPISupport/Mocks/ProductInfoProductResponse.json index 04c08dc..be870ee 100644 --- a/APIService/Sources/ProductInfoAPISupport/Mocks/ProductInfoProductResponse.json +++ b/APIService/Sources/ProductInfoAPISupport/Mocks/ProductInfoProductResponse.json @@ -1,15 +1,9 @@ { - "count": 1, - "results": [ - { - "name": "힛더티)슈퍼말차초코콘150ML", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809490180818_002.jpg", - "price": 2500, - "store": "GS25", - "tag": "2+1", - "proinfo": 0, - "date": "2023-06-01T00:00:00Z", - "id": 33580 - } - ] + "id": 135280, + "name": "코카)코카콜라제로500ml", + "price": 2300, + "promotion": "BUY_ONE_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://www.7-eleven.co.kr/upload/product/8801094/082604.1.jpg" } diff --git a/APIService/Sources/SearchAPISupport/Mocks/SearchProductResponse.json b/APIService/Sources/SearchAPISupport/Mocks/SearchProductResponse.json index af5e70d..aea5e20 100644 --- a/APIService/Sources/SearchAPISupport/Mocks/SearchProductResponse.json +++ b/APIService/Sources/SearchAPISupport/Mocks/SearchProductResponse.json @@ -1,206 +1,96 @@ { - "count": 3, - "has_more": false, + "count": 57, + "hasMore": true, "results": [ { - "name": "힛더티)슈퍼말차초코콘150ML", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809490180818_002.jpg", - "price": 2500, - "store": "GS25", - "tag": "2+1", - "proinfo": 0, - "date": "2023-06-01T00:00:00Z", - "id": 33580 - }, - { - "name": "칠성)펩시콜라제로355ml", - "img": "https://www.7-eleven.co.kr/upload/product/8801056/175900.1.jpg", - "price": 1900, - "store": "7-ELEVEn", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 84462 - }, - { - "name": "롯데)펩시콜라캔355ML", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801056150013_007.jpg", + "id": 135280, + "name": "코카)코카콜라제로500ml", + "price": 2300, + "promotion": "BUY_ONE_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://www.7-eleven.co.kr/upload/product/8801094/082604.1.jpg" + }, + { + "id": 135281, + "name": "칠성)펩시콜라600ml", + "price": 2000, + "promotion": "BUY_ONE_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://www.7-eleven.co.kr/upload/product/8801056/193010.1.jpg" + }, + { + "id": 135304, + "name": "칠성)펩시콜라제로500ml", + "price": 2000, + "promotion": "BUY_ONE_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://www.7-eleven.co.kr/upload/product/8801056/175955.1.jpg" + }, + { + "id": 135378, + "name": "코카)코카콜라제로레몬500ml", + "price": 2300, + "promotion": "BUY_ONE_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://www.ministop.co.kr/MiniStopHomePage/page/pic.do?n=event2plus1.[TZWVX6ZS_]2plus1_288.jpg" + }, + { + "id": 135677, + "name": "매일)바리스타쇼콜라모카325ml", + "price": 3000, + "promotion": "BUY_TWO_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://image.woodongs.com/imgsvr/item/GD_8801121771396_006.jpg" + }, + { + "id": 135985, + "name": "코카)코카콜라350ml캔", + "price": 2000, + "promotion": "BUY_TWO_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://www.7-eleven.co.kr/upload/product/8801094/017200.1.jpg" + }, + { + "id": 136049, + "name": "하리보)해피콜라사우어", + "price": 2000, + "promotion": "BUY_TWO_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://www.7-eleven.co.kr/upload/product/8691216/096370.1.jpg" + }, + { + "id": 136059, + "name": "롯데)핵짱셔요콜라50g", + "price": 1200, + "promotion": "BUY_TWO_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://www.ministop.co.kr/MiniStopHomePage/page/pic.do?n=event2plus1.[TZWVX6ZS_]2plus1_404.jpg" + }, + { + "id": 136308, + "name": "칠성)펩시콜라355ml", "price": 1900, - "store": "7-ELEVEn", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81629 - }, - { - "name": "CJ)워터젤리복숭아130G", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801007038032_035.jpg", - "price": 1900, - "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81340 - }, - { - "name": "CJ)워터젤리오렌지130G", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801007026275_278.jpg", - "price": 1900, - "store": "GS25", - "tag": "2+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81341 - }, - { - "name": "CJ)워터젤리포도130G", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801007067285_002.jpg", - "price": 1900, - "store": "GS25", - "tag": "2+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81342 - }, - { - "name": "안동간고등어100G(순살/냉동)", - "img": "None", - "price": 5000, - "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81343 - }, - { - "name": "노가리먹태1입", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809677723586_002.jpg", - "price": 6900, - "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81344 - }, - { - "name": "먹태랑오징어30G", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809193858434_002.jpg", - "price": 6900, - "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81345 + "promotion": "BUY_TWO_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://www.7-eleven.co.kr/upload/product/8801056/150013.1.jpg" }, { - "name": "먹태를찍먹30G", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809193858250_004.jpg", - "price": 6900, - "store": "GS25", - "tag": "2+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81346 - }, - { - "name": "복태구이(40G/1미)", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809465730147_001.jpg", - "price": 8500, - "store": "GS25", - "tag": "2+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81347 - }, - { - "name": "미닛메이드)레몬에이드제로350ML", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801094326203_001.jpg", + "id": 136372, + "name": "칠성)펩시콜라제로355ml", "price": 1900, - "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81348 - }, - { - "name": "현대)미에로화이바스파클링제로", - "img": "https://image.woodongs.com/imgsvr/item/GD_8806004000587_002.jpg", - "price": 2200, - "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81349 - }, - { - "name": "빙그레)닥터캡슐베리믹스130ML", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801104669283_001.jpg", - "price": 2200, - "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81350 - }, - { - "name": "빙그레)닥터캡슐복분자130ML", - "img": "None", - "price": 2200, - "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81351 - }, - { - "name": "빙그레)닥터캡슐사과130ML", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801104665421_001.jpg", - "price": 2200, - "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81352 - }, - { - "name": "빙그레)닥터캡슐프로텍트130ML", - "img": "https://image.woodongs.com/imgsvr/item/GD_8801104302739_004.jpg", - "price": 2200, - "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81353 - }, - { - "name": "Y(P)명품갈비탕600G(냉장)", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809396242689_001.JPG", - "price": 15900, - "store": "GS25", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81354 - }, - { - "name": "Y(P)명품염소전골500G(냉장)", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809396242733_001.jpg", - "price": 15900, - "store": "emart24", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81355 - }, - { - "name": "꿀에빠진도라지말랭이15G", - "img": "https://image.woodongs.com/imgsvr/item/GD_8809742173049_001.jpg", - "price": 2500, - "store": "emart24", - "tag": "1+1", - "proinfo": 0, - "date": "2024-02-01T00:00:00Z", - "id": 81356 + "promotion": "BUY_TWO_GET_ONE_FREE", + "store": "SEVEN_ELEVEN", + "eventDate": "2024-05-01T00:00:00Z", + "imageUrl": "https://www.7-eleven.co.kr/upload/product/8801056/175900.1.jpg" } ] } diff --git a/PyeonHaeng-iOS.xcodeproj/xcshareddata/xcschemes/PyeonHaeng-iOS.xcscheme b/PyeonHaeng-iOS.xcodeproj/xcshareddata/xcschemes/PyeonHaeng-iOS.xcscheme index d73670d..3ab6cee 100644 --- a/PyeonHaeng-iOS.xcodeproj/xcshareddata/xcschemes/PyeonHaeng-iOS.xcscheme +++ b/PyeonHaeng-iOS.xcodeproj/xcshareddata/xcschemes/PyeonHaeng-iOS.xcscheme @@ -43,9 +43,10 @@ Date: Tue, 7 May 2024 18:04:17 +0900 Subject: [PATCH 2/5] :test_tube: Add NetworkProvider Tests --- Core/Tests/CoreTests/CoreTests.swift | 5 -- Core/Tests/CoreTests/Mock/MockEndPoint.swift | 23 +++++++ .../CoreTests/Mock/MockURLProtocol.swift | 35 +++++++++++ .../CoreTests/NetworkProviderTests.swift | 60 +++++++++++++++++++ 4 files changed, 118 insertions(+), 5 deletions(-) delete mode 100644 Core/Tests/CoreTests/CoreTests.swift create mode 100644 Core/Tests/CoreTests/Mock/MockEndPoint.swift create mode 100644 Core/Tests/CoreTests/Mock/MockURLProtocol.swift create mode 100644 Core/Tests/CoreTests/NetworkProviderTests.swift diff --git a/Core/Tests/CoreTests/CoreTests.swift b/Core/Tests/CoreTests/CoreTests.swift deleted file mode 100644 index 477f783..0000000 --- a/Core/Tests/CoreTests/CoreTests.swift +++ /dev/null @@ -1,5 +0,0 @@ -import XCTest - -final class CoreTests: XCTestCase { - func testAlwaysPassed() throws {} -} diff --git a/Core/Tests/CoreTests/Mock/MockEndPoint.swift b/Core/Tests/CoreTests/Mock/MockEndPoint.swift new file mode 100644 index 0000000..af1df52 --- /dev/null +++ b/Core/Tests/CoreTests/Mock/MockEndPoint.swift @@ -0,0 +1,23 @@ +// +// MockEndPoint.swift +// +// +// Created by 홍승현 on 5/7/24. +// + +import Foundation +import NetworkAPIKit + +struct MockEndPoint: EndPoint { + var method: HTTPMethod + var path: String + var parameters: HTTPParameter + var headers: [String: String] + + init(method: HTTPMethod, path: String, parameters: HTTPParameter = .plain, headers: [String: String] = [:]) { + self.method = method + self.path = path + self.parameters = parameters + self.headers = headers + } +} diff --git a/Core/Tests/CoreTests/Mock/MockURLProtocol.swift b/Core/Tests/CoreTests/Mock/MockURLProtocol.swift new file mode 100644 index 0000000..1dc981b --- /dev/null +++ b/Core/Tests/CoreTests/Mock/MockURLProtocol.swift @@ -0,0 +1,35 @@ +// +// MockURLProtocol.swift +// +// +// Created by 홍승현 on 5/7/24. +// + +import Foundation + +class MockURLProtocol: URLProtocol { + static var mockData: Data? + static var mockError: Error? + static var mockStatusCode: Int? + + override class func canInit(with _: URLRequest) -> Bool { + true + } + + override class func canonicalRequest(for request: URLRequest) -> URLRequest { + request + } + + override func startLoading() { + if let error = MockURLProtocol.mockError { + client?.urlProtocol(self, didFailWithError: error) + } else { + let response = HTTPURLResponse(url: request.url!, statusCode: MockURLProtocol.mockStatusCode ?? 200, httpVersion: nil, headerFields: nil) + client?.urlProtocol(self, didReceive: response!, cacheStoragePolicy: .notAllowed) + client?.urlProtocol(self, didLoad: MockURLProtocol.mockData ?? Data()) + } + client?.urlProtocolDidFinishLoading(self) + } + + override func stopLoading() {} +} diff --git a/Core/Tests/CoreTests/NetworkProviderTests.swift b/Core/Tests/CoreTests/NetworkProviderTests.swift new file mode 100644 index 0000000..7aeee8f --- /dev/null +++ b/Core/Tests/CoreTests/NetworkProviderTests.swift @@ -0,0 +1,60 @@ +@testable import NetworkAPIKit +import XCTest + +// MARK: - NetworkProviderTests + +final class NetworkProviderTests: XCTestCase { + struct TestModel: Codable, Equatable { + let id: Int + let name: String + } + + var networkProvider: NetworkProvider! + var mockURLSession: URLSession! + + override func setUp() { + super.setUp() + let configuration = URLSessionConfiguration.ephemeral + configuration.protocolClasses = [MockURLProtocol.self] + mockURLSession = URLSession(configuration: configuration) + networkProvider = NetworkProvider(session: mockURLSession) + } + + override func tearDown() { + networkProvider = nil + mockURLSession = nil + super.tearDown() + } + + func testRequest_Success() async throws { + // Given + let expectedModel = TestModel(id: 1, name: "Test") + let mockData = try JSONEncoder().encode(expectedModel) + MockURLProtocol.mockData = mockData + MockURLProtocol.mockStatusCode = 200 + + let endPoint = MockEndPoint(method: .get, path: "/path") + + // When + let result: TestModel = try await networkProvider.request(with: endPoint) + + // Then + XCTAssertEqual(result, expectedModel) + } + + func testRequest_Failure() async throws { + // Given + MockURLProtocol.mockError = NetworkError.failedResponse(statusCode: 400) + + let endPoint = MockEndPoint(method: .get, path: "/path") + + // When + do { + let _: TestModel = try await networkProvider.request(with: endPoint) + XCTFail("Expected to throw an error") + } catch { + // Then + XCTAssertEqual((error as? NetworkError)?.errorDescription, NetworkError.failedResponse(statusCode: 400).errorDescription) + } + } +} From f212671284c6637e6df5951ceb185ea95ac28d57 Mon Sep 17 00:00:00 2001 From: SeungHyun Hong Date: Mon, 13 May 2024 21:11:27 +0900 Subject: [PATCH 3/5] :test_tube: Add UI test to verify product count label height consistency --- PyeonHaeng-iOS.xcodeproj/project.pbxproj | 178 ++++++++++++++++-- .../xcschemes/PyeonHaeng-iOS.xcscheme | 14 +- .../Sources/AccessibilityIdentifier.swift | 20 ++ PyeonHaeng-iOS/Sources/PyeonHaengApp.swift | 1 + .../View/HomeProductSorterView.swift | 2 + PyeonHaeng-iOSUITests/PyeonHaengUITests.swift | 47 +++++ .../PyeonHaeng_iOSUITestsLaunchTests.swift | 28 +++ 7 files changed, 275 insertions(+), 15 deletions(-) create mode 100644 PyeonHaeng-iOS/Sources/AccessibilityIdentifier.swift create mode 100644 PyeonHaeng-iOSUITests/PyeonHaengUITests.swift create mode 100644 PyeonHaeng-iOSUITests/PyeonHaeng_iOSUITestsLaunchTests.swift diff --git a/PyeonHaeng-iOS.xcodeproj/project.pbxproj b/PyeonHaeng-iOS.xcodeproj/project.pbxproj index e32c4d6..2ca4fb0 100644 --- a/PyeonHaeng-iOS.xcodeproj/project.pbxproj +++ b/PyeonHaeng-iOS.xcodeproj/project.pbxproj @@ -32,6 +32,8 @@ BA28F1A52B61572A0052855E /* Pretendard-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = BA28F19B2B61572A0052855E /* Pretendard-Light.otf */; }; BA28F1A62B61572A0052855E /* Pretendard-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = BA28F19C2B61572A0052855E /* Pretendard-Black.otf */; }; BA402F7E2B85E31800E86AAD /* ConvenienceSelectBottomSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA402F7D2B85E31800E86AAD /* ConvenienceSelectBottomSheetView.swift */; }; + BA4C95EB2BEA263E00E80D08 /* PyeonHaengUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4C95EA2BEA263E00E80D08 /* PyeonHaengUITests.swift */; }; + BA4C95ED2BEA263E00E80D08 /* PyeonHaeng_iOSUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4C95EC2BEA263E00E80D08 /* PyeonHaeng_iOSUITestsLaunchTests.swift */; }; BA4EA3602B6A37E10003DCE7 /* Entity in Frameworks */ = {isa = PBXBuildFile; productRef = BA4EA35F2B6A37E10003DCE7 /* Entity */; }; BA4FB9C52BA1BC5B00ED03C4 /* NoticeAPI in Frameworks */ = {isa = PBXBuildFile; productRef = BA4FB9C42BA1BC5B00ED03C4 /* NoticeAPI */; }; BA4FB9C72BA1BC5B00ED03C4 /* NoticeAPISupport in Frameworks */ = {isa = PBXBuildFile; productRef = BA4FB9C62BA1BC5B00ED03C4 /* NoticeAPISupport */; }; @@ -42,6 +44,9 @@ BA849A372B8F4FC0004495BF /* MockPaginatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA849A362B8F4FC0004495BF /* MockPaginatable.swift */; }; BA8E83242B8EF83B00FE968C /* ProductConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA8E83232B8EF83B00FE968C /* ProductConfiguration.swift */; }; BA9903562BBBD9F500DC3ED3 /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = BA9903552BBBD9F500DC3ED3 /* InfoPlist.xcstrings */; }; + BA9D943C2BF20EBA00E7C9F7 /* AccessibilityIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9D943B2BF20EBA00E7C9F7 /* AccessibilityIdentifier.swift */; }; + BA9D943D2BF20ECB00E7C9F7 /* AccessibilityIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9D943B2BF20EBA00E7C9F7 /* AccessibilityIdentifier.swift */; }; + BA9D943E2BF20ECC00E7C9F7 /* AccessibilityIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9D943B2BF20EBA00E7C9F7 /* AccessibilityIdentifier.swift */; }; BAA4D9AD2B5A1795005999F8 /* PyeonHaengApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAA4D9AC2B5A1795005999F8 /* PyeonHaengApp.swift */; }; BAA4D9AF2B5A1795005999F8 /* SplashView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAA4D9AE2B5A1795005999F8 /* SplashView.swift */; }; BAA4D9B12B5A1796005999F8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BAA4D9B02B5A1796005999F8 /* Assets.xcassets */; }; @@ -96,6 +101,13 @@ remoteGlobalIDString = BAA4D9A82B5A1795005999F8; remoteInfo = "PyeonHaeng-iOS"; }; + BA4C95EE2BEA263E00E80D08 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BAA4D9A12B5A1795005999F8 /* Project object */; + proxyType = 1; + remoteGlobalIDString = BAA4D9A82B5A1795005999F8; + remoteInfo = "PyeonHaeng-iOS"; + }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -126,11 +138,15 @@ BA28F19C2B61572A0052855E /* Pretendard-Black.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-Black.otf"; sourceTree = ""; }; BA28F1A72B6157E90052855E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; BA402F7D2B85E31800E86AAD /* ConvenienceSelectBottomSheetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConvenienceSelectBottomSheetView.swift; sourceTree = ""; }; + BA4C95E82BEA263E00E80D08 /* PyeonHaeng-iOSUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "PyeonHaeng-iOSUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + BA4C95EA2BEA263E00E80D08 /* PyeonHaengUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PyeonHaengUITests.swift; sourceTree = ""; }; + BA4C95EC2BEA263E00E80D08 /* PyeonHaeng_iOSUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PyeonHaeng_iOSUITestsLaunchTests.swift; sourceTree = ""; }; BA4EA35A2B6A00F70003DCE7 /* Entity */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Entity; sourceTree = ""; }; BA73DDC32BC17912009EE718 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; BA849A362B8F4FC0004495BF /* MockPaginatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockPaginatable.swift; sourceTree = ""; }; BA8E83232B8EF83B00FE968C /* ProductConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductConfiguration.swift; sourceTree = ""; }; BA9903552BBBD9F500DC3ED3 /* InfoPlist.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = InfoPlist.xcstrings; sourceTree = ""; }; + BA9D943B2BF20EBA00E7C9F7 /* AccessibilityIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityIdentifier.swift; sourceTree = ""; }; BAA4D9A92B5A1795005999F8 /* PyeonHaeng-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "PyeonHaeng-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; BAA4D9AC2B5A1795005999F8 /* PyeonHaengApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PyeonHaengApp.swift; sourceTree = ""; }; BAA4D9AE2B5A1795005999F8 /* SplashView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashView.swift; sourceTree = ""; }; @@ -175,6 +191,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + BA4C95E52BEA263E00E80D08 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; BAA4D9A62B5A1795005999F8 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -273,6 +296,7 @@ BA28F1712B6152EE0052855E /* Sources */ = { isa = PBXGroup; children = ( + BA9D943B2BF20EBA00E7C9F7 /* AccessibilityIdentifier.swift */, E5462C652B65677B00E9FDF2 /* PromotionTag.swift */, BAA4D9AC2B5A1795005999F8 /* PyeonHaengApp.swift */, BA19897B2BA95E8C0083B4BE /* DIContainer.swift */, @@ -392,6 +416,15 @@ path = BottomSheet; sourceTree = ""; }; + BA4C95E92BEA263E00E80D08 /* PyeonHaeng-iOSUITests */ = { + isa = PBXGroup; + children = ( + BA4C95EA2BEA263E00E80D08 /* PyeonHaengUITests.swift */, + BA4C95EC2BEA263E00E80D08 /* PyeonHaeng_iOSUITestsLaunchTests.swift */, + ); + path = "PyeonHaeng-iOSUITests"; + sourceTree = ""; + }; BA4FB9C32BA1BC5B00ED03C4 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -411,16 +444,17 @@ BAA4D9A02B5A1795005999F8 = { isa = PBXGroup; children = ( - BA4EA35A2B6A00F70003DCE7 /* Entity */, - BABFEA6F2B6399C30084C0EC /* Shared */, BA0564032B6219D4003D6DC7 /* APIService */, BA0564022B62179A003D6DC7 /* Core */, + BABFEA6F2B6399C30084C0EC /* Shared */, + BA4EA35A2B6A00F70003DCE7 /* Entity */, BAAF1D272BAFF1910001EA36 /* DesignSystemApp */, + BA4FB9C32BA1BC5B00ED03C4 /* Frameworks */, BAA4D9AA2B5A1795005999F8 /* Products */, BAA4D9AB2B5A1795005999F8 /* PyeonHaeng-iOS */, BA28F17A2B6155450052855E /* PyeonHaeng-iOSTests */, + BA4C95E92BEA263E00E80D08 /* PyeonHaeng-iOSUITests */, BA0564042B624629003D6DC7 /* XCConfig */, - BA4FB9C32BA1BC5B00ED03C4 /* Frameworks */, ); sourceTree = ""; }; @@ -430,6 +464,7 @@ BAA4D9A92B5A1795005999F8 /* PyeonHaeng-iOS.app */, BA28F1792B6155450052855E /* PyeonHaeng-iOSTests.xctest */, BAAF1D262BAFF1910001EA36 /* DesignSystemApp.app */, + BA4C95E82BEA263E00E80D08 /* PyeonHaeng-iOSUITests.xctest */, ); name = Products; sourceTree = ""; @@ -536,6 +571,24 @@ productReference = BA28F1792B6155450052855E /* PyeonHaeng-iOSTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + BA4C95E72BEA263E00E80D08 /* PyeonHaeng-iOSUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = BA4C95F32BEA263E00E80D08 /* Build configuration list for PBXNativeTarget "PyeonHaeng-iOSUITests" */; + buildPhases = ( + BA4C95E42BEA263E00E80D08 /* Sources */, + BA4C95E52BEA263E00E80D08 /* Frameworks */, + BA4C95E62BEA263E00E80D08 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + BA4C95EF2BEA263E00E80D08 /* PBXTargetDependency */, + ); + name = "PyeonHaeng-iOSUITests"; + productName = "PyeonHaeng-iOSUITests"; + productReference = BA4C95E82BEA263E00E80D08 /* PyeonHaeng-iOSUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; BAA4D9A82B5A1795005999F8 /* PyeonHaeng-iOS */ = { isa = PBXNativeTarget; buildConfigurationList = BAA4D9B72B5A1796005999F8 /* Build configuration list for PBXNativeTarget "PyeonHaeng-iOS" */; @@ -608,6 +661,10 @@ CreatedOnToolsVersion = 15.2; TestTargetID = BAA4D9A82B5A1795005999F8; }; + BA4C95E72BEA263E00E80D08 = { + CreatedOnToolsVersion = 15.3; + TestTargetID = BAA4D9A82B5A1795005999F8; + }; BAA4D9A82B5A1795005999F8 = { CreatedOnToolsVersion = 15.2; }; @@ -636,6 +693,7 @@ targets = ( BAA4D9A82B5A1795005999F8 /* PyeonHaeng-iOS */, BA28F1782B6155450052855E /* PyeonHaeng-iOSTests */, + BA4C95E72BEA263E00E80D08 /* PyeonHaeng-iOSUITests */, BAAF1D252BAFF1910001EA36 /* DesignSystemApp */, ); }; @@ -649,6 +707,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + BA4C95E62BEA263E00E80D08 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; BAA4D9A72B5A1795005999F8 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -687,7 +752,7 @@ BAF2BEB42B61237600931AF0 /* SwiftFormat */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; - buildActionMask = 2147483647; + buildActionMask = 12; files = ( ); inputFileListPaths = ( @@ -731,6 +796,7 @@ files = ( BA849A372B8F4FC0004495BF /* MockPaginatable.swift in Sources */, BAE7A1EA2B9DA4960022FEBB /* MockDeviceInformationProvider.swift in Sources */, + BA9D943E2BF20ECC00E7C9F7 /* AccessibilityIdentifier.swift in Sources */, BA849A342B8F4F36004495BF /* ProductConfiguration.swift in Sources */, BA28F17C2B6155450052855E /* ProductConfigurationTests.swift in Sources */, BAE7A1EB2B9DA4A50022FEBB /* DeviceProvider.swift in Sources */, @@ -738,6 +804,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + BA4C95E42BEA263E00E80D08 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BA4C95ED2BEA263E00E80D08 /* PyeonHaeng_iOSUITestsLaunchTests.swift in Sources */, + BA9D943D2BF20ECB00E7C9F7 /* AccessibilityIdentifier.swift in Sources */, + BA4C95EB2BEA263E00E80D08 /* PyeonHaengUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; BAA4D9A52B5A1795005999F8 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -773,6 +849,7 @@ E50176262B6A204F0098D1BE /* ProductInfoLineGraphView.swift in Sources */, BAB5CF252B6B7C5A008B24BF /* Services.swift in Sources */, BAA4D9AF2B5A1795005999F8 /* SplashView.swift in Sources */, + BA9D943C2BF20EBA00E7C9F7 /* AccessibilityIdentifier.swift in Sources */, BAAF1D3C2BB01D980001EA36 /* NoticeDetailViewModel.swift in Sources */, BAB8C3AD2BAC7A11003DF3CC /* LeaveReviewView.swift in Sources */, BA8E83242B8EF83B00FE968C /* ProductConfiguration.swift in Sources */, @@ -797,6 +874,11 @@ target = BAA4D9A82B5A1795005999F8 /* PyeonHaeng-iOS */; targetProxy = BA28F17D2B6155450052855E /* PBXContainerItemProxy */; }; + BA4C95EF2BEA263E00E80D08 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = BAA4D9A82B5A1795005999F8 /* PyeonHaeng-iOS */; + targetProxy = BA4C95EE2BEA263E00E80D08 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -882,8 +964,8 @@ INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -892,9 +974,11 @@ MARKETING_VERSION = 2.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.sfam.pyeonhaeng; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = 1; }; name = Staging; }; @@ -955,6 +1039,60 @@ }; name = Release; }; + BA4C95F02BEA263E00E80D08 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 2ZQR76M3UH; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.whitehyun.PyeonHaeng-iOSUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "PyeonHaeng-iOS"; + }; + name = Debug; + }; + BA4C95F12BEA263E00E80D08 /* Staging */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 2ZQR76M3UH; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.whitehyun.PyeonHaeng-iOSUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "PyeonHaeng-iOS"; + }; + name = Staging; + }; + BA4C95F22BEA263E00E80D08 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 2ZQR76M3UH; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.whitehyun.PyeonHaeng-iOSUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "PyeonHaeng-iOS"; + }; + name = Release; + }; BAA4D9B52B5A1796005999F8 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = BA0564052B624646003D6DC7 /* Shared.xcconfig */; @@ -1096,8 +1234,8 @@ INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -1106,9 +1244,11 @@ MARKETING_VERSION = 2.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.sfam.pyeonhaeng; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = 1; }; name = Debug; }; @@ -1129,8 +1269,8 @@ INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -1139,9 +1279,11 @@ MARKETING_VERSION = 2.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.sfam.pyeonhaeng; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = 1; }; name = Release; }; @@ -1248,6 +1390,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; + BA4C95F32BEA263E00E80D08 /* Build configuration list for PBXNativeTarget "PyeonHaeng-iOSUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BA4C95F02BEA263E00E80D08 /* Debug */, + BA4C95F12BEA263E00E80D08 /* Staging */, + BA4C95F22BEA263E00E80D08 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; BAA4D9A42B5A1795005999F8 /* Build configuration list for PBXProject "PyeonHaeng-iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/PyeonHaeng-iOS.xcodeproj/xcshareddata/xcschemes/PyeonHaeng-iOS.xcscheme b/PyeonHaeng-iOS.xcodeproj/xcshareddata/xcschemes/PyeonHaeng-iOS.xcscheme index 3ab6cee..d346d62 100644 --- a/PyeonHaeng-iOS.xcodeproj/xcshareddata/xcschemes/PyeonHaeng-iOS.xcscheme +++ b/PyeonHaeng-iOS.xcodeproj/xcshareddata/xcschemes/PyeonHaeng-iOS.xcscheme @@ -40,13 +40,23 @@ ReferencedContainer = "container:PyeonHaeng-iOS.xcodeproj"> + + + + : View where ViewModel: HomeViewModelRepr var body: some View { HStack { Text(productCountString) + .accessibilityIdentifier(AccessibilityIdentifier.Home.productCountLabel) .font(.title2) Spacer() Button { @@ -34,6 +35,7 @@ struct HomeProductSorterView: View where ViewModel: HomeViewModelRepr } .accessibilityLabel(accessibilityLabel(for: viewModel.state.productConfiguration.order)) .accessibilityHint("더블 탭하여 정렬 기준을 바꿔보세요") + .accessibilityIdentifier(AccessibilityIdentifier.Home.sortButton) } .padding(.all, 8) } diff --git a/PyeonHaeng-iOSUITests/PyeonHaengUITests.swift b/PyeonHaeng-iOSUITests/PyeonHaengUITests.swift new file mode 100644 index 0000000..1a5bb60 --- /dev/null +++ b/PyeonHaeng-iOSUITests/PyeonHaengUITests.swift @@ -0,0 +1,47 @@ +// +// PyeonHaengUITests.swift +// PyeonHaeng-iOSUITests +// +// Created by 홍승현 on 5/7/24. +// + +import Foundation +import XCTest + +// MARK: - PyeonHaengUITests + +final class PyeonHaengUITests: XCTestCase { + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + func testProductCountLabelDisplayedInSingleLine() { + let app = XCUIApplication() + app.launch() + XCTAssertTrue(app.otherElements[AccessibilityIdentifier.Splash.screen].exists, TestFailureMessage.splashScreenNotDisplayed) + + let productCountLabel = app.staticTexts[AccessibilityIdentifier.Home.productCountLabel] + let initialLabelHeight = productCountLabel.frame.size.height + + let productSortButton = app.buttons[AccessibilityIdentifier.Home.sortButton] + productSortButton.tap() + + let labelHeightAfterTap = productCountLabel.frame.size.height + + // 탭 전과 후의 레이블 높이 비교 + XCTAssertEqual(labelHeightAfterTap, initialLabelHeight, TestFailureMessage.productCountLabelHeightChanged) + } +} + +// MARK: PyeonHaengUITests.TestFailureMessage + +private extension PyeonHaengUITests { + enum TestFailureMessage { + static let splashScreenNotDisplayed = "Splash screen is not displayed." + static let productCountLabelHeightChanged = "Product count label height changed after tapping the sort button." + } +} diff --git a/PyeonHaeng-iOSUITests/PyeonHaeng_iOSUITestsLaunchTests.swift b/PyeonHaeng-iOSUITests/PyeonHaeng_iOSUITestsLaunchTests.swift new file mode 100644 index 0000000..570573d --- /dev/null +++ b/PyeonHaeng-iOSUITests/PyeonHaeng_iOSUITestsLaunchTests.swift @@ -0,0 +1,28 @@ +// +// PyeonHaeng_iOSUITestsLaunchTests.swift +// PyeonHaeng-iOSUITests +// +// Created by 홍승현 on 5/7/24. +// + +import XCTest + +final class PyeonHaengUITestsLaunchTests: XCTestCase { + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +} From afdbafe6e72fb6ea12050a134d2be0c1d184c457 Mon Sep 17 00:00:00 2001 From: SeungHyun Hong Date: Mon, 13 May 2024 21:22:21 +0900 Subject: [PATCH 4/5] :globe_with_meridians: Shorten Japanese and English translation of product count label --- .../Resources/Localizable.xcstrings | 63 +++++-------------- .../View/HomeProductSorterView.swift | 2 +- 2 files changed, 17 insertions(+), 48 deletions(-) diff --git a/PyeonHaeng-iOS/Resources/Localizable.xcstrings b/PyeonHaeng-iOS/Resources/Localizable.xcstrings index e6337c1..b674ee2 100644 --- a/PyeonHaeng-iOS/Resources/Localizable.xcstrings +++ b/PyeonHaeng-iOS/Resources/Localizable.xcstrings @@ -55,6 +55,22 @@ } } }, + "%lld products total!" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "合計%lld商品" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "총 %lld개의 상품이 있어요!" + } + } + } + }, "• 검색어의 단어 수를 줄이거나," : { "localizations" : { "en" : { @@ -868,53 +884,6 @@ } } }, - "총 %lld개의 상품이 있어요!" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "variations" : { - "plural" : { - "one" : { - "stringUnit" : { - "state" : "translated", - "value" : "There is a total of %lld product!" - } - }, - "other" : { - "stringUnit" : { - "state" : "translated", - "value" : "There are a total of %lld product!" - } - } - } - } - }, - "ja" : { - "variations" : { - "plural" : { - "other" : { - "stringUnit" : { - "state" : "translated", - "value" : "合計%lld個の商品があります!" - } - } - } - } - }, - "ko" : { - "variations" : { - "plural" : { - "other" : { - "stringUnit" : { - "state" : "translated", - "value" : "총 %lld개의 상품이 있어요!" - } - } - } - } - } - } - }, "편의점 브랜드 선택" : { "localizations" : { "en" : { diff --git a/PyeonHaeng-iOS/Sources/Scenes/HomeScene/View/HomeProductSorterView.swift b/PyeonHaeng-iOS/Sources/Scenes/HomeScene/View/HomeProductSorterView.swift index 83a06d2..255ab92 100644 --- a/PyeonHaeng-iOS/Sources/Scenes/HomeScene/View/HomeProductSorterView.swift +++ b/PyeonHaeng-iOS/Sources/Scenes/HomeScene/View/HomeProductSorterView.swift @@ -43,7 +43,7 @@ struct HomeProductSorterView: View where ViewModel: HomeViewModelRepr private extension HomeProductSorterView { var productCountString: AttributedString { - var string = AttributedString(localized: "총 \(viewModel.state.totalCount)개의 상품이 있어요!") + var string = AttributedString(localized: "\(viewModel.state.totalCount) products total!") if let range = string.range(of: "\(viewModel.state.totalCount.formatted())") { string[range].foregroundColor = .pyeonHaengPrimary From 4a74575c79c26556055048c3531f5fa51150aa1c Mon Sep 17 00:00:00 2001 From: SeungHyun Hong Date: Mon, 20 May 2024 16:50:47 +0900 Subject: [PATCH 5/5] :memo: Update README.md --- README.md | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 0ad906f..e246e4a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ - - +

-

편행

+

편의점 행사 정보는 어디서? | 편행

@@ -10,17 +9,42 @@

-

편의점 할인 행사를 한 눈에!

+

편의점에서 음료를 사거나, 라면을 살 때, 내지는 과자를 사고 싶을 때.

+

편의점 할인행사를 알고 싶지만, 일일이 편의점 사이트를 찾아 알아보기 귀찮을 때.

+

한 눈에 여러 편의점의 행사 정보를 확인할 수 있는 앱입니다.

- +![Introduction Image](https://github.com/PyeonHaeng/PyeonHaeng-iOS/assets/57972338/deb422bb-48e5-4000-897b-cca538ef4f7a) ---- +## Architecture -## 프로젝트 개요 +![image](https://github.com/PyeonHaeng/PyeonHaeng-iOS/assets/57972338/521a9431-b167-43b0-b6c8-75b370699a53) -편의점에서 음료를 사거나, 라면을 살 때, 내지는 과자를 사고 싶을 때 -편의점 할인행사를 알고 싶지만, 일일히 편의점 사이트를 찾아 알아보기 귀찮을 때 -한 눈에 여러 편의점의 행사 정보를 확인할 수 있는 앱입니다. +코드를 각 기능에 맞게 분리하면서 효율성과 확장성을 높이고자 **Swift Package로 모듈화**를 진행했습니다. + +실제 개발 과정에서 디자인 시스템의 컴포넌트를 확인하고자 새로운 App Target을 생성해야 하는 과정이 있었습니다. +모듈화가 되지 않았다면, **기존 코드를 복사하여 붙여넣는 작업을 반복해야 했을 것**입니다. +하지만 모듈화된 아키텍처 덕분에 **해당 모듈을 라이브러리로 참조하는 방식으로 손쉽게 구현**할 수 있었습니다. + +## Flow + +#### View - ViewModel 구조 + +![image](https://github.com/PyeonHaeng/PyeonHaeng-iOS/assets/57972338/ed9da970-a4eb-4e62-a11b-c4a46b69c0ab) + +큰 프로젝트가 아니어서 별도의 아키텍처를 고려하지 않았고, 단순 **View와 ViewModel을 활용**하였습니다. +`State`값을 Output으로 사용하고, `trigger(_:)`로 Input을 전달하는 **단방향 흐름으로 구성된 아키텍처**라고 볼 수 있습니다. + +특히 ViewModel을 protocol로 처리하여 View가 구체 타입을 알지 못하도록 하였고, 덕분에 DIP 원칙을 지킴과 동시에 테스트 용이성을 보장했습니다. + +#### Data Flow + +![image](https://github.com/PyeonHaeng/PyeonHaeng-iOS/assets/57972338/20650029-341e-4995-919f-05473e358b3c) + +View, ViewModel 그리고 네트워킹을 다루는 Service를 통해 레이어를 분리했습니다. + +덕분에 각 기능의 역할을 명확히 할 수 있었고, 버그 발생 시 관련 레이어에 집중함으로써 디버깅을 효율적으로 할 수 있었습니다. + +특히 백엔드의 API가 구현되지 않을 경우를 대비하여 **URLProtocol**과 가상의 **Mock JSON**을 파싱해 뷰를 그릴 수 있도록 구현하였습니다. ## Members