Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Don't consider an app outdated if the update can't be installed on the current OS #422

Merged
merged 8 commits into from
Oct 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Brewfile.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@
"system": {
"macos": {
"monterey": {
"HOMEBREW_VERSION": "3.2.9-73-g7e7bdca",
"HOMEBREW_PREFIX": "/opt/homebrew",
"Homebrew/homebrew-core": "42fd3eec28f71853a59e12f77bcaff2f103097b5",
"CLT": "12.5.0.22.9",
"Xcode": "12.5.1",
"HOMEBREW_VERSION": "3.2.14-35-g9b42a10",
"HOMEBREW_PREFIX": "/usr/local",
"Homebrew/homebrew-core": "4119ab758ae132acdae47e218d718ff273a47997",
"CLT": "13.0.0.0.1.1630607135",
"Xcode": "13.0",
"macOS": "12.0"
}
}
Expand Down
12 changes: 6 additions & 6 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,16 @@
"repositoryURL": "/~https://github.com/apple/swift-argument-parser.git",
"state": {
"branch": null,
"revision": "83b23d940471b313427da226196661856f6ba3e0",
"version": "0.4.4"
"revision": "d2930e8fcf9c33162b9fcc1d522bc975e2d4179b",
"version": "1.0.1"
}
},
{
"package": "swift-format",
"repositoryURL": "/~https://github.com/apple/swift-format",
"state": {
"branch": "swift-5.4-branch",
"revision": "9c15831b798d767c9af0927a931de5d557004936",
"branch": "swift-5.5-branch",
"revision": "f872223e16742fd97fabd319fbf4a939230cc796",
"version": null
}
},
Expand All @@ -78,8 +78,8 @@
"repositoryURL": "/~https://github.com/apple/swift-syntax",
"state": {
"branch": null,
"revision": "2fff9fc25cdc059379b6bd309377cfab45d8520c",
"version": "0.50400.0"
"revision": "75e60475d9d8fd5bbc16a12e0eaa2cb01b0c322e",
"version": "0.50500.0"
}
},
{
Expand Down
3 changes: 3 additions & 0 deletions Sources/MasKit/Models/SearchResult.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ struct SearchResult: Decodable {
var bundleId: String
var currentVersionReleaseDate: String
var fileSizeBytes: String?
var kind: String
var minimumOsVersion: String
var price: Double?
var sellerName: String
Expand All @@ -23,6 +24,7 @@ struct SearchResult: Decodable {
bundleId: String = "",
currentVersionReleaseDate: String = "",
fileSizeBytes: String = "0",
kind: String = "",
minimumOsVersion: String = "",
price: Double = 0.0,
sellerName: String = "",
Expand All @@ -35,6 +37,7 @@ struct SearchResult: Decodable {
self.bundleId = bundleId
self.currentVersionReleaseDate = currentVersionReleaseDate
self.fileSizeBytes = fileSizeBytes
self.kind = kind
self.minimumOsVersion = minimumOsVersion
self.price = price
self.sellerName = sellerName
Expand Down
14 changes: 14 additions & 0 deletions Sources/MasKit/Models/SoftwareProduct.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,21 @@ extension SoftwareProduct {
appName.isEmpty ? bundleIdentifier : appName
}

/// Determines whether the app is considered outdated. Updates that require a higher OS version are excluded.
/// - Parameter storeApp: App from search result.
/// - Returns: true if the app is outdated; false otherwise.
func isOutdatedWhenComparedTo(_ storeApp: SearchResult) -> Bool {
// Only look at min OS version if we have one, also only consider macOS apps
// Replace string literal with MasStoreSearch.Entity once `search` branch is merged.
if let osVersion = Version(tolerant: storeApp.minimumOsVersion), storeApp.kind == "mac-software" {
let requiredVersion = OperatingSystemVersion(majorVersion: osVersion.major, minorVersion: osVersion.minor,
patchVersion: osVersion.patch)
// Don't consider an app outdated if the version in the app store requires a higher OS version.
guard ProcessInfo.processInfo.isOperatingSystemAtLeast(requiredVersion) else {
return false
}
}

// The App Store does not enforce semantic versioning, but we assume most apps follow versioning
// schemes that increase numerically over time.
guard let semanticBundleVersion = Version(tolerant: bundleVersion),
Expand Down
43 changes: 43 additions & 0 deletions Tests/MasKitTests/Models/SoftwareProductSpec.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// SoftwareProductSpec.swift
// MasKitTests
//
// Created by Ben Chatelain on 9/30/21.
// Copyright © 2018 mas-cli. All rights reserved.
//

import Foundation
import Nimble
import Quick

@testable import MasKit

public class SoftwareProductSpec: QuickSpec {
override public func spec() {
beforeSuite {
MasKit.initialize()
}
describe("software product") {
let app = SoftwareProductMock(appName: "App", bundleIdentifier: "", bundlePath: "", bundleVersion: "1.0.0",
itemIdentifier: 111)

let currentApp = SearchResult(kind: "mac-software", version: "1.0.0")
let appUpdate = SearchResult(kind: "mac-software", version: "2.0.0")
let higherOs = SearchResult(kind: "mac-software", minimumOsVersion: "99.0.0", version: "3.0.0")
let updateIos = SearchResult(kind: "software", minimumOsVersion: "99.0.0", version: "3.0.0")

it("is not outdated when there is no new version available") {
expect(app.isOutdatedWhenComparedTo(currentApp)) == false
}
it("is outdated when there is a new version available") {
expect(app.isOutdatedWhenComparedTo(appUpdate)) == true
}
it("is not outdated when the new version requires a higher OS version") {
expect(app.isOutdatedWhenComparedTo(higherOs)) == false
}
it("ignores minimum iOS version") {
expect(app.isOutdatedWhenComparedTo(updateIos)) == true
}
}
}
}