Skip to content
Commits on Source (2)
import boostedContentService from "../../../src/common/services/boosted-content.service";
import FeedsService from "../../../src/common/services/feeds.service";
import blockListService from "../../../src/common/services/block-list.service";
jest.mock('../../../src/common/services/feeds.service');
jest.mock('../../../src/common/services/session.service');
jest.mock('../../../src/common/services/block-list.service');
/**
* Tests
*/
describe('Boosted content service', () => {
beforeEach(() => {
blockListService.has.mockClear();
});
it('should fetch the boosts from the server', async () => {
const fakeBoosts = [{guid: 1}, {guid: 2}, {guid: 3}];
blockListService.has.mockReturnValue(false);
const fakeBoosts = [
{guid: 1, ownerObj: {guid: 1}},
{guid: 2, ownerObj: {guid: 2}},
{guid: 3, ownerObj: {guid: 3}},
];
const result = fakeBoosts.map(e => {
e.boosted = true;
return e;
});
boostedContentService.feedsService.getEntities.mockResolvedValue(fakeBoosts);
boostedContentService.feedsService.fetchLocal.mockResolvedValue(true);
// load the boosts
await boostedContentService.load();
// should fetch the feed
expect(boostedContentService.feedsService.setEndpoint).toBeCalledWith('api/v2/boost/feed');
expect(boostedContentService.feedsService.setOffset).toBeCalledWith(0);
expect(boostedContentService.feedsService.setLimit).toBeCalledWith(12);
expect(boostedContentService.feedsService.fetchLocal).toBeCalled();
// should fetch the boosts entities
expect(boostedContentService.feedsService.getEntities).toBeCalled();
// the boosts should be stored in the boosts property
expect(boostedContentService.boosts).toStrictEqual(result);
});
it('should fetch the boosts and filter blocked', async () => {
blockListService.has
.mockReturnValueOnce(false)
.mockReturnValueOnce(true)
.mockReturnValueOnce(false)
.mockReturnValueOnce(false)
.mockReturnValueOnce(true)
.mockReturnValueOnce(false);
const fakeBoosts = [
{guid: 1, ownerObj: {guid: 1}},
{guid: 2, ownerObj: {guid: 2}},
{guid: 3, ownerObj: {guid: 3}},
];
const result = fakeBoosts
.map(e => {
e.boosted = true;
return e;
})
.filter(e => e.guid !== 2);
boostedContentService.feedsService.getEntities.mockResolvedValue(fakeBoosts);
boostedContentService.feedsService.fetchLocal.mockResolvedValue(true);
......@@ -25,17 +83,22 @@ describe('Boosted content service', () => {
expect(boostedContentService.feedsService.setLimit).toBeCalledWith(12);
expect(boostedContentService.feedsService.fetchLocal).toBeCalled();
// blocked should be called
expect( blockListService.has).toBeCalled();
// should fetch the boosts entities
expect(boostedContentService.feedsService.getEntities).toBeCalled();
// the boosts should be stored in the boosts property
expect(boostedContentService.boosts).toBe(fakeBoosts);
expect(boostedContentService.boosts).toStrictEqual(result);
});
it('should return next boost and start again when the end is reached', () => {
const fakeBoosts = [{guid: 1}, {guid: 2}, {guid: 3}];
blockListService.has.mockReturnValue(false);
boostedContentService.boosts = fakeBoosts;
// next
......
import React, {Component} from 'react';
import {Text, StyleSheet, View} from 'react-native';
import {Text, View} from 'react-native';
import {CommonStyle} from '../../styles/Common';
import Colors from '../../styles/Colors';
import {CommonStyle as CS} from '../../styles/Common';
import i18n from '../services/i18n.service';
import { TouchableOpacity } from 'react-native-gesture-handler';
import {TouchableOpacity} from 'react-native-gesture-handler';
/**
* Blocked Channel
*/
export default class BlockedChannel extends Component {
/**
* Navigate To channel
......@@ -20,53 +22,44 @@ export default class BlockedChannel extends Component {
}
};
/**
* Render
*/
render() {
return (
<View style={[styles.container, CommonStyle.hairLineBottom]}>
<View style={[CommonStyle.flexContainerCenter, styles.insideBox]}>
<Text style={styles.text}>
{i18n.to('channel.blockedNav', null, {
username: (
<Text style={styles.username} onPress={this.navToChannel}>
@{this.props.entity.ownerObj.username}
</Text>
),
})}
<View
style={[
CS.flexContainer,
CS.centered,
CS.padding2x,
CS.backgroundLight,
CS.fullWidth,
]}>
<Text style={[CS.fontXL, CS.colorDarkGreyed, CS.marginTop3x]}>
{i18n.to('channel.blockedNav', null, {
username: (
<Text style={CS.bold} onPress={this.navToChannel}>
@{this.props.entity.ownerObj.username}
</Text>
),
})}
</Text>
<TouchableOpacity
onPress={async () => {
await this.props.entity.unblockOwner();
}}>
<Text
style={[
CS.fontL,
CS.colorPrimary,
CS.marginTop3x,
CS.marginBottom3x,
]}>
{i18n.t('undo')}
</Text>
<TouchableOpacity
onPress={async () => {
await this.props.entity.unblockOwner();
}}>
<Text style={styles.textUndo}>{i18n.t('undo')}</Text>
</TouchableOpacity>
</View>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
overflow: 'visible',
height: 150,
backgroundColor: Colors.lightGreyed,
padding: 5,
},
insideBox: {
borderStyle: 'solid',
borderColor: Colors.darkGreyed,
borderWidth: 0.5,
alignItems: 'center',
},
text: {
color: Colors.darkGreyed,
},
username: {
fontWeight: 'bold',
},
textUndo: {
color: Colors.darkGreyed,
marginTop: 20,
fontWeight: 'bold',
}
});
export default {
has: jest.fn(),
getList: jest.fn(),
add: jest.fn(),
remove: jest.fn(),
};
\ No newline at end of file
// @flow
import FeedsService from "./feeds.service";
import logService from "./log.service";
import blockListService from "./block-list.service";
// types
import type ActivityModel from "../../newsfeed/ActivityModel";
......@@ -9,17 +10,28 @@ import type ActivityModel from "../../newsfeed/ActivityModel";
* Boosted content service
*/
class BoostedContentService {
/**
* Offset
* @var {number}
*/
offset: number = -1;
feedsService: FeedsService = new FeedsService;
/**
* Feed service
* @var {FeedsService}
*/
feedsService: FeedsService = new FeedsService();
/**
* Boosts
* @var {Array<ActivityModel>} boosts
*/
boosts: Array<ActivityModel> = [];
/**
* Reload boosts list
*/
load = async(): Promise<any> => {
load = async (): Promise<any> => {
try {
const done = await this.feedsService
.setLimit(12)
......@@ -31,14 +43,24 @@ class BoostedContentService {
if (!done) {
await this.update();
} else {
this.boosts = await this.feedsService.getEntities();
// refresh boost without the wait
this.boosts = this.cleanBoosts(await this.feedsService.getEntities());
this.update();
}
} catch (err) {
logService.exception('[BoostedContentService]', err);
}
};
/**
* Remove blocked channel's boosts and sets boosted to true
* @param {Array<ActivityModel} boosts
*/
cleanBoosts(boosts: Array<ActivityModel>): Array<ActivityModel> {
return boosts.filter((e: ActivityModel) => {
e.boosted = true;
return !blockListService.has(e.ownerObj.guid);
});
}
/**
......@@ -46,7 +68,7 @@ class BoostedContentService {
*/
async update() {
await this.feedsService.fetch();
this.boosts = await this.feedsService.getEntities();
this.boosts = this.cleanBoosts(await this.feedsService.getEntities());
}
/**
......