{FIRMWARE_CHOICES_DDI["farmduino_k18"].label}{FIRMWARE_CHOICES_DDI["farmduino_k18"].label}{colorOverride - ? `(${point.x}, ${point.y}) z${point.z}` - : `(${point.x}, ${point.y}) r${point.radius}`} + ? `(${round(point.x)}, ${round(point.y)}) z${round(point.z)}` + : `(${round(point.x)}, ${round(point.y)}) r${round(point.radius)}`} {!isUndefined(props.distance) && {` ${round(props.distance)}mm ${t("away")}`}}
diff --git a/frontend/promo/tools.ts b/frontend/promo/tools.ts index ec350a09e3..f7ccd57560 100644 --- a/frontend/promo/tools.ts +++ b/frontend/promo/tools.ts @@ -2,7 +2,7 @@ import { ToolPulloutDirection } from "farmbot/dist/resources/api_resources"; import { ToolName } from "../farm_designer/map/tool_graphics/all_tools"; import { Config } from "../three_d_garden/config"; import { ThreeDTool } from "../three_d_garden/bot/components"; -import { zZero } from "../three_d_garden/helpers"; +import { zDir, zZero } from "../three_d_garden/helpers"; export const PROMO_TOOLS = (config: Config): ThreeDTool[] => { @@ -11,7 +11,7 @@ export const PROMO_TOOLS = (config: Config): ThreeDTool[] => { const promoToolOffset = { x: 110 + config.bedWallThickness - config.bedXOffset, y: config.bedWidthOuter / 2 - config.bedYOffset, - z: zZero(config) - 60, + z: zDir(config) * (zZero(config) - 60), }; return [ @@ -53,7 +53,7 @@ export const PROMO_TOOLS = (config: Config): ThreeDTool[] => { { x: config.x - config.bedXOffset + 140, y: -config.bedYOffset + 15, - z: zZero(config) - 100, + z: zDir(config) * (zZero(config) - 100), toolName: ToolName.seedTrough, toolPulloutDirection: ToolPulloutDirection.NONE, firstTrough: true, diff --git a/frontend/reducer.ts b/frontend/reducer.ts index 2da1c134c0..8d6149b06d 100644 --- a/frontend/reducer.ts +++ b/frontend/reducer.ts @@ -29,7 +29,6 @@ export interface AppState { jobs: JobsAndLogsState; controls: ControlsState; popups: PopupsState; - hotkeyGuide: boolean; } export const emptyState = (): AppState => { @@ -104,7 +103,6 @@ export const emptyState = (): AppState => { jobs: false, connectivity: false, }, - hotkeyGuide: false, }; }; @@ -206,10 +204,6 @@ export const appReducer = s.popups.connectivity = false; return s; }) - .addDemo Queue Length: {store.getState().bot.demoQueueLength}
{alreadyAdded ? t("Already added.") : ""}
diff --git a/frontend/tools/edit_tool.tsx b/frontend/tools/edit_tool.tsx index 1ff41fa958..e5b8ba8bfe 100644 --- a/frontend/tools/edit_tool.tsx +++ b/frontend/tools/edit_tool.tsx @@ -47,7 +47,7 @@ export interface WaterFlowRateInputProps { } export const WaterFlowRateInput = (props: WaterFlowRateInputProps) => { - return{nameTaken ? t("Name already taken.") : ""}
diff --git a/frontend/tools/index.tsx b/frontend/tools/index.tsx index 2ea70ec6d1..01d15fce3e 100644 --- a/frontend/tools/index.tsx +++ b/frontend/tools/index.tsx @@ -232,6 +232,7 @@ export const ToolSlotInventoryItem = (props: ToolSlotInventoryItemProps) => { return{t("Something else happened and I need additional help")}
{otherSelected &&diff --git a/lib/tasks/api.rake b/lib/tasks/api.rake index 68593587fe..7bac1be148 100644 --- a/lib/tasks/api.rake +++ b/lib/tasks/api.rake @@ -105,6 +105,7 @@ namespace :api do desc "Don't call this directly. Use `rake assets:precompile`." task parcel_compile: :environment do + clean_assets add_monaco parcel "build" end diff --git a/lib/tasks/fe.rake b/lib/tasks/fe.rake index 9c7c0e0f1b..baecc9abb4 100644 --- a/lib/tasks/fe.rake +++ b/lib/tasks/fe.rake @@ -38,10 +38,10 @@ EXCLUDE = [ version: "19", }, { - packages: ["three"], - reason: "not working:", - version: "0.175.0", - }, + packages: ["jest", "jest-cli", "jest-environment-jsdom"], + reason: "breaking changes (jsdom window.location) in", + version: "30", + } ] # Load package.json as JSON. diff --git a/lib/tasks/hook.rake b/lib/tasks/hook.rake index 750e0dbc51..9cda2d9a8b 100644 --- a/lib/tasks/hook.rake +++ b/lib/tasks/hook.rake @@ -34,10 +34,10 @@ def commits_since_last_deploy deploy_commit_found = true break end - commits.push(commit["commit"]["message"].gsub("\n", " ")) + commits.push([commit["commit"]["message"].gsub("\n", " "), commit["sha"]]) end if !deploy_commit_found - commits.push("[LAST DEPLOY COMMIT NOT FOUND]") + commits.push(["[LAST DEPLOY COMMIT NOT FOUND]", "0000000"]) end commits end @@ -50,7 +50,7 @@ def details(environment) web_compare_url = "#{COMPARE_URL_WEB}#{last_deploy_commit}...#{COMMIT_SHA}" output += "<#{web_compare_url}|compare>\n" messages = commits_since_last_deploy.reverse.map do |commit| - output += "\n + #{commit}" + output += "\n + #{commit[0]} | ##{commit[1][0..5]}" end output += "\n" pre = environment == "production" ? "my" : environment diff --git a/package.json b/package.json index 1175679a6f..5fc354f9a3 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "scripts": { "test-very-slow": "node --expose-gc ./node_modules/.bin/jest -i --colors --coverage", "test-slow": "node scripts/run.js ./node_modules/.bin/jest -w 3 --colors", - "test": "node scripts/run.js ./node_modules/.bin/jest -w 3 --no-coverage", + "test": "node scripts/run.js ./node_modules/.bin/jest -w 3 --colors --no-coverage", "graph-modules-dot": "./node_modules/.bin/madge --dot ./frontend > module_graph.dot", "graph-modules-svg": "dot -Tsvg module_graph.dot -o module_graph.svg", "typecheck": "node scripts/run.js ./node_modules/typescript/bin/tsc --noEmit", @@ -37,40 +37,42 @@ "@parcel/watcher": "2.1.0" }, "dependencies": { - "@blueprintjs/core": "5.19.0", - "@blueprintjs/select": "5.3.20", + "@blueprintjs/core": "6.2.1", + "@blueprintjs/select": "6.0.3", "@monaco-editor/react": "4.7.0", - "@parcel/transformer-sass": "2.15.2", - "@parcel/transformer-typescript-tsc": "2.15.2", + "@parcel/transformer-sass": "2.15.4", + "@parcel/transformer-typescript-tsc": "2.15.4", "@react-spring/three": "10.0.1", "@react-three/drei": "9.122.0", "@react-three/fiber": "8.18.0", - "@rollbar/react": "0.12.1", - "@types/lodash": "4.17.17", + "@rollbar/react": "1.0.0", + "@types/lodash": "4.17.20", "@types/markdown-it": "14.1.2", - "@types/node": "22.15.21", + "@types/node": "24.3.0", "@types/promise-timeout": "1.3.3", - "@types/react": "19.1.5", + "@types/react": "19.1.12", "@types/react-color": "3.0.13", - "@types/react-dom": "19.1.5", - "@types/three": "0.176.0", + "@types/react-dom": "19.1.9", + "@types/three": "0.179.0", "@types/ws": "8.18.1", "@xterm/xterm": "5.5.0", - "axios": "1.9.0", - "bowser": "2.11.0", + "axios": "1.11.0", + "bowser": "2.12.1", "browser-speech": "1.1.1", "delaunator": "5.0.1", "events": "3.3.0", - "farmbot": "15.8.11", - "i18next": "25.2.1", + "farmbot": "15.9.2", + "fengari": "0.1.4", + "fengari-web": "0.1.4", + "i18next": "25.4.2", "lodash": "4.17.21", "markdown-it": "14.1.0", "markdown-it-emoji": "3.0.0", "moment": "2.30.1", "monaco-editor": "0.52.2", - "mqtt": "5.13.0", - "npm": "11.4.1", - "parcel": "2.15.2", + "mqtt": "5.14.0", + "npm": "11.5.2", + "parcel": "2.15.4", "process": "0.11.10", "promise-timeout": "1.3.0", "punycode": "1.4.1", @@ -79,27 +81,27 @@ "react-color": "2.19.3", "react-dom": "18.3.1", "react-redux": "9.2.0", - "react-router": "7.6.1", + "react-router": "7.8.2", "redux": "5.0.1", "redux-immutable-state-invariant": "2.1.0", "redux-thunk": "3.1.0", "rollbar": "2.26.4", "suncalc": "1.9.0", "takeme": "0.12.0", - "three": "0.174.0", - "typescript": "5.8.3", + "three": "0.179.1", + "typescript": "5.9.2", "url": "0.11.4" }, "devDependencies": { "@react-three/eslint-plugin": "0.1.2", - "@testing-library/dom": "10.4.0", - "@testing-library/jest-dom": "6.6.3", + "@testing-library/dom": "10.4.1", + "@testing-library/jest-dom": "6.8.0", "@testing-library/react": "16.3.0", "@testing-library/user-event": "14.6.1", "@types/delaunator": "5.0.3", "@types/enzyme": "3.10.12", - "@types/jest": "29.5.14", - "@types/readable-stream": "4.0.19", + "@types/jest": "30.0.0", + "@types/readable-stream": "4.0.21", "@types/suncalc": "1.9.2", "@typescript-eslint/eslint-plugin": "7.15.0", "@typescript-eslint/parser": "7.15.0", @@ -107,8 +109,8 @@ "enzyme": "3.11.0", "eslint": "8.57.0", "eslint-plugin-eslint-comments": "3.2.0", - "eslint-plugin-import": "2.31.0", - "eslint-plugin-jest": "28.11.0", + "eslint-plugin-import": "2.32.0", + "eslint-plugin-jest": "29.0.1", "eslint-plugin-no-null": "1.0.2", "eslint-plugin-promise": "7.2.1", "eslint-plugin-react": "7.37.5", @@ -125,9 +127,9 @@ "raf": "3.4.1", "react-addons-test-utils": "15.6.2", "react-test-renderer": "18.3.1", - "sass": "1.89.0", + "sass": "1.91.0", "sass-lint": "1.13.1", - "ts-jest": "29.3.4", + "ts-jest": "29.4.1", "tslint": "5.20.1" } } diff --git a/public/3D/models/cc_horizontal.glb b/public/3D/models/cc_support_horizontal.glb similarity index 100% rename from public/3D/models/cc_horizontal.glb rename to public/3D/models/cc_support_horizontal.glb diff --git a/public/3D/models/cc_vertical.glb b/public/3D/models/cc_support_vertical.glb similarity index 100% rename from public/3D/models/cc_vertical.glb rename to public/3D/models/cc_support_vertical.glb diff --git a/public/soil.png b/public/soil.png new file mode 100644 index 0000000000..f2e072f21a Binary files /dev/null and b/public/soil.png differ diff --git a/spec/controllers/api/ai/ai_controller_spec.rb b/spec/controllers/api/ai/ai_controller_spec.rb index d82545801d..3eaebaec00 100644 --- a/spec/controllers/api/ai/ai_controller_spec.rb +++ b/spec/controllers/api/ai/ai_controller_spec.rb @@ -53,7 +53,7 @@ def chunk(content, done=nil) expect(response.body).to eq("red") end - it "handles errors" do + it "handles timeout" do sign_in user payload = { prompt: "write code", @@ -69,6 +69,23 @@ def chunk(content, done=nil) expect(response.status).to eq(422) end + it "handles error" do + sign_in user + payload = { + prompt: "write code", + context_key: "lua", + sequence_id: nil, + } + stub_request(:get, URL_PATTERN).to_return( + body: "{---\n---# section\ncontent```lua\n```}") + + stub_request(:post, "https://api.openai.com/v1/chat/completions").to_return( + body: "{\"error\":\"Invalid request\"}") + + post :create, body: payload.to_json + expect(response.status).to eq(422) + end + it "handles connection issues" do sign_in user payload = { diff --git a/spec/controllers/api/devices/devices_controller_seed_spec.rb b/spec/controllers/api/devices/devices_controller_seed_spec.rb index dbad44437f..70d0322706 100644 --- a/spec/controllers/api/devices/devices_controller_seed_spec.rb +++ b/spec/controllers/api/devices/devices_controller_seed_spec.rb @@ -171,6 +171,14 @@ def sequences_pick_from_seed_tray?(device) device.sequences.find_by(name: PublicSequenceNames::PICK_FROM_SEED_TRAY) end + def sequences_pick_from_seed_trough?(device) + device.sequences.find_by(name: PublicSequenceNames::PICK_FROM_SEED_TROUGH) + end + + def sequences_pick_from_seed_bin?(device) + device.sequences.find_by(name: PublicSequenceNames::PICK_FROM_SEED_BIN) + end + def sequences_pickup_seed?(device) device.sequences.find_by(name: "Pick up seed") end @@ -365,7 +373,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to_not be - expect(sequences_pickup_seed?(device)).to be + expect(sequences_pickup_seed?(device)).to_not be expect(sequences_plant_seed?(device)).to be_kind_of(Sequence) expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence) expect(sequences_water_plant?(device)).to be_kind_of(Sequence) @@ -387,6 +395,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to be_kind_of(Sequence) expect(sequences_mow_all_weeds?(device)).to_not be expect(sequences_pick_from_seed_tray?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_trough?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_bin?(device)).to be_kind_of(Sequence) expect(settings_default_map_size_x?(device)).to eq(2900) expect(settings_default_map_size_y?(device)).to eq(1230) end @@ -439,7 +449,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to_not be - expect(sequences_pickup_seed?(device)).to be + expect(sequences_pickup_seed?(device)).to_not be expect(sequences_plant_seed?(device)).to be_kind_of(Sequence) expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence) expect(sequences_water_plant?(device)).to be_kind_of(Sequence) @@ -461,6 +471,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to be_kind_of(Sequence) expect(sequences_mow_all_weeds?(device)).to_not be expect(sequences_pick_from_seed_tray?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_trough?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_bin?(device)).to be_kind_of(Sequence) expect(settings_default_map_size_x?(device)).to eq(2900) expect(settings_default_map_size_y?(device)).to eq(1230) end @@ -513,7 +525,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to_not be - expect(sequences_pickup_seed?(device)).to be + expect(sequences_pickup_seed?(device)).to_not be expect(sequences_plant_seed?(device)).to be_kind_of(Sequence) expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence) expect(sequences_water_plant?(device)).to be_kind_of(Sequence) @@ -535,6 +547,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to be_kind_of(Sequence) expect(sequences_mow_all_weeds?(device)).to_not be expect(sequences_pick_from_seed_tray?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_trough?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_bin?(device)).to be_kind_of(Sequence) expect(settings_default_map_size_x?(device)).to eq(2900) expect(settings_default_map_size_y?(device)).to eq(1230) end @@ -589,7 +603,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to_not be - expect(sequences_pickup_seed?(device)).to be + expect(sequences_pickup_seed?(device)).to_not be expect(sequences_plant_seed?(device)).to be_kind_of(Sequence) expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence) expect(sequences_water_plant?(device)).to be_kind_of(Sequence) @@ -611,6 +625,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to be_kind_of(Sequence) expect(sequences_mow_all_weeds?(device)).to_not be expect(sequences_pick_from_seed_tray?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_trough?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_bin?(device)).to be_kind_of(Sequence) expect(settings_default_map_size_x?(device)).to eq(2900) expect(settings_default_map_size_y?(device)).to eq(1230) end @@ -666,7 +682,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to be_kind_of(Tool) - expect(sequences_pickup_seed?(device)).to be + expect(sequences_pickup_seed?(device)).to_not be expect(sequences_plant_seed?(device)).to be_kind_of(Sequence) expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence) expect(sequences_water_plant?(device)).to be_kind_of(Sequence) @@ -688,6 +704,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to be_kind_of(Sequence) expect(sequences_mow_all_weeds?(device)).to be_kind_of(Sequence) expect(sequences_pick_from_seed_tray?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_trough?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_bin?(device)).to be_kind_of(Sequence) expect(settings_default_map_size_x?(device)).to eq(2900) expect(settings_default_map_size_y?(device)).to eq(1230) end @@ -742,7 +760,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to_not be expect(tools_rotary?(device)).to be_kind_of(Tool) - expect(sequences_pickup_seed?(device)).to be + expect(sequences_pickup_seed?(device)).to_not be expect(sequences_plant_seed?(device)).to be_kind_of(Sequence) expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence) expect(sequences_water_plant?(device)).to be_kind_of(Sequence) @@ -764,6 +782,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to be_kind_of(Sequence) expect(sequences_mow_all_weeds?(device)).to be_kind_of(Sequence) expect(sequences_pick_from_seed_tray?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_trough?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_bin?(device)).to be_kind_of(Sequence) expect(settings_default_map_size_x?(device)).to eq(2900) expect(settings_default_map_size_y?(device)).to eq(1230) end @@ -818,7 +838,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to_not be expect(tools_rotary?(device)).to be_kind_of(Tool) - expect(sequences_pickup_seed?(device)).to be + expect(sequences_pickup_seed?(device)).to_not be expect(sequences_plant_seed?(device)).to be_kind_of(Sequence) expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence) expect(sequences_water_plant?(device)).to be_kind_of(Sequence) @@ -840,6 +860,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to be_kind_of(Sequence) expect(sequences_mow_all_weeds?(device)).to be_kind_of(Sequence) expect(sequences_pick_from_seed_tray?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_trough?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_bin?(device)).to be_kind_of(Sequence) expect(settings_default_map_size_x?(device)).to eq(2900) expect(settings_default_map_size_y?(device)).to eq(1230) end @@ -892,7 +914,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to_not be - expect(sequences_pickup_seed?(device)).to be + expect(sequences_pickup_seed?(device)).to_not be expect(sequences_plant_seed?(device)).to be_kind_of(Sequence) expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence) expect(sequences_water_plant?(device)).to be_kind_of(Sequence) @@ -914,6 +936,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to be_kind_of(Sequence) expect(sequences_mow_all_weeds?(device)).to_not be expect(sequences_pick_from_seed_tray?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_trough?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_bin?(device)).to be_kind_of(Sequence) expect(settings_default_map_size_x?(device)).to eq(5900) expect(settings_default_map_size_y?(device)).to eq(2730) end @@ -968,7 +992,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to_not be - expect(sequences_pickup_seed?(device)).to be + expect(sequences_pickup_seed?(device)).to_not be expect(sequences_plant_seed?(device)).to be_kind_of(Sequence) expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence) expect(sequences_water_plant?(device)).to be_kind_of(Sequence) @@ -990,6 +1014,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to be_kind_of(Sequence) expect(sequences_mow_all_weeds?(device)).to_not be expect(sequences_pick_from_seed_tray?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_trough?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_bin?(device)).to be_kind_of(Sequence) expect(settings_default_map_size_x?(device)).to eq(5900) expect(settings_default_map_size_y?(device)).to eq(2730) end @@ -1044,7 +1070,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to_not be expect(tools_rotary?(device)).to be_kind_of(Tool) - expect(sequences_pickup_seed?(device)).to be + expect(sequences_pickup_seed?(device)).to_not be expect(sequences_plant_seed?(device)).to be_kind_of(Sequence) expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence) expect(sequences_water_plant?(device)).to be_kind_of(Sequence) @@ -1066,6 +1092,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to be_kind_of(Sequence) expect(sequences_mow_all_weeds?(device)).to be_kind_of(Sequence) expect(sequences_pick_from_seed_tray?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_trough?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_bin?(device)).to be_kind_of(Sequence) expect(settings_default_map_size_x?(device)).to eq(5900) expect(settings_default_map_size_y?(device)).to eq(2730) end @@ -1120,7 +1148,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to_not be expect(tools_rotary?(device)).to be_kind_of(Tool) - expect(sequences_pickup_seed?(device)).to be + expect(sequences_pickup_seed?(device)).to_not be expect(sequences_plant_seed?(device)).to be_kind_of(Sequence) expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence) expect(sequences_water_plant?(device)).to be_kind_of(Sequence) @@ -1142,6 +1170,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to be_kind_of(Sequence) expect(sequences_mow_all_weeds?(device)).to be_kind_of(Sequence) expect(sequences_pick_from_seed_tray?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_trough?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_bin?(device)).to be_kind_of(Sequence) expect(settings_default_map_size_x?(device)).to eq(5900) expect(settings_default_map_size_y?(device)).to eq(2730) end @@ -1197,7 +1227,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to be_kind_of(Tool) - expect(sequences_pickup_seed?(device)).to be + expect(sequences_pickup_seed?(device)).to_not be expect(sequences_plant_seed?(device)).to be_kind_of(Sequence) expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence) expect(sequences_water_plant?(device)).to be_kind_of(Sequence) @@ -1219,6 +1249,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to be_kind_of(Sequence) expect(sequences_mow_all_weeds?(device)).to be_kind_of(Sequence) expect(sequences_pick_from_seed_tray?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_trough?(device)).to be_kind_of(Sequence) + expect(sequences_pick_from_seed_bin?(device)).to be_kind_of(Sequence) expect(settings_default_map_size_x?(device)).to eq(5900) expect(settings_default_map_size_y?(device)).to eq(2730) end @@ -1289,6 +1321,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to_not be expect(sequences_mow_all_weeds?(device)).to_not be expect(sequences_pick_from_seed_tray?(device)).to_not be + expect(sequences_pick_from_seed_trough?(device)).to_not be + expect(sequences_pick_from_seed_bin?(device)).to_not be expect(settings_default_map_size_x?(device)).to eq(2900) expect(settings_default_map_size_y?(device)).to eq(930) end @@ -1359,6 +1393,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to_not be expect(sequences_mow_all_weeds?(device)).to_not be expect(sequences_pick_from_seed_tray?(device)).to_not be + expect(sequences_pick_from_seed_trough?(device)).to_not be + expect(sequences_pick_from_seed_bin?(device)).to_not be expect(settings_default_map_size_x?(device)).to eq(2900) expect(settings_default_map_size_y?(device)).to eq(930) end @@ -1429,6 +1465,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to_not be expect(sequences_mow_all_weeds?(device)).to_not be expect(sequences_pick_from_seed_tray?(device)).to_not be + expect(sequences_pick_from_seed_trough?(device)).to_not be + expect(sequences_pick_from_seed_bin?(device)).to_not be expect(settings_default_map_size_x?(device)).to eq(2900) expect(settings_default_map_size_y?(device)).to eq(930) end @@ -1499,6 +1537,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to_not be expect(sequences_mow_all_weeds?(device)).to_not be expect(sequences_pick_from_seed_tray?(device)).to_not be + expect(sequences_pick_from_seed_trough?(device)).to_not be + expect(sequences_pick_from_seed_bin?(device)).to_not be expect(settings_default_map_size_x?(device)).to eq(5900) expect(settings_default_map_size_y?(device)).to eq(2130) end @@ -1569,6 +1609,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to_not be expect(sequences_mow_all_weeds?(device)).to_not be expect(sequences_pick_from_seed_tray?(device)).to_not be + expect(sequences_pick_from_seed_trough?(device)).to_not be + expect(sequences_pick_from_seed_bin?(device)).to_not be expect(settings_default_map_size_x?(device)).to eq(5900) expect(settings_default_map_size_y?(device)).to eq(2130) end @@ -1639,6 +1681,8 @@ def check_slot_pairing(slot, expected_name) expect(sequences_dismount_tool?(device)).to_not be expect(sequences_mow_all_weeds?(device)).to_not be expect(sequences_pick_from_seed_tray?(device)).to_not be + expect(sequences_pick_from_seed_trough?(device)).to_not be + expect(sequences_pick_from_seed_bin?(device)).to_not be expect(settings_default_map_size_x?(device)).to eq(5900) expect(settings_default_map_size_y?(device)).to eq(2130) end @@ -1677,6 +1721,12 @@ def check_slot_pairing(slot, expected_name) expect(sequences_grid?(device)).to be_kind_of(Sequence) end + it "seeds accounts with demo account data when tools not available" do + start_tests "none", false, true + + expect(tools_watering_nozzle?(device)).to_not be + end + it "seeds accounts when sequence versions not available: Genesis XL 1.6" do start_tests "genesis_xl_1.6", false diff --git a/spec/controllers/dashboard_spec.rb b/spec/controllers/dashboard_spec.rb index 19fceee7a0..4b56ca9618 100644 --- a/spec/controllers/dashboard_spec.rb +++ b/spec/controllers/dashboard_spec.rb @@ -24,14 +24,38 @@ expect { get :main_app, params: { path: "nope.jpg" } }.to raise_error(ActionController::RoutingError) end - it "receives CSP violation reports (malformed JSON)" do - post :csp_reports, body: "NOT JSON ! ! !" - expect(json).to eq(problem: "Crashed while parsing report") + it "receives CSP violation reports: success" do + json_payload = { "csp-report" => { "blocked-uri" => "http://malicious.com" } } + expect(Rollbar).to receive(:info).with("CSP Violation Report", json_payload) + post :csp_reports, body: json_payload.to_json, params: { format: :json } + expect(response).to have_http_status(:no_content) end - it "receives CSP violation reports (JSON)" do - post :csp_reports, body: {}.to_json, params: { format: :json } - expect(json).to eq({}) + it "receives CSP violation reports: JSON parse error" do + malformed_json = "{ this is not valid json" + expect(Rollbar).to receive(:info).with( + "CSP Violation Report", + hash_including( + error: "CSP report parse error", + exception: kind_of(String), + raw: malformed_json + ) + ) + post :csp_reports, body: malformed_json + expect(response).to have_http_status(:no_content) + end + + it "receives CSP violation reports: empty body" do + expect(Rollbar).to receive(:info).with( + "CSP Violation Report", + hash_including( + error: "CSP report parse error", + exception: kind_of(String), + raw: "" + ) + ) + post :csp_reports, body: "" + expect(response).to have_http_status(:no_content) end it "creates a new user" do