<commit_before>// ***********************************************//
//                 Router
// ***********************************************//
require('akvo-flow/core-common');

FLOW.Router = Ember.Router.extend({
  enableLogging: true,
  loggedIn: false,
  location: 'none',
  //'hash'or 'none' for URLs

  resetState: function () {
    // We could have unsaved changes
    FLOW.store.commit();

    FLOW.selectedControl.set('selectedQuestionGroup', null);
    FLOW.selectedControl.set('selectedSurveyGroup', null);
    FLOW.selectedControl.set('selectedSurvey', null);
    FLOW.selectedControl.set('selectedQuestion', null);
    FLOW.selectedControl.set('selectedCascadeResource', null);
    FLOW.selectedControl.set('cascadeImportNumLevels', null);
    FLOW.selectedControl.set('cascadeImportIncludeCodes', null);
    FLOW.surveyControl.set('content', null);
    FLOW.questionControl.set('OPTIONcontent', null);
    FLOW.metaControl.set('since', null);
  },

  root: Ember.Route.extend({
    doNavSurveys: function (router, context) {
      router.transitionTo('navSurveys.index');
    },
    doNavDevices: function (router, context) {
      router.transitionTo('navDevices.index');
    },
    doNavData: function (router, context) {
      router.transitionTo('navData.index');
    },
    doNavResources: function (router, context) {
      router.transitionTo('navResources.index');
    },
    doNavMaps: function (router, context) {
      router.transitionTo('navMaps');
    },
    doNavUsers: function (router, context) {
      router.transitionTo('navUsers');
    },
    doNavMessages: function (router, context) {
      router.transitionTo('navMessages');
    },
    // not used at the moment
    doNavAdmin: function (router, context) {
      router.transitionTo('navAdmin');
    },

    // non-working code for transitioning to navHome at first entry of the app
    //    setup: function(router){
    //      router.send("goHome");
    //    },
    //    goHome:function(router){
    //      router.transitionTo('navHome');
    //    },
    index: Ember.Route.extend({
      route: '/',
      redirectsTo: 'navSurveys.index'
    }),

    // ******************* SURVEYS ROUTER ********************
    navSurveys: Ember.Route.extend({
      route: '/surveys',
      connectOutlets: function (router, event) {
        router.get('applicationController').connectOutlet('navSurveys');
        router.set('navigationController.selected', 'navSurveys');
      },

      doNewSurvey: function (router, event) {
        router.transitionTo('navSurveys.navSurveysNew');
      },

      doEditSurvey: function (router, event) {
        FLOW.selectedControl.set('selectedSurvey', event.context);
        router.transitionTo('navSurveys.navSurveysEdit.index');
      },

      doSurveysMain: function (router, event) {
        FLOW.selectedControl.set('selectedQuestion', null);
        router.transitionTo('navSurveys.navSurveysMain');
      },

      index: Ember.Route.extend({
        route: '/',
        redirectsTo: 'navSurveysMain'
      }),

      navSurveysMain: Ember.Route.extend({
        route: '/main',
        connectOutlets: function (router, event) {
          router.get('navSurveysController').connectOutlet({
            name: 'navSurveysMain'
          });
          FLOW.projectControl.populate();
          FLOW.cascadeResourceControl.populate();
          FLOW.projectControl.set('currentProject', null);
          FLOW.projectControl.set('newlyCreated', null);
          FLOW.selectedControl.set('selectedQuestionGroup', null);
          FLOW.selectedControl.set('selectedSurvey', null);
          FLOW.selectedControl.set('selectedQuestion', null);
          FLOW.questionControl.set('OPTIONcontent', null);
        }
      }),

      navSurveysNew: Ember.Route.extend({
        route: '/new',
        connectOutlets: function (router, event) {
          var newSurvey;

          newSurvey = FLOW.store.createRecord(FLOW.Survey, {
            "name": "",
            "defaultLanguageCode": "en",
            "requireApproval": false,
            "status": "NOT_PUBLISHED",
            "surveyGroupId": FLOW.selectedControl.selectedSurveyGroup.get('keyId'),
            "version":"1.0"
          });

          FLOW.selectedControl.set('selectedSurvey', newSurvey);
          router.transitionTo('navSurveys.navSurveysEdit.index');
        }
      }),

      navSurveysEdit: Ember.Route.extend({
        route: '/edit',
        connectOutlets: function (router, event) {
          router.get('navSurveysController').connectOutlet({
            name: 'navSurveysEdit'
          });
          // all questions should be closed when we enter
          FLOW.selectedControl.set('selectedQuestion', null);
        },

        doEditQuestions: function (router, event) {
          router.transitionTo('navSurveys.navSurveysEdit.editQuestions');
        },

        index: Ember.Route.extend({
          route: '/',
          redirectsTo: 'editQuestions'
        }),

        manageNotifications: Ember.Route.extend({
          route: '/notifications',
          connectOutlets: function (router, event) {
            router.get('navSurveysEditController').connectOutlet({
              name: 'manageNotifications'
            });
            FLOW.notificationControl.populate();
          }
        }),

        manageTranslations: Ember.Route.extend({
          route: '/translations',
          connectOutlets: function (router, event) {
            router.get('navSurveysEditController').connectOutlet({
              name: 'manageTranslations'
            });
            FLOW.translationControl.populate();
          }
        }),

        editQuestions: Ember.Route.extend({
          route: '/questions',
          connectOutlets: function (router, event) {
            router.get('navSurveysEditController').connectOutlet({
              name: 'editQuestions'
            });

          }
        })
      })
    }),

    //********************** DEVICES ROUTER *******************
    navDevices: Ember.Route.extend({
      route: '/devices',
      connectOutlets: function (router, event) {
        router.get('applicationController').connectOutlet('navDevices');
        router.set('navigationController.selected', 'navDevices');
      },

      doCurrentDevices: function (router, event) {
        router.transitionTo('navDevices.currentDevices');
      },

      doAssignSurveysOverview: function (router, event) {
        router.transitionTo('navDevices.assignSurveysOverview');
      },

      doEditSurveysAssignment: function (router, event) {
        router.transitionTo('navDevices.editSurveysAssignment');
      },

      doSurveyBootstrap: function (router, event) {
        router.transitionTo('navDevices.surveyBootstrap');
      },

      index: Ember.Route.extend({
        route: '/',
        redirectsTo: 'currentDevices'
      }),

      currentDevices: Ember.Route.extend({
        route: '/current-devices',
        connectOutlets: function (router, context) {
          router.get('navDevicesController').connectOutlet('currentDevices');
          router.resetState();
          FLOW.deviceGroupControl.populate();
          FLOW.deviceControl.populate();
          router.set('devicesSubnavController.selected', 'currentDevices');
        }
      }),

      assignSurveysOverview: Ember.Route.extend({
        route: '/assign-surveys',
        connectOutlets: function (router, context) {
          router.get('navDevicesController').connectOutlet('assignSurveysOverview');
          FLOW.surveyAssignmentControl.populate();
          router.set('devicesSubnavController.selected', 'assignSurveys');
        }
      }),

      editSurveysAssignment: Ember.Route.extend({
        route: '/assign-surveys',
        connectOutlets: function (router, context) {
          router.get('navDevicesController').connectOutlet('editSurveyAssignment');
          router.set('devicesSubnavController.selected', 'assignSurveys');
        }
      }),

      surveyBootstrap: Ember.Route.extend({
        route: '/manual-transfer',
        connectOutlets: function (router, context) {
          router.get('navDevicesController').connectOutlet('surveyBootstrap');
          router.set('devicesSubnavController.selected', 'surveyBootstrap');
        }
      })
    }),

    // ******************* DATA ROUTER ***********************
    navData: Ember.Route.extend({
      route: '/data',
      connectOutlets: function (router, event) {
        router.get('applicationController').connectOutlet('navData');
        router.set('navigationController.selected', 'navData');
      },

      doInspectData: function (router, event) {
        router.transitionTo('navData.inspectData');
      },
      doBulkUpload: function (router, event) {
        router.transitionTo('navData.bulkUpload');
      },
      doDataCleaning: function (router, event) {
        router.transitionTo('navData.dataCleaning');
      },
      doMonitoringData: function (router, event) {
        router.transitionTo('navData.monitoringData');
      },

      doReportsList: function (router, event) {
        router.transitionTo('navData.reportsList');
      },

      doExportReports: function (router, event) {
        router.transitionTo('navData.exportReports');
      },

      doChartReports: function (router, event) {
        router.transitionTo('navData.chartReports');
      },

      index: Ember.Route.extend({
        route: '/',
        redirectsTo:  'inspectData'
      }),

      inspectData: Ember.Route.extend({
        route: '/inspectdata',
        connectOutlets: function (router, context) {
          router.get('navDataController').connectOutlet('inspectData');
          router.set('datasubnavController.selected', 'inspectData');
          router.resetState();
        }
      }),

      bulkUpload: Ember.Route.extend({
        route: '/bulkupload',
        connectOutlets: function (router, context) {
          router.get('navDataController').connectOutlet('bulkUpload');
          router.set('datasubnavController.selected', 'bulkUpload');
        }
      }),

      dataCleaning: Ember.Route.extend({
        route: '/datacleaning',
        connectOutlets: function (router, context) {
          router.get('navDataController').connectOutlet('dataCleaning');
          router.set('datasubnavController.selected', 'dataCleaning');
          router.resetState();
        }
      }),

      monitoringData: Ember.Route.extend({
        route: '/monitoringdata',
        connectOutlets: function (router, context) {
          router.get('navDataController').connectOutlet('monitoringData');
          router.set('datasubnavController.selected', 'monitoringData');
          router.resetState();
        }
      }),

      reportsList: Ember.Route.extend({
        route: '/reportslist',
        connectOutlets: function (router, context) {
          //if landing on tab, show reports list first
          router.get('navDataController').connectOutlet('reportsList');
          router.set('datasubnavController.selected', 'exportReports');
          router.resetState();
        }

      }),

      exportReports: Ember.Route.extend({
        route: '/exportreports',
        connectOutlets: function (router, context) {
          router.get('navDataController').connectOutlet('exportReports');
          router.set('datasubnavController.selected', 'exportReports');
          router.resetState();
        }
      }),

      chartReports: Ember.Route.extend({
        route: '/chartreports',
        connectOutlets: function (router, context) {
          router.resetState();
          router.get('navDataController').connectOutlet('chartReports');
          router.set('datasubnavController.selected', 'chartReports');
        }
      })
    }),

    // ************************** RESOURCES ROUTER **********************************
    navResources: Ember.Route.extend({
      route: '/resources',
      connectOutlets: function (router, event) {
        router.get('applicationController').connectOutlet('navResources');
        router.set('navigationController.selected', 'navResources');
      },

      doCascadeResources: function (router, event) {
        router.transitionTo('navResources.cascadeResources');
      },

      doDataApproval: function (router, event) {
          router.transitionTo('navResources.dataApproval.listApprovalGroups');
      },

      index: Ember.Route.extend({
        route: '/',
        redirectsTo: 'cascadeResources'
      }),

      cascadeResources: Ember.Route.extend({
        route: '/cascaderesources',
        connectOutlets: function (router, context) {
          router.get('navResourcesController').connectOutlet('cascadeResources');
          router.set('resourcesSubnavController.selected', 'cascadeResources');
          FLOW.cascadeResourceControl.populate();
        }
      }),

      dataApproval: Ember.Route.extend({
          route: '/dataapproval',

          connectOutlets: function (router, context) {
              router.get('navResourcesController').connectOutlet('dataApproval');
              router.set('resourcesSubnavController.selected', 'approvalGroup');
          },

          doAddApprovalGroup: function (router, event) {
              router.get('approvalGroupController').add();
              router.get('approvalStepsController').loadByGroupId();
              router.transitionTo('navResourcesController.dataApproval.editApprovalGroup');
          },

          doEditApprovalGroup: function (router, event) {
              var groupId = event.context.get('keyId');
              var lastLoadedGroup = router.get('approvalGroupController').get('content');
              if (!lastLoadedGroup || (lastLoadedGroup.get('keyId') !== groupId)) {
                  router.get('approvalGroupController').load(groupId);
                  router.get('approvalStepsController').loadByGroupId(groupId);
              }
              router.transitionTo('navResourcesController.dataApproval.editApprovalGroup');
          },

          doSaveApprovalGroup: function (router, event) {
              router.get('approvalGroupController').save();
              router.transitionTo('navResourcesController.dataApproval.listApprovalGroups');
          },

          doCancelEditApprovalGroup: function (router, event) {
              router.get('approvalGroupController').cancel();
              router.transitionTo('navResourcesController.dataApproval.listApprovalGroups');
          },

          doDeleteApprovalGroup: function (router, event) {
              var group = event.context;
              router.get('approvalGroupListController').delete(group);
          },

          // default route for dataApproval tab
          listApprovalGroups: Ember.Route.extend({
              route: '/list',

              connectOutlets: function (router, context) {
                  router.get('dataApprovalController').connectOutlet('approvalMain', 'approvalGroupList');
                  var approvalList = router.get('approvalGroupListController');
                  if (!approvalList.get('content')) {
                      approvalList.set('content', FLOW.ApprovalGroup.find())
                  }
              },
          }),

          editApprovalGroup: Ember.Route.extend({
              route: '/approvalsteps',

              connectOutlets: function (router, event) {
                  router.get('dataApprovalController').connectOutlet('approvalMain', 'approvalGroup');
                  router.get('approvalGroupController').connectOutlet('approvalStepsOutlet', 'approvalSteps');
              },
          }),
      })
    }),

    // ************************** MAPS ROUTER **********************************
    navMaps: Ember.Route.extend({
      route: '/maps',
      connectOutlets: function (router, context) {
        router.get('applicationController').connectOutlet('navMaps');
        router.set('navigationController.selected', 'navMaps');
      }
    }),

    // ************************** USERS ROUTER **********************************
    navUsers: Ember.Route.extend({
      route: '/users',
      connectOutlets: function (router, context) {
        router.get('applicationController').connectOutlet('navUsers');
        router.set('navigationController.selected', 'navUsers');
      }
    }),

    // ************************** MESSAGES ROUTER **********************************
    navMessages: Ember.Route.extend({
      route: '/users',
      connectOutlets: function (router, context) {
        router.get('applicationController').connectOutlet('navMessages');
        router.set('navigationController.selected', 'navMessages');
        FLOW.messageControl.populate();
        router.resetState();
      }
    }),

    // ************************** ADMIN ROUTER **********************************
    // not used at the moment
    navAdmin: Ember.Route.extend({
      route: '/admin',
      connectOutlets: function (router, context) {
        router.get('applicationController').connectOutlet('navAdmin');
        router.set('navigationController.selected', 'navAdmin');
      }
    })
  })
});
<commit_msg>[#2731] fix data approval transition<commit_after>// ***********************************************//
//                 Router
// ***********************************************//
require('akvo-flow/core-common');

FLOW.Router = Ember.Router.extend({
  enableLogging: true,
  loggedIn: false,
  location: 'none',
  //'hash'or 'none' for URLs

  resetState: function () {
    // We could have unsaved changes
    FLOW.store.commit();

    FLOW.selectedControl.set('selectedQuestionGroup', null);
    FLOW.selectedControl.set('selectedSurveyGroup', null);
    FLOW.selectedControl.set('selectedSurvey', null);
    FLOW.selectedControl.set('selectedQuestion', null);
    FLOW.selectedControl.set('selectedCascadeResource', null);
    FLOW.selectedControl.set('cascadeImportNumLevels', null);
    FLOW.selectedControl.set('cascadeImportIncludeCodes', null);
    FLOW.surveyControl.set('content', null);
    FLOW.questionControl.set('OPTIONcontent', null);
    FLOW.metaControl.set('since', null);
  },

  root: Ember.Route.extend({
    doNavSurveys: function (router, context) {
      router.transitionTo('navSurveys.index');
    },
    doNavDevices: function (router, context) {
      router.transitionTo('navDevices.index');
    },
    doNavData: function (router, context) {
      router.transitionTo('navData.index');
    },
    doNavResources: function (router, context) {
      router.transitionTo('navResources.index');
    },
    doNavMaps: function (router, context) {
      router.transitionTo('navMaps');
    },
    doNavUsers: function (router, context) {
      router.transitionTo('navUsers');
    },
    doNavMessages: function (router, context) {
      router.transitionTo('navMessages');
    },
    // not used at the moment
    doNavAdmin: function (router, context) {
      router.transitionTo('navAdmin');
    },

    // non-working code for transitioning to navHome at first entry of the app
    //    setup: function(router){
    //      router.send("goHome");
    //    },
    //    goHome:function(router){
    //      router.transitionTo('navHome');
    //    },
    index: Ember.Route.extend({
      route: '/',
      redirectsTo: 'navSurveys.index'
    }),

    // ******************* SURVEYS ROUTER ********************
    navSurveys: Ember.Route.extend({
      route: '/surveys',
      connectOutlets: function (router, event) {
        router.get('applicationController').connectOutlet('navSurveys');
        router.set('navigationController.selected', 'navSurveys');
      },

      doNewSurvey: function (router, event) {
        router.transitionTo('navSurveys.navSurveysNew');
      },

      doEditSurvey: function (router, event) {
        FLOW.selectedControl.set('selectedSurvey', event.context);
        router.transitionTo('navSurveys.navSurveysEdit.index');
      },

      doSurveysMain: function (router, event) {
        FLOW.selectedControl.set('selectedQuestion', null);
        router.transitionTo('navSurveys.navSurveysMain');
      },

      index: Ember.Route.extend({
        route: '/',
        redirectsTo: 'navSurveysMain'
      }),

      navSurveysMain: Ember.Route.extend({
        route: '/main',
        connectOutlets: function (router, event) {
          router.get('navSurveysController').connectOutlet({
            name: 'navSurveysMain'
          });
          FLOW.projectControl.populate();
          FLOW.cascadeResourceControl.populate();
          FLOW.projectControl.set('currentProject', null);
          FLOW.projectControl.set('newlyCreated', null);
          FLOW.selectedControl.set('selectedQuestionGroup', null);
          FLOW.selectedControl.set('selectedSurvey', null);
          FLOW.selectedControl.set('selectedQuestion', null);
          FLOW.questionControl.set('OPTIONcontent', null);
        }
      }),

      navSurveysNew: Ember.Route.extend({
        route: '/new',
        connectOutlets: function (router, event) {
          var newSurvey;

          newSurvey = FLOW.store.createRecord(FLOW.Survey, {
            "name": "",
            "defaultLanguageCode": "en",
            "requireApproval": false,
            "status": "NOT_PUBLISHED",
            "surveyGroupId": FLOW.selectedControl.selectedSurveyGroup.get('keyId'),
            "version":"1.0"
          });

          FLOW.selectedControl.set('selectedSurvey', newSurvey);
          router.transitionTo('navSurveys.navSurveysEdit.index');
        }
      }),

      navSurveysEdit: Ember.Route.extend({
        route: '/edit',
        connectOutlets: function (router, event) {
          router.get('navSurveysController').connectOutlet({
            name: 'navSurveysEdit'
          });
          // all questions should be closed when we enter
          FLOW.selectedControl.set('selectedQuestion', null);
        },

        doEditQuestions: function (router, event) {
          router.transitionTo('navSurveys.navSurveysEdit.editQuestions');
        },

        index: Ember.Route.extend({
          route: '/',
          redirectsTo: 'editQuestions'
        }),

        manageNotifications: Ember.Route.extend({
          route: '/notifications',
          connectOutlets: function (router, event) {
            router.get('navSurveysEditController').connectOutlet({
              name: 'manageNotifications'
            });
            FLOW.notificationControl.populate();
          }
        }),

        manageTranslations: Ember.Route.extend({
          route: '/translations',
          connectOutlets: function (router, event) {
            router.get('navSurveysEditController').connectOutlet({
              name: 'manageTranslations'
            });
            FLOW.translationControl.populate();
          }
        }),

        editQuestions: Ember.Route.extend({
          route: '/questions',
          connectOutlets: function (router, event) {
            router.get('navSurveysEditController').connectOutlet({
              name: 'editQuestions'
            });

          }
        })
      })
    }),

    //********************** DEVICES ROUTER *******************
    navDevices: Ember.Route.extend({
      route: '/devices',
      connectOutlets: function (router, event) {
        router.get('applicationController').connectOutlet('navDevices');
        router.set('navigationController.selected', 'navDevices');
      },

      doCurrentDevices: function (router, event) {
        router.transitionTo('navDevices.currentDevices');
      },

      doAssignSurveysOverview: function (router, event) {
        router.transitionTo('navDevices.assignSurveysOverview');
      },

      doEditSurveysAssignment: function (router, event) {
        router.transitionTo('navDevices.editSurveysAssignment');
      },

      doSurveyBootstrap: function (router, event) {
        router.transitionTo('navDevices.surveyBootstrap');
      },

      index: Ember.Route.extend({
        route: '/',
        redirectsTo: 'currentDevices'
      }),

      currentDevices: Ember.Route.extend({
        route: '/current-devices',
        connectOutlets: function (router, context) {
          router.get('navDevicesController').connectOutlet('currentDevices');
          router.resetState();
          FLOW.deviceGroupControl.populate();
          FLOW.deviceControl.populate();
          router.set('devicesSubnavController.selected', 'currentDevices');
        }
      }),

      assignSurveysOverview: Ember.Route.extend({
        route: '/assign-surveys',
        connectOutlets: function (router, context) {
          router.get('navDevicesController').connectOutlet('assignSurveysOverview');
          FLOW.surveyAssignmentControl.populate();
          router.set('devicesSubnavController.selected', 'assignSurveys');
        }
      }),

      editSurveysAssignment: Ember.Route.extend({
        route: '/assign-surveys',
        connectOutlets: function (router, context) {
          router.get('navDevicesController').connectOutlet('editSurveyAssignment');
          router.set('devicesSubnavController.selected', 'assignSurveys');
        }
      }),

      surveyBootstrap: Ember.Route.extend({
        route: '/manual-transfer',
        connectOutlets: function (router, context) {
          router.get('navDevicesController').connectOutlet('surveyBootstrap');
          router.set('devicesSubnavController.selected', 'surveyBootstrap');
        }
      })
    }),

    // ******************* DATA ROUTER ***********************
    navData: Ember.Route.extend({
      route: '/data',
      connectOutlets: function (router, event) {
        router.get('applicationController').connectOutlet('navData');
        router.set('navigationController.selected', 'navData');
      },

      doInspectData: function (router, event) {
        router.transitionTo('navData.inspectData');
      },
      doBulkUpload: function (router, event) {
        router.transitionTo('navData.bulkUpload');
      },
      doDataCleaning: function (router, event) {
        router.transitionTo('navData.dataCleaning');
      },
      doMonitoringData: function (router, event) {
        router.transitionTo('navData.monitoringData');
      },

      doReportsList: function (router, event) {
        router.transitionTo('navData.reportsList');
      },

      doExportReports: function (router, event) {
        router.transitionTo('navData.exportReports');
      },

      doChartReports: function (router, event) {
        router.transitionTo('navData.chartReports');
      },

      index: Ember.Route.extend({
        route: '/',
        redirectsTo:  'inspectData'
      }),

      inspectData: Ember.Route.extend({
        route: '/inspectdata',
        connectOutlets: function (router, context) {
          router.get('navDataController').connectOutlet('inspectData');
          router.set('datasubnavController.selected', 'inspectData');
          router.resetState();
        }
      }),

      bulkUpload: Ember.Route.extend({
        route: '/bulkupload',
        connectOutlets: function (router, context) {
          router.get('navDataController').connectOutlet('bulkUpload');
          router.set('datasubnavController.selected', 'bulkUpload');
        }
      }),

      dataCleaning: Ember.Route.extend({
        route: '/datacleaning',
        connectOutlets: function (router, context) {
          router.get('navDataController').connectOutlet('dataCleaning');
          router.set('datasubnavController.selected', 'dataCleaning');
          router.resetState();
        }
      }),

      monitoringData: Ember.Route.extend({
        route: '/monitoringdata',
        connectOutlets: function (router, context) {
          router.get('navDataController').connectOutlet('monitoringData');
          router.set('datasubnavController.selected', 'monitoringData');
          router.resetState();
        }
      }),

      reportsList: Ember.Route.extend({
        route: '/reportslist',
        connectOutlets: function (router, context) {
          //if landing on tab, show reports list first
          router.get('navDataController').connectOutlet('reportsList');
          router.set('datasubnavController.selected', 'exportReports');
          router.resetState();
        }

      }),

      exportReports: Ember.Route.extend({
        route: '/exportreports',
        connectOutlets: function (router, context) {
          router.get('navDataController').connectOutlet('exportReports');
          router.set('datasubnavController.selected', 'exportReports');
          router.resetState();
        }
      }),

      chartReports: Ember.Route.extend({
        route: '/chartreports',
        connectOutlets: function (router, context) {
          router.resetState();
          router.get('navDataController').connectOutlet('chartReports');
          router.set('datasubnavController.selected', 'chartReports');
        }
      })
    }),

    // ************************** RESOURCES ROUTER **********************************
    navResources: Ember.Route.extend({
      route: '/resources',
      connectOutlets: function (router, event) {
        router.get('applicationController').connectOutlet('navResources');
        router.set('navigationController.selected', 'navResources');
      },

      doCascadeResources: function (router, event) {
        router.transitionTo('navResources.cascadeResources');
      },

      doDataApproval: function (router, event) {
          router.transitionTo('navResources.dataApproval.listApprovalGroups');
      },

      index: Ember.Route.extend({
        route: '/',
        redirectsTo: 'cascadeResources'
      }),

      cascadeResources: Ember.Route.extend({
        route: '/cascaderesources',
        connectOutlets: function (router, context) {
          router.get('navResourcesController').connectOutlet('cascadeResources');
          router.set('resourcesSubnavController.selected', 'cascadeResources');
          FLOW.cascadeResourceControl.populate();
        }
      }),

      dataApproval: Ember.Route.extend({
          route: '/dataapproval',

          connectOutlets: function (router, context) {
              router.get('navResourcesController').connectOutlet('dataApproval');
              router.set('resourcesSubnavController.selected', 'approvalGroup');
          },

          doAddApprovalGroup: function (router, event) {
              router.get('approvalGroupController').add();
              router.get('approvalStepsController').loadByGroupId();
              router.transitionTo('navResources.dataApproval.editApprovalGroup');
          },

          doEditApprovalGroup: function (router, event) {
              var groupId = event.context.get('keyId');
              var lastLoadedGroup = router.get('approvalGroupController').get('content');
              if (!lastLoadedGroup || (lastLoadedGroup.get('keyId') !== groupId)) {
                  router.get('approvalGroupController').load(groupId);
                  router.get('approvalStepsController').loadByGroupId(groupId);
              }
              router.transitionTo('navResources.dataApproval.editApprovalGroup');
          },

          doSaveApprovalGroup: function (router, event) {
              router.get('approvalGroupController').save();
              router.transitionTo('navResources.dataApproval.listApprovalGroups');
          },

          doCancelEditApprovalGroup: function (router, event) {
              router.get('approvalGroupController').cancel();
              router.transitionTo('navResources.dataApproval.listApprovalGroups');
          },

          doDeleteApprovalGroup: function (router, event) {
              var group = event.context;
              router.get('approvalGroupListController').delete(group);
          },

          // default route for dataApproval tab
          listApprovalGroups: Ember.Route.extend({
              route: '/list',

              connectOutlets: function (router, context) {
                  router.get('dataApprovalController').connectOutlet('approvalMain', 'approvalGroupList');
                  var approvalList = router.get('approvalGroupListController');
                  if (!approvalList.get('content')) {
                      approvalList.set('content', FLOW.ApprovalGroup.find())
                  }
              },
          }),

          editApprovalGroup: Ember.Route.extend({
              route: '/approvalsteps',

              connectOutlets: function (router, event) {
                  router.get('dataApprovalController').connectOutlet('approvalMain', 'approvalGroup');
                  router.get('approvalGroupController').connectOutlet('approvalStepsOutlet', 'approvalSteps');
              },
          }),
      })
    }),

    // ************************** MAPS ROUTER **********************************
    navMaps: Ember.Route.extend({
      route: '/maps',
      connectOutlets: function (router, context) {
        router.get('applicationController').connectOutlet('navMaps');
        router.set('navigationController.selected', 'navMaps');
      }
    }),

    // ************************** USERS ROUTER **********************************
    navUsers: Ember.Route.extend({
      route: '/users',
      connectOutlets: function (router, context) {
        router.get('applicationController').connectOutlet('navUsers');
        router.set('navigationController.selected', 'navUsers');
      }
    }),

    // ************************** MESSAGES ROUTER **********************************
    navMessages: Ember.Route.extend({
      route: '/users',
      connectOutlets: function (router, context) {
        router.get('applicationController').connectOutlet('navMessages');
        router.set('navigationController.selected', 'navMessages');
        FLOW.messageControl.populate();
        router.resetState();
      }
    }),

    // ************************** ADMIN ROUTER **********************************
    // not used at the moment
    navAdmin: Ember.Route.extend({
      route: '/admin',
      connectOutlets: function (router, context) {
        router.get('applicationController').connectOutlet('navAdmin');
        router.set('navigationController.selected', 'navAdmin');
      }
    })
  })
});
<|endoftext|>


<commit_before>// Google BSD license http://code.google.com/google_bsd_license.html
// Copyright 2013 Google Inc. johnjbarton@google.com

// Feature testing API, generally async queries that wait for matching elements to appear

window.PatientSelector = (function(){

    var debug = DebugLogger.register('PatientSelector', function(flag){
        return debug = (typeof flag === 'boolean') ? flag : debug;
    })

    function doc() {
        return document.location.pathname.split('/').pop();
    }

    // http://www.kirupa.com/html5/get_element_position_using_javascript.htm
    // modified
    function getPosition(element, toParent) {
        var xPosition = 0;
        var yPosition = 0;

        while(element && element !== toParent) {
            xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);
            yPosition += (element.offsetTop - element.scrollTop + element.clientTop);
            element = element.offsetParent;
        }
        return { x: xPosition, y: yPosition };
    }

    var PatientSelector = {

        _textSelectorAll: function(nodes, textToMatch) {
               return nodes.reduce(function findTextMatching(nodes, node) {
                    if (node.textContent.indexOf(textToMatch) !== -1)
                        nodes.push(node);
                    return nodes;
                }, []);
        },

        // If selector starts with pipe ('| '), select within previous match
        _querySelectorAll: function(selector, textToMatch) {
            var m = /^\| (.*)/.exec(selector);
            if (m) {
                selector = m[1];
                targets = PatientSelector.hits;
            } else {
                targets = [document];
            }

            try {
                var nodes = PatientSelector._selected = [];
                var nodeList;
                targets.forEach(function(target) {
                    nodeList = target.querySelectorAll(selector);
                    for (var i = 0; i < nodeList.length; i++) {
                        PatientSelector._selected.push(nodeList[i]);
                    }
                }.bind(PatientSelector));
            } catch (exc) {
                console.error("....PatientSelector._querySelectorAll query failed for " + selector + ": " + exc, targets);
            }

            if (debug)
                console.log("....PatientSelector._querySelectorAll finds "+PatientSelector._selected.length+" matches for "+selector);

            if (textToMatch) {
                nodes = PatientSelector._textSelectorAll(nodes, textToMatch);
                if (debug)
                    console.log("....PatientSelector._querySelectorAll finds "+nodes.length+" matches for "+selector+" with text "+textToMatch);
            }
            return PatientSelector.hits = nodes;
        },

        ancestor: function(selector, callback) {
            var parent = PatientSelector.hits[0].parentElement;
            while (parent) {
                var hit = parent.querySelector(selector);
                if (debug) console.log("....PatientSelector.ancestor(" + selector + ")  %o " + (hit ? "hit" : "miss"), parent);
                if (hit) {
                    PatientSelector.hits[0] = hit;
                    callback(hit);
                    return;
                }
                parent = parent.parentElement;
            }
            PatientSelector.hits = [];
            callback();
        },

        _textChanges: function(textToMatch, callback, mutationSummary) {
            if (debug) console.log("....PatientSelector._textChanges mutationSummary for " + textToMatch, mutationSummary[0]);
            var target = mutationSummary[0].target;
            this.hits = this._textSelectorAll([target], textToMatch);
            if (this.hits.length)
                callback();
        },

        _totalTextChangeObservers: 0,

        _createTextChangeObserver: function(textToMatch, element) {
            PatientSelector._totalTextChangeObservers++;
            if (debug) console.log('....PatientSelector._createTextChangeObserver _totalTextChangeObservers ' + PatientSelector._totalTextChangeObservers, PatientSelector);
            var handler = PatientSelector._textChanges.bind(PatientSelector, textToMatch, PatientSelector._disconnectOnFind.bind(PatientSelector));
            var summary = new MutationSummary({
                callback: handler,
                queries:[{characterData: true}],
                rootNode: element
            });
            summary._textToMatch = textToMatch;
            return summary;
        },

        _whenSelectorHits: function(textToMatch, callback, mutationSummary) {
            if (debug) console.log("....PatientSelector._whenSelectorHits mutationSummary for " + textToMatch, mutationSummary[0]);
            var added = mutationSummary[0].added;
            PatientSelector.hits = PatientSelector._textSelectorAll(added, textToMatch);
            if (PatientSelector.hits.length) {
                callback(PatientSelector.hits);
                return;
            }
            added.forEach(function(element) {
                PatientSelector._textChangeObservers = PatientSelector._textChangeObservers || [];
                PatientSelector._textChangeObservers.push(PatientSelector._createTextChangeObserver(textToMatch, element));
            }.bind(PatientSelector));
        },

        _setMutationObservers: function(selector, textToMatch, callback) {
            PatientSelector._disconnectOnFind = function() {
                if (PatientSelector._addedSelectionObserver)
                    PatientSelector._addedSelectionObserver.disconnect();
                if (PatientSelector._textChangeObservers) {
                    PatientSelector._textChangeObservers.forEach(function(observer){
                        observer.disconnect();
                        if (debug) console.log('....PatientSelector._setMutationObservers disconnect  ' + observer._textToMatch, observer);
                    }.bind(PatientSelector));
                    PatientSelector._totalTextChangeObservers -= PatientSelector._textChangeObservers.length;
                    if (debug) console.log('....PatientSelector._setMutationObservers _totalTextChangeObservers ' + PatientSelector._totalTextChangeObservers, PatientSelector);
                }
                delete PatientSelector._addedSelectionObserver;
                delete PatientSelector._textChangeObservers;
                if (debug)
                    console.log("....PatientSelector.whenSelectorAll found "+PatientSelector.hits.length +" for " + selector + " with text "+textToMatch);
                callback();
            }

            if (PatientSelector._selected.length) {
                if (PatientSelector._textChangeObservers) {
                    console.error('....PatientSelector._setMutationObservers unexpected _textChangeObservers ', PatientSelector._textChangeObservers);
                }
                PatientSelector._textChangeObservers = PatientSelector._selected.map(PatientSelector._createTextChangeObserver.bind(PatientSelector, textToMatch));
                if (debug) console.log('....PatientSelector._setMutationObservers initial _totalTextChangeObservers ' + PatientSelector._totalTextChangeObservers, PatientSelector);
            }
            PatientSelector._addedSelectionObserver = new MutationSummary({
                callback: PatientSelector._whenSelectorHits.bind(PatientSelector, textToMatch, PatientSelector._disconnectOnFind.bind(PatientSelector)),
                queries: [
                    {element: selector}
                ]
            });
            if (debug) {
                console.log("....PatientSelector.whenSelectorAll waiting for \'" + selector + "\' with text " + textToMatch + ' in ' + doc());
            }
        },

        whenSelectorAll: function(selector, textToMatch, callback) {
            PatientSelector.hits = PatientSelector._querySelectorAll(selector, textToMatch);
            if (PatientSelector.hits.length) {
                callback();
            } else {
                try {
                    PatientSelector._setMutationObservers(selector, textToMatch, callback);
                } catch (exc) {
                    console.error("....PatientSelector._setMutationObservers FAIL "+exc, exc);
                }
            }
        },

        _click: function(elt, callback) {
            var event = document.createEvent("MouseEvent");
            event.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
            elt.dispatchEvent(event);
            if (callback)
                callback();
        },

        clickSelector: function(selector, textToMatch, callback) {
            if (debug) console.log("....PatientSelector.clickSelector(" + selector + ', ' + textToMatch + ')');
            PatientSelector.whenSelectorAll(selector, textToMatch, function() {
                PatientSelector._click(PatientSelector.hits[0], callback);
                if (debug)
                    console.log("....PatientSelector.clickSelector hit ", PatientSelector.hits[0])
            }.bind(PatientSelector));
        },

        _moveLineNumber: function(lineNumber, visibleSourceLines, selector, text) {
            while (lineNumber < visibleSourceLines.length) {
                PatientSelector.hits = [visibleSourceLines[lineNumber]];
                // select in line
                var hits = PatientSelector._querySelectorAll('| '+selector, text);
                if (hits.length) {
                    if (debug) console.log('....PatientSelector.selectTokenInSource ' + selector + '&' + text + ' match ' + visibleSourceLines[lineNumber].textContent);
                    lineNumber++;
                    break;
                } else {
                    lineNumber++;
                }
            }
            if (lineNumber === visibleSourceLines.length - 1) {
                console.error("...PatientSelector.selectTokenInSource no source line matchs " + selector + ' & ' + text, visibleSourceLines);
            } else {
                return lineNumber;
            }
        },

        _fireMouseMove: function(tokenElt, callback) {
            function onMouseMove(event) {
                tokenElt.removeEventListener('mousemove', onMouseMove);
                var target = event.target;
                PatientSelector.hits = [tokenElt];
                callback(target.textContent + ' in ' + target.parentElement.textContent);
            }
            tokenElt.addEventListener('mousemove', onMouseMove);
            var xy = getPosition(tokenElt);
            xy.x = xy.x + Math.round(tokenElt.offsetWidth/2);
            xy.y = xy.y + Math.round(tokenElt.offsetHeight/2);
            var mousemove = document.createEvent("MouseEvent");
            mousemove.initMouseEvent('mousemove', true, true, window, 0,
                0, 0, xy.x, xy.y,
                false, false, false, false, 0, null);
            tokenElt.dispatchEvent(mousemove);
            if (debug) console.log('....PatientSelector._fireMouseMove mousemove(' + xy.x + ',' + xy.y + ') sent to %o', tokenElt);
        },

        selectTokenInSource: function(editorTokens, callback) {
            if (debug) console.log("....PatientSelector.selectTokenInSource(" + editorTokens.length + " editorTokens) ", editorTokens);
            var visibleSourceElement = PatientSelector._querySelectorAll('.CodeMirror-lines');
            var visibleSourceLines = PatientSelector._querySelectorAll('| pre');

            function next(lineNumber) {
                var token = editorTokens.shift();
                var selector = 'span.cm-' + token.type;
                var text = token.text;

                if (editorTokens.length) {
                    lineNumber = PatientSelector._moveLineNumber(lineNumber, visibleSourceLines, selector, text);
                    if (lineNumber)
                        next(lineNumber);
                    else
                        callback('err');
                } else {
                    if (debug) console.log('....PatientSelector.selectTokenInSource seeking pre ancestor of ', PatientSelector.hits);
                    PatientSelector.ancestor('pre', function() {
                        if (!PatientSelector.hits.length) {
                            console.error('....PatientSelector.selectTokenInSource ancestor selection failed', PatientSelector);
                            callback();
                        }
                        // select within the previous hit
                        var tokenElt = PatientSelector._querySelectorAll('| ' + selector, text)[0];
                        PatientSelector._fireMouseMove(tokenElt, callback);
                    });
                }
            }
            next(0);
        },

        clickTokenInSource: function(editorTokens, callback) {
            PatientSelector.selectTokenInSource(editorTokens, function() {
                PatientSelector._click(PatientSelector.hits[0], callback);
            });
        },

        evaluateInPage: function(expr, callback) {
            function checkException(result, isException) {
                if (isException) {
                    console.error("....PatientSelector.evaluateInPage(" + expr + ") exception", result);
                } else {
                    callback(result);
                }
            }
            chrome.devtools.inspectedWindow.eval(expr, checkException);
        },

        evaluate: function(expr, callback) {
            try {
                callback(eval(expr));
            } catch (exc) {
                console.error("....PatientSelector.evaluate(" + expr + ") exception " + exc, exc);
            }
        },

        reloadPage: function(callback) {
            chrome.devtools.inspectedWindow.reload();
            callback();
        },

        extractText: function(selector, callback) {
            var text = PatientSelector._querySelectorAll(selector).map(function(node){
                return node.textContent;
            }).join('|');
            console.log("testResult "+text);
            callback(text);
        },

        extractFromSelection: function(selector, property, callback) {
            var text = PatientSelector._querySelectorAll(selector).map(function(node){
                return node[property];
            }).join('|');
            console.log("testResult "+text);
            callback(text);
        },

        extractAttr: function(selector, attr, callback) {
            var text = PatientSelector._querySelectorAll(selector).map(function(node){
                return node.getAttribute(attr);
            }).join('|');
            console.log("testResult "+text);
            callback(text);
        },

        getBoundingClientRect: function(selector, textToMatch, callback) {
            var rects = PatientSelector._querySelectorAll(selector, textToMatch).map(function(node){
                var rect = node.getBoundingClientRect();
                var obj = {};
                Object.keys(rect).forEach(function(prop){
                    obj[prop] = rect[prop];
                });
                return obj;
            });
            callback(rects);
        },

        getStyle: function(selector, textToMatch, callback) {
            var styles = PatientSelector._querySelectorAll(selector, textToMatch).map(function(node){
                var style = node.style;
                var obj = {};
                Object.keys(style).forEach(function(prop){
                    obj[prop] = rect[prop];
                });
                return obj;
            });
            callback(styles);
        },

        //------------------------------------------------------------------------------------
        // For addressing command to extension iframes

        proxies: {},
        postId: 0,
        proxyHandlers: [],

        createProxy: function(port, iframeURL) { // onConnect from extension iframe

            function onMessage(message) {
                if (debug) console.log("....PatientSelector.proxyTo.onMessage ", message);
                var payload = message;
                var postId = payload.shift();
                var method = payload.shift();
                var status = payload.shift();
                var handler = PatientSelector.proxyHandlers[postId];
                if (handler) {
                    if (status === 'Error')
                        handler.onError(payload);
                    else
                        handler.onResponse(payload);
                    delete PatientSelector.proxyHandlers[postId];
                } else {
                    console.error("....PatientSelector.createProxy.onMessage no handler for " + postId + ' in ' + doc(), message);
                }
            }

            var proxy = PatientSelector.proxies[iframeURL] = new ChannelPlate.Base(port, onMessage.bind(PatientSelector));
            if (debug) console.log("....PatientSelector.createProxy for " + iframeURL);
            // The frame just contacted us, maybe we have a message waiting to send it.
            PatientSelector._postToProxy(proxy);
        },

        _postToProxy: function(proxy) {
            var handler = PatientSelector.proxyHandlers[PatientSelector.postId];
            if (handler && !handler.sent) {
                handler.sent = proxy.postMessage(handler.args);
                if (debug) console.log("....PatientSelector.proxyTo.postMessage sent: " + handler.sent + " to " + handler.url, handler.args);
            }
        },

        proxyTo: function(url, proxied, callback, errback) {
            if (debug) console.log("....PatientSelector.proxyTo " + url, proxied);
            var postId = ++PatientSelector.postId;
            PatientSelector.proxyHandlers[postId] = {url: url, onResponse: callback, onError: errback, args: [postId].concat(proxied)};

            var proxy;
            Object.keys(PatientSelector.proxies).some(function(iframeURL) {
                if (iframeURL.indexOf(url) !== -1) {
                    return proxy = PatientSelector.proxies[iframeURL];
                }
            }.bind(PatientSelector));

            if (proxy) {
                PatientSelector._postToProxy(proxy);
            } else {
                if (debug) console.log("....PatientSelector.proxyTo waiting for " + url);
            }
        }
    };

    return PatientSelector;
}());
<commit_msg>Related to issue #48, delay callbacks from mouse event until handlers fire<commit_after>// Google BSD license http://code.google.com/google_bsd_license.html
// Copyright 2013 Google Inc. johnjbarton@google.com

