Compare commits

...

4 Commits

Author SHA1 Message Date
Kevin Dang
5061dab335 Remove CLIENT_UID Environment Variable (#123)
* Remove: Client UID References

* Update: version increment
2024-10-06 18:57:39 -07:00
Kevin Dang
947ff89958 Environment Variable Validation (#122)
* Update: env validation and discord token validation

* Add: IPv4 Address Validation

* Update: version increment
2024-10-05 19:29:01 -07:00
Jonathan Smoley
6a9ee2d6d0 Code Coverage and Clean References (#120)
* Add: skeleton suite for command tests (#119)

* test naming updated

* fix imports, remove old references

* added code coverage badge

* Add: coverage environment

* Fix: Readme hyperlink to coverage workflow

* grab coverage pct from env

* Update: gist hyperlink

* color range on coverage

* fix contributing, simplify coverage assessment

* lmiit coverage to master, add branch naming conventions

---------

Co-authored-by: Kevin Dang <77701718+kevinthedang@users.noreply.github.com>
2024-10-01 10:11:23 -07:00
Kevin Dang
e3b0c9abe4 Message Attachment Image Recognition (#118)
* Add: Image recognition

* Fix: Non-Attachment Query

* Update: version increment

* Remove: Debugging logs from buffer file

* Add: comments for bufferHandler
2024-09-18 20:28:23 -07:00
35 changed files with 249 additions and 93 deletions

View File

@@ -4,9 +4,6 @@ CLIENT_TOKEN = BOT_TOKEN
# model for the bot to query from (i.e. llama2 [llama2:13b], mistral, codellama, etc... )
MODEL = MODEL_NAME
# discord bot user id for mentions
CLIENT_UID = BOT_USER_ID
# ip/port address of docker container, I use 172.18.0.3 for docker, 127.0.0.1 for local
OLLAMA_IP = IP_ADDRESS
OLLAMA_PORT = PORT

View File

@@ -1,31 +1,38 @@
<!--
Author: Kevin Dang
Date: 1-30-2024
Changes:
10-01-2024 - Jonathan Smoley
-->
## Naming Conventions
* Branches
* prefix your branch name with the type of contribution:
* features: `'feature/**'`
* releases: `'releases/**'`
* bugs: `'bug/**'`
## Run the Bot
* Refer to all sections below before running the bot.
* You should now have `Ollama`, `NodeJS`, ran `npm install`.
* You will also need a discord bot to run. Refer to the [developer portal](https://discord.com/developers/) to learn how to set one up and invite it to your server. If that does not help then look up a YouTube video like this [one](https://www.youtube.com/watch?v=KZ3tIGHU314&ab_channel=UnderCtrl).
* Now run `npm run start` to run the client and ollama at the same time (this must be one in wsl or a Linux distro)
* Now run `npm run client` to run the client (this must be done in wsl or a Linux distro)
## Set up (Development-side)
* Pull the repository using `https://github.com/kevinthedang/discord-ollama.git`.
* Refer to `Ollama Setup` in the readme to set up Ollama.
* Refer to `Environment Setup` in the readme to set up Ollama.
* This must be set up in a Linux environment or wsl2.
* Install NodeJS `v18.18.2`
* You can check out `Resources` and `To Run` in the readme for a bit of help.
* You can check out `Resources` in the readme for a bit of help.
* You can also reference [NodeJS Setup](#nodejs-setup)
* When you have the project pulled from github, open up a terminal and run `npm i` or `npm install` to get all of the packages for the project.
* In some kind of terminal (`git bash` is good) to run the client. You can run Ollama but opening up wsl2 and typing `ollama serve`.
* Refer to `Ollama Setup` if there are any issues.
## Environment
* You will need two environment files:
* You will need an environment file:
* `.env`: for running the bot
* Please refer to `.env.sample` for all environment variables to include
* `.env.dev.local`: also runs the bot, but with development variables
* Currently there are no differences between the two, but when needed, you may add environment variables as needed.
## NodeJS Setup
* Install [nvm](https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating) using `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash`

View File

@@ -32,7 +32,6 @@ jobs:
touch .env
echo CLIENT_TOKEN = ${{ secrets.BOT_TOKEN }} >> .env
echo MODEL = ${{ secrets.MODEL }} >> .env
echo CLIENT_UID = ${{ secrets.CLIENT_UID }} >> .env
echo OLLAMA_IP = ${{ secrets.OLLAMA_IP }} >> .env
echo OLLAMA_PORT = ${{ secrets.OLLAMA_PORT }} >> .env
@@ -60,7 +59,6 @@ jobs:
touch .env
echo CLIENT_TOKEN = ${{ secrets.BOT_TOKEN }} >> .env
echo MODEL = ${{ secrets.MODEL }} >> .env
echo CLIENT_UID = ${{ secrets.CLIENT_UID }} >> .env
echo OLLAMA_IP = ${{ secrets.OLLAMA_IP }} >> .env
echo OLLAMA_PORT = ${{ secrets.OLLAMA_PORT }} >> .env

50
.github/workflows/coverage.yml vendored Normal file
View File

@@ -0,0 +1,50 @@
name: Coverage
run-name: Code Coverage
on:
push:
branches:
- master
jobs:
Discord-Node-Coverage:
runs-on: ubuntu-latest
environment: coverage
timeout-minutes: 2
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Set up Node Environment lts/hydrogen
uses: actions/setup-node@v4
with:
node-version: lts/hydrogen
cache: "npm"
- name: Install Project Dependencies
run: |
npm install
- name: Create Environment Variables
run: |
touch .env
echo CLIENT_TOKEN = ${{ secrets.BOT_TOKEN }} >> .env
echo MODEL = ${{ secrets.MODEL }} >> .env
echo OLLAMA_IP = ${{ secrets.OLLAMA_IP }} >> .env
echo OLLAMA_PORT = ${{ secrets.OLLAMA_PORT }} >> .env
- name: Collect Code Coverage
run: |
LINE_PCT=$(npm run test:coverage | tail -2 | head -1 | awk '{print $3}')
echo "COVERAGE=$LINE_PCT" >> $GITHUB_ENV
- name: Upload Code Coverage
uses: schneegans/dynamic-badges-action@v1.7.0
with:
auth: ${{ secrets.GIST_SECRET }}
gistID: ${{ vars.GIST_ID }}
filename: coverage.json
label: Coverage
message: ${{ env.COVERAGE }}
valColorRange: ${{ env.COVERAGE }}
maxColorRange: 100
minColorRange: 0

View File

@@ -25,7 +25,6 @@ jobs:
touch .env
echo CLIENT_TOKEN = NOT_REAL_TOKEN >> .env
echo MODEL = ${{ secrets.MODEL }} >> .env
echo CLIENT_UID = ${{ secrets.CLIENT_UID }} >> .env
echo OLLAMA_IP = ${{ secrets.OLLAMA_IP }} >> .env
echo OLLAMA_PORT = ${{ secrets.OLLAMA_PORT }} >> .env

View File

@@ -40,7 +40,6 @@ jobs:
touch .env
echo CLIENT_TOKEN = ${{ secrets.BOT_TOKEN }} >> .env
echo MODEL = ${{ secrets.MODEL }} >> .env
echo CLIENT_UID = ${{ secrets.CLIENT_UID }} >> .env
echo OLLAMA_IP = ${{ secrets.OLLAMA_IP }} >> .env
echo OLLAMA_PORT = ${{ secrets.OLLAMA_PORT }} >> .env

View File

@@ -7,6 +7,7 @@
<a href="#"></a><a href="https://github.com/kevinthedang/discord-ollama/actions/workflows/build.yml"><img alt="Build Status" src="https://github.com/kevinthedang/discord-ollama/actions/workflows/build.yml/badge.svg" /></a>
<a href="#"></a><a href="https://github.com/kevinthedang/discord-ollama/actions/workflows/release.yml"><img alt="Release Status" src="https://github.com/kevinthedang/discord-ollama/actions/workflows/release.yml/badge.svg" /></a>
<a href="#"></a><a href="https://github.com/kevinthedang/discord-ollama/actions/workflows/test.yml"><img alt="Testing Status" src="https://github.com/kevinthedang/discord-ollama/actions/workflows/test.yml/badge.svg" /></a>
<a href="#"></a><a href="https://github.com/kevinthedang/discord-ollama/actions/workflows/coverage.yml"><img alt="Code Coverage" src="https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/kevinthedang/bc7b5dcfa16561ab02bb3df67a99b22d/raw/coverage.json"></a>
</div>
## About/Goals

View File

@@ -7,11 +7,10 @@ services:
build: ./ # find docker file in designated path
container_name: discord
restart: always # rebuild container always
image: kevinthedang/discord-ollama:0.5.11
image: kevinthedang/discord-ollama:0.6.2
environment:
CLIENT_TOKEN: ${CLIENT_TOKEN}
MODEL: ${MODEL}
CLIENT_UID: ${CLIENT_UID}
OLLAMA_IP: ${OLLAMA_IP}
OLLAMA_PORT: ${OLLAMA_PORT}
networks:

View File

@@ -18,10 +18,6 @@
![Token](../imgs/tutorial/token.png)
* You will also need your App's **Client ID**, navigate to **OAuth2** and copy your id.
![Client Id](../imgs/tutorial/client-id.png)
* That should be all of the environment variables needed from Discord, now we need this app on your server.
* Navigate to **Installation** and Copy the provided **Install Link** to allow your App to your server.
* You should set the **Guild Install** permissions as you like, for this purpose we will allow admin priviledges for now. Ensure the **bot** scope is added to do this.

View File

@@ -14,7 +14,7 @@
## To Run Locally (without Docker)
* Run `npm install` to install the npm packages.
* Ensure that your [.env](../.env.sample) file's `OLLAMA_IP` is `127.0.0.1` to work properly.
* You only need your `CLIENT_TOKEN`, `MODEL`, `CLIENT_UID`, `OLLAMA_IP`, `OLLAMA_PORT`.
* You only need your `CLIENT_TOKEN`, `MODEL`, `OLLAMA_IP`, `OLLAMA_PORT`.
* The ollama ip and port should just use it's defaults by nature. If not, utilize `OLLAMA_IP = 127.0.0.1` and `OLLAMA_PORT = 11434`.
* Now, you can run the bot by running `npm run client` which will build and run the decompiled typescript and run the setup for ollama.
* **IMPORTANT**: This must be ran in the wsl/Linux instance to work properly! Using Command Prompt/Powershell/Git Bash/etc. will not work on Windows (at least in my experience).

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "discord-ollama",
"version": "0.5.11",
"version": "0.6.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "discord-ollama",
"version": "0.5.11",
"version": "0.6.2",
"license": "ISC",
"dependencies": {
"discord.js": "^14.15.3",

View File

@@ -1,6 +1,6 @@
{
"name": "discord-ollama",
"version": "0.5.11",
"version": "0.6.2",
"description": "Ollama Integration into discord",
"main": "build/index.js",
"exports": "./build/index.js",

View File

@@ -1,10 +1,8 @@
import { Client, GatewayIntentBits } from 'discord.js'
import { UserMessage, registerEvents } from './utils/events.js'
import Events from './events/index.js'
import { Ollama } from 'ollama'
import { Queue } from './queues/queue.js'
// Import keys/tokens
import { UserMessage, registerEvents } from './utils/index.js'
import Events from './events/index.js'
import Keys from './keys.js'
@@ -26,13 +24,7 @@ const ollama = new Ollama({
// Create Queue managed by Events
const messageHistory: Queue<UserMessage> = new Queue<UserMessage>
/**
* register events for bot to listen to in discord
* @param messageHistory message history for the llm
* @param Events events to register
* @param client the bot reference
* @param Keys tokens from .env files
*/
// register all events
registerEvents(client, Events, messageHistory, Keys, ollama)
// Try to log in the client
@@ -45,5 +37,6 @@ await client.login(Keys.clientToken)
// queue up bots name
messageHistory.enqueue({
role: 'assistant',
content: `My name is ${client.user?.username}`
content: `My name is ${client.user?.username}`,
images: []
})

View File

@@ -1,6 +1,5 @@
import { ChannelType, Client, CommandInteraction, ApplicationCommandOptionType } from 'discord.js'
import { SlashCommand } from '../utils/commands.js'
import { openConfig } from '../utils/index.js'
import { openConfig, SlashCommand } from '../utils/index.js'
export const Capacity: SlashCommand = {
name: 'modify-capacity',

View File

@@ -1,6 +1,5 @@
import { ChannelType, Client, CommandInteraction, TextChannel } from 'discord.js'
import { SlashCommand } from '../utils/commands.js'
import { clearChannelInfo } from '../utils/index.js'
import { clearChannelInfo, SlashCommand } from '../utils/index.js'
export const ClearUserChannelHistory: SlashCommand = {
name: 'clear-user-channel-history',

View File

@@ -1,6 +1,5 @@
import { ChannelType, Client, CommandInteraction, ApplicationCommandOptionType } from 'discord.js'
import { SlashCommand } from '../utils/commands.js'
import { openConfig } from '../utils/index.js'
import { openConfig, SlashCommand } from '../utils/index.js'
export const Disable: SlashCommand = {
name: 'toggle-chat',

View File

@@ -1,6 +1,5 @@
import { ApplicationCommandOptionType, ChannelType, Client, CommandInteraction } from 'discord.js'
import { SlashCommand } from '../utils/commands.js'
import { openConfig } from '../utils/index.js'
import { openConfig, SlashCommand } from '../utils/index.js'
export const MessageStream: SlashCommand = {
name: 'message-stream',

View File

@@ -1,6 +1,5 @@
import { ChannelType, Client, CommandInteraction, ApplicationCommandOptionType } from 'discord.js'
import { SlashCommand } from '../utils/commands.js'
import { openConfig } from '../utils/index.js'
import { openConfig, SlashCommand } from '../utils/index.js'
export const MessageStyle: SlashCommand = {
name: 'message-style',

View File

@@ -1,6 +1,5 @@
import { ChannelType, Client, CommandInteraction, TextChannel, ThreadChannel } from 'discord.js'
import { SlashCommand } from '../utils/commands.js'
import { openChannelInfo } from '../utils/index.js'
import { openChannelInfo, SlashCommand } from '../utils/index.js'
export const ThreadCreate: SlashCommand = {
name: 'thread',

View File

@@ -1,6 +1,5 @@
import { ChannelType, Client, CommandInteraction, TextChannel, ThreadChannel } from 'discord.js'
import { SlashCommand } from '../utils/commands.js'
import { openChannelInfo } from '../utils/index.js'
import { openChannelInfo, SlashCommand } from '../utils/index.js'
export const PrivateThreadCreate: SlashCommand = {
name: 'private-thread',

View File

@@ -1,7 +1,6 @@
import { embedMessage, event, Events, normalMessage, UserMessage } from '../utils/index.js'
import { getChannelInfo, getServerConfig, getUserConfig, openChannelInfo, openConfig, ServerConfig, UserConfig } from '../utils/index.js'
import { clean } from '../utils/mentionClean.js'
import { TextChannel } from 'discord.js'
import { embedMessage, event, Events, normalMessage, UserMessage, clean } from '../utils/index.js'
import { getChannelInfo, getServerConfig, getUserConfig, openChannelInfo, openConfig, UserConfig, getAttachmentData } from '../utils/index.js'
/**
* Max Message length for free users is 2000 characters (bot or not).
@@ -9,14 +8,16 @@ import { TextChannel } from 'discord.js'
*
* @param message the message received from the channel
*/
export default event(Events.MessageCreate, async ({ log, msgHist, tokens, ollama }, message) => {
log(`Message \"${clean(message.content)}\" from ${message.author.tag} in channel/thread ${message.channelId}.`)
export default event(Events.MessageCreate, async ({ log, msgHist, tokens, ollama, client }, message) => {
const clientId = client.user!!.id
const cleanedMessage = clean(message.content, clientId)
log(`Message \"${cleanedMessage}\" from ${message.author.tag} in channel/thread ${message.channelId}.`)
// Do not respond if bot talks in the chat
if (message.author.username === message.client.user.username) return
// Only respond if message mentions the bot
if (!message.mentions.has(tokens.clientUid)) return
if (!message.mentions.has(clientId)) return
// default stream to false
let shouldStream = false
@@ -102,6 +103,9 @@ export default event(Events.MessageCreate, async ({ log, msgHist, tokens, ollama
// response string for ollama to put its response
let response: string
// get message attachment if exists
const messageAttachment: string[] = await getAttachmentData(message.attachments.first())
// set up new queue
msgHist.setQueue(chatMessages)
@@ -111,7 +115,8 @@ export default event(Events.MessageCreate, async ({ log, msgHist, tokens, ollama
// push user response before ollama query
msgHist.enqueue({
role: 'user',
content: clean(message.content)
content: cleanedMessage,
images: messageAttachment || []
})
// undefined or false, use normal, otherwise use embed
@@ -129,7 +134,8 @@ export default event(Events.MessageCreate, async ({ log, msgHist, tokens, ollama
// successful query, save it in context history
msgHist.enqueue({
role: 'assistant',
content: response
content: response,
images: messageAttachment || []
})
// only update the json on success

View File

@@ -1,5 +1,5 @@
import { event, Events, registerCommands } from '../utils/index.js'
import { ActivityType } from 'discord.js'
import { event, Events, registerCommands } from '../utils/index.js'
import commands from '../commands/index.js'
// Log when the bot successfully logs in and export it

View File

@@ -1,9 +1,8 @@
import { getEnvVar } from './utils/env.js'
import { getEnvVar } from './utils/index.js'
export const Keys = {
clientToken: getEnvVar('CLIENT_TOKEN'),
model: getEnvVar('MODEL'),
clientUid: getEnvVar('CLIENT_UID'),
ipAddress: getEnvVar('OLLAMA_IP'),
portAddress: getEnvVar('OLLAMA_PORT'),
} as const // readonly keys

View File

@@ -1,4 +1,4 @@
import { UserMessage } from './events.js'
import { UserMessage } from './index.js'
export interface UserConfiguration {
'message-stream'?: boolean,

View File

@@ -1,21 +1,35 @@
import { resolve } from 'path'
import { config } from 'dotenv'
// Find config - ONLY WORKS WITH NODEMON
const envFile = process.env.NODE_ENV === 'development' ? '.env.dev.local' : '.env'
// resolve config file
const envFilePath = resolve(process.cwd(), envFile)
const envFilePath = resolve(process.cwd(), '.env')
const ipValidate: RegExp = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/
// set current environment variable file
config({ path: envFilePath })
// Getter for environment variables
/**
* Method to validate if environment variables found in file utils/env.ts
*
* @param name Name of the environment variable in .env
* @param fallback fallback value to set if environment variable is not set (used manually in src/keys.ts)
* @returns environment variable value
*/
export function getEnvVar(name: string, fallback?: string): string {
const value = process.env[name] ?? fallback
if (value == undefined)
if (!value)
throw new Error(`Environment variable ${name} is not set.`)
// validate User-Generated Discord Application Tokens
if (name === "CLIENT_TOKEN")
if (value.length < 72) throw new Error(`The "CLIENT_TOKEN" provided is not of at least length 72.
This is probably an invalid token unless Discord updated their token policy. Please provide a valid token.`)
// validate IPv4 address found in environment variables
if (name.endsWith("_IP") || name.endsWith("_ADDRESS"))
if (!ipValidate.test(value))
throw new Error(`Environment variable ${name} does not follow IPv4 formatting.`)
// return env variable
return value
}

View File

@@ -1,4 +1,4 @@
import type { ClientEvents, Awaitable, Client, User } from 'discord.js'
import type { ClientEvents, Awaitable, Client } from 'discord.js'
import { Ollama } from 'ollama'
import { Queue } from '../queues/queue.js'
@@ -10,13 +10,10 @@ export type EventKeys = keyof ClientEvents // only wants keys of ClientEvents ob
/**
* Tokens to run the bot as intended
* @param channel the channel where the bot will respond to queries
* @param model chosen model for the ollama to utilize
* @param clientUid the discord id for the bot
*/
export type Tokens = {
model: string,
clientUid: string
}
/**
@@ -38,7 +35,8 @@ export type ChatParams = {
*/
export type UserMessage = {
role: string,
content: string
content: string,
images: string[] // May or may not have images in message
}
// Event properties

View File

@@ -0,0 +1,57 @@
import { Attachment } from "discord.js"
/**
* Method to convert a Discord attachment url to an array buffer
*
* @param url Discord Attachment Url
* @returns array buffer from Attachment Url
*/
async function getAttachmentBuffer(url: string): Promise<ArrayBuffer> {
// Get the data from the image
const response = await fetch(url)
// Validate the image came in fine
if (!response.ok)
throw new Error('Failed to fetch the attachment.')
// Return image as Buffer
return await response.arrayBuffer()
}
/**
* Method to convert an array buffer to a Base64 String
*
* @param buffer Array Buffer from attachment
* @returns converted Base64 string
*/
function arrayBufferToBase64(buffer: ArrayBuffer): string {
// Converting to Uint8Array
const uint8Array = new Uint8Array(buffer)
let binary = ''
const len = uint8Array.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(uint8Array[i])
}
// Return as Base64
return Buffer.from(binary, 'binary').toString('base64')
}
/**
* Method to retrieve the Base64 Array of provided Message Attachment
*
* @param attachment Message Attachment from Discord
* @returns Base64 string array
*/
export async function getAttachmentData(attachment: Attachment | undefined): Promise<string[]> {
const url: string = attachment !== undefined ? attachment.url : "Missing Url"
// case of no attachment
if (url === "Missing Url")
return []
// Convert data to base64
const buffer = await getAttachmentBuffer(url)
const base64String = arrayBufferToBase64(buffer)
return [base64String]
}

View File

@@ -5,8 +5,10 @@ export * from './messageEmbed.js'
export * from './messageNormal.js'
export * from './commands.js'
export * from './configInterfaces.js'
export * from './mentionClean.js'
// handler imports
export * from './handlers/chatHistoryHandler.js'
export * from './handlers/configHandler.js'
export * from './handlers/streamHandler.js'
export * from './handlers/bufferHandler.js'

View File

@@ -8,9 +8,9 @@ import Keys from "../keys.js"
* - replace function works well for this
*
* @param message
* @returns
* @returns message without client id
*/
export function clean(message: string): string {
const cleanedMessage: string = message.replace(`<@${Keys.clientUid}>`, '').trim()
export function clean(message: string, clientId: string): string {
const cleanedMessage: string = message.replace(`<@${clientId}>`, '').trim()
return cleanedMessage
}

View File

@@ -2,7 +2,7 @@
// expect takes a value from an expression
// it marks a test case
import { describe, expect, it } from 'vitest'
import commands from '../src/commands'
import commands from '../src/commands/index.js'
/**
* Commands test suite, tests the commands object
@@ -12,7 +12,7 @@ import commands from '../src/commands'
* @param name name of the test suite
* @param fn function holding tests to run
*/
describe('#commands', () => {
describe('Commands Existence', () => {
// test definition of commands object
it('references defined object', () => {
// toBe compares the value to the expected value
@@ -25,3 +25,48 @@ describe('#commands', () => {
expect(commandsString).toBe('thread, private-thread, message-style, message-stream, toggle-chat, shutoff, modify-capacity, clear-user-channel-history')
})
})
/**
* User Commands Test suite for testing out commands
* that would be run by users when using the application.
*/
describe('User Command Tests', () => {
// test capacity command
it('run modify-capacity command', () => {
})
it('run clear-user-channel-history command', () => {
})
it('run message-stream command', () => {
})
it('run message-style command', () => {
})
it('run thread command', () => {
})
it('run private-thread command', () => {
})
})
/**
* Admin Commands Test suite for running administrative
* commands with the application.
*/
describe('Admin Command Tests', () => {
it('run shutoff command', () => {
})
it('run toggle-chat command', () => {
})
})

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'
import events from '../src/events'
import events from '../src/events/index.js'
/**
* Events test suite, tests the events object
@@ -9,7 +9,7 @@ import events from '../src/events'
* @param name name of the test suite
* @param fn function holding tests to run
*/
describe('#events', () => {
describe('Events Existence', () => {
// test definition of events object
it('references defined object', () => {
expect(typeof events).toBe('object')

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'
import { getEnvVar } from '../src/utils'
import { getEnvVar } from '../src/utils/index.js'
/**
* getEnvVar test suite, tests the getEnvVar function
@@ -7,7 +7,7 @@ import { getEnvVar } from '../src/utils'
* @param name name of the test suite
* @param fn function holding tests to run
*/
describe('#getEnvVar', () => {
describe('Environment Setup', () => {
// dummy set of keys
const keys = {
clientToken: 'CLIENT_TOKEN',

View File

@@ -1,6 +1,8 @@
import { describe, expect, it } from 'vitest'
import { clean } from '../src/utils/mentionClean'
import { getEnvVar } from '../src/utils'
import { clean } from '../src/utils/index.js'
// Sample UID for testing
const sampleId = '123456789'
/**
* MentionClean test suite, tests the clean function
@@ -8,10 +10,10 @@ import { getEnvVar } from '../src/utils'
* @param name name of the test suite
* @param fn function holding tests to run
*/
describe('#clean', () => {
describe('Mentions Cleaned', () => {
// test for id removal from message
it('removes the mention from a message', () => {
const message = `<@${getEnvVar('CLIENT_UID')}> Hello, World!`
expect(clean(message)).toBe('Hello, World!')
const message = `<@${sampleId}> Hello, World!`
expect(clean(message, sampleId)).toBe('Hello, World!')
})
})

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'
import { Queue } from '../src/queues/queue'
import { Queue } from '../src/queues/queue.js'
/**
* Queue test suite, tests the Queue class
@@ -7,7 +7,7 @@ import { Queue } from '../src/queues/queue'
* @param name name of the test suite
* @param fn function holding tests to run
*/
describe('#queue', () => {
describe('Queue Structure', () => {
let queue= new Queue<string>()
// test for queue creation

View File

@@ -4,9 +4,10 @@ import { defineConfig, configDefaults } from 'vitest/config'
export default defineConfig({
test: {
globals: true, // <-- reduces test file imports
reporters: ['verbose'], // <-- verbose output
coverage: {
exclude: [...configDefaults.exclude, 'build/*', 'tests/*'], // <-- exclude JS build
reporter: ['text', 'html'] // <-- reports in text, html
reporter: ['text-summary'] // <-- report in text-summary
}
}
})