in components/suggest/src/store.rs [2932:3311]
fn dynamic_basic() -> anyhow::Result<()> {
before_each();
let store = TestStore::new(
MockRemoteSettingsClient::default()
// A dynamic record whose attachment is a JSON object that only
// contains keywords
.with_record(SuggestionProvider::Dynamic.full_record(
"dynamic-0",
Some(json!({
"suggestion_type": "aaa",
})),
Some(MockAttachment::Json(json!({
"keywords": [
"aaa keyword",
"common keyword",
["common prefix", [" aaa"]],
["choco", ["bo", "late"]],
["dup", ["licate 1", "licate 2"]],
],
}))),
))
// A dynamic record with a score whose attachment is a JSON
// array with multiple suggestions with various properties
.with_record(SuggestionProvider::Dynamic.full_record(
"dynamic-1",
Some(json!({
"suggestion_type": "bbb",
"score": 1.0,
})),
Some(MockAttachment::Json(json!([
{
"keywords": [
"bbb keyword 0",
"common keyword",
"common bbb keyword",
["common prefix", [" bbb 0"]],
],
},
{
"keywords": [
"bbb keyword 1",
"common keyword",
"common bbb keyword",
["common prefix", [" bbb 1"]],
],
"dismissal_key": "bbb-1-dismissal-key",
},
{
"keywords": [
"bbb keyword 2",
"common keyword",
"common bbb keyword",
["common prefix", [" bbb 2"]],
],
"data": json!("bbb-2-data"),
"dismissal_key": "bbb-2-dismissal-key",
},
{
"keywords": [
"bbb keyword 3",
"common keyword",
"common bbb keyword",
["common prefix", [" bbb 3"]],
],
"data": json!("bbb-3-data"),
},
]))),
)),
);
store.ingest(SuggestIngestionConstraints {
providers: Some(vec![SuggestionProvider::Dynamic]),
provider_constraints: Some(SuggestionProviderConstraints {
dynamic_suggestion_types: Some(vec!["aaa".to_string(), "bbb".to_string()]),
..SuggestionProviderConstraints::default()
}),
..SuggestIngestionConstraints::all_providers()
});
// queries that shouldn't match anything
let no_match_queries = vec!["aaa", "common", "common prefi", "choc", "chocolate extra"];
for query in &no_match_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![],
);
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["bbb"])),
vec![],
);
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa", "bbb"])),
vec![],
);
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa", "zzz"])),
vec![],
);
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["zzz"])),
vec![],
);
}
// queries that should match only the "aaa" suggestion
let aaa_queries = [
"aaa keyword",
"common prefix a",
"common prefix aa",
"common prefix aaa",
"choco",
"chocob",
"chocobo",
"chocol",
"chocolate",
"dup",
"dupl",
"duplicate",
"duplicate ",
"duplicate 1",
"duplicate 2",
];
for query in aaa_queries {
for suggestion_types in [
["aaa"].as_slice(),
&["aaa", "bbb"],
&["bbb", "aaa"],
&["aaa", "zzz"],
&["zzz", "aaa"],
] {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, suggestion_types)),
vec![Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: None,
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
}],
);
}
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["bbb"])),
vec![],
);
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["zzz"])),
vec![],
);
}
// queries that should match only the "bbb 0" suggestion
let bbb_0_queries = ["bbb keyword 0", "common prefix bbb 0"];
for query in &bbb_0_queries {
for suggestion_types in [
["bbb"].as_slice(),
&["bbb", "aaa"],
&["aaa", "bbb"],
&["bbb", "zzz"],
&["zzz", "bbb"],
] {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, suggestion_types)),
vec![Suggestion::Dynamic {
suggestion_type: "bbb".into(),
data: None,
dismissal_key: None,
score: 1.0,
}],
);
}
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![],
);
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["zzz"])),
vec![],
);
}
// queries that should match only the "bbb 1" suggestion
let bbb_1_queries = ["bbb keyword 1", "common prefix bbb 1"];
for query in &bbb_1_queries {
for suggestion_types in [
["bbb"].as_slice(),
&["bbb", "aaa"],
&["aaa", "bbb"],
&["bbb", "zzz"],
&["zzz", "bbb"],
] {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, suggestion_types)),
vec![Suggestion::Dynamic {
suggestion_type: "bbb".into(),
data: None,
dismissal_key: Some("bbb-1-dismissal-key".to_string()),
score: 1.0,
}],
);
}
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![],
);
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["zzz"])),
vec![],
);
}
// queries that should match only the "bbb 2" suggestion
let bbb_2_queries = ["bbb keyword 2", "common prefix bbb 2"];
for query in &bbb_2_queries {
for suggestion_types in [
["bbb"].as_slice(),
&["bbb", "aaa"],
&["aaa", "bbb"],
&["bbb", "zzz"],
&["zzz", "bbb"],
] {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, suggestion_types)),
vec![Suggestion::Dynamic {
suggestion_type: "bbb".into(),
data: Some(json!("bbb-2-data")),
dismissal_key: Some("bbb-2-dismissal-key".to_string()),
score: 1.0,
}],
);
}
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![],
);
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["zzz"])),
vec![],
);
}
// queries that should match only the "bbb 3" suggestion
let bbb_3_queries = ["bbb keyword 3", "common prefix bbb 3"];
for query in &bbb_3_queries {
for suggestion_types in [
["bbb"].as_slice(),
&["bbb", "aaa"],
&["aaa", "bbb"],
&["bbb", "zzz"],
&["zzz", "bbb"],
] {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, suggestion_types)),
vec![Suggestion::Dynamic {
suggestion_type: "bbb".into(),
data: Some(json!("bbb-3-data")),
dismissal_key: None,
score: 1.0,
}],
);
}
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![],
);
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["zzz"])),
vec![],
);
}
// queries that should match only the "bbb" suggestions
let bbb_queries = [
"common bbb keyword",
"common prefix b",
"common prefix bb",
"common prefix bbb",
"common prefix bbb ",
];
for query in &bbb_queries {
for suggestion_types in [
["bbb"].as_slice(),
&["bbb", "aaa"],
&["aaa", "bbb"],
&["bbb", "zzz"],
&["zzz", "bbb"],
] {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, suggestion_types)),
vec![
Suggestion::Dynamic {
suggestion_type: "bbb".into(),
data: None,
dismissal_key: None,
score: 1.0,
},
Suggestion::Dynamic {
suggestion_type: "bbb".into(),
data: None,
dismissal_key: Some("bbb-1-dismissal-key".to_string()),
score: 1.0,
},
Suggestion::Dynamic {
suggestion_type: "bbb".into(),
data: Some(json!("bbb-2-data")),
dismissal_key: Some("bbb-2-dismissal-key".to_string()),
score: 1.0,
},
Suggestion::Dynamic {
suggestion_type: "bbb".into(),
data: Some(json!("bbb-3-data")),
dismissal_key: None,
score: 1.0,
}
],
);
}
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![],
);
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["zzz"])),
vec![],
);
}
// queries that should match all suggestions
let common_queries = ["common keyword", "common prefix", "common prefix "];
for query in &common_queries {
for suggestion_types in [
["aaa", "bbb"].as_slice(),
&["bbb", "aaa"],
&["zzz", "aaa", "bbb"],
&["aaa", "zzz", "bbb"],
&["aaa", "bbb", "zzz"],
] {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, suggestion_types)),
vec![
Suggestion::Dynamic {
suggestion_type: "bbb".into(),
data: None,
dismissal_key: None,
score: 1.0,
},
Suggestion::Dynamic {
suggestion_type: "bbb".into(),
data: None,
dismissal_key: Some("bbb-1-dismissal-key".to_string()),
score: 1.0,
},
Suggestion::Dynamic {
suggestion_type: "bbb".into(),
data: Some(json!("bbb-2-data")),
dismissal_key: Some("bbb-2-dismissal-key".to_string()),
score: 1.0,
},
Suggestion::Dynamic {
suggestion_type: "bbb".into(),
data: Some(json!("bbb-3-data")),
dismissal_key: None,
score: 1.0,
},
Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: None,
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
},
],
);
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["zzz"])),
vec![],
);
}
}
Ok(())
}