Extract NC talk functions from tests to library

Change-Id: I789a893d073a00025ec4bb65311bb893b58b1a06
diff --git a/lib/utils.js b/lib/utils.js
new file mode 100644
index 0000000..145a689
--- /dev/null
+++ b/lib/utils.js
@@ -0,0 +1,94 @@
+const crypto = require('crypto');
+
+const nc_talk_url = process.env.NC_TALK_URL || 'https://cloud.ids-mannheim.de';
+const nc_talk_conversation = process.env.NC_TALK_CONVERSATION;
+const nc_talk_secret = process.env.NC_TALK_SECRET;
+
+// Function to send message to Nextcloud Talk
+async function sendToNextcloudTalk(message, silent = false, screenshotPath = null) {
+    if (!nc_talk_conversation || !nc_talk_secret) {
+        return;
+    }
+
+    try {
+        const axios = require('axios');
+        const fs = require('fs');
+        const sharp = require('sharp');
+        
+        let fullMessage = message;
+        const MAX_MESSAGE_LENGTH = 32000; // Nextcloud Talk message size limit
+        
+        // If a screenshot path is provided, try to embed it
+        if (screenshotPath && fs.existsSync(screenshotPath)) {
+            try {
+                // First, try to resize the image to reduce size
+                const resizedBuffer = await sharp(screenshotPath)
+                    .resize(800, null, { // Resize to max width of 800px, maintain aspect ratio
+                        withoutEnlargement: true,
+                        fit: 'inside'
+                    })
+                    .png({ quality: 80, compressionLevel: 9 })
+                    .toBuffer();
+                
+                const base64Image = resizedBuffer.toString('base64');
+                const dataUri = `data:image/png;base64,${base64Image}`;
+                const messageWithImage = `${message}\n\n![Screenshot](${dataUri})`;
+                
+                // Check if the message with image fits within the limit
+                if (messageWithImage.length <= MAX_MESSAGE_LENGTH) {
+                    fullMessage = messageWithImage;
+                    console.log(`Screenshot will be embedded (message size: ${messageWithImage.length} chars)`);
+                } else {
+                    console.log(`Screenshot too large (${messageWithImage.length} chars), sending text-only notification`);
+                    fullMessage = `${message}\n\n_Screenshot available locally but too large to embed (${Math.round(messageWithImage.length / 1024)}KB)_`;
+                }
+            } catch (imageError) {
+                console.error('Failed to process screenshot for Nextcloud Talk:', imageError.message);
+                fullMessage = `${message}\n\n_Screenshot available locally but could not be processed_`;
+            }
+        }
+        
+        // Generate random header and signature
+        const randomHeader = crypto.randomBytes(32).toString('hex');
+        const messageToSign = randomHeader + fullMessage;
+        const signature = crypto.createHmac('sha256', nc_talk_secret)
+            .update(messageToSign)
+            .digest('hex');
+
+        // Send the message
+        await axios.post(
+            `${nc_talk_url}/ocs/v2.php/apps/spreed/api/v1/bot/${nc_talk_conversation}/message`,
+            {
+                message: fullMessage,
+                silent: silent
+            },
+            {
+                headers: {
+                    'Content-Type': 'application/json',
+                    'Accept': 'application/json',
+                    'OCS-APIRequest': 'true',
+                    'X-Nextcloud-Talk-Bot-Random': randomHeader,
+                    'X-Nextcloud-Talk-Bot-Signature': signature
+                }
+            }
+        );
+        console.log('Message sent to Nextcloud Talk successfully');
+    } catch (error) {
+        console.error('Failed to send message to Nextcloud Talk:', error.message);
+    }
+}
+
+function ifConditionIt(title, condition, test) {
+    if (typeof it !== 'function') {
+        const { it } = require('mocha');
+         return condition ? it(title, test) : it.skip(title + " (skipped)", test)
+    }
+    return condition ? it(title, test) : it.skip(title + " (skipped)", test)
+}
+
+module.exports = {
+    sendToNextcloudTalk,
+    ifConditionIt,
+    nc_talk_conversation,
+    nc_talk_secret 
+};
diff --git a/test/korap-ui.js b/test/korap-ui.js
index a0bc274..c935d79 100644
--- a/test/korap-ui.js
+++ b/test/korap-ui.js
@@ -1,5 +1,5 @@
 const https = require('https');
