<commit_before>// eslint-disable handle-callback-err
const chai = require('chai')
const chaiHttp = require('chai-http')
const server = require('../server')
// eslint-disable-next-line no-unused-vars
const should = chai.should()
const faker = require('faker')

chai.use(chaiHttp)

describe('Room', function () {
  it('should list ALL rooms on /room GET', function (done) {
    chai.request(server)
      .get('/room')
      .end(function (err, res) {
        res.should.have.status(200)
        res.should.be.json
        res.body.should.be.a('array')
        done()
      })
  })
  it('should add a SINGLE room on /room POST', function (done) {
    const newName = `${faker.company.bsBuzz()} ${faker.commerce.department()}`
    chai.request(server)
      .post('/room')
      .send({ 'name': newName })
      .end(function (err, res) {
        res.should.have.status(200)
        res.should.be.json
        res.should.be.a('object')
        res.body._id.should.be.a('string')
        res.body.name.should.equal(newName)
        res.body.reservations.should.be.a('array')
        done()
      })
  })
  it('should list a SINGLE room on /room/:id GET', function (done) {
    chai.request(server)
      .get('/room')
      .end(function (err, res) {
        chai.request(server)
          .get(`/room/${res.body[0]._id}`)
          .end(function (err, res2) {
            res2.should.have.status(200)
            res2.should.be.json
            res2.body.should.be.a('object')
            res2.body._id.should.equal(res.body[0]._id)
            res2.body.name.should.equal(res.body[0].name)
            res2.body.reservations.should.be.a('array')
            res2.body.reservations.should.eql(res.body[0].reservations)
            done()
          })
      })
  })
  it('should update a SINGLE room on /room/:id PUT', function (done) {
    const newName = `${faker.company.bsBuzz()} ${faker.commerce.department()}`
    chai.request(server)
      .get('/room')
      .end(function (err, res) {
        chai.request(server)
          .put(`/room/${res.body[0]._id}`)
          .send({
            'name': newName,
            'reservations': []
          })
          .end(function (err, res2) {
            res2.should.have.status(200)
            res2.should.be.json
            res2.body.should.be.a('object')
            res2.body._id.should.equal(res.body[0]._id)
            res2.body.name.should.equal(newName)
            res2.body.reservations.should.be.a('array')
            res2.body.reservations.should.eql([])
            done()
          })
      })
  })
  it('should delete a SINGLE room and ALL linked reservations on /room/:id PUT', function (done) {
    chai.request(server)
      .get('/room')
      .end(function (err, res) {
        chai.request(server)
          .delete(`/room/${res.body[0]._id}`)
          .end(function (err, res2) {
            // TODO: Verify reservations have been deleted
            res2.should.have.status(200)
            res2.should.be.json
            res2.body.deleted.should.equal(true)
            done()
          })
      })
  })
})
<commit_msg>Update Room tests to use its own room and clean up after itself<commit_after>// eslint-disable handle-callback-err
const chai = require('chai')
const chaiHttp = require('chai-http')
const server = require('../server')
// eslint-disable-next-line no-unused-vars
const should = chai.should()
const faker = require('faker')

chai.use(chaiHttp)

describe('Room', function () {
  let testRoom
  it('should add a SINGLE room on /room POST', function (done) {
    const newName = `${faker.company.bsBuzz()} ${faker.commerce.department()}`
    chai.request(server)
      .post('/room')
      .send({ 'name': newName })
      .end(function (err, res) {
        testRoom = {
          _id: res._id,
          name: res.name,
          reservations: res.reservations
        }
        res.should.have.status(200)
        res.should.be.json
        res.should.be.a('object')
        res.body._id.should.be.a('string')
        res.body.name.should.equal(newName)
        res.body.reservations.should.be.a('array')
        done()
      })
  })
  it('should list ALL rooms on /room GET', function (done) {
    chai.request(server)
      .get('/room')
      .end(function (err, res) {
        res.should.have.status(200)
        res.should.be.json
        res.body.should.be.a('array')
        done()
      })
  })
  it('should list a SINGLE room on /room/:id GET', function (done) {
    chai.request(server)
      .get(`/room/${testRoom._id}`)
      .end(function (err, res2) {
        res2.should.have.status(200)
        res2.should.be.json
        res2.body.should.be.a('object')
        res2.body._id.should.equal(testRoom._id)
        res2.body.name.should.equal(testRoom.name)
        res2.body.reservations.should.be.a('array')
        res2.body.reservations.should.eql(testRoom.reservations)
        done()
      })
  })
  it('should update a SINGLE room on /room/:id PUT', function (done) {
    const newName = `${faker.company.bsBuzz()} ${faker.commerce.department()}`
    testRoom.name = newName
    chai.request(server)
      .put(`/room/${testRoom._id}`)
      .send({
        'name': newName,
        'reservations': []
      })
      .end(function (err, res2) {
        res2.should.have.status(200)
        res2.should.be.json
        res2.body.should.be.a('object')
        res2.body._id.should.equal(testRoom._id)
        res2.body.name.should.equal(testRoom.name)
        res2.body.reservations.should.be.a('array')
        res2.body.reservations.should.eql([])
        done()
      })
  })
  it('should delete a SINGLE room and ALL linked reservations on /room/:id PUT', function (done) {
    chai.request(server)
      .delete(`/room/${testRoom._id}`)
      .end(function (err, res) {
        // TODO: Verify reservations have been deleted
        res.should.have.status(200)
        res.should.be.json
        res.body.deleted.should.equal(true)
        done()
      })
  })
})
<|endoftext|>


<commit_before>
/*
 __  __     __     ______     __  __        ______   __  __     __   __   ______     ______
/\ \_\ \   /\ \   /\  ___\   /\ \_\ \      /\  ___\ /\ \_\ \   /\ \ / /  /\  ___\   /\  ___\
\ \  __ \  \ \ \  \ \ \__ \  \ \  __ \     \ \  __\ \ \____ \  \ \ \'/   \ \  __\   \ \___  \
 \ \_\ \_\  \ \_\  \ \_____\  \ \_\ \_\     \ \_\    \/\_____\  \ \__|    \ \_____\  \/\_____\
  \/_/\/_/   \/_/   \/_____/   \/_/\/_/      \/_/     \/_____/   \/_/      \/_____/   \/_____/

*/

if (!window.Fyve) {
  Fyve = {};
}

Fyve.Views = {};

/*
  Welcome Screen
  ==============

  Detects whether or not the user
  is logged in and forwards them
  to either the signup/login screen
  or the chooseYourFyve screen.
*/
Fyve.Views.welcome = function () {
  return (
    '
' +
      '

' +
      '

' +
      '

' +
      '
' +
        '

Enter

' +
      '
' +
    '
'
  );
};

/*
  Choose Your Fyve
  ================

  Choose whether you want to take
  on the role of the fyver or the
  fyvee.
*/
Fyve.Views.chooseYourFyve = function () {
  return (
    '
' +
      '
Fyvee
' +
      '
Receive an epic
high five!
' +
      '

' +
      '

Go

' +
    '
' +
    '
' +
      '
Fyver
' +
      "
Go give the world's
most epic high five!
" +
      '

' +
      '

Go

' +
    '
'
  );
};

/*
  So Alone
  ========

  You haven't been paired up with
  anyone just yet. Hang on for a
  high fyve.
*/
Fyve.Views.soAlone = function () {
  return '

';
};

/*
  Ready to fyve
  =============

  You've been paired with another
  highFyves user. Get ready to
  give a High Fyve. This screen
  will be different depending on
  whether you're the fyver or
  fyvee.

  This view has buttons for
  "Fyve Complete" or "Got Left
  Hanging." One of those buttons
  will forward you to the next screen.

  @param fyveRole accepts either
    "fyver" or "fyvee".
*/
Fyve.Views.readyTofyve = function (fyveRole) {
  if (Fyve.role == 'fivee') {
    return (
      '
' +
        '
@foleyatwork
' +
        '
300ft away. Stay put and wait to be high fived.
' +
        '
' +
          '

' +
          '

' +
          '

' +
          '

' +
        '
' +
        '

Nice, Bro!

' +
        '

Left me Hanging

' +
      '
'
    );
  } else {
    console.log('yuno');
      '
' +
        '
@thefatling
' +
        '
300ft away.
' +
        '
Stay put. Your high five is on the way.
' +
        '

Nice, Bro!

' +
        '

Left me Hanging

' +
      '
'
  }
};

/*
  Nice (or not so nice) Bro
  =========================

  This High Fyve transaction is
  complete. You either executed the
  high fyve or you got left hanging.
  Now it's time to review your
  fyve partner.
*/

Fyve.Views.niceBro = function () {
  if (Fyve.success === "true") {
    return (
      '
Cowabunga!
' +
      '

' +
      '

'
    );
  } else {
    return (
      '
Lame, dude.
' +
      '

' +
      '

'
    );
  }
}

<commit_msg>Changing cowabunga to sweet.<commit_after>
/*
 __  __     __     ______     __  __        ______   __  __     __   __   ______     ______
/\ \_\ \   /\ \   /\  ___\   /\ \_\ \      /\  ___\ /\ \_\ \   /\ \ / /  /\  ___\   /\  ___\
\ \  __ \  \ \ \  \ \ \__ \  \ \  __ \     \ \  __\ \ \____ \  \ \ \'/   \ \  __\   \ \___  \
 \ \_\ \_\  \ \_\  \ \_____\  \ \_\ \_\     \ \_\    \/\_____\  \ \__|    \ \_____\  \/\_____\
  \/_/\/_/   \/_/   \/_____/   \/_/\/_/      \/_/     \/_____/   \/_/      \/_____/   \/_____/

*/

if (!window.Fyve) {
  Fyve = {};
}

Fyve.Views = {};

/*
  Welcome Screen
  ==============

  Detects whether or not the user
  is logged in and forwards them
  to either the signup/login screen
  or the chooseYourFyve screen.
*/
Fyve.Views.welcome = function () {
  return (
    '
' +
      '

' +
      '

' +
      '

' +
      '
' +
        '

Enter

' +
      '
' +
    '
'
  );
};

/*
  Choose Your Fyve
  ================

  Choose whether you want to take
  on the role of the fyver or the
  fyvee.
*/
Fyve.Views.chooseYourFyve = function () {
  return (
    '
' +
      '
Fyvee
' +
      '
Receive an epic
high five!
' +
      '

' +
      '

Go

' +
    '
' +
    '
' +
      '
Fyver
' +
      "
Go give the world's
most epic high five!
" +
      '

' +
      '

Go

' +
    '
'
  );
};

