LCOV - code coverage report
Current view: top level - pkg/playground - test.js Coverage Total Hit
Test: cockpit Lines: 59.2 % 152 90
Test Date: 2026-06-16 14:09:37

            Line data    Source code
       1              : // SPDX-License-Identifier: LGPL-2.1-or-later
       2            4 : import cockpit from "cockpit";
       3              : 
       4              : import { Channel } from '../lib/cockpit/channel';
       5              : 
       6              : import '../lib/patternfly/patternfly-6-cockpit.scss';
       7              : import "../../node_modules/@patternfly/patternfly/components/Button/button.css";
       8              : import "../../node_modules/@patternfly/patternfly/components/Page/page.css";
       9              : 
      10            4 : document.addEventListener("DOMContentLoaded", () => {
      11            0 :     document.getElementById("hammer").addEventListener("click", e => e.target.setAttribute("hidden", "hidden"));
      12              : 
      13            1 :     document.querySelector(".cockpit-internal-reauthorize .pf-v6-c-button").addEventListener("click", () => {
      14            1 :         document.querySelector(".cockpit-internal-reauthorize span").textContent = "checking...";
      15            1 :         cockpit.script("pkcheck --action-id org.freedesktop.policykit.exec --process $$ -u 2>&1", { superuser: "try" })
      16            1 :                 .stream(data => console.debug(data))
      17            1 :                 .then(() => {
      18            1 :                     document.querySelector(".cockpit-internal-reauthorize span").textContent = "result: authorized";
      19            1 :                 })
      20            1 :                 .catch(() => {
      21            1 :                     document.querySelector(".cockpit-internal-reauthorize span").textContent = "result: access-denied";
      22            1 :                 });
      23            1 :     });
      24              : 
      25            3 :     document.querySelector(".super-channel .pf-v6-c-button").addEventListener("click", () => {
      26            3 :         document.querySelector(".super-channel span").textContent = "checking...";
      27            3 :         cockpit.spawn(["id"], { superuser: "require" })
      28            2 :                 .then(data => {
      29            2 :                     console.log("done");
      30            2 :                     document.querySelector(".super-channel span").textContent = "result: " + data;
      31            2 :                 })
      32            1 :                 .catch(ex => {
      33            1 :                     console.log("fail");
      34            1 :                     document.querySelector(".super-channel span").textContent = "result: " + ex.problem;
      35            1 :                 });
      36            3 :     });
      37              : 
      38            1 :     document.querySelector(".lock-channel .pf-v6-c-button").addEventListener("click", () => {
      39            1 :         document.querySelector(".lock-channel span").textContent = "locking...";
      40            1 :         cockpit.spawn(["flock", "-o", "/tmp/playground-test-lock", "-c", "echo locked; sleep infinity"],
      41            1 :                       { superuser: "try", err: "message" })
      42            1 :                 .stream(data => {
      43            1 :                     document.querySelector(".lock-channel span").textContent = data;
      44            1 :                 })
      45            1 :                 .catch(ex => {
      46            1 :                     document.querySelector(".lock-channel span").textContent = "failed: " + ex.toString();
      47            1 :                 });
      48            1 :     });
      49              : 
      50            4 :     function update_nav() {
      51            4 :         document.getElementById("nav").textContent = '';
      52            4 :         const path = ["top"].concat(cockpit.location.path);
      53            4 :         const e_nav = document.getElementById("nav");
      54            4 :         path.forEach((p, i) => {
      55            1 :             if (i < path.length - 1) {
      56            1 :                 const e_link = document.createElement("a");
      57            1 :                 e_link.setAttribute("tabindex", "0");
      58            1 :                 e_link.textContent = p;
      59            0 :                 e_link.addEventListener("click", () => cockpit.location.go(path.slice(1, i + 1)));
      60            1 :                 e_nav.append(e_link, " >> ");
      61            1 :             } else {
      62            4 :                 const e_span = document.createElement("span");
      63            4 :                 e_span.textContent = p;
      64            4 :                 e_nav.appendChild(e_span);
      65            4 :             }
      66            4 :         });
      67            4 :     }
      68              : 
      69            4 :     cockpit.addEventListener('locationchanged', update_nav);
      70            4 :     update_nav();
      71              : 
      72            0 :     document.getElementById('go-down').addEventListener("click", () => {
      73            0 :         const len = cockpit.location.path.length;
      74            0 :         cockpit.location.go(cockpit.location.path.concat(len.toString()), { length: len.toString() });
      75            0 :     });
      76              : 
      77            4 :     const counter = cockpit.file("/tmp/counter", { syntax: JSON });
      78              : 
      79            4 :     function normalize_counter(obj) {
      80            4 :         obj = obj || { };
      81            4 :         obj.counter = obj.counter || 0;
      82            4 :         return obj;
      83            4 :     }
      84              : 
      85            0 :     function complain(error) {
      86            0 :         document.getElementById('file-error').textContent = error.toString();
      87            0 :     }
      88              : 
      89            4 :     function changed(content, tag, error) {
      90            4 :         if (error)
      91            1 :             return complain(error);
      92            4 :         document.getElementById('file-content').textContent = normalize_counter(content).counter;
      93            4 :         document.getElementById('file-error').textContent = "";
      94            4 :     }
      95              : 
      96            4 :     counter.watch(changed);
      97              : 
      98            0 :     document.getElementById('modify-file').addEventListener("click", () => {
      99            0 :         counter
     100            0 :                 .modify(obj => {
     101            0 :                     obj = normalize_counter(obj);
     102            0 :                     obj.counter += 1;
     103            0 :                     return obj;
     104            0 :                 })
     105            0 :                 .catch(complain);
     106            0 :     });
     107              : 
     108            4 :     function load_file() {
     109            4 :         cockpit.file("/tmp/counter").read()
     110            4 :                 .then(content => {
     111            4 :                     document.getElementById('edit-file').value = content;
     112            4 :                 });
     113            4 :     }
     114              : 
     115            0 :     function save_file() {
     116            0 :         cockpit.file("/tmp/counter").replace(document.getElementById('edit-file').value);
     117            0 :     }
     118              : 
     119            4 :     document.getElementById('load-file').addEventListener("click", load_file);
     120            4 :     document.getElementById('save-file').addEventListener("click", save_file);
     121            4 :     load_file();
     122              : 
     123            0 :     document.getElementById('delete-file').addEventListener("click", () => cockpit.spawn(["rm", "-f", "/tmp/counter"]));
     124              : 
     125            4 :     document.body.removeAttribute("hidden");
     126              : 
     127            4 :     function show_hidden() {
     128            1 :         document.getElementById("hidden").textContent = cockpit.hidden ? "hidden" : "visible";
     129            4 :     }
     130              : 
     131            4 :     cockpit.user().then(info => {
     132            4 :         console.log(info);
     133            4 :         document.getElementById("user-info").textContent = JSON.stringify(info);
     134            4 :     });
     135              : 
     136            4 :     cockpit.addEventListener("visibilitychange", show_hidden);
     137            4 :     show_hidden();
     138              : 
     139              :     // HACK: The user/group/mode options are not part yet of the Cockpit File API so
     140              :     // we resort to creating our own channel here. We can't use the new `Channel`
     141              :     // API as importing it with cockpit leads to the wrong cockpit.Channel being
     142              :     // used instead of the new class.
     143            0 :     const replace = (filename, content, tag, attrs) => {
     144            0 :         const channel = new Channel({ payload: "fsreplace1", superuser: 'try', path: filename, tag, attrs });
     145            0 :         channel.wait();
     146              : 
     147            0 :         return new Promise((resolve, reject) => {
     148            0 :             channel.on('close', message => {
     149            0 :                 if (message.problem) {
     150            0 :                     reject(message);
     151            0 :                 } else {
     152            0 :                     resolve();
     153            0 :                 }
     154            0 :             });
     155              : 
     156            0 :             channel.send_data(content);
     157            0 :             channel.send_control({ command: 'done' });
     158            0 :         });
     159            0 :     };
     160              : 
     161            4 :     const fsreplace_btn = document.getElementById("fsreplace1-create");
     162            4 :     const fsreplace_error = document.getElementById("fsreplace1-error");
     163            0 :     fsreplace_btn.addEventListener("click", e => {
     164            0 :         fsreplace_btn.disabled = true;
     165            0 :         fsreplace_error.textContent = '';
     166            0 :         const filename = document.getElementById("fsreplace1-filename").value;
     167            0 :         const content = document.getElementById("fsreplace1-content").value;
     168            0 :         const use_tag = document.getElementById("fsreplace1-use-tag").checked;
     169            0 :         const file = cockpit.file(filename, { superuser: "try" });
     170            0 :         const attrs = { };
     171            0 :         for (const field of ["user", "group", "mode"]) {
     172            0 :             const val = document.getElementById(`fsreplace1-${field}`).value;
     173            0 :             if (!val)
     174            0 :                 continue;
     175              : 
     176            0 :             attrs[field] = val;
     177            0 :         }
     178              : 
     179            0 :         if ('mode' in attrs)
     180            0 :             attrs.mode = Number.parseInt(attrs.mode);
     181              : 
     182            0 :         file.read().then((_content, tag) => {
     183            0 :             replace(filename, content, use_tag ? tag : undefined, attrs).catch(exc => {
     184            0 :                 fsreplace_error.textContent = cockpit.message(exc);
     185            0 :             })
     186            0 :                     .finally(() => {
     187            0 :                         fsreplace_btn.disabled = false;
     188            0 :                     });
     189            0 :         });
     190            0 :     });
     191            4 : });
        

Generated by: LCOV version 2.0-1