Canvas: Generate Github nodes out of the dodo-app config

Change-Id: Ifc5b09deb39352a3025f7ea66ce39b421daac94d
diff --git a/apps/canvas/config/src/config.test.ts b/apps/canvas/config/src/config.test.ts
new file mode 100644
index 0000000..5a927df
--- /dev/null
+++ b/apps/canvas/config/src/config.test.ts
@@ -0,0 +1,65 @@
+import { configToGraph } from "./config.js";
+import { Config } from "./types.js";
+import { Network } from "./graph.js";
+import { GithubRepository } from "./github.js";
+
+describe("configToGraph", () => {
+	it("should create a simple graph from a basic service configuration", () => {
+		const config: Config = {
+			service: [
+				{
+					nodeId: "service-1",
+					name: "my-app",
+					type: "nodejs:24.0.2",
+					source: {
+						repository: "git@github.com:user/repo.git",
+						branch: "main",
+						rootDir: "/",
+					},
+					ports: [{ name: "http", value: 3000, protocol: "TCP" }],
+				},
+			],
+		};
+
+		const networks: Network[] = [
+			{
+				name: "Public",
+				domain: "v1.dodo.cloud",
+				hasAuth: true,
+			},
+		];
+
+		const repos: GithubRepository[] = [
+			{
+				id: 123,
+				name: "repo",
+				full_name: "user/repo",
+				html_url: "https://github.com/user/repo",
+				ssh_url: "git@github.com:user/repo.git",
+			},
+		];
+
+		const graph = configToGraph(config, networks, repos);
+
+		// Expect one service node, one repo node, and one network node
+		expect(graph.nodes).toHaveLength(3);
+
+		const serviceNode = graph.nodes.find((n) => n.type === "app");
+		expect(serviceNode).toBeDefined();
+		expect(serviceNode?.data.label).toBe("my-app");
+
+		const repoNode = graph.nodes.find((n) => n.type === "github");
+		expect(repoNode).toBeDefined();
+		expect(repoNode?.data.repository?.sshURL).toBe("git@github.com:user/repo.git");
+
+		const networkNode = graph.nodes.find((n) => n.type === "network");
+		expect(networkNode).toBeDefined();
+		expect(networkNode?.data.domain).toBe("v1.dodo.cloud");
+
+		// Expect one edge from repo to service
+		expect(graph.edges).toHaveLength(1);
+		const repoEdge = graph.edges.find((e) => e.source === repoNode?.id && e.target === serviceNode?.id);
+		expect(repoEdge).toBeDefined();
+		console.log(JSON.stringify(graph, null, 2));
+	});
+});