Skip to content

Commit

Permalink
api: fix appcast when release channel behind stable
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredh159 committed Dec 29, 2023
1 parent ec564b1 commit 06e14ec
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 9 deletions.
3 changes: 1 addition & 2 deletions api/Sources/Api/Routes/Appcast.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ enum AppcastRoute {
static func handler(_ request: Request) async throws -> Response {
let query = try request.query.decode(AppcastQuery.self)
let releases = try await Current.db.query(Release.self)
.where(query.version.map { _ in .always } ?? (.channel == query.channel ?? .stable))
.where(query.version.map { .semver == $0 } ?? .always)
.orderBy(.createdAt, .desc)
.all()
.filter { $0.channel.isAtLeastAsStable(as: query.channel ?? .stable) }

return Response(
headers: ["Content-Type": "application/xml"],
Expand Down
39 changes: 39 additions & 0 deletions api/Tests/ApiTests/AppcastTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import XCTest
import XCTVapor
import XExpect

@testable import Api

final class AppcastTests: ApiTestCase {
func testAppcastVersions() async throws {
try await replaceAllReleases(with: [
Release("2.0.0", channel: .stable, pace: nil, createdAt: .epoch),
Release("2.1.0", channel: .canary, pace: nil, createdAt: .epoch.advanced(by: .days(10))),
Release("2.1.1", channel: .stable, pace: nil, createdAt: .epoch.advanced(by: .days(20))),
])

try app.test(.GET, "appcast.xml", afterResponse: { res in
expect(filenames(from: res)).toEqual([
"Gertrude.2.1.1.zip",
"Gertrude.2.0.0.zip",
])
})

// canary is one behind stable, so...
try app.test(.GET, "appcast.xml?channel=canary", afterResponse: { res in
expect(filenames(from: res)).toEqual([
"Gertrude.2.1.1.zip", // <-- ...includes stable
"Gertrude.2.1.0.zip",
"Gertrude.2.0.0.zip",
])
})
}

func filenames(from response: XCTHTTPResponse) -> [String] {
response.body.string.split(separator: "\n")
.filter { $0.contains("url=") }
.map { $0.trimmingCharacters(in: .whitespaces) }
.compactMap { $0.split(separator: "/").last }
.map { String($0.replacingOccurrences(of: "\"", with: "")) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ final class CheckInLatestReleaseTests: ApiTestCase {
}

func testAppOnLatestVersionHappyPath() async throws {
try await createReleases([
try await replaceAllReleases(with: [
Release("1.0.0", pace: 10),
Release("1.1.0", pace: 10),
])
Expand All @@ -31,7 +31,7 @@ final class CheckInLatestReleaseTests: ApiTestCase {
}

func testAppBehindOne() async throws {
try await createReleases([
try await replaceAllReleases(with: [
Release("1.0.0", pace: 10, createdAt: .epoch),
Release("1.1.0", pace: 10, createdAt: .epoch.advanced(by: .days(10))),
Release("1.2.0", pace: 10, createdAt: .epoch.advanced(by: .days(20))),
Expand All @@ -49,7 +49,7 @@ final class CheckInLatestReleaseTests: ApiTestCase {
}

func testAppBehindTwoUsesFirstPace() async throws {
try await createReleases([
try await replaceAllReleases(with: [
Release("1.0.0", pace: 10, createdAt: .epoch),
Release("1.1.0", pace: 10, createdAt: .epoch.advanced(by: .days(10))),
Release("1.2.0", pace: 10, createdAt: .epoch.advanced(by: .days(20))),
Expand All @@ -68,7 +68,7 @@ final class CheckInLatestReleaseTests: ApiTestCase {
}

func testOnBetaAheadOfStable() async throws {
try await createReleases([
try await replaceAllReleases(with: [
Release("1.0.0", pace: 10, createdAt: .epoch),
Release("1.1.0", pace: 10, createdAt: .epoch.advanced(by: .days(10))),
Release("2.0.0", channel: .beta, pace: 10, createdAt: .epoch.advanced(by: .days(20))),
Expand All @@ -88,7 +88,7 @@ final class CheckInLatestReleaseTests: ApiTestCase {
}

func testOnCanaryBehindStable() async throws {
try await createReleases([
try await replaceAllReleases(with: [
Release("2.0.0", channel: .stable, pace: nil, createdAt: .epoch),
Release("2.1.0", channel: .canary, pace: nil, createdAt: .epoch.advanced(by: .days(10))),
Release("2.1.1", channel: .stable, pace: nil, createdAt: .epoch.advanced(by: .days(20))),
Expand All @@ -110,7 +110,7 @@ final class CheckInLatestReleaseTests: ApiTestCase {

// extensions, helpers

func createReleases(_ releases: [Release]) async throws {
func replaceAllReleases(with releases: [Release]) async throws {
try await Current.db.deleteAll(Release.self)
try await Current.db.create(releases)
for var release in releases {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class CheckInResolverTests: ApiTestCase {
}

func testCheckIn_OtherProps() async throws {
try await createReleases([
try await replaceAllReleases(with: [
Release("2.0.3", channel: .stable),
Release("2.0.4", channel: .stable),
Release("3.0.0", channel: .beta),
Expand Down

0 comments on commit 06e14ec

Please sign in to comment.