mirror of
https://codeberg.org/secana/Forji.git
synced 2026-06-16 05:13:55 -07:00
test: fix tests
This commit is contained in:
parent
781826004b
commit
eede8a3467
6 changed files with 60 additions and 59 deletions
|
|
@ -240,27 +240,38 @@ struct SearchableOverviewView<Row: View, Detail: View, CreateView: View>: View {
|
|||
}
|
||||
|
||||
private func searchIssues(service: IssueService, page: Int, limit: Int) async throws -> [Issue] {
|
||||
// Forgejo's search (q=) does not work with involvement scope flags
|
||||
// (assigned, created, mentioned). When a search query is active, search
|
||||
// globally by type and state only. The scoped view returns when the
|
||||
// user clears the search.
|
||||
if !searchText.isEmpty {
|
||||
return try await service.searchIssues(
|
||||
type: issueType, state: stateFilter.rawValue, query: searchText,
|
||||
page: page, limit: limit,
|
||||
)
|
||||
}
|
||||
|
||||
switch involvementScope {
|
||||
case .involved:
|
||||
try await searchInvolved(service: service, page: page, limit: limit)
|
||||
return try await searchInvolved(service: service, page: page, limit: limit)
|
||||
case .created:
|
||||
try await service.searchIssues(
|
||||
type: issueType, state: stateFilter.rawValue, query: searchText,
|
||||
return try await service.searchIssues(
|
||||
type: issueType, state: stateFilter.rawValue,
|
||||
page: page, limit: limit, created: true,
|
||||
)
|
||||
case .assigned:
|
||||
try await service.searchIssues(
|
||||
type: issueType, state: stateFilter.rawValue, query: searchText,
|
||||
return try await service.searchIssues(
|
||||
type: issueType, state: stateFilter.rawValue,
|
||||
page: page, limit: limit, assigned: true,
|
||||
)
|
||||
case .mentioned:
|
||||
try await service.searchIssues(
|
||||
type: issueType, state: stateFilter.rawValue, query: searchText,
|
||||
return try await service.searchIssues(
|
||||
type: issueType, state: stateFilter.rawValue,
|
||||
page: page, limit: limit, mentioned: true,
|
||||
)
|
||||
case .reviewRequested:
|
||||
try await service.searchIssues(
|
||||
type: issueType, state: stateFilter.rawValue, query: searchText,
|
||||
return try await service.searchIssues(
|
||||
type: issueType, state: stateFilter.rawValue,
|
||||
page: page, limit: limit, reviewRequested: true,
|
||||
)
|
||||
}
|
||||
|
|
@ -273,14 +284,13 @@ struct SearchableOverviewView<Row: View, Detail: View, CreateView: View>: View {
|
|||
private func searchInvolved(service: IssueService, page: Int, limit: Int) async throws -> [Issue] {
|
||||
let type = issueType
|
||||
let state = stateFilter.rawValue
|
||||
let query = searchText
|
||||
|
||||
let batches = try await withThrowingTaskGroup(of: [Issue].self) { group in
|
||||
for flag in involvedFlags {
|
||||
group.addTask {
|
||||
try await resilientFetch {
|
||||
try await service.searchIssues(
|
||||
type: type, state: state, query: query, page: page, limit: limit,
|
||||
type: type, state: state, page: page, limit: limit,
|
||||
assigned: flag == .assigned, created: flag == .created,
|
||||
mentioned: flag == .mentioned, reviewRequested: flag == .reviewRequested,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,23 +13,16 @@ final class IssueUITests: ForgejoReadOnlyUITestBase {
|
|||
func testIssuesOverview() throws {
|
||||
app.tabBars.buttons["Issues"].tap()
|
||||
|
||||
// Issues list loads (may show pagination test issues first on page 1)
|
||||
XCTAssertTrue(app.cells.firstMatch.waitForExistence(timeout: 10), "Issues should load")
|
||||
// Wait for initial load (default scope: Open + All involvement)
|
||||
XCTAssertTrue(app.cells.firstMatch.waitForExistence(timeout: 15), "Issues should load")
|
||||
|
||||
// Filter All via toolbar menu
|
||||
let filterMenuButton = app.buttons["filter-menu-button"]
|
||||
XCTAssertTrue(filterMenuButton.waitForExistence(timeout: 5))
|
||||
filterMenuButton.tap()
|
||||
app.buttons["All"].firstMatch.tap()
|
||||
XCTAssertTrue(app.cells.firstMatch.waitForExistence(timeout: 10), "Issues should load after filter change")
|
||||
|
||||
// Search narrows results to specific issue (unique keyword avoids pagination test issues)
|
||||
// Search narrows results to a specific issue
|
||||
let searchField = app.searchFields.firstMatch
|
||||
XCTAssertTrue(searchField.waitForExistence(timeout: 5))
|
||||
searchField.tap()
|
||||
searchField.typeText("integration")
|
||||
searchField.typeText("Pagination test issue 25")
|
||||
|
||||
XCTAssertTrue(app.staticTexts["Test issue 1 from integration tests"].waitForExistence(timeout: 10))
|
||||
XCTAssertTrue(app.staticTexts["Pagination test issue 25"].waitForExistence(timeout: 15))
|
||||
}
|
||||
|
||||
// MARK: - Issues Overview Involvement Filter
|
||||
|
|
@ -44,10 +37,10 @@ final class IssueUITests: ForgejoReadOnlyUITestBase {
|
|||
// Wait for list to load
|
||||
XCTAssertTrue(app.cells.firstMatch.waitForExistence(timeout: 10), "Issues should load")
|
||||
|
||||
// Default filter summary should show "Open · Created by you"
|
||||
// Default filter summary should show "Open" (default scope is All involvement)
|
||||
let filterSummary = app.staticTexts["filter-summary"]
|
||||
XCTAssertTrue(filterSummary.waitForExistence(timeout: 5))
|
||||
XCTAssertEqual(filterSummary.label, "Open · Created by you")
|
||||
XCTAssertEqual(filterSummary.label, "Open")
|
||||
|
||||
let filterMenuButton = app.buttons["filter-menu-button"]
|
||||
|
||||
|
|
@ -63,11 +56,11 @@ final class IssueUITests: ForgejoReadOnlyUITestBase {
|
|||
sleep(2)
|
||||
XCTAssertTrue(filterSummary.label.contains("Mentioned"))
|
||||
|
||||
// Tap back to "All" scope via filter menu
|
||||
// Tap "Created by you" via filter menu
|
||||
filterMenuButton.tap()
|
||||
// The scope "All" button — use firstMatch since "All" also appears in State section
|
||||
app.buttons["All"].firstMatch.tap()
|
||||
app.buttons["Created by you"].tap()
|
||||
sleep(2)
|
||||
XCTAssertTrue(filterSummary.label.contains("Created by you"))
|
||||
|
||||
// "Review requested" should NOT be present for issues
|
||||
filterMenuButton.tap()
|
||||
|
|
@ -113,7 +106,7 @@ final class IssueUITests: ForgejoReadOnlyUITestBase {
|
|||
allButtons.element(boundBy: 1).tap()
|
||||
|
||||
XCTAssertTrue(filterSummary.waitForExistence(timeout: 5))
|
||||
XCTAssertEqual(filterSummary.label, "All · All",
|
||||
XCTAssertEqual(filterSummary.label, "All · All involvement",
|
||||
"Filter summary should show All state and All scope")
|
||||
|
||||
// The key assertion: items must actually load
|
||||
|
|
|
|||
|
|
@ -13,10 +13,7 @@ final class OverviewCreateUITests: ForgejoReadOnlyUITestBase {
|
|||
func testCreatePRFromOverview() throws {
|
||||
app.tabBars.buttons["Pull Requests"].tap()
|
||||
|
||||
// Test PRs were created by testbot — switch scope to "All" to see them
|
||||
setOverviewScopeAll()
|
||||
|
||||
// Wait for the PR list to load
|
||||
// Default scope is "All involvement" — testadmin is assigned to PR #4
|
||||
XCTAssertTrue(app.staticTexts["Add feature file"].waitForExistence(timeout: 10))
|
||||
|
||||
// Tap floating create button
|
||||
|
|
|
|||
|
|
@ -90,16 +90,8 @@ final class PullRequestUITests: ForgejoReadOnlyUITestBase {
|
|||
func testPullRequestsOverview() throws {
|
||||
app.tabBars.buttons["Pull Requests"].tap()
|
||||
|
||||
// Test PRs were created by testbot — switch scope to "All" to see them
|
||||
setOverviewScopeAll()
|
||||
|
||||
XCTAssertTrue(app.staticTexts["Add feature file"].waitForExistence(timeout: 10))
|
||||
|
||||
// Filter state to All via toolbar menu
|
||||
let filterMenuButton = app.buttons["filter-menu-button"]
|
||||
XCTAssertTrue(filterMenuButton.waitForExistence(timeout: 5))
|
||||
filterMenuButton.tap()
|
||||
app.buttons["All"].firstMatch.tap()
|
||||
// Wait for initial load to complete (testadmin is assigned to PR #4)
|
||||
XCTAssertTrue(app.staticTexts["Add feature file"].waitForExistence(timeout: 15))
|
||||
|
||||
// Search
|
||||
let searchField = app.searchFields.firstMatch
|
||||
|
|
@ -107,7 +99,7 @@ final class PullRequestUITests: ForgejoReadOnlyUITestBase {
|
|||
searchField.tap()
|
||||
searchField.typeText("feature")
|
||||
|
||||
XCTAssertTrue(app.staticTexts["Add feature file"].waitForExistence(timeout: 10))
|
||||
XCTAssertTrue(app.staticTexts["Add feature file"].waitForExistence(timeout: 15))
|
||||
}
|
||||
|
||||
// MARK: - Pull Requests Overview Involvement Filter
|
||||
|
|
@ -119,10 +111,10 @@ final class PullRequestUITests: ForgejoReadOnlyUITestBase {
|
|||
// Reset filters to defaults (previous test may have changed them)
|
||||
resetOverviewFilters()
|
||||
|
||||
// Default filter summary should show "Open · Created by you"
|
||||
// Default filter summary should show "Open" (default scope is All involvement)
|
||||
let filterSummary = app.staticTexts["filter-summary"]
|
||||
XCTAssertTrue(filterSummary.waitForExistence(timeout: 5))
|
||||
XCTAssertEqual(filterSummary.label, "Open · Created by you")
|
||||
XCTAssertEqual(filterSummary.label, "Open")
|
||||
|
||||
let filterMenuButton = app.buttons["filter-menu-button"]
|
||||
|
||||
|
|
@ -138,10 +130,11 @@ final class PullRequestUITests: ForgejoReadOnlyUITestBase {
|
|||
sleep(2)
|
||||
XCTAssertTrue(filterSummary.label.contains("Mentioned"))
|
||||
|
||||
// Tap back to "All" scope via filter menu
|
||||
// Tap "Created by you" via filter menu
|
||||
filterMenuButton.tap()
|
||||
app.buttons["All"].firstMatch.tap()
|
||||
app.buttons["Created by you"].tap()
|
||||
sleep(2)
|
||||
XCTAssertTrue(filterSummary.label.contains("Created by you"))
|
||||
|
||||
// "Review requested" SHOULD be present for PRs
|
||||
filterMenuButton.tap()
|
||||
|
|
|
|||
|
|
@ -28,16 +28,14 @@ extension UITestNavigating {
|
|||
picker.buttons["Pull Requests"].tap()
|
||||
}
|
||||
|
||||
/// Resets the overview filter to Open + Created by you (the app defaults).
|
||||
/// Resets the overview filter to Open + All involvement (the app defaults).
|
||||
func resetOverviewFilters() {
|
||||
let filterMenuButton = app.buttons["filter-menu-button"]
|
||||
guard filterMenuButton.waitForExistence(timeout: 5) else { return }
|
||||
filterMenuButton.tap()
|
||||
app.buttons["Open"].tap()
|
||||
sleep(1)
|
||||
filterMenuButton.tap()
|
||||
app.buttons["Created by you"].tap()
|
||||
sleep(1)
|
||||
setOverviewScopeAll()
|
||||
}
|
||||
|
||||
/// Switches the overview scope to "All" to show items from all users.
|
||||
|
|
|
|||
|
|
@ -60,17 +60,27 @@ curl -sf -X POST "$BASE_URL/api/v1/user/repos" \
|
|||
wait
|
||||
echo "Repositories created."
|
||||
|
||||
# Archive the archived-repo
|
||||
# Archive the archived-repo (retry — the repo may not be ready immediately after creation)
|
||||
echo "Archiving archived-repo..."
|
||||
curl -sf -X PATCH "$BASE_URL/api/v1/repos/$ADMIN_USER/archived-repo" \
|
||||
-u "$ADMIN_AUTH" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"archived": true}'
|
||||
for attempt in 1 2 3; do
|
||||
if curl -sf -X PATCH "$BASE_URL/api/v1/repos/$ADMIN_USER/archived-repo" \
|
||||
-u "$ADMIN_AUTH" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"archived": true}'; then
|
||||
break
|
||||
fi
|
||||
echo " Archive attempt $attempt failed, retrying..."
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Update html-readme-repo README with HTML content
|
||||
echo "Updating html-readme-repo README..."
|
||||
README_SHA=$(curl -sf "$BASE_URL/api/v1/repos/$ADMIN_USER/html-readme-repo/contents/README.md" \
|
||||
-u "$ADMIN_AUTH" | python3 -c "import sys,json; print(json.load(sys.stdin)['sha'])")
|
||||
for attempt in 1 2 3; do
|
||||
README_SHA=$(curl -sf "$BASE_URL/api/v1/repos/$ADMIN_USER/html-readme-repo/contents/README.md" \
|
||||
-u "$ADMIN_AUTH" | python3 -c "import sys,json; print(json.load(sys.stdin)['sha'])" 2>/dev/null) && break
|
||||
echo " README fetch attempt $attempt failed, retrying..."
|
||||
sleep 1
|
||||
done
|
||||
README_PAYLOAD=$(python3 -c "
|
||||
import base64, json
|
||||
content = '''# HTML Readme Test
|
||||
|
|
|
|||
Loading…
Reference in a new issue