|
10 | 10 | * Uses process.env.API_KEY set at runtime. |
11 | 11 | * |
12 | 12 | * Part 2 – AM Org (AM_ORG_UID, DAM / Contentstack Assets + scan enabled) |
13 | | - * Requires process.env.AM_API_KEY (a stack API key inside AM_ORG_UID). |
14 | | - * All tests in Part 2 are skipped when AM_API_KEY is not set. |
| 13 | + * A stack is created dynamically inside AM_ORG_UID using the same authtoken |
| 14 | + * obtained during main setup. No static AM_API_KEY required. |
| 15 | + * All tests in Part 2 are skipped when AM_ORG_UID is not set. |
15 | 16 | * |
16 | 17 | * Bug surface these tests cover (per design doc): |
17 | 18 | * § 3.1 - Scan status missing/leaking on fetch and list |
@@ -714,35 +715,105 @@ describe('Asset Scan Status – api_version Header Isolation (§ 4.2)', () => { |
714 | 715 |
|
715 | 716 | // ============================================================================ |
716 | 717 | // Part 2 – AM Org (AM_ORG_UID – DAM / Contentstack Assets + scan enabled) |
| 718 | +// |
| 719 | +// The AM org stack is created dynamically using the same authtoken that the |
| 720 | +// main test suite already obtained — no static AM_API_KEY needed in .env. |
| 721 | +// The stack is deleted in the after() hook. |
717 | 722 | // ============================================================================ |
718 | 723 |
|
719 | 724 | describe('Asset Scan Status – AM Org (AM_ORG_UID, DAM + scan enabled)', function () { |
720 | 725 | let amStack |
721 | 726 | let amFreshAssetUid |
722 | 727 | let amReplaceAssetUid |
| 728 | + let amStackApiKey = null |
| 729 | + let amStackName = null |
723 | 730 |
|
724 | | - before(function () { |
725 | | - if (!process.env.AM_API_KEY) { |
726 | | - console.log(' [scan-test] AM_API_KEY not set — skipping AM Org suite. ' + |
727 | | - 'Add AM_API_KEY=<stack key from AM_ORG_UID> to .env to enable.') |
728 | | - this.skip() |
| 731 | + // Step 1: Create a stack dynamically inside AM_ORG_UID |
| 732 | + before(async function () { |
| 733 | + this.timeout(60000) |
| 734 | + |
| 735 | + const amOrgUid = process.env.AM_ORG_UID |
| 736 | + if (!amOrgUid) { |
| 737 | + console.log(' [scan-test] AM_ORG_UID not set — skipping AM Org suite.') |
| 738 | + return this.skip() |
| 739 | + } |
| 740 | + |
| 741 | + const authtoken = testSetup.testContext && testSetup.testContext.authtoken |
| 742 | + if (!authtoken) { |
| 743 | + console.log(' [scan-test] No authtoken in testContext — skipping AM Org suite.') |
| 744 | + return this.skip() |
| 745 | + } |
| 746 | + |
| 747 | + const host = process.env.HOST || 'api.contentstack.io' |
| 748 | + const axios = (await import('axios')).default |
| 749 | + const stackName = `SDK_ScanAM_${Math.random().toString(36).substring(2, 7)}` |
| 750 | + |
| 751 | + console.log(` [scan-test] Creating AM org test stack: ${stackName}...`) |
| 752 | + |
| 753 | + try { |
| 754 | + const response = await axios.post(`https://${host}/v3/stacks`, { |
| 755 | + stack: { |
| 756 | + name: stackName, |
| 757 | + description: 'AM org asset scan status integration test stack', |
| 758 | + master_locale: 'en-us' |
| 759 | + } |
| 760 | + }, { |
| 761 | + headers: { |
| 762 | + authtoken, |
| 763 | + organization_uid: amOrgUid, |
| 764 | + 'Content-Type': 'application/json' |
| 765 | + } |
| 766 | + }) |
| 767 | + |
| 768 | + amStackApiKey = response.data.stack.api_key |
| 769 | + amStackName = response.data.stack.name || stackName |
| 770 | + console.log(` [scan-test] AM stack created: ${amStackName} (${amStackApiKey})`) |
| 771 | + |
| 772 | + // Wait for stack provisioning (same delay as main setup) |
| 773 | + await wait(5000) |
| 774 | + |
| 775 | + amStack = buildStack(amStackApiKey) |
| 776 | + } catch (err) { |
| 777 | + const msg = (err.response && err.response.data && err.response.data.error_message) || err.message |
| 778 | + console.log(` [scan-test] AM stack creation failed: ${msg} — skipping AM Org suite.`) |
| 779 | + return this.skip() |
729 | 780 | } |
730 | | - amStack = buildStack(process.env.AM_API_KEY) |
731 | 781 | }) |
732 | 782 |
|
| 783 | + // Step 2: Upload assets for tests (only runs if step 1 succeeded) |
733 | 784 | before(async function () { |
734 | 785 | this.timeout(60000) |
| 786 | + if (!amStack) return |
735 | 787 | amFreshAssetUid = await uploadScanAsset(amStack, 'am-main') |
736 | 788 | amReplaceAssetUid = await uploadScanAsset(amStack, 'am-replace') |
737 | 789 | console.log(` [scan-test] AM freshAssetUid=${amFreshAssetUid} replaceAssetUid=${amReplaceAssetUid}`) |
738 | 790 | }) |
739 | 791 |
|
| 792 | + // Cleanup: delete assets, then delete the dynamically created AM stack |
740 | 793 | after(async function () { |
| 794 | + this.timeout(30000) |
| 795 | + |
741 | 796 | for (const uid of [amFreshAssetUid, amReplaceAssetUid]) { |
742 | | - if (uid) { |
| 797 | + if (uid && amStack) { |
743 | 798 | try { await amStack.asset(uid).delete() } catch (e) { /* ignore */ } |
744 | 799 | } |
745 | 800 | } |
| 801 | + |
| 802 | + if (amStackApiKey) { |
| 803 | + try { |
| 804 | + const authtoken = testSetup.testContext && testSetup.testContext.authtoken |
| 805 | + if (authtoken) { |
| 806 | + const host = process.env.HOST || 'api.contentstack.io' |
| 807 | + const axios = (await import('axios')).default |
| 808 | + await axios.delete(`https://${host}/v3/stacks`, { |
| 809 | + headers: { api_key: amStackApiKey, authtoken } |
| 810 | + }) |
| 811 | + console.log(` [scan-test] Deleted AM stack: ${amStackName}`) |
| 812 | + } |
| 813 | + } catch (e) { |
| 814 | + console.log(` [scan-test] AM stack deletion failed: ${e.message}`) |
| 815 | + } |
| 816 | + } |
746 | 817 | }) |
747 | 818 |
|
748 | 819 | // -------------------------------------------------------------------------- |
|
0 commit comments