/*
  So Alone
  ========

  You haven't been paired up with
  anyone just yet. Hang on for a
  high fyve.
*/
Fyve.Views.soAlone = function () {
  return '

';
};

/*
  Ready to fyve
  =============

  You've been paired with another
  highFyves user. Get ready to
  give a High Fyve. This screen
  will be different depending on
  whether you're the fyver or
  fyvee.

  This view has buttons for
  "Fyve Complete" or "Got Left
  Hanging." One of those buttons
  will forward you to the next screen.

  @param fyveRole accepts either
    "fyver" or "fyvee".
*/
Fyve.Views.readyTofyve = function (fyveRole) {
  if (Fyve.role == 'fivee') {
    return (
      '
' +
        '
@foleyatwork
' +
        '
300ft away. Stay put and wait to be high fived.
' +
        '
' +
          '

' +
          '

' +
          '

' +
          '

' +
        '
' +
        '

Nice, Bro!

' +
        '

Left me Hanging

' +
      '
'
    );
  } else {
    console.log('yuno');
      '
' +
        '
@thefatling
' +
        '
300ft away.
' +
        '
Stay put. Your high five is on the way.
' +
        '

Nice, Bro!

' +
        '

Left me Hanging

' +
      '
'
  }
};

/*
  Nice (or not so nice) Bro
  =========================

  This High Fyve transaction is
  complete. You either executed the
  high fyve or you got left hanging.
  Now it's time to review your
  fyve partner.
*/

Fyve.Views.niceBro = function () {
  if (Fyve.success === "true") {
    return (
      '
Sweet!
' +
      '

' +
      '

'
    );
  } else {
    return (
      '
Lame, dude.
' +
      '

' +
      '

'
    );
  }
}

<|endoftext|>


<commit_before>
/**
 * WPCOM module
 */

var WPCOM = require('../');
var Site = require('../lib/site');
var Post = require('../lib/post');
var util = require('./util');
var assert = require('assert');

/**
 * Testing data
 */

var test = require('./data');

/**
 * WPCOM instance
 */

describe('WPCOM#Site#Post', function(){
  // var to store post in `add()` test
  var post_added;
  var comment_added;

  // Create a new_post before to start the tests
  var new_post;
  before(function(done){
    util.addPost(function(err, post, comment) {
      if (err) throw err;

      new_post = post;
      comment_added = comment;
      done();
    });
  });

  after(function(done){
    var blog = WPCOM(test.site.private.token).site(test.site.private.id);

    // clean new_post post
    blog.deletePost(new_post.ID, function(err, post) {
      if (err) throw err;

      // clean post_added post
      blog.deletePost(post_added.ID, function(err, post) {
        if (err) throw err;
        done();
      });
    });
  });

  describe('sync', function(){

    it('should create an `Post` instance from `Site`', function(){
      var post = WPCOM().site().post();

      assert.ok(post instanceof Post, 'post is not instance of Post');
    });

    it('should set post `id`', function(){
      var post = WPCOM().site().post();
      post.id(new_post.ID);

      assert.equal(new_post.ID, post._id);
    });

    it('should set post `slug`', function(){
      var post = WPCOM().site().post();
      post.slug(new_post.slug);

      assert.equal(new_post.slug, post._slug);
    });

  });

  describe('async', function(){

    describe('post.get()', function(){

      it('should get added post (by id)', function(done){
        var site = util.private_site();
        var post = site.post(new_post.ID);

        post.get(function(err, post){
          if (err) throw err;

          assert.equal(new_post.ID, post.ID);
          assert.equal(new_post.site_ID, post.site_ID);
          done();
        });
      });

      it('should get passing a query object', function(done){
        var site = util.private_site();
        var post = site.post(new_post.ID);

        post.get({ content: 'edit' }, function(err, post){
          if (err) throw err;

          assert.equal(new_post.ID, post.ID);
          assert.equal(new_post.site_ID, post.site_ID);
          done();
        });
      });

      it('should get added post (by slug)', function(done){
        var site = util.private_site();
        var post = site.post({ slug: new_post.slug });

        post.get(function(err, post){
          if (err) throw err;

          assert.equal(new_post.ID, post.ID);
          assert.equal(new_post.site_ID, post.site_ID);
          done();
        });
      });

    });

    describe('post.add()', function(){

      it('should add a new post', function(done){
        var site = util.private_site();
        var post = site.post();

        post.add(test.new_post_data, function(err, data){
          if (err) throw err;

          // checking some data date
          assert.ok(data);
          assert.ok(data instanceof Object, 'data is not an object');
          assert.equal(test.site.private.id, data.site_ID);

          post_added = data;

          done();
        });
      });

    });

    describe('post.update()', function(){

      it('should edit the new added post', function(done){
        var site = util.private_site();
        var post = site.post(new_post.ID);

        var edited_title = new_post.title + ' has been changed';

        post.update({ title: edited_title }, function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.equal(edited_title, data.title);

          done();
        });
      });

    });

    describe('post.likesList()', function(){

      it('should get post likes list', function(done){
        var site = util.private_site();
        var post = site.post(new_post.ID);

        post.likesList(function(err, data){
          if (err) throw err;

          assert.ok(data);

          assert.equal('number', typeof data.found);
          assert.equal('boolean', typeof data.i_like);
          assert.equal('object', typeof data.likes);
          assert.ok(data.likes instanceof Array);

          done();
        });

      });

    });
/*
    describe('post.related()', function(){

      it('should get related posts', function(done){
        var site = util.private_site();
        var post = site.post(new_post.ID);

        post.related({ size: 5 }, function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.equal('number', typeof data.total);
          assert.ok(data.hits instanceof Array);

          done();
        });

      });

    });
*/

    describe('post.like.add()', function(){

      it('should add a post like', function(done){
        util
        .private_site()
        .post(new_post.ID)
        .like()
        .add(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.success);
          assert.ok(data.i_like);
          assert.equal(1, data.like_count);

          done();
        });

      });

    });

    describe('post.comment.add()', function(){

      it('should add a post comment', function(done){
        util
        .private_site()
        .post(new_post.ID)
        .comment()
        .add({ content: 'Nice post Buddy !!!' }, function(err, data){
          if (err) throw err;

          assert.equal('number', typeof data.ID);
          assert.equal('object', typeof data.post);
          assert.ok(data.post instanceof Object);

          done();
        });

      });

    });

    describe('post.comment.update()', function(){

      it('should update a post comment', function(done){
        util
        .private_site()
        .post(new_post.ID)
        .comment(comment_added.ID)
        .update('Awful post Buddy !!!', function(err, data){
          if (err) throw err;

          assert.equal('number', typeof data.ID);
          assert.equal('object', typeof data.post);
          assert.ok(data.post instanceof Object);
          assert.equal(comment_added.ID, data.ID);

          done();
        });

      });

    });

    describe('post.comment.reply()', function(){

      it('should add a reply to a post comment', function(done){
        util
        .private_site()
        .post(new_post.ID)
        .comment(comment_added.ID)
        .reply('it sucks !!!', function(err, data){
          if (err) throw err;

          assert.equal('number', typeof data.ID);
          assert.equal('object', typeof data.post);
          assert.ok(data.post instanceof Object);
          assert.equal(comment_added.ID, data.parent.ID);

          done();
        });

      });

    });

    describe('post.comment.delete()', function(){

      it('should delete a comment', function(done){
        util
        .private_site()
        .post(new_post.ID)
        .comment(comment_added.ID)
        .del(function(err, data){
          if (err) throw err;

          assert.equal('number', typeof data.ID);
          assert.equal('object', typeof data.post);
          assert.ok(data.post instanceof Object);
          assert.equal(comment_added.ID, data.ID);

          done();
        });

      });

    });

    describe('post.comment.like()', function(){

      it('should add a comment like', function(done){
        util
        .private_site()
        .post(new_post.ID)
        .comment(comment_added.ID)
        .like()
        .add(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.equal(1, data.like_count);
          assert.ok(data.i_like);

          done();
        });

      });

    });

    describe('post.comment.like.mine()', function(){

      it('should get the comment like status of mine', function(done){
        util.private_site()
        .post(new_post.ID)
        .comment(comment_added.ID)
        .like()
        .mine(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.equal(1, data.like_count);
          assert.ok(data.i_like);

          done();
        });
      });

    });

    describe('post.comment.likesList()', function(){

      it('should get comment likes list', function(done){
        util.private_site()
        .post(new_post.ID)
        .comment(comment_added.ID)
        .likesList(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.equal('number', typeof data.found);
          assert.equal('boolean', typeof data.i_like);
          assert.equal('object', typeof data.likes);
          assert.ok(data.likes instanceof Array);

          done();
        });

      });

    });

    describe('post.comment.like.delete()', function(){

      it('should remove your like from the comment', function(done){
        util.private_site()
        .post(new_post.ID)
        .comment(comment_added.ID)
        .like()
        .del(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.success);
          assert.equal(0, data.like_count);
          assert.ok(!(data.i_like));

          done();
        });
      });

    });

    describe('post.like.mine()', function(){

      it('should get the post like status of mine', function(done){
        util.private_site()
        .post(new_post.ID)
        .like()
        .mine(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.equal(1, data.like_count);
          assert.ok(data.i_like);

          done();
        });
      });

    });

    describe('post.reblog.add()', function(){

      it('should get reblog the added post', function(done){
        util.private_site()
        .post(new_post.ID)
        .reblog()
        .add(test.site.reblog, function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.can_reblog);
          done();
        });
      });

    });

    describe('post.reblog.to()', function(){

      it('should get reblog the added post', function(done){
        util.private_site()
        .post(new_post.ID)
        .reblog()
        .to(test.site.reblog.destination_site_id, 'great !!!', function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.can_reblog);
          done();
        });
      });

    });

    describe('post.reblog.mine()', function(){

      it('should get the post reblog status of mine', function(done){
        util.private_site()
        .post(new_post.ID)
        .reblog()
        .mine(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.can_reblog);
          done();
        });
      });

    });

    describe('post.like.delete()', function(){

      it('should remove your like from the post', function(done){
        util.private_site()
        .post(new_post.ID)
        .like()
        .del(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.success);
          assert.equal(0, data.like_count);
          assert.ok(!(data.i_like));

          done();
        });
      });

    });

    describe('post.delete()', function(){

      it('should delete the new added post', function(done){
        var site = util.private_site();
        var post = site.post(new_post.ID);

        post.delete(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.equal(new_post.ID, data.ID);

          done();
        });
      });

    });

    describe('post.restore()', function(){

      it('should restore a post from trash', function(done){
        var site = util.private_site();
        var post = site.post(new_post.ID);

        post.delete(function(err, data){
          if (err) throw err;

            post.restore(function(err, data){
              if (err) throw err;

              assert.ok(data);
              assert.equal(new_post.status, data.status);

              done();
            });

          done();
        });
      });

    });

    describe('post.comments()', function(){

      it('should get the post like status of mine', function(done){
        util.private_site()
        .post(new_post.ID)
        .comments(function(err, data){
          if (err) throw err;

          assert.equal('number', typeof data.found);
          assert.equal('object', typeof data.comments);
          assert.ok(data.comments instanceof Array);

          done();
        });
      });

    });

  });

});
<commit_msg>test: remove duplicated calling to done()<commit_after>
/**
 * WPCOM module
 */

