Onboarding live apps without owner questions for what the stores and the code prove: storebound onboard imports the live products and subscriptions with USD / base prices (catalog diff clean), contact values, the App Review contact and demo account (credentials.json, masked), sign-in for review from Apple's review detail and auth code, and the account deletion page from the app's site; App Store keywords count characters (live fields up to 265 bytes accepted); validate accepts the 6.5-inch iPhone set and Play's default-language graphics fallback; Play Reporting API off gives the project's enable link and apps list falls back to local apps; accounts default <profile>; store-only apps (apps add --store --app-id) shown read-only in the desktop (pitfalls 43-52)
This commit is contained in:
parent
d2ce185441
commit
e5f148e534
55 changed files with 1648 additions and 158 deletions
|
|
@ -160,6 +160,40 @@ fn the_folder_list_is_the_machines() {
|
|||
assert_eq!(registry::parse(r#"{"projects":[{"path":"rel"},{"path":"/a","id":"XYZ"},{"path":"/a"}]}"#).iter().map(|e| e.id.clone()).collect::<Vec<_>>(), vec![registry::folder_id("/a")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn store_only_apps_join_their_profiles_account_and_survive_folder_writes() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let file = dir.path().join("projects.json");
|
||||
// as `storebound apps add --store apple --app-id 6400000999 --account teamA` and a Play one without a profile wrote it
|
||||
std::fs::write(&file, r#"{"version":1,"projects":[],"storeApps":[
|
||||
{"id":"x","store":"apple","appId":"6400000999","account":"teamA","name":"Example Aquarium","bundleId":"com.example.aquarium","added":"t"},
|
||||
{"store":"play","appId":"com.example.legacy","name":"Legacy"},
|
||||
{"store":"apple","appId":"not-a-number"}]}"#).unwrap();
|
||||
let apps = registry::read_store_apps(&file);
|
||||
assert_eq!(apps.iter().map(|a| a.app_id.as_str()).collect::<Vec<_>>(), vec!["6400000999", "com.example.legacy"]);
|
||||
assert_eq!(apps[1].bundle_id.as_deref(), Some("com.example.legacy"));
|
||||
// the app writes its folder list: the store-only entries stay
|
||||
let mut st = State { projects: vec![project("aaaaaaaaaaaaaaaa", "/w/Star Dash", None)], ..State::default() };
|
||||
registry::publish(&st, &file, &[]).unwrap();
|
||||
assert_eq!(registry::read_store_apps(&file).len(), 2);
|
||||
assert!(registry::sync(&mut st, &file).is_ok());
|
||||
assert_eq!(registry::read_store_apps(&file).len(), 2);
|
||||
// an account of profile teamA that never listed its apps: the entry shows as its app, read-only, no folder
|
||||
let v = registry::with_store_only(None, "apple", Some("teamA"), false, &apps, "t").unwrap();
|
||||
assert_eq!(v["store"], "ios");
|
||||
assert_eq!(v["apps"][0]["id"], "6400000999");
|
||||
assert_eq!(v["apps"][0]["bundleId"], "com.example.aquarium");
|
||||
assert_eq!(v["apps"][0]["registered"], true);
|
||||
// an account of another profile gets nothing; the list the store returned is kept, the entry not doubled
|
||||
assert_eq!(registry::with_store_only(None, "apple", Some("teamB"), false, &apps, "t"), None);
|
||||
let listed = serde_json::json!({ "store": "ios", "apps": [{ "id": "6400000999", "name": "From the store" }], "warnings": [], "at": "t" });
|
||||
assert_eq!(registry::with_store_only(Some(listed.clone()), "apple", Some("teamA"), false, &apps, "t"), Some(listed));
|
||||
// no profile named: the only Play account takes it
|
||||
let p = registry::with_store_only(None, "play", Some("any"), true, &apps, "t").unwrap();
|
||||
assert_eq!(p["apps"][0]["name"], "Legacy");
|
||||
assert_eq!(registry::with_store_only(None, "play", Some("any"), false, &apps, "t"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_folder_that_pins_another_storebound_says_so() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
|
|
|
|||
|
|
@ -208,7 +208,9 @@ fn log_entries_are_one_block_and_rotate() {
|
|||
/// next to it as `<name>.host.json`, after the start-up sync with the machine's shared stores: D1 keeps its accounts in a
|
||||
/// keychain that has no entries (the keys were never added: the accounts stay without a profile), D3's keychain has
|
||||
/// them (they move into credential profiles), and shared-profiles is the 0.8 format whose apple account comes from a
|
||||
/// profile the CLI wrote, with a folder that pins storebound 0.6.0. tools/desktop-boot-check.ts boots the built window on exactly these answers.
|
||||
/// profile the CLI wrote, with a folder that pins storebound 0.6.0 and a store-only app of that profile (`storebound
|
||||
/// apps add --store apple --app-id … --account default`: store_apps_cached lists it under the apple account).
|
||||
/// tools/desktop-boot-check.ts boots the built window on exactly these answers.
|
||||
/// After a change to the state format: STOREBOUND_UPDATE_FIXTURES=1 cargo test --test state
|
||||
#[test]
|
||||
fn host_answers_for_the_fixtures_are_current() {
|
||||
|
|
@ -240,9 +242,22 @@ fn host_answers_for_the_fixtures_are_current() {
|
|||
let pin = project_view(&p).storebound_pin.expect("0.6.0 is not this app");
|
||||
projects[0]["storeboundPin"] = json!(pin);
|
||||
}
|
||||
// store_apps_cached before any store read: only the machine's store-only entries (registry.rs)
|
||||
let store_only = if name == "shared-profiles" {
|
||||
registry::parse_store_apps(r#"{"storeApps":[{"store":"apple","appId":"6400000999","account":"default","name":"Example Aquarium","bundleId":"com.example.aquarium"}]}"#)
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
let cached: Vec<serde_json::Value> = st.accounts.iter().map(|a| {
|
||||
let store = match a.kind { AccountKind::Apple => "apple", AccountKind::Play => "play" };
|
||||
let only = st.accounts.iter().filter(|x| x.kind == a.kind).count() == 1;
|
||||
let entry = registry::with_store_only(None, store, a.profile.as_deref(), only, &store_only, "2026-10-13T00:00:00Z").map(|value| json!({ "value": value, "at": "2026-10-13T00:00:00Z" }));
|
||||
json!({ "account": a.id, "entry": entry })
|
||||
}).collect();
|
||||
let host = json!({
|
||||
"projects_list": projects,
|
||||
"accounts_list": st.accounts,
|
||||
"store_apps_cached": cached,
|
||||
"workspace_get": { "studios": st.studios, "overrides": st.overrides, "settings": st.settings },
|
||||
});
|
||||
let want = format!("{}\n", serde_json::to_string_pretty(&host).unwrap());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue