From cb7696b4711ff3d554811202d380a83ae97463a3 Mon Sep 17 00:00:00 2001 From: Rodrigo Porto Date: Fri, 28 Feb 2025 22:06:40 -0300 Subject: [PATCH 01/14] Remove Feed UI composition --- EssentialApp/EssentialApp/SceneDelegate.swift | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/EssentialApp/EssentialApp/SceneDelegate.swift b/EssentialApp/EssentialApp/SceneDelegate.swift index e52f7d0..4b11aef 100644 --- a/EssentialApp/EssentialApp/SceneDelegate.swift +++ b/EssentialApp/EssentialApp/SceneDelegate.swift @@ -4,9 +4,6 @@ // import UIKit -import CoreData -import EssentialFeed -import EssentialFeediOS class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? @@ -14,31 +11,5 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let _ = (scene as? UIWindowScene) else { return } - let remoteURL = URL(string: "https://ile-api.essentialdeveloper.com/essential-feed/v1/feed")! - - let remoteClient = URLSessionHTTPClient(session: URLSession(configuration: .ephemeral)) - let remoteFeedLoader = RemoteFeedLoader(url: remoteURL, client: remoteClient) - let remoteImageLoader = RemoteFeedImageDataLoader(client: remoteClient) - - let localStoreURL = NSPersistentContainer - .defaultDirectoryURL() - .appendingPathComponent("feed-store.sqlite") - - let localStore = try! CoreDataFeedStore(storeURL: localStoreURL) - let localFeedLoader = LocalFeedLoader(store: localStore, currentDate: Date.init) - let localImageLoader = LocalFeedImageDataLoader(store: localStore) - - window?.rootViewController = FeedUIComposer.feedComposedWith( - feedLoader: FeedLoaderWithFallbackComposite( - primary: FeedLoaderCacheDecorator( - decoratee: remoteFeedLoader, - cache: localFeedLoader), - fallback: localFeedLoader), - imageLoader: FeedImageDataLoaderWithFallbackComposite( - primary: localImageLoader, - fallback: FeedImageDataLoaderCacheDecorator( - decoratee: remoteImageLoader, - cache: localImageLoader))) } } - From 4f62d02f307879e97f958aafed86b631eae368aa Mon Sep 17 00:00:00 2001 From: Rodrigo Porto Date: Fri, 28 Feb 2025 22:27:36 -0300 Subject: [PATCH 02/14] Add UI Test target for running high-level Acceptance Tests --- EssentialApp/CI_iOS.xctestplan | 2 +- .../EssentialApp.xcodeproj/project.pbxproj | 112 ++++++++++++++++++ .../contents.xcworkspacedata | 3 + .../EssentialAppUIAcceptanceTests.xcscheme | 60 ++++++++++ .../EssentialAppTests/EssentialApp.xctestplan | 2 +- .../EssentialAppUIAcceptanceTests.swift | 10 ++ .../EssentialAppUIAcceptanceTests.xctestplan | 33 ++++++ 7 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 EssentialApp/EssentialApp.xcworkspace/xcshareddata/xcschemes/EssentialAppUIAcceptanceTests.xcscheme create mode 100644 EssentialApp/EssentialAppUIAcceptanceTests/EssentialAppUIAcceptanceTests.swift create mode 100644 EssentialApp/EssentialAppUIAcceptanceTests/EssentialAppUIAcceptanceTests.xctestplan diff --git a/EssentialApp/CI_iOS.xctestplan b/EssentialApp/CI_iOS.xctestplan index a8e2931..306fb93 100644 --- a/EssentialApp/CI_iOS.xctestplan +++ b/EssentialApp/CI_iOS.xctestplan @@ -2,7 +2,7 @@ "configurations" : [ { "id" : "91820604-8FC3-4344-8FDE-8E997DE399E6", - "name" : "Configuration 1", + "name" : "Test Scheme Action", "options" : { } diff --git a/EssentialApp/EssentialApp.xcodeproj/project.pbxproj b/EssentialApp/EssentialApp.xcodeproj/project.pbxproj index 6b093cb..917bd00 100644 --- a/EssentialApp/EssentialApp.xcodeproj/project.pbxproj +++ b/EssentialApp/EssentialApp.xcodeproj/project.pbxproj @@ -15,6 +15,13 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 5BBDA0892D72983C00D68DF0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5BDE3C692D6D12B8005D520D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5BDE3C702D6D12B8005D520D; + remoteInfo = EssentialApp; + }; 5BDE3C882D6D12BA005D520D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 5BDE3C692D6D12B8005D520D /* Project object */; @@ -41,6 +48,7 @@ /* Begin PBXFileReference section */ 5BBD9FDF2D6EA59800D68DF0 /* CI_iOS.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = CI_iOS.xctestplan; sourceTree = ""; }; + 5BBDA0832D72983C00D68DF0 /* EssentialAppUIAcceptanceTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EssentialAppUIAcceptanceTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5BDE3C712D6D12B8005D520D /* EssentialApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EssentialApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5BDE3C872D6D12BA005D520D /* EssentialAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EssentialAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5BDE3CDF2D6D186D005D520D /* EssentialFeed.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = EssentialFeed.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -59,6 +67,11 @@ /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ + 5BBDA0842D72983C00D68DF0 /* EssentialAppUIAcceptanceTests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = EssentialAppUIAcceptanceTests; + sourceTree = ""; + }; 5BDE3C732D6D12B8005D520D /* EssentialApp */ = { isa = PBXFileSystemSynchronizedRootGroup; exceptions = ( @@ -75,6 +88,13 @@ /* End PBXFileSystemSynchronizedRootGroup section */ /* Begin PBXFrameworksBuildPhase section */ + 5BBDA0802D72983C00D68DF0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5BDE3C6E2D6D12B8005D520D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -101,6 +121,7 @@ 5BDE3D0C2D6D6092005D520D /* EssentialApp.xctestplan */, 5BDE3C732D6D12B8005D520D /* EssentialApp */, 5BDE3C8A2D6D12BA005D520D /* EssentialAppTests */, + 5BBDA0842D72983C00D68DF0 /* EssentialAppUIAcceptanceTests */, 5BDE3CDE2D6D186D005D520D /* Frameworks */, 5BDE3C722D6D12B8005D520D /* Products */, ); @@ -111,6 +132,7 @@ children = ( 5BDE3C712D6D12B8005D520D /* EssentialApp.app */, 5BDE3C872D6D12BA005D520D /* EssentialAppTests.xctest */, + 5BBDA0832D72983C00D68DF0 /* EssentialAppUIAcceptanceTests.xctest */, ); name = Products; sourceTree = ""; @@ -127,6 +149,29 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 5BBDA0822D72983C00D68DF0 /* EssentialAppUIAcceptanceTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5BBDA08B2D72983C00D68DF0 /* Build configuration list for PBXNativeTarget "EssentialAppUIAcceptanceTests" */; + buildPhases = ( + 5BBDA07F2D72983C00D68DF0 /* Sources */, + 5BBDA0802D72983C00D68DF0 /* Frameworks */, + 5BBDA0812D72983C00D68DF0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5BBDA08A2D72983C00D68DF0 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + 5BBDA0842D72983C00D68DF0 /* EssentialAppUIAcceptanceTests */, + ); + name = EssentialAppUIAcceptanceTests; + packageProductDependencies = ( + ); + productName = EssentialAppUIAcceptanceTests; + productReference = 5BBDA0832D72983C00D68DF0 /* EssentialAppUIAcceptanceTests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; 5BDE3C702D6D12B8005D520D /* EssentialApp */ = { isa = PBXNativeTarget; buildConfigurationList = 5BDE3C9A2D6D12BA005D520D /* Build configuration list for PBXNativeTarget "EssentialApp" */; @@ -183,6 +228,10 @@ LastSwiftUpdateCheck = 1620; LastUpgradeCheck = 1620; TargetAttributes = { + 5BBDA0822D72983C00D68DF0 = { + CreatedOnToolsVersion = 16.2; + TestTargetID = 5BDE3C702D6D12B8005D520D; + }; 5BDE3C702D6D12B8005D520D = { CreatedOnToolsVersion = 16.2; }; @@ -209,11 +258,19 @@ targets = ( 5BDE3C702D6D12B8005D520D /* EssentialApp */, 5BDE3C862D6D12BA005D520D /* EssentialAppTests */, + 5BBDA0822D72983C00D68DF0 /* EssentialAppUIAcceptanceTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 5BBDA0812D72983C00D68DF0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5BDE3C6F2D6D12B8005D520D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -232,6 +289,13 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 5BBDA07F2D72983C00D68DF0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5BDE3C6D2D6D12B8005D520D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -249,6 +313,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 5BBDA08A2D72983C00D68DF0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5BDE3C702D6D12B8005D520D /* EssentialApp */; + targetProxy = 5BBDA0892D72983C00D68DF0 /* PBXContainerItemProxy */; + }; 5BDE3C892D6D12BA005D520D /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 5BDE3C702D6D12B8005D520D /* EssentialApp */; @@ -257,6 +326,40 @@ /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ + 5BBDA08C2D72983C00D68DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 4VK5P5723H; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = portocode.EssentialAppUIAcceptanceTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = EssentialApp; + }; + name = Debug; + }; + 5BBDA08D2D72983C00D68DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 4VK5P5723H; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = portocode.EssentialAppUIAcceptanceTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = EssentialApp; + }; + name = Release; + }; 5BDE3C9B2D6D12BA005D520D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -476,6 +579,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 5BBDA08B2D72983C00D68DF0 /* Build configuration list for PBXNativeTarget "EssentialAppUIAcceptanceTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5BBDA08C2D72983C00D68DF0 /* Debug */, + 5BBDA08D2D72983C00D68DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5BDE3C6C2D6D12B8005D520D /* Build configuration list for PBXProject "EssentialApp" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/EssentialApp/EssentialApp.xcworkspace/contents.xcworkspacedata b/EssentialApp/EssentialApp.xcworkspace/contents.xcworkspacedata index 75c7596..3a858a6 100644 --- a/EssentialApp/EssentialApp.xcworkspace/contents.xcworkspacedata +++ b/EssentialApp/EssentialApp.xcworkspace/contents.xcworkspacedata @@ -7,4 +7,7 @@ + + diff --git a/EssentialApp/EssentialApp.xcworkspace/xcshareddata/xcschemes/EssentialAppUIAcceptanceTests.xcscheme b/EssentialApp/EssentialApp.xcworkspace/xcshareddata/xcschemes/EssentialAppUIAcceptanceTests.xcscheme new file mode 100644 index 0000000..5a4bb6a --- /dev/null +++ b/EssentialApp/EssentialApp.xcworkspace/xcshareddata/xcschemes/EssentialAppUIAcceptanceTests.xcscheme @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/EssentialApp/EssentialAppTests/EssentialApp.xctestplan b/EssentialApp/EssentialAppTests/EssentialApp.xctestplan index b1d7ac6..511dade 100644 --- a/EssentialApp/EssentialAppTests/EssentialApp.xctestplan +++ b/EssentialApp/EssentialAppTests/EssentialApp.xctestplan @@ -2,7 +2,7 @@ "configurations" : [ { "id" : "1C72DE09-1522-41C2-A2CD-1727C894E236", - "name" : "Configuration 1", + "name" : "Test Scheme Action", "options" : { } diff --git a/EssentialApp/EssentialAppUIAcceptanceTests/EssentialAppUIAcceptanceTests.swift b/EssentialApp/EssentialAppUIAcceptanceTests/EssentialAppUIAcceptanceTests.swift new file mode 100644 index 0000000..0c65cf1 --- /dev/null +++ b/EssentialApp/EssentialAppUIAcceptanceTests/EssentialAppUIAcceptanceTests.swift @@ -0,0 +1,10 @@ +// +// Created by Rodrigo Porto. +// Copyright © 2025 PortoCode. All Rights Reserved. +// + +import XCTest + +final class EssentialAppUIAcceptanceTests: XCTestCase { + +} diff --git a/EssentialApp/EssentialAppUIAcceptanceTests/EssentialAppUIAcceptanceTests.xctestplan b/EssentialApp/EssentialAppUIAcceptanceTests/EssentialAppUIAcceptanceTests.xctestplan new file mode 100644 index 0000000..794f4e9 --- /dev/null +++ b/EssentialApp/EssentialAppUIAcceptanceTests/EssentialAppUIAcceptanceTests.xctestplan @@ -0,0 +1,33 @@ +{ + "configurations" : [ + { + "id" : "BEB595B4-9364-4FB0-9A36-B6EAFD0D066A", + "name" : "Test Scheme Action", + "options" : { + + } + } + ], + "defaultOptions" : { + "codeCoverage" : { + "targets" : [ + { + "containerPath" : "container:EssentialApp.xcodeproj", + "identifier" : "5BDE3C702D6D12B8005D520D", + "name" : "EssentialApp" + } + ] + }, + "testExecutionOrdering" : "random" + }, + "testTargets" : [ + { + "target" : { + "containerPath" : "container:EssentialApp.xcodeproj", + "identifier" : "5BBDA0822D72983C00D68DF0", + "name" : "EssentialAppUIAcceptanceTests" + } + } + ], + "version" : 1 +} From 9b61c081081d48f9609a4e5747f576d807c8b6be Mon Sep 17 00:00:00 2001 From: Rodrigo Porto Date: Sat, 1 Mar 2025 04:57:45 -0300 Subject: [PATCH 03/14] Displays remote feed on launch when customer has connectivity --- .../xcshareddata/xcschemes/EssentialApp.xcscheme | 11 +++++++++++ EssentialApp/EssentialApp/SceneDelegate.swift | 11 +++++++++++ .../EssentialAppUIAcceptanceTests.swift | 9 +++++++++ .../EssentialFeediOS/Feed UI/Views/Feed.storyboard | 3 +++ 4 files changed, 34 insertions(+) diff --git a/EssentialApp/EssentialApp.xcworkspace/xcshareddata/xcschemes/EssentialApp.xcscheme b/EssentialApp/EssentialApp.xcworkspace/xcshareddata/xcschemes/EssentialApp.xcscheme index a5c0df5..71a9fb6 100644 --- a/EssentialApp/EssentialApp.xcworkspace/xcshareddata/xcschemes/EssentialApp.xcscheme +++ b/EssentialApp/EssentialApp.xcworkspace/xcshareddata/xcschemes/EssentialApp.xcscheme @@ -46,6 +46,17 @@ ReferencedContainer = "container:EssentialApp.xcodeproj"> + + + + + + +