// Feature testing API, generally async queries that wait for matching elements to appear

window.PatientSelector = (function(){

    var debug = DebugLogger.register('PatientSelector', function(flag){
        return debug = (typeof flag === 'boolean') ? flag : debug;
    })

    function doc() {
        return document.location.pathname.split('/').pop();
    }

    // http://www.kirupa.com/html5/get_element_position_using_javascript.htm
    // modified
    function getPosition(element, toParent) {
        var xPosition = 0;
        var yPosition = 0;

        while(element && element !== toParent) {
            xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);
            yPosition += (element.offsetTop - element.scrollTop + element.clientTop);
            element = element.offsetParent;
        }
        return { x: xPosition, y: yPosition };
    }

    var PatientSelector = {

        _textSelectorAll: function(nodes, textToMatch) {
               return nodes.reduce(function findTextMatching(nodes, node) {
                    if (node.textContent.indexOf(textToMatch) !== -1)
                        nodes.push(node);
                    return nodes;
                }, []);
        },

        // If selector starts with pipe ('| '), select within previous match
        _querySelectorAll: function(selector, textToMatch) {
            var m = /^\| (.*)/.exec(selector);
            if (m) {
                selector = m[1];
                targets = PatientSelector.hits;
            } else {
                targets = [document];
            }

            try {
                var nodes = PatientSelector._selected = [];
                var nodeList;
                targets.forEach(function(target) {
                    nodeList = target.querySelectorAll(selector);
                    for (var i = 0; i < nodeList.length; i++) {
                        PatientSelector._selected.push(nodeList[i]);
                    }
                }.bind(PatientSelector));
            } catch (exc) {
                console.error("....PatientSelector._querySelectorAll query failed for " + selector + ": " + exc, targets);
            }

            if (debug)
                console.log("....PatientSelector._querySelectorAll finds "+PatientSelector._selected.length+" matches for "+selector);

            if (textToMatch) {
                nodes = PatientSelector._textSelectorAll(nodes, textToMatch);
                if (debug)
                    console.log("....PatientSelector._querySelectorAll finds "+nodes.length+" matches for "+selector+" with text "+textToMatch);
            }
            return PatientSelector.hits = nodes;
        },

        ancestor: function(selector, callback) {
            var parent = PatientSelector.hits[0].parentElement;
            while (parent) {
                var hit = parent.querySelector(selector);
                if (debug) console.log("....PatientSelector.ancestor(" + selector + ")  %o " + (hit ? "hit" : "miss"), parent);
                if (hit) {
                    PatientSelector.hits[0] = hit;
                    callback(hit);
                    return;
                }
                parent = parent.parentElement;
            }
            PatientSelector.hits = [];
            callback();
        },

        _textChanges: function(textToMatch, callback, mutationSummary) {
            if (debug) console.log("....PatientSelector._textChanges mutationSummary for " + textToMatch, mutationSummary[0]);
            var target = mutationSummary[0].target;
            this.hits = this._textSelectorAll([target], textToMatch);
            if (this.hits.length)
                callback();
        },

        _totalTextChangeObservers: 0,

        _createTextChangeObserver: function(textToMatch, element) {
            PatientSelector._totalTextChangeObservers++;
            if (debug) console.log('....PatientSelector._createTextChangeObserver _totalTextChangeObservers ' + PatientSelector._totalTextChangeObservers, PatientSelector);
            var handler = PatientSelector._textChanges.bind(PatientSelector, textToMatch, PatientSelector._disconnectOnFind.bind(PatientSelector));
            var summary = new MutationSummary({
                callback: handler,
                queries:[{characterData: true}],
                rootNode: element
            });
            summary._textToMatch = textToMatch;
            return summary;
        },

        _whenSelectorHits: function(textToMatch, callback, mutationSummary) {
            if (debug) console.log("....PatientSelector._whenSelectorHits mutationSummary for " + textToMatch, mutationSummary[0]);
            var added = mutationSummary[0].added;
            PatientSelector.hits = PatientSelector._textSelectorAll(added, textToMatch);
            if (PatientSelector.hits.length) {
                callback(PatientSelector.hits);
                return;
            }
            added.forEach(function(element) {
                PatientSelector._textChangeObservers = PatientSelector._textChangeObservers || [];
                PatientSelector._textChangeObservers.push(PatientSelector._createTextChangeObserver(textToMatch, element));
            }.bind(PatientSelector));
        },

        _setMutationObservers: function(selector, textToMatch, callback) {
            PatientSelector._disconnectOnFind = function() {
                if (PatientSelector._addedSelectionObserver)
                    PatientSelector._addedSelectionObserver.disconnect();
                if (PatientSelector._textChangeObservers) {
                    PatientSelector._textChangeObservers.forEach(function(observer){
                        observer.disconnect();
                        if (debug) console.log('....PatientSelector._setMutationObservers disconnect  ' + observer._textToMatch, observer);
                    }.bind(PatientSelector));
                    PatientSelector._totalTextChangeObservers -= PatientSelector._textChangeObservers.length;
                    if (debug) console.log('....PatientSelector._setMutationObservers _totalTextChangeObservers ' + PatientSelector._totalTextChangeObservers, PatientSelector);
                }
                delete PatientSelector._addedSelectionObserver;
                delete PatientSelector._textChangeObservers;
                if (debug)
                    console.log("....PatientSelector.whenSelectorAll found "+PatientSelector.hits.length +" for " + selector + " with text "+textToMatch);
                callback();
            }

            if (PatientSelector._selected.length) {
                if (PatientSelector._textChangeObservers) {
                    console.error('....PatientSelector._setMutationObservers unexpected _textChangeObservers ', PatientSelector._textChangeObservers);
                }
                PatientSelector._textChangeObservers = PatientSelector._selected.map(PatientSelector._createTextChangeObserver.bind(PatientSelector, textToMatch));
                if (debug) console.log('....PatientSelector._setMutationObservers initial _totalTextChangeObservers ' + PatientSelector._totalTextChangeObservers, PatientSelector);
            }
            PatientSelector._addedSelectionObserver = new MutationSummary({
                callback: PatientSelector._whenSelectorHits.bind(PatientSelector, textToMatch, PatientSelector._disconnectOnFind.bind(PatientSelector)),
                queries: [
                    {element: selector}
                ]
            });
            if (debug) {
                console.log("....PatientSelector.whenSelectorAll waiting for \'" + selector + "\' with text " + textToMatch + ' in ' + doc());
            }
        },

        whenSelectorAll: function(selector, textToMatch, callback) {
            PatientSelector.hits = PatientSelector._querySelectorAll(selector, textToMatch);
            if (PatientSelector.hits.length) {
                callback();
            } else {
                try {
                    PatientSelector._setMutationObservers(selector, textToMatch, callback);
                } catch (exc) {
                    console.error("....PatientSelector._setMutationObservers FAIL "+exc, exc);
                }
            }
        },

        _click: function(elt, callback) {
            function onClick(event) {
                elt.removeEventListener('click', onClick);
                if (callback) {
                    // allow the click handler to fire before next test step
                    setTimeout(function() {
                        callback();
                    });
                }
            }
            elt.addEventListener('click', onClick);
            var event = document.createEvent("MouseEvent");
            event.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
            elt.dispatchEvent(event);
        },

        clickSelector: function(selector, textToMatch, callback) {
            if (debug) console.log("....PatientSelector.clickSelector(" + selector + ', ' + textToMatch + ')');
            PatientSelector.whenSelectorAll(selector, textToMatch, function() {
                PatientSelector._click(PatientSelector.hits[0], callback);
                if (debug)
                    console.log("....PatientSelector.clickSelector hit ", PatientSelector.hits[0])
            }.bind(PatientSelector));
        },

        _moveLineNumber: function(lineNumber, visibleSourceLines, selector, text) {
            while (lineNumber < visibleSourceLines.length) {
                PatientSelector.hits = [visibleSourceLines[lineNumber]];
                // select in line
                var hits = PatientSelector._querySelectorAll('| '+selector, text);
                if (hits.length) {
                    if (debug) console.log('....PatientSelector.selectTokenInSource ' + selector + '&' + text + ' match ' + visibleSourceLines[lineNumber].textContent);
                    lineNumber++;
                    break;
                } else {
                    lineNumber++;
                }
            }
            if (lineNumber === visibleSourceLines.length - 1) {
                console.error("...PatientSelector.selectTokenInSource no source line matchs " + selector + ' & ' + text, visibleSourceLines);
            } else {
                return lineNumber;
            }
        },

        _fireMouseMove: function(tokenElt, callback) {
            function onMouseMove(event) {
                tokenElt.removeEventListener('mousemove', onMouseMove);
                var target = event.target;
                PatientSelector.hits = [tokenElt];
                // Allow the mousemove handler to fire before the next test step
                setTimeout(function(){
                    callback(target.textContent + ' in ' + target.parentElement.textContent);
                });
            }
            tokenElt.addEventListener('mousemove', onMouseMove);
            var xy = getPosition(tokenElt);
            xy.x = xy.x + Math.round(tokenElt.offsetWidth/2);
            xy.y = xy.y + Math.round(tokenElt.offsetHeight/2);
            var mousemove = document.createEvent("MouseEvent");
            mousemove.initMouseEvent('mousemove', true, true, window, 0,
                0, 0, xy.x, xy.y,
                false, false, false, false, 0, null);
            tokenElt.dispatchEvent(mousemove);
            if (debug) console.log('....PatientSelector._fireMouseMove mousemove(' + xy.x + ',' + xy.y + ') sent to %o', tokenElt);
        },

        selectTokenInSource: function(editorTokens, callback) {
            if (debug) console.log("....PatientSelector.selectTokenInSource(" + editorTokens.length + " editorTokens) ", editorTokens);
            var visibleSourceElement = PatientSelector._querySelectorAll('.CodeMirror-lines');
            var visibleSourceLines = PatientSelector._querySelectorAll('| pre');

            function next(lineNumber) {
                var token = editorTokens.shift();
                var selector = 'span.cm-' + token.type;
                var text = token.text;

                if (editorTokens.length) {
                    lineNumber = PatientSelector._moveLineNumber(lineNumber, visibleSourceLines, selector, text);
                    if (lineNumber)
                        next(lineNumber);
                    else
                        callback('err');
                } else {
                    if (debug) console.log('....PatientSelector.selectTokenInSource seeking pre ancestor of ', PatientSelector.hits);
                    PatientSelector.ancestor('pre', function() {
                        if (!PatientSelector.hits.length) {
                            console.error('....PatientSelector.selectTokenInSource ancestor selection failed', PatientSelector);
                            callback();
                        }
                        // select within the previous hit
                        var tokenElt = PatientSelector._querySelectorAll('| ' + selector, text)[0];
                        PatientSelector._fireMouseMove(tokenElt, callback);
                    });
                }
            }
            next(0);
        },

        clickTokenInSource: function(editorTokens, callback) {
            PatientSelector.selectTokenInSource(editorTokens, function() {
                PatientSelector._click(PatientSelector.hits[0], callback);
            });
        },

        evaluateInPage: function(expr, callback) {
            function checkException(result, isException) {
                if (isException) {
                    console.error("....PatientSelector.evaluateInPage(" + expr + ") exception", result);
                } else {
                    callback(result);
                }
            }
            chrome.devtools.inspectedWindow.eval(expr, checkException);
        },

        evaluate: function(expr, callback) {
            try {
                callback(eval(expr));
            } catch (exc) {
                console.error("....PatientSelector.evaluate(" + expr + ") exception " + exc, exc);
            }
        },

        reloadPage: function(callback) {
            chrome.devtools.inspectedWindow.reload();
            callback();
        },

        extractText: function(selector, callback) {
            var text = PatientSelector._querySelectorAll(selector).map(function(node){
                return node.textContent;
            }).join('|');
            console.log("testResult "+text);
            callback(text);
        },

        extractFromSelection: function(selector, property, callback) {
            var text = PatientSelector._querySelectorAll(selector).map(function(node){
                return node[property];
            }).join('|');
            console.log("testResult "+text);
            callback(text);
        },

        extractAttr: function(selector, attr, callback) {
            var text = PatientSelector._querySelectorAll(selector).map(function(node){
                return node.getAttribute(attr);
            }).join('|');
            console.log("testResult "+text);
            callback(text);
        },

        getBoundingClientRect: function(selector, textToMatch, callback) {
            var rects = PatientSelector._querySelectorAll(selector, textToMatch).map(function(node){
                var rect = node.getBoundingClientRect();
                var obj = {};
                Object.keys(rect).forEach(function(prop){
                    obj[prop] = rect[prop];
                });
                return obj;
            });
            callback(rects);
        },

        getStyle: function(selector, textToMatch, callback) {
            var styles = PatientSelector._querySelectorAll(selector, textToMatch).map(function(node){
                var style = node.style;
                var obj = {};
                Object.keys(style).forEach(function(prop){
                    obj[prop] = rect[prop];
                });
                return obj;
            });
            callback(styles);
        },

        //------------------------------------------------------------------------------------
        // For addressing command to extension iframes

        proxies: {},
        postId: 0,
        proxyHandlers: [],

        createProxy: function(port, iframeURL) { // onConnect from extension iframe

            function onMessage(message) {
                if (debug) console.log("....PatientSelector.proxyTo.onMessage ", message);
                var payload = message;
                var postId = payload.shift();
                var method = payload.shift();
                var status = payload.shift();
                var handler = PatientSelector.proxyHandlers[postId];
                if (handler) {
                    if (status === 'Error')
                        handler.onError(payload);
                    else
                        handler.onResponse(payload);
                    delete PatientSelector.proxyHandlers[postId];
                } else {
                    console.error("....PatientSelector.createProxy.onMessage no handler for " + postId + ' in ' + doc(), message);
                }
            }

            var proxy = PatientSelector.proxies[iframeURL] = new ChannelPlate.Base(port, onMessage.bind(PatientSelector));
            if (debug) console.log("....PatientSelector.createProxy for " + iframeURL);
            // The frame just contacted us, maybe we have a message waiting to send it.
            PatientSelector._postToProxy(proxy);
        },

        _postToProxy: function(proxy) {
            var handler = PatientSelector.proxyHandlers[PatientSelector.postId];
            if (handler && !handler.sent) {
                handler.sent = proxy.postMessage(handler.args);
                if (debug) console.log("....PatientSelector.proxyTo.postMessage sent: " + handler.sent + " to " + handler.url, handler.args);
            }
        },

        proxyTo: function(url, proxied, callback, errback) {
            if (debug) console.log("....PatientSelector.proxyTo " + url, proxied);
            var postId = ++PatientSelector.postId;
            PatientSelector.proxyHandlers[postId] = {url: url, onResponse: callback, onError: errback, args: [postId].concat(proxied)};

            var proxy;
            Object.keys(PatientSelector.proxies).some(function(iframeURL) {
                if (iframeURL.indexOf(url) !== -1) {
                    return proxy = PatientSelector.proxies[iframeURL];
                }
            }.bind(PatientSelector));

            if (proxy) {
                PatientSelector._postToProxy(proxy);
            } else {
                if (debug) console.log("....PatientSelector.proxyTo waiting for " + url);
            }
        }
    };

    return PatientSelector;
}());
<|endoftext|>


