From 101637b72b0dfb754dfc7b2b68220d0e62947900 Mon Sep 17 00:00:00 2001 From: Paul Robert Lloyd Date: Mon, 7 Oct 2024 00:18:54 +0100 Subject: [PATCH] fix(store-gitlab): check if file exists before creating --- helpers/mock-agent/store-gitlab.js | 29 ++++++++++++++++++++++++----- packages/store-gitlab/index.js | 25 +++++++++++++++++++++++++ packages/store-gitlab/test/index.js | 23 ++++++++++++++++++----- 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/helpers/mock-agent/store-gitlab.js b/helpers/mock-agent/store-gitlab.js index 5e63d4c0f..a2ad8024e 100644 --- a/helpers/mock-agent/store-gitlab.js +++ b/helpers/mock-agent/store-gitlab.js @@ -15,10 +15,10 @@ export function mockClient() { // Create file agent .get(origin) - .intercept({ path: filePath, method: "POST" }) + .intercept({ path: /.*new\.txt/, method: "POST" }) .reply( 201, - { file_path: "foo.txt", branch: "main" }, + { file_path: "new.txt", branch: "main" }, { headers: { "content-type": "application/json" } }, ) .persist(); @@ -29,11 +29,23 @@ export function mockClient() { .intercept({ path: /.*401\.txt/, method: "POST" }) .reply(401); + // Read file + agent + .get(origin) + .intercept({ path: /.*(foo|bar).txt\?ref=main/ }) + .reply( + 200, + { content: "Zm9v" }, // ‘foo’ Base64 encoded + { headers: { "content-type": "application/json" } }, + ) + .persist(); + // Read raw file agent .get(origin) - .intercept({ path: /.*\D{3}.txt\/raw\?ref=main/ }) - .reply(200, "foobar"); + .intercept({ path: /.*(foo|bar).txt\/raw\?ref=main/ }) + .reply(200, "foo") + .persist(); // Read raw file (Unauthorized) agent @@ -41,6 +53,13 @@ export function mockClient() { .intercept({ path: /.*401\.txt\/raw\?ref=main/ }) .reply(401); + // Read raw file (Not Found) + agent + .get(origin) + .intercept({ path: /.*404\.txt/ }) + .reply(404) + .persist(); + // Update file agent .get(origin) @@ -65,7 +84,7 @@ export function mockClient() { // Update commit agent .get(origin) - .intercept({ path: commitPath, method: "POST", body: /.*\D{3}.txt/ }) + .intercept({ path: commitPath, method: "POST", body: /.*(foo|bar).txt/ }) .reply( 200, { file_path: "foo.txt", message: "message" }, diff --git a/packages/store-gitlab/index.js b/packages/store-gitlab/index.js index 582a944f0..602b848e3 100644 --- a/packages/store-gitlab/index.js +++ b/packages/store-gitlab/index.js @@ -85,6 +85,26 @@ export default class GitlabStore { return client; } + /** + * Check if file exists + * @param {string} filePath - Path to file + * @returns {Promise} File exists + * @see {@link https://docs.gitlab.com/ee/api/repository_files.html#get-file-from-repository} + */ + async fileExists(filePath) { + try { + await this.#client.RepositoryFiles.show( + this.projectId, + filePath, + this.options.branch, + ); + + return true; + } catch { + return false; + } + } + /** * Create file * @param {string} filePath - Path to file @@ -96,6 +116,11 @@ export default class GitlabStore { */ async createFile(filePath, content, { message }) { try { + const fileExists = await this.fileExists(filePath); + if (fileExists) { + return; + } + const createResponse = await this.#client.RepositoryFiles.create( this.projectId, filePath, diff --git a/packages/store-gitlab/test/index.js b/packages/store-gitlab/test/index.js index c7bc89977..b4a823622 100644 --- a/packages/store-gitlab/test/index.js +++ b/packages/store-gitlab/test/index.js @@ -49,20 +49,33 @@ describe("store-gitlab", async () => { ); }); - it("Creates file", { timeout: 60 }, async () => { + it("Checks if file exists", async () => { + assert.equal(await gitlab.fileExists("foo.txt"), true); + assert.equal(await gitlab.fileExists("404.txt"), false); + }); + + it("Creates file", async () => { + const result = await gitlab.createFile("new.txt", "new", { + message: "Message", + }); + + assert.equal(result, "https://gitlab.com/username/repo/new.txt"); + }); + + it("Doesn’t create file if already exists", async () => { const result = await gitlab.createFile("foo.txt", "foo", { message: "Message", }); - assert.equal(result, "https://gitlab.com/username/repo/foo.txt"); + assert.equal(result, undefined); }); it("Creates file with projectId at custom instance", async () => { - const result = await gitlabInstance.createFile("foo.txt", "foo", { + const result = await gitlabInstance.createFile("new.txt", "new", { message: "Message", }); - assert.equal(result, "https://gitlab.instance/projects/1234/foo.txt"); + assert.equal(result, "https://gitlab.instance/projects/1234/new.txt"); }); it("Throws error creating file", async () => { @@ -77,7 +90,7 @@ describe("store-gitlab", async () => { it("Reads file", async () => { const result = await gitlab.readFile("foo.txt"); - assert.equal(result, "foobar"); + assert.equal(result, "foo"); }); it("Throws error reading file", async () => {