diff --git a/packages/fx-core/src/component/generator/spfx/spfxGenerator.ts b/packages/fx-core/src/component/generator/spfx/spfxGenerator.ts index 8b3489d97da..f767df2d40c 100644 --- a/packages/fx-core/src/component/generator/spfx/spfxGenerator.ts +++ b/packages/fx-core/src/component/generator/spfx/spfxGenerator.ts @@ -649,23 +649,24 @@ export class SPFxGenerator { return undefined; } - const webpartName = webparts[0].split(path.sep).pop(); - const webpartManifestPath = path.join( - webpartsDir, - webparts[0], - `${webpartName as string}WebPart.manifest.json` + const webpartManifest = (await fs.readdir(path.join(webpartsDir, webparts[0]))).find((file) => + file.endsWith("WebPart.manifest.json") ); - if (!(await fs.pathExists(webpartManifestPath))) { + if (webpartManifest === undefined) { throw new FileNotFoundError( Constants.PLUGIN_NAME, - webpartManifestPath, + path.join( + webpartsDir, + webparts[0], + `${webparts[0].split(path.sep).pop() as string}WebPart.manifest.json` + ), Constants.IMPORT_HELP_LINK ); } const matchHashComment = new RegExp(/(\/\/ .*)/, "gi"); const manifest = JSON.parse( - (await fs.readFile(webpartManifestPath, "utf8")) + (await fs.readFile(path.join(webpartsDir, webparts[0], webpartManifest), "utf8")) .toString() .replace(matchHashComment, "") .trim() diff --git a/packages/fx-core/tests/component/generator/spfxGenerator.test.ts b/packages/fx-core/tests/component/generator/spfxGenerator.test.ts index 3f8ae437ef8..fa2e9d27304 100644 --- a/packages/fx-core/tests/component/generator/spfxGenerator.test.ts +++ b/packages/fx-core/tests/component/generator/spfxGenerator.test.ts @@ -435,6 +435,40 @@ describe("SPFxGenerator", function () { } }); + it("No valid web part manifest when import SPFx solution", async () => { + const inputs: Inputs = { + platform: Platform.VSCode, + projectPath: testFolder, + "app-name": "spfxTestApp", + "spfx-solution": "import", + "spfx-folder": "c:\\test", + }; + + sinon.stub(fs, "pathExists").resolves(true); + sinon.stub(fs, "readdir").callsFake((directory: any) => { + if (directory === path.join("c:\\test", "teams")) { + return ["1_color.png", "1_outline.png"] as any; + } else if (directory === path.join("c:\\test", "src", "webparts")) { + return ["helloworld", "second"] as any; + } else { + return []; + } + }); + sinon.stub(fs, "statSync").returns({ + isDirectory: () => { + return true; + }, + } as any); + sinon.stub(fs, "copy").resolves(); + + const result = await SPFxGenerator.generate(context, inputs, testFolder); + + chai.expect(result.isErr()).to.eq(true); + if (result.isErr()) { + chai.expect(result.error.name).to.eq("FileNotFoundError"); + } + }); + it("Copy existing SPFx solution failed when import SPFx solution", async () => { const inputs: Inputs = { platform: Platform.VSCode, @@ -469,8 +503,10 @@ describe("SPFxGenerator", function () { sinon.stub(fs, "readdir").callsFake((directory: any) => { if (directory === path.join("c:\\test", "teams")) { return ["1_color.png", "1_outline.png"] as any; - } else { + } else if (directory === path.join("c:\\test", "src", "webparts")) { return ["helloworld", "second"] as any; + } else { + return ["HelloWorldWebPart.manifest.json"] as any; } }); sinon.stub(fs, "statSync").returns({ @@ -502,7 +538,15 @@ describe("SPFxGenerator", function () { }; sinon.stub(fs, "pathExists").resolves(true); - sinon.stub(fs, "readdir").resolves(["helloworld", "second"] as any); + sinon.stub(fs, "readdir").callsFake((directory: any) => { + if (directory === path.join("c:\\test", "teams")) { + return ["1_color.png", "1_outline.png"] as any; + } else if (directory === path.join("c:\\test", "src", "webparts")) { + return ["helloworld", "second"] as any; + } else { + return ["HelloWorldWebPart.manifest.json"] as any; + } + }); sinon.stub(fs, "statSync").returns({ isDirectory: () => { return true; @@ -532,8 +576,10 @@ describe("SPFxGenerator", function () { sinon.stub(fs, "readdir").callsFake((directory: any) => { if (directory === path.join("c:\\test", "teams")) { return ["1_color.png", "1_outline.png"] as any; - } else { + } else if (directory === path.join("c:\\test", "src", "webparts")) { return ["helloworld", "second"] as any; + } else { + return ["HelloWorldWebPart.manifest.json"] as any; } }); sinon.stub(fs, "statSync").returns({