mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-10-19 22:27:20 +02:00
fix: rebuild ready snapshots on an explicit refresh (#890)
* fix repository refresh failing to reflect new public GitHub commits * test: cover forced snapshot rebuilds and unchanged background refresh * fix: serialize missing-tree recovery with owner refreshes --------- Co-authored-by: Thomas Durieux <5577568+tdurieux@users.noreply.github.com>
This commit is contained in:
1 parent
bee729e0ee
commit
4a06aa9888
3 files changed
+75
-5
No files matched your search
@@ -129,6 +129,46 @@ describe("repository refresh and restoration", () => {
|
||||
return stored;
|
||||
}
|
||||
|
||||
for (const force of [false, true]) {
|
||||
for (const commit of ["saved-sha", "new-sha"]) {
|
||||
it(`refreshes a ready snapshot with force=${force}, commit=${commit}`, async () => {
|
||||
const repo = repository("ready");
|
||||
repo.model.options.update = true;
|
||||
repo.model.lastView = new Date(0);
|
||||
const stored = database(repo);
|
||||
repo.getToken = async () => "token";
|
||||
stub(github, "getRepositoryFromGitHub", async options => {
|
||||
expect(options.force).to.equal(true);
|
||||
return { fullName: "owner/repo", model: { defaultBranch: "main" },
|
||||
branches: async options => {
|
||||
expect(options.force).to.equal(true);
|
||||
return [{ name: "main", commit }];
|
||||
}, getCommitInfo: async () => ({ commit: {} }) };
|
||||
});
|
||||
let cleared = false, queued = false;
|
||||
repo.resetSate = async () => {
|
||||
expect(stored.source.commit).to.equal(commit);
|
||||
expect(stored.status).to.equal("preparing");
|
||||
cleared = true;
|
||||
};
|
||||
stub(queue, "downloadQueue", { getJob: async () => undefined, add: async (_id, data) => {
|
||||
expect(cleared).to.equal(true);
|
||||
expect(data.repoId).to.equal("restore-me");
|
||||
queued = true;
|
||||
} });
|
||||
if (force) await repo.refresh();
|
||||
else await repo.updateIfNeeded();
|
||||
const rebuilt = force || commit !== "saved-sha";
|
||||
expect(cleared).to.equal(rebuilt);
|
||||
expect(queued).to.equal(rebuilt);
|
||||
expect(stored.status).to.equal(rebuilt ? "preparing" : "ready");
|
||||
expect(stored.source.commit).to.equal(commit);
|
||||
expect(stored.repoId).to.equal("restore-me");
|
||||
expect(stored).not.to.have.property("refreshToken");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
it("claims a lease before GitHub work and rejects a concurrent refresh", async () => {
|
||||
const first = repository("ready");
|
||||
const second = new Repository(new Model(first.model.toObject()));
|
||||
@@ -151,6 +191,35 @@ describe("repository refresh and restoration", () => {
|
||||
expect(stored).not.to.have.property("refreshToken");
|
||||
});
|
||||
|
||||
for (const recoveryFirst of [false, true]) {
|
||||
it(`serializes missing-tree recovery and dashboard refresh (recovery first: ${recoveryFirst})`, async () => {
|
||||
const first = repository("ready");
|
||||
const second = new Repository(new Model(first.model.toObject()));
|
||||
const stored = database(first);
|
||||
const Files = require("../src/core/model/files/files.model").default;
|
||||
stub(Files, "exists", () => ({ exec: async () => null }));
|
||||
let release, started;
|
||||
const entered = new Promise(resolve => { started = resolve; });
|
||||
let updates = 0;
|
||||
first.updateIfNeeded = async () => {
|
||||
updates++;
|
||||
started();
|
||||
await new Promise(resolve => { release = resolve; });
|
||||
};
|
||||
second.updateIfNeeded = async () => { updates++; };
|
||||
const running = recoveryFirst ? first.isReady() : first.refresh();
|
||||
await entered;
|
||||
try {
|
||||
let failure;
|
||||
try { await (recoveryFirst ? second.refresh() : second.isReady()); } catch (error) { failure = error; }
|
||||
expect(failure?.message).to.equal("invalid_status");
|
||||
expect(updates).to.equal(1);
|
||||
expect(stored.status).to.equal("ready");
|
||||
} finally { release(); await running; }
|
||||
expect(stored).not.to.have.property("refreshToken");
|
||||
});
|
||||
}
|
||||
|
||||
it("releases a failed lease so reconnecting can be retried", async () => {
|
||||
const repo = repository("removed");
|
||||
const stored = database(repo);
|
||||
|
||||
Reference in new issue
Block a user