diff --git a/src/app/article/article-default-view-component.spec.ts b/src/app/article/article-default-view-component.spec.ts index ec15d31..0d0299d 100644 --- a/src/app/article/article-default-view-component.spec.ts +++ b/src/app/article/article-default-view-component.spec.ts @@ -1,5 +1,7 @@ import {Input, provide, Component} from 'ng-forward'; import {ArticleViewComponent, ArticleDefaultViewComponent} from './article-default-view.component'; +import {ComponentTestHelper, createClass} from './../../spec/component-test-helper'; +import {ModelEvent, ArticleEventType} from "./../shared/models/events"; import * as helpers from "../../spec/helpers"; @@ -9,113 +11,83 @@ const htmlTemplate: string = ' { - describe("ArticleView Component", () => { - - // the karma preprocessor html2js transform the templates html into js files which put - // the templates to the templateCache into the module templates - // we need to load the module templates here as the template for the - // component Noosfero ArtileView will be load on our tests - beforeEach(angular.mock.module("templates")); - - it("renders the default component when no specific component is found", (done: Function) => { - // Creating a container component (ArticleContainerComponent) to include - // the component under test (ArticleView) - @Component({ - selector: 'test-container-component', - template: htmlTemplate, - directives: [ArticleViewComponent], - providers: [ - helpers.createProviderToValue('CommentService', helpers.mocks.commentService), - helpers.provideFilters("translateFilter"), - helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService), - helpers.createProviderToValue('SessionService', helpers.mocks.sessionWithCurrentUser({})) - ] - }) - class ArticleContainerComponent { - article = { type: 'anyArticleType' }; - profile = { name: 'profile-name' }; + // the karma preprocessor html2js transform the templates html into js files which put + // the templates to the templateCache into the module templates + // we need to load the module templates here as the template for the + // component Noosfero ArtileView will be load on our tests + beforeEach(angular.mock.module("templates")); + + describe("Article Default View Component", () => { + let helper: ComponentTestHelper; + const defaultViewTemplate: string = ''; + let articleService: any = helpers.mocks.articleService; + let article = { + id: 1, + profile: { + identifier: "1" } - - helpers.createComponentFromClass(ArticleContainerComponent).then((fixture) => { - // and here we can inspect and run the test assertions - - // gets the children component of ArticleContainerComponent - let articleView: ArticleViewComponent = fixture.debugElement.componentViewChildren[0].componentInstance; - - // and checks if the article View rendered was the Default Article View - expect(articleView.constructor.prototype).toEqual(ArticleDefaultViewComponent.prototype); - - // done needs to be called (it isn't really needed, as we can read in - // here (https://github.com/ngUpgraders/ng-forward/blob/master/API.md#createasync) - // because createAsync in ng-forward is not really async, but as the intention - // here is write tests in angular 2 ways, this is recommended - done(); + }; + let state = jasmine.createSpyObj("state", ["go", "transitionTo"]); + let providers = [ + provide('$state', { useValue: state }), + provide('ArticleService', { useValue: articleService }) + ].concat(helpers.provideFilters("translateFilter")); + + /** + * The beforeEach procedure will initialize the helper and parse + * the component according to the given providers. Unfortunetly, in + * this mode, the providers and properties given to the construtor + * can't be overriden. + */ + beforeEach((done) => { + // Create the component bed for the test. Optionally, this could be done + // in each test if one needs customization of these parameters per test + let cls = createClass({ + template: defaultViewTemplate, + directives: [ArticleDefaultViewComponent], + providers: providers, + properties: { + article: article + } }); - + helper = new ComponentTestHelper(cls, done); }); - it("receives the article and profile as inputs", (done: Function) => { - - // Creating a container component (ArticleContainerComponent) to include - // the component under test (ArticleView) - @Component({ - selector: 'test-container-component', - template: htmlTemplate, - directives: [ArticleViewComponent], - providers: [ - helpers.createProviderToValue('CommentService', helpers.mocks.commentService), - helpers.provideFilters("translateFilter"), - helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService), - helpers.createProviderToValue('SessionService', helpers.mocks.sessionWithCurrentUser({})) - ] - }) - class ArticleContainerComponent { - article = { type: 'anyArticleType' }; - profile = { name: 'profile-name' }; - } - - // uses the TestComponentBuilder instance to initialize the component - helpers.createComponentFromClass(ArticleContainerComponent).then((fixture) => { - // and here we can inspect and run the test assertions - let articleView: ArticleViewComponent = fixture.debugElement.componentViewChildren[0].componentInstance; + function getArticle() { + return this.article; + } - // assure the article object inside the ArticleView matches - // the provided through the parent component - expect(articleView.article.type).toEqual("anyArticleType"); - expect(articleView.profile.name).toEqual("profile-name"); - - // done needs to be called (it isn't really needed, as we can read in - // here (https://github.com/ngUpgraders/ng-forward/blob/master/API.md#createasync) - // because createAsync in ng-forward is not really async, but as the intention - // here is write tests in angular 2 ways, this is recommended - done(); - }); + it("it should delete article when delete is activated", () => { + expect(helper.component.article).toEqual(article); + // Spy the state service + doDeleteArticle(); + expect(state.transitionTo).toHaveBeenCalled(); }); - - it("renders a article view which matches to the article type", done => { - // NoosferoTinyMceArticle component created to check if it will be used - // when a article with type 'TinyMceArticle' is provided to the noosfero-article (ArticleView) - // *** Important *** - the selector is what ng-forward uses to define the name of the directive provider - @Component({ selector: 'noosfero-tiny-mce-article', template: "

