mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-09-18 06:34:54 +08:00
fix(repository): 扩展资源索引查询面
This commit is contained in:
@@ -234,8 +234,12 @@ struct CliOptions {
|
||||
query_resource_type: Option<ResourceType>,
|
||||
query_hash: Option<String>,
|
||||
query_path_pattern: Option<String>,
|
||||
query_official_release_id: Option<String>,
|
||||
query_platform: Option<String>,
|
||||
query_destination: Option<String>,
|
||||
query_bundle_path: Option<String>,
|
||||
query_archive_entry: Option<String>,
|
||||
query_parse_status: Option<String>,
|
||||
query_path_id: Option<i64>,
|
||||
query_class_id: Option<i32>,
|
||||
query_field_path: Option<String>,
|
||||
@@ -286,8 +290,12 @@ impl Default for CliOptions {
|
||||
query_resource_type: None,
|
||||
query_hash: None,
|
||||
query_path_pattern: None,
|
||||
query_official_release_id: None,
|
||||
query_platform: None,
|
||||
query_destination: None,
|
||||
query_bundle_path: None,
|
||||
query_archive_entry: None,
|
||||
query_parse_status: None,
|
||||
query_path_id: None,
|
||||
query_class_id: None,
|
||||
query_field_path: None,
|
||||
@@ -2782,6 +2790,13 @@ fn build_resource_index_report(
|
||||
"resource_type": query.resource_type,
|
||||
"hash": query.hash,
|
||||
"path_pattern": query.path_pattern,
|
||||
"official_release_id": query.official_release_id,
|
||||
"platform": query.platform,
|
||||
"destination": query.destination,
|
||||
"bundle_path": query.bundle_path,
|
||||
"archive_entry": query.archive_entry,
|
||||
"parse_status": query.parse_status,
|
||||
"text_unit_format": query.text_unit_format,
|
||||
},
|
||||
"entries": entries,
|
||||
}))
|
||||
@@ -3243,6 +3258,17 @@ fn rpc_resource_index_params(
|
||||
resource_type,
|
||||
hash: rpc_string_param(params, "hash").map(str::to_string),
|
||||
path_pattern: rpc_string_param(params, "path_pattern").map(str::to_string),
|
||||
official_release_id: rpc_string_param(params, "official_release_id")
|
||||
.or_else(|| rpc_string_param(params, "release_id"))
|
||||
.map(str::to_string),
|
||||
platform: rpc_string_param(params, "platform").map(str::to_string),
|
||||
destination: rpc_string_param(params, "destination").map(str::to_string),
|
||||
bundle_path: rpc_string_param(params, "bundle_path").map(str::to_string),
|
||||
archive_entry: rpc_string_param(params, "archive_entry").map(str::to_string),
|
||||
parse_status: rpc_string_param(params, "parse_status").map(str::to_string),
|
||||
text_unit_format: rpc_string_param(params, "text_unit_format")
|
||||
.or_else(|| rpc_string_param(params, "format"))
|
||||
.map(str::to_string),
|
||||
};
|
||||
Ok((query, offset, limit))
|
||||
}
|
||||
@@ -4244,6 +4270,33 @@ fn readonly_query_rpc_params(options: &CliOptions) -> Option<serde_json::Value>
|
||||
if let Some(path_pattern) = options.query_path_pattern.as_ref() {
|
||||
params.insert("path_pattern".to_string(), serde_json::json!(path_pattern));
|
||||
}
|
||||
if let Some(release_id) = options.query_official_release_id.as_ref() {
|
||||
params.insert(
|
||||
"official_release_id".to_string(),
|
||||
serde_json::json!(release_id),
|
||||
);
|
||||
}
|
||||
if let Some(platform) = options.query_platform.as_ref() {
|
||||
params.insert("platform".to_string(), serde_json::json!(platform));
|
||||
}
|
||||
if let Some(destination) = options.query_destination.as_ref() {
|
||||
params.insert("destination".to_string(), serde_json::json!(destination));
|
||||
}
|
||||
if let Some(bundle_path) = options.query_bundle_path.as_ref() {
|
||||
params.insert("bundle_path".to_string(), serde_json::json!(bundle_path));
|
||||
}
|
||||
if let Some(archive_entry) = options.query_archive_entry.as_ref() {
|
||||
params.insert(
|
||||
"archive_entry".to_string(),
|
||||
serde_json::json!(archive_entry),
|
||||
);
|
||||
}
|
||||
if let Some(parse_status) = options.query_parse_status.as_ref() {
|
||||
params.insert("parse_status".to_string(), serde_json::json!(parse_status));
|
||||
}
|
||||
if let Some(format) = options.query_format.as_ref() {
|
||||
params.insert("text_unit_format".to_string(), serde_json::json!(format));
|
||||
}
|
||||
}
|
||||
CliCommand::ParseTextUnits | CliCommand::ParseErrors => {
|
||||
if let Some(destination) = options.query_destination.as_ref() {
|
||||
@@ -4314,27 +4367,28 @@ fn build_readonly_query_report(
|
||||
}
|
||||
|
||||
fn validate_readonly_query_options(options: &CliOptions) -> anyhow::Result<()> {
|
||||
let has_resource_index_filter =
|
||||
options.query_resource_type.is_some() || options.query_hash.is_some();
|
||||
let has_textunit_filter = options.query_destination.is_some()
|
||||
|| options.query_archive_entry.is_some()
|
||||
|| options.query_path_id.is_some()
|
||||
let has_resource_index_filter = options.query_resource_type.is_some()
|
||||
|| options.query_hash.is_some()
|
||||
|| options.query_official_release_id.is_some()
|
||||
|| options.query_platform.is_some()
|
||||
|| options.query_bundle_path.is_some()
|
||||
|| options.query_parse_status.is_some();
|
||||
let has_parse_object_filter = options.query_path_id.is_some()
|
||||
|| options.query_class_id.is_some()
|
||||
|| options.query_field_path.is_some()
|
||||
|| options.query_format.is_some();
|
||||
|| options.query_field_path.is_some();
|
||||
|
||||
match options.command {
|
||||
CliCommand::ResourceIndex => {
|
||||
if has_textunit_filter {
|
||||
if has_parse_object_filter {
|
||||
return Err(anyhow::anyhow!(
|
||||
"--destination/--archive-entry/--path-id/--class-id/--field-path/--format 只适用于 parse-text-units 或 parse-errors"
|
||||
"--path-id/--class-id/--field-path 只适用于 parse-text-units 或 parse-errors"
|
||||
));
|
||||
}
|
||||
}
|
||||
CliCommand::ParseTextUnits | CliCommand::ParseErrors => {
|
||||
if has_resource_index_filter {
|
||||
return Err(anyhow::anyhow!(
|
||||
"--resource-type/--hash 只适用于 resource-index"
|
||||
"--resource-type/--hash/--release-id/--platform/--bundle-path/--parse-status 只适用于 resource-index"
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -4526,6 +4580,13 @@ fn resource_index_query_from_options(options: &CliOptions) -> ResourceQuery {
|
||||
resource_type: options.query_resource_type,
|
||||
hash: options.query_hash.clone(),
|
||||
path_pattern: options.query_path_pattern.clone(),
|
||||
official_release_id: options.query_official_release_id.clone(),
|
||||
platform: options.query_platform.clone(),
|
||||
destination: options.query_destination.clone(),
|
||||
bundle_path: options.query_bundle_path.clone(),
|
||||
archive_entry: options.query_archive_entry.clone(),
|
||||
parse_status: options.query_parse_status.clone(),
|
||||
text_unit_format: options.query_format.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7261,14 +7322,30 @@ fn parse_args_with_env(
|
||||
options.query_path_pattern = Some(next_option_value(&mut args, &flag)?);
|
||||
options.query_option_explicit = true;
|
||||
}
|
||||
"--release-id" | "--official-release-id" => {
|
||||
options.query_official_release_id = Some(next_option_value(&mut args, &flag)?);
|
||||
options.query_option_explicit = true;
|
||||
}
|
||||
"--platform" => {
|
||||
options.query_platform = Some(next_option_value(&mut args, &flag)?);
|
||||
options.query_option_explicit = true;
|
||||
}
|
||||
"--destination" => {
|
||||
options.query_destination = Some(next_option_value(&mut args, &flag)?);
|
||||
options.query_option_explicit = true;
|
||||
}
|
||||
"--bundle-path" => {
|
||||
options.query_bundle_path = Some(next_option_value(&mut args, &flag)?);
|
||||
options.query_option_explicit = true;
|
||||
}
|
||||
"--archive-entry" => {
|
||||
options.query_archive_entry = Some(next_option_value(&mut args, &flag)?);
|
||||
options.query_option_explicit = true;
|
||||
}
|
||||
"--parse-status" => {
|
||||
options.query_parse_status = Some(next_option_value(&mut args, &flag)?);
|
||||
options.query_option_explicit = true;
|
||||
}
|
||||
"--path-id" => {
|
||||
options.query_path_id = Some(
|
||||
next_option_value(&mut args, &flag)?
|
||||
@@ -7675,12 +7752,16 @@ fn print_usage(binary: &str) {
|
||||
eprintln!(
|
||||
" --path-pattern <GLOB> Filter resource-index or parse detail by path pattern"
|
||||
);
|
||||
eprintln!(" --destination <PATH> Filter parse detail by official destination");
|
||||
eprintln!(" --archive-entry <PATH> Filter parse detail by ZIP/archive entry");
|
||||
eprintln!(" --release-id <ID> Filter resource-index by official release ID");
|
||||
eprintln!(" --platform <NAME> Filter resource-index by metadata platform");
|
||||
eprintln!(" --destination <PATH> Filter resource-index or parse detail by official destination");
|
||||
eprintln!(" --bundle-path <PATH> Filter resource-index by metadata bundle path");
|
||||
eprintln!(" --archive-entry <PATH> Filter resource-index or parse detail by ZIP/archive entry");
|
||||
eprintln!(" --parse-status <STATUS> Filter resource-index by parse status");
|
||||
eprintln!(" --path-id <ID> Filter parse detail by Unity object path ID");
|
||||
eprintln!(" --class-id <ID> Filter parse detail by Unity class ID");
|
||||
eprintln!(" --field-path <PATH> Filter parse detail, or TypeTree field path after UnityFS field patch commands");
|
||||
eprintln!(" --format <NAME> Filter parse text units by payload format");
|
||||
eprintln!(" --format <NAME> Filter resource-index or parse text units by payload format");
|
||||
eprintln!();
|
||||
eprintln!("Write patch:");
|
||||
eprintln!(" --patch-kind <binary|json|text> Patch type for patch-apply");
|
||||
@@ -8332,6 +8413,20 @@ mod tests {
|
||||
"abc",
|
||||
"--path-pattern",
|
||||
"TextAssets/**",
|
||||
"--release-id",
|
||||
"v-current",
|
||||
"--platform",
|
||||
"windows",
|
||||
"--destination",
|
||||
"TextAssets/Scenario.json",
|
||||
"--bundle-path",
|
||||
"Bundles/story.bundle",
|
||||
"--archive-entry",
|
||||
"story/Scenario.json",
|
||||
"--parse-status",
|
||||
"parsed",
|
||||
"--format",
|
||||
"json",
|
||||
"--offset",
|
||||
"5",
|
||||
"--limit",
|
||||
@@ -8342,6 +8437,25 @@ mod tests {
|
||||
assert_eq!(index.query_resource_type, Some(ResourceType::TextAsset));
|
||||
assert_eq!(index.query_hash.as_deref(), Some("abc"));
|
||||
assert_eq!(index.query_path_pattern.as_deref(), Some("TextAssets/**"));
|
||||
assert_eq!(
|
||||
index.query_official_release_id.as_deref(),
|
||||
Some("v-current")
|
||||
);
|
||||
assert_eq!(index.query_platform.as_deref(), Some("windows"));
|
||||
assert_eq!(
|
||||
index.query_destination.as_deref(),
|
||||
Some("TextAssets/Scenario.json")
|
||||
);
|
||||
assert_eq!(
|
||||
index.query_bundle_path.as_deref(),
|
||||
Some("Bundles/story.bundle")
|
||||
);
|
||||
assert_eq!(
|
||||
index.query_archive_entry.as_deref(),
|
||||
Some("story/Scenario.json")
|
||||
);
|
||||
assert_eq!(index.query_parse_status.as_deref(), Some("parsed"));
|
||||
assert_eq!(index.query_format.as_deref(), Some("json"));
|
||||
assert_eq!(index.query_offset, 5);
|
||||
assert_eq!(index.query_limit, 25);
|
||||
|
||||
@@ -8388,6 +8502,11 @@ mod tests {
|
||||
|
||||
let error = parse(&["bat", "parse-text-units", "--hash", "abc"]).unwrap_err();
|
||||
assert!(error.to_string().contains("--resource-type/--hash"));
|
||||
|
||||
let error = parse(&["bat", "resource-index", "--path-id", "42"]).unwrap_err();
|
||||
assert!(error
|
||||
.to_string()
|
||||
.contains("--path-id/--class-id/--field-path"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -9871,6 +9990,20 @@ mod tests {
|
||||
state_dir.to_str().unwrap(),
|
||||
"--resource-type",
|
||||
"asset_bundle",
|
||||
"--release-id",
|
||||
"v-current",
|
||||
"--platform",
|
||||
"windows",
|
||||
"--destination",
|
||||
"Bundles/story.bundle",
|
||||
"--bundle-path",
|
||||
"Bundles/story.bundle",
|
||||
"--archive-entry",
|
||||
"story/TextAsset",
|
||||
"--parse-status",
|
||||
"parsed",
|
||||
"--format",
|
||||
"json",
|
||||
"--offset",
|
||||
"2",
|
||||
"--limit",
|
||||
@@ -9896,6 +10029,13 @@ mod tests {
|
||||
assert_eq!(seen[0].0, RPC_METHOD_RESOURCE_INDEX);
|
||||
let params = seen[0].1.as_ref().unwrap();
|
||||
assert_eq!(params["resource_type"], "asset_bundle");
|
||||
assert_eq!(params["official_release_id"], "v-current");
|
||||
assert_eq!(params["platform"], "windows");
|
||||
assert_eq!(params["destination"], "Bundles/story.bundle");
|
||||
assert_eq!(params["bundle_path"], "Bundles/story.bundle");
|
||||
assert_eq!(params["archive_entry"], "story/TextAsset");
|
||||
assert_eq!(params["parse_status"], "parsed");
|
||||
assert_eq!(params["text_unit_format"], "json");
|
||||
assert_eq!(params["offset"], 2);
|
||||
assert_eq!(params["limit"], 3);
|
||||
}
|
||||
@@ -10500,6 +10640,8 @@ mod tests {
|
||||
official_release_id: Some("v-current".to_string()),
|
||||
platform: Some("windows".to_string()),
|
||||
bundle_path: Some(path.to_string()),
|
||||
archive_entries: vec!["story/Scenario.json".to_string()],
|
||||
parse_statuses: vec!["parsed".to_string()],
|
||||
text_assets: vec!["Scenario".to_string()],
|
||||
text_unit_count: 4,
|
||||
text_unit_formats: vec!["json".to_string()],
|
||||
@@ -10573,6 +10715,13 @@ mod tests {
|
||||
"resource.index",
|
||||
Some(serde_json::json!({
|
||||
"resource_type": "text_asset",
|
||||
"release_id": "v-current",
|
||||
"platform": "windows",
|
||||
"destination": "TextAssets/c.json",
|
||||
"bundle_path": "TextAssets/c.json",
|
||||
"archive_entry": "story/Scenario.json",
|
||||
"parse_status": "parsed",
|
||||
"format": "json",
|
||||
"offset": 0,
|
||||
"limit": 10
|
||||
})),
|
||||
@@ -10597,8 +10746,23 @@ mod tests {
|
||||
assert_eq!(entries[0]["entry"]["resource_type"], "TextAsset");
|
||||
assert_eq!(entries[0]["metadata"]["official_release_id"], "v-current");
|
||||
assert_eq!(entries[0]["metadata"]["platform"], "windows");
|
||||
assert_eq!(
|
||||
entries[0]["metadata"]["archive_entries"][0],
|
||||
"story/Scenario.json"
|
||||
);
|
||||
assert_eq!(entries[0]["metadata"]["parse_statuses"][0], "parsed");
|
||||
assert_eq!(entries[0]["metadata"]["text_assets"][0], "Scenario");
|
||||
assert_eq!(entries[0]["metadata"]["text_unit_count"], 4);
|
||||
assert_eq!(value["data"]["query"]["official_release_id"], "v-current");
|
||||
assert_eq!(value["data"]["query"]["platform"], "windows");
|
||||
assert_eq!(value["data"]["query"]["destination"], "TextAssets/c.json");
|
||||
assert_eq!(value["data"]["query"]["bundle_path"], "TextAssets/c.json");
|
||||
assert_eq!(
|
||||
value["data"]["query"]["archive_entry"],
|
||||
"story/Scenario.json"
|
||||
);
|
||||
assert_eq!(value["data"]["query"]["parse_status"], "parsed");
|
||||
assert_eq!(value["data"]["query"]["text_unit_format"], "json");
|
||||
|
||||
let envelope = dispatch_rpc_method(
|
||||
&rpc_request(
|
||||
|
||||
@@ -326,6 +326,12 @@ impl SqliteResourceRepository {
|
||||
.push(" ESCAPE '\\'");
|
||||
}
|
||||
|
||||
if let Some(destination) = &query.destination {
|
||||
push_condition_prefix(builder, &mut has_where);
|
||||
builder.push("path = ");
|
||||
builder.push_bind(destination);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -349,10 +355,21 @@ impl SqliteResourceRepository {
|
||||
.await
|
||||
.map_err(|error| bat_core::Error::Other(error.into()))?;
|
||||
|
||||
rows.into_iter().map(Self::resource_from_row).collect()
|
||||
let resources = rows
|
||||
.into_iter()
|
||||
.map(Self::resource_from_row)
|
||||
.collect::<bat_core::Result<Vec<_>>>()?;
|
||||
Ok(resources
|
||||
.into_iter()
|
||||
.filter(|resource| query_matches(query, resource))
|
||||
.collect())
|
||||
}
|
||||
|
||||
async fn count_resources(&self, query: &ResourceQuery) -> bat_core::Result<u64> {
|
||||
if query.requires_resource_scan() {
|
||||
return Ok(self.fetch_resources(query, None).await?.len() as u64);
|
||||
}
|
||||
|
||||
let mut builder = QueryBuilder::<Sqlite>::new("SELECT COUNT(*) FROM resources");
|
||||
Self::apply_filters(&mut builder, query)?;
|
||||
|
||||
@@ -536,6 +553,63 @@ fn query_matches(query: &ResourceQuery, resource: &Resource) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(release_id) = &query.official_release_id {
|
||||
if resource.metadata.official_release_id.as_deref() != Some(release_id.as_str()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(platform) = &query.platform {
|
||||
if resource.metadata.platform.as_deref() != Some(platform.as_str()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(destination) = &query.destination {
|
||||
if resource.entry.path != *destination {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(bundle_path) = &query.bundle_path {
|
||||
if resource.metadata.bundle_path.as_deref() != Some(bundle_path.as_str()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(archive_entry) = &query.archive_entry {
|
||||
if !resource
|
||||
.metadata
|
||||
.archive_entries
|
||||
.iter()
|
||||
.any(|entry| entry == archive_entry)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(parse_status) = &query.parse_status {
|
||||
if !resource
|
||||
.metadata
|
||||
.parse_statuses
|
||||
.iter()
|
||||
.any(|status| status == parse_status)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(text_unit_format) = &query.text_unit_format {
|
||||
if !resource
|
||||
.metadata
|
||||
.text_unit_formats
|
||||
.iter()
|
||||
.any(|format| format == text_unit_format)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
@@ -641,6 +715,7 @@ mod tests {
|
||||
resource_type: Some(ResourceType::AssetBundle),
|
||||
hash: Some("hash-a".to_string()),
|
||||
path_pattern: Some("synthetic-*.bundle".to_string()),
|
||||
..ResourceQuery::all()
|
||||
};
|
||||
|
||||
let results = repository.list(query).await.unwrap();
|
||||
@@ -653,6 +728,52 @@ mod tests {
|
||||
assert_eq!(repository.count(ResourceQuery::all()).await.unwrap(), 2);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn list_filters_by_release_parse_and_textunit_metadata() {
|
||||
let repository = InMemoryResourceRepository::new();
|
||||
let mut matching = resource(
|
||||
"resource/text-a",
|
||||
"TextAssets/a.json",
|
||||
"hash-a",
|
||||
ResourceType::TextAsset,
|
||||
);
|
||||
matching.metadata.official_release_id = Some("v-current".to_string());
|
||||
matching.metadata.platform = Some("windows".to_string());
|
||||
matching.metadata.bundle_path = Some("Bundles/story.bundle".to_string());
|
||||
matching.metadata.archive_entries = vec!["story/Scenario.json".to_string()];
|
||||
matching.metadata.parse_statuses = vec!["parsed".to_string()];
|
||||
matching.metadata.text_unit_formats = vec!["json".to_string()];
|
||||
repository.add(matching).await.unwrap();
|
||||
|
||||
let mut stale = resource(
|
||||
"resource/text-b",
|
||||
"TextAssets/b.json",
|
||||
"hash-b",
|
||||
ResourceType::TextAsset,
|
||||
);
|
||||
stale.metadata.official_release_id = Some("v-old".to_string());
|
||||
stale.metadata.platform = Some("android".to_string());
|
||||
stale.metadata.parse_statuses = vec!["failed".to_string()];
|
||||
stale.metadata.text_unit_formats = vec!["plain".to_string()];
|
||||
repository.add(stale).await.unwrap();
|
||||
|
||||
let query = ResourceQuery {
|
||||
official_release_id: Some("v-current".to_string()),
|
||||
platform: Some("windows".to_string()),
|
||||
destination: Some("TextAssets/a.json".to_string()),
|
||||
bundle_path: Some("Bundles/story.bundle".to_string()),
|
||||
archive_entry: Some("story/Scenario.json".to_string()),
|
||||
parse_status: Some("parsed".to_string()),
|
||||
text_unit_format: Some("json".to_string()),
|
||||
..ResourceQuery::all()
|
||||
};
|
||||
|
||||
let results = repository.list(query.clone()).await.unwrap();
|
||||
assert_eq!(results.len(), 1);
|
||||
assert_eq!(results[0].id, "resource/text-a");
|
||||
assert_eq!(repository.count(query).await.unwrap(), 1);
|
||||
}
|
||||
|
||||
async fn sqlite_repository() -> (tempfile::TempDir, SqliteResourceRepository) {
|
||||
let temp_dir = tempfile::tempdir().unwrap();
|
||||
let repository = SqliteResourceRepository::new(temp_dir.path().join("resources.sqlite"))
|
||||
@@ -677,8 +798,12 @@ mod tests {
|
||||
.push("assets/shared.bundle".to_string());
|
||||
resource.metadata.official_release_id = Some("release-1".to_string());
|
||||
resource.metadata.platform = Some("windows".to_string());
|
||||
resource.metadata.bundle_path = Some("assets/model.bundle".to_string());
|
||||
resource.metadata.archive_entries = vec!["serialized/Scenario".to_string()];
|
||||
resource.metadata.parse_statuses = vec!["parsed".to_string()];
|
||||
resource.metadata.text_assets = vec!["Scenario".to_string()];
|
||||
resource.metadata.text_unit_count = 3;
|
||||
resource.metadata.text_unit_formats = vec!["json".to_string()];
|
||||
|
||||
repository.add(resource.clone()).await.unwrap();
|
||||
|
||||
@@ -693,8 +818,18 @@ mod tests {
|
||||
Some("release-1")
|
||||
);
|
||||
assert_eq!(by_id.metadata.platform.as_deref(), Some("windows"));
|
||||
assert_eq!(
|
||||
by_id.metadata.bundle_path.as_deref(),
|
||||
Some("assets/model.bundle")
|
||||
);
|
||||
assert_eq!(
|
||||
by_id.metadata.archive_entries,
|
||||
vec!["serialized/Scenario".to_string()]
|
||||
);
|
||||
assert_eq!(by_id.metadata.parse_statuses, vec!["parsed".to_string()]);
|
||||
assert_eq!(by_id.metadata.text_assets, vec!["Scenario".to_string()]);
|
||||
assert_eq!(by_id.metadata.text_unit_count, 3);
|
||||
assert_eq!(by_id.metadata.text_unit_formats, vec!["json".to_string()]);
|
||||
assert_eq!(
|
||||
repository.find_by_hash("hash-sqlite-a").await.unwrap().id,
|
||||
resource.id
|
||||
@@ -709,6 +844,28 @@ mod tests {
|
||||
let count = repository.count(ResourceQuery::all()).await.unwrap();
|
||||
assert_eq!(count, 1);
|
||||
|
||||
let query = ResourceQuery {
|
||||
official_release_id: Some("release-1".to_string()),
|
||||
platform: Some("windows".to_string()),
|
||||
destination: Some("assets/model.bundle".to_string()),
|
||||
bundle_path: Some("assets/model.bundle".to_string()),
|
||||
archive_entry: Some("serialized/Scenario".to_string()),
|
||||
parse_status: Some("parsed".to_string()),
|
||||
text_unit_format: Some("json".to_string()),
|
||||
..ResourceQuery::all()
|
||||
};
|
||||
let filtered = repository.list(query.clone()).await.unwrap();
|
||||
assert_eq!(filtered.len(), 1);
|
||||
assert_eq!(filtered[0].id, resource.id);
|
||||
assert_eq!(repository.count(query).await.unwrap(), 1);
|
||||
|
||||
let missing = ResourceQuery {
|
||||
official_release_id: Some("release-missing".to_string()),
|
||||
..ResourceQuery::all()
|
||||
};
|
||||
assert!(repository.list(missing.clone()).await.unwrap().is_empty());
|
||||
assert_eq!(repository.count(missing).await.unwrap(), 0);
|
||||
|
||||
repository.delete(&resource.id).await.unwrap();
|
||||
assert!(matches!(
|
||||
repository.find_by_id(&resource.id).await,
|
||||
|
||||
Reference in New Issue
Block a user