summaryrefslogtreecommitdiffstats
path: root/extensions/permissions/test/unit/test_permmanager_notifications.js
blob: a84f79b6ec8413f153cb05dc7250193307c20b57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

// Test that the permissionmanager 'added', 'changed', 'deleted', and 'cleared'
// notifications behave as expected.

var test_generator = do_run_test();

function run_test() {
  Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
  do_test_pending();
  test_generator.next();
}

function* do_run_test() {
  let pm = Services.perms;
  let now = Number(Date.now());
  let permType = "test/expiration-perm";
  let ssm = Services.scriptSecurityManager;
  let uri = NetUtil.newURI("http://example.com");
  let principal = ssm.createContentPrincipal(uri, {});

  let observer = new permission_observer(test_generator, now, permType);
  Services.obs.addObserver(observer, "perm-changed");

  // Add a permission, to test the 'add' notification. Note that we use
  // do_execute_soon() so that we can use our generator to continue the test
  // where we left off.
  executeSoon(function() {
    pm.addFromPrincipal(
      principal,
      permType,
      pm.ALLOW_ACTION,
      pm.EXPIRE_TIME,
      now + 100000
    );
  });
  yield;

  // Alter a permission, to test the 'changed' notification.
  executeSoon(function() {
    pm.addFromPrincipal(
      principal,
      permType,
      pm.ALLOW_ACTION,
      pm.EXPIRE_TIME,
      now + 200000
    );
  });
  yield;

  // Remove a permission, to test the 'deleted' notification.
  executeSoon(function() {
    pm.removeFromPrincipal(principal, permType);
  });
  yield;

  // Clear permissions, to test the 'cleared' notification.
  executeSoon(function() {
    pm.removeAll();
  });
  yield;

  Services.obs.removeObserver(observer, "perm-changed");
  Assert.equal(observer.adds, 1);
  Assert.equal(observer.changes, 1);
  Assert.equal(observer.deletes, 1);
  Assert.ok(observer.cleared);

  do_finish_generator_test(test_generator);
}

function permission_observer(generator, now, type) {
  // Set up our observer object.
  this.generator = generator;
  this.pm = Services.perms;
  this.now = now;
  this.type = type;
  this.adds = 0;
  this.changes = 0;
  this.deletes = 0;
  this.cleared = false;
}

permission_observer.prototype = {
  observe(subject, topic, data) {
    Assert.equal(topic, "perm-changed");

    // "deleted" means a permission was deleted. aPermission is the deleted permission.
    // "added"   means a permission was added. aPermission is the added permission.
    // "changed" means a permission was altered. aPermission is the new permission.
    // "cleared" means the entire permission list was cleared. aPermission is null.
    if (data == "added") {
      let perm = subject.QueryInterface(Ci.nsIPermission);
      this.adds++;
      switch (this.adds) {
        case 1:
          Assert.equal(this.type, perm.type);
          Assert.equal(this.pm.EXPIRE_TIME, perm.expireType);
          Assert.equal(this.now + 100000, perm.expireTime);
          break;
        default:
          do_throw("too many add notifications posted.");
      }
    } else if (data == "changed") {
      let perm = subject.QueryInterface(Ci.nsIPermission);
      this.changes++;
      switch (this.changes) {
        case 1:
          Assert.equal(this.type, perm.type);
          Assert.equal(this.pm.EXPIRE_TIME, perm.expireType);
          Assert.equal(this.now + 200000, perm.expireTime);
          break;
        default:
          do_throw("too many change notifications posted.");
      }
    } else if (data == "deleted") {
      let perm = subject.QueryInterface(Ci.nsIPermission);
      this.deletes++;
      switch (this.deletes) {
        case 1:
          Assert.equal(this.type, perm.type);
          break;
        default:
          do_throw("too many delete notifications posted.");
      }
    } else if (data == "cleared") {
      // only clear once: at the end
      Assert.ok(!this.cleared);
      Assert.equal(do_count_array(Services.perms.all), 0);
      this.cleared = true;
    } else {
      do_throw("unexpected data '" + data + "'!");
    }

    // Continue the test.
    do_run_generator(this.generator);
  },
};