TinyMceArticle

" }) - class TinyMceArticleView { - @Input() article: any; - @Input() profile: any; - } - - // Creating a container component (ArticleContainerComponent) to include our NoosferoTinyMceArticle - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ArticleViewComponent, TinyMceArticleView] }) - class CustomArticleType { - article = { type: 'TinyMceArticle' }; - profile = { name: 'profile-name' }; - } - helpers.createComponentFromClass(CustomArticleType).then(fixture => { - let myComponent: CustomArticleType = fixture.componentInstance; - expect(myComponent.article.type).toEqual("TinyMceArticle"); - expect(fixture.debugElement.componentViewChildren[0].text()).toEqual("TinyMceArticle"); - done(); + /** + * Execute the delete method on the target component + */ + function doDeleteArticle() { + // Create a mock for the ArticleService removeArticle method + spyOn(helper.component.articleService, 'removeArticle').and.callFake(function(param: noosfero.Article) { + return { + catch: () => {} + }; }); - }); - + helper.component.delete(); + expect(articleService.removeArticle).toHaveBeenCalled(); + // After the component delete method execution, fire the + // ArticleEvent.removed event + simulateRemovedEvent(); + } + + /** + * Simulate the ArticleService ArticleEvent.removed event + */ + function simulateRemovedEvent() { + let event: ModelEvent = ModelEvent.event(ArticleEventType.removed); + helper.component.articleService.notifyArticleRemovedListeners(article); + } }); + }); diff --git a/src/app/article/article-default-view.component.ts b/src/app/article/article-default-view.component.ts index edba801..52f1298 100644 --- a/src/app/article/article-default-view.component.ts +++ b/src/app/article/article-default-view.component.ts @@ -4,6 +4,8 @@ import {CommentsComponent} from "./comment/comments.component"; import {MacroDirective} from "./macro/macro.directive"; import {ArticleToolbarHotspotComponent} from "../hotspot/article-toolbar-hotspot.component"; import {ArticleContentHotspotComponent} from "../hotspot/article-content-hotspot.component"; +import {ArticleService} from "./../../lib/ng-noosfero-api/http/article.service"; +import {ModelEvent, ArticleEventType} from "./../shared/models/events"; /** * @ngdoc controller @@ -16,11 +18,30 @@ import {ArticleContentHotspotComponent} from "../hotspot/article-content-hotspot selector: 'noosfero-default-article', templateUrl: 'app/article/article.html' }) +@Inject("$state", ArticleService) export class ArticleDefaultViewComponent { @Input() article: noosfero.Article; @Input() profile: noosfero.Profile; + constructor(private $state: ng.ui.IStateService, public articleService: ArticleService) { + // Subscribe to the Article Removed Event + let event = ModelEvent.event(ArticleEventType.removed); + this.articleService.subscribe(event, (article: noosfero.Article) => { + if (this.article.parent) { + this.$state.transitionTo('main.profile.page', { page: this.article.parent.path, profile: this.article.profile.identifier }); + } else { + this.$state.transitionTo('main.profile.info', { profile: this.article.profile.identifier }); + } + }); + } + + delete() { + this.articleService.removeArticle(this.article).catch((cause: any) => { + throw new Error(`Problem removing the article: ${cause}`); + }); + } + } /** @@ -60,4 +81,5 @@ export class ArticleViewComponent { private $injector: ng.auto.IInjectorService, private $compile: ng.ICompileService) { } + } diff --git a/src/app/article/article-view-component.spec.ts b/src/app/article/article-view-component.spec.ts new file mode 100644 index 0000000..40284e8 --- /dev/null +++ b/src/app/article/article-view-component.spec.ts @@ -0,0 +1,124 @@ +import {Input, provide, Component} from 'ng-forward'; +import {ArticleViewComponent, ArticleDefaultViewComponent} from './article-default-view.component'; + +import * as helpers from "../../spec/helpers"; + +// this htmlTemplate will be re-used between the container components in this spec file +const htmlTemplate: string = ''; + + +describe("Components", () => { + + // the karma preprocessor html2js transform the templates html into js files which put + // the templates to the templateCache into the module templates + // we need to load the module templates here as the template for the + // component Noosfero ArtileView will be load on our tests + beforeEach(angular.mock.module("templates")); + + describe("ArticleView Component", () => { + let state = jasmine.createSpyObj("state", ["go", "transitionTo"]); + it("renders the default component when no specific component is found", (done: Function) => { + // Creating a container component (ArticleContainerComponent) to include + // the component under test (ArticleView) + @Component({ + selector: 'test-container-component', + template: htmlTemplate, + directives: [ArticleViewComponent], + providers: [ + helpers.createProviderToValue('CommentService', helpers.mocks.commentService), + helpers.provideFilters("translateFilter"), + helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService), + helpers.createProviderToValue('SessionService', helpers.mocks.sessionWithCurrentUser({})), + helpers.createProviderToValue('ArticleService', helpers.mocks.articleService), + helpers.createProviderToValue('$state', state) + ] + }) + class ArticleContainerComponent { + article = { type: 'anyArticleType' }; + profile = { name: 'profile-name' }; + } + + helpers.createComponentFromClass(ArticleContainerComponent).then((fixture) => { + // and here we can inspect and run the test assertions + + // gets the children component of ArticleContainerComponent + let articleView: ArticleViewComponent = fixture.debugElement.componentViewChildren[0].componentInstance; + + // and checks if the article View rendered was the Default Article View + expect(articleView.constructor.prototype).toEqual(ArticleDefaultViewComponent.prototype); + + // done needs to be called (it isn't really needed, as we can read in + // here (https://github.com/ngUpgraders/ng-forward/blob/master/API.md#createasync) + // because createAsync in ng-forward is not really async, but as the intention + // here is write tests in angular 2 ways, this is recommended + done(); + }); + }); + + it("receives the article and profile as inputs", (done: Function) => { + + // Creating a container component (ArticleContainerComponent) to include + // the component under test (ArticleView) + @Component({ + selector: 'test-container-component', + template: htmlTemplate, + directives: [ArticleViewComponent], + providers: [ + helpers.createProviderToValue('CommentService', helpers.mocks.commentService), + helpers.provideFilters("translateFilter"), + helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService), + helpers.createProviderToValue('SessionService', helpers.mocks.sessionWithCurrentUser({})), + helpers.createProviderToValue('ArticleService', helpers.mocks.articleService), + helpers.createProviderToValue('$state', state) + ] + }) + class ArticleContainerComponent { + article = { type: 'anyArticleType' }; + profile = { name: 'profile-name' }; + } + + // uses the TestComponentBuilder instance to initialize the component + helpers.createComponentFromClass(ArticleContainerComponent).then((fixture) => { + // and here we can inspect and run the test assertions + let articleView: ArticleViewComponent = fixture.debugElement.componentViewChildren[0].componentInstance; + + // assure the article object inside the ArticleView matches + // the provided through the parent component + expect(articleView.article.type).toEqual("anyArticleType"); + expect(articleView.profile.name).toEqual("profile-name"); + + // done needs to be called (it isn't really needed, as we can read in + // here (https://github.com/ngUpgraders/ng-forward/blob/master/API.md#createasync) + // because createAsync in ng-forward is not really async, but as the intention + // here is write tests in angular 2 ways, this is recommended + done(); + }); + }); + + + it("renders a article view which matches to the article type", done => { + // NoosferoTinyMceArticle component created to check if it will be used + // when a article with type 'TinyMceArticle' is provided to the noosfero-article (ArticleView) + // *** Important *** - the selector is what ng-forward uses to define the name of the directive provider + @Component({ selector: 'noosfero-tiny-mce-article', template: "

TinyMceArticle

" }) + class TinyMceArticleView { + @Input() article: any; + @Input() profile: any; + } + + // Creating a container component (ArticleContainerComponent) to include our NoosferoTinyMceArticle + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ArticleViewComponent, TinyMceArticleView] }) + class CustomArticleType { + article = { type: 'TinyMceArticle' }; + profile = { name: 'profile-name' }; + } + helpers.createComponentFromClass(CustomArticleType).then(fixture => { + let myComponent: CustomArticleType = fixture.componentInstance; + expect(myComponent.article.type).toEqual("TinyMceArticle"); + expect(fixture.debugElement.componentViewChildren[0].text()).toEqual("TinyMceArticle"); + done(); + }); + }); + + }); +}); diff --git a/src/app/article/article.html b/src/app/article/article.html index d85d66d..123a264 100644 --- a/src/app/article/article.html +++ b/src/app/article/article.html @@ -7,6 +7,9 @@ {{"article.actions.edit" | translate}} + + {{"article.actions.delete" | translate}} +
diff --git a/src/app/shared/models/events.spec.ts b/src/app/shared/models/events.spec.ts new file mode 100644 index 0000000..8918f21 --- /dev/null +++ b/src/app/shared/models/events.spec.ts @@ -0,0 +1,71 @@ +import { EventEmitter } from "ng-forward"; +import {ModelEvent, ArticleEventType} from "./events"; +import {HashMap} from "./../utils/hashmap"; +import {ArrayUtils} from "./../utils/arrays"; + +describe("Events", () => { + + describe("Event Type Tests", () => { + + it("verify event type is correctly created", (done) => { + let eventType1 = ArticleEventType.removed; + expect(eventType1.type).toBe("removed"); + expect(ArrayUtils.arraysEqual(eventType1.types, ["added", "removed"])).toBeTruthy(); + done(); + }); + + it("different event types of same type should be equal", (done) => { + let eventType1 = ArticleEventType.removed; + let eventType2 = ArticleEventType.removed; + expect(eventType1).toBe(eventType2); + expect(eventType1 === eventType2).toBeTruthy(); + done(); + }); + + it("different events types of different types should not be equal", (done) => { + let eventType1 = ArticleEventType.removed; + let eventType2 = ArticleEventType.added; + expect(eventType1).not.toBe(eventType2); + expect(eventType1 === eventType2).not.toBeTruthy(); + done(); + }); + + it("different events of same type should be equal", (done) => { + let event1 = ModelEvent.event(ArticleEventType.added); + let event2 = ModelEvent.event(ArticleEventType.added); + expect(event1.equals(event2)).toBeTruthy(); + done(); + }); + + }); + + describe("Event HashMap Tests", () => { + let events: HashMap>; + beforeEach((done) => { + events = new HashMap>(); + done(); + }); + + it("verify event HashMap contains the correct event", () => { + let expected = new EventEmitter(); + events.put(ModelEvent.event(ArticleEventType.added), expected); + let actual = events.get(ModelEvent.event(ArticleEventType.added)); + expect(expected === actual).toBeTruthy(); + }); + + it("verify event HashMap does not contain the wrong event", () => { + events.put(ModelEvent.event(ArticleEventType.added), new EventEmitter()); + let actual = events.get(ModelEvent.event(ArticleEventType.removed)); + expect(actual).not.toBeTruthy(); + }); + + it("verify HashMap has been cleared", () => { + events.put(ModelEvent.event(ArticleEventType.added), new EventEmitter()); + events.clear(); + let actual = events.get(ModelEvent.event(ArticleEventType.added)); + expect(actual).not.toBeTruthy(); + }); + + }); + +}); diff --git a/src/app/shared/models/events.ts b/src/app/shared/models/events.ts new file mode 100644 index 0000000..9b96ddc --- /dev/null +++ b/src/app/shared/models/events.ts @@ -0,0 +1,62 @@ +import {ArrayUtils} from "./../utils/arrays"; + +export abstract class EventType { + /** + * All possible types for the event + */ + types = new Array(); + + /** + * The event type + */ + type: string; + + constructor(types: Array, type: string) { + this.types = types; + this.type = type; + } + + equals(other: EventType) { + return ArrayUtils.arraysEqual(this.types, other.types) && this.type === other.type; + } + +} + +export class ArticleEventType extends EventType { + static types = ["added", "removed"]; + static removed: ArticleEventType = new ArticleEventType("removed"); + static added: ArticleEventType = new ArticleEventType("added"); + + constructor(type: string) { + super(ArticleEventType.types, type); + } +} + +/** + * A model event have a type (ModelEventType), and optionally with a model element. + * Therefore, it is possible to have events related to specific model elements. + * If the model element element is not provided, then the event is a generic event + * of the given type. + */ +export class ModelEvent { + private type: EventType; + private id: number; + + static event(type: EventType, model?: noosfero.RestModel): ModelEvent { + if (model) { + return new ModelEvent(type, model.id); + } else { + return new ModelEvent(type); + } + } + + constructor(type: EventType, id?: number) { + this.type = type; + this.id = id; + } + + equals(other: ModelEvent) { + return other.type.equals(this.type) && other.id === this.id; + } + +} diff --git a/src/app/shared/models/index.ts b/src/app/shared/models/index.ts index 181d29e..14616d4 100644 --- a/src/app/shared/models/index.ts +++ b/src/app/shared/models/index.ts @@ -1,2 +1,3 @@ /* Module Index Entry - generated using the script npm run generate-index */ export * from "./interfaces"; +export * from "./events"; diff --git a/src/app/shared/models/interfaces.ts b/src/app/shared/models/interfaces.ts index 3b384f8..613c732 100644 --- a/src/app/shared/models/interfaces.ts +++ b/src/app/shared/models/interfaces.ts @@ -6,7 +6,6 @@ export interface UserResponse { user: noosfero.User; } - export interface INoosferoLocalStorage extends angular.storage.ILocalStorageService { currentUser: noosfero.User; } diff --git a/src/app/shared/utils/arrays.ts b/src/app/shared/utils/arrays.ts new file mode 100644 index 0000000..f23ef94 --- /dev/null +++ b/src/app/shared/utils/arrays.ts @@ -0,0 +1,19 @@ +export class ArrayUtils { + + /** + * Returns if two arrays are equal + */ + static arraysEqual(a: any, b: any): boolean { + if (a === b) return true; + if (a == null || b == null) return false; + if (a.length !== b.length) return false; + + // If you don't care about the order of the elements inside + // the array, you should sort both arrays here. + for (let i = 0; i < a.length; ++i) { + if (a[i] !== b[i]) return false; + } + return true; + } + +} \ No newline at end of file diff --git a/src/app/shared/utils/hashmap.ts b/src/app/shared/utils/hashmap.ts new file mode 100644 index 0000000..862fb8f --- /dev/null +++ b/src/app/shared/utils/hashmap.ts @@ -0,0 +1,36 @@ +export class HashMap { + private values: Array> = new Array(); + + get(key: K): V { + let found = this.values.find( function(value: HashItem) { + return value.key.equals(key); + }); + if (found) { + return found.value; + } + return null; + } + + put(key: K, value: V): void { + this.values.push(new HashItem(key, value)); + } + + clear() { + this.values = new Array(); + } +} + +export class HashItem { + key: K; + value: V; + constructor(key: K, value: V) { + this.key = key; + this.value = value; + } +} + +export abstract class EqualsObject { + + abstract equals(other: any): boolean; + +} \ No newline at end of file diff --git a/src/app/shared/utils/index.ts b/src/app/shared/utils/index.ts new file mode 100644 index 0000000..6102c1a --- /dev/null +++ b/src/app/shared/utils/index.ts @@ -0,0 +1,3 @@ +/* Module Index Entry - generated using the script npm run generate-index */ +export * from "./hashmap"; +export * from "./arrays"; diff --git a/src/languages/en.json b/src/languages/en.json index d30aaa1..a29f7c0 100644 --- a/src/languages/en.json +++ b/src/languages/en.json @@ -37,6 +37,7 @@ "comment.post.success.message": "Comment saved!", "comment.reply": "reply", "article.actions.edit": "Edit", + "article.actions.delete": "Delete", "article.actions.read_more": "Read More", "article.basic_editor.title": "Title", "article.basic_editor.body": "Body", diff --git a/src/languages/pt.json b/src/languages/pt.json index 09d9562..83372e6 100644 --- a/src/languages/pt.json +++ b/src/languages/pt.json @@ -37,6 +37,7 @@ "comment.post.success.message": "Comentário salvo com sucesso!", "comment.reply": "responder", "article.actions.edit": "Editar", + "article.actions.delete": "Excluir", "article.actions.read_more": "Ler mais", "article.basic_editor.title": "Título", "article.basic_editor.body": "Corpo", diff --git a/src/lib/ng-noosfero-api/http/article.service.spec.ts b/src/lib/ng-noosfero-api/http/article.service.spec.ts index 1453489..fd993ec 100644 --- a/src/lib/ng-noosfero-api/http/article.service.spec.ts +++ b/src/lib/ng-noosfero-api/http/article.service.spec.ts @@ -20,6 +20,14 @@ describe("Services", () => { describe("Succesfull requests", () => { + it("should remove article", (done) => { + let articleId = 1; + $httpBackend.expectDELETE(`/api/v1/articles/${articleId}`).respond(200, { success: "true" }); + articleService.removeArticle({id: articleId}); + $httpBackend.flush(); + done(); + }); + it("should return article children", (done) => { let articleId = 1; $httpBackend.expectGET(`/api/v1/articles/${articleId}/children`).respond(200, { articles: [{ name: "article1" }] }); diff --git a/src/lib/ng-noosfero-api/http/article.service.ts b/src/lib/ng-noosfero-api/http/article.service.ts index 1cc7bd5..ba95636 100644 --- a/src/lib/ng-noosfero-api/http/article.service.ts +++ b/src/lib/ng-noosfero-api/http/article.service.ts @@ -1,14 +1,22 @@ -import { Injectable, Inject } from "ng-forward"; +import { Injectable, Inject, EventEmitter } from "ng-forward"; import {RestangularService} from "./restangular_service"; import {ProfileService} from "./profile.service"; +import {NoosferoRootScope} from "./../../../app/shared/models/interfaces"; +import {ModelEvent, ArticleEventType} from "./../../../app/shared/models/events"; +import {HashMap} from "./../../../app/shared/utils/hashmap"; @Injectable() @Inject("Restangular", "$q", "$log", ProfileService) - export class ArticleService extends RestangularService { + private events: HashMap> = new HashMap>(); + + // This event is not tyed to any specific model element. + private removed: ModelEvent = ModelEvent.event(ArticleEventType.removed); + constructor(Restangular: restangular.IService, $q: ng.IQService, $log: ng.ILogService, protected profileService: ProfileService) { super(Restangular, $q, $log); + this.events.put(this.removed, new EventEmitter()); } getResourcePath() { @@ -22,6 +30,36 @@ export class ArticleService extends RestangularService { }; } + removeArticle(article: noosfero.Article) { + let restRequest: ng.IPromise> = this.remove(article); + let deferred = this.$q.defer>(); + restRequest.then((result: any) => { + this.notifyArticleRemovedListeners(article); + }).catch(this.getHandleErrorFunction(deferred)); + return deferred.promise; + } + + /** + * Notify listeners that this article has been removed + */ + notifyArticleRemovedListeners(article: noosfero.Article) { + let listener = this.events.get(this.removed); + listener.next(article); + } + + /** + * Subscribe a listener a given article event + */ + subscribe(eventToSubscribe: ModelEvent, fn: Function) { + // Find the requested event in map + let event: EventEmitter = this.events.get(eventToSubscribe); + if (event) { + event.subscribe(fn); + } else { + throw new Error(`The event: ${eventToSubscribe} not exists`); + } + } + updateArticle(article: noosfero.Article) { let headers = { 'Content-Type': 'application/json' @@ -103,3 +141,4 @@ export class ArticleService extends RestangularService { } + diff --git a/src/spec/mocks.ts b/src/spec/mocks.ts index 8be322b..4cf74b1 100644 --- a/src/spec/mocks.ts +++ b/src/spec/mocks.ts @@ -76,6 +76,29 @@ export var mocks: any = { isAuthenticated: () => { } }, articleService: { + events: [ + { + event: Function, + subscribe: (fn: Function) => { + mocks.articleService.events[0].event = fn; + }, + next: (param: any) => { + mocks.articleService.events[0].event(param); + } + } + ], + removeArticle: (article: noosfero.Article) => { + return { + catch: (func?: Function) => { + } + }; + }, + notifyArticleRemovedListeners: (article: noosfero.Article) => { + mocks.articleService.events[0].next(article); + }, + subscribe: (eventType: any, fn: Function) => { + mocks.articleService.events[0].subscribe(fn); + }, getByProfile: (profileId: number, params?: any) => { return { then: (func?: Function) => { -- libgit2 0.21.2