// eslint-disable-next-line @typescript-eslint/no-var-requires, no-undef
const puppeteer = require('puppeteer');
// eslint-disable-next-line @typescript-eslint/no-var-requires, no-undef
const waitForExpect = require('wait-for-expect');


/**
 * This test suite implicitly tests that communication works cross origin as localhost:3000 is a different origin to 127.0.0.1:3000.
 */
describe('RTCPushMessage', () => {
    var b1, b2;
    var p1, p2;


    beforeEach(async () => {
        b1 = await puppeteer.launch({ headless: false });
        //grant notification permission
        await b1.defaultBrowserContext().overridePermissions('http://localhost:3000', ['notifications']);
        b2 = await puppeteer.launch({ headless: false });
        //grant notification permission
        await b2.defaultBrowserContext().overridePermissions('http://127.0.0.1:3000', ['notifications']);

        p1 = await b1.newPage();
        await p1.goto('http://localhost:3000/test/');
        p2 = await b2.newPage();
        await p2.goto('http://127.0.0.1:3000/test/');
    });

    it('should be able to send a message to an added contact', async () => {
        const p1Address = await p1.evaluate(() => window.tests.getOwnAddress());
        const p2Address = await p2.evaluate(() => window.tests.getOwnAddress());
        const p1Parsed = JSON.parse(p1Address);
        const p2Parsed = JSON.parse(p2Address);
        await p1.evaluate((a) => window.tests.addContact(a), p2Address);
        await p2.evaluate((a) => window.tests.addContact(a), p1Address);
        const recCallback = jest.fn();
        //recieving a message will call our mock callback
        p2.evaluate(() => window.tests.waitForMessage()).then(recCallback);
        //send the message to the other browser (p1 -> p2)
        await p1.evaluate((add, msg) => window.tests.sendMessage(add, msg), p2Parsed.userId, 'hello world!');
        await waitForExpect(() => {
            expect(recCallback.mock.calls.length).toBe(1);
        }, 50000);
        expect(recCallback.mock.calls[0][0]).toEqual({ from: p1Parsed.userId, msg: 'hello world!' });
    }, 60000);

    it('should output a message from an unknown contact', async () => {
        const p1Address = await p1.evaluate(() => window.tests.getOwnAddress());
        const p2Address = await p2.evaluate(() => window.tests.getOwnAddress());
        const p1Parsed = JSON.parse(p1Address);
        const p2Parsed = JSON.parse(p2Address);
        await p1.evaluate((a) => window.tests.addContact(a), p2Address);
        const recCallback = jest.fn();
        //recieving a message will call our mock callback
        p2.evaluate(() => window.tests.waitForMessage()).then(recCallback);
        //send the message to the other browser (p1 -> p2)
        await p1.evaluate((add, msg) => window.tests.sendMessage(add, msg), p2Parsed.userId, 'hello world!');
        await waitForExpect(() => {
            expect(recCallback.mock.calls.length).toBe(1);
        }, 50000);
        expect(recCallback.mock.calls[0][0]).toEqual({ from: p1Parsed.userId, msg: 'hello world!' });
    }, 60000);

    //string too long for one push notification
    const randomString = 'dkhebvpislel1ucjo0px6ac7ezq34k78ygmj6r154pptl4wbifo9yrfwugsqlo287dlkun9wxvh7c66rnfv7gduakrsfqcm3u2z601pgu7rlfqhmjlesqz2rkmvoilq4t00786rapgxtgicwu6xl7u80tf94shcr9300nqgr7fsgxp0g51ucrhbkeri2xbjg0yr0maa8cjdpdp99jv4yv57lsomew7ubu4r4z8peochgh6ru73a25dxkdzpidn7x1iz7n574aqu3frzmus9lsbgoguxnz1s59xthev16kjsyd05uuqpuabw3k1w048ggdjs43u1cve0f2drwmtrxo4vy4ih4ulmask75oogtd5g08d3ui5vmkv2qqqxvqpebhpz30djtup53airvuebouv0xmvr35dksvpm5gej0owkh1pp23tn5mqr9lx55wut87gcsdodtzslfg9avqgjzqcbw3h8hp4jsgh14qewhsak1nldgmoz8dqabmbi9k7f8yrb94ptej3y9b5v1gvjl2qubrno9uilvg1eqmgh31jcvmoirar99fhtobxggshc4wxugikx5jkcpr9cwqycew4obk7xiscm3yj5aevijg8jyrazzdac6vn2bp320gbji6ce8ave44w9yvjpdjsgeqrpte7xuht7gnh1dtceoeloj1mo195kgxu9d1awosnlkbmyw84q3omxyp4aunhw6839q3xpli1sjbeqxo1bdzqpyng4wr3llzzp2xk3kzcyp6f4jzg7u8sa8gq9j1uuobszgiwe6cjzo9mtgvcjs3fpusyicmf3s9pji2cnsowv0p896p4q7ny84tf6avj3hd90v5ewqazghcs5fofbk7nydb9pb1sjkqfejw9k2r5g0ehpkvcvddgdwhegbd0aif3ks8gjzjv1j107wucqmk7poss9ue6z3v4rzxmr8rnqyovv1diyztrkwlo0lrr95jl4itt4pia8jibzacf44vql6v11qcag52qw5v6brdxihbfqihp6lh0qp90ojn8l5bmcctgh1tvi3hqd6zz4r9j63g0mm3gy0ykzdvtp0j5yu2zinkrbkfhxczlycun7nagrhgonucank3jek1r9lfu457d97ab4mbcjsaty9po36menubpizidrirlc100dnwlxm61glgxst2zq672cb6erh284slg1k208cez07dyihlvdncm33s20av4l0ivwgxveyqzix69bo9kyrlobzugjcc1p3midu0uh03l21ahpykj0imzvff7ti0yxqzk6oc3fqxivnyz589xsxjxtckcqp5welnrp2p4gdjufje4mntzejefmafbjupfleh6gzh24kcgnj5o2kr3spy1irqqtz2yue2urra0kryt6pe3wytwiw80zbdbxaykvuwo72o29zy1koeo9f1sm78vbdd76dvyfrlxxxmw7afi5ek2wsiyynxgrd7gcj5dv4ye0nlzz0u1cllqmeanj9dikuarvq989dqjpm3kbxn72fmjjj4g74n2bsyh95n1os3kashumf47xkripr5bow06jcrsm6a8cxryhttzrgfuq81zy3gv4rziosle1j22v5gnhzwp5etanxpw5myfrfzugqhnc1pv4x01vdk9eiyngcao4ipiicbor8st9xmau2qao1aainwq3buc5cd57o1vb6ncsriwrl7cwo2dcn5gkkzdru1ywkebn19d8tzwzj0bexczgaeoquhxs22wf1dubf46gdo6hfk7b8w4iqi7ajsiihwd8e8zr8hzhjkj35e5c2tjq7u8rjkqfangvczrzp8la0kmb9r35t9ogdmcknn575m6xrevvgoktxsz7funfxy24bhg7alybqsf89s9f4fu47dhosugvrctpzhzyvgb8k2mqqzzkly56v0p8jvttztqhhgso3oydq3q5hv27c1dhorpguij9sm7tofnppukemq7st0wpki90o571yvc2tpbx1qkurkkm6ak8p2moayd4f7mm5isbfg8g75cj06l2l6t9npt237sjmnawcm99ihanq48ymltyg9yrt3gk2e7wbrya101ezcfhcfdh1cs9joy88gnr5mc1sh01i0pp5izvuagbf9l1gzouohte7ly5jsncdqa5nhcru71ourakasbzr6i7qxyocgua7i5cv3n6oh9gzl4y4k2e2whlotce0e56atbqejc8x9p7hf01qm0c4y8cgbyxxch5ytim54r0ptw9qzlaj14cawhhhlxxazq1o93yn7cnth0a8ez7mfmf7sca8mpd2cvzfepn68z5kl01su2at8r6aehra77f59t44d44bppoxse19fely87qg72gouhsldbkxv7oa2e0z3mlyf4d7m1vrx0c784ew28rmbzq0il84p7211ys7rxan2khc3qtkr91kkw8vyx6xzrvjk2clqljqbhtigj6pydkz875ewnimiredwjm7f694feuh3ua7zp8e6iwl1l837ekwzde2z9dk6j75v71jje19vqfpzsjpg0rr53aum0fboyiff8kzuz2m1m0f74wd5781sgy9vms2jusmq6z4u8arsugi8wfqxbf9djhlbwrez1s5rzin9z7eaulvdlvot22qmpbir1b4cahbjgp375leci62dfdv4p5hdrru5agz2wc8ls0bwgpfuibguu0l6k1l5z009xbhg7b1mv5yjhhjv81zyz1fghtv08iazduh9oef1n3mk52twb9pjw8t2p3q7on8jy4v093ioxya35o6eu0t8n8io9vkun0evgxj9g8jhv2va94rulb8hzo716mxqpjnmdjcj9zspsk46lfvki54sdo0kbdw8b1e44zbfrzzmggvasu8fgchmjs6s3x56e3btwpgp9v7vh624naercy5u8zll3ua4efa20ixtl7k6jhp886har9v876aiweuxuj9kr8yryqydjf7rg1ry0ity28wdetxvefwyyrxgn44fosdx6b7skmrlsql79ia0trbj4j7jvhd1hz91w5i2cordhpz74wm3k2c6mctg78au4ca8njswz9osev0abgntjlq77z4rokcv2qsvhycz8upuwto8nv54qjuokkyymcbe8z31920d1b5keybmez3pk2scktodbt8ji65u92iki5dzybh3985r95j30g5lmy3xga8vczgk3c8mri2t5kl7z0d4gvbhrzxvzhnixxfanw8rsq8cu0ztci4jhy02zp3bl88pis2e6d9sqwurszau312dml1nmq5zwlqqkhkozo171ruffstuov0075us53m9tig59mg3xp6s7lyqmpe5pf9p578es7k9w20alysdeq1rrou98n6u4vwcztbijp222h1en5g3gs8yvtli4nkktnykg1y93q6awgayro5exp8hrf6uzfyfbt5hv8j1y02zpi547mst5mf1pqq9tdo1iqha8n2af4lliuom2jj427vnyzfr4afy3a9s2r7bp8t68uhqvcnqcayuzerca5r1oha6w94q4s3xcjoejdpkiuvs82a7ok2qi2z1db4ya6rvlgu1i9mjteq31tn4myugv610j2lqtlui7zr74rpxp5n2fg4rzr46k63aq5a06f3smf1x3oevxsn2sitlw7u0a5sq5cvemevnmooxbvjp9la71f31s7wyheci5w71jqqyimpwea11aw0d0j8k994co7yzxwf6utbuiujntvlfitq3tizturvsqd77plnam8ghwypey86nx3yk6oqnma4d1sn9yz0dled7ol9uqkblszk11e3x7xdya0ceztn5ghmn7q9lfb6mooop14hfjkz4wjw6v76ib9xwnrewf33le1ms78rkkn7a3zsytr50khypfohlvk4v350u3gw5amxzauc3eun54cbte7n6aaszt0klo727p7xekbwoabzu80ec1nnvzkculwh4c43qtnd1g8d2cfph';


    it('should be able to pass along large values via webRTC', async () => {
        const p1Address = await p1.evaluate(() => window.tests.getOwnAddress());
        const p2Address = await p2.evaluate(() => window.tests.getOwnAddress());
        const p1Parsed = JSON.parse(p1Address);
        const p2Parsed = JSON.parse(p2Address);
        await p1.evaluate((a) => window.tests.addContact(a), p2Address);
        const recCallback = jest.fn();
        //recieving a message will call our mock callback
        p2.evaluate(() => window.tests.waitForMessage()).then(recCallback);
        //send the message to the other browser (p1 -> p2)
        await p1.evaluate((add, msg) => window.tests.sendMessage(add, msg), p2Parsed.userId, randomString);
        await waitForExpect(() => {
            expect(recCallback.mock.calls.length).toBe(1);
        }, 50000);
        expect(recCallback.mock.calls[0][0]).toEqual({ from: p1Parsed.userId, msg: randomString });
    }, 60000);


    afterEach(async () => {
        b1.close();
        b2.close();
    });
});
