Skip to content

Commit

Permalink
feat(action): add missing action fields
Browse files Browse the repository at this point in the history
  • Loading branch information
JKRhb committed Jun 12, 2022
1 parent 5f903ae commit e86b823
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
62 changes: 62 additions & 0 deletions lib/src/definitions/interaction_affordances/action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,75 @@ class Action extends InteractionAffordance {
/// The schema of the [output] data this [Action] produces.
DataSchema? output;

bool _idempotent = false;

/// Indicates whether the Action is idempotent (=true) or not.
///
/// Informs whether the Action can be called repeatedly with the same result,
/// if present, based on the same input.
bool get idempotent => _idempotent;

bool _safe = false;

/// Signals if the Action is safe (=true) or not.
///
/// Used to signal if there is no internal state (cf. resource state) is
/// changed when invoking an Action. In that case responses can be cached as
/// example.
bool get safe => _safe;

bool? _synchronous;

/// Indicates whether the action is synchronous (=true) or not.
///
/// A synchronous action means that the response of action contains all the
/// information about the result of the action and no further querying about
/// the status of the action is needed. Lack of this keyword means that no
/// claim on the synchronicity of the action can be made.
bool? get synchronous => _synchronous;

/// Creates a new [Action] from a [List] of [forms].
Action(super.forms, super.thingDescription);

/// Creates a new [Action] from a [json] object.
Action.fromJson(Map<String, dynamic> json, ThingDescription thingDescription,
PrefixMapping prefixMapping)
: super([], thingDescription) {
final List<String> parsedFields = [];
_parseActionFields(json, parsedFields);
parseAffordanceFields(json, prefixMapping);
}

T? _parseJsonValue<T>(
Map<String, dynamic> json, String key, final List<String> parsedFields) {
parsedFields.add(key);
final dynamic value = json[key];
if (value is T) {
return value;
}

return null;
}

void _parseIdempotent(
Map<String, dynamic> json, final List<String> parsedFields) {
_idempotent =
_parseJsonValue<bool>(json, "idempotent", parsedFields) ?? _idempotent;
}

void _parseSafe(Map<String, dynamic> json, final List<String> parsedFields) {
_safe = _parseJsonValue<bool>(json, "safe", parsedFields) ?? _safe;
}

void _parseSynchronous(
Map<String, dynamic> json, final List<String> parsedFields) {
_synchronous = _parseJsonValue<bool>(json, "synchronous", parsedFields);
}

void _parseActionFields(
Map<String, dynamic> json, final List<String> parsedFields) {
_parseIdempotent(json, parsedFields);
_parseSafe(json, parsedFields);
_parseSynchronous(json, parsedFields);
}
}
38 changes: 38 additions & 0 deletions test/core/definitions_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,43 @@ void main() {
form5Json as Map<String, dynamic>, interactionAffordance),
throwsException);
});

test("should correctly parse actions", () {
final validThingDescription = {
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"title": "MyLampThing",
"security": "nosec_sc",
"securityDefinitions": {
"nosec_sc": {"scheme": "nosec"}
},
"actions": {
"action": {
"safe": true,
"idempotent": true,
"synchronous": true,
"forms": [
{"href": "https://example.org"}
]
},
"actionWithDefaults": {
"forms": [
{"href": "https://example.org"}
]
}
}
};

final thingDescription = ThingDescription.fromJson(validThingDescription);

final action = thingDescription.actions["action"];
expect(action?.safe, true);
expect(action?.idempotent, true);
expect(action?.synchronous, true);

final actionWithDefaults = thingDescription.actions["actionWithDefaults"];
expect(actionWithDefaults?.safe, false);
expect(actionWithDefaults?.idempotent, false);
expect(actionWithDefaults?.synchronous, null);
});
});
}

0 comments on commit e86b823

Please sign in to comment.