<commit_before>var should = require('should');
var request = require('supertest');
var server = require('../../../app');

var mockSchemas = require('../mock_data/mock_schemas');
var targetSchemas = require('../mock_data/target_schemas');
var mockObjects = require('../mock_data/mock_objects');
//var objects22k = require('../mock_data/NE_22k_example.json');
//We can't send large object with supertest at this point
//Even if we could swagger will freeze when validating such a large schema, replace objects and schema by "something" to get threw this
// curl -X POST -H "Content-Type: application/json" --data '{"something":{"schema":{},"objects":"'$(cat NE_22k_example.json)'-"}}' http://10.30.90.174:9000/objects/validate

//SOLUTION (OLD: before param named file)
//curl -v -s --trace-ascii http_tracery @_NE_22k_example.json.gz -H "Content-Type: application/json" -H "Content-Encoding: gzip" -X POST http://10.30.90.174:9000/objects/gzipped/validate

//SOLUTION(NEW)
// $ cd test/api/gzip_data
// TRUE $ curl -F "file=@NE_111k.json.gz" http:10.30.90.174:9000/objects/gzipped/validate
// FALSE $ curl -F "file=@NE_111k_with_errors.json.gz" http:10.30.90.174:9000/objects/gzipped/validate
var objects22k = [{"_start": 123}, {"_start": 12223}];
var basic = {
  "required": [ "_start"]
};