var WPCOM = require('../');
var Site = require('../lib/site');
var Post = require('../lib/post');
var util = require('./util');
var assert = require('assert');

/**
 * Testing data
 */

var test = require('./data');

/**
 * WPCOM instance
 */

describe('WPCOM#Site#Post', function(){
  // var to store post in `add()` test
  var post_added;
  var comment_added;

  // Create a new_post before to start the tests
  var new_post;
  before(function(done){
    util.addPost(function(err, post, comment) {
      if (err) throw err;

      new_post = post;
      comment_added = comment;
      done();
    });
  });

  after(function(done){
    var blog = WPCOM(test.site.private.token).site(test.site.private.id);

    // clean new_post post
    blog.deletePost(new_post.ID, function(err, post) {
      if (err) throw err;

      // clean post_added post
      blog.deletePost(post_added.ID, function(err, post) {
        if (err) throw err;
        done();
      });
    });
  });

  describe('sync', function(){

    it('should create an `Post` instance from `Site`', function(){
      var post = WPCOM().site().post();

      assert.ok(post instanceof Post, 'post is not instance of Post');
    });

    it('should set post `id`', function(){
      var post = WPCOM().site().post();
      post.id(new_post.ID);

      assert.equal(new_post.ID, post._id);
    });

    it('should set post `slug`', function(){
      var post = WPCOM().site().post();
      post.slug(new_post.slug);

      assert.equal(new_post.slug, post._slug);
    });

  });

  describe('async', function(){

    describe('post.get()', function(){

      it('should get added post (by id)', function(done){
        var site = util.private_site();
        var post = site.post(new_post.ID);

        post.get(function(err, post){
          if (err) throw err;

          assert.equal(new_post.ID, post.ID);
          assert.equal(new_post.site_ID, post.site_ID);
          done();
        });
      });

      it('should get passing a query object', function(done){
        var site = util.private_site();
        var post = site.post(new_post.ID);

        post.get({ content: 'edit' }, function(err, post){
          if (err) throw err;

          assert.equal(new_post.ID, post.ID);
          assert.equal(new_post.site_ID, post.site_ID);
          done();
        });
      });

      it('should get added post (by slug)', function(done){
        var site = util.private_site();
        var post = site.post({ slug: new_post.slug });

        post.get(function(err, post){
          if (err) throw err;

          assert.equal(new_post.ID, post.ID);
          assert.equal(new_post.site_ID, post.site_ID);
          done();
        });
      });

    });

    describe('post.add()', function(){

      it('should add a new post', function(done){
        var site = util.private_site();
        var post = site.post();

        post.add(test.new_post_data, function(err, data){
          if (err) throw err;

          // checking some data date
          assert.ok(data);
          assert.ok(data instanceof Object, 'data is not an object');
          assert.equal(test.site.private.id, data.site_ID);

          post_added = data;

          done();
        });
      });

    });

    describe('post.update()', function(){

      it('should edit the new added post', function(done){
        var site = util.private_site();
        var post = site.post(new_post.ID);

        var edited_title = new_post.title + ' has been changed';

        post.update({ title: edited_title }, function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.equal(edited_title, data.title);

          done();
        });
      });

    });

    describe('post.likesList()', function(){

      it('should get post likes list', function(done){
        var site = util.private_site();
        var post = site.post(new_post.ID);

        post.likesList(function(err, data){
          if (err) throw err;

          assert.ok(data);

          assert.equal('number', typeof data.found);
          assert.equal('boolean', typeof data.i_like);
          assert.equal('object', typeof data.likes);
          assert.ok(data.likes instanceof Array);

          done();
        });

      });

    });
/*
    describe('post.related()', function(){

      it('should get related posts', function(done){
        var site = util.private_site();
        var post = site.post(new_post.ID);

        post.related({ size: 5 }, function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.equal('number', typeof data.total);
          assert.ok(data.hits instanceof Array);

          done();
        });

      });

    });
*/

    describe('post.like.add()', function(){

      it('should add a post like', function(done){
        util
        .private_site()
        .post(new_post.ID)
        .like()
        .add(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.success);
          assert.ok(data.i_like);
          assert.equal(1, data.like_count);

          done();
        });

      });

    });

    describe('post.comment.add()', function(){

      it('should add a post comment', function(done){
        util
        .private_site()
        .post(new_post.ID)
        .comment()
        .add({ content: 'Nice post Buddy !!!' }, function(err, data){
          if (err) throw err;

          assert.equal('number', typeof data.ID);
          assert.equal('object', typeof data.post);
          assert.ok(data.post instanceof Object);

          done();
        });

      });

    });

    describe('post.comment.update()', function(){

      it('should update a post comment', function(done){
        util
        .private_site()
        .post(new_post.ID)
        .comment(comment_added.ID)
        .update('Awful post Buddy !!!', function(err, data){
          if (err) throw err;

          assert.equal('number', typeof data.ID);
          assert.equal('object', typeof data.post);
          assert.ok(data.post instanceof Object);
          assert.equal(comment_added.ID, data.ID);

          done();
        });

      });

    });

    describe('post.comment.reply()', function(){

      it('should add a reply to a post comment', function(done){
        util
        .private_site()
        .post(new_post.ID)
        .comment(comment_added.ID)
        .reply('it sucks !!!', function(err, data){
          if (err) throw err;

          assert.equal('number', typeof data.ID);
          assert.equal('object', typeof data.post);
          assert.ok(data.post instanceof Object);
          assert.equal(comment_added.ID, data.parent.ID);

          done();
        });

      });

    });

    describe('post.comment.delete()', function(){

      it('should delete a comment', function(done){
        util
        .private_site()
        .post(new_post.ID)
        .comment(comment_added.ID)
        .del(function(err, data){
          if (err) throw err;

          assert.equal('number', typeof data.ID);
          assert.equal('object', typeof data.post);
          assert.ok(data.post instanceof Object);
          assert.equal(comment_added.ID, data.ID);

          done();
        });

      });

    });

    describe('post.comment.like()', function(){

      it('should add a comment like', function(done){
        util
        .private_site()
        .post(new_post.ID)
        .comment(comment_added.ID)
        .like()
        .add(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.equal(1, data.like_count);
          assert.ok(data.i_like);

          done();
        });

      });

    });

    describe('post.comment.like.mine()', function(){

      it('should get the comment like status of mine', function(done){
        util.private_site()
        .post(new_post.ID)
        .comment(comment_added.ID)
        .like()
        .mine(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.equal(1, data.like_count);
          assert.ok(data.i_like);

          done();
        });
      });

    });

    describe('post.comment.likesList()', function(){

      it('should get comment likes list', function(done){
        util.private_site()
        .post(new_post.ID)
        .comment(comment_added.ID)
        .likesList(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.equal('number', typeof data.found);
          assert.equal('boolean', typeof data.i_like);
          assert.equal('object', typeof data.likes);
          assert.ok(data.likes instanceof Array);

          done();
        });

      });

    });

    describe('post.comment.like.delete()', function(){

      it('should remove your like from the comment', function(done){
        util.private_site()
        .post(new_post.ID)
        .comment(comment_added.ID)
        .like()
        .del(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.success);
          assert.equal(0, data.like_count);
          assert.ok(!(data.i_like));

          done();
        });
      });

    });

    describe('post.like.mine()', function(){

      it('should get the post like status of mine', function(done){
        util.private_site()
        .post(new_post.ID)
        .like()
        .mine(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.equal(1, data.like_count);
          assert.ok(data.i_like);

          done();
        });
      });

    });

    describe('post.reblog.add()', function(){

      it('should get reblog the added post', function(done){
        util.private_site()
        .post(new_post.ID)
        .reblog()
        .add(test.site.reblog, function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.can_reblog);
          done();
        });
      });

    });

    describe('post.reblog.to()', function(){

      it('should get reblog the added post', function(done){
        util.private_site()
        .post(new_post.ID)
        .reblog()
        .to(test.site.reblog.destination_site_id, 'great !!!', function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.can_reblog);
          done();
        });
      });

    });

    describe('post.reblog.mine()', function(){

      it('should get the post reblog status of mine', function(done){
        util.private_site()
        .post(new_post.ID)
        .reblog()
        .mine(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.can_reblog);
          done();
        });
      });

    });

    describe('post.like.delete()', function(){

      it('should remove your like from the post', function(done){
        util.private_site()
        .post(new_post.ID)
        .like()
        .del(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.success);
          assert.equal(0, data.like_count);
          assert.ok(!(data.i_like));

          done();
        });
      });

    });

    describe('post.delete()', function(){

      it('should delete the new added post', function(done){
        var site = util.private_site();
        var post = site.post(new_post.ID);

        post.delete(function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.equal(new_post.ID, data.ID);

          done();
        });
      });

    });

    describe('post.restore()', function(){

      it('should restore a post from trash', function(done){
        var site = util.private_site();
        var post = site.post(new_post.ID);

        post.delete(function(err, data){
          if (err) throw err;

            post.restore(function(err, data){
              if (err) throw err;

              assert.ok(data);
              assert.equal(new_post.status, data.status);

              done();
            });
        });
      });

    });

    describe('post.comments()', function(){

      it('should get the post like status of mine', function(done){
        util.private_site()
        .post(new_post.ID)
        .comments(function(err, data){
          if (err) throw err;

          assert.equal('number', typeof data.found);
          assert.equal('object', typeof data.comments);
          assert.ok(data.comments instanceof Array);

          done();
        });
      });

    });

  });

});
<|endoftext|>


