main
John Lauer Skip repeated Codex IDE introductory walkthrough in new editor tabs 18eb771 1mo ago
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1] / 'runtime'))
from manage import atomic
from walkthrough import MARKER, patch_tour, restore_tour

SOURCE = '''function tour(){let{data:e,isLoading:t}=query(keys.NUX_2025_09_15),{authMethod:n}=auth();if(!t){if(e)return`none`;switch(n){case`chatgpt`:return`2025-09-15-full-chatgpt-auth`;case`apikey`:return`2025-09-15-apikey-auth`;case null:return`none`}}}'''


class Walkthrough(unittest.TestCase):
    def test_new_tab_skips_tour_and_uninstall_restores_original(self):
        with tempfile.TemporaryDirectory() as d:
            ext = Path(d)
            asset = ext / 'webview/assets/app-initial-test.js'
            asset.parent.mkdir(parents=True)
            asset.write_text(SOURCE + '\nfunction signIn(){return "sign in required"}')
            self.assertEqual(patch_tour(ext, atomic)['state'], 'skipped')
            first = asset.read_text()
            patch_tour(ext, atomic)
            self.assertEqual(first, asset.read_text())
            # No saved state, a saved false, and a completed tour all get the
            # composer; authentication remains a separate, unchanged function.
            js = first + '''
const assert=require('node:assert/strict');
const keys={NUX_2025_09_15:'tour'};
let result;
function query(){return result};function auth(){return {authMethod:'chatgpt'}};
for(result of [{data:undefined,isLoading:false},{data:false,isLoading:false},{data:true,isLoading:false},{isLoading:true}]) assert.equal(tour(),'none');
assert.equal(signIn(),'sign in required');
'''
            subprocess.run(['node', '-e', js], check=True)
            asset.write_text(first + '\n// unrelated edit')
            restore_tour(ext, atomic)
            self.assertNotIn(MARKER, asset.read_text())
            self.assertEqual(asset.read_text(), SOURCE + '\nfunction signIn(){return "sign in required"}\n// unrelated edit')

    def test_unknown_or_ambiguous_upstream_left_untouched(self):
        for source in [SOURCE.replace('NUX_2025_09_15', 'NUX_FUTURE'), SOURCE + SOURCE]:
            with self.subTest(source=source), tempfile.TemporaryDirectory() as d:
                ext = Path(d)
                asset = ext / 'webview/assets/app-initial-test.js'
                asset.parent.mkdir(parents=True)
                asset.write_text(source)
                self.assertEqual(patch_tour(ext, atomic)['state'], 'unsupported')
                self.assertEqual(asset.read_text(), source)


if __name__ == '__main__':
    unittest.main()