in components/suggest/src/store.rs [3314:3666]
fn dynamic_same_type_in_different_records() -> anyhow::Result<()> {
before_each();
// Make a store with the same dynamic suggestion type in three different
// records.
let mut store = TestStore::new(
MockRemoteSettingsClient::default()
// A record whose attachment is a JSON object
.with_record(SuggestionProvider::Dynamic.full_record(
"dynamic-0",
Some(json!({
"suggestion_type": "aaa",
})),
Some(MockAttachment::Json(json!({
"keywords": [
"record 0 keyword",
"common keyword",
["common prefix", [" 0"]],
],
"data": json!("record-0-data"),
}))),
))
// Another record whose attachment is a JSON object
.with_record(SuggestionProvider::Dynamic.full_record(
"dynamic-1",
Some(json!({
"suggestion_type": "aaa",
})),
Some(MockAttachment::Json(json!({
"keywords": [
"record 1 keyword",
"common keyword",
["common prefix", [" 1"]],
],
"data": json!("record-1-data"),
}))),
))
// A record whose attachment is a JSON array with some
// suggestions
.with_record(SuggestionProvider::Dynamic.full_record(
"dynamic-2",
Some(json!({
"suggestion_type": "aaa",
})),
Some(MockAttachment::Json(json!([
{
"keywords": [
"record 2 keyword",
"record 2 keyword 0",
"common keyword",
["common prefix", [" 2-0"]],
],
"data": json!("record-2-data-0"),
},
{
"keywords": [
"record 2 keyword",
"record 2 keyword 1",
"common keyword",
["common prefix", [" 2-1"]],
],
"data": json!("record-2-data-1"),
},
]))),
)),
);
store.ingest(SuggestIngestionConstraints {
providers: Some(vec![SuggestionProvider::Dynamic]),
provider_constraints: Some(SuggestionProviderConstraints {
dynamic_suggestion_types: Some(vec!["aaa".to_string()]),
..SuggestionProviderConstraints::default()
}),
..SuggestIngestionConstraints::all_providers()
});
// queries that should match only the suggestion in record 0
let record_0_queries = ["record 0 keyword", "common prefix 0"];
for query in record_0_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-0-data")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
}],
);
}
// queries that should match only the suggestion in record 1
let record_1_queries = ["record 1 keyword", "common prefix 1"];
for query in record_1_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-1-data")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
}],
);
}
// queries that should match only the suggestions in record 2
let record_2_queries = ["record 2 keyword", "common prefix 2", "common prefix 2-"];
for query in record_2_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![
Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-2-data-0")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
},
Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-2-data-1")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
},
],
);
}
// queries that should match only record 2 suggestion 0
let record_2_0_queries = ["record 2 keyword 0", "common prefix 2-0"];
for query in record_2_0_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-2-data-0")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
}],
);
}
// queries that should match only record 2 suggestion 1
let record_2_1_queries = ["record 2 keyword 1", "common prefix 2-1"];
for query in record_2_1_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-2-data-1")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
}],
);
}
// queries that should match all suggestions
let common_queries = ["common keyword", "common prefix", "common prefix "];
for query in common_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![
Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-0-data")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
},
Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-1-data")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
},
Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-2-data-0")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
},
Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-2-data-1")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
},
],
);
}
// Delete record 0.
store
.client_mut()
.delete_record(SuggestionProvider::Dynamic.empty_record("dynamic-0"));
store.ingest(SuggestIngestionConstraints {
providers: Some(vec![SuggestionProvider::Dynamic]),
provider_constraints: Some(SuggestionProviderConstraints {
dynamic_suggestion_types: Some(vec!["aaa".to_string()]),
..SuggestionProviderConstraints::default()
}),
..SuggestIngestionConstraints::all_providers()
});
// Keywords from record 0 should not match anything.
for query in record_0_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![],
);
}
// The suggestion in record 1 should remain fetchable.
for query in record_1_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-1-data")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
}],
);
}
// The suggestions in record 2 should remain fetchable.
for query in record_2_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![
Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-2-data-0")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
},
Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-2-data-1")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
},
],
);
}
for query in record_2_0_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-2-data-0")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
}],
);
}
for query in record_2_1_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-2-data-1")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
}],
);
}
// All remaining suggestions should remain fetchable via the common
// keywords.
for query in common_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![
Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-1-data")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
},
Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-2-data-0")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
},
Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-2-data-1")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
},
],
);
}
// Delete record 2.
store
.client_mut()
.delete_record(SuggestionProvider::Dynamic.empty_record("dynamic-2"));
store.ingest(SuggestIngestionConstraints {
providers: Some(vec![SuggestionProvider::Dynamic]),
provider_constraints: Some(SuggestionProviderConstraints {
dynamic_suggestion_types: Some(vec!["aaa".to_string()]),
..SuggestionProviderConstraints::default()
}),
..SuggestIngestionConstraints::all_providers()
});
// Keywords from record 0 still should not match anything.
for query in record_0_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![],
);
}
// The suggestion in record 1 should remain fetchable.
for query in record_1_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-1-data")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
}],
);
}
// The suggestions in record 2 should not be fetchable.
for query in record_2_queries
.iter()
.chain(record_2_0_queries.iter().chain(record_2_1_queries.iter()))
{
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![]
);
}
// The one remaining suggestion, from record 1, should remain fetchable
// via the common keywords.
for query in common_queries {
assert_eq!(
store.fetch_suggestions(SuggestionQuery::dynamic(query, &["aaa"])),
vec![Suggestion::Dynamic {
suggestion_type: "aaa".into(),
data: Some(json!("record-1-data")),
dismissal_key: None,
score: DEFAULT_SUGGESTION_SCORE,
},],
);
}
Ok(())
}