//! Copyright (c) 2022-2026 GitDataAi All rights reserved. mod common; use gitks::pb::tag_service_server::TagService; use gitks::pb::*; fn hdr() -> RepositoryHeader { RepositoryHeader { relative_path: "test-repo".into(), ..Default::default() } } #[tokio::test] async fn test_list_tags() { let (dir, _gb) = common::setup_bare_repo(); let svc = common::setup_service(dir.path()); let result = svc .list_tags(tonic::Request::new(ListTagsRequest { repository: Some(hdr()), pattern: String::new(), pagination: None, sort_direction: 0, })) .await .unwrap() .into_inner(); let names: Vec = result.tags.iter().map(|t| t.name.clone()).collect(); assert!(names.contains(&"v0.1.0".to_string())); } #[tokio::test] async fn test_get_tag() { let (dir, _gb) = common::setup_bare_repo(); let svc = common::setup_service(dir.path()); let tag = svc .get_tag(tonic::Request::new(GetTagRequest { repository: Some(hdr()), name: "v0.1.0".into(), include_raw: false, })) .await .unwrap() .into_inner(); assert_eq!(tag.name, "v0.1.0"); assert!(tag.target_oid.is_some()); assert_eq!(tag.full_ref, "refs/tags/v0.1.0"); } #[tokio::test] async fn test_create_and_delete_lightweight_tag() { let (dir, _gb) = common::setup_bare_repo(); let svc = common::setup_service(dir.path()); let tag = svc .create_tag(tonic::Request::new(CreateTagRequest { repository: Some(hdr()), name: "v0.2.0".into(), target: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main".into(), })), }), message: String::new(), tagger: None, force: false, annotated: false, })) .await .unwrap() .into_inner(); assert_eq!(tag.name, "v0.2.0"); assert!(!tag.annotated); svc.delete_tag(tonic::Request::new(DeleteTagRequest { repository: Some(hdr()), name: "v0.2.0".into(), })) .await .unwrap(); let result = svc .get_tag(tonic::Request::new(GetTagRequest { repository: Some(hdr()), name: "v0.2.0".into(), include_raw: false, })) .await; assert!(result.is_err(), "deleted tag should not exist"); } #[tokio::test] async fn test_create_annotated_tag() { let (dir, _gb) = common::setup_bare_repo(); let svc = common::setup_service(dir.path()); let tag = svc .create_tag(tonic::Request::new(CreateTagRequest { repository: Some(hdr()), name: "v1.0.0".into(), target: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main".into(), })), }), message: "Release v1.0.0".into(), tagger: None, force: false, annotated: true, })) .await .unwrap() .into_inner(); assert_eq!(tag.name, "v1.0.0"); assert!(tag.annotated, "should be annotated"); assert!(tag.tag_oid.is_some(), "annotated tag should have tag_oid"); assert!( tag.message.contains("Release v1.0.0"), "message should be set" ); } #[tokio::test] async fn test_list_tags_with_pattern() { let (dir, _gb) = common::setup_bare_repo(); let svc = common::setup_service(dir.path()); svc.create_tag(tonic::Request::new(CreateTagRequest { repository: Some(hdr()), name: "release-1.0".into(), target: Some(ObjectSelector { selector: Some(object_selector::Selector::Revision(ObjectName { revision: "main".into(), })), }), message: String::new(), tagger: None, force: false, annotated: false, })) .await .unwrap(); let result = svc .list_tags(tonic::Request::new(ListTagsRequest { repository: Some(hdr()), pattern: "release".into(), pagination: None, sort_direction: 0, })) .await .unwrap() .into_inner(); assert!( result.tags.iter().all(|t| t.name.contains("release")), "all tags should match pattern" ); assert!(!result.tags.is_empty()); } #[tokio::test] async fn test_verify_tag() { let (dir, _gb) = common::setup_bare_repo(); let svc = common::setup_service(dir.path()); let result = svc .verify_tag(tonic::Request::new(VerifyTagRequest { repository: Some(hdr()), name: "v0.1.0".into(), })) .await .unwrap() .into_inner(); assert!(!result.verified, "unsigned tag should not be verified"); }