ci: add quality workflow and notifier test coverage
This commit is contained in:
parent
6912e51b14
commit
608ed32eac
3 changed files with 188 additions and 18 deletions
53
.github/workflows/quality.yml
vendored
Normal file
53
.github/workflows/quality.yml
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
name: Quality
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ["main"]
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
quality:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Linux system deps for Tauri
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y \
|
||||||
|
pkg-config \
|
||||||
|
libwebkit2gtk-4.1-dev \
|
||||||
|
libsoup-3.0-dev \
|
||||||
|
libjavascriptcoregtk-4.1-dev
|
||||||
|
|
||||||
|
- name: Setup Node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 22
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Setup Rust
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
|
- name: Install JS deps
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Check system deps script
|
||||||
|
run: npm run deps:check
|
||||||
|
|
||||||
|
- name: Frontend typecheck
|
||||||
|
run: npx tsc --noEmit
|
||||||
|
|
||||||
|
- name: Rust check
|
||||||
|
working-directory: src-tauri
|
||||||
|
run: cargo check
|
||||||
|
|
||||||
|
- name: Rust tests
|
||||||
|
working-directory: src-tauri
|
||||||
|
run: cargo test
|
||||||
|
|
||||||
|
- name: Rust clippy
|
||||||
|
working-directory: src-tauri
|
||||||
|
run: cargo clippy -- -D warnings
|
||||||
|
|
@ -9,7 +9,12 @@
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"tauri": "tauri",
|
"tauri": "tauri",
|
||||||
"deps:check": "bash scripts/tauri-system-deps.sh check",
|
"deps:check": "bash scripts/tauri-system-deps.sh check",
|
||||||
"deps:install": "bash scripts/tauri-system-deps.sh install"
|
"deps:install": "bash scripts/tauri-system-deps.sh install",
|
||||||
|
"qa:frontend": "npx tsc --noEmit",
|
||||||
|
"qa:backend:check": "cd src-tauri && cargo check",
|
||||||
|
"qa:backend:test": "cd src-tauri && cargo test",
|
||||||
|
"qa:backend:clippy": "cd src-tauri && cargo clippy -- -D warnings",
|
||||||
|
"qa": "npm run qa:frontend && npm run qa:backend:check && npm run qa:backend:test && npm run qa:backend:clippy"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^2.10.1",
|
"@tauri-apps/api": "^2.10.1",
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,26 @@ use rusqlite::Connection;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use tauri::{AppHandle, Emitter};
|
use tauri::{AppHandle, Emitter};
|
||||||
|
|
||||||
|
pub fn create(
|
||||||
|
db: &Arc<Mutex<Connection>>,
|
||||||
|
project_id: &str,
|
||||||
|
ticket_id: Option<&str>,
|
||||||
|
notification_type: &str,
|
||||||
|
title: &str,
|
||||||
|
message: &str,
|
||||||
|
) -> Result<Notification, String> {
|
||||||
|
let conn = db.lock().map_err(|e| format!("DB lock failed: {}", e))?;
|
||||||
|
Notification::insert(
|
||||||
|
&conn,
|
||||||
|
project_id,
|
||||||
|
ticket_id,
|
||||||
|
notification_type,
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
)
|
||||||
|
.map_err(|e| format!("Failed to insert notification: {}", e))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_and_emit(
|
pub fn create_and_emit(
|
||||||
db: &Arc<Mutex<Connection>>,
|
db: &Arc<Mutex<Connection>>,
|
||||||
app_handle: &AppHandle,
|
app_handle: &AppHandle,
|
||||||
|
|
@ -12,18 +32,7 @@ pub fn create_and_emit(
|
||||||
title: &str,
|
title: &str,
|
||||||
message: &str,
|
message: &str,
|
||||||
) -> Result<Notification, String> {
|
) -> Result<Notification, String> {
|
||||||
let notification = {
|
let notification = create(db, project_id, ticket_id, notification_type, title, message)?;
|
||||||
let conn = db.lock().map_err(|e| format!("DB lock failed: {}", e))?;
|
|
||||||
Notification::insert(
|
|
||||||
&conn,
|
|
||||||
project_id,
|
|
||||||
ticket_id,
|
|
||||||
notification_type,
|
|
||||||
title,
|
|
||||||
message,
|
|
||||||
)
|
|
||||||
.map_err(|e| format!("Failed to insert notification: {}", e))?
|
|
||||||
};
|
|
||||||
|
|
||||||
let _ = app_handle.emit(
|
let _ = app_handle.emit(
|
||||||
"new-notification",
|
"new-notification",
|
||||||
|
|
@ -35,6 +44,14 @@ pub fn create_and_emit(
|
||||||
Ok(notification)
|
Ok(notification)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn error_message(error: &str) -> String {
|
||||||
|
if error.is_empty() {
|
||||||
|
"Erreur lors du traitement du ticket".to_string()
|
||||||
|
} else {
|
||||||
|
error.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn notify_new_ticket(
|
pub fn notify_new_ticket(
|
||||||
db: &Arc<Mutex<Connection>>,
|
db: &Arc<Mutex<Connection>>,
|
||||||
app_handle: &AppHandle,
|
app_handle: &AppHandle,
|
||||||
|
|
@ -105,11 +122,7 @@ pub fn notify_error(
|
||||||
error: &str,
|
error: &str,
|
||||||
) {
|
) {
|
||||||
let title = format!("Erreur ticket #{}", artifact_id);
|
let title = format!("Erreur ticket #{}", artifact_id);
|
||||||
let message = if error.is_empty() {
|
let message = error_message(error);
|
||||||
"Erreur lors du traitement du ticket".to_string()
|
|
||||||
} else {
|
|
||||||
error.to_string()
|
|
||||||
};
|
|
||||||
|
|
||||||
let _ = create_and_emit(
|
let _ = create_and_emit(
|
||||||
db,
|
db,
|
||||||
|
|
@ -121,3 +134,102 @@ pub fn notify_error(
|
||||||
&message,
|
&message,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::db;
|
||||||
|
use crate::models::project::Project;
|
||||||
|
use crate::models::ticket::ProcessedTicket;
|
||||||
|
use crate::models::tracker::{AgentConfig, WatchedTracker};
|
||||||
|
|
||||||
|
fn setup() -> (Arc<Mutex<Connection>>, String) {
|
||||||
|
let conn = db::init_in_memory().expect("db init should succeed");
|
||||||
|
let project = Project::insert(&conn, "Notif Project", "/tmp/notif", None, "main")
|
||||||
|
.expect("project insert should succeed");
|
||||||
|
(Arc::new(Mutex::new(conn)), project.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_ticket(db: &Arc<Mutex<Connection>>, project_id: &str) -> String {
|
||||||
|
let conn = db.lock().expect("db lock should succeed");
|
||||||
|
|
||||||
|
let tracker = WatchedTracker::insert(
|
||||||
|
&conn,
|
||||||
|
project_id,
|
||||||
|
101,
|
||||||
|
"Bugs",
|
||||||
|
10,
|
||||||
|
AgentConfig {
|
||||||
|
analyst_command: "echo".to_string(),
|
||||||
|
analyst_args: vec![],
|
||||||
|
developer_command: "echo".to_string(),
|
||||||
|
developer_args: vec![],
|
||||||
|
},
|
||||||
|
vec![],
|
||||||
|
)
|
||||||
|
.expect("tracker insert should succeed");
|
||||||
|
|
||||||
|
let ticket = ProcessedTicket::insert_if_new(
|
||||||
|
&conn,
|
||||||
|
&tracker.id,
|
||||||
|
1,
|
||||||
|
"Ticket 1",
|
||||||
|
"{\"id\":1}",
|
||||||
|
)
|
||||||
|
.expect("ticket insert should succeed")
|
||||||
|
.expect("ticket should be inserted");
|
||||||
|
|
||||||
|
ticket.id
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_create_notification() {
|
||||||
|
let (db, project_id) = setup();
|
||||||
|
|
||||||
|
let n = create(
|
||||||
|
&db,
|
||||||
|
&project_id,
|
||||||
|
None,
|
||||||
|
"NewTicket",
|
||||||
|
"Ticket #12",
|
||||||
|
"Nouveau ticket detecte",
|
||||||
|
)
|
||||||
|
.expect("notification should be inserted");
|
||||||
|
|
||||||
|
assert_eq!(n.project_id, project_id);
|
||||||
|
assert_eq!(n.ticket_id, None);
|
||||||
|
assert_eq!(n.notification_type, "NewTicket");
|
||||||
|
assert_eq!(n.title, "Ticket #12");
|
||||||
|
assert_eq!(n.message, "Nouveau ticket detecte");
|
||||||
|
assert!(!n.read);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_create_notification_with_ticket() {
|
||||||
|
let (db, project_id) = setup();
|
||||||
|
let ticket_id = setup_ticket(&db, &project_id);
|
||||||
|
|
||||||
|
let n = create(
|
||||||
|
&db,
|
||||||
|
&project_id,
|
||||||
|
Some(&ticket_id),
|
||||||
|
"FixReady",
|
||||||
|
"Fix pret #1",
|
||||||
|
"Un correctif est disponible pour revue",
|
||||||
|
)
|
||||||
|
.expect("notification should be inserted");
|
||||||
|
|
||||||
|
assert_eq!(n.ticket_id.as_deref(), Some(ticket_id.as_str()));
|
||||||
|
assert_eq!(n.notification_type, "FixReady");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_error_message_default_when_empty() {
|
||||||
|
assert_eq!(error_message(""), "Erreur lors du traitement du ticket");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_error_message_keeps_original() {
|
||||||
|
assert_eq!(error_message("timeout"), "timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue