diff options
Diffstat (limited to 'syweb/webclient/test')
-rw-r--r-- | syweb/webclient/test/README | 51 | ||||
-rw-r--r-- | syweb/webclient/test/e2e/home.spec.js | 16 | ||||
-rw-r--r-- | syweb/webclient/test/karma.conf.js | 91 | ||||
-rw-r--r-- | syweb/webclient/test/protractor.conf.js | 18 | ||||
-rw-r--r-- | syweb/webclient/test/unit/event-handler-service.spec.js | 117 | ||||
-rw-r--r-- | syweb/webclient/test/unit/filters.spec.js | 488 | ||||
-rw-r--r-- | syweb/webclient/test/unit/matrix-service.spec.js | 504 | ||||
-rw-r--r-- | syweb/webclient/test/unit/model-service.spec.js | 30 | ||||
-rw-r--r-- | syweb/webclient/test/unit/register-controller.spec.js | 84 | ||||
-rw-r--r-- | syweb/webclient/test/unit/user-controller.spec.js | 57 |
10 files changed, 1456 insertions, 0 deletions
diff --git a/syweb/webclient/test/README b/syweb/webclient/test/README new file mode 100644 index 0000000000..e7ed4eaa87 --- /dev/null +++ b/syweb/webclient/test/README @@ -0,0 +1,51 @@ +Testing is done using Karma. + + +UNIT TESTING +============ + +Requires the following: + - npm/nodejs + - phantomjs + +Requires the following node packages: + - npm install jasmine + - npm install karma + - npm install karma-jasmine + - npm install karma-phantomjs-launcher + - npm install karma-junit-reporter + +Make sure you're in this directory so it can find the config file and run: + karma start + +You should see all the tests pass. + + +E2E TESTING +=========== + +npm install protractor + + +Setting up e2e tests (only if you don't have a selenium server to run the tests +on. If you do, edit the config to point to that url): + + webdriver-manager update + webdriver-manager start + + Create a file "environment-protractor.js" in this directory and type: + module.exports = { + seleniumAddress: 'http://localhost:4444/wd/hub', + baseUrl: "http://localhost:8008", + username: "YOUR_TEST_USERNAME", + password: "YOUR_TEST_PASSWORD" + } + +Running e2e tests: + protractor protractor.conf.js + +NOTE: This will create a public room on the target home server. + + + + diff --git a/syweb/webclient/test/e2e/home.spec.js b/syweb/webclient/test/e2e/home.spec.js new file mode 100644 index 0000000000..470237d557 --- /dev/null +++ b/syweb/webclient/test/e2e/home.spec.js @@ -0,0 +1,16 @@ +var env = require("../environment-protractor.js"); + +describe("home page", function() { + + beforeEach(function() { + ptor = protractor.getInstance(); + // FIXME we use longpoll on the event stream, and I can't get $interval + // playing nicely with it. Patches welcome to fix this. + ptor.ignoreSynchronization = true; + }); + + it("should have a title", function() { + browser.get(env.baseUrl); + expect(browser.getTitle()).toEqual("[matrix]"); + }); +}); diff --git a/syweb/webclient/test/karma.conf.js b/syweb/webclient/test/karma.conf.js new file mode 100644 index 0000000000..7ce958adc9 --- /dev/null +++ b/syweb/webclient/test/karma.conf.js @@ -0,0 +1,91 @@ +// Karma configuration +// Generated on Thu Sep 18 2014 14:25:57 GMT+0100 (BST) + +module.exports = function(config) { + config.set({ + + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: '', + + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['jasmine'], + + + // list of files / patterns to load in the browser + // XXX: Order is important, and doing /js/angular* makes the tests not run :/ + files: [ + '../js/jquery*', + '../js/angular.js', + '../js/angular-mocks.js', + '../js/angular-route.js', + '../js/angular-animate.js', + '../js/angular-sanitize.js', + '../js/ng-infinite-scroll-matrix.js', + '../js/ui-bootstrap*', + '../js/elastic.js', + '../login/**/*.js', + '../room/**/*.js', + '../components/**/*.js', + '../user/**/*.js', + '../home/**/*.js', + '../recents/**/*.js', + '../settings/**/*.js', + '../app.js', + '../app*', + './unit/**/*.js' + ], + + plugins: [ + 'karma-*', + ], + + + // list of files to exclude + exclude: [ + ], + + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + }, + + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ['progress', 'junit'], + junitReporter: { + outputFile: 'test-results.xml', + suite: '' + }, + + // web server port + port: 9876, + + + // enable / disable colors in the output (reporters and logs) + colors: true, + + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_DEBUG, + + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: true, + + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: ['PhantomJS'], + + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: true + }); +}; diff --git a/syweb/webclient/test/protractor.conf.js b/syweb/webclient/test/protractor.conf.js new file mode 100644 index 0000000000..76ae7b712b --- /dev/null +++ b/syweb/webclient/test/protractor.conf.js @@ -0,0 +1,18 @@ +var env = require("./environment-protractor.js"); +exports.config = { + seleniumAddress: env.seleniumAddress, + specs: ['e2e/*.spec.js'], + onPrepare: function() { + browser.driver.get(env.baseUrl); + browser.driver.findElement(by.id("user_id")).sendKeys(env.username); + browser.driver.findElement(by.id("password")).sendKeys(env.password); + browser.driver.findElement(by.id("login")).click(); + + // wait till the login is done, detect via url change + browser.driver.wait(function() { + return browser.driver.getCurrentUrl().then(function(url) { + return !(/login/.test(url)) + }); + }); + } +} diff --git a/syweb/webclient/test/unit/event-handler-service.spec.js b/syweb/webclient/test/unit/event-handler-service.spec.js new file mode 100644 index 0000000000..2a4dc3b5a5 --- /dev/null +++ b/syweb/webclient/test/unit/event-handler-service.spec.js @@ -0,0 +1,117 @@ +describe('EventHandlerService', function() { + var scope; + + var modelService = {}; + + // setup the service and mocked dependencies + beforeEach(function() { + // dependencies + module('matrixService'); + module('notificationService'); + module('mPresence'); + + // cleanup mocked methods + modelService = {}; + + // mocked dependencies + module(function ($provide) { + $provide.value('modelService', modelService); + }); + + // tested service + module('eventHandlerService'); + }); + + beforeEach(inject(function($rootScope) { + scope = $rootScope; + })); + + it('should be able to get the number of joined users in a room', inject( + function(eventHandlerService) { + var roomId = "!foo:matrix.org"; + // set mocked data + modelService.getRoom = function(roomId) { + return { + room_id: roomId, + current_room_state: { + members: { + "@adam:matrix.org": { + event: { + content: { membership: "join" }, + user_id: "@adam:matrix.org" + } + }, + "@beth:matrix.org": { + event: { + content: { membership: "invite" }, + user_id: "@beth:matrix.org" + } + }, + "@charlie:matrix.org": { + event: { + content: { membership: "join" }, + user_id: "@charlie:matrix.org" + } + }, + "@danice:matrix.org": { + event: { + content: { membership: "leave" }, + user_id: "@danice:matrix.org" + } + } + } + } + }; + } + + var num = eventHandlerService.getUsersCountInRoom(roomId); + expect(num).toEqual(2); + })); + + it('should be able to get a users power level', inject( + function(eventHandlerService) { + var roomId = "!foo:matrix.org"; + // set mocked data + modelService.getRoom = function(roomId) { + return { + room_id: roomId, + current_room_state: { + members: { + "@adam:matrix.org": { + event: { + content: { membership: "join" }, + user_id: "@adam:matrix.org" + } + }, + "@beth:matrix.org": { + event: { + content: { membership: "join" }, + user_id: "@beth:matrix.org" + } + } + }, + s: { + "m.room.power_levels": { + content: { + "@adam:matrix.org": 90, + "default": 50 + } + } + }, + state: function(type, key) { + return key ? this.s[type+key] : this.s[type] + } + } + }; + }; + + var num = eventHandlerService.getUserPowerLevel(roomId, "@beth:matrix.org"); + expect(num).toEqual(50); + + num = eventHandlerService.getUserPowerLevel(roomId, "@adam:matrix.org"); + expect(num).toEqual(90); + + num = eventHandlerService.getUserPowerLevel(roomId, "@unknown:matrix.org"); + expect(num).toEqual(50); + })); +}); diff --git a/syweb/webclient/test/unit/filters.spec.js b/syweb/webclient/test/unit/filters.spec.js new file mode 100644 index 0000000000..7324a8e028 --- /dev/null +++ b/syweb/webclient/test/unit/filters.spec.js @@ -0,0 +1,488 @@ +describe('mRoomName filter', function() { + var filter, mRoomName; + + var roomId = "!weufhewifu:matrix.org"; + + // test state values (f.e. test) + var testUserId, testAlias, testDisplayName, testOtherDisplayName, testRoomState; + + // mocked services which return the test values above. + var matrixService = { + getRoomIdToAliasMapping: function(room_id) { + return testAlias; + }, + + config: function() { + return { + user_id: testUserId + }; + } + }; + + var eventHandlerService = { + getUserDisplayName: function(room_id, user_id) { + if (user_id === testUserId) { + return testDisplayName; + } + return testOtherDisplayName; + } + }; + + var modelService = { + getRoom: function(room_id) { + return { + current_room_state: testRoomState + }; + } + }; + + beforeEach(function() { + // inject mocked dependencies + module(function ($provide) { + $provide.value('matrixService', matrixService); + $provide.value('eventHandlerService', eventHandlerService); + $provide.value('modelService', modelService); + }); + + module('matrixFilter'); + }); + + beforeEach(inject(function($filter) { + filter = $filter; + mRoomName = filter("mRoomName"); + + // purge the previous test values + testUserId = undefined; + testAlias = undefined; + testDisplayName = undefined; + testOtherDisplayName = undefined; + + // mock up a stub room state + testRoomState = { + s:{}, // internal; stores the state events + state: function(type, key) { + // accessor used by filter + return key ? this.s[type+key] : this.s[type]; + }, + members: {}, // struct used by filter + + // test helper methods + setJoinRule: function(rule) { + this.s["m.room.join_rules"] = { + content: { + join_rule: rule + } + }; + }, + setRoomName: function(name) { + this.s["m.room.name"] = { + content: { + name: name + } + }; + }, + setMember: function(user_id, membership, inviter_user_id) { + if (!inviter_user_id) { + inviter_user_id = user_id; + } + this.s["m.room.member" + user_id] = { + event: { + content: { + membership: membership + }, + state_key: user_id, + user_id: inviter_user_id + } + }; + this.members[user_id] = this.s["m.room.member" + user_id]; + } + }; + })); + + /**** ROOM NAME ****/ + + it("should show the room name if one exists for private (invite join_rules) rooms.", function() { + var roomName = "The Room Name"; + testUserId = "@me:matrix.org"; + testRoomState.setJoinRule("invite"); + testRoomState.setRoomName(roomName); + testRoomState.setMember(testUserId, "join"); + var output = mRoomName(roomId); + expect(output).toEqual(roomName); + }); + + it("should show the room name if one exists for public (public join_rules) rooms.", function() { + var roomName = "The Room Name"; + testUserId = "@me:matrix.org"; + testRoomState.setJoinRule("public"); + testRoomState.setRoomName(roomName); + testRoomState.setMember(testUserId, "join"); + var output = mRoomName(roomId); + expect(output).toEqual(roomName); + }); + + /**** ROOM ALIAS ****/ + + it("should show the room alias if one exists for private (invite join_rules) rooms if a room name doesn't exist.", function() { + testAlias = "#thealias:matrix.org"; + testUserId = "@me:matrix.org"; + testRoomState.setJoinRule("invite"); + testRoomState.setMember(testUserId, "join"); + var output = mRoomName(roomId); + expect(output).toEqual(testAlias); + }); + + it("should show the room alias if one exists for public (public join_rules) rooms if a room name doesn't exist.", function() { + testAlias = "#thealias:matrix.org"; + testUserId = "@me:matrix.org"; + testRoomState.setJoinRule("public"); + testRoomState.setMember(testUserId, "join"); + var output = mRoomName(roomId); + expect(output).toEqual(testAlias); + }); + + /**** ROOM ID ****/ + + it("should show the room ID for public (public join_rules) rooms if a room name and alias don't exist.", function() { + testUserId = "@me:matrix.org"; + testRoomState.setJoinRule("public"); + testRoomState.setMember(testUserId, "join"); + var output = mRoomName(roomId); + expect(output).toEqual(roomId); + }); + + it("should show the room ID for private (invite join_rules) rooms if a room name and alias don't exist and there are >2 members.", function() { + testUserId = "@me:matrix.org"; + testRoomState.setJoinRule("public"); + testRoomState.setMember(testUserId, "join"); + testRoomState.setMember("@alice:matrix.org", "join"); + testRoomState.setMember("@bob:matrix.org", "join"); + var output = mRoomName(roomId); + expect(output).toEqual(roomId); + }); + + /**** SELF-CHAT ****/ + + it("should show your display name for private (invite join_rules) rooms if a room name and alias don't exist and it is a self-chat.", function() { + testUserId = "@me:matrix.org"; + testDisplayName = "Me"; + testRoomState.setJoinRule("private"); + testRoomState.setMember(testUserId, "join"); + var output = mRoomName(roomId); + expect(output).toEqual(testDisplayName); + }); + + it("should show your user ID for private (invite join_rules) rooms if a room name and alias don't exist and it is a self-chat and they don't have a display name set.", function() { + testUserId = "@me:matrix.org"; + testRoomState.setJoinRule("private"); + testRoomState.setMember(testUserId, "join"); + var output = mRoomName(roomId); + expect(output).toEqual(testUserId); + }); + + /**** ONE-TO-ONE CHAT ****/ + + it("should show the other user's display name for private (invite join_rules) rooms if a room name and alias don't exist and it is a 1:1-chat.", function() { + testUserId = "@me:matrix.org"; + otherUserId = "@alice:matrix.org"; + testOtherDisplayName = "Alice"; + testRoomState.setJoinRule("private"); + testRoomState.setMember(testUserId, "join"); + testRoomState.setMember("@alice:matrix.org", "join"); + var output = mRoomName(roomId); + expect(output).toEqual(testOtherDisplayName); + }); + + it("should show the other user's ID for private (invite join_rules) rooms if a room name and alias don't exist and it is a 1:1-chat and they don't have a display name set.", function() { + testUserId = "@me:matrix.org"; + otherUserId = "@alice:matrix.org"; + testRoomState.setJoinRule("private"); + testRoomState.setMember(testUserId, "join"); + testRoomState.setMember("@alice:matrix.org", "join"); + var output = mRoomName(roomId); + expect(output).toEqual(otherUserId); + }); + + /**** INVITED TO ROOM ****/ + + it("should show the other user's display name for private (invite join_rules) rooms if you are invited to it.", function() { + testUserId = "@me:matrix.org"; + testDisplayName = "Me"; + otherUserId = "@alice:matrix.org"; + testOtherDisplayName = "Alice"; + testRoomState.setJoinRule("private"); + testRoomState.setMember(testUserId, "join"); + testRoomState.setMember(otherUserId, "join"); + testRoomState.setMember(testUserId, "invite"); + var output = mRoomName(roomId); + expect(output).toEqual(testOtherDisplayName); + }); + + it("should show the other user's ID for private (invite join_rules) rooms if you are invited to it and the inviter doesn't have a display name.", function() { + testUserId = "@me:matrix.org"; + testDisplayName = "Me"; + otherUserId = "@alice:matrix.org"; + testRoomState.setJoinRule("private"); + testRoomState.setMember(testUserId, "join"); + testRoomState.setMember(otherUserId, "join"); + testRoomState.setMember(testUserId, "invite"); + var output = mRoomName(roomId); + expect(output).toEqual(otherUserId); + }); +}); + +describe('duration filter', function() { + var filter, durationFilter; + + beforeEach(module('matrixWebClient')); + beforeEach(inject(function($filter) { + filter = $filter; + durationFilter = filter("duration"); + })); + + it("should represent 15000 ms as '15s'", function() { + var output = durationFilter(15000); + expect(output).toEqual("15s"); + }); + + it("should represent 60000 ms as '1m'", function() { + var output = durationFilter(60000); + expect(output).toEqual("1m"); + }); + + it("should represent 65000 ms as '1m'", function() { + var output = durationFilter(65000); + expect(output).toEqual("1m"); + }); + + it("should represent 10 ms as '0s'", function() { + var output = durationFilter(10); + expect(output).toEqual("0s"); + }); + + it("should represent 4m as '4m'", function() { + var output = durationFilter(1000*60*4); + expect(output).toEqual("4m"); + }); + + it("should represent 4m30s as '4m'", function() { + var output = durationFilter(1000*60*4 + 1000*30); + expect(output).toEqual("4m"); + }); + + it("should represent 2h as '2h'", function() { + var output = durationFilter(1000*60*60*2); + expect(output).toEqual("2h"); + }); + + it("should represent 2h35m as '2h'", function() { + var output = durationFilter(1000*60*60*2 + 1000*60*35); + expect(output).toEqual("2h"); + }); +}); + +describe('orderMembersList filter', function() { + var filter, orderMembersList; + + beforeEach(module('matrixWebClient')); + beforeEach(inject(function($filter) { + filter = $filter; + orderMembersList = filter("orderMembersList"); + })); + + it("should sort a single entry", function() { + var output = orderMembersList({ + "@a:example.com": { + last_active_ago: 50, + last_updated: 1415266943964 + } + }); + expect(output).toEqual([{ + id: "@a:example.com", + last_active_ago: 50, + last_updated: 1415266943964 + }]); + }); + + it("should sort by taking last_active_ago into account", function() { + var output = orderMembersList({ + "@a:example.com": { + last_active_ago: 1000, + last_updated: 1415266943964 + }, + "@b:example.com": { + last_active_ago: 50, + last_updated: 1415266943964 + }, + "@c:example.com": { + last_active_ago: 99999, + last_updated: 1415266943964 + } + }); + expect(output).toEqual([ + { + id: "@b:example.com", + last_active_ago: 50, + last_updated: 1415266943964 + }, + { + id: "@a:example.com", + last_active_ago: 1000, + last_updated: 1415266943964 + }, + { + id: "@c:example.com", + last_active_ago: 99999, + last_updated: 1415266943964 + }, + ]); + }); + + it("should sort by taking last_updated into account", function() { + var output = orderMembersList({ + "@a:example.com": { + last_active_ago: 1000, + last_updated: 1415266943964 + }, + "@b:example.com": { + last_active_ago: 1000, + last_updated: 1415266900000 + }, + "@c:example.com": { + last_active_ago: 1000, + last_updated: 1415266943000 + } + }); + expect(output).toEqual([ + { + id: "@a:example.com", + last_active_ago: 1000, + last_updated: 1415266943964 + }, + { + id: "@c:example.com", + last_active_ago: 1000, + last_updated: 1415266943000 + }, + { + id: "@b:example.com", + last_active_ago: 1000, + last_updated: 1415266900000 + }, + ]); + }); + + it("should sort by taking last_updated and last_active_ago into account", + function() { + var output = orderMembersList({ + "@a:example.com": { + last_active_ago: 1000, + last_updated: 1415266943000 + }, + "@b:example.com": { + last_active_ago: 100000, + last_updated: 1415266943900 + }, + "@c:example.com": { + last_active_ago: 1000, + last_updated: 1415266943964 + } + }); + expect(output).toEqual([ + { + id: "@c:example.com", + last_active_ago: 1000, + last_updated: 1415266943964 + }, + { + id: "@a:example.com", + last_active_ago: 1000, + last_updated: 1415266943000 + }, + { + id: "@b:example.com", + last_active_ago: 100000, + last_updated: 1415266943900 + }, + ]); + }); + + // SYWEB-26 comment + it("should sort members who do not have last_active_ago value at the end of the list", + function() { + // single undefined entry + var output = orderMembersList({ + "@a:example.com": { + last_active_ago: 1000, + last_updated: 1415266943964 + }, + "@b:example.com": { + last_active_ago: 100000, + last_updated: 1415266943964 + }, + "@c:example.com": { + last_active_ago: undefined, + last_updated: 1415266943964 + } + }); + expect(output).toEqual([ + { + id: "@a:example.com", + last_active_ago: 1000, + last_updated: 1415266943964 + }, + { + id: "@b:example.com", + last_active_ago: 100000, + last_updated: 1415266943964 + }, + { + id: "@c:example.com", + last_active_ago: undefined, + last_updated: 1415266943964 + }, + ]); + }); + + it("should sort multiple members who do not have last_active_ago according to presence", + function() { + // single undefined entry + var output = orderMembersList({ + "@a:example.com": { + last_active_ago: undefined, + last_updated: 1415266943964, + presence: "unavailable" + }, + "@b:example.com": { + last_active_ago: undefined, + last_updated: 1415266943964, + presence: "online" + }, + "@c:example.com": { + last_active_ago: undefined, + last_updated: 1415266943964, + presence: "offline" + } + }); + expect(output).toEqual([ + { + id: "@b:example.com", + last_active_ago: undefined, + last_updated: 1415266943964, + presence: "online" + }, + { + id: "@a:example.com", + last_active_ago: undefined, + last_updated: 1415266943964, + presence: "unavailable" + }, + { + id: "@c:example.com", + last_active_ago: undefined, + last_updated: 1415266943964, + presence: "offline" + }, + ]); + }); +}); diff --git a/syweb/webclient/test/unit/matrix-service.spec.js b/syweb/webclient/test/unit/matrix-service.spec.js new file mode 100644 index 0000000000..4959f2395d --- /dev/null +++ b/syweb/webclient/test/unit/matrix-service.spec.js @@ -0,0 +1,504 @@ +describe('MatrixService', function() { + var scope, httpBackend; + var BASE = "http://example.com"; + var PREFIX = "/_matrix/client/api/v1"; + var URL = BASE + PREFIX; + var roomId = "!wejigf387t34:matrix.org"; + + var CONFIG = { + access_token: "foobar", + homeserver: BASE + }; + + beforeEach(module('matrixService')); + + beforeEach(inject(function($rootScope, $httpBackend) { + httpBackend = $httpBackend; + scope = $rootScope; + })); + + afterEach(function() { + httpBackend.verifyNoOutstandingExpectation(); + httpBackend.verifyNoOutstandingRequest(); + }); + + it('should be able to POST /createRoom with an alias', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var alias = "flibble"; + matrixService.create(alias).then(function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectPOST(URL + "/createRoom?access_token=foobar", + { + room_alias_name: alias + }) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to GET /initialSync', inject(function(matrixService) { + matrixService.setConfig(CONFIG); + var limit = 15; + matrixService.initialSync(limit).then(function(response) { + expect(response.data).toEqual([]); + }); + + httpBackend.expectGET( + URL + "/initialSync?access_token=foobar&limit=15") + .respond([]); + httpBackend.flush(); + })); + + it('should be able to GET /rooms/$roomid/state', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + matrixService.roomState(roomId).then(function(response) { + expect(response.data).toEqual([]); + }); + + httpBackend.expectGET( + URL + "/rooms/" + encodeURIComponent(roomId) + + "/state?access_token=foobar") + .respond([]); + httpBackend.flush(); + })); + + it('should be able to POST /join', inject(function(matrixService) { + matrixService.setConfig(CONFIG); + matrixService.joinAlias(roomId).then(function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectPOST( + URL + "/join/" + encodeURIComponent(roomId) + + "?access_token=foobar", + {}) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to POST /rooms/$roomid/join', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + matrixService.join(roomId).then(function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectPOST( + URL + "/rooms/" + encodeURIComponent(roomId) + + "/join?access_token=foobar", + {}) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to POST /rooms/$roomid/invite', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var inviteUserId = "@user:example.com"; + matrixService.invite(roomId, inviteUserId).then(function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectPOST( + URL + "/rooms/" + encodeURIComponent(roomId) + + "/invite?access_token=foobar", + { + user_id: inviteUserId + }) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to POST /rooms/$roomid/leave', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + matrixService.leave(roomId).then(function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectPOST( + URL + "/rooms/" + encodeURIComponent(roomId) + + "/leave?access_token=foobar", + {}) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to POST /rooms/$roomid/ban', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var userId = "@example:example.com"; + var reason = "Because."; + matrixService.ban(roomId, userId, reason).then(function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectPOST( + URL + "/rooms/" + encodeURIComponent(roomId) + + "/ban?access_token=foobar", + { + user_id: userId, + reason: reason + }) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to GET /directory/room/$alias', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var alias = "#test:example.com"; + var roomId = "!wefuhewfuiw:example.com"; + matrixService.resolveRoomAlias(alias).then(function(response) { + expect(response.data).toEqual({ + room_id: roomId + }); + }); + + httpBackend.expectGET( + URL + "/directory/room/" + encodeURIComponent(alias) + + "?access_token=foobar") + .respond({ + room_id: roomId + }); + httpBackend.flush(); + })); + + it('should be able to send m.room.name', inject(function(matrixService) { + matrixService.setConfig(CONFIG); + var roomId = "!fh38hfwfwef:example.com"; + var name = "Room Name"; + matrixService.setName(roomId, name).then(function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectPUT( + URL + "/rooms/" + encodeURIComponent(roomId) + + "/state/m.room.name?access_token=foobar", + { + name: name + }) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to send m.room.topic', inject(function(matrixService) { + matrixService.setConfig(CONFIG); + var roomId = "!fh38hfwfwef:example.com"; + var topic = "A room topic can go here."; + matrixService.setTopic(roomId, topic).then(function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectPUT( + URL + "/rooms/" + encodeURIComponent(roomId) + + "/state/m.room.topic?access_token=foobar", + { + topic: topic + }) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to send generic state events without a state key', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var roomId = "!fh38hfwfwef:example.com"; + var eventType = "com.example.events.test"; + var content = { + testing: "1 2 3" + }; + matrixService.sendStateEvent(roomId, eventType, content).then( + function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectPUT( + URL + "/rooms/" + encodeURIComponent(roomId) + "/state/" + + encodeURIComponent(eventType) + "?access_token=foobar", + content) + .respond({}); + httpBackend.flush(); + })); + + // TODO: Skipped since the webclient is purposefully broken so as not to + // 500 matrix.org + xit('should be able to send generic state events with a state key', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var roomId = "!fh38hfwfwef:example.com"; + var eventType = "com.example.events.test:special@characters"; + var content = { + testing: "1 2 3" + }; + var stateKey = "version:1"; + matrixService.sendStateEvent(roomId, eventType, content, stateKey).then( + function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectPUT( + URL + "/rooms/" + encodeURIComponent(roomId) + "/state/" + + encodeURIComponent(eventType) + "/" + encodeURIComponent(stateKey)+ + "?access_token=foobar", + content) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to PUT generic events ', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var roomId = "!fh38hfwfwef:example.com"; + var eventType = "com.example.events.test"; + var txnId = "42"; + var content = { + testing: "1 2 3" + }; + matrixService.sendEvent(roomId, eventType, txnId, content).then( + function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectPUT( + URL + "/rooms/" + encodeURIComponent(roomId) + "/send/" + + encodeURIComponent(eventType) + "/" + encodeURIComponent(txnId)+ + "?access_token=foobar", + content) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to PUT text messages ', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var roomId = "!fh38hfwfwef:example.com"; + var body = "ABC 123"; + matrixService.sendTextMessage(roomId, body).then( + function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectPUT( + new RegExp(URL + "/rooms/" + encodeURIComponent(roomId) + + "/send/m.room.message/(.*)" + + "?access_token=foobar"), + { + body: body, + msgtype: "m.text" + }) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to PUT emote messages ', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var roomId = "!fh38hfwfwef:example.com"; + var body = "ABC 123"; + matrixService.sendEmoteMessage(roomId, body).then( + function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectPUT( + new RegExp(URL + "/rooms/" + encodeURIComponent(roomId) + + "/send/m.room.message/(.*)" + + "?access_token=foobar"), + { + body: body, + msgtype: "m.emote" + }) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to POST redactions', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var roomId = "!fh38hfwfwef:example.com"; + var eventId = "fwefwexample.com"; + matrixService.redactEvent(roomId, eventId).then( + function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectPOST(URL + "/rooms/" + encodeURIComponent(roomId) + + "/redact/" + encodeURIComponent(eventId) + + "?access_token=foobar") + .respond({}); + httpBackend.flush(); + })); + + it('should be able to GET /directory/room/$alias', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var alias = "#test:example.com"; + var roomId = "!wefuhewfuiw:example.com"; + matrixService.resolveRoomAlias(alias).then(function(response) { + expect(response.data).toEqual({ + room_id: roomId + }); + }); + + httpBackend.expectGET( + URL + "/directory/room/" + encodeURIComponent(alias) + + "?access_token=foobar") + .respond({ + room_id: roomId + }); + httpBackend.flush(); + })); + + it('should be able to GET /rooms/$roomid/members', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var roomId = "!wefuhewfuiw:example.com"; + matrixService.getMemberList(roomId).then(function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectGET( + URL + "/rooms/" + encodeURIComponent(roomId) + + "/members?access_token=foobar") + .respond({}); + httpBackend.flush(); + })); + + it('should be able to paginate a room', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var roomId = "!wefuhewfuiw:example.com"; + var from = "3t_44e_54z"; + var limit = 20; + matrixService.paginateBackMessages(roomId, from, limit).then(function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectGET( + URL + "/rooms/" + encodeURIComponent(roomId) + + "/messages?access_token=foobar&dir=b&from="+ + encodeURIComponent(from)+"&limit="+limit) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to GET /publicRooms', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + matrixService.publicRooms().then(function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectGET( + new RegExp(URL + "/publicRooms(.*)")) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to GET /profile/$userid/displayname', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var userId = "@foo:example.com"; + matrixService.getDisplayName(userId).then(function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectGET(URL + "/profile/" + encodeURIComponent(userId) + + "/displayname?access_token=foobar") + .respond({}); + httpBackend.flush(); + })); + + it('should be able to GET /profile/$userid/avatar_url', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var userId = "@foo:example.com"; + matrixService.getProfilePictureUrl(userId).then(function(response) { + expect(response.data).toEqual({}); + }); + + httpBackend.expectGET(URL + "/profile/" + encodeURIComponent(userId) + + "/avatar_url?access_token=foobar") + .respond({}); + httpBackend.flush(); + })); + + it('should be able to PUT /profile/$me/avatar_url', inject( + function(matrixService) { + var testConfig = angular.copy(CONFIG); + testConfig.user_id = "@bob:example.com"; + matrixService.setConfig(testConfig); + var url = "http://example.com/mypic.jpg"; + matrixService.setProfilePictureUrl(url).then(function(response) { + expect(response.data).toEqual({}); + }); + httpBackend.expectPUT(URL + "/profile/" + + encodeURIComponent(testConfig.user_id) + + "/avatar_url?access_token=foobar", + { + avatar_url: url + }) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to PUT /profile/$me/displayname', inject( + function(matrixService) { + var testConfig = angular.copy(CONFIG); + testConfig.user_id = "@bob:example.com"; + matrixService.setConfig(testConfig); + var displayname = "Bob Smith"; + matrixService.setDisplayName(displayname).then(function(response) { + expect(response.data).toEqual({}); + }); + httpBackend.expectPUT(URL + "/profile/" + + encodeURIComponent(testConfig.user_id) + + "/displayname?access_token=foobar", + { + displayname: displayname + }) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to login with password', inject( + function(matrixService) { + matrixService.setConfig(CONFIG); + var userId = "@bob:example.com"; + var password = "monkey"; + matrixService.login(userId, password).then(function(response) { + expect(response.data).toEqual({}); + }); + httpBackend.expectPOST(new RegExp(URL+"/login(.*)"), + { + user: userId, + password: password, + type: "m.login.password" + }) + .respond({}); + httpBackend.flush(); + })); + + it('should be able to PUT presence status', inject( + function(matrixService) { + var testConfig = angular.copy(CONFIG); + testConfig.user_id = "@bob:example.com"; + matrixService.setConfig(testConfig); + var status = "unavailable"; + matrixService.setUserPresence(status).then(function(response) { + expect(response.data).toEqual({}); + }); + httpBackend.expectPUT(URL+"/presence/"+ + encodeURIComponent(testConfig.user_id)+ + "/status?access_token=foobar", + { + presence: status + }) + .respond({}); + httpBackend.flush(); + })); +}); diff --git a/syweb/webclient/test/unit/model-service.spec.js b/syweb/webclient/test/unit/model-service.spec.js new file mode 100644 index 0000000000..e2fa8ceba3 --- /dev/null +++ b/syweb/webclient/test/unit/model-service.spec.js @@ -0,0 +1,30 @@ +describe('ModelService', function() { + + // setup the dependencies + beforeEach(function() { + // dependencies + module('matrixService'); + + // tested service + module('modelService'); + }); + + it('should be able to get a member in a room', inject( + function(modelService) { + var roomId = "!wefiohwefuiow:matrix.org"; + var userId = "@bob:matrix.org"; + + modelService.getRoom(roomId).current_room_state.storeStateEvent({ + type: "m.room.member", + id: "fwefw:matrix.org", + user_id: userId, + state_key: userId, + content: { + membership: "join" + } + }); + + var user = modelService.getMember(roomId, userId); + expect(user.event.state_key).toEqual(userId); + })); +}); diff --git a/syweb/webclient/test/unit/register-controller.spec.js b/syweb/webclient/test/unit/register-controller.spec.js new file mode 100644 index 0000000000..b5c7842358 --- /dev/null +++ b/syweb/webclient/test/unit/register-controller.spec.js @@ -0,0 +1,84 @@ +describe("RegisterController ", function() { + var rootScope, scope, ctrl, $q, $timeout; + var userId = "@foo:bar"; + var displayName = "Foo"; + var avatarUrl = "avatar.url"; + + window.webClientConfig = { + useCapatcha: false + }; + + // test vars + var testRegisterData, testFailRegisterData; + + + // mock services + var matrixService = { + config: function() { + return { + user_id: userId + } + }, + setConfig: function(){}, + register: function(mxid, password, threepidCreds, useCaptcha) { + var d = $q.defer(); + if (testFailRegisterData) { + d.reject({ + data: testFailRegisterData + }); + } + else { + d.resolve({ + data: testRegisterData + }); + } + return d.promise; + } + }; + + var eventStreamService = {}; + + beforeEach(function() { + module('matrixWebClient'); + + // reset test vars + testRegisterData = undefined; + testFailRegisterData = undefined; + }); + + beforeEach(inject(function($rootScope, $injector, $location, $controller, _$q_, _$timeout_) { + $q = _$q_; + $timeout = _$timeout_; + scope = $rootScope.$new(); + rootScope = $rootScope; + routeParams = { + user_matrix_id: userId + }; + ctrl = $controller('RegisterController', { + '$scope': scope, + '$rootScope': $rootScope, + '$location': $location, + 'matrixService': matrixService, + 'eventStreamService': eventStreamService + }); + }) + ); + + // SYWEB-109 + it('should display an error if the HS rejects the username on registration', function() { + var prevFeedback = angular.copy(scope.feedback); + + testFailRegisterData = { + errcode: "M_UNKNOWN", + error: "I am rejecting you." + }; + + scope.account.pwd1 = "password"; + scope.account.pwd2 = "password"; + scope.account.desired_user_id = "bob"; + scope.register(); // this depends on the result of a deferred + rootScope.$digest(); // which is delivered after the digest + + expect(scope.feedback).not.toEqual(prevFeedback); + }); +}); diff --git a/syweb/webclient/test/unit/user-controller.spec.js b/syweb/webclient/test/unit/user-controller.spec.js new file mode 100644 index 0000000000..798cc4de48 --- /dev/null +++ b/syweb/webclient/test/unit/user-controller.spec.js @@ -0,0 +1,57 @@ +describe("UserCtrl", function() { + var scope, ctrl, matrixService, routeParams, $q, $timeout; + var userId = "@foo:bar"; + var displayName = "Foo"; + var avatarUrl = "avatar.url"; + + beforeEach(module('matrixWebClient')); + + beforeEach(function() { + + inject(function($rootScope, $injector, $controller, _$q_, _$timeout_) { + $q = _$q_; + $timeout = _$timeout_; + + matrixService = { + config: function() { + return { + user_id: userId + }; + }, + + getDisplayName: function(uid) { + var d = $q.defer(); + d.resolve({ + data: { + displayname: displayName + } + }); + return d.promise; + }, + + getProfilePictureUrl: function(uid) { + var d = $q.defer(); + d.resolve({ + data: { + avatar_url: avatarUrl + } + }); + return d.promise; + } + }; + scope = $rootScope.$new(); + routeParams = { + user_matrix_id: userId + }; + ctrl = $controller('UserController', { + '$scope': scope, + '$routeParams': routeParams, + 'matrixService': matrixService + }); + }); + }); + + it('should display your user id', function() { + expect(scope.user_id).toEqual(userId); + }); +}); |