forgejo-hooks: Add failing tests
Signed-off-by: pep <pep@bouah.net>
This commit is contained in:
parent
979dc50644
commit
25eeacde7c
4 changed files with 285 additions and 14 deletions
|
@ -7,3 +7,7 @@ license = "AGPL-3.0+"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = { version = "0.4", default-features = false, features = ["serde"] }
|
chrono = { version = "0.4", default-features = false, features = ["serde"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
serde_json = "1.0"
|
||||||
|
serde_path_to_error = "0.1.16"
|
||||||
|
|
|
@ -13,17 +13,20 @@
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
pub struct CommitAuthor {
|
pub struct CommitAuthor {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub email: String,
|
pub email: String,
|
||||||
pub username: String,
|
pub username: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
pub login: String,
|
pub login: String,
|
||||||
|
@ -33,7 +36,7 @@ pub struct User {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
pub struct Commit {
|
pub struct Commit {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub message: String,
|
pub message: String,
|
||||||
|
@ -43,21 +46,21 @@ pub struct Commit {
|
||||||
pub timestamp: DateTime<Utc>,
|
pub timestamp: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
pub struct Perms {
|
pub struct Permissions {
|
||||||
admin: bool,
|
admin: bool,
|
||||||
push: bool,
|
push: bool,
|
||||||
pull: bool,
|
pull: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
pub struct InternalTracker {
|
pub struct InternalTracker {
|
||||||
enable_time_tracker: bool,
|
enable_time_tracker: bool,
|
||||||
allow_only_contributors_to_track_time: bool,
|
allow_only_contributors_to_track_time: bool,
|
||||||
enable_issue_dependencies: bool,
|
enable_issue_dependencies: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
pub struct Repository {
|
pub struct Repository {
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
pub owner: User,
|
pub owner: User,
|
||||||
|
@ -79,7 +82,7 @@ pub struct Repository {
|
||||||
pub updated_at: DateTime<Utc>,
|
pub updated_at: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
pub struct RepositoryFull {
|
pub struct RepositoryFull {
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
pub owner: RepositoryOwner,
|
pub owner: RepositoryOwner,
|
||||||
|
@ -134,7 +137,7 @@ pub struct RepositoryFull {
|
||||||
pub repo_transfer: Option<String>,
|
pub repo_transfer: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
pub struct RepositoryOwner {
|
pub struct RepositoryOwner {
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
pub login: String,
|
pub login: String,
|
||||||
|
@ -159,7 +162,7 @@ pub struct RepositoryOwner {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
pub struct Push {
|
pub struct Push {
|
||||||
#[serde(rename(deserialize = "ref"))]
|
#[serde(rename(deserialize = "ref"))]
|
||||||
pub ref_: String,
|
pub ref_: String,
|
||||||
|
@ -171,12 +174,12 @@ pub struct Push {
|
||||||
pub sender: User,
|
pub sender: User,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
pub enum RefType {
|
pub enum RefType {
|
||||||
Branch,
|
Branch,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
pub struct AddedBranch {
|
pub struct AddedBranch {
|
||||||
pub sha: String,
|
pub sha: String,
|
||||||
pub ref_type: String,
|
pub ref_type: String,
|
||||||
|
@ -184,7 +187,7 @@ pub struct AddedBranch {
|
||||||
pub sender: RepositoryOwner,
|
pub sender: RepositoryOwner,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
pub struct RemovedBranch {
|
pub struct RemovedBranch {
|
||||||
pub sha: String,
|
pub sha: String,
|
||||||
pub ref_type: String,
|
pub ref_type: String,
|
||||||
|
@ -193,7 +196,19 @@ pub struct RemovedBranch {
|
||||||
pub sender: RepositoryOwner,
|
pub sender: RepositoryOwner,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
impl From<Push> for Hook {
|
||||||
|
fn from(push: Push) -> Self {
|
||||||
|
Self::Push(push)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Issue> for Hook {
|
||||||
|
fn from(issue: Issue) -> Self {
|
||||||
|
Self::Issue(issue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum Hook {
|
pub enum Hook {
|
||||||
Push(Push),
|
Push(Push),
|
||||||
|
|
54
forgejo-hooks/src/tests/mod.rs
Normal file
54
forgejo-hooks/src/tests/mod.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright (C) 2024-2099 The crate authors.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify it
|
||||||
|
// under the terms of the GNU Affero General Public License as published by the
|
||||||
|
// Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
// option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
|
||||||
|
// for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use crate::{Hook, Push};
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
/// Deserializes the payload into a struct
|
||||||
|
fn parse<Output>(payload: &str) -> Result<Output, serde_path_to_error::Error<serde_json::Error>>
|
||||||
|
where
|
||||||
|
for<'a> Output: Deserialize<'a>,
|
||||||
|
{
|
||||||
|
let mut json = serde_json::Deserializer::from_str(payload);
|
||||||
|
serde_path_to_error::deserialize(&mut json)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tries to parse once into a specific type, then parses into Hook and ensure both match
|
||||||
|
fn parse_roundtrip<Output>(payload: &str) -> ()
|
||||||
|
where
|
||||||
|
for<'a> Output: Into<Hook> + Deserialize<'a> + PartialEq,
|
||||||
|
{
|
||||||
|
let res1: Result<Output, _> = parse(&payload);
|
||||||
|
match res1 {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(err) => panic!("Error: {err:?}"),
|
||||||
|
}
|
||||||
|
|
||||||
|
let res2: Result<Hook, _> = parse(&payload);
|
||||||
|
match res2 {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(err) => panic!("Error: {err:?}"),
|
||||||
|
}
|
||||||
|
|
||||||
|
let hook1: Output = res1.unwrap();
|
||||||
|
let hook2: Hook = res2.unwrap();
|
||||||
|
assert_eq!(Into::<Hook>::into(hook1), hook2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn push_payload() {
|
||||||
|
let payload = std::fs::read_to_string("src/tests/push.json").unwrap();
|
||||||
|
let _ = parse_roundtrip::<Push>(&payload);
|
||||||
|
}
|
198
forgejo-hooks/src/tests/push.json
Normal file
198
forgejo-hooks/src/tests/push.json
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
{
|
||||||
|
"ref": "refs/heads/main",
|
||||||
|
"before": "28cb105298bd70d268a1f1e7ff7f2b20ab9f1dc6",
|
||||||
|
"after": "76d3676e2516a20ee3a3819175594cf10b75fa91",
|
||||||
|
"compare_url": "https://code.bouah.net/pep/webhook-test/compare/28cb105298bd70d268a1f1e7ff7f2b20ab9f1dc6...76d3676e2516a20ee3a3819175594cf10b75fa91",
|
||||||
|
"commits": [{
|
||||||
|
"id": "76d3676e2516a20ee3a3819175594cf10b75fa91",
|
||||||
|
"message": "bar\\n\\nSigned-off-by: pep \\u003cpep@bouah.net\\u003e\\n",
|
||||||
|
"url": "https://code.bouah.net/pep/webhook-test/commit/76d3676e2516a20ee3a3819175594cf10b75fa91",
|
||||||
|
"author": {
|
||||||
|
"name": "pep",
|
||||||
|
"email": "pep@bouah.net",
|
||||||
|
"username": "pep"
|
||||||
|
},
|
||||||
|
"committer": {
|
||||||
|
"name": "pep",
|
||||||
|
"email": "pep@bouah.net",
|
||||||
|
"username": "pep"
|
||||||
|
},
|
||||||
|
"verification": null,
|
||||||
|
"timestamp": "2024-09-01T16:49:08+02:00",
|
||||||
|
"added": [],
|
||||||
|
"removed": [],
|
||||||
|
"modified": [
|
||||||
|
"foo"
|
||||||
|
]
|
||||||
|
}],
|
||||||
|
"total_commits": 1,
|
||||||
|
"head_commit": {
|
||||||
|
"id": "76d3676e2516a20ee3a3819175594cf10b75fa91",
|
||||||
|
"message": "bar\\n\\nSigned-off-by: pep \\u003cpep@bouah.net\\u003e\\n",
|
||||||
|
"url": "https://code.bouah.net/pep/webhook-test/commit/76d3676e2516a20ee3a3819175594cf10b75fa91",
|
||||||
|
"author": {
|
||||||
|
"name": "pep",
|
||||||
|
"email": "pep@bouah.net",
|
||||||
|
"username": "pep"
|
||||||
|
},
|
||||||
|
"committer": {
|
||||||
|
"name": "pep",
|
||||||
|
"email": "pep@bouah.net",
|
||||||
|
"username": "pep"
|
||||||
|
},
|
||||||
|
"verification": null,
|
||||||
|
"timestamp": "2024-09-01T16:49:08+02:00",
|
||||||
|
"added": [],
|
||||||
|
"removed": [],
|
||||||
|
"modified": [
|
||||||
|
"foo"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"id": 20,
|
||||||
|
"owner": {
|
||||||
|
"id": 1,
|
||||||
|
"login": "pep",
|
||||||
|
"login_name": "",
|
||||||
|
"source_id": 0,
|
||||||
|
"full_name": "",
|
||||||
|
"email": "pep@bouah.net",
|
||||||
|
"avatar_url": "https://code.bouah.net/avatars/7897535c1d4a7ed71eb7b9bc8773bed6",
|
||||||
|
"html_url": "https://code.bouah.net/pep",
|
||||||
|
"language": "",
|
||||||
|
"is_admin": false,
|
||||||
|
"last_login": "0001-01-01T00:00:00Z",
|
||||||
|
"created": "2023-01-02T21:57:48Z",
|
||||||
|
"restricted": false,
|
||||||
|
"active": false,
|
||||||
|
"prohibit_login": false,
|
||||||
|
"location": "",
|
||||||
|
"pronouns": "",
|
||||||
|
"website": "https://bouah.net",
|
||||||
|
"description": "",
|
||||||
|
"visibility": "public",
|
||||||
|
"followers_count": 0,
|
||||||
|
"following_count": 0,
|
||||||
|
"starred_repos_count": 0,
|
||||||
|
"username": "pep"
|
||||||
|
},
|
||||||
|
"name": "webhook-test",
|
||||||
|
"full_name": "pep/webhook-test",
|
||||||
|
"description": "",
|
||||||
|
"empty": false,
|
||||||
|
"private": false,
|
||||||
|
"fork": false,
|
||||||
|
"template": false,
|
||||||
|
"parent": null,
|
||||||
|
"mirror": false,
|
||||||
|
"size": 28,
|
||||||
|
"language": "",
|
||||||
|
"languages_url": "https://code.bouah.net/api/v1/repos/pep/webhook-test/languages",
|
||||||
|
"html_url": "https://code.bouah.net/pep/webhook-test",
|
||||||
|
"url": "https://code.bouah.net/api/v1/repos/pep/webhook-test",
|
||||||
|
"link": "",
|
||||||
|
"ssh_url": "forgejo@code.bouah.net:pep/webhook-test.git",
|
||||||
|
"clone_url": "https://code.bouah.net/pep/webhook-test.git",
|
||||||
|
"original_url": "",
|
||||||
|
"website": "",
|
||||||
|
"stars_count": 0,
|
||||||
|
"forks_count": 0,
|
||||||
|
"watchers_count": 1,
|
||||||
|
"open_issues_count": 5,
|
||||||
|
"open_pr_counter": 0,
|
||||||
|
"release_counter": 0,
|
||||||
|
"default_branch": "main",
|
||||||
|
"archived": false,
|
||||||
|
"created_at": "2024-04-23T11:49:34Z",
|
||||||
|
"updated_at": "2024-04-23T17:42:53Z",
|
||||||
|
"archived_at": "1970-01-01T00:00:00Z",
|
||||||
|
"permissions": {
|
||||||
|
"admin": true,
|
||||||
|
"push": true,
|
||||||
|
"pull": true
|
||||||
|
},
|
||||||
|
"has_issues": true,
|
||||||
|
"internal_tracker": {
|
||||||
|
"enable_time_tracker": false,
|
||||||
|
"allow_only_contributors_to_track_time": true,
|
||||||
|
"enable_issue_dependencies": true
|
||||||
|
},
|
||||||
|
"has_wiki": true,
|
||||||
|
"wiki_branch": "master",
|
||||||
|
"globally_editable_wiki": false,
|
||||||
|
"has_pull_requests": true,
|
||||||
|
"has_projects": true,
|
||||||
|
"has_releases": true,
|
||||||
|
"has_packages": true,
|
||||||
|
"has_actions": false,
|
||||||
|
"ignore_whitespace_conflicts": false,
|
||||||
|
"allow_merge_commits": true,
|
||||||
|
"allow_rebase": true,
|
||||||
|
"allow_rebase_explicit": true,
|
||||||
|
"allow_squash_merge": true,
|
||||||
|
"allow_fast_forward_only_merge": false,
|
||||||
|
"allow_rebase_update": true,
|
||||||
|
"default_delete_branch_after_merge": false,
|
||||||
|
"default_merge_style": "rebase",
|
||||||
|
"default_allow_maintainer_edit": false,
|
||||||
|
"avatar_url": "",
|
||||||
|
"internal": false,
|
||||||
|
"mirror_interval": "",
|
||||||
|
"object_format_name": "sha1",
|
||||||
|
"mirror_updated": "0001-01-01T00:00:00Z",
|
||||||
|
"repo_transfer": null,
|
||||||
|
"topics": null
|
||||||
|
},
|
||||||
|
"pusher": {
|
||||||
|
"id": 1,
|
||||||
|
"login": "pep",
|
||||||
|
"login_name": "",
|
||||||
|
"source_id": 0,
|
||||||
|
"full_name": "",
|
||||||
|
"email": "pep@forgejo-noreply",
|
||||||
|
"avatar_url": "https://code.bouah.net/avatars/7897535c1d4a7ed71eb7b9bc8773bed6",
|
||||||
|
"html_url": "https://code.bouah.net/pep",
|
||||||
|
"language": "",
|
||||||
|
"is_admin": false,
|
||||||
|
"last_login": "0001-01-01T00:00:00Z",
|
||||||
|
"created": "2023-01-02T21:57:48Z",
|
||||||
|
"restricted": false,
|
||||||
|
"active": false,
|
||||||
|
"prohibit_login": false,
|
||||||
|
"location": "",
|
||||||
|
"pronouns": "",
|
||||||
|
"website": "https://bouah.net",
|
||||||
|
"description": "",
|
||||||
|
"visibility": "public",
|
||||||
|
"followers_count": 0,
|
||||||
|
"following_count": 0,
|
||||||
|
"starred_repos_count": 0,
|
||||||
|
"username": "pep"
|
||||||
|
},
|
||||||
|
"sender": {
|
||||||
|
"id": 1,
|
||||||
|
"login": "pep",
|
||||||
|
"login_name": "",
|
||||||
|
"source_id": 0,
|
||||||
|
"full_name": "",
|
||||||
|
"email": "pep@forgejo-noreply",
|
||||||
|
"avatar_url": "https://code.bouah.net/avatars/7897535c1d4a7ed71eb7b9bc8773bed6",
|
||||||
|
"html_url": "https://code.bouah.net/pep",
|
||||||
|
"language": "",
|
||||||
|
"is_admin": false,
|
||||||
|
"last_login": "0001-01-01T00:00:00Z",
|
||||||
|
"created": "2023-01-02T21:57:48Z",
|
||||||
|
"restricted": false,
|
||||||
|
"active": false,
|
||||||
|
"prohibit_login": false,
|
||||||
|
"location": "",
|
||||||
|
"pronouns": "",
|
||||||
|
"website": "https://bouah.net",
|
||||||
|
"description": "",
|
||||||
|
"visibility": "public",
|
||||||
|
"followers_count": 0,
|
||||||
|
"following_count": 0,
|
||||||
|
"starred_repos_count": 0,
|
||||||
|
"username": "pep"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue