|
| 1 | +use spacetimedb_smoketests::{require_local_server, require_pnpm, Smoketest}; |
| 2 | + |
| 3 | +const TS_MODULE_BASIC: &str = r#"import { schema, t, table } from "spacetimedb/server"; |
| 4 | +
|
| 5 | +const person = table( |
| 6 | + { name: "person", public: true }, |
| 7 | + { |
| 8 | + id: t.u64().primaryKey().autoInc(), |
| 9 | + name: t.string() |
| 10 | + } |
| 11 | +); |
| 12 | +const spacetimedb = schema({ person }); |
| 13 | +export default spacetimedb; |
| 14 | +
|
| 15 | +export const add = spacetimedb.reducer({ name: t.string() }, (ctx, { name }) => { |
| 16 | + ctx.db.person.insert({ id: 0n, name }); |
| 17 | +}); |
| 18 | +"#; |
| 19 | + |
| 20 | +/// Tests that updating a module and also changing the host type works. |
| 21 | +/// |
| 22 | +/// Note that this test restarts the server. |
| 23 | +#[test] |
| 24 | +fn test_update_with_different_host_type() { |
| 25 | + require_pnpm!(); |
| 26 | + require_local_server!(); |
| 27 | + |
| 28 | + const PERSON_A: &str = "Person A"; |
| 29 | + const PERSON_B: &str = "Person B"; |
| 30 | + const PERSON_C: &str = "Person C"; |
| 31 | + |
| 32 | + let mut test = Smoketest::builder() |
| 33 | + .precompiled_module("modules-basic") |
| 34 | + .autopublish(false) |
| 35 | + .build(); |
| 36 | + |
| 37 | + let database_identity = test.publish_module().unwrap(); |
| 38 | + add_person(&test, PERSON_A, "initial"); |
| 39 | + |
| 40 | + // Publish a TS module. |
| 41 | + test.publish_typescript_module_source_clear("modules-basic-ts", &database_identity, TS_MODULE_BASIC, false) |
| 42 | + .unwrap(); |
| 43 | + add_person(&test, PERSON_B, "post module update"); |
| 44 | + |
| 45 | + // Restart and assert that the data is still there. |
| 46 | + test.restart_server(); |
| 47 | + assert_has_rows(&test, &[PERSON_A, PERSON_B], "post restart"); |
| 48 | + |
| 49 | + // Change back to original module and assert that the data is still there. |
| 50 | + test.publish_module_clear(false).unwrap(); |
| 51 | + add_person(&test, PERSON_C, "post revert"); |
| 52 | + |
| 53 | + // Restart once more and assert that the data is still there. |
| 54 | + test.restart_server(); |
| 55 | + assert_has_rows(&test, &[PERSON_A, PERSON_B, PERSON_C], "post restart 2"); |
| 56 | +} |
| 57 | + |
| 58 | +fn add_person(test: &Smoketest, name: &str, context: &str) { |
| 59 | + test.call("add", &[name]).unwrap(); |
| 60 | + assert_has_person(test, name, context); |
| 61 | +} |
| 62 | + |
| 63 | +fn assert_has_person(test: &Smoketest, name: &str, context: &str) { |
| 64 | + let output = test |
| 65 | + .sql_confirmed(&format!("select * from person where name = '{name}'")) |
| 66 | + .unwrap(); |
| 67 | + assert!( |
| 68 | + output.contains(name), |
| 69 | + "{}: expected {} to be in result: {}", |
| 70 | + context, |
| 71 | + name, |
| 72 | + output |
| 73 | + ); |
| 74 | +} |
| 75 | + |
| 76 | +fn assert_has_rows(test: &Smoketest, names: &[&str], context: &str) { |
| 77 | + let output = test.sql_confirmed("select * from person").unwrap(); |
| 78 | + assert!( |
| 79 | + output |
| 80 | + .lines() |
| 81 | + .skip(2) |
| 82 | + .all(|row| names.iter().any(|name| row.contains(name))), |
| 83 | + "{context}: expected all of {names:?} to be in result: {output}" |
| 84 | + ) |
| 85 | +} |
0 commit comments