Stop the first-run seed carrying one company's tools

A build gets sent to testers, and this one arrived with the apps it was
developed against baked in as defaults - including an internal Odoo
hostname and a per-person Google account index in every path. Nothing
personal ships inside the bundle, but the seed is compiled into it.

The seed is now three generic Google apps that link to each other, which
is enough for a tester to see app switching work without learning where
anyone works.

A test asserts it stays that way: every seeded URL must be a plain
google.com host with no account index. It would otherwise drift back the
next time the seed is edited for convenience.
This commit is contained in:
2026-09-01 16:07:59 +02:00
parent 2a0b934d04
commit cc0b370c4d
+38 -16
View File
@@ -177,11 +177,16 @@ pub fn new_id() -> String {
uuid::Uuid::new_v4().to_string()
}
/// First-run contents: the tools this was built for.
/// First-run contents.
///
/// Each scope is the exact host, so a link from Gmail to Drive switches rather
/// than being swallowed by whichever Google app happens to be showing. The
/// `/u/N/` paths pin the second Google account, which is the one that matters.
/// Deliberately generic. This is what someone sees the first time they open a
/// copy of the app, and a build handed to a tester would otherwise arrive
/// carrying whichever company's tools it was developed against — an internal
/// hostname is not something to put in a file you send to people.
///
/// Enough to try it on: two Google apps that link to each other, so switching
/// between configured apps can be seen working straight away. No account index
/// in the paths, since that is per person.
pub fn seed() -> Config {
let mk = |name: &str, url: &str, group: &str, order: i32| App {
id: new_id(),
@@ -197,15 +202,16 @@ pub fn seed() -> Config {
};
Config {
version: 1,
groups: vec![
Group { id: "g-work".into(), name: "Work".into(), collapsed: false, order: 0 },
Group { id: "g-google".into(), name: "Google".into(), collapsed: false, order: 1 },
],
groups: vec![Group {
id: "g-google".into(),
name: "Google".into(),
collapsed: false,
order: 0,
}],
apps: vec![
mk("Odoo", "https://example.odoo.com/web", "g-work", 0),
mk("Gmail", "https://mail.google.com/mail/u/N/", "g-google", 0),
mk("Drive", "https://drive.google.com/drive/u/N/my-drive", "g-google", 1),
mk("Chat", "https://chat.google.com/u/N/app/home", "g-google", 2),
mk("Gmail", "https://mail.google.com", "g-google", 0),
mk("Drive", "https://drive.google.com", "g-google", 1),
mk("Calendar", "https://calendar.google.com", "g-google", 2),
],
settings: Settings::default(),
}
@@ -261,15 +267,31 @@ mod tests {
let scopes: Vec<String> = cfg.apps.iter().flat_map(|a| a.scopes()).collect();
assert!(scopes.contains(&"mail.google.com".to_string()));
assert!(scopes.contains(&"drive.google.com".to_string()));
assert!(scopes.contains(&"chat.google.com".to_string()));
assert!(scopes.contains(&"example.odoo.com".to_string()));
assert!(scopes.contains(&"calendar.google.com".to_string()));
assert!(!scopes.contains(&"google.com".to_string()));
}
#[test]
fn the_seed_carries_nobody_in_particular() {
// A build gets sent to testers. Whatever company this was developed
// against must not travel with it: no internal hostname, and no
// per-person account index in a path.
let cfg = seed();
for app in &cfg.apps {
assert!(
app.url.ends_with(".google.com"),
"{} points somewhere specific: {}",
app.name,
app.url
);
assert!(!app.url.contains("/u/"), "{} pins an account", app.name);
}
}
#[test]
fn seed_apps_all_carry_a_scope() {
let cfg = seed();
assert_eq!(cfg.apps.len(), 4);
assert_eq!(cfg.apps.len(), 3);
assert!(cfg.apps.iter().all(|a| !a.scopes().is_empty()));
}
@@ -277,7 +299,7 @@ mod tests {
fn ordering_follows_group_then_position() {
let cfg = seed();
let names: Vec<&str> = cfg.ordered().iter().map(|a| a.name.as_str()).collect();
assert_eq!(names, ["Odoo", "Gmail", "Drive", "Chat"]);
assert_eq!(names, ["Gmail", "Drive", "Calendar"]);
}
#[test]