Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f19b2528a | ||
|
|
1f11c39773 | ||
|
|
b6ccb5927a | ||
|
|
1d465ee318 | ||
|
|
3ab48b1cf5 | ||
|
|
de4ac978bd | ||
|
|
8df5faf4ef | ||
|
|
99a2035fdb | ||
|
|
a0d61728ea | ||
|
|
312bf6102c | ||
|
|
f4885b6f1c | ||
|
|
ca63a0979e | ||
|
|
1f266c3353 | ||
|
|
c7b2a70312 | ||
|
|
255133af4d | ||
|
|
db74531cd4 | ||
|
|
f36d8bfc78 | ||
|
|
3b31ace726 | ||
|
|
6badfef9da | ||
|
|
8c38dd73d8 | ||
|
|
b8682a852a | ||
|
|
8c17929151 | ||
|
|
bb92c9ec28 |
48
CHANGELOG.md
48
CHANGELOG.md
@@ -1,5 +1,53 @@
|
||||
# Changelog
|
||||
|
||||
## 0.7.2 (2020-09-06)
|
||||
|
||||
* update onesync documentation and do not recommend it as it breaks other apps | [commit](https://github.com/undergroundwires/privacy.sexy/commit/f36d8bfc7848bb65ac0c641e318a689bf3816ccf)
|
||||
* add reversibility for biometric disabling and do not recommend it | [commit](https://github.com/undergroundwires/privacy.sexy/commit/db74531cd4139615c6d595959217d3651f099019)
|
||||
* fix bad highlighting of selected nodes when using keyboard navigation | [commit](https://github.com/undergroundwires/privacy.sexy/commit/255133af4dfae40171406648a3e2920f16d71cb3)
|
||||
* add reversibility to removing bloatware | [commit](https://github.com/undergroundwires/privacy.sexy/commit/c7b2a703128470a05f12c9c6e8002444def37ef8)
|
||||
* fix indeterminate state being lost | [commit](https://github.com/undergroundwires/privacy.sexy/commit/1f266c33535f72b69c65985bf2eff27cd2c5a104)
|
||||
* fix wording in default text in text area | [commit](https://github.com/undergroundwires/privacy.sexy/commit/ca63a0979ef55d07d09d9443e5cea9aa888870a5)
|
||||
* add best practice suggestion to come back | [commit](https://github.com/undergroundwires/privacy.sexy/commit/f4885b6f1c82752f2143934e336d6d1b1af03015)
|
||||
|
||||
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.7.1...0.7.2)
|
||||
|
||||
## 0.7.1 (2020-09-04)
|
||||
|
||||
* fix some browsers (including firefox) downloading the script as a text file | [commit](https://github.com/undergroundwires/privacy.sexy/commit/8c17929151f9c4fa5f48564492bbf400ced95eea)
|
||||
* rename screenshot image file | [commit](https://github.com/undergroundwires/privacy.sexy/commit/b8682a852a14ed6cf49986695d9510b840ac9d3d)
|
||||
* fix new/changed script higlighting not working on production builds | [commit](https://github.com/undergroundwires/privacy.sexy/commit/8c38dd73d8c7b77d8d341c0389f4d7229f9b97fd)
|
||||
* refactor unused imports | [commit](https://github.com/undergroundwires/privacy.sexy/commit/6badfef9daace0c5de3fd33652a82bfe22261b11)
|
||||
|
||||
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.7.0...0.7.1)
|
||||
|
||||
## 0.7.0 (2020-09-02)
|
||||
|
||||
* [search] better (multilined) message when there are no results | [commit](https://github.com/undergroundwires/privacy.sexy/commit/ec15af01dd020b364c2174fe562fd66227c2320c)
|
||||
* [search] added clear/close button | [commit](https://github.com/undergroundwires/privacy.sexy/commit/d6fa9a2a03c0ebe68b94f0b80cc52b4e200c9213)
|
||||
* move script generation to /generation | [commit](https://github.com/undergroundwires/privacy.sexy/commit/5df458739d076719e350ba194c4f3f772884fcdb)
|
||||
* add auto-highlighting of selected/updated code | [commit](https://github.com/undergroundwires/privacy.sexy/commit/b789250cb89e2130b08e1a927df8181cf945dfeb)
|
||||
* prompt admin priviliges automatically | [commit](https://github.com/undergroundwires/privacy.sexy/commit/f8ba5c46e4923d9c35f200f8a08aa6437f7c0ecc)
|
||||
* add removal of ghost (default0) telemetry user | [commit](https://github.com/undergroundwires/privacy.sexy/commit/c262681011f39b4412669b6cf233476f676ca550)
|
||||
* add more windows defender tweaks, categorization and reversibility | [commit](https://github.com/undergroundwires/privacy.sexy/commit/1a34c7374ba56bafa0209bbb55c81b233bb419ed)
|
||||
* fix NTP script documentation is on wrong place | [commit](https://github.com/undergroundwires/privacy.sexy/commit/3060ebf79cf242370433495cc3e1878b7581b202)
|
||||
* updated dependencies to latest and audit fixes (#25) | [commit](https://github.com/undergroundwires/privacy.sexy/commit/c628aa9aef8ab7c815661d3c1711e7fbc65c69a2)
|
||||
* categorize, fix and extend windows log files cleanup | [commit](https://github.com/undergroundwires/privacy.sexy/commit/594a14d6ca76cbd27a21877b8c373c1930589ca6)
|
||||
* add more OneDrive cleanup scripts and categorize them | [commit](https://github.com/undergroundwires/privacy.sexy/commit/978d7d08638dd161082f239ed088b12302f29458)
|
||||
* add disabling firefox telemetry | [commit](https://github.com/undergroundwires/privacy.sexy/commit/f8b8b4c97ab734d5ba7370894b694993924388da)
|
||||
* add disabling ccleaner telemetry | [commit](https://github.com/undergroundwires/privacy.sexy/commit/018b7e270f207aac926cb12f8069ebfcdce193ce)
|
||||
* Add disabling of PowerShell 7+ telemetry (#29) | [commit](https://github.com/undergroundwires/privacy.sexy/commit/456e40bedf9afcc846f9b13f1ea144cef6115cf6)
|
||||
* categorize, fix, make scripts reversible in "UI for privacy", "security improvements" and "configure browsers" | [commit](https://github.com/undergroundwires/privacy.sexy/commit/532915b95da9fecd6b981d91bf489359e4e53caa)
|
||||
* fix "Configure Defender" being in wrong category #28 | [commit](https://github.com/undergroundwires/privacy.sexy/commit/f709d6a566ed7846b677b383863deda9680a2a9c)
|
||||
* do not hardcode capability versions and make them reversible | [commit](https://github.com/undergroundwires/privacy.sexy/commit/2afef4ea3d0d3d09aa1fa1eedba8493680bd8f10)
|
||||
* exclude paint, wordpad and notepad from bloatware removal | [commit](https://github.com/undergroundwires/privacy.sexy/commit/d235dee95514a01745aef9479d07f88ffb4b40b8)
|
||||
* add reversibility on category level | [commit](https://github.com/undergroundwires/privacy.sexy/commit/f51e8859eeb32c944126d692cfe03a0320c8b568)
|
||||
* refactor unused imports & variables | [commit](https://github.com/undergroundwires/privacy.sexy/commit/a23d28f2cfa2d64d45460697cf5ee9d6b5920752)
|
||||
* fix search (got broken in b789250) with tests and refactorings | [commit](https://github.com/undergroundwires/privacy.sexy/commit/8bbe6ebf750f1a1cbab493fb99b5ea91f4e21609)
|
||||
* update the screenshot to show off highlighting | [commit](https://github.com/undergroundwires/privacy.sexy/commit/b4aacea2a3e0bbcf2d8a79ff67f51c0f19e888a6)
|
||||
|
||||
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.6.2...0.7.0)
|
||||
|
||||
## 0.6.2 (2020-08-16)
|
||||
|
||||
* 🐛 fixed disabling error reporting for november 2019 update | [commit](https://github.com/undergroundwires/privacy.sexy/commit/5967347b80976a519f6f4eb1972a62f3e600df2b)
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
## Get started
|
||||
|
||||
- Online version: [https://privacy.sexy](https://privacy.sexy)
|
||||
- or download latest desktop version for [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.6.2/privacy.sexy-Setup-0.6.2.exe), [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.6.2/privacy.sexy-0.6.2.AppImage), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.6.2/privacy.sexy-0.6.2.dmg)
|
||||
- or download latest desktop version for [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.7.2/privacy.sexy-Setup-0.7.2.exe), [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.7.2/privacy.sexy-0.7.2.AppImage), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.7.2/privacy.sexy-0.7.2.dmg)
|
||||
- 💡 Come back regularly to apply latest version for stronger privacy and security.
|
||||
|
||||
[](https://privacy.sexy)
|
||||
[](https://privacy.sexy)
|
||||
|
||||
## Why
|
||||
|
||||
@@ -48,8 +49,8 @@
|
||||
- Development: `npm run serve` to compile & hot-reload for development.
|
||||
- Production: `npm run build` to prepare files for distribution.
|
||||
- Or run using Docker:
|
||||
1. Build: `docker build -t undergroundwires/privacy.sexy:0.6.2 .`
|
||||
2. Run: `docker run -it -p 8080:80 --rm --name privacy.sexy-0.6.2 undergroundwires/privacy.sexy:0.6.2`
|
||||
1. Build: `docker build -t undergroundwires/privacy.sexy:0.7.2 .`
|
||||
2. Run: `docker run -it -p 8080:80 --rm --name privacy.sexy-0.7.2 undergroundwires/privacy.sexy:0.7.2`
|
||||
|
||||
## Architecture
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "privacy.sexy",
|
||||
"version": "0.6.2",
|
||||
"version": "0.7.2",
|
||||
"author": "undergroundwires",
|
||||
"description": "Enforce privacy & security best-practices on Windows, because privacy is sexy 🍑🍆",
|
||||
"private": true,
|
||||
|
||||
@@ -52,7 +52,7 @@ function parseCategoryChild(
|
||||
children.subScripts.push(script);
|
||||
} else {
|
||||
throw new Error(`Child element is neither a category or a script.
|
||||
Parent: ${parent.category}, element: ${categoryOrScript}`);
|
||||
Parent: ${parent.category}, element: ${JSON.stringify(categoryOrScript)}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,6 +41,9 @@ function mayBeUniqueLine(codeLine: string): boolean {
|
||||
if (trimmed === ')' || trimmed === '(') { // "(" and ")" are used often in batch code
|
||||
return false;
|
||||
}
|
||||
if (codeLine.startsWith(':: ') || codeLine.startsWith('REM ')) { // Is comment?
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
import fileSaver from 'file-saver';
|
||||
|
||||
export class SaveFileDialog {
|
||||
public static saveText(text: string, fileName: string): void {
|
||||
this.saveBlob(text, 'text/plain;charset=utf-8', fileName);
|
||||
export enum FileType {
|
||||
BatchFile,
|
||||
}
|
||||
export class SaveFileDialog {
|
||||
public static saveFile(text: string, fileName: string, type: FileType): void {
|
||||
const mimeType = this.mimeTypes.get(type);
|
||||
this.saveBlob(text, mimeType, fileName);
|
||||
}
|
||||
private static readonly mimeTypes = new Map<FileType, string>([
|
||||
// Some browsers (including firefox + IE) require right mime type
|
||||
// otherwise they ignore extension and save the file as text.
|
||||
[ FileType.BatchFile, 'application/bat' ], // https://en.wikipedia.org/wiki/Batch_file
|
||||
]);
|
||||
|
||||
private static saveBlob(file: BlobPart, fileType: string, fileName: string): void {
|
||||
try {
|
||||
|
||||
@@ -20,6 +20,7 @@ declare module 'liquor-tree' {
|
||||
// https://github.com/amsik/liquor-tree/blob/master/src/lib/Node.js
|
||||
export interface ILiquorTreeNodeState {
|
||||
checked: boolean;
|
||||
indeterminate: boolean;
|
||||
}
|
||||
|
||||
export interface ILiquorTreeNode {
|
||||
|
||||
@@ -5,9 +5,10 @@ export class LiquorTreeOptions implements ILiquorTreeOptions {
|
||||
public readonly checkbox = true;
|
||||
public readonly checkOnSelect = true;
|
||||
/* For checkbox mode only. Children will have the same checked state as their parent.
|
||||
⚠️ Setting this false, does not update indeterminate state of nodes.
|
||||
This is false as it's handled manually to be able to batch select for performance + highlighting */
|
||||
public readonly autoCheckChildren = false;
|
||||
public readonly parentSelect = false;
|
||||
public readonly parentSelect = true;
|
||||
public readonly keyboardNavigation = true;
|
||||
public readonly filter = { // Wrap this in an arrow function as setting filter directly does not work JS APIs
|
||||
emptyText: this.liquorTreeFilter.emptyText,
|
||||
|
||||
@@ -1,14 +1,37 @@
|
||||
import { ILiquorTreeNode } from 'liquor-tree';
|
||||
import { ILiquorTreeNode, ILiquorTreeNodeState } from 'liquor-tree';
|
||||
import { NodeType } from './../../Node/INode';
|
||||
|
||||
export function getNewCheckedState(
|
||||
oldNode: ILiquorTreeNode,
|
||||
export function getNewState(
|
||||
node: ILiquorTreeNode,
|
||||
selectedNodeIds: ReadonlyArray<string>): ILiquorTreeNodeState {
|
||||
const checked = getNewCheckedState(node, selectedNodeIds);
|
||||
const indeterminate = !checked && getNewIndeterminateState(node, selectedNodeIds);
|
||||
return {
|
||||
checked, indeterminate,
|
||||
};
|
||||
}
|
||||
|
||||
function getNewIndeterminateState(
|
||||
node: ILiquorTreeNode,
|
||||
selectedNodeIds: ReadonlyArray<string>): boolean {
|
||||
switch (oldNode.data.type) {
|
||||
switch (node.data.type) {
|
||||
case NodeType.Script:
|
||||
return selectedNodeIds.some((id) => id === oldNode.id);
|
||||
return false;
|
||||
case NodeType.Category:
|
||||
return parseAllSubScriptIds(oldNode).every((id) => selectedNodeIds.includes(id));
|
||||
return parseAllSubScriptIds(node).some((id) => selectedNodeIds.includes(id));
|
||||
default:
|
||||
throw new Error('Unknown node type');
|
||||
}
|
||||
}
|
||||
|
||||
function getNewCheckedState(
|
||||
node: ILiquorTreeNode,
|
||||
selectedNodeIds: ReadonlyArray<string>): boolean {
|
||||
switch (node.data.type) {
|
||||
case NodeType.Script:
|
||||
return selectedNodeIds.some((id) => id === node.id);
|
||||
case NodeType.Category:
|
||||
return parseAllSubScriptIds(node).every((id) => selectedNodeIds.includes(id));
|
||||
default:
|
||||
throw new Error('Unknown node type');
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ export function toNewLiquorTreeNode(node: INode): ILiquorTreeNewNode {
|
||||
text: node.text,
|
||||
state: {
|
||||
checked: false,
|
||||
indeterminate: false,
|
||||
},
|
||||
children: convertChildren(node.children, toNewLiquorTreeNode),
|
||||
data: {
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
import { StatefulVue } from '@/presentation/StatefulVue';
|
||||
import { INode } from './INode';
|
||||
import { SelectedScript } from '@/application/State/Selection/SelectedScript';
|
||||
import { IApplicationState } from '@/application/State/IApplicationState';
|
||||
import { getCategoryId, getScriptId } from './../../ScriptNodeParser';
|
||||
import { getReverter } from './Reverter/ReverterFactory';
|
||||
|
||||
@Component
|
||||
|
||||
@@ -18,14 +18,15 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
|
||||
import LiquorTree, { ILiquorTreeNewNode, ILiquorTreeExistingNode, ILiquorTree } from 'liquor-tree';
|
||||
import LiquorTree from 'liquor-tree';
|
||||
import Node from './Node/Node.vue';
|
||||
import { INode } from './Node/INode';
|
||||
import { convertExistingToNode, toNewLiquorTreeNode } from './LiquorTree/NodeWrapper/NodeTranslator';
|
||||
import { INodeSelectedEvent } from './/INodeSelectedEvent';
|
||||
import { getNewCheckedState } from './LiquorTree/NodeWrapper/NodeStateUpdater';
|
||||
import { getNewState } from './LiquorTree/NodeWrapper/NodeStateUpdater';
|
||||
import { LiquorTreeOptions } from './LiquorTree/LiquorTreeOptions';
|
||||
import { FilterPredicate, NodePredicateFilter } from './LiquorTree/NodeWrapper/NodePredicateFilter';
|
||||
import { ILiquorTreeNewNode, ILiquorTreeExistingNode, ILiquorTree, ILiquorTreeNode, ILiquorTreeNodeState } from 'liquor-tree';
|
||||
|
||||
/** Wrapper for Liquor Tree, reveals only abstracted INode for communication */
|
||||
@Component({
|
||||
@@ -49,7 +50,7 @@
|
||||
const initialNodes = this.initialNodes.map((node) => toNewLiquorTreeNode(node));
|
||||
if (this.selectedNodeIds) {
|
||||
recurseDown(initialNodes,
|
||||
(node) => node.state.checked = getNewCheckedState(node, this.selectedNodeIds));
|
||||
(node) => node.state = updateState(node.state, node, this.selectedNodeIds));
|
||||
}
|
||||
this.initialLiquourTreeNodes = initialNodes;
|
||||
} else {
|
||||
@@ -82,11 +83,11 @@
|
||||
@Watch('selectedNodeIds')
|
||||
public setSelectedStatusAsync(selectedNodeIds: ReadonlyArray<string>) {
|
||||
if (!selectedNodeIds) {
|
||||
throw new Error('Selected nodes are undefined');
|
||||
throw new Error('SelectedrecurseDown nodes are undefined');
|
||||
}
|
||||
this.getLiquorTreeApi().recurseDown((node) => {
|
||||
node.states.checked = getNewCheckedState(node, selectedNodeIds);
|
||||
});
|
||||
this.getLiquorTreeApi().recurseDown(
|
||||
(node) => node.states = updateState(node.states, node, selectedNodeIds),
|
||||
);
|
||||
}
|
||||
|
||||
private getLiquorTreeApi(): ILiquorTree {
|
||||
@@ -97,6 +98,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
function updateState(
|
||||
old: ILiquorTreeNodeState,
|
||||
node: ILiquorTreeNode,
|
||||
selectedNodeIds: ReadonlyArray<string>): ILiquorTreeNodeState {
|
||||
return {...old, ...getNewState(node, selectedNodeIds)};
|
||||
}
|
||||
|
||||
function recurseDown(
|
||||
nodes: ReadonlyArray<ILiquorTreeNewNode>,
|
||||
handler: (node: ILiquorTreeNewNode) => void) {
|
||||
|
||||
@@ -18,7 +18,8 @@ const NothingChosenCode =
|
||||
.appendCommentLine('-- 🤔 How to use')
|
||||
.appendCommentLine(' 📙 Start by exploring different categories and choosing different tweaks.')
|
||||
.appendCommentLine(' 📙 You can select "Recommended" on the top to select "safer" tweaks. Always double check!')
|
||||
.appendCommentLine(' 📙 After you choose any tweak, you can download & copy to execute your script.')
|
||||
.appendCommentLine(' 📙 After you choose any tweak, you can download or copy to execute your script.')
|
||||
.appendCommentLine(' 📙 Come back regularly to apply latest version for stronger privacy and security.')
|
||||
.appendLine()
|
||||
.appendCommentLine('-- 🧐 Why privacy.sexy')
|
||||
.appendCommentLine(' ✔️ Rich tweak pool to harden security & privacy of the OS and other softwares on it.')
|
||||
@@ -114,7 +115,7 @@ function initializeEditor(theme: string, editorId: string): ace.Ace.Editor {
|
||||
min-height: 200px;
|
||||
&__highlight {
|
||||
background-color:$accent;
|
||||
opacity: 20%;
|
||||
opacity: 0.2; // having procent fails in production (minified) build
|
||||
position:absolute;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<script lang="ts">
|
||||
import { Component } from 'vue-property-decorator';
|
||||
import { StatefulVue } from './StatefulVue';
|
||||
import { SaveFileDialog } from './../infrastructure/SaveFileDialog';
|
||||
import { SaveFileDialog, FileType } from './../infrastructure/SaveFileDialog';
|
||||
import { Clipboard } from './../infrastructure/Clipboard';
|
||||
import IconButton from './IconButton.vue';
|
||||
|
||||
@@ -43,7 +43,7 @@ export default class TheCodeButtons extends StatefulVue {
|
||||
|
||||
public async saveCodeAsync() {
|
||||
const state = await this.getCurrentStateAsync();
|
||||
SaveFileDialog.saveText(state.code.current, 'privacy-script.bat');
|
||||
SaveFileDialog.saveFile(state.code.current, 'privacy-script.bat', FileType.BatchFile);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -2,37 +2,27 @@
|
||||
@import "@/presentation/styles/colors.scss";
|
||||
|
||||
.tree {
|
||||
background-color: $slate;
|
||||
}
|
||||
|
||||
.tree-node > .tree-content > .tree-anchor > span {
|
||||
color: $white !important;
|
||||
background: $slate;
|
||||
&-node {
|
||||
white-space: normal !important;
|
||||
> .tree-content {
|
||||
> .tree-anchor > span {
|
||||
color: $white;
|
||||
text-transform: uppercase;
|
||||
color: $light-gray;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.tree-node {
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
.tree-arrow.has-child {
|
||||
&.rtl:after, &:after {
|
||||
border-color: $white !important;
|
||||
}
|
||||
}
|
||||
|
||||
.tree-node.selected > .tree-content {
|
||||
> .tree-anchor > span {
|
||||
font-weight: bolder;
|
||||
}
|
||||
}
|
||||
|
||||
.tree-content:hover {
|
||||
&:hover {
|
||||
background: $dark-gray !important;
|
||||
}
|
||||
|
||||
.tree-checkbox {
|
||||
}
|
||||
&.selected { // When using keyboard navigation it higlights current item and its child items
|
||||
background: $gray;
|
||||
.tree-text {
|
||||
color: $black !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-checkbox {
|
||||
&.checked {
|
||||
background: $accent !important;
|
||||
}
|
||||
@@ -41,3 +31,11 @@
|
||||
}
|
||||
background: $dark-slate !important;
|
||||
}
|
||||
&-arrow {
|
||||
&.has-child {
|
||||
&.rtl:after, &:after {
|
||||
border-color: $white !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,31 +2,32 @@ import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { ILiquorTreeNode } from 'liquor-tree';
|
||||
import { NodeType } from '@/presentation/Scripts/ScriptsTree/SelectableTree/Node/INode';
|
||||
import { getNewCheckedState } from '@/presentation/Scripts/ScriptsTree/SelectableTree/LiquorTree/NodeWrapper/NodeStateUpdater';
|
||||
import { getNewState } from '@/presentation/Scripts/ScriptsTree/SelectableTree/LiquorTree/NodeWrapper/NodeStateUpdater';
|
||||
|
||||
describe('getNewCheckedState', () => {
|
||||
describe('getNewState', () => {
|
||||
describe('checked', () => {
|
||||
describe('script node', () => {
|
||||
it('state is true when selected', () => {
|
||||
it('true when selected', () => {
|
||||
// arrange
|
||||
const node = getScriptNode();
|
||||
const selectedScriptNodeIds = [ 'a', 'b', node.id, 'c' ];
|
||||
// act
|
||||
const actual = getNewCheckedState(node, selectedScriptNodeIds);
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(actual).to.equal(true);
|
||||
expect(state.checked).to.equal(true);
|
||||
});
|
||||
it('state is false when unselected', () => {
|
||||
it('false when unselected', () => {
|
||||
// arrange
|
||||
const node = getScriptNode();
|
||||
const selectedScriptNodeIds = [ 'a', 'b', 'c' ];
|
||||
// act
|
||||
const actual = getNewCheckedState(node, selectedScriptNodeIds);
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(actual).to.equal(false);
|
||||
expect(state.checked).to.equal(false);
|
||||
});
|
||||
});
|
||||
describe('category node', () => {
|
||||
it('state is true when every child selected', () => {
|
||||
it('true when every child selected', () => {
|
||||
// arrange
|
||||
const node = {
|
||||
id: '1',
|
||||
@@ -44,11 +45,11 @@ describe('getNewCheckedState', () => {
|
||||
};
|
||||
const selectedScriptNodeIds = [ 'a', 'b', 'c' ];
|
||||
// act
|
||||
const actual = getNewCheckedState(node, selectedScriptNodeIds);
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(actual).to.equal(true);
|
||||
expect(state.checked).to.equal(true);
|
||||
});
|
||||
it('state is false when none of the children is selected', () => {
|
||||
it('false when none of the children is selected', () => {
|
||||
// arrange
|
||||
const node = {
|
||||
id: '1',
|
||||
@@ -66,11 +67,11 @@ describe('getNewCheckedState', () => {
|
||||
};
|
||||
const selectedScriptNodeIds = [ 'none', 'of', 'them', 'are', 'selected' ];
|
||||
// act
|
||||
const actual = getNewCheckedState(node, selectedScriptNodeIds);
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(actual).to.equal(false);
|
||||
expect(state.checked).to.equal(false);
|
||||
});
|
||||
it('state is false when some of the children is selected', () => {
|
||||
it('false when some of the children is selected', () => {
|
||||
// arrange
|
||||
const node = {
|
||||
id: '1',
|
||||
@@ -90,9 +91,100 @@ describe('getNewCheckedState', () => {
|
||||
};
|
||||
const selectedScriptNodeIds = [ 'a', 'c', 'unrelated' ];
|
||||
// act
|
||||
const actual = getNewCheckedState(node, selectedScriptNodeIds);
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(actual).to.equal(false);
|
||||
expect(state.checked).to.equal(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('indeterminate', () => {
|
||||
describe('script node', () => {
|
||||
it('false when selected', () => {
|
||||
// arrange
|
||||
const node = getScriptNode();
|
||||
const selectedScriptNodeIds = [ 'a', 'b', node.id, 'c' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.indeterminate).to.equal(false);
|
||||
});
|
||||
it('false when not selected', () => {
|
||||
// arrange
|
||||
const node = getScriptNode();
|
||||
const selectedScriptNodeIds = [ 'a', 'b', 'c' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.indeterminate).to.equal(false);
|
||||
});
|
||||
});
|
||||
describe('category node', () => {
|
||||
it('false when all children are selected', () => {
|
||||
// arrange
|
||||
const node = {
|
||||
id: '1',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [
|
||||
{ id: '2',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('a'), getScriptNode('b') ],
|
||||
},
|
||||
{ id: '3',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('c') ],
|
||||
},
|
||||
],
|
||||
};
|
||||
const selectedScriptNodeIds = [ 'a', 'b', 'c' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.indeterminate).to.equal(false);
|
||||
});
|
||||
it('true when all some are selected', () => {
|
||||
// arrange
|
||||
const node = {
|
||||
id: '1',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [
|
||||
{ id: '2',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('a'), getScriptNode('b') ],
|
||||
},
|
||||
{ id: '3',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('c') ],
|
||||
},
|
||||
],
|
||||
};
|
||||
const selectedScriptNodeIds = [ 'a' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.indeterminate).to.equal(true);
|
||||
});
|
||||
it('false when no children are selected', () => {
|
||||
// arrange
|
||||
const node = {
|
||||
id: '1',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [
|
||||
{ id: '2',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('a'), getScriptNode('b') ],
|
||||
},
|
||||
{ id: '3',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('c') ],
|
||||
},
|
||||
],
|
||||
};
|
||||
const selectedScriptNodeIds = [ 'none', 'of', 'them', 'are', 'selected' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.indeterminate).to.equal(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -108,6 +108,7 @@ function getNewNode(): ILiquorTreeNewNode {
|
||||
const base = getNode();
|
||||
const commonState = {
|
||||
checked: false,
|
||||
indeterminate: false,
|
||||
};
|
||||
return {
|
||||
id: base.id,
|
||||
|
||||
@@ -68,7 +68,7 @@ describe('ScriptReverter', () => {
|
||||
selection: [ new SelectedScript(script, true)], revert: true, expectRevert: true,
|
||||
},
|
||||
{
|
||||
name: 'keeps revert state deselected when already selected wtih non revert state',
|
||||
name: 'keeps revert state deselected when already selected with non revert state',
|
||||
selection: [ new SelectedScript(script, false)], revert: false, expectRevert: false,
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user