<commit_before>define(['../lib/ssf'], function(ssf){
    return {
        'module': "Alignment Test",
        'tests': [
            ["Simple left alignment",
            function(){
                assert.equal(ssf.format("a@(a,-4)b", {'a': '1'}), "a1   b");
            }],
            ["Simple left alignment",
            function(){
                assert.equal(ssf.format("a@(a,4)b", {'a': '1'}), "a   1b");
            }],

            ["Too long left alignment",
            function(){
                assert.equal(ssf.format("a@(a,-4)b", {'a': 'ccccccc'}), "acccccccb");
            }],
            ["Too long right alignment",
            function(){
                assert.equal(ssf.format("a@(a,4)b", {'a': 'ccccccc'}), "acccccccb");
            }],

            ["No alignment",
            function(){
                assert.equal(ssf.format("a@(a,)b", {'a': '1'}), "a1b");
            }],
            ["Invalid alignment",
            function(){
                assert.equal(ssf.format("a@(a,c)b", {'a': '1'}), "a1b");
            }],
            ["Other number formats alignment",
            function(){
                assert.equal(ssf.format("a@(a,4.0)b", {'a': '1'}), "a   1b");
                assert.equal(ssf.format("a@(a,0x4)b", {'a': '1'}), "a   1b");
            }],
        ],
    };
});
<commit_msg>Removed test for other number format alignment, only support decimal numbers.<commit_after>define(['../lib/ssf'], function(ssf){
    return {
        'module': "Alignment Test",
        'tests': [
            ["Simple left alignment",
            function(){
                assert.equal(ssf.format("a@(a,-4)b", {'a': '1'}), "a1   b");
            }],
            ["Simple left alignment",
            function(){
                assert.equal(ssf.format("a@(a,4)b", {'a': '1'}), "a   1b");
            }],

            ["Too long left alignment",
            function(){
                assert.equal(ssf.format("a@(a,-4)b", {'a': 'ccccccc'}), "acccccccb");
            }],
            ["Too long right alignment",
            function(){
                assert.equal(ssf.format("a@(a,4)b", {'a': 'ccccccc'}), "acccccccb");
            }],

            ["No alignment",
            function(){
                assert.equal(ssf.format("a@(a,)b", {'a': '1'}), "a1b");
            }],
            ["Invalid alignment",
            function(){
                assert.equal(ssf.format("a@(a,c)b", {'a': '1'}), "a1b");
            }],
        ],
    };
});
<|endoftext|>


<commit_before>app.controller('simulatorController', function($scope) {
  console.log('SimulatorController');

  function resizeVideo() {
    // TODO dynamic toolbar height
    $scope.videoRight.height = window.innerHeight - 44;
    $scope.video.height = window.innerHeight - 44;
    $scope.videoRight.width = window.innerWidth;
    $scope.video.width = window.innerWidth;
  }

  function switchOnAR() {
    $scope.videoRight.src = $scope.video.src;
    $scope.videoRight.play();
    $scope.videoRight.className = $scope.video.className;
  }

  function switchOffAR() {
    $scope.videoRight.pause();
    $scope.videoRight.className = '';
  }

  function stopVideo() {
    $scope.video.pause();
    $scope.videoRight.pause();
    $scope.video.src = '';
    $scope.videoRight.src = '';

    if ($scope.stream) {
      $scope.stream.getVideoTracks()[0].stop();
    }
  }

  function successCallback(stream) {
    $scope.stream = stream;
    $scope.video.src = window.URL.createObjectURL(stream);
    resizeVideo();

    navigatorMain.on('prepush', stopVideo);
    navigatorMain.on('postpop',stopVideo);

  }

  function errorCallback(error) {
    console.log('navigator.getUserMedia error: ', error);
  }

  // Export functions
  $scope.updateFilter = function() {
    var prefix = '';
    var filter = $scope.selectedFilter.toLowerCase() + 'Effect';
    if ($scope.armode) {
      prefix += 'stereo ';
      $scope.videoRight.className = prefix + filter;
    }
    $scope.video.className = prefix + filter;
  };

  $scope.toggleAR = function() {
    $scope.armode = !$scope.armode;
    if ($scope.armode) {
      switchOnAR();
    } else {
      switchOffAR();
    }
  };

  // Init
  $scope.selectedFilter = 'NORMAL';
  $scope.video = document.querySelector('video#left');
  $scope.videoRight = document.querySelector('video#right');

  // Events
  window.addEventListener('resize', resizeVideo);
  ons.orientation.on('change', function() {
    if (ons.orientation.isPortrait()) {
      $scope.armode = false;
      switchOffAR();
      $scope.$apply();
    }
  });

  // Load media stream
  if (typeof MediaStreamTrack === 'undefined' ||
    typeof MediaStreamTrack.getSources === 'undefined') {

    // TODO onsenUI clean modal
    alert('This browser does not support MediaStreamTrack.\n\nTry Chrome.');
    navigatorMain.popPage();
  } else {
    // Deprecated but supported by android webview
    MediaStreamTrack.getSources(function(sources) {
      var targetSourceId;
      sources.forEach(function(source) {
        if (source.facing === 'environment') {
          targetSourceId = source.id;
        }
      });
      if (!targetSourceId) {
        if (sources[0]) {
          targetSourceId = sources[0].id;
        }
        if (sources[1]) {
          targetSourceId = sources[1].id;
        }
        if (sources[2]) {
          targetSourceId = sources[2].id;
        }
      }

      console.log(targetSourceId);

      navigator.webkitGetUserMedia({
        audio: false,
        video: {
          optional: [{
            sourceId: targetSourceId,
          },],
        },
      }, successCallback, errorCallback);
    });
  }

});
<commit_msg>fix orientation event issue<commit_after>app.controller('simulatorController', function($scope) {
  console.log('SimulatorController');

  function resizeVideo() {
    // TODO dynamic toolbar height
    $scope.videoRight.height = window.innerHeight - 44;
    $scope.video.height = window.innerHeight - 44;
    $scope.videoRight.width = window.innerWidth;
    $scope.video.width = window.innerWidth;
  }

  function switchOnAR() {
    $scope.videoRight.src = $scope.video.src;
    $scope.videoRight.play();
    $scope.videoRight.className = $scope.video.className;
  }

  function switchOffAR() {
    $scope.videoRight.pause();
    $scope.videoRight.className = '';
  }

  function stopVideo() {
    $scope.video.pause();
    $scope.videoRight.pause();
    $scope.video.src = '';
    $scope.videoRight.src = '';

    if ($scope.stream) {
      $scope.stream.getVideoTracks()[0].stop();
    }
  }

  function successCallback(stream) {
    $scope.stream = stream;
    $scope.video.src = window.URL.createObjectURL(stream);
    resizeVideo();

    navigatorMain.on('prepush', stopVideo);
    navigatorMain.on('postpop',stopVideo);

  }

  function errorCallback(error) {
    console.log('navigator.getUserMedia error: ', error);
  }

  // Export functions
  $scope.updateFilter = function() {
    var prefix = '';
    var filter = $scope.selectedFilter.toLowerCase() + 'Effect';
    if ($scope.armode) {
      prefix += 'stereo ';
      $scope.videoRight.className = prefix + filter;
    }
    $scope.video.className = prefix + filter;
  };

  $scope.toggleAR = function() {
    $scope.armode = !$scope.armode;
    if ($scope.armode) {
      switchOnAR();
    } else {
      switchOffAR();
    }
  };

  // Init
  $scope.selectedFilter = 'NORMAL';
  $scope.video = document.querySelector('video#left');
  $scope.videoRight = document.querySelector('video#right');

  // Events
  window.addEventListener('resize', resizeVideo);
  ons.orientation.on('change', function() {
    if (ons.orientation.isPortrait() && $scope.armode) {
      $scope.armode = false;
      switchOffAR();
      $scope.$apply();
    }
  });

  // Load media stream
  if (typeof MediaStreamTrack === 'undefined' ||
    typeof MediaStreamTrack.getSources === 'undefined') {

    // TODO onsenUI clean modal
    alert('This browser does not support MediaStreamTrack.\n\nTry Chrome.');
    navigatorMain.popPage();
  } else {
    // Deprecated but supported by android webview
    MediaStreamTrack.getSources(function(sources) {
      var targetSourceId;
      sources.forEach(function(source) {
        if (source.facing === 'environment') {
          targetSourceId = source.id;
        }
      });
      if (!targetSourceId) {
        if (sources[0]) {
          targetSourceId = sources[0].id;
        }
        if (sources[1]) {
          targetSourceId = sources[1].id;
        }
        if (sources[2]) {
          targetSourceId = sources[2].id;
        }
      }

      console.log(targetSourceId);

      navigator.webkitGetUserMedia({
        audio: false,
        video: {
          optional: [{
            sourceId: targetSourceId,
          },],
        },
      }, successCallback, errorCallback);
    });
  }

});
<|endoftext|>


<commit_before>import moment from 'moment';
import DS from 'ember-data';
import Ember from 'ember';
import PublishableModel from 'ilios-common/mixins/publishable-model';
import CategorizableModel from 'ilios-common/mixins/categorizable-model';
import SortableByPosition from 'ilios-common/mixins/sortable-by-position';

const { computed, isEmpty, isPresent, RSVP } = Ember;
const { alias, mapBy, sum } = computed;
const { attr, belongsTo, hasMany, Model } = DS;
const { all, Promise } = RSVP;

