Skip to content

Commit

Permalink
Fix #5431 : Todo Checks Should Check Exclusively Against Issues (#5564)
Browse files Browse the repository at this point in the history
<!-- READ ME FIRST: Please fill in the explanation section below and
check off every point from the Essential Checklist! -->
## Explanation

Fix #5431
This pull request fixes issue by implementing the following changes:

Filters out pull requests from the "open issues" list.
Ensures all "To-Do" checks will pass only for open issues (not for prs).
<!--
- Explain what your PR does. If this PR fixes an existing bug, please
include
- "Fixes #bugnum:" in the explanation so that GitHub can auto-close the
issue
  - when this PR is merged.
  -->

## Essential Checklist
<!-- Please tick the relevant boxes by putting an "x" in them. -->
- [x] The PR title and explanation each start with "Fix #bugnum: " (If
this PR fixes part of an issue, prefix the title with "Fix part of
#bugnum: ...".)
- [x] Any changes to
[scripts/assets](https://github.com/oppia/oppia-android/tree/develop/scripts/assets)
files have their rationale included in the PR explanation.
- [x] The PR follows the [style
guide](https://github.com/oppia/oppia-android/wiki/Coding-style-guide).
- [x] The PR does not contain any unnecessary code changes from Android
Studio
([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#undo-unnecessary-changes)).
- [x] The PR is made from a branch that's **not** called "develop" and
is up-to-date with "develop".
- [x] The PR is **assigned** to the appropriate reviewers
([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#clarification-regarding-assignees-and-reviewers-section)).

## For UI-specific PRs only
<!-- Delete these section if this PR does not include UI-related
changes. -->
If your PR includes UI-related changes, then:
- Add screenshots for portrait/landscape for both a tablet & phone of
the before & after UI changes
- For the screenshots above, include both English and pseudo-localized
(RTL) screenshots (see [RTL
guide](https://github.com/oppia/oppia-android/wiki/RTL-Guidelines))
- Add a video showing the full UX flow with a screen reader enabled (see
[accessibility
guide](https://github.com/oppia/oppia-android/wiki/Accessibility-A11y-Guide))
- For PRs introducing new UI elements or color changes, both light and
dark mode screenshots must be included
- Add a screenshot demonstrating that you ran affected Espresso tests
locally & that they're passing

---------

Co-authored-by: Sneha Datta <snehadatta431@gmail.com>
Co-authored-by: Adhiambo Peres <59600948+adhiamboperes@users.noreply.github.com>
Co-authored-by: Mr. 17 <saptakmanna100@gmail.com>
  • Loading branch information
4 people authored Nov 19, 2024
1 parent 7955f7f commit 2f68639
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 5 deletions.
5 changes: 5 additions & 0 deletions scripts/assets/todo_open_exemptions.textproto
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,11 @@ todo_open_exemption {
line_number: 689
line_number: 737
line_number: 741
line_number: 790
line_number: 791
line_number: 792
line_number: 798
line_number: 800
}
todo_open_exemption {
exempted_file_path: "scripts/static_checks.sh"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,14 @@ class GitHubClient(
val call = gitHubService.fetchOpenIssues(repoOwner, repoName, authorizationBearer, pageNumber)
// Deferred blocking I/O operation to the dedicated I/O dispatcher.
val response = withContext(Dispatchers.IO) { call.execute() }

check(response.isSuccessful()) {
"Failed to fetch issues at page $pageNumber: ${response.code()}\n${call.request()}" +
"\n${response.errorBody()}."
}
return@async checkNotNull(response.body()) {
"No issues response from GitHub for page: $pageNumber."
}
}.filter { it.pullRequest == null }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,18 @@ import com.squareup.moshi.JsonClass
* 'issues/' in an issue's GitHub URL)
*/
@JsonClass(generateAdapter = true)
data class GitHubIssue(@Json(name = "number") val number: Int)
data class GitHubIssue(
@Json(name = "number") val number: Int,
@Json(name = "pull_request") val pullRequest: PullRequestInfo? = null
)

/**
* Data class representing information about a pull request associated with a GitHub issue.
*
* @property url the URL of the pull request, if it exists. This provides the link to the specific
* pull request associated with the issue on GitHub.
*/
@JsonClass(generateAdapter = true)
data class PullRequestInfo(
@Json(name = "url") val url: String? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -777,11 +777,67 @@ class TodoOpenCheckTest {
assertThat(outContent.toString().trim()).isEqualTo(failureMessage)
}

private fun setUpGitHubService(issueNumbers: List<Int>) {
val issueJsons = issueNumbers.joinToString(separator = ",") { "{\"number\":$it}" }
@Test
fun testTodoCheck_PrPresent_checkShouldFail() {
setUpGitHubService(
issueNumbers = listOf(11004, 11003, 11002, 11001),
pullRequestNumbers = listOf(11005)
)
val tempFile1 = tempFolder.newFile("testfiles/TempFile1.kt")
val tempFile2 = tempFolder.newFile("testfiles/TempFile2.kt")
val testContent1 =
"""
// TODO(#11002): test summary 1.
# TODO(#11004): test summary 2.
# TODO(#11001): test summary 3.
test Todo
test TODO
""".trimIndent()
val testContent2 =
"""
// TODO(#11005): test summary 3.
todo
<!-- TODO(#11003): test summary 4-->
""".trimIndent()
tempFile1.writeText(testContent1)
tempFile2.writeText(testContent2)

val exception = assertThrows<Exception>() { runScript() }

assertThat(exception).hasMessageThat().contains(TODO_SYNTAX_CHECK_FAILED_OUTPUT_INDICATOR)
val failureMessage =
"""
TODOs not corresponding to open issues on GitHub:
- TempFile2.kt:1
$wikiReferenceNote
$regenerateNote
""".trimIndent()
assertThat(outContent.toString().trim()).isEqualTo(failureMessage)
}

private fun setUpGitHubService(
issueNumbers: List<Int>,
pullRequestNumbers: List<Int> = emptyList()
) {
// Create JSON for issues with "pull_request" set to null
val issueJsons = issueNumbers
.joinToString(separator = ",") { "{\"number\":$it,\"pull_request\":null}" }

// Create JSON for pull requests with "pull_request" as an empty object
val pullRequestJsons = pullRequestNumbers
.joinToString(separator = ",") { "{\"number\":$it,\"pull_request\":{}}" }

// Combine issues and pull requests into one JSON array
val combinedJsons =
"[$issueJsons${if (pullRequestNumbers.isNotEmpty()) ", $pullRequestJsons" else ""}]"

val mockWebServer = MockWebServer()
mockWebServer.enqueue(MockResponse().setBody("[$issueJsons]"))
mockWebServer.enqueue(MockResponse().setBody("[]")) // No more issues.
mockWebServer.enqueue(MockResponse().setBody(combinedJsons))
mockWebServer.enqueue(MockResponse().setBody("[]"))
GitHubClient.remoteApiUrl = mockWebServer.url("/").toString()
}

Expand Down

0 comments on commit 2f68639

Please sign in to comment.