diff --git a/ee/tabby-db/migrations/0027_remove-github-repository-columns-on-oauth.up.sql b/ee/tabby-db/migrations/0027_remove-github-repository-columns-on-oauth.up.sql index 424f642b519d..d8116958d01d 100644 --- a/ee/tabby-db/migrations/0027_remove-github-repository-columns-on-oauth.up.sql +++ b/ee/tabby-db/migrations/0027_remove-github-repository-columns-on-oauth.up.sql @@ -3,5 +3,6 @@ DROP TABLE github_repository_provider; CREATE TABLE github_repository_provider( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, display_name TEXT NOT NULL, - access_token TEXT + access_token TEXT, + synced_at TIMESTAMP ); diff --git a/ee/tabby-db/migrations/0028_gitlab-provider.up.sql b/ee/tabby-db/migrations/0028_gitlab-provider.up.sql index 4c1103d69d07..f0e387f91ca8 100644 --- a/ee/tabby-db/migrations/0028_gitlab-provider.up.sql +++ b/ee/tabby-db/migrations/0028_gitlab-provider.up.sql @@ -1,7 +1,8 @@ CREATE TABLE gitlab_repository_provider( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, display_name TEXT NOT NULL, - access_token TEXT + access_token TEXT, + synced_at TIMESTAMP ); CREATE TABLE gitlab_provided_repositories( diff --git a/ee/tabby-db/schema.sqlite b/ee/tabby-db/schema.sqlite index 325abece2c60..e9dce0a00e75 100644 Binary files a/ee/tabby-db/schema.sqlite and b/ee/tabby-db/schema.sqlite differ diff --git a/ee/tabby-db/schema/schema.sql b/ee/tabby-db/schema/schema.sql index e855a24eb36d..30bee964deb0 100644 --- a/ee/tabby-db/schema/schema.sql +++ b/ee/tabby-db/schema/schema.sql @@ -147,12 +147,14 @@ CREATE TABLE password_reset( CREATE TABLE github_repository_provider( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, display_name TEXT NOT NULL, - access_token TEXT + access_token TEXT, + synced_at TIMESTAMP ); CREATE TABLE gitlab_repository_provider( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, display_name TEXT NOT NULL, - access_token TEXT + access_token TEXT, + synced_at TIMESTAMP ); CREATE TABLE gitlab_provided_repositories( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, diff --git a/ee/tabby-db/schema/schema.svg b/ee/tabby-db/schema/schema.svg index 096664001962..adb349a8a540 100644 --- a/ee/tabby-db/schema/schema.svg +++ b/ee/tabby-db/schema/schema.svg @@ -128,6 +128,10 @@   access_token + +  + +synced_at @@ -186,6 +190,10 @@   access_token + +  + +synced_at diff --git a/ee/tabby-db/src/github_repository_provider.rs b/ee/tabby-db/src/github_repository_provider.rs index f6c666783a0c..3be170a834f3 100644 --- a/ee/tabby-db/src/github_repository_provider.rs +++ b/ee/tabby-db/src/github_repository_provider.rs @@ -9,6 +9,7 @@ pub struct GithubRepositoryProviderDAO { pub id: i64, pub display_name: String, pub access_token: Option, + pub synced_at: Option, } #[derive(FromRow)] @@ -36,7 +37,7 @@ impl DbConn { pub async fn get_github_provider(&self, id: i64) -> Result { let provider = query_as!( GithubRepositoryProviderDAO, - "SELECT id, display_name, access_token FROM github_repository_provider WHERE id = ?;", + r#"SELECT id, display_name, access_token, synced_at AS "synced_at: DateTimeUtc" FROM github_repository_provider WHERE id = ?;"#, id ) .fetch_one(&self.pool) @@ -54,23 +55,6 @@ impl DbConn { Ok(()) } - pub async fn reset_github_provider_access_token(&self, id: i64) -> Result<()> { - let res = query!( - "UPDATE github_repository_provider SET access_token = NULL WHERE id = ?", - id - ) - .execute(&self.pool) - .await?; - - if res.rows_affected() != 1 { - return Err(anyhow!( - "The specified Github repository provider does not exist" - )); - } - - Ok(()) - } - pub async fn update_github_provider( &self, id: i64, @@ -95,6 +79,19 @@ impl DbConn { Ok(()) } + pub async fn update_github_provider_sync_status(&self, id: i64, success: bool) -> Result<()> { + let time = success.then_some(DateTimeUtc::now()); + query!( + "UPDATE github_repository_provider SET synced_at = ?, access_token = IIF(?, access_token, NULL) WHERE id = ?", + time, + success, + id + ) + .execute(&self.pool) + .await?; + Ok(()) + } + pub async fn list_github_repository_providers( &self, ids: Vec, @@ -113,7 +110,7 @@ impl DbConn { let providers = query_paged_as!( GithubRepositoryProviderDAO, "github_repository_provider", - ["id", "display_name", "access_token"], + ["id", "display_name", "access_token", "synced_at" as "synced_at: DateTimeUtc"], limit, skip_id, backwards, diff --git a/ee/tabby-db/src/gitlab_repository_provider.rs b/ee/tabby-db/src/gitlab_repository_provider.rs index 509498333185..e12dddb37781 100644 --- a/ee/tabby-db/src/gitlab_repository_provider.rs +++ b/ee/tabby-db/src/gitlab_repository_provider.rs @@ -9,6 +9,7 @@ pub struct GitlabRepositoryProviderDAO { pub id: i64, pub display_name: String, pub access_token: Option, + pub synced_at: Option, } #[derive(FromRow)] @@ -36,7 +37,7 @@ impl DbConn { pub async fn get_gitlab_provider(&self, id: i64) -> Result { let provider = query_as!( GitlabRepositoryProviderDAO, - "SELECT id, display_name, access_token FROM gitlab_repository_provider WHERE id = ?;", + r#"SELECT id, display_name, access_token, synced_at AS "synced_at: DateTimeUtc" FROM gitlab_repository_provider WHERE id = ?;"#, id ) .fetch_one(&self.pool) @@ -54,23 +55,6 @@ impl DbConn { Ok(()) } - pub async fn reset_gitlab_provider_access_token(&self, id: i64) -> Result<()> { - let res = query!( - "UPDATE gitlab_repository_provider SET access_token = NULL WHERE id = ?", - id - ) - .execute(&self.pool) - .await?; - - if res.rows_affected() != 1 { - return Err(anyhow!( - "The specified gitlab repository provider does not exist" - )); - } - - Ok(()) - } - pub async fn update_gitlab_provider( &self, id: i64, @@ -95,6 +79,19 @@ impl DbConn { Ok(()) } + pub async fn update_gitlab_provider_sync_status(&self, id: i64, success: bool) -> Result<()> { + let time = success.then_some(DateTimeUtc::now()); + query!( + "UPDATE gitlab_repository_provider SET synced_at = ?, access_token = IIF(?, access_token, NULL) WHERE id = ?", + time, + success, + id + ) + .execute(&self.pool) + .await?; + Ok(()) + } + pub async fn list_gitlab_repository_providers( &self, ids: Vec, @@ -113,7 +110,7 @@ impl DbConn { let providers = query_paged_as!( GitlabRepositoryProviderDAO, "gitlab_repository_provider", - ["id", "display_name", "access_token"], + ["id", "display_name", "access_token", "synced_at" as "synced_at: DateTimeUtc"], limit, skip_id, backwards, diff --git a/ee/tabby-ui/app/(dashboard)/settings/(integrations)/repository/github/components/github-form.tsx b/ee/tabby-ui/app/(dashboard)/settings/(integrations)/repository/github/components/github-form.tsx index 2b1c11cee917..0284528294fb 100644 --- a/ee/tabby-ui/app/(dashboard)/settings/(integrations)/repository/github/components/github-form.tsx +++ b/ee/tabby-ui/app/(dashboard)/settings/(integrations)/repository/github/components/github-form.tsx @@ -34,13 +34,7 @@ import { IconExternalLink, IconSpinner } from '@/components/ui/icons' import { Input } from '@/components/ui/input' export const createGithubProviderSchema = z.object({ - displayName: z - .string() - .trim() - .regex( - /^[\w-]+$/, - 'Display name must contain only alphanumeric characters, underscores, and hyphens' - ), + displayName: z.string(), accessToken: z.string() }) diff --git a/ee/tabby-ui/app/(dashboard)/settings/(integrations)/repository/github/components/github.tsx b/ee/tabby-ui/app/(dashboard)/settings/(integrations)/repository/github/components/github.tsx index 0535c097248c..39352adcf59b 100644 --- a/ee/tabby-ui/app/(dashboard)/settings/(integrations)/repository/github/components/github.tsx +++ b/ee/tabby-ui/app/(dashboard)/settings/(integrations)/repository/github/components/github.tsx @@ -3,7 +3,10 @@ import Link from 'next/link' import { useQuery } from 'urql' -import { ListGithubRepositoryProvidersQuery } from '@/lib/gql/generates/graphql' +import { + ListGithubRepositoryProvidersQuery, + RepositoryProviderStatus +} from '@/lib/gql/generates/graphql' import { listGithubRepositoryProviders } from '@/lib/tabby/query' import { buttonVariants } from '@/components/ui/button' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' @@ -65,11 +68,7 @@ const GitProvidersList: React.FC = ({ data }) => { Status - - {item.node?.connected - ? 'Connected' - : 'access_token needs update'} - + {toStatusMessage(item.node.status)} @@ -79,6 +78,17 @@ const GitProvidersList: React.FC = ({ data }) => { ) } +function toStatusMessage(status: RepositoryProviderStatus) { + switch (status) { + case RepositoryProviderStatus.Ready: + return 'Ready' + case RepositoryProviderStatus.Error: + return 'Processing error. Please check if the access token is still valid' + case RepositoryProviderStatus.Pending: + return 'Awaiting the next data synchronization' + } +} + const GitProvidersPlaceholder = () => { return (
diff --git a/ee/tabby-ui/app/(dashboard)/settings/(integrations)/repository/github/detail/components/detail.tsx b/ee/tabby-ui/app/(dashboard)/settings/(integrations)/repository/github/detail/components/detail.tsx index 5427f9251f5f..4e5f50cbf409 100644 --- a/ee/tabby-ui/app/(dashboard)/settings/(integrations)/repository/github/detail/components/detail.tsx +++ b/ee/tabby-ui/app/(dashboard)/settings/(integrations)/repository/github/detail/components/detail.tsx @@ -5,6 +5,7 @@ import { useRouter, useSearchParams } from 'next/navigation' import { useQuery } from 'urql' import { DEFAULT_PAGE_SIZE } from '@/lib/constants' +import { RepositoryProviderStatus } from '@/lib/gql/generates/graphql' import { QueryResponseData, QueryVariables, useMutation } from '@/lib/tabby/gql' import { listGithubRepositories, @@ -68,7 +69,7 @@ const DetailPage: React.FC = () => { return ( - +
- {provider?.connected ? ( - Connected - ) : ( - Not Connected - )} + {provider && toStatusBadge(provider.status)}
@@ -108,6 +105,17 @@ const DetailPage: React.FC = () => { ) } +function toStatusBadge(status: RepositoryProviderStatus) { + switch (status) { + case RepositoryProviderStatus.Ready: + return Ready + case RepositoryProviderStatus.Error: + return Error + case RepositoryProviderStatus.Error: + return Pending + } +} + const LinkedRepoTable: React.FC<{ data: GithubRepositories | undefined onDelete?: () => void diff --git a/ee/tabby-ui/lib/tabby/query.ts b/ee/tabby-ui/lib/tabby/query.ts index 3b630e042025..dfb099da152b 100644 --- a/ee/tabby-ui/lib/tabby/query.ts +++ b/ee/tabby-ui/lib/tabby/query.ts @@ -186,7 +186,7 @@ export const listGithubRepositoryProviders = graphql(/* GraphQL */ ` node { id displayName - connected + status } cursor } diff --git a/ee/tabby-webserver/graphql/schema.graphql b/ee/tabby-webserver/graphql/schema.graphql index 0f940e9425bd..f386e0cece92 100644 --- a/ee/tabby-webserver/graphql/schema.graphql +++ b/ee/tabby-webserver/graphql/schema.graphql @@ -13,7 +13,7 @@ input UpdateRepositoryProviderInput { type GitlabRepositoryProvider { id: ID! displayName: String! - connected: Boolean! + status: RepositoryProviderStatus! } enum Language { @@ -119,6 +119,12 @@ type UserConnection { pageInfo: PageInfo! } +enum RepositoryProviderStatus { + READY + PENDING + ERROR +} + type DiskUsageStats { events: DiskUsage! indexedRepositories: DiskUsage! @@ -142,7 +148,7 @@ type ServerInfo { type GithubRepositoryProvider { id: ID! displayName: String! - connected: Boolean! + status: RepositoryProviderStatus! } input PasswordChangeInput { diff --git a/ee/tabby-webserver/src/cron/github.rs b/ee/tabby-webserver/src/cron/github.rs index 4d49a3a1e3fa..bef73e9f4b3b 100644 --- a/ee/tabby-webserver/src/cron/github.rs +++ b/ee/tabby-webserver/src/cron/github.rs @@ -38,7 +38,7 @@ async fn refresh_repositories_for_provider( .. }) if source.status_code.is_client_error() => { service - .reset_github_repository_provider_access_token(provider.id.clone()) + .update_github_repository_provider_sync_status(provider.id.clone(), false) .await?; warn!( "GitHub credentials for provider {} are expired or invalid", @@ -66,6 +66,9 @@ async fn refresh_repositories_for_provider( .upsert_github_provided_repository(provider.id.clone(), id, repo.name, url) .await?; } + service + .update_github_repository_provider_sync_status(provider.id.clone(), true) + .await?; Ok(()) } diff --git a/ee/tabby-webserver/src/cron/gitlab.rs b/ee/tabby-webserver/src/cron/gitlab.rs index 1639c673d14b..6c7e27ec28fd 100644 --- a/ee/tabby-webserver/src/cron/gitlab.rs +++ b/ee/tabby-webserver/src/cron/gitlab.rs @@ -39,7 +39,7 @@ async fn refresh_repositories_for_provider( Ok(repos) => repos, Err(e) if e.to_string().contains("401 Unauthorized") => { service - .reset_gitlab_repository_provider_access_token(provider.id.clone()) + .update_gitlab_repository_provider_sync_status(provider.id.clone(), false) .await?; warn!( "GitLab credentials for provider {} are expired or invalid", @@ -64,6 +64,9 @@ async fn refresh_repositories_for_provider( ) .await?; } + service + .update_gitlab_repository_provider_sync_status(provider.id.clone(), true) + .await?; Ok(()) } diff --git a/ee/tabby-webserver/src/schema/github_repository_provider.rs b/ee/tabby-webserver/src/schema/github_repository_provider.rs index fdf4ebaf319e..3412729f2b6e 100644 --- a/ee/tabby-webserver/src/schema/github_repository_provider.rs +++ b/ee/tabby-webserver/src/schema/github_repository_provider.rs @@ -2,7 +2,7 @@ use async_trait::async_trait; use chrono::{DateTime, Utc}; use juniper::{GraphQLObject, ID}; -use super::{repository::RepositoryProvider, Context}; +use super::{repository::RepositoryProvider, types::RepositoryProviderStatus, Context}; use crate::{juniper::relay::NodeType, schema::Result}; #[derive(GraphQLObject, Debug, PartialEq)] @@ -11,7 +11,7 @@ pub struct GithubRepositoryProvider { pub id: ID, pub display_name: String, - pub connected: bool, + pub status: RepositoryProviderStatus, #[graphql(skip)] pub access_token: Option, @@ -75,7 +75,11 @@ pub trait GithubRepositoryProviderService: Send + Sync + RepositoryProvider { display_name: String, access_token: String, ) -> Result<()>; - async fn reset_github_repository_provider_access_token(&self, id: ID) -> Result<()>; + async fn update_github_repository_provider_sync_status( + &self, + id: ID, + success: bool, + ) -> Result<()>; async fn list_github_repository_providers( &self, diff --git a/ee/tabby-webserver/src/schema/gitlab_repository_provider.rs b/ee/tabby-webserver/src/schema/gitlab_repository_provider.rs index 71316f44aa6f..b446ddbe80ca 100644 --- a/ee/tabby-webserver/src/schema/gitlab_repository_provider.rs +++ b/ee/tabby-webserver/src/schema/gitlab_repository_provider.rs @@ -2,7 +2,7 @@ use async_trait::async_trait; use chrono::{DateTime, Utc}; use juniper::{GraphQLObject, ID}; -use super::{repository::RepositoryProvider, Context}; +use super::{repository::RepositoryProvider, types::RepositoryProviderStatus, Context}; use crate::{juniper::relay::NodeType, schema::Result}; #[derive(GraphQLObject, Debug, PartialEq)] @@ -11,7 +11,7 @@ pub struct GitlabRepositoryProvider { pub id: ID, pub display_name: String, - pub connected: bool, + pub status: RepositoryProviderStatus, #[graphql(skip)] pub access_token: Option, @@ -75,7 +75,11 @@ pub trait GitlabRepositoryProviderService: Send + Sync + RepositoryProvider { display_name: String, access_token: String, ) -> Result<()>; - async fn reset_gitlab_repository_provider_access_token(&self, id: ID) -> Result<()>; + async fn update_gitlab_repository_provider_sync_status( + &self, + id: ID, + success: bool, + ) -> Result<()>; async fn list_gitlab_repository_providers( &self, diff --git a/ee/tabby-webserver/src/schema/types.rs b/ee/tabby-webserver/src/schema/types.rs index 06ff4ceed7c7..caff9449b590 100644 --- a/ee/tabby-webserver/src/schema/types.rs +++ b/ee/tabby-webserver/src/schema/types.rs @@ -1,4 +1,4 @@ -use juniper::{GraphQLInputObject, ID}; +use juniper::{GraphQLEnum, GraphQLInputObject, ID}; use validator::Validate; #[derive(GraphQLInputObject, Validate)] @@ -23,3 +23,20 @@ pub struct UpdateRepositoryProviderInput { #[validate(length(code = "access_token", min = 10))] pub access_token: String, } + +#[derive(GraphQLEnum, Debug, PartialEq)] +pub enum RepositoryProviderStatus { + Ready, + Pending, + Error, +} + +impl RepositoryProviderStatus { + pub fn new(access_token_set: bool, synced_at_set: bool) -> Self { + match (access_token_set, synced_at_set) { + (true, true) => RepositoryProviderStatus::Ready, + (true, false) => RepositoryProviderStatus::Pending, + _ => RepositoryProviderStatus::Error, + } + } +} diff --git a/ee/tabby-webserver/src/service/dao.rs b/ee/tabby-webserver/src/service/dao.rs index 6d8b0dca8765..620abd705e57 100644 --- a/ee/tabby-webserver/src/service/dao.rs +++ b/ee/tabby-webserver/src/service/dao.rs @@ -16,6 +16,7 @@ use crate::{ gitlab_repository_provider::{GitlabProvidedRepository, GitlabRepositoryProvider}, job, setting::{NetworkSetting, SecuritySetting}, + types::RepositoryProviderStatus, user_event::{EventKind, UserEvent}, CoreError, }, @@ -130,7 +131,10 @@ impl From for GithubRepositoryProvider { Self { display_name: value.display_name, id: value.id.as_id(), - connected: value.access_token.is_some(), + status: RepositoryProviderStatus::new( + value.access_token.is_some(), + value.synced_at.is_some(), + ), access_token: value.access_token, } } @@ -154,7 +158,10 @@ impl From for GitlabRepositoryProvider { Self { display_name: value.display_name, id: value.id.as_id(), - connected: value.access_token.is_some(), + status: RepositoryProviderStatus::new( + value.access_token.is_some(), + value.synced_at.is_some(), + ), access_token: value.access_token, } } diff --git a/ee/tabby-webserver/src/service/github_repository_provider.rs b/ee/tabby-webserver/src/service/github_repository_provider.rs index fb78553415fb..b5d764929599 100644 --- a/ee/tabby-webserver/src/service/github_repository_provider.rs +++ b/ee/tabby-webserver/src/service/github_repository_provider.rs @@ -50,13 +50,6 @@ impl GithubRepositoryProviderService for GithubRepositoryProviderServiceImpl { Ok(()) } - async fn reset_github_repository_provider_access_token(&self, id: ID) -> Result<()> { - self.db - .reset_github_provider_access_token(id.as_rowid()?) - .await?; - Ok(()) - } - async fn list_github_repository_providers( &self, ids: Vec, @@ -183,6 +176,17 @@ impl GithubRepositoryProviderService for GithubRepositoryProviderServiceImpl { .await?; Ok(()) } + + async fn update_github_repository_provider_sync_status( + &self, + id: ID, + success: bool, + ) -> Result<()> { + self.db + .update_github_provider_sync_status(id.as_rowid()?, success) + .await?; + Ok(()) + } } #[async_trait] @@ -217,7 +221,7 @@ mod tests { use chrono::Duration; use super::*; - use crate::service::AsID; + use crate::{schema::types::RepositoryProviderStatus, service::AsID}; #[tokio::test] async fn test_github_provided_repositories() { @@ -318,7 +322,7 @@ mod tests { id: id.clone(), display_name: "id".into(), access_token: Some("secret".into()), - connected: true, + status: RepositoryProviderStatus::Pending, } ); @@ -330,21 +334,6 @@ mod tests { assert_eq!(providers.len(), 1); assert_eq!(providers[0].access_token, Some("secret".into())); - // Test resetgithub provider tokens - service - .reset_github_repository_provider_access_token(id.clone()) - .await - .unwrap(); - - assert_eq!( - service - .get_github_repository_provider(id.clone()) - .await - .unwrap() - .access_token, - None - ); - // Test deleting github provider service .delete_github_repository_provider(id.clone()) @@ -392,6 +381,37 @@ mod tests { ); } + #[tokio::test] + async fn test_sync_status() { + let db = DbConn::new_in_memory().await.unwrap(); + let service = create(db.clone()); + + let provider_id = db + .create_github_provider("provider1".into(), "token".into()) + .await + .unwrap(); + + service + .update_github_repository_provider_sync_status(provider_id.as_id(), true) + .await + .unwrap(); + + let provider = db.get_github_provider(provider_id).await.unwrap(); + + assert!(provider.access_token.is_some()); + assert!(provider.synced_at.is_some()); + + service + .update_github_repository_provider_sync_status(provider_id.as_id(), false) + .await + .unwrap(); + + let provider = db.get_github_provider(provider_id).await.unwrap(); + + assert!(provider.access_token.is_none()); + assert!(provider.synced_at.is_none()); + } + #[tokio::test] async fn test_delete_outdated_repos() { let db = DbConn::new_in_memory().await.unwrap(); diff --git a/ee/tabby-webserver/src/service/gitlab_repository_provider.rs b/ee/tabby-webserver/src/service/gitlab_repository_provider.rs index 5c4d328d75cd..a948f9377ee0 100644 --- a/ee/tabby-webserver/src/service/gitlab_repository_provider.rs +++ b/ee/tabby-webserver/src/service/gitlab_repository_provider.rs @@ -50,13 +50,6 @@ impl GitlabRepositoryProviderService for GitlabRepositoryProviderServiceImpl { Ok(()) } - async fn reset_gitlab_repository_provider_access_token(&self, id: ID) -> Result<()> { - self.db - .reset_gitlab_provider_access_token(id.as_rowid()?) - .await?; - Ok(()) - } - async fn list_gitlab_repository_providers( &self, ids: Vec, @@ -186,6 +179,17 @@ impl GitlabRepositoryProviderService for GitlabRepositoryProviderServiceImpl { .await?; Ok(()) } + + async fn update_gitlab_repository_provider_sync_status( + &self, + id: ID, + success: bool, + ) -> Result<()> { + self.db + .update_gitlab_provider_sync_status(id.as_rowid()?, success) + .await?; + Ok(()) + } } fn deduplicate_gitlab_repositories(repositories: &mut Vec) { @@ -220,7 +224,7 @@ mod tests { use chrono::Duration; use super::*; - use crate::service::AsID; + use crate::{schema::types::RepositoryProviderStatus, service::AsID}; #[tokio::test] async fn test_gitlab_provided_repositories() { @@ -321,7 +325,7 @@ mod tests { id: id.clone(), display_name: "id".into(), access_token: Some("secret".into()), - connected: true, + status: RepositoryProviderStatus::Pending } ); @@ -333,21 +337,6 @@ mod tests { assert_eq!(providers.len(), 1); assert_eq!(providers[0].access_token, Some("secret".into())); - // Test resetgitlab provider tokens - service - .reset_gitlab_repository_provider_access_token(id.clone()) - .await - .unwrap(); - - assert_eq!( - service - .get_gitlab_repository_provider(id.clone()) - .await - .unwrap() - .access_token, - None - ); - // Test deleting gitlab provider service .delete_gitlab_repository_provider(id.clone()) @@ -364,6 +353,37 @@ mod tests { ); } + #[tokio::test] + async fn test_sync_status() { + let db = DbConn::new_in_memory().await.unwrap(); + let service = create(db.clone()); + + let provider_id = db + .create_gitlab_provider("provider1".into(), "token".into()) + .await + .unwrap(); + + service + .update_gitlab_repository_provider_sync_status(provider_id.as_id(), true) + .await + .unwrap(); + + let provider = db.get_gitlab_provider(provider_id).await.unwrap(); + + assert!(provider.access_token.is_some()); + assert!(provider.synced_at.is_some()); + + service + .update_gitlab_repository_provider_sync_status(provider_id.as_id(), false) + .await + .unwrap(); + + let provider = db.get_gitlab_provider(provider_id).await.unwrap(); + + assert!(provider.access_token.is_none()); + assert!(provider.synced_at.is_none()); + } + #[tokio::test] async fn test_provided_git_urls() { let db = DbConn::new_in_memory().await.unwrap();