export default Model.extend(PublishableModel, CategorizableModel, SortableByPosition, {
  title: attr('string'),
  attireRequired: attr('boolean'),
  equipmentRequired: attr('boolean'),
  supplemental: attr('boolean'),
  attendanceRequired: attr('boolean'),
  updatedAt: attr('date'),
  sessionType: belongsTo('session-type', {async: true}),
  course: belongsTo('course', {async: true}),
  ilmSession: belongsTo('ilm-session', {async: true}),
  objectives: hasMany('objective', {async: true}),
  meshDescriptors: hasMany('mesh-descriptor', {async: true}),
  sessionDescription: belongsTo('session-description', {async: true}),
  learningMaterials: hasMany('session-learning-material', {async: true}),
  offerings: hasMany('offering', {async: true}),
  administrators: hasMany('user', {
    async: true,
    inverse: 'administeredSessions'
  }),
  offeringLearnerGroups: mapBy('offerings', 'learnerGroups'),
  offeringLearnerGroupsLength: mapBy('offeringLearnerGroups', 'length'),
  learnerGroupCount: sum('offeringLearnerGroupsLength'),

  isIndependentLearning: computed('ilmSession', function(){
    return !isEmpty(this.belongsTo('ilmSession').id());
  }),

  /**
   * All offerings for this session, sorted by offering startdate in ascending order.
   * @property sortedOfferingsByDate
   * @type {Ember.computed}
   */
  sortedOfferingsByDate: computed('offerings.@each.startDate', function() {
    return new Promise(resolve => {
      this.get('offerings').then(offerings => {
        let filteredOfferings = offerings.filter(offering => isPresent(offering.get('startDate')));
        let sortedOfferings = filteredOfferings.sort((a, b) => {
          let aDate = moment(a.get('startDate'));
          let bDate = moment(b.get('startDate'));
          if(aDate === bDate){
            return 0;
          }
          return aDate > bDate ? 1 : -1;
        });
        resolve(sortedOfferings);
      });
    });
  }),

  /**
   * The earliest start date of all offerings in this session, or, if this is an ILM session, the ILM's due date.
   *
   * @property firstOfferingDate
   * @type {Ember.computed}
   */
  firstOfferingDate: computed('sortedOfferingsByDate.@each.startDate', 'ilmSession.dueDate', function(){
    return new Promise(resolve => {
      this.get('ilmSession').then(ilmSession => {
        if(ilmSession){
          resolve(ilmSession.get('dueDate'));
        } else {
          this.get('sortedOfferingsByDate').then(offerings => {
            if(isEmpty(offerings)){
              resolve(null);
            } else {
              resolve(offerings.get('firstObject.startDate'));
            }
          });
        }
      });
    });
  }),

  /**
   * The maximum duration in hours (incl. fractions) of any session offerings.
   * @property sortedTerms
   * @type {Ember.computed}
   */
  maxSingleOfferingDuration: computed('offerings.@each.startDate', 'offerings.@each.endDate', function(){
    return new Promise(resolve => {
      this.get('offerings').then(offerings => {
        if (! offerings.length) {
          resolve(0);
        } else {
          const sortedOfferings = offerings.toArray().sort(function (a, b) {
            const diffA = moment(a.get('endDate')).diff(moment(a.get('startDate')), 'minutes');
            const diffB = moment(b.get('endDate')).diff(moment(b.get('startDate')), 'minutes');
            if (diffA > diffB) {
              return 1;
            } else if (diffA < diffB) {
              return -1;
            }
            return 0;
          });
          const offering = sortedOfferings[0];
          const duration = moment(offering.get('endDate')).diff(moment(offering.get('startDate')), 'hours', true);
          resolve(duration.toFixed(2));
        }
      });
    });
  }),

  /**
   * The total duration in hours (incl. fractions) of all session offerings.
   * @property sortedTerms
   * @type {Ember.computed}
   */
  totalSumOfferingsDuration: computed('offerings.@each.startDate', 'offerings.@each.endDate', async function() {
    const offerings = await this.get('offerings');
    if (isEmpty(offerings)) {
      return 0;
    }

    const total = offerings.reduce((total, offering) => {
      return total + moment(offering.get('endDate')).diff(moment(offering.get('startDate')), 'hours', true);
    }, 0);

    return total.toFixed(2);
  }),

  optionalPublicationLengthFields: ['terms', 'objectives', 'meshDescriptors'],
  requiredPublicationIssues: computed(
    'title',
    'offerings.length',
    'ilmSession.dueDate',
    'isIndependentLearning',
    function(){
      if(!this.get('isIndependentLearning')){
        this.set('requiredPublicationLengthFields', ['offerings']);
        this.set('requiredPublicationSetFields', ['title']);
      } else {
        this.set('requiredPublicationLengthFields', []);
        this.set('requiredPublicationSetFields', ['title', 'ilmSession.dueDate']);
      }
      return this.getRequiredPublicationIssues();
    }
  ),
  optionalPublicationIssues: computed(
    'terms.length',
    'objectives.length',
    'meshDescriptors.length',
    function(){
      return this.getOptionalPublicationIssues();
    }
  ),

  /**
   * Learner-groups associated with this session via its offerings.
   *
   * @property associatedOfferingLearnerGroups
   * @type {Ember.computed}
   */
  associatedOfferingLearnerGroups: computed('offerings.@each.learnerGroups', async function(){
    const offerings = await this.get('offerings');
    const offeringLearnerGroups = await all(offerings.mapBy('learnerGroups'));
    return offeringLearnerGroups.reduce((array, set) => {
      array.pushObjects(set.toArray());
      return array;
    }, []).uniq().sortBy('title');
  }),

  /**
   * Learner-groups associated with this session via its ILM.
   * @property associatedIlmLearnerGroups
   * @type {Ember.computed}
   */
  associatedIlmLearnerGroups: computed('ilmSession.learnerGroups', async function(){
    const ilmSession = await this.get('ilmSession');
    if (! isPresent(ilmSession)) {
      return [];
    }

    const learnerGroups = await ilmSession.get('learnerGroups');
    return learnerGroups.sortBy('title');
  }),

  /**
   * Learner-groups associated with this session via its ILM and offerings.
   * @property associatedLearnerGroups
   * @type {Ember.computed}
   */
  associatedLearnerGroups: computed('associatedIlmLearnerGroups.[]', 'associatedOfferingLearnerGroups.[]', async function(){
    const ilmLearnerGroups = await this.get('associatedIlmLearnerGroups');
    const offeringLearnerGroups = await this.get('associatedOfferingLearnerGroups');
    const allGroups = [].pushObjects(offeringLearnerGroups).pushObjects(ilmLearnerGroups);
    return allGroups.uniq().sortBy('title');
  }),

  assignableVocabularies: alias('course.assignableVocabularies'),

  /**
   * A list of session objectives, sorted by position (asc) and then id (desc).
   * @property sortedObjectives
   * @type {Ember.computed}
   */
  sortedObjectives: computed('objectives.@each.position', async function() {
    const objectives = await this.get('objectives');
    return objectives.toArray().sort(this.positionSortingCallback);
  })

});
<commit_msg>BUGFIX: corrected sort order in maxSingleOfferingDuration CP.<commit_after>import moment from 'moment';
import DS from 'ember-data';
import Ember from 'ember';
import PublishableModel from 'ilios-common/mixins/publishable-model';
import CategorizableModel from 'ilios-common/mixins/categorizable-model';
import SortableByPosition from 'ilios-common/mixins/sortable-by-position';

const { computed, isEmpty, isPresent, RSVP } = Ember;
const { alias, mapBy, sum } = computed;
const { attr, belongsTo, hasMany, Model } = DS;
const { all, Promise } = RSVP;

export default Model.extend(PublishableModel, CategorizableModel, SortableByPosition, {
  title: attr('string'),
  attireRequired: attr('boolean'),
  equipmentRequired: attr('boolean'),
  supplemental: attr('boolean'),
  attendanceRequired: attr('boolean'),
  updatedAt: attr('date'),
  sessionType: belongsTo('session-type', {async: true}),
  course: belongsTo('course', {async: true}),
  ilmSession: belongsTo('ilm-session', {async: true}),
  objectives: hasMany('objective', {async: true}),
  meshDescriptors: hasMany('mesh-descriptor', {async: true}),
  sessionDescription: belongsTo('session-description', {async: true}),
  learningMaterials: hasMany('session-learning-material', {async: true}),
  offerings: hasMany('offering', {async: true}),
  administrators: hasMany('user', {
    async: true,
    inverse: 'administeredSessions'
  }),
  offeringLearnerGroups: mapBy('offerings', 'learnerGroups'),
  offeringLearnerGroupsLength: mapBy('offeringLearnerGroups', 'length'),
  learnerGroupCount: sum('offeringLearnerGroupsLength'),

  isIndependentLearning: computed('ilmSession', function(){
    return !isEmpty(this.belongsTo('ilmSession').id());
  }),

  /**
   * All offerings for this session, sorted by offering startdate in ascending order.
   * @property sortedOfferingsByDate
   * @type {Ember.computed}
   */
  sortedOfferingsByDate: computed('offerings.@each.startDate', function() {
    return new Promise(resolve => {
      this.get('offerings').then(offerings => {
        let filteredOfferings = offerings.filter(offering => isPresent(offering.get('startDate')));
        let sortedOfferings = filteredOfferings.sort((a, b) => {
          let aDate = moment(a.get('startDate'));
          let bDate = moment(b.get('startDate'));
          if(aDate === bDate){
            return 0;
          }
          return aDate > bDate ? 1 : -1;
        });
        resolve(sortedOfferings);
      });
    });
  }),

  /**
   * The earliest start date of all offerings in this session, or, if this is an ILM session, the ILM's due date.
   *
   * @property firstOfferingDate
   * @type {Ember.computed}
   */
  firstOfferingDate: computed('sortedOfferingsByDate.@each.startDate', 'ilmSession.dueDate', function(){
    return new Promise(resolve => {
      this.get('ilmSession').then(ilmSession => {
        if(ilmSession){
          resolve(ilmSession.get('dueDate'));
        } else {
          this.get('sortedOfferingsByDate').then(offerings => {
            if(isEmpty(offerings)){
              resolve(null);
            } else {
              resolve(offerings.get('firstObject.startDate'));
            }
          });
        }
      });
    });
  }),

  /**
   * The maximum duration in hours (incl. fractions) of any session offerings.
   * @property sortedTerms
   * @type {Ember.computed}
   */
  maxSingleOfferingDuration: computed('offerings.@each.startDate', 'offerings.@each.endDate', function(){
    return new Promise(resolve => {
      this.get('offerings').then(offerings => {
        if (! offerings.length) {
          resolve(0);
        } else {
          const sortedOfferings = offerings.toArray().sort(function (a, b) {
            const diffA = moment(a.get('endDate')).diff(moment(a.get('startDate')), 'minutes');
            const diffB = moment(b.get('endDate')).diff(moment(b.get('startDate')), 'minutes');
            if (diffA > diffB) {
              return -1;
            } else if (diffA < diffB) {
              return 1;
            }
            return 0;
          });
          const offering = sortedOfferings[0];
          const duration = moment(offering.get('endDate')).diff(moment(offering.get('startDate')), 'hours', true);
          resolve(duration.toFixed(2));
        }
      });
    });
  }),

  /**
   * The total duration in hours (incl. fractions) of all session offerings.
   * @property sortedTerms
   * @type {Ember.computed}
   */
  totalSumOfferingsDuration: computed('offerings.@each.startDate', 'offerings.@each.endDate', async function() {
    const offerings = await this.get('offerings');
    if (isEmpty(offerings)) {
      return 0;
    }

    const total = offerings.reduce((total, offering) => {
      return total + moment(offering.get('endDate')).diff(moment(offering.get('startDate')), 'hours', true);
    }, 0);

    return total.toFixed(2);
  }),

  optionalPublicationLengthFields: ['terms', 'objectives', 'meshDescriptors'],
  requiredPublicationIssues: computed(
    'title',
    'offerings.length',
    'ilmSession.dueDate',
    'isIndependentLearning',
    function(){
      if(!this.get('isIndependentLearning')){
        this.set('requiredPublicationLengthFields', ['offerings']);
        this.set('requiredPublicationSetFields', ['title']);
      } else {
        this.set('requiredPublicationLengthFields', []);
        this.set('requiredPublicationSetFields', ['title', 'ilmSession.dueDate']);
      }
      return this.getRequiredPublicationIssues();
    }
  ),
  optionalPublicationIssues: computed(
    'terms.length',
    'objectives.length',
    'meshDescriptors.length',
    function(){
      return this.getOptionalPublicationIssues();
    }
  ),

  /**
   * Learner-groups associated with this session via its offerings.
   *
   * @property associatedOfferingLearnerGroups
   * @type {Ember.computed}
   */
  associatedOfferingLearnerGroups: computed('offerings.@each.learnerGroups', async function(){
    const offerings = await this.get('offerings');
    const offeringLearnerGroups = await all(offerings.mapBy('learnerGroups'));
    return offeringLearnerGroups.reduce((array, set) => {
      array.pushObjects(set.toArray());
      return array;
    }, []).uniq().sortBy('title');
  }),

  /**
   * Learner-groups associated with this session via its ILM.
   * @property associatedIlmLearnerGroups
   * @type {Ember.computed}
   */
  associatedIlmLearnerGroups: computed('ilmSession.learnerGroups', async function(){
    const ilmSession = await this.get('ilmSession');
    if (! isPresent(ilmSession)) {
      return [];
    }

    const learnerGroups = await ilmSession.get('learnerGroups');
    return learnerGroups.sortBy('title');
  }),

  /**
   * Learner-groups associated with this session via its ILM and offerings.
   * @property associatedLearnerGroups
   * @type {Ember.computed}
   */
  associatedLearnerGroups: computed('associatedIlmLearnerGroups.[]', 'associatedOfferingLearnerGroups.[]', async function(){
    const ilmLearnerGroups = await this.get('associatedIlmLearnerGroups');
    const offeringLearnerGroups = await this.get('associatedOfferingLearnerGroups');
    const allGroups = [].pushObjects(offeringLearnerGroups).pushObjects(ilmLearnerGroups);
    return allGroups.uniq().sortBy('title');
  }),

  assignableVocabularies: alias('course.assignableVocabularies'),

  /**
   * A list of session objectives, sorted by position (asc) and then id (desc).
   * @property sortedObjectives
   * @type {Ember.computed}
   */
  sortedObjectives: computed('objectives.@each.position', async function() {
    const objectives = await this.get('objectives');
    return objectives.toArray().sort(this.positionSortingCallback);
  })

});
<|endoftext|>


