currentUserService + refactor

stable
Juanfran 2015-05-19 09:02:32 +02:00
parent 56385e6ad7
commit 5ffc33fe0c
30 changed files with 579 additions and 559 deletions

View File

@ -40,7 +40,7 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven
$compileProvider, $translateProvider) ->
$routeProvider.when("/",
{
templateUrl: "home/home-page.html",
templateUrl: "home/home.html",
access: {
requiresLogin: true
},
@ -365,6 +365,10 @@ init = ($log, $rootscope, $auth, $events, $analytics, $translate, $location, $na
lang = ctx.language
i18nInit(lang, $translate)
# bluebird
Promise.setScheduler (cb) ->
$rootscope.$evalAsync(cb)
# Load user
if $auth.isAuthenticated()
$events.setupConnection()

View File

@ -36,15 +36,21 @@ class AuthService extends taiga.Service
"$tgHttp",
"$tgUrls",
"$tgConfig",
"$translate"]
"$translate",
"tgCurrentUserService"]
constructor: (@rootscope, @storage, @model, @rs, @http, @urls, @config, @translate) ->
constructor: (@rootscope, @storage, @model, @rs, @http, @urls, @config, @translate, @currentUserService) ->
super()
userModel = @.getUser()
@.setUserdata(userModel)
setUserdata: (userModel) ->
if userModel
@.userData = Immutable.fromJS(userModel.getAttrs())
@currentUserService.setUser(@.userData)
else
@.userData = null
_setLocales: ->
lang = @rootscope.user.lang || @config.get("defaultLanguage") || "en"
@ -67,6 +73,7 @@ class AuthService extends taiga.Service
@rootscope.auth = user
@storage.set("userInfo", user.getAttrs())
@rootscope.user = user
@.setUserdata(user)
@._setLocales()

View File

@ -22,11 +22,12 @@
taiga = @.taiga
class HttpService extends taiga.Service
@.$inject = ["$http", "$q", "$tgStorage", "$rootScope"]
@.$inject = ["$http", "$q", "$tgStorage", "$rootScope", "$cacheFactory"]
constructor: (@http, @q, @storage, @rootScope) ->
constructor: (@http, @q, @storage, @rootScope, @cacheFactory) ->
super()
@.cache = @cacheFactory("httpget");
headers: ->
headers = {}
@ -52,7 +53,12 @@ class HttpService extends taiga.Service
get: (url, params, options) ->
options = _.merge({method: "GET", url: url}, options)
options.params = params if params
return @.request(options)
# prevent duplicated http request
options.cache = @.cache
return @.request(options).finally (data) =>
@.cache.removeAll()
post: (url, data, params, options) ->
options = _.merge({method: "POST", url: url}, options)

View File

@ -105,7 +105,7 @@ Loader = () ->
clearInterval(intervalAuto)
clearTimeout(timeoutAuto)
), 200
), 50
start = () ->
startLoadTime = new Date().getTime()

View File

@ -1 +0,0 @@
div(tg-home)

View File

@ -1,37 +0,0 @@
HomeDirective = ($q, homeService, projectsService) ->
link = (scope, el, attrs, ctrl) ->
scope.vm = {}
projectsPromise = projectsService.getCurrentUserProjects()
workInProgresPromise = homeService.getWorkInProgress()
$q.all([projectsPromise, workInProgresPromise]).then ->
homeService.attachProjectInfoToWorkInProgress(projectsService.currentUserProjectsById)
taiga.defineImmutableProperty(scope.vm, "projects", () -> projectsService.currentUserProjects)
taiga.defineImmutableProperty(scope.vm, "workInProgress", () -> homeService.workInProgress)
if scope.vm.workInProgress.size > 0
userStories = scope.vm.workInProgress.get("assignedTo").get("userStories")
tasks = scope.vm.workInProgress.get("assignedTo").get("tasks")
issues = scope.vm.workInProgress.get("assignedTo").get("issues")
scope.vm.assignedTo = userStories.concat(tasks).concat(issues)
userStories = scope.vm.workInProgress.get("watching").get("userStories")
tasks = scope.vm.workInProgress.get("watching").get("tasks")
issues = scope.vm.workInProgress.get("watching").get("issues")
scope.vm.watching = userStories.concat(tasks).concat(issues)
return {
templateUrl: "home/home.html"
scope: {}
link: link
}
HomeDirective.$inject = [
"$q",
"tgHomeService",
"tgProjectsService"
]
angular.module("taigaHome").directive("tgHome", HomeDirective)

View File

@ -1,91 +0,0 @@
describe "homeDirective", () ->
scope = compile = provide = timeout = null
mockTgHomeService = mockTgProjectsService = null
thenStubGetCurrentUserProjectsById = thenStubGetWorkInProgress = null
template = "<div tg-home></div>"
createDirective = () ->
elm = compile(template)(scope)
return elm
_mockTgHomeService = () ->
thenStubGetWorkInProgress = sinon.stub()
mockTgHomeService = {
getWorkInProgress: sinon.stub()
workInProgress: Immutable.fromJS({
assignedTo: {
userStories: [{"id": 1}]
tasks: [{"id": 2}]
issues: [{"id": 3}]
}
watching: {
userStories: [{"id": 4}]
tasks: [{"id": 5}]
issues: [{"id": 6}]
}
})
attachProjectInfoToWorkInProgress: sinon.stub()
}
mockTgHomeService.getWorkInProgress.returns({
then: thenStubGetWorkInProgress
})
provide.value "tgHomeService", mockTgHomeService
_mockTranslateFilter = () ->
mockTranslateFilter = (value) ->
return value
provide.value "translateFilter", mockTranslateFilter
_mockTgDuty = () ->
provide.factory 'tgDutyDirective', () -> {}
_mockHomeProjectList = () ->
provide.factory 'tgHomeProjectListDirective', () -> {}
_mockTgProjectsService = () ->
thenStubGetCurrentUserProjectsById = sinon.stub()
mockTgProjectsService = {
getCurrentUserProjects: sinon.stub()
currentUserProjectsById: {
get: sinon.stub()
}
}
mockTgProjectsService.getCurrentUserProjects.returns({
then: thenStubGetCurrentUserProjectsById
})
provide.value "tgProjectsService", mockTgProjectsService
_mocks = () ->
module ($provide) ->
provide = $provide
_mockTgDuty()
_mockHomeProjectList()
_mockTgHomeService()
_mockTranslateFilter()
_mockTgProjectsService()
return null
beforeEach ->
module "templates"
module "taigaHome"
_mocks()
inject ($rootScope, $compile, $timeout) ->
scope = $rootScope.$new()
compile = $compile
timeout = $timeout
it "home directive content", () ->
elm = createDirective()
scope.$apply()
thenStubGetCurrentUserProjectsById.callArg(0)
thenStubGetWorkInProgress.callArg(0)
timeout.flush()
expect(elm.isolateScope().vm.assignedTo.size).to.be.equal(3)
expect(elm.isolateScope().vm.watching.size).to.be.equal(3)

