Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor iter 1 #146

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
59fab83
setup tests
justinnguyen0 Nov 11, 2023
96455bc
Merge pull request #1 from CSE-210-Team-6/justin-tests
justinnguyen0 Nov 11, 2023
262cb0b
setup tests
justinnguyen0 Nov 11, 2023
c6b3b9f
Merge pull request #2 from CSE-210-Team-6/justin-tests
justinnguyen0 Nov 11, 2023
5c46a91
add first test
justinnguyen0 Nov 11, 2023
3ad97dc
Merge pull request #3 from CSE-210-Team-6/justin-tests
justinnguyen0 Nov 11, 2023
c1b434e
add more tests
justinnguyen0 Nov 12, 2023
f3ff5db
Merge pull request #4 from CSE-210-Team-6/justin-tests
justinnguyen0 Nov 12, 2023
702926d
add more tests
justinnguyen0 Nov 12, 2023
a2f64f4
Merge pull request #5 from CSE-210-Team-6/justin-tests
justinnguyen0 Nov 12, 2023
bab8692
CI-CD Workflow
kashishvjain Nov 12, 2023
2f64f75
Update test.yml
kashishvjain Nov 12, 2023
4ec4c04
Merge pull request #10 from CSE-210-Team-6/kashishvjain-patch-1
kashishvjain Nov 12, 2023
99b77d0
add more tests
justinnguyen0 Nov 12, 2023
1009b78
Merge pull request #12 from CSE-210-Team-6/justin-tests
justinnguyen0 Nov 12, 2023
534f92f
refactor for jest to pass
justinnguyen0 Nov 12, 2023
0e777db
Merge pull request #13 from CSE-210-Team-6/justin-tests
justinnguyen0 Nov 12, 2023
1453359
add more tests for storage.js
justinnguyen0 Nov 12, 2023
e8658aa
Merge pull request #14 from CSE-210-Team-6/justin-tests
justinnguyen0 Nov 12, 2023
df85684
add more tests for storage.js
justinnguyen0 Nov 12, 2023
51f643d
Merge pull request #15 from CSE-210-Team-6/justin-tests
justinnguyen0 Nov 13, 2023
3741ace
test: add tests for notes.js
Melody-Creator Nov 13, 2023
c741d6a
Merge pull request #16 from CSE-210-Team-6/test
Melody-Creator Nov 16, 2023
c5f0bd1
Code standardization
smruthig Nov 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ module.exports = {
sourceType: 'module'
},
rules: {
}
},
ignorePatterns: ["**/*.jest.js"],
}
25 changes: 25 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Unit Tests

on: [push, pull_request]

jobs:
tests:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18.x, 16.x]

steps:
- uses: actions/checkout@v2

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}

- name: Install dependencies
run: npm install

- name: Run tests
run: npm test
3 changes: 3 additions & 0 deletions babel.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: [['@babel/preset-env', {targets: {node: 'current'}}]],
};
6 changes: 6 additions & 0 deletions jest.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
fakeTimers: {
enableGlobally: true,
},
transformIgnorePatterns: [],
}
31 changes: 26 additions & 5 deletions lib/Markdown.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* This module contains the markdown renderer used to format posts

By default, urls will be linkified with nofollow noopener and noreferrer attributes
By default, urls will be linkifies with nofollow, noopener, and noreferrer attributes
Override those attributes by setting LINK_ATTRIBUTES in the .env file

Usage:
Expand All @@ -10,6 +10,7 @@ const html = md.render(markdown);

import dotenv from 'dotenv';
import MarkdownIt from 'markdown-it';

dotenv.config();