describe('controllers', function () {

  describe('json_object', function () {

    describe('POST /object/validate', function () {

      it('should return an error 400 if body is missing', function (done) {

        request(server)
          .post('/object/validate')
          .set('Accept', 'application/json')
          .expect('Content-Type', /json/)
          .expect(400)
          .end(function (err, res) {
            should.not.exist(err);
            //res.status.should.eql(400);
            done();
          });
      });

      it('should return an error 400 if schema is missing from body', function (done) {

        request(server)
          .post('/object/validate')
          .send({object: {}})
          .set('Accept', 'application/json')
          .expect('Content-Type', /json/)
          .expect(400)
          .end(function (err, res) {
            should.not.exist(err);
            done();
          });
      });

      it('should return an error 422 if schema is an invalid json schema', function (done) {

        request(server)
          .post('/object/validate')
          .send({ schema: { "required": "yolo123"}, object: { yolo : 123}})
          .set('Accept', 'application/json')
          .expect('Content-Type', /json/)
          .expect(422)
          .end(function (err, res) {
            should.not.exist(err);
            should.exist(res.body.code);
            should.exist(res.body.message);
            done();
          });
      });

      it('should accept master schema and a valid faceDetect object', function (done) {

        request(server)
          .post('/object/validate')
          .send({schema: targetSchemas.master, object: mockObjects.faceValid})
          .set('Accept', 'application/json')
          .expect('Content-Type', /json/)
          .expect(200)
          .end(function (err, res) {
            should.not.exist(err);
            res.body.should.eql({ isValid: true });
            done();
          });
      });

      it('should accept multimedia_document_content schema and a valid faceDetect object', function (done) {

        request(server)
          .post('/object/validate')
          .send({schema: targetSchemas.multimedia_document_content, object: mockObjects.faceValid})
          .set('Accept', 'application/json')
          .expect('Content-Type', /json/)
          .expect(200)
          .end(function (err, res) {
            should.not.exist(err);
            res.body.should.eql({ isValid: true });
            done();
          });
      });

      it('should return { isValid: false, errors: [] } with multimedia_document_content schema and invalid faceDetect object', function (done) {

        request(server)
          .post('/object/validate')
          .send({schema: targetSchemas.multimedia_document_content, object: { yolo : 123}})
          .set('Accept', 'application/json')
          .expect('Content-Type', /json/)
          .expect(200)
          .end(function (err, res) {
            //TODO fix
            should.not.exist(err);
            should.exist(res.body.isValid);
            should.exist(res.body.errors);
            res.body.isValid.should.eql(false);
            done();
          });
      });

    });

    describe('POST /objects/validate', function () {

      it('should return { isValid : true } with objects22k', function (done) {
        request(server)
          .post('/objects/validate')
          .send({schema: basic, objects: objects22k})
          .set('Accept', 'application/json')
          .expect('Content-Type', /json/)
          .expect(200)
          .end(function (err, res) {
            should.not.exist(err);
            done();
          });
      });
    });

    describe('POST /objects/gzipped/validate', function () {

      it('should return { isValid : true } with 22k', function (done) {
        request(server)
          .post('/objects/gzipped/validate')
          .attach('file', './test/api/gzip_data/NE_22k.json.gz')
          .expect('Content-Type', /json/)
          .expect(200)
          .end(function (err, res) {
            should.not.exist(err);
            res.body.isValid.should.eql(true);
            done();
          });
      });

      it('should return { isValid : false } with 22k_with_errors', function (done) {
        request(server)
          .post('/objects/gzipped/validate')
          .attach('file', './test/api/gzip_data/NE_22k_with_error.json.gz')
          .expect('Content-Type', /json/)
          .expect(200)
          .end(function (err, res) {
            should.not.exist(err);
            res.body.isValid.should.eql(false);
            done();
          });
      });

      it('should return 400 with 22k_missing_schema', function (done) {
        request(server)
          .post('/objects/gzipped/validate')
          .attach('file', './test/api/gzip_data/NE_22k_missing_schema.json.gz')
          .expect('Content-Type', /json/)
          .expect(400)
          .end(function (err, res) {
            should.not.exist(err);
            done();
          });
      });

      it('should return 422 with 22k_invalid_schema', function (done) {
        request(server)
          .post('/objects/gzipped/validate')
          .attach('file', './test/api/gzip_data/NE_22k_invalid_schema.json.gz')
          .expect('Content-Type', /json/)
          .expect(422)
          .end(function (err, res) {
            should.not.exist(err);
            done();
          });
      });
    });

  });

});
<commit_msg>Fixed comments<commit_after>var should = require('should');
var request = require('supertest');
var server = require('../../../app');

