2017-05-03 14:16:09 +00:00
|
|
|
use std::collections::HashMap;
|
2019-01-27 17:57:07 +00:00
|
|
|
use std::path::PathBuf;
|
2020-05-23 09:46:50 +00:00
|
|
|
use std::{fs, io, result};
|
2018-10-18 15:32:30 +00:00
|
|
|
|
2021-02-20 12:31:37 +00:00
|
|
|
use base64::encode as encode_b64;
|
2021-02-20 13:07:36 +00:00
|
|
|
use sha2::{digest, Sha256, Sha384, Sha512};
|
2020-06-18 19:11:22 +00:00
|
|
|
use tera::{from_value, to_value, Error, Function as TeraFn, Result, Value};
|
2017-05-03 14:16:09 +00:00
|
|
|
|
2017-08-07 11:38:13 +00:00
|
|
|
use config::Config;
|
2019-06-02 18:21:06 +00:00
|
|
|
use utils::site::resolve_internal_link;
|
2018-10-29 19:13:09 +00:00
|
|
|
|
|
|
|
#[macro_use]
|
|
|
|
mod macros;
|
2018-02-02 20:35:04 +00:00
|
|
|
|
2021-05-11 16:05:00 +00:00
|
|
|
mod content;
|
|
|
|
mod images;
|
2018-10-29 19:13:09 +00:00
|
|
|
mod load_data;
|
|
|
|
|
2021-05-11 16:05:00 +00:00
|
|
|
pub use self::content::{GetPage, GetSection, GetTaxonomy, GetTaxonomyUrl};
|
|
|
|
pub use self::images::{GetImageMeta, ResizeImage};
|
2019-02-09 18:54:46 +00:00
|
|
|
pub use self::load_data::LoadData;
|
2017-11-16 17:08:06 +00:00
|
|
|
|
2019-01-23 18:20:02 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Trans {
|
|
|
|
config: Config,
|
|
|
|
}
|
|
|
|
impl Trans {
|
|
|
|
pub fn new(config: Config) -> Self {
|
2019-02-09 18:54:46 +00:00
|
|
|
Self { config }
|
2019-01-23 18:20:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
impl TeraFn for Trans {
|
|
|
|
fn call(&self, args: &HashMap<String, Value>) -> Result<Value> {
|
2018-02-02 20:35:04 +00:00
|
|
|
let key = required_arg!(String, args.get("key"), "`trans` requires a `key` argument.");
|
2018-10-31 07:18:57 +00:00
|
|
|
let lang = optional_arg!(String, args.get("lang"), "`trans`: `lang` must be a string.")
|
2019-01-23 18:20:02 +00:00
|
|
|
.unwrap_or_else(|| self.config.default_language.clone());
|
2019-09-03 08:51:41 +00:00
|
|
|
|
2019-10-14 16:31:03 +00:00
|
|
|
let term = self
|
|
|
|
.config
|
2021-03-21 17:15:38 +00:00
|
|
|
.get_translation(&lang, &key)
|
2020-11-28 12:04:49 +00:00
|
|
|
.map_err(|e| Error::chain("Failed to retrieve term translation", e))?;
|
2019-09-03 08:51:41 +00:00
|
|
|
|
|
|
|
Ok(to_value(term).unwrap())
|
2017-05-03 14:16:09 +00:00
|
|
|
}
|
|
|
|
}
|
2017-05-17 10:04:26 +00:00
|
|
|
|
2019-01-23 18:20:02 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct GetUrl {
|
|
|
|
config: Config,
|
|
|
|
permalinks: HashMap<String, String>,
|
2020-06-09 20:38:29 +00:00
|
|
|
search_paths: Vec<PathBuf>,
|
2019-01-23 18:20:02 +00:00
|
|
|
}
|
|
|
|
impl GetUrl {
|
2020-06-18 19:11:22 +00:00
|
|
|
pub fn new(
|
|
|
|
config: Config,
|
|
|
|
permalinks: HashMap<String, String>,
|
|
|
|
search_paths: Vec<PathBuf>,
|
|
|
|
) -> Self {
|
2020-06-09 20:38:29 +00:00
|
|
|
Self { config, permalinks, search_paths }
|
2017-05-23 11:03:25 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-12 17:23:17 +00:00
|
|
|
|
|
|
|
fn make_path_with_lang(path: String, lang: &str, config: &Config) -> Result<String> {
|
2020-06-18 19:11:22 +00:00
|
|
|
if lang == config.default_language {
|
2020-04-12 17:23:17 +00:00
|
|
|
return Ok(path);
|
|
|
|
}
|
|
|
|
|
2021-03-06 22:31:04 +00:00
|
|
|
if !config.other_languages().contains_key(lang) {
|
2020-04-22 08:07:17 +00:00
|
|
|
return Err(
|
|
|
|
format!("`{}` is not an authorized language (check config.languages).", lang).into()
|
|
|
|
);
|
2020-04-12 17:23:17 +00:00
|
|
|
}
|
|
|
|
|
2020-06-18 19:11:22 +00:00
|
|
|
let mut splitted_path: Vec<String> = path.split('.').map(String::from).collect();
|
2020-04-12 17:23:17 +00:00
|
|
|
let ilast = splitted_path.len() - 1;
|
|
|
|
splitted_path[ilast] = format!("{}.{}", lang, splitted_path[ilast]);
|
|
|
|
Ok(splitted_path.join("."))
|
|
|
|
}
|
|
|
|
|
2020-06-18 19:11:22 +00:00
|
|
|
fn open_file(search_paths: &[PathBuf], url: &str) -> result::Result<fs::File, io::Error> {
|
|
|
|
let cleaned_url = url.trim_start_matches("@/").trim_start_matches('/');
|
2020-06-09 20:38:29 +00:00
|
|
|
for base_path in search_paths {
|
|
|
|
match fs::File::open(base_path.join(cleaned_url)) {
|
|
|
|
Ok(f) => return Ok(f),
|
2020-06-18 19:11:22 +00:00
|
|
|
Err(_) => continue,
|
2020-06-09 20:38:29 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
Err(io::Error::from(io::ErrorKind::NotFound))
|
|
|
|
}
|
|
|
|
|
2021-02-20 13:07:36 +00:00
|
|
|
fn compute_file_hash<D: digest::Digest>(
|
|
|
|
mut file: fs::File,
|
|
|
|
base64: bool,
|
|
|
|
) -> result::Result<String, io::Error>
|
|
|
|
where
|
|
|
|
digest::Output<D>: core::fmt::LowerHex,
|
|
|
|
D: std::io::Write,
|
|
|
|
{
|
|
|
|
let mut hasher = D::new();
|
2020-05-23 09:46:50 +00:00
|
|
|
io::copy(&mut file, &mut hasher)?;
|
2021-02-20 13:07:36 +00:00
|
|
|
if base64 {
|
2021-02-21 08:09:02 +00:00
|
|
|
Ok(format!("{}", encode_b64(hasher.finalize())))
|
2021-02-20 13:07:36 +00:00
|
|
|
} else {
|
2021-02-21 08:09:02 +00:00
|
|
|
Ok(format!("{:x}", hasher.finalize()))
|
2021-02-20 13:07:36 +00:00
|
|
|
}
|
2021-02-20 12:31:37 +00:00
|
|
|
}
|
|
|
|
|
2020-06-18 19:11:22 +00:00
|
|
|
fn file_not_found_err(search_paths: &[PathBuf], url: &str) -> Result<Value> {
|
|
|
|
Err(format!(
|
|
|
|
"file `{}` not found; searched in{}",
|
|
|
|
url,
|
|
|
|
search_paths.iter().fold(String::new(), |acc, arg| acc + " " + arg.to_str().unwrap())
|
|
|
|
)
|
|
|
|
.into())
|
2020-06-09 20:38:29 +00:00
|
|
|
}
|
2020-05-23 09:46:50 +00:00
|
|
|
|
2019-01-23 18:20:02 +00:00
|
|
|
impl TeraFn for GetUrl {
|
|
|
|
fn call(&self, args: &HashMap<String, Value>) -> Result<Value> {
|
2018-10-31 07:18:57 +00:00
|
|
|
let cachebust =
|
|
|
|
args.get("cachebust").map_or(false, |c| from_value::<bool>(c.clone()).unwrap_or(false));
|
2017-11-16 17:08:06 +00:00
|
|
|
|
2017-11-10 16:46:14 +00:00
|
|
|
let trailing_slash = args
|
|
|
|
.get("trailing_slash")
|
2018-10-31 07:18:57 +00:00
|
|
|
.map_or(false, |c| from_value::<bool>(c.clone()).unwrap_or(false));
|
2017-11-16 17:08:06 +00:00
|
|
|
|
2018-06-25 17:13:21 +00:00
|
|
|
let path = required_arg!(
|
|
|
|
String,
|
|
|
|
args.get("path"),
|
|
|
|
"`get_url` requires a `path` argument with a string value"
|
|
|
|
);
|
2020-04-12 17:23:17 +00:00
|
|
|
|
|
|
|
let lang = optional_arg!(String, args.get("lang"), "`get_url`: `lang` must be a string.")
|
|
|
|
.unwrap_or_else(|| self.config.default_language.clone());
|
|
|
|
|
2019-05-27 12:35:14 +00:00
|
|
|
if path.starts_with("@/") {
|
2020-04-12 17:23:17 +00:00
|
|
|
let path_with_lang = match make_path_with_lang(path, &lang, &self.config) {
|
|
|
|
Ok(x) => x,
|
2020-04-22 08:07:17 +00:00
|
|
|
Err(e) => return Err(e),
|
2020-04-12 17:23:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
match resolve_internal_link(&path_with_lang, &self.permalinks) {
|
2019-06-06 17:49:31 +00:00
|
|
|
Ok(resolved) => Ok(to_value(resolved.permalink).unwrap()),
|
2018-10-31 07:18:57 +00:00
|
|
|
Err(_) => {
|
2020-04-22 08:07:17 +00:00
|
|
|
Err(format!("Could not resolve URL for link `{}` not found.", path_with_lang)
|
|
|
|
.into())
|
2018-10-31 07:18:57 +00:00
|
|
|
}
|
2017-11-16 17:08:06 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// anything else
|
2021-03-06 21:49:04 +00:00
|
|
|
let mut segments = vec![];
|
|
|
|
|
|
|
|
if lang != self.config.default_language {
|
|
|
|
segments.push(lang);
|
|
|
|
};
|
|
|
|
|
|
|
|
segments.push(path);
|
|
|
|
|
|
|
|
let path_with_lang = segments.join("/");
|
|
|
|
|
|
|
|
let mut permalink = self.config.make_permalink(&path_with_lang);
|
2018-09-30 19:15:09 +00:00
|
|
|
if !trailing_slash && permalink.ends_with('/') {
|
2017-11-16 17:08:06 +00:00
|
|
|
permalink.pop(); // Removes the slash
|
|
|
|
}
|
|
|
|
|
|
|
|
if cachebust {
|
2021-03-06 21:49:04 +00:00
|
|
|
match open_file(&self.search_paths, &path_with_lang)
|
2021-02-20 13:07:36 +00:00
|
|
|
.and_then(|f| compute_file_hash::<Sha256>(f, false))
|
|
|
|
{
|
2020-06-09 20:38:29 +00:00
|
|
|
Ok(hash) => {
|
|
|
|
permalink = format!("{}?h={}", permalink, hash);
|
2020-06-18 19:11:22 +00:00
|
|
|
}
|
2021-03-06 21:49:04 +00:00
|
|
|
Err(_) => return file_not_found_err(&self.search_paths, &path_with_lang),
|
2020-05-23 09:46:50 +00:00
|
|
|
};
|
2017-11-16 17:08:06 +00:00
|
|
|
}
|
2021-03-06 21:49:04 +00:00
|
|
|
|
2017-11-16 17:08:06 +00:00
|
|
|
Ok(to_value(permalink).unwrap())
|
|
|
|
}
|
2019-01-23 18:20:02 +00:00
|
|
|
}
|
2017-11-16 17:08:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-09 20:38:29 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct GetFileHash {
|
|
|
|
search_paths: Vec<PathBuf>,
|
|
|
|
}
|
|
|
|
impl GetFileHash {
|
|
|
|
pub fn new(search_paths: Vec<PathBuf>) -> Self {
|
|
|
|
Self { search_paths }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const DEFAULT_SHA_TYPE: u16 = 384;
|
2021-02-20 12:31:37 +00:00
|
|
|
const DEFAULT_BASE64: bool = false;
|
2020-06-09 20:38:29 +00:00
|
|
|
|
|
|
|
impl TeraFn for GetFileHash {
|
|
|
|
fn call(&self, args: &HashMap<String, Value>) -> Result<Value> {
|
|
|
|
let path = required_arg!(
|
|
|
|
String,
|
|
|
|
args.get("path"),
|
|
|
|
"`get_file_hash` requires a `path` argument with a string value"
|
|
|
|
);
|
|
|
|
let sha_type = optional_arg!(
|
|
|
|
u16,
|
|
|
|
args.get("sha_type"),
|
|
|
|
"`get_file_hash`: `sha_type` must be 256, 384 or 512"
|
2020-06-18 19:11:22 +00:00
|
|
|
)
|
|
|
|
.unwrap_or(DEFAULT_SHA_TYPE);
|
2021-02-20 12:31:37 +00:00
|
|
|
let base64 = optional_arg!(
|
|
|
|
bool,
|
|
|
|
args.get("base64"),
|
|
|
|
"`get_file_hash`: `base64` must be true or false"
|
|
|
|
)
|
|
|
|
.unwrap_or(DEFAULT_BASE64);
|
|
|
|
|
2021-02-20 13:07:36 +00:00
|
|
|
let f = match open_file(&self.search_paths, &path) {
|
|
|
|
Ok(f) => f,
|
|
|
|
Err(e) => {
|
2021-02-22 19:39:31 +00:00
|
|
|
return Err(format!(
|
|
|
|
"File {} could not be open: {} (searched in {:?})",
|
|
|
|
path, e, self.search_paths
|
|
|
|
)
|
|
|
|
.into());
|
2021-02-20 13:07:36 +00:00
|
|
|
}
|
2020-06-09 20:38:29 +00:00
|
|
|
};
|
|
|
|
|
2021-02-20 13:07:36 +00:00
|
|
|
let hash = match sha_type {
|
|
|
|
256 => compute_file_hash::<Sha256>(f, base64),
|
|
|
|
384 => compute_file_hash::<Sha384>(f, base64),
|
|
|
|
512 => compute_file_hash::<Sha512>(f, base64),
|
|
|
|
_ => return Err("`get_file_hash`: Invalid sha value".into()),
|
|
|
|
};
|
2020-06-09 20:38:29 +00:00
|
|
|
|
|
|
|
match hash {
|
|
|
|
Ok(digest) => Ok(to_value(digest).unwrap()),
|
2020-06-18 19:11:22 +00:00
|
|
|
Err(_) => file_not_found_err(&self.search_paths, &path),
|
2020-06-09 20:38:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-07 11:38:13 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2020-06-18 19:11:22 +00:00
|
|
|
use super::{GetFileHash, GetTaxonomy, GetTaxonomyUrl, GetUrl, Trans};
|
2017-08-07 11:38:13 +00:00
|
|
|
|
|
|
|
use std::collections::HashMap;
|
2020-05-23 09:46:50 +00:00
|
|
|
use std::env::temp_dir;
|
|
|
|
use std::fs::remove_dir_all;
|
|
|
|
use std::path::PathBuf;
|
2019-02-09 18:54:46 +00:00
|
|
|
use std::sync::{Arc, RwLock};
|
2017-08-07 11:38:13 +00:00
|
|
|
|
2020-05-23 09:46:50 +00:00
|
|
|
use lazy_static::lazy_static;
|
|
|
|
|
2019-02-09 18:54:46 +00:00
|
|
|
use tera::{to_value, Function, Value};
|
2017-08-07 11:38:13 +00:00
|
|
|
|
2018-07-16 08:54:05 +00:00
|
|
|
use config::{Config, Taxonomy as TaxonomyConfig};
|
2018-10-31 07:18:57 +00:00
|
|
|
use library::{Library, Taxonomy, TaxonomyItem};
|
2020-05-23 09:46:50 +00:00
|
|
|
use utils::fs::{create_directory, create_file};
|
2020-02-05 08:13:14 +00:00
|
|
|
use utils::slugs::SlugifyStrategy;
|
2017-08-07 11:38:13 +00:00
|
|
|
|
2020-05-23 09:46:50 +00:00
|
|
|
struct TestContext {
|
2020-06-09 20:38:29 +00:00
|
|
|
static_path: PathBuf,
|
2020-05-23 09:46:50 +00:00
|
|
|
}
|
|
|
|
impl TestContext {
|
|
|
|
fn setup() -> Self {
|
2020-06-09 20:38:29 +00:00
|
|
|
let dir = temp_dir().join("static");
|
2020-05-23 09:46:50 +00:00
|
|
|
create_directory(&dir).expect("Could not create test directory");
|
|
|
|
create_file(&dir.join("app.css"), "// Hello world!")
|
|
|
|
.expect("Could not create test content (app.css)");
|
2020-06-09 20:38:29 +00:00
|
|
|
Self { static_path: dir }
|
2020-05-23 09:46:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
impl Drop for TestContext {
|
|
|
|
fn drop(&mut self) {
|
2020-06-09 20:38:29 +00:00
|
|
|
remove_dir_all(&self.static_path).expect("Could not free test directory");
|
2020-05-23 09:46:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lazy_static! {
|
|
|
|
static ref TEST_CONTEXT: TestContext = TestContext::setup();
|
|
|
|
}
|
|
|
|
|
2017-08-07 11:38:13 +00:00
|
|
|
#[test]
|
2017-08-07 14:29:58 +00:00
|
|
|
fn can_add_cachebust_to_url() {
|
2017-08-07 11:38:13 +00:00
|
|
|
let config = Config::default();
|
2020-06-09 20:38:29 +00:00
|
|
|
let static_fn = GetUrl::new(config, HashMap::new(), vec![TEST_CONTEXT.static_path.clone()]);
|
2017-08-07 11:38:13 +00:00
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value("app.css").unwrap());
|
2017-08-07 14:29:58 +00:00
|
|
|
args.insert("cachebust".to_string(), to_value(true).unwrap());
|
2020-05-23 09:46:50 +00:00
|
|
|
assert_eq!(static_fn.call(&args).unwrap(), "http://a-website.com/app.css?h=572e691dc68c3fcd653ae463261bdb38f35dc6f01715d9ce68799319dd158840");
|
2017-08-07 11:38:13 +00:00
|
|
|
}
|
2017-11-16 17:08:06 +00:00
|
|
|
|
2017-11-10 16:46:14 +00:00
|
|
|
#[test]
|
2018-09-10 18:13:44 +00:00
|
|
|
fn can_add_trailing_slashes() {
|
2017-11-10 16:46:14 +00:00
|
|
|
let config = Config::default();
|
2020-06-09 20:38:29 +00:00
|
|
|
let static_fn = GetUrl::new(config, HashMap::new(), vec![TEST_CONTEXT.static_path.clone()]);
|
2017-11-10 16:46:14 +00:00
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value("app.css").unwrap());
|
2018-09-10 18:13:44 +00:00
|
|
|
args.insert("trailing_slash".to_string(), to_value(true).unwrap());
|
2019-01-23 18:20:02 +00:00
|
|
|
assert_eq!(static_fn.call(&args).unwrap(), "http://a-website.com/app.css/");
|
2017-11-10 16:46:14 +00:00
|
|
|
}
|
2017-11-16 17:08:06 +00:00
|
|
|
|
2017-11-10 16:46:14 +00:00
|
|
|
#[test]
|
2018-09-10 18:13:44 +00:00
|
|
|
fn can_add_slashes_and_cachebust() {
|
2017-11-10 16:46:14 +00:00
|
|
|
let config = Config::default();
|
2020-06-09 20:38:29 +00:00
|
|
|
let static_fn = GetUrl::new(config, HashMap::new(), vec![TEST_CONTEXT.static_path.clone()]);
|
2017-11-10 16:46:14 +00:00
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value("app.css").unwrap());
|
2018-09-10 18:13:44 +00:00
|
|
|
args.insert("trailing_slash".to_string(), to_value(true).unwrap());
|
2017-11-10 16:46:14 +00:00
|
|
|
args.insert("cachebust".to_string(), to_value(true).unwrap());
|
2020-05-23 09:46:50 +00:00
|
|
|
assert_eq!(static_fn.call(&args).unwrap(), "http://a-website.com/app.css/?h=572e691dc68c3fcd653ae463261bdb38f35dc6f01715d9ce68799319dd158840");
|
2017-11-10 16:46:14 +00:00
|
|
|
}
|
2017-08-07 11:38:13 +00:00
|
|
|
|
|
|
|
#[test]
|
2017-08-07 14:29:58 +00:00
|
|
|
fn can_link_to_some_static_file() {
|
2017-08-07 11:38:13 +00:00
|
|
|
let config = Config::default();
|
2020-06-09 20:38:29 +00:00
|
|
|
let static_fn = GetUrl::new(config, HashMap::new(), vec![TEST_CONTEXT.static_path.clone()]);
|
2017-08-07 11:38:13 +00:00
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value("app.css").unwrap());
|
2019-01-23 18:20:02 +00:00
|
|
|
assert_eq!(static_fn.call(&args).unwrap(), "http://a-website.com/app.css");
|
2017-08-07 11:38:13 +00:00
|
|
|
}
|
2017-11-16 17:08:06 +00:00
|
|
|
|
2019-09-03 08:51:41 +00:00
|
|
|
const TRANS_CONFIG: &str = r#"
|
2018-01-12 23:10:19 +00:00
|
|
|
base_url = "https://remplace-par-ton-url.fr"
|
|
|
|
default_language = "fr"
|
2021-02-22 21:26:19 +00:00
|
|
|
|
2018-01-12 23:10:19 +00:00
|
|
|
[translations]
|
|
|
|
title = "Un titre"
|
|
|
|
|
2021-03-21 17:15:38 +00:00
|
|
|
[languages]
|
|
|
|
[languages.en]
|
|
|
|
[languages.en.translations]
|
|
|
|
title = "A title" "#;
|
2018-01-12 23:10:19 +00:00
|
|
|
|
2019-09-03 08:51:41 +00:00
|
|
|
#[test]
|
|
|
|
fn can_translate_a_string() {
|
|
|
|
let config = Config::parse(TRANS_CONFIG).unwrap();
|
2019-01-23 18:20:02 +00:00
|
|
|
let static_fn = Trans::new(config);
|
2018-01-12 23:10:19 +00:00
|
|
|
let mut args = HashMap::new();
|
|
|
|
|
|
|
|
args.insert("key".to_string(), to_value("title").unwrap());
|
2019-01-23 18:20:02 +00:00
|
|
|
assert_eq!(static_fn.call(&args).unwrap(), "Un titre");
|
2018-01-12 23:10:19 +00:00
|
|
|
|
|
|
|
args.insert("lang".to_string(), to_value("en").unwrap());
|
2019-01-23 18:20:02 +00:00
|
|
|
assert_eq!(static_fn.call(&args).unwrap(), "A title");
|
2018-01-12 23:10:19 +00:00
|
|
|
|
|
|
|
args.insert("lang".to_string(), to_value("fr").unwrap());
|
2019-01-23 18:20:02 +00:00
|
|
|
assert_eq!(static_fn.call(&args).unwrap(), "Un titre");
|
2018-01-12 23:10:19 +00:00
|
|
|
}
|
2019-09-03 08:51:41 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn error_on_absent_translation_lang() {
|
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("lang".to_string(), to_value("absent").unwrap());
|
|
|
|
args.insert("key".to_string(), to_value("title").unwrap());
|
|
|
|
|
|
|
|
let config = Config::parse(TRANS_CONFIG).unwrap();
|
|
|
|
let error = Trans::new(config).call(&args).unwrap_err();
|
2020-11-28 12:04:49 +00:00
|
|
|
assert_eq!("Failed to retrieve term translation", format!("{}", error));
|
2019-09-03 08:51:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn error_on_absent_translation_key() {
|
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("lang".to_string(), to_value("en").unwrap());
|
|
|
|
args.insert("key".to_string(), to_value("absent").unwrap());
|
|
|
|
|
|
|
|
let config = Config::parse(TRANS_CONFIG).unwrap();
|
|
|
|
let error = Trans::new(config).call(&args).unwrap_err();
|
2020-11-28 12:04:49 +00:00
|
|
|
assert_eq!("Failed to retrieve term translation", format!("{}", error));
|
2019-09-03 08:51:41 +00:00
|
|
|
}
|
2020-04-12 17:23:17 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn error_when_language_not_available() {
|
|
|
|
let config = Config::parse(TRANS_CONFIG).unwrap();
|
2020-06-09 20:38:29 +00:00
|
|
|
let static_fn = GetUrl::new(config, HashMap::new(), vec![TEST_CONTEXT.static_path.clone()]);
|
2020-04-12 17:23:17 +00:00
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value("@/a_section/a_page.md").unwrap());
|
|
|
|
args.insert("lang".to_string(), to_value("it").unwrap());
|
|
|
|
let err = static_fn.call(&args).unwrap_err();
|
2020-04-22 08:07:17 +00:00
|
|
|
assert_eq!(
|
|
|
|
"`it` is not an authorized language (check config.languages).",
|
|
|
|
format!("{}", err)
|
|
|
|
);
|
2020-04-12 17:23:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn can_get_url_with_default_language() {
|
|
|
|
let config = Config::parse(TRANS_CONFIG).unwrap();
|
|
|
|
let mut permalinks = HashMap::new();
|
|
|
|
permalinks.insert(
|
|
|
|
"a_section/a_page.md".to_string(),
|
2020-04-22 08:07:17 +00:00
|
|
|
"https://remplace-par-ton-url.fr/a_section/a_page/".to_string(),
|
2020-04-12 17:23:17 +00:00
|
|
|
);
|
|
|
|
permalinks.insert(
|
|
|
|
"a_section/a_page.en.md".to_string(),
|
2020-04-22 08:07:17 +00:00
|
|
|
"https://remplace-par-ton-url.fr/en/a_section/a_page/".to_string(),
|
2020-04-12 17:23:17 +00:00
|
|
|
);
|
2020-06-09 20:38:29 +00:00
|
|
|
let static_fn = GetUrl::new(config, permalinks, vec![TEST_CONTEXT.static_path.clone()]);
|
2020-04-12 17:23:17 +00:00
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value("@/a_section/a_page.md").unwrap());
|
|
|
|
args.insert("lang".to_string(), to_value("fr").unwrap());
|
2020-04-22 08:07:17 +00:00
|
|
|
assert_eq!(
|
|
|
|
static_fn.call(&args).unwrap(),
|
|
|
|
"https://remplace-par-ton-url.fr/a_section/a_page/"
|
|
|
|
);
|
2020-04-12 17:23:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn can_get_url_with_other_language() {
|
|
|
|
let config = Config::parse(TRANS_CONFIG).unwrap();
|
|
|
|
let mut permalinks = HashMap::new();
|
|
|
|
permalinks.insert(
|
|
|
|
"a_section/a_page.md".to_string(),
|
2020-04-22 08:07:17 +00:00
|
|
|
"https://remplace-par-ton-url.fr/a_section/a_page/".to_string(),
|
2020-04-12 17:23:17 +00:00
|
|
|
);
|
|
|
|
permalinks.insert(
|
|
|
|
"a_section/a_page.en.md".to_string(),
|
2020-04-22 08:07:17 +00:00
|
|
|
"https://remplace-par-ton-url.fr/en/a_section/a_page/".to_string(),
|
2020-04-12 17:23:17 +00:00
|
|
|
);
|
2020-06-09 20:38:29 +00:00
|
|
|
let static_fn = GetUrl::new(config, permalinks, vec![TEST_CONTEXT.static_path.clone()]);
|
2020-04-12 17:23:17 +00:00
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value("@/a_section/a_page.md").unwrap());
|
|
|
|
args.insert("lang".to_string(), to_value("en").unwrap());
|
2020-04-22 08:07:17 +00:00
|
|
|
assert_eq!(
|
|
|
|
static_fn.call(&args).unwrap(),
|
|
|
|
"https://remplace-par-ton-url.fr/en/a_section/a_page/"
|
|
|
|
);
|
2020-04-12 17:23:17 +00:00
|
|
|
}
|
2020-06-09 20:38:29 +00:00
|
|
|
|
2021-03-06 21:49:04 +00:00
|
|
|
#[test]
|
|
|
|
fn can_get_feed_url_with_default_language() {
|
|
|
|
let config = Config::parse(TRANS_CONFIG).unwrap();
|
2021-03-07 12:57:41 +00:00
|
|
|
let static_fn =
|
|
|
|
GetUrl::new(config.clone(), HashMap::new(), vec![TEST_CONTEXT.static_path.clone()]);
|
2021-03-06 21:49:04 +00:00
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value(config.feed_filename).unwrap());
|
|
|
|
args.insert("lang".to_string(), to_value("fr").unwrap());
|
2021-03-07 12:57:41 +00:00
|
|
|
assert_eq!(static_fn.call(&args).unwrap(), "https://remplace-par-ton-url.fr/atom.xml");
|
2021-03-06 21:49:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn can_get_feed_url_with_other_language() {
|
|
|
|
let config = Config::parse(TRANS_CONFIG).unwrap();
|
2021-03-07 12:57:41 +00:00
|
|
|
let static_fn =
|
|
|
|
GetUrl::new(config.clone(), HashMap::new(), vec![TEST_CONTEXT.static_path.clone()]);
|
2021-03-06 21:49:04 +00:00
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value(config.feed_filename).unwrap());
|
|
|
|
args.insert("lang".to_string(), to_value("en").unwrap());
|
2021-03-07 12:57:41 +00:00
|
|
|
assert_eq!(static_fn.call(&args).unwrap(), "https://remplace-par-ton-url.fr/en/atom.xml");
|
2021-03-06 21:49:04 +00:00
|
|
|
}
|
|
|
|
|
2020-06-09 20:38:29 +00:00
|
|
|
#[test]
|
|
|
|
fn can_get_file_hash_sha256() {
|
|
|
|
let static_fn = GetFileHash::new(vec![TEST_CONTEXT.static_path.clone()]);
|
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value("app.css").unwrap());
|
|
|
|
args.insert("sha_type".to_string(), to_value(256).unwrap());
|
2020-06-18 19:11:22 +00:00
|
|
|
assert_eq!(
|
|
|
|
static_fn.call(&args).unwrap(),
|
|
|
|
"572e691dc68c3fcd653ae463261bdb38f35dc6f01715d9ce68799319dd158840"
|
|
|
|
);
|
2020-06-09 20:38:29 +00:00
|
|
|
}
|
|
|
|
|
2021-02-20 12:31:37 +00:00
|
|
|
#[test]
|
|
|
|
fn can_get_file_hash_sha256_base64() {
|
|
|
|
let static_fn = GetFileHash::new(vec![TEST_CONTEXT.static_path.clone()]);
|
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value("app.css").unwrap());
|
|
|
|
args.insert("sha_type".to_string(), to_value(256).unwrap());
|
|
|
|
args.insert("base64".to_string(), to_value(true).unwrap());
|
|
|
|
assert_eq!(static_fn.call(&args).unwrap(), "Vy5pHcaMP81lOuRjJhvbOPNdxvAXFdnOaHmTGd0ViEA=");
|
|
|
|
}
|
|
|
|
|
2020-06-09 20:38:29 +00:00
|
|
|
#[test]
|
|
|
|
fn can_get_file_hash_sha384() {
|
|
|
|
let static_fn = GetFileHash::new(vec![TEST_CONTEXT.static_path.clone()]);
|
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value("app.css").unwrap());
|
2021-02-20 12:31:37 +00:00
|
|
|
assert_eq!(
|
|
|
|
static_fn.call(&args).unwrap(),
|
|
|
|
"141c09bd28899773b772bbe064d8b718fa1d6f2852b7eafd5ed6689d26b74883b79e2e814cd69d5b52ab476aa284c414"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn can_get_file_hash_sha384_base64() {
|
|
|
|
let static_fn = GetFileHash::new(vec![TEST_CONTEXT.static_path.clone()]);
|
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value("app.css").unwrap());
|
|
|
|
args.insert("base64".to_string(), to_value(true).unwrap());
|
|
|
|
assert_eq!(
|
|
|
|
static_fn.call(&args).unwrap(),
|
|
|
|
"FBwJvSiJl3O3crvgZNi3GPodbyhSt+r9XtZonSa3SIO3ni6BTNadW1KrR2qihMQU"
|
|
|
|
);
|
2020-06-09 20:38:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn can_get_file_hash_sha512() {
|
|
|
|
let static_fn = GetFileHash::new(vec![TEST_CONTEXT.static_path.clone()]);
|
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value("app.css").unwrap());
|
|
|
|
args.insert("sha_type".to_string(), to_value(512).unwrap());
|
2021-02-20 12:31:37 +00:00
|
|
|
assert_eq!(
|
|
|
|
static_fn.call(&args).unwrap(),
|
|
|
|
"379dfab35123b9159d9e4e92dc90e2be44cf3c2f7f09b2e2df80a1b219b461de3556c93e1a9ceb3008e999e2d6a54b4f1d65ee9be9be63fa45ec88931623372f"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn can_get_file_hash_sha512_base64() {
|
|
|
|
let static_fn = GetFileHash::new(vec![TEST_CONTEXT.static_path.clone()]);
|
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value("app.css").unwrap());
|
|
|
|
args.insert("sha_type".to_string(), to_value(512).unwrap());
|
|
|
|
args.insert("base64".to_string(), to_value(true).unwrap());
|
|
|
|
assert_eq!(
|
|
|
|
static_fn.call(&args).unwrap(),
|
|
|
|
"N536s1EjuRWdnk6S3JDivkTPPC9/CbLi34Chshm0Yd41Vsk+GpzrMAjpmeLWpUtPHWXum+m+Y/pF7IiTFiM3Lw=="
|
|
|
|
);
|
2020-06-09 20:38:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn error_when_file_not_found_for_hash() {
|
|
|
|
let static_fn = GetFileHash::new(vec![TEST_CONTEXT.static_path.clone()]);
|
|
|
|
let mut args = HashMap::new();
|
|
|
|
args.insert("path".to_string(), to_value("doesnt-exist").unwrap());
|
2021-02-21 08:09:02 +00:00
|
|
|
let err = format!("{}", static_fn.call(&args).unwrap_err());
|
|
|
|
println!("{:?}", err);
|
|
|
|
|
|
|
|
assert!(err.contains("File doesnt-exist could not be open"));
|
2020-06-09 20:38:29 +00:00
|
|
|
}
|
2017-08-07 11:38:13 +00:00
|
|
|
}
|