Skip to content

Commit

Permalink
feat: Add column-related partial methods to Widgets and Columns.
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-coster committed Jul 2, 2021
1 parent 956dcd7 commit 42001de
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 16 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,15 @@ As environment variables:
- ✔ Find widgets by name
- ✔ Create a widget
- ✔ Delete a widget
- ✔ List columns
- ✔ Find columns
- ✔ Create columns
- ✔ Delete columns
- List cards
- Search cards by title
- Create a card
- Delete a card
- Add some sort of warning when a user tries to delete the LAST column on a Widget, since that's guaranteed to throw a 403.

## Usage

Expand Down
7 changes: 7 additions & 0 deletions src/lib/entities/BravoColumn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,11 @@ export class BravoColumn extends BravoEntity<DataFavroColumn> {
equals(column: BravoColumn) {
return this.hasSameConstructor(column) && this.columnId === column.columnId;
}

async delete() {
if (!this.deleted) {
await this._client.deleteColumn(this.widgetCommonId, this.columnId);
}
this._deleted = true;
}
}
29 changes: 17 additions & 12 deletions src/lib/entities/BravoWidget.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import { DataFavroWidget } from '$types/FavroWidgetTypes.js';
import { BravoEntity } from '$lib/BravoEntity.js';
import { selectRandom } from '$lib/utility.js';
import { BravoColumn } from './BravoColumn.js';
import { ArrayMatchFunction } from '$/types/Utility.js';
import { selectRandom, stringsMatch } from '$lib/utility.js';
import type { BravoColumn } from './BravoColumn.js';
import type { ArrayMatchFunction } from '$/types/Utility.js';

export type OptionWidgetColor = typeof BravoWidget['colors'][number];

export class BravoWidget extends BravoEntity<DataFavroWidget> {
/** TODO: Move to cache! */
private _columns?: BravoColumn[];

get widgetCommonId() {
return this._data.widgetCommonId;
}
Expand All @@ -29,19 +26,27 @@ export class BravoWidget extends BravoEntity<DataFavroWidget> {
return this._data.editRole;
}

async createColumn(name: string, options?: { position?: number }) {
return await this._client.createColumn(this.widgetCommonId, name, options);
}

async listColumns() {
if (!this._columns) {
this._columns = await this._client.listColumns(this.widgetCommonId);
}
return [...this._columns];
return await this._client.listColumns(this.widgetCommonId);
}

async findColumn(matchFunction: ArrayMatchFunction<BravoColumn>) {
return await this._client.findColumn(this.widgetCommonId, matchFunction);
}

async deleteColumnById(columnId: string) {
return await this.findColumn((col) => col.columnId == columnId);
async findColumnByName(name: string, options?: { ignoreCase?: boolean }) {
const column = await this.findColumn((col) => {
return stringsMatch(col.name, name, options);
});
return column;
}

async deleteColumn(columnId: string) {
return await this._client.deleteColumn(this.widgetCommonId, columnId);
}

async delete() {
Expand Down
53 changes: 49 additions & 4 deletions src/test/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { BravoClient } from '$lib/BravoClient.js';
import { expect } from 'chai';
import fs from 'fs-extra';
import dotenv from 'dotenv';
import { BravoCollection } from '$entities/BravoCollection.js';
import { BravoWidget } from '$entities/BravoWidget.js';
import type { BravoCollection } from '$entities/BravoCollection.js';
import type { BravoWidget } from '$entities/BravoWidget.js';
import type { BravoColumn } from '$/lib/entities/BravoColumn.js';

/**
* @note A root .env file must be populated with the required
Expand All @@ -12,9 +13,12 @@ import { BravoWidget } from '$entities/BravoWidget.js';
dotenv.config();
const organizationName = process.env.FAVRO_ORGANIZATION_NAME!;
const myUserEmail = process.env.FAVRO_USER_EMAIL!;

const testCollectionName =
process.env.BRAVO_TEST_COLLECTION_NAME || '___BRAVO_TEST_COLLECTION';
const testWidgetName = '___BRAVO_TEST_WIDGET';
const testColumnName = '___BRAVO_TEST_COLUMN';

const sandboxRoot = './sandbox';
const samplesRoot = './samples';

Expand Down Expand Up @@ -82,15 +86,35 @@ describe('BravoClient', function () {
const client = new BravoClient();
let testWidget: BravoWidget;
let testCollection: BravoCollection;
let testColumn: BravoColumn;

// !!!
// Tests are in a specific order to ensure that dependencies
// happen first, and cleanup happens last. This is tricky to
// do with good test design -- to minimize API calls (the limits
// are low) the tests become dependent on the outcomes of prior tests.

before(function () {
before(async function () {
await client.setOrganizationIdByName(organizationName);

resetSandbox();
// Clean up any leftover remote testing content
// (Since names aren't required to be unique, there could be quite a mess!)
// NOTE:
while (true) {
const collection = await client.findCollectionByName(testCollectionName);
if (!collection) {
break;
}
for (const widget of await collection.listWidgets()) {
if (!widget) {
break;
}
// TODO: delete cards
await widget.delete();
}
await collection.delete();
}
});

it('can list organizations', async function () {
Expand All @@ -112,7 +136,6 @@ describe('BravoClient', function () {
});

it('can find all users for an organization, including self', async function () {
await client.setOrganizationIdByName(organizationName);
const partialUsers = await client.listOrganizationMembers();
expect(partialUsers.length, 'has partial users').to.be.greaterThan(0);
const fullUsers = await client.listFullUsers();
Expand Down Expand Up @@ -165,8 +188,30 @@ describe('BravoClient', function () {
).to.be.true;
});

it('can create a column', async function () {
testColumn = await testWidget.createColumn(testColumnName);
expect(testColumn).to.exist;
});
it('can find a created column', async function () {
const foundColumn = await testWidget.findColumnByName(testColumnName);
assertBravoTestClaim(foundColumn);
expect(foundColumn!.equals(testColumn)).to.be.true;
});

// TODO: NEXT HEIRARCHY LEVEL

it('can delete a created column', async function () {
// Can't delete the last column, so we need to make another to delete!
const deletableName = 'DELETE ME';
const deletableColumn = await testWidget.createColumn(deletableName);
assertBravoTestClaim(deletableColumn);
await deletableColumn.delete();
expect(
await testWidget.findColumnByName(deletableName),
'Should not find deleted column',
).to.be.undefined;
});

it('can delete a created widget', async function () {
await testWidget.delete();
await expectAsyncError(
Expand Down

0 comments on commit 42001de

Please sign in to comment.