diff --git a/PyeonHaeng-iOS.xcodeproj/project.pbxproj b/PyeonHaeng-iOS.xcodeproj/project.pbxproj index bbcb30b..12635a8 100644 --- a/PyeonHaeng-iOS.xcodeproj/project.pbxproj +++ b/PyeonHaeng-iOS.xcodeproj/project.pbxproj @@ -15,8 +15,9 @@ BA05640B2B6248EA003D6DC7 /* HomeAPISupport in Frameworks */ = {isa = PBXBuildFile; productRef = BA05640A2B6248EA003D6DC7 /* HomeAPISupport */; }; BA05640D2B6248EA003D6DC7 /* Network in Frameworks */ = {isa = PBXBuildFile; productRef = BA05640C2B6248EA003D6DC7 /* Network */; }; BA0623D82B68E51400A0A3B2 /* Log in Frameworks */ = {isa = PBXBuildFile; productRef = BA0623D72B68E51400A0A3B2 /* Log */; }; + BA097F0E2B9CA82A002D3E1E /* MailSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA097F0D2B9CA82A002D3E1E /* MailSheetView.swift */; }; BA1688E02B99B85500A8F462 /* NoticeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA1688DF2B99B85500A8F462 /* NoticeView.swift */; }; - BA28F17C2B6155450052855E /* PyeonHaeng_iOSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA28F17B2B6155450052855E /* PyeonHaeng_iOSTests.swift */; }; + BA28F17C2B6155450052855E /* ProductConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA28F17B2B6155450052855E /* ProductConfigurationTests.swift */; }; BA28F1852B6155810052855E /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA28F1842B6155810052855E /* OnboardingView.swift */; }; BA28F1882B6155910052855E /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA28F1872B6155910052855E /* HomeView.swift */; }; BA28F18B2B6155BD0052855E /* ProductInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA28F18A2B6155BD0052855E /* ProductInfoView.swift */; }; @@ -47,6 +48,11 @@ BAE159D82B65FA6F002DCF94 /* HomeProductDetailSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAE159D72B65FA6F002DCF94 /* HomeProductDetailSelectionView.swift */; }; BAE159DA2B65FC35002DCF94 /* HomeProductListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAE159D92B65FC35002DCF94 /* HomeProductListView.swift */; }; BAE159DE2B663A9A002DCF94 /* HomeProductSorterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAE159DD2B663A9A002DCF94 /* HomeProductSorterView.swift */; }; + BAE7A1E62B9D7CA70022FEBB /* MailRowItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAE7A1E52B9D7CA70022FEBB /* MailRowItem.swift */; }; + BAE7A1E82B9DA0360022FEBB /* DeviceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAE7A1E72B9DA0360022FEBB /* DeviceProvider.swift */; }; + BAE7A1EA2B9DA4960022FEBB /* MockDeviceInformationProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAE7A1E92B9DA4960022FEBB /* MockDeviceInformationProvider.swift */; }; + BAE7A1EB2B9DA4A50022FEBB /* DeviceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAE7A1E72B9DA0360022FEBB /* DeviceProvider.swift */; }; + BAE7A1ED2B9DA5090022FEBB /* DeviceInformationProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAE7A1EC2B9DA5090022FEBB /* DeviceInformationProviderTests.swift */; }; BAF2BEB32B61236100931AF0 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = BAF2BEB22B61236100931AF0 /* Localizable.xcstrings */; }; E50176262B6A204F0098D1BE /* ProductInfoLineGraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E50176252B6A204F0098D1BE /* ProductInfoLineGraphView.swift */; }; E5028D5C2B96BA9400B36C16 /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA28F1902B61566E0052855E /* SearchView.swift */; }; @@ -82,9 +88,10 @@ BA0564022B62179A003D6DC7 /* Core */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Core; sourceTree = ""; }; BA0564032B6219D4003D6DC7 /* APIService */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = APIService; sourceTree = ""; }; BA0564052B624646003D6DC7 /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Shared.xcconfig; path = XCConfig/Shared.xcconfig; sourceTree = SOURCE_ROOT; }; + BA097F0D2B9CA82A002D3E1E /* MailSheetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MailSheetView.swift; sourceTree = ""; }; BA1688DF2B99B85500A8F462 /* NoticeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeView.swift; sourceTree = ""; }; BA28F1792B6155450052855E /* PyeonHaeng-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "PyeonHaeng-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - BA28F17B2B6155450052855E /* PyeonHaeng_iOSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PyeonHaeng_iOSTests.swift; sourceTree = ""; }; + BA28F17B2B6155450052855E /* ProductConfigurationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductConfigurationTests.swift; sourceTree = ""; }; BA28F1842B6155810052855E /* OnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingView.swift; sourceTree = ""; }; BA28F1872B6155910052855E /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = ""; }; BA28F18A2B6155BD0052855E /* ProductInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductInfoView.swift; sourceTree = ""; }; @@ -117,6 +124,10 @@ BAE159D72B65FA6F002DCF94 /* HomeProductDetailSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeProductDetailSelectionView.swift; sourceTree = ""; }; BAE159D92B65FC35002DCF94 /* HomeProductListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeProductListView.swift; sourceTree = ""; }; BAE159DD2B663A9A002DCF94 /* HomeProductSorterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeProductSorterView.swift; sourceTree = ""; }; + BAE7A1E52B9D7CA70022FEBB /* MailRowItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MailRowItem.swift; sourceTree = ""; }; + BAE7A1E72B9DA0360022FEBB /* DeviceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceProvider.swift; sourceTree = ""; }; + BAE7A1E92B9DA4960022FEBB /* MockDeviceInformationProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockDeviceInformationProvider.swift; sourceTree = ""; }; + BAE7A1EC2B9DA5090022FEBB /* DeviceInformationProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceInformationProviderTests.swift; sourceTree = ""; }; BAF2BEB22B61236100931AF0 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; E50176252B6A204F0098D1BE /* ProductInfoLineGraphView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductInfoLineGraphView.swift; sourceTree = ""; }; E50584522B763C8C002FDACF /* ProductInfoViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductInfoViewModel.swift; sourceTree = ""; }; @@ -175,6 +186,16 @@ name = Frameworks; sourceTree = ""; }; + BA097F0C2B9CA820002D3E1E /* Mail */ = { + isa = PBXGroup; + children = ( + BA097F0D2B9CA82A002D3E1E /* MailSheetView.swift */, + BAE7A1E52B9D7CA70022FEBB /* MailRowItem.swift */, + BAE7A1E72B9DA0360022FEBB /* DeviceProvider.swift */, + ); + path = Mail; + sourceTree = ""; + }; BA1688EB2B99D0B700A8F462 /* Notice */ = { isa = PBXGroup; children = ( @@ -224,7 +245,8 @@ isa = PBXGroup; children = ( BA849A352B8F4FB0004495BF /* Mocks */, - BA28F17B2B6155450052855E /* PyeonHaeng_iOSTests.swift */, + BA28F17B2B6155450052855E /* ProductConfigurationTests.swift */, + BAE7A1EC2B9DA5090022FEBB /* DeviceInformationProviderTests.swift */, ); path = "PyeonHaeng-iOSTests"; sourceTree = ""; @@ -273,6 +295,7 @@ BA28F18C2B6155EC0052855E /* SettingsScene */ = { isa = PBXGroup; children = ( + BA097F0C2B9CA820002D3E1E /* Mail */, BA1688EB2B99D0B700A8F462 /* Notice */, BA28F18D2B6156420052855E /* SettingsView.swift */, ); @@ -319,6 +342,7 @@ isa = PBXGroup; children = ( BA849A362B8F4FC0004495BF /* MockPaginatable.swift */, + BAE7A1E92B9DA4960022FEBB /* MockDeviceInformationProvider.swift */, ); path = Mocks; sourceTree = ""; @@ -563,8 +587,11 @@ buildActionMask = 2147483647; files = ( BA849A372B8F4FC0004495BF /* MockPaginatable.swift in Sources */, + BAE7A1EA2B9DA4960022FEBB /* MockDeviceInformationProvider.swift in Sources */, BA849A342B8F4F36004495BF /* ProductConfiguration.swift in Sources */, - BA28F17C2B6155450052855E /* PyeonHaeng_iOSTests.swift in Sources */, + BA28F17C2B6155450052855E /* ProductConfigurationTests.swift in Sources */, + BAE7A1EB2B9DA4A50022FEBB /* DeviceProvider.swift in Sources */, + BAE7A1ED2B9DA5090022FEBB /* DeviceInformationProviderTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -573,6 +600,7 @@ buildActionMask = 2147483647; files = ( E5028D5D2B96BA9F00B36C16 /* ProductInfoDetailView.swift in Sources */, + BAE7A1E62B9D7CA70022FEBB /* MailRowItem.swift in Sources */, E5028D5C2B96BA9400B36C16 /* SearchView.swift in Sources */, BAE159DA2B65FC35002DCF94 /* HomeProductListView.swift in Sources */, BA5E51932B9AC8510036209A /* NoticeDetailView.swift in Sources */, @@ -591,10 +619,12 @@ E57F2AA82B774CA700E12B3D /* ProductInfoDependency.swift in Sources */, E55DD5122B91DE9500AA63C0 /* SearchListCardView.swift in Sources */, 9CE4B4712B6F0B57002DC446 /* OnboardingPage.swift in Sources */, + BA097F0E2B9CA82A002D3E1E /* MailSheetView.swift in Sources */, E52F371B2B947DC8000EBAD5 /* SearchViewModel.swift in Sources */, BAE159DE2B663A9A002DCF94 /* HomeProductSorterView.swift in Sources */, BA1688E02B99B85500A8F462 /* NoticeView.swift in Sources */, BAE159D82B65FA6F002DCF94 /* HomeProductDetailSelectionView.swift in Sources */, + BAE7A1E82B9DA0360022FEBB /* DeviceProvider.swift in Sources */, E50176262B6A204F0098D1BE /* ProductInfoLineGraphView.swift in Sources */, BAB5CF252B6B7C5A008B24BF /* AppRootComponent.swift in Sources */, BAA4D9AF2B5A1795005999F8 /* SplashView.swift in Sources */, diff --git a/PyeonHaeng-iOS/Resources/Localizable.xcstrings b/PyeonHaeng-iOS/Resources/Localizable.xcstrings index 53a18c2..f8adfa0 100644 --- a/PyeonHaeng-iOS/Resources/Localizable.xcstrings +++ b/PyeonHaeng-iOS/Resources/Localizable.xcstrings @@ -164,6 +164,38 @@ } } }, + "Cannot Send Mail" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "メールを送信できません" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "메일을 보낼 수 없음" + } + } + } + }, + "Close" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "閉じる" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "닫기" + } + } + } + }, "Contact Us" : { "localizations" : { "ja" : { @@ -292,6 +324,22 @@ } } }, + "Open App Store" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "App Storeを開く" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "앱 스토어 열기" + } + } + } + }, "Select Promotion Items" : { "localizations" : { "ja" : { @@ -324,6 +372,22 @@ } } }, + "Your device is not configured to send mail.\nWould you like to install a mail app from the App Store?" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "お使いのデバイスはメールを送信するために設定されていません。App Storeからメールアプリをインストールしますか?" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "기기에서 메일을 보낼 수 있도록 설정되어 있지 않아요. 앱 스토어에서 메일 앱을 설치할까요?" + } + } + } + }, "개당" : { "extractionState" : "manual", "localizations" : { @@ -446,13 +510,13 @@ }, "ja" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "検索する商品名を入力してください。" } }, "ko" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "검색할 상품이름을 입력해주세요." } } diff --git a/PyeonHaeng-iOS/Sources/Scenes/SettingsScene/Mail/DeviceProvider.swift b/PyeonHaeng-iOS/Sources/Scenes/SettingsScene/Mail/DeviceProvider.swift new file mode 100644 index 0000000..f65ccc4 --- /dev/null +++ b/PyeonHaeng-iOS/Sources/Scenes/SettingsScene/Mail/DeviceProvider.swift @@ -0,0 +1,44 @@ +// +// DeviceProvider.swift +// PyeonHaeng-iOS +// +// Created by 홍승현 on 3/10/24. +// + +import UIKit + +// MARK: - DeviceInformationProvider + +protocol DeviceInformationProvider { + var deviceModel: String { get } + var deviceOS: String { get } + var appVersion: String { get } +} + +// MARK: - SystemDeviceProvider + +struct SystemDeviceProvider: DeviceInformationProvider { + var deviceModel: String { + deviceIdentifier() + } + + var deviceOS: String { + UIDevice.current.systemVersion + } + + var appVersion: String { + Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "Unknown" + } + + /// 기종을 가져오는 함수 + private func deviceIdentifier() -> String { + var systemInfo = utsname() + uname(&systemInfo) + let machineMirror = Mirror(reflecting: systemInfo.machine) + let identifier = machineMirror.children.reduce("") { identifier, element in + guard let value = element.value as? Int8, value != 0 else { return identifier } + return identifier + String(UnicodeScalar(UInt8(value))) + } + return identifier + } +} diff --git a/PyeonHaeng-iOS/Sources/Scenes/SettingsScene/Mail/MailRowItem.swift b/PyeonHaeng-iOS/Sources/Scenes/SettingsScene/Mail/MailRowItem.swift new file mode 100644 index 0000000..dcf7b11 --- /dev/null +++ b/PyeonHaeng-iOS/Sources/Scenes/SettingsScene/Mail/MailRowItem.swift @@ -0,0 +1,119 @@ +// +// MailRowItem.swift +// PyeonHaeng-iOS +// +// Created by 홍승현 on 3/10/24. +// + +import DesignSystem +import MessageUI +import SwiftUI + +// MARK: - MailRowItem + +struct MailRowItem: View { + @State private var isMailPresented: Bool = false + @State private var showAlert: Bool = false + @Environment(\.openURL) var openURL + + private let deviceProvider: DeviceInformationProvider + + // MARK: Initializations + + init(deviceProvider: DeviceInformationProvider) { + self.deviceProvider = deviceProvider + } + + // MARK: Body + + var body: some View { + Button(action: attemptToSendMail) { + HStack { + Image.notePencil + .renderingMode(.template) + .foregroundStyle(.gray900) + Text("Contact Us") + .font(.b1) + Spacer() + Image(systemName: Constants.disclosureImageName) + .font(.system(size: Metrics.disclosureSize, weight: .semibold)) // Styled to look like a disclosure indicator + .foregroundStyle(.gray.opacity(Metrics.disclosureOpacity)) + } + } + .sheet(isPresented: $isMailPresented) { + MailSheetView( + subject: Constants.emailSubject, + recipients: [Constants.emailAddress], + messageBody: generateDefaultMessageBody() + ) + } + .alert(isPresented: $showAlert) { + Alert( + title: Text(Constants.alertTitle), + message: Text(Constants.alertDescription), + primaryButton: .default(Text(Constants.openAppStoreButtonText), action: moveToMailApp), + secondaryButton: .cancel(Text(Constants.closeButtonText)) + ) + } + } + + // MARK: Private methods + + /// Attempts to present the mail view or shows an alert if mail cannot be sent. + private func attemptToSendMail() { + if MFMailComposeViewController.canSendMail() { + isMailPresented = true + } else { + showAlert = true + } + } + + /// Opens the Mail app's page in the App Store. + private func moveToMailApp() { + if let url = URL(string: Constants.emailURL) { + openURL(url) + } + } + + /// mail default contents + private func generateDefaultMessageBody() -> String { + """ + Please write your message here. + + ------------------- + + Device Model : \(deviceProvider.deviceModel) + Device OS : \(deviceProvider.deviceOS) + App Version : \(deviceProvider.appVersion) + + ------------------- + """ + } +} + +// MARK: - Metrics + +private enum Metrics { + static let disclosureSize: CGFloat = 14 + static let disclosureOpacity: CGFloat = 0.5 +} + +// MARK: - Constants + +private enum Constants { + static let alertTitle: LocalizedStringKey = "Cannot Send Mail" + static let alertDescription: LocalizedStringKey = """ + Your device is not configured to send mail. + Would you like to install a mail app from the App Store? + """ + + static let disclosureImageName: String = "chevron.right" + + static let openAppStoreButtonText: LocalizedStringKey = "Open App Store" + static let closeButtonText: LocalizedStringKey = "Close" + + /// Represents the URL to the Mail app in the App Store. + static let emailURL: String = "https://apps.apple.com/app/mail/id1108187098" + static let emailSubject: String = "<편행> 문의하기" + static let emailAddress: String = "whitehyun@icloud.com" +} diff --git a/PyeonHaeng-iOS/Sources/Scenes/SettingsScene/Mail/MailSheetView.swift b/PyeonHaeng-iOS/Sources/Scenes/SettingsScene/Mail/MailSheetView.swift new file mode 100644 index 0000000..61ac48b --- /dev/null +++ b/PyeonHaeng-iOS/Sources/Scenes/SettingsScene/Mail/MailSheetView.swift @@ -0,0 +1,46 @@ +// +// MailSheetView.swift +// PyeonHaeng-iOS +// +// Created by 홍승현 on 3/9/24. +// + +import MessageUI +import SwiftUI + +// MARK: - MailSheetView + +/// 메일 보내기 뷰를 구현하는 구조체 +struct MailSheetView: UIViewControllerRepresentable { + @Environment(\.presentationMode) var presentationMode + var subject: String + var recipients: [String] + var messageBody: String + + func makeUIViewController(context: Context) -> MFMailComposeViewController { + let mail = MFMailComposeViewController() + mail.mailComposeDelegate = context.coordinator + mail.setSubject(subject) + mail.setToRecipients(recipients) + mail.setMessageBody(messageBody, isHTML: false) + return mail + } + + func updateUIViewController(_: MFMailComposeViewController, context _: Context) {} + + final class Coordinator: NSObject, MFMailComposeViewControllerDelegate { + var parent: MailSheetView + + init(_ parent: MailSheetView) { + self.parent = parent + } + + func mailComposeController(_: MFMailComposeViewController, didFinishWith _: MFMailComposeResult, error _: Error?) { + parent.presentationMode.wrappedValue.dismiss() + } + } + + func makeCoordinator() -> Coordinator { + Coordinator(self) + } +} diff --git a/PyeonHaeng-iOS/Sources/Scenes/SettingsScene/SettingsView.swift b/PyeonHaeng-iOS/Sources/Scenes/SettingsScene/SettingsView.swift index d46a254..2fadebd 100644 --- a/PyeonHaeng-iOS/Sources/Scenes/SettingsScene/SettingsView.swift +++ b/PyeonHaeng-iOS/Sources/Scenes/SettingsScene/SettingsView.swift @@ -38,12 +38,6 @@ struct SettingsView: View { } } -private extension String { - static var version: String? { - Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String - } -} - // MARK: - SettingsRow private struct SettingsRow: View { @@ -67,6 +61,7 @@ private struct SettingsRow: View { Spacer() Text(verbatim: .version ?? "-") .font(.c2) + .accessibilityLabel(Text(verbatim: "\(.version ?? "Unknown") Version")) } case .announcements: @@ -77,6 +72,9 @@ private struct SettingsRow: View { subject } + case .contacts: + MailRowItem(deviceProvider: SystemDeviceProvider()) + default: NavigationLink {} label: { subject @@ -89,7 +87,9 @@ private struct SettingsRow: View { image(from: item) .renderingMode(.template) .foregroundStyle(.gray900) + .accessibilityHidden(true) Text(item.rawValue) + .font(.b1) } } @@ -120,6 +120,12 @@ private extension SettingsView { } } +private extension String { + static var version: String? { + Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String + } +} + #Preview { SettingsView() } diff --git a/PyeonHaeng-iOSTests/DeviceInformationProviderTests.swift b/PyeonHaeng-iOSTests/DeviceInformationProviderTests.swift new file mode 100644 index 0000000..1ce6c7e --- /dev/null +++ b/PyeonHaeng-iOSTests/DeviceInformationProviderTests.swift @@ -0,0 +1,34 @@ +// +// DeviceInformationProviderTests.swift +// PyeonHaeng-iOSTests +// +// Created by 홍승현 on 3/10/24. +// + +import XCTest + +final class DeviceInformationProviderTests: XCTestCase { + var mockProvider: MockDeviceInformationProvider? + + override func setUp() { + super.setUp() + mockProvider = MockDeviceInformationProvider(deviceModel: "iPhone16,2", deviceOS: "iOS 17.4", appVersion: "2.0.0") + } + + override func tearDown() { + mockProvider = nil + super.tearDown() + } + + func testDeviceModel() throws { + XCTAssertEqual(mockProvider?.deviceModel, "iPhone16,2", "Mock device model should be 'iPhone16,2'") + } + + func testDeviceOS() throws { + XCTAssertEqual(mockProvider?.deviceOS, "iOS 17.4", "Mock device OS should be 'iOS 17.4'") + } + + func testAppVersion() throws { + XCTAssertEqual(mockProvider?.appVersion, "2.0.0", "Mock app version should be '2.0.0'") + } +} diff --git a/PyeonHaeng-iOSTests/Mocks/MockDeviceInformationProvider.swift b/PyeonHaeng-iOSTests/Mocks/MockDeviceInformationProvider.swift new file mode 100644 index 0000000..ea2eebd --- /dev/null +++ b/PyeonHaeng-iOSTests/Mocks/MockDeviceInformationProvider.swift @@ -0,0 +1,14 @@ +// +// MockDeviceInformationProvider.swift +// PyeonHaeng-iOSTests +// +// Created by 홍승현 on 3/10/24. +// + +import Foundation + +struct MockDeviceInformationProvider: DeviceInformationProvider { + var deviceModel: String + var deviceOS: String + var appVersion: String +} diff --git a/PyeonHaeng-iOSTests/PyeonHaeng_iOSTests.swift b/PyeonHaeng-iOSTests/ProductConfigurationTests.swift similarity index 98% rename from PyeonHaeng-iOSTests/PyeonHaeng_iOSTests.swift rename to PyeonHaeng-iOSTests/ProductConfigurationTests.swift index 49f292e..1e225a4 100644 --- a/PyeonHaeng-iOSTests/PyeonHaeng_iOSTests.swift +++ b/PyeonHaeng-iOSTests/ProductConfigurationTests.swift @@ -1,5 +1,5 @@ // -// PyeonHaeng_iOSTests.swift +// ProductConfigurationTests.swift // PyeonHaeng-iOSTests // // Created by 홍승현 on 1/24/24.