diff --git a/ByeBoo-iOS/ByeBoo-iOS.xcodeproj/xcshareddata/xcschemes/ByeBooTests.xcscheme b/ByeBoo-iOS/ByeBoo-iOS.xcodeproj/xcshareddata/xcschemes/ByeBooTests.xcscheme new file mode 100644 index 00000000..059c58bd --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS.xcodeproj/xcshareddata/xcschemes/ByeBooTests.xcscheme @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/ByeBoo-iOS/ByeBoo-iOS/Core/ByeBooError.swift b/ByeBoo-iOS/ByeBoo-iOS/Core/ByeBooError.swift index 1f3f8642..03c1c6bb 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Core/ByeBooError.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Core/ByeBooError.swift @@ -25,6 +25,8 @@ enum ByeBooError: Error, LocalizedError, Equatable { case appleLoginError case endTimer case configError + case fileNotFound + case nicknameViolation var errorDescription: String? { switch self { @@ -62,6 +64,10 @@ enum ByeBooError: Error, LocalizedError, Equatable { return nil case .configError: return "info에서 값을 찾을 수 없음" + case .fileNotFound: + return "파일을 찾을 수 없음" + case .nicknameViolation: + return nil } } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Data/DataDependencyAssembler.swift b/ByeBoo-iOS/ByeBoo-iOS/Data/DataDependencyAssembler.swift index 8a4305d2..c81a75e4 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Data/DataDependencyAssembler.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Data/DataDependencyAssembler.swift @@ -44,12 +44,8 @@ struct DataDependencyAssembler: DependencyAssembler { ) } - DIContainer.shared.register(type: DefaultNotificationRepository.self) { _ in - return DefaultNotificationRepository( - network: networkService, - userDefaultsService: userDefaultService, - keychainService: keychainService - ) + DIContainer.shared.register(type: ForbiddenWordInterface.self) { _ in + return DefaultForbiddenWordRepository() } } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Data/ForbiddenWords.json b/ByeBoo-iOS/ByeBoo-iOS/Data/ForbiddenWords.json new file mode 100644 index 00000000..528c9a12 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Data/ForbiddenWords.json @@ -0,0 +1,1550 @@ +{ + "words": [ + "10새끼", + "10쎄끼", + "10알", + "10창", + "10탱", + "10탱아", + "10팔", + "10팔년", + "10팔놈", + "10팔연", + "10할년", + "10할연", + "18넘", + "18년", + "18놈", + "18눔", + "18늠", + "18세끼", + "18쉑끼", + "18쎄리", + "18쒜리", + "18쒝끼", + "18씨끼", + "2c8", + "2c팔", + "갈보", + "강간", + "개넘", + "개년", + "개놈", + "개뇬", + "개눔", + "개늠", + "개때꺄", + "개때끼", + "개또라이", + "개똥", + "개보지", + "개부랄", + "개부럴", + "개불알", + "개새", + "개새꺄", + "개새끼", + "개새리", + "개새야", + "개색", + "개색기", + "개색꺄", + "개색끼", + "개색히", + "개샥", + "개세", + "개세끼", + "개세이", + "개섹", + "개섺", + "개셃", + "개셋키", + "개셐", + "개소리", + "개쇄끼", + "개쇅", + "개쇅갸", + "개쇅기", + "개쇅꺄", + "개쇅끼", + "개쇅캬", + "개쇅키", + "개쇗", + "개쇗기", + "개쇠리", + "개쉐", + "개쉐끼", + "개쉐리", + "개쉐이", + "개쉑", + "개쉑갸", + "개쉑기", + "개쉑꺄", + "개쉑끼", + "개쉑이", + "개쉑캬", + "개쉑키", + "개쉑히", + "개쉢", + "개쉨", + "개쉬끼", + "개싀끼", + "개싘", + "개시퀴", + "개시키", + "개십팔", + "개싯끼", + "개싯키", + "개싴", + "개쌍넘", + "개쌍년", + "개쌍놈", + "개쌔", + "개쌔꺄", + "개쌔끼", + "개쌕", + "개쌕끼", + "개썅넘", + "개썅년", + "개썅놈", + "개썅늠", + "개썅연", + "개쎅", + "개쐐리", + "개쒜", + "개쒜끼", + "개쒜리", + "개쒝", + "개쒝갸", + "개쒝기", + "개쒝꺄", + "개쒝끼", + "개쒝키", + "개쒯", + "개쒸", + "개쒹기", + "개씌끼", + "개씨끼", + "개씨발", + "개씨팕", + "개씹", + "개씹창", + "개씹팔", + "개자슥", + "개자싁", + "개자식", + "개자지", + "개젓", + "개젖", + "개졋", + "개졎", + "개조또", + "개조옷", + "개족", + "개좆", + "개지랄", + "개후레", + "개후장", + "거시기", + "겁탈", + "게넘", + "게년", + "게놈", + "게뇬", + "게뇽", + "게눔", + "게새끼", + "게새리", + "게색", + "게색기", + "게색끼", + "게세", + "게세꺄", + "게세끼", + "게섹", + "게쉐", + "게쉐이", + "게시끼", + "게시퀴", + "고환", + "공짜버그", + "공짜캐쉬", + "그룹섹스", + "그지새끼", + "그지좃밥", + "그지좃빱", + "그지좆밥", + "근친", + "근친상간", + "기엉아", + "기형아", + "꼴려", + "꼴리는", + "꼴리다", + "난교", + "넣게벌려", + "넣고싸고", + "네에미", + "년놈", + "니미랄", + "니미럴", + "니미롤", + "니미를", + "니보지", + "니애미", + "니애비", + "니어미", + "니에미", + "니에비", + "니좆", + "대딸", + "딸딸이", + "떡치기", + "떡칠녀", + "룸섹스", + "마스터베이션", + "매춘", + "매춘부", + "몸안에사정", + "몸캠", + "몸켐", + "몸파는", + "뮈칀세끼", + "뮈칀세리", + "뮈칀섹끼", + "뮈친", + "뮈친세리", + "뮈친섹끼", + "뮈친섹이", + "미췬", + "미췬년", + "미췬세끼", + "미췬쉐리", + "미친", + "미친넘", + "미친년", + "미친놈", + "미친뇬", + "미친새끼", + "미친세리", + "미친섹이", + "미친자식", + "미튄", + "미틘", + "미틩", + "미틴", + "미틴뇬", + "밑구녕", + "밑구녕빨기", + "박고싶다", + "박고싶퍼", + "박아줄게", + "박아줄께", + "박을께", + "박을년", + "뱅쉰", + "뱅싄", + "뱅신", + "뱡신", + "버즤", + "버지", + "버지물", + "버짓물", + "번섹", + "번쌕", + "번쎅", + "벙어리", + "벼엉신", + "변섹", + "변태", + "변퇴", + "병쉰", + "병싀", + "병싄", + "병신", + "병씬", + "보오지", + "보쥐", + "보즤", + "보지", + "보지걸", + "보지구녕", + "보지구멍", + "보지나라", + "보지당", + "보지물", + "보지보지", + "보지털", + "보짓년", + "보짓물", + "보짖물", + "보G", + "봉알", + "뵤즤", + "뵤지", + "뵨태", + "뵹딱", + "뵹싄", + "뵹신", + "부랄", + "부부섹스", + "부카케", + "불륜", + "불알", + "붕딱", + "붕딲", + "붕뛴", + "붕싄", + "붕시나", + "붕신", + "붕알", + "붜지", + "붱신", + "뷍슨", + "뷍싄", + "뷍신", + "뷩쉬", + "뷩쉰", + "뷩싄", + "뷩신", + "뷰웅신", + "븅딱", + "븅쉰", + "븅싄", + "븅시", + "븅신", + "븅아", + "브랄", + "블알", + "븡딱", + "븡쉰", + "븡신", + "븽딱", + "븽쉬", + "븽슨", + "븽싄", + "븽시", + "븽신", + "비잉신", + "빙딱", + "빙쉬", + "빙쉰", + "빙싀", + "빙싄", + "빙시", + "빙신", + "빠걸", + "빠구리", + "빠굴", + "빠굴이", + "빠꾸리", + "빠도리", + "빠돌이", + "빠라", + "빠라조", + "빠라줘", + "빠러", + "빠수니", + "빠순이", + "빠큐", + "빡돌", + "빡촌", + "빡큐", + "빨어핥어박어", + "빨자좃", + "빨자좆", + "빽보지", + "빽자지", + "뺑신", + "뺑쒼", + "뺑씬", + "뺘큐", + "뻐어큐", + "뻐큐", + "뻐킹", + "뼝신", + "뽀개", + "뽀로노", + "뽀르나", + "뽀르너", + "뽀르노", + "뽀쥐", + "뽀지", + "뽀쮜", + "뽕알", + "뿅신", + "뿅씬", + "뿡알", + "쁑신", + "삐꾸", + "삥쉰", + "삥쒼", + "삥씬", + "사까시", + "사까치", + "사이버섹스", + "사창가", + "사카시", + "사카치", + "삽쥘", + "삿가시", + "삿까시", + "삿깟시", + "상년", + "상노무", + "상놈", + "새꺄", + "새뀌", + "새끠", + "새끼", + "새뤼", + "새에끼", + "새키", + "새X", + "색갸", + "색걸", + "색골", + "색광", + "색기", + "색꺄", + "색끼", + "색남", + "색녀", + "색마", + "색스", + "색쑤", + "색쓰", + "색캬", + "색키", + "색할", + "색햐", + "색히", + "샊꺄", + "샤불년", + "샤앙년", + "샵년", + "샹넘", + "샹년", + "샹놈", + "샹늠", + "성관계", + "성교", + "성매매", + "성섹스", + "성욕구", + "성인용품", + "성체위", + "성체험", + "성추행", + "성충동", + "성폭력", + "성폭행", + "성행위", + "세게빨아", + "세꺄", + "세뀌", + "세끠", + "세끼", + "세액스", + "세에끼", + "세에쓰", + "세엑", + "세퀴", + "세키", + "섹남", + "섹녀", + "섹마", + "섹보지", + "섹수", + "섹쉬", + "섹슈", + "섹스", + "섹시", + "섹파트너", + "섹하자", + "섹하장", + "섹할", + "섹해", + "섹히", + "섹s", + "수간", + "수음", + "쉑수", + "쉑스", + "쉑쑤", + "쉑쓰", + "쉑캬", + "스와핑", + "스트립쇼", + "스트립쑈", + "스펄", + "십8", + "십넘", + "십녀", + "십놈", + "십때꺄", + "십때끼", + "십떼끼", + "십밸", + "십새", + "십새꺄", + "십새끼", + "십새캬", + "십새키", + "십색", + "십색꺄", + "십색끼", + "십색히", + "십세", + "십세끼", + "십쇄리", + "십쉐", + "십쉐리", + "십쉐이", + "십쉑", + "십쉑히", + "십시끼", + "십쌔", + "십쌔꺄", + "십쎄끼", + "십씨키", + "십알", + "십질", + "십창", + "십탱", + "십탱구리", + "십팔", + "십팔년", + "십팔련", + "십팔연", + "십할", + "십할련", + "싯끼", + "싯빨", + "싯팔", + "싲팔", + "싴팔", + "싵팔", + "싶알", + "싶팔", + "싸발년", + "싸앙넘", + "싸앙녀", + "싸앙년", + "싸줄께", + "싹년", + "쌉년", + "쌍넌", + "쌍넘", + "쌍년", + "쌍념", + "쌍노무", + "쌍놈", + "쌍놈아", + "쌍뇨나", + "쌍뇬", + "쌍뇸", + "쌍뇽", + "쌍뉸", + "쌍연", + "쌔꺄", + "쌔끼", + "쌔리", + "쌔캬", + "쌔키", + "쌕", + "쌕갸", + "쌕걸", + "쌕꺄", + "쌕수", + "쌕스", + "쌕쑤", + "쌕쓰", + "쌩보지", + "쌩포르노", + "쌰앙넘", + "쌰앙녀", + "쌰앙년", + "쌰앙눔", + "쌰앙뉸", + "썁색", + "썅", + "썅넌", + "썅넘", + "썅녀", + "썅년", + "썅놈", + "썅뇬", + "썅연", + "썩을년", + "쎅스", + "쓰글넘", + "쓰글년", + "쓰글놈", + "쓰글늠", + "쓰발", + "쓰발넘", + "쓰벌", + "쓰불", + "쓰뷀", + "쓰블", + "씨댕", + "씨댕년", + "씨뎅", + "씨바", + "씨바라", + "씨박", + "씨발", + "씨발넘", + "씨발년", + "씨발놈", + "씨발놈아", + "씨방새", + "씨방세", + "씨뱔", + "씨벌", + "씨벌년", + "씨벧", + "씨벨년", + "씨벵", + "씨봉", + "씨봉알", + "씨부랄", + "씨부럴", + "씨불", + "씨불년", + "씨불얼", + "씨붕", + "씨뷀", + "씨브", + "씨브랄", + "씨브럴", + "씨블", + "씨블년", + "씨앙년", + "씨양년", + "씨이바", + "씨이발", + "씨이방", + "씨이밸", + "씨이벌", + "씨이빨", + "씨이팔", + "씨입년", + "씨입뇬", + "씨파", + "씨팍", + "씨팏", + "씨팔", + "씨팔년", + "씨펄", + "씹", + "씹8", + "씹넘", + "씹년", + "씹놈", + "씹뇬", + "씹딱꿍", + "씹때꺄", + "씹때끼", + "씹떼", + "씹떼끼", + "씹물", + "씹밸", + "씹벌", + "씹보지", + "씹보지년", + "씹블", + "씹빡", + "씹빨", + "씹뻘", + "씹새", + "씹새꺄", + "씹새끼", + "씹새캬", + "씹새키", + "씹색꺄", + "씹색끼", + "씹색히", + "씹샛길", + "씹생알", + "씹세", + "씹세끼", + "씹세이", + "씹쉐", + "씹쉐리", + "씹쉐이", + "씹쉑", + "씹쉑히", + "씹쌔", + "씹쌔기", + "씹쌔꺄", + "씹쌔끼", + "씹쌔키", + "씹쎄", + "씹쎄끼", + "씹쒜", + "씹씨키", + "씹알", + "씹연", + "씹질", + "씹창", + "씹탱", + "씹탱구리", + "씹팔", + "씹팔년", + "씹팔련", + "씹팔연", + "씹펄", + "씹풀", + "씹할", + "씹할련", + "씹할연", + "씻끼", + "씻발", + "씻벌", + "씻뻘", + "씻퐁", + "씾팔", + "앂년", + "앂팔", + "아이템매니아", + "아이템메니아", + "아이템베이", + "안에사정", + "알몸", + "알몸공개", + "알몸사진", + "알몸쇼", + "애액", + "앰병", + "앰창", + "야녀", + "야동", + "야설", + "엄창", + "에믜", + "에미", + "여자보지", + "염병", + "염병할", + "엿먹", + "엿먹어", + "옘병", + "오나니", + "오랄", + "오럴", + "오럴섹스", + "오르가즘", + "옹녀", + "왕보지", + "왕자지", + "우라질", + "원조교재", + "원조교제", + "원조알바", + "월경", + "유두", + "유방", + "육봉", + "육시랄", + "육시럴", + "윤간", + "윤락", + "음경", + "음담패설", + "음란", + "음순", + "음액", + "음욕", + "입사후장", + "입안사정", + "자위", + "자위기구", + "자위남", + "자위녀", + "자지", + "잡년", + "잡놈", + "잡뇬", + "젓가튼", + "젓같은", + "젓까", + "젓까는", + "젓나", + "젓나게", + "젓마난", + "젓만한", + "젓밥", + "젓빠지게", + "정박아", + "정자", + "젖", + "젖가튼", + "젖같은", + "젖까", + "젖까는", + "젖꼭지", + "젖나게", + "젖도", + "젖마난", + "젖만한", + "젖물", + "젖밥", + "젖빠지게", + "젖탱이", + "젖통", + "조가틍", + "조까", + "조까는", + "조까라", + "조까튼", + "조낸", + "조또", + "조루", + "조빠라", + "조빠지게", + "조빱", + "조옷나", + "조질래", + "조카툰", + "조털", + "족가튼", + "좀물", + "좃", + "좃가튼", + "좃같은", + "좃까", + "좃까는", + "좃까라", + "좃나", + "좃나게", + "좃도", + "좃물", + "좃밥", + "좃빠지게", + "좄까", + "좆", + "좆구녕", + "좆까", + "좆까는", + "좆나", + "좆대가리", + "좆도", + "좆물", + "좆밥", + "좇", + "좇까", + "죳", + "죶", + "죶가튼", + "죶빠지게", + "지랄", + "짬지", + "찌찌", + "창남", + "창녀", + "창녀촌", + "창년", + "창뇨", + "창뇬", + "챵녀", + "챵년", + "챵뇬", + "처녀막", + "최음제", + "카섹", + "카섹스", + "캐세끼", + "캐쉬버그", + "캐시버그", + "큰보지", + "큰자지", + "페니스", + "포르노", + "포르노사진", + "포르노섹스", + "폰색", + "폰세엑", + "폰섹", + "폰섹스", + "폰쉑", + "폰쌕", + "폰쎅", + "프리섹스", + "플레이보지", + "한번꽂자", + "한번주께", + "한번줄래", + "핥아주께", + "핧아줄께", + "함대주까", + "함대줄래", + "함빨자", + "항문", + "허벌", + "허벌창", + "호로년", + "호로새끼", + "호로새리", + "호로색", + "호로색끼", + "호로자슥", + "호로자식", + "호모섹기", + "호모쎄끼", + "호빠", + "호스트바", + "호스트빠", + "혼음", + "화냥", + "화냥년", + "화류", + "화양년", + "후레자식", + "후장", + "후장입사", + "ac발", + "x대가리", + "간나새끼", + "간나", + "개간나", + "쌍간나", + "종간나", + "좆간나", + "개판", + "개꼴통", + "개똥차", + "개쌍판", + "개꿈", + "개수작", + "개망나니", + "개돼지", + "개쓰레기", + "개족새", + "개차반", + "개초딩", + "걸레", + "고자", + "광녀", + "광년이", + "괴뢰", + "괴뢰군", + "그지깽깽이", + "급식충", + "김치녀", + "김치남", + "꺼벙이", + "꼬붕", + "꼰대", + "꼴통", + "남창", + "ㄴㄷㅆ", + "느개비", + "느금마", + "니미", + "니기미", + "닥쳐", + "따까리", + "또라이", + "똘추", + "렉카충", + "맘충", + "매국노", + "머저리", + "먹사", + "멍청도", + "메갈리아", + "워마드", + "보슬아치", + "무뇌", + "무뇌충", + "미친개", + "바보", + "버러지", + "변태새끼", + "벌레새끼", + "보전깨", + "보지년", + "보추", + "빠돼쌍", + "빨통", + "빡대가리", + "빨갱이", + "싸이코", + "사이코", + "상폐녀", + "상폐년", + "상폐놈", + "썩을놈", + "씨방놈", + "씨방년", + "시부랄", + "씹창년", + "씹덕", + "씹쓰레기", + "씹치남", + "씹치년", + "쌍노무새끼", + "아다", + "후다", + "애비충", + "애새끼", + "애자", + "양놈", + "앰흑", + "엠창", + "니미씨발", + "오유충", + "운지", + "육변기", + "응 니애미", + "인조새", + "일베충", + "저능아", + "정신병자", + "제기랄", + "제길", + "졸라", + "좆망", + "좆무위키", + "좆만이", + "존만이", + "좆집", + "좆심", + "좆병신", + "쥐새끼", + "쥐박이", + "짭새", + "짱깨", + "쪼다", + "쩌리", + "쪽발이", + "쪽바리", + "쫄보", + "찌랭이", + "찌질이", + "찐따", + "찐찌버거", + "창놈", + "촛불좀비", + "최순실", + "추남", + "추녀", + "트롤", + "틀딱충", + "피싸개", + "한남", + "한남충", + "한녀", + "한녀충", + "호구", + "호모", + "후빨", + "흑형", + "땅크", + "달창", + "네다홍", + "레이디가카", + "레이디 가카", + "민주화", + "ㅁㅈㅎ", + "전땅크", + "보빨", + "산업화", + "슨상", + "슨탄절", + "슨삭절", + "슨상그라드", + "ㅇㅂ", + "암베", + "앙망", + "엑윽", + "엑윽엑엑", + "엑엑윽엑", + "엘젤두환", + "엔두나", + "원조가카", + "가카", + "이시국충", + "일게이", + "일밍아웃", + "파오후", + "쿰척쿰척", + "허버허버", + "폭동절", + "혁명절", + "탕탕절", + "혼모노", + "MC무현", + "노무", + "노알라", + "노운지", + "노탄절", + "뇌물현", + "부엉이바위", + "이기야", + "중력절", + "운지절", + "달빛기사단", + "박사모", + "관잦", + "관좆", + "군무새", + "군쾅이", + "김아재", + "꽁치남", + "냄져", + "냄적냄", + "느갭", + "빠가남", + "소추", + "6.9", + "싸튀충", + "대디충", + "애호박남", + "와랄랄라", + "자댕이", + "자릉내", + "자들자들", + "자이루", + "자적자", + "자혐", + "조팔", + "좆들좆들", + "좆스플레인", + "줄쓰콘", + "팥죽남", + "후전깨", + "한남유충", + "함흥자지", + "운동권", + "꿘", + "방관충", + "박근혜", + "문재인", + "이명박", + "전두환", + "김대중", + "박정희", + "노태우", + "김영삼", + "노무현", + "번탈남", + "자르셋", + "자트릭스", + "좆의숙주", + "한남또", + "허수애비", + "투명애비", + "씹치", + "재기하다", + "명자", + "갓치", + "보지대장부", + "성님", + "탈코르셋", + "보력지원", + "흉자", + "가좆", + "기수짓", + "기안내", + "남리남리", + "똥냐", + "망혼", + "바용가", + "쓰까페미", + "앱친", + "앱티엠", + "정혈", + "젠신병자", + "하용가", + "혐애", + "힘조", + "힘죠", + "홍본자무죄", + "6작은따옴표9", + "66큰따옴표99", + "좆한민국", + "개저씨", + "페미니즘", + "페미나치", + "트페미", + "병신새끼", + "좆나게", + "존나게", + "전나게", + "졸라게", + "절라게", + "존나", + "젖나", + "전나", + "절라", + "좆만한", + "좃만한", + "존만한", + "좆마난", + "좃마난", + "존마난", + "좆같은", + "좆가튼", + "좃가튼,", + "저까튼", + "좆빠지게", + "저빠지게", + "좁밥", + "접밥", + "저빱", + "저까", + "씨이불", + "띠발", + "띠벌", + "띠불", + "띠방", + "띠바", + "띠붕", + "띠밸", + "띠팔", + "띠펄", + "시벌", + "시팔", + "시이발", + "시이벌", + "시이불", + "시이바", + "시이붕", + "시이부", + "시이밸", + "시이팔", + "시이펄", + "시이풀", + "시이빡", + "쒸발", + "쒸벌", + "쒸불", + "쒸방", + "쒸바", + "쒸빡", + "쒸이발", + "쒸이벌", + "쒸이불", + "쒸이방", + "쒸이바", + "쉬발", + "쉬벌", + "쉬불", + "쉬방", + "쉬바", + "쉬붕", + "쉬부", + "쉬밸", + "쉬팔", + "쉬풀", + "쉬빡", + "쓰방", + "쓰바", + "쓰붕", + "쓰부", + "쓰밸", + "쓰팔", + "쓰펄", + "쓰풀", + "쓰빡", + "쓰이발", + "쓰이벌", + "쓰이불", + "까대", + "까댄", + "니미룰", + "제기럴", + "제기롤", + "제기룰", + "닝기미", + "니주가리", + "개넌", + "지럴", + "지롤", + "쥐랄", + "쥐럴", + "쥐롤", + "등신", + "미췬놈", + "미췬넘", + "미친넌", + "미췬뇬", + "미췬넌", + "싸가지", + "싹아지", + "c팔", + "개같은년", + "c8", + "개같은놈", + "씝할", + "쉐끼", + "쇄끼", + "쇅끼", + "씨키", + "ㅅ ㅐ끼", + "ㅅ ㅐㄲ ㅣ", + "ㅅ ㅐ ㄲ ㅣ", + "시발", + "싀발", + "스발", + "스벌", + "쉬이발", + "쓰으방", + "쉬빨", + "쉬팍", + "씁알", + "씝알", + "씝탱", + "존니", + "죶나", + "죨라", + "죶니", + "죤니", + "죤나", + "죶마난", + "죶같은", + "즤랄", + "질알", + "ㅇㅐ자", + "니엠", + "믜친", + "ㅁl친", + "애쟈", + "떠라이", + "ㅆl팔", + "ㅆl발", + "ㄴ ㅣㅁ ㅣ", + "ㄴlㅁl", + "늬미", + "니믜", + "쓰팍", + "씌팔", + "씌발", + "싀팔", + "ㅆ1팔", + "ㅆ1발", + "계같은뇬", + "개같은뇬", + "죳나", + "니앰", + "애미", + "씹땡", + "씝년", + "ㄱH뇬", + "씌벌", + "싀방", + "싀봉", + "씌방", + "ㅆI발", + "ㅅ1발", + "ㄴ1ㅇH미", + "ㅈl랄", + "미칀", + "호로자슥애", + "젠장", + "젱장", + "제긜", + "젝일", + "바부", + "듕신", + "씨벨", + "시벵", + "시펄", + "등쉬", + "늬귀미", + "씨밝", + "개샛끼", + "개쓰렉기", + "쉬키", + "세캬", + "식키", + "시키", + "새캬", + "듕시나", + "똘아이", + "ㅁ1친", + "ㅁ1친년", + "뮈췬", + "뮈친년", + "미췐", + "미췐년", + "및친", + "벵신", + "병시나", + "병시", + "뷩시", + "색귀", + "셥새", + "쉽년", + "쉽새", + "시바라", + "쉽팔", + "시밝", + "시벨", + "십샹", + "ㅆ│발", + "쒸뱅", + "씌파", + "씌빨", + "씌밸", + "씌바", + "쒸박", + "씨뱅", + "c발", + "g랄", + "zl랄", + "凸,미워", + "뉘미", + "뉘귀미", + "^^ㅣ발", + "ㄱ ㅐ", + "ㅅ ㅐㄱㄱㅣ", + "ㄱH", + "ㅅ ㅔㄲ ㅣ", + "ㅅHㄲI", + "ㅅH끼", + "ㅅ ㅔㄲ", + "ㅅ1팔", + "ㅆ ㅣ불", + "ㅆㅂ", + "ㅅㅂ", + "씹발", + "개`", + "개쇄", + "씨`발", + "새'꺄", + "새'끼", + "섀캬", + "샹뇬", + "쇄키", + "섀끼", + "쌔기", + "ㅁ ㅣ친", + "망할", + "씨'발", + "씨빨", + "씹쌍", + "ㅈ1랄", + "ㅆ ㅣ발", + "ㅆ ㅣ방", + "ㅆ ㅣ팔", + "ㅆ ㅣ벌", + "ㅆ!발", + "쒸벨", + "등쉰", + "똘츄", + "ㄴ ㅣ미", + "ㄴ ㅣㄱ ㅣ", + "ㄴ1ㄱ1", + "ㄴ1ㅁ1", + "ㄴ1미", + "ㄴ1 ㅇ ㅐ", + "ㄴ1 애", + "니M창", + "니OH미", + "시팍", + "시빨", + "시파", + "시밸", + "쉽뇬", + "개련", + "ㅆ1밸", + "ㅆ1벨", + "씌벨", + "애좌", + "씻팔", + "ㅆ1바", + "개샛히애", + "색휘", + "섹키", + "쓉년", + "쓉창", + "호로자식애", + "씌뱅", + "씨팰", + "씌댕", + "씌뎅", + "엠병", + "후레자식애", + "후레자슥애", + "후레년", + "씹빠", + "뻑큐", + "ㅃr큐", + "개섀끼", + "개샹련", + "니뮈럴", + "늬기미", + "쓰박", + "씹샹", + "연병", + "시밟", + "뒤져", + "짜져", + "꺼져", + "뒤질래", + "디질래", + "아갈", + "허접", + "흐접", + "낙태아", + "다방년", + "애비자지", + "애미보지", + "잠지", + "공알", + "딸따리", + "섹쓰", + "쎅쓰", + "개싑창", + "죷", + "좇나", + "욧나", + "쟈지", + "죠또", + "죵나", + "자쥣", + "죠빠", + "쫓까", + "죡쳐", + "쟘쥐", + "꼬추", + "꼬츄", + "걸레년", + "곧휴", + "쟘지", + "ㅈ ㅏㅈ ㅣ", + "ㅈ ㅏ지", + "자쥐", + "잠쥐", + "보'지", + "섹'스", + "차앙년", + "창ㄴ ㅕ", + "촹년", + "촹뇬", + "ㅃr굴", + "고츄", + "죠까", + "sex", + "fuck", + "fuk", + "porno", + "dildo", + "pussy", + "shit", + "bitch", + "anal", + "fetish", + "gay", + "lesbien", + "bastard", + "cunt", + "damn", + "asshole", + "귀두" + ] +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Data/Model/ForbiddenWordList.swift b/ByeBoo-iOS/ByeBoo-iOS/Data/Model/ForbiddenWordList.swift new file mode 100644 index 00000000..25aacb78 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Data/Model/ForbiddenWordList.swift @@ -0,0 +1,19 @@ +// +// ForbiddenWordList.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/27/26. +// + +import Foundation + +struct ForbiddenWordList: Decodable { + let words: Set +} + +extension ForbiddenWordList { + + func toEntity() -> ForbiddenWordEntity { + .init(words: words) + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Data/Repository/ForbiddenWordRepository.swift b/ByeBoo-iOS/ByeBoo-iOS/Data/Repository/ForbiddenWordRepository.swift new file mode 100644 index 00000000..d2b01955 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Data/Repository/ForbiddenWordRepository.swift @@ -0,0 +1,51 @@ +// +// ForbiddenWordRepository.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/27/26. +// + +import Foundation + +final class DefaultForbiddenWordRepository: ForbiddenWordInterface { + + private let resource = "ForbiddenWords" + private let fileExtension = "json" + private var cachedForbiddenWords: ForbiddenWordEntity? + + func getForbiddenWords(_ word: String) -> ForbiddenWordEntity? { + if let cached = cachedForbiddenWords { + return cached + } + + guard let url = fetchURL(), + let forbiddenWordList = decodeForbiddenWords(url: url) else { + return nil + } + + let forbiddenWordEntity = forbiddenWordList.toEntity() + cachedForbiddenWords = forbiddenWordEntity + return forbiddenWordEntity + } + + private func fetchURL() -> URL? { + guard let url = Bundle.main.url(forResource: resource, withExtension: fileExtension) else { + ByeBooLogger.error(ByeBooError.fileNotFound) + return nil + } + + return url + } + + private func decodeForbiddenWords(url: URL) -> ForbiddenWordList? { + do { + let data = try Data(contentsOf: url) + let decoder = JSONDecoder() + let decodedData = try decoder.decode(ForbiddenWordList.self, from: data) + return decodedData + } catch { + ByeBooLogger.error(ByeBooError.decodingError) + return nil + } + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Domain/DomainDependencyAssembler.swift b/ByeBoo-iOS/ByeBoo-iOS/Domain/DomainDependencyAssembler.swift index 058335a9..ba2900d8 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Domain/DomainDependencyAssembler.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Domain/DomainDependencyAssembler.swift @@ -19,7 +19,9 @@ struct DomainDependencyAssembler: DependencyAssembler { guard let userRepository = DIContainer.shared.resolve(type: UsersInterface.self), let questRepository = DIContainer.shared.resolve(type: QuestsInterface.self), - let authRepository = DIContainer.shared.resolve(type: AuthInterface.self) else { + let authRepository = DIContainer.shared.resolve(type: AuthInterface.self), + let forbiddenWordRepository = DIContainer.shared.resolve(type: ForbiddenWordInterface.self) + else { ByeBooLogger.error(ByeBooError.DIFailedError) return } @@ -163,5 +165,9 @@ struct DomainDependencyAssembler: DependencyAssembler { DIContainer.shared.register(type: CheckAlarmEnabledUseCase.self) { _ in return DefaultCheckAlarmEnabledUseCase(repository: userRepository) } + + DIContainer.shared.register(type: IsForbiddenWordUseCase.self) { _ in + return DefaultIsForbiddenWordUseCase(repository: forbiddenWordRepository) + } } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/ForbiddenWordEntity.swift b/ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/ForbiddenWordEntity.swift new file mode 100644 index 00000000..efcdd442 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/ForbiddenWordEntity.swift @@ -0,0 +1,16 @@ +// +// ForbiddenWordEntity.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/27/26. +// + +struct ForbiddenWordEntity { + let words: Set +} + +extension ForbiddenWordEntity { + static func stub() -> Self { + .init(words: ["word1", "word2", "word3"]) + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/NicknameRule.swift b/ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/NicknameRule.swift index e0b30722..dfcd4650 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/NicknameRule.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/NicknameRule.swift @@ -10,4 +10,5 @@ import Foundation enum NicknameRule { private static let regularExpression = "(?=.{2,5}$)(?!.*[ㄱ-ㅎㅏ-ㅣ])[가-힣a-zA-Z0-9]+" static let predicate = NSPredicate(format: "SELF MATCHES %@", regularExpression) + static let bannedWords: Set = ["admin", "master", "test", "운영자", "관리자"] } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Domain/Interface/ForbiddenWordInterface.swift b/ByeBoo-iOS/ByeBoo-iOS/Domain/Interface/ForbiddenWordInterface.swift new file mode 100644 index 00000000..55d49722 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Domain/Interface/ForbiddenWordInterface.swift @@ -0,0 +1,10 @@ +// +// ForbiddenWordInterface.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/27/26. +// + +protocol ForbiddenWordInterface { + func getForbiddenWords(_ word: String) -> ForbiddenWordEntity? +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/CheckValidNicknameUseCase.swift b/ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/CheckValidNicknameUseCase.swift index 83e010a5..17a295bc 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/CheckValidNicknameUseCase.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/CheckValidNicknameUseCase.swift @@ -6,12 +6,17 @@ // protocol CheckValidNicknameUseCase { - func execute(nickname: String) -> Bool + func isValidRegulation(nickname: String) -> Bool + func isPermitteed(nickname: String) -> Bool } struct DefaultCheckValidNicknameUseCase: CheckValidNicknameUseCase { - func execute(nickname: String) -> Bool { + func isValidRegulation(nickname: String) -> Bool { return NicknameRule.predicate.evaluate(with: nickname) } + + func isPermitteed(nickname: String) -> Bool { + return !NicknameRule.bannedWords.contains(nickname) + } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/IsForbiddenWordUseCase.swift b/ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/IsForbiddenWordUseCase.swift new file mode 100644 index 00000000..87466347 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/IsForbiddenWordUseCase.swift @@ -0,0 +1,29 @@ +// +// IsForbiddenWordUseCase.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/27/26. +// + +import Foundation + +protocol IsForbiddenWordUseCase { + func execute(word: String) -> Bool +} + +struct DefaultIsForbiddenWordUseCase: IsForbiddenWordUseCase { + + private let repository: ForbiddenWordInterface + + init(repository: ForbiddenWordInterface) { + self.repository = repository + } + + func execute(word: String) -> Bool { + guard let forbiddenWordEntity = repository.getForbiddenWords(word) else { + return true + } + + return forbiddenWordEntity.words.contains { word.contains($0) } + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/isValidQuestAnswerUseCase.swift b/ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/IsValidQuestAnswerUseCase.swift similarity index 97% rename from ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/isValidQuestAnswerUseCase.swift rename to ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/IsValidQuestAnswerUseCase.swift index 9f31c5bd..cbd57801 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/isValidQuestAnswerUseCase.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/IsValidQuestAnswerUseCase.swift @@ -1,5 +1,5 @@ // -// isValidQuestAnswerUseCase.swift +// IsValidQuestAnswerUseCase.swift // ByeBoo-iOS // // Created by 이나연 on 12/4/25. diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Information/ViewController/InformationViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Information/ViewController/InformationViewController.swift index 1e1621a4..b63dd098 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Information/ViewController/InformationViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Information/ViewController/InformationViewController.swift @@ -91,7 +91,6 @@ extension InformationViewController { viewModel.action(.nicknameButtonDidTap(nickname)) Mixpanel.mainInstance().track(event: CommonEvents.Name.nicknameComplete) } - move(view: selectQuestView, progress: .second) } private func saveQuest() { @@ -140,6 +139,19 @@ extension InformationViewController: ToastPresentable, ToastErrorHandler { self?.informationBaseView.updateButtonWhenBack(condition: result) } .store(in: &cancellables) + + viewModel.output.isForbiddenWordPublisher + .sink { [weak self] result in + guard let self else { return } + + switch result { + case .success: + move(view: selectQuestView, progress: .second) + case .failure(let error): + handleError(error) + } + } + .store(in: &cancellables) } private func bindName() { diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Information/ViewModel/InformationViewModel.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Information/ViewModel/InformationViewModel.swift index b684c69c..e45cb786 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Information/ViewModel/InformationViewModel.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Information/ViewModel/InformationViewModel.swift @@ -11,6 +11,7 @@ final class InformationViewModel { private var cancellables = Set() private let nicknameValidationSubject = CurrentValueSubject(false) + private let isForbiddenWordSubject = PassthroughSubject, Never>() private let userInformationSubject = PassthroughSubject, Never>() private let userNameSubject = PassthroughSubject, Never>() private(set) var output: Output @@ -21,20 +22,24 @@ final class InformationViewModel { private var user: UserEntity = UserEntity(id: 1, name: "") private let checkValidNicknameUseCase: CheckValidNicknameUseCase + private let isForbiddenWordUseCase: IsForbiddenWordUseCase private let sendUserUseCase: SendUserUseCase private let getUserNameUseCase: GetUserNameUseCase init( checkValidNicknameUseCase: CheckValidNicknameUseCase, + isForbiddenWordUseCase: IsForbiddenWordUseCase, sendUserUseCase: SendUserUseCase, getUserNameUseCase: GetUserNameUseCase ) { self.checkValidNicknameUseCase = checkValidNicknameUseCase + self.isForbiddenWordUseCase = isForbiddenWordUseCase self.sendUserUseCase = sendUserUseCase self.getUserNameUseCase = getUserNameUseCase self.output = Output( nicknameValidationPublisher: nicknameValidationSubject.eraseToAnyPublisher(), + isForbiddenWordPublisher: isForbiddenWordSubject.eraseToAnyPublisher(), userInformationPublisher: userInformationSubject.eraseToAnyPublisher(), userNamePublisher: userNameSubject.eraseToAnyPublisher() ) @@ -80,6 +85,7 @@ extension InformationViewModel: ViewModelType { struct Output { let nicknameValidationPublisher: AnyPublisher + let isForbiddenWordPublisher: AnyPublisher, Never> let userInformationPublisher: AnyPublisher, Never> let userNamePublisher: AnyPublisher, Never> } @@ -87,12 +93,22 @@ extension InformationViewModel: ViewModelType { func action(_ trigger: Input) { switch trigger { case .editingNickname(let nickname): - let isValidNickname = checkValidNicknameUseCase.execute(nickname: nickname) + let isValidNickname = checkValidNicknameUseCase.isValidRegulation(nickname: nickname) nicknameValidationSubject.send(isValidNickname) + case .nicknameButtonDidTap(let nickname): + guard checkValidNicknameUseCase.isPermitteed(nickname: nickname), + !isForbiddenWordUseCase.execute(word: nickname) + else { + isForbiddenWordSubject.send(.failure(.nicknameViolation)) + return + } currentNickname = nickname + isForbiddenWordSubject.send(.success(())) + case .feelingButtonDidTap(let feeling): currentFeeling = feeling + case .questButtonDidTap(let questStyle): currentQuestStyle = questStyle createUserInformation( diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/ViewModel/ModifyNicknameViewModel.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/ViewModel/ModifyNicknameViewModel.swift index b9cf43d0..5225b0c3 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/ViewModel/ModifyNicknameViewModel.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/ViewModel/ModifyNicknameViewModel.swift @@ -16,13 +16,16 @@ final class ModifyNicknameViewModel: ViewModelType { private(set) var output: Output private let checkValidNicknameUseCase: CheckValidNicknameUseCase + private let isForbiddenWordUseCase: IsForbiddenWordUseCase private let modifyNicknameUseCase: ModifyNicknameUseCase init( checkValidNicknameUseCase: CheckValidNicknameUseCase, + isForbiddenWordUseCase: IsForbiddenWordUseCase, modifyNicknameUseCase: ModifyNicknameUseCase ) { self.checkValidNicknameUseCase = checkValidNicknameUseCase + self.isForbiddenWordUseCase = isForbiddenWordUseCase self.modifyNicknameUseCase = modifyNicknameUseCase output = Output( @@ -34,7 +37,7 @@ final class ModifyNicknameViewModel: ViewModelType { func action(_ trigger: Input) { switch trigger { case .editingNickname(let name): - let isValidNickname = checkValidNicknameUseCase.execute(nickname: name) + let isValidNickname = checkValidNicknameUseCase.isValidRegulation(nickname: name) checkValidNameSubject.send(isValidNickname) case .modifyNameDidTap(let name): modifyUserName(name: name) @@ -58,6 +61,12 @@ extension ModifyNicknameViewModel { extension ModifyNicknameViewModel { private func modifyUserName(name: String) { + if isForbiddenWordUseCase.execute(word: name) || + !checkValidNicknameUseCase.isPermitteed(nickname: name) { + userNameSubject.send(.failure(.nicknameViolation)) + return + } + Task { do { let name = try await modifyNicknameUseCase.execute(name: name) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/PresentationDependencyAssembler.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/PresentationDependencyAssembler.swift index f1190d13..8b0522c3 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/PresentationDependencyAssembler.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/PresentationDependencyAssembler.swift @@ -18,7 +18,9 @@ struct PresentationDependencyAssembler: DependencyAssembler { preAssembler.assemble() guard let getUserNameUseCase = DIContainer.shared.resolve(type: GetUserNameUseCase.self), - let fetchUserJourneyUseCase = DIContainer.shared.resolve(type: FetchUserJourneyUseCase.self) else { + let fetchUserJourneyUseCase = DIContainer.shared.resolve(type: FetchUserJourneyUseCase.self), + let isForbiddenWordUseCase = DIContainer.shared.resolve(type: IsForbiddenWordUseCase.self) + else { ByeBooLogger.error(ByeBooError.DIFailedError) return } @@ -66,13 +68,15 @@ struct PresentationDependencyAssembler: DependencyAssembler { DIContainer.shared.register(type: InformationViewModel.self) { container in guard let sendUserUseCase = container.resolve(type: SendUserUseCase.self), - let checkValidNicknameUseCase = container.resolve(type: CheckValidNicknameUseCase.self) else { + let checkValidNicknameUseCase = container.resolve(type: CheckValidNicknameUseCase.self) + else { ByeBooLogger.error(ByeBooError.DIFailedError) return } return InformationViewModel( checkValidNicknameUseCase: checkValidNicknameUseCase, + isForbiddenWordUseCase: isForbiddenWordUseCase, sendUserUseCase: sendUserUseCase, getUserNameUseCase: getUserNameUseCase ) @@ -208,6 +212,7 @@ struct PresentationDependencyAssembler: DependencyAssembler { return ModifyNicknameViewModel( checkValidNicknameUseCase: checkValidNicknameUseCase, + isForbiddenWordUseCase: isForbiddenWordUseCase, modifyNicknameUseCase: modifyNicknameUseCase ) } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Protocol/ToastErrorHandler.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Protocol/ToastErrorHandler.swift index 89352e2b..e1fba882 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Protocol/ToastErrorHandler.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Protocol/ToastErrorHandler.swift @@ -15,6 +15,8 @@ extension ToastErrorHandler where Self: BaseViewController & ToastPresentable { switch error { case .networkConnect: presentToastMessage(type: .connectServerError) + case .nicknameViolation: + presentToastMessage(type: .nicknameViolation) default: ByeBooLogger.error(error) } diff --git a/ByeBoo-iOS/ByeBooTests/Feature/ForbiddenWordTest.swift b/ByeBoo-iOS/ByeBooTests/Feature/ForbiddenWordTest.swift new file mode 100644 index 00000000..7cd82703 --- /dev/null +++ b/ByeBoo-iOS/ByeBooTests/Feature/ForbiddenWordTest.swift @@ -0,0 +1,39 @@ +// +// ForbiddenWordTest.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/28/26. +// + +import Testing +@testable import ByeBoo_iOS + +struct ForbiddenWordTest { + + private let repository = DefaultForbiddenWordRepository() + private let isForbiddenWordUseCase: DefaultIsForbiddenWordUseCase + + init() { + self.isForbiddenWordUseCase = DefaultIsForbiddenWordUseCase(repository: repository) + } + + @Test( + "🏁 단어에 금칙어가 포함되어있는 경우 ✅ true", + arguments: ["10알", "10알아"] + ) + func containsForbiddenWord__true(word: String) { + let isForbiddenWord = isForbiddenWordUseCase.execute(word: word) + + #expect(isForbiddenWord == true) + } + + @Test( + "🏁 단어에 금칙어가 포함되어있지 않은 경우 ✅ false", + arguments: ["주리", "승준", "나연"] + ) + func containsForbiddenWord__false(word: String) { + let isForbiddenWord = isForbiddenWordUseCase.execute(word: word) + + #expect(isForbiddenWord == false) + } +} diff --git a/ByeBoo-iOS/ByeBooTests/Feature/Information/NicknameTests.swift b/ByeBoo-iOS/ByeBooTests/Feature/Information/NicknameTests.swift index 891aba6b..9eb9432e 100644 --- a/ByeBoo-iOS/ByeBooTests/Feature/Information/NicknameTests.swift +++ b/ByeBoo-iOS/ByeBooTests/Feature/Information/NicknameTests.swift @@ -17,7 +17,7 @@ struct NicknameTests { arguments: ["a", "abcdef"] ) func isNicknameLessThan2OrGreaterThan5__false(nickname: String) async { - let result = checkValidNicknameUseCase.execute(nickname: nickname) + let result = checkValidNicknameUseCase.isValidRegulation(nickname: nickname) #expect(result == false) } @@ -27,21 +27,21 @@ struct NicknameTests { arguments: ["고ㅜ", "ㄱ우"] ) func isNicknamUsingKoreanConsonantsOrVowelsAlone__false(nickname: String) async { - let result = checkValidNicknameUseCase.execute(nickname: nickname) + let result = checkValidNicknameUseCase.isValidRegulation(nickname: nickname) #expect(result == false) } @Test("🏁 한글 자음과 모음이 혼합되어있지만 불완전한 글자일 때 ✅ false") func isNicknamUsingIncompleteKorean__false() async { - let result = checkValidNicknameUseCase.execute(nickname: "ㄱㅗ우") + let result = checkValidNicknameUseCase.isValidRegulation(nickname: "ㄱㅗ우") #expect(result == false) } @Test("🏁 닉네임에 특수문자가 포함되어있을 때 ✅ false") func isNicknameContainsSpecialCharacter__false() async { - let result = checkValidNicknameUseCase.execute(nickname: "가나디@") + let result = checkValidNicknameUseCase.isValidRegulation(nickname: "가나디@") #expect(result == false) } @@ -51,7 +51,7 @@ struct NicknameTests { arguments: [" 가나디", "가 나디", "가나디 "] ) func isNicknamContainsSpace__false(nickname: String) async { - let result = checkValidNicknameUseCase.execute(nickname: nickname) + let result = checkValidNicknameUseCase.isValidRegulation(nickname: nickname) #expect(result == false) } @@ -61,8 +61,18 @@ struct NicknameTests { arguments: ["허승준", "123", "Atom", "허1a"] ) func isValidNickname__true(nickname: String) async { - let result = checkValidNicknameUseCase.execute(nickname: nickname) + let result = checkValidNicknameUseCase.isValidRegulation(nickname: nickname) #expect(result == true) } + + @Test( + "🏁 설정 불가한 닉네임을 입력한 경우 ✅ true", + arguments: ["admin", "master", "test", "운영자", "관리자"] + ) + func isPermittedNickname__false(nickname: String) async { + let result = checkValidNicknameUseCase.isPermitteed(nickname: nickname) + + #expect(result == false) + } }