Skip to content

Commit 859b6b6

Browse files
committed
Transition Current.allowTwitterPosts() to environment.allowSocialPosts()
1 parent f1513f9 commit 859b6b6

File tree

11 files changed

+125
-103
lines changed

11 files changed

+125
-103
lines changed

Sources/App/Core/AppEnvironment.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import FoundationNetworking
2323

2424

2525
struct AppEnvironment: Sendable {
26-
var allowTwitterPosts: @Sendable () -> Bool
2726
var apiSigningKey: @Sendable () -> String?
2827
var appVersion: @Sendable () -> String?
2928
var awsAccessKeyId: @Sendable () -> String?
@@ -109,11 +108,6 @@ extension AppEnvironment {
109108
nonisolated(unsafe) static var logger: Logger!
110109

111110
static let live = AppEnvironment(
112-
allowTwitterPosts: {
113-
Environment.get("ALLOW_TWITTER_POSTS")
114-
.flatMap(\.asBool)
115-
?? Constants.defaultAllowTwitterPosts
116-
},
117111
apiSigningKey: { Environment.get("API_SIGNING_KEY") },
118112
appVersion: { App.appVersion },
119113
awsAccessKeyId: { Environment.get("AWS_ACCESS_KEY_ID") },

Sources/App/Core/Constants.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import Vapor
1717

1818
enum Constants {
1919
static let defaultAllowBuildTriggering = true
20-
static let defaultAllowTwitterPosts = true
20+
static let defaultAllowSocialPosts = true
2121
static let defaultGitlabPipelineLimit = 200
2222
static let defaultHideStagingBanner = false
2323

Sources/App/Core/Dependencies/EnvironmentClient.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct EnvironmentClient {
2222
// See https://swiftpackageindex.com/pointfreeco/swift-dependencies/main/documentation/dependenciesmacros/dependencyclient()#Restrictions
2323
// regarding the use of XCTFail here.
2424
var allowBuildTriggers: @Sendable () -> Bool = { XCTFail(#function); return true }
25+
var allowSocialPosts: @Sendable () -> Bool = { XCTFail(#function); return true }
2526
// We're not defaulting current to XCTFail, because its use is too pervasive and would require the vast
2627
// majority of tests to be wrapped with `withDependencies`.
2728
// We can do so at a later time once more tests are transitioned over for other dependencies. This is
@@ -37,6 +38,11 @@ extension EnvironmentClient: DependencyKey {
3738
allowBuildTriggers: {
3839
Environment.get("ALLOW_BUILD_TRIGGERS").flatMap(\.asBool) ?? Constants.defaultAllowBuildTriggering
3940
},
41+
allowSocialPosts: {
42+
Environment.get("ALLOW_SOCIAL_POSTS")
43+
.flatMap(\.asBool)
44+
?? Constants.defaultAllowSocialPosts
45+
},
4046
current: { (try? Environment.detect()) ?? .development }
4147
)
4248
}

Sources/App/Core/Social.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
import Dependencies
1516
import SemanticVersion
1617
import Vapor
1718

@@ -96,9 +97,8 @@ enum Social {
9697
static func postToFirehose(client: Client,
9798
package: Joined<Package, Repository>,
9899
version: Version) async throws {
99-
guard Current.allowTwitterPosts() else {
100-
throw Error.postingDisabled
101-
}
100+
@Dependency(\.environment) var environment
101+
guard environment.allowSocialPosts() else { throw Error.postingDisabled }
102102
guard let message = firehoseMessage(package: package,
103103
version: version,
104104
maxLength: postMaxLength) else {

Tests/AppTests/AnalyzeErrorTests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ final class AnalyzeErrorTests: AppTestCase {
107107
func test_analyze_refreshCheckout_failed() async throws {
108108
try await withDependencies {
109109
$0.date.now = .t0
110+
$0.environment.allowSocialPosts = { true }
110111
} operation: {
111112
Current.shell.run = { @Sendable cmd, path in
112113
switch cmd {
@@ -139,6 +140,7 @@ final class AnalyzeErrorTests: AppTestCase {
139140
func test_analyze_updateRepository_invalidPackageCachePath() async throws {
140141
try await withDependencies {
141142
$0.date.now = .t0
143+
$0.environment.allowSocialPosts = { true }
142144
} operation: {
143145
// setup
144146
let pkg = try await Package.find(badPackageID, on: app.db).unwrap()
@@ -166,6 +168,7 @@ final class AnalyzeErrorTests: AppTestCase {
166168
func test_analyze_getPackageInfo_gitCheckout_error() async throws {
167169
try await withDependencies {
168170
$0.date.now = .t0
171+
$0.environment.allowSocialPosts = { true }
169172
} operation: {
170173
// setup
171174
Current.shell.run = { @Sendable cmd, path in
@@ -196,6 +199,7 @@ final class AnalyzeErrorTests: AppTestCase {
196199
func test_analyze_dumpPackage_missing_manifest() async throws {
197200
try await withDependencies {
198201
$0.date.now = .t0
202+
$0.environment.allowSocialPosts = { true }
199203
} operation: {
200204
// setup
201205
Current.fileManager.fileExists = { @Sendable path in

Tests/AppTests/AnalyzerTests.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class AnalyzerTests: AppTestCase {
3535
// expected shell commands for the happy path.)
3636
try await withDependencies {
3737
$0.date.now = .now
38+
$0.environment.allowSocialPosts = { true }
3839
} operation: {
3940
// setup
4041
let urls = ["https://github.com/foo/1", "https://github.com/foo/2"]
@@ -216,6 +217,7 @@ class AnalyzerTests: AppTestCase {
216217
// changing as well as a tag being moved to a different commit.
217218
try await withDependencies {
218219
$0.date.now = .now
220+
$0.environment.allowSocialPosts = { true }
219221
} operation: {
220222
// setup
221223
let pkgId = UUID()
@@ -354,6 +356,7 @@ class AnalyzerTests: AppTestCase {
354356
// Ensure packages record success/error status
355357
try await withDependencies {
356358
$0.date.now = .now
359+
$0.environment.allowSocialPosts = { true }
357360
} operation: {
358361
// setup
359362
let urls = ["https://github.com/foo/1", "https://github.com/foo/2"]
@@ -404,6 +407,7 @@ class AnalyzerTests: AppTestCase {
404407
// Test to ensure exceptions don't interrupt processing
405408
try await withDependencies {
406409
$0.date.now = .now
410+
$0.environment.allowSocialPosts = { true }
407411
} operation: {
408412
// setup
409413
let urls = ["https://github.com/foo/1", "https://github.com/foo/2"]
@@ -881,6 +885,7 @@ class AnalyzerTests: AppTestCase {
881885
// https://github.com/SwiftPackageIndex/SwiftPackageIndex-Server/issues/29
882886
try await withDependencies {
883887
$0.date.now = .now
888+
$0.environment.allowSocialPosts = { true }
884889
} operation: {
885890
// setup
886891
Current.git.commitCount = { @Sendable _ in 12 }

Tests/AppTests/MastodonTests.swift

Lines changed: 86 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -22,96 +22,100 @@ import XCTVapor
2222
final class MastodonTests: AppTestCase {
2323

2424
func test_endToEnd() async throws {
25-
// setup
26-
let message = QueueIsolated<String?>(nil)
27-
Current.mastodonPost = { _, msg in
28-
if message.value == nil {
29-
message.setValue(msg)
30-
} else {
31-
XCTFail("message must only be set once")
25+
try await withDependencies {
26+
$0.environment.allowSocialPosts = { true }
27+
} operation: {
28+
// setup
29+
let message = QueueIsolated<String?>(nil)
30+
Current.mastodonPost = { _, msg in
31+
if message.value == nil {
32+
message.setValue(msg)
33+
} else {
34+
XCTFail("message must only be set once")
35+
}
3236
}
33-
}
34-
35-
let url = "https://github.com/foo/bar"
36-
Current.fetchMetadata = { _, owner, repository in .mock(owner: owner, repository: repository) }
37-
38-
Current.git.commitCount = { @Sendable _ in 12 }
39-
Current.git.firstCommitDate = { @Sendable _ in .t0 }
40-
Current.git.lastCommitDate = { @Sendable _ in .t2 }
41-
Current.git.getTags = { @Sendable _ in [Reference.tag(1, 2, 3)] }
42-
Current.git.hasBranch = { @Sendable _, _ in true }
43-
Current.git.revisionInfo = { @Sendable _, _ in .init(commit: "sha", date: .t0) }
44-
Current.git.shortlog = { @Sendable _ in
37+
38+
let url = "https://github.com/foo/bar"
39+
Current.fetchMetadata = { _, owner, repository in .mock(owner: owner, repository: repository) }
40+
41+
Current.git.commitCount = { @Sendable _ in 12 }
42+
Current.git.firstCommitDate = { @Sendable _ in .t0 }
43+
Current.git.lastCommitDate = { @Sendable _ in .t2 }
44+
Current.git.getTags = { @Sendable _ in [Reference.tag(1, 2, 3)] }
45+
Current.git.hasBranch = { @Sendable _, _ in true }
46+
Current.git.revisionInfo = { @Sendable _, _ in .init(commit: "sha", date: .t0) }
47+
Current.git.shortlog = { @Sendable _ in
4548
"""
4649
10\tPerson 1
4750
2\tPerson 2
4851
"""
49-
}
50-
51-
Current.shell.run = { @Sendable cmd, path in
52-
if cmd.description.hasSuffix("swift package dump-package") {
53-
return #"{ "name": "Mock", "products": [], "targets": [] }"#
5452
}
55-
return ""
56-
}
57-
58-
try await withDependencies {
59-
$0.date.now = .now
60-
$0.packageListRepository.fetchPackageList = { @Sendable _ in [url.url] }
61-
$0.packageListRepository.fetchPackageDenyList = { @Sendable _ in [] }
62-
$0.packageListRepository.fetchCustomCollections = { @Sendable _ in [] }
63-
$0.packageListRepository.fetchCustomCollection = { @Sendable _, _ in [] }
64-
} operation: {
65-
// run first two processing steps
66-
try await reconcile(client: app.client, database: app.db)
67-
try await ingest(client: app.client, database: app.db, mode: .limit(10))
68-
69-
// MUT - analyze, triggering the post
70-
try await Analyze.analyze(client: app.client,
71-
database: app.db,
72-
mode: .limit(10))
73-
74-
do {
75-
let msg = try XCTUnwrap(message.value)
76-
XCTAssertTrue(msg.hasPrefix("📦 foo just added a new package, Mock"), "was \(msg)")
53+
54+
Current.shell.run = { @Sendable cmd, path in
55+
if cmd.description.hasSuffix("swift package dump-package") {
56+
return #"{ "name": "Mock", "products": [], "targets": [] }"#
57+
}
58+
return ""
7759
}
78-
79-
// run stages again to simulate the cycle...
80-
message.setValue(nil)
81-
try await reconcile(client: app.client, database: app.db)
82-
}
83-
84-
try await withDependencies {
85-
$0.date.now = .now.addingTimeInterval(Constants.reIngestionDeadtime)
86-
} operation: {
87-
try await ingest(client: app.client, database: app.db, mode: .limit(10))
88-
89-
// MUT - analyze, triggering posts if any
90-
try await Analyze.analyze(client: app.client,
91-
database: app.db,
92-
mode: .limit(10))
93-
}
94-
95-
// validate - there are no new posts to send
96-
XCTAssertNil(message.value)
97-
98-
// Now simulate receiving a package update: version 2.0.0
99-
Current.git.getTags = { @Sendable _ in [.tag(2, 0, 0)] }
100-
101-
try await withDependencies {
102-
// fast forward our clock by the deadtime interval again (*2) and re-ingest
103-
$0.date.now = .now.addingTimeInterval(Constants.reIngestionDeadtime * 2)
104-
} operation: {
105-
try await ingest(client: app.client, database: app.db, mode: .limit(10))
106-
// MUT - analyze again
107-
try await Analyze.analyze(client: app.client,
108-
database: app.db,
109-
mode: .limit(10))
60+
61+
try await withDependencies {
62+
$0.date.now = .now
63+
$0.packageListRepository.fetchPackageList = { @Sendable _ in [url.url] }
64+
$0.packageListRepository.fetchPackageDenyList = { @Sendable _ in [] }
65+
$0.packageListRepository.fetchCustomCollections = { @Sendable _ in [] }
66+
$0.packageListRepository.fetchCustomCollection = { @Sendable _, _ in [] }
67+
} operation: {
68+
// run first two processing steps
69+
try await reconcile(client: app.client, database: app.db)
70+
try await ingest(client: app.client, database: app.db, mode: .limit(10))
71+
72+
// MUT - analyze, triggering the post
73+
try await Analyze.analyze(client: app.client,
74+
database: app.db,
75+
mode: .limit(10))
76+
77+
do {
78+
let msg = try XCTUnwrap(message.value)
79+
XCTAssertTrue(msg.hasPrefix("📦 foo just added a new package, Mock"), "was \(msg)")
80+
}
81+
82+
// run stages again to simulate the cycle...
83+
message.setValue(nil)
84+
try await reconcile(client: app.client, database: app.db)
85+
}
86+
87+
try await withDependencies {
88+
$0.date.now = .now.addingTimeInterval(Constants.reIngestionDeadtime)
89+
} operation: {
90+
try await ingest(client: app.client, database: app.db, mode: .limit(10))
91+
92+
// MUT - analyze, triggering posts if any
93+
try await Analyze.analyze(client: app.client,
94+
database: app.db,
95+
mode: .limit(10))
96+
}
97+
98+
// validate - there are no new posts to send
99+
XCTAssertNil(message.value)
100+
101+
// Now simulate receiving a package update: version 2.0.0
102+
Current.git.getTags = { @Sendable _ in [.tag(2, 0, 0)] }
103+
104+
try await withDependencies {
105+
// fast forward our clock by the deadtime interval again (*2) and re-ingest
106+
$0.date.now = .now.addingTimeInterval(Constants.reIngestionDeadtime * 2)
107+
} operation: {
108+
try await ingest(client: app.client, database: app.db, mode: .limit(10))
109+
// MUT - analyze again
110+
try await Analyze.analyze(client: app.client,
111+
database: app.db,
112+
mode: .limit(10))
113+
}
114+
115+
// validate
116+
let msg = try XCTUnwrap(message.value)
117+
XCTAssertTrue(msg.hasPrefix("⬆️ foo just released Mock v2.0.0"), "was: \(msg)")
110118
}
111-
112-
// validate
113-
let msg = try XCTUnwrap(message.value)
114-
XCTAssertTrue(msg.hasPrefix("⬆️ foo just released Mock v2.0.0"), "was: \(msg)")
115119
}
116120

117121
}

Tests/AppTests/Mocks/AppEnvironment+mock.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import Vapor
2222
extension AppEnvironment {
2323
static func mock(eventLoop: EventLoop) -> Self {
2424
.init(
25-
allowTwitterPosts: { true },
2625
apiSigningKey: { nil },
2726
appVersion: { "test" },
2827
awsAccessKeyId: { nil },

Tests/AppTests/ReAnalyzeVersionsTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ReAnalyzeVersionsTests: AppTestCase {
2828
// Basic end-to-end test
2929
try await withDependencies {
3030
$0.date.now = .t0
31+
$0.environment.allowSocialPosts = { true }
3132
} operation: {
3233
// setup
3334
// - package dump does not include toolsVersion, targets to simulate an "old version"

Tests/AppTests/SocialTests.swift

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
@testable import App
1616

17+
import Dependencies
1718
import InlineSnapshotTesting
1819
import NIOConcurrencyHelpers
1920
import XCTVapor
@@ -194,10 +195,14 @@ class SocialTests: AppTestCase {
194195
let posted: NIOLockedValueBox<Int> = .init(0)
195196
Current.mastodonPost = { _, _ in posted.withLockedValue { $0 += 1 } }
196197

197-
// MUT
198-
try await Social.postToFirehose(client: app.client,
199-
package: jpr,
200-
versions: versions)
198+
try await withDependencies {
199+
$0.environment.allowSocialPosts = { true }
200+
} operation: {
201+
// MUT
202+
try await Social.postToFirehose(client: app.client,
203+
package: jpr,
204+
versions: versions)
205+
}
201206

202207
// validate
203208
try await XCTAssertEqualAsync(posted.withLockedValue { $0 }, 2)
@@ -225,11 +230,15 @@ class SocialTests: AppTestCase {
225230
posted.withLockedValue { $0 += 1 }
226231
}
227232

228-
// MUT
229-
try await Social.postToFirehose(client: app.client,
230-
package: jpr,
231-
versions: versions)
232-
233+
try await withDependencies {
234+
$0.environment.allowSocialPosts = { true }
235+
} operation: {
236+
// MUT
237+
try await Social.postToFirehose(client: app.client,
238+
package: jpr,
239+
versions: versions)
240+
}
241+
233242
// validate
234243
try await XCTAssertEqualAsync(posted.withLockedValue { $0 }, 1)
235244
}

0 commit comments

Comments
 (0)