-const crypto = require('crypto');
+
 const puppeteer = require('puppeteer-extra');
 puppeteer.use(require('puppeteer-extra-plugin-user-preferences')({
     userPrefs: {
@@ -21,93 +21,15 @@
 const KORAP_QUERIES = process.env.KORAP_QUERIES || 'geht, [orth=geht & cmc/pos=VVFIN]'
 const KORAP_MIN_TOKENS_IN_CORPUS = parseInt(process.env.KORAP_MIN_TOKENS_IN_CORPUS || "100000", 10);
 const korap_rc = require('../lib/korap_rc.js').new(KORAP_URL)
+const { sendToNextcloudTalk, ifConditionIt } = require('../lib/utils.js');
 
 const slack_webhook = process.env.SLACK_WEBHOOK_URL;
-const nc_talk_url = process.env.NC_TALK_URL || 'https://cloud.ids-mannheim.de';
-const nc_talk_conversation = process.env.NC_TALK_CONVERSATION;
-const nc_talk_secret = process.env.NC_TALK_SECRET;
 
 if (slack_webhook) {
     slack = require('slack-notify')(slack_webhook);
 }
 
-// Function to send message to Nextcloud Talk
-async function sendToNextcloudTalk(message, silent = false, screenshotPath = null) {
-    if (!nc_talk_conversation || !nc_talk_secret) {
-        return;
-    }
 
-    try {
-        const axios = require('axios');
-        const fs = require('fs');
-        const sharp = require('sharp');
-        
-        let fullMessage = message;
-        const MAX_MESSAGE_LENGTH = 32000; // Nextcloud Talk message size limit
-        
-        // If a screenshot path is provided, try to embed it
-        if (screenshotPath && fs.existsSync(screenshotPath)) {
-            try {
-                // First, try to resize the image to reduce size
-                const resizedBuffer = await sharp(screenshotPath)
-                    .resize(800, null, { // Resize to max width of 800px, maintain aspect ratio
-                        withoutEnlargement: true,
-                        fit: 'inside'
-                    })
-                    .png({ quality: 80, compressionLevel: 9 })
-                    .toBuffer();
-                
-                const base64Image = resizedBuffer.toString('base64');
-                const dataUri = `data:image/png;base64,${base64Image}`;
-                const messageWithImage = `${message}\n\n![Screenshot](${dataUri})`;
-                
-                // Check if the message with image fits within the limit
-                if (messageWithImage.length <= MAX_MESSAGE_LENGTH) {
-                    fullMessage = messageWithImage;
-                    console.log(`Screenshot will be embedded (message size: ${messageWithImage.length} chars)`);
-                } else {
-                    console.log(`Screenshot too large (${messageWithImage.length} chars), sending text-only notification`);
-                    fullMessage = `${message}\n\n_Screenshot available locally but too large to embed (${Math.round(messageWithImage.length / 1024)}KB)_`;
-                }
-            } catch (imageError) {
-                console.error('Failed to process screenshot for Nextcloud Talk:', imageError.message);
-                fullMessage = `${message}\n\n_Screenshot available locally but could not be processed_`;
-            }
-        }
-        
-        // Generate random header and signature
-        const randomHeader = crypto.randomBytes(32).toString('hex');
-        const messageToSign = randomHeader + fullMessage;
-        const signature = crypto.createHmac('sha256', nc_talk_secret)
-            .update(messageToSign)
-            .digest('hex');
-
-        // Send the message
-        await axios.post(
-            `${nc_talk_url}/ocs/v2.php/apps/spreed/api/v1/bot/${nc_talk_conversation}/message`,
-            {
-                message: fullMessage,
-                silent: silent
-            },
-            {
-                headers: {
-                    'Content-Type': 'application/json',
-                    'Accept': 'application/json',
-                    'OCS-APIRequest': 'true',
-                    'X-Nextcloud-Talk-Bot-Random': randomHeader,
-                    'X-Nextcloud-Talk-Bot-Signature': signature
-                }
-            }
-        );
-        console.log('Message sent to Nextcloud Talk successfully');
-    } catch (error) {
-        console.error('Failed to send message to Nextcloud Talk:', error.message);
-    }
-}
-
-function ifConditionIt(title, condition, test) {
-    return condition ? it(title, test) : it.skip(title + " (skipped)", test)
-}
 
 describe('Running KorAP UI end-to-end tests on ' + KORAP_URL, () => {
 
@@ -205,13 +127,11 @@
             }
 
             // Send notification to Nextcloud Talk with screenshot
-            if (nc_talk_conversation && nc_talk_secret) {
-                try {
-                    const message = `🚨 Test on ${KORAP_URL} failed: **${this.currentTest.title}**`;
-                    await sendToNextcloudTalk(message, false, screenshotPath);
-                } catch (ncError) {
-                    console.error('Failed to send notification to Nextcloud Talk:', ncError.message);
-                }
+            try {
+                const message = `🚨 Test on ${KORAP_URL} failed: **${this.currentTest.title}**`;
+                await sendToNextcloudTalk(message, false, screenshotPath);
+            } catch (ncError) {
+                console.error('Failed to send notification to Nextcloud Talk:', ncError.message);
             }
         }
     })