// defmodule WebWars.Engine.Ability.ProduceTest { // @moduledoc false // use WebWars.DataCase // import WebWars.Factory // alias Ecto.UUID // alias Ecto.Changeset // alias WebWars.Engine.{ // Action, // Ability, // AbilityData, // Coord, // Game, // Power, // PowerData, // Tile, // TileData, // UnitData, // UserData, // } // describe "validate/2" { // test "validates cost, valid" { // id = UUID.generate() // unit = insert(:unit, %{ // cost: 100 // }) // action = Action { // kind: "ability", // ability_id: AbilityKind::Produce, // params: [unit.id], // subject_tile_data_id: id, // subject: TileData { // id: id, // coord: Coord {x: 0, y: 0}, // tile_id: Tile.Base.id(), // tile: Tile.Base.create() // }, // subject_user_data: UserData { // funds: 100 // }, // game: Game {} // } // changeset = Changeset.change(action) // Changeset {valid?: true} = Ability.Produce.create().validate.(changeset, action) // } // test "validates cost" { // id = UUID.generate() // unit = insert(:unit, %{ // cost: 100 // }) // action = Action { // kind: "ability", // ability_id: AbilityKind::Produce, // params: [unit.id], // subject_tile_data_id: id, // subject: TileData { // id: id, // coord: Coord {x: 0, y: 0}, // tile_id: Tile.Base.id(), // tile: Tile.Base.create() // }, // subject_user_data: UserData { // funds: 90 // }, // game: Game {} // } // changeset = Changeset.change(action) // Changeset { // errors: [ // params: {"can't afford", []} // ] // } = Ability.Produce.create().validate.(changeset, action) // } // test "validates cost with cost bonus" { // id = UUID.generate() // unit = insert(:unit, %{ // cost: 100 // }) // action = Action { // kind: "ability", // ability_id: AbilityKind::Produce, // params: [unit.id], // subject_tile_data_id: id, // subject: TileData { // id: id, // coord: Coord {x: 0, y: 0}, // tile_id: Tile.Base.id(), // tile: Tile.Base.create() // }, // subject_user_data: UserData { // funds: 90, // power_data: [ // PowerData { // power_id: Power.CostBonus.id(), // params: ["-10"] // } // ] // }, // game: Game {} // } // changeset = Changeset.change(action) // Changeset {valid?: true} = Ability.Produce.create().validate.(changeset, action) // } // test "validates specified unit exists" { // id = UUID.generate() // action = Action { // kind: "ability", // ability_id: AbilityKind::Produce, // params: ["00000000-0000-0000-0000-000000000000"], // subject_tile_data_id: id, // subject: TileData { // id: id, // coord: Coord {x: 0, y: 0}, // tile_id: Tile.Base.id(), // tile: Tile.Base.create() // }, // subject_user_data: UserData { // funds: 100 // }, // game: Game {} // } // changeset = Changeset.change(action) // assert_raise Ecto.NoResultsError, fn -> // Ability.Produce.create().validate.(changeset, action) // } // } // test "validates tile can produce" { // id = UUID.generate() // unit = insert(:unit, %{ // cost: 100 // }) // action = Action { // kind: "ability", // ability_id: AbilityKind::Produce, // params: [unit.id], // subject_tile_data_id: id, // subject: TileData { // id: id, // coord: Coord {x: 0, y: 0}, // tile_id: Tile.City.id(), // tile: Tile.City.create() // }, // subject_user_data: UserData { // funds: 100 // }, // game: Game {} // } // changeset = Changeset.change(action) // Changeset { // errors: [ // ability_id: {"is invalid", []} // ] // } = Ability.Produce.create().validate.(changeset, action) // } // test "validates unit can produce" { // id = UUID.generate() // unit = insert(:unit, %{ // cost: 100, // ability_data: [ // AbilityData {ability_id: Ability.Produce.id()}, // AbilityData {ability_id: Ability.Load.id(), params: ["1"]} // ] // }) // action = Action { // kind: "ability", // ability_id: AbilityKind::Produce, // params: [unit.id], // subject_tile_data_id: id, // subject: UnitData { // id: id, // unit: unit, // load_data: [] // }, // subject_user_data: UserData { // funds: 100 // }, // game: Game {} // } // changeset = Changeset.change(action) // Changeset {valid?: true} = Ability.Produce.create().validate.(changeset, action) // } // test "validates unit can produce, invalid" { // id = UUID.generate() // unit = insert(:unit, %{ // cost: 100 // }) // action = Action { // kind: "ability", // ability_id: AbilityKind::Produce, // params: [unit.id], // subject_tile_data_id: id, // subject: UnitData { // id: id, // unit: unit // }, // subject_user_data: UserData { // funds: 100 // }, // game: Game {} // } // changeset = Changeset.change(action) // Changeset { // errors: [ // ability_id: {"is invalid", []} // ] // } = Ability.Produce.create().validate.(changeset, action) // } // test "validates tile is unoccupied" { // id = UUID.generate() // unit = insert(:unit, %{ // cost: 100 // }) // action = Action { // kind: "ability", // ability_id: AbilityKind::Produce, // params: [unit.id], // subject_tile_data_id: id, // subject: TileData { // id: id, // coord: Coord {x: 0, y: 0}, // tile_id: Tile.Base.id(), // tile: Tile.Base.create() // }, // subject_user_data: UserData { // funds: 100 // }, // game: Game { // unit_data: [ // UnitData { // coord: Coord {x: 0, y: 0} // } // ] // } // } // changeset = Changeset.change(action) // Changeset { // errors: [ // subject: {"has no space", []} // ] // } = Ability.Produce.create().validate.(changeset, action) // } // test "validates unit isn't overloaded" { // id = UUID.generate() // unit = insert(:unit, %{ // cost: 100, // ability_data: [ // AbilityData {ability_id: Ability.Produce.id()}, // AbilityData {ability_id: Ability.Load.id(), params: ["2"]} // ] // }) // action = Action { // kind: "ability", // ability_id: AbilityKind::Produce, // params: [unit.id], // subject_tile_data_id: id, // subject: UnitData { // id: id, // unit: unit, // load_data: ["some id", "another id"] // }, // subject_user_data: UserData { // funds: 100 // }, // game: Game {} // } // changeset = Changeset.change(action) // Changeset { // errors: [ // subject: {"has no space", []} // ] // } = Ability.Produce.create().validate.(changeset, action) // } // } // describe "apply/2" { // test "creates unit when used with tile" { // id = UUID.generate() // unit = insert(:unit, %{ // cost: 100, // fuel: 23 // }) // action = Action { // kind: "ability", // ability_id: AbilityKind::Produce, // params: [unit.id], // subject_tile_data_id: id, // subject: TileData { // id: id, // coord: Coord {x: 0, y: 0}, // tile_id: Tile.City.id(), // tile: Tile.City.create() // }, // subject_user_data: UserData { // funds: 120, // user_id: "00000000-0000-0000-0000-000000000000", // team: 1, // faction: 1, // power_data: [ // PowerData {power_id: Power.CostBonus.id(), params: ["10"]} // ] // }, // game: Game {} // } // {game, _} = Ability.Produce.create().apply.(action) // assert Game { // user_data: [ // UserData { // funds: 10, // user_id: "00000000-0000-0000-0000-000000000000" // } // ], // unit_data: [ // UnitData { // unit_id: unit_id, // coord: Coord {x: 0, y: 0}, // team: 1, // faction: 1, // fuel: 23, // user_id: "00000000-0000-0000-0000-000000000000" // } // ] // } = game // assert unit_id == unit.id // } // test "creates unit when used with unit" { // id = UUID.generate() // unit = insert(:unit, %{ // cost: 100, // fuel: 23 // }) // action = Action { // kind: "ability", // ability_id: AbilityKind::Produce, // params: [unit.id], // subject_tile_data_id: id, // subject: UnitData { // id: id, // coord: Coord {x: 0, y: 0}, // unit_id: unit.id, // unit: unit, // load_data: [] // }, // subject_user_data: UserData { // funds: 100, // user_id: "00000000-0000-0000-0000-000000000000", // team: 1, // faction: 1, // power_data: [ // PowerData {power_id: Power.CostBonus.id(), params: ["-10"]} // ] // }, // game: Game {} // } // {game, _} = Ability.Produce.create().apply.(action) // assert Game { // user_data: [ // UserData { // funds: 10, // user_id: "00000000-0000-0000-0000-000000000000" // } // ], // unit_data: [ // UnitData { // id: new_unit_id, // unit_id: unit_id, // coord: Coord {x: 0, y: 0}, // team: 1, // faction: 1, // fuel: 23, // state: "exhausted", // user_id: "00000000-0000-0000-0000-000000000000" // }, // UnitData { // load_data: [new_unit_id], // state: "exhausted" // } // ] // } = game // assert unit_id == unit.id // } // } // } // test "create_action/1 kind: ability/produce as tile" { // user = insert(:user) // commander = insert(:commander) // user_data = build(:user_data, %{ // turn: true, // user_id: user.id, // commander_id: commander.id, // funds: 2_000 // }) // unit = insert(:unit, %{cost: 1_000}) // tile_data = build(:tile_data, %{ // user_id: user_data.user_id, // tile_id: Tile.Base.id(), // faction: user_data.faction, // team: user_data.team, // ability_data: [ // build(:ability_data, %{ability_id: Ability.Produce.id()}) // ] // }) // game = insert(:game, %{ // weather: "Clear", // unit_data: [], // user_data: [user_data], // tile_data: [tile_data] // }) // tile_data = game.tile_data |> Enum.at(0) // insert(:game_user, %{game: game, faction: 1}) // insert(:game_user, %{game: game, faction: 2}) // action = build(:action, %{ // kind: "ability", // ability_id: AbilityKind::Produce, // subject_tile_data_id: tile_data.id, // params: [unit.id], // game_id: game.id, // user_id: user.id // }) // |> Map.from_struct() // assert {:ok, Action { // game: Game { // unit_data: [ // UnitData {unit_id: unit_id}, // ], // user_data: [ // UserData {turn: true, funds: 1_000} // ] // } // }} = Engine.create_action(action) // assert unit.id == unit_id // } // test "create_action/1 kind: ability/produce as unit" { // user = insert(:user) // commander = insert(:commander) // user_data = build(:user_data, %{ // turn: true, // user_id: user.id, // commander_id: commander.id, // funds: 2_000 // }) // unit = insert(:unit, %{ // cost: 1_000, // ability_data: [ // build(:ability_data, %{ability_id: Ability.Produce.id()}), // build(:ability_data, %{ability_id: Ability.Load.id(), params: ["1"]}) // ] // }) // unit_data = build(:unit_data, %{ // user_id: user_data.user_id, // unit_id: unit.id // }) // game = insert(:game, %{ // unit_data: [unit_data], // user_data: [user_data] // }) // unit_data = game.unit_data |> Enum.at(0) // insert(:game_user, %{game: game, faction: 1}) // insert(:game_user, %{game: game, faction: 2}) // action = build(:action, %{ // kind: "ability", // ability_id: AbilityKind::Produce, // subject_unit_data_id: unit_data.id, // params: [unit.id], // game_id: game.id, // user_id: user.id // }) // |> Map.from_struct() // assert {:ok, Action { // game: Game { // unit_data: [ // UnitData {unit_id: unit_one_id, load_data: []} = new_unit, // UnitData {unit_id: unit_two_id, load_data: [unit_three_id]} // ], // user_data: [ // UserData {turn: true, funds: 1_000} // ] // } // }} = Engine.create_action(action) // assert unit.id == unit_one_id // assert unit.id == unit_two_id // assert new_unit.id == unit_three_id // }