"use strict";

const { BaseAction } = ChromeUtils.importESModule(
  "resource://normandy/actions/BaseAction.sys.mjs"
);
const { ActionsManager } = ChromeUtils.importESModule(
  "resource://normandy/lib/ActionsManager.sys.mjs"
);
const { Uptake } = ChromeUtils.importESModule(
  "resource://normandy/lib/Uptake.sys.mjs"
);
const { ActionSchemas } = ChromeUtils.importESModule(
  "resource://normandy/actions/schemas/index.sys.mjs"
);

// Test life cycle methods for actions
decorate_task(async function () {
  let manager = new ActionsManager();
  const recipe = { id: 1, action: "test-local-action-used" };

  let actionUsed = {
    processRecipe: sinon.stub(),
    finalize: sinon.stub(),
  };
  let actionUnused = {
    processRecipe: sinon.stub(),
    finalize: sinon.stub(),
  };
  manager.localActions = {
    "test-local-action-used": actionUsed,
    "test-local-action-unused": actionUnused,
  };

  await manager.processRecipe(recipe, BaseAction.suitability.FILTER_MATCH);
  await manager.finalize();

  Assert.deepEqual(
    actionUsed.processRecipe.args,
    [[recipe, BaseAction.suitability.FILTER_MATCH]],
    "used action should be called with the recipe"
  );
  ok(
    actionUsed.finalize.calledOnce,
    "finalize should be called on used action"
  );
  Assert.deepEqual(
    actionUnused.processRecipe.args,
    [],
    "unused action should not be called with the recipe"
  );
  ok(
    actionUnused.finalize.calledOnce,
    "finalize should be called on the unused action"
  );
});

decorate_task(async function () {
  for (const [name, Constructor] of Object.entries(
    ActionsManager.actionConstructors
  )) {
    const action = new Constructor();
    Assert.deepEqual(
      ActionSchemas[name],
      action.schema,
      "action name should map to a schema"
    );
  }
});