<commit_before>import { registerWaiter, unregisterWaiter } from '@ember/test';
import { Promise as EmberPromise } from 'rsvp';
import { next } from '@ember/runloop';
import { getOwner } from '@ember/application';
import Service from '@ember/service';
import { DEBUG } from '@glimmer/env';
import RunningTransition from "./running-transition";
import DSL from "./dsl";
import Ember from "ember";
import Action from "./action";
import Constraints from "./constraints";

var TransitionMap = Service.extend({
  init() {
    this._super(...arguments);

    this.activeCount = 0;
    this.constraints = new Constraints();
    var owner = getOwner(this);
    var config;
    if (owner.factoryFor) {
      let maybeConfig = owner.factoryFor('transitions:main');
      config = maybeConfig && maybeConfig.class;
    } else {
      config = owner._lookupFactory('transitions:main');
    }
    if (config) {
      this.map(config);
    }
  },

  runningTransitions() {
    return this.activeCount;
  },

  incrementRunningTransitions() {
    this.activeCount++;
  },

  decrementRunningTransitions() {
    this.activeCount--;
    next(() => {
      this._maybeResolveIdle();
    });
  },

  waitUntilIdle() {
    if (this._waitingPromise) {
      return this._waitingPromise;
    }
    return this._waitingPromise = new EmberPromise((resolve) => {
      this._resolveWaiting = resolve;
      next(() => {
        this._maybeResolveIdle();
      });
    });
  },

  _maybeResolveIdle() {
    if (this.activeCount === 0 && this._resolveWaiting) {
      var resolveWaiting = this._resolveWaiting;
      this._resolveWaiting = null;
      this._waitingPromise = null;
      resolveWaiting();
    }
  },

  lookup(transitionName) {
    var owner = getOwner(this);
    var handler;
    if (owner.factoryFor) {
      let maybeHandler = owner.factoryFor('transition:' + transitionName);
      handler = maybeHandler && maybeHandler.class;
    } else {
      handler = owner._lookupFactory('transition:' + transitionName);
    }
    if (!handler) {
      throw new Error("unknown transition name: " + transitionName);
    }
    return handler;
  },

  defaultAction() {
    if (!this._defaultAction) {
      this._defaultAction = new Action(this.lookup('default'));
    }
    return this._defaultAction;
  },

  constraintsFor(conditions) {
    if (conditions.rules) {
      let constraints = new Constraints();
      this.map(conditions.rules, constraints);
      return constraints;
    } else {
      return this.constraints;
    }
  },

  transitionFor(conditions) {
    var action;
    if (conditions.use && conditions.firstTime !== 'yes') {
      action = new Action(conditions.use);
      action.validateHandler(this);
    } else {
      let rule = this.constraintsFor(conditions).bestMatch(conditions);
      if (rule) {
        action = rule.use;
      } else {
        action = this.defaultAction();
      }
    }
    return new RunningTransition(this, conditions.versions, action);
  },

  map(handler, constraints) {
    if (handler){
      handler.apply(new DSL(this, constraints || this.constraints));
    }
    return this;
  }
});

if (DEBUG) {
  TransitionMap.reopen({
    init() {
      this._super(...arguments);

      if (Ember.testing) {
        this._waiter = () => {
          return this.runningTransitions() === 0;
        };
        registerWaiter(this._waiter);
      }
    },

    willDestroy() {
      if (this._waiter) {
        unregisterWaiter(this._waiter);
        this._waiter = null;
      }

      this._super(...arguments);
    }
  });
}

TransitionMap.reopenClass({
  map(handler) {
    var t = TransitionMap.create();
    t.map(handler);
    return t;
  }
});

export default TransitionMap;
<commit_msg>maintain working older embers<commit_after>import { Promise as EmberPromise } from 'rsvp';
import { next } from '@ember/runloop';
import { getOwner } from '@ember/application';
import Service from '@ember/service';
import { DEBUG } from '@glimmer/env';
import RunningTransition from "./running-transition";
import DSL from "./dsl";
import Ember from "ember";
import Action from "./action";
import Constraints from "./constraints";

var TransitionMap = Service.extend({
  init() {
    this._super(...arguments);

    this.activeCount = 0;
    this.constraints = new Constraints();
    var owner = getOwner(this);
    var config;
    if (owner.factoryFor) {
      let maybeConfig = owner.factoryFor('transitions:main');
      config = maybeConfig && maybeConfig.class;
    } else {
      config = owner._lookupFactory('transitions:main');
    }
    if (config) {
      this.map(config);
    }
  },

  runningTransitions() {
    return this.activeCount;
  },

  incrementRunningTransitions() {
    this.activeCount++;
  },

  decrementRunningTransitions() {
    this.activeCount--;
    next(() => {
      this._maybeResolveIdle();
    });
  },

  waitUntilIdle() {
    if (this._waitingPromise) {
      return this._waitingPromise;
    }
    return this._waitingPromise = new EmberPromise((resolve) => {
      this._resolveWaiting = resolve;
      next(() => {
        this._maybeResolveIdle();
      });
    });
  },

  _maybeResolveIdle() {
    if (this.activeCount === 0 && this._resolveWaiting) {
      var resolveWaiting = this._resolveWaiting;
      this._resolveWaiting = null;
      this._waitingPromise = null;
      resolveWaiting();
    }
  },

  lookup(transitionName) {
    var owner = getOwner(this);
    var handler;
    if (owner.factoryFor) {
      let maybeHandler = owner.factoryFor('transition:' + transitionName);
      handler = maybeHandler && maybeHandler.class;
    } else {
      handler = owner._lookupFactory('transition:' + transitionName);
    }
    if (!handler) {
      throw new Error("unknown transition name: " + transitionName);
    }
    return handler;
  },

  defaultAction() {
    if (!this._defaultAction) {
      this._defaultAction = new Action(this.lookup('default'));
    }
    return this._defaultAction;
  },

  constraintsFor(conditions) {
    if (conditions.rules) {
      let constraints = new Constraints();
      this.map(conditions.rules, constraints);
      return constraints;
    } else {
      return this.constraints;
    }
  },

  transitionFor(conditions) {
    var action;
    if (conditions.use && conditions.firstTime !== 'yes') {
      action = new Action(conditions.use);
      action.validateHandler(this);
    } else {
      let rule = this.constraintsFor(conditions).bestMatch(conditions);
      if (rule) {
        action = rule.use;
      } else {
        action = this.defaultAction();
      }
    }
    return new RunningTransition(this, conditions.versions, action);
  },

  map(handler, constraints) {
    if (handler){
      handler.apply(new DSL(this, constraints || this.constraints));
    }
    return this;
  }
});

if (DEBUG) {
  TransitionMap.reopen({
    init() {
      this._super(...arguments);

      if (Ember.testing) {
        this._waiter = () => {
          return this.runningTransitions() === 0;
        };

        // The new module imports version of this function doesn't
        // work in some of the older ember versions we support
        // (because it depends on `this` context).
        Ember.Test.registerWaiter(this._waiter); // eslint-disable-line ember/new-module-imports
      }
    },

    willDestroy() {
      if (this._waiter) {
        // The new module imports version of this function doesn't
        // work in some of the older ember versions we support
        // (because it depends on `this` context).
        Ember.Test.unregisterWaiter(this._waiter); // eslint-disable-line ember/new-module-imports
        this._waiter = null;
      }

      this._super(...arguments);
    }
  });
}

TransitionMap.reopenClass({
  map(handler) {
    var t = TransitionMap.create();
    t.map(handler);
    return t;
  }
});

export default TransitionMap;
<|endoftext|>


<commit_before>/*global seqJS:true  */

