| ... | @@ -297,10 +297,14 @@ fn issue(html: &str, repository: &str, id: Option<u64>) -> Result<Value> { | ... | @@ -297,10 +297,14 @@ fn issue(html: &str, repository: &str, id: Option<u64>) -> Result<Value> { |
| 297 | .unwrap_or((None, None)) | 297 | .unwrap_or((None, None)) |
| 298 | } else { (None, None) } | 298 | } else { (None, None) } |
| 299 | } else { (None, None) }; | 299 | } else { (None, None) }; |
| 300 | let status = document | 300 | let statuses: Vec<_> = document |
| 301 | .select(&Selector::parse("select[name=status] option[selected]").unwrap()) | 301 | .select(&Selector::parse("dl.sidebar dd span[class*='issuestatus-']").unwrap()) |
| 302 | .next() | 302 | .filter_map(|status| status.value().classes().find_map(|class| class.strip_prefix("issuestatus-"))) |
| 303 | .and_then(|e| e.attr("value")); | 303 | .collect(); |
| | 304 | let status = match statuses.as_slice() { |
| | 305 | [status] => Some(*status), |
| | 306 | _ => None, |
| | 307 | }; |
| 304 | if title.as_ref().is_none_or(|title| title.is_empty()) | 308 | if title.as_ref().is_none_or(|title| title.is_empty()) |
| 305 | || issue_id.is_none_or(|n| n == 0 || id.is_some_and(|id| n != id)) | 309 | || issue_id.is_none_or(|n| n == 0 || id.is_some_and(|id| n != id)) |
| 306 | || status.is_none() | 310 | || status.is_none() |
| ... | @@ -911,16 +915,20 @@ mod tests { | ... | @@ -911,16 +915,20 @@ mod tests { |
| 911 | } | 915 | } |
| 912 | #[test] | 916 | #[test] |
| 913 | fn issue_pages_must_match_repository_identity_and_issue_number() { | 917 | fn issue_pages_must_match_repository_identity_and_issue_number() { |
| 914 | let page = "<meta name='astheno.shale.repo.name' content='owned'><body id=page-issue><h1><span>#3</span><span>Snow &amp; ☃</span></h1><select name=status><option selected value=done>Done</option></select>"; | 918 | let page = "<meta name='astheno.shale.repo.name' content='owned'><body id=page-issue><h1><span>#3</span><span>Snow &amp; ☃</span></h1><dl class=sidebar><dd><span class=issuestatus-done><span>Done</span></span></dd></dl>"; |
| 915 | assert_eq!(issue(page, "owned", Some(3)).unwrap()["title"], "Snow & ☃"); | 919 | assert_eq!(issue(page, "owned", Some(3)).unwrap()["title"], "Snow & ☃"); |
| | 920 | assert_eq!(issue(page, "owned", Some(3)).unwrap()["status"], "done"); |
| | 921 | let owner = format!("{page}<form><select name=status><option selected value=todo>Todo</option></select></form>"); |
| | 922 | assert_eq!(issue(&owner, "owned", Some(3)).unwrap()["status"], "done"); |
| 916 | assert!(issue(page, "other", Some(3)).is_err()); | 923 | assert!(issue(page, "other", Some(3)).is_err()); |
| 917 | assert!(issue(page, "owned", Some(4)).is_err()); | 924 | assert!(issue(page, "owned", Some(4)).is_err()); |
| 918 | assert!(issue(&page.replace("page-issue", "page-login"), "owned", Some(3)).is_err()); | 925 | assert!(issue(&page.replace("page-issue", "page-login"), "owned", Some(3)).is_err()); |
| 919 | assert!(issue(&page.replace("selected", ""), "owned", Some(3)).is_err()); | 926 | assert!(issue(&page.replace("issuestatus-done", "unknown"), "owned", Some(3)).is_err()); |
| | 927 | assert!(issue(&format!("{page}<dl class=sidebar><dd><span class=issuestatus-todo></span></dd></dl>"), "owned", Some(3)).is_err()); |
| 920 | } | 928 | } |
| 921 | #[test] | 929 | #[test] |
| 922 | fn verified_r1616_issue_heading_keeps_identity_checks() { | 930 | fn verified_r1616_issue_heading_keeps_identity_checks() { |
| 923 | let page = "<head><meta name='astheno.shale.repo.name' content='owned'></head><body id=page-issue><h1>Issue #3: Snow &amp; ☃</h1><select name=status><option selected value=done>Done</option></select><footer class=usa-footer><div class=usa-footer__secondary-section><a href='https://astheno.software/shale/'>shale r1616-ga87d2f5.zig.0.16.0</a></div></footer></body>"; | 931 | let page = "<head><meta name='astheno.shale.repo.name' content='owned'></head><body id=page-issue><h1>Issue #3: Snow &amp; ☃</h1><dl class=sidebar><dd><span class=issuestatus-done><span>Done</span></span></dd></dl><footer class=usa-footer><div class=usa-footer__secondary-section><a href='https://astheno.software/shale/'>shale r1616-ga87d2f5.zig.0.16.0</a></div></footer></body>"; |
| 924 | assert_eq!(issue(page, "owned", Some(3)).unwrap()["title"], "Snow & ☃"); | 932 | assert_eq!(issue(page, "owned", Some(3)).unwrap()["title"], "Snow & ☃"); |
| 925 | assert!(issue(page, "other", Some(3)).is_err()); | 933 | assert!(issue(page, "other", Some(3)).is_err()); |
| 926 | assert!(issue(page, "owned", Some(4)).is_err()); | 934 | assert!(issue(page, "owned", Some(4)).is_err()); |