Skip to content
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
73 changes: 39 additions & 34 deletions Tests/AppTests/PackageInfoTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,46 +14,51 @@

@testable import App

import XCTest
import Testing


class PackageInfoTests: AppTestCase {
@Suite struct PackageInfoTests {

func test_title_package_name() async throws {
@Test func title_package_name() async throws {
// Ensure title is populated from package.name()
// setup
let p = try await savePackage(on: app.db, "1")
try await Repository(package: p, name: "repo name", owner: "owner")
.save(on: app.db)
try await Version(package: p, latest: .defaultBranch, packageName: "package name")
.save(on: app.db)
let joined = try await XCTUnwrapAsync(try await Joined3<Package, Repository, Version>
.query(on: app.db, version: .defaultBranch)
.first())

// MUT
let pkgInfo = PackageInfo(package: joined)

// validate
XCTAssertEqual(pkgInfo?.title, "package name")
try await withApp { app in
// setup
let p = try await savePackage(on: app.db, "1")
try await Repository(package: p, name: "repo name", owner: "owner")
.save(on: app.db)
try await Version(package: p, latest: .defaultBranch, packageName: "package name")
.save(on: app.db)
let joined = try await XCTUnwrapAsync(try await Joined3<Package, Repository, Version>
.query(on: app.db, version: .defaultBranch)
.first())

// MUT
let pkgInfo = PackageInfo(package: joined)

// validate
#expect(pkgInfo?.title == "package name")
}
}

func test_title_repo_name() async throws {
@Test func title_repo_name() async throws {
// Ensure title is populated from repoName if package.name() is nil
// setup
let p = try await savePackage(on: app.db, "1")
try await Repository(package: p, name: "repo name", owner: "owner")
.save(on: app.db)
try await Version(package: p, latest: .defaultBranch, packageName: nil)
.save(on: app.db)
let joined = try await XCTUnwrapAsync(try await Joined3<Package, Repository, Version>
.query(on: app.db, version: .defaultBranch)
.first())

// MUT
let pkgInfo = PackageInfo(package: joined)

// validate
XCTAssertEqual(pkgInfo?.title, "repo name")
try await withApp { app in
// setup
let p = try await savePackage(on: app.db, "1")
try await Repository(package: p, name: "repo name", owner: "owner")
.save(on: app.db)
try await Version(package: p, latest: .defaultBranch, packageName: nil)
.save(on: app.db)
let joined = try await XCTUnwrapAsync(try await Joined3<Package, Repository, Version>
.query(on: app.db, version: .defaultBranch)
.first())

// MUT
let pkgInfo = PackageInfo(package: joined)

// validate
#expect(pkgInfo?.title == "repo name")
}
}

}
65 changes: 32 additions & 33 deletions Tests/AppTests/PackageReadmeModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,38 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import Foundation

@testable import App

import SnapshotTesting
import SwiftSoup
import XCTVapor
import Testing


class PackageReadmeModelTests: SnapshotTestCase {
@Suite struct PackageReadmeModelTests {

func test_Element_extractReadme() throws {
@Test func Element_extractReadme() throws {
let element = Element.extractReadme("""
<div id="readme">
<article>
<p>README content.</p>
</article>
</div>
""")
XCTAssertEqual(try element?.html(), "<p>README content.</p>")
#expect(try element?.html() == "<p>README content.</p>")
}

func test_URL_rewriteRelative() throws {
@Test func URL_rewriteRelative() throws {
let triple = ("owner", "repo", "main")
XCTAssertEqual(URL(string: "https://example.com")?.rewriteRelative(to: triple, fileType: .raw), nil)
XCTAssertEqual(URL(string: "https://example.com/foo")?.rewriteRelative(to: triple, fileType: .raw), nil)
XCTAssertEqual(URL(string: "/foo")?.rewriteRelative(to: triple, fileType: .raw),
"https://github.com/owner/repo/raw/main/foo")
XCTAssertEqual(URL(string: "/foo")?.rewriteRelative(to: triple, fileType: .blob),
"https://github.com/owner/repo/blob/main/foo")
XCTAssertEqual(URL(string: "/foo/bar?query")?.rewriteRelative(to: triple, fileType: .raw),
"https://github.com/owner/repo/raw/main/foo/bar?query")
#expect(URL(string: "https://example.com")?.rewriteRelative(to: triple, fileType: .raw) == nil)
#expect(URL(string: "https://example.com/foo")?.rewriteRelative(to: triple, fileType: .raw) == nil)
#expect(URL(string: "/foo")?.rewriteRelative(to: triple, fileType: .raw) == "https://github.com/owner/repo/raw/main/foo")
#expect(URL(string: "/foo")?.rewriteRelative(to: triple, fileType: .blob) == "https://github.com/owner/repo/blob/main/foo")
#expect(URL(string: "/foo/bar?query")?.rewriteRelative(to: triple, fileType: .raw) == "https://github.com/owner/repo/raw/main/foo/bar?query")
}

func test_Element_rewriteRelativeImages() throws {
@Test func Element_rewriteRelativeImages() throws {
// setup
let element = Element.extractReadme("""
<div id="readme">
Expand All @@ -64,11 +63,11 @@ class PackageReadmeModelTests: SnapshotTestCase {
element?.rewriteRelativeImages(to: ("owner", "repo", "main"))

// validate
let html = try XCTUnwrap(try element?.html())
let html = try #require(try element?.html())
assertSnapshot(of: html, as: .lines)
}

func test_Element_rewriteRelativeLinks() throws {
@Test func Element_rewriteRelativeLinks() throws {
// setup
let element = Element.extractReadme("""
<div id="readme">
Expand All @@ -89,26 +88,26 @@ class PackageReadmeModelTests: SnapshotTestCase {
element?.rewriteRelativeLinks(to: ("owner", "repo", "main"))

// validate
let html = try XCTUnwrap(try element?.html())
let html = try #require(try element?.html())
assertSnapshot(of: html, as: .lines)
}

func test_URL_initWithPotentiallyUnencodedPath() throws {
@Test func URL_initWithPotentiallyUnencodedPath() throws {
// Relative URLs
XCTAssertEqual(try XCTUnwrap(URL(withPotentiallyUnencodedPath: "/root/relative/url")).absoluteString, "/root/relative/url")
XCTAssertEqual(try XCTUnwrap(URL(withPotentiallyUnencodedPath: "relative/url")).absoluteString, "relative/url")
XCTAssertEqual(try XCTUnwrap(URL(withPotentiallyUnencodedPath: "/encoded%20spaces")).absoluteString, "/encoded%20spaces")
XCTAssertEqual(try XCTUnwrap(URL(withPotentiallyUnencodedPath: "/unencoded spaces")).absoluteString, "/unencoded%20spaces")
XCTAssertEqual(try XCTUnwrap(URL(withPotentiallyUnencodedPath: "/multiple%20%7Bencoded%7D")).absoluteString, "/multiple%20%7Bencoded%7D")
XCTAssertEqual(try XCTUnwrap(URL(withPotentiallyUnencodedPath: "/multiple {unencoded}")).absoluteString, "/multiple%20%7Bunencoded%7D")
#expect(try #require(URL(withPotentiallyUnencodedPath: "/root/relative/url")).absoluteString == "/root/relative/url")
#expect(try #require(URL(withPotentiallyUnencodedPath: "relative/url")).absoluteString == "relative/url")
#expect(try #require(URL(withPotentiallyUnencodedPath: "/encoded%20spaces")).absoluteString == "/encoded%20spaces")
#expect(try #require(URL(withPotentiallyUnencodedPath: "/unencoded spaces")).absoluteString == "/unencoded%20spaces")
#expect(try #require(URL(withPotentiallyUnencodedPath: "/multiple%20%7Bencoded%7D")).absoluteString == "/multiple%20%7Bencoded%7D")
#expect(try #require(URL(withPotentiallyUnencodedPath: "/multiple {unencoded}")).absoluteString == "/multiple%20%7Bunencoded%7D")

// Absolute URLs
XCTAssertEqual(try XCTUnwrap(URL(withPotentiallyUnencodedPath: "https://full.host/and/path")).absoluteString, "https://full.host/and/path")
XCTAssertEqual(try XCTUnwrap(URL(withPotentiallyUnencodedPath: "https://full.host/encoded%20spaces")).absoluteString, "https://full.host/encoded%20spaces")
XCTAssertEqual(try XCTUnwrap(URL(withPotentiallyUnencodedPath: "https://full.host/unencoded spaces")).absoluteString, "https://full.host/unencoded%20spaces")
#expect(try #require(URL(withPotentiallyUnencodedPath: "https://full.host/and/path")).absoluteString == "https://full.host/and/path")
#expect(try #require(URL(withPotentiallyUnencodedPath: "https://full.host/encoded%20spaces")).absoluteString == "https://full.host/encoded%20spaces")
#expect(try #require(URL(withPotentiallyUnencodedPath: "https://full.host/unencoded spaces")).absoluteString == "https://full.host/unencoded%20spaces")
}

func test_Element_fixInlineAnchors() throws {
@Test func Element_fixInlineAnchors() throws {
// setup
let element = Element.extractReadme("""
<div id="readme">
Expand All @@ -126,11 +125,11 @@ class PackageReadmeModelTests: SnapshotTestCase {
element?.fixInlineAnchors()

// validate
let html = try XCTUnwrap(try element?.html())
let html = try #require(try element?.html())
assertSnapshot(of: html, as: .lines)
}

func test_Element_fixProtectedCachedImages() throws {
@Test func Element_fixProtectedCachedImages() throws {
// setup
let element = Element.extractReadme("""
<div id="readme">
Expand All @@ -150,11 +149,11 @@ class PackageReadmeModelTests: SnapshotTestCase {
element?.fixProtectedCachedImages()

// validate
let html = try XCTUnwrap(try element?.html())
let html = try #require(try element?.html())
assertSnapshot(of: html, as: .lines)
}

func test_Element_disableTurboOnLinks() throws {
@Test func Element_disableTurboOnLinks() throws {
// setup
let element = Element.extractReadme("""
<div id="readme">
Expand All @@ -172,7 +171,7 @@ class PackageReadmeModelTests: SnapshotTestCase {
element?.disableTurboOnLinks()

// validate
let html = try XCTUnwrap(try element?.html())
let html = try #require(try element?.html())
assertSnapshot(of: html, as: .lines)
}
}
91 changes: 46 additions & 45 deletions Tests/AppTests/PackageReleasesModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import Foundation

@testable import App

import XCTVapor
import Dependencies
import Testing


class PackageReleasesModelTests: AppTestCase {
@Suite struct PackageReleasesModelTests {

func test_initialise() async throws {
@Test func initialise() async throws {
// Setup

// Work-around to set the local time zone for time sensitive
Expand All @@ -36,36 +38,38 @@ class PackageReleasesModelTests: AppTestCase {
try await withDependencies {
$0.date.now = .spiBirthday
} operation: {
let pkg = Package(id: UUID(), url: "1".asGithubUrl.url)
try await pkg.save(on: app.db)

try await Repository(package: pkg, releases: [
.mock(description: "Release Notes", descriptionHTML: "Release Notes",
publishedAt: 2, tagName: "1.0.0", url: "some url"),

.mock(description: nil, descriptionHTML: nil,
publishedAt: 1, tagName: "0.0.1", url: "some url"),
]).save(on: app.db)
let jpr = try await Package.fetchCandidate(app.db, id: pkg.id!)


// MUT
let model = try XCTUnwrap(PackageReleases.Model(package: jpr))

// Validate
XCTAssertEqual(model.releases, [
.init(title: "1.0.0", date: "Released 50 years ago on 1 January 1970",
html: "Release Notes", link: "some url"),

.init(title: "0.0.1", date: "Released 50 years ago on 1 January 1970",
html: nil, link: "some url"),
])
// NOTE(heckj): test is sensitive to local time zones, breaks when run at GMT-7
// resolves as `31 December 1969`
try await withApp { app in
let pkg = Package(id: UUID(), url: "1".asGithubUrl.url)
try await pkg.save(on: app.db)

try await Repository(package: pkg, releases: [
.mock(description: "Release Notes", descriptionHTML: "Release Notes",
publishedAt: 2, tagName: "1.0.0", url: "some url"),

.mock(description: nil, descriptionHTML: nil,
publishedAt: 1, tagName: "0.0.1", url: "some url"),
]).save(on: app.db)
let jpr = try await Package.fetchCandidate(app.db, id: pkg.id!)


// MUT
let model = try #require(PackageReleases.Model(package: jpr))

// Validate
#expect(model.releases == [
.init(title: "1.0.0", date: "Released 50 years ago on 1 January 1970",
html: "Release Notes", link: "some url"),

.init(title: "0.0.1", date: "Released 50 years ago on 1 January 1970",
html: nil, link: "some url"),
])
// NOTE(heckj): test is sensitive to local time zones, breaks when run at GMT-7
// resolves as `31 December 1969`
}
}
}

func test_dateFormatting() throws {
@Test func dateFormatting() throws {

// Work-around to set the local time zone for time sensitive
// tests. Sets the explicit default time zone to UTC for the duration
Expand All @@ -80,24 +84,22 @@ class PackageReleasesModelTests: AppTestCase {
let currentDate = Date(timeIntervalSince1970: 500)
let targetDate = Date(timeIntervalSince1970: 0)

XCTAssertEqual(PackageReleases.Model.formatDate(targetDate, currentDate: currentDate),
"Released 8 minutes ago on 1 January 1970")
#expect(PackageReleases.Model.formatDate(targetDate, currentDate: currentDate) == "Released 8 minutes ago on 1 January 1970")
// NOTE(heckj): test is sensitive to local time zones, breaks when run at GMT-7
// resolves as `31 December 1969`

XCTAssertNil(PackageReleases.Model.formatDate(nil, currentDate: currentDate))
#expect(PackageReleases.Model.formatDate(nil, currentDate: currentDate) == nil)
}

func test_removeDuplicateHeader() throws {
@Test func removeDuplicateHeader() throws {

do { // First header is removed if it contains the version (positive case)
let descriptionHTML = """
<h2>Header for v1.0.0</h2>
<h2>Second Header for v1.0.0</h2>
"""

XCTAssertEqual(PackageReleases.Model.updateDescription(descriptionHTML, replacingTitle: "v1.0.0"),
"<h2>Second Header for v1.0.0</h2>")
#expect(PackageReleases.Model.updateDescription(descriptionHTML, replacingTitle: "v1.0.0") == "<h2>Second Header for v1.0.0</h2>")
}

do { // First header is *only* removed if it contains the version
Expand All @@ -106,25 +108,24 @@ class PackageReleasesModelTests: AppTestCase {
<h2>Second Header for v1.0.0</h2>
"""

XCTAssertEqual(PackageReleases.Model.updateDescription(descriptionHTML, replacingTitle: "v1.0.0"),
"<h2>Header for version 1</h2> \n<h2>Second Header for v1.0.0</h2>")
#expect(PackageReleases.Model.updateDescription(descriptionHTML, replacingTitle: "v1.0.0") == "<h2>Header for version 1</h2> \n<h2>Second Header for v1.0.0</h2>")
}

do { // Supports all header versions (h1-h6)
["h1", "h2", "h3", "h4", "h5", "h6"].forEach { header in
let descriptionHTML = "<\(header)>v1.0.0</\(header)>"
XCTAssertEqual(PackageReleases.Model.updateDescription(descriptionHTML, replacingTitle: "v1.0.0"), "")
#expect(PackageReleases.Model.updateDescription(descriptionHTML, replacingTitle: "v1.0.0") == "")
}
}
}

func test_descriptionIsTrimmed() throws {
XCTAssertEqual(PackageReleases.Model.updateDescription(nil, replacingTitle: ""), nil)
XCTAssertEqual(PackageReleases.Model.updateDescription("", replacingTitle: ""), nil)
XCTAssertEqual(PackageReleases.Model.updateDescription(" ", replacingTitle: ""), nil)
XCTAssertEqual(PackageReleases.Model.updateDescription("""
@Test func descriptionIsTrimmed() throws {
#expect(PackageReleases.Model.updateDescription(nil, replacingTitle: "") == nil)
#expect(PackageReleases.Model.updateDescription("", replacingTitle: "") == nil)
#expect(PackageReleases.Model.updateDescription(" ", replacingTitle: "") == nil)
#expect(PackageReleases.Model.updateDescription("""


""", replacingTitle: ""), nil)
""", replacingTitle: "") == nil)
}
}
Loading
Loading