(function() {
  /*
    ======== A Handy Little QUnit Reference ========
    http://api.qunitjs.com/

    Test methods:
      module(name, {[setup][ ,teardown]})
      test(name, callback)
      expect(numberOfequalions)
      stop(increment)
      start(decrement)
    Test equalions:
      ok(value, [message])
      equal(actual, expected, [message])
      notEqual(actual, expected, [message])
      deepEqual(actual, expected, [message])
      notDeepEqual(actual, expected, [message])
      strictEqual(actual, expected, [message])
      notStrictEqual(actual, expected, [message])
      throws(block, [expected], [message])
  */

module('seqJS.Span');

    var test_span_init = function(str, e_str){
        test('seqJS.Span(\''+str+'\')', function(){
            expect(1);
            var s = new seqJS.Span(str);
            equal(s.toString(-1), e_str);
        });
    };

    test_span_init('100..150', 'S(L(99):L(150))');
    test_span_init('<100..>150', 'S(L(<99):L(>150))');
    test_span_init('100.105..150', 'S(L(99.105):L(150))');
    test_span_init('100..150.160', 'S(L(99):L(150.161))');

    var test_span_init_fail = function(name, str){
        test(name, function(){
            expect(1);
            throws(function(){
                new seqJS.Span(str);
            });
        });
    };

    test_span_init_fail('locations inverted', '200..100');
    test_span_init_fail('bad formating', '100.200');

    var test_span_invertDatum = function(str, expected_str){
        test('seqJS.Span(\''+str+'\').invertDatum(100)', function(){
            expect(2);
            var s = new seqJS.Span(str);
            var orig = s.toString(-1);

            equal(s.invertDatum(100).toString(-1), expected_str, "InvertDatum failed");
            equal(s.toString(-1), orig, "InvertDatum changed original");
        });
    };

    test_span_invertDatum('5..10', 'S(L(90):L(96))');
    test_span_invertDatum('6..11', 'S(L(89):L(95))');
    test_span_invertDatum('4.5..10.11', 'S(L(89.91):L(96.98))');
    test_span_invertDatum('<5..>10', 'S(L(<90):L(>96))');

    var test_span_offset = function(str, offset, expected_str){
        test('seqJS.Span(\''+str+'\').offset('+offset+')', function(){
            expect(2);
            var s = new seqJS.Span(str);
            var orig = s.toString(-1);

            equal(s.offset(offset).toString(-1), expected_str, "Offset failed");
            equal(s.toString(-1), orig, "Offset changed original");
        });
    };

    test_span_offset('5..10', 5, 'S(L(9):L(15))');
    test_span_offset('5..10', -2, 'S(L(2):L(8))');
    test_span_offset('5..10', 0, 'S(L(4):L(10))');

module('seqJS.Span.crop');
    var test_span_crop = function(span_left, span_right, start, end, expected_str){
        var span = new seqJS.Span(new seqJS.Location(span_left[0], span_left[1], span_left[2]),
                                  new seqJS.Location(span_right[0], span_right[1], span_right[2]));

        test(span.toString(-1) + '.crop('+start+', '+end+')',
             function(){
            var original = span.toString(-1);

            equal(span.crop(start,end).toString(-1),
                  expected_str,
                  "crop with integers");
            equal(span.toString(-1), original, "Span changed by crop calls");

            equal(span.crop(new seqJS.Location(start),
                            new seqJS.Location(end)).toString(-1),
                  expected_str,
                  "crop with Locations");

            equal(span.toString(-1), original, "Span changed by crop calls");
        });
    };

        test_span_crop([20],[30], 10, 40, 'S(L(10):L(20))');
        test_span_crop([20],[30], 25, 40, 'S(L(0):L(5))');
        test_span_crop([20],[30], 10, 25, 'S(L(10):L(15))');

        test_span_crop([20, '<'],[30, '>'], 10, 40, 'S(L(<10):L(>20))');
        test_span_crop([20, '<'],[30, '>'], 25, 40, 'S(L(0):L(>5))');
        test_span_crop([20, '<'],[30, '>'], 10, 25, 'S(L(<10):L(15))');

}());
<commit_msg>Improve span tests<commit_after>/*global seqJS:true  */

(function() {
  /*
    ======== A Handy Little QUnit Reference ========
    http://api.qunitjs.com/

    Test methods:
      module(name, {[setup][ ,teardown]})
      test(name, callback)
      expect(numberOfequalions)
      stop(increment)
      start(decrement)
    Test equalions:
      ok(value, [message])
      equal(actual, expected, [message])
      notEqual(actual, expected, [message])
      deepEqual(actual, expected, [message])
      notDeepEqual(actual, expected, [message])
      strictEqual(actual, expected, [message])
      notStrictEqual(actual, expected, [message])
      throws(block, [expected], [message])
  */

module('seqJS.Span');

    var test_span_init = function(str, e_str){
        test('seqJS.Span(\''+str+'\')', function(){
            expect(1);
            var s = new seqJS.Span(str);
            equal(s.toString(-1), e_str);
        });
    };

    test_span_init('100..150', 'S(L(99):L(150))');
    test_span_init('<100..>150', 'S(L(<99):L(>150))');
    test_span_init('100.105..150', 'S(L(99.105):L(150))');
    test_span_init('100..150.160', 'S(L(99):L(150.161))');

    var test_span_init_fail = function(name, str){
        test(name, function(){
            expect(1);
            throws(function(){
                new seqJS.Span(str);
            });
        });
    };

    test_span_init_fail('locations inverted', '200..100');
    test_span_init_fail('bad formating', '100.200');

    var test_span_invertDatum = function(str, expected_str){
        test('seqJS.Span(\''+str+'\').invertDatum(100)', function(){
            expect(2);
            var s = new seqJS.Span(str);
            var orig = s.toString(-1);

            equal(s.invertDatum(100).toString(-1), expected_str, "InvertDatum failed");
            equal(s.toString(-1), orig, "InvertDatum changed original");
        });
    };

    test_span_invertDatum('5..10', 'S(L(90):L(96))');
    test_span_invertDatum('6..11', 'S(L(89):L(95))');
    test_span_invertDatum('4.5..10.11', 'S(L(89.91):L(96.98))');
    test_span_invertDatum('<5..>10', 'S(L(<90):L(>96))');

    var test_span_offset = function(str, offset, expected_str){
        test('seqJS.Span(\''+str+'\').offset('+offset+')', function(){
            expect(2);
            var s = new seqJS.Span(str);
            var orig = s.toString(-1);

            equal(s.offset(offset).toString(-1), expected_str, "Offset failed");
            equal(s.toString(-1), orig, "Offset changed original");
        });
    };

    test_span_offset('5..10', 5, 'S(L(9):L(15))');
    test_span_offset('5..10', -2, 'S(L(2):L(8))');
    test_span_offset('5..10', 0, 'S(L(4):L(10))');

    var test_span_crop = function(span_left, span_right, start, end, expected_str){
        var span = new seqJS.Span(new seqJS.Location(span_left[0], span_left[1], span_left[2]),
                                  new seqJS.Location(span_right[0], span_right[1], span_right[2]));

        test(span.toString(-1) + '.crop('+start+', '+end+')',
             function(){
            var original = span.toString(-1);

            equal(span.crop(start,end).toString(-1),
                  expected_str,
                  "crop with integers");
            equal(span.toString(-1), original, "Span changed by crop calls");

            equal(span.crop(new seqJS.Location(start),
                            new seqJS.Location(end)).toString(-1),
                  expected_str,
                  "crop with Locations");

            equal(span.toString(-1), original, "Span changed by crop calls");
        });
    };

    test_span_crop([20],[30], 10, 40, 'S(L(10):L(20))');
    test_span_crop([20],[30], 25, 40, 'S(L(0):L(5))');
    test_span_crop([20],[30], 10, 25, 'S(L(10):L(15))');

    test_span_crop([20, '<'],[30, '>'], 10, 40, 'S(L(<10):L(>20))');
    test_span_crop([20, '<'],[30, '>'], 25, 40, 'S(L(0):L(>5))');
    test_span_crop([20, '<'],[30, '>'], 10, 25, 'S(L(<10):L(15))');

}());
<|endoftext|>


<commit_before>$(window).keyup(function (event) {
    if (event.keyCode === 27 && $('#contextmenu').length) {
        $('#context-menu-blocker, #contextmenu').remove();
    }
});