View File

@ -3,17 +3,6 @@ doctype html
include ../../partials/includes/components/beta
div.home-wrapper.centered
div.duty-summary
div.title-bar.working-on-title(ng-show="vm.assignedTo.size", translate="HOME.WORKING_ON_SECTION")
section.working-on(ng-show="vm.assignedTo.size")
div.duty-single(tg-duty="duty", tg-repeat="duty in vm.assignedTo", ng-class="{blocked: duty.is_blocked}")
div.title-bar.watching-title(translate="HOME.WATCHING_SECTION")
section.watching-empty(ng-show="!vm.watching.size")
include ../../svg/hide.svg
p(translate="HOME.EMPTY_WATCHING")
section.watching(ng-show="vm.watching.size")
div.duty-single(tg-duty="duty", tg-repeat="duty in vm.watching", ng-class="{blocked: duty.is_blocked}")
div(tg-working-on)
aside.project-list(tg-home-project-list)

View File

@ -1,18 +1,18 @@
groupBy = @.taiga.groupBy
class HomeService extends taiga.Service
@.$inject = ["$q", "$tgNavUrls", "tgResources", "$rootScope", "$projectUrl", "$tgAuth"]
@.$inject = [
"$tgNavUrls",
"tgResources",
"tgProjectsService"
]
constructor: (@q, @navurls, @rs, @rootScope, @projectUrl, @auth) ->
@._workInProgress = Immutable.Map()
@._projectPromise = null
@._inProgress = false
constructor: (@navurls, @rs, @projectsService) ->
taiga.defineImmutableProperty @, "workInProgress", () => return @._workInProgress
@.fetchWorkInProgress()
attachProjectInfoToWorkInProgress: (projectsById) ->
_attachProjectInfoToWorkInProgress: (workInProgress, projectsById) ->
_attachProjectInfoToDuty = (duty, objType) =>
project = projectsById.get(String(duty.get('project')))
ctx = {
project: project.get('slug')
ref: duty.get('ref')
@ -26,105 +26,105 @@ class HomeService extends taiga.Service
return duty
assignedTo = Immutable.Map()
assignedTo = workInProgress.get("assignedTo")
if @.assignedToUserStories
_duties = @.assignedToUserStories.map (duty) ->
if assignedTo.get("userStories")
_duties = assignedTo.get("userStories").map (duty) ->
return _attachProjectInfoToDuty(duty, "userstories")
assignedTo = assignedTo.set("userStories", _duties)
if @.assignedToTasks
_duties = @.assignedToTasks.map (duty) ->
if assignedTo.get("tasks")
_duties = assignedTo.get("tasks").map (duty) ->
return _attachProjectInfoToDuty(duty, "tasks")
assignedTo = assignedTo.set("tasks", _duties)
if @.assignedToIssues
_duties = @.assignedToIssues.map (duty) ->
if assignedTo.get("issues")
_duties = assignedTo.get("issues").map (duty) ->
return _attachProjectInfoToDuty(duty, "issues")
assignedTo = assignedTo.set("issues", _duties)
watching = Immutable.Map()
watching = workInProgress.get("watching")
if @.watchingUserStories
_duties = @.watchingUserStories.map (duty) ->
if watching.get("userStories")
_duties = watching.get("userStories").map (duty) ->
return _attachProjectInfoToDuty(duty, "userstories")
watching = watching.set("userStories", _duties)
if @.watchingTasks
_duties = @.watchingTasks.map (duty) ->
if watching.get("tasks")
_duties = watching.get("tasks").map (duty) ->
return _attachProjectInfoToDuty(duty, "tasks")
watching = watching.set("tasks", _duties)
if @.watchingIssues
_duties = @.watchingIssues.map (duty) ->
if watching.get("issues")
_duties = watching.get("issues").map (duty) ->
return _attachProjectInfoToDuty(duty, "issues")
watching = watching.set("issues", _duties)
@._workInProgress = Immutable.Map({
assignedTo: assignedTo,
watching: watching
})
getWorkInProgress: () ->
return @._projectPromise
workInProgress = workInProgress.set("assignedTo", assignedTo)
workInProgress = workInProgress.set("watching", watching)
fetchWorkInProgress: () ->
userId = @auth.getUser().id
if not @._inProgress
@._inProgress = true
getWorkInProgress: (userId) ->
projectsById = Immutable.Map()
projectsPromise = @projectsService.getProjectsByUserId(userId).then (projects) ->
projectsById = Immutable.fromJS(groupBy(projects.toJS(), (p) -> p.id))
assignedTo = Immutable.Map()
params = {
status__is_closed: false
assigned_to: userId
}
assignedUserStoriesPromise = @rs.userstories.listInAllProjects(params).then (userstories) =>
@.assignedToUserStories = userstories
assignedTasksPromise = @rs.tasks.listInAllProjects(params).then (tasks) =>
@.assignedToTasks = tasks
assignedUserStoriesPromise = @rs.userstories.listInAllProjects(params).then (userstories) ->
assignedTo = assignedTo.set("userStories", userstories)
assignedIssuesPromise = @rs.issues.listInAllProjects(params).then (issues) =>
@.assignedToIssues = issues
assignedTasksPromise = @rs.tasks.listInAllProjects(params).then (tasks) ->
assignedTo = assignedTo.set("tasks", tasks)
assignedIssuesPromise = @rs.issues.listInAllProjects(params).then (issues) ->
assignedTo = assignedTo.set("issues", issues)
params = {
status__is_closed: false
watchers: userId
}
watchingUserStoriesPromise = @rs.userstories.listInAllProjects(params).then (userstories) =>
@.watchingUserStories = userstories
watchingTasksPromise = @rs.tasks.listInAllProjects(params).then (tasks) =>
@.watchingTasks = tasks
watching = Immutable.Map()
watchingIssuesPromise = @rs.issues.listInAllProjects(params).then (issues) =>
@.watchingIssues = issues
watchingUserStoriesPromise = @rs.userstories.listInAllProjects(params).then (userstories) ->
watching = watching.set("userStories", userstories)
@._projectPromise = @q.all([assignedUserStoriesPromise, assignedTasksPromise,
assignedIssuesPromise, watchingUserStoriesPromise,
watchingUserStoriesPromise, watchingIssuesPromise])
watchingTasksPromise = @rs.tasks.listInAllProjects(params).then (tasks) ->
watching = watching.set("tasks", tasks)
@._projectPromise.then =>
@._workInProgress = Immutable.fromJS({
assignedTo: {
userStories: @.assignedToUserStories
tasks: @.assignedToTasks
issues: @.assignedToIssues
}
watching: {
userStories: @.watchingUserStories
tasks: @.watchingTasks
issues: @.watchingIssues
}
})
watchingIssuesPromise = @rs.issues.listInAllProjects(params).then (issues) ->
watching = watching.set("issues", issues)
@._inProgress = false
workInProgress = Immutable.Map()
return @._projectPromise
Promise.all([
projectsPromise
assignedUserStoriesPromise,
assignedTasksPromise,
assignedIssuesPromise,
watchingUserStoriesPromise,
watchingTasksPromise,
watchingIssuesPromise
]).then =>
workInProgress = workInProgress.set("assignedTo", assignedTo)
workInProgress = workInProgress.set("watching", watching)
workInProgress = @._attachProjectInfoToWorkInProgress(workInProgress, projectsById)
return workInProgress
angular.module("taigaHome").service("tgHomeService", HomeService)

View File

@ -1,90 +1,36 @@
describe "tgHome", ->
homeService = provide = timeout = null
homeService = provide = null
mocks = {}
_mockResources = () ->
mocks.resources = {}
mocks.resources.userstories = {
listInAllProjects: sinon.stub()
}
mocks.resources.userstories = {}
mocks.resources.tasks = {}
mocks.resources.issues = {}
mocks.resources.tasks = {
listInAllProjects: sinon.stub()
}
mocks.resources.issues = {
listInAllProjects: sinon.stub()
}
paramsAssignedTo = {
status__is_closed: false
assigned_to: 1
}
paramsWatching = {
status__is_closed: false
watchers: 1
}
mocks.thenStubAssignedToUserstories = sinon.stub()
mocks.resources.userstories.listInAllProjects.withArgs(paramsAssignedTo).returns({
then: mocks.thenStubAssignedToUserstories
})
mocks.thenStubAssignedToTasks = sinon.stub()
mocks.resources.tasks.listInAllProjects.withArgs(paramsAssignedTo).returns({
then: mocks.thenStubAssignedToTasks
})
mocks.thenStubAssignedToIssues = sinon.stub()
mocks.resources.issues.listInAllProjects.withArgs(paramsAssignedTo).returns({
then: mocks.thenStubAssignedToIssues
})
mocks.thenStubWatchingUserstories = sinon.stub()
mocks.resources.userstories.listInAllProjects.withArgs(paramsWatching).returns({
then: mocks.thenStubWatchingUserstories
})
mocks.thenStubWatchingTasks = sinon.stub()
mocks.resources.tasks.listInAllProjects.withArgs(paramsWatching).returns({
then: mocks.thenStubWatchingTasks
})
mocks.thenStubWatchingIssues = sinon.stub()
mocks.resources.issues.listInAllProjects.withArgs(paramsWatching).returns({
then: mocks.thenStubWatchingIssues
})
mocks.resources.userstories.listInAllProjects = sinon.stub().promise()
mocks.resources.tasks.listInAllProjects = sinon.stub().promise()
mocks.resources.issues.listInAllProjects = sinon.stub().promise()
provide.value "tgResources", mocks.resources
_mockProjectUrl = () ->
mocks.projectUrl = {get: sinon.stub()}
mocks.projectUrl.get = (project) ->
return "url-" + project.id
provide.value "$projectUrl", mocks.projectUrl
_mockAuth = () ->
mocks.auth = {
getUser: sinon.stub()
}
mocks.auth.getUser.returns(id: 1)
provide.value "$tgAuth", mocks.auth
_mockTgNavUrls = () ->
mocks.tgNavUrls = {
resolve: sinon.stub()
}
provide.value "$tgNavUrls", mocks.tgNavUrls
_mockProjectsService = () ->
mocks.projectsService = {
getProjectsByUserId: sinon.stub().promise()
}
provide.value "tgProjectsService", mocks.projectsService
_inject = (callback) ->
inject (_$timeout_, _tgHomeService_) ->
timeout = _$timeout_
inject (_tgHomeService_) ->
homeService = _tgHomeService_
callback() if callback
@ -92,9 +38,9 @@ describe "tgHome", ->
module ($provide) ->
provide = $provide
_mockResources()
_mockProjectUrl()
_mockAuth()
_mockTgNavUrls()
_mockProjectsService()
return null
_setup = ->
@ -105,80 +51,93 @@ describe "tgHome", ->
_setup()
_inject()
describe "fetch items", ->
it "work in progress filled", () ->
mocks.thenStubAssignedToUserstories.callArg(0, Immutable.fromJS([{"id": 1}]))
mocks.thenStubAssignedToTasks.callArg(0, Immutable.fromJS([{"id": 2}]))
mocks.thenStubAssignedToIssues.callArg(0, Immutable.fromJS([{"id": 3}]))
mocks.thenStubWatchingUserstories.callArg(0, Immutable.fromJS([{"id": 4}]))
mocks.thenStubWatchingTasks.callArg(0, Immutable.fromJS([{"id": 5}]))
mocks.thenStubWatchingIssues.callArg(0, Immutable.fromJS([{"id": 6}]))
it "get work in progress by user", (done) ->
userId = 3
timeout.flush()
expect(homeService.workInProgress.toJS()).to.be.eql({
assignedTo: {
userStories: [{"id": 1}]
tasks: [{"id": 2}]
issues: [{"id": 3}]
}
watching: {
userStories: [{"id": 4}]
tasks: [{"id": 5}]
issues: [{"id": 6}]
}
})
mocks.projectsService.getProjectsByUserId
.withArgs(userId)
.resolve(Immutable.fromJS([
{id: 1, name: "fake1", slug: "project-1"},
{id: 2, name: "fake2", slug: "project-2"}
]))
it "_inProgress change to false when tgResources end", () ->
expect(homeService._inProgress).to.be.true
timeout.flush()
expect(homeService._inProgress).to.be.false
mocks.resources.userstories.listInAllProjects
.resolve(Immutable.fromJS([{id: 1, ref: 1, project: "1"}]))
it "project info filled", () ->
duty = {
id: 66
ref: 123
project: 1
}
mocks.resources.tasks.listInAllProjects
.resolve(Immutable.fromJS([{id: 2, ref: 2, project: "1"}]))
mocks.thenStubAssignedToUserstories.callArg(0, Immutable.fromJS([duty]))
mocks.thenStubAssignedToTasks.callArg(0, Immutable.fromJS([]))
mocks.thenStubAssignedToIssues.callArg(0, Immutable.fromJS([]))
mocks.thenStubWatchingUserstories.callArg(0, Immutable.fromJS([]))
mocks.thenStubWatchingTasks.callArg(0, Immutable.fromJS([]))
mocks.thenStubWatchingIssues.callArg(0, Immutable.fromJS([]))
timeout.flush()
mocks.resources.issues.listInAllProjects
.resolve(Immutable.fromJS([{id: 3, ref: 3, project: "1"}]))
projectsById = {
get: () -> Immutable.fromJS({
name: "Testing project"
slug: "testing-project"
})
}
# mock urls
mocks.tgNavUrls.resolve
.withArgs("project-userstories-detail", {project: "project-1", ref: 1})
.returns("/testing-project/us/1")
mocks.tgNavUrls.resolve
.withArgs("project-userstories-detail", {project: "testing-project", ref: 123})
.returns("/testing-project/us/123")
.withArgs("project-tasks-detail", {project: "project-1", ref: 2})
.returns("/testing-project/tasks/1")
homeService.attachProjectInfoToWorkInProgress(projectsById)
mocks.tgNavUrls.resolve
.withArgs("project-issues-detail", {project: "project-1", ref: 3})
.returns("/testing-project/issues/1")
expect(homeService.workInProgress.toJS()).to.be.eql({
homeService.getWorkInProgress(userId)
.then (workInProgress) ->
expect(workInProgress.toJS()).to.be.eql({
assignedTo: {
userStories: [
{
id: 66
_name: "userstories"
ref: 123
project: 1
url: "/testing-project/us/123"
projectName: "Testing project"
}
]
tasks: []
issues: []
userStories: [{
id: 1,
ref: 1,
project: '1',
url: '/testing-project/us/1',
projectName: 'fake1',
_name: 'userstories'
}]
tasks: [{
id: 2,
ref: 2,
project: '1',
url: '/testing-project/tasks/1',
projectName: 'fake1',
_name: 'tasks'
}]
issues: [{
id: 3,
ref: 3,
project: '1',
url: '/testing-project/issues/1',
projectName: 'fake1',
_name: 'issues'
}]
}
watching: {
userStories: []
tasks: []
issues: []
userStories: [{
id: 1,
ref: 1,
project: '1',
url: '/testing-project/us/1',
projectName: 'fake1',
_name: 'userstories'
}]
tasks: [{
id: 2,
ref: 2,
project: '1',
url: '/testing-project/tasks/1',
projectName: 'fake1',
_name: 'tasks'
}]
issues: [{
id: 3,
ref: 3,
project: '1',
url: '/testing-project/issues/1',
projectName: 'fake1',
_name: 'issues'
}]
}
})
done()

View File

@ -1,21 +1,31 @@
describe "homeProjectListDirective", () ->
scope = compile = provide = null
mockTgProjectsService = null
mocks = {}
template = "<div tg-home-project-list></div>"
recents = []
projects = Immutable.fromJS({
recents: [
{id: 1},
{id: 2},
{id: 3}
]
})
createDirective = () ->
elm = compile(template)(scope)
return elm
_mockTgCurrentUserService = () ->
mocks.currentUserService = {
projects: projects
}
provide.value "tgCurrentUserService", mocks.currentUserService
_mockTgProjectsService = () ->
mockTgProjectsService = {
mocks.projectsService = {
newProject: sinon.stub()
currentUserProjects: {
get: sinon.stub()
}
}
provide.value "tgProjectsService", mockTgProjectsService
provide.value "tgProjectsService", mocks.projectsService
_mockTranslateFilter = () ->
mockTranslateFilter = (value) ->
@ -25,6 +35,7 @@ describe "homeProjectListDirective", () ->
_mocks = () ->
module ($provide) ->
provide = $provide
_mockTgCurrentUserService()
_mockTgProjectsService()
_mockTranslateFilter()
return null
@ -49,17 +60,14 @@ describe "homeProjectListDirective", () ->
])
it "home project list directive scope content", () ->
mockTgProjectsService.currentUserProjects.get
.withArgs("recents")
.returns(recents)
elm = createDirective()
scope.$apply()
expect(elm.isolateScope().vm.projects.size).to.be.equal(2)
expect(elm.isolateScope().vm.projects.size).to.be.equal(3)
it "home project list directive newProject", () ->
elm = createDirective()
scope.$apply()
expect(mockTgProjectsService.newProject.callCount).to.be.equal(0)
expect(mocks.projectsService.newProject.callCount).to.be.equal(0)
elm.isolateScope().vm.newProject()
expect(mockTgProjectsService.newProject.callCount).to.be.equal(1)
expect(mocks.projectsService.newProject.callCount).to.be.equal(1)

View File

@ -1,8 +1,8 @@
HomeProjectListDirective = (projectsService) ->
HomeProjectListDirective = (currentUserService, projectsService) ->
link = (scope, el, attrs, ctrl) ->
scope.vm = {}
taiga.defineImmutableProperty(scope.vm, "projects", () -> projectsService.currentUserProjects.get("recents"))
taiga.defineImmutableProperty(scope.vm, "projects", () -> currentUserService.projects.get("recents"))
scope.vm.newProject = ->
projectsService.newProject()
@ -15,6 +15,9 @@ HomeProjectListDirective = (projectsService) ->
return directive
HomeProjectListDirective.$inject = ["tgProjectsService"]
HomeProjectListDirective.$inject = [
"tgCurrentUserService",
"tgProjectsService"
]
angular.module("taigaHome").directive("tgHomeProjectList", HomeProjectListDirective)

View File

@ -0,0 +1,29 @@
class WorkingOnController
@.$inject = [
"tgHomeService"
]
constructor: (@homeService) ->
@.assignedTo = Immutable.Map()
@.watching = Immutable.Map()
_setAssignedTo: (workInProgress) ->
userStories = workInProgress.get("assignedTo").get("userStories")
tasks = workInProgress.get("assignedTo").get("tasks")
issues = workInProgress.get("assignedTo").get("issues")
@.assignedTo = userStories.concat(tasks).concat(issues)
_setWatching: (workInProgress) ->
userStories = workInProgress.get("watching").get("userStories")
tasks = workInProgress.get("watching").get("tasks")
issues = workInProgress.get("watching").get("issues")
@.watching = userStories.concat(tasks).concat(issues)
getWorkInProgress: (userId) ->
return @homeService.getWorkInProgress(userId).then (workInProgress) =>
@._setAssignedTo(workInProgress)
@._setWatching(workInProgress)
angular.module("taigaHome").controller("WorkingOn", WorkingOnController)

View File

@ -0,0 +1,59 @@
describe "WorkingOn", ->
$controller = null
$provide = null
mocks = {}
_mockHomeService = () ->
mocks.homeService = {
getWorkInProgress: sinon.stub().promise()
}
$provide.value("tgHomeService", mocks.homeService)
_mocks = () ->
module (_$provide_) ->
$provide = _$provide_
_mockHomeService()
return null
_inject = () ->
inject (_$controller_) ->
$controller = _$controller_
beforeEach ->
module "taigaHome"
_mocks()
_inject()
it "get work in progress items", (done) ->
userId = 3
workInProgress = Immutable.fromJS({
assignedTo: {
userStories: [{id: 1}, {id: 2}],
tasks: [{id: 3}, {id: 4}],
issues: [{id: 5}, {id: 6}]
},
watching: {
userStories: [{id: 7}, {id: 8}],
tasks: [{id: 9}, {id: 10}],
issues: [{id: 11}, {id: 12}]
}
})
mocks.homeService.getWorkInProgress.withArgs(userId).resolve(workInProgress)
ctrl = $controller("WorkingOn")
ctrl.getWorkInProgress(userId).then () ->
expect(ctrl.assignedTo.toJS()).to.be.eql([
{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}
])
expect(ctrl.watching.toJS()).to.be.eql([
{id: 7}, {id: 8}, {id: 9}, {id: 10}, {id: 11}, {id: 12}
])
done()

View File

@ -0,0 +1,20 @@
WorkingOnDirective = (homeService, currentUserService) ->
link = (scope, el, attrs, ctrl) ->
userId = currentUserService.getUser().get("id")
ctrl.getWorkInProgress(userId)
return {
controller: "WorkingOn",
controllerAs: "vm",
templateUrl: "home/working-on/working-on.html",
scope: {},
link: link
}
WorkingOnDirective.$inject = [
"tgHomeService",
"tgCurrentUserService"
]
angular.module("taigaHome").directive("tgWorkingOn", WorkingOnDirective)

View File

@ -0,0 +1,12 @@
div.title-bar.working-on-title(ng-show="vm.assignedTo.size", translate="HOME.WORKING_ON_SECTION")
section.working-on(ng-show="vm.assignedTo.size")
div.duty-single(tg-duty="duty", tg-repeat="duty in vm.assignedTo", ng-class="{blocked: duty.is_blocked}")
div.title-bar.watching-title(translate="HOME.WATCHING_SECTION")
section.watching-empty(ng-show="!vm.watching.size")
include ../../../svg/hide.svg
p(translate="HOME.EMPTY_WATCHING")
section.watching(ng-show="vm.watching.size")
div.duty-single(tg-duty="duty", tg-repeat="duty in vm.watching", ng-class="{blocked: duty.is_blocked}")

View File

@ -1,8 +1,8 @@
DropdownProjectListDirective = (projectsService) ->
DropdownProjectListDirective = (currentUserService, projectsService) ->
link = (scope, el, attrs, ctrl) ->
scope.vm = {}
taiga.defineImmutableProperty(scope.vm, "projects", () -> projectsService.currentUserProjects.get("recents"))
taiga.defineImmutableProperty(scope.vm, "projects", () -> currentUserService.projects.get("recents"))
scope.vm.newProject = ->
projectsService.newProject()
@ -16,6 +16,7 @@ DropdownProjectListDirective = (projectsService) ->
return directive
DropdownProjectListDirective.$inject = [
"tgCurrentUserService",
"tgProjectsService"
]

View File

@ -1,32 +1,45 @@
describe "dropdownProjectListDirective", () ->
scope = compile = provide = null
mockTgProjectsService = null
mocks = {}
template = "<div tg-dropdown-project-list></div>"
recents = []
createDirective = () ->
elm = compile(template)(scope)
return elm
_mockTgProjectsService = () ->
mockTgProjectsService = {
newProject: sinon.stub()
currentUserProjects: {
get: sinon.stub()
}
}
provide.value "tgProjectsService", mockTgProjectsService
projects = Immutable.fromJS({
recents: [
{id: 1},
{id: 2},
{id: 3}
]
})
_mockTranslateFilter = () ->
mockTranslateFilter = (value) ->
return value
provide.value "translateFilter", mockTranslateFilter
createDirective = () ->
elm = compile(template)(scope)
return elm
_mockTgProjectsService = () ->
mocks.projectsService = {
newProject: sinon.stub()
}
provide.value "tgProjectsService", mocks.projectsService
_mockTgCurrentUserService = () ->
mocks.currentUserService = {
projects: projects
}
provide.value "tgCurrentUserService", mocks.currentUserService
_mocks = () ->
module ($provide) ->
provide = $provide
_mockTgProjectsService()
_mockTgCurrentUserService()
_mockTranslateFilter()
return null
beforeEach ->
@ -39,20 +52,7 @@ describe "dropdownProjectListDirective", () ->
scope = $rootScope.$new()
compile = $compile
recents = Immutable.fromJS([
{
id:1
},
{
id: 2
}
])
it "dropdown project list directive scope content", () ->
mockTgProjectsService.currentUserProjects.get
.withArgs("recents")
.returns(recents)
elm = createDirective()
scope.$apply()
expect(elm.isolateScope().vm.projects.size).to.be.equal(2)
expect(elm.isolateScope().vm.projects.size).to.be.equal(3)

View File

@ -1,8 +1,8 @@
NavigationBarDirective = (projectsService) ->
NavigationBarDirective = (currentUserService) ->
link = (scope, el, attrs, ctrl) ->
scope.vm = {}
taiga.defineImmutableProperty(scope.vm, "projects", () -> projectsService.currentUserProjects.get("recents"))
taiga.defineImmutableProperty(scope.vm, "projects", () -> currentUserService.projects.get("recents"))
directive = {
templateUrl: "navigation-bar/navigation-bar.html"
@ -13,7 +13,7 @@ NavigationBarDirective = (projectsService) ->
return directive
NavigationBarDirective.$inject = [
"tgProjectsService"
"tgCurrentUserService"
]
angular.module("taigaNavigationBar").directive("tgNavigationBar", NavigationBarDirective)

View File

@ -1,21 +1,26 @@
describe "navigationBarDirective", () ->
scope = compile = provide = null
mockTgProjectsService = null
mocks = {}
template = "<div tg-navigation-bar></div>"
recents = []
projects = Immutable.fromJS({
recents: [
{id: 1},
{id: 2},
{id: 3}
]
})
createDirective = () ->
elm = compile(template)(scope)
return elm
_mockTgProjectsService = () ->
mockTgProjectsService = {
newProject: sinon.stub()
currentUserProjects: {
get: sinon.stub()
_mocksCurrentUserService = () ->
mocks.currentUserService = {
projects: projects
}
}
provide.value "tgProjectsService", mockTgProjectsService
provide.value "tgCurrentUserService", mocks.currentUserService
_mockTranslateFilter = () ->
mockTranslateFilter = (value) ->
@ -31,7 +36,8 @@ describe "navigationBarDirective", () ->
_mocks = () ->
module ($provide) ->
provide = $provide
_mockTgProjectsService()
_mocksCurrentUserService()
_mockTranslateFilter()
_mockTgDropdownProjectListDirective()
_mockTgDropdownUserDirective()
@ -57,10 +63,6 @@ describe "navigationBarDirective", () ->
])
it "navigation bar directive scope content", () ->
mockTgProjectsService.currentUserProjects.get
.withArgs("recents")
.returns(recents)
elm = createDirective()
scope.$apply()
expect(elm.isolateScope().vm.projects.size).to.be.equal(2)
expect(elm.isolateScope().vm.projects.size).to.be.equal(3)

View File

@ -1,10 +1,11 @@
class ProjectsListingController
@.$inject = [
"tgProjectsService"
"tgCurrentUserService",
"tgProjectsService",
]
constructor: (@projectsService) ->
taiga.defineImmutableProperty(@, "projects", () => @projectsService.currentUserProjects.get("all"))
constructor: (@currentUserService, @projectsService) ->
taiga.defineImmutableProperty(@, "projects", () => @currentUserService.projects.get("all"))
newProject: ->
@projectsService.newProject()

View File

@ -4,30 +4,37 @@ describe "ProjectsListingController", ->
controller = null
mocks = {}
projects = Immutable.fromJS([
projects = Immutable.fromJS({
all: [
{id: 1},
{id: 2},
{id: 3}
])
]
})
_mockCurrentUserService = () ->
stub = sinon.stub()
mocks.currentUserService = {
projects: projects
}
provide.value "tgCurrentUserService", mocks.currentUserService
_mockProjectsService = () ->
stub = sinon.stub()
mocks.projectsService = {
currentUserProjects: {
get: stub
},
newProject: sinon.stub()
}
stub.withArgs("all").returns(projects)
provide.value "tgProjectsService", mocks.projectsService
_mocks = () ->
module ($provide) ->
provide = $provide
_mockProjectsService()
_mockCurrentUserService()
return null
@ -43,7 +50,7 @@ describe "ProjectsListingController", ->
pageCtrl = controller "ProjectsListing",
$scope: {}
expect(pageCtrl.projects).to.be.equal(projects)
expect(pageCtrl.projects).to.be.equal(projects.get('all'))
it "new project", () ->
pageCtrl = controller "ProjectsListing",

View File

@ -2,21 +2,9 @@ taiga = @.taiga
groupBy = @.taiga.groupBy
class ProjectsService extends taiga.Service
@.$inject = ["tgResources", "$tgAuth", "$projectUrl", "tgLightboxFactory"]
@.$inject = ["tgResources", "$projectUrl", "tgLightboxFactory"]
constructor: (@rs, @auth, @projectUrl, @lightboxFactory) ->
@._currentUserProjects = Immutable.Map()
@._currentUserProjectsById = Immutable.Map()
@._inProgress = false
@._currentUserProjectsPromise = null
taiga.defineImmutableProperty @, "currentUserProjects", () => return @._currentUserProjects
taiga.defineImmutableProperty @, "currentUserProjectsById", () => return @._currentUserProjectsById
@.fetchProjects()
getCurrentUserProjects: ->
return @._currentUserProjectsPromise
constructor: (@rs, @projectUrl, @lightboxFactory) ->
getProjectBySlug: (projectSlug) ->
return @rs.projects.getProjectBySlug(projectSlug)
@ -47,24 +35,6 @@ class ProjectsService extends taiga.Service
return project
fetchProjects: ->
if not @._inProgress
@._inProgress = true
@._currentUserProjectsPromise = @.getProjectsByUserId(@auth.userData.get("id"))
@._currentUserProjectsPromise.then (projects) =>
@._currentUserProjects = @._currentUserProjects.set("all", projects)
@._currentUserProjects = @._currentUserProjects.set("recents", projects.slice(0, 10))
@._currentUserProjectsById = Immutable.fromJS(groupBy(projects.toJS(), (p) -> p.id))
return @.projects
@._currentUserProjectsPromise.finally =>
@._inProgress = false
return @._currentUserProjectsPromise
newProject: ->
@lightboxFactory.create("tg-lb-create-project", {
"class": "wizard-create-project"
@ -74,5 +44,4 @@ class ProjectsService extends taiga.Service
@rs.projects.bulkUpdateOrder(sortData).then =>
@.fetchProjects()
angular.module("taigaProjects").service("tgProjectsService
", ProjectsService)
angular.module("taigaProjects").service("tgProjectsService", ProjectsService)

View File

@ -35,13 +35,9 @@ describe "tgProjects", ->
provide.value "tgLightboxFactory", mocks.lightboxFactory
_inject = (callback) ->
inject (_$q_, _$rootScope_) ->
inject (_$q_, _$rootScope_, _tgProjectsService_) ->
$q = _$q_
$rootScope = _$rootScope_
callback() if callback
_injectService = (callback) ->
inject (_tgProjectsService_) ->
projectsService = _tgProjectsService_
callback() if callback
@ -60,75 +56,7 @@ describe "tgProjects", ->
_mocks()
_inject()
describe "fetch items", ->
projects = []
beforeEach ->
projects = [
{"id": 1, url: 'url-1', tags: ['xx', 'yy', 'aa'], tags_colors: {xx: "red", yy: "blue", aa: "white"}, colorized_tags: [{name: 'aa', color: 'white'}, {name: 'xx', color: 'red'}, {name: 'yy', color: 'blue'}]},
{"id": 2, url: 'url-2'},
{"id": 3, url: 'url-3'},
{"id": 4, url: 'url-4'},
{"id": 5, url: 'url-5'},
{"id": 6, url: 'url-6'},
{"id": 7, url: 'url-7'},
{"id": 8, url: 'url-8'},
{"id": 9, url: 'url-9'},
{"id": 10, url: 'url-10'},
{"id": 11, url: 'url-11'},
{"id": 12, url: 'url-12'}
]
mocks.resources.projects.getProjectsByUserId = () ->
return $q (resolve) ->
resolve(Immutable.fromJS(projects))
_injectService()
it "all & recents filled", () ->
projectsService.fetchProjects()
$rootScope.$digest()
expect(projectsService.currentUserProjects.get("all").toJS()).to.be.eql(projects)
expect(projectsService.currentUserProjects.get("recents").toJS()).to.be.eql(projects.slice(0, 10))
it "_inProgress change to false when tgResources end", () ->
expect(projectsService._inProgress).to.be.true
$rootScope.$digest()
expect(projectsService._inProgress).to.be.false
it "group projects by id", () ->
$rootScope.$digest()
expect(projectsService.currentUserProjectsById.size).to.be.equal(12)
expect(projectsService.currentUserProjectsById.toJS()[1].id).to.be.equal(projects[0].id)
it "add urls in the project object", () ->
$rootScope.$digest()
expect(projectsService.currentUserProjectsById.toJS()[1].url).to.be.equal("url-1")
expect(projectsService.currentUserProjects.get("all").toJS()[0].url).to.be.equal("url-1")
expect(projectsService.currentUserProjects.get("recents").toJS()[0].url).to.be.equal("url-1")
it "add sorted colorized_tags project object", () ->
$rootScope.$digest()
tags = [
{name: "aa", color: "white"},
{name: "xx", color: "red"},
{name: "yy", color: "blue"}
];
colorized_tags = projectsService.currentUserProjects.get("all").toJS()[0].colorized_tags
expect(colorized_tags).to.be.eql(tags)
it "newProject, create the wizard lightbox", () ->
_injectService()
projectsService.newProject()
expect(mocks.lightboxFactory.create).to.have.been.calledWith("tg-lb-create-project", {
@ -136,8 +64,6 @@ describe "tgProjects", ->
})
it "bulkUpdateProjectsOrder and then fetch projects again", () ->
_injectService()
projects_order = [
{"id": 8},
{"id": 2},
@ -170,8 +96,6 @@ describe "tgProjects", ->
expect(projectsService.fetchProjects).to.have.been.calledOnce
it "getProjectBySlug", () ->
_injectService()
projectSlug = "project-slug"
mocks.resources.projects = {}
@ -181,8 +105,6 @@ describe "tgProjects", ->
expect(projectsService.getProjectBySlug(projectSlug)).to.be.true
it "getProjectStats", () ->
_injectService()
projectId = 3
mocks.resources.projects = {}
@ -190,3 +112,31 @@ describe "tgProjects", ->
mocks.resources.projects.getProjectStats.withArgs(projectId).returns(true)
expect(projectsService.getProjectStats(projectId)).to.be.true
it "getProjectsByUserId", (done) ->
projectId = 3
projects = Immutable.fromJS([
{id: 1, url: 'url-1'},
{id: 2, url: 'url-2', tags: ['xx', 'yy', 'aa'], tags_colors: {xx: "red", yy: "blue", aa: "white"}}
])
mocks.resources.projects = {}
mocks.resources.projects.getProjectsByUserId = sinon.stub().promise()
mocks.resources.projects.getProjectsByUserId.withArgs(projectId).resolve(projects)
projectsService.getProjectsByUserId(projectId).then (projects) ->
expect(projects.toJS()).to.be.eql([{
id: 1,
url: 'url-1'
},
{
id: 2,
url: 'url-2',
tags: ['xx', 'yy', 'aa'],
tags_colors: {xx: "red", yy: "blue", aa: "white"},
colorized_tags: [{name: 'aa', color: 'white'}, {name: 'xx', color: 'red'}, {name: 'yy', color: 'blue'}]
}
])
done()

View File

@ -0,0 +1,45 @@
taiga = @.taiga
groupBy = @.taiga.groupBy
class CurrentUserService
@.$inject = [
"tgProjectsService",
"$tgStorage"
]
constructor: (@projectsService, @storageService) ->
@._user = Immutable.Map()
@._projects = Immutable.Map()
@._projectsById = Immutable.Map()
taiga.defineImmutableProperty @, "projects", () => return @._projects
taiga.defineImmutableProperty @, "projectsById", () => return @._projectsById
getUser: () ->
if !@._user.size
userData = @storageService.get("userInfo")
userData = Immutable.fromJS(userData)
@.setUser(userData) if userData
return @._user
setUser: (user) ->
@._user = user
return @._loadUserInfo()
_loadProjects: () ->
return @projectsService.getProjectsByUserId(@._user.get("id"))
.then (projects) =>
@._projects = @._projects.set("all", projects)
@._projects = @._projects.set("recents", projects.slice(0, 10))
@._projectsById = Immutable.fromJS(groupBy(projects.toJS(), (p) -> p.id))
return @.projects
_loadUserInfo: () ->
return @._loadProjects()
angular.module("taigaCommon").service("tgCurrentUserService", CurrentUserService)

View File

@ -0,0 +1,77 @@
describe "tgCurrentUserService", ->
currentUserService = provide = null
mocks = {}
_mockTgStorage = () ->
mocks.storageService = {
get: sinon.stub()
}
provide.value "$tgStorage", mocks.storageService
_mockProjectsService = () ->
mocks.projectsService = {
getProjectsByUserId: sinon.stub().promise()
}
provide.value "tgProjectsService", mocks.projectsService
_inject = (callback) ->
inject (_tgCurrentUserService_) ->
currentUserService = _tgCurrentUserService_
callback() if callback
_mocks = () ->
module ($provide) ->
provide = $provide
_mockTgStorage()
_mockProjectsService()
return null
_setup = ->
_mocks()
beforeEach ->
module "taigaCommon"
_setup()
_inject()
describe "get user", () ->
it "return the user if it is defined", () ->
currentUserService._user = 123
expect(currentUserService.getUser()).to.be.equal(123)
it "get user form storage if it is not defined", () ->
user = {id: 1, name: "fake1"}
currentUserService.setUser = sinon.spy()
mocks.storageService.get.withArgs("userInfo").returns(user)
_user = currentUserService.getUser()
expect(currentUserService.setUser).to.be.calledOnce
it "set user and load user info", (done) ->
user = Immutable.fromJS({id: 1, name: "fake1"})
projects = Immutable.fromJS([
{id: 1, name: "fake1"},
{id: 2, name: "fake2"},
{id: 3, name: "fake3"},
{id: 4, name: "fake4"},
{id: 5, name: "fake5"}
])
mocks.projectsService.getProjectsByUserId = sinon.stub().promise()
mocks.projectsService.getProjectsByUserId.withArgs(user.get("id")).resolve(projects)
currentUserService.setUser(user).then () ->
expect(currentUserService._user).to.be.equal(user)
expect(currentUserService.projects.get("all").size).to.be.equal(5)
expect(currentUserService.projects.get("recents").size).to.be.equal(5)
expect(currentUserService.projectsById.size).to.be.equal(5)
expect(currentUserService.projectsById.get("3").get("name")).to.be.equal("fake3")
done()

View File

@ -79,7 +79,8 @@
"angular-translate-interpolation-messageformat": "~2.6.1",
"ngInfiniteScroll": "1.0.0",
"eventemitter2": "~0.4.14",
"immutable": "~3.7.2"
"immutable": "~3.7.2",
"bluebird": "~2.9.25"
},
"resolutions": {
"lodash": "~2.4.1",

View File

@ -116,6 +116,7 @@ paths.coffee_order = [
];
paths.libs = [
paths.vendor + "bluebird/js/browser/bluebird.js",
paths.vendor + "jquery/dist/jquery.js",
paths.vendor + "lodash/dist/lodash.js",
paths.vendor + "emoticons/lib/emoticons.js",

View File

@ -18,7 +18,7 @@ module.exports = function(config) {
'karma.app.conf.js',
'dist/js/libs.js',
'node_modules/angular-mocks/angular-mocks.js',
'node_modules/bluebird/js/browser/bluebird.js',
'vendor/bluebird/js/browser/bluebird.js',
'test-utils.js',
'dist/js/app.js',
'dist/js/templates.js',

View File

@ -21,7 +21,6 @@
},
"devDependencies": {
"angular-mocks": "^1.3.15",
"bluebird": "^2.9.21",
"chai": "^2.2.0",
"cli-color": "^0.3.3",
"coffee-script": "^1.9.1",