mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-17 21:23:54 +01:00
Fixed number formatting and added tests
This commit is contained in:
parent
28bd5e1b30
commit
90fd496a24
@ -52,24 +52,25 @@ class NumeralFormatter {
|
||||
}
|
||||
|
||||
formatBigNumber(n: number): string {
|
||||
return this.format(n, "0.000a");
|
||||
return this.format(n, "0.[000]a");
|
||||
}
|
||||
|
||||
// TODO: leverage numeral.js to do it. This function also implies you can
|
||||
// use this format in some text field but you can't. ( "1t" will parse but
|
||||
// "1s" will not)
|
||||
formatReallyBigNumber(n: number, decimalPlaces = 3): string {
|
||||
const nAbs = Math.abs(n);
|
||||
if (n === Infinity) return "∞";
|
||||
for (let i = 0; i < extraFormats.length; i++) {
|
||||
if (extraFormats[i] < n && n <= extraFormats[i] * 1000) {
|
||||
if (extraFormats[i] < nAbs && nAbs <= extraFormats[i] * 1000) {
|
||||
return this.format(n / extraFormats[i], "0." + "0".repeat(decimalPlaces)) + extraNotations[i];
|
||||
}
|
||||
}
|
||||
if (Math.abs(n) < 1000) {
|
||||
return this.format(n, "0." + "0".repeat(decimalPlaces));
|
||||
if (nAbs < 1000) {
|
||||
return this.format(n, "0.[" + "0".repeat(decimalPlaces) + "]");
|
||||
}
|
||||
const str = this.format(n, "0." + "0".repeat(decimalPlaces) + "a");
|
||||
if (str === "NaNt") return this.format(n, "0." + " ".repeat(decimalPlaces) + "e+0");
|
||||
const str = this.format(n, "0.[" + "0".repeat(decimalPlaces) + "]a");
|
||||
if (str === "NaNt") return this.format(n, "0.[" + " ".repeat(decimalPlaces) + "]e+0");
|
||||
return str;
|
||||
}
|
||||
|
||||
@ -187,19 +188,52 @@ class NumeralFormatter {
|
||||
return this.format(n, "0.00");
|
||||
}
|
||||
|
||||
parseCustomLargeNumber(str: string): number {
|
||||
const numericRegExp = new RegExp('^(\-?\\d+\\.?\\d*)([' + extraNotations.join("") + ']?)$');
|
||||
const match = str.match(numericRegExp);
|
||||
if (match == null) {
|
||||
return NaN;
|
||||
}
|
||||
const [, number, notation] = match;
|
||||
const notationIndex = extraNotations.indexOf(notation);
|
||||
if (notationIndex === -1) {
|
||||
return NaN;
|
||||
}
|
||||
return parseFloat(number) * extraFormats[notationIndex];
|
||||
}
|
||||
|
||||
furthestFrom0(n1: number, n2 = 0, n3 = 0): number {
|
||||
const minValue = Math.min(n1, n2, n3);
|
||||
if(minValue < 0) {
|
||||
return minValue;
|
||||
} else {
|
||||
return Math.max(n1, n2, n3);
|
||||
}
|
||||
}
|
||||
|
||||
parseMoney(s: string): number {
|
||||
// numeral library does not handle formats like 1e10 well (returns 110),
|
||||
// so if both return a valid number, return the biggest one
|
||||
// numeral library does not handle formats like 1s (returns 1) and 1e10 (returns 110) well,
|
||||
// so if more then 1 return a valid number, return the one farthest from 0
|
||||
const numeralValue = numeral(s).value();
|
||||
const parsed = parseFloat(s);
|
||||
if (isNaN(parsed) && numeralValue === null) {
|
||||
const selfParsed = this.parseCustomLargeNumber(s);
|
||||
// Check for one or more NaN values
|
||||
if (isNaN(parsed) && numeralValue === null && isNaN(selfParsed)) { // 3x NaN
|
||||
return NaN;
|
||||
} else if (isNaN(parsed)) {
|
||||
} else if (isNaN(parsed) && isNaN(selfParsed)) { // 2x NaN
|
||||
return numeralValue;
|
||||
} else if (numeralValue === null) {
|
||||
} else if (numeralValue === null && isNaN(selfParsed)) { // 2x NaN
|
||||
return parsed;
|
||||
} else {
|
||||
return Math.max(numeralValue, parsed);
|
||||
} else if (isNaN(parsed) && numeralValue === null) { // 2x NaN
|
||||
return selfParsed;
|
||||
} else if (isNaN(parsed)) { // 1x NaN
|
||||
return this.furthestFrom0(numeralValue, selfParsed);
|
||||
} else if (numeralValue === null) { // 1x NaN
|
||||
return this.furthestFrom0(parsed, selfParsed);
|
||||
} else if (isNaN(selfParsed)) { // 1x NaN
|
||||
return this.furthestFrom0(numeralValue, parsed);
|
||||
} else { // no NaN
|
||||
return this.furthestFrom0(numeralValue, parsed, selfParsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
220
test/jest/ui/nFormat.test.js
Normal file
220
test/jest/ui/nFormat.test.js
Normal file
@ -0,0 +1,220 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
import { jest, describe, expect, test } from "@jest/globals";
|
||||
import { numeralWrapper } from "../../../src/ui/numeralFormat";
|
||||
|
||||
let decimalFormat = '0.[000000]';
|
||||
|
||||
describe('Numeral formatting for positive numbers', () => {
|
||||
test('should not format too small numbers', () => {
|
||||
expect(numeralWrapper.format(0.0000000001, decimalFormat)).toEqual('0');
|
||||
expect(numeralWrapper.format(0.000000001, decimalFormat)).toEqual('0');
|
||||
expect(numeralWrapper.format(0.00000001, decimalFormat)).toEqual('0');
|
||||
expect(numeralWrapper.format(0.0000001, decimalFormat)).toEqual('0');
|
||||
expect(numeralWrapper.format(0.000001, decimalFormat)).toEqual('0.000001');
|
||||
expect(numeralWrapper.format(0.00001, decimalFormat)).toEqual('0.00001');
|
||||
expect(numeralWrapper.format(0.0001, decimalFormat)).toEqual('0.0001');
|
||||
expect(numeralWrapper.format(0.001, decimalFormat)).toEqual('0.001');
|
||||
expect(numeralWrapper.format(0.01, decimalFormat)).toEqual('0.01');
|
||||
expect(numeralWrapper.format(0.1, decimalFormat)).toEqual('0.1');
|
||||
expect(numeralWrapper.format(1, decimalFormat)).toEqual('1');
|
||||
});
|
||||
test('should format big numbers in short format', () => {
|
||||
expect(numeralWrapper.formatBigNumber(987654000000000000)).toEqual('987654t');
|
||||
expect(numeralWrapper.formatBigNumber(987654300000000000)).toEqual('987654.3t');
|
||||
expect(numeralWrapper.formatBigNumber(987654320000000000)).toEqual('987654.32t');
|
||||
expect(numeralWrapper.formatBigNumber(987654321000000000)).toEqual('987654.321t');
|
||||
expect(numeralWrapper.formatBigNumber(987654321900000000)).toEqual('987654.322t');
|
||||
});
|
||||
test('should format really big numbers in readable format', () => {
|
||||
expect(numeralWrapper.formatReallyBigNumber(987)).toEqual('987');
|
||||
expect(numeralWrapper.formatReallyBigNumber(987654)).toEqual('987.654k');
|
||||
expect(numeralWrapper.formatReallyBigNumber(987654321)).toEqual('987.654m');
|
||||
expect(numeralWrapper.formatReallyBigNumber(987654321987)).toEqual('987.654b');
|
||||
expect(numeralWrapper.formatReallyBigNumber(987654321987654)).toEqual('987.654t');
|
||||
expect(numeralWrapper.formatReallyBigNumber(987654321987654321)).toEqual('987.654q');
|
||||
expect(numeralWrapper.formatReallyBigNumber(987654321987654321987)).toEqual('987.654Q');
|
||||
expect(numeralWrapper.formatReallyBigNumber(987654321987654321987654)).toEqual('987.654s');
|
||||
expect(numeralWrapper.formatReallyBigNumber(987654321987654321987654321)).toEqual('987.654S');
|
||||
expect(numeralWrapper.formatReallyBigNumber(987654321987654321987654321987)).toEqual('987.654o');
|
||||
expect(numeralWrapper.formatReallyBigNumber(987654321987654321987654321987654)).toEqual('987.654n');
|
||||
});
|
||||
test('should format even bigger really big numbers in scientific format', () => {
|
||||
expect(numeralWrapper.formatReallyBigNumber(987654321987654321987654321987654321)).toEqual('9.877e+35');
|
||||
expect(numeralWrapper.formatReallyBigNumber(9876543219876543219876543219876543219)).toEqual('9.877e+36');
|
||||
expect(numeralWrapper.formatReallyBigNumber(98765432198765432198765432198765432198)).toEqual('9.877e+37');
|
||||
});
|
||||
test('should format percentage', () => {
|
||||
expect(numeralWrapper.formatPercentage(1234.56789)).toEqual('123456.79%');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Numeral formatting for negative numbers', () => {
|
||||
test('should not format too small numbers', () => {
|
||||
expect(numeralWrapper.format(-0.0000000001, decimalFormat)).toEqual('0');
|
||||
expect(numeralWrapper.format(-0.000000001, decimalFormat)).toEqual('0');
|
||||
expect(numeralWrapper.format(-0.00000001, decimalFormat)).toEqual('0');
|
||||
expect(numeralWrapper.format(-0.0000001, decimalFormat)).toEqual('0');
|
||||
expect(numeralWrapper.format(-0.000001, decimalFormat)).toEqual('-0.000001');
|
||||
expect(numeralWrapper.format(-0.00001, decimalFormat)).toEqual('-0.00001');
|
||||
expect(numeralWrapper.format(-0.0001, decimalFormat)).toEqual('-0.0001');
|
||||
expect(numeralWrapper.format(-0.001, decimalFormat)).toEqual('-0.001');
|
||||
expect(numeralWrapper.format(-0.01, decimalFormat)).toEqual('-0.01');
|
||||
expect(numeralWrapper.format(-0.1, decimalFormat)).toEqual('-0.1');
|
||||
expect(numeralWrapper.format(-1, decimalFormat)).toEqual('-1');
|
||||
});
|
||||
test('should format big numbers in short format', () => {
|
||||
expect(numeralWrapper.formatBigNumber(-987654000000000000)).toEqual('-987654t');
|
||||
expect(numeralWrapper.formatBigNumber(-987654300000000000)).toEqual('-987654.3t');
|
||||
expect(numeralWrapper.formatBigNumber(-987654320000000000)).toEqual('-987654.32t');
|
||||
expect(numeralWrapper.formatBigNumber(-987654321000000000)).toEqual('-987654.321t');
|
||||
expect(numeralWrapper.formatBigNumber(-987654321900000000)).toEqual('-987654.322t');
|
||||
});
|
||||
test('should format really big numbers in readable format', () => {
|
||||
expect(numeralWrapper.formatReallyBigNumber(-987)).toEqual('-987');
|
||||
expect(numeralWrapper.formatReallyBigNumber(-987654)).toEqual('-987.654k');
|
||||
expect(numeralWrapper.formatReallyBigNumber(-987654321)).toEqual('-987.654m');
|
||||
expect(numeralWrapper.formatReallyBigNumber(-987654321987)).toEqual('-987.654b');
|
||||
expect(numeralWrapper.formatReallyBigNumber(-987654321987654)).toEqual('-987.654t');
|
||||
expect(numeralWrapper.formatReallyBigNumber(-987654321987654321)).toEqual('-987.654q');
|
||||
expect(numeralWrapper.formatReallyBigNumber(-987654321987654321987)).toEqual('-987.654Q');
|
||||
expect(numeralWrapper.formatReallyBigNumber(-987654321987654321987654)).toEqual('-987.654s');
|
||||
expect(numeralWrapper.formatReallyBigNumber(-987654321987654321987654321)).toEqual('-987.654S');
|
||||
expect(numeralWrapper.formatReallyBigNumber(-987654321987654321987654321987)).toEqual('-987.654o');
|
||||
expect(numeralWrapper.formatReallyBigNumber(-987654321987654321987654321987654)).toEqual('-987.654n');
|
||||
});
|
||||
test('should format even bigger really big numbers in scientific format', () => {
|
||||
expect(numeralWrapper.formatReallyBigNumber(-987654321987654321987654321987654321)).toEqual('-9.877e+35');
|
||||
expect(numeralWrapper.formatReallyBigNumber(-9876543219876543219876543219876543219)).toEqual('-9.877e+36');
|
||||
expect(numeralWrapper.formatReallyBigNumber(-98765432198765432198765432198765432198)).toEqual('-9.877e+37');
|
||||
});
|
||||
test('should format percentage', () => {
|
||||
expect(numeralWrapper.formatPercentage(-1234.56789)).toEqual('-123456.79%');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Numeral formatting of text', () => {
|
||||
test('should filter non-numeric text', () => {
|
||||
expect(numeralWrapper.format('abc')).toEqual('0');
|
||||
expect(numeralWrapper.format('123abc')).toEqual('123');
|
||||
expect(numeralWrapper.format('!3')).toEqual('3');
|
||||
expect(numeralWrapper.format('3!')).toEqual('3');
|
||||
expect(numeralWrapper.format('0.001', decimalFormat)).toEqual('0.001');
|
||||
});
|
||||
test('should not format too small numbers', () => {
|
||||
expect(numeralWrapper.format('0.00000001', decimalFormat)).toEqual('0');
|
||||
expect(numeralWrapper.format('0.0000001', decimalFormat)).toEqual('0');
|
||||
expect(numeralWrapper.format('0.000001', decimalFormat)).toEqual('0.000001');
|
||||
expect(numeralWrapper.format('0.00001', decimalFormat)).toEqual('0.00001');
|
||||
expect(numeralWrapper.format('1', decimalFormat)).toEqual('1');
|
||||
expect(numeralWrapper.format('-0.00000001', decimalFormat)).toEqual('0');
|
||||
expect(numeralWrapper.format('-0.0000001', decimalFormat)).toEqual('0');
|
||||
expect(numeralWrapper.format('-0.000001', decimalFormat)).toEqual('-0.000001');
|
||||
expect(numeralWrapper.format('-0.00001', decimalFormat)).toEqual('-0.00001');
|
||||
expect(numeralWrapper.format('-1', decimalFormat)).toEqual('-1');
|
||||
});
|
||||
test('should format big numbers in short format', () => {
|
||||
expect(numeralWrapper.formatBigNumber('987654000000000000')).toEqual('987654t');
|
||||
expect(numeralWrapper.formatBigNumber('987654300000000000')).toEqual('987654.3t');
|
||||
expect(numeralWrapper.formatBigNumber('987654320000000000')).toEqual('987654.32t');
|
||||
expect(numeralWrapper.formatBigNumber('987654321000000000')).toEqual('987654.321t');
|
||||
expect(numeralWrapper.formatBigNumber('987654321900000000')).toEqual('987654.322t');
|
||||
expect(numeralWrapper.formatBigNumber('-987654000000000000')).toEqual('-987654t');
|
||||
expect(numeralWrapper.formatBigNumber('-987654300000000000')).toEqual('-987654.3t');
|
||||
expect(numeralWrapper.formatBigNumber('-987654320000000000')).toEqual('-987654.32t');
|
||||
expect(numeralWrapper.formatBigNumber('-987654321000000000')).toEqual('-987654.321t');
|
||||
expect(numeralWrapper.formatBigNumber('-987654321900000000')).toEqual('-987654.322t');
|
||||
});
|
||||
test('should format really big numbers in readable format', () => {
|
||||
expect(numeralWrapper.formatReallyBigNumber('987')).toEqual('987');
|
||||
expect(numeralWrapper.formatReallyBigNumber('987654')).toEqual('987.654k');
|
||||
expect(numeralWrapper.formatReallyBigNumber('987654321')).toEqual('987.654m');
|
||||
expect(numeralWrapper.formatReallyBigNumber('987654321987')).toEqual('987.654b');
|
||||
expect(numeralWrapper.formatReallyBigNumber('987654321987654')).toEqual('987.654t');
|
||||
expect(numeralWrapper.formatReallyBigNumber('987654321987654321')).toEqual('987.654q');
|
||||
expect(numeralWrapper.formatReallyBigNumber('987654321987654321987')).toEqual('987.654Q');
|
||||
expect(numeralWrapper.formatReallyBigNumber('987654321987654321987654')).toEqual('987.654s');
|
||||
expect(numeralWrapper.formatReallyBigNumber('987654321987654321987654321')).toEqual('987.654S');
|
||||
expect(numeralWrapper.formatReallyBigNumber('987654321987654321987654321987')).toEqual('987.654o');
|
||||
expect(numeralWrapper.formatReallyBigNumber('987654321987654321987654321987654')).toEqual('987.654n');
|
||||
expect(numeralWrapper.formatReallyBigNumber('-987')).toEqual('-987');
|
||||
expect(numeralWrapper.formatReallyBigNumber('-987654')).toEqual('-987.654k');
|
||||
expect(numeralWrapper.formatReallyBigNumber('-987654321')).toEqual('-987.654m');
|
||||
expect(numeralWrapper.formatReallyBigNumber('-987654321987')).toEqual('-987.654b');
|
||||
expect(numeralWrapper.formatReallyBigNumber('-987654321987654')).toEqual('-987.654t');
|
||||
expect(numeralWrapper.formatReallyBigNumber('-987654321987654321')).toEqual('-987.654q');
|
||||
expect(numeralWrapper.formatReallyBigNumber('-987654321987654321987')).toEqual('-987.654Q');
|
||||
expect(numeralWrapper.formatReallyBigNumber('-987654321987654321987654')).toEqual('-987.654s');
|
||||
expect(numeralWrapper.formatReallyBigNumber('-987654321987654321987654321')).toEqual('-987.654S');
|
||||
expect(numeralWrapper.formatReallyBigNumber('-987654321987654321987654321987')).toEqual('-987.654o');
|
||||
expect(numeralWrapper.formatReallyBigNumber('-987654321987654321987654321987654')).toEqual('-987.654n');
|
||||
});
|
||||
test('should format even bigger really big numbers in scientific format', () => {
|
||||
expect(numeralWrapper.formatReallyBigNumber('987654321987654321987654321987654321')).toEqual('9.877e+35');
|
||||
expect(numeralWrapper.formatReallyBigNumber('9876543219876543219876543219876543219')).toEqual('9.877e+36');
|
||||
expect(numeralWrapper.formatReallyBigNumber('98765432198765432198765432198765432198')).toEqual('9.877e+37');
|
||||
expect(numeralWrapper.formatReallyBigNumber('-987654321987654321987654321987654321')).toEqual('-9.877e+35');
|
||||
expect(numeralWrapper.formatReallyBigNumber('-9876543219876543219876543219876543219')).toEqual('-9.877e+36');
|
||||
expect(numeralWrapper.formatReallyBigNumber('-98765432198765432198765432198765432198')).toEqual('-9.877e+37');
|
||||
});
|
||||
test('should format percentage', () => {
|
||||
expect(numeralWrapper.formatPercentage('1234.56789')).toEqual('123456.79%');
|
||||
expect(numeralWrapper.formatPercentage('-1234.56789')).toEqual('-123456.79%');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Numeral formatting of scientific text', () => {
|
||||
test('should format even bigger really big numbers in scientific format', () => {
|
||||
// Accepted by numeral.js
|
||||
expect(numeralWrapper.parseMoney('123')).toEqual(123);
|
||||
expect(numeralWrapper.parseMoney('123.456')).toEqual(123.456);
|
||||
expect(numeralWrapper.parseMoney('123k')).toEqual(123000);
|
||||
expect(numeralWrapper.parseMoney('123.456k')).toEqual(123456);
|
||||
expect(numeralWrapper.parseMoney('123m')).toEqual(123000000);
|
||||
expect(numeralWrapper.parseMoney('123.456m')).toEqual(123456000);
|
||||
expect(numeralWrapper.parseMoney('123b')).toEqual(123000000000);
|
||||
expect(numeralWrapper.parseMoney('123.456b')).toEqual(123456000000);
|
||||
expect(numeralWrapper.parseMoney('123t')).toEqual(123000000000000);
|
||||
expect(numeralWrapper.parseMoney('123.456t')).toEqual(123456000000000);
|
||||
// Custom formats, parseFloat has some rounding issues
|
||||
expect(numeralWrapper.parseMoney('123q')).toBeCloseTo(123000000000000000);
|
||||
expect(numeralWrapper.parseMoney('123.456q')).toBeCloseTo(123456000000000000);
|
||||
expect(numeralWrapper.parseMoney('123Q')).toBeCloseTo(123000000000000000000);
|
||||
expect(numeralWrapper.parseMoney('123.456Q')).toBeCloseTo(123456000000000000000);
|
||||
expect(numeralWrapper.parseMoney('123s')).toBeCloseTo(123000000000000000000000);
|
||||
expect(numeralWrapper.parseMoney('123.456s')).toBeCloseTo(123456000000000000000000);
|
||||
expect(numeralWrapper.parseMoney('123S')).toBeCloseTo(123000000000000000000000000);
|
||||
expect(numeralWrapper.parseMoney('123.456S')).toBeCloseTo(123456000000000000000000000);
|
||||
// Larger numbers fail the test due to rounding issues
|
||||
//expect(numeralWrapper.parseMoney('123o')).toBeCloseTo(123000000000000000000000000000);
|
||||
//expect(numeralWrapper.parseMoney('123.456o')).toBeCloseTo(123456000000000000000000000000);
|
||||
//expect(numeralWrapper.parseMoney('123n')).toBeCloseTo(123000000000000000000000000000000);
|
||||
//expect(numeralWrapper.parseMoney('123.456n')).toBeCloseTo(123456000000000000000000000000000);
|
||||
});
|
||||
test('should format even bigger really big negative numbers in scientific format', () => {
|
||||
// Accepted by numeral.js
|
||||
expect(numeralWrapper.parseMoney('-123')).toEqual(-123);
|
||||
expect(numeralWrapper.parseMoney('-123.456')).toEqual(-123.456);
|
||||
expect(numeralWrapper.parseMoney('-123k')).toEqual(-123000);
|
||||
expect(numeralWrapper.parseMoney('-123.456k')).toEqual(-123456);
|
||||
expect(numeralWrapper.parseMoney('-123m')).toEqual(-123000000);
|
||||
expect(numeralWrapper.parseMoney('-123.456m')).toEqual(-123456000);
|
||||
expect(numeralWrapper.parseMoney('-123b')).toEqual(-123000000000);
|
||||
expect(numeralWrapper.parseMoney('-123.456b')).toEqual(-123456000000);
|
||||
expect(numeralWrapper.parseMoney('-123t')).toEqual(-123000000000000);
|
||||
expect(numeralWrapper.parseMoney('-123.456t')).toEqual(-123456000000000);
|
||||
// Custom formats, parseFloat has some rounding issues
|
||||
expect(numeralWrapper.parseMoney('-123q')).toBeCloseTo(-123000000000000000);
|
||||
expect(numeralWrapper.parseMoney('-123.456q')).toBeCloseTo(-123456000000000000);
|
||||
expect(numeralWrapper.parseMoney('-123Q')).toBeCloseTo(-123000000000000000000);
|
||||
expect(numeralWrapper.parseMoney('-123.456Q')).toBeCloseTo(-123456000000000000000);
|
||||
expect(numeralWrapper.parseMoney('-123s')).toBeCloseTo(-123000000000000000000000);
|
||||
expect(numeralWrapper.parseMoney('-123.456s')).toBeCloseTo(-123456000000000000000000);
|
||||
expect(numeralWrapper.parseMoney('-123S')).toBeCloseTo(-123000000000000000000000000);
|
||||
expect(numeralWrapper.parseMoney('-123.456S')).toBeCloseTo(-123456000000000000000000000);
|
||||
// Larger numbers fail the test due to rounding issues
|
||||
//expect(numeralWrapper.parseMoney('-123o')).toBeCloseTo(-123000000000000000000000000000);
|
||||
//expect(numeralWrapper.parseMoney('-123.456o')).toBeCloseTo(-123456000000000000000000000000);
|
||||
//expect(numeralWrapper.parseMoney('-123n')).toBeCloseTo(-123000000000000000000000000000000);
|
||||
//expect(numeralWrapper.parseMoney('-123.456n')).toBeCloseTo(-123456000000000000000000000000000);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user