Skip to content

Commit

Permalink
Merge pull request #19 from rapidpro/master
Browse files Browse the repository at this point in the history
Merge pull request
  • Loading branch information
teehamaral authored Sep 26, 2016
2 parents 2e4f929 + 6c51252 commit b360845
Show file tree
Hide file tree
Showing 86 changed files with 7,644 additions and 7,576 deletions.
166 changes: 146 additions & 20 deletions karma/flows/test_controllers.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ describe 'Controllers:', ->
'rules_first': { id: 2, languages:[], channel_countries: [] },
'loop_detection': { id: 3, languages:[], channel_countries: [] },
'webhook_rule_first': { id: 4, languages:[], channel_countries: [] },
'ussd_example': { id: 5, languages:[], channel_countries: [] },
}

$http.whenGET('/contactfield/json/').respond([])
Expand Down Expand Up @@ -73,15 +74,17 @@ describe 'Controllers:', ->

flowController = null
flowService = null
utils = null

beforeEach inject(($controller, _Flow_) ->
beforeEach inject(($controller, _Flow_, _utils_) ->

flowService = _Flow_
flowController = $controller 'FlowController',
$scope: $scope
$rootScope: $rootScope
$log: $log
Flow: flowService
utils = _utils_
)

getRuleConfig = (type) ->
Expand Down Expand Up @@ -109,9 +112,7 @@ describe 'Controllers:', ->
if not modalScope.splitEditor
modalScope.splitEditor = {}
modalScope.okRules(modalScope.splitEditor)

$timeout.flush()
return ruleset

editAction = (actionset, action, edits) ->
# open our editor modal so we can save it
Expand All @@ -121,6 +122,16 @@ describe 'Controllers:', ->
edits(modalScope)
$timeout.flush()

editRuleset = (ruleset, edits) ->
# open our editor modal so we can save it
$scope.clickRuleset(ruleset)
$scope.dialog.opened.then ->
modalScope = $modalStack.getTop().value.modalScope
edits(modalScope)
modalScope.ok()
$timeout.flush()


it 'should show warning when attempting an infinite loop', ->

flowService.fetch(flows.webhook_rule_first.id).then ->
Expand All @@ -139,7 +150,6 @@ describe 'Controllers:', ->
$http.flush()

it 'should view localized flows without org language', ->

# mock our contact fields
flowService.contactFieldSearch = []

Expand Down Expand Up @@ -177,15 +187,10 @@ describe 'Controllers:', ->

# now toggle our language so we are in translation mode
flowService.language = {iso_code:'ara', name:'Arabic'}
$scope.clickRuleset(ruleset)
$scope.dialog.opened.then ->
modalScope = $modalStack.getTop().value.modalScope

editRuleset ruleset, (scope) ->
# we should be in translation mode now
expect(modalScope.languages.from).toBe('eng')
expect(modalScope.languages.to).toBe('ara')

$timeout.flush()
expect(scope.languages.from).toBe('eng')
expect(scope.languages.to).toBe('ara')

it 'should filter split options based on flow type', ->

Expand Down Expand Up @@ -214,6 +219,14 @@ describe 'Controllers:', ->
expect(scope.isVisibleRulesetType(getRuleConfig('wait_digits'))).toBe(false)
expect(scope.isVisibleRulesetType(getRuleConfig('webhook'))).toBe(false)

# USSD flow
flowService.flow.flow_type = 'U'
expect(scope.isVisibleRulesetType(getRuleConfig('wait_menu'))).toBe(true)
expect(scope.isVisibleRulesetType(getRuleConfig('wait_ussd'))).toBe(true)
expect(scope.isVisibleRulesetType(getRuleConfig('wait_message'))).toBe(false)

$timeout.flush()

it 'should create timeout rules if necessary', ->

loadFavoritesFlow()
Expand All @@ -235,6 +248,101 @@ describe 'Controllers:', ->
expect(lastRule['test']['type']).toBe('timeout')
expect(lastRule['test']['minutes']).toBe(10)

it 'should save group split rulesets', ->
loadFavoritesFlow()
ruleset = flowService.flow.rule_sets[0]

editRules ruleset, (scope) ->
scope.ruleset.ruleset_type = 'group'
scope.splitEditor =
omnibox:
selected:
groups: [{name:"Can't Hold Us", id:'group1_uuid'}]
variables: []

ruleset = flowService.flow.rule_sets[0]
expect(ruleset.ruleset_type).toBe('group')
expect(ruleset.rules.length).toBe(2)
expect(ruleset.operand).toBe('@step.value')
expect(JSON.stringify(ruleset.rules[0].test)).toBe('{"type":"in_group","test":{"name":"Can\'t Hold Us","uuid":"group1_uuid"}}')
expect(JSON.stringify(ruleset.rules[1].test)).toBe('{"test":"true","type":"true"}')

it 'should retain destination for group split', ->
loadFavoritesFlow()

ruleset = flowService.flow.rule_sets[0]
editRules ruleset, (scope) ->
scope.ruleset.ruleset_type = 'group'
scope.splitEditor =
omnibox:
selected:
groups: [{name:"Can't Hold Us", id:'group1_uuid'}]
variables: []

# set a destination
flowService.flow.rule_sets[0].rules[0]['destination'] = flowService.flow.action_sets[1].uuid

# now edit our rule again
ruleset = flowService.flow.rule_sets[0]
editRules ruleset, (scope) ->
scope.ruleset.ruleset_type = 'group'
scope.splitEditor =
omnibox:
selected:
groups: [
{ name:"Can't Hold Us", id:'group1_uuid' }
{ name:"In the Pines", id:'group2_uuid' }
{ name:"New Group" }
]
variables: []

ruleset = flowService.flow.rule_sets[0]
expect(ruleset.rules.length).toBe(4)

expect(ruleset.rules[0]['destination']).toBe(flowService.flow.action_sets[1].uuid)
expect(JSON.stringify(ruleset.rules[0].test)).toBe('{"type":"in_group","test":{"name":"Can\'t Hold Us","uuid":"group1_uuid"}}')
expect(JSON.stringify(ruleset.rules[1].test)).toBe('{"type":"in_group","test":{"name":"In the Pines","uuid":"group2_uuid"}}')
expect(JSON.stringify(ruleset.rules[2].test)).toBe('{"type":"in_group","test":{"name":"New Group"}}')
expect(JSON.stringify(ruleset.rules[3].test)).toBe('{"test":"true","type":"true"}')

it 'should honor order when saving group split', ->

loadFavoritesFlow()
ruleset = flowService.flow.rule_sets[0]

# now try reordering our rules
editRules ruleset, (scope) ->
scope.ruleset.ruleset_type = 'group'
scope.splitEditor =
omnibox:
selected:
groups: [
{ name:"Can't Hold Us", id:'group1_uuid' }
{ name:"In the Pines", id:'group2_uuid' }
]
variables: []

ruleset = flowService.flow.rule_sets[0]

# now try reordering our rules
editRules ruleset, (scope) ->
scope.ruleset.ruleset_type = 'group'
scope.splitEditor =
omnibox:
selected:
groups: [
{ name:"In the Pines", id:'group2_uuid' }
{ name:"Can't Hold Us", id:'group1_uuid' }
]
variables: []

ruleset = flowService.flow.rule_sets[0]
expect(ruleset.rules.length).toBe(3)

# check that our order has been swapped
expect(JSON.stringify(ruleset.rules[0].test)).toBe('{"type":"in_group","test":{"name":"In the Pines","uuid":"group2_uuid"}}')
expect(JSON.stringify(ruleset.rules[1].test)).toBe('{"type":"in_group","test":{"name":"Can\'t Hold Us","uuid":"group1_uuid"}}')

it 'should save random rulesets', ->
loadFavoritesFlow()

Expand Down Expand Up @@ -472,6 +580,13 @@ describe 'Controllers:', ->
expect(modalScope.validActionFilter(getAction('play'))).toBe(false)
expect(modalScope.validActionFilter(getAction('api'))).toBe(false)

# USSD flow
flowService.flow.flow_type = 'U'
expect(modalScope.validActionFilter(getAction('reply'))).toBe(true)
expect(modalScope.validActionFilter(getAction('say'))).toBe(false)
expect(modalScope.validActionFilter(getAction('play'))).toBe(false)
expect(modalScope.validActionFilter(getAction('api'))).toBe(false)

$timeout.flush()

it 'should allow users to create groups in place', ->
Expand Down Expand Up @@ -578,15 +693,29 @@ describe 'Controllers:', ->

$timeout.flush()

it 'should have the USSD Menu synced with ruleset', ->

# load a USSD flow
flowService.fetch(flows.ussd_example.id)
flowService.contactFieldSearch = []
flowService.language = {iso_code:'base'}
$http.flush()

ruleset = flowService.flow.rule_sets[0]
editRuleset ruleset, (scope) ->
for rule in scope.ruleset.rules
if rule.label
expect(rule.uuid).toBeDefined()
expect(rule.category.base).toBeDefined()
expect(rule.label).toBeDefined()
expect(rule._config.type).toBe('eq')

it 'isRuleComplete should have proper validation', ->

loadFavoritesFlow()

ruleset = flowService.flow.rule_sets[0]
$scope.clickRuleset(ruleset)

$scope.dialog.opened.then ->
modalScope = $modalStack.getTop().value.modalScope
editRuleset ruleset, (scope) ->

rule_tests = [
{rule: {category: null, _config: {operands: null}, test: {}}, complete: false},
Expand All @@ -606,7 +735,4 @@ describe 'Controllers:', ->
]

for rule_test in rule_tests
expect(modalScope.isRuleComplete(rule_test['rule'])).toBe(rule_test['complete'])

$timeout.flush()

expect(scope.isRuleComplete(rule_test['rule'])).toBe(rule_test['complete'])
71 changes: 71 additions & 0 deletions karma/flows/test_directives.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,74 @@ describe 'Directives:', ->
expect(ele.html()).toMatch(/ng-invalid-validate-type/)


describe 'USSD directive', ->

scope = null
ele = null
html = null
result = null

beforeEach ->
Flow.flow = utils.clone(getJSONFixture('ussd_example.json').flows[0])
scope = $rootScope.$new()

compileElement = ->
scope.ruleset = []
scope.ruleset.rules = []

ele = $compile(ele)(scope)
scope.$digest()
$timeout.flush()

html = ele.html()
result = ele.children().scope()

it 'should have USSD flow type', ->
expect(Flow.flow.flow_type).toBe('U')

it 'should create a USSD Menu widget', ->
# ussd="0" is for USSD Menu functionality
ele = angular.element("<div ng-form><span class='wait-ussd' ussd='0'/></div>")

compileElement()

expect(html).toContain('Add menu:')

expect(result.USSD_MENU).toBeTruthy()
expect(result.USSD_RESPONSE).toBeFalsy()

# USSD menu directive creates a default menu point for the widget, that initially takes up some characters
expect(result.characters).toBe(178)

it 'should create a USSD response widget', ->
# ussd="1" is for USSD Response functionality
ele = angular.element("<div ng-form><span class='wait-ussd' ussd='1'/></div>")

compileElement()

expect(result.USSD_MENU).toBeFalsy()
expect(result.USSD_RESPONSE).toBeTruthy()

# no menus here, the default textarea is initially empty hence should be the max length of a USSD message
expect(result.characters).toBe(182)

it 'should call countCharacters for every menu change', ->

ele = angular.element("<div ng-form><span class='wait-ussd' ussd='0'/></div>")

compileElement()

spyOn(result, 'countCharacters')

testItem =
uuid: uuid()
option: ""
label:
base: ""
category:
_autoName: true
_base: ""

result.updateMenu(testItem, 0)

expect(result.countCharacters).toHaveBeenCalled();
25 changes: 24 additions & 1 deletion karma/flows/test_services.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ describe 'Services:', ->

# wire up our mock flows
flows = {
'favorites': { id: 1, languages:[] },
'favorites': { id: 1, languages:[] }
'rules_first': { id: 2, languages:[] }
'loop_detection': { id: 3, languages:[] }
'ussd_example': { id: 4, languages:[] }
}

$http.whenGET('/contactfield/json/').respond([])
Expand Down Expand Up @@ -329,6 +330,28 @@ describe 'Services:', ->
allowed = flowService.isConnectionAllowed(endOfFlow, messageSplitA)
expect(allowed).toBe(true, 'Failed to find expression step value')


describe 'isConnectionAllowed() with USSD rulesets', ->
flow = null
beforeEach ->
flowService.fetch(flows.ussd_example.id).then ->
flow = flowService.flow
$http.flush()

ussdMenu = '5e0fe53f-1caa-434d-97e7-189f33353372'
ussdResponse = '66aa0bb5-d1e5-4026-a056-fd22c353539e'

it 'should have the appropriate flow type', ->
expect(flow.flow_type).toBe('U')

it 'should allow two rulesets connected', ->
ruleConnection = flowService.isConnectionAllowed(ussdMenu, ussdResponse)
expect(ruleConnection).toBeTruthy()

it 'should allow self loops', ->
ruleLoop = flowService.isConnectionAllowed(ussdMenu, ussdMenu)
expect(ruleLoop).toBeTruthy()

describe 'getFieldSelection()', ->

flow = null
Expand Down
Loading

0 comments on commit b360845

Please sign in to comment.