var mockSchemas = require('../mock_data/mock_schemas');
var targetSchemas = require('../mock_data/target_schemas');
var mockObjects = require('../mock_data/mock_objects');

//BATCH ARRAY VALIDATION:
// 1- We can't send large object with supertest at this point (POST objects/validate is for small arrays)
//    Even if we could swagger will freeze when validating such a large dataset, replace objects and schema by "something" to get threw this
//    Following CURL will fail but this is an example:
//    $ curl -X POST -H "Content-Type: application/json" --data '{"something":{"schema":{},"objects":"'$(cat NE_22k_example.json)'-"}}' http://10.30.90.174:9000/objects/validate
//
// 2- To send large number of object use the POST objects/gzipped/validate and attach to it a gzipped json file containing {schema: {} and objects: []}
//    Following curl was used at some point before sending multipart/form-data and a param named "file"
//    $ curl -v -s --trace-ascii http_tracery @_NE_22k_example.json.gz -H "Content-Type: application/json" -H "Content-Encoding: gzip" -X POST http://10.30.90.174:9000/objects/gzipped/validate
//
// 3- Method POST objects/gzipped/valdiate now attends multipart/form-data so we can retreive file inside the express api
//    Both following curls commands actually should still works
//    TRUE <= $ curl -F "file=@NE_111k.json.gz" http:10.30.90.174:9000/objects/gzipped/validate
//    FALSE <= $ curl -F "file=@NE_111k_with_errors.json.gz" http:10.30.90.174:9000/objects/gzipped/validate
//    But now supertest method attach() support attached files with multipart/form-data so curl are kinda useless

