From 9d75d585508939928328a9208f26b6703c7e3f3c Mon Sep 17 00:00:00 2001 From: Decheng Date: Mon, 12 Oct 2020 17:51:24 +1100 Subject: [PATCH 1/3] Add error throwing and handling in sync command operations --- .../Sync/TestFlightProgramDifference.swift | 17 ++++++++++++++++- .../TestFlight/Sync/TestFlightPushCommand.swift | 2 +- .../TestFlightConfigurationProcessor.swift | 7 +++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Sources/AppStoreConnectCLI/Commands/TestFlight/Sync/TestFlightProgramDifference.swift b/Sources/AppStoreConnectCLI/Commands/TestFlight/Sync/TestFlightProgramDifference.swift index e63e2682..3a96883f 100644 --- a/Sources/AppStoreConnectCLI/Commands/TestFlight/Sync/TestFlightProgramDifference.swift +++ b/Sources/AppStoreConnectCLI/Commands/TestFlight/Sync/TestFlightProgramDifference.swift @@ -52,9 +52,20 @@ struct TestFlightProgramDifference { } } + enum Error: LocalizedError, Equatable { + case duplicateTesters(email: String) + + var errorDescription: String? { + switch self { + case .duplicateTesters(let email): + return "There are two beta testers with the same email '\(email)' exists in your account, please clean that up before continue." + } + } + } + let changes: [Change] - init(local: TestFlightProgram, remote: TestFlightProgram) { + init(local: TestFlightProgram, remote: TestFlightProgram) throws { var changes: [Change] = [] // Groups @@ -80,6 +91,10 @@ struct TestFlightProgramDifference { let remoteApps = remoteTester.apps let remoteBetaGroups = remoteTester.betaGroups + if remote.testers.filter({ $0.email == remoteTester.email}).count > 1 { + throw Error.duplicateTesters(email: remoteTester.email ?? "") + } + if let localTester = local.testers.first(where: { $0.email == remoteTester.email }) { let appsToAdd = localTester.apps.filter { app in let appIds = remoteApps.map(\.id) + remoteBetaGroups.compactMap(\.app?.id) diff --git a/Sources/AppStoreConnectCLI/Commands/TestFlight/Sync/TestFlightPushCommand.swift b/Sources/AppStoreConnectCLI/Commands/TestFlight/Sync/TestFlightPushCommand.swift index d336c110..50ecea9e 100644 --- a/Sources/AppStoreConnectCLI/Commands/TestFlight/Sync/TestFlightPushCommand.swift +++ b/Sources/AppStoreConnectCLI/Commands/TestFlight/Sync/TestFlightPushCommand.swift @@ -26,7 +26,7 @@ struct TestFlightPushCommand: CommonParsableCommand { let local = try FileSystem.readTestFlightConfiguration(from: inputPath) let remote = try service.getTestFlightProgram() - let difference = TestFlightProgramDifference(local: local, remote: remote) + let difference = try TestFlightProgramDifference(local: local, remote: remote) difference.changes.forEach { print($0.description) } diff --git a/Sources/FileSystem/Configuration/TestFlightConfigurationProcessor.swift b/Sources/FileSystem/Configuration/TestFlightConfigurationProcessor.swift index d52d39f4..fbc7f1c3 100644 --- a/Sources/FileSystem/Configuration/TestFlightConfigurationProcessor.swift +++ b/Sources/FileSystem/Configuration/TestFlightConfigurationProcessor.swift @@ -60,18 +60,25 @@ struct TestFlightConfigurationProcessor { enum Error: LocalizedError { case testerNotInTestersList(email: String, betaGroup: BetaGroup, app: App) + case noValidApp var errorDescription: String? { switch self { case .testerNotInTestersList(let email, let betaGroup, let app): return "Tester with email: \(email) in beta group named: \(betaGroup.groupName) " + "for app: \(app.bundleId) is not included in the \(betaTestersCSVName) file" + + case .noValidApp: + return "There's no valid app folder found in your local configuration file path, please run 'sync pull' first" } } } func readConfiguration() throws -> TestFlightConfiguration { let folder = try Folder(path: path) + + guard folder.subfolders.count() > 0 else { throw Error.noValidApp } + var configuration = TestFlightConfiguration() let decodeBetaTesters: (Data) throws -> [BetaTester] = { data in From 38816b4ec870dd292ecbce799c2ec678129b1a18 Mon Sep 17 00:00:00 2001 From: Decheng Date: Mon, 12 Oct 2020 17:52:28 +1100 Subject: [PATCH 2/3] Add tests for TestFlightProgramDifference duplicateTester error throwing --- .../TestFlightProgramDifferenceTests.swift | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Tests/appstoreconnect-cliTests/Sync/TestFlightProgramDifferenceTests.swift diff --git a/Tests/appstoreconnect-cliTests/Sync/TestFlightProgramDifferenceTests.swift b/Tests/appstoreconnect-cliTests/Sync/TestFlightProgramDifferenceTests.swift new file mode 100644 index 00000000..71c4244e --- /dev/null +++ b/Tests/appstoreconnect-cliTests/Sync/TestFlightProgramDifferenceTests.swift @@ -0,0 +1,52 @@ +// Copyright 2020 Itty Bitty Apps Pty Ltd + +@testable import AppStoreConnectCLI + +import FileSystem +import Model +import Foundation +import XCTest + +final class TestFlightProgramDifferenceTests: XCTestCase { + + func testErrorWillBeThrow_whenDuplicateTesters() throws { + let local = TestFlightProgram( + apps: [], + testers: [BetaTester(email: "foo@gmail.com", firstName: "Foo", lastName: "Bar", inviteType: "EMAIL", betaGroups: [], apps: [])], + groups: [] + ) + + let remote = TestFlightProgram( + apps: [], + testers: [BetaTester(email: "foo@gmail.com", firstName: "Foo", lastName: "Bar", inviteType: "EMAIL", betaGroups: [], apps: []), + BetaTester(email: "foo@gmail.com", firstName: "Foo", lastName: "Bar", inviteType: "EMAIL", betaGroups: [], apps: [])], + groups: [] + ) + + XCTAssertThrowsError(try TestFlightProgramDifference(local: local, remote: remote)) { error in + XCTAssertEqual( + error as? TestFlightProgramDifference.Error, + TestFlightProgramDifference.Error.duplicateTesters(email: "foo@gmail.com") + ) + } + } + + func testErrorNotThrow_withoutDuplicateTesters() throws { + let local = TestFlightProgram( + apps: [], + testers: [BetaTester(email: "foo@gmail.com", firstName: "Foo", lastName: "Bar", inviteType: "EMAIL", betaGroups: [], apps: [])], + groups: [] + ) + + let remote = TestFlightProgram( + apps: [], + testers: [BetaTester(email: "foo@gmail.com", firstName: "Foo", lastName: "Bar", inviteType: "EMAIL", betaGroups: [], apps: [])], + groups: [] + ) + + let result = try TestFlightProgramDifference(local: local, remote: remote) + + XCTAssertTrue(result.changes.isEmpty) + } + +} From b7d4d7a9394b949082ab463fc3e6b1decb2abb2c Mon Sep 17 00:00:00 2001 From: Decheng Date: Tue, 13 Oct 2020 10:18:08 +1100 Subject: [PATCH 3/3] fix lint issue in TestFlightProgramDifferenceTests --- .../Sync/TestFlightProgramDifferenceTests.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Tests/appstoreconnect-cliTests/Sync/TestFlightProgramDifferenceTests.swift b/Tests/appstoreconnect-cliTests/Sync/TestFlightProgramDifferenceTests.swift index 71c4244e..bd0c70aa 100644 --- a/Tests/appstoreconnect-cliTests/Sync/TestFlightProgramDifferenceTests.swift +++ b/Tests/appstoreconnect-cliTests/Sync/TestFlightProgramDifferenceTests.swift @@ -18,8 +18,10 @@ final class TestFlightProgramDifferenceTests: XCTestCase { let remote = TestFlightProgram( apps: [], - testers: [BetaTester(email: "foo@gmail.com", firstName: "Foo", lastName: "Bar", inviteType: "EMAIL", betaGroups: [], apps: []), - BetaTester(email: "foo@gmail.com", firstName: "Foo", lastName: "Bar", inviteType: "EMAIL", betaGroups: [], apps: [])], + testers: [ + BetaTester(email: "foo@gmail.com", firstName: "Foo", lastName: "Bar", inviteType: "EMAIL", betaGroups: [], apps: []), + BetaTester(email: "foo@gmail.com", firstName: "Foo", lastName: "Bar", inviteType: "EMAIL", betaGroups: [], apps: []), + ], groups: [] )