summaryrefslogtreecommitdiffstats
path: root/toolkit/components/passwordmgr/test/unit/test_remote_recipes.js
blob: 7d16e205e9ff3bf22b521c1f9aae859bb04e37b0 (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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

/**
 * Tests retrieving remote LoginRecipes in the parent process.
 * See https://firefox-source-docs.mozilla.org/services/settings/#unit-tests for explanation of db.importChanges({}, Date.now());
 */

"use strict";

const { RemoteSettings } = ChromeUtils.importESModule(
  "resource://services-settings/remote-settings.sys.mjs"
);

const REMOTE_SETTINGS_COLLECTION = "password-recipes";

add_task(async function test_init_remote_recipe() {
  const db = RemoteSettings(REMOTE_SETTINGS_COLLECTION).db;
  await db.clear();
  const record1 = {
    id: "some-fake-ID",
    hosts: ["www.testDomain.com"],
    description: "Some description here",
    usernameSelector: "#username",
  };
  await db.importChanges({}, Date.now(), [record1], { clear: true });
  let parent = new LoginRecipesParent({ defaults: true });

  let recipesParent = await parent.initializationPromise;
  Assert.ok(
    recipesParent instanceof LoginRecipesParent,
    "Check initialization promise value which should be an instance of LoginRecipesParent"
  );
  Assert.strictEqual(
    recipesParent._recipesByHost.size,
    1,
    "Initially 1 recipe based on our test record"
  );
  let rsClient = recipesParent._rsClient;

  recipesParent.reset();
  await recipesParent.initializationPromise;
  Assert.ok(
    recipesParent instanceof LoginRecipesParent,
    "Ensure that the instance of LoginRecipesParent has not changed after resetting"
  );
  Assert.strictEqual(
    rsClient,
    recipesParent._rsClient,
    "Resetting recipes should not modify the rs client"
  );
  Assert.strictEqual(
    recipesParent._recipesByHost.size,
    1,
    "Initially 1 recipe based on our test record"
  );
  await db.clear();
  await db.importChanges({}, 42);
});

add_task(async function test_add_recipe_sync() {
  const db = RemoteSettings(REMOTE_SETTINGS_COLLECTION).db;
  const record1 = {
    id: "some-fake-ID",
    hosts: ["www.testDomain.com"],
    description: "Some description here",
    usernameSelector: "#username",
  };
  await db.importChanges({}, Date.now(), [record1], { clear: true });
  let parent = new LoginRecipesParent({ defaults: true });
  let recipesParent = await parent.initializationPromise;

  const record2 = {
    id: "some-fake-ID-2",
    hosts: ["www.testDomain2.com"],
    description: "Some description here. Wow it changed!",
    usernameSelector: "#username",
  };
  const payload = {
    current: [record1, record2],
    created: [record2],
    updated: [],
    deleted: [],
  };
  await RemoteSettings(REMOTE_SETTINGS_COLLECTION).emit("sync", {
    data: payload,
  });
  Assert.strictEqual(
    recipesParent._recipesByHost.size,
    2,
    "New recipe from sync event added successfully"
  );
  await db.clear();
  await db.importChanges({}, 42);
});

add_task(async function test_remove_recipe_sync() {
  const db = RemoteSettings(REMOTE_SETTINGS_COLLECTION).db;
  const record1 = {
    id: "some-fake-ID",
    hosts: ["www.testDomain.com"],
    description: "Some description here",
    usernameSelector: "#username",
  };
  await db.importChanges({}, Date.now(), [record1], { clear: true });
  let parent = new LoginRecipesParent({ defaults: true });
  let recipesParent = await parent.initializationPromise;

  const deletePayload = {
    current: [],
    created: [],
    updated: [],
    deleted: [record1],
  };
  await RemoteSettings(REMOTE_SETTINGS_COLLECTION).emit("sync", {
    data: deletePayload,
  });
  Assert.strictEqual(
    recipesParent._recipesByHost.size,
    0,
    "Recipes successfully deleted on sync event"
  );
  await db.clear();
});

add_task(async function test_malformed_recipes_in_db() {
  const db = RemoteSettings(REMOTE_SETTINGS_COLLECTION).db;
  const malformedRecord = {
    id: "some-ID",
    hosts: ["www.testDomain.com"],
    description: "Some description here",
    usernameSelector: "#username",
    fieldThatDoesNotExist: "value",
  };
  await db.importChanges({}, Date.now(), [malformedRecord], { clear: true });
  let parent = new LoginRecipesParent({ defaults: true });
  try {
    await parent.initializationPromise;
  } catch (e) {
    Assert.ok(
      e == "There were 1 recipe error(s)",
      "It should throw an error because of field that does not match the schema"
    );
  }

  await db.clear();
  const missingHostsRecord = {
    id: "some-ID",
    description: "Some description here",
    usernameSelector: "#username",
  };
  await db.importChanges({}, Date.now(), [missingHostsRecord], { clear: true });
  parent = new LoginRecipesParent({ defaults: true });
  try {
    await parent.initializationPromise;
  } catch (e) {
    Assert.ok(
      e == "There were 1 recipe error(s)",
      "It should throw an error because of missing hosts field"
    );
  }
});