var objects22k = [{"_start": 123}, {"_start": 12223}];
var basic = {
  "required": [ "_start"]
};

describe('controllers', function () {

  describe('json_object', function () {

    describe('POST /object/validate', function () {

      it('should return an error 400 if body is missing', function (done) {

        request(server)
          .post('/object/validate')
          .set('Accept', 'application/json')
          .expect('Content-Type', /json/)
          .expect(400)
          .end(function (err, res) {
            should.not.exist(err);
            //res.status.should.eql(400);
            done();
          });
      });

      it('should return an error 400 if schema is missing from body', function (done) {

        request(server)
          .post('/object/validate')
          .send({object: {}})
          .set('Accept', 'application/json')
          .expect('Content-Type', /json/)
          .expect(400)
          .end(function (err, res) {
            should.not.exist(err);
            done();
          });
      });

      it('should return an error 422 if schema is an invalid json schema', function (done) {

        request(server)
          .post('/object/validate')
          .send({ schema: { "required": "yolo123"}, object: { yolo : 123}})
          .set('Accept', 'application/json')
          .expect('Content-Type', /json/)
          .expect(422)
          .end(function (err, res) {
            should.not.exist(err);
            should.exist(res.body.code);
            should.exist(res.body.message);
            done();
          });
      });

      it('should accept master schema and a valid faceDetect object', function (done) {

        request(server)
          .post('/object/validate')
          .send({schema: targetSchemas.master, object: mockObjects.faceValid})
          .set('Accept', 'application/json')
          .expect('Content-Type', /json/)
          .expect(200)
          .end(function (err, res) {
            should.not.exist(err);
            res.body.should.eql({ isValid: true });
            done();
          });
      });

      it('should accept multimedia_document_content schema and a valid faceDetect object', function (done) {

        request(server)
          .post('/object/validate')
          .send({schema: targetSchemas.multimedia_document_content, object: mockObjects.faceValid})
          .set('Accept', 'application/json')
          .expect('Content-Type', /json/)
          .expect(200)
          .end(function (err, res) {
            should.not.exist(err);
            res.body.should.eql({ isValid: true });
            done();
          });
      });

      it('should return { isValid: false, errors: [] } with multimedia_document_content schema and invalid faceDetect object', function (done) {

        request(server)
          .post('/object/validate')
          .send({schema: targetSchemas.multimedia_document_content, object: { yolo : 123}})
          .set('Accept', 'application/json')
          .expect('Content-Type', /json/)
          .expect(200)
          .end(function (err, res) {
            //TODO fix
            should.not.exist(err);
            should.exist(res.body.isValid);
            should.exist(res.body.errors);
            res.body.isValid.should.eql(false);
            done();
          });
      });

    });

    describe('POST /objects/validate', function () {

      it('should return { isValid : true } with objects22k', function (done) {
        request(server)
          .post('/objects/validate')
          .send({schema: basic, objects: objects22k})
          .set('Accept', 'application/json')
          .expect('Content-Type', /json/)
          .expect(200)
          .end(function (err, res) {
            should.not.exist(err);
            done();
          });
      });
    });

    describe('POST /objects/gzipped/validate', function () {

      it('should return { isValid : true } with 22k', function (done) {
        request(server)
          .post('/objects/gzipped/validate')
          .attach('file', './test/api/gzip_data/NE_22k.json.gz')
          .expect('Content-Type', /json/)
          .expect(200)
          .end(function (err, res) {
            should.not.exist(err);
            res.body.isValid.should.eql(true);
            done();
          });
      });

      it('should return { isValid : false } with 22k_with_errors', function (done) {
        request(server)
          .post('/objects/gzipped/validate')
          .attach('file', './test/api/gzip_data/NE_22k_with_error.json.gz')
          .expect('Content-Type', /json/)
          .expect(200)
          .end(function (err, res) {
            should.not.exist(err);
            res.body.isValid.should.eql(false);
            done();
          });
      });

      it('should return 400 with 22k_missing_schema', function (done) {
        request(server)
          .post('/objects/gzipped/validate')
          .attach('file', './test/api/gzip_data/NE_22k_missing_schema.json.gz')
          .expect('Content-Type', /json/)
          .expect(400)
          .end(function (err, res) {
            should.not.exist(err);
            done();
          });
      });

      it('should return 422 with 22k_invalid_schema', function (done) {
        request(server)
          .post('/objects/gzipped/validate')
          .attach('file', './test/api/gzip_data/NE_22k_invalid_schema.json.gz')
          .expect('Content-Type', /json/)
          .expect(422)
          .end(function (err, res) {
            should.not.exist(err);
            done();
          });
      });
    });

  });

});
<|endoftext|>


