Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion Invoro.WebApp/Invoro/invoro/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ export default class App extends React.Component {
state = { userIdentifier: "AUserIdentity" };

render() {
return <Invoro userIdentifier={this.state.userIdentifier} />;
return <Invoro userIdentifier={this.state.userIdentifier} fetchApi={fetch.bind(window)} />;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import React from 'react';
import FeaturesTableComponent from './FeaturesTable.component';
import Feature from '../../dataModel/Feature';
import Status from '../../dataModel/Status';
import { shallow } from 'enzyme';
import { shallow, mount, ReactWrapper } from 'enzyme';
import FeatureCategory from '../../dataModel/FeaturesCategory';
import { TableCell } from '@material-ui/core';

it('render one feature with the correct name', () => {

Expand All @@ -17,12 +18,14 @@ it('render one feature with the correct name', () => {

// Action
let result =
shallow(<FeaturesTableComponent
mount(<FeaturesTableComponent
featuresCategories={featuresCategories}
featuresVoted={featuresVoted}
featureVoteHandle={voteHandle}
featureUnvoteHandle={unvoteHandle} />)
.find(".feature-row").shallow()
.find(`#${features[0].id}`)
.find(TableCell)
.first()
.find("span");

// Assert
Expand All @@ -41,12 +44,14 @@ it('render feature with the correct link as linkable', () => {

// Action
let result =
shallow(<FeaturesTableComponent
mount(<FeaturesTableComponent
featuresCategories={featuresCategories}
featuresVoted={featuresVoted}
featureVoteHandle={voteHandle}
featureUnvoteHandle={unvoteHandle} />)
.find(".feature-row").shallow()
.find(`#${features[0].id}`)
.find(TableCell)
.first()
.find('a');

// Assert
Expand All @@ -71,8 +76,222 @@ it('render multiple features', () => {
featuresVoted={featuresVoted}
featureVoteHandle={voteHandle}
featureUnvoteHandle={unvoteHandle} />)
.find(".feature-row");
.find(".featureRow")

// Assert
expect(tableRows).toHaveLength(features.length);
});
});

describe("Order features", () => {
let featuresVoted: Set<string> = new Set<string>();
let voteHandle = (id: string) => { };
let unvoteHandle = (id: string) => { };

describe('with default comparer', () => {
let expectedIdOrder: string[] = ["ID1", "ID2", "ID3"];

it('already ordered - render alphabetically,', () => {

// Prepare
let features: Feature[] = [
new Feature("ID1", "AFirst", Status.NotPlanned, "Link", new Date(), new Date()),
new Feature("ID2", "BSecond", Status.NotPlanned, "Link", new Date(), new Date()),
new Feature("ID3", "CThird", Status.NotPlanned, "Link", new Date(), new Date())];
let featuresCategories: FeatureCategory[] = [new FeatureCategory("MyCategory", features)];

// Action
let tableRows =
mount(<FeaturesTableComponent
featuresCategories={featuresCategories}
featuresVoted={featuresVoted}
featureVoteHandle={voteHandle}
featureUnvoteHandle={unvoteHandle} />).
find("TableRow.featureRow");

expectIdOrder(tableRows, expectedIdOrder);
});

it('scrambled - render alphabetically,', () => {

// Prepare
let features: Feature[] = [
new Feature("ID2", "BSecond", Status.NotPlanned, "Link", new Date(), new Date()),
new Feature("ID1", "AFirst", Status.NotPlanned, "Link", new Date(), new Date()),
new Feature("ID3", "CThird", Status.NotPlanned, "Link", new Date(), new Date())];
let featuresCategories: FeatureCategory[] = [new FeatureCategory("MyCategory", features)];

// Action
let tableRows =
mount(<FeaturesTableComponent
featuresCategories={featuresCategories}
featuresVoted={featuresVoted}
featureVoteHandle={voteHandle}
featureUnvoteHandle={unvoteHandle} />).
find("TableRow.featureRow");

expectIdOrder(tableRows, expectedIdOrder);
});
})
describe('with costume comparer', () => {
let costumeFeaturesComparerReverse = (a: Feature, b: Feature): number => { return a.name.localeCompare(b.name) * (-1)};
let expectedIdOrder: string[] = ["ID1", "ID2", "ID3"];
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The order shoul be the opposite, since you use the custome (reverse) comparer


it('already ordered - render alphabetically,', () => {

// Prepare
let features: Feature[] = [
new Feature("ID3", "AThird", Status.NotPlanned, "Link", new Date(), new Date()),
new Feature("ID2", "BSecond", Status.NotPlanned, "Link", new Date(), new Date()),
new Feature("ID1", "CFirst", Status.NotPlanned, "Link", new Date(), new Date())];
let featuresCategories: FeatureCategory[] = [new FeatureCategory("MyCategory", features)];

// Action
let tableRows =
mount(<FeaturesTableComponent
featuresCategories={featuresCategories}
featuresVoted={featuresVoted}
featureVoteHandle={voteHandle}
featureUnvoteHandle={unvoteHandle}
featuresCompareFn = {costumeFeaturesComparerReverse} />).
find("TableRow.featureRow");

expectIdOrder(tableRows, expectedIdOrder);
});

it('scrambled - render alphabetically,', () => {

// Prepare
let features: Feature[] = [
new Feature("ID3", "AThird", Status.NotPlanned, "Link", new Date(), new Date()),
new Feature("ID2", "BSecond", Status.NotPlanned, "Link", new Date(), new Date()),
new Feature("ID1", "CFirst", Status.NotPlanned, "Link", new Date(), new Date())];
let featuresCategories: FeatureCategory[] = [new FeatureCategory("MyCategory", features)];

// Action
let tableRows =
mount(<FeaturesTableComponent
featuresCategories={featuresCategories}
featuresVoted={featuresVoted}
featureVoteHandle={voteHandle}
featureUnvoteHandle={unvoteHandle}
featuresCompareFn = {costumeFeaturesComparerReverse} />).
find("TableRow.featureRow");

expectIdOrder(tableRows, expectedIdOrder);
});
})

});

describe("Order categories", () => {

let featuresVoted: Set<string> = new Set<string>();
let voteHandle = (id: string) => { };
let unvoteHandle = (id: string) => { };

let featuresOfCategoryOne: Feature[] = [
new Feature("ID1", "Name", Status.NotPlanned, "Link", new Date(), new Date())];
let featuresOfCategoryTwo: Feature[] = [
new Feature("ID2", "Name", Status.NotPlanned, "Link", new Date(), new Date())];
let featuresOfCategoryThree: Feature[] = [
new Feature("ID3", "Name", Status.NotPlanned, "Link", new Date(), new Date())];

describe('with default comparer', () => {
let expectedIdOrder: string[] = ["A - FirstCategory", "B - SecondCategory", "C - ThirdCategory"];

it('already ordered - render alphabetically,', () => {
// Prepare
let featuresCategories: FeatureCategory[] = [
new FeatureCategory("A - FirstCategory", featuresOfCategoryOne),
new FeatureCategory("B - SecondCategory", featuresOfCategoryTwo),
new FeatureCategory("C - ThirdCategory", featuresOfCategoryThree)
];

// Action
let tableRows =
mount(<FeaturesTableComponent
featuresCategories={featuresCategories}
featuresVoted={featuresVoted}
featureVoteHandle={voteHandle}
featureUnvoteHandle={unvoteHandle} />).
find("TableRow.categoryRow");

expectIdOrder(tableRows, expectedIdOrder);
});

it('scrambled - render alphabetically,', () => {
// Prepare
let featuresCategories: FeatureCategory[] = [
new FeatureCategory("B - SecondCategory", featuresOfCategoryTwo),
new FeatureCategory("A - FirstCategory", featuresOfCategoryOne),
new FeatureCategory("C - ThirdCategory", featuresOfCategoryThree)
];

// Action
let tableRows =
mount(<FeaturesTableComponent
featuresCategories={featuresCategories}
featuresVoted={featuresVoted}
featureVoteHandle={voteHandle}
featureUnvoteHandle={unvoteHandle} />).
find("TableRow.categoryRow");

expectIdOrder(tableRows, expectedIdOrder);
});
})
describe('with costume comparer', () => {
let costumeCategoriesComparerReverse = (a: FeatureCategory, b: FeatureCategory): number =>
{ return a.name.localeCompare(b.name) * (-1)};
let expectedIdOrder: string[] = ["C - FirstCategory", "B - SecondCategory", "A - ThirdCategory"];

it('already ordered - render alphabetically,', () => {
// Prepare
let featuresCategories: FeatureCategory[] = [
new FeatureCategory("C - FirstCategory", featuresOfCategoryThree),
new FeatureCategory("B - SecondCategory", featuresOfCategoryTwo),
new FeatureCategory("A - ThirdCategory", featuresOfCategoryOne)
];

// Action
let tableRows =
mount(<FeaturesTableComponent
featuresCategories={featuresCategories}
featuresVoted={featuresVoted}
featureVoteHandle={voteHandle}
featureUnvoteHandle={unvoteHandle}
featuresCategoryCompareFn = {costumeCategoriesComparerReverse} />).
find("TableRow.categoryRow");

expectIdOrder(tableRows, expectedIdOrder);
});

it('scrambled - render alphabetically,', () => {

// Prepare
let featuresCategories: FeatureCategory[] = [
new FeatureCategory("B - SecondCategory", featuresOfCategoryTwo),
new FeatureCategory("A - ThirdCategory", featuresOfCategoryOne),
new FeatureCategory("C - FirstCategory", featuresOfCategoryThree)
];

// Action
let tableRows =
mount(<FeaturesTableComponent
featuresCategories={featuresCategories}
featuresVoted={featuresVoted}
featureVoteHandle={voteHandle}
featureUnvoteHandle={unvoteHandle}
featuresCategoryCompareFn = {costumeCategoriesComparerReverse} />).
find("TableRow.categoryRow");

expectIdOrder(tableRows, expectedIdOrder);
});
})

});

function expectIdOrder(tableRows: ReactWrapper, expectedNameOrder: string[]) {
for (let i: number = 0; i < tableRows.length; i++) {
expect(tableRows.at(i).prop('id')).toEqual(expectedNameOrder[i]);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ReactElement } from "react";
import React from "react";
import { Paper, Table, TableHead, TableRow, TableCell, TableBody } from "@material-ui/core";
import StatusComponent from "../Status.component";
import VoteComponent from "../Vote.component";
Expand All @@ -8,6 +8,8 @@ import FeaturesCategory from "../../dataModel/FeaturesCategory";

interface FeaturesTableProps {
featuresCategories: FeaturesCategory[];
featuresCategoryCompareFn?: (a: FeaturesCategory, b: FeaturesCategory) => number;
featuresCompareFn?: (a: Feature, b: Feature) => number;
featuresVoted: Set<string>;
featureVoteHandle(featureId: string): void;
featureUnvoteHandle(featureId: string): void;
Expand All @@ -22,7 +24,7 @@ export default class FeaturesTableComponent extends React.Component<FeaturesTabl
{this.CreateTableHeaderRow()}
</TableHead>
<TableBody>
{this.props.featuresCategories.map(category =>
{this.props.featuresCategories.sort(this.getFeaturesCategoryComparerFunc()).map(category =>
[this.CreateCategoryRow(category),
this.CreateFeatureRow(category.features)])}
</TableBody>
Expand All @@ -43,16 +45,16 @@ export default class FeaturesTableComponent extends React.Component<FeaturesTabl
}

private CreateCategoryRow(category: FeaturesCategory): JSX.Element {
return <TableRow key={category.name}>
return <TableRow className="categoryRow" id={category.name} key={category.name}>
<TableCell colSpan={7} style={{ fontWeight: 'bold' }}>
{category.name}
</TableCell>
</TableRow>;
}

private CreateFeatureRow(features: Feature[]): JSX.Element[] {
return features.map(feature =>
<TableRow key={feature.id} className="feature-row">
return features.sort(this.getFeaturesComparerFunc()).map(feature=>
<TableRow className="featureRow" id={feature.id} key={feature.id} >
<TableCell style={{ paddingLeft: '2%' }}>
{this.getLinkableFeatureTitle(feature)}
</TableCell>
Expand All @@ -62,7 +64,7 @@ export default class FeaturesTableComponent extends React.Component<FeaturesTabl
{this.getTableCell(Status.ReadySoon, feature)}
{this.getTableCell(Status.Released, feature)}
{this.getVoteCell(feature)}
</TableRow >);
</TableRow >);
}

private getLinkableFeatureTitle(feature: Feature): JSX.Element {
Expand Down Expand Up @@ -98,4 +100,12 @@ export default class FeaturesTableComponent extends React.Component<FeaturesTabl
return <TableCell align="left"></TableCell>
}
}

private getFeaturesCategoryComparerFunc(): (a: FeaturesCategory, b: FeaturesCategory) => number {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return this.props.featuresCategoryCompareFn ? this.props.featuresCategoryCompareFn : FeaturesCategory.Compare;
}

private getFeaturesComparerFunc(): (a: Feature, b: Feature) => number {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return this.props.featuresCompareFn ? this.props.featuresCompareFn : Feature.Compare;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import Invoro from './Invoro.component';

it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<Invoro userIdentifier="FakeUserIdentity" />, div);
const fetchMock = (input: RequestInfo, init?: RequestInit) => new Promise<Response>(() => null);
ReactDOM.render(<Invoro userIdentifier={"FakeUserIdentity"} fetchApi={fetchMock} />, div);
ReactDOM.unmountComponentAtNode(div);
});
});

// Check all APIs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import FeaturesCategory from '../../dataModel/FeaturesCategory'
import Feature from '../../dataModel/Feature';
import FeaturesApi from '../../services/FeaturesApi.service';
import FeaturesTableComponent from '../FeaturesTable/FeaturesTable.component'

Expand All @@ -10,14 +11,17 @@ interface InvoroState {

interface InvoroProps {
userIdentifier: string;
fetchApi: (input: RequestInfo, init?: RequestInit) => Promise<Response>;
featuresCategoryCompareFn?: (a: FeaturesCategory, b: FeaturesCategory) => number;
featuresCompareFn?: (a: Feature, b: Feature) => number;
}

export default class Invoro extends React.Component<InvoroProps> {
private featuresApi: FeaturesApi;

constructor(props: any) {
super(props);
this.featuresApi = new FeaturesApi(props.userIdentifier, fetch.bind(window));
this.featuresApi = new FeaturesApi(props.userIdentifier, props.fetchApi);
}

state: InvoroState = {
Expand All @@ -40,7 +44,9 @@ export default class Invoro extends React.Component<InvoroProps> {
featuresCategories={this.state.featuresCategories}
featuresVoted={this.state.featuresVoted}
featureVoteHandle={(featureId) => this.voteToFeature(featureId)}
featureUnvoteHandle={(featureId) => this.unvoteToFeature(featureId)} />;
featureUnvoteHandle={(featureId) => this.unvoteToFeature(featureId)}
featuresCategoryCompareFn={this.props.featuresCategoryCompareFn}
featuresCompareFn={this.props.featuresCompareFn} />;
}
else {
return <div>Loading..</div>;
Expand Down
Loading