diff options
Diffstat (limited to 'rust')
| -rw-r--r-- | rust/src/api_helpers.rs | 21 | ||||
| -rw-r--r-- | rust/src/api_server.rs | 64 | ||||
| -rw-r--r-- | rust/src/api_wrappers.rs | 26 | ||||
| -rw-r--r-- | rust/src/database_models.rs | 5 | ||||
| -rw-r--r-- | rust/src/lib.rs | 26 | ||||
| -rw-r--r-- | rust/tests/test_api_server.rs | 64 | ||||
| -rw-r--r-- | rust/tests/test_fcid.rs | 20 | 
7 files changed, 137 insertions, 89 deletions
| diff --git a/rust/src/api_helpers.rs b/rust/src/api_helpers.rs index 62fc4569..1ee08c76 100644 --- a/rust/src/api_helpers.rs +++ b/rust/src/api_helpers.rs @@ -1,8 +1,10 @@ +use data_encoding::BASE32_NOPAD;  use database_models::*;  use database_schema::*;  use diesel;  use diesel::prelude::*;  use errors::*; +use uuid::Uuid;  pub fn get_or_create_editgroup(editor_id: i64, conn: &PgConnection) -> Result<i64> {      // check for current active @@ -85,3 +87,22 @@ pub fn accept_editgroup(editgroup_id: i64, conn: &PgConnection) -> Result<Change          Ok(entry)      })  } + +/// Convert fatcat IDs (base32 strings) to UUID +pub fn fcid2uuid(fcid: &str) -> Result<Uuid> { +    if fcid.len() != 26 { +        return Err(ErrorKind::InvalidFatcatId(fcid.to_string()).into()); +    } +    let mut raw = vec![0; 16]; +    BASE32_NOPAD +        .decode_mut(fcid.to_uppercase().as_bytes(), &mut raw) +        .map_err(|_dp| ErrorKind::InvalidFatcatId(fcid.to_string()))?; +    // unwrap() is safe here, because we know raw is always 16 bytes +    Ok(Uuid::from_bytes(&raw).unwrap()) +} + +/// Convert UUID to fatcat ID string (base32 encoded) +pub fn uuid2fcid(id: &Uuid) -> String { +    let raw = id.as_bytes(); +    BASE32_NOPAD.encode(raw).to_lowercase() +} diff --git a/rust/src/api_server.rs b/rust/src/api_server.rs index bd211d1f..b7b19a85 100644 --- a/rust/src/api_server.rs +++ b/rust/src/api_server.rs @@ -1,7 +1,7 @@  //! API endpoint handlers  use ConnectionPool; -use api_helpers::{get_or_create_editgroup, accept_editgroup}; +use api_helpers::{accept_editgroup, get_or_create_editgroup, fcid2uuid, uuid2fcid};  use chrono;  use database_models::*;  use database_schema::{changelog, container_edit, container_ident, container_rev, creator_edit, @@ -40,7 +40,7 @@ macro_rules! entity_history_handler {              limit: Option<i64>,          ) -> Result<Vec<EntityHistoryEntry>> {              let conn = self.db_pool.get().expect("db_pool error"); -            let id = uuid::Uuid::parse_str(&id)?; +            let id = fcid2uuid(&id)?;              let limit = limit.unwrap_or(50);              let rows: Vec<(EditgroupRow, ChangelogRow, $edit_row_type)> = editgroup::table @@ -86,8 +86,8 @@ fn container_row2entity(      let (state, ident_id, redirect_id) = match ident {          Some(i) => (              Some(i.state().unwrap().shortname()), -            Some(i.id.to_string()), -            i.redirect_id.map(|u| u.to_string()), +            Some(uuid2fcid(&i.id)), +            i.redirect_id.map(|u| uuid2fcid(&u)),          ),          None => (None, None, None),      }; @@ -110,8 +110,8 @@ fn creator_row2entity(ident: Option<CreatorIdentRow>, rev: CreatorRevRow) -> Res      let (state, ident_id, redirect_id) = match ident {          Some(i) => (              Some(i.state().unwrap().shortname()), -            Some(i.id.to_string()), -            i.redirect_id.map(|u| u.to_string()), +            Some(uuid2fcid(&i.id)), +            i.redirect_id.map(|u| uuid2fcid(&u)),          ),          None => (None, None, None),      }; @@ -137,8 +137,8 @@ fn file_row2entity(      let (state, ident_id, redirect_id) = match ident {          Some(i) => (              Some(i.state().unwrap().shortname()), -            Some(i.id.to_string()), -            i.redirect_id.map(|u| u.to_string()), +            Some(uuid2fcid(&i.id)), +            i.redirect_id.map(|u| uuid2fcid(&u)),          ),          None => (None, None, None),      }; @@ -147,7 +147,7 @@ fn file_row2entity(          .filter(file_release::file_rev.eq(rev.id))          .get_results(conn)?          .iter() -        .map(|r: &FileReleaseRow| r.target_release_ident_id.to_string()) +        .map(|r: &FileReleaseRow| uuid2fcid(&r.target_release_ident_id))          .collect();      Ok(FileEntity { @@ -175,8 +175,8 @@ fn release_row2entity(      let (state, ident_id, redirect_id) = match ident {          Some(i) => (              Some(i.state().unwrap().shortname()), -            Some(i.id.to_string()), -            i.redirect_id.map(|u| u.to_string()), +            Some(uuid2fcid(&i.id)), +            i.redirect_id.map(|u| uuid2fcid(&u)),          ),          None => (None, None, None),      }; @@ -195,7 +195,7 @@ fn release_row2entity(              year: r.year.clone(),              title: r.title.clone(),              locator: r.locator.clone(), -            target_release_id: r.target_release_ident_id.map(|v| v.to_string()), +            target_release_id: r.target_release_ident_id.map(|v| uuid2fcid(&v)),          })          .collect(); @@ -209,7 +209,7 @@ fn release_row2entity(              index: c.index,              role: c.role.clone(),              raw: c.raw.clone(), -            creator_id: c.creator_ident_id.map(|v| v.to_string()), +            creator_id: c.creator_ident_id.map(|v| uuid2fcid(&v)),          })          .collect(); @@ -224,10 +224,10 @@ fn release_row2entity(          volume: rev.volume,          issue: rev.issue,          pages: rev.pages, -        container_id: rev.container_ident_id.map(|u| u.to_string()), +        container_id: rev.container_ident_id.map(|u| uuid2fcid(&u)),          publisher: rev.publisher,          language: rev.language, -        work_id: Some(rev.work_ident_id.to_string()), +        work_id: Some(uuid2fcid(&rev.work_ident_id)),          refs: Some(refs),          contribs: Some(contribs),          state: state, @@ -243,8 +243,8 @@ fn work_row2entity(ident: Option<WorkIdentRow>, rev: WorkRevRow) -> Result<WorkE      let (state, ident_id, redirect_id) = match ident {          Some(i) => (              Some(i.state().unwrap().shortname()), -            Some(i.id.to_string()), -            i.redirect_id.map(|u| u.to_string()), +            Some(uuid2fcid(&i.id)), +            i.redirect_id.map(|u| uuid2fcid(&u)),          ),          None => (None, None, None),      }; @@ -262,7 +262,7 @@ fn work_row2entity(ident: Option<WorkIdentRow>, rev: WorkRevRow) -> Result<WorkE  impl Server {      pub fn get_container_handler(&self, id: String) -> Result<ContainerEntity> {          let conn = self.db_pool.get().expect("db_pool error"); -        let id = uuid::Uuid::parse_str(&id)?; +        let id = fcid2uuid(&id)?;          // TODO: handle Deletions          let (ident, rev): (ContainerIdentRow, ContainerRevRow) = container_ident::table @@ -288,7 +288,7 @@ impl Server {      pub fn get_creator_handler(&self, id: String) -> Result<CreatorEntity> {          let conn = self.db_pool.get().expect("db_pool error"); -        let id = uuid::Uuid::parse_str(&id)?; +        let id = fcid2uuid(&id)?;          let (ident, rev): (CreatorIdentRow, CreatorRevRow) = creator_ident::table              .find(id) @@ -313,7 +313,7 @@ impl Server {      pub fn get_creator_releases_handler(&self, id: String) -> Result<Vec<ReleaseEntity>> {          let conn = self.db_pool.get().expect("db_pool error"); -        let id = uuid::Uuid::parse_str(&id)?; +        let id = fcid2uuid(&id)?;          // TODO: some kind of unique or group-by?          let rows: Vec<(ReleaseRevRow, ReleaseIdentRow, ReleaseContribRow)> = release_rev::table @@ -331,7 +331,7 @@ impl Server {      pub fn get_file_handler(&self, id: String) -> Result<FileEntity> {          let conn = self.db_pool.get().expect("db_pool error"); -        let id = uuid::Uuid::parse_str(&id)?; +        let id = fcid2uuid(&id)?;          let (ident, rev): (FileIdentRow, FileRevRow) = file_ident::table              .find(id) @@ -356,7 +356,7 @@ impl Server {      pub fn get_release_handler(&self, id: String) -> Result<ReleaseEntity> {          let conn = self.db_pool.get().expect("db_pool error"); -        let id = uuid::Uuid::parse_str(&id)?; +        let id = fcid2uuid(&id)?;          let (ident, rev): (ReleaseIdentRow, ReleaseRevRow) = release_ident::table              .find(id) @@ -381,7 +381,7 @@ impl Server {      pub fn get_release_files_handler(&self, id: String) -> Result<Vec<FileEntity>> {          let conn = self.db_pool.get().expect("db_pool error"); -        let id = uuid::Uuid::parse_str(&id)?; +        let id = fcid2uuid(&id)?;          let rows: Vec<(FileRevRow, FileIdentRow, FileReleaseRow)> = file_rev::table              .inner_join(file_ident::table) @@ -398,7 +398,7 @@ impl Server {      pub fn get_work_handler(&self, id: String) -> Result<WorkEntity> {          let conn = self.db_pool.get().expect("db_pool error"); -        let id = uuid::Uuid::parse_str(&id)?; +        let id = fcid2uuid(&id)?;          let (ident, rev): (WorkIdentRow, WorkRevRow) = work_ident::table              .find(id) @@ -410,7 +410,7 @@ impl Server {      pub fn get_work_releases_handler(&self, id: String) -> Result<Vec<ReleaseEntity>> {          let conn = self.db_pool.get().expect("db_pool error"); -        let id = uuid::Uuid::parse_str(&id)?; +        let id = fcid2uuid(&id)?;          let rows: Vec<(ReleaseRevRow, ReleaseIdentRow)> = release_rev::table              .inner_join(release_ident::table) @@ -559,7 +559,8 @@ impl Server {                          .iter()                          .map(|r| FileReleaseRow {                              file_rev: edit.rev_id.unwrap(), -                            target_release_ident_id: uuid::Uuid::parse_str(r).expect("valid UUID"), +                            target_release_ident_id: fcid2uuid(r) +                                .expect("invalid fatcat identifier"),                          })                          .collect();                      let release_rows: Vec<FileReleaseRow> = insert_into(file_release::table) @@ -595,7 +596,7 @@ impl Server {          };          let work_id = match entity.work_id { -            Some(work_id) => uuid::Uuid::parse_str(&work_id)?, +            Some(work_id) => fcid2uuid(&work_id)?,              None => {                  // If a work_id wasn't passed, create a new work under the current editgroup                  let work_model = models::WorkEntity { @@ -608,12 +609,12 @@ impl Server {                      extra: None,                  };                  let new_entity = self.create_work_handler(work_model, Some(&conn))?; -                uuid::Uuid::parse_str(&new_entity.ident)? +                fcid2uuid(&new_entity.ident)?              }          };          let container_id: Option<uuid::Uuid> = match entity.container_id { -            Some(id) => Some(uuid::Uuid::parse_str(&id)?), +            Some(id) => Some(fcid2uuid(&id)?),              None => None,          }; @@ -657,7 +658,7 @@ impl Server {                              release_rev: edit.rev_id.unwrap(),                              target_release_ident_id: r.target_release_id                                  .clone() -                                .map(|v| uuid::Uuid::parse_str(&v).expect("valid UUID")), +                                .map(|v| fcid2uuid(&v).expect("valid fatcat identifier")),                              index: r.index,                              key: r.key.clone(),                              container_title: r.container_title.clone(), @@ -688,7 +689,7 @@ impl Server {                              release_rev: edit.rev_id.unwrap(),                              creator_ident_id: c.creator_id                                  .clone() -                                .map(|v| uuid::Uuid::parse_str(&v).expect("valid UUID")), +                                .map(|v| fcid2uuid(&v).expect("valid fatcat identifier")),                              index: c.index,                              role: c.role.clone(),                              raw: c.raw.clone(), @@ -1005,4 +1006,3 @@ impl Server {      entity_history_handler!(get_release_history_handler, ReleaseEditRow, release_edit);      entity_history_handler!(get_work_history_handler, WorkEditRow, work_edit);  } - diff --git a/rust/src/api_wrappers.rs b/rust/src/api_wrappers.rs index 8651252c..e10906a8 100644 --- a/rust/src/api_wrappers.rs +++ b/rust/src/api_wrappers.rs @@ -1,7 +1,7 @@  //! API endpoint handlers -use errors::*;  use api_server::Server; +use errors::*;  use fatcat_api::models;  use fatcat_api::models::*;  use fatcat_api::*; @@ -32,6 +32,8 @@ macro_rules! wrap_entity_handlers {                      $get_resp::NotFound(ErrorResponse { message: format!("No such entity {}: {}", stringify!($model), id) }),                  Err(Error(ErrorKind::Uuid(e), _)) =>                      $get_resp::BadRequest(ErrorResponse { message: e.to_string() }), +                Err(Error(ErrorKind::InvalidFatcatId(e), _)) => +                    $get_resp::BadRequest(ErrorResponse { message: e.to_string() }),                  Err(e) => {                      error!("{}", e);                      $get_resp::GenericError(ErrorResponse { message: e.to_string() }) @@ -52,6 +54,8 @@ macro_rules! wrap_entity_handlers {                      $post_resp::BadRequest(ErrorResponse { message: e.to_string() }),                  Err(Error(ErrorKind::Uuid(e), _)) =>                      $post_resp::BadRequest(ErrorResponse { message: e.to_string() }), +                Err(Error(ErrorKind::InvalidFatcatId(e), _)) => +                    $post_resp::BadRequest(ErrorResponse { message: e.to_string() }),                  Err(e) => {                      error!("{}", e);                      $post_resp::GenericError(ErrorResponse { message: e.to_string() }) @@ -72,6 +76,8 @@ macro_rules! wrap_entity_handlers {                      $post_batch_resp::BadRequest(ErrorResponse { message: e.to_string() }),                  Err(Error(ErrorKind::Uuid(e), _)) =>                      $post_batch_resp::BadRequest(ErrorResponse { message: e.to_string() }), +                Err(Error(ErrorKind::InvalidFatcatId(e), _)) => +                    $post_batch_resp::BadRequest(ErrorResponse { message: e.to_string() }),                  Err(e) => {                      error!("{}", e);                      $post_batch_resp::GenericError(ErrorResponse { message: e.to_string() }) @@ -93,6 +99,8 @@ macro_rules! wrap_entity_handlers {                      $get_history_resp::NotFound(ErrorResponse { message: format!("No such entity {}: {}", stringify!($model), id) }),                  Err(Error(ErrorKind::Uuid(e), _)) =>                      $get_history_resp::BadRequest(ErrorResponse { message: e.to_string() }), +                Err(Error(ErrorKind::InvalidFatcatId(e), _)) => +                    $get_history_resp::BadRequest(ErrorResponse { message: e.to_string() }),                  Err(e) => {                      error!("{}", e);                      $get_history_resp::GenericError(ErrorResponse { message: e.to_string() }) @@ -259,17 +267,18 @@ impl Api for Server {          id: i64,          _context: &Context,      ) -> Box<Future<Item = AcceptEditgroupResponse, Error = ApiError> + Send> { -          let ret = match self.accept_editgroup_handler(id) {              Ok(()) => AcceptEditgroupResponse::MergedSuccessfully(Success {                  message: "horray!".to_string(),              }), -            Err(Error(ErrorKind::Diesel(::diesel::result::Error::NotFound), _)) => -                AcceptEditgroupResponse::NotFound( -                    ErrorResponse { message: format!("No such editgroup: {}", id) }), -            Err(e) => -                AcceptEditgroupResponse::GenericError( -                    ErrorResponse { message: e.to_string() }), +            Err(Error(ErrorKind::Diesel(::diesel::result::Error::NotFound), _)) => { +                AcceptEditgroupResponse::NotFound(ErrorResponse { +                    message: format!("No such editgroup: {}", id), +                }) +            } +            Err(e) => AcceptEditgroupResponse::GenericError(ErrorResponse { +                message: e.to_string(), +            }),          };          Box::new(futures::done(Ok(ret)))      } @@ -298,7 +307,6 @@ impl Api for Server {          entity: models::Editgroup,          _context: &Context,      ) -> Box<Future<Item = CreateEditgroupResponse, Error = ApiError> + Send> { -          let ret = match self.create_editgroup_handler(entity) {              Ok(eg) =>                  CreateEditgroupResponse::SuccessfullyCreated(eg), diff --git a/rust/src/database_models.rs b/rust/src/database_models.rs index 8489b336..15dffad0 100644 --- a/rust/src/database_models.rs +++ b/rust/src/database_models.rs @@ -1,3 +1,4 @@ +use api_helpers::uuid2fcid;  use chrono;  use database_schema::*;  use errors::*; @@ -54,8 +55,8 @@ macro_rules! entity_structs {                  Ok(EntityEdit {                      editgroup_id: self.editgroup_id,                      revision: self.rev_id, -                    redirect_ident: self.redirect_id.map(|v| v.to_string()), -                    ident: self.ident_id.to_string(), +                    redirect_ident: self.redirect_id.map(|v| uuid2fcid(&v)), +                    ident: uuid2fcid(&self.ident_id),                      edit_id: self.id,                      extra: self.extra_json,                  }) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 9de94d86..86e367e4 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -33,7 +33,12 @@ mod errors {                          Uuid(::uuid::ParseError);                          Io(::std::io::Error) #[cfg(unix)];                          Serde(::serde_json::Error); -                        Base32(::data_encoding::DecodeError); +        } +        errors { +            InvalidFatcatId(id: String) { +                description("invalid fatcat identifier syntax") +                display("invalid fatcat identifier (expect 26-char base32 encoded): {}", id) +            }          }      }  } @@ -49,7 +54,6 @@ use dotenv::dotenv;  use iron::middleware::AfterMiddleware;  use iron::{Request, Response};  use std::env; -use data_encoding::BASE32_NOPAD;  #[cfg(feature = "postgres")]  embed_migrations!("../migrations/"); @@ -103,21 +107,3 @@ impl AfterMiddleware for XClacksOverheadMiddleware {          Ok(res)      }  } - -/// Convert fatcat IDs (base32 strings) to UUID -pub fn fcid2uuid(fcid: &str) -> Result<uuid::Uuid> { -    if fcid.len() != 20 { -        bail!("invalid fatcat ID (expecting 20-chars of base32"); -    } -    let mut raw = vec![0; 16]; -    BASE32_NOPAD.decode_mut(fcid.to_uppercase().as_bytes(), &mut raw) -        .map_err(|dp| dp.error)?; -    // unwrap() is safe here, because we know raw is always 16 bytes -    Ok(uuid::Uuid::from_bytes(&raw).unwrap()) -} - -/// Convert UUID to fatcat ID string (base32 encoded) -pub fn uuid2fcid(id: &uuid::Uuid) -> String { -    let raw = id.as_bytes(); -    BASE32_NOPAD.encode(raw).to_lowercase() -} diff --git a/rust/tests/test_api_server.rs b/rust/tests/test_api_server.rs index b00d22eb..e7ac9585 100644 --- a/rust/tests/test_api_server.rs +++ b/rust/tests/test_api_server.rs @@ -47,7 +47,7 @@ fn test_entity_gets() {      check_response(          request::get( -            "http://localhost:9411/v0/container/00000000-0000-0000-1111-000000000002", +            "http://localhost:9411/v0/container/aaaaaaaaaaaaaeiraaaaaaaaai",              headers.clone(),              &router,          ), @@ -57,7 +57,7 @@ fn test_entity_gets() {      check_response(          request::get( -            "http://localhost:9411/v0/creator/00000000-0000-0000-2222-000000000001", +            "http://localhost:9411/v0/creator/aaaaaaaaaaaaaircaaaaaaaaae",              headers.clone(),              &router,          ), @@ -67,7 +67,7 @@ fn test_entity_gets() {      check_response(          request::get( -            "http://localhost:9411/v0/file/00000000-0000-0000-3333-000000000002", +            "http://localhost:9411/v0/file/aaaaaaaaaaaaamztaaaaaaaaai",              headers.clone(),              &router,          ), @@ -77,7 +77,7 @@ fn test_entity_gets() {      check_response(          request::get( -            "http://localhost:9411/v0/release/00000000-0000-0000-4444-000000000002", +            "http://localhost:9411/v0/release/aaaaaaaaaaaaarceaaaaaaaaai",              headers.clone(),              &router,          ), @@ -87,7 +87,7 @@ fn test_entity_gets() {      check_response(          request::get( -            "http://localhost:9411/v0/work/00000000-0000-0000-5555-000000000002", +            "http://localhost:9411/v0/work/aaaaaaaaaaaaavkvaaaaaaaaai",              headers.clone(),              &router,          ), @@ -102,7 +102,7 @@ fn test_entity_404() {      check_response(          request::get( -            "http://localhost:9411/v0/creator/00000000-0000-0000-2222-999999999999", +            "http://localhost:9411/v0/creator/aaaaaaaaaaaaairceeeeeeeeee",              headers.clone(),              &router,          ), @@ -117,7 +117,7 @@ fn test_entity_history() {      check_response(          request::get( -            "http://localhost:9411/v0/container/00000000-0000-0000-1111-000000000002/history", +            "http://localhost:9411/v0/container/aaaaaaaaaaaaaeiraaaaaaaaai/history",              headers.clone(),              &router,          ), @@ -127,7 +127,7 @@ fn test_entity_history() {      check_response(          request::get( -            "http://localhost:9411/v0/creator/00000000-0000-0000-2222-000000000001/history", +            "http://localhost:9411/v0/creator/aaaaaaaaaaaaaircaaaaaaaaae/history",              headers.clone(),              &router,          ), @@ -137,7 +137,7 @@ fn test_entity_history() {      check_response(          request::get( -            "http://localhost:9411/v0/file/00000000-0000-0000-3333-000000000002/history", +            "http://localhost:9411/v0/file/aaaaaaaaaaaaamztaaaaaaaaai/history",              headers.clone(),              &router,          ), @@ -147,7 +147,7 @@ fn test_entity_history() {      check_response(          request::get( -            "http://localhost:9411/v0/release/00000000-0000-0000-4444-000000000002/history", +            "http://localhost:9411/v0/release/aaaaaaaaaaaaarceaaaaaaaaai/history",              headers.clone(),              &router,          ), @@ -157,7 +157,7 @@ fn test_entity_history() {      check_response(          request::get( -            "http://localhost:9411/v0/work/00000000-0000-0000-5555-000000000002/history", +            "http://localhost:9411/v0/work/aaaaaaaaaaaaavkvaaaaaaaaai/history",              headers.clone(),              &router,          ), @@ -207,7 +207,7 @@ fn test_reverse_lookups() {      check_response(          request::get( -            "http://localhost:9411/v0/creator/00000000-0000-0000-2222-000000000002/releases", +            "http://localhost:9411/v0/creator/aaaaaaaaaaaaaircaaaaaaaaai/releases",              headers.clone(),              &router,          ), @@ -217,7 +217,7 @@ fn test_reverse_lookups() {      check_response(          request::get( -            "http://localhost:9411/v0/release/00000000-0000-0000-4444-000000000002/files", +            "http://localhost:9411/v0/release/aaaaaaaaaaaaarceaaaaaaaaai/files",              headers.clone(),              &router,          ), @@ -227,7 +227,7 @@ fn test_reverse_lookups() {      check_response(          request::get( -            "http://localhost:9411/v0/work/00000000-0000-0000-5555-000000000002/releases", +            "http://localhost:9411/v0/work/aaaaaaaaaaaaavkvaaaaaaaaai/releases",              headers.clone(),              &router,          ), @@ -310,8 +310,8 @@ fn test_post_file() {                  "url": "http://archive.org/asdf.txt",                  "mimetype": "application/pdf",                  "releases": [ -                    "00000000-0000-0000-4444-000000000001", -                    "00000000-0000-0000-4444-000000000002" +                    "aaaaaaaaaaaaarceaaaaaaaaae", +                    "aaaaaaaaaaaaarceaaaaaaaaai"                  ],                  "extra": { "source": "speculation" }                  }"#, @@ -333,7 +333,7 @@ fn test_post_release() {              // TODO: target_release_id              r#"{"title": "secret minimal paper",                  "release_type": "journal-article", -                "work_id": "00000000-0000-0000-5555-000000000001" +                "work_id": "aaaaaaaaaaaaavkvaaaaaaaaae"                  }"#,              &router,          ), @@ -367,8 +367,8 @@ fn test_post_release() {                  "volume": "439",                  "issue": "IV",                  "pages": "1-399", -                "work_id": "00000000-0000-0000-5555-000000000002", -                "container_id": "00000000-0000-0000-1111-000000000001", +                "work_id": "aaaaaaaaaaaaavkvaaaaaaaaai", +                "container_id": "aaaaaaaaaaaaaeiraaaaaaaaae",                  "refs": [{                          "index": 3,                          "raw": "just a string" @@ -378,7 +378,7 @@ fn test_post_release() {                  "contribs": [{                          "index": 1,                          "raw": "textual description of contributor (aka, name)", -                        "creator_id": "00000000-0000-0000-2222-000000000001", +                        "creator_id": "aaaaaaaaaaaaaircaaaaaaaaae",                          "contrib_type": "author"                      },{                          "raw": "shorter" @@ -505,13 +505,21 @@ fn test_changelog() {      let (headers, router, _conn) = setup();      check_response( -        request::get("http://localhost:9411/v0/changelog", headers.clone(), &router), +        request::get( +            "http://localhost:9411/v0/changelog", +            headers.clone(), +            &router, +        ),          status::Ok,          Some("editgroup_id"),      );      check_response( -        request::get("http://localhost:9411/v0/changelog/1", headers.clone(), &router), +        request::get( +            "http://localhost:9411/v0/changelog/1", +            headers.clone(), +            &router, +        ),          status::Ok,          Some("files"),      ); @@ -527,7 +535,11 @@ fn test_stats() {          Some("merged_editgroups"),      );      check_response( -        request::get("http://localhost:9411/v0/stats?more=yes", headers.clone(), &router), +        request::get( +            "http://localhost:9411/v0/stats?more=yes", +            headers.clone(), +            &router, +        ),          status::Ok,          Some("merged_editgroups"),      ); @@ -547,8 +559,8 @@ fn test_400() {                  "volume": "439",                  "issue": "IV",                  "pages": "1-399", -                "work_id": "00000000-0000-0000-5555-00002", -                "container_id": "00000000-0000-0000-1111-000000001", +                "work_id": "aaaaaaaaaaaaavkvaaaaaaaaae", +                "container_id": "aaaaaaaaaaaaaeiraaaaaae",                  "refs": [{                          "index": 3,                          "raw": "just a string" @@ -558,7 +570,7 @@ fn test_400() {                  "contribs": [{                          "index": 1,                          "raw": "textual description of contributor (aka, name)", -                        "creator_id": "00000000-0000-0000-2222-000000000001", +                        "creator_id": "aaaaaaaaaaaaaircaaaaaaaaae",                          "contrib_type": "author"                      },{                          "raw": "shorter" diff --git a/rust/tests/test_fcid.rs b/rust/tests/test_fcid.rs new file mode 100644 index 00000000..c9f6c00d --- /dev/null +++ b/rust/tests/test_fcid.rs @@ -0,0 +1,20 @@ +extern crate fatcat; +extern crate uuid; + +use fatcat::api_helpers::{fcid2uuid, uuid2fcid}; +use uuid::Uuid; + +#[test] +fn test_fcid_conversions() { +    let test_uuid = Uuid::parse_str("86daea5b-1b6b-432a-bb67-ea97795f80fe").unwrap(); +    let test_fcid = "q3nouwy3nnbsvo3h5klxsx4a7y"; + +    assert_eq!(test_fcid, uuid2fcid(&test_uuid)); +    assert_eq!(test_uuid, fcid2uuid(test_fcid).unwrap()); +    assert_eq!(test_uuid, fcid2uuid(&test_fcid.to_uppercase()).unwrap()); +    assert_eq!(test_uuid, fcid2uuid(&uuid2fcid(&test_uuid)).unwrap()); + +    assert_eq!(false, fcid2uuid("asdf").is_ok()); +    assert_eq!(false, fcid2uuid("q3nouwy3nnbsvo3h5klx").is_ok()); +    assert_eq!(false, fcid2uuid("10Oouwy3nnbsvo3h5klxsx4a7y").is_ok()); +} | 