<commit_before>import appReducer from 'src/shared/reducers/app'
import {
  enablePresentationMode,
  disablePresentationMode,
  // delayEnablePresentationMode,
  setAutoRefresh,
} from 'src/shared/actions/app'

describe('Shared.Reducers.appReducer', () => {
  const initialState = {
    ephemeral: {
      inPresentationMode: false,
    },
    persisted: {
      autoRefresh: 0,
    },
  }

  it('should handle ENABLE_PRESENTATION_MODE', () => {
    const reducedState = appReducer(initialState, enablePresentationMode())

    expect(reducedState.ephemeral.inPresentationMode).to.equal(true)
  })

  it('should handle DISABLE_PRESENTATION_MODE', () => {
    Object.assign(initialState, {ephemeral: {inPresentationMode: true}})

    const reducedState = appReducer(initialState, disablePresentationMode())

    expect(reducedState.ephemeral.inPresentationMode).to.equal(false)
  })

  it('should handle SET_AUTOREFRESH', () => {
    const expectedMs = 15000

    const reducedState = appReducer(initialState, setAutoRefresh(expectedMs))

    expect(reducedState.persisted.autoRefresh).to.equal(expectedMs)
  })
})
<commit_msg>Write test for tempvar controls toggle<commit_after>import appReducer from 'src/shared/reducers/app'
import {
  enablePresentationMode,
  disablePresentationMode,
  // delayEnablePresentationMode,
  setAutoRefresh,
  tempVarControlsToggled,
} from 'src/shared/actions/app'