const md = new MarkdownIt({
Expand All @@ -19,10 +20,30 @@ const md = new MarkdownIt({

const LINK_ATTRIBUTES = process.env.LINK_ATTRIBUTES || 'nofollow noopener noreferrer';

// customize the link formatter to include noopener noreferrer links
// this prevents browsers from telling downstream pages about where the links came from
// and protects the privacy of our users.
// code from: https://publishing-project.rivendellweb.net/customizing-markdown-it/
/**
* The above function modifies the rendering of link tags in Markdown by adding a "rel" attribute with
* the value of LINK_ATTRIBUTES.
* @param tokens - The `tokens` parameter is an array of token objects. Each token object represents a
* part of the Markdown document, such as a paragraph, heading, link, etc. The `tokens` array is passed
* to the renderer function to generate the corresponding HTML output.
* @param idx - The `idx` parameter in the code refers to the index of the current token being rendered
* in the array of tokens.
* @param options - The `options` parameter is an object that contains various options and
* configurations for the Markdown renderer. It can include settings such as the rendering mode, the
* HTML tag names to use for different elements, and other customization options.
* @param env - The `env` parameter in the code snippet refers to the environment object. It is an
* optional parameter that can be used to pass additional information or configuration to the rendering
* rules. It can be used to store and access data that needs to be shared between different rendering
* rules.
* @param self - The `self` parameter refers to the Markdown-it instance. It is used to access the
* `renderToken` method and the `renderer` object, which contains the rules for rendering Markdown
* tokens.
*
* customize the link formatter to include noopener noreferrer links
* this prevents browsers from telling downstream pages about where the links came from
* and protects the privacy of our users.
* code from: https://publishing-project.rivendellweb.net/customizing-markdown-it/
*/
const proxy = (tokens, idx, options, env, self) => self.renderToken(tokens, idx, options);
const defaultLinkOpenRenderer = md.renderer.rules.link_open || proxy;
md.renderer.rules.link_open = function (tokens, idx, options, env, self) {
Expand Down
24 changes: 24 additions & 0 deletions lib/__tests__/account.jest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const { isMyPost } = require('../account');

import 'node-fetch';

jest.mock('node-fetch', () => jest.fn());

describe('Tests for isMyPost', () => {
test('Check if a post is my post', () => {
const { DOMAIN } = process.env;
const activity = {
id: `https://${DOMAIN}/m/`
};

expect(isMyPost(activity)).toBe(true);
});

test('Check if a post is not my post', () => {
const activity = {
id: 'https://garbage/m/'
};

expect(isMyPost(activity)).toBe(false);
});
});
5 changes: 5 additions & 0 deletions lib/__tests__/files/likedata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"id": "abc",
"likes": [],
"boosts": []
}
3 changes: 3 additions & 0 deletions lib/__tests__/files/readJSONDictionary.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"id": "test"
}
177 changes: 177 additions & 0 deletions lib/__tests__/notes.jest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import fs from 'fs';
import {
INDEX,
deleteActivityFromIndex,
addActivityToIndex,
getLikesFileName,
writeJSONDictionary
} from '../storage.js';
import {
getLikesForNote,
getReplyCountForNote,
recordLike,
recordBoost,
recordUndoLike
} from '../notes.js';

beforeEach(() => {
jest.resetModules();
});

jest.mock('../storage', () => ({
...jest.requireActual('../storage'),
getLikesFileName: jest.fn(() => 'lib/__tests__/files/likedata.json'),
}));

describe('Tests for getLikesForNote', () => {
test('Check if the output matches', () => {
const mockDate = new Date('2023-01-01T00:00:00Z');
const spy = jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
const id = 'abc';
const attributedTo = 'justin';
const published = '2023-01-01T00:00:00Z';
const inReplyTo = 'ever';
const note = { id: id, attributedTo: attributedTo, published: published, inReplyTo: inReplyTo };

addActivityToIndex(note);

const content = { id: 'abc', likes: [], boosts: [] };

expect(getLikesForNote(id)).toStrictEqual(content);
deleteActivityFromIndex(id);
spy.mockRestore();
});
});

describe('Tests for getReplyCountForNote', () => {
test('Check on empty array', () => {
INDEX.splice(0, INDEX.length);
expect(getReplyCountForNote('A')).toBe(0);
});

test('Check with existing inReplyTo in INDEX', () => {
INDEX.splice(0, INDEX.length);
INDEX.push(
{ id: '1', inReplyTo: 'AB' },
{ id: '2', inReplyTo: 'AB' },
{ id: '3', inReplyTo: 'AC' }
);
expect(getReplyCountForNote('AB')).toBe(2);
});

test('Check with non-existing inReplyTo in INDEX', () => {
INDEX.splice(0, INDEX.length);
INDEX.push(
{ id: '1', inReplyTo: 'AB' },
{ id: '2', inReplyTo: 'CD' }
);
expect(getReplyCountForNote('AC')).toBe(0);
});
});

describe('Tests for recordLike', () => {
test('Check for no actor like records', () => {
const mockDate = new Date('2023-01-01T00:00:00Z');
const spy = jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
const id = 'abc';
const attributedTo = 'justin';
const published = '2023-01-01T00:00:00Z';
const inReplyTo = 'ever';
const note = { id: id, attributedTo: attributedTo, published: published, inReplyTo: inReplyTo };

addActivityToIndex(note);
const request = { actor: "Ever", object: id };

const old_likes = getLikesForNote(id);

expect(old_likes.likes.indexOf("Ever")).toBeLessThan(0);
recordLike(request);

const likes = getLikesForNote(id);
expect(likes.likes.indexOf("Ever")).toBeGreaterThanOrEqual(0);

const fileName = getLikesFileName(id);
const fileContent = fs.readFileSync(fileName, 'utf-8');

expect(fileContent).toMatch(JSON.stringify(likes, null, 2));
deleteActivityFromIndex(id);

spy.mockRestore();
// To-do: check notification
});

test('Check with existing actor like records', () => {
// To-do: check notification
});
});

describe('Tests for recordBoost', () => {
test('Check for no actor boost records', () => {
const mockDate = new Date('2023-01-01T00:00:00Z');
const spy = jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
const id = 'abc';
const attributedTo = 'justin';
const published = '2023-01-01T00:00:00Z';
const inReplyTo = 'ever';
const note = { id: id, attributedTo: attributedTo, published: published, inReplyTo: inReplyTo };

addActivityToIndex(note);
const request = { actor: "def", object: id };

const old_likes = getLikesForNote(id);

expect(old_likes.boosts.indexOf("def")).toBeLessThan(0);
recordBoost(request);

const likes = getLikesForNote(id);
expect(likes.boosts.indexOf("def")).toBeGreaterThanOrEqual(0);

const fileName = getLikesFileName(id);
const fileContent = fs.readFileSync(fileName, 'utf-8');

expect(fileContent).toMatch(JSON.stringify(likes, null, 2));
deleteActivityFromIndex(id);

spy.mockRestore();
// To-do: check notification
});

test('Check with existing actor boost records', () => {
// To-do: check notification
});
});

describe('Tests for recordUndoLike', () => {
test('Check when undoing a like', () => {
const mockDate = new Date('2023-01-01T00:00:00Z');
const spy = jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
const id = 'abc';
const attributedTo = 'justin';
const published = '2023-01-01T00:00:00Z';
const inReplyTo = 'ever';
const note = { id: id, attributedTo: attributedTo, published: published, inReplyTo: inReplyTo };

addActivityToIndex(note);
const request = { actor: "Ever", object: id };

recordUndoLike(request);

const likes = getLikesForNote(id);
expect(likes.likes.indexOf("Ever")).toBeLessThan(0);

const fileName = getLikesFileName(id);
const fileContent = fs.readFileSync(fileName, 'utf-8');

expect(fileContent).toMatch(JSON.stringify(likes, null, 2));
deleteActivityFromIndex(id);

likes.boosts = [];
writeJSONDictionary(fileName, likes);
spy.mockRestore();
// To-do: check notification
});

test('Check with existing actor like records', () => {
// To-do: check notification
});
});
Loading