campaign workflow tests
This commit is contained in:
parent
2c4d2e5358
commit
377b825fe4
4 changed files with 284 additions and 84 deletions
|
@ -87,22 +87,6 @@
|
||||||
"nullable": []
|
"nullable": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"3e31af624e06a2261fa85f25b5ec4c62a8408cd7283042e24b2aee2998931426": {
|
|
||||||
"query": "\nINSERT INTO survey_campaigns (\n user_id, ID, name, difficulties, created_at\n ) VALUES(\n (SELECT id FROM survey_admins WHERE name = $1),\n $2, $3, $4, $5\n );",
|
|
||||||
"describe": {
|
|
||||||
"columns": [],
|
|
||||||
"parameters": {
|
|
||||||
"Left": [
|
|
||||||
"Text",
|
|
||||||
"Uuid",
|
|
||||||
"Varchar",
|
|
||||||
"Int4Array",
|
|
||||||
"Timestamptz"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"nullable": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"43b3e771f38bf8059832169227705be06a28925af1b3799ffef5371d511fd138": {
|
"43b3e771f38bf8059832169227705be06a28925af1b3799ffef5371d511fd138": {
|
||||||
"query": "\n INSERT INTO survey_users (created_at, id) VALUES($1, $2)",
|
"query": "\n INSERT INTO survey_users (created_at, id) VALUES($1, $2)",
|
||||||
"describe": {
|
"describe": {
|
||||||
|
@ -182,6 +166,22 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"82feafc36533144e49ba374c8c47ca4aa0d6558a9803778ad28cfa7b62382c3e": {
|
||||||
|
"query": "\n INSERT INTO survey_campaigns (\n user_id, ID, name, difficulties, created_at\n ) VALUES(\n (SELECT id FROM survey_admins WHERE name = $1),\n $2, $3, $4, $5\n );",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Text",
|
||||||
|
"Uuid",
|
||||||
|
"Varchar",
|
||||||
|
"Int4Array",
|
||||||
|
"Timestamptz"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
}
|
||||||
|
},
|
||||||
"8320dda2b3e107d1451fdfb35eb2a4b8e97364e7b1b74ffe4d6913faf132fb61": {
|
"8320dda2b3e107d1451fdfb35eb2a4b8e97364e7b1b74ffe4d6913faf132fb61": {
|
||||||
"query": "SELECT ID \n FROM survey_responses \n WHERE \n user_id = $1 \n AND \n device_software_recognised = $2;",
|
"query": "SELECT ID \n FROM survey_responses \n WHERE \n user_id = $1 \n AND \n device_software_recognised = $2;",
|
||||||
"describe": {
|
"describe": {
|
||||||
|
|
|
@ -45,23 +45,25 @@ pub mod runners {
|
||||||
|
|
||||||
pub async fn add_runner(
|
pub async fn add_runner(
|
||||||
username: &str,
|
username: &str,
|
||||||
payload: &AddCapmaign,
|
payload: &mut AddCapmaign,
|
||||||
data: &AppData,
|
data: &AppData,
|
||||||
) -> ServiceResult<uuid::Uuid> {
|
) -> ServiceResult<uuid::Uuid> {
|
||||||
let mut uuid;
|
let mut uuid;
|
||||||
let now = OffsetDateTime::now_utc();
|
let now = OffsetDateTime::now_utc();
|
||||||
|
|
||||||
|
payload.difficulties.sort();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
uuid = get_uuid();
|
uuid = get_uuid();
|
||||||
|
|
||||||
let res = sqlx::query!(
|
let res = sqlx::query!(
|
||||||
"
|
"
|
||||||
INSERT INTO survey_campaigns (
|
INSERT INTO survey_campaigns (
|
||||||
user_id, ID, name, difficulties, created_at
|
user_id, ID, name, difficulties, created_at
|
||||||
) VALUES(
|
) VALUES(
|
||||||
(SELECT id FROM survey_admins WHERE name = $1),
|
(SELECT id FROM survey_admins WHERE name = $1),
|
||||||
$2, $3, $4, $5
|
$2, $3, $4, $5
|
||||||
);",
|
);",
|
||||||
username,
|
username,
|
||||||
&uuid,
|
&uuid,
|
||||||
&payload.name,
|
&payload.name,
|
||||||
|
@ -89,13 +91,19 @@ INSERT INTO survey_campaigns (
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct AddCapmaign {
|
pub struct AddCapmaign {
|
||||||
name: String,
|
pub name: String,
|
||||||
difficulties: Vec<i32>,
|
pub difficulties: Vec<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct AddCapmaignResp {
|
||||||
|
pub campaign_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn services(cfg: &mut web::ServiceConfig) {
|
pub fn services(cfg: &mut web::ServiceConfig) {
|
||||||
cfg.service(add);
|
cfg.service(add);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[my_codegen::post(path = "crate::V1_API_ROUTES.admin.campaign.add")]
|
#[my_codegen::post(path = "crate::V1_API_ROUTES.admin.campaign.add")]
|
||||||
async fn add(
|
async fn add(
|
||||||
payload: web::Json<AddCapmaign>,
|
payload: web::Json<AddCapmaign>,
|
||||||
|
@ -103,7 +111,82 @@ async fn add(
|
||||||
id: Identity,
|
id: Identity,
|
||||||
) -> ServiceResult<impl Responder> {
|
) -> ServiceResult<impl Responder> {
|
||||||
let username = id.identity().unwrap();
|
let username = id.identity().unwrap();
|
||||||
let payload = payload.into_inner();
|
let mut payload = payload.into_inner();
|
||||||
let _campaign_id = runners::add_runner(&username, &payload, &data).await?;
|
let campaign_id = runners::add_runner(&username, &mut payload, &data).await?;
|
||||||
Ok(HttpResponse::Ok())
|
let resp = AddCapmaignResp {
|
||||||
|
campaign_id: campaign_id.to_string(),
|
||||||
|
};
|
||||||
|
Ok(HttpResponse::Ok().json(resp))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use crate::api::v1::bench::{Bench, BenchConfig, Submission, SubmissionProof};
|
||||||
|
use crate::data::Data;
|
||||||
|
use crate::tests::*;
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn test_add_campaign() {
|
||||||
|
const NAME: &str = "testadminuser";
|
||||||
|
const EMAIL: &str = "testuserupda@testadminuser.com";
|
||||||
|
const PASSWORD: &str = "longpassword2";
|
||||||
|
|
||||||
|
const DEVICE_USER_PROVIDED: &str = "foo";
|
||||||
|
const DEVICE_SOFTWARE_RECOGNISED: &str = "Foobar.v2";
|
||||||
|
const THREADS: i32 = 4;
|
||||||
|
|
||||||
|
let benches = vec![
|
||||||
|
Bench {
|
||||||
|
difficulty: 1,
|
||||||
|
duration: 1.00,
|
||||||
|
},
|
||||||
|
Bench {
|
||||||
|
difficulty: 2,
|
||||||
|
duration: 2.00,
|
||||||
|
},
|
||||||
|
Bench {
|
||||||
|
difficulty: 3,
|
||||||
|
duration: 3.00,
|
||||||
|
},
|
||||||
|
Bench {
|
||||||
|
difficulty: 4,
|
||||||
|
duration: 4.00,
|
||||||
|
},
|
||||||
|
Bench {
|
||||||
|
difficulty: 5,
|
||||||
|
duration: 5.00,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
{
|
||||||
|
let data = Data::new().await;
|
||||||
|
delete_user(NAME, &data).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (data, _creds, signin_resp) =
|
||||||
|
register_and_signin(NAME, EMAIL, PASSWORD).await;
|
||||||
|
let cookies = get_cookie!(signin_resp);
|
||||||
|
let survey = get_survey_user(data.clone()).await;
|
||||||
|
let survey_cookie = get_cookie!(survey);
|
||||||
|
// let app = get_app!(data).await;
|
||||||
|
|
||||||
|
let campaign = create_new_campaign(NAME, data.clone(), cookies.clone()).await;
|
||||||
|
let campaign_config =
|
||||||
|
get_campaign_config(&campaign, data.clone(), survey_cookie.clone()).await;
|
||||||
|
|
||||||
|
assert_eq!(DIFFICULTIES.to_vec(), campaign_config.difficulties);
|
||||||
|
|
||||||
|
let submit_payload = Submission {
|
||||||
|
device_user_provided: DEVICE_USER_PROVIDED.into(),
|
||||||
|
device_software_recognised: DEVICE_SOFTWARE_RECOGNISED.into(),
|
||||||
|
threads: THREADS,
|
||||||
|
benches: benches.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let _proof =
|
||||||
|
submit_bench(&submit_payload, &campaign, survey_cookie, data.clone()).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,31 +99,31 @@ pub mod runners {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[my_codegen::post(path = "crate::V1_API_ROUTES.benches.register")]
|
#[my_codegen::get(path = "crate::V1_API_ROUTES.benches.register")]
|
||||||
async fn register(data: AppData, id: Identity) -> ServiceResult<impl Responder> {
|
async fn register(data: AppData, id: Identity) -> ServiceResult<impl Responder> {
|
||||||
let uuid = runners::register_runner(&data).await?;
|
let uuid = runners::register_runner(&data).await?;
|
||||||
id.remember(uuid.to_string());
|
id.remember(uuid.to_string());
|
||||||
Ok(HttpResponse::Ok())
|
Ok(HttpResponse::Ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
struct Bench {
|
pub struct Bench {
|
||||||
duration: f32,
|
pub duration: f32,
|
||||||
difficulty: i32,
|
pub difficulty: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
struct Submission {
|
pub struct Submission {
|
||||||
device_user_provided: String,
|
pub device_user_provided: String,
|
||||||
device_software_recognised: String,
|
pub device_software_recognised: String,
|
||||||
threads: i32,
|
pub threads: i32,
|
||||||
benches: Vec<Bench>,
|
pub benches: Vec<Bench>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
struct SubmissionProof {
|
pub struct SubmissionProof {
|
||||||
token: String,
|
pub token: String,
|
||||||
proof: String,
|
pub proof: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_check_login() -> crate::CheckLogin {
|
fn get_check_login() -> crate::CheckLogin {
|
||||||
|
|
199
src/tests.rs
199
src/tests.rs
|
@ -14,15 +14,21 @@
|
||||||
* 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/>.
|
||||||
*/
|
*/
|
||||||
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use actix_web::cookie::Cookie;
|
use actix_web::cookie::Cookie;
|
||||||
use actix_web::test;
|
use actix_web::test;
|
||||||
use actix_web::{dev::ServiceResponse, error::ResponseError, http::StatusCode};
|
use actix_web::{dev::ServiceResponse, error::ResponseError, http::StatusCode};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::api::v1::admin::auth::runners::{Login, Register};
|
use crate::api::v1::admin::{
|
||||||
|
auth::runners::{Login, Register},
|
||||||
|
campaigns::{AddCapmaign, AddCapmaignResp},
|
||||||
|
};
|
||||||
|
use crate::api::v1::bench::{Bench, BenchConfig, Submission, SubmissionProof};
|
||||||
use crate::data::Data;
|
use crate::data::Data;
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
use crate::V1_API_ROUTES;
|
use crate::V1_API_ROUTES;
|
||||||
|
@ -91,7 +97,7 @@ macro_rules! get_app {
|
||||||
test::init_service(get_app!("APP"))
|
test::init_service(get_app!("APP"))
|
||||||
};
|
};
|
||||||
($data:expr) => {
|
($data:expr) => {
|
||||||
test::init_service(
|
actix_web::test::init_service(
|
||||||
get_app!("APP").app_data(actix_web::web::Data::new($data.clone())),
|
get_app!("APP").app_data(actix_web::web::Data::new($data.clone())),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -192,29 +198,62 @@ pub async fn bad_post_req_test<T: Serialize>(
|
||||||
// //println!("{}", txt.error);
|
// //println!("{}", txt.error);
|
||||||
// assert_eq!(resp_err.error, format!("{}", err));
|
// assert_eq!(resp_err.error, format!("{}", err));
|
||||||
//}
|
//}
|
||||||
//
|
|
||||||
//pub async fn create_new_campaign(
|
pub const DIFFICULTIES: [i32; 5] = [1, 2, 3, 4, 5];
|
||||||
// campaign_name: &str,
|
|
||||||
// data: Arc<Data>,
|
pub async fn create_new_campaign(
|
||||||
// cookies: Cookie<'_>,
|
campaign_name: &str,
|
||||||
//) -> CreateResp {
|
data: Arc<Data>,
|
||||||
// let new = CreateReq {
|
cookies: Cookie<'_>,
|
||||||
// name: campaign_name.into(),
|
) -> AddCapmaignResp {
|
||||||
// };
|
let new = AddCapmaign {
|
||||||
//
|
name: campaign_name.into(),
|
||||||
// let app = get_app!(data).await;
|
difficulties: DIFFICULTIES.into(),
|
||||||
// let new_resp = test::call_service(
|
};
|
||||||
// &app,
|
|
||||||
// post_request!(&new, crate::V1_API_ROUTES.campaign.new)
|
let app = get_app!(data).await;
|
||||||
// .cookie(cookies)
|
let new_resp = test::call_service(
|
||||||
// .to_request(),
|
&app,
|
||||||
// )
|
post_request!(&new, crate::V1_API_ROUTES.admin.campaign.add)
|
||||||
// .await;
|
.cookie(cookies)
|
||||||
// assert_eq!(new_resp.status(), StatusCode::OK);
|
.to_request(),
|
||||||
// let uuid: CreateResp = test::read_body_json(new_resp).await;
|
)
|
||||||
// uuid
|
.await;
|
||||||
//}
|
assert_eq!(new_resp.status(), StatusCode::OK);
|
||||||
//
|
let uuid: AddCapmaignResp = test::read_body_json(new_resp).await;
|
||||||
|
uuid
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_survey_user(data: Arc<Data>) -> ServiceResponse {
|
||||||
|
let app = get_app!(data).await;
|
||||||
|
let signin_resp = test::call_service(
|
||||||
|
&app,
|
||||||
|
test::TestRequest::get()
|
||||||
|
.uri(V1_API_ROUTES.benches.register)
|
||||||
|
.to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(signin_resp.status(), StatusCode::OK);
|
||||||
|
signin_resp
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_campaign_config(
|
||||||
|
campaign: &AddCapmaignResp,
|
||||||
|
data: Arc<Data>,
|
||||||
|
cookies: Cookie<'_>,
|
||||||
|
) -> BenchConfig {
|
||||||
|
let app = get_app!(data).await;
|
||||||
|
let route = V1_API_ROUTES
|
||||||
|
.benches
|
||||||
|
.fetch_routes(&campaign.campaign_id.to_string());
|
||||||
|
let new_resp =
|
||||||
|
test::call_service(&app, post_request!(&route).cookie(cookies).to_request())
|
||||||
|
.await;
|
||||||
|
assert_eq!(new_resp.status(), StatusCode::OK);
|
||||||
|
test::read_body_json(new_resp).await
|
||||||
|
}
|
||||||
|
|
||||||
//pub async fn delete_campaign(
|
//pub async fn delete_campaign(
|
||||||
// camapign: &CreateResp,
|
// camapign: &CreateResp,
|
||||||
// data: Arc<Data>,
|
// data: Arc<Data>,
|
||||||
|
@ -244,22 +283,100 @@ pub async fn bad_post_req_test<T: Serialize>(
|
||||||
// test::read_body_json(list_resp).await
|
// test::read_body_json(list_resp).await
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub async fn add_feedback(
|
pub async fn submit_bench(
|
||||||
// rating: &RatingReq,
|
payload: &Submission,
|
||||||
// campaign: &CreateResp,
|
campaign: &AddCapmaignResp,
|
||||||
// data: Arc<Data>,
|
cookies: Cookie<'_>,
|
||||||
//) -> RatingResp {
|
data: Arc<Data>,
|
||||||
// let add_feedback_route = V1_API_ROUTES.feedback.add_feedback_route(&campaign.uuid);
|
) -> SubmissionProof {
|
||||||
// let app = get_app!(data).await;
|
let route = V1_API_ROUTES.benches.submit_route(&campaign.campaign_id);
|
||||||
// let add_feedback_resp = test::call_service(
|
let app = get_app!(data).await;
|
||||||
// &app,
|
let add_feedback_resp = test::call_service(
|
||||||
// post_request!(&rating, &add_feedback_route).to_request(),
|
&app,
|
||||||
// )
|
post_request!(&payload, &route).cookie(cookies).to_request(),
|
||||||
// .await;
|
)
|
||||||
// assert_eq!(add_feedback_resp.status(), StatusCode::OK);
|
.await;
|
||||||
//
|
assert_eq!(add_feedback_resp.status(), StatusCode::OK);
|
||||||
// test::read_body_json(add_feedback_resp).await
|
|
||||||
//}
|
let proof: SubmissionProof = test::read_body_json(add_feedback_resp).await;
|
||||||
|
|
||||||
|
let survey_user_id = Uuid::from_str(&proof.token).unwrap();
|
||||||
|
let proof_uuid = Uuid::from_str(&proof.proof).unwrap();
|
||||||
|
|
||||||
|
struct Exists {
|
||||||
|
exists: Option<bool>,
|
||||||
|
}
|
||||||
|
let res = sqlx::query_as!(
|
||||||
|
Exists,
|
||||||
|
"SELECT EXISTS (
|
||||||
|
SELECT 1 from survey_responses
|
||||||
|
WHERE device_software_recognised = $1
|
||||||
|
AND device_user_provided = $2
|
||||||
|
AND THREADS = $3
|
||||||
|
AND user_id = $4
|
||||||
|
);",
|
||||||
|
&payload.device_software_recognised,
|
||||||
|
&payload.device_user_provided,
|
||||||
|
payload.threads,
|
||||||
|
&survey_user_id,
|
||||||
|
)
|
||||||
|
.fetch_one(&data.db)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(res.exists.as_ref().unwrap());
|
||||||
|
|
||||||
|
let res = sqlx::query_as!(
|
||||||
|
Exists,
|
||||||
|
"SELECT EXISTS (
|
||||||
|
SELECT 1 from survey_response_tokens
|
||||||
|
WHERE id = $1
|
||||||
|
);",
|
||||||
|
&proof_uuid
|
||||||
|
)
|
||||||
|
.fetch_one(&data.db)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(res.exists.as_ref().unwrap());
|
||||||
|
|
||||||
|
struct ID {
|
||||||
|
id: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
let resp_id = sqlx::query_as!(
|
||||||
|
ID,
|
||||||
|
"SELECT ID
|
||||||
|
FROM survey_responses
|
||||||
|
WHERE
|
||||||
|
user_id = $1
|
||||||
|
AND
|
||||||
|
device_software_recognised = $2;",
|
||||||
|
&survey_user_id,
|
||||||
|
&payload.device_software_recognised
|
||||||
|
)
|
||||||
|
.fetch_one(&data.db)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
for bench in payload.benches.iter() {
|
||||||
|
let res = sqlx::query_as!(
|
||||||
|
Exists,
|
||||||
|
"SELECT EXISTS(
|
||||||
|
SELECT 1 FROM survey_benches
|
||||||
|
WHERE resp_id = $1
|
||||||
|
AND difficulty = $2
|
||||||
|
AND duration = $3);",
|
||||||
|
&resp_id.id,
|
||||||
|
&bench.difficulty,
|
||||||
|
bench.duration
|
||||||
|
)
|
||||||
|
.fetch_one(&data.db)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(res.exists.as_ref().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
proof
|
||||||
|
}
|
||||||
//
|
//
|
||||||
//pub async fn get_feedback(
|
//pub async fn get_feedback(
|
||||||
// campaign: &CreateResp,
|
// campaign: &CreateResp,
|
||||||
|
|
Loading…
Reference in a new issue