diff --git a/api.planx.uk/modules/analytics/metabase/collection/collection.test.ts b/api.planx.uk/modules/analytics/metabase/collection/collection.test.ts index 1b66e90a88..4b9829dd69 100644 --- a/api.planx.uk/modules/analytics/metabase/collection/collection.test.ts +++ b/api.planx.uk/modules/analytics/metabase/collection/collection.test.ts @@ -1 +1,92 @@ -test.todo("should test collection check and creation"); +import { $api } from "../../../../client/index.js"; +import { updateMetabaseId } from "./updateMetabaseId.js"; +import { getTeamIdAndMetabaseId } from "./getTeamIdAndMetabaseId.js"; + +describe("getTeamIdAndMetabaseId", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + test("successfully gets team and existing metabase id", async () => { + vi.spyOn($api.client, "request").mockResolvedValue({ + teams: [ + { + id: 26, + slug: "barnet", + metabaseId: 20, + }, + ], + }); + + const teamAndMetabaseId = await getTeamIdAndMetabaseId("barnet"); + + expect(teamAndMetabaseId.id).toEqual(26); + expect(teamAndMetabaseId.metabaseId).toEqual(20); + }); + + test("handles team with null metabase id", async () => { + vi.spyOn($api.client, "request").mockResolvedValue({ + teams: [ + { + id: 26, + slug: "barnet", + metabaseId: null, + }, + ], + }); + + const teamAndMetabaseId = await getTeamIdAndMetabaseId("Barnet"); + + expect(teamAndMetabaseId.id).toEqual(26); + expect(teamAndMetabaseId.metabaseId).toBeNull(); + }); +}); + +describe("updateMetabaseId", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + test("successfully updates metabase ID", async () => { + // Mock the GraphQL request + vi.spyOn($api.client, "request").mockResolvedValue({ + update_teams: { + returning: [ + { + id: 1, + slug: "testteam", + metabase_id: 123, + }, + ], + }, + }); + + const result = await updateMetabaseId(1, 123); + + expect(result).toEqual({ + update_teams: { + returning: [ + { + id: 1, + slug: "testteam", + metabase_id: 123, + }, + ], + }, + }); + + expect($api.client.request).toHaveBeenCalledWith(expect.any(String), { + id: 1, + metabaseId: 123, + }); + }); + + test("handles GraphQL error", async () => { + // Mock a failed GraphQL request + vi.spyOn($api.client, "request").mockRejectedValue( + new Error("GraphQL error"), + ); + + await expect(updateMetabaseId(1, 123)).rejects.toThrow("GraphQL error"); + }); +}); diff --git a/api.planx.uk/modules/analytics/metabase/collection/getTeamIdAndMetabaseId.ts b/api.planx.uk/modules/analytics/metabase/collection/getTeamIdAndMetabaseId.ts new file mode 100644 index 0000000000..4007bfef64 --- /dev/null +++ b/api.planx.uk/modules/analytics/metabase/collection/getTeamIdAndMetabaseId.ts @@ -0,0 +1,38 @@ +import { gql } from "graphql-request"; +import { $api } from "../../../../client/index.js"; + +interface GetMetabaseId { + teams: { + id: number; + slug: string; + metabaseId: number | null; + }[]; +} + +export const getTeamIdAndMetabaseId = async (slug: string) => { + try { + const response = await $api.client.request( + gql` + query GetTeamAndMetabaseId($slug: String!) { + teams(where: { slug: { _eq: $slug } }) { + id + slug + metabaseId: metabase_id + } + } + `, + { + slug: slug, + }, + ); + + const result = response.teams[0]; + return result; + } catch (e) { + console.error( + "Error fetching team's ID / Metabase ID from PlanX DB:", + (e as Error).stack, + ); + throw e; + } +}; diff --git a/api.planx.uk/modules/analytics/metabase/collection/updateMetabaseId.ts b/api.planx.uk/modules/analytics/metabase/collection/updateMetabaseId.ts new file mode 100644 index 0000000000..93ffe1042d --- /dev/null +++ b/api.planx.uk/modules/analytics/metabase/collection/updateMetabaseId.ts @@ -0,0 +1,43 @@ +import { gql } from "graphql-request"; +import { $api } from "../../../../client/index.js"; + +interface UpdateMetabaseId { + teams: { + id: number; + slug: string; + metabaseId: number; + }; +} + +/** Updates column `metabase_id` in the Planx DB `teams` table */ +export const updateMetabaseId = async (teamId: number, metabaseId: number) => { + try { + const response = await $api.client.request( + gql` + mutation UpdateTeamMetabaseId($id: Int!, $metabaseId: Int!) { + update_teams( + where: { id: { _eq: $id } } + _set: { metabase_id: $metabaseId } + ) { + returning { + id + slug + metabase_id + } + } + } + `, + { + id: teamId, + metabaseId: metabaseId, + }, + ); + return response; + } catch (e) { + console.error( + "There's been an error while updating the Metabase ID for this team", + (e as Error).stack, + ); + throw e; + } +}; diff --git a/hasura.planx.uk/metadata/tables.yaml b/hasura.planx.uk/metadata/tables.yaml index fe53e49f90..2557257e6c 100644 --- a/hasura.planx.uk/metadata/tables.yaml +++ b/hasura.planx.uk/metadata/tables.yaml @@ -2370,6 +2370,7 @@ - created_at - domain - id + - metabase_id - name - slug - updated_at @@ -2422,6 +2423,13 @@ - updated_at filter: {} update_permissions: + - role: api + permission: + columns: + - metabase_id + filter: {} + check: {} + comment: "" - role: platformAdmin permission: columns: diff --git a/hasura.planx.uk/migrations/1733738650997_alter_table_public_teams_add_column_metabase_id/down.sql b/hasura.planx.uk/migrations/1733738650997_alter_table_public_teams_add_column_metabase_id/down.sql new file mode 100644 index 0000000000..c620678461 --- /dev/null +++ b/hasura.planx.uk/migrations/1733738650997_alter_table_public_teams_add_column_metabase_id/down.sql @@ -0,0 +1 @@ +alter table "public"."teams" drop column "metabase_id"; diff --git a/hasura.planx.uk/migrations/1733738650997_alter_table_public_teams_add_column_metabase_id/up.sql b/hasura.planx.uk/migrations/1733738650997_alter_table_public_teams_add_column_metabase_id/up.sql new file mode 100644 index 0000000000..8ab49dd71b --- /dev/null +++ b/hasura.planx.uk/migrations/1733738650997_alter_table_public_teams_add_column_metabase_id/up.sql @@ -0,0 +1,2 @@ +alter table "public"."teams" add column "metabase_id" integer + null; diff --git a/hasura.planx.uk/tests/teams.test.js b/hasura.planx.uk/tests/teams.test.js index 0c2aa8e35b..53defcf1b0 100644 --- a/hasura.planx.uk/tests/teams.test.js +++ b/hasura.planx.uk/tests/teams.test.js @@ -98,8 +98,15 @@ describe("teams", () => { expect(i.queries).toContain("teams"); }); - test("cannot create, update, or delete teams", () => { - expect(i).toHaveNoMutationsFor("teams"); + test("can update teams", () => { + expect(i.mutations).toContain("update_teams"); + expect(i.mutations).toContain("update_teams_by_pk"); + expect(i.mutations).toContain("update_teams_many"); + }); + + test("cannot create or delete teams", () => { + expect(i.mutations).not.toContain("insert_teams"); + expect(i.mutations).not.toContain("delete_teams"); }); }); });