function showContextMenu(buttons, x, y) {
    var contextmenu = $('
');

    $.each(buttons, function(i, item) {
        $('
')
            .text(item.title)
            .data('args', item.args)
            .data('callback', item.callback)
            .click(function() {
                $(this).data('callback')($(this).data('args'));
                $('#context-menu-blocker, #contextmenu').remove();
            })
            .appendTo(contextmenu);
    });

    // Set up a blocker div that closes the menu when clicked
    var blocker = $('

').mousedown(function(event) {
        $('#context-menu-blocker, #contextmenu').remove();
        event.stopPropagation();
    });

    blocker.appendTo('body');
    contextmenu.appendTo('body');

	// Make sure contextmenu does not reach outside the window
	if ((y + contextmenu.height()) > $(window).height()) {
		y -= contextmenu.height();
	}
    if ((x + contextmenu.width()) > $(window).width()) {
        x -= contextmenu.width();
    }
    contextmenu.css({
        'top': y,
        'left': x
    });

    // Finally, prevent contextmenu on our contextmenu :)
    $('#context-menu-blocker, #contextmenu, #contextmenu li.option').bind('contextmenu', function (event) {
        event.preventDefault();
    });
}

function showPlaylistContextMenu(event) {
    $('#left .selected').removeClass('selected');
    $(this).addClass('selected');
    event.preventDefault();

    var buttons = [
		{
            title: 'Import from Spotify',
            args: $(this),
            callback: function(li) {
                li.arrowPopup('#spotify-importer', 'left');
            }
        },
        {
            title: 'Remove duplicate videos',
            args: $(this),
            callback: function(li) {
                var index = li.index(),
                    playlist = playlistManager.getPlaylist(index);
				if (confirm(TranslationSystem.translations['This will delete duplicate videos from your playlist. Continue?'])) {
					Notifications.append(playlist.removeDuplicates() + TranslationSystem.translations[' duplicates removed.']);
				}
            }
        },
        {
            title: 'Rename',
            args: $(this),
            callback: function(li) {
                var playlist = null,
                    input = $('<input type="text"/>')
                    .addClass('rename')
                    .val(li.text())
                    .data('li', li)
                    .blur(function(event) {
                        li.find('.title').show();
                        input.remove();
                    })
                    .keyup(function(event) {
                        var playlist;
                        switch (event.keyCode) {
                            case 13: // RETURN
                                playlist = li.data('model');
                                playlist.rename(input.val());
                                playlistManager.save();
                                $(this).blur();
                                break;
                            case 27: // ESC
                                $(this).blur();
                                break;
                        }
                        event.stopPropagation();
                    });

                li.find('.title').hide();
                li.append(input);
                input.focus().select();
            }
        },
        {
            title: 'Delete',
            args: $(this),
            callback: function(li) {
                var index = li.index(),
                    playlist = playlistManager.getPlaylist(index);

                if (confirm("Are you sure you want to delete this playlist (" + playlist.title + ")?")) {
                    playlistManager.deletePlaylist(index);
                    playlistManager.save();
                }
            }
        }
    ];

    if (logged_in && $(this).data('model').remoteId) {
        buttons.push({
            title: 'Share',
            args: $(this),
            callback: function(li) {
                showPlaylistSharePopup(li.data('model'), li, 'left');
            }
        });
    }

    if (logged_in && !$(this).data('model').remoteId) {
        buttons.push({
            title: 'Sync',
            args: $(this),
            callback: function(li) {
                li.data('model').sync(function() {
                    playlistManager.save();
                    li.addClass('remote');
                });
            }
        });
    }

    if (logged_in && $(this).data('model').remoteId) {
        buttons.push({
            title: 'Unsync',
            args: $(this),
            callback: function(li) {
                li.data('model').unsync();
                playlistManager.save();
                li.removeClass('remote');
            }
        });
    }

    if (ON_DEV) {
        buttons.push({
            title: 'View JSON',
            args: $(this),
            callback: function(li) {
                var playlist = li.data('model');
                alert(JSON.stringify(playlist.toJSON()));
                console.log(playlist.toJSON());
            }
        });
    }

    showContextMenu(buttons, event.pageX, event.pageY);
}

function showResultsItemContextMenu(event) {
    var li = $(this);
    var allSelectedVideos = $(this).parent().find('.video.selected');
    var video = $(this).data('model');

    if (!$(li).hasClass('selected')) {
        li.parent().find('.selected').removeClass('selected');
        li.addClass('selected');
    }

    var buttons = [
        {
            title: 'Play',
            args: $(this),
            callback: function(elem) {
                elem.data('model').play();
            }
        },
		{
            title: 'Queue',
            args: allSelectedVideos,
            callback: function(allSelectedVideos) {
                $.each(allSelectedVideos, function(index, li) {
                    var model = $(li).data('model');
                    if (model) {
                        Queue.addManual(model);
                    }
                });
            }
        },
		{
			title: 'Share',
			args: $(this),
			callback: function(elem) {
                var video = $(elem).data('model');
                showVideoSharePopup(video, elem, 'up');
			}
		}
    ];

    switch (video.type) {
        case 'youtube':
        buttons.push({
            title: 'Watch on YouTube',
            args: $(this),
            callback: function(elem) {
                window.open('http://www.youtube.com/watch?v=' + video.videoId);
            }
        });
        break;

        case 'soundcloud':
        buttons.push({
            title: 'Watch on SoundCloud',
            args: $(this),
            callback: function(elem) {
                var url = "http://api.soundcloud.com/tracks/" + video.videoId + ".json";
                var params = {
                    client_id: SOUNDCLOUD_API_KEY
                };
                $.getJSON(url, params, function(data) {
                    window.open(data.permalink_url);
                });
            }
        });
        break;

        case 'officialfm':
        buttons.push({
            title: 'Watch on Official.fm',
            args: $(this),
            callback: function(elem) {
                window.open('http://www.official.fm/tracks/' + video.videoId);
            }
        });
        break;
    }

    if (ON_DEV) {
        buttons.push({
            title: 'View JSON',
            args: $(this),
            callback: function(li) {
                alert(JSON.stringify(video.toJSON()));
                console.log(video.toJSON());
            }
        });
    }

    if ($(this).data('additionalMenuButtons')) {
        buttons = $.merge(buttons, $(this).data('additionalMenuButtons'));
    }

    showContextMenu(buttons, (event.pageX || $(this).offset().left + $(this).width()) , (event.pageY || $(this).offset().top));

    return false;
}
<commit_msg>Changed delete text in contextmenu<commit_after>$(window).keyup(function (event) {
    if (event.keyCode === 27 && $('#contextmenu').length) {
        $('#context-menu-blocker, #contextmenu').remove();
    }
});

function showContextMenu(buttons, x, y) {
    var contextmenu = $('
');

    $.each(buttons, function(i, item) {
        $('
')
            .text(item.title)
            .data('args', item.args)
            .data('callback', item.callback)
            .click(function() {
                $(this).data('callback')($(this).data('args'));
                $('#context-menu-blocker, #contextmenu').remove();
            })
            .appendTo(contextmenu);
    });

    // Set up a blocker div that closes the menu when clicked
    var blocker = $('

').mousedown(function(event) {
        $('#context-menu-blocker, #contextmenu').remove();
        event.stopPropagation();
    });

    blocker.appendTo('body');
    contextmenu.appendTo('body');

	// Make sure contextmenu does not reach outside the window
	if ((y + contextmenu.height()) > $(window).height()) {
		y -= contextmenu.height();
	}
    if ((x + contextmenu.width()) > $(window).width()) {
        x -= contextmenu.width();
    }
    contextmenu.css({
        'top': y,
        'left': x
    });

    // Finally, prevent contextmenu on our contextmenu :)
    $('#context-menu-blocker, #contextmenu, #contextmenu li.option').bind('contextmenu', function (event) {
        event.preventDefault();
    });
}

function showPlaylistContextMenu(event) {
    $('#left .selected').removeClass('selected');
    $(this).addClass('selected');
    event.preventDefault();

    var buttons = [
		{
            title: 'Import from Spotify',
            args: $(this),
            callback: function(li) {
                li.arrowPopup('#spotify-importer', 'left');
            }
        },
        {
            title: 'Remove duplicate videos',
            args: $(this),
            callback: function(li) {
                var index = li.index(),
                    playlist = playlistManager.getPlaylist(index);
				if (confirm(TranslationSystem.translations['This will delete duplicate videos from your playlist. Continue?'])) {
					Notifications.append(playlist.removeDuplicates() + TranslationSystem.translations[' duplicates removed.']);
				}
            }
        },
        {
            title: 'Rename',
            args: $(this),
            callback: function(li) {
                var playlist = null,
                    input = $('<input type="text"/>')
                    .addClass('rename')
                    .val(li.text())
                    .data('li', li)
                    .blur(function(event) {
                        li.find('.title').show();
                        input.remove();
                    })
                    .keyup(function(event) {
                        var playlist;
                        switch (event.keyCode) {
                            case 13: // RETURN
                                playlist = li.data('model');
                                playlist.rename(input.val());
                                playlistManager.save();
                                $(this).blur();
                                break;
                            case 27: // ESC
                                $(this).blur();
                                break;
                        }
                        event.stopPropagation();
                    });

                li.find('.title').hide();
                li.append(input);
                input.focus().select();
            }
        },
        {
            title: 'Delete/Unsubscribe',
            args: $(this),
            callback: function(li) {
                var index = li.index(),
                    playlist = playlistManager.getPlaylist(index);

                if (confirm("Are you sure you want to delete this playlist (" + playlist.title + ")?")) {
                    playlistManager.deletePlaylist(index);
                    playlistManager.save();
                }
            }
        }
    ];

    if (logged_in && $(this).data('model').remoteId) {
        buttons.push({
            title: 'Share',
            args: $(this),
            callback: function(li) {
                showPlaylistSharePopup(li.data('model'), li, 'left');
            }
        });
    }

    if (logged_in && !$(this).data('model').remoteId) {
        buttons.push({
            title: 'Sync',
            args: $(this),
            callback: function(li) {
                li.data('model').sync(function() {
                    playlistManager.save();
                    li.addClass('remote');
                });
            }
        });
    }

    if (logged_in && $(this).data('model').remoteId) {
        buttons.push({
            title: 'Unsync',
            args: $(this),
            callback: function(li) {
                li.data('model').unsync();
                playlistManager.save();
                li.removeClass('remote');
            }
        });
    }

    if (ON_DEV) {
        buttons.push({
            title: 'View JSON',
            args: $(this),
            callback: function(li) {
                var playlist = li.data('model');
                alert(JSON.stringify(playlist.toJSON()));
                console.log(playlist.toJSON());
            }
        });
    }

    showContextMenu(buttons, event.pageX, event.pageY);
}

function showResultsItemContextMenu(event) {
    var li = $(this);
    var allSelectedVideos = $(this).parent().find('.video.selected');
    var video = $(this).data('model');

    if (!$(li).hasClass('selected')) {
        li.parent().find('.selected').removeClass('selected');
        li.addClass('selected');
    }

    var buttons = [
        {
            title: 'Play',
            args: $(this),
            callback: function(elem) {
                elem.data('model').play();
            }
        },
		{
            title: 'Queue',
            args: allSelectedVideos,
            callback: function(allSelectedVideos) {
                $.each(allSelectedVideos, function(index, li) {
                    var model = $(li).data('model');
                    if (model) {
                        Queue.addManual(model);
                    }
                });
            }
        },
		{
			title: 'Share',
			args: $(this),
			callback: function(elem) {
                var video = $(elem).data('model');
                showVideoSharePopup(video, elem, 'up');
			}
		}
    ];

    switch (video.type) {
        case 'youtube':
        buttons.push({
            title: 'Watch on YouTube',
            args: $(this),
            callback: function(elem) {
                window.open('http://www.youtube.com/watch?v=' + video.videoId);
            }
        });
        break;

        case 'soundcloud':
        buttons.push({
            title: 'Watch on SoundCloud',
            args: $(this),
            callback: function(elem) {
                var url = "http://api.soundcloud.com/tracks/" + video.videoId + ".json";
                var params = {
                    client_id: SOUNDCLOUD_API_KEY
                };
                $.getJSON(url, params, function(data) {
                    window.open(data.permalink_url);
                });
            }
        });
        break;

        case 'officialfm':
        buttons.push({
            title: 'Watch on Official.fm',
            args: $(this),
            callback: function(elem) {
                window.open('http://www.official.fm/tracks/' + video.videoId);
            }
        });
        break;
    }

    if (ON_DEV) {
        buttons.push({
            title: 'View JSON',
            args: $(this),
            callback: function(li) {
                alert(JSON.stringify(video.toJSON()));
                console.log(video.toJSON());
            }
        });
    }

    if ($(this).data('additionalMenuButtons')) {
        buttons = $.merge(buttons, $(this).data('additionalMenuButtons'));
    }

    showContextMenu(buttons, (event.pageX || $(this).offset().left + $(this).width()) , (event.pageY || $(this).offset().top));

    return false;
}
<|endoftext|>