forgejo-hooks: Add failing tests

Signed-off-by: pep <pep@bouah.net>
This commit is contained in:
pep 2024-09-04 16:27:56 +02:00
parent 979dc50644
commit 25eeacde7c
4 changed files with 285 additions and 14 deletions

View file

@ -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"

View file

@ -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),

View 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);
}

View 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"
}
}