diff --git a/src/views/Share.vue b/src/views/Share.vue index dae2687..f37b631 100644 --- a/src/views/Share.vue +++ b/src/views/Share.vue @@ -31,7 +31,7 @@


- Will require any {{ requiredShards }} shards out of + Will require any {{ requiredShardsLabel }} shards out of -

+
@@ -131,12 +131,18 @@ export default Vue.extend({ shardCountValid(): boolean { return isValidShardCount(this.totalShards); }, - requiredShards(): number { - return defaultThreshold(this.totalShards); + // Same contract as Print.vue's `threshold`: `undefined` while the count is + // not usable, so a coerced value ("" divides to 0, giving a bogus 1) can + // neither be printed nor reach ShardInfo's required Number prop. + requiredShards(): number | undefined { + return isValidShardCount(this.totalShards) ? defaultThreshold(this.totalShards) : undefined; + }, + requiredShardsLabel(): string { + return this.requiredShards === undefined ? "—" : String(this.requiredShards); }, shards(): string[] { this.$eventHub.$emit("clearAlerts"); - if (!this.encryptionMode) { + if (!this.encryptionMode || this.requiredShards === undefined) { return []; } try { diff --git a/tests/unit/shards.spec.ts b/tests/unit/shards.spec.ts index 4d9f575..ea41d6b 100644 --- a/tests/unit/shards.spec.ts +++ b/tests/unit/shards.spec.ts @@ -16,9 +16,14 @@ describe("defaultThreshold", () => { expect(defaultThreshold(total)).toBe(expected); }); - test("always requires a strict majority across the whole UI range", () => { + // A lower bound alone is too weak to pin the policy: floor(8/2)+2 = 6 is also + // "more than half of 8". Assert the threshold is the *smallest* strict + // majority, which is the property that makes floor(n/2)+1 the only answer. + test("is the smallest strict majority across the whole UI range", () => { for (let n = 3; n <= 255; n++) { - expect(defaultThreshold(n)).toBeGreaterThan(n / 2); + const threshold = defaultThreshold(n); + expect(threshold).toBeGreaterThan(n / 2); + expect(threshold - 1).toBeLessThanOrEqual(n / 2); } }); });