describe('Shared.Reducers.appReducer', () => {
  const initialState = {
    ephemeral: {
      inPresentationMode: false,
    },
    persisted: {
      autoRefresh: 0,
      showTempVarControls: false,
    },
  }

  it('should handle ENABLE_PRESENTATION_MODE', () => {
    const reducedState = appReducer(initialState, enablePresentationMode())

    expect(reducedState.ephemeral.inPresentationMode).to.equal(true)
  })

  it('should handle DISABLE_PRESENTATION_MODE', () => {
    Object.assign(initialState, {ephemeral: {inPresentationMode: true}})

    const reducedState = appReducer(initialState, disablePresentationMode())

    expect(reducedState.ephemeral.inPresentationMode).to.equal(false)
  })

  it('should handle SET_AUTOREFRESH', () => {
    const expectedMs = 15000

    const reducedState = appReducer(initialState, setAutoRefresh(expectedMs))

    expect(reducedState.persisted.autoRefresh).to.equal(expectedMs)
  })

  it('should handle TEMP_VAR_CONTROLS_TOGGLED', () => {
    const reducedState = appReducer(initialState, tempVarControlsToggled())

    const expectedTestState = !reducedState.persisted.showTempVarControls

    expect(initialState.persisted.showTempVarControls).to.equal(
      expectedTestState
    )
  })
})
<|endoftext|>


<commit_before>const chai = require('chai')

const should = chai.should()

module.exports = function () {
  describe('Libtorrent bindings', function () {
    this.bindings = null

    it('should successfullly import the bindings', function () {
      try {
        this.bindings = require('../../../bindings/build/Release/kawatorrent.node')
      } catch (e) {
        should.fail('Could not import Libtorrent bindings: ' + e.stack)
      }
    })

    it('should be formatted properly', function () {
      this.bindings.should.be.an('object')
      this.bindings.should.include.keys('torrent')
      this.bindings.torrent.should.be.a('object')
      this.bindings.torrent.should.include.keys(['Client', 'version'])
      this.bindings.torrent.version.should.be.a('string')
      this.bindings.torrent.Client.should.be.a('function')
    })
  })
}
<commit_msg>Added tests for torrent bindings<commit_after>const chai = require('chai')

const should = chai.should()

const MAGNET_LINK = 'magnet:?xt=urn:btih:50af27af300b44aec651add3eeb7135fd0c15bfa&dn=%5BHorribleSubs%5D%20Hoshiai%20no%20Sora%20-%2005%20%5B720p%5D.mkv&tr=http%3A%2F%2Fnyaa.tracker.wf%3A7777%2Fannounce&tr=udp%3A%2F%2Fopen.stealth.si%3A80%2Fannounce&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337%2Fannounce&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969%2Fannounce&tr=udp%3A%2F%2Fexodus.desync.com%3A6969%2Fannounce'
const DIR = './downloads'

module.exports = function () {
  describe('Libtorrent bindings', function () {
    this.bindings = null
    this.client = null

    it('should successfullly import the bindings', function () {
      try {
        this.bindings = require('../../../bindings/build/Release/kawatorrent.node')
      } catch (e) {
        should.fail('Could not import Libtorrent bindings: ' + e.stack)
      }
    })

    it('should be formatted properly', function () {
      this.bindings.should.be.an('object')
      this.bindings.should.include.keys('torrent')
      this.bindings.torrent.should.be.a('object')
      this.bindings.torrent.should.include.keys(['Client', 'version'])
      this.bindings.torrent.version.should.be.a('string')
      this.bindings.torrent.Client.should.be.a('function')
    })

    it('should create a valid client', function () {
      this.client = new this.bindings.torrent.Client()

      this.client.addTorrent.should.be.a('function')
      this.client.destroy.should.be.a('function')
      this.client.addTorrent.should.be.a('function')
      this.client.getTorrents.should.be.a('function')
      this.client.getTorrent.should.be.a('function')
      this.client.removeTorrent.should.be.a('function')
      this.client.getClientInfo.should.be.a('function')
      this.client.hasTorrents.should.be.a('function')
      this.client.isDestroyed.should.be.a('function')
    })

    it('should add a torrent', function () {
      const addedTorrent = this.client.addTorrent(DIR, MAGNET_LINK)

      addedTorrent.should.not.equal(null)

      this.client.getTorrents().length.should.equal(1)

      const torrent = this.client.getTorrents()[0]

      torrent.info.should.be.a('function')
      torrent.setLimit.should.be.a('function')
      torrent.pause.should.be.a('function')
      torrent.resume.should.be.a('function')

      const info = torrent.info()

      info.should.not.equal(null)

      info.should.include.keys([
        'id',
        'downloadLimit',
        'uploadLimit',
        'name',
        'progress',
        'done',
        'totalSize',
        'magnetURI',
        'downloaded',
        'state',
        'uploadRate',
        'downloadRate',
        'path',
        'numPeers',
        'isAutoManaged',
        'isPaused',
        'savePath',
        'timeRemaining',
        'files'
      ])
    })
  })
}
<|endoftext|>